diff --git a/.gitignore b/.gitignore index fd8fe070c..4ee047c9e 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ Makefile.platform # cmake client/build/ +client/android/build/ # Coverity cov-int/ @@ -60,9 +61,9 @@ flasher !flasher/ lua luac -fpga_compress -mfkey32 -mfkey64 +tools/fpga_compress/fpga_compress +tools/mfkey/mfkey32 +tools/mfkey/mfkey64 tools/nonce2key/nonce2key fpga/* @@ -87,7 +88,7 @@ client/dumps/* *.ice *.new armsrc/TEMP EMV/* -tools/mf_nonce_brute/* +tools/mf_nonce_brute/mf_nonce_brute tools/andrew/* tools/jtag_openocd/openocd_configuration ppls patches/* @@ -99,3 +100,6 @@ client/lualibs/pm3_cmd.lua fpga_version_info.c .proxmark3/* + +# .tmp files are created during compilation +*.tmp diff --git a/.travis.yml b/.travis.yml index d136892a4..fbf7e1df3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ os: - linux - osx -dist: xenial +dist: bionic osx_image: xcode11 @@ -27,11 +27,12 @@ addons: packages: - gcc-arm-none-eabi - libnewlib-dev - - libsndfile1-dev + - libbluetooth-dev + - python3-dev + - libbz2-dev homebrew: packages: - readline - - libsndfile - qt5 - RfidResearchGroup/proxmark3/arm-none-eabi-gcc taps: RfidResearchGroup/proxmark3 @@ -55,9 +56,9 @@ install: script: - if [ "$TO_TEST" = "MAKEFILE" ]; then make clean && make V=1 "$MAKE_PARAMS"; - ./pm3test.sh; + make check; fi - if [ "$TO_TEST" = "CMAKE" ]; then mkdir -p client/build && ( cd client/build && cmake .. && make VERBOSE=1 ); - PM3BIN=./client/build/proxmark3 ./pm3test.sh client; + make client/check CHECKARGS="--clientbin ./client/build/proxmark3"; fi diff --git a/CHANGELOG.md b/CHANGELOG.md index a81289d4c..3975e12cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,143 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix stack size and automatically use available space for BigBuf. Stack is now 5K (@slurdge) + - Added Mifare MAD Card Holder Information decoding (@lukaskuzmiak) + - Change Better precision for HF and LF voltage measurements and Add theremin.py script (@rosco) + - Added Mifare MAD Info Byte decoding. Easier to identify Card Publisher (@lukaskuzmiak) + - Change use system Bzip2 library instead of Zlib for hardnested tables, tables are now 7x smaller (@doegox) + - Change pushed some ARM source to compile with THUMB. Saves a lot of space of ARM flash memory (@slurdge) + - Change from using ZLIB compression of FPGA images in ARM to LZ4. 15%+ speedups when swapping between HF & LF now (@slurdge) + - Fix `emv scan -w` - hash mismatch, solution similar to below (@iceman1001) + - Fix 'emv roca' - hash mismatch, merged from offical repo (@pwpiwi) + - Fix 'lf ti demod' - now calculates correct crc (@iceman1001) + - Add Python3 as possible script engine (@iceman1001, @doegox) + - Add doc/mfu_binary_format_notes.md (@iceman1001) + - Fix `hf mfu dump` - now reads Ulev1 3counter vs NTAG 1 counters (@iceman1001) + - Fix `hf mfu info` - now print correct cfg1 - nfc protection (@iceman1001) + - Fix `hf mfu eload` - now detects and converts between plain/old/new mfu binary format (@iceman1001) + - Change, hitag2crack now integrated into main Makefile, tests added (@doegox) + - Add `make check` mechanics (@doegox) + - Change, log files moved to subfolders (@doegox) + - Change, use system Lua library if available (@doegox) + - Change, use system Jansson library if available (@doegox) + - Change, use system Whereami library if available (@doegox) + - Change, use system Zlib library if available (@doegox) + - Fix release version information (@doegox) + +## [ice coffee.4.9237][2020-05-21] + - Updated documentation (@doegox, @iceman1001) + - Change `pm3test.sh` - more regression tests to (@doegox, @iceman1001) + - Change `hf 15 dump` - now supports basic json format (@iceman1001) + - Change Test and fix many `-Wxxxxxx` warnings [compiler trials] (@doegox) + - Fix COVERITY warnings [compiler trials] (@doegox, @iceman1001) + - Fix CPPCHECKER warnings [compiler trials] (@doegox, @iceman1001) + - Fix CLANG warnings [compiler trials] (@doegox) + - Change, stricter warnings [compiler trials] (@doegox) + - Change, remove section version_information for client (@doegox) + - Change, Add RELEASE_NAME (@doegox) + - Change, version info also for client (@doegox) + - Added `make release` (@doegox) + - Change `trace load` - err if offline mode (@doegox) + - Fix `standalone mode matty_run` eloadcard (@iceman1001) + - Added, HF 15 traces (@FlUxIUS) + - Fix, follow naming conventions [android] (@dxl) + - Change, work directory supported [android] (@dxl) + - Added `lf fdx demod` - decoding of Bio-Thermo lf tag. Thanks to Rosco! (@iceman1001) + - Fix, 32-bit time_t compilation error on [WIN64] (@grspy) + - Change, LogTrace error msg (@doegox) + - Change, remove inline [compiler trials] (@iceman1001) + - Change, adding execute/home/current working directory functions to lua (<@iceman1001) + - Change, fix max duration in LogTrace (@doegox) + - Change, first attempt for trace log header (@iceman1001) + - Change, pm3.sh, attempt to detect BT dongle when udevadm is not available (@doegox) + - Change, pm3.sh, test access to /dev/ttyXXX files as prerequisite for [linux] (@doegox) + - iclass bf: avoid slowdown (@doegox) + - Change, pm3tests.sh, shellcheck (@doegox) + - Change, pm3.sh, shellcheck (@doegox) + - Change, pm3.sh, err msgs on stderr (@doegox) + - Change, pm3.sh, textual and --list with no device, exit 1 (@doegox) + - Change, pm3.sh, without udev: change detection routine (@doegox) + - Change, pm3.sh, alternative if udevadm is not available [termux] (@doegox) + - Change `makefiles` - allow to skip pthread [termux] (@doegox) + - Change `script run test_t55x7` - enabled param to swap modulation to test (@iceman1001) + - Add mf_nonce_brute from https://github.com/@iceman1001/mf_nonce_brute and merge to pm3 Makefile (@doegox) + - Change `lf indala demod` - more lenient size check (@iceman1001) + - Change clarify BUTTON macro usages (@doegox) + - Change fix REV macros & hitagS (@doegox) + - Change, `hf iclass loclass` -removed printvar function (@iceman1001) + - Change, clock can be negative (@iceman1001) + - Change `data tune` (@doegox) + - fancy timers (@doegox) + - Change, copied from pm3 repo (@iceman1001) + - Change psk demodualtion, keep starting samples to easily find the zero init bit (@iceman1001) + - Change use machine/endian.h with osx (Jamie Fiedler) + - Fix 2 issues in proxendian.h (@doegox) + - Fix issue #729. Avoid stalling on non-rdv4 when polling for FeliCa without card in proximity (@doegox) + - Change `lf nexwatch demod` - lenient demod sizes (@iceman1001) + - Change `lf nexwath sim/clone` - now supports 88bit format direct. (@iceman1001) + - Rewrited `standalone mode lf_em4100rwc `, added card bruteforce mode. (Dmitriy Loginoov) + - Change `data load` - color (@iceman1001) + - Change appveyor verbose (@doegox) + - Change `lf nexwatch demod` - now detects type, and show parity /chksum (@iceman1001) + - Change `lfsampling` - interruptible only when logging not yet triggered (@doegox) + - Change `lf keri demod - more leanient when it comes to bits (@iceman1001) + - fix, proper filtering of RL markers (@doegox) + - Change, clean deps [compiler trials] (@doegox) + - Change, remove c99 restrictions [compiler trials] (@doegox) + - Added tracelog file for hf mfu sniff or a ntag (@iceman1001) + - Change `trace list` - different alloc (@iceman1001) + - Change, convert OLD -> MIX (@iceman1001) + - Change `trace list` - adjust messages (@iceman1001) + - Fix a mem corruption in `trace load/list` (@doegox) + - Change, rework banners (@doegox) + - Change, Let's see if the prompt suffixed spaces are still needed.(@doegox) + - Fix colored readline prompt bug (@doegox) + - Change, simpler ul_print_type (@doegox) + - Fix cmake for reveng [compiler trials] (@doegox) + - Change, hook reveng outputs to pm3 machinery, add regression test (@doegox) + - Change, cmake android: add backslashes for host compatibility [compiler trials](@doegox) + - Change, Translation some comments from Chinese to English. [android] (@dxl) + - Change, cmake android: use common cmake files for deps [android] (@doegox) + - Fix, proper way to fix reveng getopt bug(@doegox) + - Change, cmake deps: add prefix pm3rrg_rdv4_ [compiler trials] (@doegox) + - Change, cmake deps: add -fPIC so they can be integrated in a pm3 shared lib [compiler trials] (@doegox) + - Change, platform adaptation [android] (@dxl) + - Change, don't mix ifdef and defined [android] (@dxl) + - fix `trace list`- too short array for explanation (@iceman1001) + - Change, check for sim module fw file (@iceman1001) + - Change, rpi aling warning [compiler trials] (@iceman1001) + - Change, more LF demodulation tests (@iceman1001) + - Change, update whereami and avoid compiling unnneded troublesome parts [compiler trials] (@doegox) + - Change, rework C includes in C++ [compiler trials] (@doegox) + - Change, leanient parsing of tcp:/bt:/socket: vars (@iceman1001) + - Change, add bluetooth group to `make accessrights` (@iceman1001) + - Change, `Makefile` - fix PKG_CONFIG_ENV (@uli) + - Change, `f sim` - now only fills until bigbuffer is full (@iceman1001) + - Change, `hf mf hardnested` - don't drop field when in test mode (@doegox) + - Change, `lf sim` - better to return err on faulty offset, thanks @iceman (@doegox) + - Change, `lf sim` - fix offset of last packet (@doegox) + - Change, `client Makefile` - make sure to rebuild deps when needed [compiler trials](@doegox) + - Change, silent err if dbus absent [linux] (@doegox) + - Change, `pm3.sh` - for direct bt devices (@doegox) + - Change, `pm3.sh` - moved WSL/PS3.x bt native to be tested first. Since call to Win32_serialport crashes it. (@iceman1001) + - Change, `pm3.sh` - Bt dongle, bt direct listing of serial ports on WSL and PS3.x, now using powershell.exe since wmic is deprecated (@iceman1001) + - Change, remove libsndfile (@doegox) + - Change, enforce PACKED structs [compiler trials] (@iceman1001) + - Change, adjust number of threads according to cpu (@iceman1001) + - Change, `hitag2crack` compile flags(@doegox) + - Change, msdsal fix bug after var de-shadowing (@doegox) + - Change, lighter msg for loading prefs, json will anyway always tell the filename (@doegox) + - Change, make sure colors and emoji are disabled when not on TTY (@doegox) + - Added `pref` command. PM3 client now support user preferences saved to a json file. (@mwalker33) + - Added native support for Bluetooth in client [linux] (@doegox) + - Added `LF_EM4100RSWB` (based on `LF_EM4100RWC`) standalone mode to read/sim/clone/brute EM4100 cards (@Monster1024) - Added `HF_MSDSAL` standalone mode which read and emulate Visa EMV cards (@Netxing) - - Added Mifare Ultralight tear off experiment (@cintainfinita and @fukmar) + - Added `hf mfu tear` - Mifare Ultralight tear off experiment (@cintainfinitam, @fukmar) - Added Mifare Desfire Read/Write/Create files/records/values functionality and several fixes to `hf mfdes` (@bkerler) - Added CreateStdFile command to Mifare `hf mfdes` (@bkerler) - Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler) - - Port 'hf mfdes' Authentification to CommandNG structure, fix auth session key (@bkerler) + - Port `hf mfdes` Authentification to CommandNG structure, fix auth session key (@bkerler) - Updates `hf mfdes` functions, improved logging and added new commands (@bkerler) - Updated 'legic.lua' and 'legic_clone.lua' script - works with current command set (@Pizza_4u) - Rewrote `hf mfdes` functions and added apdu debugging (@bkerler) @@ -17,10 +148,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Improved `hf 14a info` - card detection handling (@bkerler) - Updated helptext layout in all luascripts (@iceman1001) - Change `hf mfdes info` - output and logging (@bkerler) - - Updated texts in legic commands (@ikarus23) + - Updated texts in `hf legic` commands (@ikarus23) - Fix timing bug inside 40x5 (@mwalker33) - Refactored all Hitag2 attacks (@doegox) - Added two new Hitag2 attacks (@doegox) + - Change `hf iclass decrypt` - limit amount of data to read if wrong app limit (@iceman1001) - Change `hf search` - now continue to search in case of dual tech cards (@iceman1001) Thanks to @ikarus23 for the suggestion! - Added `hf topas info` - old reader command, now also prints NDEF (@iceman1001) - Change `hf topaz reader` - now only prints lighter info, like UID. (@iceman1001) @@ -39,14 +171,14 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Change - NDEF supports more signatures now (@iceman1001) - OSX Makefile now supports `make style` and `make checks` (@Pizza_4u) - Added `HF_LEGIC` standalone mode to read and simulate a Legic prime tag (@Pizza_4u) - - Added keri MS decode/encode and update 'lf keri clone' to support MS fc/cid cloning. (@mwalker33) - - Fix 'hf mfdes enum' - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001) - - Fix 'hf mfdes info' - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001) + - Added keri MS decode/encode and update `lf keri clone` to support MS fc/cid cloning. (@mwalker33) + - Fix `hf mfdes enum` - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001) + - Fix `hf mfdes info` - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001) - :smiling_imp: support (@doegox) - Additional colour changes as recommended by @iceman (@dunderhay) - Change type colour for `hf 14a` card types (@dunderhay) - Add colour to `hf mfdes` command (@dunderhay) - - Add 'HINTS' command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001) + - Add `HINTS` command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001) - Add colour to `hf 14a` and `hf mfu` commands (@dunderhay) - Add colour to `lf hid` commands (@dunderhay) - Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay) diff --git a/Makefile b/Makefile index 5c7947fc5..f7a434d3b 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,9 @@ ifneq (,$(DESTDIR)) endif endif -all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% +all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% mf_nonce_brute/% fpga_compress/% +# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack" +#all clean install uninstall check: %: hitag2crack/% INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py INSTALLSIMFW=sim011.bin sim011.sha512.txt @@ -78,12 +80,49 @@ ifeq ($(platform),Linux) endif $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) +# tests +mfkey/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +nonce2key/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +mf_nonce_brute/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +fpga_compress/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +bootrom/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +armsrc/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +client/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +recovery/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +hitag2crack/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +common/check: FORCE + $(info [*] CHECK $(patsubst %/check,%,$@)) + $(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@) +check: common/check + $(info [*] ALL CHECKS DONE) + mfkey/%: FORCE $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR) nonce2key/%: FORCE $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR) +mf_nonce_brute/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C tools/mf_nonce_brute $(patsubst mf_nonce_brute/%,%,$@) DESTDIR=$(MYDESTDIR) fpga_compress/%: FORCE $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR) @@ -101,9 +140,12 @@ recovery/install: bootrom/all armsrc/all recovery/%: FORCE cleanifplatformchanged $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR) +hitag2crack/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C tools/hitag2crack $(patsubst hitag2crack/%,%,$@) DESTDIR=$(MYDESTDIR) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) -.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged +.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key mf_nonce_brute hitag2crack style miscchecks release FORCE udev accessrights cleanifplatformchanged help: @echo "Multi-OS Makefile" @@ -122,10 +164,14 @@ help: @echo "+ client - Make only the OS-specific host client" @echo "+ mfkey - Make tools/mfkey" @echo "+ nonce2key - Make tools/nonce2key" + @echo "+ mf_nonce_brute - Make tools/mf_nonce_brute" + @echo "+ hitag2crack - Make tools/hitag2crack" @echo "+ fpga_compress - Make tools/fpga_compress" @echo @echo "+ style - Apply some automated source code formatting rules" - @echo "+ checks - Detect various encoding issues in source code" + @echo "+ check - Run offline tests. Set CHECKARGS to pass arguments to the test script" + @echo "+ .../check - Run offline tests against specific target. See above." + @echo "+ miscchecks - Detect various encoding issues in source code" @echo @echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4" @echo "To activate verbose mode, use make V=1" @@ -152,8 +198,12 @@ mfkey: mfkey/all nonce2key: nonce2key/all +mf_nonce_brute: mf_nonce_brute/all + fpga_compress: fpga_compress/all +hitag2crack: hitag2crack/all + newtarbin: $(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz @touch proxmark3-$(platform)-bin.tar @@ -164,7 +214,7 @@ tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin # detect if there were changes in the platform definitions, requiring a clean cleanifplatformchanged: -ifeq ($(PLATFORM_CHANGED), true) +ifeq ($(PLATFORM_CHANGED),true) $(info [!] Platform definitions changed, cleaning bootrom/armsrc/recovery first...) $(Q)$(MAKE) --no-print-directory -C bootrom clean $(Q)$(MAKE) --no-print-directory -C armsrc clean @@ -186,8 +236,10 @@ udev: accessrights: ifneq ($(wildcard /etc/arch-release),) #If user is running ArchLinux sudo usermod -aG uucp $(USER) #Use specific command and group + sudo usermod -aG bluetooth $(USER) #Use specific command and group else sudo adduser $(USER) dialout + sudo adduser $(USER) bluetooth endif # easy printing of MAKE VARIABLES @@ -209,7 +261,7 @@ style: --align-pointer=name {} \; # Detecting weird codepages and tabs. -checks: +miscchecks: # Make sure recode is installed @which recode >/dev/null || ( echo "Please install 'recode' package first" ; exit 1 ) @echo "Files with suspicious chars:" @@ -228,5 +280,39 @@ endif # @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ # -exec grep -lP '\\t' {} \; +release: VERSION="v4.$(shell git log --oneline master | wc -l)" +release: + $(if $(findstring master,$(shell git rev-parse --abbrev-ref HEAD)),,$(error "!!! you are not on master branch, aborting")) + $(if $(findstring dirty,$(shell git describe --dirty --always)),$(error "!!! you have pending changes, aborting")) + $(if $(RELEASE_NAME),,$(error "!!! missing RELEASE_NAME, aborting")) + # Preparing a commit for release tagging, to be reverted after tagging. + @echo "# - Release Tag: $(VERSION)" + @echo "# - Release Name: $(RELEASE_NAME)" + # - Removing -Werror... + @find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \; + @find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \; + # - Changing banner... + @sed -i "s/^#define BANNERMSG3 .*/#define BANNERMSG3 \"Release $(VERSION) - $(RELEASE_NAME)\"/" client/src/proxmark3.c + @echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c + # - Committing temporarily... + @git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)" + # - Tagging temporarily... + @git tag -a -m "Release $(VERSION) - $(RELEASE_NAME)" $(VERSION) + # - Changing default version information based on new tag + @$(SH) tools/mkversion.sh > common/default_version.c.tmp && $(MV) common/default_version.c.tmp common/default_version.c + # - Removing mkversion calls + @sed -i 's#^.*\.\./tools/mkversion.sh.*|| #\t$$(Q)#' client/Makefile bootrom/Makefile armsrc/Makefile + @sed -i '/COMMAND/s/sh .*|| //' client/CMakeLists.txt + # - Deleting tag... + @git tag -d $(VERSION) + # - Amending commit... + @git commit -a --amend -m "Release $(VERSION) - $(RELEASE_NAME)" + # - Tagging again... + @git tag -a -m "Release $(VERSION) - $(RELEASE_NAME)" $(VERSION) + # - Reverting tagged commit... + @git revert --no-edit HEAD + @echo "===================================================================" + @echo "Done! You can now execute 'git push && git push origin $(VERSION)'" + # Dummy target to test for GNU make availability _test: diff --git a/Makefile.defs b/Makefile.defs index 4068d7516..fb8a7a45b 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -24,6 +24,9 @@ CROSS ?= arm-none-eabi- CC = gcc CXX = g++ LD = g++ +SH = sh +BASH = bash +PERL = perl PATHSEP=/ PREFIX ?= /usr/local @@ -44,3 +47,57 @@ else AR= ar rcs RANLIB= ranlib endif + +DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe +# Some more warnings we want as errors: +DEFCFLAGS += -Wbad-function-cast -Wredundant-decls -Wmissing-prototypes -Wchar-subscripts -Wshadow -Wundef -Wwrite-strings -Wunused -Wuninitialized -Wpointer-arith -Winline -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wmissing-declarations -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits -Wold-style-definition +# Some more warnings we need first to eliminate, so temporarely tolerated: +DEFCFLAGS += -Wcast-align -Wno-error=cast-align +DEFCFLAGS += -Wswitch-enum -Wno-error=switch-enum + +ifeq ($(platform),Darwin) +# their readline has strict-prototype issues +DEFCFLAGS += -Wno-strict-prototypes +else +DEFCFLAGS += -Wstrict-prototypes +endif + +# Next ones are activated only if GCCEXTRA=1 or CLANGEXTRA=1 +EXTRACFLAGS = +EXTRACFLAGS += -Wunused-parameter -Wno-error=unused-parameter +EXTRACFLAGS += -Wsign-compare -Wno-error=sign-compare +EXTRACFLAGS += -Wconversion -Wno-error=conversion -Wno-error=sign-conversion -Wno-error=float-conversion + +# unknown to clang or old gcc: +# First we activate Wextra then we explicitly list those we know about +# Those without -Wno-error are supposed to be completely solved +GCCEXTRACFLAGS = -Wextra +GCCEXTRACFLAGS += -Wclobbered -Wno-error=clobbered +GCCEXTRACFLAGS += -Wcast-function-type +GCCEXTRACFLAGS += -Wimplicit-fallthrough=3 -Wno-error=implicit-fallthrough +GCCEXTRACFLAGS += -Wmissing-parameter-type +GCCEXTRACFLAGS += -Wold-style-declaration -Wno-error=old-style-declaration +GCCEXTRACFLAGS += -Woverride-init +GCCEXTRACFLAGS += -Wshift-negative-value +GCCEXTRACFLAGS += -Wunused-but-set-parameter -Wno-error=unused-but-set-parameter +ifeq ($(GCCEXTRA),1) + DEFCFLAGS += $(GCCEXTRACFLAGS) $(EXTRACFLAGS) +endif +# unknown to gcc or old clang: +# First we activate Wextra then we explicitly list those we know about +# Those without -Wno-error are supposed to be completely solved +CLANGEXTRACFLAGS = -Wextra +CLANGEXTRACFLAGS += -Wtautological-type-limit-compare +CLANGEXTRACFLAGS += -Wnull-pointer-arithmetic +CLANGEXTRACFLAGS += -Woverride-init +CLANGEXTRACFLAGS += -Wshift-negative-value +CLANGEXTRACFLAGS += -Wimplicit-fallthrough +ifeq ($(CLANGEXTRA),1) + DEFCFLAGS += $(CLANGEXTRACFLAGS) $(EXTRACFLAGS) +endif +ifeq ($(CLANGEVERYTHING),1) + DEFCFLAGS += -Weverything -Wno-error +endif +ifeq ($(NOERROR),1) + DEFCFLAGS += -Wno-error +endif diff --git a/Makefile.host b/Makefile.host index 9f5688939..07b8c2199 100644 --- a/Makefile.host +++ b/Makefile.host @@ -15,8 +15,10 @@ ifeq ($(DEFSBEENHERE),) $(error Can't find Makefile.defs) endif -CFLAGS ?= -Wall -Werror -O3 +CFLAGS ?= $(DEFCFLAGS) CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) +LDFLAGS += $(MYLDFLAGS) +LDLIBS += $(MYLDLIBS) vpath %.c $(MYSRCPATHS) @@ -66,7 +68,7 @@ $(BINDIR)/$(LIB_A): $(MYOBJS) $(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS) $(info [=] LD $(notdir $@)) - $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) + $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) $(MYLDLIBS) $(OBJDIR)/%.o : %.c | $(OBJDIR) $(info [-] CC $<) diff --git a/Makefile.platform.sample b/Makefile.platform.sample index 8d587e3b7..8a31a0e9c 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -2,7 +2,7 @@ # Run 'make PLATFORM=' to get an exhaustive list of possible parameters for this file. PLATFORM=PM3RDV4 +#PLATFORM=PM3OTHER # If you want more than one PLATFORM_EXTRAS option, separate them by spaces: #PLATFORM_EXTRAS=BTADDON -#STANDALONE=LF_SAMYRUN -STANDALONE=LF_ICEHID +#STANDALONE=HF_MSDSAL diff --git a/README.md b/README.md index f97017965..9d69ba832 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # RRG / Iceman repo - Proxmark3 + + | Releases | Linux & OSX CI | Windows CI | Coverity | | ------------------- |:-------------------:| -------------------:| -------------------:| -| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| +| [![Latest release](https://img.shields.io/github/v/release/rfidresearchgroup/proxmark3)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://api.travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| @@ -16,15 +18,22 @@ |[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| **[Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md)** | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| |[Proxmark3 GUI](#proxmark3-gui)|**[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)**|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) || -|[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| -|[Notes on frame format](/doc/new_frame_format.md)|[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| -|[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| -|[Notes on Termux / Android](/doc/termux_notes.md)|**[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)**|[Complete client command set](/doc/commands.md)| -|[Notes on tracedata / wireshark](/doc/trace_notes.md)|**[JTAG](/doc/jtag_notes.md)**|| -|[Notes on loclass](/doc/loclass_notes.md)||| -|[Notes on paths](/doc/path_notes.md)||| -|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || -|[Donations](#Donations)||| +|[Donations](#Donations)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| +||[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| +||**[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)**|[Complete client command set](/doc/commands.md)| +||**[JTAG](/doc/jtag_notes.md)**|| + + +## Notes / helpful documents + +| Notes ||| +| ------------------- |:-------------------:| -------------------:| +|[Notes on UART](/doc/uart_notes.md)|[Notes on Termux / Android](/doc/termux_notes.md)|[Notes on paths](/doc/path_notes.md)| +|[Notes on frame format](/doc/new_frame_format.md)|[Notes on tracelog / wireshark](/doc/trace_notes.md)|[Notes on EMV](/doc/emv_notes.md)| +|[Notes on external flash](/doc/ext_flash_notes.md)|[Notes on loclass](/doc/loclass_notes.md)|[Notes on Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md)| +|[Notes on file formats used with Proxmark3](/doc/extensions_notes.md)|[Notes on MFU binary format](/doc/mfu_binary_format_notes.md)|[Notes on FPGA & ARM](/doc/fpga_arm_notes.md)| +|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)|| + ## Build for non-RDV4 Proxmark3 platforms @@ -48,30 +57,63 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). This repo compiles nicely on - Proxspace v3.x - - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - - Ubuntu 1604, 1804, 1904 + - [latest release v3.4](https://github.com/Gator96100/ProxSpace/releases) + - Windows/mingw environment with Qt5.6.1 & GCC 4.9 + - Ubuntu 1604 -> 2004 + - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora, Debian + - Rasbian + - Android / Termux - Mac OS X / Homebrew - - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container + - [ RRG / Iceman repo based ubuntu 18.04 container ](https://hub.docker.com/r/secopsconsult/proxmark3) + - [ Iceman fork based container v1.7 ](https://hub.docker.com/r/iceman1001/proxmark3/) +Hardware to run client on + - PC + - Android + - Raspberry Pi & Raspberry Pi Zero + - Jetson Nano + +## Precompiled binaries +We don't maintain any precompiled binaries in this repo. There is community effort over at the Proxmark3 forum where @gator96100 has set up a google drive with many mingw binaries which is up-to-date. We link to these files here as to make it easier for users. +If you are having troubles with these files, contact the package maintainer @gator96100 and read the [sticky thread at forum](http://www.proxmark.org/forum/viewtopic.php?pid=24763#p24763) where known issues has been documented. + + +Ref: + +- [Precompiled builds for RDV40 dedicated x86](https://drive.google.com/open?id=13zUs-aiQkYaSl5KWrBtuW5IWCoHJPsue) +- [Precompiled builds for RDV40 dedicated x64](https://drive.google.com/open?id=1SyPB8t5Vo8O0Lh7PjNm3Kv-mO4BNbxjX) + +- [Precompiled builds for RDV40 dedicated with Bluetooth addon x86](https://drive.google.com/open?id=1TqWYctkRvkLshQ1ZRBHPLDzYHR-asuMO) +- [Precompiled builds for RDV40 dedicated with Bluetooth addon x64](https://drive.google.com/open?id=17ful7u2QyYmMQzQzc5fAf8nJvyoDJfSL) + +Generice Proxmark3 devices (non RDV4) +- [Precompiled builds for RRG / Iceman repository x86](https://drive.google.com/open?id=1PI3Xr1mussPBPnYGu4ZjWzGPARK4N7JR) +- [Precompiled builds for RRG / Iceman repository x64](https://drive.google.com/open?id=1uX9RtYGinuFrpHybu4xq_BE3HrobI20e) + + +## Roadmap The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing. > 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. -## Notes / helpful documents -- notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md). -- notes on [UART](/doc/uart_notes.md) -- notes on [Frame format](/doc/new_frame_format.md) -- notes on [external flash](/doc/ext_flash_notes.md) -- notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) -- notes on [Termux / Android](/doc/termux_notes.md) -- notes on [tracedata / Wireshark](/doc/trace_notes.md) -- notes on [loclass](/doc/loclass_notes.md) -- notes on [EMV](/doc/emv_notes.md) -- notes on [Paths](/doc/path_notes.md) -- notes on [file formats used with Proxmark3](/doc/extensions_notes.md) + +## Issues & Troubleshooting +Please search the [issues](https://github.com/rfidresearchgroup/proxmark3/issues) page here and see if your issue is listed in the first instance. Next place to visit is the [Proxmark Forum](http://www.proxmark.org/forum/index.php). Learn to search it well and finally Google / duckduckgo is your friend :) You will find many blogposts, youtube videos, tweets, reddit + +Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems. + +Offical channels + - [Proxmark3 IRC channel](http://webchat.freenode.net/?channels=#proxmark3) + - [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/) + - [Twitter](https://twitter.com/proxmark3/) + + _no discord or slack channel_ + +Iceman has quite a few videos on his [youtube channel](https://www.youtube.com/c/ChrisHerrmann1001) + ## Cheat sheet Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) @@ -90,13 +132,6 @@ The separation from official Proxmark3 repo gives us a lot of freedom to create The official PM3-GUI from Gaucho will not work. The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) Almost, change needed in order to show helptext when client isn't connected to a device. -## Issues - -Please see the [Proxmark Forum](http://www.proxmark.org/forum/index.php) and see if your issue is listed in the first instance Google is your friend :) Questions will be answered via the forum by Iceman and the team. - -Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems. - - ## The end - July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001) diff --git a/appveyor.yml b/appveyor.yml index 230bb44bf..a97a65276 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -187,7 +187,7 @@ build_script: #make - bash -c -i 'pwd;make clean;make all' + bash -c -i 'pwd;make clean;make V=1' #some checks @@ -204,7 +204,7 @@ build_script: } - if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z)){ + if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.bz2)){ throw "Files in client\resources\hardnested_tables is not exists." @@ -371,7 +371,7 @@ test_script: ExecTest "arm recovery image exists" "proxmark3_recovery.bin" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\proxmark3_recovery.bin} - ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.z} + ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.bz2} ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip} diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 765d230a5..6d272f571 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -12,35 +12,50 @@ #include "string.h" #include "dbprint.h" +#include "pm3_cmd.h" + +extern uint8_t _stack_start, __bss_end__; // BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces. // Also used to hold various smaller buffers and the Mifare Emulator Memory. -// declare it as uint32_t to achieve alignment to 4 Byte boundary -static uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)]; +// We know that bss is aligned to 4 bytes. +static uint8_t* BigBuf = &__bss_end__; /* BigBuf memory layout: Pointer to highest available memory: BigBuf_hi - - high BIGBUF_SIZE + high BigBuf_size reserved = BigBuf_malloc() subtracts amount from BigBuf_hi, low 0x00 */ +static uint32_t BigBuf_size = 0; + // High memory mark -static uint16_t BigBuf_hi = BIGBUF_SIZE; +static uint32_t BigBuf_hi = 0; // pointer to the emulator memory. static uint8_t *emulator_memory = NULL; // trace related variables static uint32_t traceLen = 0; -static bool tracing = true; //todo static? +static bool tracing = true; + +// compute the available size for BigBuf +void BigBuf_initialize(void) { + BigBuf_size = (uint32_t)&_stack_start - (uint32_t)&__bss_end__; + BigBuf_hi = BigBuf_size; + traceLen = 0; +} // get the address of BigBuf uint8_t *BigBuf_get_addr(void) { return (uint8_t *)BigBuf; } +uint32_t BigBuf_get_size(void) { + return BigBuf_size; +} + // get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done uint8_t *BigBuf_get_EM_addr(void) { // not yet allocated @@ -57,9 +72,9 @@ void BigBuf_Clear(void) { // clear ALL of BigBuf void BigBuf_Clear_ext(bool verbose) { - memset(BigBuf, 0, BIGBUF_SIZE); + memset(BigBuf, 0, BigBuf_size); if (verbose) - Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE); + Dbprintf("Buffer cleared (%i bytes)", BigBuf_size); } void BigBuf_Clear_EM(void) { @@ -73,7 +88,7 @@ void BigBuf_Clear_keep_EM(void) { // allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory // at the beginning of BigBuf is always for traces/samples uint8_t *BigBuf_malloc(uint16_t chunksize) { - if (BigBuf_hi - chunksize < 0) + if (BigBuf_hi < chunksize) return NULL; // no memory left chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4 @@ -83,7 +98,7 @@ uint8_t *BigBuf_malloc(uint16_t chunksize) { // free ALL allocated chunks. The whole BigBuf is available for traces or samples again. void BigBuf_free(void) { - BigBuf_hi = BIGBUF_SIZE; + BigBuf_hi = BigBuf_size; emulator_memory = NULL; // shouldn't this empty BigBuf also? } @@ -93,16 +108,16 @@ void BigBuf_free_keep_EM(void) { if (emulator_memory != NULL) BigBuf_hi = emulator_memory - (uint8_t *)BigBuf; else - BigBuf_hi = BIGBUF_SIZE; + BigBuf_hi = BigBuf_size; // shouldn't this empty BigBuf also? } void BigBuf_print_status(void) { - DbpString(_BLUE_("Memory")); - Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE); + DbpString(_CYAN_("Memory")); + Dbprintf(" BigBuf_size.............%d", BigBuf_size); Dbprintf(" Available memory........%d", BigBuf_hi); - DbpString(_BLUE_("Tracing")); + DbpString(_CYAN_("Tracing")); Dbprintf(" tracing ................%d", tracing); Dbprintf(" traceLen ...............%d", traceLen); } @@ -146,41 +161,37 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ if (!tracing) return false; uint8_t *trace = BigBuf_get_addr(); + tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + traceLen); uint32_t num_paritybytes = (iLen - 1) / 8 + 1; // number of valid paritybytes in *parity - uint32_t duration = timestamp_end - timestamp_start; // Return when trace is full - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) { + if (TRACELOG_HDR_LEN + iLen + num_paritybytes >= BigBuf_max_traceLen() - traceLen) { tracing = false; // don't trace any more return false; } - // Traceformat: - // 32 bits timestamp (little endian) - // 16 bits duration (little endian) - // 16 bits data length (little endian, Highest Bit used as readerToTag flag) - // y Bytes data - // x Bytes parity (one byte per 8 bytes data) - // timestamp (start) - trace[traceLen++] = ((timestamp_start >> 0) & 0xff); - trace[traceLen++] = ((timestamp_start >> 8) & 0xff); - trace[traceLen++] = ((timestamp_start >> 16) & 0xff); - trace[traceLen++] = ((timestamp_start >> 24) & 0xff); - - // duration - trace[traceLen++] = ((duration >> 0) & 0xff); - trace[traceLen++] = ((duration >> 8) & 0xff); - - // data length - trace[traceLen++] = ((iLen >> 0) & 0xff); - trace[traceLen++] = ((iLen >> 8) & 0xff); - - // readerToTag flag - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; + uint32_t duration; + if (timestamp_end > timestamp_start) { + duration = timestamp_end - timestamp_start; + } else { + duration = (UINT32_MAX - timestamp_start) + timestamp_end; } + if (duration > 0x7FFF) { + if (DBGLEVEL >= DBG_DEBUG) { + Dbprintf("Error in LogTrace: duration too long for 15 bits encoding: 0x%08x start:0x%08x end:0x%08x", duration, timestamp_start, timestamp_end); + Dbprintf("Forcing duration = 0"); + } + duration = 0; + } + + hdr->timestamp = timestamp_start; + hdr->duration = duration; + hdr->data_len = iLen; + hdr->isResponse = !readerToTag; + traceLen += TRACELOG_HDR_LEN; + // data bytes if (btBytes != NULL && iLen != 0) { memcpy(trace + traceLen, btBytes, iLen); diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index ad967c4c7..60857e82a 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -14,7 +14,6 @@ #include "common.h" -#define BIGBUF_SIZE 40000 #define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame #define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8) #define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC @@ -23,8 +22,10 @@ #define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!? uint8_t *BigBuf_get_addr(void); +uint32_t BigBuf_get_size(void); uint8_t *BigBuf_get_EM_addr(void); uint16_t BigBuf_max_traceLen(void); +void BigBuf_initialize(void); void BigBuf_Clear(void); void BigBuf_Clear_ext(bool verbose); void BigBuf_Clear_keep_EM(void); diff --git a/armsrc/Makefile b/armsrc/Makefile index 747f4254b..f4eb19963 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -20,8 +20,7 @@ endif #in the next section to remove that particular feature from compilation. # NO space,TABs after the "\" sign. APP_CFLAGS = $(PLATFORM_DEFS) \ - -DON_DEVICE \ - -fno-strict-aliasing -ffunction-sections -fdata-sections + -ffunction-sections -fdata-sections SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c SRC_ISO15693 = iso15693.c iso15693tools.c @@ -76,13 +75,13 @@ include Standalone/Makefile.inc #the FPGA bitstream files. Note: order matters! FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit -#the zlib source files required for decompressing the fpga config at run time -SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c -#additional defines required to compile zlib -ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED -APP_CFLAGS += $(ZLIB_CFLAGS) -# zlib includes: -APP_CFLAGS += -I../common/zlib +#the lz4 source files required for decompressing the fpga config at run time +SRC_LZ4 = lz4.c +#additional defines required to compile lz4 +LZ4_CFLAGS = -DLZ4_MEMORY_USAGE=8 +APP_CFLAGS += $(LZ4_CFLAGS) +# lz4 includes: +APP_CFLAGS += -I../common/lz4 # stdint.h provided locally until GCC 4.5 becomes C99 compliant, # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc @@ -94,13 +93,21 @@ THUMBSRC = start.c \ $(SRC_ISO15693) \ $(SRC_NFCBARCODE) \ $(SRC_LF) \ - $(SRC_ZLIB) \ + $(SRC_LZ4) \ $(SRC_LEGIC) \ $(SRC_FLASH) \ $(SRC_SMARTCARD) \ $(SRC_FPC) \ $(SRC_HITAG) \ $(SRC_SPIFFS) \ + $(SRC_ISO14443a) \ + $(SRC_ISO14443b) \ + $(SRC_CRAPTO1) \ + $(SRC_ICLASS) \ + $(SRC_EMV) \ + $(SRC_CRC) \ + $(SRC_FELICA) \ + $(SRC_STANDALONE) \ appmain.c \ printf.c \ dbprint.c \ @@ -115,14 +122,6 @@ THUMBSRC = start.c \ # These are to be compiled in ARM mode ARMSRC = fpgaloader.c \ - $(SRC_ISO14443a) \ - $(SRC_ISO14443b) \ - $(SRC_CRAPTO1) \ - $(SRC_ICLASS) \ - $(SRC_EMV) \ - $(SRC_CRC) \ - $(SRC_FELICA) \ - $(SRC_STANDALONE) \ parity.c \ usb_cdc.c \ cmd.c @@ -133,8 +132,6 @@ VERSIONSRC = version.c \ # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common_arm/Makefile.common -COMMON_FLAGS = -Os - INSTALLFW = $(OBJDIR)/fullimage.elf ifneq (,$(FWTAG)) INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf)) @@ -145,16 +142,19 @@ endif OBJS = $(OBJDIR)/fullimage.s19 FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress -all: $(OBJS) +all: showinfo $(OBJS) + +showinfo: + $(info compiler version: $(shell $(CC) --version|head -n 1)) .DELETE_ON_ERROR: # version.c should be remade on every time fullimage.stage1.elf should be remade version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [-] GEN $@) - $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ -fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR) +fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) $(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@ @@ -176,7 +176,7 @@ $(FPGA_COMPRESSOR): $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [=] LD $@) - $(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) + $(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) $(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf $(info [-] GEN $@) @@ -204,7 +204,7 @@ $(OBJDIR)/fullimage.data.o: $(OBJDIR)/fullimage.data.bin.z $(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o $(info [=] LD $@) - $(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ + $(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ tarbin: $(OBJS) $(info TAR $@) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 5c462053b..c6dc9952e 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -17,6 +17,9 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_EM4100EMUL | Simulate predefined em4100 tags only | | | | +----------------------------------------------------------+ +| LF_EM4100RSWB | Read/simulate/brute em4100 tags & | +| | clone it to T555x tags | ++----------------------------------------------------------+ | LF_EM4100RWC | Read/simulate em4100 tags & clone it | | | to T555x tags | +----------------------------------------------------------+ @@ -55,7 +58,7 @@ define KNOWN_STANDALONE_DEFINITIONS +----------------------------------------------------------+ endef -STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RWC LF_HIDBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN +STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RWC LF_HIDBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN STANDALONE_MODES += HF_14ASNIFF HF_BOG HF_COLIN HF_LEGIC HF_MATTYRUN HF_MSDSAL HF_YOUNG STANDALONE_MODES_REQ_SMARTCARD := STANDALONE_MODES_REQ_FLASH := LF_ICEHID HF_14ASNIFF HF_BOG HF_COLIN diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index 6182b6948..a06cfe75e 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -45,6 +45,10 @@ endif ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS))) SRC_STANDALONE = lf_em4100emul.c endif +# WITH_STANDALONE_LF_EM4100RSWB +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWB,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100rswb.c +endif # WITH_STANDALONE_LF_EM4100RWC ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS))) SRC_STANDALONE = lf_em4100rwc.c diff --git a/armsrc/Standalone/hf_14asniff.c b/armsrc/Standalone/hf_14asniff.c index 706a41b8b..c52928825 100644 --- a/armsrc/Standalone/hf_14asniff.c +++ b/armsrc/Standalone/hf_14asniff.c @@ -68,7 +68,7 @@ #define HF_14ASNIFF_LOGFILE "hf_14asniff.trc" -void DownloadTraceInstructions() { +static void DownloadTraceInstructions(void) { Dbprintf(""); Dbprintf("To get the trace from flash and display it:"); Dbprintf("1. mem spiffs dump o "HF_14ASNIFF_LOGFILE" f trace.trc"); @@ -81,7 +81,7 @@ void ModInfo(void) { DownloadTraceInstructions(); } -void RunMod() { +void RunMod(void) { StandAloneMode(); Dbprintf("Starting standalone mode: hf_14asniff"); diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index d1cc2e202..50e1d824f 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -41,7 +41,7 @@ from the client to view the stored quadlets. #define HF_BOG_LOGFILE "hf_bog.log" // This is actually copied from SniffIso14443a -void RAMFUNC SniffAndStore(uint8_t param) { +static void RAMFUNC SniffAndStore(uint8_t param) { iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); @@ -235,7 +235,7 @@ void ModInfo(void) { DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)"); } -void RunMod() { +void RunMod(void) { StandAloneMode(); diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index ffe2a613f..8e20ae414 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -81,12 +81,12 @@ */ -uint8_t cjuid[10]; -uint32_t cjcuid; -iso14a_card_select_t p_card; -int currline; -int currfline; -int curlline; +static uint8_t cjuid[10]; +static uint32_t cjcuid; +static iso14a_card_select_t p_card; +static int currline; +static int currfline; +static int curlline; // TODO : Implement fast read of KEYS like in RFIdea // also http://ext.delaat.net/rp/2015-2016/p04/report.pdf @@ -104,7 +104,7 @@ static const uint8_t is_hex[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static inline uint64_t hex2i(const char *s) { +static uint64_t hex2i(const char *s) { uint64_t val = 0; if (s == NULL || s[0] == 0) return 0; @@ -162,7 +162,7 @@ static void scan_keys(const char *str, int len, uint64_t *user_data) { } } -MFC1KSchema Schemas[MAX_SCHEMAS]; +static MFC1KSchema Schemas[MAX_SCHEMAS]; /*MFC1KSchema Noralsy = { .name = "Noralsy", @@ -196,16 +196,16 @@ MFC1KSchema InfiHexact = {.name = "Infineon/Hexact", 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}}; */ -int total_schemas = 0; +static int total_schemas = 0; -void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) { +static void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) { if (*schemas_counter < MAX_SCHEMAS) { p[*schemas_counter] = a; *schemas_counter += 1; } } - -void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) { +/* +static void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) { if (*schemas_counter > 0 && index < *schemas_counter && index > -1) { int last_index = *schemas_counter - 1; for (int i = index; i < last_index; i++) { @@ -214,33 +214,25 @@ void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) { *schemas_counter -= 1; } } - -void cjSetCursFRight() { +*/ +static void cjSetCursFRight(void) { vtsend_cursor_position(NULL, 98, (currfline)); currfline++; } -void cjSetCursRight() { +static void cjSetCursRight(void) { vtsend_cursor_position(NULL, 59, (currline)); currline++; } -void cjSetCursLeft() { +static void cjSetCursLeft(void) { vtsend_cursor_position(NULL, 0, (curlline)); curlline++; } -void cjTabulize() { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); } +static void cjTabulize(void) { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); } -/* -void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) { - char tosendkey[13]; - sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4], -foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type); -} -*/ - -char *ReadSchemasFromSPIFFS(char *filename) { +static char *ReadSchemasFromSPIFFS(char *filename) { SpinOff(0); int changed = rdv40_spiffs_lazy_mount(); @@ -255,7 +247,7 @@ char *ReadSchemasFromSPIFFS(char *filename) { return (char *)mem; } -void add_schemas_from_json_in_spiffs(char *filename) { +static void add_schemas_from_json_in_spiffs(char *filename) { char *jsonfile = ReadSchemasFromSPIFFS((char *)filename); @@ -275,7 +267,7 @@ void add_schemas_from_json_in_spiffs(char *filename) { } } -void ReadLastTagFromFlash() { +static void ReadLastTagFromFlash(void) { SpinOff(0); LED_A_ON(); LED_B_ON(); @@ -292,6 +284,7 @@ void ReadLastTagFromFlash() { // this one will handle filetype (symlink or not) and resolving by itself rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE); + // copy 64blocks (16bytes) starting w block0, to emulator mem. emlSetMem(mem, 0, 64); DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator"); @@ -330,16 +323,22 @@ void WriteTagToFlash(uint32_t uid, size_t size) { return; } -void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); } +void ModInfo(void) { + DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); +} -void RunMod() { +void RunMod(void) { StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + Dbprintf(">> HF Mifare ultra fast sniff/sim/clone a.k.a VIGIKPWN Started <<"); + + // turn off all debugging. + DBGLEVEL = DBG_NONE; // add_schema(Schemas, Noralsy, &total_schemas); // add_schema(Schemas, InfiHexact, &total_schemas); // add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON); // add_schema(Schemas, UrmetCaptive, &total_schemas); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); currline = 20; curlline = 20; @@ -386,11 +385,11 @@ void RunMod() { ACCBITS : 796788[00]+VALUE */ -//---------------------------- +// ---------------------------- // Set of keys to be used. // This should cover ~98% of // French VIGIK system @2017 -//---------------------------- +// ---------------------------- const uint64_t mfKeys[] = { 0xffffffffffff, // TRANSPORTS @@ -459,7 +458,6 @@ void RunMod() { bool err = 0; bool trapped = 0; bool allKeysFound = true; - uint32_t size = mfKeysCnt; // banner: @@ -487,7 +485,7 @@ failtag: SpinOff(50); LED_A_ON(); uint8_t ticker = 0; - // while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) + while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) { WDT_HIT(); @@ -496,7 +494,7 @@ failtag: LED_A_INV(); } - if (BUTTON_HELD(10) > 0) { + if (BUTTON_HELD(10) == BUTTON_HOLD) { WDT_HIT(); DbprintfEx(FLAG_NEWLINE, "\t\t\t[ READING FLASH ]"); ReadLastTagFromFlash(); @@ -505,8 +503,8 @@ failtag: } SpinOff(50); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + vtsend_cursor_position_restore(NULL); DbprintfEx(FLAG_NEWLINE, "\t\t\t%s[ GOT a Tag ! ]%s", _XGREEN_, _XWHITE_); cjSetCursLeft(); @@ -534,7 +532,7 @@ failtag: uint32_t start_time = GetTickCount(); uint32_t delta_time = 0; - //--------------------------------------------------------------------------- + // --------------------------------------------------------------------------- // WE SHOULD FIND A WAY TO GET UID TO AVOID THIS "TESTRUN" // -------------------------------------------------------- // + HERE IS TO BE THOUGHT AS ONLY A KEY SHOULD BE CHECK @@ -544,7 +542,7 @@ failtag: // `-+ THEN FILL EMULATOR WITH B KEEY // `-+ THEN EMULATOR WITH CARD WITH B KEY // `-+ IF IT HAS FAILED OF ANY OF SORT THEN WE ARE MARRON LIKE POMALO. - //---------------------------------------------------------------------------- + // ---------------------------------------------------------------------------- // AN EVEN BETTER IMPLEMENTATION IS TO CHECK EVERY KEY FOR SECTOR 0 KEY A // THEN IF FOUND CHECK THE SAME KEY FOR NEXT SECTOR ONLY KEY A // THEN IF FAIL CHECK EVERY SECTOR A KEY FOR EVERY OTHER KEY BUT NOT THE BLOCK @@ -558,7 +556,7 @@ failtag: // DERIVATION // THEN IF B KEY IS NOT OF THIS SCHEME CHECK EVERY REMAINING B KEYED SECTOR // WITH EVERY REMAINING KEYS, BUT DISCARDING ANY DEFAULT TRANSPORT KEYS. - //----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- // also we could avoid first UID check for every block // then let's expose this optimal case of well known vigik schemes : @@ -625,7 +623,6 @@ failtag: break; } } - /* etc etc for testing schemes quick schemes */ } } @@ -641,7 +638,7 @@ failtag: return; } - /* Settings keys to emulator */ + // Settings keys to emulator emlClearMem(); uint8_t mblock[16]; for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { @@ -655,7 +652,7 @@ failtag: DbprintfEx(FLAG_NEWLINE, "%s>>%s Setting Keys->Emulator MEM...[%sOK%s]", _XYELLOW_, _XWHITE_, _XGREEN_, _XWHITE_); - /* filling TAG to emulator */ + // filling TAG to emulator int filled; cjSetCursLeft(); @@ -666,11 +663,10 @@ failtag: DbprintfEx(FLAG_NEWLINE, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _XRED_, _XORANGE_, _XWHITE_); - /* no trace, no dbg */ + // no trace, no dbg filled = e_MifareECardLoad(sectorsCnt, 1); if (filled != PM3_SUCCESS) { cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B"); SpinErr(LED_C, 100, 8); SpinOff(100); @@ -717,10 +713,9 @@ readysim: SpinOff(100); LED_C_ON(); - DBGLEVEL = DBG_NONE; - - //uint16_t flags=0; - /*switch (p_card.uidlen) { + /* + uint16_t flags = 0; + switch (p_card.uidlen) { case 10: flags = FLAG_10B_UID_IN_DATA; break; @@ -733,19 +728,18 @@ readysim: default: flags = FLAG_UID_IN_EMUL; break; - }*/ - + } // Use UID, SAK, ATQA from EMUL, if uid not defined - // if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { - //flags |= FLAG_UID_IN_EMUL; - //} - //flags |= FLAG_MF_1K; - //if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { - // flags |= FLAG_UID_IN_EMUL; - //} - //flags = 0x10; - uint16_t flags = 0; - flags = 16; + if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { + flags |= FLAG_UID_IN_EMUL; + } + flags |= FLAG_MF_1K; + if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { + flags |= FLAG_UID_IN_EMUL; + } + flags = 0x10; + */ + uint16_t flags = FLAG_UID_IN_EMUL; DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags); cjSetCursLeft(); SpinOff(1000); @@ -789,8 +783,6 @@ readysim: * - tracing is falsed */ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { - DBGLEVEL = DBG_NONE; - uint8_t numSectors = numofsectors; uint8_t keyType = keytype; @@ -802,7 +794,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { uint8_t dataoutbuf2[16]; iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); set_tracing(false); @@ -810,24 +801,17 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) { isOK = false; - if (DBGLEVEL >= 1) - DbprintfEx(FLAG_RAWPRINT, "Can't select card"); } for (uint8_t s = 0; isOK && s < numSectors; s++) { uint64_t ui64Key = emlGetKey(s, keyType); if (s == 0) { if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) { - - if (DBGLEVEL >= 1) - DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth error", s); break; } } else { if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) { isOK = false; - if (DBGLEVEL >= 1) - DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth nested error", s); break; } } @@ -835,8 +819,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(s); blockNo++) { if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) { isOK = false; - if (DBGLEVEL >= 1) - DbprintfEx(FLAG_NEWLINE, "Error reading sector %2d block %2d", s, blockNo); break; }; if (isOK) { @@ -852,23 +834,18 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { } } - if (mifare_classic_halt(pcs, cjcuid)) { - if (DBGLEVEL >= 1) - DbprintfEx(FLAG_NEWLINE, "Halt error"); - }; + int res = mifare_classic_halt(pcs, cjcuid); + (void)res; crypto1_deinit(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - return (isOK) ? PM3_SUCCESS : PM3_EUNDEF; } /* the chk function is a piwi'ed(tm) check that will try all keys for a particular sector. also no tracing no dbg */ -int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, - uint64_t *key) { - DBGLEVEL = DBG_NONE; +int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, + uint8_t keyCount, uint8_t *datain, uint64_t *key) { iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); set_tracing(false); @@ -876,14 +853,16 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui struct Crypto1State *pcs; pcs = &mpcs; - for (int i = 0; i < keyCount; ++i) { + int retval = -1; + + for (uint8_t i = 0; i < keyCount; i++) { /* no need for anticollision. just verify tag is still here */ // if (!iso14443a_fast_select_card(cjuid, 0)) { if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) { cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_); - return -1; + break; } uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); @@ -894,15 +873,13 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui SpinDelayUs(AUTHENTICATION_TIMEOUT); continue; } - crypto1_deinit(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); *key = ui64Key; - return i; + retval = i; + break; } crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - return -1; + return retval; } void saMifareMakeTag(void) { @@ -920,7 +897,6 @@ void saMifareMakeTag(void) { int flags = 0; for (int blockNum = 0; blockNum < 16 * 4; blockNum++) { uint8_t mblock[16]; - // cnt = 0; emlGetMem(mblock, blockNum, 1); // switch on field and send magic sequence if (blockNum == 0) @@ -935,21 +911,15 @@ void saMifareMakeTag(void) { flags = 0x04 + 0x10; if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) { - //&& cnt <= retry) { - // cnt++; cjSetCursFRight(); if (currfline > 53) { currfline = 54; } DbprintfEx(FLAG_NEWLINE, "Block :%02x %sOK%s", blockNum, _XGREEN_, _XWHITE_); - // DbprintfEx(FLAG_RAWPRINT,"FATAL:E_MF_CHINESECOOK_NORICE"); - // cfail=1; - // return; continue; } else { cjSetCursLeft(); cjSetCursLeft(); - DbprintfEx(FLAG_NEWLINE, "`--> %sFAIL%s : CHN_FAIL_BLK_%02x_NOK", _XRED_, _XWHITE_, blockNum); cjSetCursFRight(); DbprintfEx(FLAG_NEWLINE, "%s>>>>%s STOP AT %02x", _XRED_, _XWHITE_, blockNum); @@ -957,14 +927,9 @@ void saMifareMakeTag(void) { break; } cjSetCursFRight(); - DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>> END <<<<<<<<%s", _XYELLOW_, _XWHITE_); - // break; - /*if (cfail == 1) { - DbprintfEx(FLAG_RAWPRINT,"FATAL: E_MF_HARA_KIRI_\r\n"); - break; - } */ } + if (cfail == 0) { SpinUp(50); SpinUp(50); diff --git a/armsrc/Standalone/hf_legic.c b/armsrc/Standalone/hf_legic.c index d72c8148e..73590268e 100644 --- a/armsrc/Standalone/hf_legic.c +++ b/armsrc/Standalone/hf_legic.c @@ -44,7 +44,8 @@ * */ -void DownloadLogInstructions() { +#ifdef WITH_FLASH +static void DownloadLogInstructions(void) { Dbprintf(""); Dbprintf("[=] List all dumps from flash:"); Dbprintf("[=] " _YELLOW_("-") " mem spiffs tree"); @@ -52,8 +53,9 @@ void DownloadLogInstructions() { Dbprintf("[=] To save a dump file from flash to client:"); Dbprintf("[=] " _YELLOW_("-") " mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin"); } +#endif -void save_dump_to_file(legic_card_select_t *p_card) { +static void save_dump_to_file(legic_card_select_t *p_card) { #ifdef WITH_FLASH @@ -99,7 +101,7 @@ void ModInfo(void) { // A, B, C = Reading // A, D = Simulating -void RunMod() { +void RunMod(void) { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); Dbprintf("[=] >> HF Legic Prime Read/Simulate Started <<"); diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 60619e657..c0d603fbd 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -49,9 +49,16 @@ on a blank card. #include "mifaresim.h" // mifare1ksim #include "mifareutil.h" -uint8_t uid[10]; -uint32_t cuid; -iso14a_card_select_t p_card; +static uint8_t uid[10]; +static uint32_t cuid; +static iso14a_card_select_t p_card; + +// Pseudo-configuration block. +static bool printKeys = false; // Prints keys +static bool transferToEml = true; // Transfer keys to emulator memory +static bool ecfill = true; // Fill emulator memory with cards content. +static bool simulation = true; // Simulates an exact copy of the target tag +static bool fillFromEmulator = false; // Dump emulator memory. //----------------------------------------------------------------------------- // Matt's StandAlone mod. @@ -169,7 +176,8 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_ /* the chk function is a piwi’ed(tm) check that will try all keys for a particular sector. also no tracing no dbg */ -static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) { +static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, + uint8_t keyCount, uint8_t *datain, uint64_t *key) { DBGLEVEL = DBG_NONE; iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); set_tracing(false); @@ -178,13 +186,15 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui struct Crypto1State *pcs; pcs = &mpcs; - for (int i = 0; i < keyCount; ++i) { + int retval = -1; + + for (uint8_t i = 0; i < keyCount; i++) { /* no need for anticollision. just verify tag is still here */ // if (!iso14443a_fast_select_card(cjuid, 0)) { if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) { DbprintfEx(FLAG_NEWLINE, "FATAL : E_MF_LOSTTAG"); - return -1; + break; } uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); @@ -195,66 +205,120 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui SpinDelayUs(AUTHENTICATION_TIMEOUT); continue; } - crypto1_deinit(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); *key = ui64Key; - return i; + retval = i; + break; } crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - return -1; + return retval; } +/* Abusive microgain on original MifareECardLoad : + * - *datain used as error return + * - tracing is falsed + */ +static int saMifareECardLoad(uint32_t numofsectors, uint8_t keytype) { + DBGLEVEL = DBG_NONE; + + uint8_t numSectors = numofsectors; + uint8_t keyType = keytype; + + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + + uint8_t dataoutbuf[16]; + uint8_t dataoutbuf2[16]; + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(false); + + int retval = PM3_SUCCESS; + + if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) { + retval = PM3_ESOFT; + DbprintfEx(FLAG_RAWPRINT, "Can't select card"); + goto out; + } + + for (uint8_t s = 0; s < numSectors; s++) { + uint64_t ui64Key = emlGetKey(s, keyType); + if (s == 0) { + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) { + retval = PM3_ESOFT; + break; + } + } else { + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) { + retval = PM3_ESOFT; + break; + } + } + + // failure to read one block, skips to next sector. + for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(s); blockNo++) { + if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) { + retval = PM3_ESOFT; + break; + }; + + if (blockNo < NumBlocksPerSector(s) - 1) { + emlSetMem(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1); + } else { + // sector trailer, keep the keys, set only the AC + emlGetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1); + memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4); + emlSetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1); + } + } + } + + int res = mifare_classic_halt(pcs, cuid); + (void)res; + +out: + crypto1_deinit(pcs); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + return retval; +} + + void ModInfo(void) { DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)"); } -void RunMod() { +/* + It will check if the keys from the attacked tag are a subset from + the hardcoded set of keys inside of the ARM. If this is the case + then it will load the keys into the emulator memory and also the + content of the victim tag, to finally simulate it. + + Alternatively, it can be dumped into a blank card. + + This source code has been tested only in Mifare 1k. + + If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug + messages, you MUST uncomment usb_disable(). +*/ +void RunMod(void) { StandAloneMode(); - Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<"); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - - /* - It will check if the keys from the attacked tag are a subset from - the hardcoded set of keys inside of the ARM. If this is the case - then it will load the keys into the emulator memory and also the - content of the victim tag, to finally simulate it. - - Alternatively, it can be dumped into a blank card. - - This source code has been tested only in Mifare 1k. - - If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug - messages, you MUST uncomment usb_disable(). - */ + Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<"); // Comment this line below if you want to see debug messages. // usb_disable(); - /* - Pseudo-configuration block. - */ - bool printKeys = false; // Prints keys - bool transferToEml = true; // Transfer keys to emulator memory - bool ecfill = true; // Fill emulator memory with cards content. - bool simulation = true; // Simulates an exact copy of the target tag - bool fillFromEmulator = false; // Dump emulator memory. - - uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now) uint8_t sectorSize = 64; // 1k's sector size is 64 bytes. uint8_t blockNo = 3; // Security block is number 3 for each sector. uint8_t sectorsCnt = (mifare_size / sectorSize); - uint8_t keyType = 2; // Keytype buffer uint64_t key64; // Defines current key uint8_t *keyBlock; // Where the keys will be held in memory. - uint8_t stKeyBlock = 20; // Set the quantity of keys in the block. bool keyFound = false; - /* - Set of keys to be used. - */ + // Set of keys to be used. uint64_t mfKeys[] = { 0xffffffffffff, // Default key 0x000000000000, // Blank key @@ -269,22 +333,73 @@ void RunMod() { 0xa0478cc39091, 0x533cb6c723f6, 0x8fd0a4f256e9, + 0x484558414354, // INFINEONON A / 0F SEC B / INTRATONE / HEXACT... + 0x414c41524f4e, // ALARON NORALSY + 0x424c41524f4e, // BLARON NORALSY + 0x4a6352684677, // COMELIT A General Key / 08 [2] 004 + 0x536653644c65, // COMELIT B General Key / 08 [2] 004 + 0x8829da9daf76, // URMET CAPTIV IF A => ALL A/B / BTICINO + 0x314B49474956, // "1KIGIV" VIGIK'S SERVICE BADGE A KEY + 0x021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key + 0x010203040506, // VIGIK's B Derivative + 0xa22ae129c013, // INFINEON B 00 + 0x49fae4e3849f, // INFINEON B 01 + 0x38fcf33072e0, // INFINEON B 02 + 0x8ad5517b4b18, // INFINEON B 03 + 0x509359f131b1, // INFINEON B 04 + 0x6c78928e1317, // INFINEON B 05 + 0xaa0720018738, // INFINEON B 06 + 0xa6cac2886412, // INFINEON B 07 + 0x62d0c424ed8e, // INFINEON B 08 + 0xe64a986a5d94, // INFINEON B 09 + 0x8fa1d601d0a2, // INFINEON B 0A + 0x89347350bd36, // INFINEON B 0B + 0x66d2b7dc39ef, // INFINEON B 0C + 0x6bc1e1ae547d, // INFINEON B 0D + 0x22729a9bd40f, // INFINEON B 0E + 0xd2ece8b9395e, // lib / Nat Bieb + 0x1494E81663D7, // # NSCP default key + 0x569369c5a0e5, // # kiev + 0x632193be1c3c, // # kiev + 0x644672bd4afe, // # kiev + 0x8fe644038790, // # kiev + 0x9de89e070277, // # kiev + 0xb5ff67cba951, // # kiev / ov-chipkaart + 0xeff603e1efe9, // # kiev + 0xf14ee7cae863, // # kiev + 0xfc00018778f7, // # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA + 0x0297927c0f77, // # Västtrafiken KeyA + 0x54726176656c, // # Västtrafiken KeyA + 0x00000ffe2488, // # Västtrafiken KeyB + 0x776974687573, // # Västtrafiken KeyB + 0xee0042f88840, // # Västtrafiken KeyB + 0x26940b21ff5d, // # RKF SLKeyA + 0xa64598a77478, // # RKF SLKeyA + 0x5c598c9c58b5, // # RKF SLKeyB + 0xe4d2770a89be, // # RKF SLKeyB + 0x722bfcc5375f, // # RKF RejskortDanmark KeyA + 0xf1d83f964314, // # RKF RejskortDanmark KeyB + 0x505249564141, // # RKF JOJOPRIVAKeyA + 0x505249564142, // # RKF JOJOPRIVAKeyB + 0x47524f555041, // # RKF JOJOGROUPKeyA + 0x47524f555042, // # RKF JOJOGROUPKeyB + 0x434f4d4d4f41, // # RKF JOJOGROUPKeyA + 0x434f4d4d4f42, // # RKF JOJOGROUPKeyB + 0x4b0b20107ccb, // # TNP3xxx }; /* This part allocates the byte representation of the keys in keyBlock's memory space . */ - keyBlock = BigBuf_malloc(stKeyBlock * 6); + keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6); int mfKeysCnt = ARRAYLEN(mfKeys); for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) { num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); } - /* - Pretty print of the keys to be checked. - */ + // Pretty print of the keys to be checked. if (printKeys) { Dbprintf("[+] Printing mf keys"); for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++) @@ -301,30 +416,31 @@ void RunMod() { */ bool validKey[2][40]; uint8_t foundKey[2][40][6]; - for (uint16_t t = 0; t < 2; t++) { + for (uint8_t i = 0; i < 2; i++) { for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { - validKey[t][sectorNo] = false; - for (uint16_t i = 0; i < 6; i++) { - foundKey[t][sectorNo][i] = 0xff; - } + validKey[i][sectorNo] = false; + foundKey[i][sectorNo][0] = 0xFF; + foundKey[i][sectorNo][1] = 0xFF; + foundKey[i][sectorNo][2] = 0xFF; + foundKey[i][sectorNo][3] = 0xFF; + foundKey[i][sectorNo][4] = 0xFF; + foundKey[i][sectorNo][5] = 0xFF; } } - /* - Iterates through each sector checking if there is a correct key. - */ + // Iterates through each sector checking if there is a correct key. bool err = 0; bool allKeysFound = true; uint32_t size = mfKeysCnt; - for (int type = !keyType; type < 2 && !err; keyType == 2 ? (type++) : (type = 2)) { + for (int type = 0; type < 2 && !err; type++) { int block = blockNo; for (int sec = 0; sec < sectorsCnt && !err; ++sec) { Dbprintf("\tCurrent sector:%3d, block:%3d, key type: %c, key count: %i ", sec, block, type ? 'B' : 'A', mfKeysCnt); int key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64); if (key == -1) { LED(LED_RED, 50); - Dbprintf("\t✕ Key not found for this sector!"); + Dbprintf("\t [✕] Key not found for this sector!"); allKeysFound = false; // break; } else if (key == -2) { @@ -334,7 +450,7 @@ void RunMod() { num_to_bytes(key64, 6, foundKey[type][sec]); validKey[type][sec] = true; keyFound = true; - Dbprintf("\t✓ Found valid key: [%02x%02x%02x%02x%02x%02x]\n", + Dbprintf("\t [✓] Found valid key: [%02x%02x%02x%02x%02x%02x]\n", (keyBlock + 6 * key)[0], (keyBlock + 6 * key)[1], (keyBlock + 6 * key)[2], (keyBlock + 6 * key)[3], (keyBlock + 6 * key)[4], (keyBlock + 6 * key)[5] ); @@ -371,8 +487,9 @@ void RunMod() { emlClearMem(); uint8_t mblock[16]; - for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { + for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { if (validKey[0][sectorNo] || validKey[1][sectorNo]) { + emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4) for (uint16_t t = 0; t < 2; t++) { if (validKey[t][sectorNo]) { @@ -382,47 +499,40 @@ void RunMod() { emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); } } - Dbprintf("\t✓ Found keys have been transferred to the emulator memory."); + + Dbprintf("\t [✓] Found keys have been transferred to the emulator memory."); + if (ecfill) { int filled; Dbprintf("\tFilling in with key A."); - filled = MifareECardLoad(sectorsCnt, 0); - if (filled != PM3_SUCCESS) { - Dbprintf("\t✕ Failed filling with A."); - } - Dbprintf("\tFilling in with key B."); - filled = MifareECardLoad(sectorsCnt, 1); + filled = saMifareECardLoad(sectorsCnt, 0); if (filled != PM3_SUCCESS) { - Dbprintf("\t✕ Failed filling with B."); + + Dbprintf("\t [✕] Failed filling with A."); + Dbprintf("\tFilling in with key B."); + filled = saMifareECardLoad(sectorsCnt, 1); + if (filled != PM3_SUCCESS) { + Dbprintf("\t [✕] Failed filling with B."); + } } if ((filled == PM3_SUCCESS) && simulation) { - Dbprintf("\t✓ Emulator memory filled, simulation started."); + Dbprintf("\t [✓] Emulator memory filled, simulation started."); // This will tell the fpga to emulate using previous keys and current target tag content. Dbprintf("\t Press button to abort simulation at anytime."); LED_B_ON(); // green - // assuming arg0==0, use hardcoded uid 0xdeadbeaf - uint16_t simflags; - switch (p_card.uidlen) { - case 10: - simflags = FLAG_10B_UID_IN_DATA; - break; - case 7: - simflags = FLAG_7B_UID_IN_DATA; - break; - default: - simflags = FLAG_4B_UID_IN_DATA; - break; - } - Mifare1ksim(simflags | FLAG_MF_1K, 0, uid, 0, 0); - LED_B_OFF(); - /* - Needs further testing. - */ + uint16_t simflags = FLAG_UID_IN_EMUL | FLAG_MF_1K; + + SpinOff(1000); + Mifare1ksim(simflags, 0, uid, 0, 0); + LED_B_OFF(); + Dbprintf("\t [✓] Simulation ended"); + + // Needs further testing. if (fillFromEmulator) { uint8_t retry = 5; Dbprintf("\t Trying to dump into blank card."); @@ -457,8 +567,10 @@ void RunMod() { } } - } else if (filled != PM3_SUCCESS) { - Dbprintf("\t✕ Emulator memory could not be filled due to errors."); + } + + if (filled != PM3_SUCCESS) { + Dbprintf("\t [✕] Emulator memory could not be filled due to errors."); LED_C_ON(); } } diff --git a/armsrc/Standalone/hf_msdsal.c b/armsrc/Standalone/hf_msdsal.c index c79d01aed..f97dc0d7c 100644 --- a/armsrc/Standalone/hf_msdsal.c +++ b/armsrc/Standalone/hf_msdsal.c @@ -52,9 +52,9 @@ void ModInfo(void) { * technologies. Be brave enough to share your knowledge & inspire others. Salvador Mendoza. */ -uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING +static uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING -uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING +static uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING uint8_t plen = 7; //PDOL Format: 80 A8 00 00 + (PDOL Length+2) + 83 + PDOL Length + PDOL + 00 for (uint8_t i = 1; i <= apdu[0]; i++) { //Magic stuff, the generation order is important @@ -117,9 +117,9 @@ uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING return plen; } -void RunMod() { +void RunMod(void) { StandAloneMode(); - Dbprintf(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started<<"); + DbpString(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started " _YELLOW_("<<")); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); //For reading process @@ -183,8 +183,8 @@ void RunMod() { uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 }; uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 }; - uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE]; - uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE]; + uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0}; + uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0}; // to know the transaction status uint8_t prevCmd = 0; @@ -206,10 +206,10 @@ void RunMod() { //Checking if the user wants to go directly to emulation mode using a hardcoded track 2 if (chktoken == true && token[0] != 0x00) { state = STATE_EMU; - Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]")); DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); } else { - DbpString(_YELLOW_("[") "Initialized reading mode " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]")); DbpString("\n"_YELLOW_("!!") "Waiting for a Visa card..."); } @@ -222,18 +222,18 @@ void RunMod() { // Was our button held down or pressed? int button_pressed = BUTTON_HELD(1000); - if (button_pressed == 1) //Holding down the button + if (button_pressed == BUTTON_HOLD) //Holding down the button break; - else if (button_pressed == -1) { //Pressing one time change between reading & emulation + else if (button_pressed == BUTTON_SINGLE_CLICK) { //Pressing one time change between reading & emulation if (state == STATE_READ) { if (chktoken == true && token[0] != 0x00) { //Only change to emulation if it saved a track 2 in memory state = STATE_EMU; - Dbprintf(_YELLOW_("[") "In emulation mode " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]")); } else - Dbprintf(_YELLOW_("!!") "Nothing in memory to emulate"); + DbpString(_YELLOW_("!!") "Nothing in memory to emulate"); } else { state = STATE_READ; - Dbprintf(_YELLOW_("[") "In reading mode " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]")); } } @@ -248,7 +248,7 @@ void RunMod() { if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) { - Dbprintf(_YELLOW_("+") "Found ISO 14443 Type A!"); + DbpString(_YELLOW_("+") "Found ISO 14443 Type A!"); for (uint8_t i = 0; i < 4; i++) { chktoken = false; @@ -257,11 +257,11 @@ void RunMod() { uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL); if (apdulen > 0) { - Dbprintf(_YELLOW_("[") "Proxmark command " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]")); Dbhexdump(apdusLen[i], apdus[i], false); - Dbprintf(_GREEN_("[") "Card answer " _GREEN_("]")); + DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]")); Dbhexdump(apdulen - 2, apdubuffer, false); - Dbprintf("----"); + DbpString("----"); for (uint8_t u = 0; u < apdulen; u++) { if (i == 1) { @@ -284,24 +284,24 @@ void RunMod() { } if (i == 1) { - Dbprintf(_GREEN_("[") "Challenge generated " _GREEN_("]")); + DbpString(_GREEN_("[ ") "Challenge generated" _GREEN_(" ]")); Dbhexdump(plen, existpdol ? ppdol : processing, false); } } else { - Dbprintf(_YELLOW_("!!") "Error reading the card"); + DbpString(_YELLOW_("!!") "Error reading the card"); } LED_B_OFF(); } if (chktoken) { - Dbprintf(_RED_("[") "Track 2 " _RED_("]")); + DbpString(_RED_("[ ") "Track 2" _RED_(" ]")); Dbhexdump(19, (uint8_t *)token, false); - Dbprintf(_YELLOW_("!!") "Card number"); + DbpString(_YELLOW_("!!") "Card number"); Dbhexdump(8, (uint8_t *)token, false); DbpString("---"); LED_C_ON(); state = STATE_EMU; - Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]")); DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); } } @@ -318,7 +318,7 @@ void RunMod() { DbpString(_YELLOW_("!!") "Error initializing the emulation process!"); SpinDelay(500); state = STATE_READ; - DbpString(_YELLOW_("[") "Initialized reading mode " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]")); DbpString("\n" _YELLOW_("!!") "Waiting for a Visa card..."); break; } @@ -336,7 +336,7 @@ void RunMod() { LED_B_OFF(); // Clean receive command buffer if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { - Dbprintf(_YELLOW_("!!") "Emulator stopped"); + DbpString(_YELLOW_("!!") "Emulator stopped"); retval = PM3_EOPABORTED; break; } @@ -367,7 +367,7 @@ void RunMod() { DbpString(_YELLOW_("+") "Request for RATS"); p_response = &responses[RATS]; } else { - Dbprintf(_YELLOW_("[") "Card reader command " _YELLOW_("]")); + DbpString(_YELLOW_("[ ") "Card reader command" _YELLOW_(" ]")); Dbhexdump(len, receivedCmd, false); if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) { //Emulate a Visa MSD(Magnetic stripe data) card @@ -408,7 +408,7 @@ void RunMod() { } } } else { - Dbprintf(_YELLOW_("!!") "Received unknown command!"); + DbpString(_YELLOW_("!!") "Received unknown command!"); if (prevCmd < 4) { memcpy(dynamic_response_info.response, receivedCmd, len); dynamic_response_info.response_n = len; @@ -418,9 +418,9 @@ void RunMod() { } } if (dynamic_response_info.response_n > 0) { - Dbprintf(_GREEN_("[") "Proxmark3 answer " _GREEN_("]")); + DbpString(_GREEN_("[ ") "Proxmark3 answer" _GREEN_(" ]")); Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false); - Dbprintf("----"); + DbpString("----"); // Add CRC bytes, always used in ISO 14443A-4 compliant cards AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n); diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index f137e9992..a1b32dfab 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -37,7 +37,7 @@ void ModInfo(void) { DbpString(" HF Mifare sniff/simulation - (Craig Young)"); } -void RunMod() { +void RunMod(void) { StandAloneMode(); Dbprintf(">> Craig Young Mifare sniff UID/clone uid 2 magic/sim a.k.a YoungRun Started <<"); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -151,10 +151,10 @@ void RunMod() { SpinDelay(500); // Begin clone function here: /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards: - SendCommandOLD(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16); + SendCommandMIX(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16); Block read is similar: - SendCommandOLD(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...}; + SendCommandMIX(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...}; We need to imitate that call with blockNo 0 to set a uid. The get and set commands are handled in this file: @@ -222,8 +222,8 @@ void RunMod() { // exit from Standalone Mode, send a usbcommand. if (data_available()) return; - int button_action = BUTTON_HELD(1000); - if (button_action == 0) { // No button action, proceed with sim + int button_pressed = BUTTON_HELD(1000); + if (button_pressed == BUTTON_NO_CLICK) { // No button action, proceed with sim uint8_t flags = FLAG_4B_UID_IN_DATA; uint8_t data[PM3_CMD_DATA_SIZE] = {0}; // in case there is a read command received we shouldn't break @@ -259,12 +259,12 @@ void RunMod() { SimulateIso14443aTag(1, flags, data); } - } else if (button_action == BUTTON_SINGLE_CLICK) { + } else if (button_pressed == BUTTON_SINGLE_CLICK) { selected = (selected + 1) % OPTS; Dbprintf("Done playing. Switching to record mode on bank %d", selected); iGotoRecord = 1; break; - } else if (button_action == BUTTON_HOLD) { + } else if (button_pressed == BUTTON_HOLD) { Dbprintf("Playtime over. Begin cloning..."); iGotoClone = 1; break; diff --git a/armsrc/Standalone/lf_em4100emul.c b/armsrc/Standalone/lf_em4100emul.c index dce6c455e..e6ac2f6ff 100644 --- a/armsrc/Standalone/lf_em4100emul.c +++ b/armsrc/Standalone/lf_em4100emul.c @@ -18,23 +18,22 @@ #include "ticks.h" #include "string.h" #include "BigBuf.h" +#include "commonutil.h" #define MAX_IND 16 // 4 LEDs - 2^4 combinations #define CLOCK 64 //for 125kHz // low & high - array for storage IDs. Its length must be equal. // Predefined IDs must be stored in low[]. -// In high[] must be nulls -uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF}; -uint32_t high[] = {0, 0, 0, 0}; -uint8_t *bba, slots_count; -int buflen; +static uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF}; +static uint8_t *bba, slots_count; +static int buflen; void ModInfo(void) { DbpString(" LF EM4100 simulator standalone mode"); } -uint64_t ReversQuads(uint64_t bits) { +static uint64_t ReversQuads(uint64_t bits) { uint64_t result = 0; for (int i = 0; i < 16; i++) { result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); @@ -42,14 +41,14 @@ uint64_t ReversQuads(uint64_t bits) { return result >> 24; } -void FillBuff(uint8_t bit) { +static void FillBuff(uint8_t bit) { memset(bba + buflen, bit, CLOCK / 2); buflen += (CLOCK / 2); memset(bba + buflen, bit ^ 1, CLOCK / 2); buflen += (CLOCK / 2); } -void ConstructEM410xEmulBuf(uint64_t id) { +static void ConstructEM410xEmulBuf(uint64_t id) { int i, j, binary[4], parity[4]; buflen = 0; @@ -70,7 +69,7 @@ void ConstructEM410xEmulBuf(uint64_t id) { FillBuff(0); } -void LED_Slot(int i) { +static void LED_Slot(int i) { LEDsoff(); if (slots_count > 4) { LED(i % MAX_IND, 0); //binary indication for slots_count > 4 @@ -79,7 +78,7 @@ void LED_Slot(int i) { } } -void RunMod() { +void RunMod(void) { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); Dbprintf("[=] >> LF EM4100 simulator started <<"); diff --git a/armsrc/Standalone/lf_em4100rswb.c b/armsrc/Standalone/lf_em4100rswb.c new file mode 100644 index 000000000..ac470ce29 --- /dev/null +++ b/armsrc/Standalone/lf_em4100rswb.c @@ -0,0 +1,340 @@ +//----------------------------------------------------------------------------- +// Monster1024 +// based on code by: Artyom Gnatyuk, 2020 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// LF rswb - This mode can simulate ID from selected slot, read ID to +// selected slot, write from selected slot to T5555/T55x7 tag and store +// readed ID to flash (only RDV4). +// Predefined its is not recomended because you can incedently rewrite your MANDATORY tag data. +// +// To recall stored ID from flash execute: +// mem spifss dump o emdump p +// or: +// mem spifss dump o emdump f emdump +// then from shell: +// hexdump emdump -e '5/1 "%02X" /0 "\n"' +// +// Mode list (switched by single click): +// +// 0 - READ Read source card ID and store it to current slot +// Will switch to SIM mode automatically. +// +// 1 - SIM Simulate readed ID +// +// 2 - WRITE(CLONE) Write readed ID to T55x7 card +// !!! Warning, card id WILL BE OVERRWRITED +// +// 3 - BRUTE Brute upper or down from readed card) +// You can PRESS SINGLE to exit brute mode OR +// PRESS DOUBLE to save bruted ID to current slot (will automatically switch to SIM mode) AND +// Also You can HOLD button to change brute speeds. +// +// Slots are switched by HOLD (LONG PRESS) +//----------------------------------------------------------------------------- +#include "standalone.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "lfops.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "string.h" +#include "BigBuf.h" +#include "spiffs.h" +#include "inttypes.h" +#include "parity.h" + +#ifdef WITH_FLASH +#include "flashmem.h" +#endif + +#define LF_CLOCK 64 //for 125kHz +#define LF_RWSB_T55XX_TYPE 1 //Tag type: 0 - T5555, 1-T55x7 + +#define LF_RWSB_UNKNOWN_RESULT 0 +#define LF_RWSB_BRUTE_STOPED 1 +#define LF_RWSB_BRUTE_SAVED 2 + +//modes +#define LF_RWSB_MODE_READ 0 +#define LF_RWSB_MODE_SIM 1 +#define LF_RWSB_MODE_WRITE 2 +#define LF_RWSB_MODE_BRUTE 3 + +// Predefined bruteforce speed +// avg: 1s, 1.2s, 1.5s, 2s +static int bruteforceSpeedCurrent = 1; +static int bruteforceSpeed[] = {10, 12, 14, 16}; + +// low & high - array for storage IDs. Its length must be equal. +// Predefined IDs must be stored in low[]. +// In high[] must be nulls +static uint64_t low[] = {0, 0, 0, 0}; +static uint32_t high[] = {0, 0, 0, 0}; +static uint8_t *bba; +static int buflen; + +void ModInfo(void) { + DbpString(" LF EM4100 read/sim/write/brute mode"); +} + +static uint64_t ReversQuads(uint64_t bits) { + uint64_t result = 0; + for (int i = 0; i < 16; i++) { + result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); + } + return result >> 24; +} + +static void FillBuff(uint8_t bit) { + memset(bba + buflen, bit, LF_CLOCK / 2); + buflen += (LF_CLOCK / 2); + memset(bba + buflen, bit ^ 1, LF_CLOCK / 2); + buflen += (LF_CLOCK / 2); +} + +static void ConstructEM410xEmulBuf(uint64_t id) { + bba = BigBuf_get_addr(); + + int i, j, binary[4], parity[4]; + buflen = 0; + for (i = 0; i < 9; i++) + FillBuff(1); + parity[0] = parity[1] = parity[2] = parity[3] = 0; + for (i = 0; i < 10; i++) { + for (j = 3; j >= 0; j--, id /= 2) + binary[j] = id % 2; + for (j = 0; j < 4; j++) + FillBuff(binary[j]); + FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]); + for (j = 0; j < 4; j++) + parity[j] ^= binary[j]; + } + for (j = 0; j < 4; j++) + FillBuff(parity[j]); + FillBuff(0); +} + +static void LED_Update(int mode, int slot) { + LEDsoff(); + switch (mode) { + case 0: + break; + case 1: + LED_A_ON(); + break; + case 2: + LED_B_ON(); + break; + case 3: + LED_A_ON(); + LED_B_ON(); + break; + } + switch (slot) { + case 0: + break; + case 1: + LED_C_ON(); + break; + case 2: + LED_D_ON(); + break; + case 3: + LED_C_ON(); + LED_D_ON(); + break; + } +} + +static void FlashLEDs(uint32_t speed, uint8_t times) { + for (int i = 0; i < times * 2; i++) { + LED_A_INV(); + LED_B_INV(); + LED_C_INV(); + LED_D_INV(); + SpinDelay(speed); + } +} + +#ifdef WITH_FLASH +static void SaveIDtoFlash(int addr, uint64_t id) { + uint8_t bt[5]; + char *filename = "emdump"; + rdv40_spiffs_mount(); + for (int i = 0; i < 5; i++) { + bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff); + } + if (exists_in_spiffs(filename) == false) { + rdv40_spiffs_write(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); + } else { + rdv40_spiffs_append(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL); + } +} +#endif + +static uint64_t PackEmID(uint64_t original, int newCardNum) { + uint64_t buf = original; + //clear pairity bits + buf &= ~(1 << 0); + buf &= ~(1 << 25); + //clear card number + for (int i = 1; i <= 16; i++) { + buf &= ~(1 << i); + } + buf |= (newCardNum & 0xFFFF) << 1; + buf |= oddparity32((buf >> 1) & 0xFFF) & 1; + buf |= (evenparity32((buf >> 13) & 0xFFF) & 1) << 25; + + uint32_t cardnumNew = (buf >> 1) & 0xFFFF; + uint32_t fcNew = (buf >> 17) & 0xFF; + Dbprintf("[=] RECONSTRUCT TAG ID: %"PRIx64" - FC: %u - Card: %u\n", buf, fcNew, cardnumNew); + return buf; +} + + +static void PrintFcAndCardNum(uint64_t lowData) { + // Calculate Facility Code and Card Number from high and low + uint32_t fc = (lowData >> 17) & 0xFF; + uint32_t cardnum = (lowData >> 1) & 0xFFFF; + Dbprintf("[=] READ TAG ID: %"PRIx64" - FC: %u - Card: %u", lowData, fc, cardnum); +} + +static int ButeEMTag(uint64_t originalCard, int slot) { + int speed_count = 4; + + int direction = 1; + + uint32_t cardnum = (originalCard >> 1) & 0xFFFF; + if (cardnum > 32767) { + direction = -1; + } + + while (cardnum > 1 && cardnum < 65535) { + WDT_HIT(); + if (data_available()) break; + + cardnum = cardnum + direction; + uint64_t currentCard = PackEmID(originalCard, cardnum); + Dbprintf("[=] >> Simulating card id %"PRIx64" <<", currentCard); + ConstructEM410xEmulBuf(ReversQuads(currentCard)); + SimulateTagLowFrequencyEx(buflen, 0, 1, bruteforceSpeed[bruteforceSpeedCurrent] * 10000); + + int button_pressed = BUTTON_CLICKED(1000); + if (button_pressed == BUTTON_SINGLE_CLICK) { + Dbprintf("[=] >> Exit bruteforce mode without saving. <<"); + return LF_RWSB_BRUTE_STOPED; + } else if (button_pressed == BUTTON_DOUBLE_CLICK) { + FlashLEDs(100, 10); + Dbprintf("[=] >> Saving bruteforced card to current slot <<"); + low[slot] = currentCard; +#ifdef WITH_FLASH + SaveIDtoFlash(slot, low[slot]); +#endif + return LF_RWSB_BRUTE_SAVED; + } else if (button_pressed == BUTTON_HOLD) { + FlashLEDs(100, 1); + WAIT_BUTTON_RELEASED(); + bruteforceSpeedCurrent = (bruteforceSpeedCurrent + 1) % speed_count; + FlashLEDs(100, bruteforceSpeedCurrent + 1); + Dbprintf("[=] >> Setting speed to %d (%d) <<", bruteforceSpeedCurrent, bruteforceSpeed[bruteforceSpeedCurrent]); + } + } + return LF_RWSB_BRUTE_STOPED; +} + +static int ExecuteMode(int mode, int slot) { + LED_Update(mode, slot); + WDT_HIT(); + + switch (mode) { + //default first mode is simulate + case LF_RWSB_MODE_READ: + Dbprintf("[=] >> Read mode started <<"); + CmdEM410xdemod(1, &high[slot], &low[slot], 0); + LED_Update(mode, slot); + Dbprintf("[=] >> Tag found. Saving. <<"); + FlashLEDs(100, 5); + PrintFcAndCardNum(low[slot]); +#ifdef WITH_FLASH + SaveIDtoFlash(slot, low[slot]); +#endif + return LF_RWSB_UNKNOWN_RESULT; + case LF_RWSB_MODE_SIM: + Dbprintf("[=] >> Sim mode started <<"); + ConstructEM410xEmulBuf(ReversQuads(low[slot])); + SimulateTagLowFrequency(buflen, 0, 1); + return LF_RWSB_UNKNOWN_RESULT; + case LF_RWSB_MODE_WRITE: + Dbprintf("[!!] >> Write mode started <<"); + WriteEM410x(LF_RWSB_T55XX_TYPE, (uint32_t)(low[slot] >> 32), (uint32_t)(low[slot] & 0xffffffff)); + return LF_RWSB_UNKNOWN_RESULT; + case LF_RWSB_MODE_BRUTE: + Dbprintf("[=] >> Bruteforce mode started <<"); + return ButeEMTag(low[slot], slot); + } + return LF_RWSB_UNKNOWN_RESULT; +} + +static int SwitchMode(int mode, int slot) { + WDT_HIT(); + ExecuteMode(mode, slot); + + if (mode == LF_RWSB_MODE_READ) { + //After read mode we need to switch to sim mode automatically + Dbprintf("[=] >> automatically switch to sim mode after read <<"); + + return SwitchMode(LF_RWSB_MODE_SIM, slot); + } else if (mode == LF_RWSB_MODE_BRUTE) { + //We have already have a click inside brute mode. Lets switch next mode + Dbprintf("[=] >> automatically switch to read mode after brute <<"); + + return SwitchMode(LF_RWSB_MODE_READ, slot); + } + return mode; +} + +void RunMod() { + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf("[=] >> LF EM4100 read/write/clone/brute started <<"); + int slots_count = 4; + int mode_count = 4; + + int mode = 0; + int slot = 0; + mode = SwitchMode(mode, slot); + + bba = BigBuf_get_addr(); + for (;;) { + WDT_HIT(); + if (data_available()) break; + + int button_pressed = BUTTON_CLICKED(1000); + LED_Update(mode, slot); + + //press button - switch mode + //hold button - switch slot + if (button_pressed == BUTTON_SINGLE_CLICK) { + Dbprintf("[=] >> Single click <<"); + mode = (mode + 1) % mode_count; + SpinDown(100); + + mode = SwitchMode(mode, slot); + } else if (button_pressed == BUTTON_HOLD) { + Dbprintf("[=] >> Button hold <<"); + slot = (slot + 1) % slots_count; + SpinUp(100); + SpinDelay(300); + + //automatically switch to SIM mode on slot selection + mode = LF_RWSB_MODE_SIM; + mode = SwitchMode(mode, slot); + } + } +} diff --git a/armsrc/Standalone/lf_em4100rwc.c b/armsrc/Standalone/lf_em4100rwc.c index fcd3fe294..f69820513 100644 --- a/armsrc/Standalone/lf_em4100rwc.c +++ b/armsrc/Standalone/lf_em4100rwc.c @@ -27,6 +27,7 @@ #include "string.h" #include "BigBuf.h" #include "spiffs.h" +#include "commonutil.h" #ifdef WITH_FLASH #include "flashmem.h" @@ -38,16 +39,16 @@ // low & high - array for storage IDs. Its length must be equal. // Predefined IDs must be stored in low[]. // In high[] must be nulls -uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -uint8_t *bba, slots_count; -int buflen; +static uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static uint8_t *bba, slots_count; +static int buflen; void ModInfo(void) { DbpString(" LF EM4100 read/write/clone mode"); } -uint64_t ReversQuads(uint64_t bits) { +static uint64_t ReversQuads(uint64_t bits) { uint64_t result = 0; for (int i = 0; i < 16; i++) { result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); @@ -55,14 +56,14 @@ uint64_t ReversQuads(uint64_t bits) { return result >> 24; } -void FillBuff(uint8_t bit) { +static void FillBuff(uint8_t bit) { memset(bba + buflen, bit, CLOCK / 2); buflen += (CLOCK / 2); memset(bba + buflen, bit ^ 1, CLOCK / 2); buflen += (CLOCK / 2); } -void ConstructEM410xEmulBuf(uint64_t id) { +static void ConstructEM410xEmulBuf(uint64_t id) { int i, j, binary[4], parity[4]; buflen = 0; @@ -83,7 +84,7 @@ void ConstructEM410xEmulBuf(uint64_t id) { FillBuff(0); } -void LED_Slot(int i) { +static void LED_Slot(int i) { LEDsoff(); if (slots_count > 4) { LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 @@ -92,7 +93,7 @@ void LED_Slot(int i) { } } -void FlashLEDs(uint32_t speed, uint8_t times) { +static void FlashLEDs(uint32_t speed, uint8_t times) { for (int i = 0; i < times * 2; i++) { LED_A_INV(); LED_B_INV(); @@ -103,9 +104,9 @@ void FlashLEDs(uint32_t speed, uint8_t times) { } #ifdef WITH_FLASH -void SaveIDtoFlash(int addr, uint64_t id) { +static void SaveIDtoFlash(int addr, uint64_t id) { uint8_t bt[5]; - char *filename = "emdump"; + const char *filename = "emdump"; rdv40_spiffs_mount(); for (int i = 0; i < 5; i++) { bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff); @@ -118,7 +119,7 @@ void SaveIDtoFlash(int addr, uint64_t id) { } #endif -void RunMod() { +void RunMod(void) { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); Dbprintf("[=] >> LF EM4100 read/write/clone started <<"); @@ -140,12 +141,12 @@ void RunMod() { switch (state) { case 0: // Select mode - if (button_pressed == 1) { + if (button_pressed == BUTTON_HOLD) { // Long press - switch to simulate mode SpinUp(100); LED_Slot(selected); state = 2; - } else if (button_pressed < 0) { + } else if (button_pressed == BUTTON_SINGLE_CLICK) { // Click - switch to next slot selected = (selected + 1) % slots_count; LED_Slot(selected); @@ -153,12 +154,12 @@ void RunMod() { break; case 1: // Read mode. - if (button_pressed > 0) { + if (button_pressed == BUTTON_HOLD) { // Long press - switch to read mode SpinUp(100); LED_Slot(selected); state = 3; - } else if (button_pressed < 0) { + } else if (button_pressed == BUTTON_SINGLE_CLICK) { // Click - exit to select mode CmdEM410xdemod(1, &high[selected], &low[selected], 0); FlashLEDs(100, 5); @@ -170,12 +171,12 @@ void RunMod() { break; case 2: // Simulate mode - if (button_pressed > 0) { + if (button_pressed == BUTTON_HOLD) { // Long press - switch to read mode SpinDown(100); LED_Slot(selected); state = 1; - } else if (button_pressed < 0) { + } else if (button_pressed == BUTTON_SINGLE_CLICK) { // Click - start simulating. Click again to exit from simulate mode LED_Slot(selected); ConstructEM410xEmulBuf(ReversQuads(low[selected])); @@ -187,12 +188,12 @@ void RunMod() { break; case 3: // Write tag mode - if (button_pressed > 0) { + if (button_pressed == BUTTON_HOLD) { // Long press - switch to select mode SpinDown(100); LED_Slot(selected); state = 0; - } else if (button_pressed < 0) { + } else if (button_pressed == BUTTON_SINGLE_CLICK) { // Click - write ID to tag WriteEM410x(0, (uint32_t)(low[selected] >> 32), (uint32_t)(low[selected] & 0xffffffff)); LED_Slot(selected); diff --git a/armsrc/Standalone/lf_hidbrute.c b/armsrc/Standalone/lf_hidbrute.c index 7cae49a5b..8c4412ebe 100644 --- a/armsrc/Standalone/lf_hidbrute.c +++ b/armsrc/Standalone/lf_hidbrute.c @@ -42,7 +42,7 @@ void ModInfo(void) { } // samy's sniff and repeat routine for LF -void RunMod() { +void RunMod(void) { StandAloneMode(); Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<"); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -85,7 +85,7 @@ void RunMod() { // so next button push begins playing what we recorded playing = 0; cardRead = 1; - } else if (button_pressed > 0 && cardRead == 1) { + } else if (button_pressed == BUTTON_HOLD && cardRead == 1) { LEDsoff(); LED(selected + 1, 0); LED(LED_A, 0); @@ -109,7 +109,7 @@ void RunMod() { } // Change where to record (or begin playing) - else if (button_pressed) { + else if (button_pressed != BUTTON_NO_CLICK) { // Next option if we were previously playing if (playing) selected = (selected + 1) % OPTS; @@ -131,7 +131,7 @@ void RunMod() { CmdHIDsimTAG(0, high[selected], low[selected], 0, 0); DbpString("[=] done playing"); - if (BUTTON_HELD(1000) > 0) + if (BUTTON_HELD(1000) == BUTTON_HOLD) goto out; /* We pressed a button so ignore it here with a delay */ @@ -169,7 +169,7 @@ void RunMod() { // Needed for exiting from proxbrute when button is pressed if (BUTTON_PRESS()) { - if (BUTTON_HELD(1000) > 0) { + if (BUTTON_HELD(1000) == BUTTON_HOLD) { goto out; } else { while (BUTTON_PRESS()) { @@ -199,7 +199,7 @@ void RunMod() { // Needed for exiting from proxbrute when button is pressed if (BUTTON_PRESS()) { - if (BUTTON_HELD(1000) > 0) { + if (BUTTON_HELD(1000) == BUTTON_HOLD) { goto out; } else { while (BUTTON_PRESS()) { WDT_HIT(); } @@ -220,7 +220,7 @@ void RunMod() { } DbpString("[=] done bruteforcing"); - if (BUTTON_HELD(1000) > 0) + if (BUTTON_HELD(1000) == BUTTON_HOLD) goto out; /* We pressed a button so ignore it here with a delay */ diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index c71ff344d..7ac91d126 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -54,7 +54,7 @@ #define LF_HIDCOLLECT_LOGFILE "lf_hidcollect.log" -void DownloadLogInstructions() { +static void DownloadLogInstructions(void) { Dbprintf(""); Dbprintf("[=] To get the logfile from flash and display it:"); Dbprintf("[=] " _YELLOW_("1.") " mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE); @@ -64,7 +64,7 @@ void DownloadLogInstructions() { bool log_exists; -void append(uint8_t *entry, size_t entry_len) { +static void append(uint8_t *entry, size_t entry_len) { LED_B_ON(); if (log_exists == false) { @@ -76,7 +76,7 @@ void append(uint8_t *entry, size_t entry_len) { LED_B_OFF(); } -uint32_t IceEM410xdemod() { +static uint32_t IceEM410xdemod(void) { uint8_t *dest = BigBuf_get_addr(); size_t idx = 0; @@ -128,7 +128,7 @@ uint32_t IceEM410xdemod() { return PM3_SUCCESS; } -uint32_t IceAWIDdemod() { +static uint32_t IceAWIDdemod(void) { uint8_t *dest = BigBuf_get_addr(); size_t size = MIN(12800, BigBuf_max_traceLen()); @@ -180,7 +180,7 @@ uint32_t IceAWIDdemod() { return PM3_SUCCESS; } -uint32_t IceIOdemod() { +static uint32_t IceIOdemod(void) { int dummyIdx = 0; uint8_t version = 0, facilitycode = 0; @@ -224,7 +224,7 @@ uint32_t IceIOdemod() { return PM3_SUCCESS; } -uint32_t IceHIDDemod() { +static uint32_t IceHIDDemod(void) { int dummyIdx = 0; @@ -320,7 +320,7 @@ void ModInfo(void) { DbpString(_YELLOW_(" LF HID / IOprox / AWID / EM4100 collector mode") " - a.k.a IceHID (Iceman)"); } -void RunMod() { +void RunMod(void) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); LFSetupFPGAForADC(LF_DIVISOR_125, true); diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index 3cdfa6819..b4caf2e3f 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -23,7 +23,7 @@ void ModInfo(void) { } // samy's sniff and repeat routine for LF -void RunMod() { +void RunMod(void) { StandAloneMode(); Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<"); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 4dc45b0b3..971304918 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -31,7 +31,7 @@ void ModInfo(void) { // C = playing bank A // D = playing bank B -void RunMod() { +void RunMod(void) { StandAloneMode(); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<"); @@ -56,11 +56,6 @@ void RunMod() { int button_pressed = BUTTON_HELD(280); if (button_pressed != BUTTON_HOLD) continue; - /* - #define BUTTON_NO_CLICK 0 - #define BUTTON_SINGLE_CLICK -1 - #define BUTTON_DOUBLE_CLICK -2 - */ if (state == STATE_READ) { diff --git a/armsrc/Standalone/lf_skeleton.c b/armsrc/Standalone/lf_skeleton.c index 0d00c698d..a2d566cb7 100644 --- a/armsrc/Standalone/lf_skeleton.c +++ b/armsrc/Standalone/lf_skeleton.c @@ -18,7 +18,7 @@ void ModInfo(void) { DbpString(" LF skeleton mode - aka Skeleton (iceman)"); } -void RunMod() { +void RunMod(void) { StandAloneMode(); Dbprintf("[=] LF skeleton code a.k.a Skeleton started"); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -35,7 +35,7 @@ void RunMod() { Dbprintf("button %d", button_pressed); - if (button_pressed) + if (button_pressed != BUTTON_NO_CLICK) break; } diff --git a/armsrc/Standalone/placeholder.c b/armsrc/Standalone/placeholder.c index 84f724920..49028e27c 100644 --- a/armsrc/Standalone/placeholder.c +++ b/armsrc/Standalone/placeholder.c @@ -6,5 +6,5 @@ void ModInfo(void) { DbpString(" No standalone mode present"); } -void RunMod() { +void RunMod(void) { } diff --git a/armsrc/Standalone/readme.md b/armsrc/Standalone/readme.md index d46943778..3775d848c 100644 --- a/armsrc/Standalone/readme.md +++ b/armsrc/Standalone/readme.md @@ -131,7 +131,7 @@ Remember only one can be selected at a time for now. The final steps is to - force recompilation of all code. ```make clean``` -- compile ```make -j8``` +- compile ```make -j``` - flash your device - connect to your device - press button long time to trigger ledshow and enter your new standalone mode diff --git a/armsrc/Standalone/standalone.h b/armsrc/Standalone/standalone.h index 2dd35e94a..29363f82f 100644 --- a/armsrc/Standalone/standalone.h +++ b/armsrc/Standalone/standalone.h @@ -11,7 +11,7 @@ #ifndef __STANDALONE_H #define __STANDALONE_H -void RunMod(); -void ModInfo(); +void RunMod(void); +void ModInfo(void); #endif /* __STANDALONE_H */ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b05a143f0..afa822c7f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -70,10 +70,14 @@ #define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits uint8_t ToSend[TOSEND_BUFFER_SIZE]; int ToSendMax = -1; + +extern uint32_t _stack_start, _stack_end; + + static int ToSendBit; struct common_area common_area __attribute__((section(".commonarea"))); -int button_status = BUTTON_NO_CLICK; -bool allow_send_wtx = false; +static int button_status = BUTTON_NO_CLICK; +static bool allow_send_wtx = false; inline void send_wtx(uint16_t wtx) { if (allow_send_wtx) { @@ -106,7 +110,7 @@ void ToSendStuffBit(int b) { //----------------------------------------------------------------------------- // Read an ADC channel and block till it completes, then return the result -// in ADC units (0 to 1023). Also a routine to average 32 samples and +// in ADC units (0 to 1023). Also a routine to sum up a number of samples and // return that. //----------------------------------------------------------------------------- static uint16_t ReadAdc(int ch) { @@ -136,15 +140,17 @@ static uint16_t ReadAdc(int ch) { // was static - merlok uint16_t AvgAdc(int ch) { - uint16_t a = 0; - for (uint8_t i = 0; i < 32; i++) - a += ReadAdc(ch); - - //division by 32 - return (a + 15) >> 5; + return SumAdc(ch, 32) >> 5; } -void MeasureAntennaTuning(void) { +uint16_t SumAdc(int ch, int NbSamples) { + uint16_t a = 0; + for (uint8_t i = 0; i < NbSamples; i++) + a += ReadAdc(ch); + return (a + (NbSamples >> 1) - 1); +} + +static void MeasureAntennaTuning(void) { uint32_t peak = 0; @@ -184,7 +190,7 @@ void MeasureAntennaTuning(void) { WDT_HIT(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); - uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); + uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14); if (i == LF_DIVISOR_125) payload.v_lf125 = adcval; // voltage at 125kHz @@ -210,9 +216,9 @@ void MeasureAntennaTuning(void) { SpinDelay(50); #if defined RDV4 - payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15; #else - payload.v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + payload.v_hf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; #endif FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -221,19 +227,19 @@ void MeasureAntennaTuning(void) { } // Measure HF in milliVolt -uint16_t MeasureAntennaTuningHfData(void) { +static uint16_t MeasureAntennaTuningHfData(void) { #if defined RDV4 - return (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + return (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15; #else - return (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + return (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; #endif } // Measure LF in milliVolt -uint32_t MeasureAntennaTuningLfData(void) { - return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; +static uint32_t MeasureAntennaTuningLfData(void) { + return (MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14; } void ReadMem(int addr) { @@ -242,11 +248,10 @@ void ReadMem(int addr) { Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); } -/* osimage version information is linked in */ -extern struct version_information version_information; +/* osimage version information is linked in, cf commonutil.h */ /* bootrom version information is pointed to from _bootphase1_version_pointer */ extern char *_bootphase1_version_pointer, _flash_start, _flash_end, __data_src_start__; -void SendVersion(void) { +static void SendVersion(void) { char temp[PM3_CMD_DATA_SIZE - 12]; /* Limited data payload in USB packets */ char VersionString[PM3_CMD_DATA_SIZE - 12] = { '\0' }; @@ -256,17 +261,19 @@ void SendVersion(void) { */ char *bootrom_version = *(char **)&_bootphase1_version_pointer; - strncat(VersionString, " [ ARM ]\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, " "_YELLOW_("[ ARM ]")"\n", sizeof(VersionString) - strlen(VersionString) - 1); if (bootrom_version < &_flash_start || bootrom_version >= &_flash_end) { strcat(VersionString, "bootrom version information appears invalid\n"); } else { FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); } FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); #if defined(__clang__) strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); @@ -274,11 +281,11 @@ void SendVersion(void) { strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); #endif - strncat(VersionString, "\n [ FPGA ]\n ", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, "\n "_YELLOW_("[ FPGA ]")"\n ", sizeof(VersionString) - strlen(VersionString) - 1); - for (int i = 0; i < fpga_bitstream_num; i++) { - strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); - if (i < fpga_bitstream_num - 1) { + for (int i = 0; i < g_fpga_bitstream_num; i++) { + strncat(VersionString, g_fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); + if (i < g_fpga_bitstream_num - 1) { strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1); } } @@ -302,7 +309,7 @@ void SendVersion(void) { reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len); } -void TimingIntervalAcquisition(void) { +static void TimingIntervalAcquisition(void) { // trigger new acquisition by turning main oscillator off and on mck_from_pll_to_slck(); mck_from_slck_to_pll(); @@ -312,8 +319,8 @@ void TimingIntervalAcquisition(void) { // measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included. -void printConnSpeed(void) { - DbpString(_BLUE_("Transfer Speed")); +static void printConnSpeed(void) { + DbpString(_CYAN_("Transfer Speed")); Dbprintf(" Sending packets to client..."); #define CONN_SPEED_TEST_MIN_TIME 500 // in milliseconds @@ -339,7 +346,7 @@ void printConnSpeed(void) { /** * Prints runtime information about the PM3. **/ -void SendStatus(void) { +static void SendStatus(void) { BigBuf_print_status(); Fpga_print_status(); #ifdef WITH_FLASH @@ -353,7 +360,13 @@ void SendStatus(void) { printT55xxConfig(); // LF T55XX Config #endif printConnSpeed(); - DbpString(_BLUE_("Various")); + DbpString(_CYAN_("Various")); + for (uint32_t *p = &_stack_start; ; ++p) { + if (*p != 0xdeadbeef) { + Dbprintf(" Max stack usage so far..%d", (&_stack_end - p)*4); + break; + } + } Dbprintf(" DBGLEVEL................%d", DBGLEVEL); Dbprintf(" ToSendMax...............%d", ToSendMax); Dbprintf(" ToSendBit...............%d", ToSendBit); @@ -372,7 +385,7 @@ void SendStatus(void) { Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"), (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); } - DbpString(_BLUE_("Installed StandAlone Mode")); + DbpString(_CYAN_("Installed StandAlone Mode")); ModInfo(); #ifdef WITH_FLASH @@ -382,15 +395,16 @@ void SendStatus(void) { reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0); } -void SendCapabilities(void) { +static void SendCapabilities(void) { capabilities_t capabilities; capabilities.version = CAPABILITIES_VERSION; - capabilities.via_fpc = reply_via_fpc; - capabilities.via_usb = reply_via_usb; + capabilities.via_fpc = g_reply_via_fpc; + capabilities.via_usb = g_reply_via_usb; + capabilities.bigbuf_size = BigBuf_get_size(); capabilities.baudrate = 0; // no real baudrate for USB-CDC #ifdef WITH_FPC_USART - if (reply_via_fpc) - capabilities.baudrate = usart_baudrate; + if (g_reply_via_fpc) + capabilities.baudrate = g_usart_baudrate; #endif #ifdef WITH_FLASH @@ -524,7 +538,7 @@ at the same place! :-) void ListenReaderField(uint8_t limit) { #define LF_ONLY 1 #define HF_ONLY 2 -#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE +#define REPORT_CHANGE 1000 // report new values only if they have changed at least by REPORT_CHANGE mV uint16_t lf_av = 0, lf_av_new, lf_baseline = 0, lf_max = 0; uint16_t hf_av = 0, hf_av_new, hf_baseline = 0, hf_max = 0; @@ -538,8 +552,8 @@ void ListenReaderField(uint8_t limit) { LEDsoff(); if (limit == LF_ONLY) { - lf_av = lf_max = AvgAdc(ADC_CHAN_LF); - Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10); + lf_av = lf_max = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15; + Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av); lf_baseline = lf_av; } @@ -547,11 +561,11 @@ void ListenReaderField(uint8_t limit) { #if defined RDV4 // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader. - hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40); + hf_av = hf_max = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15; #else - hf_av = hf_max = AvgAdc(ADC_CHAN_HF); + hf_av = hf_max = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; #endif - Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); + Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av); hf_baseline = hf_av; } @@ -583,10 +597,10 @@ void ListenReaderField(uint8_t limit) { LED_D_OFF(); } - lf_av_new = AvgAdc(ADC_CHAN_LF); + lf_av_new = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15; // see if there's a significant change if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) { - Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10); + Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new); lf_av = lf_av_new; if (lf_av > lf_max) lf_max = lf_av; @@ -602,13 +616,13 @@ void ListenReaderField(uint8_t limit) { } #if defined RDV4 - hf_av_new = AvgAdc(ADC_CHAN_HF_RDV40); + hf_av_new = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15; #else - hf_av_new = AvgAdc(ADC_CHAN_HF); + hf_av_new = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; #endif // see if there's a significant change if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) { - Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); + Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new); hf_av = hf_av_new; if (hf_av > hf_max) hf_max = hf_av; @@ -701,8 +715,8 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_BREAK_LOOP: break; case CMD_QUIT_SESSION: { - reply_via_fpc = false; - reply_via_usb = false; + g_reply_via_fpc = false; + g_reply_via_usb = false; break; } // emulator @@ -1428,7 +1442,7 @@ static void PacketReceived(PacketCommandNG *packet) { // upload file from client uint8_t *mem = BigBuf_get_addr(); memcpy(mem + packet->oldarg[0], packet->data.asBytes, PM3_CMD_DATA_SIZE); - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); break; } case CMD_SMART_UPGRADE: { @@ -1628,7 +1642,7 @@ static void PacketReceived(PacketCommandNG *packet) { // arg1 = RFU // arg2 = tracelen? // asbytes = samplingconfig array - reply_old(CMD_ACK, 1, 0, BigBuf_get_traceLen(), getSamplingConfig(), sizeof(sample_config)); + reply_mix(CMD_ACK, 1, 0, BigBuf_get_traceLen(), getSamplingConfig(), sizeof(sample_config)); LED_B_OFF(); break; } @@ -1642,7 +1656,7 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint8_t flag; uint16_t offset; - uint8_t *data; + uint8_t data[PM3_CMD_DATA_SIZE - sizeof(uint8_t) - sizeof(uint16_t)]; } PACKED; struct p *payload = (struct p *)packet->data.asBytes; @@ -1653,18 +1667,17 @@ static void PacketReceived(PacketCommandNG *packet) { BigBuf_free(); } - // 40 000 - (512-3) 509 = 39491 - uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); - - // need to copy len bytes of data, not PM3_CMD_DATA_SIZE - 3 - offset + // offset should not be over buffer + if (payload->offset >= BigBuf_get_size()) { + reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_EOVFLOW, NULL, 0); + break; + } // ensure len bytes copied wont go past end of bigbuf - uint16_t len = MIN(BIGBUF_SIZE - offset, PM3_CMD_DATA_SIZE - 3); + uint16_t len = MIN(BigBuf_get_size() - payload->offset, sizeof(payload->data)); uint8_t *mem = BigBuf_get_addr(); - // x + 394 - memcpy(mem + offset, &payload->data, len); - // memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset); + memcpy(mem + payload->offset, &payload->data, len); reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0); break; } @@ -1760,7 +1773,7 @@ static void PacketReceived(PacketCommandNG *packet) { int changed = rdv40_spiffs_lazy_mount(); uint32_t size = size_in_spiffs((char *)filename); if (changed) rdv40_spiffs_lazy_unmount(); - reply_old(CMD_ACK, size, 0, 0, 0, 0); + reply_mix(CMD_ACK, size, 0, 0, 0, 0); LED_B_OFF(); break; } @@ -1936,7 +1949,7 @@ static void PacketReceived(PacketCommandNG *packet) { Flash_UniqueID(info->flashid); FlashStop(); } - reply_old(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t)); + reply_mix(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t)); BigBuf_free(); LED_B_OFF(); @@ -2050,8 +2063,12 @@ static void PacketReceived(PacketCommandNG *packet) { void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); - clear_trace(); + BigBuf_initialize(); + for (uint32_t * p = &_stack_start; p < (uint32_t *)((uintptr_t)&_stack_end - 0x200); ++p) { + *p = 0xdeadbeef; + } + if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { /* Initialize common area */ memset(&common_area, 0, sizeof(common_area)); @@ -2117,6 +2134,10 @@ void __attribute__((noreturn)) AppMain(void) { for (;;) { WDT_HIT(); + if (_stack_start != 0xdeadbeef) { + Dbprintf("Stack overflow detected! Please increase stack size."); + } + // Check if there is a packet available PacketCommandNG rx; memset(&rx.data, 0, sizeof(rx.data)); diff --git a/armsrc/appmain.h b/armsrc/appmain.h index 141c943f9..6a650f163 100644 --- a/armsrc/appmain.h +++ b/armsrc/appmain.h @@ -13,10 +13,8 @@ #include "common.h" -extern const uint8_t OddByteParity[256]; -extern int rsamples; // = 0; -extern uint8_t trigger; -extern bool allow_send_wtx; +extern int g_rsamples; // = 0; +extern uint8_t g_trigger; // ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV #define MAX_ADC_HF_VOLTAGE 36300 @@ -33,6 +31,7 @@ void ReadMem(int addr); void __attribute__((noreturn)) AppMain(void); uint16_t AvgAdc(int ch); +uint16_t SumAdc(int ch, int NbSamples); //void PrintToSendBuffer(void); void ToSendStuffBit(int b); diff --git a/armsrc/cmd.c b/armsrc/cmd.c index c7f76960b..b0dc4aef8 100644 --- a/armsrc/cmd.c +++ b/armsrc/cmd.c @@ -36,11 +36,11 @@ #include "string.h" // Flags to tell where to add CRC on sent replies -bool reply_with_crc_on_usb = false; -bool reply_with_crc_on_fpc = true; +bool g_reply_with_crc_on_usb = false; +bool g_reply_with_crc_on_fpc = true; // "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART -bool reply_via_fpc = false; -bool reply_via_usb = false; +bool g_reply_via_fpc = false; +bool g_reply_via_usb = false; int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { PacketResponseOLD txcmd = {CMD_UNKNOWN, {0, 0, 0}, {{0}}}; @@ -62,15 +62,17 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *d } } +#ifdef WITH_FPC_USART_HOST int resultfpc = PM3_EUNDEF; +#endif int resultusb = PM3_EUNDEF; // Send frame and make sure all bytes are transmitted - if (reply_via_usb) { + if (g_reply_via_usb) { resultusb = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); } - if (reply_via_fpc) { + if (g_reply_via_fpc) { #ifdef WITH_FPC_USART_HOST resultfpc = usart_writebuffer_sync((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); #else @@ -78,8 +80,10 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *d #endif } // we got two results, let's prioritize the faulty one and USB over FPC. - if (reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb; - if (reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc; + if (g_reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb; +#ifdef WITH_FPC_USART_HOST + if (g_reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc; +#endif return PM3_SUCCESS; } @@ -108,7 +112,7 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t PacketResponseNGPostamble *tx_post = (PacketResponseNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketResponseNGPreamble) + len); // Note: if we send to both FPC & USB, we'll set CRC for both if any of them require CRC - if ((reply_via_fpc && reply_with_crc_on_fpc) || ((reply_via_usb) && reply_with_crc_on_usb)) { + if ((g_reply_via_fpc && g_reply_with_crc_on_fpc) || ((g_reply_via_usb) && g_reply_with_crc_on_usb)) { uint8_t first, second; compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketResponseNGPreamble) + len, &first, &second); tx_post->crc = (first << 8) + second; @@ -117,14 +121,16 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t } txBufferNGLen = sizeof(PacketResponseNGPreamble) + len + sizeof(PacketResponseNGPostamble); +#ifdef WITH_FPC_USART_HOST int resultfpc = PM3_EUNDEF; +#endif int resultusb = PM3_EUNDEF; // Send frame and make sure all bytes are transmitted - if (reply_via_usb) { + if (g_reply_via_usb) { resultusb = usb_write((uint8_t *)&txBufferNG, txBufferNGLen); } - if (reply_via_fpc) { + if (g_reply_via_fpc) { #ifdef WITH_FPC_USART_HOST resultfpc = usart_writebuffer_sync((uint8_t *)&txBufferNG, txBufferNGLen); #else @@ -132,8 +138,10 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t #endif } // we got two results, let's prioritize the faulty one and USB over FPC. - if (reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb; - if (reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc; + if (g_reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb; +#ifdef WITH_FPC_USART_HOST + if (g_reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc; +#endif return PM3_SUCCESS; } @@ -208,8 +216,8 @@ static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *da if ((first << 8) + second != rx->crc) return PM3_EIO; } - reply_via_usb = usb; - reply_via_fpc = fpc; + g_reply_via_usb = usb; + g_reply_via_fpc = fpc; } else { // Old style command PacketCommandOLD rx_old; memcpy(&rx_old, &rx_raw.pre, sizeof(PacketCommandNGPreamble)); @@ -217,8 +225,8 @@ static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *da if (bytes != sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble)) return PM3_EIO; - reply_via_usb = usb; - reply_via_fpc = fpc; + g_reply_via_usb = usb; + g_reply_via_fpc = fpc; rx->ng = false; rx->magic = 0; rx->crc = 0; diff --git a/armsrc/cmd.h b/armsrc/cmd.h index e04f397a3..f4ae95ab1 100644 --- a/armsrc/cmd.h +++ b/armsrc/cmd.h @@ -37,11 +37,11 @@ #include "pm3_cmd.h" // Flags to tell where to add CRC on sent replies -extern bool reply_with_crc_on_usb; -extern bool reply_with_crc_on_fpc; +extern bool g_reply_with_crc_on_usb; +extern bool g_reply_with_crc_on_fpc; // "Session" flag, to tell via which interface next msgs should be sent: USB and/or FPC USART -extern bool reply_via_fpc; -extern bool reply_via_usb; +extern bool g_reply_via_fpc; +extern bool g_reply_via_usb; int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len); diff --git a/armsrc/dbprint.c b/armsrc/dbprint.c index 9b18b7aca..bfeb0ded2 100644 --- a/armsrc/dbprint.c +++ b/armsrc/dbprint.c @@ -22,7 +22,7 @@ // Debug print functions, to go out over USB, to the usual PC-side client. //============================================================================= -void DbpStringEx(uint32_t flags, char *src, size_t srclen) { +void DbpStringEx(uint32_t flags, const char *src, size_t srclen) { #if DEBUG struct { uint16_t flag; @@ -35,7 +35,7 @@ void DbpStringEx(uint32_t flags, char *src, size_t srclen) { #endif } -void DbpString(char *str) { +void DbpString(const char *str) { #if DEBUG DbpStringEx(FLAG_LOG, str, strlen(str)); #endif @@ -98,7 +98,7 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) { #endif } -void print_result(char *name, uint8_t *buf, size_t len) { +void print_result(const char *name, uint8_t *buf, size_t len) { uint8_t *p = buf; uint16_t tmp = len & 0xFFF0; diff --git a/armsrc/dbprint.h b/armsrc/dbprint.h index c3229f46f..993e06289 100644 --- a/armsrc/dbprint.h +++ b/armsrc/dbprint.h @@ -15,39 +15,39 @@ #include "ansi.h" #define Dbprintf_usb(...) {\ - bool tmpfpc = reply_via_fpc;\ - bool tmpusb = reply_via_usb;\ - reply_via_fpc = false;\ - reply_via_usb = true;\ + bool tmpfpc = g_reply_via_fpc;\ + bool tmpusb = g_reply_via_usb;\ + g_reply_via_fpc = false;\ + g_reply_via_usb = true;\ Dbprintf(__VA_ARGS__);\ - reply_via_fpc = tmpfpc;\ - reply_via_usb = tmpusb;} + g_reply_via_fpc = tmpfpc;\ + g_reply_via_usb = tmpusb;} #define Dbprintf_fpc(...) {\ - bool tmpfpc = reply_via_fpc;\ - bool tmpusb = reply_via_usb;\ - reply_via_fpc = true;\ - reply_via_usb = false;\ + bool tmpfpc = g_reply_via_fpc;\ + bool tmpusb = g_reply_via_usb;\ + g_reply_via_fpc = true;\ + g_reply_via_usb = false;\ Dbprintf(__VA_ARGS__);\ - reply_via_fpc = tmpfpc;\ - reply_via_usb = tmpusb;} + g_reply_via_fpc = tmpfpc;\ + g_reply_via_usb = tmpusb;} #define Dbprintf_all(...) {\ - bool tmpfpc = reply_via_fpc;\ - bool tmpusb = reply_via_usb;\ - reply_via_fpc = true;\ - reply_via_usb = true;\ + bool tmpfpc = g_reply_via_fpc;\ + bool tmpusb = g_reply_via_usb;\ + g_reply_via_fpc = true;\ + g_reply_via_usb = true;\ Dbprintf(__VA_ARGS__);\ - reply_via_fpc = tmpfpc;\ - reply_via_usb = tmpusb;} + g_reply_via_fpc = tmpfpc;\ + g_reply_via_usb = tmpusb;} -void DbpString(char *str); -void DbpStringEx(uint32_t flags, char *src, size_t srclen); +void DbpString(const char *str); +void DbpStringEx(uint32_t flags, const char *src, size_t srclen); void Dbprintf(const char *fmt, ...); void DbprintfEx(uint32_t flags, const char *fmt, ...); void Dbhexdump(int len, uint8_t *d, bool bAsci); -void print_result(char *name, uint8_t *buf, size_t len); +void print_result(const char *name, uint8_t *buf, size_t len); //void PrintToSendBuffer(void); #endif diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index 99bb54743..cafa98de1 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -36,6 +36,7 @@ #include "printf.h" #include "iso14443a.h" #include "dbprint.h" +#include "BigBuf.h" #ifndef AddCrc14A # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) @@ -45,9 +46,9 @@ static mbedtls_des_context ctx; static mbedtls_des3_context ctx3; static mbedtls_aes_context actx; -static inline void update_key_schedules(desfirekey_t key); +static void update_key_schedules(desfirekey_t key); -static inline void update_key_schedules(desfirekey_t key) { +static void update_key_schedules(desfirekey_t key) { // DES_set_key ((DES_cblock *)key->data, &(key->ks1)); // DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2)); // if (T_3K3DES == key->type) { @@ -282,7 +283,10 @@ void cmac_generate_subkeys(desfirekey_t key) { void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) { int kbs = key_block_size(key); - uint8_t *buffer = malloc(padded_data_length(len, kbs)); + if (kbs == 0) + return; + + uint8_t *buffer = BigBuf_malloc(padded_data_length(len, kbs)); memcpy(buffer, data, len); @@ -299,7 +303,7 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le mifare_cypher_blocks_chained(NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER); memcpy(cmac, ivect, kbs); - free(buffer); + //free(buffer); } size_t key_block_size(const desfirekey_t key) { @@ -538,7 +542,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes } size_t edl = enciphered_data_length(tag, *nbytes - 1, communication_settings); - edata = malloc(edl); + edata = BigBuf_malloc(edl); memcpy(edata, data, *nbytes - 1); memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1); diff --git a/armsrc/desfire_crypto.h b/armsrc/desfire_crypto.h index 58588cd0d..f8a99a991 100644 --- a/armsrc/desfire_crypto.h +++ b/armsrc/desfire_crypto.h @@ -99,8 +99,6 @@ struct desfire_tag { uint32_t selected_application; }; typedef struct desfire_tag *desfiretag_t; -void crc32_ex(const uint8_t *data, const size_t len, uint8_t *crc); -void crc32_append(uint8_t *data, const size_t len); void des_encrypt(void *out, const void *in, const void *key); void des_decrypt(void *out, const void *in, const void *key); void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode); diff --git a/armsrc/epa.c b/armsrc/epa.c index 867f4a43f..cdc83fe5d 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -113,7 +113,7 @@ static char iso_type = 0; //----------------------------------------------------------------------------- // Wrapper for sending APDUs to type A and B cards //----------------------------------------------------------------------------- -int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) { +static int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) { switch (iso_type) { case 'a': return iso14_apdu(apdu, (uint16_t) length, false, response, NULL); @@ -130,7 +130,7 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) { //----------------------------------------------------------------------------- // Closes the communication channel and turns off the field //----------------------------------------------------------------------------- -void EPA_Finish() { +void EPA_Finish(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); iso_type = 0; @@ -501,7 +501,7 @@ void EPA_PACE_Replay(PacketCommandNG *c) { // Set up a communication channel (Card Select, PPS) // Returns 0 on success or a non-zero error code on failure //----------------------------------------------------------------------------- -int EPA_Setup() { +int EPA_Setup(void) { // first, look for type A cards // power up the field diff --git a/armsrc/epa.h b/armsrc/epa.h index 66a95c059..237238181 100644 --- a/armsrc/epa.h +++ b/armsrc/epa.h @@ -23,12 +23,12 @@ typedef struct { } pace_version_info_t; // general functions -void EPA_Finish(); +void EPA_Finish(void); size_t EPA_Parse_CardAccess(uint8_t *data, size_t length, pace_version_info_t *pace_info); int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length); -int EPA_Setup(); +int EPA_Setup(void); // PACE related functions int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password); diff --git a/armsrc/felica.c b/armsrc/felica.c index 2cb23b48c..f8375f0cc 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -35,13 +35,13 @@ static uint32_t felica_lasttime_prox2air_start; static void iso18092_setup(uint8_t fpga_minor_mode); static uint8_t felica_select_card(felica_card_select_t *card); static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed); -bool WaitForFelicaReply(uint16_t maxbytes); +static bool WaitForFelicaReply(uint16_t maxbytes); -void iso18092_set_timeout(uint32_t timeout) { +static void iso18092_set_timeout(uint32_t timeout) { felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2; } -uint32_t iso18092_get_timeout(void) { +static uint32_t iso18092_get_timeout(void) { return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) - 2; } @@ -80,7 +80,7 @@ static struct { # define SYNC_16BIT 0xB24D #endif -static void FelicaFrameReset() { +static void FelicaFrameReset(void) { FelicaFrame.state = STATE_UNSYNCD; FelicaFrame.posCnt = 0; FelicaFrame.crc_ok = false; @@ -431,7 +431,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { ); if (DBGLEVEL >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL"); return true; - } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { + } else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) { if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD"); return false; } @@ -481,7 +481,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) { LED_D_ON(); } -void felica_reset_frame_mode() { +static void felica_reset_frame_mode(void) { switch_off(); //Resetting Frame mode (First set in fpgaloader.c) AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); @@ -738,7 +738,7 @@ void felica_sim_lite(uint64_t uid) { #define RES_SVC_LEN 11 + 3 -void felica_dump_lite_s() { +void felica_dump_lite_s(void) { uint8_t ndef[8]; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; uint16_t liteblks[28] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x90, 0x91, 0x92, 0xa0}; diff --git a/armsrc/felica.h b/armsrc/felica.h index ef34dc108..885815abb 100644 --- a/armsrc/felica.h +++ b/armsrc/felica.h @@ -17,6 +17,6 @@ void felica_sendraw(PacketCommandNG *c); void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); void felica_sim_lite(uint64_t uid); -void felica_dump_lite_s(); +void felica_dump_lite_s(void); #endif diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index e3a20cacc..f09ae8c40 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -16,8 +16,8 @@ /// Calculates the value of the CSR DLYBCT field given the desired delay (in ns) #define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24) - -uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD; +static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD; +#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST) void FlashmemSetSpiBaudrate(uint32_t baudrate) { FLASHMEM_SPIBAUDRATE = baudrate; @@ -25,7 +25,7 @@ void FlashmemSetSpiBaudrate(uint32_t baudrate) { } // initialize -bool FlashInit() { +bool FlashInit(void) { FlashSetup(FLASHMEM_SPIBAUDRATE); StartTicks(); @@ -435,7 +435,7 @@ bool Flash_WipeMemoryPage(uint8_t page) { return true; } // Wipes flash memory completely, fills with 0xFF -bool Flash_WipeMemory() { +bool Flash_WipeMemory(void) { if (!FlashInit()) { if (DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail"); return false; @@ -462,7 +462,7 @@ bool Flash_WipeMemory() { } // enable the flash write -void Flash_WriteEnable() { +void Flash_WriteEnable(void) { FlashSendLastByte(WRITEENABLE); if (DBGLEVEL > 3) Dbprintf("Flash Write enabled"); } @@ -523,7 +523,7 @@ void Flash_EraseChip(void) { */ void Flashmem_print_status(void) { - DbpString(_BLUE_("Flash memory")); + DbpString(_CYAN_("Flash memory")); Dbprintf(" Baudrate................" _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000); if (!FlashInit()) { @@ -562,7 +562,7 @@ void Flashmem_print_info(void) { if (!FlashInit()) return; - DbpString(_BLUE_("Flash memory dictionary loaded")); + DbpString(_CYAN_("Flash memory dictionary loaded")); // load dictionary offsets. uint8_t keysum[2]; diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 42fc3d2f0..54a101ea6 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -106,12 +106,10 @@ #define FLASH_FASTBAUD MCK #define FLASH_MINBAUD FLASH_FASTBAUD -#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST) - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// void FlashmemSetSpiBaudrate(uint32_t baudrate); -bool FlashInit(); +bool FlashInit(void); void FlashSetup(uint32_t baudrate); void FlashStop(void); bool Flash_WaitIdle(void); @@ -122,9 +120,9 @@ void Flash_TransferAdresse(uint32_t address); bool Flash_CheckBusy(uint32_t timeout); -void Flash_WriteEnable(); +void Flash_WriteEnable(void); bool Flash_WipeMemoryPage(uint8_t page); -bool Flash_WipeMemory(); +bool Flash_WipeMemory(void); bool Flash_Erase4k(uint8_t block, uint8_t sector); //bool Flash_Erase32k(uint32_t address); bool Flash_Erase64k(uint8_t block); diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index a5ca3f6d1..f1f157eec 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -17,10 +17,19 @@ #include "ticks.h" #include "dbprint.h" #include "util.h" -#include "zlib.h" #include "fpga.h" #include "string.h" +#include "lz4.h" // uncompress + +typedef struct lz4_stream_s { + LZ4_streamDecode_t *lz4StreamDecode; + char *next_in; + int avail_in; +} lz4_stream; + +typedef lz4_stream *lz4_streamp; + // remember which version of the bitstream we have already downloaded to the FPGA static int downloaded_bitstream = 0; @@ -30,8 +39,6 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end; static uint8_t *fpga_image_ptr = NULL; static uint32_t uncompressed_bytes_cnt; -#define OUTPUT_BUFFER_LEN 80 - //----------------------------------------------------------------------------- // Set up the Serial Peripheral Interface as master // Used to write the FPGA config word @@ -180,18 +187,23 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) { // Uncompress (inflate) the FPGA data. Returns one decompressed byte with // each call. //---------------------------------------------------------------------------- -static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) { - if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data - compressed_fpga_stream->next_out = output_buffer; - compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; +static int get_from_fpga_combined_stream(lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) { + if (fpga_image_ptr == output_buffer + FPGA_RING_BUFFER_BYTES) { // need more data fpga_image_ptr = output_buffer; - int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH); - - if (res != Z_OK) - Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg); - - if (res < 0) + int cmp_bytes; + memcpy(&cmp_bytes, compressed_fpga_stream->next_in, sizeof(int)); + compressed_fpga_stream->next_in += 4; + compressed_fpga_stream->avail_in -= cmp_bytes + 4; + int res = LZ4_decompress_safe_continue(compressed_fpga_stream->lz4StreamDecode, + compressed_fpga_stream->next_in, + (char *)output_buffer, + cmp_bytes, + FPGA_RING_BUFFER_BYTES); + if (res <= 0) { + Dbprintf("inflate returned: %d", res); return res; + } + compressed_fpga_stream->next_in += cmp_bytes; } uncompressed_bytes_cnt++; return *fpga_image_ptr++; @@ -202,8 +214,8 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8 // are combined into one big file: // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc. //---------------------------------------------------------------------------- -static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { - while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) { +static int get_from_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) { + while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) { // skip undesired data belonging to other bitstream_versions get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); } @@ -211,37 +223,23 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); } -static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) { - return BigBuf_malloc(items * size); -} - -// free eventually allocated BigBuf memory -static void fpga_inflate_free(voidpf opaque, voidpf address) { - BigBuf_free(); - BigBuf_Clear_ext(false); -} - //---------------------------------------------------------------------------- // Initialize decompression of the respective (HF or LF) FPGA stream //---------------------------------------------------------------------------- -static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { +static bool reset_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) { uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE]; uncompressed_bytes_cnt = 0; // initialize z_stream structure for inflate: - compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start; + compressed_fpga_stream->next_in = (char *)&_binary_obj_fpga_all_bit_z_start; compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start; - compressed_fpga_stream->next_out = output_buffer; - compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; - compressed_fpga_stream->zalloc = &fpga_inflate_malloc; - compressed_fpga_stream->zfree = &fpga_inflate_free; - int res = inflateInit2(compressed_fpga_stream, 0); - if (res < 0) + int res = LZ4_setStreamDecode(compressed_fpga_stream->lz4StreamDecode, NULL, 0); + if (res == 0) return false; - fpga_image_ptr = output_buffer; + fpga_image_ptr = output_buffer + FPGA_RING_BUFFER_BYTES; for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); @@ -266,7 +264,7 @@ static void DownloadFPGA_byte(uint8_t w) { } // Download the fpga image starting at current stream position with length FpgaImageLen bytes -static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { +static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) { int i = 0; AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; @@ -348,7 +346,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp * (big endian), bytes content. Except for section 'e' which has 4 bytes * length. */ -static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { +static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) { int result = 0; #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section uint16_t numbytes = 0; @@ -407,8 +405,6 @@ void FpgaDownloadAndGo(int bitstream_version) { // Send waiting time extension request as this will take a while send_wtx(1500); - z_stream compressed_fpga_stream; - uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00}; bool verbose = (DBGLEVEL > 3); @@ -416,6 +412,11 @@ void FpgaDownloadAndGo(int bitstream_version) { BigBuf_free(); BigBuf_Clear_ext(verbose); + lz4_stream compressed_fpga_stream; + LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }}; + compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body; + uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES); + if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) return; @@ -425,8 +426,6 @@ void FpgaDownloadAndGo(int bitstream_version) { downloaded_bitstream = bitstream_version; } - inflateEnd(&compressed_fpga_stream); - // turn off antenna FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -508,8 +507,8 @@ void SetAdcMuxFor(uint32_t whichGpio) { } void Fpga_print_status(void) { - DbpString(_BLUE_("Currently loaded FPGA image")); - Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream - 1]); + DbpString(_CYAN_("Current FPGA image")); + Dbprintf(" mode....................%s", g_fpga_version_information[downloaded_bitstream - 1]); } int FpgaGetCurrent(void) { diff --git a/armsrc/frozen.c b/armsrc/frozen.c index 6477e0602..b8a6f3a02 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -863,7 +863,7 @@ struct json_scanf_info { int json_unescape(const char *src, int slen, char *dst, int dlen) WEAK; int json_unescape(const char *src, int slen, char *dst, int dlen) { if (dst == NULL || dlen == 0) - return JSON_STRING_INVALID; + return JSON_STRING_INVALID; char *send = (char *) src + slen; char *dend = dst + dlen; @@ -1471,10 +1471,9 @@ char *json_vasprintf(const char *fmt, va_list ap) { char *json_asprintf(const char *fmt, ...) WEAK; char *json_asprintf(const char *fmt, ...) { - char *result = NULL; va_list ap; va_start(ap, fmt); - result = json_vasprintf(fmt, ap); + char *result = json_vasprintf(fmt, ap); va_end(ap); return result; } diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 7e4c7ca14..cf1aa46c1 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -48,8 +48,8 @@ static bool bCrypto; // Is in auth stage static bool bAuthenticating; // Successful password auth -bool bSelecting; -bool bCollision; +static bool bSelecting; +static bool bCollision; static bool bPwd; static bool bSuccessful; @@ -89,14 +89,14 @@ static uint8_t password[4]; static uint8_t NrAr[8]; static uint8_t key[8]; static uint8_t writedata[4]; -uint8_t logdata_0[4], logdata_1[4]; -uint8_t nonce[4]; -bool key_no; +static uint8_t logdata_0[4], logdata_1[4]; +static uint8_t nonce[4]; +static bool key_no; static uint64_t cipher_state; -int16_t blocknr; -size_t flipped_bit = 0; -uint32_t byte_value = 0; +static int16_t blocknr; +static size_t flipped_bit = 0; +static uint32_t byte_value = 0; static int hitag2_reset(void) { tag.state = TAG_STATE_RESET; @@ -373,7 +373,7 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) return wait; } -uint8_t hitag_crc(uint8_t *data, size_t length) { +static uint8_t hitag_crc(uint8_t *data, size_t length) { uint8_t crc = 0xff; unsigned int byte, bit; for (byte = 0; byte < ((length + 7) / 8); byte++) { @@ -411,7 +411,7 @@ void fix_ac_decoding(uint8_t *input, size_t len) { // looks at number of received bits. // 0 = collision? // 32 = good response -bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { +static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { uint8_t crc; *txlen = 0; switch (rxlen) { @@ -480,7 +480,7 @@ bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bo } -bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { +static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { uint8_t crc; *txlen = 0; switch (rxlen) { @@ -997,7 +997,7 @@ void SniffHitag2(void) { lf_init(false, false); - logging = false; + g_logging = false; size_t periods = 0; uint8_t periods_bytes[4]; @@ -1031,8 +1031,8 @@ void SniffHitag2(void) { // Test if we detected the first reader modulation edge if (periods != 0) { - if (logging == false) { - logging = true; + if (g_logging == false) { + g_logging = true; LED_D_ON(); } } @@ -1062,7 +1062,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { lf_init(false, true); int response = 0; - uint8_t rx[HITAG_FRAME_LEN]; + uint8_t rx[HITAG_FRAME_LEN] = {0}; size_t rxlen = 0; uint8_t tx[HITAG_FRAME_LEN]; size_t txlen = 0; @@ -1238,7 +1238,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { // Check if frame was captured if (rxlen > 4) { - LogTrace(rx, nbytes(rxlen), response, 0, NULL, true); + LogTrace(rx, nbytes(rxlen), response, response, NULL, true); // Process the incoming frame (rx) and prepare the outgoing frame (tx) hitag2_handle_reader_command(rx, rxlen, tx, &txlen); @@ -1397,21 +1397,23 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { uint8_t attempt_count = 0; // Tag specific configuration settings (sof, timings, etc.) - if (htf < 10) { - // hitagS settings - t_wait_1 = 204; - t_wait_2 = 128; - flipped_bit = 0; - tag_size = 8; - DBG DbpString("Configured for hitagS reader"); - } else if (htf < 20) { +// TODO HTS + /* if (htf <= HTS_LAST_CMD) { + // hitagS settings + t_wait_1 = 204; + t_wait_2 = 128; + flipped_bit = 0; + tag_size = 8; + DBG DbpString("Configured for hitagS reader"); + } else */ + if (htf <= HT1_LAST_CMD) { // hitag1 settings t_wait_1 = 204; t_wait_2 = 128; tag_size = 256; flipped_bit = 0; DBG DbpString("Configured for hitag1 reader"); - } else if (htf < 30) { + } else if (htf <= HT2_LAST_CMD) { // hitag2 settings t_wait_1 = HITAG_T_WAIT_1_MIN; t_wait_2 = HITAG_T_WAIT_2_MIN; @@ -1721,28 +1723,32 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) { lf_init(true, false); // Tag specific configuration settings (sof, timings, etc.) - if (htf < 10) { - // hitagS settings - t_wait_1 = 204; - t_wait_2 = 128; - /*tag_size = 256;*/ - flipped_bit = 0; - tag_size = 8; - DbpString("Configured for hitagS writer"); - } else if (htf < 20) { - // hitag1 settings - t_wait_1 = 204; - t_wait_2 = 128; - tag_size = 256; - flipped_bit = 0; - DbpString("Configured for hitag1 writer"); - } else if (htf < 30) { - // hitag2 settings - t_wait_1 = HITAG_T_WAIT_1_MIN; - t_wait_2 = HITAG_T_WAIT_2_MIN; - tag_size = 48; - DbpString("Configured for hitag2 writer"); - } +// TODO HTS + /* if (htf <= HTS_LAST_CMD) { + // hitagS settings + t_wait_1 = 204; + t_wait_2 = 128; + //tag_size = 256; + flipped_bit = 0; + tag_size = 8; + DbpString("Configured for hitagS writer"); + } else */ +// TODO HT1 + /* if (htf <= HT1_LAST_CMD) { + // hitag1 settings + t_wait_1 = 204; + t_wait_2 = 128; + tag_size = 256; + flipped_bit = 0; + DbpString("Configured for hitag1 writer"); + } else */ +// if (htf <= HT2_LAST_CMD) { + // hitag2 settings + t_wait_1 = HITAG_T_WAIT_1_MIN; + t_wait_2 = HITAG_T_WAIT_2_MIN; + tag_size = 48; + DbpString("Configured for hitag2 writer"); +// } uint8_t tag_modulation; size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit diff --git a/armsrc/hitag2crack.c b/armsrc/hitag2crack.c index faf530897..a79c166d6 100644 --- a/armsrc/hitag2crack.c +++ b/armsrc/hitag2crack.c @@ -17,9 +17,9 @@ #define READP0CMD "1100000111" #define ERROR_RESPONSE "F402889C" -extern const uint8_t Hitag2Sync[5]; -extern bool CryptoActive; -extern Hitag_State Hitag_Crypto_State; +static const uint8_t Hitag2Sync[5]; +static bool CryptoActive; +static Hitag_State Hitag_Crypto_State; // hitag2_crack implements the first crack algorithm described in the paper, // Gone In 360 Seconds by Verdult, Garcia and Balasch. diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 8e9a4bb88..7a49d65cd 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -48,8 +48,7 @@ static int temp2 = 0; static int sof_bits; // number of start-of-frame bits static uint8_t pwdh0, pwdl0, pwdl1; // password bytes static uint32_t rnd = 0x74124485; // randomnumber -size_t blocknr; -bool end = false; +static bool end = false; //#define SENDBIT_TEST /* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3 @@ -110,7 +109,7 @@ bool end = false; * Implementation of the crc8 calculation from Hitag S * from http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HitagS.V11.pdf */ -void calc_crc(unsigned char *crc, unsigned char data, unsigned char Bitcount) { +static void calc_crc(unsigned char *crc, unsigned char data, unsigned char Bitcount) { *crc ^= data; // crc = crc (exor) data do { if (*crc & 0x80) { // if (MSB-CRC == 1) @@ -333,7 +332,7 @@ static int check_select(uint8_t *rx, uint32_t uid) { return 0; } -void hitagS_set_frame_modulation() { +static void hitagS_set_frame_modulation(void) { switch (tag.mode) { case HT_STANDARD: sof_bits = 1; @@ -434,8 +433,8 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, temp2++; *txlen = 32; state = _hitag2_init(REV64(tag.key), - REV32(tag.pages[0][0]), - REV32(((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0])) + REV32((tag.pages[0][3] << 24) + (tag.pages[0][2] << 16) + (tag.pages[0][1] << 8) + tag.pages[0][0]), + REV32((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0]) ); Dbprintf(",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}", rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]); @@ -446,7 +445,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, _hitag2_byte(&state); //send con2, pwdh0, pwdl0, pwdl1 encrypted as a response - tx[0] = _hitag2_byte(&state) ^ ((tag.pages[0][1] >> 16) & 0xff); + tx[0] = _hitag2_byte(&state) ^ tag.pages[1][2]; tx[1] = _hitag2_byte(&state) ^ tag.pwdh0; tx[2] = _hitag2_byte(&state) ^ tag.pwdl0; tx[3] = _hitag2_byte(&state) ^ tag.pwdl1; @@ -454,7 +453,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, //add crc8 *txlen = 40; crc = CRC_PRESET; - calc_crc(&crc, ((tag.pages[0][1] >> 16) & 0xff), 8); + calc_crc(&crc, tag.pages[1][2], 8); calc_crc(&crc, tag.pwdh0, 8); calc_crc(&crc, tag.pwdl0, 8); calc_crc(&crc, tag.pwdl1, 8); @@ -466,10 +465,16 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, if (temp2 % 2 == 0) { tag.uid = 0x11223344; - tag.pages[0][0] = 0x44332211; + tag.pages[0][0] = 0x11; + tag.pages[0][1] = 0x22; + tag.pages[0][2] = 0x33; + tag.pages[0][3] = 0x44; } else { tag.uid = 0x55667788; - tag.pages[0][0] = 0x88776655; + tag.pages[0][0] = 0x55; + tag.pages[0][1] = 0x66; + tag.pages[0][2] = 0x77; + tag.pages[0][3] = 0x88; } */ } @@ -480,16 +485,20 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, //data received to be written if (tag.tstate == HT_WRITING_PAGE_DATA) { tag.tstate = HT_NO_OP; - tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] - << 0) + (rx[1] << 8) + (rx[2] << 16) + (rx[3] << 24); + tag.pages[page_to_be_written][0] = rx[0]; + tag.pages[page_to_be_written][1] = rx[1]; + tag.pages[page_to_be_written][2] = rx[2]; + tag.pages[page_to_be_written][3] = rx[3]; //send ack *txlen = 2; tx[0] = 0x40; page_to_be_written = 0; hitagS_set_frame_modulation(); } else if (tag.tstate == HT_WRITING_BLOCK_DATA) { - tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] - << 24) + (rx[1] << 16) + (rx[2] << 8) + rx[3]; + tag.pages[page_to_be_written][0] = rx[0]; + tag.pages[page_to_be_written][1] = rx[1]; + tag.pages[page_to_be_written][2] = rx[2]; + tag.pages[page_to_be_written][3] = rx[3]; //send ack *txlen = 2; tx[0] = 0x40; @@ -889,9 +898,12 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { } tag.uid = ((tag.pages[0][3]) << 24) | ((tag.pages[0][2]) << 16) | ((tag.pages[0][1]) << 8) | tag.pages[0][0]; - tag.key = ((tag.pages[3][3]) << 24) | ((tag.pages[3][2]) << 16) | ((tag.pages[3][1]) << 8) | tag.pages[3][0]; - tag.key <<= 16; - tag.key += ((tag.pages[2][3]) << 8) + tag.pages[2][2]; + tag.key = (((uint64_t)tag.pages[3][3]) << 40) | + (((uint64_t)tag.pages[3][2]) << 32) | + (((uint64_t)tag.pages[3][1]) << 24) | + (((uint64_t)tag.pages[3][0]) << 16) | + (((uint64_t)tag.pages[2][3]) << 8) | + (((uint64_t)tag.pages[2][2])); tag.pwdl0 = tag.pages[2][0]; tag.pwdl1 = tag.pages[2][1]; tag.pwdh0 = tag.pages[1][3]; @@ -1027,7 +1039,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { // Check if frame was captured if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, 0, NULL, true); + LogTrace(rx, nbytes(rxlen), response, response, NULL, true); // Disable timer 1 with external trigger to avoid triggers during our own modulation AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; @@ -1075,7 +1087,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { DbpString("Sim Stopped"); } -void hitagS_receive_frame(uint8_t *rx, size_t *rxlen, int *response) { +static void hitagS_receive_frame(uint8_t *rx, size_t *rxlen, int *response) { // Reset values for receiving frames memset(rx, 0x00, HITAG_FRAME_LEN * sizeof(uint8_t)); @@ -1269,7 +1281,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { // Check if frame was captured and store it if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); + LogTrace(rx, nbytes(rxlen), response, response, NULL, false); } // By default reset the transmission buffer @@ -1398,7 +1410,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { // Add transmitted frame to total count if (txlen > 0) { // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); + LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); } hitagS_receive_frame(rx, &rxlen, &response); @@ -1526,7 +1538,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { // Check if frame was captured and store it if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); + LogTrace(rx, nbytes(rxlen), response, response, NULL, false); } //check for valid input @@ -1613,7 +1625,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { // Add transmitted frame to total count if (txlen > 0) { // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); + LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); } hitagS_receive_frame(rx, &rxlen, &response); @@ -1645,7 +1657,7 @@ void check_challenges(bool file_given, uint8_t *data) { size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; int t_wait = HITAG_T_WAIT_MAX; - int lastbit, STATE = 0;; + int lastbit, STATE = 0; bool bStop; int response_bit[200]; unsigned char mask = 1; @@ -1720,7 +1732,7 @@ void check_challenges(bool file_given, uint8_t *data) { // Check if frame was captured and store it if (rxlen > 0) { // frame_count++; - LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); + LogTrace(rx, nbytes(rxlen), response, response, NULL, false); } uint8_t *tx = txbuf; @@ -1852,7 +1864,7 @@ void check_challenges(bool file_given, uint8_t *data) { // Add transmitted frame to total count if (txlen > 0) { // frame_count++; - LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); + LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); } hitagS_receive_frame(rx, &rxlen, &response); diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 3d1f050c3..7e7ba4605 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -27,19 +27,19 @@ #define SDA_H HIGH(GPIO_SDA) #define SDA_L LOW(GPIO_SDA) -#define SCL_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL) -#define SDA_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA) +#define SCL_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL) == GPIO_SCL) +#define SDA_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA) == GPIO_SDA) #define I2C_ERROR "I2C_WaitAck Error" -volatile unsigned long c; +static volatile uint32_t c; // Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz, // delay=1 is about 200kbps // timer. // I2CSpinDelayClk(4) = 12.31us // I2CSpinDelayClk(1) = 3.07us -void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { +static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { for (c = delay * 2; c; c--) {}; } @@ -47,6 +47,12 @@ void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define I2C_DELAY_2CLK I2CSpinDelayClk(2) #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) +#define I2C_DELAY_100us I2CSpinDelayClk( 100 / 3) +#define I2C_DELAY_600us I2CSpinDelayClk( 600 / 3) +#define I2C_DELAY_10ms I2CSpinDelayClk( 10 * 1000 / 3 ) +#define I2C_DELAY_30ms I2CSpinDelayClk( 30 * 1000 / 3 ) +#define I2C_DELAY_100ms I2CSpinDelayClk( 100 * 1000 / 3) + #define ISO7618_MAX_FRAME 255 // try i2c bus recovery at 100kHz = 5us high, 5us low @@ -69,6 +75,7 @@ void I2C_recovery(void) { //a STOP signal (SDA from low to high while CLK is high) SDA_L; WaitUS(5); + SCL_H; WaitUS(2); SDA_H; @@ -127,11 +134,11 @@ void I2C_Reset_EnterMainProgram(void) { StartTicks(); I2C_init(); I2C_SetResetStatus(0, 0, 0); - WaitMS(30); + I2C_DELAY_30ms; I2C_SetResetStatus(1, 0, 0); - WaitMS(30); + I2C_DELAY_30ms; I2C_SetResetStatus(1, 1, 1); - WaitMS(10); + I2C_DELAY_10ms; } // Reset the SIM_Adapter, then enter the bootloader program @@ -140,13 +147,13 @@ void I2C_Reset_EnterBootloader(void) { StartTicks(); I2C_init(); I2C_SetResetStatus(0, 1, 1); - WaitMS(100); + I2C_DELAY_100ms; I2C_SetResetStatus(1, 1, 1); - WaitMS(10); + I2C_DELAY_10ms; } // Wait for the clock to go High. -bool WaitSCL_H_delay(uint32_t delay) { +static bool WaitSCL_H_delay(uint32_t delay) { while (delay--) { if (SCL_read) { return true; @@ -158,11 +165,11 @@ bool WaitSCL_H_delay(uint32_t delay) { // 5000 * 3.07us = 15350us. 15.35ms // 15000 * 3.07us = 46050us. 46.05ms -bool WaitSCL_H(void) { +static bool WaitSCL_H(void) { return WaitSCL_H_delay(15000); } -bool WaitSCL_L_delay(uint32_t delay) { +static bool WaitSCL_L_delay(uint32_t delay) { while (delay--) { if (!SCL_read) { return true; @@ -172,26 +179,26 @@ bool WaitSCL_L_delay(uint32_t delay) { return false; } // 5000 * 3.07us = 15350us. 15.35ms -bool WaitSCL_L(void) { +static bool WaitSCL_L(void) { return WaitSCL_L_delay(15000); } // Wait max 1800ms or until SCL goes LOW. // It timeout reading response from card // Which ever comes first -bool WaitSCL_L_timeout(void) { - volatile uint16_t delay = 1800; +static bool WaitSCL_L_timeout(void) { + volatile uint32_t delay = 18000; while (delay--) { // exit on SCL LOW if (!SCL_read) return true; - WaitMS(1); + I2C_DELAY_100us; } return (delay == 0); } -bool I2C_Start(void) { +static bool I2C_Start(void) { I2C_DELAY_XCLK(4); SDA_H; @@ -209,7 +216,7 @@ bool I2C_Start(void) { return true; } -bool I2C_WaitForSim() { +static bool I2C_WaitForSim(void) { // wait for data from card if (!WaitSCL_L_timeout()) @@ -218,14 +225,14 @@ bool I2C_WaitForSim() { // 8051 speaks with smart card. // 1000*50*3.07 = 153.5ms // 1byte transfer == 1ms with max frame being 256bytes - if (!WaitSCL_H_delay(10 * 1000 * 50)) + if (!WaitSCL_H_delay(20 * 1000 * 50)) return false; return true; } // send i2c STOP -void I2C_Stop(void) { +static void I2C_Stop(void) { SCL_L; I2C_DELAY_2CLK; SDA_L; @@ -238,7 +245,7 @@ void I2C_Stop(void) { } // Send i2c ACK -void I2C_Ack(void) { +static void I2C_Ack(void) { SCL_L; I2C_DELAY_2CLK; SDA_L; @@ -251,7 +258,7 @@ void I2C_Ack(void) { } // Send i2c NACK -void I2C_NoAck(void) { +static void I2C_NoAck(void) { SCL_L; I2C_DELAY_2CLK; SDA_H; @@ -263,7 +270,7 @@ void I2C_NoAck(void) { I2C_DELAY_2CLK; } -bool I2C_WaitAck(void) { +static bool I2C_WaitAck(void) { SCL_L; I2C_DELAY_1CLK; SDA_H; @@ -282,7 +289,7 @@ bool I2C_WaitAck(void) { return true; } -void I2C_SendByte(uint8_t data) { +static void I2C_SendByte(uint8_t data) { uint8_t bits = 8; while (bits--) { @@ -308,7 +315,7 @@ void I2C_SendByte(uint8_t data) { SCL_L; } -int16_t I2C_ReadByte(void) { +static int16_t I2C_ReadByte(void) { uint8_t bits = 8, b = 0; SDA_H; @@ -433,7 +440,9 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d // extra wait 500us (514us measured) // 200us (xx measured) - WaitUS(600); +// WaitUS(600); + I2C_DELAY_600us; + bool bBreak = true; uint16_t readcount = 0; @@ -474,7 +483,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d *data = (uint8_t)tmp & 0xFF; len--; - // 读å–的第一个字节为åŽç»­é•¿åº¦ + // The first byte in response is the message length if (!readcount && (len > *data)) { len = *data; @@ -601,7 +610,7 @@ bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t d } void I2C_print_status(void) { - DbpString(_BLUE_("Smart card module (ISO 7816)")); + DbpString(_CYAN_("Smart card module (ISO 7816)")); uint8_t maj, min; if (I2C_get_version(&maj, &min) == PM3_SUCCESS) Dbprintf(" version................." _YELLOW_("v%x.%02d"), maj, min); @@ -623,7 +632,7 @@ int I2C_get_version(uint8_t *maj, uint8_t *min) { } // Will read response from smart card module, retries 3 times to get the data. -bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) { +static bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) { uint8_t i = 3; int16_t len = 0; @@ -799,7 +808,8 @@ void SmartCardUpgrade(uint64_t arg0) { } // writing takes time. - WaitMS(50); +// WaitMS(50); + I2C_DELAY_100ms; // read res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 9ab2b5013..1e9bb671f 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -520,7 +520,7 @@ static RAMFUNC int OutOfNDecoding(int bit) { // Manchester //============================================================================= static tDemodIc Demod; -static void DemodIcReset() { +static void DemodIcReset(void) { Demod.bitCount = 0; Demod.posCount = 0; Demod.syncBit = 0; @@ -985,7 +985,7 @@ void RAMFUNC SniffIClass(void) { switch_off(); } -void rotateCSN(uint8_t *originalCSN, uint8_t *rotatedCSN) { +static void rotateCSN(uint8_t *originalCSN, uint8_t *rotatedCSN) { int i; for (i = 0; i < 8; i++) rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i + 1) % 8] << 5); @@ -1146,7 +1146,7 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) { } // Only SOF -static void CodeIClassTagSOF() { +static void CodeIClassTagSOF(void) { //So far a dummy implementation, not used //int lastProxToAirDuration =0; @@ -1757,7 +1757,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *wait) { //----------------------------------------------------------------------------- // Prepare iClass reader command to send to FPGA //----------------------------------------------------------------------------- -void CodeIClassCommand(const uint8_t *cmd, int len) { +static void CodeIClassCommand(const uint8_t *cmd, int len) { int i, j, k; ToSendReset(); @@ -1793,7 +1793,7 @@ void CodeIClassCommand(const uint8_t *cmd, int len) { ToSendMax++; } -void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) { +static void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) { // This is tied to other size changes CodeIClassCommand(frame, len); @@ -1802,9 +1802,9 @@ void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) { TransmitIClassCommand(ToSend, ToSendMax, &wait); LED_A_ON(); - LogTrace(frame, len, rsamples, rsamples, NULL, true); + LogTrace(frame, len, g_rsamples, g_rsamples, NULL, true); } -void ReaderTransmitIClass(uint8_t *frame, int len) { +static void ReaderTransmitIClass(uint8_t *frame, int len) { ReaderTransmitIClass_ext(frame, len, 330); } @@ -1862,16 +1862,16 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) { return false; } -int ReaderReceiveIClass(uint8_t *receivedAnswer) { +static int ReaderReceiveIClass(uint8_t *receivedAnswer) { if (GetIClassAnswer(receivedAnswer, 0, NULL) == false) return 0; - LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false); + LogTrace(receivedAnswer, Demod.len, g_rsamples, g_rsamples, NULL, false); return Demod.len; } -void setupIclassReader() { +static void setupIclassReader(void) { LEDsoff(); @@ -1898,7 +1898,7 @@ void setupIclassReader() { LED_A_ON(); } -bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) { +static bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) { while (retries-- > 0) { ReaderTransmitIClass(command, cmdsize); @@ -1935,7 +1935,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re * 1 = Got CSN * 2 = Got CSN and CC */ -uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { +static uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { // act_all... static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; @@ -2000,7 +2000,7 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { // we got all data; return 2; } -uint8_t handshakeIclassTag(uint8_t *card_data) { +static uint8_t handshakeIclassTag(uint8_t *card_data) { return handshakeIclassTag_ext(card_data, false); } @@ -2458,7 +2458,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { BigBuf_free(); } -bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) { +static bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) { uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t write[] = { 0x80 | ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(write + 2, data, 12); // data + mac diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 402d35d8a..a657dff35 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -31,9 +31,9 @@ static uint32_t iso14a_timeout; // if iso14443a not active - transmit/receive dont try to execute static bool hf_field_active = false; -uint8_t colpos = 0; -int rsamples = 0; -uint8_t trigger = 0; +static uint8_t colpos = 0; +int g_rsamples = 0; +uint8_t g_trigger = 0; // the block number for the ISO14443-4 PCB static uint8_t iso14_pcb_blocknum = 0; @@ -67,7 +67,7 @@ static uint8_t iso14_pcb_blocknum = 0; #define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) // The FPGA will report its internal sending delay in -uint16_t FpgaSendQueueDelay; +static uint16_t FpgaSendQueueDelay; // the 5 first bits are the number of bits buffered in mod_sig_buf // the last three bits are the remaining ticks/2 after the mod_sig_buf shift #define DELAY_FPGA_QUEUE (FpgaSendQueueDelay<<1) @@ -123,7 +123,7 @@ static uint32_t LastProxToAirDuration; #define SEC_Z 0xc0 void iso14a_set_trigger(bool enable) { - trigger = enable; + g_trigger = enable; } void iso14a_set_timeout(uint32_t timeout) { @@ -184,14 +184,14 @@ static tUart14a Uart; // 0011 - a 2 tick wide pause, or a three tick wide pause shifted left // 0111 - a 2 tick wide pause shifted left // 1001 - a 2 tick wide pause shifted right -const bool Mod_Miller_LUT[] = { +static const bool Mod_Miller_LUT[] = { false, true, false, true, false, false, false, true, false, true, false, false, false, false, false, false }; #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) -tUart14a *GetUart14a() { +tUart14a *GetUart14a(void) { return &Uart; } @@ -351,11 +351,11 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { // 8 ticks modulated: A collision. Save the collision position and treat as Sequence D // Note 1: the bitstream may start at any time. We therefore need to sync. // Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only) -tDemod14a Demod; +static tDemod14a Demod; // Lookup-Table to decide if 4 raw bits are a modulation. // We accept three or four "1" in any position -const bool Mod_Manchester_LUT[] = { +static const bool Mod_Manchester_LUT[] = { false, false, false, false, false, false, false, true, false, false, false, true, false, true, true, true }; @@ -363,7 +363,7 @@ const bool Mod_Manchester_LUT[] = { #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4]) #define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)]) -tDemod14a *GetDemod14a() { +tDemod14a *GetDemod14a(void) { return &Demod; } void Demod14aReset(void) { @@ -480,7 +480,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t // Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits. -RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { +static RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { Demod.twoBits = (Demod.twoBits << 8) | bit; if (Demod.state == DEMOD_14A_UNSYNCD) { @@ -1150,8 +1150,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { // Such a response is less time critical, so we can prepare them on the fly #define DYNAMIC_RESPONSE_BUFFER_SIZE 64 #define DYNAMIC_MODULATION_BUFFER_SIZE 512 - uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE]; - uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE]; + uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0}; + uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0}; tag_response_info_t dynamic_response_info = { .response = dynamic_response_buffer, .response_n = 0, @@ -1613,7 +1613,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { // prepare a delayed transfer. This simply shifts ToSend[] by a number // of bits specified in the delay parameter. -void PrepareDelayedTransfer(uint16_t delay) { +static void PrepareDelayedTransfer(uint16_t delay) { delay &= 0x07; if (!delay) return; @@ -1683,7 +1683,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing //----------------------------------------------------------------------------- // Prepare reader command (in bits, support short frames) to send to FPGA //----------------------------------------------------------------------------- -void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *par) { +static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *par) { int last = 0; ToSendReset(); @@ -1759,10 +1759,11 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8 //----------------------------------------------------------------------------- // Prepare reader command to send to FPGA //----------------------------------------------------------------------------- -void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *par) { +/* +static void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *par) { CodeIso14443aBitsAsReaderPar(cmd, len * 8, par); } - +*/ //----------------------------------------------------------------------------- // Wait for commands from reader // Stop when button is pressed (return 1) or field was gone (return 2) @@ -2144,7 +2145,7 @@ void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t CodeIso14443aBitsAsReaderPar(frame, bits, par); // Send command to tag TransmitFor14443a(ToSend, ToSendMax, timing); - if (trigger) LED_A_ON(); + if (g_trigger) LED_A_ON(); LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true); } @@ -2153,7 +2154,7 @@ void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *tim ReaderTransmitBitsPar(frame, len * 8, par, timing); } -void ReaderTransmitBits(uint8_t *frame, uint16_t len, uint32_t *timing) { +static void ReaderTransmitBits(uint8_t *frame, uint16_t len, uint32_t *timing) { // Generate parity and redirect uint8_t par[MAX_PARITY_SIZE] = {0x00}; GetParity(frame, len / 8, par); @@ -2167,7 +2168,7 @@ void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing) { ReaderTransmitBitsPar(frame, len * 8, par, timing); } -int ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t offset, uint8_t *par) { +static int ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t offset, uint8_t *par) { if (!GetIso14443aAnswerFromTag(receivedAnswer, par, offset)) return false; LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, par, false); @@ -2769,7 +2770,7 @@ OUT: // Determine the distance between two nonces. // Assume that the difference is small, but we don't know which is first. // Therefore try in alternating directions. -int32_t dist_nt(uint32_t nt1, uint32_t nt2) { +static int32_t dist_nt(uint32_t nt1, uint32_t nt2) { if (nt1 == nt2) return 0; diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 10beb4489..4999c4d85 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -91,7 +91,7 @@ static struct { uint8_t *output; } Uart; -static void Uart14bReset() { +static void Uart14bReset(void) { Uart.state = STATE_14B_UNSYNCD; Uart.shiftReg = 0; Uart.bitCnt = 0; @@ -134,7 +134,7 @@ static struct { } Demod; // Clear out the state of the "UART" that receives from the tag. -static void Demod14bReset() { +static void Demod14bReset(void) { Demod.state = DEMOD_UNSYNCD; Demod.bitCount = 0; Demod.posCount = 0; @@ -641,9 +641,9 @@ void SimulateIso14443bTag(uint32_t pupi) { if (cardSTATE == SIM_NOFIELD) { #if defined RDV4 - vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15; #else - vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; #endif if (vHf > MF_MINFIELDV) { cardSTATE = SIM_IDLE; @@ -765,7 +765,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { // The soft decision on the bit uses an estimate of just the // quadrant of the reference angle, not the exact angle. -#define MAKE_SOFT_DECISION() { \ +#define MAKE_SOFT_DECISION(void) { \ if (Demod.sumI > 0) { \ v = ci; \ } else { \ @@ -780,7 +780,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by abs(ci) + abs(cq) // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq))) -#define CHECK_FOR_SUBCARRIER_old() { \ +#define CHECK_FOR_SUBCARRIER_old(void) { \ if (ci < 0) { \ if (cq < 0) { /* ci < 0, cq < 0 */ \ if (cq < ci) { \ @@ -813,7 +813,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { } //note: couldn't we just use MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2) from common.h - marshmellow -#define CHECK_FOR_SUBCARRIER() { v = MAX(myI, myQ) + (MIN(myI, myQ) >> 1); } +#define CHECK_FOR_SUBCARRIER(void) { v = MAX(myI, myQ) + (MIN(myI, myQ) >> 1); } switch (Demod.state) { case DEMOD_UNSYNCD: @@ -964,7 +964,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { * Demodulate the samples we received from the tag, also log to tracebuffer * quiet: set to 'TRUE' to disable debug output */ -static void GetTagSamplesFor14443bDemod() { +static void GetTagSamplesFor14443bDemod(void) { bool finished = false; // int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; uint32_t time_0 = 0, time_stop = 0; @@ -1150,9 +1150,9 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) { TransmitFor14443b_AsReader(); - if (trigger) LED_A_ON(); + if (g_trigger) LED_A_ON(); - LogTrace(cmd, len, time_start, GetCountSspClk() - time_start, NULL, true); + LogTrace(cmd, len, time_start, GetCountSspClk(), NULL, true); } /* Sends an APDU to the tag @@ -1195,7 +1195,7 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r /** * SRx Initialise. */ -uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card) { +static uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card) { // INITIATE command: wake up the tag using the INITIATE static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b }; // SELECT command (with space for CRC) @@ -1332,7 +1332,7 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card) { // Set up ISO 14443 Type B communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" -void iso14443b_setup() { +void iso14443b_setup(void) { LEDsoff(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -1577,8 +1577,8 @@ void RAMFUNC SniffIso14443b(void) { switch_off(); } -void iso14b_set_trigger(bool enable) { - trigger = enable; +static void iso14b_set_trigger(bool enable) { + g_trigger = enable; } /* diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index 12ee316e9..62dbd6590 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -26,7 +26,7 @@ # define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) #endif -void iso14443b_setup(); +void iso14443b_setup(void); uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response); uint8_t iso14443b_select_card(iso14b_card_select_t *card); uint8_t iso14443b_select_card_srx(iso14b_card_select_t *card); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index a35ac4c57..9dbdd4f94 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -431,7 +431,7 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) { getNext = !getNext; } } - time_stop = GetCountSspClk() - time_0 ; + time_stop = GetCountSspClk(); int len = DemodAnswer(received, buf, counter); LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false); BigBuf_free(); @@ -478,7 +478,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elap } } - time_stop = GetCountSspClk() - time_0; + time_stop = GetCountSspClk(); int k = DemodAnswer(received, buf, counter); LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false); return k; @@ -522,7 +522,7 @@ void AcquireRawAdcSamplesIso15693(void) { } - LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + LogTrace(cmd, CMD_ID_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); @@ -703,7 +703,7 @@ static void BuildInventoryResponse(uint8_t *cmdout, uint8_t *uid) { // If you do not need the answer use NULL for *recv[] // return: length of received data // logging enabled -int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) { +static int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) { int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0; @@ -723,7 +723,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outda uint32_t time_start = GetCountSspClk(); TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait); - LogTrace(send, sendlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + LogTrace(send, sendlen, time_start << 4, GetCountSspClk() << 4, NULL, true); // Now wait for a response if (outdata != NULL) { @@ -741,7 +741,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outda // Decodes a message from a tag and displays its metadata and content #define DBD15STATLEN 48 -void DbdecodeIso15693Answer(int len, uint8_t *d) { +static void DbdecodeIso15693Answer(int len, uint8_t *d) { if (len > 3) { char status[DBD15STATLEN + 1] = {0}; @@ -825,7 +825,7 @@ void ReaderIso15693(uint32_t parameter) { uint8_t cmd[CMD_ID_RESP] = {0}; BuildIdentifyRequest(cmd); TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait); - LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + LogTrace(cmd, CMD_ID_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true); // Now wait for a response answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ; @@ -906,7 +906,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) { time_start = GetCountSspClk(); TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait); - LogTrace(cmd, CMD_INV_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + LogTrace(cmd, CMD_INV_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true); if (DBGLEVEL >= DBG_EXTENDED) { Dbprintf("[+] %d octets read from reader command: %x %x %x %x %x %x %x %x", ans, diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 35ac379ad..21b0c0a42 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -64,8 +64,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ //----------------------------------------------------------------------------- // I/O interface abstraction (FPGA -> ARM) //----------------------------------------------------------------------------- - -static inline uint8_t rx_byte_from_fpga() { +static uint8_t rx_byte_from_fpga(void) { for (;;) { WDT_HIT(); @@ -92,7 +91,8 @@ static inline uint8_t rx_byte_from_fpga() { // // Note: The SSC receiver is never synchronized the calculation may be performed // on a i/q pair from two subsequent correlations, but does not matter. -static inline int32_t sample_power() { +// Note: inlining this function would fail with -Os +static int32_t sample_power(void) { int32_t q = (int8_t)rx_byte_from_fpga(); q = ABS(q); int32_t i = (int8_t)rx_byte_from_fpga(); @@ -108,7 +108,9 @@ static inline int32_t sample_power() { // // Note: The demodulator would be drifting (18.9us * 5 != 100us), rx_frame // has a delay loop that aligns rx_bit calls to the TAG tx timeslots. -static inline bool rx_bit() { + +// Note: inlining this function would fail with -Os +static bool rx_bit(void) { int32_t power; for (size_t i = 0; i < 5; ++i) { @@ -127,7 +129,7 @@ static inline bool rx_bit() { // be circumvented, but the adventage over bitbang would be little. //----------------------------------------------------------------------------- -static inline void tx_bit(bool bit) { +static void tx_bit(bool bit) { // insert pause LOW(GPIO_SSC_DOUT); last_frame_end += RWD_TIME_PAUSE; @@ -206,7 +208,7 @@ static uint32_t rx_frame(uint8_t len) { return frame; } -static bool rx_ack() { +static bool rx_ack(void) { // change fpga into rx mode FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ @@ -382,7 +384,7 @@ static int16_t read_byte(uint16_t index, uint8_t cmd_sz) { // Transmit write command, wait until (3.6ms) the tag sends back an unencrypted // ACK ('1' bit) and forward the prng time based. -bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) { +static bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) { uint32_t cmd = index << 1 | LEGIC_WRITE; // prepare command uint8_t crc = calc_crc4(cmd, addr_sz + 1, byte); // calculate crc cmd |= byte << (addr_sz + 1); // append value @@ -431,7 +433,7 @@ void LegicRfInfo(void) { // read MCC and check against UID int16_t mcc = read_byte(4, card.cmdsize); - int16_t calc_mcc = CRC8Legic(card.uid, 4);; + int16_t calc_mcc = CRC8Legic(card.uid, 4); if (mcc != calc_mcc) { reply_mix(CMD_ACK, 0, 0, 0, 0, 0); goto OUT; diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index ee658f4bd..35eefc56c 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -65,7 +65,8 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ //----------------------------------------------------------------------------- // Returns true if a pulse/pause is received within timeout -static inline bool wait_for(bool value, const uint32_t timeout) { +// Note: inlining this function would fail with -Os +static bool wait_for(bool value, const uint32_t timeout) { while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { if (GetCountSspClk() > timeout) { return false; @@ -83,7 +84,7 @@ static inline bool wait_for(bool value, const uint32_t timeout) { // - A bit length >80.2us is a 1 // - A bit length <80.2us is a 0 // - A bit length >148.6us is a code violation -static inline int8_t rx_bit() { +static int8_t rx_bit(void) { // backup ts for threshold calculation uint32_t bit_start = last_frame_end; @@ -126,7 +127,8 @@ static inline int8_t rx_bit() { // Note: The Subcarrier is not disabled during bits to prevent glitches. This is // not mandatory but results in a cleaner signal. tx_frame will disable // the subcarrier when the frame is done. -static inline void tx_bit(bool bit) { +// Note: inlining this function would fail with -Os +static void tx_bit(bool bit) { LED_C_ON(); if (bit) { @@ -177,7 +179,7 @@ static void tx_frame(uint32_t frame, uint8_t len) { LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, false); } -static void tx_ack() { +static void tx_ack(void) { // wait for ack timeslot last_frame_end += TAG_ACK_WAIT; legic_prng_forward(TAG_ACK_WAIT / TAG_BIT_PERIOD - 1); @@ -298,7 +300,7 @@ static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) { return 0; } -static void init_tag() { +static void init_tag(void) { // configure FPGA FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 0a85312bc..cec945b20 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -25,13 +25,18 @@ // T0 = timer/carrier = 1500kHz/125kHz = 1500000/125000 = 6 //#define HITAG_T0 3 +////////////////////////////////////////////////////////////////////////////// +// Exported global variables +////////////////////////////////////////////////////////////////////////////// + +bool g_logging = true; + ////////////////////////////////////////////////////////////////////////////// // Global variables ////////////////////////////////////////////////////////////////////////////// -bool rising_edge = false; -bool logging = true; -bool reader_mode = false; +static bool rising_edge = false; +static bool reader_mode = false; ////////////////////////////////////////////////////////////////////////////// // Auxiliary functions @@ -46,8 +51,8 @@ bool lf_test_periods(size_t expected, size_t count) { ////////////////////////////////////////////////////////////////////////////// // Low frequency (LF) adc passthrough functionality ////////////////////////////////////////////////////////////////////////////// -uint8_t previous_adc_val = 0; -uint8_t adc_avg = 0; +static uint8_t previous_adc_val = 0; +static uint8_t adc_avg = 0; void lf_sample_mean(void) { uint8_t periods = 0; @@ -65,7 +70,7 @@ void lf_sample_mean(void) { Dbprintf("LF ADC average %u", adc_avg); } -size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { +static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { size_t periods = 0; volatile uint8_t adc_val; uint8_t avg_peak = adc_avg + 3, avg_through = adc_avg - 3; @@ -90,7 +95,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { adc_val = AT91C_BASE_SSC->SSC_RHR; periods++; - if (logging) logSampleSimple(adc_val); + if (g_logging) logSampleSimple(adc_val); // Only test field changes if state of adc values matter if (wait == false) { @@ -120,7 +125,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { if (periods >= max) return 0; } } - if (logging) logSampleSimple(0xFF); + if (g_logging) logSampleSimple(0xFF); return 0; } @@ -132,7 +137,7 @@ size_t lf_detect_gap(size_t max) { return lf_count_edge_periods_ex(max, false, true); } -void lf_reset_counter() { +void lf_reset_counter(void) { // TODO: find out the correct reset settings for tag and reader mode // if (reader_mode) { @@ -147,11 +152,11 @@ void lf_reset_counter() { // } } -bool lf_get_tag_modulation() { +bool lf_get_tag_modulation(void) { return (rising_edge == false); } -bool lf_get_reader_modulation() { +bool lf_get_reader_modulation(void) { return rising_edge; } @@ -223,12 +228,12 @@ void lf_init(bool reader, bool simulate) { uint32_t bufsize = 10000; // use malloc - if (logging) initSampleBufferEx(&bufsize, true); + if (g_logging) initSampleBufferEx(&bufsize, true); lf_sample_mean(); } -void lf_finalize() { +void lf_finalize(void) { // Disable timers AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; @@ -269,7 +274,7 @@ size_t lf_detect_field_drop(size_t max) { periods++; volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR; - if (logging) logSampleSimple(adc_val); + if (g_logging) logSampleSimple(adc_val); if (adc_val == 0) { rising_edge = false; diff --git a/armsrc/lfadc.h b/armsrc/lfadc.h index 09e5762c6..1c8a4211f 100644 --- a/armsrc/lfadc.h +++ b/armsrc/lfadc.h @@ -15,21 +15,21 @@ #include "util.h" #include "string.h" -extern bool logging; +extern bool g_logging; void lf_sample_mean(void); bool lf_test_periods(size_t expected, size_t count); size_t lf_count_edge_periods(size_t max); size_t lf_detect_gap(size_t max); -void lf_reset_counter(); +void lf_reset_counter(void); -bool lf_get_tag_modulation(); -bool lf_get_reader_modulation(); +bool lf_get_tag_modulation(void); +bool lf_get_reader_modulation(void); void lf_wait_periods(size_t periods); //void lf_init(bool reader); void lf_init(bool reader, bool simulate); -void lf_finalize(); +void lf_finalize(void); size_t lf_detect_field_drop(size_t max); bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len); void lf_modulation(bool modulation); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index c65696d1a..03c6c5164 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -198,7 +198,7 @@ void printT55xxConfig(void) { #define PRN_NA sprintf(s + strlen(s), _RED_("N/A") " | "); - DbpString(_BLUE_("LF T55XX config")); + DbpString(_CYAN_("LF T55XX config")); Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]"); Dbprintf(" mode |start|write|write|write| read|write|write"); Dbprintf(" | gap | gap | 0 | 1 | gap | 2 | 3"); @@ -261,8 +261,9 @@ void printT55xxConfig(void) { else PRN_NA; + // remove last space s[strlen(s)] = 0; - DbpString(s); + DbpStringEx(FLAG_LOG, s, sizeof(s)); } DbpString(""); } @@ -621,7 +622,7 @@ void ReadTItag(void) { StopTicks(); } -void WriteTIbyte(uint8_t b) { +static void WriteTIbyte(uint8_t b) { int i = 0; // modulate 8 bits out to the antenna @@ -1534,7 +1535,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { calccrc &= 0xff; calccrc = 0xff - calccrc; - char *crcStr = (crc == calccrc) ? "ok" : "!crc"; + const char *crcStr = (crc == calccrc) ? "ok" : "!crc"; Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]", version, facilitycode, number, code, code2, crc, crcStr); // if we're only looking for one tag @@ -1570,10 +1571,10 @@ void TurnReadLFOn(uint32_t delay) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // measure antenna strength. - //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); + //int adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14); WaitUS(delay); } -void TurnReadLF_off(uint32_t delay) { +static void TurnReadLF_off(uint32_t delay) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(delay); } @@ -1585,7 +1586,7 @@ void TurnReadLF_off(uint32_t delay) { #define T55_LLR_REF (136 * 8) // Write one bit to chip -void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { +static void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { switch (bit) { case 0 : @@ -1621,7 +1622,7 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { // num_bits - how many bits (low x bits of data) Max 32 bits at a time // max_len - how many bytes can the bit_array hold (ensure no buffer overflow) // returns "Next" bit offset / bits stored (for next store) -uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { +static uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { int8_t next_offset = start_offset; // Check if data will fit. @@ -1645,7 +1646,7 @@ uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t } // Send one downlink command to the card -void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { +static void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { /* arg bits @@ -2029,7 +2030,7 @@ void T55xx_ChkPwds(uint8_t flags) { Dbprintf("[=] Baseline determined [%u]", baseline); uint8_t *pwds = BigBuf_get_EM_addr(); - uint16_t pwdCount = 0; + uint16_t pwd_count = 0; uint32_t candidate = 0; #ifdef WITH_FLASH @@ -2040,20 +2041,27 @@ void T55xx_ChkPwds(uint8_t flags) { if (isok != sizeof(counter)) goto OUT; - pwdCount = (uint16_t)(counter[1] << 8 | counter[0]); - - if (pwdCount == 0 || pwdCount == 0xFFFF) + pwd_count = (uint16_t)(counter[1] << 8 | counter[0]); + if (pwd_count == 0) goto OUT; - isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET + 2, pwds, pwdCount * 4); - if (isok != pwdCount * 4) + // since flash can report way too many pwds, we need to limit it. + // bigbuff EM size is determined by CARD_MEMORY_SIZE + // a password is 4bytes. + uint16_t pwd_size_available = MIN(CARD_MEMORY_SIZE, pwd_count * 4); + + // adjust available pwd_count + pwd_count = pwd_size_available / 4; + + isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET + 2, pwds, pwd_size_available); + if (isok != pwd_size_available) goto OUT; - Dbprintf("[=] Password dictionary count %d ", pwdCount); + Dbprintf("[=] Password dictionary count %d ", pwd_count); #endif uint32_t pwd = 0, curr = 0, prev = 0; - for (uint16_t i = 0; i < pwdCount; ++i) { + for (uint16_t i = 0; i < pwd_count; ++i) { if (BUTTON_PRESS() && !data_available()) { goto OUT; @@ -2107,7 +2115,7 @@ void T55xxWakeUp(uint32_t pwd, uint8_t flags) { /*-------------- Cloning routines -----------*/ -void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { +static void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { t55xx_write_block_t cmd; cmd.pwd = 0; @@ -2281,10 +2289,10 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { #define FWD_CMD_READ 0x9 #define FWD_CMD_DISABLE 0x5 -uint8_t forwardLink_data[64]; //array of forwarded bits -uint8_t *forward_ptr; //ptr for forward message preparation -uint8_t fwd_bit_sz; //forwardlink bit counter -uint8_t *fwd_write_ptr; //forwardlink bit pointer +static uint8_t forwardLink_data[64]; //array of forwarded bits +static uint8_t *forward_ptr; //ptr for forward message preparation +static uint8_t fwd_bit_sz; //forwardlink bit counter +static uint8_t *fwd_write_ptr; //forwardlink bit pointer //==================================================================== // prepares command bits @@ -2299,7 +2307,7 @@ uint8_t *fwd_write_ptr; //forwardlink bit pointer // These timings work for 4469/4269/4305 (with the 55*8 above) // WRITE_0 = 23*8 , 9*8 -uint8_t Prepare_Cmd(uint8_t cmd) { +static uint8_t Prepare_Cmd(uint8_t cmd) { *forward_ptr++ = 0; //start bit *forward_ptr++ = 0; //second pause for 4050 code @@ -2319,7 +2327,7 @@ uint8_t Prepare_Cmd(uint8_t cmd) { // prepares address bits // see EM4469 spec //==================================================================== -uint8_t Prepare_Addr(uint8_t addr) { +static uint8_t Prepare_Addr(uint8_t addr) { register uint8_t line_parity; @@ -2340,7 +2348,7 @@ uint8_t Prepare_Addr(uint8_t addr) { // prepares data bits intreleaved with parity bits // see EM4469 spec //==================================================================== -uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) { +static uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) { register uint8_t column_parity; register uint8_t i, j; @@ -2376,7 +2384,7 @@ uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) { // Requires: forwarLink_data filled with valid bits (1 bit per byte) // fwd_bit_count set with number of bits to be sent //==================================================================== -void SendForward(uint8_t fwd_bit_count) { +static void SendForward(uint8_t fwd_bit_count) { // iceman, 21.3us increments for the USclock verification. // 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead @@ -2410,7 +2418,7 @@ void SendForward(uint8_t fwd_bit_count) { } } -void EM4xLogin(uint32_t pwd) { +static void EM4xLogin(uint32_t pwd) { uint8_t len; forward_ptr = forwardLink_data; len = Prepare_Cmd(FWD_CMD_LOGIN); diff --git a/armsrc/lfops.h b/armsrc/lfops.h index b697cffd1..eb31e54a6 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -15,10 +15,6 @@ #include "pm3_cmd.h" // struct -extern uint8_t decimation; -extern uint8_t bits_per_sample ; -extern bool averaging; - void AcquireRawAdcSamples125k(int divisor); void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command); void ReadTItag(void); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 2851dc08b..f74101573 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -27,12 +27,12 @@ Default LF config is set to: samples_to_skip = 0 verbose = YES */ -sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ; +static sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ; -void printConfig() { +void printConfig(void) { uint32_t d = config.divisor; - DbpString(_BLUE_("LF Sampling config")); - Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); + DbpString(_CYAN_("LF Sampling config")); + Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")" )", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); Dbprintf(" [b] bits per sample.....%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); @@ -90,7 +90,7 @@ sample_config *getSamplingConfig(void) { * @param stream * @param bit */ -void pushBit(BitstreamOut *stream, uint8_t bit) { +static void pushBit(BitstreamOut *stream, uint8_t bit) { int bytepos = stream->position >> 3; // divide by 8 int bitpos = stream->position & 7; *(stream->buffer + bytepos) &= ~(1 << (7 - bitpos)); @@ -100,34 +100,37 @@ void pushBit(BitstreamOut *stream, uint8_t bit) { } // Holds bit packed struct of samples. -BitstreamOut data = {0, 0, 0}; +static BitstreamOut data = {0, 0, 0}; // internal struct to keep track of samples gathered -sampling_t samples = {0, 0, 0, 0}; +static sampling_t samples = {0, 0, 0, 0}; void initSampleBuffer(uint32_t *sample_size) { initSampleBufferEx(sample_size, false); } void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) { - + if (sample_size == NULL) { + Dbprintf("initSampleBufferEx, param NULL"); + return; + } BigBuf_free(); + // We can't erase the buffer now, it would drastically delay the acquisition if (use_malloc) { - if (sample_size == NULL || *sample_size == 0) { + if (*sample_size == 0) { *sample_size = BigBuf_max_traceLen(); data.buffer = BigBuf_get_addr(); } else { *sample_size = MIN(*sample_size, BigBuf_max_traceLen()); data.buffer = BigBuf_malloc(*sample_size); - } } else { - if (sample_size == NULL || *sample_size == 0) { + if (*sample_size == 0) { *sample_size = BigBuf_max_traceLen(); } data.buffer = BigBuf_get_addr(); @@ -140,7 +143,7 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) { samples.total_saved = 0; } -uint32_t getSampleCounter() { +uint32_t getSampleCounter(void) { return samples.total_saved; } @@ -256,7 +259,8 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in while (!BUTTON_PRESS()) { // only every 1000th times, in order to save time when collecting samples. - if (checked == 1000) { + // interruptible only when logging not yet triggered + if ((checked == 1000) && (trigger_threshold > 0)) { if (data_available()) { checked = -1; break; @@ -342,7 +346,7 @@ uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t samp return DoAcquisition(1, 8, 0, trigger_threshold, verbose, sample_size, cancel_after, 0); } -uint32_t ReadLF(bool reader_field, bool verbose, uint32_t sample_size) { +static uint32_t ReadLF(bool reader_field, bool verbose, uint32_t sample_size) { if (verbose) printConfig(); @@ -364,7 +368,7 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size) { * Initializes the FPGA for sniffer-mode (field off), and acquires the samples. * @return number of bits sampled **/ -uint32_t SniffLF() { +uint32_t SniffLF(void) { BigBuf_Clear_ext(false); return ReadLF(false, true, 0); } @@ -522,7 +526,7 @@ void doCotagAcquisition(size_t sample_size) { computeSignalProperties(dest, bufsize); } -uint32_t doCotagAcquisitionManchester() { +uint32_t doCotagAcquisitionManchester(void) { uint8_t *dest = BigBuf_get_addr(); uint16_t bufsize = BigBuf_max_traceLen(); diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index bad90d62c..44910316d 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -40,7 +40,7 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size); * Initializes the FPGA for sniff-mode (field off), and acquires the samples. * @return number of bits sampled **/ -uint32_t SniffLF(); +uint32_t SniffLF(void); uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip); @@ -73,7 +73,7 @@ void initSampleBuffer(uint32_t *sample_size); void initSampleBufferEx(uint32_t *sample_size, bool use_malloc); void logSampleSimple(uint8_t sample); void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg); -uint32_t getSampleCounter(); +uint32_t getSampleCounter(void); /** * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream @@ -97,8 +97,8 @@ void LFSetupFPGAForADC(int divisor, bool reader_field); */ void setSamplingConfig(sample_config *sc); -sample_config *getSamplingConfig(); +sample_config *getSamplingConfig(void); -void printConfig(); +void printConfig(void); #endif // __LFSAMPLING_H diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 0266af633..9e19cbc53 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -44,7 +44,7 @@ // send an incomplete dummy response in order to trigger the card's authentication failure timeout #ifndef CHK_TIMEOUT -# define CHK_TIMEOUT() { \ +# define CHK_TIMEOUT(void) { \ ReaderTransmit(&dummy_answer, 1, NULL); \ uint32_t timeout = GetCountSspClk() + HARDNESTED_AUTHENTICATION_TIMEOUT; \ while (GetCountSspClk() < timeout) {}; \ @@ -627,7 +627,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { } // Return 1 if the nonce is invalid else return 0 -int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) { +static int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) { return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) & \ (oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) & \ (oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))) ? 1 : 0; @@ -1229,7 +1229,7 @@ typedef struct chk_t { // 2 = failed to select. // 1 = wrong key // 0 = correct key -uint8_t chkKey(struct chk_t *c) { +static uint8_t chkKey(struct chk_t *c) { uint8_t i = 0, res = 2; while (i < 5) { // this part is from Piwi's faster nonce collecting part in Hardnested. @@ -1250,7 +1250,7 @@ uint8_t chkKey(struct chk_t *c) { return res; } -uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { +static uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { if (!iso14443a_fast_select_card(c->uid, c->cl)) return 2; @@ -1275,7 +1275,7 @@ uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { return res; } -void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { +static void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { for (uint8_t s = 0; s < *sectorcnt; s++) { // skip already found A keys @@ -1293,7 +1293,7 @@ void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui } } -void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { +static void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { for (uint8_t s = 0; s < *sectorcnt; s++) { // skip already found B keys @@ -1313,7 +1313,7 @@ void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui // loop all A keys, // when A is found but not B, try to read B. -void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { +static void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { // read Block B, if A is found. for (uint8_t s = 0; s < *sectorcnt; ++s) { @@ -1387,15 +1387,21 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da keyCount = size[1] << 8 | size[0]; - if (keyCount == 0 || keyCount == 0xFFFF) + if (keyCount == 0) goto OUT; - datain = BigBuf_malloc(keyCount * 6); + // limit size of availlable for keys in bigbuff + // a key is 6bytes + uint16_t key_mem_available = MIN(BigBuf_get_size(), keyCount * 6); + + keyCount = key_mem_available / 6; + + datain = BigBuf_malloc(key_mem_available); if (datain == NULL) goto OUT; - isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET + 2, datain, keyCount * 6); - if (isok != keyCount * 6) + isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET + 2, datain, key_mem_available); + if (isok != key_mem_available) goto OUT; } @@ -1702,14 +1708,16 @@ void MifareChkKeys(uint8_t *datain) { bool found; } PACKED keyresult; keyresult.found = false; - uint8_t blockNo, keyType; - uint16_t keyCount; - bool clearTrace, have_uid = false; + bool have_uid = false; + + uint8_t keyType = datain[0]; + uint8_t blockNo = datain[1]; + bool clearTrace = datain[2]; + uint16_t key_count = (datain[3] << 8) | datain[4]; + + uint16_t key_mem_available = MIN((PM3_CMD_DATA_SIZE - 5), key_count * 6); + key_count = key_mem_available / 6; - keyType = datain[0]; - blockNo = datain[1]; - clearTrace = datain[2]; - keyCount = (datain[3] << 8) | datain[4]; datain += 5; LEDsoff(); @@ -1725,7 +1733,7 @@ void MifareChkKeys(uint8_t *datain) { set_tracing(false); - for (i = 0; i < keyCount; i++) { + for (i = 0; i < key_count; i++) { // Iceman: use piwi's faster nonce collecting part in hardnested. if (!have_uid) { // need a full select cycle to get the uid first @@ -1840,7 +1848,7 @@ void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key) { int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL); if (len != 1 || receivedAnswer[0] != CARD_ACK) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - break;; + break; } if (mifare_classic_halt(pcs, cuid)) { @@ -1932,7 +1940,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { clear_trace(); set_tracing(true); - int retval; + int retval = PM3_SUCCESS; if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { retval = PM3_ESOFT; @@ -1944,8 +1952,9 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { uint64_t ui64Key = emlGetKey(sectorNo, keytype); if (sectorNo == 0) { if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) { + retval = PM3_ESOFT; if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo); - break; + goto out; } } else { if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) { @@ -1971,10 +1980,8 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { } } - if (mifare_classic_halt(pcs, cuid)) { - if (DBGLEVEL > DBG_ERROR) - Dbprintf("Halt error"); - } + int res = mifare_classic_halt(pcs, cuid); + (void)res; if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished"); @@ -2000,9 +2007,9 @@ out: // bit 6 - wipe tag. //----------------------------------------------------------------------------- // magic uid card generation 1 commands -uint8_t wupC1[] = { MIFARE_MAGICWUPC1 }; -uint8_t wupC2[] = { MIFARE_MAGICWUPC2 }; -uint8_t wipeC[] = { MIFARE_MAGICWIPEC }; +static uint8_t wupC1[] = { MIFARE_MAGICWUPC1 }; +static uint8_t wupC2[] = { MIFARE_MAGICWUPC2 }; +static uint8_t wipeC[] = { MIFARE_MAGICWIPEC }; void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { @@ -2190,7 +2197,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { OnSuccessMagic(); } -void MifareCIdent() { +void MifareCIdent(void) { // variables uint8_t isGen = 0; uint8_t rec[1] = {0x00}; @@ -2248,7 +2255,7 @@ OUT: BigBuf_free(); } -void MifareHasStaticNonce() { +void MifareHasStaticNonce(void) { // variables int retval = PM3_SUCCESS, len; @@ -2297,7 +2304,7 @@ OUT: crypto1_deinit(pcs); } -void OnSuccessMagic() { +void OnSuccessMagic(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index a4bf2b30b..2d9a4799a 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -41,18 +41,17 @@ int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype); void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); -void MifareCIdent(); // is "magic chinese" card? -void MifareHasStaticNonce(); // Has the tag a static nonce? +void MifareCIdent(void); // is "magic chinese" card? +void MifareHasStaticNonce(void); // Has the tag a static nonce? void MifareSetMod(uint8_t *datain); void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key); void MifareUSetPwd(uint8_t arg0, uint8_t *datain); -void OnSuccessMagic(); +void OnSuccessMagic(void); void OnErrorMagic(uint8_t reason); int32_t dist_nt(uint32_t nt1, uint32_t nt2); -void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); //void RAMFUNC SniffMifare(uint8_t param); void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain); diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index ff5babda0..d578d026b 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -25,7 +25,7 @@ #define RECEIVE_SIZE 64 // the block number for the ISO14443-4 PCB -uint8_t pcb_blocknum = 0; +static uint8_t pcb_blocknum = 0; // Deselect card by sending a s-block. the crc is precalced for speed static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4}; @@ -33,10 +33,10 @@ static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4}; /* PCB CID CMD PAYLOAD */ //static uint8_t __res[MAX_FRAME_SIZE]; -struct desfire_key skey = {0}; +static struct desfire_key skey = {0}; static desfirekey_t sessionkey = &skey; -bool InitDesfireCard() { +bool InitDesfireCard(void) { pcb_blocknum = 0; @@ -107,7 +107,7 @@ void MifareSendCommand(uint8_t *datain) { LED_B_OFF(); } -void MifareDesfireGetInformation() { +void MifareDesfireGetInformation(void) { LEDsoff(); @@ -683,7 +683,7 @@ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout) { // crc_update(&desfire_crc32, byte, 8); // uint32_t crc = crc_finish(&desfire_crc32); -void OnSuccess() { +void OnSuccess(void) { pcb_blocknum = 0; ReaderTransmit(deselect_cmd, 3, NULL); if (mifare_ultra_halt()) { diff --git a/armsrc/mifaredesfire.h b/armsrc/mifaredesfire.h index 1e19ec49f..b34e436f1 100644 --- a/armsrc/mifaredesfire.h +++ b/armsrc/mifaredesfire.h @@ -13,14 +13,14 @@ #include "common.h" -bool InitDesfireCard(); +bool InitDesfireCard(void); void MifareSendCommand(uint8_t *datain); -void MifareDesfireGetInformation(); +void MifareDesfireGetInformation(void); void MifareDES_Auth1(uint8_t *datain); void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain); int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout); -void OnSuccess(); +void OnSuccess(void); void OnError(uint8_t reason); void OnErrorNG(uint16_t cmd, uint8_t reason); diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index ecc0ee505..60f9a7810 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -539,9 +539,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 if (cardSTATE == MFEMUL_NOFIELD) { #if defined RDV4 - vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15; #else - vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; #endif if (vHf > MF_MINFIELDV) { diff --git a/armsrc/mifaresniff_disabled.c b/armsrc/mifaresniff_disabled.c index 6ccdc8e6c..76d25d228 100644 --- a/armsrc/mifaresniff_disabled.c +++ b/armsrc/mifaresniff_disabled.c @@ -308,7 +308,7 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, ui } */ -void RAMFUNC MfSniffSend() { +void RAMFUNC MfSniffSend(void) { uint16_t tracelen = BigBuf_get_traceLen(); int packlen = tracelen; // total number of bytes to send uint8_t *data = BigBuf_get_addr(); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 893db4763..71c57a963 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -355,7 +355,7 @@ int mifare_ultra_auth(uint8_t *keybytes) { return 1; } -int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) { +static int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) { uint16_t len = 0; uint8_t bt[2] = {0x00, 0x00}; uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; @@ -509,7 +509,7 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { return mifare_classic_halt_ex(pcs); } -int mifare_ultra_halt() { +int mifare_ultra_halt(void) { uint16_t len = 0; uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 64eb04545..b1d6396d5 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -75,7 +75,7 @@ int mifare_ultra_auth(uint8_t *keybytes); int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData); //int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData); -int mifare_ultra_halt(); +int mifare_ultra_halt(void); // desfire int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); diff --git a/armsrc/nprintf.c b/armsrc/nprintf.c index 645454b4e..1ce3842d3 100644 --- a/armsrc/nprintf.c +++ b/armsrc/nprintf.c @@ -127,7 +127,7 @@ typedef struct { // internal buffer output -static inline void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) { +static void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) { if (idx < maxlen) { ((char *)buffer)[idx] = character; } @@ -135,7 +135,7 @@ static inline void _out_buffer(char character, void *buffer, size_t idx, size_t // internal null output -static inline void _out_null(char character, void *buffer, size_t idx, size_t maxlen) { +static void _out_null(char character, void *buffer, size_t idx, size_t maxlen) { (void)character; (void)buffer; (void)idx; @@ -144,7 +144,7 @@ static inline void _out_null(char character, void *buffer, size_t idx, size_t ma // internal _putchar wrapper -static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { +static void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { (void)buffer; (void)idx; (void)maxlen; @@ -155,7 +155,7 @@ static inline void _out_char(char character, void *buffer, size_t idx, size_t ma // internal output function wrapper -static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) { +static void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) { (void)idx; (void)maxlen; if (character) { @@ -167,7 +167,7 @@ static inline void _out_fct(char character, void *buffer, size_t idx, size_t max // internal secure strlen // \return The length of the string (excluding the terminating 0) limited by 'maxsize' -static inline unsigned int _strnlen_s(const char *str, size_t maxsize) { +static unsigned int _strnlen_s(const char *str, size_t maxsize) { const char *s; for (s = str; *s && maxsize--; ++s); return (unsigned int)(s - str); @@ -176,7 +176,7 @@ static inline unsigned int _strnlen_s(const char *str, size_t maxsize) { // internal test if char is a digit (0-9) // \return true if char is a digit -static inline bool _is_digit(char ch) { +static bool _is_digit(char ch) { return (ch >= '0') && (ch <= '9'); } diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 21a739f45..6ad44d7c4 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -173,7 +173,7 @@ bool IsBlock1PCF7931(uint8_t *block) { return false; } -void ReadPCF7931() { +void ReadPCF7931(void) { int found_blocks = 0; // successfully read blocks int max_blocks = 8; // readable blocks uint8_t memory_blocks[8][17]; // PCF content diff --git a/armsrc/pcf7931.h b/armsrc/pcf7931.h index 67a11f5f8..b9ad40a92 100644 --- a/armsrc/pcf7931.h +++ b/armsrc/pcf7931.h @@ -6,7 +6,7 @@ size_t DemodPCF7931(uint8_t **outBlocks); bool IsBlock0PCF7931(uint8_t *block); bool IsBlock1PCF7931(uint8_t *block); -void ReadPCF7931(); +void ReadPCF7931(void); void SendCmdPCF7931(uint32_t *tab); bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p); bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p); diff --git a/armsrc/printf.c b/armsrc/printf.c index 0dffbb037..2d18a9c53 100644 --- a/armsrc/printf.c +++ b/armsrc/printf.c @@ -47,7 +47,7 @@ typedef int ssize_t; #define NBBY 8 /* number of bits in a byte */ -char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #define hex2ascii(hex) (hex2ascii_data[hex]) #define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z'))) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 3db0e3c27..025146b55 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -108,7 +108,7 @@ static enum spiffs_mount_status { RDV40_SPIFFS_UNKNOWN } RDV40_SPIFFS_MOUNT_STATUS; -int rdv40_spiffs_mounted() { +static int rdv40_spiffs_mounted(void) { int ret = 0; switch (RDV40_SPIFFS_MOUNT_STATUS) { @@ -124,7 +124,7 @@ int rdv40_spiffs_mounted() { return ret; } -int rdv40_spiffs_mount() { +int rdv40_spiffs_mount(void) { if (rdv40_spiffs_mounted()) { Dbprintf("ERR: SPIFFS already mounted !"); return SPIFFS_ERR_MOUNTED; @@ -146,7 +146,7 @@ int rdv40_spiffs_mount() { return ret; } -int rdv40_spiffs_unmount() { +int rdv40_spiffs_unmount(void) { if (!rdv40_spiffs_mounted()) { Dbprintf("ERR: SPIFFS not mounted !"); return SPIFFS_ERR_NOT_MOUNTED; @@ -162,7 +162,7 @@ int rdv40_spiffs_unmount() { return ret; } -int rdv40_spiffs_check() { +int rdv40_spiffs_check(void) { rdv40_spiffs_lazy_mount(); SPIFFS_check(&fs); SPIFFS_gc_quick(&fs, 0); @@ -195,17 +195,17 @@ void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size) { SPIFFS_close(&fs, fd); } -void rename_in_spiffs(const char *old_filename, const char *new_filename) { +static void rename_in_spiffs(const char *old_filename, const char *new_filename) { if (SPIFFS_rename(&fs, old_filename, new_filename) < 0) Dbprintf("errno %i\n", SPIFFS_errno(&fs)); } -void remove_from_spiffs(const char *filename) { +static void remove_from_spiffs(const char *filename) { if (SPIFFS_remove(&fs, filename) < 0) Dbprintf("errno %i\n", SPIFFS_errno(&fs)); } -spiffs_stat stat_in_spiffs(const char *filename) { +static spiffs_stat stat_in_spiffs(const char *filename) { spiffs_stat s; if (SPIFFS_stat(&fs, filename, &s) < 0) Dbprintf("errno %i\n", SPIFFS_errno(&fs)); @@ -217,7 +217,7 @@ uint32_t size_in_spiffs(const char *filename) { return s.size; } -rdv40_spiffs_fsinfo info_of_spiffs() { +static rdv40_spiffs_fsinfo info_of_spiffs(void) { rdv40_spiffs_fsinfo fsinfo; fsinfo.blockSize = SPIFFS_CFG_LOG_BLOCK_SZ; fsinfo.pageSize = LOG_PAGE_SIZE; @@ -238,7 +238,7 @@ int exists_in_spiffs(const char *filename) { return rc == SPIFFS_OK; } -RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { +static RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { RDV40SpiFFSFileType filetype = RDV40_SPIFFS_FILETYPE_UNKNOWN; char symlinked[SPIFFS_OBJ_NAME_LEN]; sprintf(symlinked, "%s.lnk", filename); @@ -270,16 +270,16 @@ RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { } return filetype; } - -int is_valid_filename(const char *filename) { +/* +static int is_valid_filename(const char *filename) { if (filename == NULL) { return false; } uint32_t len = strlen(filename); return len > 0 && len < SPIFFS_OBJ_NAME_LEN; } - -void copy_in_spiffs(const char *src, const char *dst) { +*/ +static void copy_in_spiffs(const char *src, const char *dst) { uint32_t size = size_in_spiffs((char *)src); uint8_t *mem = BigBuf_malloc(size); read_from_spiffs((char *)src, (uint8_t *)mem, size); @@ -297,7 +297,7 @@ void copy_in_spiffs(const char *src, const char *dst) { // 1 if the mount status actually changed // so you know what to do IN CASE you wished to set things "back to previous // state" -int rdv40_spiffs_lazy_mount() { +int rdv40_spiffs_lazy_mount(void) { int changed = 0; if (!rdv40_spiffs_mounted()) { changed = rdv40_spiffs_mount(); @@ -309,7 +309,7 @@ int rdv40_spiffs_lazy_mount() { } // unmount if not already -int rdv40_spiffs_lazy_unmount() { +int rdv40_spiffs_lazy_unmount(void) { int changed = 0; if (rdv40_spiffs_mounted()) { changed = rdv40_spiffs_unmount(); @@ -362,7 +362,7 @@ void my_lazy_spiffs_act(){ // this lazy_mount since needed and can also report back the change on state implied by eventual mount, if needed rdv40_spiffs_lazy_read((const char *)".SHOULDRESET",(uint8_t *)resetret,4); if( resetret == "YESS" ) { uint8_t -changed = rdv40_spiffs_lazy_format(); // this will imply change only if we where +changed = rdv40_spiffs_lazy_format(void); // this will imply change only if we where already mounted beforehand, was the case after our reading without further rollback rdv40_spiffs_lazy_mount_rollback(changed); // so if we were mounted just get back to this state. If not, just don't. @@ -400,20 +400,20 @@ int rdv40_spiffs_lazy_mount_rollback(int changed) { // statement or some function taking function parameters // TODO : forbid writing to a filename which already exists as lnk ! // TODO : forbid writing to a filename.lnk which already exists without lnk ! -int rdv40_spiffs_write(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { +int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( write_to_spiffs(filename, src, size); ) } -int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { +int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( append_to_spiffs(filename, src, size); ) } // todo integrate reading symlinks transparently -int rdv40_spiffs_read(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { +int rdv40_spiffs_read(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( read_from_spiffs(filename, dst, size); ) @@ -444,7 +444,7 @@ int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel leve ) } -int rdv40_spiffs_getfsinfo(rdv40_spiffs_fsinfo *fsinfo, RDV40SpiFFSSafetyLevel level) { +static int rdv40_spiffs_getfsinfo(rdv40_spiffs_fsinfo *fsinfo, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // *fsinfo = info_of_spiffs(); // ) @@ -536,13 +536,13 @@ int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, R //////////////////////////////////////////////////////////////////////////////// ///////// MISC HIGH LEVEL FUNCTIONS //////////////////////////////////////////// -#define SPIFFS_BANNER DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); +#define SPIFFS_BANNER DbpString(_CYAN_("Flash Memory FileSystem tree (SPIFFS)")); -void rdv40_spiffs_safe_print_fsinfo() { +void rdv40_spiffs_safe_print_fsinfo(void) { rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); - DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); + DbpString(_CYAN_("Flash Memory FileSystem Info (SPIFFS)")); Dbprintf(" Logical Block Size........." _YELLOW_("%d")" bytes", fsinfo.blockSize); @@ -570,7 +570,7 @@ void rdv40_spiffs_safe_print_fsinfo() { void rdv40_spiffs_safe_print_tree(uint8_t banner) { if (banner) { - DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); + DbpString(_CYAN_("Flash Memory FileSystem tree (SPIFFS)")); Dbprintf("-------------------------------------"); } @@ -603,7 +603,7 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner) { // Selftest function -void test_spiffs() { +void test_spiffs(void) { Dbprintf("----------------------------------------------"); Dbprintf("Testing SPIFFS operations"); Dbprintf("----------------------------------------------"); diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index f10c86db0..5a9e58a94 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -33,27 +33,27 @@ typedef struct rdv40_spiffs_fsinfo { int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); -int rdv40_spiffs_check(); -int rdv40_spiffs_lazy_unmount(); -int rdv40_spiffs_lazy_mount(); +int rdv40_spiffs_check(void); +int rdv40_spiffs_lazy_unmount(void); +int rdv40_spiffs_lazy_mount(void); int rdv40_spiffs_lazy_mount_rollback(int changed); -int rdv40_spiffs_write(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); -int rdv40_spiffs_read(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_read(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_rename(char *old_filename, char *new_filename, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_remove(char *filename, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); void write_to_spiffs(const char *filename, uint8_t *src, uint32_t size); void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size); -void test_spiffs(); +void test_spiffs(void); void rdv40_spiffs_safe_print_tree(uint8_t banner); -int rdv40_spiffs_unmount(); -int rdv40_spiffs_mount(); +int rdv40_spiffs_unmount(void); +int rdv40_spiffs_mount(void); int rdv40_spiffs_is_symlink(const char *s); -void rdv40_spiffs_safe_print_fsinfo(); +void rdv40_spiffs_safe_print_fsinfo(void); int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyLevel level); void append_to_spiffs(const char *filename, uint8_t *src, uint32_t size); int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level); -int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); +int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level); uint32_t size_in_spiffs(const char *filename); int exists_in_spiffs(const char *filename); diff --git a/armsrc/spiffs_config.h b/armsrc/spiffs_config.h index 7710a65a8..0cf3b96f5 100644 --- a/armsrc/spiffs_config.h +++ b/armsrc/spiffs_config.h @@ -18,8 +18,6 @@ #include "string.h" #include "flashmem.h" -void Dbprintf(const char *fmt, ...); - //#include //#include // ----------- >8 ------------ diff --git a/armsrc/spiffs_hydrogen.c b/armsrc/spiffs_hydrogen.c index 7290e676a..a166c3b7a 100644 --- a/armsrc/spiffs_hydrogen.c +++ b/armsrc/spiffs_hydrogen.c @@ -39,13 +39,12 @@ s32_t SPIFFS_format(spiffs *fs) { return -1; } - s32_t res; SPIFFS_LOCK(fs); spiffs_block_ix bix = 0; while (bix < fs->block_count) { fs->max_erase_count = 0; - res = spiffs_erase_block(fs, bix); + s32_t res = spiffs_erase_block(fs, bix); if (res != SPIFFS_OK) { res = SPIFFS_ERR_ERASE_FAIL; } @@ -1121,11 +1120,11 @@ s32_t SPIFFS_check(spiffs *fs) { SPIFFS_LOCK(fs); res = spiffs_lookup_consistency_check(fs, 0); - + (void)res; res = spiffs_object_index_consistency_check(fs); - + (void)res; res = spiffs_page_consistency_check(fs); - + (void)res; res = spiffs_obj_lu_scan(fs); SPIFFS_UNLOCK(fs); diff --git a/armsrc/start.c b/armsrc/start.c index 3e6f34702..e2904f6e1 100644 --- a/armsrc/start.c +++ b/armsrc/start.c @@ -14,69 +14,40 @@ #include "proxmark3_arm.h" #include "appmain.h" -#include "zlib.h" +#include "lz4.h" #include "BigBuf.h" +#include "string.h" static uint8_t *next_free_memory; extern struct common_area common_area; extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__; -static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) { - uint8_t *allocated_memory; - - allocated_memory = next_free_memory; - next_free_memory += items * size; - return allocated_memory; -} - -static void inflate_free(voidpf opaque, voidpf address) { - // nothing to do -} - static void uncompress_data_section(void) { - z_stream data_section; - next_free_memory = BigBuf_get_addr(); + int avail_in; + memcpy(&avail_in, &__data_start__, sizeof(int)); + int avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct. + // uncompress data segment to RAM + uintptr_t p = (uintptr_t)&__data_src_start__; + int res = LZ4_decompress_safe((char *)p + 4, &__data_start__, avail_in, avail_out); - // initialize zstream structure - data_section.next_in = (uint8_t *) &__data_src_start__; - data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter. - data_section.next_out = (uint8_t *) &__data_start__; - data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct. - data_section.zalloc = &inflate_malloc; - data_section.zfree = &inflate_free; - data_section.opaque = NULL; - - // initialize zlib for inflate - int res = inflateInit2(&data_section, 15); if (res < 0) return; - - // uncompress data segment to RAM - inflate(&data_section, Z_FINISH); - // save the size of the compressed data section - common_area.arg1 = data_section.total_in; + common_area.arg1 = res; } -void __attribute__((section(".startos"))) Vector(void) { +void __attribute__((section(".startos"))) Vector(void); +void Vector(void) { /* Stack should have been set up by the bootloader */ - // char *src; - char *dst, *end; uncompress_data_section(); /* Set up (that is: clear) BSS. */ - dst = &__bss_start__; - end = &__bss_end__; + char *dst = &__bss_start__; + char *end = &__bss_end__; while (dst < end) *dst++ = 0; - // Set up data segment: Copy from flash to ram - // src = &__data_src_start__; - // dst = &__data_start__; - // end = &__data_end__; - // while(dst < end) *dst++ = *src++; - AppMain(); } #endif diff --git a/armsrc/string.c b/armsrc/string.c index 8dbe26808..a3b49dcb1 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -20,6 +20,21 @@ void *memcpy(void *dest, const void *src, int len) { return dest; } +void *memmove(void *dest, const void *src, size_t len) { + char *d = dest; + const char *s = src; + if (d < s) + while (len--) + *d++ = *s++; + else { + char *lasts = (char *)s + (len - 1); + char *lastd = d + (len - 1); + while (len--) + *lastd-- = *lasts--; + } + return dest; +} + void *memset(void *dest, int c, int len) { uint8_t *d = dest; while ((len--) > 0) { diff --git a/armsrc/string.h b/armsrc/string.h index 0ebb4ab54..f4d6e3fc1 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -16,6 +16,7 @@ int strlen(const char *str); void *memcpy(void *dest, const void *src, int len); +void *memmove(void *dest, const void *src, size_t len); void *memset(void *dest, int c, int len); int memcmp(const void *av, const void *bv, int len); void memxor(uint8_t *dest, uint8_t *src, size_t len); @@ -33,6 +34,8 @@ char *strrchr(const char *s, int c); size_t strcspn(const char *s1, const char *s2); char *strpbrk(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); +unsigned long strtoul(const char *p, char **out_p, int base); +long strtol(const char *p, char **out_p, int base); char c_tolower(int c); char c_isprint(unsigned char c); diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index e4b2e9b23..a77a70744 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -49,9 +49,9 @@ void ReadThinFilm(void) { #define SEC_D 0xf0 #define SEC_E 0x0f #define SEC_F 0x00 -uint16_t FpgaSendQueueDelay; +static uint16_t FpgaSendQueueDelay; -uint16_t ReadReaderField(void) { +static uint16_t ReadReaderField(void) { #if defined RDV4 return AvgAdc(ADC_CHAN_HF_RDV40); #else @@ -71,7 +71,7 @@ static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) { ToSendMax++; } -int EmSendCmdThinfilmRaw(uint8_t *resp, uint16_t respLen) { +static int EmSendCmdThinfilmRaw(uint8_t *resp, uint16_t respLen) { volatile uint8_t b; uint16_t i = 0; uint32_t ThisTransferTime; diff --git a/armsrc/ticks.h b/armsrc/ticks.h index b39ec52bd..9d8d178d5 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -30,10 +30,10 @@ uint32_t RAMFUNC GetCountUS(void); void ResetUSClock(void); void SpinDelayCountUs(uint32_t us); -void StartCountSspClk(); +void StartCountSspClk(void); void ResetSspClk(void); -uint32_t RAMFUNC GetCountSspClk(); -uint32_t RAMFUNC GetCountSspClkDelta(); +uint32_t RAMFUNC GetCountSspClk(void); +uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start); void StartTicks(void); uint32_t GetTicks(void); diff --git a/armsrc/usart.c b/armsrc/usart.c index 2062c9441..203572f90 100644 --- a/armsrc/usart.c +++ b/armsrc/usart.c @@ -15,8 +15,8 @@ volatile AT91PS_USART pUS1 = AT91C_BASE_US1; volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1; -uint32_t usart_baudrate = 0; -uint8_t usart_parity = 0; +uint32_t g_usart_baudrate = 0; +uint8_t g_usart_parity = 0; /* void usart_close(void) { // Reset the USART mode @@ -41,8 +41,8 @@ void usart_close(void) { static uint8_t us_inbuf1[USART_BUFFLEN]; static uint8_t us_inbuf2[USART_BUFFLEN]; -uint8_t *usart_cur_inbuf = NULL; -uint16_t usart_cur_inbuf_off = 0; +static uint8_t *usart_cur_inbuf = NULL; +static uint16_t usart_cur_inbuf_off = 0; static uint8_t us_rxfifo[USART_FIFOLEN]; static size_t us_rxfifo_low = 0; static size_t us_rxfifo_high = 0; @@ -166,9 +166,9 @@ inline int usart_writebuffer_sync(uint8_t *data, size_t len) { void usart_init(uint32_t baudrate, uint8_t parity) { if (baudrate != 0) - usart_baudrate = baudrate; + g_usart_baudrate = baudrate; if ((parity == 'N') || (parity == 'O') || (parity == 'E')) - usart_parity = parity; + g_usart_parity = parity; // For a nice detailed sample, interrupt driven but still relevant. // See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf @@ -197,7 +197,7 @@ void usart_init(uint32_t baudrate, uint8_t parity) { AT91C_US_NBSTOP_1_BIT | // 1 stop bit AT91C_US_CHMODE_NORMAL; // channel mode: normal - switch (usart_parity) { + switch (g_usart_parity) { case 'N': mode |= AT91C_US_PAR_NONE; // parity: none break; @@ -227,9 +227,9 @@ void usart_init(uint32_t baudrate, uint8_t parity) { // OVER = 1, -yes we are oversampling // baudrate == selected clock/8/CD --> this is ours // - uint32_t brgr = MCK / (usart_baudrate << 3); - // doing fp = round((mck / (usart_baudrate << 3) - brgr) * 8) with integers: - uint32_t fp = ((16 * MCK / (usart_baudrate << 3) - 16 * brgr) + 1) / 2; + uint32_t brgr = MCK / (g_usart_baudrate << 3); + // doing fp = round((mck / (g_usart_baudrate << 3) - brgr) * 8) with integers: + uint32_t fp = ((16 * MCK / (g_usart_baudrate << 3) - 16 * brgr) + 1) / 2; pUS1->US_BRGR = (fp << 16) | brgr; diff --git a/armsrc/usart.h b/armsrc/usart.h index 01ca0d809..5a7dea38f 100644 --- a/armsrc/usart.h +++ b/armsrc/usart.h @@ -9,8 +9,8 @@ // Higher baudrates are pointless, only increasing overflow risk -extern uint32_t usart_baudrate; -extern uint8_t usart_parity; +extern uint32_t g_usart_baudrate; +extern uint8_t g_usart_parity; void usart_init(uint32_t baudrate, uint8_t parity); int usart_writebuffer_sync(uint8_t *data, size_t len); diff --git a/armsrc/util.c b/armsrc/util.c index d1a4fb938..443c9e5f4 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -83,7 +83,7 @@ uint8_t hex2int(char hexchar) { } } -void LEDsoff() { +void LEDsoff(void) { LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); @@ -289,40 +289,6 @@ int BUTTON_HELD(int ms) { return BUTTON_ERROR; } -/* Similar to FpgaGatherVersion this formats stored version information - * into a string representation. It takes a pointer to the struct version_information, - * verifies the magic properties, then stores a formatted string, prefixed by - * prefix in dst. - */ -void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) { - struct version_information *v = (struct version_information *)version_information; - dst[0] = 0; - strncat(dst, prefix, len - 1); - if (v->magic != VERSION_INFORMATION_MAGIC) { - strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1); - return; - } - if (v->versionversion != 1) { - strncat(dst, "Version information not understood\n", len - strlen(dst) - 1); - return; - } - if (!v->present) { - strncat(dst, "Version information not available\n", len - strlen(dst) - 1); - return; - } - - strncat(dst, v->gitversion, len - strlen(dst) - 1); - if (v->clean == 0) { - strncat(dst, "-unclean", len - strlen(dst) - 1); - } else if (v->clean == 2) { - strncat(dst, "-suspect", len - strlen(dst) - 1); - } - - strncat(dst, " ", len - strlen(dst) - 1); - strncat(dst, v->buildtime, len - strlen(dst) - 1); - strncat(dst, "\n", len - strlen(dst) - 1); -} - bool data_available(void) { #ifdef WITH_FPC_USART_HOST return usb_poll_validate_length() || (usart_rxdata_available() > 0); diff --git a/armsrc/util.h b/armsrc/util.h index 40a7c3026..c6523a813 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -55,15 +55,15 @@ #endif #ifndef REV16 -#define REV16(x) (REV8(x) + (REV8 (x >> 8) << 8)) +#define REV16(x) (REV8(x) + (REV8 ((x) >> 8) << 8)) #endif #ifndef REV32 -#define REV32(x) (REV16(x) + (REV16(x >> 16) << 16)) +#define REV32(x) (REV16(x) + (REV16((x) >> 16) << 16)) #endif #ifndef REV64 -#define REV64(x) (REV32(x) + (REV32(x >> 32) << 32)) +#define REV64(x) (REV32(x) + (REV32((x) >> 32) << 32)) #endif #ifndef BIT32 @@ -91,7 +91,6 @@ void SpinUp(uint32_t speed); int BUTTON_CLICKED(int ms); int BUTTON_HELD(int ms); -void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information); bool data_available(void); #endif diff --git a/bootrom/Makefile b/bootrom/Makefile index 5c7823896..75a4e5ced 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -23,7 +23,7 @@ VERSIONSRC = version.c # THUMBSRC := # stdint.h provided locally until GCC 4.5 becomes C99 compliant -APP_CFLAGS = -I. -fno-strict-aliasing -ffunction-sections -fdata-sections +APP_CFLAGS = -I. -ffunction-sections -fdata-sections # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc APP_CFLAGS += -fno-stack-protector -fno-pie @@ -39,9 +39,12 @@ OBJS = $(OBJDIR)/bootrom.s19 # version.c should be remade on every compilation version.c: default_version.c $(info [=] GEN $@) - $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ -all: $(OBJS) +all: showinfo $(OBJS) + +showinfo: + $(info compiler version: $(shell $(CC) --version|head -n 1)) tarbin: $(OBJS) $(info [=] GEN $@) @@ -49,7 +52,7 @@ tarbin: $(OBJS) $(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ) $(info [=] LD $@) - $(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) + $(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) clean: $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o @@ -68,7 +71,7 @@ uninstall: $(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...) $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) -.PHONY: all clean help install +.PHONY: all clean help install showinfo help: @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index aa633f448..77305f22c 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -10,6 +10,7 @@ #include "usb_cdc.h" #include "proxmark3_arm.h" +#define DEBUG 0 struct common_area common_area __attribute__((section(".commonarea"))); unsigned int start_addr, end_addr, bootrom_unlocked; @@ -37,21 +38,19 @@ static int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, } } - int result = PM3_EUNDEF; // Send frame and make sure all bytes are transmitted - - result = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); - - return result; + return usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); } -void DbpString(char *str) { +#if DEBUG +static void DbpString(char *str) { uint8_t len = 0; while (str[len] != 0x00) len++; reply_old(CMD_DEBUG_PRINT_STRING, len, 0, 0, (uint8_t *)str, len); } +#endif static void ConfigClocks(void) { // we are using a 16 MHz crystal as the basis for everything @@ -76,8 +75,8 @@ static void Fatal(void) { for (;;) {}; } -void UsbPacketReceived(uint8_t *packet, int len) { - int i, dont_ack = 0; +static void UsbPacketReceived(uint8_t *packet) { + int dont_ack = 0; PacketCommandOLD *c = (PacketCommandOLD *)packet; //if ( len != sizeof(PacketCommandOLD`)) Fatal(); @@ -125,7 +124,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { // We need to offset the writes or it will not fill the correct bank write buffer. offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t); } - for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { + for (int i = 0 + (64 * j); i < 64 + (64 * j); i++) { _flash_start[offset + i] = c->d.asDwords[i]; } @@ -217,7 +216,7 @@ static void flash_mode(void) { // Check if there is a usb packet available if (usb_poll_validate_length()) { if (usb_read(rx, sizeof(rx))) { - UsbPacketReceived(rx, sizeof(rx)); + UsbPacketReceived(rx); } } @@ -235,6 +234,7 @@ static void flash_mode(void) { } } +void BootROM(void); void BootROM(void) { //------------ // First set up all the I/O pins; GPIOs configured directly, other ones @@ -312,7 +312,7 @@ void BootROM(void) { if (!common_area_present) { /* Common area not ok, initialize it */ - int i; + size_t i; /* Makeshift memset, no need to drag util.c into this */ for (i = 0; i < sizeof(common_area); i++) ((char *)&common_area)[i] = 0; diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0bbf1067c..8db8ebf9c 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -7,209 +7,314 @@ cmake_minimum_required(VERSION 3.10) project(proxmark3) +SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..) if(CMAKE_VERSION VERSION_LESS "3.7.0") set(CMAKE_INCLUDE_CURRENT_DIR ON) endif() -if(APPLE AND EXISTS /usr/local/opt/qt5) - # Homebrew installs Qt5 (up to at least 5.11.0) in - # /usr/local/qt5. Ensure that it can be found by CMake - # since it is not in the default /usr/local prefix. - # Add it to PATHS so that it doesn't override the - # CMAKE_PREFIX_PATH environment variable. - # QT_FIND_PACKAGE_OPTIONS should be passed to find_package, - # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) - list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) -endif() -set(QT_PACKAGELIST - Qt5Core - Qt5Widgets - Qt5Gui -) -set(Qt5_FOUND ON) -foreach(_qt_package IN LISTS QT_PACKAGELIST) - find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS}) - if(NOT ${_qt_package}_FOUND) - set(Qt5_FOUND OFF) - endif(NOT ${_qt_package}_FOUND) -endforeach() +if (NOT SKIPQT EQUAL 1) + if(APPLE AND EXISTS /usr/local/opt/qt5) + # Homebrew installs Qt5 (up to at least 5.11.0) in + # /usr/local/qt5. Ensure that it can be found by CMake + # since it is not in the default /usr/local prefix. + # Add it to PATHS so that it doesn't override the + # CMAKE_PREFIX_PATH environment variable. + # QT_FIND_PACKAGE_OPTIONS should be passed to find_package, + # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) + list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) + endif(APPLE AND EXISTS /usr/local/opt/qt5) + set(QT_PACKAGELIST + Qt5Core + Qt5Widgets + Qt5Gui + ) + set(Qt5_FOUND ON) + foreach(_qt_package IN LISTS QT_PACKAGELIST) + find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS}) + set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES}) + if(NOT ${_qt_package}_FOUND) + set(Qt5_FOUND OFF) + endif(NOT ${_qt_package}_FOUND) + endforeach() +endif (NOT SKIPQT EQUAL 1) -SET (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +find_package(PkgConfig) +if (NOT SKIPBT EQUAL 1) + pkg_search_module(BLUEZ QUIET bluez) +endif (NOT SKIPBT EQUAL 1) -add_subdirectory(deps) +if (NOT SKIPPYTHON EQUAL 1) + pkg_search_module(PYTHON3 QUIET python3) + pkg_search_module(PYTHON3EMBED QUIET python3-embed) +endif (NOT SKIPPYTHON EQUAL 1) + +if (NOT SKIPREADLINE EQUAL 1) + if (APPLE) + find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH) + endif (APPLE) + find_path(READLINE_INCLUDE_DIRS readline/readline.h) + + if (APPLE) + find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH) + endif (APPLE) + find_library(READLINE_LIBRARIES readline) + if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) + set(READLINE_FOUND ON) + endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) +endif (NOT SKIPREADLINE EQUAL 1) + +add_subdirectory(${PM3_ROOT}/client/deps deps) set (TARGET_SOURCES - src/proxmark3.c - ../common/commonutil.c - ../common/util_posix.c - ../common/parity.c - ../common/bucketsort.c - ../common/crapto1/crapto1.c - ../common/crapto1/crypto1.c - ../common/crc.c - ../common/crc16.c - ../common/crc32.c - ../common/crc64.c - ../common/lfdemod.c - ../common/legic_prng.c - ../common/iso15693tools.c - ../common/cardhelper.c - ../common/generator.c - src/crypto/asn1dump.c - src/crypto/asn1utils.c - src/crypto/libpcrypto.c - src/emv/test/cda_test.c - src/emv/test/crypto_test.c - src/emv/test/cryptotest.c - src/emv/test/dda_test.c - src/emv/test/sda_test.c - src/emv/apduinfo.c - src/emv/cmdemv.c - src/emv/crypto.c - src/emv/crypto_polarssl.c - src/emv/dol.c - src/emv/dump.c - src/emv/emv_pk.c - src/emv/emv_pki.c - src/emv/emv_pki_priv.c - src/emv/emv_roca.c - src/emv/emv_tags.c - src/emv/emvcore.c - src/emv/emvjson.c - src/emv/tlv.c - src/fido/additional_ca.c - src/fido/cbortools.c - src/fido/cose.c - src/fido/fidocore.c - src/loclass/cipher.c - src/loclass/cipherutils.c - src/loclass/elite_crack.c - src/loclass/hash1_brute.c - src/loclass/ikeys.c - src/mifare/mad.c - src/mifare/mfkey.c - src/mifare/mifare4.c - src/mifare/mifaredefault.c - src/mifare/mifarehost.c - src/mifare/ndef.c - src/mifare/desfire_crypto.c - src/uart/uart_posix.c - src/uart/uart_win32.c - src/ui/overlays.ui - src/aidsearch.c - src/cmdanalyse.c - src/cmdcrc.c - src/cmddata.c - src/cmdflashmem.c - src/cmdflashmemspiffs.c - src/cmdhf.c - src/cmdhf14a.c - src/cmdhf14b.c - src/cmdhf15.c - src/cmdhfcryptorf.c - src/cmdhfepa.c - src/cmdhffelica.c - src/cmdhffido.c - src/cmdhficlass.c - src/cmdhflegic.c - src/cmdhflist.c - src/cmdhflto.c - src/cmdhfmf.c - src/cmdhfmfdes.c - src/cmdhfmfhard.c - src/cmdhfmfp.c - src/cmdhfmfu.c - src/cmdhfthinfilm.c - src/cmdhftopaz.c - src/cmdhw.c - src/cmdlf.c - src/cmdlfawid.c - src/cmdlfcotag.c - src/cmdlfem4x.c - src/cmdlffdx.c - src/cmdlfgallagher.c - src/cmdlfguard.c - src/cmdlfhid.c - src/cmdlfhitag.c - src/cmdlfindala.c - src/cmdlfio.c - src/cmdlfjablotron.c - src/cmdlfkeri.c - src/cmdlfmotorola.c - src/cmdlfnedap.c - src/cmdlfnexwatch.c - src/cmdlfnoralsy.c - src/cmdlfpac.c - src/cmdlfparadox.c - src/cmdlfpcf7931.c - src/cmdlfpresco.c - src/cmdlfpyramid.c - src/cmdlfsecurakey.c - src/cmdlft55xx.c - src/cmdlfti.c - src/cmdlfverichip.c - src/cmdlfviking.c - src/cmdlfvisa2000.c - src/cmdmain.c - src/cmdparser.c - src/cmdscript.c - src/cmdsmartcard.c - src/cmdtrace.c - src/cmdusart.c - src/cmdwiegand.c - src/comms.c - src/fileutils.c - src/flash.c - src/graph.c - src/preferences.c - src/pm3_binlib.c - src/pm3_bitlib.c - src/prng.c - src/scandir.c - src/scripting.c - src/tea.c - src/ui.c - src/util.c - src/whereami.c - src/wiegand_formats.c - src/wiegand_formatutils.c + ${PM3_ROOT}/common/commonutil.c + ${PM3_ROOT}/common/util_posix.c + ${PM3_ROOT}/common/parity.c + ${PM3_ROOT}/common/bucketsort.c + ${PM3_ROOT}/common/crapto1/crapto1.c + ${PM3_ROOT}/common/crapto1/crypto1.c + ${PM3_ROOT}/common/crc.c + ${PM3_ROOT}/common/crc16.c + ${PM3_ROOT}/common/crc32.c + ${PM3_ROOT}/common/crc64.c + ${PM3_ROOT}/common/lfdemod.c + ${PM3_ROOT}/common/legic_prng.c + ${PM3_ROOT}/common/iso15693tools.c + ${PM3_ROOT}/common/cardhelper.c + ${PM3_ROOT}/common/generator.c + ${PM3_ROOT}/client/src/crypto/asn1dump.c + ${PM3_ROOT}/client/src/crypto/asn1utils.c + ${PM3_ROOT}/client/src/crypto/libpcrypto.c + ${PM3_ROOT}/client/src/emv/test/cda_test.c + ${PM3_ROOT}/client/src/emv/test/crypto_test.c + ${PM3_ROOT}/client/src/emv/test/cryptotest.c + ${PM3_ROOT}/client/src/emv/test/dda_test.c + ${PM3_ROOT}/client/src/emv/test/sda_test.c + ${PM3_ROOT}/client/src/emv/apduinfo.c + ${PM3_ROOT}/client/src/emv/cmdemv.c + ${PM3_ROOT}/client/src/emv/crypto.c + ${PM3_ROOT}/client/src/emv/crypto_polarssl.c + ${PM3_ROOT}/client/src/emv/dol.c + ${PM3_ROOT}/client/src/emv/dump.c + ${PM3_ROOT}/client/src/emv/emv_pk.c + ${PM3_ROOT}/client/src/emv/emv_pki.c + ${PM3_ROOT}/client/src/emv/emv_pki_priv.c + ${PM3_ROOT}/client/src/emv/emv_roca.c + ${PM3_ROOT}/client/src/emv/emv_tags.c + ${PM3_ROOT}/client/src/emv/emvcore.c + ${PM3_ROOT}/client/src/emv/emvjson.c + ${PM3_ROOT}/client/src/emv/tlv.c + ${PM3_ROOT}/client/src/fido/additional_ca.c + ${PM3_ROOT}/client/src/fido/cbortools.c + ${PM3_ROOT}/client/src/fido/cose.c + ${PM3_ROOT}/client/src/fido/fidocore.c + ${PM3_ROOT}/client/src/loclass/cipher.c + ${PM3_ROOT}/client/src/loclass/cipherutils.c + ${PM3_ROOT}/client/src/loclass/elite_crack.c + ${PM3_ROOT}/client/src/loclass/hash1_brute.c + ${PM3_ROOT}/client/src/loclass/ikeys.c + ${PM3_ROOT}/client/src/mifare/mad.c + ${PM3_ROOT}/client/src/mifare/mfkey.c + ${PM3_ROOT}/client/src/mifare/mifare4.c + ${PM3_ROOT}/client/src/mifare/mifaredefault.c + ${PM3_ROOT}/client/src/mifare/mifarehost.c + ${PM3_ROOT}/client/src/mifare/ndef.c + ${PM3_ROOT}/client/src/mifare/desfire_crypto.c + ${PM3_ROOT}/client/src/uart/uart_posix.c + ${PM3_ROOT}/client/src/uart/uart_win32.c + ${PM3_ROOT}/client/src/ui/overlays.ui + ${PM3_ROOT}/client/src/aidsearch.c + ${PM3_ROOT}/client/src/cmdanalyse.c + ${PM3_ROOT}/client/src/cmdcrc.c + ${PM3_ROOT}/client/src/cmddata.c + ${PM3_ROOT}/client/src/cmdflashmem.c + ${PM3_ROOT}/client/src/cmdflashmemspiffs.c + ${PM3_ROOT}/client/src/cmdhf.c + ${PM3_ROOT}/client/src/cmdhf14a.c + ${PM3_ROOT}/client/src/cmdhf14b.c + ${PM3_ROOT}/client/src/cmdhf15.c + ${PM3_ROOT}/client/src/cmdhfcryptorf.c + ${PM3_ROOT}/client/src/cmdhfepa.c + ${PM3_ROOT}/client/src/cmdhffelica.c + ${PM3_ROOT}/client/src/cmdhffido.c + ${PM3_ROOT}/client/src/cmdhficlass.c + ${PM3_ROOT}/client/src/cmdhflegic.c + ${PM3_ROOT}/client/src/cmdhflist.c + ${PM3_ROOT}/client/src/cmdhflto.c + ${PM3_ROOT}/client/src/cmdhfmf.c + ${PM3_ROOT}/client/src/cmdhfmfdes.c + ${PM3_ROOT}/client/src/cmdhfmfhard.c + ${PM3_ROOT}/client/src/cmdhfmfp.c + ${PM3_ROOT}/client/src/cmdhfmfu.c + ${PM3_ROOT}/client/src/cmdhfthinfilm.c + ${PM3_ROOT}/client/src/cmdhftopaz.c + ${PM3_ROOT}/client/src/cmdhw.c + ${PM3_ROOT}/client/src/cmdlf.c + ${PM3_ROOT}/client/src/cmdlfawid.c + ${PM3_ROOT}/client/src/cmdlfcotag.c + ${PM3_ROOT}/client/src/cmdlfem4x.c + ${PM3_ROOT}/client/src/cmdlffdx.c + ${PM3_ROOT}/client/src/cmdlfgallagher.c + ${PM3_ROOT}/client/src/cmdlfguard.c + ${PM3_ROOT}/client/src/cmdlfhid.c + ${PM3_ROOT}/client/src/cmdlfhitag.c + ${PM3_ROOT}/client/src/cmdlfindala.c + ${PM3_ROOT}/client/src/cmdlfio.c + ${PM3_ROOT}/client/src/cmdlfjablotron.c + ${PM3_ROOT}/client/src/cmdlfkeri.c + ${PM3_ROOT}/client/src/cmdlfmotorola.c + ${PM3_ROOT}/client/src/cmdlfnedap.c + ${PM3_ROOT}/client/src/cmdlfnexwatch.c + ${PM3_ROOT}/client/src/cmdlfnoralsy.c + ${PM3_ROOT}/client/src/cmdlfpac.c + ${PM3_ROOT}/client/src/cmdlfparadox.c + ${PM3_ROOT}/client/src/cmdlfpcf7931.c + ${PM3_ROOT}/client/src/cmdlfpresco.c + ${PM3_ROOT}/client/src/cmdlfpyramid.c + ${PM3_ROOT}/client/src/cmdlfsecurakey.c + ${PM3_ROOT}/client/src/cmdlft55xx.c + ${PM3_ROOT}/client/src/cmdlfti.c + ${PM3_ROOT}/client/src/cmdlfverichip.c + ${PM3_ROOT}/client/src/cmdlfviking.c + ${PM3_ROOT}/client/src/cmdlfvisa2000.c + ${PM3_ROOT}/client/src/cmdmain.c + ${PM3_ROOT}/client/src/cmdparser.c + ${PM3_ROOT}/client/src/cmdscript.c + ${PM3_ROOT}/client/src/cmdsmartcard.c + ${PM3_ROOT}/client/src/cmdtrace.c + ${PM3_ROOT}/client/src/cmdusart.c + ${PM3_ROOT}/client/src/cmdwiegand.c + ${PM3_ROOT}/client/src/comms.c + ${PM3_ROOT}/client/src/fileutils.c + ${PM3_ROOT}/client/src/flash.c + ${PM3_ROOT}/client/src/graph.c + ${PM3_ROOT}/client/src/jansson_path.c + ${PM3_ROOT}/client/src/preferences.c + ${PM3_ROOT}/client/src/pm3_binlib.c + ${PM3_ROOT}/client/src/pm3_bitlib.c + ${PM3_ROOT}/client/src/prng.c + ${PM3_ROOT}/client/src/scandir.c + ${PM3_ROOT}/client/src/scripting.c + ${PM3_ROOT}/client/src/tea.c + ${PM3_ROOT}/client/src/ui.c + ${PM3_ROOT}/client/src/util.c + ${PM3_ROOT}/client/src/wiegand_formats.c + ${PM3_ROOT}/client/src/wiegand_formatutils.c + ${CMAKE_BINARY_DIR}/version.c ) +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/version.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c + DEPENDS ${PM3_ROOT}/common/default_version.c +) + set(ADDITIONAL_SRC "") set(ADDITIONAL_LNK "") - +set(ADDITIONAL_DIRS "") +set(ADDITIONAL_LNKDIRS "") set(X86_CPUS x86 x86_64 i686) message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") if (APPLE) message("Apple device detected.") - set(ADDITIONAL_SRC src/util_darwin.h src/util_darwin.m ${ADDITIONAL_SRC}) + set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") endif (APPLE) -if (Qt5_FOUND) - message("Qt5 library found, building gui :)") +if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) set (TARGET_SOURCES - src/proxgui.cpp - src/proxguiqt.cpp + ${PM3_ROOT}/client/src/proxgui.cpp + ${PM3_ROOT}/client/src/proxguiqt.cpp ${TARGET_SOURCES}) add_definitions("-DHAVE_GUI") - set(ADDITIONAL_LNK Qt5::Core Qt5::Widgets Qt5::Gui ${ADDITIONAL_LNK}) -else (Qt5_FOUND) - message("Qt5 library not found, not building gui") + set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK}) +else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) set(TARGET_SOURCES - src/guidummy.cpp + ${PM3_ROOT}/client/src/guidummy.cpp ${TARGET_SOURCES}) -endif (Qt5_FOUND) +endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) -add_executable( - proxmark3 +if (NOT SKIPBT EQUAL 1) + if (BLUEZ_FOUND) + add_definitions("-DHAVE_BLUEZ") + set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK}) + endif (BLUEZ_FOUND) +endif(NOT SKIPBT EQUAL 1) + +if (NOT SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND) + add_definitions(-DHAVE_PYTHON) + set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK}) + set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) + elseif (PYTHON3_FOUND) + add_definitions(-DHAVE_PYTHON) + set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK}) + set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) + endif (PYTHON3EMBED_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) + +if (NOT SKIPREADLINE EQUAL 1) + if (READLINE_FOUND) + add_definitions("-DHAVE_READLINE") + set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) + set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK}) + endif (READLINE_FOUND) +endif(NOT SKIPREADLINE EQUAL 1) + +message("===================================================================") +if (SKIPQT EQUAL 1) + message("GUI support: skipped") +else (SKIPQT EQUAL 1) + if (Qt5_FOUND) + message("GUI support: QT5 found, enabled") + else (Qt5_FOUND) + message("GUI support: QT5 not found, disabled") + endif (Qt5_FOUND) +endif (SKIPQT EQUAL 1) + +if (SKIPBT EQUAL 1) + message("native BT support: skipped") +else (SKIPBT EQUAL 1) + if (BLUEZ_FOUND) + message("native BT support: Bluez found, enabled") + else (BLUEZ_FOUND) + message("native BT support: Bluez not found, disabled") + endif (BLUEZ_FOUND) +endif(SKIPBT EQUAL 1) + +if (SKIPPYTHON EQUAL 1) + message("Python3 library: skipped") +else (SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND) + message("Python3 library: Python3 embed found, enabled") + elseif (PYTHON_FOUND) + message("Python3 library: Python3 found, enabled") + else (PYTHON3EMBED_FOUND) + message("Python3 library: Python3 not found, disabled") + endif (PYTHON3EMBED_FOUND) +endif(SKIPPYTHON EQUAL 1) + +if (SKIPREADLINE EQUAL 1) + message("Readline library: skipped") +else (SKIPREADLINE EQUAL 1) + if (READLINE_FOUND) + message("Readline library: enabled") + else (READLINE_FOUND) + message("Readline library: Readline not found, disabled") + endif (READLINE_FOUND) +endif(SKIPREADLINE EQUAL 1) +message("===================================================================") + +add_executable(proxmark3 + ${PM3_ROOT}/client/src/proxmark3.c ${TARGET_SOURCES} ${ADDITIONAL_SRC} ) @@ -228,34 +333,60 @@ if (MINGW) endif (MINGW) target_include_directories(proxmark3 PRIVATE - ../common - ../common_fpga - ../include - src + ${PM3_ROOT}/common + ${PM3_ROOT}/common_fpga + ${PM3_ROOT}/include + ${PM3_ROOT}/client/src + ${PM3_ROOT}/client/include + ${ADDITIONAL_DIRS} ) -if (APPLE) - set_target_properties(proxmark3 PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks, -L/usr/local/opt/readline/lib") - set_target_properties(proxmark3 PROPERTIES COMPILE_FLAGS "-I/usr/local/opt/readline/include") -else (APPLE) +if (NOT APPLE) # required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line. set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) -endif (APPLE) +endif (NOT APPLE) -find_library(cliparser REQUIRED) -find_library(jansson REQUIRED) -find_library(tinycbor REQUIRED) -find_library(lua REQUIRED) -find_library(mbedtls REQUIRED) -find_library(reveng REQUIRED) -find_library(z REQUIRED) -find_library(hardnested REQUIRED) +find_library(pm3rrg_rdv4_cliparser REQUIRED) +find_library(pm3rrg_rdv4_jansson REQUIRED) +find_library(pm3rrg_rdv4_tinycbor REQUIRED) +find_library(pm3rrg_rdv4_lua REQUIRED) +find_library(pm3rrg_rdv4_mbedtls REQUIRED) +find_library(pm3rrg_rdv4_reveng REQUIRED) +find_library(pm3rrg_rdv4_hardnested REQUIRED) +find_library(pm3rrg_rdv4_whereami REQUIRED) -target_link_libraries(proxmark3 PRIVATE readline pthread m mbedtls cliparser jansson lua tinycbor amiibo reveng z hardnested ${ADDITIONAL_LNK}) +target_link_libraries(proxmark3 PRIVATE + bz2 + m + pm3rrg_rdv4_mbedtls + pm3rrg_rdv4_cliparser + pm3rrg_rdv4_jansson + pm3rrg_rdv4_lua + pm3rrg_rdv4_tinycbor + pm3rrg_rdv4_amiibo + pm3rrg_rdv4_reveng + pm3rrg_rdv4_hardnested + pm3rrg_rdv4_whereami + ${ADDITIONAL_LNK}) + +if (NOT SKIPPTHREAD EQUAL 1) + target_link_libraries(proxmark3 PRIVATE pthread) +endif (NOT SKIPPTHREAD EQUAL 1) + +if (NOT SKIPPYTHON EQUAL 1) + # OSX have a hard time compiling python3 dependency with older cmake. + if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) + if (NOT CMAKE_VERSION VERSION_LESS 3.13) + target_link_directories(proxmark3 PRIVATE ${ADDITIONAL_LNKDIRS}) + elseif (APPLE) + message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" ) + endif (NOT CMAKE_VERSION VERSION_LESS 3.13) + endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) install(TARGETS proxmark3 DESTINATION "bin") -install(DIRECTORY cmdscripts lualibs luascripts resources dictionaries DESTINATION "share/proxmark3") +install(DIRECTORY cmdscripts lualibs luascripts pyscripts resources dictionaries DESTINATION "share/proxmark3") add_custom_command(OUTPUT lualibs/pm3_cmd.lua COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua" diff --git a/client/Makefile b/client/Makefile index d3461a302..3bd059318 100644 --- a/client/Makefile +++ b/client/Makefile @@ -4,26 +4,163 @@ # the license. #----------------------------------------------------------------------------- -# reveng will compile without macros, but these may be useful: -# Add -DBMPMACRO to use bitmap size constant macros (edit config.h) -# Add -DNOFORCE to disable the -F switch -# Add -DPRESETS to compile with preset models (edit config.h) - # Must be called before any Makefile include ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) include ../Makefile.defs INSTALLBIN = proxmark3 -INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries +INSTALLSHARE = cmdscripts lualibs luascripts pyscripts resources dictionaries VPATH = ../common src vpath %.dic dictionaries OBJDIR = obj -LDLIBS ?= -L/usr/local/lib -LDLIBS += -lreadline -lpthread -lm +ifeq ($(platform),Darwin) + # cf brew info qt: qt not symlinked anymore + PKG_CONFIG_ENV := PKG_CONFIG_PATH=/usr/local/opt/qt/lib/pkgconfig +endif +################### +# local libraries # +################### + +## Amiibo +AMIIBOLIBPATH = ./deps/amiitool +AMIIBOLIBINC = -I$(AMIIBOLIBPATH) +AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a + +## Cliparser / Argtable3 +CLIPARSERLIBPATH = ./deps/cliparser +CLIPARSERLIBINC = -I$(CLIPARSERLIBPATH) +CLIPARSERLIB = $(CLIPARSERLIBPATH)/libcliparser.a + +## Hardnested +HARDNESTEDLIBPATH = ./deps/hardnested +HARDNESTEDLIBINC = -I$(HARDNESTEDLIBPATH) +HARDNESTEDLIB = $(HARDNESTEDLIBPATH)/libhardnested.a + +## Jansson +JANSSONLIBPATH = ./deps/jansson +JANSSONLIBINC = -I$(JANSSONLIBPATH) +JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a + +## Lua +LUALIBPATH = ./deps/liblua +LUALIBINC = -I$(LUALIBPATH) +LUALIB = $(LUALIBPATH)/liblua.a +LUAPLATFORM = generic +ifneq (,$(findstring MINGW,$(platform))) + LUAPLATFORM = mingw +else + ifeq ($(platform),Darwin) + LUAPLATFORM = macosx + else + LUALIB += -ldl + LUAPLATFORM = linux + endif +endif + +## Reveng +REVENGLIBPATH = ./deps/reveng +REVENGLIBINC = -I$(REVENGLIBPATH) +REVENGLIB = $(REVENGLIBPATH)/libreveng.a + +## Tinycbor +TINYCBORLIBPATH = ./deps/tinycbor +TINYCBORLIBINC = -I$(TINYCBORLIBPATH) +TINYCBORLIB = $(TINYCBORLIBPATH)/tinycbor.a + +## Whereami +WHEREAMILIBPATH = ./deps/whereami +WHEREAMILIBINC = -I$(WHEREAMILIBPATH) +WHEREAMILIB = $(WHEREAMILIBPATH)/libwhereami.a + +########################## +# common local libraries # +########################## + +## mbed TLS +MBEDTLSLIBPATH = ../common/mbedtls +MBEDTLSLIBINC = -I$(MBEDTLSLIBPATH) +MBEDTLSLIB = $(OBJDIR)/libmbedtls.a + +######################################################## +# optional system libraries to replace local libraries # +######################################################## + +## Amiibo +# not distributed as system library +LDLIBS += $(AMIIBOLIB) +INCLUDES += $(AMIIBOLIBINC) + +## Cliparser / Argtable3 +# not distributed as system library +LDLIBS += $(CLIPARSERLIB) +INCLUDES += $(CLIPARSERLIBINC) + +## Hardnested +# not distributed as system library +LDLIBS += $(HARDNESTEDLIB) +INCLUDES += $(HARDNESTEDLIBINC) + +## Jansson +ifneq ($(SKIPJANSSONSYSTEM),1) + JANSSONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags jansson 2>/dev/null) + JANSSONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs jansson 2>/dev/null) + ifneq ($(JANSSONLDLIBS),) + JANSSONLIB = $(JANSSONLDLIBS) + JANSSONLIBINC = $(JANSSONINCLUDES) + JANSSON_FOUND = 1 + endif +endif +LDLIBS += $(JANSSONLIB) +INCLUDES += $(JANSSONLIBINC) + +## Lua +ifneq ($(SKIPLUASYSTEM),1) + LUAINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags lua5.2 2>/dev/null) + LUALDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs lua5.2 2>/dev/null) + ifneq ($(LUALDLIBS),) + LUALIB = $(LUALDLIBS) + LUALIBINC = $(LUAINCLUDES) + LUA_FOUND = 1 + endif +endif +LDLIBS += $(LUALIB) +INCLUDES += $(LUALIBINC) + +## mbed TLS +# system library cannot be used because it is compiled by default without CMAC support +LDLIBS +=$(MBEDTLSLIB) +INCLUDES += $(MBEDTLSLIBINC) + +## Reveng +# not distributed as system library +LDLIBS += $(REVENGLIB) +INCLUDES += $(REVENGLIBINC) + +## Tinycbor +# not distributed as system library +LDLIBS += $(TINYCBORLIB) +INCLUDES += $(TINYCBORLIBINC) + +## Whereami +ifneq ($(SKIPWHEREAMISYSTEM),1) + ifneq (,$(wildcard /usr/include/whereami.h)) + WHEREAMILIB = -lwhereami + WHEREAMILIBINC = + WHEREAMI_FOUND = 1 + endif +endif +LDLIBS += $(WHEREAMILIB) +INCLUDES += $(WHEREAMILIBINC) + +#################### +# system libraries # +#################### + +## Atomic # RPi Zero gcc requires -latomic # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld # doesn't recognize option --as-needed @@ -31,35 +168,111 @@ ifneq ($(platform),Darwin) LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed endif -# local libraries -LUALIBPATH = ./deps/liblua -LUALIB = $(LUALIBPATH)/liblua.a -JANSSONLIBPATH = ./deps/jansson -JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a -CBORLIBPATH = ./deps/tinycbor -CBORLIB = $(CBORLIBPATH)/tinycbor.a -REVENGPATH = ./deps/reveng -REVENGLIB = $(REVENGPATH)/libreveng.a -AMIIBOLIBPATH = ./deps/amiitool -AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a -HARDNESTEDPATH = ./deps/hardnested -HARDNESTEDLIB = $(HARDNESTEDPATH)/libhardnested.a -CLIPARSERPATH = ./deps/cliparser -CLIPARSERLIB = $(CLIPARSERPATH)/libcliparser.a +## BZIP2 +LDLIBS += -lbz2 -# common libraries -MBEDTLSLIBPATH = ../common/mbedtls -MBEDTLSLIB = $(OBJDIR)/libmbedtls.a -ZLIBPATH = ../common/zlib -ZLIB = $(OBJDIR)/libz.a +## Bluez (optional) +ifneq ($(SKIPBT),1) + BTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags bluez 2>/dev/null) + BTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs bluez 2>/dev/null) + ifneq ($(BTLDLIBS),) + BTLIB = $(BTLDLIBS) + BTLIBINC = $(BTINCLUDES) + BT_FOUND = 1 + endif +endif +LDLIBS += $(BTLIB) +INCLUDES += $(BTLIBINC) -LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH) -I$(HARDNESTEDPATH) -I$(CLIPARSERPATH) -INCLUDES_CLIENT = -I./src -I../include -I../common -I../common_fpga $(LIBS) -CFLAGS ?= -Wall -Werror -O3 +## Math +LDLIBS += -lm + +## Pthread +# Some have no pthread, e.g. termux +ifneq ($(SKIPPTHREAD),1) + LDLIBS += -lpthread +endif + +## Python3 (optional) +ifneq ($(SKIPPYTHON),1) + PYTHONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags python3 2>/dev/null) + PYTHONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs python3 2>/dev/null) + ifneq ($(PYTHONLDLIBS),) + PYTHONLIB = $(PYTHONLDLIBS) + PYTHONLIBINC = $(PYTHONINCLUDES) + PYTHON_FOUND = 1 + else + # since python3.8, applications willing to embed python must use -embed: + PYTHONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags python3-embed 2>/dev/null) + PYTHONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs python3-embed 2>/dev/null) + ifneq ($(PYTHONLDLIBS),) + PYTHONLIB = $(PYTHONLDLIBS) + PYTHONLIBINC = $(PYTHONINCLUDES) + PYTHON_FOUND = 1 + endif + endif +endif +LDLIBS += $(PYTHONLIB) +INCLUDES += $(PYTHONLIBINC) + +## QT5 (or QT4 fallback) (optional) +ifneq ($(SKIPQT),1) + # Check for correctly configured Qt5 + QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null) + QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null) + MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/moc + UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/uic + ifneq ($(QTLDLIBS),) + QT5_FOUND = 1 + else + # if Qt5 not found check for correctly configured Qt4 + QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags QtCore QtGui 2>/dev/null) + QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs QtCore QtGui 2>/dev/null) + MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=moc_location QtCore) + UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=uic_location QtCore) + endif + ifeq ($(QTLDLIBS),) + # if both pkg-config commands failed, search in common places + ifneq ($(QTDIR),) + ifneq ($(wildcard $(QTDIR)/include/QtWidgets),) + # QT5 + QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui -I$(QTDIR)/include/QtWidgets + QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets + QT5_FOUND = 1 + else + # QT4 + QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui + QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4 + endif + MOC = $(QTDIR)/bin/moc + UIC = $(QTDIR)/bin/uic + endif + endif + ifneq ($(QTLDLIBS),) + QT_FOUND = 1 + endif +endif +LDLIBS += $(QTLDLIBS) +CXXINCLUDES += $(QTINCLUDES) + +## Readline +ifneq ($(SKIPREADLINE),1) + ifeq ($(platform),Darwin) + LDLIBS += -L/usr/local/opt/readline/lib + INCLUDES += -I/usr/local/opt/readline/include + endif + LDLIBS += -lreadline + READLINE_FOUND = 1 +endif + +####################################################################################################### +CFLAGS ?= $(DEFCFLAGS) # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: -PM3CFLAGS = $(CFLAGS) $(INCLUDES_CLIENT) +PM3CFLAGS = $(CFLAGS) +PM3CFLAGS += -I./src -I../include -I../common -I../common_fpga $(INCLUDES) # WIP Testing -#PM3CFLAGS = $(CFLAGS) -std=c11 -pedantic $(INCLUDES_CLIENT) +#PM3CFLAGS += -std=c11 -pedantic + PREFIX ?= /usr/local ifneq (,$(findstring MINGW,$(platform))) # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) @@ -69,227 +282,303 @@ ifneq (,$(findstring MINGW,$(platform))) PM3CFLAGS += -D_ISOC99_SOURCE PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850 endif + +ifeq ($(READLINE_FOUND),1) + PM3CFLAGS += -DHAVE_READLINE +endif + +ifeq ($(BT_FOUND),1) + PM3CFLAGS += -DHAVE_BLUEZ +endif + +ifeq ($(PYTHON_FOUND),1) + PM3CFLAGS += -DHAVE_PYTHON +endif + + CXXFLAGS ?= -Wall -Werror -O3 -PM3CXXFLAGS = $(CXXFLAGS) -I../include +PM3CXXFLAGS = $(CXXFLAGS) +PM3CXXFLAGS += -I../include -LUAPLATFORM = generic -ifneq (,$(findstring MINGW,$(platform))) - LUAPLATFORM = mingw -else - ifeq ($(platform),Darwin) - LUAPLATFORM = macosx - OBJCSRCS = util_darwin.m - LDFLAGS += -framework Foundation -framework AppKit - LDLIBS := -L/usr/local/opt/readline/lib $(LDLIBS) - LIBS := -I/usr/local/opt/readline/include $(LIBS) - # cf brew info qt: qt not symlinked anymore - PKG_CONFIG_ENV := PKG_CONFIG_ENV=/usr/local/opt/qt/lib/pkgconfig -else - LUALIB += -ldl - LUAPLATFORM = linux -endif -endif - -ifneq ($(SKIPQT),1) - # Check for correctly configured Qt5 - QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null) - QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null) - MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/moc - UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/uic - ifeq ($(QTINCLUDES), ) - # if Qt5 not found check for correctly configured Qt4 - QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags QtCore QtGui 2>/dev/null) - QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs QtCore QtGui 2>/dev/null) - MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=moc_location QtCore) - UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=uic_location QtCore) - else +ifeq ($(QT_FOUND),1) + PM3CFLAGS += -DHAVE_GUI + PM3CXXFLAGS += -DQT_NO_DEBUG + ifeq ($(QT5_FOUND),1) # On OSX Qt5 is claiming for a C++11 compiler (gnu++14 works too, but if nothing it fails) PM3CXXFLAGS += -fPIC -std=c++11 endif - ifeq ($(QTINCLUDES), ) - # if both pkg-config commands failed, search in common places - ifneq ($(QTDIR), ) - QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui - QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4 - ifneq ($(wildcard $(QTDIR)/include/QtWidgets),) - QTINCLUDES += -I$(QTDIR)/include/QtWidgets - QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core - PM3CXXFLAGS += -fPIC -std=c++11 - endif - MOC = $(QTDIR)/bin/moc - UIC = $(QTDIR)/bin/uic +endif + +PM3LDFLAGS = $(LDFLAGS) +ifeq ($(platform),Darwin) + PM3LDFLAGS += -framework Foundation -framework AppKit +endif + +################### +# printing status # +################### + +$(info ===================================================================) +$(info Client platform: $(platform)) + +ifeq ($(SKIPQT),1) + $(info GUI support: skipped) +else + ifeq ($(QT_FOUND),1) + ifeq ($(QT5_FOUND),1) + $(info GUI support: QT5 found, enabled) + else + $(info GUI support: QT4 found, enabled) endif + else + $(info GUI support: QT not found, disabled) endif endif -ifneq ($(QTLDLIBS),) - QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp - QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o - PM3CFLAGS += -DHAVE_GUI - PM3CXXFLAGS += -DQT_NO_DEBUG +ifeq ($(SKIPBT),1) + $(info native BT support: skipped) else - QTGUISRCS = guidummy.cpp - QTGUIOBJS = $(OBJDIR)/guidummy.o + ifeq ($(BT_FOUND),1) + $(info native BT support: Bluez found, enabled) + else + $(info native BT support: Bluez not found, disabled) + endif endif +ifeq ($(SKIPJANSSONSYSTEM),1) + $(info Jansson library: local library forced) +else ifeq ($(JANSSON_FOUND),1) + $(info Jansson library: system library found) +else + $(info Jansson library: system library not found, using local library) +endif + +ifeq ($(SKIPLUASYSTEM),1) + $(info Lua library: local library forced) +else + ifeq ($(LUA_FOUND),1) + $(info Lua library: system library found) + else + $(info Lua library: system library not found, using local library) + endif +endif + +ifeq ($(SKIPPYTHON),1) + $(info Python3 library: skipped) +else + ifeq ($(PYTHON_FOUND),1) + $(info Python3 library: Python3 v$(shell pkg-config --modversion python3) found, enabled) + else + $(info Python3 library: Python3 not found, disabled) + endif +endif + +ifeq ($(SKIPREADLINE),1) + $(info Readline library: skipped) +else + ifeq ($(READLINE_FOUND),1) + $(info Readline library: enabled) + else + $(info Readline library: Readline not found, disabled) + endif +endif + +ifeq ($(SKIPWHEREAMISYSTEM),1) + $(info Whereami library: local library forced) +else + ifeq ($(WHEREAMI_FOUND),1) + $(info Whereami library: system library found) + else + $(info Whereami library: system library not found, using local library) + endif +endif + +$(info compiler version: $(shell $(CC) --version|head -n 1)) +$(info ===================================================================) + +################ +# dependencies # +################ + # Flags to generate temporary dependency files DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td # make temporary to final dependency files after successful compilation POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ -CORESRCS = uart/uart_posix.c \ - uart/uart_win32.c \ - ui.c \ - commonutil.c \ - util.c \ - util_posix.c \ - scandir.c \ - crc16.c \ - crc32.c \ - comms.c +################ +# enumerations # +################ -CMDSRCS = crapto1/crapto1.c \ - crapto1/crypto1.c \ - mifare/mifaredefault.c \ - mifare/mfkey.c \ - tea.c \ - fido/additional_ca.c \ - fido/cose.c \ - fido/cbortools.c \ - fido/fidocore.c \ - crypto/asn1dump.c \ - crypto/libpcrypto.c\ - crypto/asn1utils.c\ - loclass/cipher.c \ - loclass/cipherutils.c \ - loclass/ikeys.c \ - loclass/elite_crack.c \ - fileutils.c \ - whereami.c \ - mifare/mifarehost.c \ - parity.c \ - crc.c \ - crc64.c \ - legic_prng.c \ - iso15693tools.c \ - prng.c \ - generator.c \ - graph.c \ - cmddata.c \ - lfdemod.c \ - emv/crypto_polarssl.c\ - emv/crypto.c\ - emv/emv_pk.c\ - emv/emv_pki.c\ - emv/emv_pki_priv.c\ - emv/test/cryptotest.c\ - emv/apduinfo.c \ - emv/dump.c \ - emv/tlv.c \ - emv/emv_tags.c \ - emv/dol.c \ - emv/emvjson.c\ - emv/emvcore.c \ - emv/test/crypto_test.c\ - emv/test/sda_test.c\ - emv/test/dda_test.c\ - emv/test/cda_test.c\ - emv/cmdemv.c \ - emv/emv_roca.c \ - mifare/mifare4.c \ - mifare/mad.c \ - mifare/ndef.c \ - mifare/desfire_crypto.c \ - cmdanalyse.c \ - cmdhf.c \ - cmdhflist.c \ - aidsearch.c \ - cmdhf14a.c \ - cmdhf14b.c \ - cmdhf15.c \ - cmdhfepa.c \ - cmdhflegic.c \ - cmdhficlass.c \ - cmdhfmf.c \ - cmdhfmfu.c \ - cmdhfmfp.c \ - cmdhfmfhard.c \ - cmdhfmfdes.c \ - cmdhftopaz.c \ - cmdhffido.c \ - cmdhffelica.c \ - cmdhfthinfilm.c \ - cmdhfcryptorf.c \ - cmdhflto.c \ - cmdhw.c \ - cmdlf.c \ - cmdlfawid.c \ - cmdlfcotag.c \ - cmdlfem4x.c \ - cmdlffdx.c \ - cmdlfguard.c \ - cmdlfgallagher.c \ - cmdlfhid.c \ - cmdlfhitag.c \ - cmdlfio.c \ - cmdlfindala.c \ - cmdlfjablotron.c \ - cmdlfkeri.c \ - cmdlfnexwatch.c \ - cmdlfnedap.c \ - cmdlfnoralsy.c \ - cmdlfpac.c \ - cmdlfparadox.c \ - cmdlfpcf7931.c \ - cmdlfpresco.c \ - cmdlfpyramid.c \ - cmdlfsecurakey.c \ - cmdlft55xx.c \ - cmdlfti.c \ - cmdlfviking.c \ - cmdlfvisa2000.c \ - cmdlfmotorola.c \ - cmdtrace.c \ - cmdflashmem.c \ - cmdflashmemspiffs.c \ - cmdsmartcard.c \ - cmdusart.c \ - cmdwiegand.c \ - cmdparser.c \ - cmdmain.c \ - pm3_binlib.c \ - scripting.c \ - cmdscript.c \ - pm3_bitlib.c \ - cmdcrc.c \ - bucketsort.c \ - flash.c \ - wiegand_formats.c \ - wiegand_formatutils.c \ - cardhelper.c \ - preferences.c +SRCS = aidsearch.c \ + cmdanalyse.c \ + cmdcrc.c \ + cmddata.c \ + cmdflashmem.c \ + cmdflashmemspiffs.c \ + cmdhf.c \ + cmdhf14a.c \ + cmdhf14b.c \ + cmdhf15.c \ + cmdhfcryptorf.c \ + cmdhfepa.c \ + cmdhffelica.c \ + cmdhffido.c \ + cmdhficlass.c \ + cmdhflegic.c \ + cmdhflist.c \ + cmdhflto.c \ + cmdhfmf.c \ + cmdhfmfdes.c \ + cmdhfmfhard.c \ + cmdhfmfu.c \ + cmdhfmfp.c \ + cmdhfthinfilm.c \ + cmdhftopaz.c \ + cmdhw.c \ + cmdlf.c \ + cmdlfawid.c \ + cmdlfcotag.c \ + cmdlfem4x.c \ + cmdlffdx.c \ + cmdlfguard.c \ + cmdlfgallagher.c \ + cmdlfhid.c \ + cmdlfhitag.c \ + cmdlfindala.c \ + cmdlfio.c \ + cmdlfjablotron.c \ + cmdlfkeri.c \ + cmdlfmotorola.c \ + cmdlfnedap.c \ + cmdlfnexwatch.c \ + cmdlfnoralsy.c \ + cmdlfpac.c \ + cmdlfparadox.c \ + cmdlfpcf7931.c \ + cmdlfpresco.c \ + cmdlfpyramid.c \ + cmdlfsecurakey.c \ + cmdlft55xx.c \ + cmdlfti.c \ + cmdlfviking.c \ + cmdlfvisa2000.c \ + cmdmain.c \ + cmdparser.c \ + cmdscript.c \ + cmdsmartcard.c \ + cmdtrace.c \ + cmdusart.c \ + cmdwiegand.c \ + comms.c \ + crypto/asn1dump.c \ + crypto/asn1utils.c\ + crypto/libpcrypto.c\ + emv/apduinfo.c \ + emv/cmdemv.c \ + emv/crypto.c\ + emv/crypto_polarssl.c\ + emv/dol.c \ + emv/dump.c \ + emv/emv_pk.c\ + emv/emv_pki.c\ + emv/emv_pki_priv.c\ + emv/emv_roca.c \ + emv/emv_tags.c \ + emv/emvcore.c \ + emv/emvjson.c\ + emv/tlv.c \ + emv/test/crypto_test.c\ + emv/test/cryptotest.c\ + emv/test/cda_test.c\ + emv/test/dda_test.c\ + emv/test/sda_test.c\ + fido/additional_ca.c \ + fido/cose.c \ + fido/cbortools.c \ + fido/fidocore.c \ + fileutils.c \ + flash.c \ + generator.c \ + graph.c \ + jansson_path.c \ + loclass/cipher.c \ + loclass/cipherutils.c \ + loclass/elite_crack.c \ + loclass/ikeys.c \ + mifare/desfire_crypto.c \ + mifare/mad.c \ + mifare/mfkey.c \ + mifare/mifare4.c \ + mifare/mifaredefault.c \ + mifare/mifarehost.c \ + mifare/ndef.c \ + pm3_binlib.c \ + pm3_bitlib.c \ + preferences.c \ + prng.c \ + proxmark3.c \ + scandir.c \ + uart/uart_posix.c \ + uart/uart_win32.c \ + scripting.c \ + tea.c \ + ui.c \ + util.c \ + version.c \ + wiegand_formats.c \ + wiegand_formatutils.c +# common +SRCS += bucketsort.c \ + cardhelper.c \ + crapto1/crapto1.c \ + crapto1/crypto1.c \ + crc.c \ + crc16.c \ + crc32.c \ + crc64.c \ + commonutil.c \ + iso15693tools.c \ + legic_prng.c \ + lfdemod.c \ + parity.c \ + util_posix.c +# gui +ifeq ($(QT_FOUND),1) + CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp +else + CXXSRCS = guidummy.cpp +endif -COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) -CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) -OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o) +# OS X +ifeq ($(platform),Darwin) + OBJCSRCS = util_darwin.m +endif + +OBJS = $(SRCS:%.c=$(OBJDIR)/%.o) +OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o) +OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o) BINS = proxmark3 -CLEAN = $(BINS) src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua + +CLEAN = $(BINS) src/version.c src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua # transition: cleaning also old path stuff CLEAN += flasher *.moc.cpp ui/ui_overlays.h +########### +# targets # +########### + # need to assign dependancies to build these first... all: $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) -proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) $(QTLDLIBS) -proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua +proxmark3: $(OBJS) amiibo cliparser jansson hardnested lua mbedtls reveng tinycbor whereami lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(LDLIBS) -o $@ + $(Q)$(LD) $(PM3LDFLAGS) $(OBJS) $(LDLIBS) -o $@ src/proxgui.cpp: src/ui/ui_overlays.h @@ -312,13 +601,16 @@ lualibs/mfc_default_keys.lua : mfc_default_keys.dic clean: $(Q)$(RM) $(CLEAN) $(Q)$(RMDIR) $(OBJDIR) - $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(CLIPARSERPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean + $(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) clean + @# Just in case someone compiled within these dirs: + $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean install: all $(info [@] Installing client to $(DESTDIR)$(PREFIX)...) @@ -346,45 +638,62 @@ tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) -# local libraries: -$(LUALIB): - $(info [*] MAKE liblua for $(LUAPLATFORM)) - $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) +########################### +# local libraries targets # +########################### -$(JANSSONLIB): - $(info [*] MAKE jansson) - $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all - -$(CBORLIB): - $(info [*] MAKE tinycbor) - $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all - -$(REVENGLIB): - $(info [*] MAKE reveng) - $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all - -$(HARDNESTEDLIB): - $(info [*] MAKE hardnested) - $(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDPATH) all - -$(AMIIBOLIB): - $(info [*] MAKE amiibo) +amiibo: + $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all -$(CLIPARSERLIB): - $(info [*] MAKE cliparser) - $(Q)$(MAKE) --no-print-directory -C $(CLIPARSERPATH) all +cliparser: + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) all -# common libraries: -$(MBEDTLSLIB): - $(info [*] MAKE mbedtls) +hardnested: + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) all + +jansson: +ifneq ($(JANSSON_FOUND),1) + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all +endif + +lua: +ifneq ($(LUA_FOUND),1) + $(info [*] MAKE $@ for $(LUAPLATFORM)) + $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) +endif + +mbedtls: + $(info [*] MAKE $@) $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all -$(ZLIB): - $(info [*] MAKE zlib) - $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all +reveng: + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) all -.PHONY: all clean install uninstall +tinycbor: + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) all + +whereami: +ifneq ($(WHEREAMI_FOUND),1) + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all +endif + +######## +# misc # +######## + +.PHONY: all clean install uninstall tarbin amiibo cliparser hardnested jansson lua mbedtls reveng tinycbor whereami + +# version.c should be remade on every compilation +src/version.c: default_version.c + $(info [=] GEN $@) + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) @@ -400,7 +709,7 @@ $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d $(info [-] CXX $<) $(Q)$(MKDIR) $(dir $@) - $(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $< + $(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(CXXINCLUDES) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.m @@ -410,10 +719,9 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) -DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS)) \ - $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ - $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ - $(OBJDIR)/proxmark3.d +DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \ + $(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \ + $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) $(DEPENDENCY_FILES): ; .PRECIOUS: $(DEPENDENCY_FILES) diff --git a/client/android/CMakeLists.txt b/client/android/CMakeLists.txt new file mode 100644 index 000000000..11da2f5e4 --- /dev/null +++ b/client/android/CMakeLists.txt @@ -0,0 +1,183 @@ +# version +cmake_minimum_required(VERSION 3.4.1) + +# We are build on android platform, so we need add def "ANDROID" +# NDK version for SDK 19 doesn't implement the whole C++11 standard in the STL. +# see: https://stackoverflow.com/questions/44736135/ndk-clang-error-undefined-reference-to-localeconv +# so we need add def getlocaledecpoint()='.' +add_definitions(-DANDROID -D"getlocaledecpoint\(\)='.'") + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -fvisibility=hidden -w") + +# Root path into client +set(PM3_ROOT ../../) + +add_subdirectory(../deps deps) + +# client resources +add_library(pm3rrg_rdv4 SHARED + ${PM3_ROOT}/common/util_posix.c + ${PM3_ROOT}/common/crapto1/crapto1.c + ${PM3_ROOT}/common/crapto1/crypto1.c + ${PM3_ROOT}/common/crc.c + ${PM3_ROOT}/common/crc16.c + ${PM3_ROOT}/common/crc32.c + ${PM3_ROOT}/common/crc64.c + ${PM3_ROOT}/common/cardhelper.c + ${PM3_ROOT}/common/parity.c + ${PM3_ROOT}/common/commonutil.c + ${PM3_ROOT}/common/generator.c + ${PM3_ROOT}/common/lfdemod.c + ${PM3_ROOT}/common/iso15693tools.c + ${PM3_ROOT}/common/bucketsort.c + ${PM3_ROOT}/common/legic_prng.c + # client inside + ${PM3_ROOT}/client/src/fileutils.c + ${PM3_ROOT}/client/src/uart/uart_posix.c + ${PM3_ROOT}/client/src/loclass/cipherutils.c + ${PM3_ROOT}/client/src/loclass/cipher.c + ${PM3_ROOT}/client/src/loclass/ikeys.c + ${PM3_ROOT}/client/src/loclass/elite_crack.c + ${PM3_ROOT}/client/src/emv/emvcore.c + ${PM3_ROOT}/client/src/emv/cmdemv.c + ${PM3_ROOT}/client/src/emv/tlv.c + ${PM3_ROOT}/client/src/emv/dol.c + ${PM3_ROOT}/client/src/emv/emv_tags.c + ${PM3_ROOT}/client/src/emv/emv_roca.c + ${PM3_ROOT}/client/src/emv/dump.c + ${PM3_ROOT}/client/src/emv/crypto_polarssl.c + ${PM3_ROOT}/client/src/emv/crypto.c + ${PM3_ROOT}/client/src/emv/emv_pk.c + ${PM3_ROOT}/client/src/emv/emv_pki.c + ${PM3_ROOT}/client/src/emv/emvjson.c + ${PM3_ROOT}/client/src/emv/apduinfo.c + ${PM3_ROOT}/client/src/emv/test/cryptotest.c + ${PM3_ROOT}/client/src/emv/test/sda_test.c + ${PM3_ROOT}/client/src/emv/test/dda_test.c + ${PM3_ROOT}/client/src/emv/test/cda_test.c + ${PM3_ROOT}/client/src/emv/test/crypto_test.c + ${PM3_ROOT}/client/src/emv/test/cryptotest.c + ${PM3_ROOT}/client/src/emv/test/sda_test.c + ${PM3_ROOT}/client/src/emv/test/dda_test.c + ${PM3_ROOT}/client/src/emv/test/cda_test.c + ${PM3_ROOT}/client/src/emv/test/crypto_test.c + ${PM3_ROOT}/client/src/crypto/libpcrypto.c + ${PM3_ROOT}/client/src/crypto/asn1utils.c + ${PM3_ROOT}/client/src/crypto/asn1dump.c + ${PM3_ROOT}/client/src/mifare/mad.c + ${PM3_ROOT}/client/src/mifare/mfkey.c + ${PM3_ROOT}/client/src/mifare/mifare4.c + ${PM3_ROOT}/client/src/mifare/mifarehost.c + ${PM3_ROOT}/client/src/mifare/ndef.c + ${PM3_ROOT}/client/src/mifare/desfire_crypto.c + ${PM3_ROOT}/client/src/mifare/mifaredefault.c + ${PM3_ROOT}/client/src/fido/cose.c + ${PM3_ROOT}/client/src/fido/fidocore.c + ${PM3_ROOT}/client/src/fido/cbortools.c + ${PM3_ROOT}/client/src/fido/additional_ca.c + ${PM3_ROOT}/client/src/preferences.c + ${PM3_ROOT}/client/src/graph.c + ${PM3_ROOT}/client/src/ui.c + ${PM3_ROOT}/client/src/tea.c + ${PM3_ROOT}/client/src/util.c + ${PM3_ROOT}/client/src/comms.c + ${PM3_ROOT}/client/src/cmdcrc.c + ${PM3_ROOT}/client/src/cmdanalyse.c + ${PM3_ROOT}/client/src/cmddata.c + ${PM3_ROOT}/client/src/cmdtrace.c + ${PM3_ROOT}/client/src/cmdhf.c + ${PM3_ROOT}/client/src/cmdhflto.c + ${PM3_ROOT}/client/src/aidsearch.c + ${PM3_ROOT}/client/src/cmdhf14a.c + ${PM3_ROOT}/client/src/cmdhf14b.c + ${PM3_ROOT}/client/src/cmdwiegand.c + ${PM3_ROOT}/client/src/wiegand_formatutils.c + ${PM3_ROOT}/client/src/wiegand_formats.c + ${PM3_ROOT}/client/src/cmdlfmotorola.c + ${PM3_ROOT}/client/src/cmdlfgallagher.c + ${PM3_ROOT}/client/src/cmdhf15.c + ${PM3_ROOT}/client/src/cmdhfepa.c + ${PM3_ROOT}/client/src/cmdhflegic.c + ${PM3_ROOT}/client/src/cmdhfthinfilm.c + ${PM3_ROOT}/client/src/cmdflashmemspiffs.c + ${PM3_ROOT}/client/src/cmdhffelica.c + ${PM3_ROOT}/client/src/cmdhficlass.c + ${PM3_ROOT}/client/src/cmdhflist.c + ${PM3_ROOT}/client/src/cmdhfmf.c + ${PM3_ROOT}/client/src/cmdhfmfdes.c + ${PM3_ROOT}/client/src/cmdhfmfu.c + ${PM3_ROOT}/client/src/cmdhfmfp.c + ${PM3_ROOT}/client/src/cmdhffido.c + ${PM3_ROOT}/client/src/cmdhftopaz.c + ${PM3_ROOT}/client/src/cmdhw.c + ${PM3_ROOT}/client/src/cmdlf.c + ${PM3_ROOT}/client/src/cmdlfkeri.c + ${PM3_ROOT}/client/src/cmdlffdx.c + ${PM3_ROOT}/client/src/cmdlfio.c + ${PM3_ROOT}/client/src/cmdlfem4x.c + ${PM3_ROOT}/client/src/cmdlfhid.c + ${PM3_ROOT}/client/src/cmdlfnedap.c + ${PM3_ROOT}/client/src/cmdlfguard.c + ${PM3_ROOT}/client/src/cmdlfhitag.c + ${PM3_ROOT}/client/src/cmdlfjablotron.c + ${PM3_ROOT}/client/src/cmdsmartcard.c + ${PM3_ROOT}/client/src/cmdlfti.c + ${PM3_ROOT}/client/src/cmdlfpac.c + ${PM3_ROOT}/client/src/cmdlfnoralsy.c + ${PM3_ROOT}/client/src/cmdlfnexwatch.c + ${PM3_ROOT}/client/src/cmdlfpresco.c + ${PM3_ROOT}/client/src/cmdlfindala.c + ${PM3_ROOT}/client/src/cmdlfviking.c + ${PM3_ROOT}/client/src/cmdlfsecurakey.c + ${PM3_ROOT}/client/src/cmdlfpyramid.c + ${PM3_ROOT}/client/src/cmdlfparadox.c + ${PM3_ROOT}/client/src/cmdlfcotag.c + ${PM3_ROOT}/client/src/cmdlfawid.c + ${PM3_ROOT}/client/src/cmdparser.c + ${PM3_ROOT}/client/src/cmdscript.c + ${PM3_ROOT}/client/src/cmdlfvisa2000.c + ${PM3_ROOT}/client/src/cmdmain.c + ${PM3_ROOT}/client/src/cmdflashmem.c + ${PM3_ROOT}/client/src/scripting.c + ${PM3_ROOT}/client/src/pm3_binlib.c + ${PM3_ROOT}/client/src/pm3_bitlib.c + ${PM3_ROOT}/client/src/cmdlft55xx.c + ${PM3_ROOT}/client/src/cmdlfpcf7931.c + ${PM3_ROOT}/client/src/cmdhfmfhard.c + ${PM3_ROOT}/client/src/cmdusart.c + ${PM3_ROOT}/client/src/jansson_path.c + # android resources + jni_tools.c + pm3_main.c + ) + +# includes +target_include_directories(pm3rrg_rdv4 PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${PM3_ROOT}/include/ + ${PM3_ROOT}/common + ${PM3_ROOT}/common_fpga + ${PM3_ROOT}/client/src) + +find_library(pm3rrg_rdv4_cliparser REQUIRED) +find_library(pm3rrg_rdv4_jansson REQUIRED) +find_library(pm3rrg_rdv4_tinycbor REQUIRED) +find_library(pm3rrg_rdv4_lua REQUIRED) +find_library(pm3rrg_rdv4_mbedtls REQUIRED) +find_library(pm3rrg_rdv4_reveng REQUIRED) +find_library(pm3rrg_rdv4_hardnested REQUIRED) +find_library(pm3rrg_rdv4_whereami REQUIRED) + +target_link_libraries(pm3rrg_rdv4 + bz2 + pm3rrg_rdv4_hardnested + pm3rrg_rdv4_mbedtls + pm3rrg_rdv4_cliparser + pm3rrg_rdv4_jansson + pm3rrg_rdv4_lua + pm3rrg_rdv4_tinycbor + pm3rrg_rdv4_amiibo + pm3rrg_rdv4_reveng + pm3rrg_rdv4_whereami + android + log) diff --git a/client/android/jni_tools.c b/client/android/jni_tools.c new file mode 100644 index 000000000..5c7558853 --- /dev/null +++ b/client/android/jni_tools.c @@ -0,0 +1,81 @@ +// +// Created by DXL on 2017/9/1. +// + +//including header +#include +#include +#include "stdbool.h" + +// native thread attach label +static bool g_IsAttach; + +// get current env for jvm +JNIEnv *getJniEnv() { + JNIEnv *currentThreadEnv; + g_IsAttach = false; + if ((*g_JavaVM)->GetEnv(g_JavaVM, (void **) ¤tThreadEnv, JNI_VERSION_1_4) != JNI_OK) { + LOGE("Get Env Fail!"); + if ((*g_JavaVM)->AttachCurrentThread(g_JavaVM, ¤tThreadEnv, NULL) != JNI_OK) { + LOGE("Attach the current thread Fail!"); + g_IsAttach = false; + return NULL; + } else { + g_IsAttach = true; + LOGE("Attach the current thread Success!"); + return currentThreadEnv; + } + } else { + g_IsAttach = false; + //LOGE("Get Env Success!"); + return currentThreadEnv; + } +} + +// detach native thread from jvm +void detachThread() { + if (g_IsAttach) { + (*g_JavaVM)->DetachCurrentThread(g_JavaVM); + } +} + +// cmd arg parse +CMD *parse_command_line(const char *commandStr) { + CMD *cmd = (CMD *) malloc(sizeof(CMD)); + if (!cmd) { + return NULL; + } + // copy the source to the heap + char *pTmp = strdup(commandStr); + // new memory size is default 20 for char ** + int size = 20; + cmd->cmd = (char **) malloc(size * sizeof(char **)); + if (!cmd->cmd) { + free(cmd); + return NULL; + } + // parse + char *pStr = strtok(pTmp, " "); + cmd->cmd[0] = pStr; + int count = 1; + for (; pStr != NULL; ++count) { + // Capacity expansion + if (count == (size - 1)) { + size += 20; + cmd->cmd = (char **) realloc(cmd->cmd, size * sizeof(char **)); + } + pStr = strtok(NULL, " "); + if (pStr) { + cmd->cmd[count] = pStr; + } + } + cmd->len = (count - 1); + return cmd; +} + +// cmd arg struct free +void free_command_line(CMD *cmd) { + free(cmd->cmd[0]); + free(cmd->cmd); + free(cmd); +} diff --git a/client/android/jni_tools.h b/client/android/jni_tools.h new file mode 100644 index 000000000..8e900374f --- /dev/null +++ b/client/android/jni_tools.h @@ -0,0 +1,40 @@ +// +// Created by dell on 2017/9/1. +// + +#ifndef DXL_TOOLS_H +#define DXL_TOOLS_H + +#include +#include +#include + +//JNI LOG +#define TAG "PM3" +#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,TAG,__VA_ARGS__) +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) + +// a global jvm instance +JavaVM *g_JavaVM; + +// get current env for jvm +JNIEnv *getJniEnv(); + +// detach native thread from jvm, must native thread can detach! +void detachThread(); + +typedef struct { + char **cmd; + int len; +} CMD; + +// cmd arg parse +CMD *parse_command_line(const char *commandStr); + +// cmd arg struct free +void free_command_line(CMD *); + +#endif //DXL_TOOLS_H diff --git a/client/android/pm3_main.c b/client/android/pm3_main.c new file mode 100644 index 000000000..af45725cd --- /dev/null +++ b/client/android/pm3_main.c @@ -0,0 +1,167 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2009 Michael Gernoth +// Copyright (C) 2010 iZsh +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Main binary +//----------------------------------------------------------------------------- + +#include "proxmark3.h" + +#include +#include // for Mingw readline +#include +#include +#include +#include "usart_defs.h" +#include "util_posix.h" +#include "proxgui.h" +#include "cmdmain.h" +#include "ui.h" +#include "cmdhw.h" +#include "whereami.h" +#include "comms.h" +#include "fileutils.h" +#include "jni_tools.h" + +//iceman, todo: proxify socker server name. Maybe set in preferences? +#define PM3_LOCAL_SOCKET_SERVER "DXL.COM.ASL" + +void ShowGraphWindow(void) { +} + +void HideGraphWindow(void) { +} + +void RepaintGraphWindow(void) { +} + +int push_cmdscriptfile(char *path, bool stayafter) { + return PM3_SUCCESS; +} + +static char *g_android_executable_directory = NULL; +static const char *g_android_user_directory = NULL; + +const char *get_executable_directory(void) { + + if (g_android_executable_directory == NULL) { + char buf[FILE_PATH_SIZE] = {0}; + getcwd(buf, sizeof(buf)); + strncat(buf, PATHSEP, 1); + g_android_executable_directory = strdup(buf); + } + return g_android_executable_directory; +} + +const char *get_user_directory(void) { + return g_android_user_directory; +} + +static bool OpenPm3(void) { + if (conn.run) { + return true; + } + // Open with LocalSocket. Not a tcp connection! + bool ret = OpenProxmark("socket:"PM3_LOCAL_SOCKET_SERVER, false, 1000, false, 115200); + return ret; +} + +/* + * Transfers to the command buffer and waits for a new command to be executed + * */ +jint Console(JNIEnv *env, jobject instance, jstring cmd_) { + + if (!conn.run) { + if (OpenPm3() && TestProxmark() == PM3_SUCCESS) { + LOGD("Connected to device"); + PrintAndLogEx(SUCCESS, "Connected to device"); + } else { + LOGD("Failed to connect to device"); + PrintAndLogEx(ERR, "Failed to connect to device"); + CloseProxmark(); + } + } + + PrintAndLogEx(NORMAL, ""); + + char *cmd = (char *)((*env)->GetStringUTFChars(env, cmd_, 0)); + int ret = CommandReceived(cmd); + if (ret == 99) { + // exit / quit + // TODO: implement this + PrintAndLogEx(NORMAL, "Asked to exit, can't really do that yet..."); + } + + (*env)->ReleaseStringUTFChars(env, cmd_, cmd); + return ret; +} + +/* + * Is client running! + * */ +jboolean IsClientRunning(JNIEnv *env, jobject instance) { + return (jboolean)((jboolean) conn.run); +} + +/* + * test hw and hw and client. + * */ +jboolean TestPm3(JNIEnv *env, jobject instance) { + if (open() == false) { + CloseProxmark(); + return false; + } + bool ret = (TestProxmark() == PM3_SUCCESS); + return (jboolean)(ret); +} + +/* + * stop pm3 client + * */ +void ClosePm3(JNIEnv *env, jobject instance) { + CloseProxmark(); +} + +/* + * native function map to jvm + * */ + +//iceman: todo, pm3:ify java class root. Return codes, should match PM3_E* codes. +JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { + JNIEnv *jniEnv = NULL; + if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) { + return -1; + } + (*jniEnv)->GetJavaVM(jniEnv, &g_JavaVM); + jclass clazz = (*jniEnv)->FindClass(jniEnv, "cn/rrg/natives/Proxmark3RRGRdv4Tools"); + if (clazz == NULL) { + return -1; + } + jclass clz_test = (*jniEnv)->FindClass(jniEnv, "cn/rrg/devices/Proxmark3RRGRdv4"); + JNINativeMethod methods[] = { + {"startExecute", "(Ljava/lang/String;)I", (void *) Console}, + {"stopExecute", "()V", (void *) ClosePm3}, + {"isExecuting", "()Z", (void *) IsClientRunning} + }; + + JNINativeMethod methods1[] = { + {"testPm3", "()Z", (void *) TestPm3}, + {"closePm3", "()V", ClosePm3} + }; + + if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) != JNI_OK) { + return -1; + } + + if ((*jniEnv)->RegisterNatives(jniEnv, clz_test, methods1, sizeof(methods1) / sizeof(methods1[0])) != JNI_OK) { + return -1; + } + + (*jniEnv)->DeleteLocalRef(jniEnv, clazz); + (*jniEnv)->DeleteLocalRef(jniEnv, clz_test); + return JNI_VERSION_1_4; +} diff --git a/client/deps/CMakeLists.txt b/client/deps/CMakeLists.txt index 6b577d438..f7b96a7ea 100644 --- a/client/deps/CMakeLists.txt +++ b/client/deps/CMakeLists.txt @@ -1,9 +1,27 @@ -include(cliparser.cmake) -include(tinycbor.cmake) -include(jansson.cmake) -include(lua.cmake) -include(mbedtls.cmake) -include(amiibo.cmake) -include(reveng.cmake) -include(zlib.cmake) -include(hardnested.cmake) \ No newline at end of file +if (NOT TARGET pm3rrg_rdv4_amiibo) + include(amiibo.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_cliparser) + include(cliparser.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_hardnested) + include(hardnested.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_jansson) + include(jansson.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_lua) + include(lua.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_mbedtls) + include(mbedtls.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_reveng) + include(reveng.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_tinycbor) + include(tinycbor.cmake) +endif() +if (NOT TARGET pm3rrg_rdv4_whereami) + include(whereami.cmake) +endif() diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index 857074f9e..234547cd1 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -5,12 +5,20 @@ #amiitool.c $(MYSRCS) ../../../../common/../../commonutil.c ../ui.c -lreadline -lm ../../../../common/mbedtls/libmbedtls.a \ #-o amiitool -add_library(amiibo STATIC +add_library(pm3rrg_rdv4_amiibo STATIC amiitool/amiibo.c amiitool/drbg.c amiitool/keygen.c ) -target_include_directories(amiibo PRIVATE ../../include ../../common) -target_include_directories(amiibo INTERFACE amiitool) -target_compile_options(amiibo PRIVATE -Wall -Werror -O3) +if (NOT TARGET pm3rrg_rdv4_mbedtls) + include(mbedtls.cmake) +endif() +find_library(pm3rrg_rdv4_mbedtls REQUIRED) +target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE + m + pm3rrg_rdv4_mbedtls) +target_include_directories(pm3rrg_rdv4_amiibo PRIVATE ../../include ../../common) +target_include_directories(pm3rrg_rdv4_amiibo INTERFACE amiitool) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) +set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/amiitool/Makefile b/client/deps/amiitool/Makefile index 7fe532878..dd064227e 100644 --- a/client/deps/amiitool/Makefile +++ b/client/deps/amiitool/Makefile @@ -1,5 +1,5 @@ MYSRCPATHS = -MYINCLUDES = -I. -I.. -I../jansson -I../../../common -I../../../include +MYINCLUDES = -I. -I.. -I../jansson -I../../../common -I../../../common/mbedtls -I../../../include MYCFLAGS = MYDEFS = MYSRCS = \ diff --git a/client/deps/amiitool/amiibo.c b/client/deps/amiitool/amiibo.c index 809f611d3..cbe3a0ba0 100644 --- a/client/deps/amiitool/amiibo.c +++ b/client/deps/amiitool/amiibo.c @@ -6,14 +6,14 @@ */ #include "amiibo.h" -#include "mbedtls/md.h" -#include "mbedtls/aes.h" +#include "md.h" +#include "aes.h" #include "commonutil.h" #define HMAC_POS_DATA 0x008 #define HMAC_POS_TAG 0x1B4 -void nfc3d_amiibo_calc_seed(const uint8_t *dump, uint8_t *key) { +static void nfc3d_amiibo_calc_seed(const uint8_t *dump, uint8_t *key) { memcpy(key + 0x00, dump + 0x029, 0x02); memset(key + 0x02, 0x00, 0x0E); memcpy(key + 0x10, dump + 0x1D4, 0x08); @@ -21,14 +21,14 @@ void nfc3d_amiibo_calc_seed(const uint8_t *dump, uint8_t *key) { memcpy(key + 0x20, dump + 0x1E8, 0x20); } -void nfc3d_amiibo_keygen(const nfc3d_keygen_masterkeys *masterKeys, const uint8_t *dump, nfc3d_keygen_derivedkeys *derivedKeys) { +static void nfc3d_amiibo_keygen(const nfc3d_keygen_masterkeys *masterKeys, const uint8_t *dump, nfc3d_keygen_derivedkeys *derivedKeys) { uint8_t seed[NFC3D_KEYGEN_SEED_SIZE]; nfc3d_amiibo_calc_seed(dump, seed); nfc3d_keygen(masterKeys, seed, derivedKeys); } -void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys *keys, const uint8_t *in, uint8_t *out) { +static void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys *keys, const uint8_t *in, uint8_t *out) { mbedtls_aes_context aes; size_t nc_off = 0; unsigned char nonce_counter[16]; @@ -47,7 +47,7 @@ void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys *keys, const uint8_t *in memcpy(out + 0x1D4, in + 0x1D4, 0x034); } -void nfc3d_amiibo_tag_to_internal(const uint8_t *tag, uint8_t *intl) { +static void nfc3d_amiibo_tag_to_internal(const uint8_t *tag, uint8_t *intl) { memcpy(intl + 0x000, tag + 0x008, 0x008); memcpy(intl + 0x008, tag + 0x080, 0x020); memcpy(intl + 0x028, tag + 0x010, 0x024); @@ -57,7 +57,7 @@ void nfc3d_amiibo_tag_to_internal(const uint8_t *tag, uint8_t *intl) { memcpy(intl + 0x1DC, tag + 0x054, 0x02C); } -void nfc3d_amiibo_internal_to_tag(const uint8_t *intl, uint8_t *tag) { +static void nfc3d_amiibo_internal_to_tag(const uint8_t *intl, uint8_t *tag) { memcpy(tag + 0x008, intl + 0x000, 0x008); memcpy(tag + 0x080, intl + 0x008, 0x020); memcpy(tag + 0x010, intl + 0x028, 0x024); diff --git a/client/deps/amiitool/amiitool.c b/client/deps/amiitool/amiitool.c index b63222d50..d7cd08351 100644 --- a/client/deps/amiitool/amiitool.c +++ b/client/deps/amiitool/amiitool.c @@ -15,7 +15,7 @@ static char *self; -void amiitool_usage() { +void amiitool_usage(void) { fprintf(stderr, /*"amiitool build %i (commit %s-%08x)\n"*/ "by Marcos Del Sol Vives \n" diff --git a/client/deps/amiitool/drbg.c b/client/deps/amiitool/drbg.c index c1297920f..1aaba0a7f 100644 --- a/client/deps/amiitool/drbg.c +++ b/client/deps/amiitool/drbg.c @@ -8,7 +8,7 @@ #include "drbg.h" #include #include -#include "mbedtls/md.h" +#include "md.h" void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) { assert(ctx != NULL); diff --git a/client/deps/amiitool/keygen.c b/client/deps/amiitool/keygen.c index f148c0dc8..6322a0fe9 100644 --- a/client/deps/amiitool/keygen.c +++ b/client/deps/amiitool/keygen.c @@ -10,7 +10,7 @@ #include #include -void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys *baseKeys, const uint8_t *baseSeed, uint8_t *output, size_t *outputSize) { +static void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys *baseKeys, const uint8_t *baseSeed, uint8_t *output, size_t *outputSize) { assert(baseKeys != NULL); assert(baseSeed != NULL); assert(output != NULL); diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index 890fd39c5..b16451c07 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -1,11 +1,12 @@ -add_library(cliparser STATIC +add_library(pm3rrg_rdv4_cliparser STATIC cliparser/argtable3.c cliparser/cliparser.c ) -target_include_directories(cliparser PRIVATE +target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../common ../../include ../src) -target_include_directories(cliparser INTERFACE cliparser) -target_compile_options(cliparser PRIVATE -Wall -Werror -O3) +target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) +set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/cliparser/Makefile b/client/deps/cliparser/Makefile index 7f4409de0..4873372c4 100644 --- a/client/deps/cliparser/Makefile +++ b/client/deps/cliparser/Makefile @@ -1,6 +1,6 @@ MYSRCPATHS = MYINCLUDES = -I../../../common -I../../../include -I../../src -MYCFLAGS = +MYCFLAGS = -Wno-cast-align MYDEFS = MYSRCS = \ argtable3.c \ diff --git a/client/deps/cliparser/argtable3.c b/client/deps/cliparser/argtable3.c index f66c22d6d..f0b6a4d37 100644 --- a/client/deps/cliparser/argtable3.c +++ b/client/deps/cliparser/argtable3.c @@ -3398,13 +3398,13 @@ void trex_free(TRex *exp) { } TRexBool trex_match(TRex *exp, const TRexChar *text) { - const TRexChar *res = NULL; exp->_bol = text; exp->_eol = text + scstrlen(text); exp->_currsubexp = 0; - res = trex_matchnode(exp, exp->_nodes, text, NULL); - if (res == NULL || res != exp->_eol) + const TRexChar *res = trex_matchnode(exp, exp->_nodes, text, NULL); + if (res == NULL || res != exp->_eol) { return TRex_False; + } return TRex_True; } @@ -4135,7 +4135,8 @@ int arg_parse(int argc, char * *argv, void * *argtable) { */ static void arg_cat(char **pdest, const char *src, size_t *pndest) { char *dest = *pdest; - char *end = dest + *pndest; + // PM3 fix: leave room for null terminate char + char *end = dest + *pndest - 1; /*locate null terminator of dest string */ while (dest < end && *dest != 0) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index 1845aff29..3eaec2b55 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -10,50 +10,53 @@ #include "cliparser.h" #include +#include +#ifndef ARRAYLEN +# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) +#endif -void **argtable = NULL; -size_t argtableLen = 0; -const char *programName = NULL; -const char *programHint = NULL; -const char *programHelp = NULL; -char buf[500] = {0}; - -int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { - argtable = NULL; - argtableLen = 0; - programName = vprogramName; - programHint = vprogramHint; - programHelp = vprogramHelp; - memset(buf, 0x00, 500); +int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { + *ctx = malloc(sizeof(CLIParserContext)); + if (!*ctx) { + printf("ERROR: Insufficient memory\n"); + fflush(stdout); + return 2; + } + (*ctx)->argtable = NULL; + (*ctx)->argtableLen = 0; + (*ctx)->programName = vprogramName; + (*ctx)->programHint = vprogramHint; + (*ctx)->programHelp = vprogramHelp; + memset((*ctx)->buf, 0x00, sizeof((*ctx)->buf)); return 0; } -int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { +int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { int nerrors; - argtable = vargtable; - argtableLen = vargtableLen; + ctx->argtable = vargtable; + ctx->argtableLen = vargtableLen; /* verify the argtable[] entries were allocated sucessfully */ - if (arg_nullcheck(argtable) != 0) { + if (arg_nullcheck(ctx->argtable) != 0) { /* NULL entries were detected, some allocations must have failed */ printf("ERROR: Insufficient memory\n"); fflush(stdout); return 2; } /* Parse the command line as defined by argtable[] */ - nerrors = arg_parse(argc, argv, argtable); + nerrors = arg_parse(argc, argv, ctx->argtable); /* special case: '--help' takes precedence over error reporting */ - if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)argtable[0])->count > 0) { // help must be the first record - printf("Usage: %s", programName); - arg_print_syntaxv(stdout, argtable, "\n"); - if (programHint) - printf("%s\n\n", programHint); - arg_print_glossary(stdout, argtable, " %-20s %s\n"); + if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)(ctx->argtable)[0])->count > 0) { // help must be the first record + printf("Usage: %s", ctx->programName); + arg_print_syntaxv(stdout, ctx->argtable, "\n"); + if (ctx->programHint) + printf("%s\n\n", ctx->programHint); + arg_print_glossary(stdout, ctx->argtable, " %-20s %s\n"); printf("\n"); - if (programHelp) - printf("%s \n", programHelp); + if (ctx->programHelp) + printf("%s \n", ctx->programHelp); fflush(stdout); return 1; @@ -62,8 +65,8 @@ int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtable /* If the parser returned any errors then display them and exit */ if (nerrors > 0) { /* Display the error details contained in the arg_end struct.*/ - arg_print_errors(stdout, ((struct arg_end *)argtable[vargtableLen - 1]), programName); - printf("Try '%s --help' for more information.\n", programName); + arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName); + printf("Try '%s --help' for more information.\n", ctx->programName); fflush(stdout); return 3; } @@ -79,23 +82,24 @@ enum ParserState { #define isSpace(c)(c == ' ' || c == '\t') -int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { - return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false); +int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { + return CLIParserParseStringEx(ctx, str, vargtable, vargtableLen, allowEmptyExec, false); } -int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { +int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { int argc = 0; char *argv[200] = {NULL}; int len = strlen(str); - char *bufptr = buf; + memset(ctx->buf, 0x00, ARRAYLEN(ctx->buf)); + char *bufptr = ctx->buf; char *spaceptr = NULL; enum ParserState state = PS_FIRST; argv[argc++] = bufptr; // param0 = program name - memcpy(buf, programName, strlen(programName) + 1); // with 0x00 - bufptr += strlen(programName) + 1; + memcpy(ctx->buf, ctx->programName, strlen(ctx->programName) + 1); // with 0x00 + bufptr += strlen(ctx->programName) + 1; if (len) argv[argc++] = bufptr; @@ -140,14 +144,7 @@ int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableL } } - return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec); -} - -void CLIParserFree() { - arg_freetable(argtable, argtableLen); - argtable = NULL; - - return; + return CLIParserParseArg(ctx, argc, argv, vargtable, vargtableLen, allowEmptyExec); } // convertors diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index 866ee07d6..86ed21977 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -11,32 +11,41 @@ #ifndef __CLIPARSER_H #define __CLIPARSER_H #include "argtable3.h" +#include #include "util.h" #define arg_param_begin arg_lit0("hH", "help", "This help") #define arg_param_end arg_end(20) #define arg_getsize(a) (sizeof(a) / sizeof(a[0])) -#define arg_get_lit(n) (((struct arg_lit*)argtable[n])->count) -#define arg_get_int_count(n)(((struct arg_int*)argtable[n])->count) -#define arg_get_int(n) (((struct arg_int*)argtable[n])->ival[0]) -#define arg_get_int_def(n, def)(arg_get_int_count(n) ? (arg_get_int(n)) : (def)) -#define arg_get_str(n) ((struct arg_str*)argtable[n]) -#define arg_get_str_len(n) (strlen(((struct arg_str*)argtable[n])->sval[0])) +#define arg_get_lit(ctx, n) (((struct arg_lit*)((ctx)->argtable)[n])->count) +#define arg_get_int_count(ctx, n)(((struct arg_int*)((ctx)->argtable)[n])->count) +#define arg_get_int(ctx, n) (((struct arg_int*)((ctx)->argtable)[n])->ival[0]) +#define arg_get_int_def(ctx, n, def)(arg_get_int_count((ctx), n) ? (arg_get_int((ctx), n)) : (def)) +#define arg_get_str(ctx, n) ((struct arg_str*)((ctx)->argtable)[n]) +#define arg_get_str_len(ctx, n) (strlen(((struct arg_str*)((ctx)->argtable)[n])->sval[0])) #define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary))) #define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary))) -#define CLIExecWithReturn(cmd, atbl, ifempty) if (CLIParserParseString(cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree();return PM3_ESOFT;} -#define CLIGetHexBLessWithReturn(paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree();return PM3_ESOFT;} -#define CLIGetHexWithReturn(paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;} -#define CLIGetStrWithReturn(paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;} +#define CLIParserFree(ctx) if ((ctx)) {arg_freetable(ctx->argtable, ctx->argtableLen); free((ctx)); (ctx)=NULL;} +#define CLIExecWithReturn(ctx, cmd, atbl, ifempty) if (CLIParserParseString(ctx, cmd, atbl, arg_getsize(atbl), ifempty)) {CLIParserFree((ctx)); return PM3_ESOFT;} +#define CLIGetHexBLessWithReturn(ctx, paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;} +#define CLIGetHexWithReturn(ctx, paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;} +#define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), datalen)) {CLIParserFree((ctx)); return PM3_ESOFT;} -int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp); -int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); -int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData); -int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); -void CLIParserFree(void); +typedef struct { + void **argtable; + size_t argtableLen; + const char *programName; + const char *programHint; + const char *programHelp; + char buf[1024 + 60]; +} CLIParserContext; +int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp); +int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); +int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData); +int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 8945d68a8..9efff1445 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -1,10 +1,11 @@ -add_library(hardnested_nosimd OBJECT +add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(hardnested_nosimd PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) +set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) -target_include_directories(hardnested_nosimd PRIVATE +target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE ../../common ../../include) @@ -18,92 +19,98 @@ message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) message(STATUS "Building optimised x86/x86_64 binaries") - target_compile_options(hardnested_nosimd BEFORE PRIVATE + target_compile_options(pm3rrg_rdv4_hardnested_nosimd BEFORE PRIVATE -mno-mmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) ## x86 / MMX - add_library(hardnested_mmx OBJECT + add_library(pm3rrg_rdv4_hardnested_mmx OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(hardnested_mmx PRIVATE -Wall -Werror -O3) - target_compile_options(hardnested_mmx BEFORE PRIVATE + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) + set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) - target_include_directories(hardnested_mmx PRIVATE + target_include_directories(pm3rrg_rdv4_hardnested_mmx PRIVATE ../../common ../../include) ## x86 / SSE2 - add_library(hardnested_sse2 OBJECT + add_library(pm3rrg_rdv4_hardnested_sse2 OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(hardnested_sse2 PRIVATE -Wall -Werror -O3) - target_compile_options(hardnested_sse2 BEFORE PRIVATE + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) + set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) - target_include_directories(hardnested_sse2 PRIVATE + target_include_directories(pm3rrg_rdv4_hardnested_sse2 PRIVATE ../../common ../../include) ## x86 / AVX - add_library(hardnested_avx OBJECT + add_library(pm3rrg_rdv4_hardnested_avx OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(hardnested_avx PRIVATE -Wall -Werror -O3) - target_compile_options(hardnested_avx BEFORE PRIVATE + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) + set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) - target_include_directories(hardnested_avx PRIVATE + target_include_directories(pm3rrg_rdv4_hardnested_avx PRIVATE ../../common ../../include) ## x86 / AVX2 - add_library(hardnested_avx2 OBJECT + add_library(pm3rrg_rdv4_hardnested_avx2 OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(hardnested_avx2 PRIVATE -Wall -Werror -O3) - target_compile_options(hardnested_avx2 BEFORE PRIVATE + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) + set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) - target_include_directories(hardnested_avx2 PRIVATE + target_include_directories(pm3rrg_rdv4_hardnested_avx2 PRIVATE ../../common ../../include) ## x86 / AVX512 - add_library(hardnested_avx512 OBJECT + add_library(pm3rrg_rdv4_hardnested_avx512 OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(hardnested_avx512 PRIVATE -Wall -Werror -O3) - target_compile_options(hardnested_avx512 BEFORE PRIVATE + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) + set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) - target_include_directories(hardnested_avx512 PRIVATE + target_include_directories(pm3rrg_rdv4_hardnested_avx512 PRIVATE ../../common ../../include) set(SIMD_TARGETS - $ - $ - $ - $ - $) + $ + $ + $ + $ + $) else () message(STATUS "Not building optimised targets") set(SIMD_TARGETS) endif () -add_library(hardnested STATIC +add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c - $ + $ ${SIMD_TARGETS}) -target_include_directories(hardnested PRIVATE +set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) +target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common ../../include ../src jansson) -target_include_directories(hardnested INTERFACE hardnested) +target_include_directories(pm3rrg_rdv4_hardnested INTERFACE hardnested) diff --git a/client/deps/hardnested/hardnested_bf_core.c b/client/deps/hardnested/hardnested_bf_core.c index 4e30dd894..5f4fcf991 100644 --- a/client/deps/hardnested/hardnested_bf_core.c +++ b/client/deps/hardnested/hardnested_bf_core.c @@ -468,7 +468,7 @@ uint64_t CRACK_STATES_BITSLICED(uint32_t cuid, uint8_t *best_first_bytes, statel } // remember feedback and keystream vectors for later use uint8_t bit = KEYSTREAM_SIZE - ks_idx; - if (bit <= next_common_bits) { // if needed and not yet stored + if (bit <= MIN(next_common_bits, 7)) { // if needed and not yet stored fbb[bit] = fb_bits; ksb[bit] = ks_bits; par[bit] = parity_bit_vector; @@ -556,29 +556,31 @@ void SetSIMDInstr(SIMDExecInstr instr) { bitslice_test_nonces_function_p = &bitslice_test_nonces_dispatch; } -static SIMDExecInstr GetSIMDInstr() { - SIMDExecInstr instr = SIMD_NONE; +static SIMDExecInstr GetSIMDInstr(void) { + SIMDExecInstr instr; -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) - if (__builtin_cpu_supports("avx512f")) instr = SIMD_AVX512; - else if (__builtin_cpu_supports("avx2")) instr = SIMD_AVX2; -#else - if (__builtin_cpu_supports("avx2")) instr = SIMD_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) instr = SIMD_AVX; - else if (__builtin_cpu_supports("sse2")) instr = SIMD_SSE2; - else if (__builtin_cpu_supports("mmx")) instr = SIMD_MMX; +#if defined(COMPILER_HAS_SIMD_AVX512) + if (__builtin_cpu_supports("avx512f")) + instr = SIMD_AVX512; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) + instr = SIMD_AVX2; + else if (__builtin_cpu_supports("avx")) + instr = SIMD_AVX; + else if (__builtin_cpu_supports("sse2")) + instr = SIMD_SSE2; + else if (__builtin_cpu_supports("mmx")) + instr = SIMD_MMX; + else #endif - instr = SIMD_NONE; + instr = SIMD_NONE; return instr; } -SIMDExecInstr GetSIMDInstrAuto() { +SIMDExecInstr GetSIMDInstrAuto(void) { SIMDExecInstr instr = intSIMDInstr; if (instr == SIMD_AUTO) return GetSIMDInstr(); @@ -589,13 +591,12 @@ SIMDExecInstr GetSIMDInstrAuto() { // determine the available instruction set at runtime and call the correct function uint64_t crack_states_bitsliced_dispatch(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, uint8_t *bf_test_nonce_2nd_byte, noncelist_t *nonces) { switch (GetSIMDInstrAuto()) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) case SIMD_AVX512: crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX512; break; #endif +#if defined(COMPILER_HAS_SIMD) case SIMD_AVX2: crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX2; break; @@ -609,8 +610,8 @@ uint64_t crack_states_bitsliced_dispatch(uint32_t cuid, uint8_t *best_first_byte crack_states_bitsliced_function_p = &crack_states_bitsliced_MMX; break; #endif -#endif - default: + case SIMD_AUTO: + case SIMD_NONE: crack_states_bitsliced_function_p = &crack_states_bitsliced_NOSIMD; break; } @@ -621,13 +622,12 @@ uint64_t crack_states_bitsliced_dispatch(uint32_t cuid, uint8_t *best_first_byte void bitslice_test_nonces_dispatch(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonce, uint8_t *bf_test_nonce_par) { switch (GetSIMDInstrAuto()) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) case SIMD_AVX512: bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX512; break; #endif +#if defined(COMPILER_HAS_SIMD) case SIMD_AVX2: bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX2; break; @@ -641,8 +641,8 @@ void bitslice_test_nonces_dispatch(uint32_t nonces_to_bruteforce, uint32_t *bf_t bitslice_test_nonces_function_p = &bitslice_test_nonces_MMX; break; #endif -#endif - default: + case SIMD_AUTO: + case SIMD_NONE: bitslice_test_nonces_function_p = &bitslice_test_nonces_NOSIMD; break; } diff --git a/client/deps/hardnested/hardnested_bf_core.h b/client/deps/hardnested/hardnested_bf_core.h index 00b20b786..51eca7de5 100644 --- a/client/deps/hardnested/hardnested_bf_core.h +++ b/client/deps/hardnested/hardnested_bf_core.h @@ -52,13 +52,26 @@ THE SOFTWARE. #include "hardnested_bruteforce.h" // statelist_t +#if ( defined (__i386__) || defined (__x86_64__) ) && \ + ( !defined(__APPLE__) || \ + (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) ) +# define COMPILER_HAS_SIMD +# if defined(COMPILER_HAS_SIMD) && ((__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2)) +# define COMPILER_HAS_SIMD_AVX512 +# endif +#endif + typedef enum { SIMD_AUTO, +#if defined(COMPILER_HAS_SIMD_AVX512) SIMD_AVX512, +#endif +#if defined(COMPILER_HAS_SIMD) SIMD_AVX2, SIMD_AVX, SIMD_SSE2, SIMD_MMX, +#endif SIMD_NONE, } SIMDExecInstr; void SetSIMDInstr(SIMDExecInstr instr); diff --git a/client/deps/hardnested/hardnested_bitarray_core.c b/client/deps/hardnested/hardnested_bitarray_core.c index e9e84aa40..d62da774c 100644 --- a/client/deps/hardnested/hardnested_bitarray_core.c +++ b/client/deps/hardnested/hardnested_bitarray_core.c @@ -17,6 +17,7 @@ // #include "hardnested_bitarray_core.h" +#include "hardnested_bf_core.h" #include #include @@ -305,273 +306,234 @@ count_bitarray_AND4_t *count_bitarray_AND4_function_p = &count_bitarray_AND4_dis // determine the available instruction set at runtime and call the correct function uint32_t *malloc_bitarray_dispatch(uint32_t x) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) malloc_bitarray_function_p = &malloc_bitarray_AVX512; - else if (__builtin_cpu_supports("avx2")) malloc_bitarray_function_p = &malloc_bitarray_AVX2; -#else - if (__builtin_cpu_supports("avx2")) malloc_bitarray_function_p = &malloc_bitarray_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) malloc_bitarray_function_p = &malloc_bitarray_AVX; - else if (__builtin_cpu_supports("sse2")) malloc_bitarray_function_p = &malloc_bitarray_SSE2; - else if (__builtin_cpu_supports("mmx")) malloc_bitarray_function_p = &malloc_bitarray_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) malloc_bitarray_function_p = &malloc_bitarray_AVX2; + else if (__builtin_cpu_supports("avx")) malloc_bitarray_function_p = &malloc_bitarray_AVX; + else if (__builtin_cpu_supports("sse2")) malloc_bitarray_function_p = &malloc_bitarray_SSE2; + else if (__builtin_cpu_supports("mmx")) malloc_bitarray_function_p = &malloc_bitarray_MMX; + else #endif - malloc_bitarray_function_p = &malloc_bitarray_NOSIMD; + malloc_bitarray_function_p = &malloc_bitarray_NOSIMD; // call the most optimized function for this CPU return (*malloc_bitarray_function_p)(x); } void free_bitarray_dispatch(uint32_t *x) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) free_bitarray_function_p = &free_bitarray_AVX512; - else if (__builtin_cpu_supports("avx2")) free_bitarray_function_p = &free_bitarray_AVX2; -#else - if (__builtin_cpu_supports("avx2")) free_bitarray_function_p = &free_bitarray_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) free_bitarray_function_p = &free_bitarray_AVX; - else if (__builtin_cpu_supports("sse2")) free_bitarray_function_p = &free_bitarray_SSE2; - else if (__builtin_cpu_supports("mmx")) free_bitarray_function_p = &free_bitarray_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) free_bitarray_function_p = &free_bitarray_AVX2; + else if (__builtin_cpu_supports("avx")) free_bitarray_function_p = &free_bitarray_AVX; + else if (__builtin_cpu_supports("sse2")) free_bitarray_function_p = &free_bitarray_SSE2; + else if (__builtin_cpu_supports("mmx")) free_bitarray_function_p = &free_bitarray_MMX; + else #endif - free_bitarray_function_p = &free_bitarray_NOSIMD; + free_bitarray_function_p = &free_bitarray_NOSIMD; // call the most optimized function for this CPU (*free_bitarray_function_p)(x); } uint32_t bitcount_dispatch(uint32_t a) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) bitcount_function_p = &bitcount_AVX512; - else if (__builtin_cpu_supports("avx2")) bitcount_function_p = &bitcount_AVX2; -#else - if (__builtin_cpu_supports("avx2")) bitcount_function_p = &bitcount_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) bitcount_function_p = &bitcount_AVX; - else if (__builtin_cpu_supports("sse2")) bitcount_function_p = &bitcount_SSE2; - else if (__builtin_cpu_supports("mmx")) bitcount_function_p = &bitcount_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) bitcount_function_p = &bitcount_AVX2; + else if (__builtin_cpu_supports("avx")) bitcount_function_p = &bitcount_AVX; + else if (__builtin_cpu_supports("sse2")) bitcount_function_p = &bitcount_SSE2; + else if (__builtin_cpu_supports("mmx")) bitcount_function_p = &bitcount_MMX; + else #endif - bitcount_function_p = &bitcount_NOSIMD; + bitcount_function_p = &bitcount_NOSIMD; // call the most optimized function for this CPU return (*bitcount_function_p)(a); } uint32_t count_states_dispatch(uint32_t *bitarray) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) count_states_function_p = &count_states_AVX512; - else if (__builtin_cpu_supports("avx2")) count_states_function_p = &count_states_AVX2; -#else - if (__builtin_cpu_supports("avx2")) count_states_function_p = &count_states_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) count_states_function_p = &count_states_AVX; - else if (__builtin_cpu_supports("sse2")) count_states_function_p = &count_states_SSE2; - else if (__builtin_cpu_supports("mmx")) count_states_function_p = &count_states_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) count_states_function_p = &count_states_AVX2; + else if (__builtin_cpu_supports("avx")) count_states_function_p = &count_states_AVX; + else if (__builtin_cpu_supports("sse2")) count_states_function_p = &count_states_SSE2; + else if (__builtin_cpu_supports("mmx")) count_states_function_p = &count_states_MMX; + else #endif - count_states_function_p = &count_states_NOSIMD; + count_states_function_p = &count_states_NOSIMD; // call the most optimized function for this CPU return (*count_states_function_p)(bitarray); } void bitarray_AND_dispatch(uint32_t *A, uint32_t *B) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) bitarray_AND_function_p = &bitarray_AND_AVX512; - else if (__builtin_cpu_supports("avx2")) bitarray_AND_function_p = &bitarray_AND_AVX2; -#else - if (__builtin_cpu_supports("avx2")) bitarray_AND_function_p = &bitarray_AND_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) bitarray_AND_function_p = &bitarray_AND_AVX; - else if (__builtin_cpu_supports("sse2")) bitarray_AND_function_p = &bitarray_AND_SSE2; - else if (__builtin_cpu_supports("mmx")) bitarray_AND_function_p = &bitarray_AND_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) bitarray_AND_function_p = &bitarray_AND_AVX2; + else if (__builtin_cpu_supports("avx")) bitarray_AND_function_p = &bitarray_AND_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_AND_function_p = &bitarray_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_AND_function_p = &bitarray_AND_MMX; + else #endif - bitarray_AND_function_p = &bitarray_AND_NOSIMD; + bitarray_AND_function_p = &bitarray_AND_NOSIMD; // call the most optimized function for this CPU (*bitarray_AND_function_p)(A, B); } void bitarray_low20_AND_dispatch(uint32_t *A, uint32_t *B) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX512; - else if (__builtin_cpu_supports("avx2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX2; -#else - if (__builtin_cpu_supports("avx2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX; - else if (__builtin_cpu_supports("sse2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_SSE2; - else if (__builtin_cpu_supports("mmx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX2; + else if (__builtin_cpu_supports("avx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_MMX; + else #endif - bitarray_low20_AND_function_p = &bitarray_low20_AND_NOSIMD; + bitarray_low20_AND_function_p = &bitarray_low20_AND_NOSIMD; // call the most optimized function for this CPU (*bitarray_low20_AND_function_p)(A, B); } uint32_t count_bitarray_AND_dispatch(uint32_t *A, uint32_t *B) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX512; - else if (__builtin_cpu_supports("avx2")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX2; -#else - if (__builtin_cpu_supports("avx2")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX; - else if (__builtin_cpu_supports("sse2")) count_bitarray_AND_function_p = &count_bitarray_AND_SSE2; - else if (__builtin_cpu_supports("mmx")) count_bitarray_AND_function_p = &count_bitarray_AND_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX2; + else if (__builtin_cpu_supports("avx")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND_function_p = &count_bitarray_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND_function_p = &count_bitarray_AND_MMX; + else #endif - count_bitarray_AND_function_p = &count_bitarray_AND_NOSIMD; + count_bitarray_AND_function_p = &count_bitarray_AND_NOSIMD; // call the most optimized function for this CPU return (*count_bitarray_AND_function_p)(A, B); } uint32_t count_bitarray_low20_AND_dispatch(uint32_t *A, uint32_t *B) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX512; - else if (__builtin_cpu_supports("avx2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX2; -#else - if (__builtin_cpu_supports("avx2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX; - else if (__builtin_cpu_supports("sse2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_SSE2; - else if (__builtin_cpu_supports("mmx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX2; + else if (__builtin_cpu_supports("avx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_MMX; + else #endif - count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_NOSIMD; + count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_NOSIMD; // call the most optimized function for this CPU return (*count_bitarray_low20_AND_function_p)(A, B); } void bitarray_AND4_dispatch(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) bitarray_AND4_function_p = &bitarray_AND4_AVX512; - else if (__builtin_cpu_supports("avx2")) bitarray_AND4_function_p = &bitarray_AND4_AVX2; -#else - if (__builtin_cpu_supports("avx2")) bitarray_AND4_function_p = &bitarray_AND4_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) bitarray_AND4_function_p = &bitarray_AND4_AVX; - else if (__builtin_cpu_supports("sse2")) bitarray_AND4_function_p = &bitarray_AND4_SSE2; - else if (__builtin_cpu_supports("mmx")) bitarray_AND4_function_p = &bitarray_AND4_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) bitarray_AND4_function_p = &bitarray_AND4_AVX2; + else if (__builtin_cpu_supports("avx")) bitarray_AND4_function_p = &bitarray_AND4_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_AND4_function_p = &bitarray_AND4_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_AND4_function_p = &bitarray_AND4_MMX; + else #endif - bitarray_AND4_function_p = &bitarray_AND4_NOSIMD; + bitarray_AND4_function_p = &bitarray_AND4_NOSIMD; // call the most optimized function for this CPU (*bitarray_AND4_function_p)(A, B, C, D); } void bitarray_OR_dispatch(uint32_t *A, uint32_t *B) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) bitarray_OR_function_p = &bitarray_OR_AVX512; - else if (__builtin_cpu_supports("avx2")) bitarray_OR_function_p = &bitarray_OR_AVX2; -#else - if (__builtin_cpu_supports("avx2")) bitarray_OR_function_p = &bitarray_OR_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) bitarray_OR_function_p = &bitarray_OR_AVX; - else if (__builtin_cpu_supports("sse2")) bitarray_OR_function_p = &bitarray_OR_SSE2; - else if (__builtin_cpu_supports("mmx")) bitarray_OR_function_p = &bitarray_OR_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) bitarray_OR_function_p = &bitarray_OR_AVX2; + else if (__builtin_cpu_supports("avx")) bitarray_OR_function_p = &bitarray_OR_AVX; + else if (__builtin_cpu_supports("sse2")) bitarray_OR_function_p = &bitarray_OR_SSE2; + else if (__builtin_cpu_supports("mmx")) bitarray_OR_function_p = &bitarray_OR_MMX; + else #endif - bitarray_OR_function_p = &bitarray_OR_NOSIMD; + bitarray_OR_function_p = &bitarray_OR_NOSIMD; // call the most optimized function for this CPU (*bitarray_OR_function_p)(A, B); } uint32_t count_bitarray_AND2_dispatch(uint32_t *A, uint32_t *B) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX512; - else if (__builtin_cpu_supports("avx2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX2; -#else - if (__builtin_cpu_supports("avx2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX; - else if (__builtin_cpu_supports("sse2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_SSE2; - else if (__builtin_cpu_supports("mmx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX2; + else if (__builtin_cpu_supports("avx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_MMX; + else #endif - count_bitarray_AND2_function_p = &count_bitarray_AND2_NOSIMD; + count_bitarray_AND2_function_p = &count_bitarray_AND2_NOSIMD; // call the most optimized function for this CPU return (*count_bitarray_AND2_function_p)(A, B); } uint32_t count_bitarray_AND3_dispatch(uint32_t *A, uint32_t *B, uint32_t *C) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX512; - else if (__builtin_cpu_supports("avx2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX2; -#else - if (__builtin_cpu_supports("avx2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX; - else if (__builtin_cpu_supports("sse2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_SSE2; - else if (__builtin_cpu_supports("mmx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX2; + else if (__builtin_cpu_supports("avx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_MMX; + else #endif - count_bitarray_AND3_function_p = &count_bitarray_AND3_NOSIMD; + count_bitarray_AND3_function_p = &count_bitarray_AND3_NOSIMD; // call the most optimized function for this CPU return (*count_bitarray_AND3_function_p)(A, B, C); } uint32_t count_bitarray_AND4_dispatch(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { -#if defined (__i386__) || defined (__x86_64__) -#if !defined(__APPLE__) || (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) -#if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) +#if defined(COMPILER_HAS_SIMD_AVX512) if (__builtin_cpu_supports("avx512f")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX512; - else if (__builtin_cpu_supports("avx2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX2; -#else - if (__builtin_cpu_supports("avx2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX2; -#endif - else if (__builtin_cpu_supports("avx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX; - else if (__builtin_cpu_supports("sse2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_SSE2; - else if (__builtin_cpu_supports("mmx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_MMX; else #endif +#if defined(COMPILER_HAS_SIMD) + if (__builtin_cpu_supports("avx2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX2; + else if (__builtin_cpu_supports("avx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX; + else if (__builtin_cpu_supports("sse2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_SSE2; + else if (__builtin_cpu_supports("mmx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_MMX; + else #endif - count_bitarray_AND4_function_p = &count_bitarray_AND4_NOSIMD; + count_bitarray_AND4_function_p = &count_bitarray_AND4_NOSIMD; // call the most optimized function for this CPU return (*count_bitarray_AND4_function_p)(A, B, C, D); diff --git a/client/deps/hardnested/hardnested_bruteforce.c b/client/deps/hardnested/hardnested_bruteforce.c index 159454110..82f8c6c04 100644 --- a/client/deps/hardnested/hardnested_bruteforce.c +++ b/client/deps/hardnested/hardnested_bruteforce.c @@ -433,7 +433,7 @@ static bool read_bench_data(statelist_t *test_candidates) { } -float brute_force_benchmark() { +float brute_force_benchmark(void) { statelist_t test_candidates[NUM_BRUTE_FORCE_THREADS]; test_candidates[0].states[ODD_STATE] = malloc((TEST_BENCH_SIZE + 1) * sizeof(uint32_t)); diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index 216f7a830..c91a47047 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -1,4 +1,4 @@ -add_library(jansson STATIC +add_library(pm3rrg_rdv4_jansson STATIC jansson/dump.c jansson/error.c jansson/hashtable.c @@ -9,10 +9,10 @@ add_library(jansson STATIC jansson/strbuffer.c jansson/strconv.c jansson/utf.c - jansson/path.c jansson/value.c ) -target_compile_definitions(jansson PRIVATE HAVE_STDINT_H) -target_include_directories(jansson INTERFACE jansson) -target_compile_options(jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) +target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) +target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) +set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/jansson/Makefile b/client/deps/jansson/Makefile index 152e8bcb9..b51c4a77c 100644 --- a/client/deps/jansson/Makefile +++ b/client/deps/jansson/Makefile @@ -1,6 +1,6 @@ MYSRCPATHS = MYINCLUDES = -I. -MYCFLAGS = -Wno-unused-function +MYCFLAGS = -Wno-unused-function -Wno-cast-align -Wno-bad-function-cast -Wno-switch-enum MYDEFS = -DHAVE_STDINT_H MYSRCS = \ dump.c \ @@ -13,7 +13,6 @@ MYSRCS = \ strbuffer.c \ strconv.c \ utf.c \ - path.c \ value.c LIB_A = libjansson.a diff --git a/client/deps/jansson/hashtable.c b/client/deps/jansson/hashtable.c index 38c10a0c7..23fbc867b 100644 --- a/client/deps/jansson/hashtable.c +++ b/client/deps/jansson/hashtable.c @@ -5,14 +5,14 @@ * it under the terms of the MIT license. See LICENSE for details. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include #endif #include #include -#if HAVE_STDINT_H +#ifdef HAVE_STDINT_H #include #endif diff --git a/client/deps/jansson/hashtable_seed.c b/client/deps/jansson/hashtable_seed.c index 3856691d3..715279879 100644 --- a/client/deps/jansson/hashtable_seed.c +++ b/client/deps/jansson/hashtable_seed.c @@ -162,7 +162,7 @@ static int seed_from_timestamp_and_pid(uint32_t *seed) { return 0; } -static uint32_t generate_seed() { +static uint32_t generate_seed(void) { uint32_t seed = 0; int done = 0; diff --git a/client/deps/jansson/jansson.h b/client/deps/jansson/jansson.h index 0f868c2f2..75cbb5d51 100644 --- a/client/deps/jansson/jansson.h +++ b/client/deps/jansson/jansson.h @@ -302,14 +302,6 @@ int json_equal(const json_t *json1, const json_t *json2); json_t *json_copy(json_t *json) JANSSON_ATTRS(warn_unused_result); json_t *json_deep_copy(const json_t *json) JANSSON_ATTRS(warn_unused_result); -json_t *json_path_get(const json_t *json, const char *path); -int json_path_set_new(json_t *json, const char *path, json_t *value, size_t flags, json_error_t *error); - -static JSON_INLINE -int json_path_set(json_t *json, const char *path, json_t *value, size_t flags, json_error_t *error) { - return json_path_set_new(json, path, json_incref(value), flags, error); -} - /* decoding */ #define JSON_REJECT_DUPLICATES 0x1 diff --git a/client/deps/jansson/load.c b/client/deps/jansson/load.c index 7f3fa7458..52b9bed89 100644 --- a/client/deps/jansson/load.c +++ b/client/deps/jansson/load.c @@ -1040,8 +1040,6 @@ json_t *json_loadfd(int input, size_t flags, json_error_t *error) { json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { json_t *result; - FILE *fp; - jsonp_error_init(error, path); if (path == NULL) { @@ -1049,15 +1047,13 @@ json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { return NULL; } - fp = fopen(path, "rb"); + FILE *fp = fopen(path, "rb"); if (!fp) { - error_set(error, NULL, json_error_cannot_open_file, "unable to open %s: %s", - path, strerror(errno)); + error_set(error, NULL, json_error_cannot_open_file, "unable to open %s: %s", path, strerror(errno)); return NULL; } result = json_loadf(fp, flags, error); - fclose(fp); return result; } diff --git a/client/deps/liblua/Makefile b/client/deps/liblua/Makefile index 54e45185b..e2cf7baa3 100644 --- a/client/deps/liblua/Makefile +++ b/client/deps/liblua/Makefile @@ -1,7 +1,7 @@ MYSRCPATHS = MYINCLUDES = -I. # Lua lib requires GNU extensions (implicit declarations of functions): -std=gnu99 or -std=gnu11 -MYCFLAGS = +MYCFLAGS = -Wno-cast-align -Wno-bad-function-cast -Wno-switch-enum MYDEFS = -DLUA_COMPAT_ALL $(SYSCFLAGS) MYSRCS = lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \ lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \ diff --git a/client/deps/liblua/llex.c b/client/deps/liblua/llex.c index 3f0a1601b..bde26fa4f 100644 --- a/client/deps/liblua/llex.c +++ b/client/deps/liblua/llex.c @@ -197,7 +197,7 @@ static void buffreplace(LexState *ls, char from, char to) { } -#if ANDROID +#if defined(ANDROID) #define getlocaldecpoint() '.' #elif !defined(getlocaledecpoint) #define getlocaledecpoint() (localeconv()->decimal_point[0]) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 3850863b5..12870342e 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -1,4 +1,4 @@ -add_library(lua STATIC +add_library(pm3rrg_rdv4_lua STATIC liblua/lapi.c liblua/lcode.c liblua/lctype.c @@ -33,16 +33,24 @@ add_library(lua STATIC liblua/linit.c ) -target_compile_definitions(lua PRIVATE LUA_COMPAT_ALL) +target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_COMPAT_ALL) if (NOT MINGW) if (APPLE) - target_compile_definitions(lua PRIVATE LUA_USE_MACOSX) + target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_MACOSX) + elseif (ANDROID) + # Required: + add_definitions(-D"getlocaledecpoint\(\)='.'") + # Same as for LUA_USE_LINUX except LUA_USE_POSIX and client-specific LUA_USE_READLINE + target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_DLOPEN LUA_USE_STRTODHEX LUA_USE_AFORMAT LUA_USE_LONGLONG) + # Same as for LUA_USE_POSIX except client-specific LUA_USE_ISATTY. LUA_USE_MKSTEMP is needed. + target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_MKSTEMP LUA_USE_POPEN LUA_USE_ULONGJMP LUA_USE_GMTIME_R) else (APPLE) - target_compile_definitions(lua PRIVATE LUA_USE_LINUX) - target_link_libraries(lua INTERFACE dl) + target_compile_definitions(pm3rrg_rdv4_lua PRIVATE LUA_USE_LINUX) + target_link_libraries(pm3rrg_rdv4_lua INTERFACE dl) endif (APPLE) endif (NOT MINGW) -target_include_directories(lua INTERFACE liblua) -target_compile_options(lua PRIVATE -Wall -Werror -O3) +target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) +set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index 932c1757c..b18537c84 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -1,4 +1,4 @@ -add_library(mbedtls STATIC +add_library(pm3rrg_rdv4_mbedtls STATIC ../../common/mbedtls/aes.c ../../common/mbedtls/asn1parse.c ../../common/mbedtls/asn1write.c @@ -44,5 +44,7 @@ add_library(mbedtls STATIC ../../common/mbedtls/x509_crt.c ) -target_include_directories(mbedtls PRIVATE ../../common) -target_compile_options(mbedtls PRIVATE -Wall -Werror -O3) +target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) +target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) +set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index 0d24c9d49..d7e3cfd8a 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -1,4 +1,4 @@ -add_library(reveng STATIC +add_library(pm3rrg_rdv4_reveng STATIC reveng/bmpbit.c reveng/cli.c reveng/model.c @@ -7,7 +7,11 @@ add_library(reveng STATIC reveng/reveng.c ) -target_compile_definitions(reveng PRIVATE PRESETS) -target_include_directories(reveng PRIVATE ../cliparser) -target_include_directories(reveng INTERFACE reveng) -target_compile_options(reveng PRIVATE -Wall -Werror -O3) +target_compile_definitions(pm3rrg_rdv4_reveng PRIVATE PRESETS) +target_include_directories(pm3rrg_rdv4_reveng PRIVATE + cliparser + ../src + ../../include) +target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) +set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng/Makefile b/client/deps/reveng/Makefile index 1794b0bdb..d0382771d 100644 --- a/client/deps/reveng/Makefile +++ b/client/deps/reveng/Makefile @@ -4,7 +4,7 @@ # Add -DPRESETS to compile with preset models (edit config.h) MYSRCPATHS = -MYINCLUDES = -I../cliparser +MYINCLUDES = -I../cliparser -I../../src -I../../../include MYCFLAGS = MYDEFS = -DPRESETS MYSRCS = \ @@ -22,6 +22,7 @@ MYCLEANOLDPATH = ../../reveng include ../../../Makefile.host +ifneq ($(SKIPREVENGTEST),1) CLEAN += bmptst $(BINDIR)/$(LIB_A): $(BINDIR)/bmptst @@ -31,5 +32,6 @@ $(BINDIR)/bmptst: bmpbit.c config.h reveng.h $(Q)$(CC) $(CFLAGS) -DBMPTST -o $@ $< $(info [=] TEST $@) $(Q)( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) ) +endif .PHONY: all clean diff --git a/client/deps/reveng/bmpbit.c b/client/deps/reveng/bmpbit.c index e44ddb250..522d71ecc 100644 --- a/client/deps/reveng/bmpbit.c +++ b/client/deps/reveng/bmpbit.c @@ -30,6 +30,12 @@ #endif #include "reveng.h" +#ifdef BMPTST +# undef fprintf +# undef puts +# undef fputs +#endif + #if (defined BMPTST) || (BMP_BIT < 32) /* Size in bits of a bmp_t. Not necessarily a power of two. */ int bmpbit; diff --git a/client/deps/reveng/cli.c b/client/deps/reveng/cli.c index 9d849dfc3..88e8d3722 100644 --- a/client/deps/reveng/cli.c +++ b/client/deps/reveng/cli.c @@ -97,7 +97,10 @@ int reveng_main(int argc, char *argv[]) { SETBMP(); // pos=0; --- not in this ver of getopt + int err = 0; optind = 1; + // Remember to consume always all the option string till getopt returns -1 ! + // else next invocations will be corrupted do { c = getopt(argc, argv, "?A:BDFGLMP:SVXa:bcdefhi:k:lm:p:q:rstuvw:x:yz"); switch (c) { @@ -105,8 +108,8 @@ int reveng_main(int argc, char *argv[]) { case 'a': /* a: bits per character */ if ((obperhx = atoi(optarg)) > BMP_BIT) { fprintf(stderr, "%s: argument to -%c must be between 1 and %d\n", myname, c, BMP_BIT); - return 0; - //exit(EXIT_FAILURE); + err = 1; + break; } if (c == 'a') ibperhx = obperhx; break; @@ -130,8 +133,8 @@ int reveng_main(int argc, char *argv[]) { case 'v': /* v calculate reversed CRC */ if (mode) { fprintf(stderr, "%s: more than one mode switch specified. Use %s -h for help.\n", myname, myname); - return 0; - //exit(EXIT_FAILURE); + err = 1; + break; } mode = c; break; @@ -151,8 +154,7 @@ int reveng_main(int argc, char *argv[]) { case '?': /* ? get help / usage */ default: usage(); - return 0; - //exit(EXIT_FAILURE); + err = 1; break; case 'i': /* i: Init value */ pptr = &model.init; @@ -184,12 +186,13 @@ int reveng_main(int argc, char *argv[]) { case 'm': /* m: select preset CRC model */ if (!(c = mbynam(&model, optarg))) { fprintf(stderr, "%s: preset model '%s' not found. Use %s -D to list presets.\n", myname, optarg, myname); - return 0; - //exit(EXIT_FAILURE); + err = 1; + break; } if (c < 0) { uerror("no preset models available"); - return 0; + err = 1; + break; } /* must set width so that parameter to -ipx is not zeroed */ width = plen(model.spoly); @@ -246,6 +249,9 @@ ipqx: } } while (c != -1); + if (err) + return 0; + /* canonicalise the model, so the one we dump is the one we * calculate with (not with -s, spoly may be blank which will * normalise to zero and clear init and xorout.) diff --git a/client/deps/reveng/config.h b/client/deps/reveng/config.h index 94d3c4da5..177df030e 100644 --- a/client/deps/reveng/config.h +++ b/client/deps/reveng/config.h @@ -101,4 +101,10 @@ * * *****************************************/ +// Proxmark3 stdout/stderr hooking +#include "ui.h" +#define fprintf(stream, ...) PrintAndLogEx(INFO, __VA_ARGS__) +#define fputs(s, stream) PrintAndLogEx(INFO, "%s", s) +#define puts(s) PrintAndLogEx(SUCCESS, "%s", s) + #endif /* CONFIG_H */ diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index 14ebb5326..5a6abda25 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -1,4 +1,4 @@ -add_library(tinycbor STATIC +add_library(pm3rrg_rdv4_tinycbor STATIC tinycbor/cborencoder.c tinycbor/cborencoder_close_container_checked.c tinycbor/cborerrorstrings.c @@ -9,6 +9,7 @@ add_library(tinycbor STATIC tinycbor/cborvalidation.c ) -target_include_directories(tinycbor INTERFACE tinycbor) +target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(tinycbor PRIVATE -Wall -Werror -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) +set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor/Makefile b/client/deps/tinycbor/Makefile index 99039ac98..b50c1584f 100644 --- a/client/deps/tinycbor/Makefile +++ b/client/deps/tinycbor/Makefile @@ -1,7 +1,7 @@ MYSRCPATHS = MYINCLUDES = # Strange errors on Mingw when compiling with C99 -MYCFLAGS = +MYCFLAGS = -Wno-bad-function-cast -Wno-redundant-decls -Wno-incompatible-pointer-types-discards-qualifiers -Wno-discarded-qualifiers -Wno-unknown-warning-option -Wno-maybe-uninitialized -Wno-conversion MYDEFS = MYSRCS = \ cborencoder.c \ @@ -18,7 +18,4 @@ LIB_A = tinycbor.a # Transition: remove old directories and objects MYCLEANOLDPATH = ../../tinycbor -# Strange errors on Mingw when compiling with -O3 -CFLAGS ?= -Wall -Werror -O2 - include ../../../Makefile.host diff --git a/client/deps/tinycbor/cbor.h b/client/deps/tinycbor/cbor.h index 238a2717f..e595caeb1 100644 --- a/client/deps/tinycbor/cbor.h +++ b/client/deps/tinycbor/cbor.h @@ -555,8 +555,11 @@ enum CborPrettyFlags { CborPrettyDefaultFlags = CborPrettyIndicateIndeterminateLength }; +/* cf https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ */ typedef CborError(*CborStreamFunction)(void *token, const char *fmt, ...) -#ifdef __GNUC__ +#if defined(__MINGW32__) || defined(__MINGW64__) +__attribute__((format(__MINGW_PRINTF_FORMAT, 2, 3))); +#elif defined(__GNUC__) __attribute__((__format__(printf, 2, 3))) #endif ; diff --git a/client/deps/tinycbor/open_memstream.c b/client/deps/tinycbor/open_memstream.c index 098bf90fe..7a134286f 100644 --- a/client/deps/tinycbor/open_memstream.c +++ b/client/deps/tinycbor/open_memstream.c @@ -36,7 +36,7 @@ # include #endif -#ifdef __APPLE__ || defined(__ANDROID__) || defined(ANDROID) +#if defined(__APPLE__) || defined(__ANDROID__) || defined(ANDROID) typedef int RetType; typedef int LenType; #elif __GLIBC__ @@ -102,7 +102,7 @@ FILE *open_memstream(char **bufptr, size_t *lenptr) { *bufptr = NULL; *lenptr = 0; -#ifdef __APPLE__ || defined(__ANDROID__) || defined(ANDROID) +#if defined(__APPLE__) || defined(__ANDROID__) || defined(ANDROID) return funopen(b, NULL, write_to_buffer, NULL, close_buffer); #elif __GLIBC__ static const cookie_io_functions_t vtable = { diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake new file mode 100644 index 000000000..d2d6a5b2a --- /dev/null +++ b/client/deps/whereami.cmake @@ -0,0 +1,6 @@ +add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) + +target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) +target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) +set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami/Makefile b/client/deps/whereami/Makefile new file mode 100644 index 000000000..c25e4b056 --- /dev/null +++ b/client/deps/whereami/Makefile @@ -0,0 +1,9 @@ +MYSRCPATHS = +MYINCLUDES = +MYCFLAGS = +MYDEFS = -DWAI_PM3_TUNED +MYSRCS = whereami.c + +LIB_A = libwhereami.a + +include ../../../Makefile.host diff --git a/client/src/whereami.c b/client/deps/whereami/whereami.c similarity index 90% rename from client/src/whereami.c rename to client/deps/whereami/whereami.c index 30d70c4d9..ca2220953 100644 --- a/client/src/whereami.c +++ b/client/deps/whereami/whereami.c @@ -3,9 +3,7 @@ // by Gregory Pakosz (@gpakosz) // https://github.com/gpakosz/whereami -#ifdef __cplusplus -extern "C" { -#endif +#ifdef WAI_PM3_TUNED #include "whereami.h" @@ -14,6 +12,19 @@ extern "C" { #define _DEFAULT_SOURCE #endif +#else // WAI_PM3_TUNED + +// in case you want to #include "whereami.c" in a larger compilation unit +#if !defined(WHEREAMI_H) +#include +#endif + +#endif // WAI_PM3_TUNED + +#ifdef __cplusplus +extern "C" { +#endif + #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC) #include #endif @@ -50,11 +61,14 @@ extern "C" { #if defined(_WIN32) +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #if defined(_MSC_VER) #pragma warning(push, 3) #endif #include +#include #if defined(_MSC_VER) #pragma warning(pop) #endif @@ -123,36 +137,36 @@ static int WAI_PREFIX(getModulePath_)(HMODULE module, char *out, int capacity, i return length; } -WAI_NOINLINE -WAI_FUNCSPEC +WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) { return WAI_PREFIX(getModulePath_)(NULL, out, capacity, dirname_length); } // GetModuleHandleEx() is not available on old mingw environments. We don't need getModulePath() yet. // Sacrifice it for the time being to improve backwards compatibility -/* WAI_NOINLINE -WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - HMODULE module; - int length = -1; +#ifndef WAI_PM3_TUNED + +WAI_NOINLINE WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { + HMODULE module; + int length = -1; #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4054) #endif - if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module)) + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module)) #if defined(_MSC_VER) #pragma warning(pop) #endif - { - length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length); - } + { + length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length); + } - return length; + return length; } -*/ + +#endif // WAI_PM3_TUNED #elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun) || defined(WAI_USE_PROC_SELF_EXE) @@ -228,14 +242,14 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) #include #endif -WAI_NOINLINE -WAI_FUNCSPEC +#ifndef WAI_PM3_TUNED + +WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { int length = -1; FILE *maps = NULL; - int i; - for (i = 0; i < WAI_PROC_SELF_MAPS_RETRY; ++i) { + for (int r = 0; r < WAI_PROC_SELF_MAPS_RETRY; ++r) { maps = fopen(WAI_PROC_SELF_MAPS, "r"); if (!maps) break; @@ -252,8 +266,8 @@ int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { if (!fgets(buffer, sizeof(buffer), maps)) break; - if (sscanf(buffer, "%" SCNx64 "-%" SCNx64 " %s %" SCNx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8) { - uint64_t addr = (uint64_t)(uintptr_t)WAI_RETURN_ADDRESS(); + if (sscanf(buffer, "%" PRIx64 "-%" PRIx64 " %s %" PRIx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8) { + uint64_t addr = (uintptr_t)WAI_RETURN_ADDRESS(); if (low <= addr && addr <= high) { char *resolved; @@ -299,9 +313,11 @@ int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { memcpy(out, resolved, length); if (dirname_length) { - for (int j = length - 1; j >= 0; --j) { - if (out[j] == '/') { - *dirname_length = j; + int i; + + for (i = length - 1; i >= 0; --i) { + if (out[i] == '/') { + *dirname_length = i; break; } } @@ -325,6 +341,7 @@ int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { return length; } +#endif // WAI_PM3_TUNED #elif defined(__APPLE__) @@ -380,8 +397,9 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) return length; } -WAI_NOINLINE -WAI_FUNCSPEC +#ifndef WAI_PM3_TUNED + +WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { char buffer[PATH_MAX]; char *resolved = NULL; @@ -418,6 +436,8 @@ int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { return length; } +#endif // WAI_PM3_TUNED + #elif defined(__QNXNTO__) #include @@ -474,6 +494,8 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) return length; } +#ifndef WAI_PM3_TUNED + WAI_FUNCSPEC int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { char buffer[PATH_MAX]; @@ -511,11 +533,12 @@ int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { return length; } +#endif // WAI_PM3_TUNED + #elif defined(__DragonFly__) || defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || defined(__NetBSD__) #include -#include #include #include #include @@ -531,8 +554,8 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) int length = -1; for (;;) { -#ifdef KERN_PROC_ARGV - int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; +#if defined(__NetBSD__) + int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME }; #else int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; #endif @@ -570,8 +593,9 @@ int WAI_PREFIX(getExecutablePath)(char *out, int capacity, int *dirname_length) return length; } -WAI_NOINLINE -WAI_FUNCSPEC +#ifndef WAI_PM3_TUNED + +WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { char buffer[PATH_MAX]; char *resolved = NULL; @@ -608,6 +632,8 @@ int WAI_PREFIX(getModulePath)(char *out, int capacity, int *dirname_length) { return length; } +#endif // WAI_PM3_TUNED + #else #error unsupported platform diff --git a/client/src/whereami.h b/client/deps/whereami/whereami.h similarity index 100% rename from client/src/whereami.h rename to client/deps/whereami/whereami.h diff --git a/client/deps/zlib.cmake b/client/deps/zlib.cmake deleted file mode 100644 index dc6044f80..000000000 --- a/client/deps/zlib.cmake +++ /dev/null @@ -1,12 +0,0 @@ -add_library(z STATIC - ../../common/zlib/deflate.c - ../../common/zlib/adler32.c - ../../common/zlib/trees.c - ../../common/zlib/zutil.c - ../../common/zlib/inflate.c - ../../common/zlib/inffast.c - ../../common/zlib/inftrees.c -) - -target_compile_definitions(z PRIVATE Z_SOLO NO_GZIP ZLIB_PM3_TUNED) -target_compile_options(z PRIVATE -Wall -Werror -O3) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 6e2a2f4da..26f1f938e 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -741,7 +741,6 @@ D3A297DC2698 9EA3387A63C1 A3FAA6DAFF67 A7141147D430 -AAFB06045877 ACFFFFFFFFFF AFCEF64C9913 B27ADDFB64B0 @@ -763,7 +762,6 @@ FD8705E721B0 00ada2cd516d # # -D3F7D3F7D3F7 ## 237a4d0d9119 0ed7846c2bc9 @@ -1068,7 +1066,6 @@ a2a3cca2a3cc 385efa542907 3864fcba5937 3f3865fccb69 -5c8ff9990da2 6291b3860fc8 63fca9492f38 863fcb959373 @@ -1114,7 +1111,6 @@ fe04ecfe5577 5a7a52d5e20d # Bosch Solution 6000 # # Found in TagInfo app -8A19D40CF2B5 # Hotel key card key C1E51C63B8F5 # RATB key 1DB710648A65 18F34C92A56E # E-GO card key diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index 511be26d1..c35014d79 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -24,6 +24,8 @@ A5B4C3D2 575F4F4B # 50520901 +# default PROX +50524F58 # Default pwd, simple: 00000000 11111111 diff --git a/client/luascripts/test_t55x7.lua b/client/luascripts/test_t55x7.lua index b92375520..4be0ed4b6 100644 --- a/client/luascripts/test_t55x7.lua +++ b/client/luascripts/test_t55x7.lua @@ -9,7 +9,7 @@ local floor = math.floor copyright = '' author = "Iceman" -version = 'v1.0.2' +version = 'v1.0.3' desc =[[ This script will program a T55x7 TAG with a configuration and four blocks of data. It will then try to detect and read back those block data and compare if read data matches the expected data. @@ -31,12 +31,17 @@ testsuit for T55XX commands demodulation ]] example = [[ 1. script run test_t55x7 + 2. script run test_t55x7 -t FSK2A + 3. script run test_t55x7 -t PSK1 ]] usage = [[ -script run test_t55x7 [-h] +script run test_t55x7 [-h] [-t ]] arguments = [[ -h this help + -t (optional, defaults to ASK) 'PSK1', 'PSK2', 'PSK3', + 'FSK1', 'FSK2', 'FSK1A', 'FSK2A', + 'ASK', 'BI' ]] local DEBUG = true -- the debug flag @@ -303,9 +308,11 @@ local function main(args) print( string.rep('--',20) ) print( string.rep('--',20) ) + local modulation_type = 'ASK' -- Arguments for the script - for o, arg in getopt.getopt(args, 'h') do + for o, arg in getopt.getopt(args, 'ht:') do if o == 'h' then return help() end + if o == 't' then modulation_type = arg end end core.clearCommandBuffer() @@ -313,7 +320,8 @@ local function main(args) -- Adjust this table to set which configurations should be tested -- local test_modes = { 'PSK1', 'PSK2', 'PSK3', 'FSK1', 'FSK2', 'FSK1A', 'FSK2A', 'ASK', 'BI' } - local test_modes = { 'ASK' } + --local test_modes = { 'PSK1' } + local test_modes = { modulation_type } for _ = 1, #test_modes do res = WipeCard() diff --git a/client/luascripts/test_t55x7_psk.lua b/client/luascripts/test_t55x7_psk.lua index 0c991dcb0..361b231c4 100644 --- a/client/luascripts/test_t55x7_psk.lua +++ b/client/luascripts/test_t55x7_psk.lua @@ -6,7 +6,7 @@ local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.2' +version = 'v1.0.3' desc = [[ This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040 The outlined procedure is as following: @@ -31,7 +31,6 @@ In all 12 individual test for the PSK demod ]] example = [[ 1. script run test_t55x7_psk - 2. script run test_t55x7_psk -o ]] usage = [[ script run test_t55x7_psk [-h] diff --git a/client/luascripts/tracetest.lua b/client/luascripts/tracetest.lua index c1917b401..b7e931b99 100644 --- a/client/luascripts/tracetest.lua +++ b/client/luascripts/tracetest.lua @@ -7,15 +7,15 @@ local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.2' +version = 'v1.0.3' desc = [[ -This script will load several traces files in ../traces/ folder and do +This script will load several traces files in current working directory/traces/ folder and do "data load" "lf search 1 u" The following tracefiles will be loaded: em*.pm3 - m*.pm3 + modulation*.pm3 ]] example = [[ 1. script run tracetest @@ -78,8 +78,10 @@ local function main(args) print( string.rep('--',20) ) local cmdDataLoad = 'data load %s'; - local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f" - local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f" + local cwd = core.cwd(); + + local tracesEM = "find '"..cwd.."/traces/ ' -iname 'em*.pm3' -type f" + local tracesMOD = "find '"..cwd.."/traces/' -iname 'modulation*.pm3' -type f" local write2File = false local outputTemplate = os.date('testtest_%Y-%m-%d_%H%M%S') @@ -100,7 +102,7 @@ local function main(args) end p.close(); - -- Find a set of traces staring with MOD + -- Find a set of traces staring with MODULATION p = assert( io.popen(tracesMOD) ) for file in p:lines() do table.insert(files, file) diff --git a/client/pyscripts/findbits.py b/client/pyscripts/findbits.py new file mode 100755 index 000000000..809465a2e --- /dev/null +++ b/client/pyscripts/findbits.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 + +# findbits.py - find Binary, Octal, Decimal or Hex number in bitstream +# +# Adam Laurie +# http://rfidiot.org/ +# +# This code is copyright (c) Adam Laurie, 2009, All rights reserved. +# For non-commercial use only, the following terms apply - for all other +# uses, please contact the author: +# +# This code 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 2 of the License, or +# (at your option) any later version. +# +# This code 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. +# + +import sys +import os + +# invert binary string +def invert(data): + return ''.join('0' if c == '1' else '1' for c in data) + +# do the actual search +def search(target,data): + location = data.find(target) + if location >= 0: + print('*** Match at bit {:d}: {}<{}>{}'.format(location, data[:location],target,data[location+len(target):])) + else: + print('Not found') + +# convert integer to binary string +def binstring(number): + return bin(number)[2:] if number > 0 else '' + +# reverse string order +def stringreverse(data): + return data[::-1] + +# match forward, backward and inverted +def domatch(binary,number): + reversed= stringreverse(number) + inverted= invert(binary) + + print(' Forward: (%s) ' % number, end = '') + search(binary,number) + print(' Reverse: (%s) ' % reversed, end = '') + search(binary,reversed) + print(' Inverse: (%s) ' % inverted) + print(' Forward: (%s) ' % number, end = '') + search(inverted,number) + print(' Reverse: (%s) ' % reversed, end = '') + search(inverted,reversed) + +def main(): + if(len(sys.argv) < 3): + print(""" +\t{0} - Search bitstream for a known number + +Usage: {0} + +\tNUMBER will be converted to it\'s BINARY equivalent for all valid +\tinstances of BINARY, OCTAL, DECIMAL and HEX, and the bitstream +\tand it\'s inverse will be searched for a pattern match. Note that +\tNUMBER must be specified in BINARY to match leading zeros. + +Example: + +\t{0} 73 0110010101110011 +""".format(sys.argv[0])) + os._exit(True) + + bases= { + 2:'BINARY', + 8:'OCTAL', + 10:'DECIMAL', + 16:'HEX', + } + + for base, base_name in sorted(bases.items()): + try: + number= int(sys.argv[1],base) + print('\nTrying ' + base_name) + # do BINARY as specified to preserve leading zeros + if base == 2: + domatch(sys.argv[1],sys.argv[2]) + else: + domatch(binstring(number),sys.argv[2]) + except: + continue + +if __name__ == '__main__': + main() diff --git a/client/pyscripts/ice.py b/client/pyscripts/ice.py new file mode 100644 index 000000000..9a223a059 --- /dev/null +++ b/client/pyscripts/ice.py @@ -0,0 +1,4 @@ +import os +import sys + +print("SP %s" % sys.path) diff --git a/client/pyscripts/parity.py b/client/pyscripts/parity.py new file mode 100644 index 000000000..6be9d979d --- /dev/null +++ b/client/pyscripts/parity.py @@ -0,0 +1,78 @@ +# This code is contributed by +# Shubham Singh(SHUBHAMSINGH10) +# 2020, modified (@iceman1001) + +import sys + +# Python3 program to illustrate Compute the +# parity of a number using XOR +# Generating the look-up table while pre-processing +def P2(n, table): + table.extend([n, n ^ 1, n ^ 1, n]) +def P4(n, table): + return (P2(n, table), P2(n ^ 1, table), + P2(n ^ 1, table), P2(n, table)) +def P6(n, table): + return (P4(n, table), P4(n ^ 1, table), + P4(n ^ 1, table), P4(n, table)) +def LOOK_UP(table): + return (P6(0, table), P6(1, table), + P6(1, table), P6(0, table)) + +# LOOK_UP is the macro expansion to generate the table +table = [0] * 256 +LOOK_UP(table) + +# Function to find the parity +def Parity(num) : + # Number is considered to be of 32 bits + max = 16 + + # Dividing the number o 8-bit + # chunks while performing X-OR + while (max >= 8): + num = num ^ (num >> max) + max = max // 2 + + # Masking the number with 0xff (11111111) + # to produce valid 8-bit result + return table[num & 0xff] + +def main(): + if(len(sys.argv) < 2): + print(""" + \t{0} - Calculate parity of a given number + + Usage: {0} <2,10,16> + + \t Specify type as in 2 Bin, 10 Decimal, 16 Hex, and number in that particular format + \t number can only be 32bit long. + + Example: + + \t{0} 10 1234 + + Should produce the output: + + \tOdd parity\n""".format(sys.argv[0])) + return 0 + + + numtype= int(sys.argv[1], 10) + print("numtype: {0}".format(numtype)) + input= int(sys.argv[2], numtype) + print("num: {0} 0x{0:X}".format(input)) + + #num = "001111100010100011101010111101011110" + # Result is 1 for odd parity + # 0 for even parity +# result = Parity( int(input, numtype) ) + result = Parity(input) + print("Odd parity") if result else print("Even parity") + + +if __name__ == "__main__": + main() + + + diff --git a/client/pyscripts/pm3_eml2mfd.py b/client/pyscripts/pm3_eml2mfd.py new file mode 100755 index 000000000..90803cf5e --- /dev/null +++ b/client/pyscripts/pm3_eml2mfd.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +''' +# Andrei Costin , 2011 +# pm3_eml2mfd.py +# Converts PM3 Mifare Classic emulator EML text file to MFD binary dump file +''' + +import sys +import binascii + +def main(argv): + argc = len(argv) + if argc < 3: + print('Usage:', argv[0], 'input.eml output.mfd') + return 1 + + with open(argv[1], "r") as file_inp, open(argv[2], "wb") as file_out: + for line in file_inp: + line = line.rstrip('\n').rstrip('\r') + print(line) + data = binascii.unhexlify(line) + file_out.write(data) + +if __name__ == '__main__': + main(sys.argv) diff --git a/client/pyscripts/pm3_eml_mfd_test.py b/client/pyscripts/pm3_eml_mfd_test.py new file mode 100755 index 000000000..8fae5965e --- /dev/null +++ b/client/pyscripts/pm3_eml_mfd_test.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +from tempfile import mkdtemp +from shutil import rmtree +from string import hexdigits +import unittest, os +import pm3_eml2mfd, pm3_mfd2eml + +class TestEmlMfd(unittest.TestCase): + def setUp(self): + self.tmpdir = mkdtemp() + + def tearDown(self): + rmtree(self.tmpdir) + + EML2MFD_TESTCASES = [ + ('', ''), + ("41424344\r\n45464748\n494A4B4C\n", "ABCDEFGHIJKL") + ] + def test_eml2mfd(self): + self.three_argument_test(pm3_eml2mfd.main, self.EML2MFD_TESTCASES) + + def test_mfd2eml(self): + self.three_argument_test(pm3_mfd2eml.main, + map(reversed, self.EML2MFD_TESTCASES), c14n=hex_c14n) + + def three_argument_test(self, operation, cases, c14n=str): + for case_input, case_output in cases: + try: + inp_name = os.path.join(self.tmpdir, 'input') + out_name = os.path.join(self.tmpdir, 'output') + with open(inp_name, 'w') as in_file: + in_file.write(case_input) + operation(['', inp_name, out_name]) + with open(out_name, 'r') as out_file: + self.assertEqual(c14n(case_output), c14n(out_file.read())) + finally: + for file_name in inp_name, out_name: + if os.path.exists(file_name): + os.remove(file_name) + + +def hex_c14n(inp): + """ + Canonicalizes the input string by removing non-hexadecimal + characters and making everything uppercase + """ + return ''.join(c.upper() for c in inp if c in hexdigits) + +if __name__ == '__main__': + unittest.main() diff --git a/client/pyscripts/pm3_mfd2eml.py b/client/pyscripts/pm3_mfd2eml.py new file mode 100755 index 000000000..ae7a79825 --- /dev/null +++ b/client/pyscripts/pm3_mfd2eml.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +''' +# Andrei Costin , 2011 +# pm3_eml2mfd.py +# Converts PM3 Mifare Classic MFD binary dump file to emulator EML text file +''' +import sys + +READ_BLOCKSIZE = 16 + +def main(argv): + argc = len(argv) + if argc < 3: + print('Usage:', argv[0], 'input.mfd output.eml') + return 1 + + with open(argv[1], "rb") as file_inp, open(argv[2], "w") as file_out: + while True: + byte_s = file_inp.read(READ_BLOCKSIZE) + if not byte_s: + break + hex_char_repr = byte_s.hex() + file_out.write(hex_char_repr) + file_out.write("\n") + +if __name__ == '__main__': + main(sys.argv) diff --git a/client/pyscripts/theremin.py b/client/pyscripts/theremin.py new file mode 100755 index 000000000..a286d6193 --- /dev/null +++ b/client/pyscripts/theremin.py @@ -0,0 +1,82 @@ +#!/usr/bin/python3 + +### Parameters +# Sound output parameters +volume = 1.0 +sample_buf_size = 44 +sampling_freq = 44100 #Hz + +# Frequency generator parameters +min_freq = 200 #Hz +max_freq = 2000 #Hz + +# Proxmark3 parameters +pm3_client="/usr/local/bin/proxmark3" +pm3_reader_dev_file="/dev/ttyACM0" +pm3_tune_cmd="hf tune" + + +### Modules +import numpy +import pyaudio +from select import select +from subprocess import Popen, DEVNULL, PIPE + + +### Main program +p = pyaudio.PyAudio() + +# For paFloat32 sample values must be in range [-1.0, 1.0] +stream = p.open(format=pyaudio.paFloat32, + channels=1, + rate=sampling_freq, + output=True) + +# Initial voltage to frequency values +min_v = 100.0 +max_v = 0.0 +v = 0 +out_freq = min_freq + +# Spawn the Proxmark3 client +pm3_proc = Popen([pm3_client, pm3_reader_dev_file, "-c", pm3_tune_cmd], + bufsize=0, env={}, stdin=DEVNULL, stdout=PIPE, stderr=DEVNULL) +mv_recbuf = "" + +# Read voltages from the Proxmark3, generate the sine wave, output to soundcard +sample_buf = [0.0 for x in range(0, sample_buf_size)] +i = 0 +sinev = 0 +while True: + + # Read Proxmark3 client's stdout and extract voltage values + if(select([pm3_proc.stdout], [], [], 0)[0]): + + b = pm3_proc.stdout.read(256).decode("ascii") + if "Done" in b: + break; + for c in b: + if c in "0123456789 mV": + mv_recbuf += c + else: + mv_recbuf = "" + if mv_recbuf[-3:] == " mV": + v = int(mv_recbuf[:-3]) / 1000 + if v < min_v: + min_v = v - 0.001 + if v > max_v: + max_v = v + + # Recalculate the audio frequency to generate + out_freq = (max_freq - min_freq) * (max_v - v) / (max_v - min_v) \ + + min_freq + + # Generate the samples and write them to the soundcard + sinevs = out_freq / sampling_freq * numpy.pi * 2 + sample_buf[i] = sinev + sinev += sinevs + sinev = sinev if sinev < numpy.pi * 2 else sinev - numpy.pi * 2 + i = (i + 1) % sample_buf_size + if not i: + stream.write((numpy.sin(sample_buf) * volume). + astype(numpy.float32).tobytes()) diff --git a/client/pyscripts/xorcheck.py b/client/pyscripts/xorcheck.py new file mode 100755 index 000000000..a10c3bba6 --- /dev/null +++ b/client/pyscripts/xorcheck.py @@ -0,0 +1,51 @@ +# xorcheck.py - find xor values for 8-bit LRC +# +# Adam Laurie +# http://rfidiot.org/ +# +# This code is copyright (c) Adam Laurie, 2009, All rights reserved. +# For non-commercial use only, the following terms apply - for all other +# uses, please contact the author: +# +# This code 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 2 of the License, or +# (at your option) any later version. +# +# This code 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. +# +# 2020, Modified (@iceman1001) + +import sys + +def main(): + if(len(sys.argv) < 3): + print(""" + \t{0} - Generate final byte for XOR LRC + + Usage: {0} ... + + \tSpecifying the bytes of a UID with a known LRC will find the last byte value + \tneeded to generate that LRC with a rolling XOR. All bytes should be specified in HEX. + + Example: + + \t{0} 04 00 80 64 ba + + Should produce the output: + + \tTarget (BA) requires final LRC XOR byte value: 5A\n""".format(sys.argv[0])) + return 0 + + target= int(sys.argv[len(sys.argv) - 1],16) + + lrc= 0x00 + for i in range(len(sys.argv) - 1): + lrc ^= int(sys.argv[i + 1],16) + print('\nTarget (%02X) requires final LRC XOR byte value: %02X\n' % (target,lrc)) + +if __name__ == "__main__": + main() diff --git a/client/resources/hardnested_tables/bitflip_0_001_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_001_states.bin.bz2 new file mode 100644 index 000000000..e65f22471 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_001_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_001_states.bin.z b/client/resources/hardnested_tables/bitflip_0_001_states.bin.z deleted file mode 100644 index d697d83ce..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_001_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_003_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_003_states.bin.bz2 new file mode 100644 index 000000000..5ae156039 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_003_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_003_states.bin.z b/client/resources/hardnested_tables/bitflip_0_003_states.bin.z deleted file mode 100644 index 2973d69cb..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_003_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_005_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_005_states.bin.bz2 new file mode 100644 index 000000000..473c32fca Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_005_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_005_states.bin.z b/client/resources/hardnested_tables/bitflip_0_005_states.bin.z deleted file mode 100644 index 01b274abe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_005_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_007_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_007_states.bin.bz2 new file mode 100644 index 000000000..0cfda87cb Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_007_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_007_states.bin.z b/client/resources/hardnested_tables/bitflip_0_007_states.bin.z deleted file mode 100644 index 8a2ee5530..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_007_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_009_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_009_states.bin.bz2 new file mode 100644 index 000000000..1103e29bc Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_009_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_009_states.bin.z b/client/resources/hardnested_tables/bitflip_0_009_states.bin.z deleted file mode 100644 index f1de49a74..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_009_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_00b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_00b_states.bin.bz2 new file mode 100644 index 000000000..2e1c29d87 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_00b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_00b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00b_states.bin.z deleted file mode 100644 index 8c919a282..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_00b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_00d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_00d_states.bin.bz2 new file mode 100644 index 000000000..c76301638 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_00d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_00d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00d_states.bin.z deleted file mode 100644 index 214457920..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_00d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_00f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_00f_states.bin.bz2 new file mode 100644 index 000000000..39e7afc47 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_00f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_00f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00f_states.bin.z deleted file mode 100644 index 07f00ab05..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_00f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_010_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_010_states.bin.bz2 new file mode 100644 index 000000000..74890f1ff Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_010_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_010_states.bin.z b/client/resources/hardnested_tables/bitflip_0_010_states.bin.z deleted file mode 100644 index 3b5f8c3d1..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_010_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_014_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_014_states.bin.bz2 new file mode 100644 index 000000000..b7fb646d1 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_014_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_014_states.bin.z b/client/resources/hardnested_tables/bitflip_0_014_states.bin.z deleted file mode 100644 index ec220c704..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_014_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_01c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_01c_states.bin.bz2 new file mode 100644 index 000000000..c865be04e Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_01c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_01c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_01c_states.bin.z deleted file mode 100644 index 3d38583d3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_01c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_021_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_021_states.bin.bz2 new file mode 100644 index 000000000..b2fef5781 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_021_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_021_states.bin.z b/client/resources/hardnested_tables/bitflip_0_021_states.bin.z deleted file mode 100644 index 39fc37c15..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_021_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_023_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_023_states.bin.bz2 new file mode 100644 index 000000000..32c7adfd5 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_023_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_023_states.bin.z b/client/resources/hardnested_tables/bitflip_0_023_states.bin.z deleted file mode 100644 index db4897a35..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_023_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_025_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_025_states.bin.bz2 new file mode 100644 index 000000000..e21a5ee93 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_025_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_025_states.bin.z b/client/resources/hardnested_tables/bitflip_0_025_states.bin.z deleted file mode 100644 index 339b9222f..000000000 --- a/client/resources/hardnested_tables/bitflip_0_025_states.bin.z +++ /dev/null @@ -1,49 +0,0 @@ -xÚíëë°Ž€§€¦¥-n › äï–1ðîÙÀWëM9”Ã/ÀœœÄ‘iŠâC$Eþ×ÿü÷×ó±ïÇß¶=ÿÞ¿¾Žï~¿·ÿ{¹ëÇÿßýý<ÿ¾Û¶pü¿÷ßïóø¿üúzýÿßï¾¾üû̓ß¶þ¿o¿þÿþàþ!þÛv|·m%ø¯ßÏÇ¿~ÿóxÿãßðÞsá»y9ãü67ŸÐúëÐÿ¸¯ûûGCŽBøÏGß}ïèŽ?¾÷ïÿ9øK×ÿ¼ùÇû×ïú”ðß¶2ü¹üß¿†ÿ¶¯ûßÁÿð?üþØÿéñ?©ë!üÔó?åñû^/…>Êã¡Zÿ=¥ùÏ}–Òû¿ŒþùÓò,Æ??:ëÿ,?s×cúÆß§éŸ¿ÿªú¿éúŸ7ÿû>‡>è俦ü•¿i~É??û?ô?úúCüÿÈÿ:|Ÿ·­}|ŽþÀ¿|âÿŸˆ{üÅÿý¶µïsþÿ^ù[^ÿùñ9ù;ÿš+ÿïÿKÓ_*úá‡ô¯×ë¶­´þÖ“ÿ­öû§ŽÇÿÓ¶™;ÿÚü׊ÿøþùÚù»~ü»âÄ?‰bÿ¯—ÿÒjÙÿZömøÒù'ÿü?øŸü?«òϺÿÿþ?üvýRûoVþ¿VüþÇþ'þÿüÁŸøù_äÿBÛþ?íó?Ú矬ûÿrŸÓïóÏ?iÛÿœÿãüçÿ8ÿÇþ‡üw;ð±ÿ±ÿ‰ÿcÿÿGþ—à;9§ÿúüoüÐßÞùì?øúÛ£ÿ¿ûýý„þÿŸóõã{ç¿úû Çÿý”Çï{y¼~<þï§<>‡ÿï·?Gÿþïì误ó÷áø¿Ÿãó×—¿þÿ~æÂÇ»ëÇ篯;Ðß:þï]ÿãþçÚ{î~uÿþïôÿçð“úÿ{ç«w¾[?â˜!ÿJþÔ~ýïç]þÿ±õ×kÿ ÿÐÿúô?K鿆üOáß¶þæÈÿõÖ?öòÏòþÇþóìÏ1{Vÿó÷ÓoΣ¿~~¼Ýÿî÷{æþOªÿ׳ÿméÿõøÿ^òOªÿõ÷ÿ¶åú5ÿߨü™ÿß®¤þô?úÿ?þüÿøÿñ€?øƒ¿nü§%ÿhžü_/þcKþCÛôŸ·ÿŒ÷™þýó÷»;þŸçÿÇþ‡ÿá;üÿŸýO‹ÿ1öß~êøÜüûã¿ÛÇçè¿|òÿˆÿk~Ö^ÿÄÿ[õoÚž›?ÿ}ðëãsö'òFÿ0©þm—¿íã¥ýÿlûÿ´éß²þ¯íùÎõ§mÿbÿÙ¶ÿðÿÿÇÿþàOþïHügÜÿ¿jþŸõü_âœÿçü+çÿÙÿqþŸóÿÈ?ì[çÿÉÿ!ÿûŸü?øŸü?òÿðÿáÿÃÿ‡þÿ\ýÿÃÿð¿5þÿúzù£|üç{qÊñݶùóóï~ÇõÚøãú‹ïBü7øÏGÛÂñœVøÏÇ\øñøm á‡òß:þÛvîrô'y½Â~%þïg¬¿üÚúoy~ÿyKø´ÁçÛÎý_ì:|è7úÏ…¯-ÿ¯ËŸoŸzþw^—ä¿Îÿëöÿjë_?{þßÝ/Å¿=øÕÆKﯷþ[ó?dùÚúOŠÿùùŸ¾ù>æÎÿXýS«òýû_ËðûíÿpŸ#]ÿaßÌû¯øùÃþŸçïmïÿ´û¯»ÿ±iÿ÷Ð_gþ?kýÝOþãÿÃÿ‡ÿïSüØð?ô·KmÿãŠ×­ûÊó3×ÿy¿õ=þ2øµû—ý¿½ñiüOÛþêÇ?œ¿³þz>zâ?«ùÿ[ão³ìÿã–ìô?ù_šñë÷ÿ–âÿضí?âß¶ñ'ÿÏvüktÿã¯÷™ùOuû¿ÿ<ý¾wnL?ÏÝÿ­¶ÿ_ÿ×ζžÿGüÿ“ü¿+úÿÞ¹ÿê÷?ÍÿÿOþÿJöo¯ý'Íÿ׎ÿâÿ“³âÿï·ÿ‰ÿô9êüý„õŽú ¯—ûþîUO ôý1>ü>¿9ðãñ__éçð·¿Ôÿ)Å¿&ÿjø_íÿƒß®ÿ ?ôצ¿fýûã?cý¯[ÿ¿î˜ƒ¿ný7øþ‡ÿmâÏþç„ÃçÞ÷ÞûIáKÏþ¯5þ,¥ÿªöÿóѶž¤ñ_íõ¯Ýÿfmý_ÇÆú¿sÿô?òÿ -ù/“¿óò_­úÿÐÿvô?ô‡þøÿ‘ÿœ>ç8ÿÓsþ{Fþõºçÿ­çÿrþŸóÿœÿçü?çÿ9ÿÏùÎÿcÿÛ:ÿOýoÛçÿ9ÿCýøŸúÿœÿ·yþÿþ?üÖúöØ3úŸ¯{þþÇþ·Yÿÿøƒ¿Ýøý_èÿý­ûÿôú¯QÿÔ¦ÿú¿ÔÿÕæÿ;É?{õ?Kþ±ÿ!ÿþÏØÿØÿÄÿ±ÿ‰ÿ#ÿéÿŽÿú[‰ÿcÿÁÿПúÿÔÿ£þã*ô§þåûëÿûŸÇëÿ­Pÿ¥„Ký=¹ÿúÔÿ¶WÿýOýGê¿Ù­ÿ†ý‡ücÿc[þ¯Xÿ{úçÖûÿÔ÷s꟯gÿSÿŸúÿÔÿ§þ¿%ý¿’ÿïõÿKþ¯Úú›“ÿƒþGÿãÿÇÿÿÿÿ»õÿï·?¿¼ÜüŸõÇ¡Üwþ÷éñ>ýSã¥ðSú/þàþ/IåË÷C>åäÿY~Jñ?äóïw -~ÿòøm;_Ÿ¿Œÿü×çüüùö?ô‡þkÈ?/YþÜû×v¿»ã/•ÿóæ¿ç÷þ™šm;O]wë{&ÿ§á×ð©O]÷Ÿþ‡ÿ-ó?øÛ¶ÿGâ?¾ÿî÷»}üáŽý?šðGèÿIãeþ¿tüÁ}_Ÿmû_ÿ™Qÿv•øOìïOËÓø÷¿ßíããßÿ~¯´þÛñ÷ýîÒõßo~~¼}†þ¿†~³ŸçÝÏoGþûñ«yú¿]þúú_ZÿÁúþO›þ#óß>¾>ÿÚëoûûÏ¢ý‡ÿŸø„þRü[è× ýÁü­àïë²òçÔ_=¾RŽÏœë¥¤ê?çñ/j>Ÿþ߇ -¿sÅÿ»ðùãþS-ñ«øòø—”þ²õ¿mÒùï{Þóïç­¿1úëð¿ÔþŸaÿjÖ¿´.ÿµû¿iËYÿ·tÿ7/-ýïWÿu&ÿ#ÿØÿëØÿ3ìÏûÿþøKéýýÿÃÿºüoô?þ?üèÛúþ‡ÿá;üo=ÿ‘ñœÿçüÿxþ¤týiç’ÿý5áßñüËÌó?ëœÿ³yþÕ§WØŸ=½?ÈÓ_šÿß~þ¿¶?ê¹Nþÿ¬óoéï[Îÿ­qþ…óœÿgÿÃþ×ÖxÎÿPÿ‡ó×è?Îÿ#ÿñÿàÿƒþ¶üØð?ô§þ õÿ¬×šW¤ÇÿyÇõ?ÿ•êÿÉâ?cñ¿uê?¥ñ¯ùßçÕÿÑñÿKãgóìOøñô?õŸ©ÿGüûÏ¢ýGüùOþŸÝø×ÈþïøÝÜú¯:ý¨ÿOýòÿˆÿãÿÕñÿ­Sÿ_ª¤ñòÿÉÿ×Íÿ—ÙcùÿëÔÿÇÿOÿOkñÿ×½èáã<_úºãŸ×ÿÜ·éëµûÇã¥ðk÷ï}>ðÿÏÅÿU‹$¬Rþ¾¤øŸ_!¼þµñõWß~ø½÷‡þÐ_‡þÚõtý¯WÿºVÿê\ëjþ:õßàøþ·‹¿uûÿðÅüý„þË|çßzùû‡ãŸÿãú™þ¯ßÏ…Æ?„ý}úoÛ¹ÿMN_Å}n¤ô×¶ÿ[𯭿ܼÄöˆû>œOÍõ¯Ýÿf…õ/Á†ü»sÿô?ò_ºþþi3äïYþ§å2û?ô?úúÛ¥?þâ?Uû‡ë\'þÿ¡öÿHü'î_2~þrLþö/Û3²þ/RùÏø_}êûÿÞù—Œ??¿æúÓ–ïcþ—OÛ÷¹ñeÿ¿|äÿÈþ/ÜÏHç_WþìÿÂõ×2åýßÝøožÿ›ø'ñOìÿ»å¿´×OmËÿÑ´tŸ_{þÉÿ#ÿþ'ÿϪü³îßÅÿ‡ÿÿŸeÿŸÌþ›‘ÿ¯ÿ‡ÿ±ÿ±ÿµÎÿÜýü øƒÿgáÿ^ý¯-ÿ¥ú? ?ü®¾‚þÐ_‹þÒú_ÛvþþùH×—z>Òõ¬Ö8ÿ2Vÿjžü——ֿ=Ó?ä4¥õÏ|HÁkÅ¿4¾ôw>ÿUâÿ–õ÷zOñÿóqæíõ¯ÍÿŸ#ÿÆëÿ=sç?5¿þü§ëßÙ”ØÿêñgÆß6þýÿ9û?iÿ´+ú¯½sý[×Úô³¾þî#ÿçÅÿµã¿Èè¿|ì?ì?üÿÐÿýþ/ú_ÚîÿHÿW‹ëŸþ?ôÿ¡ÿÕþ?È?ô¿¬þë¼þ¿Úòßzÿ_ì?äŸ=ù‡üŸÕÿzÌþ_gýKûïJéŸþ¿éýŸTÿëØÿè]þÿù'Õÿ:ûëòý¯ëÿ+ç?Éß™ùÿíúGêÿAÿ£ÿñÿãÿÇÿÿÿøƒ?ø_¿ôüÓ<ù¯£ÿ­ËèþŸãÿiß®äÿ³îÿÂþ‡ÿáüßàOþw«ÿqßCÿcëø\üKþý?i<ùøÿ{ãß9~m|.þ¿Æú'þ/û,¥ßìçy÷óÛ‘ÿn=ÏÔÿíò××ÿÛÖþü¹úsœÿУÿÈü·¯Ï¿öú[ÇþÆþ³hÿáÿÇÿGüüÁßzü_ÿó/¯#ÿmæÿÿcÿÇùWâ?ìÿ8ÿÏùäö¿UüÉÿ!ÿûŸü?øŸü?òÿðÿáÿÃÿ‡þ·sþ þ‡ÿá[üÿz¢=|üçã:×Ï×ü|ýÏ}›¾^»<^ -¿vÿÞçûlü_½HÂþ'=Ÿ¥ëKzéó÷Ãç¯öªÝúß‹þsákÊwyþ·<ÿùëë•ÏìÏ=¿ÿðëµñÇõ3þ²üW©ü_©ÿ“ë_Ÿïÿ~þü¿»ÿžÃ×Ç?ÇŸ©õWï_ù_ýKó?dùÚúOŠÿqÿpþynÿçcîüÕ?µ(ÿ°ÿÙßZ¿Þo¿†/éúªí—ú÷_åçíߟ}îþO»ÿ°þþǺý¯K?ëëïžòÿþ?üŸàÿÃþƒÿ¡¿eû_ßÿ¨ ߺý76ÿóüŸ÷\ÿsý¿ÿþ ÿŒ^üGÿÓ¶¿ÆðçßÅ‘œ?–ÿ¥øÏZþÿ¾øÙüýÿ{ãÄÿÑÿ–ã?-ñïX^ÅòL:ÿÚòßzüûÏ®ýGüùOþŸÝø—dÿãô¿Dþû“mk·ÿSñÏÒøàzôÿý?wÿ·ÚþÿüÏügëùÄÿ?Éÿ«éÿÓßøŸæÅÈÿ'ÿµüÿûoFþ¿füÿÿÿÌ‹ÿëØÿÄÿñGÉøý+óÊý®6¾ö=ðü÷ÃOûžœ|‰ýWïáß¶ÿ.û?4áCè¯Mÿsýé¸~µûÿXýë|ýé»ã÷ùOï?âý›óÄû9øçá×ñoÙ–ö?ð?üoÿíâÏþ# ßú»õýŸó/–¯KçyUû¿?íù›1ÿiùëäl|ýù˜7~]ý/{þ»Ì?úù¿¢ü—üeÿ‡þ·®ÿ¡?ôÇÿoYþÛ>ÿ þãü5ÿÿzøšùqÞÜœóçü¿t^^:ÿÎÇ«ÿjËÿëƒß›ÿÒ=ÿ“šÿöüËþéü?÷¼œÿ©ë¿Ð~ÝwÙþºvÿçc.ü}Ÿµÿ· ÿOë¿úù,¯$ô×–ÿ5|kë/7/­ó¹âú×¾®ÍwŸ?äð¯;ÿ;¯ÿÇ=Ï?ÒùßÖýOz¿2gýï¿Òöj|Éþ?ÃÏo³ÿËöü¯Íÿãûï+Ö¿öþßšü£þ'þ?üøÿìÖÿ·ÿf¬?mû þÇþ·mÿ«¯?àø7”ÿïƒü_ >ô‡þô?¿ÿý¼ózŸÊ]ñŸ7>|?Ε¸ùwµ²üû_5ÿýðËãýï·Í?7“¥OçûÜù÷k#Žà¯}Þäð«­¿Öñ¹Ïk¬mþ¿Ÿü»ûü[—víÝøŸ~üÛ:þØÿ¶íÿ}å§[?~}Øqùëßÿ÷;¼ÿ:ëß®þ›C©ü›·þâñmø£ÿtâÿÚñ_ä¿uú×o£ÿû`ÿaÿáÿ‡þzô_±þÔ=ê_i×ß¼¾õù·´þ¥þcé»nýg9~Rÿ¿ö»Äÿ0¯þx~ü?ÿµþÿ÷¬?äúgµúÿýòKª´å -ÿñççüÁÈ?äðeðµßµ×øÞj^5ÿýðËãKßÏÙÿÍÝjÛÿöôÿZü?ùw÷ù·+ÿØÿ­çÿ{§ü£¤þô?úÿ?þüÿøÿé|àŸþïôþПþßôÿ~oü¿-ÿtþºö7üÿÛæúÿÚÞì{8¾ö¹÷½÷~RøÒßÇË}›wÿÚýæÀÇÓÿ—þ¯¥þó®_б~ÂøÁ¾Ëâñø:ÿ¿sýKâ'sæ_;þ“£ÿ¡?ë£ú?/ÿÒÏß?­ÿãñ5ýo]þ÷ÿ“êÿZÿ²š>¿ºÿŸÕþÏÚôß¶¶õuÿ˱õ×ÞÿPÛþÅþÃþÃÿOü‡þ‹À¾ÕþŸôÿ¡ÿý¬öÿ¡ÿµmù_ï__~—ο6ÿIñÓž?øù‡üþ]ûÿÝÿO쿈ýOÿOøß.ÿ[ÃýÿÿúýÿÃÿð¿%þ·žÿþœáüÿ¾—ó'ïFó¿ÊùßúùŸäÿÚ¦ÿ¾Ï…ÓßCøîþkœYïüÏ;óŸ9ÿ›ëžJÕ/›‘ÿ_êW?ÿ#ïg=ÿ_óüÙºçÿ-ÿãü?çÿÙÿsþŸó?6ëÿŒŸÿn“¿îþ¾ÍµÎþûŸóÿœÿÇÿ‡ÿÿŸ=ÿöç¿¡¿MúSÿÿÇ -uHVó¿Yy—Ƥñ¿ì?iÿ'éù»UêÿåãgÇõÑúßµýÿzñ?+ö?úŸü/êÿÙÿcÿÙ¶ÿˆ#ÿÉÿ³ÿ’ö/³ÿ\¯ÿõÿ©ÿOýâÿâÿ+úÿÞYÿ_¢æœ%ÿŸüMûwNÿúQý£ÿÅÿOÿO»ù!}çËÑÿ<Œg<ãï?>®K’®ÿr®Ÿò.øW?¿6|èýuåÇùý÷û×ïŽÿ½ç_ú'çÿÚý¯}~øþ·ÌÿàoÓþ¿wýi9|è¯[ÿU[ÿê×]…ÿÂ÷œüôÂ/÷¿_IþÎÃÿîóþGþkÔÿÖ•¿Ö÷èô?ô·KüÿøÿÜùÎã|bîüçüx¼;Ÿ•/…ŸÊÿâߌ/­ÿp¯XúÜŸñÇ¿rQõ™–Ÿî÷íë¿4¾MþKãORù¯·ÿC™üÛ¶6ø-ñ¿–ç=ÿ~ÞúKÙÌîþþyýÿNù/«ÿÐfºûŸé_Îÿƒß“ÿÿ'¦iýíÿJô×–ÿãø·ïÿ|ücþ×^ÿÖãoÄ?±±ÿËöy‹ý%µÿõ÷ÿRü¥ûÿyóŸž_òÿÈÿƒÿÉÿë§Ï§Ë?üßøÿðÿáÿ³èÿ›gÿIÏŸhÇíò?ö?çÏxÆsþŸü/ÎÿC‹ùß:çOÖ‰Ùôÿåè_Ú+§~'Ï?Ö±ÿÉÿçüçÿ8ÿGüŸüËùÿØÿÄÿ‰ÿÿ'þo[ÿÕâŸ#ò«-þ«ÿçü§UúÿÇþÃÿý­úÿµûÏhÂ?Æ»ïb˜ñõÏo}þ­¯©ÿÙ#ùýh]Âëñ÷eùU§ßÕþÿ3ýÿ?õù«Í³|þÇüRþk¿úïZÿÍõëù‡þצ¿$þ,ÿuä¿Vÿ1øù‡üc¼öú×±?×YÿÒ?)ýtþæíÿ¤ú_ÇþGÿëòÿçÈ¿»Ï¿Mù‡þ×õÿiËßyúGêÿAÿ£ÿñÿãÿÇÿÿÿðüwêøÏ -ööôÇÿgÓÿoÝÿ§½ÿŸ·ÿº¢þüÿ>ÿƒ¿mûßÃñÇw¯Ïñõ~îùKã÷½<^ -?ÿ÷SŸÃÿ˜¿ãúèü»ûŸÿÁÈÓ_ -??bûü^íÿú׿Eû_úüïœ?éxÇ/mŸ{ßÛî§·þGñšK?½÷}~¿ÏçéGô›ü“Âϯéëò?×ÿ/œÏqùUÓÿ¹þg­ú??¾MþZßÿ­Jÿ–õ?£ÿݾÏ]ÏGyþÜýÖ°±ÿlÛøÿñÿøÀçü¿µü_ëùÄÿÐÿÚöçŠã­ç±ÿ³³ÿƒÿ˜ìoëðÉÿ!ÿûŸü?øŸü?òÿðÿáÿÃÿ‡þçü?üÿÃÿŸËÿ__¯|,?ÿéèÏòzÒã»móý›ÿî÷º¾máøžþøãúÑŸÄõyý~.üx¼»~ÔgðçüŸòó»QcøeøG¿#׿Øõ':ú!¹~EaŸãë?ì›|†_[ÿç犟?쿜ú>…—ƒ_žÿܼ´Â‡þÚôß÷¹ðc8îþ©ùÔ–ÿòüoYþs -ÿðz¬ŸŸ¾ñgþz>æä¿Îà?ýþïçõÚÓiúûðÊô9ÛW¥ù/õßkÁ?ÝÿÏñßóQçÿ˜Jø¥ôGé~çû¯¸þ¥çgÚÇkë¿+žÿNóo]þ±ÿ`ÿoÿÚþ§´_š³ÿÐÝYßÿåíÿsÿá1ùëïâþÏ+ì°ÿGé?Cþ•ÎÿŽ­¿¾ó¿ÈüøÿðÿYõÿaÿYçèo™þ5ÿl¿ÿ±Ïÿ«íÿÄÿ!ó_^q]Ûÿ¦ÿ;¯Kã?ÒøŸ¶ýwŽ?¥òÑòþózü§ü®ïÿß÷‘øÛ,ûÅøŸ%ûýOþWO¼zÛæÆÿWÜÿ[ŠÿcÿÙ¶ÿˆÛ†OþŸíø×èþ§]ÿ÷å?½Þ¶î¦Ç—ìÿçCbßH÷«íÿWàýø¿¥ü?âÿ–ý¿+úÿdû¯}—øßzôÏŒøùÿäÿ¯”ÿßkÿIõvüÿ‹üKÏ×ù×ÛÿÄÿëG½€øý+óÊý®6¾ö=ðü÷×ʟ«á×ð¿Úÿz5|èýµé¯Yèîøß}þ¥þ‡9øëÖß‚ÿáÛüoöiøÖß­ïÿZýÇÒy^ÕþoÅO{þfÌ¿fÿ™uõ¿ìùï2ÿèäÿŠòÿ]ò—ýúߺþ‡þÐÿ¿eùOý?Îÿsþ†ó?ýç¿gÔÿ[óü?ù¿œÿçü?çÿ9ÿÏùÎÿsþŸóÿØßÖÎÿ[©ÿÍùÎÿPÿŸúÿÔÿçü?çÿñÿáÿÃÿg©ÿç¸ý7cý­yþßÿcÿÛ®ÿ|àßnü‡þ/ôÿþvýëõÿ~oýSëþ?êÿÚ®ÿ»ÿßIþÝ¿þ¯mùÇþƒüÛýŸ±ÿ‰ÿÿ'þOüߦü·ÞÿݺÿÏ:ýmÇÿ±ÿðÿCêÿóNýGæßÖûÿ±¬þœvý—þ£Ïßçÿ×®ÿGýo«õÐ÷Ô¤þ›ÝúoðóÍþǶü_±þ·~ýsëýÚö×í?uíêÿSÿŸúÿÔÿ·¡ÿ×óÿ½³þ¿DÿÌñ?¢ÿÑÿøÿñÿãÿÇÿÿnýè§â9¯Çÿg<ã×ñ¡|?äSNþŸåçµð¯~møÐú¯!?´ÿîŽÿ=çß­Ïó{Ëõyü_»ÿ5ÏÿÃÿ–ùümÛÿîü§ó¸ó“þoÆýÏîþþ™Ë¼ÿ[ -?_òÿ~û÷½òðÇæ?ïãŸ/…ŸÂ¿DÉùciüA[ÿêûõã?ûúûÝúñùÃýß÷;ÿ~—¿÷ÇßÇ÷×^ÿ?åçqIã?>ÿsà—Ç—î[¢wž^íú³MþIáKoWþKêÌÐÿùúuý/­ÿ`}ÿ§MÿÔüõ¬ÿòø6ý¿ïs×__ý]ûû϶ý‡ÿŸøxþÏxÆßz¼ôO‰ë¢¤ë?—ž¿<>¼ÿNŽŸ¾<~%)ý¯]W?¿öúÓâÿõêÏ¿¾uù¯ÝÿM›ÿôûÀÈ?äãµÇëÚŸ÷ÇÿÞóýoÓþ‡ÿáðGÿãÿÃÿ‡þ·«ÿáøþ·ÇÿÖóÁŸóóÖÏÿ»üÎtþdx½?©´þµó?Éÿ‚þyüÇàÇôçÏÏÿ]'ÿ_çüÏ -çÿ,Ÿõéý|œéïÖ¯û¿_n^þ¿{ï9ÿS_Û?ÿ¯þLûü‹õóœÿ·½`ÿoÎÿPÿgÎùïöóØ+ÿGÿqþߺüÇÿ‡ÿÿŸMÿöüý©ÿBý?»õŸ4ë¬ãÿÕ«¿·Jý?Yüg,þ·Bý§çãüÞêŸWÿGÇÿÓ7EŸøzoýï6û_'þGüýOýgêÿÿÇþ³hÿÿFþ[Ïÿ³ÿªíbûy$ÿ¯­þ¨NÿêÿSÿŸúÿÄÿ©ÿ¯ãÿ[§þ¿TÿHã?äÿ“ÿ¯Yÿ_jÿûŸ×¨ÿo×ÿOÿO«ñÿד¼d†ï?=äSúº{þ×ÿÜ·éëµûÇã¥ðk÷ï}>ðÿÏÅÿßo_ÛÖö9|Iñ?¿Bx5ükãë¯2¾ýð{ïý¡¿ýåùß²ü‡»ã/]ÿmñëÞù—ä¿¿Öç±ß?Ã?׺šƒÿ¶µÁo©¿Ï×ß‚ÿáøß.þÖíÿÃßù÷ú?sðëåO<îŽ>büëgú¿~?þÿ>ô÷éèK׿&¯¯â>7RúkÛÿ-ø×Ö_n^b{Ä}Χæú—çÊâ+¬ þ3ä_)þ96ÿ½ñOô?ò_GþŸû¦Í¿gùŸ–ËìÿÐÿèèo—þøÿ‰ÿTí®søÿ‡Úÿ#ñ_ìcùß+ûÆ—í™^üÏûG‰ü¿gü¯>õýïüKÆŸŸ_sýiË÷1ÿ¿ËçŽíûÜø²ÿ_>òdÿîg¤ó¯+ÿGöáúk™¿òþïnü7ÏÿMü“ø'öÿÝò_JöW¿ý¯kÿè>¿öü“ÿGþüOþŸUùgÝ¿‹ÿÿþ?Ëþ?™ý7#ÿ_7þÿcÿcÿkÿ¹ûùðÿÏÂÿ½ú_[þKõ~ø]}ÿý¡¿ý¥õßü9ÌÕóïßWÿïç_Æú_Ì“ÿRøÒúwgú‡ü‘¦³´þÏ)x­ø—Æ—þÎç¿Jüß²þ^ï)þ>Îü¯½þµùÿsäßxýÇçcîü§æ×Ÿÿtÿ›òû_=þÌøÛÆÿ±ÿ?gÿW•¿_×^ÿÖõŸ6ý¬¯¿ûÈÿyñíø/òú¯ûûÿ?ô¿ÿËnÿ_ú?éÑŸþ×úý4û­Óÿ9­ÿá¼þOóú/¦úe•úÿHüRù§Ýÿ«l?­¿ûù‡þ_ƒþcñçyýÿ´å¿ÝþØÈ?«òù¯Ûÿ{õo³ÿ5ýÑÿšüÿ9òOªÿuöÿÖåú_×ÿWΓ¿3óÿÛõÔÿƒþGÿãÿÇÿÿÿ?þ/+þOðÿ5ð׉ÿhÛÿØÐúÛõÿ[÷ÿiïÿkçŸÛ÷_cçŸáøþìÿóø×çøú¿ÿ;øŸ<>7ÿþøßïöñ9ú¯ÿ¬ÿþ~R×Cû?µ~ÿ~úæUû?÷ü?åç>ÊóçîWæÿVøµñ?åñ9ùÿÞÏÚë¿ýyÓïãëÿïgüy¿¯éß´=7þûà×ÇçìOäŸüå×ýÛ.ÛÇ÷ÿŸ{ÁÿØÿØÿãö¯”ÿïiÿ‚?ø*þïÕÿÚò_ªÿÓðÃïêû'èýµèïοÄõ®^4ôkd…õ—^çVü9ôëKý~ŸÇßû÷×®ã?_êº[ß3å¿~~||Ý_¢Èi:§æßÑ¿^Óç¼VüKãK²úéúcn^Zê®RÿQ‡ÿ?Gþ­ÿxÞfÌj~ýùùDzüÃþW?3þ¶ñìÿÏÙÿUåïÅ׵׿uý§M?ëëï>ò^ü_;þ‹ü‡þkÁÇþÃþÃÿýßïÿÒ¨ÿu÷úWÒú§úõ?µéoíõ/õûq¤¿Ÿó÷þ~ëï§×ÿuýç:þ©xåßÏ\ÿ¿¿^ø©ùÇÿ~§é2Ãÿ/•5ÿEêóï÷»üÿcë¯ÇþAþ¡ÿ× ÿXüYJÿuä -ÿúú›'ÿµõ?öòÏžüCþ‡öù û³Çþ_gýçíÍ’ý9þRøc¿Ÿ·ÿ“êûý¯ËÿŸ#ÿ¤ú_gÿo]þ¡ÿuýåüç1ù;3ÿ¿]ÿHý?èô?þüÿøÿñÿÓÿˆþïàþô§ÿ ô‡þôÿ¦ÿ÷5þÙùW9þºû?øþ·Íÿôÿµlÿþ¾þ“ç~žµñ¹þŸÚð­¦ÿ+ýûóß=CýQŽÿ¬°þ%ù3úŸß/ÿoæüËàk?¿Mùò³DÿŽÉ_w¿«ûÿ}þþO—þcóß>^Úÿòêõ§mÿbÿÙ¶ÿðÿÿ¡ÿ#øƒ?ý?éÿCÿúÿXëÿCÿkÛòß[ú×ûõêý:÷3ú¿ëÊÿ:þµõ—›—X¹ïÃùÔ\ÿÚüüCþaÿÛíÿwwü?¯ÿ7ö?ý?á»üo ô?þ?üèô?üÿÃÿÖøŸ|x>sþŸóÿ£ù“Òõ¤ÿIþôׄÏó/óÎÿèç?[?ÿ;Rÿæù‘ú[íãëõ·Èÿ׬¿ÂùÎÿqþŸýû[‹Ÿ9ÿCýË篱ÿ9ÿüÇÿƒÿú[ôÿaÿÁÿÐß.ý©ÿgûóØüÏóÞsýÏÃ¥ú#ñiüo…úO’þO3Îÿéúÿeñ3ùþ_7þgÝþGÿÛŽÿPÿÏvüû϶ýGüùOþŸÝø×Øþo^ý×ú¿RÿŸúÿäÿÿ·Zÿ_Óÿ§½ÿ’ö–Ÿ%ÿŸüÿ5òÿGì?iþÿ -õÿñÿÓÿÓrÿ—ƒŸýõÖïpówæWC£<Þ­ÿxÿ|àø¯wW'%üüûwÁoÇ?=ÞÕ_kÁ¬úC ú‡ï‡]éà;[ñø]¿<ÞÿÞÕû$üï>ÿáû¶¥ÿr¿› ·ÿÜsçñÿáøß.þØÿþxç—Š¯‡ð?u¼õýß™/·­í³tþ×°ÿëø—Ÿ_oþFÇŸßß{}-ý/}þûÍ?úù¿Žüד¿øÿÐÿõ?ô‡þøÿ-ÊIþO |¿ÿé9ÿꌿ~*ÿü‰¿´þ¾rýSüü°Zü'¿ÿòïïò…sû¯Rÿ—6ù›êÿR—¿Òø“TþëíçÐ_*ÿúáçðÇ×âû>wýÅôû»ãÛ¶¶þûûI]ï·?ãñþùþ£ðãñøÿ{è¿miy0¾é£ÿûåÿþíû¿4þùù[aý[¿ÿÄþ¶nÿÇöû¨ýÙgÿkÙ?RüçÛ¿£ó'ÿü?øŸü¿Þý¿ù‡ÿÿþ?üVýsì¿YùWZö—]þÇþ'ÿ øÀ>ðÉÿ"ÿúsþWûüöù'ëçûßçο¶ýÏù?Îÿqþóöò¿Èÿ·ÿýOüŸø?ñâÿ6õ_kü³]þ÷á¯ÿçü§UúÿÇþÃÿ ý­Ò?î?qø…^Ÿãëaÿ‰OÿûêŸÓÖ#5>×cUøÖçßÒú—ú¥ïyùW§ÿ;üÿ#Ïßãÿ×~—øfð_ ~ü?ÿµþÿ÷¬?äúGþù%Õ?Úò?…ÿøó¿sþà?äòø2øÚïÚë?|oµ?¯šÿ~øåñ¥ïçìÿæî?µí{ú-þ¿Ÿü»ûüÛ•ìÿÖóÿ½SþÎÑ?Rÿúýÿÿ?þüÿø?€|àëÅZó®…¯ÿ±$ÿ¡?úÿ þìøþ·êÿÆÿoÕþß÷pü¾‡þÃ}—ùãñû^/…¿ï}þÏþÇü×GçßÝÿøüFžþRøñxòÿÈÿ«¯ÿç£õsï{ÛýôÖ¿õøŽ>ñùQýß&ÿ¤ðóãkúߺü—öÿ“êÿ|ÿ²6ý]ÿ?û¿Uéß²þ¯í9¶þzûjÛ¿Øäàÿ'þ|àŸüß±ø4þ´VþŸõü_âœÿçü+çÿÙÿqþŸóÿÌ?ö·­óÿäÿÿ‡ýOþüOþùøÿðÿáÿCÿòù/øþ‡ÿíñÿ××+ËÏ:ú³¼žôønÛ|ÿæ¿û½®o[8þ…§?þ¸þú>ìÿòïß¹ðãñÛÂçüŸòó»QcøeøÛvîtô'z½Â~E~Ÿ“ë?î›ï­ÿósÅÏö_I}ŸÂËÁ/Ïn^ZáCmúïû\ø1œ°ÿW<ŸÚò_žÿ-ËNá^õóóÑ7þÌ_ÏÇœü×ü·nÿ¿^¥~õeúœí«Òü¿»ÿ_Šÿc~(á—Ò¥ûï¿âú—žŸi¯­ÿ®xþ;Í¿uùÇþƒý¿eükûŸÒ~iÎþCwÿe}ÿ§Ýÿ\ÿƒý?JÿòO»ÿ5òÿþ?üVýØÖùú[¦Í?Ûïìóÿjû?ñÈü—W\×ö¿iãÿÎëÒø4þ§mÿãOé~@9ÿy=þS~×÷ÿïûHüm–ý¿büÏ’ýþ'ÿ«'^½msãÿ+îÿ-Åÿ±ÿlÛÄ¿mÃ'ÿÏvüktÿÓ®ÿûòŸ^ïN[÷Æ?ÓãKöÿó!±o¤û¿Õöÿ+ð¿~üßRþñËþßý²ý×¾Küo=úgFü‡üòÿWÊÿïµÿ¤úG;þŠÿ¿Eþ¥çëŠüÇëíâÿÇõ£_ÈßOØ?äèOôz¹Ïáï^õJßãÃïó÷›?ÿõ•~.ðÛøK÷?RükûŸþWŸÿƒß¾ÿƒþÐ_›þšýïŽÿŒõ¿nÿǺÿmþºýÿàøþ·‰?ûŸþ Ÿ{ß{ï'…/ý=û¿Vÿ³”þ«ÚÿÏGÛz’Æ?´×Yþönïÿ¼¶þ¯ã?cýë÷Fÿ#ÿ×’ÿ2ù;ïüŸUÿúߎþ‡þÐÿ?ò¿þnýÆøåÆ—ó/øÔ´‘ÿ›Ë¿ô¿míñ£tý¿þó×áúo©_U:=zþ}Öùoýó?ãôŸ!Fá;ü[Çùq=3Ýõ·¢üï;¿ÿy×­×ìË_—Í¿6ÿIñÓž¿÷_¿¾þõO¨†ý¯Ýÿç÷{Äþêµÿµí þÚðgÌ?õ¿èÿÿ[®ÿa[þY÷ÿâÿÃÿ‡ÿÏ®ÿObÿÍèÿ£_ÿþÇþ§þ/þðâ?ô²Öÿ úãÿ£þ/þ?êÿÙ¬ÿg½þ¯ ÿÙë_>ÿñxêÿRÿwæþ‡üûO‚ýýOüûŸø?ò¿MþÏÿ®˜ÿÿú[‰ÿcÿÁÿÐß&ý©ÿGýÇéOýË÷×ÿ÷?×ÿ[¡þK ÿ–ú{rÿÿõÿ¨ÿm¯þúŸúÔ³[ÿ ûùÇþǶü_±þ÷õÏ­÷ÿ©ïÿæÔ?_Ïþ§þ?õÿ©ÿOýKú%ÿß;ëÿ—ü_µõ7'ÿýþÇÿÿÿ?þÿwëÿßo~x¹ù?ëCÿ¸ïüïÓã}ú§ÆKá§ô_8üÁü_’Ê—ï‡|ÊÉÿ³ü”âÈçßïü:þåñÛv¾>ÿ1ø¯Ïùùóíèý×þ^²ü¹÷¯í~wÇ_*ÿçÍÏïý35ÛvŸºîÖ÷LþOïáSŸºî??üÿ[æð·mÿÄ|ÿÝïwûøÃÿû4áÐÿ“ÆËüéøƒû¾>ÿÚö¿,þ3£þí*ñŸØßŸ–§ñï¿ÛÇÇ¿ÿý^iý·ãïûÝ¥ë?¾ß8üüxÿú ý ýf?Ï»ŸßŽü÷ãWóô»üõõ¿´þƒõýŸ6ýGæ¿}|}þµ×ß:ö7öŸEûÿ?ñ ý¥ø·Ð¯þ<úƒ?ø[Áß×eåÏ©¿z|¥Ÿ9×KIÕÎã_Ô|>ý¿ÿ~çŠ/þwáóÇý§ZâW-ðåñ/)ýeëÛ¤óß÷¼çßÏ[cô×á©ý?ÃþÕ¬i]þk÷Ó–ÿ²þoéþn^ZúÞ¯þëLþGþ!ÿ°ÿ×±ÿgØŸ#öÿýñ—Òûûþ‡ÿuùß.þèüøÿÐÿ¶õ?üÿÃÿvøßzþ#ã9ÿÏùÿñüIéúÓÎÿ$ÿ úk¿ãù—™çÖ9ÿgóü«O¯°?{z§¿4ÿ¿ýümÔsüÿYçßÒß·œÿ[ãü çÿ8ÿÏþ‡ý¯­ñœÿ¡þç¯ÑœÿGþãÿÁÿýmùÿ°ÿàèOýêÿY¯ÿ4¯þHÿóŽë&þ+Õÿ“ÅÆâëÔJã_ó¿Ï«ÿ£ãÿ—ÆÏæÙŸ:ñ?âÿèê?Sÿø?öŸEûø7òŸü?»ñ¯‘ýßñ»¹õ_uúÿPÿŸúÿäÿÿÇÿ«ãÿ[§þ¿TÿHã?äÿ“ÿ¯›ÿ/³ÿÆòÿשÿÿŸþŸÖâÿ¯'zÑÃÇÿx¾ôuÇ?¯ÿ¹oÓ×k÷ÇKá×îßû|àþŸ‹ÿ«IXÿ¤ü9|Iñ?¿Bx5ükãë¯2¾ýð{ïý¡¿ýµëÞéú_¯þu­þÕ¹ÖÕüuê¿Áÿð?üoëöÿá‹ùû ý—9øÎ¿õò'÷Ç?1þÇõ3ý_¿Ÿ ÿŒúûôß¶sÿ›œ¾ŠûÜHé¯mÿ·à_[¹y‰í÷}8Ÿšë_»ÿÍ -ë_‚ÿ ùwçþ?èä¿tý‡}ÓfÈß³üOËeöèô?ô·KüÿĪö×¹NüÿCíÿ‘øOÜ¿düüå˜üí_¶gdý_¤òÿžñ¿>úÔ÷ÿ½ó/~~Íõ§-ßÇüÿ.Ÿ8¶ïsãËþ=øÈÿ‘ý_¸Ÿ‘ο®üÙÿ…ë¯eþÊû¿»ñß<ÿ7ñOâŸØÿwËi¯ŸÚ–ÿ£iÿè>¿öü“ÿGþüOþŸUùgÝ¿‹ÿÿþ?Ëþ?™ý7#ÿ_7þÿcÿcÿkÿ¹ûùðÿÏÂÿ½ú_[þKõ~ø]}ÿý¡¿ý¥õ¿¶íüýó‘®/õ|¤ëY­qþe¬þÕ<ù/…/­{¦Èi:KëŸù<‚׊i|éï|þ«Äÿ-ëïõžâÿçãÌÿÚë_›ÿ?Gþ×ÿ{>æÎj~ýùO׿³)ÿ°ÿÕãÏŒ¿müûÿsöÒþiWô_{çú·®ÿ´ég}ýÝGþÏ‹ÿkÇ‘ÿÐ-øØØøÿ¡ÿûý_ô¿´Ýÿ‘þ¯×?ýèÿCÿ«ýèYý×yýµå¿õþ¿ØÈ?{òù?«ÿõ˜ý¿Îú—öß•Òÿ>ýÓû?©þ×±ÿÑÿºüÿ9òOªÿuöÿÖåú_×ÿWΓ¿3óÿÛõÔÿƒþGÿãÿÇÿÿÿ?þðð¿éù§yò_Gÿ[—ÿÐý?ÇÿÓ¾]ÉÿgÝÿ…ýÿÃÿø¿ÁŸüïVÿ㾇þÇÖñ¹ø—&üúÒxòÿðÿ÷Æ¿sþüÚø\üõOü_öYJ¿ÙÏóîç·#ÿÝzž©ÿÛ寯ÿ·­ýùsõç8ÿ¡Gÿ‘ùo_Ÿíõ·ŽýýgÑþÃÿÿø/øƒ¿õø¿4þ3æ_^GþÛÌÿ%þÇþó¯ÄØÿqþŸóÿÈ?ì«ø“ÿCþö?ùð?ùäÿáÿÃÿ‡ÿýoçüüÿÃÿ¶øÿõD/zøøÏÇu®Ÿ¯;ùùúŸû6}½vÿx¼~íþ½Ï÷Ùø¿z‘„ýOz>K×—ôþÒçï‡Ï_íU»?ô¿ýçÂ×”ïòüoyþó××+ŸÙŸ{~ÿþÿà×kãëgüeù¯Rù¿Rÿ'׿>ßÿ*þýüùwÿ=‡¯Ž?Së¯6Þ¿ó¿þú—æÈò´õŸÿãþáüóÜ:ÿÏÇÜù«jQþaÿ³¿µ~½ß~ _ÒõUÛ/õï¿ÊÏÛ¿?ûÜýŸvÿaýýuû_—~Ö×ß=å?þ?üøÿ>Áÿ‡ýÿCËö¿¾ÿQ¾uûolþçù?ï¹þçúÿý;þÿþ¼ø4þ§máο‹#9?~,ÿKñŸµüÿ}ñ³ùûÿ÷Æÿˆÿ£ÿ-ÇZâß±¼Šå™tþµå¿õø?öŸ]ûø7òŸü?»ñ/ÉþÇé‰ü;ö'ÛÖnÿ§âŸ¥ñÁõèÿ#úîþoµýÿ;ùÿžùÏÖóÿˆÿ’ÿWÓÿ§¿ÿñ?Í‹ÿÿOþÿjùÿ=öߌüÍø/þÿþ™ÿ×±ÿ‰ÿã:’ñûWæ•û]m|í{àøï‡Ÿö?<9ùû®†_ÿmÿ]öh‡þÐ_›þçúÓqýj÷ÿ±ú×ùúÓwÇÿîóŸÞÄû7ç?ˆ÷sðÏïãß²ÿ,íàøß:ÿÛÅŸýG¾õwëû?ç_,_—Îóªö+~Úó7cþÓò×ÉÙøúó1oüºú_öüw™ô?òEùÿ.ùËþýo]ÿCèÿß²ü·}þüÇùÿjþþõð5óÿâ¼¹9ç/Îùé¼¼tþW-þÕ–ÿ׿'þ6#þ¥{þ'5ÿíù—)üÓùîy9ÿSסýºï²ýuíþÏÇ\øû>kÿoAþŸÖõóY^Iè¯-ÿkøÖÖ_n^ZçsÅõ¯}]›ÿî>È?à_wþw^ÿ{žþ¤ó¿­ûŸô~eÎúߥíÿÔø’ý†Ÿ;ß4fÿ—íø_›ÿÇ÷ßW¬íý¿5ùGýOüøÿðÿÙ­ÿ3nÿÍXÚöüýoÛþW_À>ðo(ÿßÿ:ù¿|èý5è~ÿûyçõ8>•»â?o|ø~œ+qóïjeù÷¿jþûá—Çûßo›n&KŸÎ÷¹óï×FÁ?_ûþ¼ÈáW[­ãsŸ×XÿÚü?ùw÷ù·.ÿìÚÿºñ?ýø·uü±ÿmÛÿûÊO·~üú°ãò׿ÿïwxÿuÖ¿]ý7‡þRù7oýÅãÛðGÿéÄÿµã¿Èëô¯ÿÞFÿ0þ÷ÀþÃþÃÿýõè¿bý©{Ô¿Ò®¿y|ëóoiýKýÇÒwÝúÏrü¤þíw‰ÿa^ýñ4üø/~þkýÿïYÈ?ôÏjõÿûå—TÿhËÿþãÏÿÎùƒÿÈ?àËàk¿k¯ÿð½Õþ¼jþûá—Ç—¾Ÿ³ÿ›»ÿÔ¶ÿíéÿµøÿ~òïîóoWþ±ÿ[Ïÿ÷Nù;GÿHý?èô?þüÿøÿñÿÓÿøÀ>ýßéÿý¡?ý¿éÿýÞø[þéüuíoøþ·Íÿôÿµ½ÿØ÷p|ísï{ïý¤ð¥¿?þŽ—û<6ÿîþµûͧÿ/ý_Kýç]¿ cý„ñƒ}—Åâñuþçú—ÄOæÌ¿vü'GÿC×Gõ^þ¥Ÿ¿~ZÿÇãkúߺüïÿ'Õÿµþe5}~uÿ?«ýŸµé¿mmëÿêþ—c믽ÿ¡¶ý‹ý‡ý‡ÿŸøý|«ý?éÿCÿúÿXíÿCÿkÛò¿Þ¿¾ü.mþ“â§=ðòùü»öÿ»3þŸØûŸþŸð¿]þ·†?úÿþ?ô?úþ‡ÿáKüo=ÿü9ÿÂùÿ}/çOßæ•ó¿õó?ÉÿµMÿ}Ÿ ?¦ÿ¾‡ðÝý×8ÿ²ÞùŸwæ?sþ7×ÿ2<”ª_6#ÿ¿Ôÿ®~þGÞÿÎzþ¿æù³uÏÿ[:ÿÇùÎÿ³ÿçü?çlÖÿ?ÿÝ&Ýý}›kýö?çÿ9ÿÿÿþ?{þ?ì?ÎC›ô§þþê¬æ³ò.ÿHã+ØÒþOÒów«ÔÿËÇÏŽë£õ¿kûÿõâVìô?ù_Ôÿ³ÿÇþ³mÿÿFþ“ÿg7þ%í_:gÿ¹^ÿêÿSÿŸúÿÄÿ-ÄÿWôÿ½³þ¿DÿÌ9ÿJþ?ùÿšöïœþõ£úG;þ‹ÿŸþŸvó?BúÏ—£ÿyþÏxÆß|\—$]ÿå\?å]ð¯~~møÐúëÊóûï÷;¯ßÿ{Ï¿ôOÎÿµû_ûüð?üo™ÿÁߦýïúÓrøÐ_·þ«¶þÕ¯?º -ÿ…ï9ùéÿ.„_ï¿’ü‡ÿÝçýüרÿ­+­ïÿÐÿèèo—þøÿñÿ¹óÇùÄÜùÏ1øñxw>+=^ -?•ÿþÄ¿_Zÿá^±ô¹7>ãå¢ë3-?ÝïÛ×i|›ü—ÆŸ¤ò_oÿ;‡þ2ù·mmð[â-Ï{þý¼õ—²™Ýýüóúÿò_Vÿ¡Íþt÷?Ó¿œÿ=¿'ÿÿOLÿÒúÛÿ•è¯-ÿÇñoßÿùøÇü¯½þ­Ç߈bÿbÿ—íóûKjÿëïÿ¥øK÷ÿóæ?=¿äÿ‘ÿÿ“ÿ×OŸO—ø¿ñÿáÿÃÿgÑÿ7Ïþ“ž?ÑŽÿÚåìÎÿ0žñŒçü?ù_œÿ‡þó¿uΟ¬ÿ²éÿËÑ¿´WNýNž¬cÿ“ÿÏù?Îÿqþø?ùÿ–óÿ±ÿ‰ÿÿ'þOüß¶þ«Å?GäW[üW;þÏùO«ô'þý‡ÿú[õÿk÷ŸÑ„ŒwßÅ0ãëŸ5Þúü[_ÿRÿ³GòûÑ8º„×ãïËò«N¿«ýÿ9‡ÿ1ÇõÑùw÷?>ÿƒ‘§¿~<~Äþöù)¼Úÿ-ô¯ÍÿŠö¿ôùß9ÒñŽ_Ú>÷¾·ÝOoýâ5—~zï9úü~ŸÏÓèÿ6ù'…Ÿ_ÓÿÖå®ÿ_8Ÿãò«¦ÿsýÏZõ~|›üµ¾ÿ[•þ-ëFÿ»}Ÿ»þžòü¹û­aÿbÿÙ¶ÿðÿãÿ>ðÏùkù¿Öóÿˆÿ¡ÿµíÏÇ[Ïÿbÿggÿÿ1ÿØßÖá“ÿCþö?ùð?ùäÿáÿÃÿ‡ÿýÏùøþ‡ÿ?—ÿ¿¾^ùX~þÓÑŸåõ¤ÇwÛæû7ÿÝïu}ÛÂñ/<ýñÇõ£?‰ëÿòúý\øñxwý¨ÏàÏ?ø?åçw£ÆðþÊð~G®±ëOtôCrýŠÂ>Ç3ÖØ7ù ¿¶þÏÏ?Ø9õ} -/¿<ÿ¹yi…ýµé¿ïsáÇpÜýSó©-ÿåùß²üçþáõX??}ãÏüõ|ÌÉÁúýßÏë?´§Óô÷á•és¶¯Jó_ê¿×‚ºÿŸã¿ç£Îÿ1?”ðKéÒýÎ÷_qýKÏÏ´×ÖW<ÿæßºücÿÁþß2þµýOi¿4gÿ¡»ÿ²¾ÿËÛÿçþÃcò×ßÿÄýŸWØÿ`ÿÒ†ü+ÿ[}ç‘ÿøÿðÿáÿ³êÿÃþ³ÎÿÐß2ýkþÙ~ÿcŸÿWÛÿ‰ÿC濼⺶ÿMÿw^—Ƥñ?mûïJå£åýçõøOù]ßÿ¿ï#ñ·YöÿŠñ?Kö?úŸü¯žxõ¶Íÿ¯¸ÿ·ÿÇþ³mÿÿ¶ Ÿü?Ûñ¯ÑýO»þïËz½;mÝÿL/Ùÿχľ‘îÿVÛÿ¯ÀÿúñKùÄÿ-ûWôÿÉö_û.ñ¿õèŸñòÿÉÿ_)ÿ¿×þ“êíø+þÿù—ž¯+ò¯·ÿ‰ÿ×~!?aÿ£?Ñëå>‡¿{Õ(}Œ¿Ïßoüxü×Wú¹Àümã/ÝÿHñ¯íjø_}þg ~ûþúCmúkö?¼;þ3Öÿºýëþ·9øëöÿƒÿáøß&þìNø7|î}⦅¾ô÷ìÿZýÏRú¯jÿ?mëIÿÐ^ÿeù?Ú¸½ÿóÚú¿ŽÿŒõ¯ßÿýü_KþËäï¼óVýè;úúCüÿÈÿvú»õã—_Îþ½àSÿÑFþo.ÿÒÿý¶µÇÒõÿúÏ_‡ë¿¥~Uéüõèù÷Yç¿õÏÿŒÓ†ü…ïðoäÿÅõÌt×ߊò¿ïüþç]·^ÿ±/]6ÿÚü'ÅO{þÞýúúÔ?¡þö¿vÿŸßïû«×þ×¶$økß1ÿÔÿ¢ÿüo¹þ‡mùgÝÿ‹ÿÿþ?»þ?‰ý7£ÿ~ý_øûŸú¿øÀü‰ÿÐÿÉZÿ'èÿú¿øÿ¨ÿg³þŸõú¿2üg¯ùüÇã©ÿKýß™ûòï? >ö?ö?ñìâÿÈÿ6ù?7þ»bþ7þ?èo%þýÿC›ô§þõW¤?õ/ß_ÿoÜÿ<^ÿo…ú/%ü[êïÉýÿkÔÿ£þ·½ú?èê?RÿÍný7ì?äûÛòÅúßkÔ?·Þÿ§¾ÿ›Sÿ|=ûŸúÿÔÿ§þ?õÿ-éÿ•üï¬ÿ_òÕÖßœüô?úÿ?þüÿøÿß­ÿ¿ýù=àåæÿ¬?ýã¾ó¿O÷éŸ/…ŸÒáððI*_¾ò)'ÿÏòSŠÿ!Ÿ¿Sðëø—ÇoÛùzøüeüÇà¿>ççÏ·ÿ¡?ô_Cþù{ÉòçÞ¿¶ûÝ©üŸ7ÿ=¿÷ÏÔlÛy|êº[ß3ù? ¿†Om|êºÿüð?üo™ÿÁß¶ý?ÿñýw¿ßíãÿsìÿÑ„?BÿO/óÿ¥ãîûúükÛÿ²øÏŒú·«ÄbZžÆ¿ÿýnÿþ÷{¥õߎ¿ïw—®ÿø~ãðóãýë3ôÿ5ô›ý<ï~~;òß_ÍÓÿíò××ÿÒúÖ÷Úô™ÿöñõù×^ëØßØí?üÿÄ$ô—âßB¿^øóèþào_—•?§þêñ•r|æ\/%Uÿ9i|Póùôÿ>üSø+¾øß…Ï÷Ÿj‰_µÀ—Ç¿¤ô—­ÿm“Îßóž?oýÑ_‡ÿ¥öÿ ûW³þ¥uù¯ÝÿM[þËú¿¥û¸yié?x¿ú¯3ùù‡üÃþ_ÇþŸaŽØÿ÷Ç_Jììøþ×廸£ÿñÿáÿCÿÛÖÿð?üÿÛáëùŒçü?çÿÇó'¥ëO;ÿ“ü/è¯ ÿŽç_fžÿYçüŸÍó¯>½ÂþìéýAžþÒüÿöóÿµýQÏuòÿgKßrþoó/œÿãü?ûö¿¶Æsþ‡ú?œ¿Fÿqþùÿÿô·åÿÃþƒÿ¡?õ_¨ÿg½þÓ¼ú#=þÏ;®ÿ™ø¯TÿOÿ‹ÿ­Sÿ)Íÿ>¯þŽÿ_?›gêÄÿˆÿ£ÿ©ÿLý?âÿØí?âßÈòÿìÆ¿FöÇïæÖÕéÿCýêÿ“ÿGüÿ¯ŽÿoúÿRý#ÿÿOþ¿nþ¿ÌþËÿ_§þ?þúZ‹ÿ¿žèxj÷üpë\ÿìëÒ×Õð¯~~møÐúkÑ¿Í~©åOŽ¿;þwŸÿ¶úUùúióð¯Á¿îùáøþ·‰¿uûÿðWýý„þ«ÜxçßzùëµñÇõÕàCÿ¸o;—4dêwÒù×Ô¿-ø×Ö_n^RpRßkóß¹ÿÌó‘“ŸcýoòýgVXÿüï>ÿè俦ü×–¿ìÿÐÿÖõ?ô·KüÿÄ^¹aþÑŸ¾>ûþñx)üÚýÁû—ëéó“µþ'©þ9ãùOi‰èú£´¬ÿÚø²þ—ÅŸäöÇ -þÿqúKåŸvÿ§ôz‘®¿ÞûëÉÿ#3´óðÇìOwÿ3ýSö¯þüÿ¥ý˜¿^Z¯cû¿<ýõåÿÚú«ïÿüüïó|j®ëñ7âŸØÇØÿzýõíþóì_Íþ¯äÿÙÎÿ³ÎÿÖóÿìÊ?ëþ_üøÿðÿYöÿÉì§úS7þÿcÿsþç®çOÏxÆëÉÿ÷Á¿úùµáCè¯AÿÿÔ½ŠÞsõ•âú_î|Iy¼ÿ}\uó/ùúPm×¥ô“»ž£Èy:ÏšÿÚ_ ¿Ñ¿óú{½§ù¿eý¥Ç»øÈÿÚë_›ÿ?GþÝ}þmÊ?ìÍøßñoëøcÿÛÞÿIê¿¶×W­ÕgÕ]ÿ–õßúKåß¼õ7¯þ¯=ý÷Þø¿vüùýûð¡<~þ?ööþè¯éÿúû)÷¯rÿëYë?¦ ¿¥E­äÇ[Ÿëë_ênéÿSë?“—_uú]íÿÏá1Óÿ÷ÿÉõékíÿ36ÿcþ)ÿµß¿½ÿÏ<ÿÍõëù‡þצ¿$þ,ÿuä -ÿúú›'ÿá?äòñZë_Çþ\gýKÿ¤ôÓù›·ÿ“êûý¯ËÿŸ#ÿî>ÿ6åú_×ÿ§-çé©ÿýþÇÿÿÿ?þü_À>ðß©ÿuâ?+Ø_ØÐÿŸMÿ¿uÿŸöþÞþëŠúð?üÿùüþ¶íÿ}Çß½>Ç×Cø¹ç/ß÷òx)üxüßOy|ÿcþŽë£óïîï÷\ÊÓ_ -??bûü^íÿú׿Eû_úüïœ?éxÇ/mŸ{ßÛî§·þGñšK?½÷}~¿ÏçéGô›ü“Âϯéëò?ìæëÏÔõ~ùUÓÿ±üìÕÿùñmò×úþoUú·¬ÿÔü§Î¿—æß箿ç£<î~kؿضí?üÿøÿ€|àsþßZþ¯õü?âèmûsÅñÖó¿ØÿÙÙÿÁÌ?ö·uøäÿÿ‡ýOþüOþùøÿðÿáÿCÿsþþ‡ÿáÿÏåÿ¯¯W>–Ÿÿtôgy=éñݶùþÍ÷{]ß¶pü OüqýèOâú¿¼~?~<Þ]?ê3øóþÏGùùݨ1ü¿2ü£ß‘ë_ìúý\¿¢°ÏñŒõöM>ï­ÿósÅÏö_N}ŸÂËÁ/Ïn^ZáCmúïû\ø1wÿÔ|jËyþ·,ÿ9…x=ÖÏÏGßø3=sò_gðŸ~ÿ÷óúíé4ý}xeúœí«Òü—úïµàŸîÿçøïù¨óÌ%üRú£t¿óýW\ÿÒó3íãµõßϧù·.ÿذÿ·ŒmÿSÚ/ÍÙèïÿòöÿ¹ÿð˜üõ÷?qÿçö?Øÿ£ôŸ!ÿJçÇÖ_ßù_ä?þ?üøÿ¬úÿ°ÿ¬ó?ô·Lÿš¶ßÿØçÿÕöâÿù/¯¸®íÓÆÿ×¥ñiüOÛþ;ÇŸRùhyÿy=þS~×÷ÿïûHüm–ý¿büÏ’ýþ'ÿ«'^½msãÿ+îÿ-Åÿ±ÿlÛÄ¿mÃ'ÿÏvüktÿÓ®ÿûòŸ^ïN[÷Æ?ÓãKöÿó!±o¤û¿Õöÿ+ð¿~üßRþñËþßý²ý×¾Küo=úgFü‡üòÿWÊÿïµÿ¤úG;þŠÿ¿Eþ¥çëŠüÇëíâÿÇu^¼xÙ}Åò%–µëWÿúùµáCè¯ùòk+¥¾ÿ®$wüï>ÿ~}/}æü±ÿ@ŽþÕÏÿÃÿ¶ùß6þÖ_G½Àø½õ÷µïãë«Á·þ’úŸ¤ó¯­kø×ÖŸÔÿ¦½þµë®°þ%øß}þÑÿÈMù¯-Ùÿ¡ÿ­ëèo—þøÿ‰ÿøù…q~búzïüÖî—¯ݿ÷ù>®[½îz£„õžrù—çü©–ø‹?>¬ÿ—®2“?ÿ™Â¯6¾ôrÏŸþ¾%~$yIãWsÆÓ_*ÿÒó_‚ŸÃ¿4þ¼fËëEºþzï¯'ÿ­Ÿ@þëÖÿÓ—ÿÔÿÐÌ?^aý[>ÿ}ŒýÛW¥ó—cögÙþ×µdøÏ³¿çÍêükmÿPÛÿäígùúßÍxþÚ«†Ÿôÿkóÿuù£Wß¿ÿ·%ÿ¬ûñÿáÿÃÿgÙÿ'³ŸfèOMû þÇþÇþW_Œg<ão(ÿßÿêç׆ý¡¿ýÏu®^ïǹ -7ÞíýúR®¾Ry¼ÿ½{>ýúw1~ñóµ_—ÒO -ìzŽþ!oäéÿ6åú_×ÿ§-çé©ÿýþÇÿÿÿ?þúñâÅ‹þïôþПþßôÿ¾Æÿ#³_åøëÚßð?üo›ÿéÿkùõ÷ãúÿ8ÿáñw¼Üç±þ“îþµûÍÏ÷¿Œïßö¹÷Õ{?)üößÓÿ•þ¿ÇŸÏ?ÇùAÿ7ãñw¿çØ*ë_™3ÿÚùO޾Çüåè?¦?óôLëïvømãkúߺüïÿ'Õÿµþg5ýuÿ¿ÏßÿéÒ¿V¿¾¶ž¯î9¶þÚûjۿضí?üÿÄèÈu®[îÿIÿúÿÐÿÇfÿú_Û–ÿqÝúTÿúm+õ¹—ο®ü¯ã_[¹yIÁI}ÿ!ÿ\·ØÿïîøNÿEìúÂÿvùß&þèüøÿÐÿèøþ‡ÿ­ñ¿õüGðçÅù—ߙΟŒ¯÷æ/å׳vþ'ù_п„ÿüÞûkŸÑ;ÿ£Ÿÿlýü¯£¿Ÿÿžë?×ÿ—Ÿÿ(÷¯«Ÿÿ‘ö¿#ÿ_óüÙ -ç_8ÿÇùÛ/öÿVñçüõ$ç¿Ûäo<~¥óÏÔÿáü¿uùÿÿþ?‹þ?ì?øúÛ¥?õÿlÛÚõGÖXÿzø¯Tÿo$þ#ÿ­PÿIÒÿiÆù?]ÿHßtü,¼Þ_ÿ»´ÿ×ÿY·ÿÑÿ¶_Ôÿ³ÿÇþ³mÿñBþ“ÿg7þUÛÿÄöóXþ_iþõû¿RÿŸúÿÔÿ'þoÑÿ«íÿÓ®ÿ/Õ?òó¯äÿ“ÿ¯ÿ?nÿIõÏ -õÿñÿÓÿÓnþ¯Tÿó[’îþ¯ùwò/ÍRø)ùïÃùüÁü]ýâã»m+Áý~>þ­ðsøŸÇ‡õ—ÃZ0ãøçá»y9ãü67ŸÐúëÐÿ¸¯ûûGCŽBøÏGß}ïèŽ?¾÷ïÿ9øK×ÿ¼ùÇû×ïܾ!ÿ¶•áÏåÿ~ø5üýújñóÆ÷†ÿáøß2þØÿñø¿ŸÔõ~ÎVïâeüGáÇãŸòxèŸÖÏGiþsŸ¥ô_Çþ/ãŸþ´<‹ñÏÏŸÎú?ËÏÜõ˜¾ñ÷iúç↑þïÃ_ºþçÍÿ¾Ï¡úù¯)ÿGåoš_òÏÏþýþ‡þÐÿ?ò¿ßçßmkŸ£?ðïŸøÿ'âßñ¿míûÇœÿ¿Wþ–×~|NþŽÆ¿æÊÿûÄÿÒô—ÊŸ~ø!ýëããõºm+­¿õä«ýþ©ãñÿ´í_æÎ¿6ÿµâ?¾¾vþ®ÿ®øñOâŸØÿëå¿´Ú_cö¿–ý#Å_¾tþÉÿ#ÿþ'ÿϪü³îÿÅÿ‡ÿÿŸ]ÿŸÔþ›•ÿ¯ÿ…ÿ±ÿ‰ÿãÿð'þCþù¿Ðß¶ÿOûüöù'ëþ¿ÜçôûüóOÚö?çÿ8ÿÇù?Îÿ±ÿ!ÿÝ|ììâÿØÿÄÿ‘ÿ%øNÎéÀ¿>ÿÿô·wþûþ‡þöèîÿõú_ûOäúW”Æï{y¼~<þï§<^¯ÿYùùGá§ú_åú¬Lëø¿wýûŸkï¹ûÕýÿuú¿ÓÿŸÃOêÿï¯Þùnýýˆÿa†ü+ù?Rûõ¿ŸwùÿÇÖ_¯ýƒüCÿëÓ<þ,¥ÿò?…Ûú›#ÿ×[ÿØÈ?Ëû[øÏ³?ÇìYýýÏßO¿ý9þRøùñþuÿ»ßï™û?©þ_Ïþ·¥ÿ×ãÿ{É?©þ×ßÿÛ–èÿÕü£òwfþ»þ‘úÐÿèüÿøÿñÿãÿÇÿþàþºñŸ–ü£yò½ø-ùýmÓÞþ3Þgú÷Ïßïîøžÿûþ‡ÿíð?þö?-þÇØû©ãsóïÿýnŸ£ÿðÉÿ#þ¯ùY{ýÿoÕ¿i{nþü÷Á¯ÏÙŸÈÿýäú·]þ¶—öÿ³íÿÓ¦Ëú¿¶ÿå;ן¶ý‹ýgÛþÃÿOüÿøƒ?ù¿#ñŸqÿÿªùÖó‰ÿqþŸó¯œÿgÿÇùÎÿ#ÿ°ÿmÿ'ÿ‡ü?ìòÿàòÿÈÿÃÿ‡ÿÿúÿsõ?üÿÃÿÖøÿëëåòñ?žïÅ)ÇwÛæÏÏ¿û×kãë/¾ ñþÝà?!üm ÇpZá?sáÇã·-„ÊëøoÛ¹ÿÉÑŸäõ -û•ø¿Ÿ±þjðkë¿åùýç-áÓ?œÿm;÷q°ëð¡ÿÝè?¾¶ü¿.¾m|êùßy]’ÿ:Cþ¯Ûÿ«­ýìùwÿ½ÿöàW/½¿ÞúoÍÿå?hë?)þçç>úæÿù˜;ÿcõO­Ê?ö?ì-Ãï·ÿÃ}Žtý‡}3gì¿âçûž¿·½ÿÓî?¼îþǦýßCùÿ¬õw?ùÿÿþ¿OñÿaÿÁÿÐß.ýµý+^·î(ÏÏ\ÿçýÖÿõøËà×î_öÿöƤñ?mû«ÿpþÎúëùè‰ÿ¬æÿo¿Í²ÿWŒÿY²ÿÑÿäiƯWÜÿ[ŠÿcÿÙ¶ÿˆÛÆŸü?Ûñ¯Ñý¿Þgæ?Õíÿrüó<>ôÿùÞ¹1ýuÝ­ï™üŸ†_ç6>uÝ~øþ·ÌÿàoÛþ‰ÿøþ»ßïöñ‡ÿ9öÿh¡ÿ'—ùÿÒñ÷}}þµíYügFýÛUâ?±¿?-Oãßÿ~·ÿû½ÒúoÇß÷»K×|¿qøùñþõúÿúÍ~žw?¿ùïǯæéÿvùëëiýëû?múÌûøúük¯¿uìoì?‹öþâ?úKño¡_/üyôð·‚¿¯ËÊŸSõøJ9>s®—’ªÿœÇ¿4>¨ù|úþ)üÎ_üïÂçûOµÄ¯ZàËã_RúËÖÿ¶Iç¿ïyÏ¿Ÿ·þÆè¯ÃÿRû†ý«YÿÒºü×îÿ¦-ÿeýßÒýܼ´ô¼_ý×™üüCþaÿ¯cÿϰ?Gìÿûã/¥?ö?ö?üÿëò¿]üÑÿøÿðÿ¡ÿmëøþ‡ÿíð¿õüGÆsþŸóÿãù“Òõ§ÿIþôׄÇó/3Ïÿ¬sþÏæùWŸ^aöôþ OiþûùÿÚþ¨ç:ùÿ³Î¿¥¿o9ÿ·ÆùÎÿqþŸýû_[ã9ÿCýÎ_£ÿ8ÿüÇÿƒÿúÛòÿaÿÁÿПú/Ôÿ³^ÿi^ý‘ÿç×ÿLüWªÿ'‹ÿŒÅÿÖ©ÿ”Æ¿æŸWÿGÇÿ/ŸÍ³?uâÄÿÑÿÔ¦þñì?‹öñoä?ùvã_#û¿ãwsë¿êôÿ¡þ?õÿÉÿ#þÿWÇÿ·Ný©þ‘ÆÈÿ'ÿ_7ÿ_fÿåÿ¯Sÿÿ?ý?­Åÿ_Oô¢‡ÿñ|éëŽ^ÿsߦ¯×î—¯ݿ÷ùÀü?ÿW-’°þIùsø’â~…ðjø×Æ×_e|ûá÷ÞúCúk×?¼;þÒõ¿^ýëZý«s­«9øëÔƒÿáøß.þÖíÿÃó÷ú/sðëåO<îŽ>büëgú¿~?þÿ>ô÷é¿mçþ79}÷¹‘Ò_ÛþoÁ¿¶þróÛ#îûp>5׿vÿ›Ö¿ÿòïÎýÐÿÈéúû¦Í¿gùŸ–ËìÿÐÿèèo—þøÿ‰ÿTí®søÿ‡Úÿ#ñŸ¸ÉøùË1ùÛ7¾lÏÈú¿Håÿ=ã}ô©ïÿ{ç_2þüüšëO[¾ùÿ]>qlßçÆ—ýÿzð‘ÿ#û¿p?#]ù?²ÿ ×_Ëü•÷wã¿yþoâŸÄ?±ÿï–ÿÒ^?µ-ÿGÓþÑ}~íù'ÿü?øŸü?«òϺÿþ?ü–ý2ûoFþ¿nüþÇþÇþ×:ÿs÷ó/àþŸ…ÿ{õ¿¶ü—êÿ4üð»úþ úC-úKëmÛùûç#]_êùH׳ZãüËXý«yò_ -_ZÿöLÿ?Òt–Ö?óy ¯ÿÒøÒßùüW‰ÿ[Ößë=ÅÿÏÇ™ÿµ×¿6ÿŽü¯ÿ÷|ÌÿÔüúóŸ®gSþaÿ«ÇŸÛø?öÿçìÿ¤ýÓ®è¿öÎõo]ÿiÓÏúú»üŸÿ׎ÿ"ÿ¡ÿZð±ÿ°ÿðÿCÿ÷û¿èi»ÿ#ý_-®úÿÐÿ‡þ?Vûÿ ÿÐÿ²ú¯óúÿjËëý±ÿöäòVÿë1ûõ/í¿+¥ÿ}úÿ¦÷Rý¯cÿ£ÿuùÿsäŸTÿëìÿ­Ë?ô¿®ÿ¯œÿ<&gæÿ·ë©ÿýþÇÿÿÿ?þüàþà=þÒóOó俎þ·.ÿ¡?úŽÿ§}?º’ÿϺÿ ûþ‡ÿñƒ?ùß­þÇ}ý­ãsñ/Mø#ôÿ¤ñäÿáÿïçüùµñ¹øÿëŸø¿ì³”~³ŸçÝÏoGþ»õ¾>ÿÚëoûûÏ¢ý‡ÿÿñ_ðëñiügÌ¿¼Žü·™ÿKüýç_‰ÿ°ÿãü?çÿ‘ØÿVñ'ÿ‡ü?ìòÿàòÿÈÿÃÿ‡ÿÿúßÎù/øþ‡ÿmñÿë‰^ôðñ?žë\?_wòóõ?÷múzíþñx)üÚý{Ÿï³ñõ" ûŸô|–®/éý¥Ïß?ž¿Ú«vè/úÏ…¯)ßåùßòü篯W>³?>÷üþýÿÁ?®×Æ×ÏøËò_¥ò¥þO®}¾ÿUüûùóÿîþ{_ÿ¦Ö_m¼=æýõ/Íÿå?hë?)þÇýÃù?æ¹uþŸ¹ó?VÿÔ¢üÃþgkýz¿ý¾¤ë«¶_êß•Ÿ·ö¹û?íþÃúûëö¿.ý¬¯¿{Êüøÿðÿ}‚ÿûþ‡þ–í}ÿ£&|ëöߨüÏóÞsýÏõÿþûw.ü3þ!üyñiüOÛþÃ?œGr~üXþ—â?kùÿûâgó÷ÿïÿÿGÿ[Žÿ´Ä¿cyË3éükËëñì?»öñoä?ùvã_’ýÓÿùwìO¶­ÝþOÅ?KãƒëÑÿGôÿÜýßjûÿwòÿ=óŸ­çÿÿÿ$ÿ¯¦ÿOÿ5âšÿ!ÿŸüÿÕòÿ{ì¿ùÿšñ_üÿ#ü3/þ¯cÿÿ?Æu$ã÷¯Ì+÷»ÚøÚ÷À>ðß?íx>rò%ö?\ ¿†Ûþ»ìÿЄý¡¿6ýÏõ§ãúÕîÿcõ¯óõ§ïŽÿÝç?½ÿˆ÷oÎï?æàŸ‡_Ç¿eÿYÚÿÀÿð¿uþ·‹?û4|ëïÖ÷οX¾.çUíÿVü´çoÆü§å¯“³ñõçcÞøuõ¿ìùï2ÿèäÿŠòÿ]ò—ýúߺþ‡þÐÿ¿eùoûü3øóÿÕüüëákæÿÅyssÎ_œóÿÒyyéü;¯Zü«-ÿ¯~OümFüK÷üOjþÛó/Sø§óÿÜórþ§®ÿBûußeûëÚýŸ¹ð÷}Öþß‚ü?­ÿêç³¼’Ð_[þ×𭭿ܼ´ÎçŠë_ûº6ÿÝ}þÀ¿îüï¼þ÷<ÿüIç[÷?éýÊœõ7¾ÿJÛÿ©ñ%ûÿ ?w¾iÌþ/Ûð¿6ÿ￯XÿÚûkòúŸøÿðÿáÿ³[ÿgÜþ›±þ´í/øûß¶ý¯¾þ€|àßPþ¿þuò5øÐúkÐÿüþ÷óÎëq|*w=ÄÞøðý8WâæßÕÊòïÕü÷Ã/÷¿ß6ÿÜL–>ïsç߯8‚<¾öýyï¶þZÇç>¯±þµùÿ~òïîóo]þÙµÿuãúñoëøcÿÛ¶ÿ÷=”ŸnýøõaÇå¯ÿßïðþ묻úoý¥òoÞú‹Ç·áþÓ‰ÿkÇ‘ÿÖé?^ÿ½þaü?î?€ý‡ý‡ÿúëÑÅúS÷¨¥]ó:øÖçßÒú—ú¥ïºõŸåøIýÿÚïÿüúãiøñ_üü×úÿß³þèŸÕêÿ÷Ë/©þÑ–ÿ)üÇŸÿóÿ!ÿÀ—Á×~×^ÿá{«ýyÕü÷Ã//}?gÿ7wÿ©mÿÛÓÿkñÿýäßÝçß®ücÿ·žÿïòwŽþ‘úÐÿèüÿøÿñÿãÿ§ÿð|ú¿ÓÿúCúÓÿû½ñÿ¶üÓ9øëÚßð?üo›ÿéÿk{ÿ±ïáøÚçÞ÷ÞûIáKü/÷ylþÝýk÷›?Oÿ_ú¿–úÏ»~AÇú ãû.‹?ÄãëüÿÎõ/‰ŸÌ™íøOŽþ‡þ<®êÿ¼üK?;ü´þÇ×ô¿uù?ÞÿOªÿkýËjúüêþVû?kÓÛÚÖÿÕý/ÇÖ_{ÿCmûûûÿ?ñú/øVûÒÿ‡þ?ôÿ±Úÿ‡þ×¶å½}ù]:ÿÚü'ÅO{þà?äòøwíÿwgü?±ÿ"ö?ý?á»üo ô?þ?üèô?üÿÃÿ–øßzþ#øsþ…óÿû^Ο<¾Íÿ*çëç’ÿk›þû>~Lÿ}á»û¯qþe½ó?ïÌæüo®ÿex>(U¿lFþ©ÿ]ýü¼ÿõüÍógëžÿ·tþóÿœÿgÿÏùÎÿجÿ3~þ»Mþºûû6×:ûìÎÿsþÿþ?üöüØœÿ†þ6éOý?ü+Ô!YÍÿfå]ÿ‘ÆÿV°ÿ¤ýŸ¤çïV©ÿ—Ÿ×Gë×öÿëÅÿ¬Øÿèò¿¨ÿg7þýgÛþ#þü'ÿÏnüKÚ¿tÎþs½þ?Ôÿ§þ?õÿ‰ÿ[ˆÿ¯èÿ{gý‰þ™sþ•üòÿ5íß9ýëGõvüÿ?ý?íæ„ô=ž/Gÿóü1žñŒ¿ÿø¸.Iºþ˹~Ê»à_ýüÚð¡?ôוç÷ßïw^¿;þ÷ž韜ÿk÷¿öùáøß2ÿƒ¿MûÿÞõ§åð¡¿nýWmý«_tþ ßsòÓÿ]¿<Þÿ~%ù;ÿ»Ï?úù¯Qÿ[WþZßÿ¡ÿÑÿÐß.ýñÿãÿsç;ó‰¹óŸcðãñî|Vz¼~*ÿ ü‰3¾´þýbéso|ÆÿÊE=ÖgZ~ºß·¯ÿÒø6ù/?Iå¿ÞþwýeòoÛÚà·ÄÿZž÷üûyë/e3»ûøçõÿ;忬þC›ýéî¦9ÿ{ ~Oþ7þŸ˜þ¥õ?¶ÿ+Ñ_[þãß¾ÿóñù_{ý[¿ÿÄþÅþ/Ûç-ö—Ôþ×ßÿKñ—îÿçÍz~Éÿ#ÿþ'ÿ¯Ÿ>Ÿ.ÿðãÿÃÿ‡ÿÏ¢ÿožý'=¢ÿµËÿØÿœÿa<ãÏùò¿8ÿý-æëœ?Y'þeÓÿ—£i¯œú<ÿXÇþ'ÿŸóœÿãüñòÿ-çÿcÿÿ'þOüŸø¿mýW‹ŽÈ¯¶ø¯vüŸóŸVéOüûÿ?ô·êÿ×î?£ ÿヒaÆ×?k¼õù·¾þ¥þg?Žä÷£qt ¯Çß—åW~WûÿsxÌôÿÿýÔç¯6ÏòùóHù¯ýþé¿ký7ׯ?äú_›þ’ø³tþבÿZýÇà?äòñÚë_Çþ\gýKÿ¤ôÓù›·ÿ“êûý¯ËÿŸ#ÿî>ÿ6åú_×ÿ§-çé©ÿýþÇÿÿÿ?þü_À>ðß©ÿuâ?+Ø_ØÐÿŸMÿ¿uÿŸöþÞþëŠúð?üÿùüþ¶íÿ}Çß½>Ç×Cø¹ç/ß÷òx)üxüßOy|ÿcþŽë£óïî|þ#O)üxüˆýíóSx=´ÿ[è_›ÿíéó¿sþ¤ã¿´}î}o»ŸÞúÅk.ýôÞsôùý>Ÿ§ÑÿmòO -??¾¦ÿ­Ëÿ\ÿ¿p>ÇåWMÿçúŸµêÿüø6ùk}ÿ·*ý[ÖÿŒþwû>wý=åùs÷[ÃþÅþ³mÿáÿÇÿ|àŸóÿÖò­çÿÿCÿkÛŸ+Ž·žÿÅþÏÎþþcþ±¿­Ã'ÿ‡ü?ìòÿàòÿÈÿÃÿ‡ÿÿúŸóÿð?üÿ.ÿ}½ò±üü§£?ËëIï¶Í÷oþ»ßëú¶…ã_xúãëG×ÿåõû¹ðãñîúQŸÁŸð>ÊÏïFáü•áýŽ\ÿbןèè‡äú…}Žg¬ÿ°oò~mýŸŸ+~þ°ÿrêû^~yþsóÒ -úkÓßçÂá¸û§æS[þËó¿eùÏ)üÃë±~~>úÆŸùëù˜“ÿ:ƒÿôû¿Ÿ×hO§éïÃ+Óçl_•æ¿Ô¯ÿtÿ?ÇÏGÿc~(á—Ò¥ûï¿âú—žŸi¯­ÿ®xþ;Í¿uùÇþƒý¿eükûŸÒ~iÎþCwÿe}ÿ—·ÿÏý‡Ç䯿ÿ‰û?¯°ÿÁþ¥ÿ ùW:ÿ;¶þúÎÿ"ÿñÿáÿÃÿgÕÿ‡ýgÿ¡¿eú×ü³ýþÇ>ÿ¯¶ÿÿ‡ÌyÅumÿ›6þï¼.ÿHãÚöß9þ”ÊGËûÏëñŸò»¾ÿßGâo³ìÿã–ìô?ù_=ñêm›ÿ_qÿo)þýgÛþ#þm>ù¶ã_£ûŸvýß—ÿôzwÚº7þ™_²ÿŸ‰}#Ýÿ­¶ÿ_ÿõãÿ–òÿˆÿ[öÿ®èÿ“í¿ö]âëÑ?3â?äÿ“ÿ¿Rþ¯ý'Õ?ÚñWüÿ-ò/=_Wä?^oÿÿ?®õâ÷¯Ì+÷»ÚøÚ÷À>ðß_*®†_ÃÿjÿëÕð¡?ôצ¿fý¡»ã÷ù—úæà¯[ þ‡ÿmó¿]üÙ¤á[·¾ÿkõKçyUû¿?íù›1ÿšýgÖÕÿ²ç¿Ëü£ÿ‘ÿ+ÊÿwÉ_öèëúúCüÿ–å?õÿ8ÿÏùÎÿôŸÿžQÿoÍóÿäÿrþŸóÿœÿçü?çÿ9ÿÏùÎÿc[;ÿo¥þ7çÿ9ÿCýêÿSÿŸóÿœÿÇÿ‡ÿÿŸ¥þŸãöߌõ·æùKüýo»þ?ð|»ñú¿ÐÿúÛõÿ­×ÿû½õO­ûÿ¨ÿk»þïzü'ùwÿú¿¶åûòÿm÷Æþ'þOüŸø?ñ›òßzÿwëþ?ëô·ÿÇþÃÿý©ÿÏ;õ™[ïsüDzúsÚõ_Jø>Ÿÿ_»þõ¿­ÖÿAßSÿ‘úovë¿ÁÌ7ûÛòÅúßúõÏ­÷ÿiÛÿ]·ÿÔµÿ©ÿOýêÿSÿ߆þ_Ïÿ÷Îúÿý3ÇÿˆþGÿãÿÇÿÿÿÿ»õÿ¡?œNˆç<¾ÿŸñŒgü]LJòýO9ù–Ÿ×¿þùµáC迆üÐþ»;þ÷œ·>Ïï-×çñíþ×_ þ‡ÿá»ø[·ÿçßOèÿÌÁwþ­—?ñ¸8þùˆñ?®Ÿéÿúý\øgüCøÐß§ÿ¡/]ÿš¼¾ŠûÜHé¯mÿ·à_[¹y‰í÷}8Ÿšë_žÿ)‹¬°þ%øÏ¥øçØü÷Æ?ÑÿÈùî›6CþžåZ.³ÿCÿ£ÿ¡¿]úãÿ'þSµ¸ÎuâÿjÿÄ|ý5²Œå¯üí_¶gzñ?ï%òÿžñ¿>úÔ÷ÿ½ó/~~Íõ§-ßÇüÿ.Ÿ;¶ïsãËþ=øÈÿ‘ý_¸Ÿ‘ο®üÙÿ…ë¯eþÊû¿»ñß<ÿ7ñOâŸØÿwË)Ù_ýö¿®ý£ûüÚóOþùð?ùVåŸuÿ.þ?üøÿ,ûÿdöߌüÝø?üýý¯uþçîç_Àü? ÿ÷êmù/Õÿiøáwõýô‡þZô—Öóç0W?Ì¿_ý¿wžë1OþKáKëßéòGšÎÒúw>¤àµâ__ú;Ÿÿ*ñËú{½§øÿù8ó¿öú׿ÿÏ‘ãõŸ¹óŸš_þÓýolÊ?ìõø3ãoÿÇþÿœý_Uþ^|]{ý[×Úô³¾þî#ÿçÅÿµã¿Èè¿|ì?ì?üÿÐÿýþ/»ýéÿ¤Gú_ë÷ÿÑìÿµNÿç4þµþ‡óú?Í뿘ê—Uêÿ#ñHåŸvÿ¯²ý<¶þzìäú úÅŸçõÿÓ–ÿvûÿaÿ!ÿ¬Ê?ä¿nÿïuÖ¿Íþ×ôÿEÿkòÿçÈ?©þ×Ùÿ[—è]ÿ_9ÿyLþÎÌÿo×?Rÿúýÿÿ?þüÿø¿¬ø?Áü×À_'þ£mÿcÿAèo×ÿoÝÿ§½ÿ¯n߆ÿáøü±ÿÏã_ŸãëÿþïàòøÜüûã¿ÛÇçè¿ü³þûûI]íÿÔúýûé›ÿUíÿÜóÿý”Ÿÿù(ÏŸ»_™ÿ[áׯÿý”Ççäÿ{?k¯ÿöçM¿¯ÿ¿Ÿðçý¾¦ÓöÜüùïƒ_Ÿ³?‘ÿ}ò?–_sôo»ümßóüøÿV£Ëúß¶vÿenþ×XÚö/öŸmûÿ?çð€?øsþßNþ¯õü?âèÿ}ŸkŽù¿´í_ò¿ØÿYÞÿ­ÇÿÈ?äö?ù?äÿ`ÿcÿÃÿð?ùäÿáÿÃÿ‡þGÿÃÿð?üÿKùÿëëåòñ?žïÅ)ÇwÛæÏÏ¿û×kãëG}àß þóÂß¶pü§þó1~<Þ]?êsøòß:þÛvî¼ma?¿_±ÿû믿¶þ[žßÞ>mðÃùß¶sÿç°L>ô¿ýçÂ×–ÿ×åÏ·O=ÿ;¯Kò_gÈÿUú¿ûë7eOÇôóáÍœÿRÿ­óúÙ¶öñÏǹÿVšÿ{ð«—Þ_oý·æÈò´õŸÿóó?}óÿ|ÌÿxüóQo[þ±ÿaÿk~¿ýîs¤ë߿ߜýWüü>ÿÇ}:ÙÿõËÿ²ýÕ{þrÝýMû¿‡þ:óÿYëï~òÿþ?üŸâÿÃþƒÿ¡¿]úkûW¼nÝÿPžŸ¹þÏû­ÿëñ—Á¯Ý¿ìÿíÿHãÚöW?þáüõ×óÑÿYÍÿß›eÿ¯ÿ³dÿ£ÿÉÿÒŒ_¯¸ÿ·ÿÇþ³mÿÿ¶?ù¶ã_£û½Ï̪Ûÿåøçy|èÿó½scúyîþoµýÿ -ü¿vþ³õü?âÿŸäÿ]Ñÿ÷ÎýW¿ÿinü‡üòÿW²{í?iþ¿vüÿÿ˜ü›ÿ¿ýOüÿ Ïëåê1´}î}õÞO -_ú{ðøÇò%–Ïéë±üÇÿOÇÿcø5|jãÓ×Ýó×ðƒß{èýuèötãsõ‡Îõƒ\-©ó}sãבRü¥ë?=ÒùOÕúýNíëc}æü±ÿ@ŽÿaŸÿ~§à×ñ/ß¶óuÿùáøß6ÿ󮧼ýÔ üû ëæà‡¿{Õ,}Œ¿Ïßoü3þéç‚þÒü)ýµíÿþµõ'õj¯íúç+¬ þÒõ¯_ÿýüדÿµøÇ˜üm°ÿCÿ[×ÿÐß.ýñÿÿ©ÒŸë\Ïð¿tý·ño/üyüÿéøŸã?ÛVÊ¿:çOŽÄÂç+Õ›i™¿Úør=›^üÏñ£ú«¿¿Ê×ƿ¤ô—Ê—±ù—Œ??¿æúÓ–ïÖÏ? ÿuëÿéËêhž^aý[>ÿýý/±ßgØÿºöîókÏÿ˜ýîn$ëßí_¶mdÿÕ6>>óÓ¾?ká?Éþþ¿#ÿÏ“ÿëíÿmÉ?ëþ]üøÿðÿYöÿÉì¿ôúsýÕÛø¿Ì/ýö×ùüîÿcÿcÿÛ¿Rþ¿§ý þàÿ©ø¿WÿkË©þOÿ«ïŸ ?ô×¢¿;ÿ×»zÑЯ‘Ö_z[ñçЯ/õû}|ïß_»þ]Œ_ü|©ën}Ï”ÿRøùññu|‰þ!¤éœšGÿzýMŸRðZñ//ýÉê?¦ë¹yi©?¸JýGþÿù7¶þãy›1ÿ©ùõç?æËòû_=þÌøÛÆÿ±ÿ?gÿW•¿_×^ÿÖõŸ6ý¬¯¿ûÈÿyñíø/òú¯ûûÿ?ô¿ÿK£þ×Ýë_IëŸê×ÿÔ¦¿uüµ×¿ÔÿíÇ‘þ~Îßûû­¿Ÿ^ÿÿÕõŸëø§â•?sýÿþýzá§æ?ÿû¦Ë ÿ¿TþÕü©Ï¿ßïòÿ­¿ûù‡þ_ƒþcñg)ýבÿ)üëëožü×ÖÿØÈ?{òùÚç3ìÏûõŸ·7Köç<úKáý~ÞþOªÿuìô¿.ÿŽü“êý¿uù‡þ×õÿ•óŸÇäïÌüÿvý#õÿ ÿÑÿøÿñÿãÿÇÿOÿ#ú¿ƒ?øÓÿþ/ÐúÓÿ›þß×ødç_åøëîÿàøß6ÿÓÿײýø ûúOžûyÖÆçúj÷þ™þ¯ôÿíÏsô õGmü9þ³Âú—äÿÍè~¿ü¿™ó/ƒ¯ýü6åÈÏý;&Ýý®îÿ÷ùû?]úÍûxiÿ˫ן¶ý‹ýgÛþÃÿOü‡þàþôÿ¤ÿýèÿc­ÿý¯mËÿ}oé_ï׫÷ëÜÏèÿ®+ÿëø×Ö_n^byä¾çSsýkó?òù‡ýo·ÿßÝñÿ¼þߨÿôÿ„ÿíò¿-üÑÿøÿðÿ¡ÿÑÿð?üÿ[ãòáùÌùÎÿæOJדvþ'ù_Ð_þ=Ï¿Ì;ÿ£ŸÿlýüïHýÿ™ç?Fêoµ¯×ß"ÿ_³þý -ç_8ÿÇùö?ìo-~æüõ,Ÿ¿Æþçü?òÿþ?èoÑÿ‡ýÿC»ô§þŸíÏcó?ÏÿyÏõ?ÿ•êÿĤñ¿ê?Iú?Í8ÿ§ëÿ—ÅÏäûÝøŸuûýo;þCý?Ûñì?Ûöñoä?ùvã_cû¿yõ_WèÿJýêÿ“ÿGüßjýMÿŸöþKÚÿY~þ•üòÿ×Èÿ±ÿ¤ùÿ+ÔÿÇÿOÿOËý_~ö×oX¿ÃÍß™ÿ] òx·þãýðüuà¿Þ]”ðÿñïß¿ÿôxW9¬³|èý5è¾v¥ƒïlÅãw!üòxÿ{Wì“ð¿ûü‡ïÛ–þËýn6þ1Ü^üsÏÇþ‡ÿá»øcÿûã_*¾ÂÿÔñÖ÷g¾Ü¶¶ÏÒù_Ãþ¯ã_~~½ù~ïõµô¿ôùï7ÿèäÿ:ò_OþâÿCÿ[ÔÿÐúãÿ·(ÿ%ù?-ðýþ§çü«3þRø©üð'þ üÒúwúÊõOñóÃjñŸüþË¿¿ËÎí¿Jý_ÚäoªÿK]þJãORù¯·ÿC©ü뇟Ã?_‹ÿíûÜõÓ?ìÿízŒoÛÚúïï'u½ßþŒÇûçJøÂÇãÿï¡ÿ¶¥åÁøþ¥þï—ÿcø·ïÿÒøçço…õo=þFüûÛºýÛï£ögŸý¯eÿHñŸoÿŽÎ<žü?òÿàòÿz÷ÿVäþoüøÿðÿYõÿͱÿfå_iÙ_vùûŸü/àøÀ'ÿ‹ü_èÏù_íó?Ú矬ŸÿíŸ;ÿÚö?çÿ8ÿÇù?ÎÿÙËÿ"ÿßvþ?ö?ñâÿÄÿ‰ÿÛÔ­ñÏvù߇¿VüŸóŸVéOüûÿ/ô·Jÿ¸ÿÄáz}ޝ‡ý'>uüïwªN[ÿÔø\ÿUá[ŸKë_ê?–¾çå_þïðÿ<ÿ_û]â˜Á%øñ_üü×úÿß³þèMøsä—TÿhËÿþãÏÿÎùƒÿÈ?àËàk¿k¯ÿð½Õþ¼jþûá—Ç—¾Ÿ³ÿ›»ÿÔ¶ÿíéÿµøÿ~òïîóoWþ±ÿ[Ïÿ÷Nù;GÿHý?èô?þüÿøÿñÿãÿ>ð¯ÿiÍ?º¾^üÇ’ü‡þèü/øÿ±ÿáøßªÿÿ¿UûßÃñûú÷]æŒÇï{y¼þ¾÷ù?søów\wÿãó?yúKáÇãÉÿ#ÿ¯¾þŸÖϽïm÷Ó[ÿÖãÿ9úÄgäGõ›ü“Âϯéëò_ÚÿOªÿóýËÚôÿuýÿlìÿV¥Ëú¿¶ÿåØúëí¨mÿbÿ‘ÿÿŸø?ð|òÇâ?ÒøÓZùÖó‰ÿqþŸó¯œÿgÿÇùÎÿ3ÿØß¶Îÿ“ÿCþö?ùð?ùäÿáÿÃÿ‡ÿýÿÉç¿àøþ·Çÿ__¯|,?ÿéèÏòzÒã»móý›ÿî÷º¾máøžþøãúëû°ÿË¿çÂÇo[?œð>ÊÏïFáü•áoÛ¹ÿÑÑŸèõ -ûù}Nf¬ÿ¸or ¿¶þÏÏ?Ø%õ} -/¿<ÿ¹yi…ýµé¿ïsáÇpÂþ_ñ|jËyþ·,ÿ9…x=ÖÏÏGßø3=sò_gðߺýÿBz•úÕ—és¶¯Jóÿîþ)þù¡„_J”îw¾ÿŠë_z~¦}¼¶þ»âùï4ÿÖåûöÿ–ñ¯íJû¥9ûÝý—õýŸvÿsýýöÿ(ýgÈ?íþ×ÈüøÿðÿYõÿaÿYçèo™þ5ÿl¿ÿ±Ïÿ«íÿÄÿ!ó_^q]Ûÿ¦ÿ;¯Kã?ÒøŸ¶ýwŽ?¥ûåüçõøOù]ßÿ¿ï#ñ·YöÿŠñ?Kö?úŸü¯žxõ¶Íÿ¯¸ÿ·ÿÇþ³mÿÿ¶ Ÿü?Ûñ¯ÑýO»þïËz½;mÝÿL/Ùÿχľ‘îÿVÛÿ¯ÀÿúñKùÄÿ-ûWôÿÉö_û.ñ¿õèŸñòÿÉÿ_)ÿ¿×þ“êíø+þÿù—ž¯+ò¯·ÿ‰ÿ×~!?aÿ£?Ñëå>‡¿{Õ(}Œ¿Ïßoüxü×Wú¹Àümã/ÝÿHñ¯íjø_}þg ~ûþúCmúkö?¼;þ3Öÿºýëþ·9øëöÿƒÿáøß&þìNø7|î}⦅¾ô÷ìÿZýÏRú¯jÿ?mëIÿÐ^ÿeù?Ú¸½ÿóÚú¿ŽÿŒõ¯ßÿýü_KþËäï¼óVýè;úúCüÿÈÿvú»õã—_Îþ½àSÿÑFþo.ÿÒÿý¶µÇÒõÿúÏ_‡ë¿¥~Uéüõèù÷Yç¿õÏÿŒÓ†ü…ïðoäÿÅõÌt×ߊò¿ïüþç]·^ÿ±/]6ÿÚü'ÅO{þÞýúúÔ?¡þö¿vÿŸßïû«×þ×¶$økß1ÿÔÿ¢ÿüo¹þ‡mùgÝÿ‹ÿÿþ?»þ?‰ý7£ÿ~ý_øûŸú¿øÀü‰ÿÐÿÉZÿ'èÿú¿øÿ¨ÿg³þŸõú¿2üg¯ùüÇã©ÿKýß™ûòï? >ö?ö?ñìâÿÈÿ6ù?7þ»bþ7þ?èo%þýÿC›ô§þõW¤?õ/ß_ÿoÜÿ<^ÿo…ú/%ü[êïÉýÿkÔÿ£þ·½ú?èê?RÿÍný7ì?äûÛòÅúßkÔ?·Þÿ§¾ÿ›Sÿ|=ûŸúÿÔÿ§þ?õÿ-éÿ•üï¬ÿ_òÕÖßœüô?úÿ?þüÿøÿß­ÿ¿ýù=àåæÿ¬?ýã¾ó¿O÷éŸ/…ŸÒáððI*_¾ò)'ÿÏòSŠÿ!Ÿ¿Sðëø—ÇoÛùzøüeüÇà¿>ççÏ·ÿ¡?ô_Cþù{ÉòçÞ¿¶ûÝ©üŸ7ÿ=¿÷ÏÔlÛy|êº[ß3ù? ¿†Om|êºÿüð?üo™ÿÁß¶ý?ÿñýw¿ßíãÿsìÿÑ„?BÿO/óÿ¥ãîûúükÛÿ²øÏŒú·«ÄbZžÆ¿ÿýnÿþ÷{¥õߎ¿ïw—®ÿø~ãðóãýë3ôÿ5ô›ý<ï~~;òß_ÍÓÿíò××ÿÒúÖ÷Úô™ÿöñõù×^ëØßØí?üÿÄ$ô—âßB¿^øóèþào_—•?§þêñ•r|æ\/%Uÿ9i|Póùôÿ>üSø+¾øß…Ï÷Ÿj‰_µÀ—Ç¿¤ô—­ÿm“Îßóž?oýÑ_‡ÿ¥öÿ ûW³þ¥uù¯ÝÿM[þËú¿¥û¸yié?x¿ú¯3ùù‡üÃþ_ÇþŸaŽØÿ÷Ç_Jììøþ×廸£ÿñÿáÿCÿÛÖÿð?üÿÛáëùŒçü?çÿÇó'¥ëO;ÿ“ü/è¯ ÿŽç_fžÿYçüŸÍó¯>½ÂþìéýAžþÒüÿöóÿµýQÏuòÿgKßrþoó/œÿãü?ûö¿¶Æsþ‡ú?œ¿Fÿqþùÿÿô·åÿÃþƒÿ¡?õ_¨ÿg½þÓ¼ú#=þÏ;®ÿ™ø¯TÿOÿ‹ÿ­Sÿ)Íÿ>¯þŽÿ_?›gêÄÿˆÿ£ÿ©ÿLý?âÿØí?âßÈòÿìÆ¿FöÇïæÖÕéÿCýêÿ“ÿGüÿ¯ŽÿoúÿRý#ÿÿOþ¿nþ¿ÌþËÿ_§þ?þúZ‹ÿ¿žèEÿãùÒ×ÿ¼þç¾M_¯Ý?/…_»ïó?ø.þ¯Z$aý“òçð%Åÿü -áÕð¯¯¿ÊøöÃï½?ô‡þ:ô×®xwü¥ë½ú×µúWçZWsðשÿÿÃÿð¿]ü­Ûÿ‡/æï'ô_æà;ÿÖËŸxÜ?ÿ|Äø×Ïôý~.ü3þ!|èïÓÛÎýorú*îs#¥¿¶ýß‚mýåæ%¶GÜ÷á|j®íþ7+¬ þ3äßûÿ ÿ‘ÿÒõöM›!Ïò?-—Ùÿ¡ÿÑÿÐß.ýñÿÿ©Ú?\ç:ñÿµÿGâ?qÿ’ñó—cò·o|Ùž‘õ‘Êÿ{ÆÿúèSßÿ÷οdüùù5ן¶|óÿ»|âØ¾Ï/ûÿõà#ÿGöá~F:ÿºòdÿ®¿–ù+ïÿîÆóüßÄ?‰bÿß-ÿ¥½~j[þ¦ý£ûüÚóOþùð?ùVåŸuÿ.þ?üøÿ,ûÿdöߌüÝø?üýý¯uþçîç_Àü? ÿ÷êmù/Õÿiøáwõýô‡þZô—ÖÿÚ¶ó÷ÏGº¾Ôó‘®gµÆù—±úWó俾´þí™þ!¤é,­æó@ -^+þ¥ñ¥¿óù¯ÿ·¬¿×{ŠÿŸ3ÿk¯mþÿù7^ÿïù˜;ÿ©ùõç?]ÿΦüÃþW?3þ¶ñìÿÏÙÿIû§]ÑíëߺþÓ¦Ÿõõwù?/þ¯ÿEþCÿµàcÿaÿáÿ‡þï÷ÑÿÒvÿGú¿Z\ÿôÿ¡ÿý¬öÿAþ¡ÿeõ_çõÿÕ–ÿÖûÿbÿ!ÿìÉ?äÿ¬þ×cöÿ:ë_ÚWJÿûôÿMïÿ¤ú_ÇþGÿëòÿçÈ?©þ×Ùÿ[—è]ÿ_9ÿyLþÎÌÿo×?Rÿúýÿÿ?þüÿø?ÀüÁÿzü¥çŸæÉýo]þCôÿÿOû~t%ÿŸuÿö?üÿãÿò¿[ýûú[Ççâ_šðGèÿIãÉÿÃÿßÿÎùókãsñÿ5Ö?ñÙg)ýf?Ï»ŸßŽüwëy¦þo—¿¾þß¶öçÏÕŸãü‡ýGæ¿}|}þµ×ß:ö7öŸEûÿ?þ?â¿àþÖãÿÒøÏ˜yùo3ÿ—øû?οÿaÿÇùÎÿ#ÿ°ÿ­âOþùØÿäÿÁÿäÿ‘ÿ‡ÿÿþ?ô¿ó_ð?üÿÛâÿ×½èáã<×¹~¾îäçëîÛôõÚýãñRøµû÷>ßgãÿêEö?éù,]_ÒûKŸ¿~<µWíþÐÿ^ôŸ _S¾Ëó¿åùÏ__¯|f|îùýûÿƒ\¯?®Ÿñ—å¿JåÿJýŸ\ÿú|ÿ«ø÷óçÿÝý÷¾>þ9þL­¿ÚxÿzÌÿúë_šÿ!ËÐÖRüû‡óÌsëü?sç¬þ©Eù‡ýÏþÖúõ~û5|I×Wm¿Ô¿ÿ*?oÿþìs÷Úý‡õ÷?Öí]úY_÷”ÿøÿðÿáÿûÿöüý-ÛÿúþGMøÖí¿±ùŸçÿ¼çúŸëÿý÷ï\øgüCøóâ?ÒøŸ¶ý5†8ÿ.Žäüø±ü/ÅÖòÿ÷ÅÏæïÿßÿ#þþ·ÿi‰Çò*–gÒù×–ÿÖãÿØví?âßÈòÿìÆ¿$û§ÿ%òïØŸl[»ýŸŠ–Æ×£ÿèÿ¹û¿Õöÿïäÿ{æ?[Ïÿ#þÿIþ_MÿŸþþkÄÿ4/þCþ?ùÿ«åÿ÷Ø3òÿ5ã¿øÿGøg^ü_Çþ'þŒ?êHÆï_™Wîwµñµï|à¿~Úÿð|ääKì¸~ ÿ¶ýwÙÿ¡ úCmúŸëOÇõ«ÝÿÇê_çëOßÿ»Ïzÿïßœÿ ÞÌÁ?¿ŽËþ³´ÿÿáëüoöiøÖß­ïÿœ±|]:Ï«Úÿ­øiÏߌùOË_'gãëÏǼñëêÙóßeþÑÿÈÿåÿ»ä/û?ô¿uýý¡?þËòßöùgðçÿ«ùø×Ã×Ìÿ‹óææœ¿8çÿ¥óòÒùw>^µøW[þ_üžøÛŒø—îùŸÔü·ç_¦ðOçÿ¹çåüO]ÿ…öë¾Ëö×µû?sáïû¬ý¿ùZÿÕÏgy%¡¿¶ü¯á[[¹yiÏ׿öumþ»ûü!ÿ€Ýùßyý?îyþù“Îÿ¶îÒû•9ëo|ÿ•¶ÿSãKöÿ~î|Ó˜ý_¶?àmþß_±þµ÷ÿÖäõ?ñÿáÿÃÿg·þϸý7cýiÛ_ð?ö¿mû_}ýøÀ¿¡üüëäÿjð¡?ô× ÿùýïç×ãøTîzˆÿ¼ñáûq®ÄÍ¿«•åßÿªùï‡_ï¿mþ¹™,}:ßçο_qÿx|íûó> ‡_mýµŽÏ}^cýkóÿýäßÝçߺü³kÿëÆÿôãßÖñÇþ·mÿï{(?ÝúñëÃŽË_ÿþ¿ßáý×YÿvõßúKåß¼õoÃý§ÿ׎ÿ"ÿ­Ó¼þ{ýÃøÜûûÿ?ô×£ÿŠõ§îQÿJ»þæuð­Ï¿¥õ/õKßuë?Ëñ“úÿµß%þ‡yõÇÓðã¿øù¯õÿ¿gý!ÿÐ?«Õÿï—_Rý£-ÿSø?ÿ;çþCþ!ÿ€/ƒ¯ý®½þÃ÷Vûóªùï‡__ú~ÎþoîþSÛþ·§ÿ×âÿûÉ¿»Ï¿]ùÇþo=ÿß;åïý#õÿ ÿÑÿøÿñÿãÿÇÿOÿ#àøô§ÿ ô‡þôÿ¦ÿ÷{ãÿmù§sð×µ¿áøß6ÿÓÿ×öþcßÃñµÏ½ï½÷“—þþø;^îóØü»û×î7~<žþ¿ô-õŸwý‚ŽõÆö]ˆÇ×ùÿë_?™3ÿÚñŸýýy\Õÿyù—~þvøiý¯éëò¼ÿŸTÿ×ú—ÕôùÕýÿ¬öÖ¦ÿ¶µ­ÿ«û_Ž­¿öþ‡Úö/ööþâ?ô_>ð­öÿ¤ÿýèÿcµÿý¯mËÿzÿúò»tþµùOŠŸöüÁÈ?äðïÚÿïÎøbÿEìúÂÿvùßþèüøÿÐÿèøþ‡ÿ-ñ¿õüGðçü çÿ÷½œ?y|7šÿUÎÿÖÏÿ$ÿ×6ý÷}.ü˜þûÂw÷_ãüËzçÞ™ÿÌùß\ÿËð|Pª~ÙŒüÿRÿ»úùyÿ;ëùÿšçÏÖ=ÿoéüçÿ9ÿÏþŸóÿœÿ±Yÿgüüw›üu÷÷m®uö?Øÿœÿçü?þ?üøÿìùÿ°ÿ8ÿ ýmÒŸúø?V¨C²šÿÍÊ»4þ#ÿ­`ÿIû?IÏß­Rÿ/?;®Öÿ®íÿ׋ÿY±ÿÑÿäQÿÏnüû϶ýGüùOþŸÝø—´éœýçzý¨ÿOýêÿÿ·ÿ_Ñÿ÷Îúÿý3çü+ùÿäÿkÚ¿sú×êíø/þúÚÍÿé{<_Žþçùc<ãÿñq]’tý—sý”wÁ¿úùµáCè¯+?Îï¿ßï¼~wüï=ÿÒ?9ÿ×îíóÃÿð¿eþ›öÿ½ëOËáCÝú¯ÚúW¿þè*ü¾çä§ÿ»~y¼ÿýJòwþwŸô?ò_£þ·®üµ¾ÿCÿ£ÿ¡¿]úãÿÇÿçÎwçsç?ÇàÇãÝù¬ôx)üTþøÿf|iý‡{ÅÒçÞøŒ?þ•‹z¬Ï´üt¿o_ÿ¥ñmò_’ʽýïúËäß¶µÁo‰ÿµ<ïù÷óÖ_Êfv÷?ðÏëÿwÊYý‡6ûÓÝÿLÿrþ÷üžüoü?1ýKëlÿW¢¿¶üÇ¿}ÿçãó¿öú·#þ‰ý‹ý_¶Ï[ì/©ý¯¿ÿ—â/ÝÿÏ›ÿôü’ÿGþüOþ_?}>]þáÿÆÿ‡ÿÿŸEÿß<ûOzþD;þk—ÿ±ÿ9ÿÃxÆ3žóÿäqþú[ÌÿÖ9²Nü˦ÿ/GÿÒ^9õ;yþ±ŽýOþ?çÿ8ÿÇù?âÿäÿ[ÎÿÇþ'þOüŸø?ñÛú¯ÿ‘_mñ_íø?ç?­ÒŸø?öþèoÕÿ¯ÝFþ1Þ}ÃŒ¯Öxëóo}ýKýÏ~ÉïGãè^¿/˯:ý®öÿçð˜éÿÿû©Ï_mžåó?æ?ò_ûýÓ×úo®_È?ô¿6ý%ñgéü¯#ÿµúÁÈ?äãµ×¿Žý¹Îú—þIé§ó7oÿ'Õÿ:ö?ú_—ÿ?GþÝ}þmÊ?ô¿®ÿO[þÎÓ?Rÿúýÿÿ?þüÿø¿€|à¿SÿëÄV°¿°ÿ ?þ?›þëþ?íýÿ¼ý×õ'àøÿóùümÛÿûŽ?¾{}ޝ‡ðsÏ_¿ïåñRøñø¿ŸòøþÇü×GçßÝÿøüFžþRøñøûÛç§ðzhÿ·Ð¿6ÿ+ÚÿÒççüIÇ;~iûÜûÞv?½õ?Š×\úé½çèóû}>O?¢ÿÛäŸ~~|Mÿ[—ÿ¹þá|ŽË¯šþÏõ?kÕÿùñmò×úþoUú·¬ÿýïö}îú{>Êóçî·†ý‹ýgÛþÃÿÿøÀ>çÿ­åÿZÏÿ#þ‡þ×¶?Wo=ÿ‹ýŸýüÇüc[‡OþùØÿäÿÁÿäÿ‘ÿ‡ÿÿþ?ô?çÿáøþÿ\þÿúzåcùùOG–דßm›ïßüw¿×õm Ç¿ðôÇ×þ$®ÿËë÷sáÇãÝõ£>ƒ?ÿàÿ|”ŸßÃø+Ã?ú¹þÅ®?ÑÑÉõ+ -ûÏXÿaßä3üÚú??WüüaÿåÔ÷)¼üòüçæ¥>ôצÿ¾Ï…Ãq÷Oͧ¶ü—çËòŸSø‡×cýü|ô?ó×ó1'ÿuÿé÷?¯ÿОNÓ߇W¦ÏÙ¾*Í©ÿ^ þéþŽÿž:ÿÇüPÂ/¥?J÷;ßÅõ/=?Ó>^[ÿ]ñüwšëòýûËø×ö?¥ýÒœý‡îþËúþ/oÿŸûÉ_ÿ÷^aÿƒý?Jÿò¯tþwlýõÿEþãÿÃÿ‡ÿϪÿûÏ:ÿCËô¯ùgûý}þ_mÿ'þ™ÿòŠëÚþ7müßy]ÿ‘Æÿ´í¿sü)•–÷Ÿ×ã?åw}ÿÿ¾ÄßfÙÿ+Æÿ,Ùÿèò¿zâÕÛ67þ¿âþßRüû϶ýGüÛ6|òÿlÇ¿F÷?íú¿/ÿéõî´uoü3=¾dÿ?ûFºÿ[mÿ¿ÿëÇÿ-åÿÿ·ìÿ]Ñÿ'Ûí»ÄÿÖ£fÄÈÿ'ÿ¥üÿ^ûOª´ã¯øÿ[ä_z¾®È¼Þþ'þ\?ú…üý„ýCŽþD¯—ûþîUO ôý1>ü>¿9ðãñ__éçð·¿tÿ#Å¿¶ÿ©áõùŸ1øíû?èýµé¯ÙÿðîøÏXÿëö¬ûßæà¯Ûÿþ‡ÿá›ø³ÿ9áßð¹÷½÷~RøÒß³ÿkõ?K鿪ýÿ|´­'iüC{ý—åÿhÿáöþÏkëÿ:þ3Ö¿~ÿgô?ò-ù/“¿óÎÿYõÿ¡ÿíèèýñÿ#ÿÛéïÖoŒ_n|9ÿø÷‚OýGù¿¹üKÿ÷ÛÖ?J×ÿë?®ÿ–úU¥ó×£çßgÿÖ?ÿ3Nÿòg¾Ã¿uü‘ÿ×3Ó]+Êÿ¾óûŸwÝzýǾüuÙükóŸ?íù{ÿõëëPÿ„úgØÿÚý~¿Gì¯^û_Ûþ‘௠ÆüSÿ‹þ_ð¿åú¶åŸuÿ/þ?üøÿìúÿ$öߌþ?úõáìêÿâÿð'þCÿ'kýŸ ?þ?êÿâÿ£þŸÍúÖëÿÊðŸ½þåó§þ/õgîÈ¿ÿ$øØÿØÿÄÿ±ÿ‰ÿ#ÿÛäÿÜøïŠùßøÿ ¿•ø?öüýmÒŸúÔ\‘þÔ¿|ý¿qÿóxý¿ê¿”ðo©¿'÷ÿ¯Qÿúßöêÿ ÿ©ÿHý7»õß°ÿìlËÿë¯QÿÜzÿŸúþoNýóõìêÿSÿŸúÿÔÿ·¤ÿWòÿ½³þÉÿU[sòÐÿèüÿøÿñÿãÿ·þÿýöç÷€—›ÿ³þ8ôûÎÿ>=Þ§j¼~Jÿ…cÀüÁÿ%©|ù~ȧœü?ËO)þ‡|þýNÁ¯ã_¿mçëáó—ñƒÿúœŸ?ßþ‡þÐ ùçï%ËŸ{ÿÚîwwü¥òÞü÷üÞ?S³mçñ©ën}Ïäÿ4ü>µñ©ëþóÃÿð¿eþÛöÿHüÇ÷ßý~·?üϱÿGþý?i¼Ìÿ—Ž?¸ïëó¯mÿËâ?3êß®ÿ‰ýýiyÿþ÷»}|üûßï•Ö;þ¾ß]ºþãûÃÏ÷¯ÏÐÿ×Ðoöó¼ûùíÈ?~5Oÿ·Ë__ÿKë?XßÿiÓdþÛÇ×ç_{ý­ccÿY´ÿðÿÿ‘Ð_Š ýzáÏ£?øƒ¿ü}]Vþœú«ÇWÊñ™s½”Týç<þ¥ñAÍçÓÿûðOáw®øâ>ܪ%~Õ_ÿ’Ò_¶þ·M:ÿ}Ï{þý¼õ7Fþ—Úÿ3ì_Íú—Öå¿vÿ7mù/ëÿ–î?àæ¥¥ÿàýê¿Îääòûû†ý9bÿß)ý±ÿ±ÿáø_—ÿíâþÇÿ‡ÿýo[ÿÃÿð?üo‡ÿ­ç?2žóÿœÿÏŸ”®?íüOò¿ ¿&ü;ž™yþgó6Ï¿úô -û³§÷yúKóÿÛÏÿ×öG=×ÉÿŸuþ-ý}Ëù¿5οpþóÿìØÿÚÏùêÿpþýÇùä?þüÐß–ÿûþ‡þÔ¡þŸõúOóêôø?ï¸þgâ¿Rý?Yüg,þ·Ný§4þ5ÿû¼ú?:þiülžý©ÿ#þþ§þ3õÿˆÿcÿY´ÿˆ#ÿÉÿ³ÿÙÿ¿›[ÿU§ÿõÿ©ÿOþñü¿:þ¿uêÿKõ4þCþ?ùÿºùÿ2ûo,ÿúÿøÿéÿi-þÿz¢ã©ÝóüÁu®sý³¯K_WÿúùµáCè¯Eÿ6û¥–?9>þîøß}þÛêWåë§Íÿÿºç‡ÿáøß&þÖíÿÃ_õ÷ú¯rãëåO<®×Æ×Wƒýã¾5û^Ò©ßIç_Sÿ¶à_[¹yIÁI}¯Íçþ3ÏGN~Žõ¿É÷ŸYaýKð¿ûü£ÿ‘ÿšò_[þ²ÿCÿ[×ÿÐß.ýñÿÿyåb„ùG~BúúìûÇã¥ðk÷ì_®§ÏOÖúŸ¤úçŒç?¥%¢ëÒ²þkãËú_’Û+øÿÇé/•ÚýŸÒëEºþzï¯'ÿ\ÌÐ~Ìó?ÝýÏôOÙ¿Røgüñÿ—öÿaþzi½Žíÿòô×—ÿuük믾ÿóó¿Ïó©¹þ­Ç߈bcÿëõ?Ö·døÏ³5û¿’ÿg;ÿÏ:ÿ[Ïÿ³+ÿ¬ûñÿáÿÃÿgÙÿ'³ŸfèOÝø?üýÏùŸ»ž?a<ã¯'ÿßÿêç׆ý¡¿ýÿS÷*zÏÕWŠë¹ó%åñþ÷qýÕ5οäëCµ]—ÒO -ìzŽþ!oä韧ÑÿmòO -??¾¦ÿ­Ëÿ°ÿ™¯?S×ûåWMÿÇò³WÿçÇ·É_ëû¿Uéß²þSóŸ:ÿ^šÿ}Ÿ»þžòü¹û­aÿbÿÙ¶ÿðÿãÿ>ðÏùkù¿Öóÿˆÿ¡ÿµíÏÇ[Ïÿbÿggÿÿ1ÿØßÖá“ÿCþö?ùð?ùäÿáÿÃÿ‡ÿýÏùøþ‡ÿ?—ÿ¿¾^ùX~þÓÑŸåõ¤ÇwÛæû7ÿÝïu}ÛÂñ/<ýñÇõ£?‰ëÿòúý\øñxwý¨ÏàÏ?ø?åçw£ÆðþÊð~G®±ëOtôCrýŠÂ>Ç3ÖØ7ù ¿¶þÏÏ?Ø9õ} -/¿<ÿ¹yi…ýµé¿ïsáÇpÜýSó©-ÿåùß²üçþáõX??}ãÏüõ|ÌÉÁúýßÏë?´§Óô÷á•és¶¯Jó_ê¿×‚ºÿŸã¿ç£Îÿ1?”ðKéÒýÎ÷_qýKÏÏ´×ÖW<ÿæßºücÿÁþß2þµýOi¿4gÿ¡»ÿ²¾ÿËÛÿçþÃcò×ßÿÄýŸWØÿ`ÿÒ†ü+ÿ[}ç‘ÿøÿðÿáÿ³êÿÃþ³ÎÿÐß2ýkþÙ~ÿcŸÿWÛÿ‰ÿC濼⺶ÿMÿw^—Ƥñ?mûïJå£åýçõøOù]ßÿ¿ï#ñ·YöÿŠñ?Kö?úŸü¯žxõ¶Íÿ¯¸ÿ·ÿÇþ³mÿÿ¶ Ÿü?Ûñ¯ÑýO»þïËz½;mÝÿL/Ùÿχľ‘îÿVÛÿ¯ÀÿúñKùÄÿ-ûWôÿÉö_û.ñ¿õèŸñòÿÉÿ_)ÿ¿×þ“êíø+þÿù—ž¯+ò¯·ÿ‰ÿ×yñâe÷Ë—X>Ô®_ ÿêç׆ý¡¿æË¯­”ú>þÿ¹~lüÝñ¿ûüûõ½üõ™ó?Äþ9þeøW??üÿÛæÛø[õã÷Öß×¾¯¯ßúKê’ο¶þ­á_[Rÿ›öú×®?ºÂú—à÷ùGÿ#ÿ5å¿¶üeÿ‡þ·®ÿ¡¿]úãÿ'þãçÆù‰éë½ó[»<^ -¿vÿÞçûtü¹nõºëÖ{Êå_žó§Zâ/þø°þ_ºÊLþüg -¿ÚøÒË=úû–ø‘ä%_Í?N©üKÏ ~ÿÒøóš-¯éú뽿žü·~þù¯[ÿO_þSÿC3ÿx…õoùü7ö1öl_•Î_ŽÙŸeû_×þ‘á?Ïþýýž7ÿ©ó¯µýCmÿ“·Ÿåëo|ÿ5ãùk¯~Òü¯Íÿ×å^ þþß–ü³îÿÅÿ‡ÿÿŸeÿŸÌ~š¡?5í/øûû_}ý1žñŒ¿¡üü«Ÿ_>ô‡þô?×¹z½ç*Üx·WôëK¹úJåñþ÷îùôëßÅøÅÏ×~]J?)ü±ë9ú‡¼‘§ó¬ù¯ýÕðýÓ¯?¦_ÿQ“ÿ?GþÝ}þmÊ?ìÍøßñoëøcÿÛÞÿ¹x‰³ _ë'}½W¾Öî¿Âú·¬ÿæÐ_*ÿæ­¿ôúªáþ{ü_;þ‹ü‡þ}øÐ?ž??ÿûûÿ?ô×ôiÖŸºwý«û·>ÿÖ׿ÔÿìÇ‘þ~ÎßÇ×ãïuë?×ñÏá1Óÿÿ÷SŸ¿Ú<ËçÌ0¯þxíþé¿ký7ׯ?äú_›þ’ø³tþבÿ)üëëožü‡ÿÈ?Æk­ûsõ/ý“ÒOçoÞþOªÿuìô¿.ÿŽü»ûüÛ”è]ÿŸ¶ü§¤þô?úÿ?þüÿøÿéÄ‹/ú¿ÓÿúCúÓÿûÿÌ~•ã¯kÃÿð¿mþ§ÿ¯å×ßëÿãü‡ÇßñrŸÇúOºû×î7~<>ßÿ2¾ÛçÞWïý¤ðÛOÿWúÿ>ÿçýߌÇÜýýžc«¬IüeÎükç?9úó—£ÿ˜þÌÓ3­¿Ûá·¯éëò¼ÿŸTÿ×úŸÕôÿÕýÿ>ÿ§KÿZýúÚz¾ºÿåØúkï¨mÿbÿÙ¶ÿðÿÿ¡?"×¹n¹ÿ'ýèÿCÿ›ýèm[þÇuëSýë·­Ôç^:ÿºò¿Žmýåæ%'õ=ü‡üCþqÝbÿ¿»ãÿ9ý±ÿéÿ ÿÛ囸£ÿñÿáÿCÿ£ÿáøþ·ÆÿÖóÁŸçÿ]~g:2¾Þ›¿”_ÏÚùŸäAÿþcð{ï¯}þEïü~þ³õó¿Žþ~þ{®ÿ\\ÿ_~þ£Ü¿®~þGÚÿŽüÍóg+œáüçÿm¿Øÿ[ÅŸó?Ôÿ‘œÿn“¿ñø•Î?Sÿ‡óÿÖå?þ?üøÿ,úÿ°ÿàèo—þÔÿ³mÿi×Ycýëá¿Rý¿‘ø4þ·Bý'Iÿ§çÿtýÿ!}Óñ³ðzýïÒþ_7þgÝþGÿÛ~QÿÏvüû϶ýÇ ùOþŸÝøWmÿÛÏcù¥ù×ïÿJýêÿSÿŸø¿Eÿ¯¶ÿO»þ¿TÿÈÏ¿’ÿOþ¿vþÿ¸ý'Õ?+ÔÿÇÿOÿO«ñÿÿ=Hj— \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_027_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_027_states.bin.bz2 new file mode 100644 index 000000000..7b51fd6b1 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_027_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_027_states.bin.z b/client/resources/hardnested_tables/bitflip_0_027_states.bin.z deleted file mode 100644 index 365da6804..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_027_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_029_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_029_states.bin.bz2 new file mode 100644 index 000000000..b55556692 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_029_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_029_states.bin.z b/client/resources/hardnested_tables/bitflip_0_029_states.bin.z deleted file mode 100644 index 32da12571..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_029_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_02b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_02b_states.bin.bz2 new file mode 100644 index 000000000..f22242565 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_02b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_02b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02b_states.bin.z deleted file mode 100644 index 3cb26a7ee..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_02b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_02d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_02d_states.bin.bz2 new file mode 100644 index 000000000..54170b83b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_02d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_02d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02d_states.bin.z deleted file mode 100644 index 84db51d15..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_02d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_02f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_02f_states.bin.bz2 new file mode 100644 index 000000000..e20b10f3d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_02f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_02f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02f_states.bin.z deleted file mode 100644 index 8858e63b4..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_02f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_030_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_030_states.bin.bz2 new file mode 100644 index 000000000..8042c6366 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_030_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_030_states.bin.z b/client/resources/hardnested_tables/bitflip_0_030_states.bin.z deleted file mode 100644 index a9643322a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_030_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_034_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_034_states.bin.bz2 new file mode 100644 index 000000000..06fc562c4 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_034_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_034_states.bin.z b/client/resources/hardnested_tables/bitflip_0_034_states.bin.z deleted file mode 100644 index 959af96a9..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_034_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_03c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_03c_states.bin.bz2 new file mode 100644 index 000000000..1a354ec8a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_03c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_03c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_03c_states.bin.z deleted file mode 100644 index 7ee384996..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_03c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_040_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_040_states.bin.bz2 new file mode 100644 index 000000000..54b71e2ce Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_040_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_040_states.bin.z b/client/resources/hardnested_tables/bitflip_0_040_states.bin.z deleted file mode 100644 index 372d2d4ad..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_040_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_044_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_044_states.bin.bz2 new file mode 100644 index 000000000..b268ec935 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_044_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_044_states.bin.z b/client/resources/hardnested_tables/bitflip_0_044_states.bin.z deleted file mode 100644 index ea9324375..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_044_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_04c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_04c_states.bin.bz2 new file mode 100644 index 000000000..26977703d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_04c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_04c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_04c_states.bin.z deleted file mode 100644 index 2bf23856d..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_04c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_051_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_051_states.bin.bz2 new file mode 100644 index 000000000..3c889d07c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_051_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_051_states.bin.z b/client/resources/hardnested_tables/bitflip_0_051_states.bin.z deleted file mode 100644 index 0b78915aa..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_051_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_053_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_053_states.bin.bz2 new file mode 100644 index 000000000..751724d3d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_053_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_053_states.bin.z b/client/resources/hardnested_tables/bitflip_0_053_states.bin.z deleted file mode 100644 index 700af31b9..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_053_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_055_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_055_states.bin.bz2 new file mode 100644 index 000000000..1cf3f2ad9 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_055_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_055_states.bin.z b/client/resources/hardnested_tables/bitflip_0_055_states.bin.z deleted file mode 100644 index 307828e64..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_055_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_057_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_057_states.bin.bz2 new file mode 100644 index 000000000..099cc0e38 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_057_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_057_states.bin.z b/client/resources/hardnested_tables/bitflip_0_057_states.bin.z deleted file mode 100644 index 3e8d1b279..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_057_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_059_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_059_states.bin.bz2 new file mode 100644 index 000000000..fea5cf3e8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_059_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_059_states.bin.z b/client/resources/hardnested_tables/bitflip_0_059_states.bin.z deleted file mode 100644 index 1356800e0..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_059_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_05b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_05b_states.bin.bz2 new file mode 100644 index 000000000..4dd885ec3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_05b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_05b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05b_states.bin.z deleted file mode 100644 index efe41d503..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_05b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_05d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_05d_states.bin.bz2 new file mode 100644 index 000000000..7ea71a9c6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_05d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_05d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05d_states.bin.z deleted file mode 100644 index 2830ce686..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_05d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_05f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_05f_states.bin.bz2 new file mode 100644 index 000000000..bda71a64e Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_05f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_05f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05f_states.bin.z deleted file mode 100644 index 890893050..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_05f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_064_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_064_states.bin.bz2 new file mode 100644 index 000000000..3bec7c36b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_064_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_064_states.bin.z b/client/resources/hardnested_tables/bitflip_0_064_states.bin.z deleted file mode 100644 index 05cd17e54..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_064_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_06c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_06c_states.bin.bz2 new file mode 100644 index 000000000..ff80c2233 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_06c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_06c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_06c_states.bin.z deleted file mode 100644 index d787bcc99..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_06c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_071_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_071_states.bin.bz2 new file mode 100644 index 000000000..6073d4e52 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_071_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_071_states.bin.z b/client/resources/hardnested_tables/bitflip_0_071_states.bin.z deleted file mode 100644 index 2d2f4a1c2..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_071_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_073_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_073_states.bin.bz2 new file mode 100644 index 000000000..d1ae56fec Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_073_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_073_states.bin.z b/client/resources/hardnested_tables/bitflip_0_073_states.bin.z deleted file mode 100644 index 552cff66c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_073_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_075_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_075_states.bin.bz2 new file mode 100644 index 000000000..6c8258ae3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_075_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_075_states.bin.z b/client/resources/hardnested_tables/bitflip_0_075_states.bin.z deleted file mode 100644 index e37d90e2a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_075_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_077_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_077_states.bin.bz2 new file mode 100644 index 000000000..acaf1e210 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_077_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_077_states.bin.z b/client/resources/hardnested_tables/bitflip_0_077_states.bin.z deleted file mode 100644 index f03f0bba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_077_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_079_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_079_states.bin.bz2 new file mode 100644 index 000000000..427506dd8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_079_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_079_states.bin.z b/client/resources/hardnested_tables/bitflip_0_079_states.bin.z deleted file mode 100644 index b05646ac5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_079_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_07b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_07b_states.bin.bz2 new file mode 100644 index 000000000..bcc281932 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_07b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_07b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_07b_states.bin.z deleted file mode 100644 index 184354a44..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_07b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_07f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_07f_states.bin.bz2 new file mode 100644 index 000000000..b56e0f7a0 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_07f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_07f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_07f_states.bin.z deleted file mode 100644 index 87ac36ab2..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_07f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_081_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_081_states.bin.bz2 new file mode 100644 index 000000000..c5426ace6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_081_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_081_states.bin.z b/client/resources/hardnested_tables/bitflip_0_081_states.bin.z deleted file mode 100644 index b8f66386b..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_081_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_083_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_083_states.bin.bz2 new file mode 100644 index 000000000..3421417ed Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_083_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_083_states.bin.z b/client/resources/hardnested_tables/bitflip_0_083_states.bin.z deleted file mode 100644 index 81c4c59f9..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_083_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_085_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_085_states.bin.bz2 new file mode 100644 index 000000000..17f1aaeed Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_085_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_085_states.bin.z b/client/resources/hardnested_tables/bitflip_0_085_states.bin.z deleted file mode 100644 index e642accdf..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_085_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_087_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_087_states.bin.bz2 new file mode 100644 index 000000000..5b9302627 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_087_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_087_states.bin.z b/client/resources/hardnested_tables/bitflip_0_087_states.bin.z deleted file mode 100644 index 1a844e453..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_087_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_089_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_089_states.bin.bz2 new file mode 100644 index 000000000..9f37987c7 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_089_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_089_states.bin.z b/client/resources/hardnested_tables/bitflip_0_089_states.bin.z deleted file mode 100644 index d02b3c777..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_089_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_08b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_08b_states.bin.bz2 new file mode 100644 index 000000000..0f42f9246 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_08b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_08b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08b_states.bin.z deleted file mode 100644 index 9c546f94f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_08b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_08d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_08d_states.bin.bz2 new file mode 100644 index 000000000..f7e2d1674 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_08d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_08d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08d_states.bin.z deleted file mode 100644 index e0e985fcf..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_08d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_08f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_08f_states.bin.bz2 new file mode 100644 index 000000000..f66b803eb Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_08f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_08f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08f_states.bin.z deleted file mode 100644 index f5b38b584..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_08f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_090_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_090_states.bin.bz2 new file mode 100644 index 000000000..7f559b40c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_090_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_090_states.bin.z b/client/resources/hardnested_tables/bitflip_0_090_states.bin.z deleted file mode 100644 index f901235a3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_090_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_094_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_094_states.bin.bz2 new file mode 100644 index 000000000..bcdcbd26f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_094_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_094_states.bin.z b/client/resources/hardnested_tables/bitflip_0_094_states.bin.z deleted file mode 100644 index f97d41f4e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_094_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_09c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_09c_states.bin.bz2 new file mode 100644 index 000000000..4b0316dc3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_09c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_09c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_09c_states.bin.z deleted file mode 100644 index 7946dcf31..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_09c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.bz2 new file mode 100644 index 000000000..daa61d3b7 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.z deleted file mode 100644 index 23198e8ae..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.bz2 new file mode 100644 index 000000000..d7171c287 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.z deleted file mode 100644 index 3d2cbe6d7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.bz2 new file mode 100644 index 000000000..958b8ed3d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.z deleted file mode 100644 index 9e6803572..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.bz2 new file mode 100644 index 000000000..9992d1259 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.z deleted file mode 100644 index e7ad43a84..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.bz2 new file mode 100644 index 000000000..5893a4938 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.z deleted file mode 100644 index cd17efb23..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.bz2 new file mode 100644 index 000000000..7deaece19 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.z deleted file mode 100644 index 8469638d5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.bz2 new file mode 100644 index 000000000..19c36b526 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.z deleted file mode 100644 index 591851878..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0af_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0af_states.bin.bz2 new file mode 100644 index 000000000..3e99de95c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0af_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0af_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0af_states.bin.z deleted file mode 100644 index 51e59ea2e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0af_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.bz2 new file mode 100644 index 000000000..cb2ac918b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.z deleted file mode 100644 index 09370ddf3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.bz2 new file mode 100644 index 000000000..f9c8c8183 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.z deleted file mode 100644 index 4048a702c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.bz2 new file mode 100644 index 000000000..19e1fe89a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.z deleted file mode 100644 index ab0b3755d..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.bz2 new file mode 100644 index 000000000..87d8693df Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.z deleted file mode 100644 index d3f655b04..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.bz2 new file mode 100644 index 000000000..57823403b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.z deleted file mode 100644 index d5c5f5edf..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.bz2 new file mode 100644 index 000000000..38fc1e0ae Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.z deleted file mode 100644 index 868afc9f9..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.bz2 new file mode 100644 index 000000000..4d1b27593 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.z deleted file mode 100644 index f7dd752f4..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.bz2 new file mode 100644 index 000000000..cb9afb002 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.z deleted file mode 100644 index 68ef2a6d5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.bz2 new file mode 100644 index 000000000..ae6e859a8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.z deleted file mode 100644 index 7720f54a3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.bz2 new file mode 100644 index 000000000..90c562613 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.z deleted file mode 100644 index 5f05c9cd3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.bz2 new file mode 100644 index 000000000..ad2df6b55 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.z deleted file mode 100644 index f9ead3d9f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0db_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0db_states.bin.bz2 new file mode 100644 index 000000000..353c48c88 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0db_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0db_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0db_states.bin.z deleted file mode 100644 index c272e158b..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0db_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.bz2 new file mode 100644 index 000000000..2d2e19707 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.z deleted file mode 100644 index 6247d26df..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0df_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0df_states.bin.bz2 new file mode 100644 index 000000000..14ca3fcda Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0df_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0df_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0df_states.bin.z deleted file mode 100644 index 63e00d2cd..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0df_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.bz2 new file mode 100644 index 000000000..19e2e6109 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.z deleted file mode 100644 index 5b4d867fd..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.bz2 new file mode 100644 index 000000000..f376b1cd1 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.z deleted file mode 100644 index 764188911..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.bz2 new file mode 100644 index 000000000..b263afc60 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.z deleted file mode 100644 index 9740a1a39..000000000 --- a/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.z +++ /dev/null @@ -1,28 +0,0 @@ -xÚíѱë,¬¨W)$.!Æçá6r*p )Å%øÌž\~ Æ#áèÛ™=Y ÁB ! éÿýïÿüMó²<^ïÿÏû8ŒÃ²üý-ËûûÇëyÞ}û¿_üû{šß¿»Ý¦yšÿ}ûÿo¶ýÇáyÿû{ÿýïwÿþ4·…÷Ÿæþ4ÿ{÷ðÁüíâïþ»þÏ»ûîßïžwßþ†ÿïû÷ïÆ¡þÿžq?‡®ÿºÝ}þ÷¾Æ­-ü÷¼lçÏÁÃpCè߃üsx<^¾ÿûùqû4‡íÓ¼m¼Òý¯ðù¿ƒ¿Tþ·›ÿeÙo÷ߺù÷ÿ§yûyš·íë÷vü¿?‡®<Þí÷ð?üo—ÿÁŸóÏ^ÿqض‡ð—%ÿQÿe9î/…÷Ÿæãþœÿöö¿qض‡ú¿œþ=ëÿ%ë/½ÿÍ߲ϟÎúOËÏe9–¿)ù·çžßóþ_Ž¿Tþµ›ÿeiGö俞ü¯“¿ñø§ùhüØÿØÿ-ïÿÐúcÿÇþWÍ¿Ó\ÞOÿþµàãÿÿEý¿Üÿ“óÏß¶öÿóò7\ÿåûWZþžÇ/í’ÊÿëøÿÒóS+¤ëëÜø÷¯µþz–ÿeö«ßíý§äü"›ÿ^äùù¯|üߘ¿ï÷ÿžÿÿ'þOôÿÞâ_$í©øŸ>ô)~Úð¥ç/âÿˆÿƒÿ‰ÿ³&ÿ¬Û±ÿaÿÃþg×þ×Jÿ«ÿïÅÿ ÿ£ÿãÿÇþþàÿ‡ø/â¡?ö?Ýû?ú÷Ÿ¬ßÿO}ß[Å÷¨ÿsÿûÜÿãþçâßÝÿƒþþÿÿ?þäÿ±ü_Ÿ_>_3þûô·âÿGÿƒÿ¡¿-ú?^^þü{ÞíöîÿþîñºÝ¶íîûŸÝïÂþ·Ûqÿe9î/…÷¼Žûï㿞£oû?^iü¯mÿÛÍ}þ÷=^máÇý}»ûü÷w ú[ÇÿÓë_jÿ~¼JÞ—eïsNþåèÿiûGzüþ]jÿ?;_uó½ÿ.µHå_Îþâ”ÿgíÿuë¯\ÿAþ±ÿkÒ_zÿYJÿžäªnýµ”ÿ=®ô?äŸåó%üÛéŸuú¬öúOïXÿlI)üýþ©ß—úÿÊÏÒý¿GýßÒþß#ÿ_IþI÷ó¿uùÇù¯oû_ümÿ|fÿ‘ÚØÿÙÿ±ÿcÿÇþýûøƒ?økûrñG-åþŸ_—ÿПý¿•ýgÿœYö¼«ãÿ›öôøþ·`ÿÆþÏù§Ìþû¯~·zþ×ý¯òþ{ô׃OüþÿÓþï}Öæ?üÿ¥ûoºý3óÿxµmßÿ=òÿ|ý0éþ['ËûKëŸY·ÿiÓ?·þ?ãÓëO[ÿEÿ#þû?ö?ìàþÄÿJü?5öÿþãÿ¬Çÿâÿãþ?÷_¹ÿÏùûÿÜÿGþ¡ÿÛºÿOüñèÿÄÿÁÿÄÿÿ‡ýûö?öÿ_Œÿ€ÿáøßÿ;|o·7¾ãÓÊÇüýyû¥kÏõwío¾óíÀ¿"üqá?ïa§þ8´…÷ÞCøïoÁÿïÏÕ;‡°þ‰«Oò~ùÏñï[¬¿üÜú/ÿz¼Gø”Áçß?Ç×ñ°óð¡ÿÕèß¾¦üÿtü|®ÿþßj—Æ¿Jåïõ¿rõë[Ì¿fý½=þ?ƒ_®¿ôùšë?ÿ!ÐÞÿ¤ø§Ç?çæšÛÎ]þS‹òýŸó¯uøçõÿðœ#]ÿëçµ9ÅãÞÓç2ÎÚõ‡{?ÿXÐÿ%ô×™ÿßY×”ÿØÿ°ÿaÿûûúüýmÓ_ÓþØk»uûÃñüŒC+ûç5×ÿçñ—Á_–ÒñIý?-üšúW þ9ûÿvÿ‡RÿOöÿrÿÙóÓ¿Åù¿GÿŸ%ýŸýŸø/Mÿuç+þô?ÛúòÏ6þÄÿÙöÕÿÞ߯׻$þÉéðåúèÿÌõ_·»Ï9ûßñþ<­Î=œÿ{äÿ¾ãŸ­Çÿáÿÿûo¯ö¿o¿êìOÓÜÊÿCü?ñÿÚú¯Dÿkÿ¯éÿÅþ_cÿ÷ôoÿ8ÍÓ<ÍËò¼Ã8,Ëó¾,Ó¼,Ó<ÍÏûóþx-Ëãµ,Ïûó>ËòxMó8,Ëßßí6ÍÓ<ÍÓ<ÍËò¼Ã8,Ëó¾,Ó¼,Ó<ÍÏûó>ÍÓ<ÍËò¼Ãóþ¼Os^ÿ·âÿwùn·0€ËÏðþç?‡¿{ç8úÞõ¿ß^øqÿ¿¿ô¸Àümã/µJñÏÉ¿þŸ¶ÿÖÁ/ßÿ ?ôפ¿vþëã/]ÿ½çÿÏéßRüµó¿Áÿð¿eþ·Ž?çŸ þŸÏ¾Ÿ}ž¾ô÷œÿJýÏRú÷ªÿCÙz’úµ×¿vý›Þ÷ÿþÒõõú?ìÿÈÿOÈ™ümÿjÕþÇþocÿ‡þÐû?òŸûïÀçþÍû?’ûß-â¯{¾ÿo=þ—ûÿÜÿçþ?÷ÿ¹ÿÏýîÿsÿýßÖýòÛ¾ÿÏýòÿÃÿäÿçþ¿ÍûÿØÿ°ÿaÿûíúŸýOZÿ¼÷ûÿð?ú¿ÅüÿØÀüíú¨ÿBýèýO«þw/ùO-ØÿÈÿKþßÞøÿ*òÏfþßß‘èÿÄ¿Sÿýýÿ?þüÿÈê¿cÿƒþ–îÿ ÿÁÿПüÿäÿ#ÿc/ô'ÿåwÖ¿Ôþ-Íÿ§ÿ%‡.ÿžÔþ¯ÿüß¶óÿ°ÿ“ÿ‘üovó¿¡ÿ!ÿ8ÿØÅ¿×üß½ä?·^ÿ'wþ“Ê¿^õòÿ“ÿŸüÿäÿÿõý¿Wûß·òÿçðÏ­?©ý‡ýŸýû?öìÿØÿuôßÇk=¿ÞÞþ³­é_Ûçîõ_ë©þRø©ý/ìþàþaü´Û÷å,?¥ø{ùýx¥àçðÏõ÷òß·‡ñïÇø×ÁÞÓùüµþý¡òo}–<þ|öUö¼«ã/•ÿíæ¿ü÷ëõÿ¾'ÿîïֺݽ?^-ù??‡O®ºÝþ‡ÿ-ó?ø[?ÿÔøÖþ«Ç«¼¿³?ÇþMø5ôÿþRû_Úÿà¿ÏÍ¿¾þ/óÿHóßjûÖüÊÎ=ù+mßÿ¬Ã?5ø¯ßeë?ýÜ:øûýS¿—ìÿŸ¡_ëñ\cý]Qþ¯ýW²ý·Nþ®ýÇÒú7ÖíÚô¯™ÿòþ¹ù×^Úú/úŸmýû?þ ý¥ø—Ñï,üvôðÿuü}èi.û¾Jý+{þ÷ZçKÙËÿœÿqÿ¸=þ;‡ï‘ÿ+ ?„¹®Ÿן*ó_×ú¿ZÑ¿výo_uó_:޽߷[uô×á™þ/Õõó_Z—ÿºõßô忬þ[ºþÀ{^Jê^3ÿkKþGþ!ÿÐÿ{À¿þyNÿÿü¥ôGÿGÿ‡ÿáÿoó?øcÿÃþ‡ýýßæþÿÃÿð¿Mþ·ÿHîÿsÿ¿>~R¬ÿIüô׃Íû/-ïÿôsÿÏæý?ÿN>>„í-ãÿËïÿûÏuöËu»íøÿ–÷ßöï™õ|ÿŸûÜÿçüÃù×êýOîÿÿ‡û×ìÜÿGþcÿÁþý-ÙÿÐÿàèoYÿ'ÿŸmû¬þ—ÜþyÅõßÿ~ê?Iý?5þ¿žò?•ãçß[æÿѰÿKýg-õOÿþöËñ_äÿÃÿþgUÿÃÿMþâÿìú¿êÎî]ÿ¤_ÿ‡üÿäÿ'þÿ?ùÿuìýäÿ—î?RÿñÿÄÿkæÿ—ê5ñÿ=åÿÇþOýOkþÿ÷ˆÞôXãïÆ—nwïî/ÿmº=÷ü¸¿~îùgÇþàÿ»ø¿s‘„ùOŽ?‡/)þÛW/‡®þuŒïyøgŸý¡¿ýµó^éúï)ÿÛ~þ´8U˜ëJŠ¿fþ7øþ·Îÿ–ñ·®ÿ;{åíÚ/÷à;û–‹ÿrÏûCŒ¿kÇç~ßþÿ>ç¿5ýÿývÂú7{ûUø»qÒ_[ÿ/Á?·þöæe=žðûp>5׿výýý_†¿tý_½þû?ò_ºÿ¯Ÿ×FþnåZ.sþcÿ·½ÿCÛôÇþÿ'«ÿÐN;þÿŸÄ¿Îÿ×/©¿Y'Ïõ?ú,­ÿ"•ÿ×ôÿ£OÞÿwvþÏõÏ_sýiË÷:û¿¿ÿë÷{ýíÿzð±ÿÔœÿÂóŒtþ5ù¯îü®¿’ù;>ÿ]ÿÚùÿðâÿDÿ¿ZüKyþÔ²ø=ýG{üÚóOüñð?ñVåŸuû.ö?ìØÿìÚÿ¤ú_‹øMÿ/üþþ¯wÿçê÷_Àü¯Ž¿æþ¯-ÿ¥û~3~‚þÐ_‹þ²ü_ëû'a{i~©~î¿Ôä¿j)ÿ¥ðkóßúÿÓ¼ý<ÍÛöõ»ìþךÒðòøçú¿<¾kÿýÿ§ÖŸ{Î:þ;Íÿã°åíõ¯Íÿ¿#ÿêÖ¿§»ùOÍï‘ü°,ÿÐÿµýÏô¿®ÿýÿúç¿VõÓ>Qí›üc}ÿÓ¦ŸõõwùßÎÿ¯íÿEþCmøèèØÿ¡¿ý©IýGê¿Ú]ÿÔÿ¡þõìÖÿaÿ·½ÿK󟶬ÿ«-ÿ­×ÿEÿCþÙ;ÿpþkUÿºFÿïiýKëïJéú¿éóŸtÿ×ÑÿÙÿuùÿwäŸtÿ×8ÿ[—œÿ´íÇñÏuò·]üÿ™ýGjÿaÿgÿÇþýû?öìàþàÿyý_vÿ©¥ü×ÙÿmËèÏþßÊþSo_ú ü¯iÿGÿ‡ÿáìßàOüw©ýqYBûciÿ=ÿ—&üúÿNâÿðÿgýßMÛ÷?ëðþÿZzµ¦_ëñ\cý]QþûúcÒý·Nþúý?<¿åÆŸÎ?gÛþ§Mÿšù/¬»þ´õ_ô?ëñØÿ±ÿáÿð·îÿ—újΗ=É›ñ¿øÿ¸ÿÏýWîpþãþ?÷ÿ‘èÿVñ'þ‡ø?ôâÿàâÿˆÿÃþ‡ýûû¿û_ð?üÿÛâÿ÷ˆÞôXãïÆG;íÛv÷îþòߦÛsÏûKáçžv|¿ÿ»IXÿäÌgéú’>_:þóðãù˽rχþ×¢[øšò]ÿ-v¿¿ÝÂþ{ãwí¾kÏõwí[üeñ¯RùßCýóu}úwýúýú_ãðþÛÕ¹o1ÿšõ÷¾ãâ¿ÇŸ©õ—ë¿nù_ýËâ?¤ñÚûŸ÷üpþÝ<—Îÿ4·ÿºü§åú?ç[ëíçõ×ð%]_¹óÒùó×ñxÏŸÏ~÷ü§]Xÿüc]ÿ×¥ŸõõwMùýûö¿_°ÿ¡ÿÁÿÐß.ýµíÚð­ëuó?­ìŸ×\ÿíðw¿o ‹ÿyoåÿ‘úÿ´õ¯üsöïG‡ÐÏ“÷ÿô`ÿ—øÏZœÿ5ýÖõöÛþŸÿw쯎å™tþ5ùϺÿý϶þ‡ÿÛ6þÄÿÙöÕÿ¦9Üÿ%ñOþU®ÿÇç—ãþqûúïºýZÿz8ÿkòÿ5㟭Çÿáÿÿ•vmûŸöù«Îþ4Í­ü?Äÿÿ¯ÿ/ÑÿZÄÿkú±ÿ×ðÏZ×–Ç?~_ÿÇoÙÿïòHÆï;ÿö~—ëŸûøÀþ÷á§íã°'_bûçáçð/;ïÛ?´áCè¯Iÿtþé8µÿ».ÿõ~þé«ãõùOŸ?âó›·Äç)þ9ø9üËΟûçøþ·ÌÿÖñçü‘†oýÝúùÏíï¹vé<÷ªÿ—â§=Ò÷}ùëålÜÊ_Yÿ~÷Ùø¯2ÿìÿÈÿåÿ·ä/ö?öËû?ô‡þØÿ­Ë»÷_À_ÆÿŸæ?à¾vü_7׿þÅ6þ/—çp{ÇÀ­Ç±Ž;ò•Åÿ׸ߤþ/ýû?©ù/¿ôÑGã÷íÜÿ)ÛÿBýuYdçëÜóÇ¡-üeiuþ·°ÿlÖösø.¥¿¦ü/Á7·þöæ¥t>{\ÿÚíÚüwõùCþÿs÷ÛÕÿ¸æýç_ºÿ›?ÿ¬ÿ®ÓÿsçÏúóWZÿOÿHÿßîÛ{÷›êôÿcýþ׿ÿúów›ù×=ÿ[–äÿÄþ‡ýûŸåü?ý¯Åý Mý þGÿGÿ×Ö?|à_Qþþ'åð¡?ôïAþ¸qþûìì'ßlÇÿn‡m{ˆ»þáøÞó·Î¯—ÿ§æÿ<üãþ®Ýëæÿ¿`•ïÒùO?׿røçú—}ó¯—s¥ãßë·‡ò³×õ¯ÍÿדWŸ«òó‡žÿ¯ÿ·uüÑÿ­ëÿËÊO¿~Öù½ëåïºÿû.öñþùmþ·¾ÿµ¡¿Tþµ[qÿ2üíÊ=ÿ¿¶ÿùý%ùßËèïŸ×@ÿCÿÃþýµèßoþ©kä¿Òοù9øÖç߯ú—Ú/Ù»vþg)~Rû¿tþZÎý¡eþñüí+ÿgíÿŸ^È?öŸ>óÿŸ—_ÒýG[þ§ð¯ÿwæþCþ!ÿ€ß¾ö»öúßËôÏÏÍÿyøÇýÓß·<ÿµ=jëÿööÿ¾øÿzòïêóoQþqþëÕþ÷ùÛrÿ‘ÚØÿÙÿ±ÿcÿÇþýŸúGÀ>ð©ÿNýèý©ÿMýïïúÿËâO¥økëßð?üo™ÿ©ÿËùÃågõýsŸÏ¾Ÿ}ž¾ô÷î¿ûç?×Í¿~îymàÇý©ÿKý×£úóïÿëõú–Eæˆûçùÿ[ë_ê?i3ÿÚñûô÷s´,õûÿ¾üK¿~zÿûçöëò¿¾þŸtÿÏÕ/Ëí矮ÿgµþ³6ýŸ÷²õÿéú—u민þ¡¶þ‹þg[ÿÃþü§þ"ðo·þ'õ¨ÿCý›õ¨Íþ“¯_ü.mþ“â§=ðòùü+Öÿ»:þ¿PýŸúŸð¿]þ·Œ?û?ö?ììÿ–÷øþ‡ÿmò¿õøGðçþ ÷ÿ—å8~Ò}Wÿµ¿þûˆÿ$þ×6ý—¥-ü˜þËÂ÷ÏïãþK÷¾ÿÌýÿãú—ã°m_ëßÒøÿ\ý»Üýiý;ëñÿÚ÷Ïú½ÿoéþ÷ÿ¹ÿÏùŸûÿÜÿ±™ÿ§þþw™üõÏwŸ{Yÿäÿáþ?òûö?ìíèð?ô·Kòÿaÿè!Ioö7+ïRÿÔÿ§­ÿIë?IïßõQÿiYŽýg®½6ÿ÷¾üëÕÿgEÿgÿ'þ‹üvýÿè¶õ?üß¶áÿgÛÿ%­_ÚæüÙ_ýòÿ“ÿŸüÿøÿÝþÛ«ýï[ùÿ¥ûÔÿCü?ñÿšúoËúõ5û¶ÿû?õ?-ûÿýü½çÊoþÛüô§?ý¯Ü+Åç¥Iç‰ó§|þ§Ç¯ úCÿäÇ{”î¯wÿo¶_ÿ«Î¿ôÕŠÿsÏÿÔøáøß2ÿƒ¿eýÿÚù§åð¡¿fþWýýW7ÿhOüçÆy,?]ûÛ»†ÜYú”¿íð¿úü³ÿ#ÿ¿/ÿµå¯õóû¿õýú[¦?öìþ~§»Ÿ¸wÿ³~ÜßßÏJ÷—ÂOÅ?þoú§å×{½¬÷²ãÏçü3nýúv¿>ÓòÓÃ+Yÿ¹þ¥ò_ê’Ê=ÿ_ú×Ê¿í+„·]?9ÿßñx÷~ßnýÅôŸÿþûýY_þËò?”éŸþù[úÇ×Á/ÿFþ»µ¾>¿ÄòӯߺóßýµåÿÜúËŸÿüó·ü¯½þ­ûßð¢?[ײַçô/©þßËù_Š¿ôüßnþÓóKüñð?ñçéóÛòϺýûö?ìVííô?éýmÿ¯]þGÿçþýéOîÿÿÅýèo)þ[÷þI?þ/›ö¿ÿ轕ÃßµŠ?ÖÑÿ‰ÿçþ÷ÿ¸ÿ‡ÿŸø«þôüÿøÿñÿãÿ·ìÿß÷ŸÇþ˳ò«Ìÿ«íÿ·kÿ³NüÿèØÿ¡¿=úkןчï_a]°4üßëo}þm¯©ýy ?|_éïsò+G¿OÛÿ÷ñhcÿßÎÛÞüåæY>ÿ5ö)ÿyþ'Ư½þìÿšý¥þgùþÓüר?ÿ!ÿôïaýkèŸ=­éKJ?WËóŸtÿ×ÑÿÙÿuùÿwäßÕçߢüãü§mÿÓ•¿-÷©ý‡ýŸýû?öìÿØÿ±øÀÿæþ¯ãÿÑÖÿÑÿ ?ö?»öÛö?ýó»ó×'òOÀÿðÿoÛÿÁŸóDz„ýÝwo8q{oüGý—帿~Üÿñ:î¿ÿzŽêçß?ß}þcŸþRøqÿýûݶí¡þ_BÿýùïWÿ—Žÿ;óצ¿_/eŸÏ¾—=OcýËðz¼ZÒOïýˆ>ëïj÷ÿ2ù'…¿ß?·ÿ[—ÿûõÿÆaÛ~^~íïÿ¹úg¹ý?×?'±ÿõMÿÜúoSÿnYÚ®¿q8ž¿e‡>ô_ô?ÛúöìÀ>ðñÿÛŒÿµÿ‡ÿý_ÛþØcëñ_œÿìØÿá?æýÛ:|âˆÿCÿ'þþ'þø?ìØÿ°ÿ±ÿsÿþ‡ÿáÿßäït»…ñO®>Ë;cûîywø9ûå»ýyû¿ñ\÷wí®>‰{¾û}[øqßîò3¸ñ -~<~ß«à÷ ÿßZqu‹Ýçç=¬‡ä>‡¿‡ëý¼üÜúߎ+¿o_—Â'õ»ÜüïÍK)|è¯Mÿei ?†ãŸŸšOMù/ÿ–Æ?ïá¶Çûó8œë¿å¯qhÿ*å¿ê¿ûút~ý»úwã°mw߯áÓg«_­çßéí)øqý»þ¹þëö¸þÖÿ‡ø¯¿Ôþqô¼íó{\ÿÒû3eýµ÷¿Oÿ*óo]þ¡ÿsþµŽîüst^jsþÐ=Y>ÿåôÿý+/ýóãúÏ}œlëÿúKå_îþoÝú+¿ÿ‹üÇþƒýûŸUûúüýmÓÿÈ>[g,·ÿjÛ?ÑÿdöËOµkÛß´ñÿV»ÔÿÓÂÿ§©ÿ¥ýOã°Æ?gÿÏûöß{°ÿÑßÏ‘Ÿÿ5ý[œÿ{ôÿYÒÿÙÿ‰ÿ:㯎ߥôïñüoÅÿþg[ÿCþÙ†OüŸmÿWÉù'n?ÿ—;¦à¿_%þÏ\ÿ¼þ?ýFrþëáüß#ÿëûÿ-Åÿáÿ·jÿíÕþ';ŸWSû\íþ#õÿÿOü¿¶þ+ÑÿZ쟚þWìÿyù·þ»ÎþŸÛ¦yš—åy‡qX–ç}¦yš§yšŸ÷çýñšæÇëñzÞŸ÷qX–ÇkšÇaYþþn·ižæižæi^–ç}ÆaYž÷q˜æižæi~ÞŸ÷ižæi^–ç}ž÷ç}šóú¿ÿ¿Ë¿ÿíüÛû]®î{àøß‡/•?Ÿ†ŸÃÿÓö×OÇþÐ_“þÚù‡®ŽÿÕç_j⯠þ‡ÿ-ó¿uü9¤á[·~þ+µKç¹Wý¿?íù“¾kןéwÿ—ÿ*óÏþüïQþKþbÿcÿ·¼ÿCèýߺü'ÿ÷ÿ¹cõþäþw‹ü}Þÿ'þ—ûÿÜÿçþ?÷ÿ¹ÿÏýîÿsÿýÛÞýù¿¹ÿÏýòÿ“ÿŸüÿÜÿçþ?ö?ìØÿìÔÿ”è-î_ôyÿßÿ£ÿÛÎÿ|àß®ÿ‡ú/ÔÿþvíýÕÿþnþSÛö?òÿZÏÿÛÿ_EþýFþ_»òýŸøwê?£ÿãÿÇÿÿÿ¿Mùo½þ»uûŸuúÛ¾ÿƒþ‡ýú“ÿŸwò?2ÿ¶Þ¥öciþ9íü+9ükÇ_jÿ×ÎÿGþoÛùØïÉÿHþ7»ùßà?æ›ó]ø½æÿÖÏn½þOÙùïsçO]ýŸüÿäÿ'ÿ?ùÿ}ÿïÕþ÷-ù+ݤçOööìÿØÿ±ÿcÿ×Ñý+õ}ü÷¶~$ýéOÿ«ö÷òó-+|Ú“ÿ±üü4üO_>ô‡þ½Èí×Õñ¿âü¯×ïûž¼ÿ¶¤½%ÿçžÿ‰ñÃÿð¿eþëçÿÓÛÜw®¿k¯µ?ûç»Ïï;M{öo)ü¸ÿ¾ýÛµ¹ç¿ÿíï›ÿ¸ÿÿT)üþ{û—Ìþ'÷?hëÿºöGmÿÏšÿ×¼à??^Ûöõûãuü}Ü?õYoýçñJá’Æ¿~þÛÀ?îôÜ}Òô*ß?Ë䟾ô÷vå}þéþŸËÿÛÿåõo¬Ûÿ´éŸš¿}ú—ÍŠþGûÿ²´]åùo´õ_ô?Ûúöü?âù£?ýéÙþÒ—Ôÿ²ÎÕìëâ¤ó?¯Üÿ-ÅO -¿•ÿJ:ÿRújý}züÚëO—ÿ{È?© ߺü×­ÿ¦Ïºõà?äòþ=ô×Ò?ÿ«Î?ú¿eýþ·Îÿàýûö?ö›û?üÿÃÿ6ùßzü#øsžûÿ>¾3?¶Ÿ_Ú_ÿúñŸÄAÿ}üëàÇôçoÿÛÃýÍû?=Üÿ³|ÿßÓÛù©/¿þ×üáÛÝûãÕ2þßë÷~î>O®þü`;þ¿ûgÚ÷Ÿ­ßÿãþ¿íóç»÷?¹ÿCþŸ6÷¿ëï—÷aÿ²»ÿqÿß¶üÇþ‡ýûŸEûúüý-ëÿäÿ³mÿÐÎ?×ýW/ÿžvý§6þŸÿ_ùŸ¦y‹_™ý½eþ ûÿ–¾)ÿYÜ~6ÿw™þ¯ãÿÃÿÏþo9þ‹üøÿÑÿ¬êø¿ÉÿOüŸ]ÿWîü³ÕŸkâÿÊòêÔÿ!ÿ?ùÿÉÿÿŸüÿ:ö¿~òÿK÷©ÿ‡øâÿ5óÿKõ¿zûsùÿíÚÿ©ÿiÕÿÿÑ[f¬í§N>¥ÛÝ»ûË›nÏ=?î/…Ÿ{þÙñ?øÿ.þÿ~ûþÿ¼—}_Rü·¯^ÿ\ÿüëßóðÏ>úCúKã¿¥ñWÇ_ºþËü×gçÿ\üû;~¸>]^|Ÿ#߷ǹ®¤øoóg…ðsøçúåß‚ÿáëüoëú¿³wÞn¡ýs¾³o¹ø/÷ü°ÿ8Äø»öx|î÷máoñásþ[Óÿßo]Ý÷yo¿ -7Rúkëÿ%øçÖßÞ¼¬Ç~Χæú—ÆJýúû¿ éúÏù?ëæÿ¬ÿ“ýù¯#ÿã絑¿[ùŸ–ËœÿØÿmïÿÐß6ý±ÿãÿÉê?´ÓŽÿÿ'ñ¯óÿxùUw~ŒåÿYù{®ÿÑçüsç_‰ü¿¦ÿï}òþ¿³ó®nüšëO[¾×Ùÿ—%Ô?óýíÿzð±ÿÔœÿÂóŒtþ5ù¯îü®¿’ù;>ÿ]ÿÚùÿðâÿDÿ¿ZüKì¿‘éÿšúöøµçŸø?âÿàâÿ¬Ê?ëö]ìØÿ°ÿÙµÿIõ¿ñÿšþ_øýý_ïþÏÕï¿€?ø_Íý_[þK÷ÿ4üfþüý¡¿ýeùßÖ÷Oöó‡Õ—èçþKMý‹–ò_ -¿6ÿÿ?ÍÛÏÓ¼m_¿Ëî­ù' /®ÿñËã»ößïñjý¹ç¬ã¿Óü?[þ×^ÿÚüÿ;ò¯ný§òJç?5¿GòòüCÿ×ö?ÓÿºþôÿëŸÿ²òÿKíÚüc}ÿÓ¦ŸõõwùßÎÿ¯íÿEþCmøèèØÿ¡¿ý©ÿk»þ“>ý©­_ÿG³þW?õŸSøç궬ÿÔ®þbª^ÖQýŸzû‡Tþé×ÿ:ÖŸëÖ_¹þƒücÿï¥þcÿ¹eý?mùo±þúòÏöù‡óŸnýï~Ö¿Åú×Ôÿeÿ×åÿß‘Òý_ãüo]þqþÓ¶ÿÇ?×Éßvñÿgö©ý‡ýŸýû?öìÿØÿ±Y±‚?ø÷±ÿëø´õô?èýÏ®ýß¶ýOÿü|ÿùÌù«îþ3üÿ[¶ÿƒ?çŸ}üo·mû¿¿=üßÿuÿÇ«¼ÿýõàçö¿qض‡újýÞn¥óß»þŸÿãu<þq8ž?_¿'Çÿ9øeý¯ãþGòÿ{Ÿµù¯|¼é÷šõŸßÿÊá·û}nÿM·fþ¯¶íû¿Gþ—ÊÿX~Õï¿uò·¼nüØÿú¦ný‡þ»œýr/ÿšÞúÓÖÑÿlëØÿ±ÿaÿðÇÿo3þ×züþ?öÿei«ÖÙ¿´íŸÄqþ³lÿï‘ÿ‘È?ôâˆÿAÿGÿ‡ÿáâÿˆÿÃþ‡ýýŸýþ‡ÿáø¿žÿ¾·[ˆ¿ß;cûîywíÎ~éÚsý]»Ë¯àÚEøãÂÞÃþN)üqh ?îïÛ]~7>ðÿvÂúÇÏ{XÅ}ŽßbýåàçÖÉø×ã=§ ~8ÿþ9¾þóºL>ô¿ýÛÂ×”ÿŸŽŸÏõßÃÿ[íÒøW©üï¡þûº>½[¿®þÕ8lÛ§9\ïÒù?‚ŸÆÝšsý×íqý­=þ?ƒ_®¿ôùšë?ÿ!ÐÞÿ¤ø§Ç?çæšÛÎÜšûÛ•èÿœ­Ã?¯ÿ‡çéú_?¯Íù+ÿóž>—qþ«“ÿ¡þ%¹ÙûùÇ‚þ/¡¿ÎüÿÎú»¦üÇþ‡ýûß/ØÿÐÿàèo›þšöÇ^Û­ÛŽçgZÙ?¯¹þ?¿ þ²”ŽOêÿiáÿÓÔ¿JðÏÙÿ·û×8”úz°ÿ—ûÏž÷˜þ-Îÿ=úÿ,éÿìÿÄiú¯{<ÿ[ñÿ£ÿÙÖÿ¶ñ'þ϶ÿ«îü÷þ~½Þ%ñON‡/×ÿCÿg®ÿºÝ}ÎÙÿŽ÷çqhuþëáüß#ÿ÷ÿl=þÿÿ¯Ø{µÿ}ëüUgšæVþâÿ‰ÿ×Ö%ú_‹øMÿ/öÿû¿§‹øÇižæi^–ç}ÆaYž÷e™æe™æi~ÞŸ÷ÇkY¯eyÞŸ÷qX–ÇkšÇaYþþn·ižæižæi^–ç}ÆaYž÷e™æe™æi~ÞŸ÷ižæi^–ç}ž÷ç}šóú¿ÿÿûŸÏÇPöù쿳ϓ—þüÁßþ±|‰åsº=–õø;ùäþŽáçðÉõO·ûñçð¯ƒöùÐúëÐ?¬èûïåÚæÏô¯ís÷ú÷#ÿ¤øK×zþ¤óŸÊÿöñùßÖö3¿>÷ì±ý@Š¿·_<^)ø9üsý½ýãñJþ‡ÿ-ó¿uü­ëÿ._àíæ܃þîOðè{×?ü~ÿymàoñO úKã_¤ô×ÖÿsøçÖŸÔþ©½þµóŸëïÿ2ü¥ë_¿þû?ò_Oþçüuò·ÜÿaýüÇþo{ÿ‡þ¶éýÿO–þ´Ó¾ÃÿÒõ_Æ¿gá·ãÿ_Ç?ŒŸôñJ{ñ_qüdÿ(ßQ¾™’ùËõ?ú\‚ÿ‘ÿëy/yÃÏû¯öáKý_RúKåKÝüŸëŸ¿æúÓ–ïÖï?X—ÿÚùÿ´ùüº÷Ÿ{Xÿ–ï£ÿ£ÿKô÷ú¿¦þ£=~íù¯ÓŸýýéú÷÷w¦¹æüUÒ?nÇ^ÿxÞ[ÿàÿ+ò?*[ÿÚçËòϺ}ûö?ìvíRý/½þž÷týó=þ?æ—óú×öþÿÞ þGÿGÿ¯×¥üMýüÁÿwð×Üÿµå¿tÿOÃaæÏOÐúkÑßßqsñxùþkùèÛ§9lŸæmûã•îÿx…Ï×Η_ª=Ưü—Âßï·¯ûûü_k^ðŸ§yÛ¾~Ÿætþ·Ç«,ÿpêÂÏáŸëü’åLç‡4ÿoóöTÿU‡ÿGþÕ­OÿvóŸšß#ùaYþ¡ÿkûŸé]ÿ?úÿõÏYùÿ¥vmþ±¾ÿiÓÏúú»Žüoçÿ×öÿ"ÿ¡¿6|ô?ô?ìÿÐ_ƒþÚù¿®žÿJšÿT?ÿ§6ý­ã¯»þ¥öï5üð=n[–ÔgíüÏ9ü·ãߥöÿôs÷çkžúïÑEnÿ—Ê¿œý"½~âñÎþ_·þÊõäû¿nþÿšú›Þÿ,¥Oò?…nýµ”ÿ:ëýùgùüÃùo«_JõÏrý¿§õ_6Þý—”þRø5¿oyþ“îÿ:ú?û¿.ÿÿŽü“îÿçëòóŸ¶ýï8þ¹Nþ¶‹ÿ?³ÿHí?ìÿìÿØÿ±ÿcÿÇþOý#꿃?øSÿú/ÐúSÿ›úߟ±ÿÈî¿Jñ×>ÿÁÿð¿eþ§þ¯mýßÙ ÏÕŸÜÖóÌõß«ÿ© ßúgê¿Ú®ÿZÿæéî¹þ[ÿöú—ÆÿI×ÿ5ãÿZο ¾öømÊ_LºÿÖÉ_ÿ¼O×ÿûõóŸ6ýëæ¿¼¿´þå§×Ÿ¶þ‹þg[ÿÃþÿ‡úàþvëRÿ‡ú?Ôÿ±Yÿ‡ú×¶å¿ËwŸ«_¿®W¿Îsߢþ»¦ü/Á?·þöæe=žðûp>5׿6ÿ#ÿèÿvëÿ]ÿ_¨ÿþOýOøß.ÿ[ÆŸýûö?öËû?üÿÃÿ6ùŸxx>sÿŸûÿµñ“Òõ¤ÿIüôׄÍû/íîÿhÇ?sÿ¿&ÿ»øÿºü[åýsçOëñÿÚùïõïÿsÿûÿœ8ßÚüÌýòÿX¾Mþîÿ#ÿ±ÿ`ÿƒþíèð?ô·KòÿÙþ\7ÿ·[+ûç5×;üµó¿Hý?RÿŸ¶þ%­ÿ$½ÿ§_ÿIæ?“ÊmÿŸuýŸýß¶ÿ‡ü¶ýÿè¶õ?üß¶ñ'þ϶ÿ«îü7Í­ò¿j×ÿ!ÿ?ùÿ‰ÿÃÿoõ³¶ýOûü%­ÿ,õÿÿOü¿¦þ+Õÿ¤ñÿÚþ_ìÿÔÿ´ìÿÏÓ{ ¬×o˜¿ÃÏ_Ìÿ~þsýýúó7øÀׄïrÀ¬ó¯s¦¬ÿ‡÷ï׿û4üþeã÷ù—Ã\0úð¡?ôïAþ¸qþûìú¯õ«°ý­_­á÷wíWØþ;ø_uþÿ˼カ¿kÅÿ{ðsø—?÷=üÿÛäðçü±íÿžßqض‡ðµ¿õóŸ×óãöPÿ—ÏŸú¿Ç³nüß›¿VýÓòõ{í}íÿÒñ_oþÙÿ‘ÿýÈÿïÉ_ììÿ–÷èý±ÿ[¶ÿÕÇÿ”Á÷Ïã¯ÒøKá§â?Àÿ7ðÓò××KÙ~^wìÿÙ?-Kxþòë3-÷ë¿”ÉßTý—¼ü—úŸ¤ò_Ïÿ׆þµòoûÜ~¸~Jüñøsþ¿ei»þbúûç»Ï¾þSßûŸ‹÷–éŸq?žÃ¿~Üû‰üO­ÿqضŸ?¿Ó__þãŸ[ùó_<Ër<=¬ëþ7üŸèßVàÇúÕZ?Ïë_Rý¿ýGŠ¿ôüßnþãþÄÿÿÿÿ·çÿ¶-ÿ¬Û±ÿaÿÃþg×þ×Jÿ“Þ?ÑöÿÚåôîÿøÀ'þ—ø/â¡?÷µïÿhß²~ÿ¿ü½Uüq_ú?÷ÿ¸ÿÇý?îÿÙñÿÿoÕÿƒþÿÿ?þüÿ–ýÿûþs×^+ÿËü¿Úþ»ö?ëôÇÿþ‡ýúÛ£ºþÄ¿º¾ÎDÜÖŸøÕþWª~NYýTÿ½ú[½Â·>ÿ6Ö¿Ô~üxÉÞsò/GÿOÛÿëÇ_fÿ—Î_Ëù¯±?Hù/ûŠÇÿYûÿ§×òýG~Kù%Ý´å -ÿúñgþà?äòø-àk¿k¯ÿð½LÿüÜüŸ‡Ü?ý}Ëó_Ûó§¶þooÿï‹ÿ¯'ÿ®>ÿåç¿^íß‘¿-÷©ý‡ýŸýû?öìÿØÿ±øÀ×óÿ”Å}¾žÿdžü‡þìÿØ_°ÿ£ÿÃÿð¿mû7ö«çe û/Kh?\™ý1î¿,Çý¥ð—åœýtÿõÕÏ¿¾ûüÆ>ý¥ðãþÄÿÿ—_ÿ^æ>Ÿ}/{žÆúÇÿŸ£Ïú»Úý¿LþIáï÷ÏíÿÖå}ý?éþŸ»ÿœÛÿ?]ÿφý¯_úçÖÿ§ó?Õ­¿òú‡Úú/úñØÿ±ÿøÀ'þWâÿ‘úŸúŠÿ³ÿ‹ÿûÿÜåþ?ç?îÿsÿŸùGÿ¶uÿŸøâÿÐÿ‰ÿƒÿ‰ÿ#þûö?ììÿ¿|ÿ þ‡ÿá[üïân·0þÉÕgù7þw¬¢¯?ò¯—³_¾ÛŸ÷°ÿÏu×þþÞ?ßý¾-ü¸ÿó þ{ðãñû^uø¿gøÿÖÊ8„õ\}¢÷Ë7-Öÿúy)ø¹õ¿W<~ß¾þ.…Oêw¹ùß›—RøÐ_›þËÒ~ Ç??5Ÿšò_ÿ-ÞÃ?l÷çq8×Ë_ãÐ&þUʽ×ÿ‡mûºþWn~÷ô«õükÖÿÛãÿ¿ãõ—Ú?Žž·}~ë_z¦¬¿öþ÷©ñ_eþ­Ë?ôοÖñÏŽÎKmκç/Ëç?íúç}œlëÿúKåŸvýkä?öìØÿ¬ÚÿÐÿàèo›þGöÙ:ûc¹ýWÛþ‰þ'³_~ª]Ûþ¦ÿ·Ú¥þŸþ?Mý/í‡5þ9ûÞÿ³ÿÞƒýÿˆþ~Žüü¯éßâüߣÿÏ’þÏþOü×uü.¥ç+þô?ÛúòÏ6|âÿlû¿JÎ?qûùø¿Üù3ÿý*ñæúçõÿqè7’ó_çÿù_ßÿo)þÿ¿Uûo¯ö?Ùùëø¼šÚçj÷©ÿ‡øâÿµõ_‰þ×bÿÔô¿bÿÏË¿õßuöÿÜþ3ÍÓ¼,Ïû8ŒÃ²<ïã0ÍÓ<ÍÓü¼?ï×4?^×óþ¼Ã²<^Ó<Ëò÷w»Mó4Oó4Oó²<ïã0Ëò¼Ã4Oó4Oóóþ¼Oó4Oó²<ïãð¼?ïÓœ×ÿ­øÿ]½Û-¬âê½ÿùÏáïÞù޾wýÃï÷Ÿ×~Üÿï/=.ðÛøKÏ?RüsçŸþŸ¾ÿS¿üüý¡¿&ýµë^éúï½þcîü-Å_»þüÿ[æëøsþÙà_ðùìûÙçIáKÏù¯Ôþ,¥¯úÿ8”­'©ÿC{ýçä]ýáòúϽïÿ9ü¥ë_»þ3û?ò¿Gù/“¿íîÿYµÿ±ÿÛØÿ¡?ôÇþü?G¿~cüöúÇ?ÿZðÉÿh%þ7}ÿÛÇ/¾ý/¥þ£tþ¿ó÷¯Ãõ_’¿jïþu þ¹øwÉýï>îÿÔÓ_*êæ?<Íåãwñq>3½õ׫ü?wÿ÷Ú­ç<¿.›mþ“â§=ßoÿ|þòŸÿ ý_¿þO‰þ%Õÿ5õ)þÚð¥óOþ/êÁÿ¶óX–Öí¿Øÿ°ÿaÿ³kÿ“ê-êÿèçÿ…ÿÑÿÉÿ‹ýüÁÿõŸ¬Õ‚þØÿÈÿk7ÿ/ùÿ,çÿ#ÿo=þ-ÖÿÿÖÍÜŸü¿äÿmyþ!þþ—à£ÿ£ÿãÿÇÿÿù_&ÿÛù{ÿÆþý­ÜÿAÿƒÿ¡¿Mú“ÿü=ÒŸü—ßYÿRû·4ÿŸvþ—þ¹ü{Rû¿vþ?òÛÎÿÃþOþGò¿ÙÍÿ†þ‡üãücÿ^ó÷’ÿÜzýŸÜùO*ÿzÕÿÉÿOþòÿ“ÿÿ×÷ÿ^íßÊÿŸÃ?·þ¤öööìÿØÿ±ÿcÿ×ѯõü:x{û϶~¤mŸ»×­ÿ¥úKá§ö¿°øƒ?øÿý…ñÓn_Ü—ÿ±ü”âïå÷ã•‚ŸÃ?×ßË߯¿ã_ÿyOç?rð×ú?ô‡þ}È¿õYòøóÙWÙ󮎿Tþ·›ÿò߯×ÿûžü»¿[ÿév÷þxµäÿü>¹þév?~øþ·ÌÿàoýüSãÿYû¯¯òþÎþû4á×ÐÿwúKíiÿƒÿ>7ÿúú¿Ìÿ#Í«íÿYó_(;÷䯴}ÿ³ÿÔà¿~—­ÿôsëàï÷Oý^²ÿ†~­ÇsõwEù¿ö_Éöß:ù»öKëßX·ÿiÓ¿fþËûçæ_{ýië¿è¶õ?ìÿø$ô—â_F¿³ðÛÑüÁÿ×ñ÷9 §¹ìsø*õ¯ìùgÜk/e/ÿszüÇýãöøï¾Gþ¯4üæº~N\ªÌu _êÿjEÿÚõ¿}ÕÍéx÷~ßnýÕÑ_‡ÿeú¿TÿÕÏi]þëÖÓ—ÿ²úoéúïy)©?xÍü¯-ùù‡üCÿïÿvúç9ýÿWð—Òýýþ‡ÿ¿Íÿàýûö?ö›û?üÿÃÿ6ùßzü#ý¹ÿÏýÿúøIyü±vü'ñ_Ð_þ5ï¿´¼ÿÓÏý?›÷ÿýü;]øøü¶·Œÿ/¿ÿï?×Ù/×í¶ãÿ[ÞÛ¿gÖóýîÿqÿŸóç_«÷?¹ÿCþî_³ÿqÿùýûô·dÿCÿƒÿ¡¿eýŸü¶í²ú_rûç×Küû©ÿ$õÿÔøÿzÊÿTŽŸo™ÿGÃþ/õŸµÔ?uüøÿÙÿ-Ç‘ÿÿ?úŸUýÿ7ùÿ‰ÿ³ëÿª;ÿ¹wyü“~ýòÿ“ÿŸø?üÿäÿ×±ÿõ“ÿ_ºÿHý?Äÿÿ¯™ÿ_ªÿÕÄÿ÷”ÿû?õ?­ùÿß#zÓc¿_ºÝ½»¿ü·éöÜóãþRø¹çŸøƒÿïâÿÎEæ?9þ¾¤øo_!¼þ¹þù×1¾çáŸ}>ô‡þ:ô×Îxuü¥ë¿§üoûùÓâüUa®+)þšùßàøß:ÿ[Æßºþïì•·[h¿Üƒïì[.þË=?ì?1þ®=Ÿû}[ø[üCøœÿÖôÿ÷ÛqëßìíWáïÆAJmý¿ÿÜúÛ›—õxÂïÃùÔ\ÿÚõoô÷þÒõõú?ìÿÈéþ¿~^ù»•ÿi¹ÌùýßöþýmÓû?þŸ¬þC;íøÿÿ:ÿO\¿¤þþeü=×ÿè³´þ‹Tþ_ÓÿwŽ>yÿßÙù?×?7~Íõ§-ßëìÿþþw¬ßïõ?¶ÿëÁÇþSsþ Ï3Òù×俺ó_¸þJæïøüw5þkçÿÃÿ‰ÿýÿjñ/åùSËâôôíñkÏ?ñÄÿÁÿÄÿY•Öí»Øÿ°ÿaÿ³kÿ“ê-âÿ5ý¿ð?ú?ú¿ÞýŸ«ßð¿:þšû¿¶ü—îÿiø!Ìüù úC-úËò­ïŸ„í¥ù¥ú¹ÿR“ÿª¥ü—¯ÍëÿOóöó4oÛ×ï²û_kþIÃËãŸëüòø®ý÷{üŸZî9ëøï4ÿÖÿµ×¿6ÿÿŽü«[ÿžþíæ?5¿GòòüCÿ×ö?ÓÿºþôÿëŸÿZÕOûDýµoòõýO›~Ö×ßuä;ÿ¿¶ÿùýµá£ÿ¡ÿaÿ‡þô§þ%õ©ÿjwýSÿ‡ú?Ôÿ±[ÿ‡ýßöþ/ÍÚ²þ¯¶ü·^ÿýùgïüÃù¯Uýëý¿§õ/­¿+¥ÿuêÿ¦ÏÒý_Gÿgÿ×åÿß‘Òý_ãüo]þqþÓ¶ÿÇ?×Éßvñÿgö©ý‡ýŸýû?öìÿØÿ±€?øƒÿçõÙý§–ò_gÿ·-ÿ¡?û+ûO½}é7ð¿¦ýýþ‡ÿ±ƒ?ñߥöÇe í¥ý÷ü_šðkèÿ;ý‰ÿÃÿŸõ7mßÿ¬Ã?øÿkéÕš~­ÇsõwEùïëI÷ß:ùë÷ÿðü–:ÿœmûŸ6ýk濼þþ±îúÓÖÑÿ¬Ç`ÿÇþ‡ÿüÁߺÿ_êÿ©9_ö$ÿmÆÿâÿãþ?÷_¹ÿÁùûÿÜÿGþ¡ÿ[ÅŸøâÿÐÿ‰ÿƒÿ‰ÿ#þûö?ììÿvîÁÿð?üo‹ÿß#zÓc¿í´oÛÝ»ûË›nÏ=?î/…Ÿ{þÙñý6þïZ$aý“3Ÿ¥ëKú|éøÏÃç/÷Ê=ú_‹þmákÊwiü·4þÙýþv ûïßµ;ø®=×ßµoñ—Å¿JåõÏ×õéßõë÷ëÃûoWç¾ÅükÖßsøŽCˆÿ¦Ö_®ÿº=æýõ/‹ÿÆ?hïRüÝóÃùwó\:ÿÓÜvþëòŸZ”èÿœo­·Ÿ×_×t}åÎKçÏ_Çã=>ûÝóŸvýaýóuý_—~Ö×ß5å?ö?ìØÿ~Áþ‡þÿC»ô×¶?j÷®ÿÕÍÿ8´²^sý·Ãßý¾-ü-þ!ü罕ÿGêÿÓÖ¿JðÏÙÿ½iB?OÞÿÓƒý_â?kqþ×ôÿY×ÿÙÿmûJüß±¿:–gÒù×ä?ëþô?ÛúþoÛøÿgÛÿUwþ›æpÿ—Ä?ùW¹þŸ_ŽûÇíë¿ëöÿqhuþëáü¯Éÿ׌¶ÿ‡ÿÿWÚµíÚç¯:ûÓ4·òÿÿOü¿vü¿Dÿkÿ¯éÿÅþ_Ã?k][ÿø}ý?¿eÿ¿Ë#¿ÿíüÛû]®î{àøß‡Ÿ¶?ŒÃž|‰íŸ†ŸÃ¿ìü½oÿІý¡¿&ýÓù§ãüÕþïºü×ûù§¯ŽÿÕç?}þˆÏoÞ~Ÿ?¤øçàçð/;îŸàøß2ÿ[ÇŸóG¾õwëç?·¿çÚ¥óÜ«þ_ŠŸöüIß÷寗³q{(eýûÝÿeã¿Êü³ÿ#ÿ{”ÿß’¿ØÿØÿ-ïÿÐúcÿ·.ÿíÞÿšÿ€ÿYøÚñqÜ\›ûÛø¿t\žÃí·Ç:fìÈÿUÿw _â“ú¿ôïÿ¤æ¿<þÒGÿß·sÿ§lÿ õ×e‘¯sχ¶ð—¥ÕùßÂþ³YÿÙÏá»”þšò¿ßÜúÛ›—Òùìqýk·kóßÕçùüÏÝÿmWÿãš÷Ÿéþoþü³þ»NÿÏ?ëÏ_iý?5þ#ý»oïÝoªÓÿõø_›ÿëÏßmæ_÷üoYþ‘ÿûö?ì–óÿHô¿÷/4õ/øýý_[ÿ>ðEùÿ øŸ”ÿ=À‡þпùãÆùï³³Ÿ|³=ÿ»}¶í!þíú‡ã{Ïß:¿^züŸšÿóðû»vÿ­›ÿÿr€U¾Kç?ý\ÿÊáŸë_ö}Ì¿^ΕŽ¯ÜÊÏ^׿6ÿ_Oþ]}þ­Ê?Îzþ¿üßÖñGÿ·®ÿ/K(?ýúYç÷®—¿ëþï»ØÇûç·ùßúþ׆þRù×nýÅýËð·+ÿõüÿÚþ_ä?ô—ä/£¿~\ýýû?ô×¢¿ù§®‘ÿJ;ÿæçà[Ÿë_j?~¼dïÚùŸ¥øIíÿÒùk9ÿ5ö‡–ùÇSð·¯xüŸµÿzý!ÿØúÌÿ^~I÷mùŸÂ¿~üß™?øù‡ü~ øÚïÚë?|/Ó??7ÿçá÷Oßòü×öü©­ÿÛÛÿûâÿëÉ¿«Ï¿EùÇù¯WûßwäoËýGjÿaÿgÿÇþýû?öêøÀ§þ;õ_ ?ô§þ7õ¿¿ëÿ/‹?•⯭Ãÿð¿eþ§þ/ç—ŸÕ÷Ï}>û~öyRøÒß»ÿîŸÿ\7ÿþù¹çµ÷§þ/õ_êÏ¿ÿ¯×Oè?X™ÿ!îŸçÿo­©ÿ¤ÍükÇìÓßÏѲÔïÿûò/=þrøéý?îŸÛÿ­ËÿúúÒý?W¿,·ŸºþŸÕúÏÚôÞËÖÿ§ë_Ö­¿òú‡Úú/úŸmýû?òŸú‹À¾ÝúŸÔÿ¡þõlÖÿ¡þ5ûO¾~ýñ»tþµùOŠŸöüÁÈ?äð¯XÿïêøÿBýEôêÂÿvùß2þìÿØÿ°ÿ±ÿ[Þÿáøþ·ÉÿÖãÁŸû/Üÿ_–ãøI÷]mü×þúï#þ“ø_Ûô_–¶ðcú/Kß?¿û/ýÝÿùVü3÷ÿë_ŽÃ¶}­Kãÿsõïr÷¤õï¬Çÿkß?ë÷þ¿¥ûÜÿçþ?çîÿsÿÇfþŸúûßeò×?ß}îeý“ÿ‡ûÿÈìØÿ°ÿY´ÿ¡ÿÁÿÐß.ýÉÿ‡ý£‡<$½Ù߬¼Ký?RÿŸ¶þ'­ÿ$½×Gý§e9öŸ¹öÚüßûò¯WÿŸýŸýŸø/òÿÙõÿ£ÿÙÖÿðÛ†OüŸmÿ—´~i›ógõÈÿOþòÿãÿÿuûo¯ö¿oåÿ—î?RÿñÿÄÿkê¿-ë××ì?ÚþWìÿÔÿ´ìÿ÷ó÷ž+7¾=úoóGПþô¿rÿu®Ÿ—&ÿ%Οò øŸ¿6|èý{ïQº¿Þý¿Ù~uü¯:ÿÒW+þÏ=ÿSã‡ÿáËüþ–õÿk矖Çþšù_õ÷_Ýü£=ñŸç±ütío;ìþqÿeéSþ¶ÃÿêóÏþüÿ¾ü×–¿ÖÏìÿÖ÷èo™þØÿ±ÿùûî~âÞýÏ:øq?+Ý_ -?ÿþø¿éŸ–_ïõ²ÞËŽ?ŸóϸõëÛýúLËO¯dýçú—Ê©ÿI*ÿõümè_+ÿ¶¯ÞvýäüÇãÝû}»õÓ?|þûï÷g}ù/ËÿP¦úçoéÿ]¿<þùïÖúúüËO¿~ëÎGô×–ÿyüsë/þóÏßò¿öú·îÃÿ‰þl½ÿ±~žÓ¿¤ú/ç)þÒó»ùOÏ/ñÄÿÁÿÄÿ§ÏoË?ëö_ìØÿ°ÿYµÿµÓÿ¤÷O´ý¿vùýŸû?ô§?ý¹ÿOü÷ÿ¡¿¥øoÝû'ýø¿lÚÿþ£[ô~tV×*þXGÿ'þŸûÜÿãþþâÿ­úÐÿñÿãÿÇÿÿß²ÿßû/Ïʯ2ÿ¯¶ÿß®ýÏ:ýñÿ£ÿaÿ‡þöè¯]F¾…uÁÒð¯¿õù·½þ¥öç5üð=~¥¿Ïɯý>mÿßÇ£ý;o{ó—›gùüר¤üwæùŸ¿öúCþ±ÿkö—úŸåûO?ò_£þü‡üCþÑ¿‡õ¯¡ö´þ¥/)ý4^-ÏÒý_Gÿgÿ×åÿß‘WŸ‹òóŸ¶ýOWþ¶Ü¤öööìÿØÿ±ÿcÿÇþ|àÿ›û¿ŽÿG[ÿGÿƒþØÿìÚÿmÛÿôÏÿíÎ_ŸÈ?ÿÃÿ¿mÿÎËöwß½áÄí!ü½ñõ_–ãþRøqÿÇë¸ÿ>þë9ªŸÿ|÷ùŒ}úKáÇýkôïwÿqض‡ú ý÷ç¿_ý_:þïÌ_›þ~½”}>û^ö<õ/ÃëñjI?½÷#ú¬¿«ÝÿËäŸþ~ÿÜþo]þï×ÿ‡mûyùµ¿ÿçêŸåöÿ\ÿœüÅþ×7ýsë¿Mý»ei»þÆáxþ–eúÐÑÿlëØÿ±ÿøÀÇÿo3þ×züþ?ömûcý­Çqþ³cÿ‡ÿ˜ôoëð‰ÿ!þýŸø?øŸø?âÿ°ÿaÿÃþÇþÏýøþ‡ÿ“ÿ]¼ÓíÆ?¹ú,ïŒî»çÝáçì—ïöç=ìÿÆsÝßµ»ú$îùî÷máÇý}»ËÏàÆþ)øñø}¯:üß3ükÅÕ-vŸŸ÷°’ûþnZ¬ÿõóRðsë;®xü¾}ý] -ŸÔïró¿7/¥ð¡¿6ý—¥-üŽ~j>5å¿4þ[ÿ¼‡ØïÏãp®ÿ–¿Æ¡Mü«”ÿz¨ÿîëÓùõïêßöÝ}¿†wLŸ­~µž§·§àÇõïRøçú¯Ûãú[{üâw¼þRûÇÑó¶ÏïqýKïÏ”õ×Þÿ>5þ«Ì¿uù‡þÏù×:þ¹óÏÑy©ÍùC÷üeùü—ÓÿKô¯¼üõÏë?÷qþ±­ÿKè/•¹û¿uë¯üþ/òûö?ìVíèð?ô·Mÿ#ûlý±Üþ«mÿDÿ“Ù/?Õ®mÓÆÿ[íRÿO ÿŸ¦þ—ö?Ãÿœý?ïÿÙïÁþD?G~þ×ôoqþïÑÿgIÿgÿ'þ댿:~—Ò¿Çó¿ÿ?úŸmýùg>ñ¶ý_%矸ý|ü_îü™‚ÿ~•ø?sýóúÿ8HôÉù¯‡óü¯ïÿ·ÿ‡ÿߪý·WûŸìüu|^MísµûÔÿCü?ñÿÚú¯Dÿk±jú_±ÿçåßúï:ûnÿ™æi^–ç}ÆaYž÷q˜æižæi~ÞŸ÷Çkš¯ÇëyÞÇaY¯i‡eùû»Ý¦yš§yš§yYž÷q‡eyÞÇaš§yš§ùyÞ§yš§yYž÷qxÞŸ÷iÎëÿVüÿ®^ÈíÖqõ‰Þÿüçðwï|Gß»þá÷ûÏk?îÿ÷—øƒ¿mü¥ç)þ¹óOÿOßÿ©ƒ_~þƒþÐ_“þÚõ¯Ž¿tý÷^ÿ1wþ–â¯]ÿþ‡ÿ-ó¿uü9ÿlð/ø|öýìó¤ð¥¿çüWj–Ò¿WýÊÖ“Ôÿ¡½þsò¿®þpyýçÞ÷ÿþÒõ¯]ÿ™ýùߣü—Éßv÷ÿ¬ÚÿØÿmìÿÐúcÿGþŸ£¿_¿1~{ýã-øä´ÿ›¾ÿíãßþ—RÿQ:ÿßùû×áú/É_µwÿºÿ\ü»äþw÷êé/•?uó¿Žžæòñ»ø¿8Ÿ™ÞúëUþŸ»¿ÿ{íÖó?ž‹_—Í¿6ÿIñÓž¿ï·>ÿùOȆþ¯_ÿ§Dÿ’êÿšúmøÒù'ÿõ¿àÛù?,Ë?ëö_ìØÿ°ÿÙµÿIõ¿õôóÿÂÿèÿäÿÅþþàÿ‡úOÖê?Aìäÿµ›ÿ—ü–óÿ‘ÿ·ÿëÿˆëæ?îOþ_òÿ¶<ÿÿKðÑÿÑÿñÿãÿÇÿü/“ÿíü¿½ÆcÿƒþVîÿ ÿÁÿÐß&ýÉÿGþÇéOþË﬩ý[šÿO;ÿKÿ\þ=©ý_;ÿù¿mçÿaÿ'ÿ#ùßìæCÿCþqþ±‹¯ù¿{Én½þOîü'•½êÿäÿ'ÿ?ùÿÉÿÿëû¯ö¿oåÿÏáŸ[Rûû?û?öìÿØÿ±ÿëè¿×z~¼½ýg[?Ò¿¶ÏÝë¿ÖÿRý¥ðSû_ØüÁüÿþÂøi·/îËÿX~Jñ÷òûñJÁÏáŸëïå¿oãßñ¯ƒÿ¼§ó9økýúCÿ>äßú,yüùì«ìyWÇ_*ÿÛÍùï×ëÿ}OþÝß­ÿt»{¼Zò -~Ÿ\ÿt»?üÿ[æð·~þ©ñÿ¬ýWWygŽý?šðkèÿ;ý¥ö¿´ÿÁŸ›}ý_æÿ‘æ¿Õöÿ¬ù/”{òWÚ¾ÿY‡jð_¿ËÖú¹uð÷û§~/Ùÿ?C¿Öã¹Æú»¢ü_û¯dûoü]û¥õo¬Ûÿ´é_3ÿåýsó¯½þ´õ_ô?Ûúöü?úKñ/£ßYøíèþàÿëøûÐÓ\ö9|•úWöü3îµÎ—²—ÿ9=þãþq{üwß#ÿW~s]?'®?Uæ¿:†/õµ¢íúß¾êæ¿t¼{¿o·þêè¯Ãÿ2ý_ªÿêç¿´.ÿuë¿éËYý·tý÷¼”Ô¼fþ×–üüCþ¡ÿ÷€;ýóœþÿ+øKéþþÿÃÿßæðÇþ‡ýûû¿Íýþ‡ÿá›üo=þ‘þÜÿçþ}ü¤<þX;þ“ø/è¯ÿš÷_ZÞÿéçþŸÍûÿ~þ.||þÛ[Æÿ—ßÿ÷Ÿëì—ëvÛñÿ-ï¿íß3ëùþ?÷ÿ¸ÿÏù‡ó¯ÕûŸÜÿ!ÿ÷¯Ùÿ¸ÿüÇþƒýú[²ÿ¡ÿÁÿÐß²þOþ?ÛöYý/¹ýóŠë¿%þýÔ’újü=å*ÇÏ¿·Ìÿ£aÿ—úÏZêŸ:þ?üÿìÿ–ã¿Èÿ‡ÿýϪþ‡ÿ›üÿÄÿÙõÕÿÜ»<þI¿þùÿÉÿOüþòÿëØÿúÉÿ/ݤþâÿ‰ÿ×Ìÿ/Õÿjâÿ{ÊÿýŸúŸÖüÿï¹Qûñ;þ vÚ»]úú4üO_>ô‡þZô/Ó_rñ“õý¯ŽÿÕç¿,Õ~þ´øçàzüð?üo™ÿ-ão]ÿwöªÛ-´_íõwí.þ˵çú»öÞàCÿ°n{ßÛ«R¿“οæþ[‚nýíÍK -Nê{ÍõŸ®?3{ò³®þÍ~ýýý_†ÿÕçŸýù¯)ÿµå¯õóû¿íýúÛ¦?öü?ïXŒ0þÁÅ'¤Û[??î/…Ÿ{>ø£ÿÒ×ÿÙ¯Ÿ×/ })’ø§´DôõQJÖ®ÿÑKê’Êþ>üõô—Ê?íúOéõ"]Ïû¹çëɯêûðëôOÿüx|iýW -‹?öÿ£óÿ²„ç—ýõZwþÛ§¿¶ü/Á?·þòç?ÿüÔ|j®ëþ7üŸèÇÖõÍúÇÚúÿú¯~ýWâÿlÇÿYçëñvåŸuû/ö?ìØÿìÚÿ¤úS‹ýSSÿ‚ÿÑÿÑÿ¯{ÿ„þô§¿žüÿüO_>ô‡þzô÷÷OÂü^{ù•Âü_ëû'ÇýÓù£zºÿ²Ÿª¬]J?)üºöÿè½ï½¶¿“Îî•ÃOöòø¬ý÷{üŸZ¹þëö-ÿk¯mþÿùwõù·)ÿÐÿ5ý=ø¿­ãþoûü'Éÿz&¿j.?«ÿ[ßÿÚÐ_*ÿÚ­¿vùmÈ=ÿ¿¶ÿùýsøŸ‡Ó?ž?ïÿGÿCÿÃþýµèŸ®?ׯò×Õ¿ÌÕÓ„_R¿"W?òÊý­Ï¿íõ/µ?—Õÿy¼jëgåëWÖþ¿Gû¾®Ï1ü–ó_c?òß™çbüÚëùÇþ¯Ù_ê–ï?ýÈÿþ¹õ×RþÃÈ?äýµÖ¿†þÙÓú—¾¤ôÓxµ<ÿI÷ýŸý_—ÿGþ]}þ-Ê?ÎÚö?]ùÛrÿ‘ÚØÿÙÿ±ÿcÿÇþýûðüoîÿ:þmýýúcÿ³kÿ·mÿÓ?ÿ·;}"ÿüÿÿ¶ýü9,KØß}÷†·‡ð÷ÆÔYŽûKáÇý¯ãþûø¯ç¨~þýóÝçwN×=úKáÇýkôïwÿqض‡ú ý÷ç¿_ý_:þïÌ_›þ~½”}>û^ö<õ/ÃëñjI?½÷#ú¬¿«ÝÿËäŸþ~ÿÜþo]þ»ûž~X(¿–E&¿ö÷ÿ´üôðsû®Nþbÿë›þ¹õŸžÿÔý÷£ýYÚ®¿q8ž¿w=Àô_ô?ÛúöìÀ>ðñÿÛŒÿµÿ‡ÿý_ÛþØcëñ_œÿìØÿá?æýÛ:|âˆÿCÿ'þþ'þø?ìØÿ°ÿ±ÿsÿþ‡ÿáÿßäït»…ñO®>Ë;cûîywø9ûå»ýyû¿ñ\÷wí®>‰{¾û}[øqßîò3¸ñ -~<~ß«à÷ ÿßZqu‹Ýçç=¬‡ä>‡¿‡ëý¼üÜúߎ+¿o_—Â'õ»ÜüïÍK)|è¯Mÿei ?†ãŸŸšOMù/ÿ–Æ?ïá¶Çûó8œë¿å¯qhÿ*å¿ê¿ûút~ý»úwã°mw߯áÓg«_­çßéí)øqý»þ¹þëö¸þÖÿ‡ø¯¿Ôþqô¼íó{\ÿÒû3eýµ÷¿Oÿ*óo]þ¡ÿsþµŽîüst^jsþÐ=Y>ÿåôÿý+/ýóãúÏ}œlëÿúKå_îþoÝú+¿ÿ‹üÇþƒýûŸUûúüýmÓÿÈ>[g,·ÿjÛ?ÑÿdöËOµkÛß´ñÿV»ÔÿÓÂÿ§©ÿ¥ýOã°Æ?gÿÏûöß{°ÿÑßÏ‘Ÿÿ5ý[œÿ{ôÿYÒÿÙÿ‰ÿ:㯎ߥôïñüoÅÿþg[ÿCþÙ†OüŸmÿWÉù'n?ÿ—;¦à¿_%þÏ\ÿ¼þ?ýFrþëáüß#ÿëûÿ-Åÿáÿ·jÿíÕþ';ŸWSû\íþ#õÿÿOü¿¶þ+ÑÿZ쟚þWìÿyù·þ»ÎþŸÛ¦yš—åy‡qX–ç}¦yš§yšŸ÷çýñšæÇëñzÞŸ÷qX–ÇkšÇaYþþn·ižæižæi^–ç}ÆaYž÷q˜æižæi~ÞŸ÷ižæi^–ç}ž÷ç}šóú¿ÿ?ÿøÇ?»ÿbùˇ\û§ázüÚð¡?ô×ü·Î¬”ú>þ{›¿PÖÿêø_}þ×ù½ÖësÏþÛ¤ÿrð?=~øþ·ÌÿÖñ·þÏå ŒßKŸû>nï ¾õRû“tþµ÷ßþ¹õ'µ¿i¯íü£úû¿ ÿ«Ï?û?ò_SþkË_ëç?öÛû?ô·MìÿøÖñ…q|bºýìüæž÷—ÂÏ=ÿìø~Ú­¶»Ø¨ió=íÝÿŽã§Êü/>~3Îÿ—Î2³ÿ3…_®ÿÑËÇyœâ˜·œÿHò’ú¯Zô—Ð_*ÿÒó¿ÿ›ÿqÿ¸=ÿQ¾³ºõ÷¼Ÿ{¾žü·~ÿÁºü×Îÿ§-ÿÉÿ¡ÜÃú·|ÿýý?Ö¯Žî_ÖéŸÇú¿¦þ#Å¿…þ»?éü§î¿éÿÇ矜þ,?ÖŸ¿ZŒ?÷Êá'}ÁÿÚüÿ¹øÑOÃoÓß®ü³nÿÅþ‡ýûŸ]ûŸTj±jê_ð?ú?ú¿¶þIúÓÿŠòÿð?=~møÐúëÑßç‡rgÁŸ]ÿõóÃö·}ek¼Âvíüw1~ñøÊÛ¥ô“¯kÿnÑûÞkû;éüç^9üd/Ýüc}ÔÕäÿß‘WŸ›òý_Óÿ׃ÿÛ:þèÿ¶Ïn}yùè×Oºý¬|Í=_›ÿ­ïmè/•íÖ_z}åð·+ÿõüÿÚþ_ä?ôÏá~Lÿxþ¼ÿýýû?ô×¢¿~þ©k翺~ëóo{ýKíÏkøá{üJ¯ÿ9‡ÿ>mìÿÛyÛ›¿Ü<Ëç¿Æ~Ð2ÿxîùŸ¿öúCþ±ÿëæÿ—ùŸåûO?ò?…nýµ”ÿðòùG­õ¯¡ö´þ¥/)ý4^-ÏÒý_Gÿgÿ×åÿß‘WŸ‹òóŸ¶ýOWþ¶Ü¤öööìÿØÿ±ÿcÿ§þÿøÇ?ê¿SÿúCêSÿû3ö™þ*ý§­Ãÿð¿eþ§þ¯í·›¯ÿãí‡î¿ûç?×ÕŸôÏÏ=¯ ü¸ÿ~ýËøùeŸÏþ;û<)üòßSÿÕvýWw·0ô¸ïœütíµþÿ|÷¹—õ/õ¿´™íø'O_7{ô¯Û?÷é™Þ¿Ëá—õÏíÿÖå}ý?éþŸ«–Ûÿ?]ÿï×ÏÚôÏå¯Ï­çO׿¬[åõµõ_ô?Ûúöü?ÔG¤v»õ?©ÿCýêÿجÿCýkÛò?®[Ÿ®_ÿ¼Õ¹—ο&ÿ•àŸ[{ó’‚“úþCþ!ÿh·XÿïêøÿBýEôêÂÿvùß2þìÿØÿ°ÿ±ÿ[Þÿáøþ·ÉÿÖãÁŸÜÿ÷ñéøÉ¸ýlüÒþzÖŽÿ$þ úá_ÿìóµï¿èÝÿÑŽæþ¿§ÿ:þ}¯þ\œÿ_ÿŸ«_—»ÿ#­g=þ_ûþ™þýîÿqÿßú?ÎÿVñçþù$÷¿ËäoÜ¿§ûÿäÿáþ¿uùýûö?‹ö?ô?øúÛ¥?ùÿlëÚùGúXÿzøk×ú¤þ?mýOZÿIzÿN¿þÓ4¯é›öŸ…íçóïË3mÿŸuýŸýßö?òÿÙöÿ£ÿÙÖÿøgûñ¶ý_¹óO¬?×Åÿ?uëÿÿŸüÿÄÿáÿ·jÿÕ¶ÿiçÿ—î?RÿñÿÄÿkê¿RýOºÿhû_±ÿSÿÓ²ÿ_*ÿýüÉÿü÷ü{ù—æ?)ü”ü_Ã_çð·¿ûïó»ï\þ×þ†ÿï{—ϸþïì,ûðsøçú¯Û·ù‹òøŸ‡ÿž—íü9øoîoèý{ÇË÷_LJøöiÛ§yÛþx¥û?^áó©üo7ÿ˲ßî¿uóïÿOóöó4oÛ×ïíø~ÿ\ÿx¼Ûïáøß.ÿƒ?矽þã°máïÙÏŽú/Ëq)ü¸ÿ4÷çü··ÿö=ÔÿåôïYÿ/Yéýÿhþ–åxþtÖZ~.˱üMÉï¸=÷üž÷ÿrü¥ò¯Ýü/K;ú°ÿ#ÿõäüÇ?ÍGãÇþÇþoyÿ‡þÐû?ö¿røkþæòþ{úð¯ÿÿ/êÿåþŸœæèü¶µÿŸ—¿áú/ß¿Òò÷<~iÿ“Tþ_Çÿ—žŸZù#]_çÆ¿ÿ{­õ׳ü/³_ýnì?%çÙü÷"ÿËÏåãÿÆü}¿ÿ÷üø?ñ¢ÿ÷ÿ"iOÅÿô¡ÿHñÓ†/=ÿGüüOüŸ5ùgÝþ‹ýûö?»ö¿Vú_mü/þ_øýÿ?öðü?Äÿ ý±ÿéÞÿÑ¿ÿdýþêsøÞ*þ»GýŸûÜÿãþ÷ÿ8ÿÿþëþôôüÿøÿñÿ#ÿåÿúüòyøšñߨÿ ¿ÿ?úüýmÑ?WÿëvÛ¶‡õ'öêWõ_–ãþRøqÿÇ븿^ý³Üøëà§ê_íÕÿê›þÖñÿôú—Ú¿¯’÷eÙûœ“9úÚþ‘¿—ÚÿÏÎWÝ|ï¿KíRù—³„8¥ÆÿYûÝú+×ìÿšô—Þ–Ò¿'ùŸêŸ[-åëýùgùüc ÿvúg>«½þÓã;Ö?[Ò_ -¿ê÷¥þ¿òóŸtÿïQÿ·´ÿ÷ÈÿW’Òý_ãüo]þqþëÛþW'ÛÅ?ŸÙ¤öööìÿØÿ±ÿcÿÇþþàþÚþŸ\üQKùߣÿç×å?ôgÿoeÿÙ?g–=ïêøÿ¦ýýþ‡ÿ-Ø¿±ÿsþ)³?Æþ«ßퟞÿuÿÇ«¼ÿýõàÿ‡ÿÿ´ÿûCŸµùÿéþ›nÿÌü?^mÛ÷ü?_?LºÿÖÉßòþÒúgÖíÚôÏ­ÿOçßøôúÓÖÑÿˆÿÀþýûøƒ?ñ¿ÿOý¿ÿø?ëñ¿øÿ¸ÿÏýWîÿsþãþ?÷ÿ‘èÿ¶îÿÿCüú?ñð?ñÄÿaÿÃþ‡ýýÿã?àøþ·ÅÿßÛ-Äßïßøß´òñÞ~éÚsý]û›ï|;ð¯BøÏ{ØßÁ)…?máÇýŸ÷þû[ðÿûsõNÆ!¬âꓼ_þsüûë/?·þKÆ¿ï>eðÃù÷Ïñõ_<ì<|è5ú·…¯)ÿ??Ÿë¿‡ÿ·Ú¥ñ¯Rùß{ý¯\ýúó¯YoÿÏà—ë/}¾æúÏÅHã´÷?)þéñùùŸæ¶ó_—ÿÔ¢üCÿçükþyý?<çH×ÿúymÎ_ñøŸ÷ô¹ŒóŸvýáÞÏ?ô ýuæÿwÖß5å?ö?ìØÿ~Áþ‡þÿCÛô×´?öÚnÝþp‡¯RÿÊžƽÖùRöò?§ÇÜ?nÿÎá{äÿJÃa®ëçÄõ§ÊüWÇð¥þ¯Vô¯]ÿÛWÝü—Žwï÷íÖ_ýuø_¦ÿKõ_ýü—Öå¿ný7}ù/«ÿ–®?ðž—’úƒ×ÌÿÚ’ÿ‘È?ôÿðo§žÓÿ)ýÑÿÑÿáøÿÛüþØÿ°ÿaÿcÿ·¹ÿÃÿð?üo“ÿ­Ç?ÒŸûÿÜÿ¯Ÿ”ÇkÇÿýõà_óþKËû?ýÜÿ³yÿßϿӅÏa{ËøÿòûÿþsýrÝn;þ¿åý·ý{f=ßÿçþ÷ÿ9ÿpþµzÿ“û?äÿáþ5û÷ÿ‘ÿذÿAKö?ô?øú[ÖÿÉÿgÛ~ «ÿ%·^qý·Ä¿ŸúORÿOÿ¯§üOåøù÷–ù4ìÿRÿYKýSÇÿ‡ÿŸýßrüùÿðÿ£ÿYÕÿð“ÿŸø?»þ¯ºóŸ{—Ç?é×ÿ!ÿ?ùÿ‰ÿÃÿOþû_?ùÿ¥ûÔÿCü?ñÿšùÿ¥ú_MüOùÿ±ÿSÿÓšÿÿ=¢7=Öø»ñ¥ÛÝ»ûË›nÏ=?î/…Ÿ{þÙñ?øÿ.þï\$aþ“ãÏáKŠÿöÂËáŸëŸã{þÙçCè¯Cíü‡WÇ_ºþ{Êÿ¶Ÿ?-Î_溒⯙ÿ þ‡ÿ­ó¿eü­ëÿÎ^y»…öË=øÎ¾åâ¿ÜóÃþããïÚãñ¹ß·…¿Å?„ÏùoMÿ¿‡°þÍÞ~þn¤ô×ÖÿKðÏ­¿½yY'ü>œOÍõ¯]ÿFÿ—á/]ÿW¯ÿÃþü—îÿë絑¿[ùŸ–ËœÿØÿmïÿÐß6ý±ÿãÿÉê?´ÓŽÿÿ'ñ¯óÿÄõKêï_ÖÉßsý>Kë¿Håÿ5ýçè“÷ÿÿsýsã×\Úò½ÎþïïÇúý^ÿcû¿|ì?5ç¿ð<#Mþ«;ÿ…ë¯dþŽÏWã¿vþ?üŸø?Ñÿ¯ÿRž?µ,þGOÿÑ¿öüÿGüüOüŸUùgݾ‹ýûö?»ö?©þ×"þ_Óÿ ÿ£ÿ£ÿëÝÿ¹úýðÿ«ã¯¹ÿkËéþŸ†ÂÌŸŸ ?ô×¢¿,ÿ×úþIØ^š_ªŸû/5ù¯ZÊ)üÚü·þÿ4o?Oó¶}ý.»ÿµæŸ4¼<þ¹þÇ/ïÚ¿Çÿ©õçž³ŽÿNóÿ8lù_{ýkóÿïÈ¿ºõïéßnþSó{$?,Ë?ômÿ3ý¯ëÿGÿ¿þù¯Uý´OÔ_û&ÿXßÿ´ég}ý]Gþ·óÿkû‘ÿÐ_>úúöè¯Aê_Rÿ‘ú¯v×?õ¨ÿCý»õØÿmïÿÒü§-ëÿjËëõÑÿöÎ?œÿZÕ¿®Ñÿ{ZÿÒú»Rú_§þoúü'Ýÿuôö]þÿù'Ýÿ5ÎÿÖåç?mûßqüsümÿfÿ‘ÚØÿÙÿ±ÿcÿÇþýûøƒ?ø^ÿ—Ýj)ÿuöÛòú³ÿ·²ÿÔÛ—~ÿkÚÿÑÿáøû7øÿ]j\–ÐþXÚÏÿ¥ ¿†þ¿ÓŸø?üÿYÿwÓöýÏ:üƒÿ¿–^­é×z<×XW”ÿ¾þ˜tÿ­“¿~ÿÏo¹ñ§óÏÙ¶ÿiÓ¿fþËûçïë®?mýýÏzüöìøÁü­ûÿ¥þŸšóeOòßfü/þ?îÿsÿ•ûœÿ¸ÿÏýäú¿Uü‰ÿ!þýŸø?øŸø?âÿ°ÿaÿÃþÇþoçþüÿÃÿ¶øÿ=¢7=Öø»ñÑNû¶Ý½»¿ü·éöÜóãþRø¹çŸßoãÿ®EÖ?9óYº¾¤Ï—Žÿ<üxþr¯Üó¡ÿµèß¾¦|—ÆKãŸÝïo·°ÿÞø]»ƒïÚsý]ûYü«Tþ÷Pÿ|]Ÿþ]¿~¿þ×8¼ÿvuî[Ì¿fý=‡ï8„øïñgjýåú¯Ûcþ×_ÿ²øiüƒöþ'Åß=?œ7Ï¥ó?Ímç¿.ÿ©Eù‡þÏùÖzûyý5|I×Wî¼tþüu<Þóç³ß=ÿi×Ö?ÿX×ÿuég}ý]SþcÿÃþ‡ýïìèð?ô·Kmû£6|ëú_ÝüC+ûç5×;üÝïÛÂßâÂÞ[ù¤þ?mý«ÿœýßû‘Æ!ôóäý?=Øÿ%þ³çMÿŸuýŸýß¶ÿ§Äÿû«cy&Mþ³îÿGÿ³­ÿáÿ¶?ñ¶ý_uç¿i÷Iü“•ëÿñùå¸ܾþ»nÿ‡Vç¿ÎÿšüÍøgëñøÿ¥]Ûþ§}þª³?Ms+ÿñÿÄÿkÇÿKô¿ñÿšþ_ìÿ5ü³Öµåñß×ÿÃñ[öÿ»<’ñûßο½ßåúç¾>ðÿ}øiûÃ8ìÉ—Øþðiø9üËÎßûömøÐúkÒ?:Î_íÿ®Ë½Ÿúêø_}þÓçøüæíñùCŠ~ÿ²óçþùþ‡ÿ-ó¿uü9¤á[·~þsû{®]:Ͻêÿ¥øiÏŸô}_þz9·‡òWÖ¿ßý_6þ«Ì?û?ò¿Gùÿ-ù‹ýýßòþý¡?öëòßîýð—ñÿ§ùøŸ…¯ÿÇ͵¹±ÿKÇå9ÜÞ1pëq¬cÆŽü_eñÇð%þ7©ÿKÿþOjþËã/}ôßÑø};÷Êö¿P]Ùù:÷üqh YZÿ-ì?›õŸý¾Ké¯)ÿKðÍ­¿½y)Ï׿v»6ÿ]}þÀÿÜýßvõ?®yÿù—îÿæÏ?ë¿ëôÿÜù³þü•ÖÿSã?Òÿ·ûöÞý¦:ýÿXÿ€ÿµù¿þüÝfþuÏÿ–åù?±ÿaÿÃþg9ÿDÿkqÿBSÿ‚ÿÑÿÑÿµõOàøW”ÿ߀ÿIùß|èý{?nœÿ>;ûÉ7ÛÃñ¿ÛÇaÛâß®8¾÷ü­óë¥Çÿ©ù?ÿ¸¿k÷ߺùÿ/Xå»tþÓÏõ¯þ¹þeßÇüëå\éø÷úÇí¡üìuýkóÿõäßÕçߪüãü¡çÿëÁÿmôëúÿ²„òÓ¯Ÿu~ïzù»îÿ¾‹}¼~›ÿ­ïmè/•íÖ_Ü¿ »ò_Ïÿ¯íÿEþCIþ÷2úûçÇõÐÿÐÿ°ÿC-ú÷›êù¯´óo~¾õù·±þ¥öãÇKö®ÿYŠŸÔþ/¿–ó_ch™<ûŠÇÿYûÿ§×òý§Ïüÿçå—tÿÑ–ÿ)üëÇÿùƒÿÈ?à·€¯ý®½þÃ÷2ýósóþqÿô÷-ÏmÏŸÚú¿½ý¿/þ¿žü»úü[”œÿzµÿ}Gþ¶Ü¤öööìÿØÿ±ÿcÿ§þð|ê¿SÿúCêSÿû»þÿ²øS)þÚú7üÿ[æêÿrþpùY}ÿÜç³ïgŸ'…/ý½ûïþùÏuó{^øqêÿRÿõ¨þüûÿzý„þƒe‘ùâþyþÿÖú—úOÚÌ¿vüÇ>ýý-Kýþ¿/ÿÒã/‡ŸÞÿãþ¹ýߺü¯¯ÿ'ÝÿsõËrûù§ëÿY­ÿ¬Mÿç½lýºþeÝú+¯¨­ÿ¢ÿÙÖÿ°ÿ#ÿ©¿|àÛ­ÿIýêÿPÿÇfýê_³ÿäë׿Kç_›ÿ¤øiÏü‡üCþÿŠõÿ®Žÿ/Ô_Dÿ§þ'üo—ÿ-ãÏþýûû¿åýþ‡ÿá›üo=þü¹ÿÂýÿe9ŽŸtßÕÆí¯ÿ>â?‰ÿµMÿei ?¦ÿ²„ðýóû¸ÿÒßýŸoÅ?sÿÿ¸þå8lÛ×ú·4þ?Wÿ.wÿGZÿÎzü¿öý³~ïÿ[ºÿÇýîÿsþçþ?÷læÿ©¿ÿ]&ýóÝç^Ö?ù¸ÿüÇþ‡ýûŸEûúüýíÒŸüØ?zÈCÒ›ýÍÊ»Ôÿ#õÿiëÒúOÒûw}ÔZ–cÿ™k¯Íÿ½/ÿzõÿYÑÿÙÿ‰ÿ"ÿŸ]ÿ?úŸmýÿ·møÄÿÙöIë—¶9öWÿ‡üÿäÿ'ÿ?þÿ_·ÿöjÿûVþéþ#õÿÿOü¿¦þÛ²~}Íþ£íÅþOýOËþ?ï¹rãÛ£ÿ6ýéOÿ+÷_çJñyiÒù_âü)߀ÿéñkÇþпùñ¥ûëÝÿ›íWÇÿªó/}µâÿÜó?5~øþ·ÌÿàoYÿ¿vþi9|诙ÿUÿÕÍ?Úÿ¹qËO×þ¶Ã®á÷_–>åo;ü¯>ÿìÿÈÿïËmùkýüÇþo}ÿ‡þ–éýûŸ¿ßéî'îÝÿ¬ƒ÷÷÷³Òý¥ðSñ_àÿ›þiùõ^/ë½ìøó9ÿŒ[¿¾Ý¯Ï´üôðJÖ®©ü—úŸ¤ò_Ïÿ׆þµòoû -ám×OÎÿw<޽߷[1ýÃç¿ÿ~Ö—ÿ²üeú§þ–þÇñßuðËã¿‘ÿn­¯Ï/±üôë·îüwDmùŸÇ?·þòç?ÿü-ÿk¯ëþ7üŸèÏÖûëç9ýKªÿ÷rþ—â/=ÿ·›ÿôüÿGüüOüßyúü¶ü³nÿÅþ‡ýûŸUû_;ýOzÿDÛÿk—ÿÑÿ¹ÿCúÓŸûÿÄqÿú[ŠÿÖ½Òÿ˦ýï?ºEïGgåðw­âuôâÿ¹ÿÇý?îÿáÿ'þߪÿýÿ?þüÿøÿ-ûÿ÷ýç±ÿò¬ü*óÿjûÿíÚÿ¬Óÿ?úöèoþÚõgôáûWX, ÿ÷ú[ŸÛë_j^ÃßãWúûœüÊÑïÓöÿ}<ÚØÿ·ó¶7¹y–Ïý@Êgžÿ‰ñk¯?äû¿f©ÿY¾ÿô#ÿ5êÁÈ?äý{XÿúgOë_ú’ÒOãÕòü'Ýÿuôö]þÿùwõù·(ÿ8ÿiÛÿtåoËýGjÿaÿgÿÇþýû?öì_À>ð¿¹ÿëø´õô?èýÏ®ýß¶ýOÿüßîüõ‰üð?üÿÛöðçü±,a÷ÝNÜÂßÿQÿe9î/…÷¼Žûï㿞£úù÷ÏwŸÿÁا¿~Ü¿Fÿ~÷‡m{¨ÿ—ÐþûÕÿ¥ãÿÎüµéï×KÙç³ïeÏÓXÿ2¼¯–ôÓ{?¢Ïú»Úý¿LþIáï÷ÏíÿÖåÿ~ý¿qضŸ—_ûû®þYnÿÏõÏÉ_ì}Ó?·þÛÔ¿[–¶ëoŽçoYÆ¡ýý϶þ‡ýûð|üÿ6ã­Çÿáÿcÿ×¶?öØßzüç?;öøùGÿ¶ŸøâÿÐÿ‰ÿƒÿ‰ÿ#þûö?ììÿÜÿ‡ÿáøÿ7ùßÅ;Ýnaü“«ÏòÎXà¾{Þ~Î~ùnÞÃþo<×ý]»«Oâžï~ß~Üß·»ü n|àŸ‚ß÷ªÃø=Ãÿ·V\Ýb÷ùyë!¹ÏáïÆ¡Åú_?/?·þ·ãŠÇïÛ×ߥðIý.7ÿ{óR -úkÓYÚÂáøç§æSSþKã¿¥ñÏ{ø‡íñþ<çúoùkÚÄ¿Jù¯‡úï¾>_ÿ®þÝ8lÛÝ÷kxÇôÙêWëùwz{ -~\ÿ.…®ÿº=®¿µÇÿ!~Çë/µ=oûü׿ôþLYíýïSã¿Êü[—èÿœ­ãŸ;ÿ—Úœ?tÏ_–Ï9ý¿DÿÊË_ÿü¸þsçÛú¿„þRù—»ÿ[·þÊïÿ"ÿ±ÿ`ÿÃþgÕþ‡þÿCÛô?²ÏÖÙËí¿ÚöOô?™ýòSíÚö7mü¿Õ.õÿ´ðÿiêiÿÓ8¬ñÏÙÿóþŸý÷ìÿGô÷säçMÿçÿý–ôöâ¿Îø«ãw)ý{<ÿ[ñÿ£ÿÙÖÿ¶áÿgÛÿUrþ‰ÛÏÇÿåΟ)øïW‰ÿ3×?¯ÿƒD¿‘œÿz8ÿ÷ÈÿúþKñøÿ­Ú{µÿÉÎ_ÇçÕÔ>W»ÿHý?Äÿÿ¯­ÿJô¿û§¦ÿû^þ­ÿ®³ÿçöŸižæeyÞÇa–åy‡ižæižæçýy¼¦ùñz¼ž÷ç}–åñšæqX–¿¿Ûmš§yš§yš—åy‡qX–ç}¦yš§yšŸ÷ç}š§yš—åy‡çýyŸæ¼þoÅÿïòÄï;ÿö~—ëŸûøÀþ÷áKåϧáçðÿ´ýõÓð¡?ôפ¿vþ¡«ãõù—Ú¤økçß‚ÿáËüoÎiøÖß­ŸÿJíÇÒyîUÿ/ÅO{þ¤ïÚõgúÝÿeã¿Êü³ÿ#ÿ{”ÿß’¿ØÿØÿ-ïÿÐúcÿ·.ÿÉÿÇýîßX½ÿ#¹ÿÝ"ÿ_Ÿ÷ÿ‰ÿåþ?÷ÿ¹ÿÏýîÿsÿŸûÿÜÿGÿ¶wÿßFþoîÿsÿ‡üÿäÿ'ÿ?÷ÿ¹ÿýûö?;õ?%ú_‹û}Þÿ·Äÿèÿ¶óÿøÀ·ëÿ¡þ õ ¿]û_õ¿¿›ÿÔ¶ýü¿ÖóÿöÇÿW‘¿‘ÿ×®üCÿ'þúÏèÿøÿñÿãÿÇÿoSþ[¯ÿnÝþgþ¶ïÿ ÿaÿ‡þäÿçüÌ¿­w©ýXšN;ÿJÿÚñ—Úÿµóÿ‘ÿÛvþö{ò?’ÿÍnþ7øùæüc~¯ù¿õóŸ[¯ÿSvþûÜùSWÿ'ÿ?ùÿÉÿOþÿ_ßÿ{µÿ}KþJ÷éù“ýŸýû?öìÿØÿuô_ÿJ}ÿ½­IúÓÿªý½ü|ËJ'Ÿöä,?? ÿÓã׆ý¡/òCûuuü¯8ÿëõû¾'ï¿-ioÉÿ¹çbüð?üo™ÿÁßúùÁßÿôö÷ëïÚkíÏþùîóûNÓžý[ -?î¿oÿvmîùïûðëæ?î¿Æ?Õ_ -?…ÿÞþ%³ÿÉýÚú¿®ýQÛÿ³æÿ5/øÏ×¶}ýþx÷O}Ö[ÿy¼R¸¤ñ¯Ÿÿ6ðû=7GŸ4½Ê÷Ï2ù'…/ý½]ù_ŸÿAºÿçò?äöyýëö?mú§æoŸþeóŸ¢ÿÑþ¿,m×_yþmýý϶þ‡ýÿxþèOú_¶¿ô%õ¿¬s5ûº8éüÏGãßë·ÇKñ“Âo忒ο”þŸZŸ¿öúÓåÿòOj·.ÿuë¿éóŸnýøù‡ü£ýµôÏ_ÁÿªóþoYÿ‡ÿ­ó?øcÿÃþ‡ýýßæþÿÃÿð¿Mþ·ÿþÜŸçþ¿ïLÇO†íçã—ö׿~ü'ñ_Ðÿ:ø1ýãù[ÇÿöpÿEóþO÷ÿ,ßÿ÷ôv~êÇ˯ÿ5øv÷þxµŒÿ÷ú½‡Ÿ»Ï“ëŸ??ØŽÿïãþ™öýgë÷ÿ¸ÿoûüÀùßîýOîÿÿ§Íýïúûå}Ø¿ìîÜÿ·-ÿ±ÿaÿÃþgÑþ‡þÿCËú?ùÿlÛ?´óÏõcÿÕË¿§]ÿ©ÿ§Æÿ×Gþ§iÞâWfo™ÿGÃþ¿¥oÊ·ŸÍÿ]¦ÿëøÿðÿ³ÿ[Žÿ"ÿþô?«úþoòÿÿg×ÿ•;ÿlõçšø¿²ü£:õÈÿOþòÿãÿ'ÿ¿Žý¯ŸüÿÒýGêÿ!þŸøÍüÿRý¯ÞþÜGþ»öêZõÿ¿Gô–kû©“Oév÷îþòߦÛsÏûKáçžv|àþ¿‹ÿ¿ß¾ÿ?ïeŸÃ—ÿí+„—Ã?×?ÿ:Æ÷<ü³Ï‡þÐ_‡þÒøoiüÃÕñ—®ÿ2ÿõÙù?ÿþήO—ßçÈ÷íq®+)þÛüY!üþ¹þGù·àøß:ÿ[Æßºþïì·[hÿ܃ïì[.þË=?ì?1þ®=Ÿû}[ø[üCøœÿÖôÿ÷[W·Æ}ÞÛ¯Â߃”þÚú þ¹õ·7/ëñ„߇ó©¹þ¥ñŸRÿ‡þþ/Ã_ºþsþϺù?ëÿdÿGþëÈÿøymäïVþ§å2ç?öÛû?ô·Mìÿø²úí´ãÿÿIüëü?^~ÕcùVþžëô¹ÿÜùW"ÿ¯éÿ;GŸ¼ÿïìüŸëŸ¿æúÓ–ïuöÿe õÏ|ÿcû¿|ì?5ç¿ð<#Mþ«;ÿ…ë¯dþŽÏWã¿vþ?üŸø?Ñÿ¯ÿûodú¿¦þ£=~íù'þø?øŸø?«òϺ}ûö?ìvíRý¯Eü¿¦ÿþGÿGÿ×»ÿsõû/àþWÇ_sÿ×–ÿÒý? ?„™??Aè¯EYþ·õý“ýüaGõ%ú¹ÿRSÿ¢¥ü—¯ÍçÿOóöó4oÛ×ï²û_kþIÃËãŸëüòø®ý÷{üŸZî9ëøï4ÿÖÿµ×¿6ÿÿŽü«[ÿ©üƒÒùOÍï‘ü°,ÿÐÿµýÏô¿®ÿýÿú翬üÿR»6ÿXßÿ´ég}ý]Gþ·óÿkû‘ÿÐ_>úúöè¯AêÿÚ®ÿ¤Oê_ë×ÿѬÿÕOýçþ¹ú‡-ë?µ«¿˜ª—uTÿ§Þþ!•úõ¿ŽõçºõW®ÿ ÿØÿ{©ÿXãnYÿO[þ[¬ÿ‡þ‡ü³}þáü§[ÿ»Ÿõo±þ5õÙÿuùÿwäŸtÿ×8ÿ[—œÿ´íÇñÏuò·]üÿ™ýGjÿaÿgÿÇþýû?öì_VìŸàþ}ìÿ:þmýýúcÿ³kÿ·mÿÓ?ÿß>sþª»ÿ ÿÃÿ–íÿàÏùgÿÛmÛþïoÿ·û§çÝÿñ*ï¿G=ø¹ýo¶í¡þŸZ¿·[éü÷®ÿ§ÇÿxŽçÏ×ïÉñ~YÿÇë¸ÿ‘üÿÞgmþ+oú½fýç÷¿røí~ŸÛÓퟙÿÇ«mûþï‘ÿ¥ò?–_õûoü-ïŸ?ö¿¾éŸ[ÿ¡ÿ.g¿ÜË¿¦·þ´õ_ô?ÛúöìØ?ÀüñÿÛŒÿµÿ‡ÿýYÚêŸuö/mû'ñ_œÿ,Ûÿ{ääòýŸøâÐÿÑÿáøŸø?âÿ°ÿaÿcÿgÿ‡ÿáøþ¯ç‡ïíâïÆ÷ÎXà¾{Þ]»³_ºö\×îò+¸và_þ8„ðŸ÷°¿ƒS -ÚÂûûv—ŸÃüß¿‡°þñóÖCqŸãß·X9ø¹õ_2þõxð)ƒοޝÿ¼®“ƒý¯Fÿ¶ð5åÿ§ãçsý÷ðÿV»4þU*ÿ{¨ÿ¾®OïÖ¯«5Ûöi×»tþà§ñ_÷Ÿæ\ÿu{\kÿÏà—ë/}¾æúÏÅHã´÷?)þéñùùŸæ¶ó÷Ÿæãþvåú?ç_ëðÏëÿá9Gºþ×ÏksþŠÇÿ¼§Ïeœÿêä¨Iî_ö~þ± ÿKè¯3ÿ¿³þ®)ÿ±ÿaÿÃþ÷ ö?ô?øúÛ¦¿¦ý±×vëö‡ãù‡VöÏk®ÿÏã/ƒ¿,¥ã“úZøÿ4õ¯üsöÿíþ5¥þŸìÿåþ³ç=¦‹óþ?Kú?û?ñ_šþëÏÿVüÿè¶õ?äŸmü‰ÿ³íÿª;ÿ½¿_¯wIü“ÓáËõÿÐÿ™ë¿nwŸsö¿ãýyZÿz8ÿ÷Èÿ}Ç?[ÿÃÿÿ+öß^íß:ÕÙŸ¦¹•ÿ‡øâÿµõ_‰þ×"þ_Óÿ‹ý¿Æþïéß"þqš§yš—åy‡qX–ç}Y¦yY¦yšŸ÷çýñZ–ÇkYž÷ç}–åñšæqX–¿¿Ûmš§yš§yš—åy‡qX–ç}Y¦yY¦yšŸ÷ç}š§yš—åy‡çýyŸæ¼þoÅÿÿþçó1”}>ûïìó¤ð¥¿ð·,_bùœnåG=þN>¹¿cø9|rýÓí~ü9üëàŸ}>ô‡þ:ôëúþ{ù‡¶ù3ýkûܽþýÈ?)þÒõŸž?éü§ò?…}|þ·µý̯Ï=ûCl?âïíW -~ÿ\oÿx¼Rã‡ÿáËüoëú¿Ëx»…ù÷à‡¿{ç<úÞõ¿ß^ø[üÓã‚þÒø)ýµõÿþ¹õ'µj¯íüçúû¿ éúׯÀþüדÿ9ÿGü-÷X?ÿ±ÿÛÞÿ¡¿múcÿÇÿ“¥?í´ïð¿tý—ñïYøíøÿ×ñã'}¼Ò^üW?Yç? -Çw”o¦dþrý>—àäÿzÞK^Çðóþ«}øRÿ—”þRùR7ÿçúçÆ¯¹þ´å»õûÖå¿vþ?mþ#ÿ‡îýçÖ¿åûßèÿèÿý½…þ¯©ÿh_{þëôgFºþýýi®9•ôÛãñŸ×?ž÷Vç?øÿŠüÇÊÖ¿öùß²ü³nßÅþ‡ýûŸ]ûŸTÿK¯¿ç=]ÿ|ÿùå¼þµ½ÿ¿÷‚ÿÑÿÑÿëõ_)ÿ_Sÿðÿü5÷mù/ÝÿÓðC˜ùóô‡þZô÷÷_Ü\<^¾ÿZ>úöiÛ§yÛþx¥û?^áóµóß寗jñk#ÿ¥ð÷ûÇíëþ>ÿךüçiÞ¶¯ß§9ÿíñ*Ë?œz…ðsøçú¿dùÓùÇÆ!ÍÿÛüƒ=ÕÕáÿß‘uëßÓ¿Ýü§æ÷H~X–èÿÚþgú_×ÿþýó_Vþ©]›¬ïÚô³¾þ®#ÿÛùÿµý¿Èè¯ ýýû?ô× ¿vþ¯«ç¿’æ?ÕÏÿ©Mëøë®©ý{ ?|Û–%õY;ÿsÿíøÃw©ý?ýÜýùÚŸç£þ{t‘Ûÿ¥ò/g¿H¯ŸxüŸ³ÿ×­¿rýùÇþ¯›ÿ¿¦þ¦÷?Kéß“üOáŸ[-å¿ÎúGÿCþY>ÿpþÛê—Rý³\ÿïiý—wÿ%¥¿~Íï[žÿ¤û¿ŽþÏþ¯Ëÿ¿#ÿ¤û¿Æùߺüãü§mÿ;Ž®“¿íâÿÏì?Rûû?û?öìÿØÿ±ÿSÿˆúïàþÔ§þ ô‡þÔÿ¦þ÷gì?²û¯RüµÏð?üo™ÿ©ÿk[ÿwöÂsõ'·õœOÍõ¯ÍÿÈ?äú¿ÝúWÇÿê£ÿSÿþ·Ëÿ–ñgÿÇþ‡ýýßòþÿÃÿð¿Mþ'žÏÜÿçþmü¤t=iÇÿý5á_óþK»û?ÚñÏÜÿ¯Éÿß.þ¿.ÿVyÿÜùÓzü¿vþ{ýûÿÜÿãþ?çη6?sÿ‡ü?–ï_“ÿ‡ûÿÈì?Øÿ ¿EûúüýíÒŸü¶?×ÍÿíÖÊþyÍõßíü/RÿÔÿ§­Ië?Iïÿé×’ùϤòGÛÿg]ÿgÿ·íÿ!ÿŸmÿ?úŸmýÿ·mü‰ÿ³íÿª;ÿMs«ü¯ÚõÈÿOþâÿðÿ[ý¬mÿÓ>Ië?Ký?Äÿÿ¯©ÿJõ?iü¿¶ÿû?õ?-ûÿßóô^ëõæïðóó¿Ÿÿ\¿þÃü À>ð5á»0ëüÅëœ)ë¿Çáýûõï> ?‡Ùø}þå0Œ>|èý{?nœÿ>»þký*lëWkøÇý]ûã¶ÿþWÿÿr€ï{¯íïZñÿüþeãÏ}ÿÃÿ6ùü9lû¿çw¶í!ü_íoýüçõü¸=Ôÿåóß§þïñ¬ÿ÷æ¯Uÿ´|ý^{_û¿tü×›öä?òÿ{òûû¿åýúCìÿ–íõñ?eðýóãø«4þRø©øðÇÿ ü´üõõR¶Ÿ×ßûöÏ_Ëž¿üúLËßýú/eò7Uÿ%/ÿ¥þ'©ü×óÿµ¡­üÛ>7„®Ÿÿ_<þœÿoYÚ®¿˜þþùÿÔ÷þçâ½eúgÜßÇçð¯ƒ÷Çþ_"ÿSë¶íçÏ/Çô×—ÿÇøçÖ_þüÏß²Ï_ëߺÿ ÿ'ú·ø±~µÖÏóú—TÿïEÿ‘â/=ÿ·›ÿ¸?ñÄÿÁÿÄÿíù¿mË?ëö_ìØÿ°ÿÙµÿµÒÿ¤÷O´ý¿vùýŸû?À>ð‰ÿ%þ‹ø_èÏý_íû?Ú÷Ÿ¬ßÿ/oÜ—þÏý?îÿqÿûvüÿÄÿ[õÿ ÿãÿÇÿÿÿ¿eÿÿ¾ÿܵ×Êÿ2ÿ¯¶ÿß®ýÏ:ýñÿ£ÿaÿ‡þö蟮?ñ¯®„¯3·‡õ'~µÿ㕪ŸSV#Õ¯þV¯ð­Ï¿õ/µ?^²÷œüËÑÿÓöÿúñ—Ùÿ¥ó×rþkìRþËÁß¾âñÖþÿéõ‡ücÿÑ„ßR~I÷mùŸÂ¿~üß™?øù‡ü~ øÚïÚë?|/Ó??7ÿçá÷Oßòü×öü©­ÿÛÛÿûâÿëÉ¿«Ï¿EùÇù¯WûßwäoËýGjÿaÿgÿÇþýû?öìÀ>ðõü?eñGŸ†¯çÿ±!ÿ¡?û?öìÿèÿð?üoÛþýßêùcYÂþËÚ—EfŒû/Ëq)üe9g?ÝÇ=GõóïŸï>ÿƒ±O)ü¸?ñÄÿå׿—‡¹ÏgßËž§±þñÿçè³þ®vÿ/“Røûýsû¿uù__ÿOºÿçî?çöÿO×ÿ³aÿë—þ¹õÿéüOu민þ¡¶þ‹þGüöìÀ>ð‰ÿ•ø¤þ§¾âÿ¬Çÿâÿãþ?÷_¹ÿÏùûÿÜÿgþÑ¿mÝÿ'þ‡ø?ôâÿàâÿˆÿÃþ‡ýûûÿ/ßÿ‚ÿáøßÿ»x§Û-ŒrõYþÿ«èëüëåì—ïöç=ìÿÆsÝßµ¿¿÷Ïw¿o ?îÿ¼‡ðßß‚ÿüxü¾WþÀïþ¿µ2aý#WŸèýòŸÃßC‹õ¿~^ -~nýoÇß·¯¿Ká“ú]nþ÷æ¥>ôצÿ²´…ÃñÏOͧ¦ü—ÆKãŸ÷ðÛãýyÎõßò×8´‰•ò_ïõÿÆaÛ¾®ÿ•›ß=ýj=ÿšõÿöø?Äïxý¥ö£çmŸßãú—ÞŸ)믽ÿ}jüW™ëòýŸó¯uüs矣óR›ó‡îùËòùO»þyçÛú¿„þRù§]ÿùýûö?«ö?ô?øúÛ¦ÿ‘}¶ÎþXnÿÕ¶¢ÿÉì—Ÿj×¶¿iãÿ­v©ÿ§…ÿOSÿKûŸÆaÎþŸ÷ÿì¿÷`ÿ?¢¿Ÿ#?ÿkú·8ÿ÷èÿ³¤ÿ³ÿÿuÆ_¿Kéßãùߊÿý϶þ‡ü³ Ÿø?Ûþ¯’óOÜ~>þ/wþLÁ¿JüŸ¹þyý$úäü×Ãù¿Gþ×÷ÿ[ŠÿÃÿoÕþÛ«ýOvþ:>¯¦ö¹ÚýGêÿ!þŸømýW¢ÿµØ?5ý¯Øÿóòoýwý?·ÿLó4/Ëó>ã°,Ïû8Ló4Oó4?ïÏûã5Í×ãõ¼?ïã°,×4òüýÝnÓ<ÍÓ<ÍÓ¼,Ïû8ŒÃ²<ïã0ÍÓ<ÍÓü¼?ïÓ<ÍÓ¼,Ïû8<ïÏû4çõ+þW/äv 뇸úDïþsø»w>£ï]ÿðûýçµ÷ÿûK üÁß6þÒóÿÜù'‡ÿ§ïÿÔÁ/?ÿAè¯Iíú‡WÇ_ºþ{¯ÿ˜;Kñ×®ÿÿÃÿ–ùß:þœ6ø|>û~öyRøÒßsþ+µ?Kéß«þ?eëIêÿÐ^ÿ9ù_W¸¼þsïûéú×®ÿÌþüïQþËäo»ûVíìÿ6öèý±ÿ#ÿÏÑ߯ß¿½þÇñÀ¿|ò?Z‰ÿMßÿöñ‹oÿK©ÿ(ÿïüýëpý—ä¯Ú»]‚.þ]rÿ»û?õô—ÊŸºù_ÇOsùø]ü_œÏLoýõ*ÿÏÝßÿ½vëùÏÅ¯Ëæ_›ÿ¤øiÏß÷Û?Ÿÿƒü'ä?CÿׯÿS¢IõMýGŠ¿6|éü“ÿ‹ú_ð¿íü–åŸuû/ö?ìØÿìÚÿ¤ú_‹ú?úùáôòÿbÿðÇÿCý'kõŸ ?ö?òÿÚÍÿKþ?ËùÿÈÿ[‹õÄ¿uó÷'ÿ/ù[žˆ¿ÿ%øèÿèÿøÿñÿãÿGþ—Éÿvþß^㿱ÿA+÷Ðÿàèo“þäÿ#ÿcô'ÿåwÖ¿Ôþ-Íÿ§ÿ%‡.ÿžÔþ¯ÿüß¶óÿ°ÿ“ÿ‘üovó¿¡ÿ!ÿ8ÿØÅ¿×üß½ä?·^ÿ'wþ“Ê¿^õòÿ“ÿŸüÿäÿÿõý¿Wûß·òÿçðÏ­?©ý‡ýŸýû?öìÿØÿuôßÇk=¿ÞÞþ³­é_Ûçîõ_ë©þRø©ý/ìþàþaü´Û÷å,?¥ø{ùýx¥àçðÏõ÷òß·‡ñïÇø×ÁÞÓùüµþý¡òo}–<þ|öUö¼«ã/•ÿíæ¿ü÷ëõÿ¾'ÿîïֺݽ?^-ù??‡O®ºÝþ‡ÿ-ó?ø[?ÿÔøÖþ«Ç«¼¿³?ÇþMø5ôÿþRû_Úÿà¿ÏÍ¿¾þ/óÿHóßjûÖüÊÎ=ù+mßÿ¬Ã?5ø¯ßeë?ýÜ:øûýS¿—ìÿŸ¡_ëñ\cý]Qþ¯ýW²ý·Nþ®ýÇÒú7ÖíÚô¯™ÿòþ¹ù×^Úú/úŸmýû?þ ý¥ø—Ñï,üvôðÿuü}èi.û¾Jý+{þ÷ZçKÙËÿœÿqÿ¸=þ;‡ï‘ÿ+ ?„¹®Ÿן*ó_×ú¿ZÑ¿výo_uó_:޽߷[uô×á™þ/Õõó_Z—ÿºõßô忬þ[ºþÀ{^Jê^3ÿkKþGþ!ÿÐÿ{À¿þyNÿÿü¥ôGÿGÿ‡ÿáÿoó?øcÿÃþ‡ýýßæþÿÃÿð¿Mþ·ÿHîÿsÿ¿>~R¬ÿIüô׃Íû/-ïÿôsÿÏæý?ÿN>>„í-ãÿËïÿûÏuöËu»íøÿ–÷ßöï™õ|ÿŸûÜÿçüÃù×êýOîÿÿ‡û×ìÜÿGþcÿÁþý-ÙÿÐÿàèoYÿ'ÿŸmû¬þ—ÜþyÅõßÿ~ê?Iý?5þ¿žò?•ãçß[æÿѰÿKýg-õOÿþöËñ_äÿÃÿþgUÿÃÿMþâÿìú¿êÎî]ÿ¤_ÿ‡üÿäÿ'þÿ?ùÿuìýäÿ—î?RÿñÿÄÿkæÿ—ê5ñÿ=åÿÇþOýOkþÿ÷ˆÞôXãïÆ—nwïî/ÿmº=÷ü¸¿~îùgÇþàÿ»ø¿s‘„ùOŽ?‡/)þÛW/‡®þuŒïyøgŸý¡¿ýµó^éúï)ÿÛ~þ´8U˜ëJŠ¿fþ7øþ·Îÿ–ñ·®ÿ;{åíÚ/÷à;û–‹ÿrÏûCŒ¿kÇç~ßþÿ>ç¿5ýÿývÂú7{ûUø»qÒ_[ÿ/Á?·þöæe=žðûp>5׿výýý_†¿tý_½þû?ò_ºÿ¯Ÿ×FþnåZ.sþcÿ·½ÿCÛôÇþÿ'«ÿÐN;þÿŸÄ¿Îÿ×/©¿Y'Ïõ?ú,­ÿ"•ÿ×ôÿ£OÞÿwvþÏõÏ_sýiË÷:û¿¿ÿë÷{ýíÿzð±ÿÔœÿÂóŒtþ5ù¯îü®¿’ù;>ÿ]ÿÚùÿðâÿDÿ¿ZüKyþÔ²ø=ýG{üÚóOüñð?ñVåŸuû.ö?ìØÿìÚÿ¤ú_‹øMÿ/üþþ¯wÿçê÷_Àü¯Ž¿æþ¯-ÿ¥û~3~‚þÐ_‹þ²ü_ëû'a{i~©~î¿Ôä¿j)ÿ¥ðkóßúÿÓ¼ý<ÍÛöõ»ìþךÒðòøçú¿<¾kÿýÿ§ÖŸ{Î:þ;Íÿã°åíõ¯Íÿ¿#ÿêÖ¿§»ùOÍï‘ü°,ÿÐÿµýÏô¿®ÿýÿúç¿VõÓ>Qí›üc}ÿÓ¦ŸõõwùßÎÿ¯íÿEþCmøèèØÿ¡¿ý©IýGê¿Ú]ÿÔÿ¡þõìÖÿaÿ·½ÿK󟶬ÿ«-ÿ­×ÿEÿCþÙ;ÿpþkUÿºFÿïiýKëïJéú¿éóŸtÿ×ÑÿÙÿuùÿwäŸtÿ×8ÿ[—œÿ´íÇñÏuò·]üÿ™ýGjÿaÿgÿÇþýû?öìàþàÿyý_vÿ©¥ü×ÙÿmËèÏþßÊþSo_ú ü¯iÿGÿ‡ÿáìßàOüw©ýqYBûciÿ=ÿ—&üúÿNâÿðÿgýßMÛ÷?ëðþÿZzµ¦_ëñ\cý]QþûúcÒý·Nþúý?<¿åÆŸÎ?gÛþ§Mÿšù/¬»þ´õ_ô?ëñØÿ±ÿáÿð·îÿ—újΗ=É›ñ¿øÿ¸ÿÏýWîpþãþ?÷ÿ‘èÿVñ'þ‡ø?ôâÿàâÿˆÿÃþ‡ýûû¿û_ð?üÿÛâÿ÷ˆÞôXãïÆG;íÛv÷îþòߦÛsÏûKáçžv|¿ÿ»IXÿäÌgéú’>_:þóðãù˽rχþ×¢[øšò]ÿ-v¿¿ÝÂþ{ãwí¾kÏõwí[üeñ¯RùßCýóu}úwýúýú_ãðþÛÕ¹o1ÿšõ÷¾ãâ¿ÇŸ©õ—ë¿nù_ýËâ?¤ñÚûŸ÷üpþÝ<—Îÿ4·ÿºü§åú?ç[ëíçõ×ð%]_¹óÒùó×ñxÏŸÏ~÷ü§]Xÿüc]ÿ×¥ŸõõwMùýûö¿_°ÿ¡ÿÁÿÐß.ýµíÚð­ëuó?­ìŸ×\ÿíðw¿o ‹ÿyoåÿ‘úÿ´õ¯üsöïG‡ÐÏ“÷ÿô`ÿ—øÏZœÿ5ýÖõöÛþŸÿw쯎å™tþ5ùϺÿý϶þ‡ÿÛ6þÄÿÙöÕÿ¦9Üÿ%ñOþU®ÿÇç—ãþqûúïºýZÿz8ÿkòÿ5㟭Çÿáÿÿ•vmûŸöù«Îþ4Í­ü?Äÿÿ¯ÿ/ÑÿZÄÿkú±ÿ×ðÏZ×–Ç?~_ÿÇoÙÿïòHÆï;ÿö~—ëŸûøÀþ÷á§íã°'_bûçáçð/;ïÛ?´áCè¯Iÿtþé8µÿ».ÿõ~þé«ãõùOŸ?âó›·Äç)þ9ø9üËΟûçøþ·ÌÿÖñçü‘†oýÝúùÏíï¹vé<÷ªÿ—â§=Ò÷}ùëålÜÊ_Yÿ~÷Ùø¯2ÿìÿÈÿåÿ·ä/ö?öËû?ô‡þØÿ­Ë»÷_À_ÆÿŸæ?à¾vü_7׿þÅ6þ/—çp{ÇÀ­Ç±Ž;ò•Åÿ׸ߤþ/ýû?©ù/¿ôÑGã÷íÜÿ)ÛÿBýuYdçëÜóÇ¡-üeiuþ·°ÿlÖösø.¥¿¦ü/Á7·þöæ¥t>{\ÿÚíÚüwõùCþÿs÷ÛÕÿ¸æýç_ºÿ›?ÿ¬ÿ®ÓÿsçÏúóWZÿOÿHÿßîÛ{÷›êôÿcýþ׿ÿúów›ù×=ÿ[–äÿÄþ‡ýûŸåü?ý¯Åý Mý þGÿGÿ×Ö?|à_Qþþ'åð¡?ôïAþ¸qþûìì'ßlÇÿn‡m{ˆ»þáøÞó·Î¯—ÿ§æÿ<üãþ®Ýëæÿ¿`•ïÒùO?׿røçú—}ó¯—s¥ãßë·‡ò³×õ¯ÍÿדWŸ«òó‡žÿ¯ÿ·uüÑÿ­ëÿËÊO¿~Öù½ëåïºÿû.öñþùmþ·¾ÿµ¡¿Tþµ[qÿ2üíÊ=ÿ¿¶ÿùý%ùßËèïŸ×@ÿCÿÃþýµèßoþ©kä¿Òοù9øÖç߯ú—Ú/Ù»vþg)~Rû¿tþZÎý¡eþñüí+ÿgíÿŸ^È?öŸ>óÿŸ—_ÒýG[þ§ð¯ÿwæþCþ!ÿ€ß¾ö»öúßËôÏÏÍÿyøÇýÓß·<ÿµ=jëÿööÿ¾øÿzòïêóoQþqþëÕþ÷ùÛrÿ‘ÚØÿÙÿ±ÿcÿÇþýŸúGÀ>ð©ÿNýèý©ÿMýïïúÿËâO¥økëßð?üo™ÿ©ÿËùÃågõýsŸÏ¾Ÿ}ž¾ô÷î¿ûç?×Í¿~îymàÇý©ÿKý×£úóïÿëõú–Eæˆûçùÿ[ë_ê?i3ÿÚñûô÷s´,õûÿ¾üK¿~zÿûçöëò¿¾þŸtÿÏÕ/Ëí矮ÿgµþ³6ýŸ÷²õÿéú—u민þ¡¶þ‹þg[ÿÃþü§þ"ðo·þ'õ¨ÿCý›õ¨Íþ“¯_ü.mþ“â§=ðòùü+Öÿ»:þ¿PýŸúŸð¿]þ·Œ?û?ö?ììÿ–÷øþ‡ÿmò¿õøGðçþ ÷ÿ—å8~Ò}Wÿµ¿þûˆÿ$þ×6ý—¥-ü˜þËÂ÷ÏïãþK÷¾ÿÌýÿãú—ã°m_ëßÒøÿ\ý»Üýiý;ëñÿÚ÷Ïú½ÿoéþ÷ÿ¹ÿÏùŸûÿÜÿ±™ÿ§þþw™üõÏwŸ{Yÿäÿáþ?òûö?ìíèð?ô·Kòÿaÿè!Ioö7+ïRÿÔÿ§­ÿIë?IïßõQÿiYŽýg®½6ÿ÷¾üëÕÿgEÿgÿ'þ‹üvýÿè¶õ?üß¶áÿgÛÿ%­_ÚæüÙ_ýòÿ“ÿŸüÿøÿÝþÛ«ýï[ùÿ¥ûÔÿCü?ñÿšúoËúõ5û¶ÿû?õ?-ûÿýü½çÊoþÛüô§?ý¯Ü+Åç¥Iç‰ó§|þ§Ç¯ úCÿäÇ{”î¯wÿo¶_ÿ«Î¿ôÕŠÿsÏÿÔøáøß2ÿƒ¿eýÿÚù§åð¡¿fþWýýW7ÿhOüçÆy,?]ûÛ»†ÜYú”¿íð¿úü³ÿ#ÿ¿/ÿµå¯õóû¿õýú[¦?öìþ~§»Ÿ¸wÿ³~ÜßßÏJ÷—ÂOÅ?þoú§å×{½¬÷²ãÏçü3nýúv¿>ÓòÓÃ+Yÿ¹þ¥ò_ê’Ê=ÿ_ú×Ê¿í+„·]?9ÿßñx÷~ßnýÅôŸÿþûýY_þËò?”éŸþù[úÇ×Á/ÿFþ»µ¾>¿ÄòӯߺóßýµåÿÜúËŸÿüó·ü¯½þ­ûßð¢?[ײַçô/©þßËù_Š¿ôüßnþÓóKüñð?ñçéóÛòϺýûö?ìVííô?éýmÿ¯]þGÿçþýéOîÿÿÅýèo)þ[÷þI?þ/›ö¿ÿ轕ÃßµŠ?ÖÑÿ‰ÿçþ÷ÿ¸ÿ‡ÿŸø«þôüÿøÿñÿãÿ·ìÿß÷ŸÇþ˳ò«Ìÿ«íÿ·kÿ³NüÿèØÿ¡¿=úkןчï_a]°4üßëo}þm¯©ýy ?|_éïsò+G¿OÛÿ÷ñhcÿßÎÛÞüåæY>ÿ5ö)ÿyþ'Ư½þìÿšý¥þgùþÓüר?ÿ!ÿôïaýkèŸ=­éKJ?WËóŸtÿ×ÑÿÙÿuùÿwäßÕçߢüãü§mÿÓ•¿-÷©ý‡ýŸýû?öìÿØÿ±øÀÿæþ¯ãÿÑÖÿÑÿ ?ö?»öÛö?ýó»ó×'òOÀÿðÿoÛÿÁŸóDz„ýÝwo8q{oüGý—帿~Üÿñ:î¿ÿzŽêçß?ß}þcŸþRøqÿýûݶí¡þ_BÿýùïWÿ—Žÿ;óצ¿_/eŸÏ¾—=OcýËðz¼ZÒOïýˆ>ëïj÷ÿ2ù'…¿ß?·ÿ[—ÿûõÿÆaÛ~^~íïÿ¹úg¹ý?×?'±ÿõMÿÜúoSÿnYÚ®¿q8ž¿e‡>ô_ô?ÛúöìÀ>ðñÿÛŒÿµÿ‡ÿý_ÛþØcëñ_œÿìØÿá?æýÛ:|âˆÿCÿ'þþ'þø?ìØÿ°ÿ±ÿsÿþ‡ÿáÿßäït»…ñO®>Ë;cûîywø9ûå»ýyû¿ñ\÷wí®>‰{¾û}[øqßîò3¸ñ -~<~ß«à÷ ÿßZqu‹Ýçç=¬‡ä>‡¿‡ëý¼üÜúߎ+¿o_—Â'õ»ÜüïÍK)|è¯Mÿei ?†ãŸŸšOMù/ÿ–Æ?ïá¶Çûó8œë¿å¯qhÿ*å¿ê¿ûút~ý»úwã°mw߯áÓg«_­çßéí)øqý»þ¹þëö¸þÖÿ‡ø¯¿Ôþqô¼íó{\ÿÒû3eýµ÷¿Oÿ*óo]þ¡ÿsþµŽîüst^jsþÐ=Y>ÿåôÿý+/ýóãúÏ}œlëÿúKå_îþoÝú+¿ÿ‹üÇþƒýûŸUûúüýmÓÿÈ>[g,·ÿjÛ?ÑÿdöËOµkÛß´ñÿV»ÔÿÓÂÿ§©ÿ¥ýOã°Æ?gÿÏûöß{°ÿÑßÏ‘Ÿÿ5ý[œÿ{ôÿYÒÿÙÿ‰ÿ:㯎ߥôïñüoÅÿþg[ÿCþÙ†OüŸmÿWÉù'n?ÿ—;¦à¿_%þÏ\ÿ¼þ?ýFrþëáüß#ÿëûÿ-Åÿáÿ·jÿíÕþ';ŸWSû\íþ#õÿÿOü¿¶þ+ÑÿZ쟚þWìÿyù·þ»ÎþŸÛ¦yš—åy‡qX–ç}¦yš§yšŸ÷çýñšæÇëñzÞŸ÷qX–ÇkšÇaYþþn·ižæižæi^–ç}ÆaYž÷q˜æižæi~ÞŸ÷ižæi^–ç}ž÷ç}šóú¿ÿ¿«r»…õC\}¢÷?ÿ9üÝ;ŸÀÑ÷®øýþóÚÀûÿý¥ÇþàoéùGŠîü“ÃÿÓ÷êà—Ÿÿ ?ôפ¿výëã/]ÿ½×Ì¿¥øk×ÿƒÿáËüoÎ?ü >Ÿ}?û<)|éï9ÿ•ÚŸ¥ôïUÿ‡²õ$õh¯ÿœü¯«?\^ÿ¹÷ý?‡¿týk×fÿGþ÷(ÿeò·Ýý?«ö?öû?ô‡þØÿ‘ÿçèï×oŒß^ÿãøGà_ >ù­Äÿ¦ïûøÅ·ÿ¥Ô”Îÿwþþu¸þKòWíÝ¿.Á?ÿ.¹ÿÝÇýŸzúKåOÝü¯ã‡§¹|ü.þ/Îg¦·þz•ÿçîïÿ^»õüçâ×eó¯ÍRü´çïûíŸÏÿAþòŸ¡ÿë×ÿ)Ñ¿¤ú¿¦þ#Å_¾tþÉÿEý/øßvþËòϺýûö?ìvíRý¯Eýýü¿ð?ú?ù±ÿ€?øãÿ¡þ“µúOÐûùíæÿ%ÿŸåüäÿ­Ç¿Åú?âߺùû“ÿ—ü¿-Ï?Äßÿ|ôôüÿøÿñÿ#ÿËä;ÿo¯ñߨÿ ¿•û?èð?ô·Iòÿ‘ÿ±Gú“ÿò;ë_jÿ–æÿÓÎÿ’Ã?—Ojÿ×ÎÿGþoÛùØÿÉÿHþ7»ùßÐÿœìâßkþï^òŸ[¯ÿ“;ÿIå_¯ú?ùÿÉÿOþòÿÿúþß«ýï[ùÿsøçÖŸÔþÃþÏþýû?öìÿ:úï㵞_ooÿÙÖô¯ís÷ú¯õ¿T)üÔþöðÿ¿¿0~Úí‹ûò?–ŸRü½ü~¼Rðsøçú{ùïÛÃø÷cüëà?ïéüGþZÿ‡þпù·>K>û*{ÞÕñ—Êÿvó_þûõúß“÷wë?ÝîÞ¯–üŸ‚ŸÃ'×?ÝîÇÿÃÿ–ùü­Ÿjü?kÿÕãUÞßÙŸcÿ&üúÿN©ý/íðßçæ__ÿ—ù¤ùoµý?kþ eçžü•¶ïÖáŸü×ï²õŸ~nüýþ©ßKöÿÏЯõx®±þ®(ÿ×þ+Ùþ['×þciýëö?mú×ÌyÿÜük¯?mýý϶þ‡ýÿ„þRüËèw~;úƒ?øÿ:þ>ô4—}_¥þ•=ÿŒ{­ó¥ìåNÿ¸ÜÿÃ÷Èÿ•†Â\×ωëO•ù¯ŽáKý_­è_»þ·¯ºù/ïÞïÛ­¿:úëð¿Lÿ—ê¿úù/­ËÝúoúò_Vÿ-]à=/%õ¯™ÿµ%ÿ#ÿèÿ=àßNÿ<§ÿÿ -þRú£ÿ£ÿÃÿðÿ·ùü±ÿaÿÃþÇþosÿ‡ÿáøß&ÿ[¤?÷ÿ¹ÿ_?)?ÖŽÿ$þ úëÁ¿æý—–÷ú¹ÿgóþ¿Ÿ§ Ÿ?Âö–ñÿå÷ÿýç:ûåºÝvüËûoû÷Ìz¾ÿÏý?îÿsþáükõþ'÷ÈÿÃýkö?îÿ#ÿ±ÿ`ÿƒþ–ìèð?ô·¬ÿ“ÿ϶ý@VÿKnÿ¼âúo‰?õŸ¤þŸÿ_OùŸÊñóï-óÿhØÿ¥þ³–ú§Žÿÿ?û¿åø/òÿáÿGÿ³ªÿáÿ&ÿ?ñvý_uç?÷.Ò¯ÿCþòÿÿ‡ÿŸüÿ:ö¿~òÿK÷©ÿ‡øâÿ5óÿKõ¿šøÿžòÿcÿ§þ§5ÿÿ{DnÔ~üŽ?h§ößn—¾> ÿÓã׆ý¡¿ýËô—\üd}ÿ«ãõù/Ë_µŸ?­þ9øŸ?üÿ[æËø[×ÿ½êv íW{ý]»‹ÿrí¹þ®½7øÐ?¬[ãÞ÷öªÔï¤ó¯¹ÿ–àŸ[{ó’‚“ú^sý§ëόÞü¬«³_Fÿ—áõùgÿGþkÊmùkýüÇþo{ÿ‡þ¶éýÿÏ;#Œpñ éöÖÏûKáçžþè¿´ÇõöëçÄõKB_Š$þ)-}}”’õŸëô’úŸ¤²¿ÿ_=ý¥òO»þSz½H×ßó~îùzòßÅ+‡úã>ü:ýÓ??_Zÿ•Âßâýÿèü¿,áùe½Öÿöé¯-ÿKðÏ­¿üùÏ??5Ÿšëߺÿ ÿ'ú±uý_³þ±¶þ#Å¿…þ«_ÿ•ø?ÛñÖùßzüŸ]ùgÝþ‹ýûö?»ö?©þÔbÿÔÔ¿àôôÿëÞ?¡?ýé¯'ÿ¿ÿÓã׆ý¡¿ýýý“0¿×^~¥0ÿ×úþÉqÿtþ¨žî¿ìç‡*k—ÒO -¿®ý?ºEï{¯íï¤óŸ{åð“½<>kÿýÿ§Ö_®ÿº}ËÿÚë_›ÿGþ]}þmÊ?ôMÿ_þoëø£ÿÛ>ÿIò¿žÉ¯šËϪÇÿÖ÷¿6ô—Ê¿vë¯]þ_ò_Ïÿ¯íÿEþCÿþçáÇôçÏûÿÑÿÐÿ°ÿC-ú§ëÅõ«üßuõ/sõÇ4á—Ô¯ÈÕ¼rëóo{ýKíÏeõ¯ÚúYùúÕŸµÿïãÑÆþŸ¯ës ¿åüר¤üwæùŸ¿öúCþ±ÿkö—úŸåûO?ò?…nýµ”ÿðòùG­õ¯¡ö´þ¥/)ý4^-ÏÒý_Gÿgÿ×åÿß‘WŸ‹òóŸ¶ýOWþ¶Ü¤öööìÿØÿ±ÿcÿÇþ|àÿ›û¿ŽÿG[ÿGÿƒþØÿìÚÿmÛÿôÏÿíÎ_ŸÈ?ÿÃÿ¿mÿÎËöwß½áÄí!ü½ñõ_–ãþRøqÿÇë¸ÿ>þë9ªŸÿ|÷ùÓuþRøqÿýûݶí¡þ_BÿýùïWÿ—Žÿ;óצ¿_/eŸÏ¾—=OcýËðz¼ZÒOïýˆ>ëïj÷ÿ2ù'…¿ß?·ÿ[—ÿî~±¯ʯe‘ɯýý?-?=üÜþŸëŸ“¿Øÿú¦ný§ç?uÿýhÿ_–¶ëoŽçï]°ýý϶þ‡ýûð|üÿ6ã­Çÿáÿcÿ×¶?öØßzüç?;öøùGÿ¶ŸøâÿÐÿ‰ÿƒÿ‰ÿ#þûö?ììÿÜÿ‡ÿáøÿ7ùßÅ;Ýnaü“«ÏòÎXà¾{Þ~Î~ùnÞÃþo<×ý]»«Oâžï~ß~Üß·»ü n|àŸ‚ß÷ªÃø=Ãÿ·V\Ýb÷ùyë!¹ÏáïÆ¡Åú_?/?·þ·ãŠÇïÛ×ߥðIý.7ÿ{óR -úkÓYÚÂáøç§æSSþKã¿¥ñÏ{ø‡íñþ<çúoùkÚÄ¿Jù¯‡úï¾>_ÿ®þÝ8lÛÝ÷kxÇôÙêWëùwz{ -~\ÿ.…®ÿº=®¿µÇÿ!~Çë/µ=oûü׿ôþLYíýïSã¿Êü[—èÿœ­ãŸ;ÿ—Úœ?tÏ_–Ï9ý¿DÿÊË_ÿü¸þsçÛú¿„þRù—»ÿ[·þÊïÿ"ÿ±ÿ`ÿÃþgÕþ‡þÿCÛô?²ÏÖÙËí¿ÚöOô?™ýòSíÚö7mü¿Õ.õÿ´ðÿiêiÿÓ8¬ñÏÙÿóþŸý÷ìÿGô÷säçMÿçÿý–ôöâ¿Îø«ãw)ý{<ÿ[ñÿ£ÿÙÖÿ¶áÿgÛÿUrþ‰ÛÏÇÿåΟ)øïW‰ÿ3×?¯ÿƒD¿‘œÿz8ÿ÷ÈÿúþKñøÿ­Ú{µÿÉÎ_ÇçÕÔ>W»ÿHý?Äÿÿ¯­ÿJô¿û§¦ÿû^þ­ÿ®³ÿçöŸižæeyÞÇa–åy‡ižæižæçýy¼¦ùñz¼ž÷ç}–åñšæqX–¿¿Ûmš§yš§yš—åy‡qX–ç}¦yš§yšŸ÷ç}š§yš—åy‡çýyŸæ¼þoÅÿÏ?þñÏî¿X¾Äò!×þiøŸ¿6|èý5ÿ­3+¥¾ÿÞæ/”õ¿:þWŸÿu~¯õúܳ?Äöé¿üOþ‡ÿ-ó¿uü­ÿsùã÷Òßç¾Û{ƒoýŸÔþ$íý7‡nýIíoÚë_;ÿ¨þþ/ÃÿêóÏþü×”ÿÚò×úùýßöþýmÓû?þŸu|aŸ˜n?;¿¹çÇý¥ðsÏ?;¾_ÇŸv«í.6jšÃ|O{÷¿ãø©2ÿ‹ßŒóÿ¥³ÌìßÿLá—ëôòñc§8æ-ç?’¼¤þ«ý%ô—Ê¿ôüïÇÿ¦ÇÜ?nÇ”ï¬ný=ï瞯'ÿ­ß°.ÿµóÿiËòèÆ÷°þ-ßÿF?Fÿõ«£û—uúç±þ¯©ÿHño¡ÿnçO:ÿ©û¯Gúÿñù'§?ËÏŸõç¯ãϽrøI_ð¿6ÿ.~ôÓðÛô·+ÿ¬Û±ÿaÿÃþg×þ'ÕŸZ쟚úüþþ¯­ÒŸþô¿¢üÿüO_>ô‡þzô÷ù¡ÜYðßg×ýü°ým_YçŸ;îïÚ¯°];ÿ]Œ_<¾òv)ý¤ðëÚÿ£[ô¾÷ÚþN:ÿ¹W?ÙK7ÿXõ_5ùÿwäßÕçߦüCÿ×ôÿõàÿ¶Ž?ú¿íóŸ[_^>úõ“n?+_sÏ׿ëû_úKå_»õ—^_9üíÊ=ÿ¿¶ÿùýsøŸ‡Ó?ž?ïÿGÿCÿÃþýµè¯ŸêÚù¯®ßßúüÛ^ÿRûó~ø¿ÒßkçÎá¿GûÿvÞöæ/7Ïòù¯±´Ì?ž{þ'Ư½þìÿºùÿeþgùþÓüOáŸ[-å?ü‡üCþÑ_kýkèŸ=­éKJ?WËóŸtÿ×ÑÿÙÿuùÿwäßÕçߢüãü§mÿÓ•¿-÷©ý‡ýŸýû?öìÿØÿ©Ä?þñúïÔþПúßÔÿþŒýG¦¿Jÿiëßð?üo™ÿ©ÿkûßíæëÿxû¡ûïþùÏuõ'ýósÏk?î¿_ÿ2~~Ùç³ÿÎ>O -¿ü÷Ôµ]ÿÕÝ- ýî;'?]{­ÿÁ?ß}îeýKý/mæ_;þÉÓ×ÍßýëöÏ}z¦÷ïrøeýsû¿uù__ÿOºÿçêŸåöÿO×ÿûõóŸ6ýsùësëùÓõ/ëÖ_yýCmýý϶þ‡ýÿõi§ÝnýOêÿPÿ‡ú?6ëÿPÿÚ¶üëÖ§ë×?ïGuî¥ó¯É%øçÖßÞ¼¤à¤¾‡ÿÈ?Ú-Öÿ»:þ¿PýŸúŸð¿]þ·Œ?û?ö?ììÿ–÷øþ‡ÿmò¿õøGðç÷ÿ}|g:~2n?¿´¿žµã?‰ÿ‚þGø×Á?û|íû/z÷´ãŸ¹ÿï鿎ß«?çÿ—Æÿçê×åîÿHëßYÿ×¾¦ÿŸûÜÿ·þó¿Uü¹ÿCþÉýï2ù÷ïéþ?ù¸ÿo]þcÿÃþ‡ýÏ¢ýýþ‡þvéOþ?ÛúŸvþ‘>Ö¿þÚð¥þ©ÿO[ÿ“Ö’Þ¿Ó¯ÿ4Íkú¦ýgaûùüßûòLÛÿg]ÿgÿ·ýü¶ýÿè¶õ?þÙþGüŸmÿWîüëÏuñGçOÝú?äÿ'ÿ?ñøÿ­ÚµíÚùÿ¥ûÔÿCü?ñÿšú¯Tÿ“î?ÚþWìÿÔÿ´ìÿÿ?›Ê \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.bz2 new file mode 100644 index 000000000..d18971ec8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.z deleted file mode 100644 index 8f783f784..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.bz2 new file mode 100644 index 000000000..7102292c4 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.z deleted file mode 100644 index aa13d9a1d..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.bz2 new file mode 100644 index 000000000..4da9f8558 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.z deleted file mode 100644 index 6d19ae6ae..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.bz2 new file mode 100644 index 000000000..476895cd1 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.z deleted file mode 100644 index 2606b9409..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.bz2 new file mode 100644 index 000000000..39a913d64 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.z deleted file mode 100644 index b263f23ae..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.bz2 new file mode 100644 index 000000000..ffc3cf539 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.z deleted file mode 100644 index 68b581ee2..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.bz2 new file mode 100644 index 000000000..0c96f7625 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.z deleted file mode 100644 index f73f50d8e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_104_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_104_states.bin.bz2 new file mode 100644 index 000000000..a5c2ad9bf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_104_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_104_states.bin.z b/client/resources/hardnested_tables/bitflip_0_104_states.bin.z deleted file mode 100644 index a65adef0e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_104_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_10c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_10c_states.bin.bz2 new file mode 100644 index 000000000..e3aa0c2b5 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_10c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_10c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_10c_states.bin.z deleted file mode 100644 index f9cb945ef..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_10c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_111_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_111_states.bin.bz2 new file mode 100644 index 000000000..8cd2e0ba0 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_111_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_111_states.bin.z b/client/resources/hardnested_tables/bitflip_0_111_states.bin.z deleted file mode 100644 index 10cbb8de5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_111_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_113_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_113_states.bin.bz2 new file mode 100644 index 000000000..c1b73e1cf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_113_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_113_states.bin.z b/client/resources/hardnested_tables/bitflip_0_113_states.bin.z deleted file mode 100644 index b350136d5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_113_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_115_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_115_states.bin.bz2 new file mode 100644 index 000000000..464b2e5d6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_115_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_115_states.bin.z b/client/resources/hardnested_tables/bitflip_0_115_states.bin.z deleted file mode 100644 index c6661ae8c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_115_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_117_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_117_states.bin.bz2 new file mode 100644 index 000000000..87f7542d3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_117_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_117_states.bin.z b/client/resources/hardnested_tables/bitflip_0_117_states.bin.z deleted file mode 100644 index 647feb09f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_117_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_119_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_119_states.bin.bz2 new file mode 100644 index 000000000..05620bba0 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_119_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_119_states.bin.z b/client/resources/hardnested_tables/bitflip_0_119_states.bin.z deleted file mode 100644 index 289598b1a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_119_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_11b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_11b_states.bin.bz2 new file mode 100644 index 000000000..cce41a523 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_11b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_11b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11b_states.bin.z deleted file mode 100644 index 099dab124..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_11b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_11d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_11d_states.bin.bz2 new file mode 100644 index 000000000..6aa3f4638 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_11d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_11d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11d_states.bin.z deleted file mode 100644 index 3d9511d85..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_11d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_11f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_11f_states.bin.bz2 new file mode 100644 index 000000000..5892009d2 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_11f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_11f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11f_states.bin.z deleted file mode 100644 index bb92ebe2a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_11f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_124_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_124_states.bin.bz2 new file mode 100644 index 000000000..d3601defe Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_124_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_124_states.bin.z b/client/resources/hardnested_tables/bitflip_0_124_states.bin.z deleted file mode 100644 index 0a37cc5ce..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_124_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_12c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_12c_states.bin.bz2 new file mode 100644 index 000000000..38dbdf227 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_12c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_12c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_12c_states.bin.z deleted file mode 100644 index ce9a966fa..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_12c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_131_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_131_states.bin.bz2 new file mode 100644 index 000000000..0afa8f655 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_131_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_131_states.bin.z b/client/resources/hardnested_tables/bitflip_0_131_states.bin.z deleted file mode 100644 index 6928656f3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_131_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_133_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_133_states.bin.bz2 new file mode 100644 index 000000000..400272bcc Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_133_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_133_states.bin.z b/client/resources/hardnested_tables/bitflip_0_133_states.bin.z deleted file mode 100644 index acdb9d972..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_133_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_135_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_135_states.bin.bz2 new file mode 100644 index 000000000..242ba30a6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_135_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_135_states.bin.z b/client/resources/hardnested_tables/bitflip_0_135_states.bin.z deleted file mode 100644 index 8ae5ed323..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_135_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_137_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_137_states.bin.bz2 new file mode 100644 index 000000000..293c1f93f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_137_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_137_states.bin.z b/client/resources/hardnested_tables/bitflip_0_137_states.bin.z deleted file mode 100644 index 73202f119..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_137_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_139_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_139_states.bin.bz2 new file mode 100644 index 000000000..97761432b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_139_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_139_states.bin.z b/client/resources/hardnested_tables/bitflip_0_139_states.bin.z deleted file mode 100644 index e43946366..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_139_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_13b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_13b_states.bin.bz2 new file mode 100644 index 000000000..fb869e7cb Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_13b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_13b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13b_states.bin.z deleted file mode 100644 index 742c3309b..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_13b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_13d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_13d_states.bin.bz2 new file mode 100644 index 000000000..46b67bf83 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_13d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_13d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13d_states.bin.z deleted file mode 100644 index 4b95e1ca9..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_13d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_13f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_13f_states.bin.bz2 new file mode 100644 index 000000000..33b2abfc2 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_13f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_13f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13f_states.bin.z deleted file mode 100644 index 469361ed5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_13f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_141_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_141_states.bin.bz2 new file mode 100644 index 000000000..3be41189c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_141_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_141_states.bin.z b/client/resources/hardnested_tables/bitflip_0_141_states.bin.z deleted file mode 100644 index 61746bf77..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_141_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_143_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_143_states.bin.bz2 new file mode 100644 index 000000000..99328786c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_143_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_143_states.bin.z b/client/resources/hardnested_tables/bitflip_0_143_states.bin.z deleted file mode 100644 index 685cf9d00..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_143_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_145_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_145_states.bin.bz2 new file mode 100644 index 000000000..b31bd720a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_145_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_145_states.bin.z b/client/resources/hardnested_tables/bitflip_0_145_states.bin.z deleted file mode 100644 index eab4935d1..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_145_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_147_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_147_states.bin.bz2 new file mode 100644 index 000000000..fab2780c7 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_147_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_147_states.bin.z b/client/resources/hardnested_tables/bitflip_0_147_states.bin.z deleted file mode 100644 index 4d6674400..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_147_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_149_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_149_states.bin.bz2 new file mode 100644 index 000000000..eda7650e5 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_149_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_149_states.bin.z b/client/resources/hardnested_tables/bitflip_0_149_states.bin.z deleted file mode 100644 index b9da604a0..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_149_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_14b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_14b_states.bin.bz2 new file mode 100644 index 000000000..c3c3dfaf3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_14b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_14b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14b_states.bin.z deleted file mode 100644 index 608337840..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_14b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_14d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_14d_states.bin.bz2 new file mode 100644 index 000000000..adf20a10f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_14d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_14d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14d_states.bin.z deleted file mode 100644 index fd8e92850..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_14d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_14f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_14f_states.bin.bz2 new file mode 100644 index 000000000..f61babefa Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_14f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_14f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14f_states.bin.z deleted file mode 100644 index f8af0a6f0..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_14f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_150_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_150_states.bin.bz2 new file mode 100644 index 000000000..612d6295e Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_150_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_150_states.bin.z b/client/resources/hardnested_tables/bitflip_0_150_states.bin.z deleted file mode 100644 index 587807efd..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_150_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_154_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_154_states.bin.bz2 new file mode 100644 index 000000000..9efc40fd9 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_154_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_154_states.bin.z b/client/resources/hardnested_tables/bitflip_0_154_states.bin.z deleted file mode 100644 index 56cb4f168..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_154_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_15c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_15c_states.bin.bz2 new file mode 100644 index 000000000..0180aa901 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_15c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_15c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_15c_states.bin.z deleted file mode 100644 index 4eb487853..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_15c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_161_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_161_states.bin.bz2 new file mode 100644 index 000000000..5c12567e4 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_161_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_161_states.bin.z b/client/resources/hardnested_tables/bitflip_0_161_states.bin.z deleted file mode 100644 index ef9f67c09..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_161_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_163_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_163_states.bin.bz2 new file mode 100644 index 000000000..b68ad5995 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_163_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_163_states.bin.z b/client/resources/hardnested_tables/bitflip_0_163_states.bin.z deleted file mode 100644 index f08b3e0fe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_163_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_165_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_165_states.bin.bz2 new file mode 100644 index 000000000..69e051fbf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_165_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_165_states.bin.z b/client/resources/hardnested_tables/bitflip_0_165_states.bin.z deleted file mode 100644 index 9e846f209..000000000 --- a/client/resources/hardnested_tables/bitflip_0_165_states.bin.z +++ /dev/null @@ -1,31 +0,0 @@ -xÚíì ®€·€HÛÉ+ðUtËH‘he @ÊÕÑ(—„ ˜“ñ·G{fg2Ä1Æ?ØÆþÏÿýÿwëºýN³wÿ^~¶Ïæiš§9\ßþÞ¾÷÷ëݲ¼~÷ãÿ½ÎÓy¼wÓüóóúûß÷~~ö÷ë?¿,GøËòï5Àðÿmü4oŸ-Kþëûýñ¯……ÿyüÿiÞ>ßß»/ü0/gü§yƒ‘žOèýuè¿Ý7üÎÓ6v›ã÷ŽðÃçþÇñÛçûûþÒõßoþãñûëÛg}rø/K~_þ¿¿„ÿ²œ¯ï?Ûßþ‡ÿáËøcÿÇãÿ~S×ðSÏï]~üºæÇKáÇã½Ë‡þiýç]nþ¯ÞKé?ŽýŸÇÿúùÓò,ÆÿzþtÖÿY~^]鞦ÿõýGÕÿ÷ð—®ÿ~ó¿®}èƒþGþkÊÿVù›æ—ëçgÿ‡þGÿCèÿù_†¿çße©Eà? >ñÿoÄ¿>þ²ÿþ²Ôï¯üÿwåo~ý_¿’¿­ñ¯¾òÿ9ñ¿4ý¥òç>ü#ýËããõº,#­¿ñä­ýþ­ãñÿÔí_úο6ÿÕâß¾~ïü½ü§âÄ?‰bÿ—ÿRkµÙÿZömøÒù'ÿü?øŸü?«òϺÿÿþ?üvýRû¯Wþ¿VüþÇþ'þÿüÁŸøù_äÿBÛþ?íó?Ú矬ûÿ®Þ§_ûŸÒ¶ÿ9ÿÇù?ÎÿqþýùïvàcÿcÿÿÇþ'þüÏÁrNþûó¿ñÿA{ç°ÿàèoþÿî÷÷{ôþýž¯oŸÿÕßïqüßo~üºæÇKáÇãÿ~óã¯ðŸ§ýýûû<>ØÑ??çÏãÿ~·÷??ûõÿ÷Û~<>\ßÞÿü<þÖñÿìúo÷?—^¯îWöÿ—éÿIÿÿ~RÿÿÝùº;ßµßoñ?ô9ÿGj¿þ÷û)ÿÛú»kÿ ÿÐÿúôo?Ké?†üOá_·þúÈÿñÖ?öòÏòþÇþýìÏ6{Vÿó÷{ßþìG)üëñûëûÏæ©çþOªÿdzÿméÿñøÿYòOªÿõ÷ÿ¶åú4ÿ_«üí™ÿ_¯¤þô?úÿ?þüÿøÿñ€?øƒ¿nü§&ÿ¨Ÿü/þcKþCÛôï·ÿŒ÷™ûû_ßïéøŸÿûþ‡ÿíð?þö?5þÇØû­ã¯æ?~žêÇ_Ñ øäÿÿ×|¯½þ‰ÿ×êß´=×þïÁ/¿²?‘ÿ=ú‡Iõo½ü­/íÿgÛÿ§MÿšõÿÞþ—Ÿ\Úö/öŸmûÿ?ñüàþäÿ¶ÄÚýÿ£æÿYÏÿ%þÇùοrþŸýçÿ9ÿüÃþ·uþŸüòÿ°ÿÉÿƒÿÉÿ#ÿÿþ?üèÿïÕÿð?üÿ[ãÿŸŸ—?jÿö|ÿžÿE«ÿñóè¹]/ß®¿øîˆ?ðŸß»#üi>ŽßàÔÂ÷®/üxü4á¿>ÿ ‹âþ'[’׿c¿’ý÷{¬¿üÒú¯yþýóæð©ƒœÿpŸ`ÇØeøÐÿiôï _[þ¿/¾n|êù?y]’ÿÚCþÛÿ«®}ïùÿtÿ½ÿÞÁ¯4^z½õ_›ÿ!ËÐÖRüÏÏïݽù÷®ïü·Õ?µ*ÿØÿ°ÿµ ÿ¾ýÜçH×ÿ±ofýWüüӜޗ±ÿ¡ÿð¸û›öÿúëÌÿw­¿çÉüøÿðÿ}‹ÿûþ‡þvé¯íñºuÿC~~úú?Ÿ·þß¿ ~éþyÿïÝø4þ§mÝÇÿ8gýåÝøÏhþÿÚø[/ûÄøŸ%ûýOþ—füzÄý¿¥ø?öŸmûø·müÉÿ³ÿjÝÿì×{Ïü§²ýŸžÇï㟯÷%ÿ_^?÷Ýÿ¶ÿÿÇζžÿGüÿ›ü¿#úÿ>¹ÿºïêÿ!ÿŸüÿ‘ìß»öŸ4ÿ_;þ‹ÿ¿MþõŠÿ{çwë:ÍÞy·®Ó¼®Þ­«wË2ÍÓìݺz·®Ó<ÍÞ­«wÞy·®??¿Þ-‹wËâݺN³wÞ­ë4¯«wëêݲLó4{·,Þ­ë4{7ÍÓì]Ùþ·ÿßêüýëlõ^?áýñ{¯z¹Ï·ñÇϯï×~<þç'ý\àþ¶ñ—ú?¥ø—ä_ ÿwûÛà×ë?èýµé¯Yÿðéø÷XÿãÖÿ/ûúà¯[ÿ þ‡ÿá›ø³ÿ9á_ñþîëÝûIáK¿Ïþ¯6þ,¥ÿ¨ö¿wuëIÿÕ^ÿÚýoÆÖÿeü{¬ÿ'÷ÿAÿ#ÿß!ÿeò·_þ«Uÿúߎþ‡þÐÿ?òŸóïÀçüçîœÿî‘=îùëù¿œÿçü?çÿ9ÿÏùÎÿsþŸóÿØÿ¶ÎÿSÿÛöùÎÿPÿþ§þ?çÿmžÿÇÿ‡ÿÿŸµþŸwì¿ýÏÇ=ÿÿcÿÛ¬ÿÿüÁßnü‡þ/ôÿþÖýzý¿Ç¨jÓÿGý_êÿjóÿ“䟽ú¿ß%ÿØÿÿNÿgììâÿØÿÄÿ‘ÿôÇÿý­Äÿ±ÿàèOýêÿQÿqúSÿòóõÿÚýÏíõÿF¨ÿ’ÿ¦þžÜÿ?Fý?êÛ«ÿƒþ§þ#õßìÖÃþCþ±ÿ±-ÿG¬ÿ=FýsëýÊû¿>õÏdzÿ©ÿOýêÿSÿß’þÉÿ÷Éúÿ9ÿWiýõÉÿAÿ£ÿñÿãÿÇÿÿÿÓúžöó»Á»šÿ³þØôOølÿyzüžþ©ñRø)ýwþàþ/Y¸—ï›|º’ÿgù)Å“ßó”‚_Æ??>ÈÿyJ?ÿ6øÓœ®4ÍçüsèýÇû½dþýÝߺû=©üï7ÿw¾Öÿ¶ŽãS×—¥þÒðKø”Ƨ®ïŸþ‡ÿ-ó?øÛ¶ÿ[â?{ÿÝ<ÕßüϱÿG~ ý¿i¼Ìÿ—Ž?„ÏËó¯mÿËâ?=êߎÿ‰ýýiyžêÇÇߟ§‘Ö=þ{¿»týÇ÷k‡=~½‡þýz?ϧŸßŽüßǯúéÿzù»×ÿÒúÖ÷Úôo™ÿúñåù×^ãØßØí?üÿÄ$ô—â_C¿»ðûÑüÁß -þ{]–Ÿú-ÇWòñ™P“9WÿùÿÜøãõøï{ø§ð‹áaŸ?î?U¿ª/Ié/[ÿË"ÿ{Ï{þ~¿õ×Fþ—Úÿ=ì_Íú—Öå¿vÿ7mù/ëÿ–î?楦ÿàóê¿öääòûû¿‡ýÙbÿ?)ý±ÿ±ÿáø_—ÿíâþÇÿ‡ÿýo[ÿÃÿð?üo‡ÿ­ç?2žóÿœÿoÏŸ”®?íüOò¿ ¿&ü'žéyþgœó6Ï¿îéuìÏžÞ\Ó_šÿ_þ¿´?ºsüÿ^çßҟלÿãü çÿ8ÿÏþ‡ý¯­ñœÿ¡þç¯ÑœÿGþãÿÁÿýmùÿ°ÿàèOýêÿY¯ÿÔ¯þÈÿç×OüGªÿ'‹ÿ´ÅÿÆ©ÿ”Æ¿äïWÿGÇÿ/Ÿõ³?uâÄÿÑÿÔ¦þñì?‹öñoä?ùvã_-û¿í{}ë¿êôÿ¡þ?õÿÉÿ#þÿWÇÿ7Ný©þ‘ÆÈÿ'ÿ_7ÿ_fÿµåÿSÿÿ?ý?­Åÿ_Oô¢ÇÿíùÒ×·×í¯ðiúzéþñx)üÒýï>øƒÿ÷âÿªEr¬’ü'Åÿü﯄i|ù_ßûðïÞúCúk×?|:þÒõ?^ýëRý«cý´~øëÔƒÿáøß.þÖíÿÍó÷{ô_^Áþ­—?q»ÿq¼w1þÛõ3ý_ßï ÿŒÿ>û¿=ý§ùÜÿæJ_Å}n¤ô×¶ÿkð/­¿«y‰í‘ðùq>5׿vÿ›Ö¿ÿòïÉýÐÿÈéú?öMë!Ïò?-—Ùÿ¡ÿÑÿÐß.ýñÿÿ)Ú?\ç:ñÿ/µÿ[â?qÿ’öó—mò÷Þø¼=#ëÿ"•ÿÏŒÿÝ£Oyÿwþ%ãÏϯ¹þ´å{›ÿ?äÇöýÕø¼ÿ_>ò¿eÿwÜÏHç_Wþ·ìÿŽë¯fþòû¿§ñ_?ÿ7ñOâŸØÿOË©¯ŸZ—ÿ£iÿè>¿öü“ÿGþüOþŸUùgÝ¿‹ÿÿþ?Ëþ?™ý×#ÿ_7þÿcÿcÿkÿyúùðÿïÂÿ³ú_[þKõþfyÿý¡¿ý¥õ¿–åü¹wéúRÞ¥ëYqþ¥­þU?ù/…/­{¦ÿ²äéï¼þYàŸ4¼Züsãs¿çó_9þ¯Y¯×ÿ{wæíõ¯Íÿß#ÿÚëÿy×wþSó»Ÿÿtý;›òû_=þÌøÇÆÿ±ÿ¿gÿ'íŸöŽþkŸ\ÿÖõŸ6ý¬¯¿çÈÿ~ñíø/òúûûÿ?ôÿ¼ÿ‹þ—¶û?ÒÿÕâú§ÿýèÿcµÿòý/«ÿÚ¯ÿ¯¶ü·ÞÿûùgOþ!ÿ{õ¿n³ÿÇYÿÒþ»Rú?§ÿozÿ'Õÿ:ö?ú_—ÿ¿GþIõ¿ÎþߺüCÿëúÿòùÏmò·gþ½þ‘úÐÿèüÿøÿñÿãÿÇÿþàþïÇ_zþ©Ÿü×ÑÿÖå?ôGÿ÷ñÿÔïGGòÿY÷aÿÃÿð?þoð'ÿ»Öÿ¸®Gÿcíø«ø—&üúÓxòÿðÿß_ùóKã¯âÿc¬âÿ²÷Rúõ~žO?¿ùÖsOý_/÷úYêŸÿªþç?ôèß2ÿõãËó¯½þƱ¿±ÿ,Úøÿñÿÿð·ÿ—ÆÚüËãÈ›ù¿ÄÿØÿqþ•øû?Îÿsþù‡ýoòÈÿÃþ'ÿþ'ÿü?üøÿðÿ¡ÿíœÿ‚ÿáøßÿ¿žèE=þÛóqëçëÛëöWø4}½tÿx¼~éþwŸï»ñõ"9ö?¹ó^º¾¤÷—>ÿ}øñü•þ•îýŸEÿ¾ð5å»<ÿ[žÿüóóÊgÞ¿zþýýÿÁß®—Æo×ÏøËò_¥ò¤þO¡ýuÿ«øûýçÿÓý÷¾{ü¯ø3µþJã÷×cþ×_ÿÒüYþƒ¶þ“â¿Ýÿ8ÿÛ<×οw}ç¿­þ©Eù‡ýÏþÖúõûöëñŸt}•öK÷÷_ù罿?ûÞýŸvÿaýýuû_—~Ö×ß3å?þ?üøÿ¾Áÿ‡ýÿCËö¿¾ÿQ¾uû¯mþûù?Ÿ¹þûúÿýßþÿ#üiîÿ‘Æÿ´í¯6üóâHÁËÿ\üg,ÿÿ½øYÿýÿgãÄÿÑÿ–ã?5ñïX^ÅòL:ÿÚòßzüûÏ®ýGüùOþŸÝø—dÿô¿Dþmû—e©·ÿSñÏÜøãõãß-ú¿ïþo´ýÿ'ùÿ™ùÏÖóÿˆÿ“ÿWÓÿ§¿ÿjñ?-K¯øùÿäÿ–ÿÇþë‘ÿ¯ÿÅÿßÂ?{[»Wþã'íÿãó[Žÿou$ãן‹Ÿ«ï•Æ—>>ðÿyøiÿƒwWò%ö?¼~ ÿºýwÞÿ¡ úCmúŸëOÇõ«Ãßmõ¯¯ëO?ÿ§Ïzÿïß‚ÿ ÞôÁÿ~ÿšýgnÿÿÃÿÖùß.þì?Òð­¿ZßÿÿbþºtžGµÿkñÓž¿óŸ–¿AÎÆ×½ë7~\ý/{þ§Ì?úù?¢üÿ”üeÿ‡þ·®ÿ¡?ôÇÿoYþÛ>ÿ þíüÿnþþûákæÿÅys}Î_œóÿÒyyéü»=^¥øW]þß=øwâo=â_ºçRó_Ÿ™Â?ÿž—ó?eýw´_×U¶¿.Ýß»¾ð×µ×þß‚ü?­ÿâû³¼’Ð_[þ—ð-­¿«y©Ï׿öumþ{úü!ÿ€ÿ¾ó¿ýú<óüó7ÿ­Ýÿ,K»ý_šÿöýWÚþOÏÙÿgøWç›Úìÿ¼ýÿkóûþûë_{ÿoMþQÿÿþ?üvëÿ´Û=ÖŸ¶ýÿcÿÛ¶ÿÕ×ðüÊÿÏÁŸü >ô‡þô?¿þý~òzŸºº~Ä¿ßøãëv®$Ô× µ²ö÷×ü߇Ÿ¿ÿ|Yöçf.ésóµïü‡º^møÇãKŸŸ÷Wø•Ö_íø«÷c¬mþžü{úü[—víÝøŸ~üÛ:þØÿ¶íÿu=Êϰ~öõaÛåïþþót¼ÿ8ëß®þëC©üë·þâñuø£ÿtâÿÚñ_ä¿uú·×¯£ÿ1þ÷ÀþÃþÃÿýõè?bý©gÔ¿Ò®¿ù>øÖçßÒú—ú¥¯ºõŸåøIýÿÚ¯ÿC¿úãiøñoüüïõÿfý!ÿÐ?£Õÿ¿/¿¤úG[þ§ðoþOÎü‡üCþ__ûU{ý_kíÏwÍÿ}øùñ¹Ïûìÿúî?µí{ú,þžü{úüÛ•ìÿÆóÿ}RþöÑ?Rÿúýÿÿ?þüÿô?>ðOÿwú¿@èOÿoú6þ_—Ú]ûþ‡ÿmó?ýmï?Öõ8¾ôþîëÝûIáK¿¿ýn?á}Ûü‡û—î×~<žþ¿ôÍõŸý‚¶õsŒ¬«,þ/óÿ'׿$~Ògþµã?Wôßôçv½Uÿ_Ë¿ôó×ÃOëÿx|Iÿ[—ÿíýÿ¤ú¿Ô¿¬¤ÏßÝÿÏjÿgmúOsÝúwÿ˶õWßÿPÛþÅþÃþÃÿOü‡þ‹À¾ÕþŸôÿ¡ÿý¬öÿ¡ÿµmù_î_Ÿ•ο6ÿIñÓž?øù‡üþSûÿ=ÿo쿈ýOÿOøß.ÿ[ÃýÿÿúýÿÃÿð¿%þ·žÿþœáüÿºæó'·ÏZó¿òùßúùŸäÿÚ¦ÿºö…Ó]ðÃýÇ8ÿ2ÞùŸOæ?sþ÷ªÿåñ|Pª~Yüÿ\ÿ»òùyÿ;ëùÿšçÏÆ=ÿoéüçÿ9ÿÏþŸóÿœÿ±Yÿ§ýüwü ÷ßÛ\ãì°ÿ9ÿÏùüøÿðÿÙóÿaÿqþúÛ¤?õÿðŒP‡d4ÿ›•WiüGÿÁþ“ö’ž¿¥þßuül»ÞZÿ»´ÿ/þgÅþGÿ“ÿEý?»ñì?Ûöñoä?ùvã_Òþ¥}öŸãõÿ¡þ?õÿ©ÿOüßBüDÿß'ëÿKôOŸó¯äÿ“ÿ¯iÿöé_ߪ´ã¿øÿéÿi7ÿcYöôÝžïŠþçùc<ãÿüñ¡&ʹæËñzü÷gà¿ûùµáCè¯+?ίóôÉëOÇÿÙó/ý•óéþï}~øþ·ÌÿàoÓþvýi9|è¯[ÿU[ÿê×…ÿޝWòsÿ½#üüøýç#Éß~ø?}þÑÿÈúߺò×úþýþ‡þvéÿÿ_8ß¹O¼:ÿÙ?Îg¥ÇKá§ò¿ÀŸø7ãsëÿ¸W̽¿ŸÙå¢në3-?Ã÷ë×n|ü—ÆŸ¤ò_oÿÛ‡þ2ù·,uðkâ5Ï{þ~¿õ—²™Ãý7ü¯õÿ'忬þCýî¦>ÿ» þüoü?1ýsë¿mÿ—£¿¶üoÇ¿~ÿ·Ç?æíõo=þFüûû?oŸ×Ø_Rû_ÿ/Å_ºÿï7ÿéù%ÿü?øŸü¿ûôùvù‡ÿÿþ?üýýì?éùíø¯]þÇþçüãÏxÎÿ“ÿÅùèo1ÿ[çüÉ8ñ/›þ¿+úçöÊ©ïÉóuìòÿ9ÿÇù?Îÿÿ'ÿßrþ?ö?ñâÿÄÿ‰ÿÛÖ¥øg‹üª‹ÿjÇÿ9ÿi•þÄÿ±ÿðÿC«þíþ3šð·ñá³f|ý»Æ[Ÿëë_êÞÇ‘öýh]Ž×ãÏóò«L¿wûÿ¯ðèéÿÿû-Ï_ižåóßæ?ò_ýýÓ¿ïõß¼ý!ÿÐÿÚô—ÄŸ¥ó?Žü×ê?ÿ!ÿŒ×^ÿ:öç8ë_ú+¥ŸÎo¿ýŸTÿëØÿè]þÿù÷ôù·)ÿÐÿºþ?mùÛOÿHý?èô?þüÿøÿñÿãÿ>ðÿIý¯ÿÁþÂþƒþøÿlúÿ­ûÿ´÷ÿýö_ï¨?ÿÃÿßÏÿàoÛþ_×ãøí³×ûøúþÕóçÆ¯k~¼~<þï7?þ -ÿmþ¶ë­óÿãšþRøñøû{ÏOÇëGû¿†þ¥ùÑþ—>ÿ'çO:>ðKÝû»¯u÷Ó[ÿ­xõ¥ŸÞë}æé|ž¾Eÿ×É?)üëñ%ýo]þ_õÿ;Îg»ü*éÿ«þgµúÿz|üµ¾ÿ•þ5ë¿Gÿ»uí»þ¼ËÏ_¸ßö/öŸmûÿ?þ?àøœÿ·–ÿk=ÿøú_Ûþq¼õü/övöðóým>ù?äÿaÿ“ÿÿ“ÿGþþ?üøÿÐÿœÿ‡ÿáøÿ{ùÿç畵ÏÚú³¼*lŸMóÞ¿ùï~¯ëÓ|ÿÂs?~»¾õ' ý_^ßï ?®oõöóþÞåŸ?ŒjÃø#Ãßú…þÅ¡?ÑÖ)ô+:ö9î±þ}“ÏðKëÿü\ñó‡ëûÏRø¤¾Wšÿ«y©…ýµé¿®}áÇpÂýSó©-ÿåùß²üçþÇë±~öîÞø3y×'ÿµÿé÷?¯ÿ£=¦ÿ^ž>gû*7ÿ¹þ{5ø§ûÿþ;ößJóÌ9üRú#w¿óýG\ÿÒó3õãµõß;žÿIóo]þ±ÿ`ÿoÿÒþ'·_ê³ÿÐÝYßÿ]ÛÿçþÃmòw¿ÿ‰û?°ÿÁþo¥ù—;ÿÛ¶þîÿEþãÿÃÿ‡ÿϪÿûÏ:ÿCËô/ùgïûïùµýŸø?dþËw\×ö¿iãÿÉëÒø4þ§mÿãO©|´kÿy9þ“Õ÷ÿ¯kKü­—ý?büÏ’ýþ'ÿëN¼zšûÆÿGÜÿ[ŠÿcÿÙ¶ÿˆÛ†OþŸíøWëþ§^ÿßËz½¾ðj‰¦Ççìï$ötÿ7Úþþ×ÿ[Êÿ#þoÙÿ;¢ÿO¶ÿZW‰ÿíŽþéÿ!ÿŸüÿ‘òÿïÚRý£Åÿ_#ÿö¼Ø7þïwÞ­ë4{çݺN³wÞ-‹wË2ÍÓìݲx7OÓ<ÍÞ­«wÞy·®??¿Þ-‹wËâݺN³wÞ­ë4{çݲx·,Ó<ÍÞ-‹wë:ÍÞMó4{W¶ÿ­Äÿ·zñëÏÅÏÕ÷JãKŸøÀÿ<|©üy7üþïö¿¾>ô‡þÚô׬?ôtüŸ>ÿRÿCüuëoÁÿð¿mþ·‹?û4|ë¯Ö÷µþcéÿgÎX¿çךëýø¿tÿ÷ÿº§·wgúþïëÃõËÿ¯wÎÿ”Æ—öäÿëŸ?Ó>ÿbýüçÿmïØÿÛÅŸó?Ôÿésþ»þ<öHçÿÑœÿ·.ÿñÿáÿÃÿgÓÿ‡ýÿCê¿PÿÏný'Íú#ãøõêïRÿOÿi‹ÿPÿÉ»ók­ÿ½_ýÿLß}âëwë×Ùÿ:ñ?âÿèê?Sÿø?öŸEûø7òßzþŸåøWiÿÛÏ-ùuõGuúÿPÿŸúÿÔÿ'þOýÿß8õÿ¥úGÿ!ÿŸüÍúÿRû¯Ýÿ¥¯o¯Û_áÓôõÒýãñRø¥ûß}>ðÿïÅÿßw_¿Ó\÷þøOŠÿùß^ ÿÒøò¿<¾÷áß½?ô‡þ:ô—çËòžŽ¿tý×ůïο$ÿýµ>·ýþþ±~U?ü—¥~Mý­xüuý-øþ‡ÿíâoÝþßü¿Gÿçüàßzù·ûÇ{ã¿]?Óÿõý¾ðÏøá³ÿÛÓÓ—¡͵¾ŠûÜHé¯mÿ×à_ZWóÛ#áóã|j®yþ§,þ1Âú—àßCþåâŸmó7þ‰þGþëÈÿsß´ò÷,ÿÓr™ýúýýíÒÿ?ñŸ¢ýÃu®ÿÿRû¿%þ³×_-ûÇXþß•¿÷Æçí™»øŸ÷ùÿÌøß=ú”÷ÿwç_2þüüšëO[¾·ùÿC>wlß_Ïûÿõà#ÿ[öÇýŒtþuåËþï¸þjæ/¿ÿ{ÿõóÿ$þ‰ýÿ´ü—œýußþ×µtŸ_{þÉÿ#ÿþ'ÿϪü³îßÅÿ‡ÿÿŸeÿŸÌþë‘ÿ¯ÿ‡ÿ±ÿ±ÿµÎÿ<ýü øƒÿwáÿYý¯-ÿ¥ú? ÿ³¼‚þÐ_‹þÒúoáüÉuý°ýýïÕÿûäù—¶þý俾´þÝ™þË’§¿wòúwÒðjñÏÏýžÏåø¿fý½^SüïÝ™ÿµ×¿6ÿük¯ÿè]ßùOÍï~þÓýolÊ?ìõø3ãÿÇþÿžý_Qþ¾ùºöú·®ÿ´ég}ý=Gþ÷‹ÿkÇ‘ÿÐ,øØØøÿ¡ÿçý_vûÿÒÿIþô¿Öïÿ£ÙÿkœþÏiüKýûõê×1Õ/+×ÿGâÿÊ?íþ_yû¹mýݱèÿ1èßî×ÿO[þÛíÿ‡ý‡ü³*ÿÿºý¿ÇYÿ6û_Óÿý¯Éÿß#ÿ¤ú_gÿo]þ¡ÿuýùüç6ùÛ3ÿ¿^ÿHý?èô?þüÿøÿñÿãÿ²âÿðø¶ýýý¡¿]ÿ¿uÿŸöþ¿tþ¹~ÿÕvþþ‡ÿáðÇþ?½¯ÿû;ÀÿæñWó¿?Oõã¯è?ü³þûûM]?Úÿ©õû÷{oþGµÿ¯žÿï7ÿüÞåç/Ü/ÏÿµðKãÿ~óã¯äÿgßk¯ÿúçM¿¶¯ÿ¿ßðû}¿¤Óö\ÿù¿¿<þÊþDþß“ÿ±üê£ëåoýø;Ïÿo4ú׬ÿe©÷_^ÍÿëOÛþÅþ³mÿáÿçüþðÎÿÛÉÿµžÿGüý¿®}íÏ6ÿ—¶ýKþû?Ëû¿ñøù‡üÃþ'ÿ‡üììøþ'ÿü?üøÿÐÿèøþ‡ÿá)ÿÿü¼üQ{ü·ç{U,Ø>›æýüü»ßv½4~»¾ÕWØãü§Á÷îšã78µð½ë ?®oõ9öòß:þÓ|î<ÍÇ~(û~Åûï÷X%ø¥õ_óüûçÍáSÿ8ÿá>ÁŽÙ÷‚)Á‡þO£_øÚòÿ}ùóuãSÏÿÉë’ü×ò”þïûõ›²§cúíáõœÿ\ÿ­óúY–úñÞûo¥ùÿ~¥ñÒûë­ÿÚüYþƒ¶þ“â~~ïîÍ¿w}ç?ï]~¼mùÇþ‡ý¯eø÷íÿã>Gºþ÷÷ë³ÿŠŸšÓû2ömò?oÝ=9îþǦý‡þ:óÿ]ëïyòÿþ?üßâÿÃþƒÿ¡¿]úkûG¼nÝÿŸŸ¾þÏç­ÿ÷ã/ƒ_ºÞÿ{7þ#ÿiÛ_÷ñ?ÎßYyw'þ3šÿ¿6þÖËþ1þgÉþGÿ“ÿ¥¿qÿo)þýgÛþ#þmòÿlÇ¿Z÷?ûõÞ3ÿ©lÿçãŸçñûøçë}Éÿ—×Ï}÷£íÿGàÿ±óŸ­çÿÿÿ&ÿïˆþ¿Oî¿îûŸúÆÈÿ'ÿ$û÷®ý'Íÿ׎ÿâÿo“½âÿÞyçݺN³wÞ­ë4¯«wëêݲLó4{·®Þ­ë4O³wëêwÞ­ëÏÏ߯wËâݲx·®Óìwë:Íëêݺz·,Ó<ÍÞ-‹wë:ÍÞMó4{W¶ÿ­Äÿ_?¡CÝû»?wï'…/ý>øƒ¿ ücùËçôõX~´ã¿É§íï~ ŸÒøôõðü%üÛàß½?ô‡þ:ô?ö ã¯êë…ZRçû^GþIñ—®ÿôüIç?UÿižÒã÷ûç°>¯ü±ÿ@Žÿf¿ÏS -~ÿüø`ÿÏSêùáøß6ÿ󮧼ý¿Õ üû=Ö¼‚üÞ«ž`îómüñóëûõÆ?ý\Ð_šÿ"¥¿¶ý_¿´þ¤þOíõ¯]ÿ|„õ/Á_ºþõë¿¢ÿ‘ÿzò¿ÿh“¿õñöèëúúÛ¥?þâ?Eúsëü/]ÿuü{~?þÿvüÏñŸiÎå_ó'[âGÇçËÕ›©™¿Òø|=›»øŸãGå%ø¥øÕ5|iüKJ©|i›Éøóók®?mùnýüò_·þŸ¾ü§þ‡æùçÖ¿åóߨÿØÿû½‡ý¯kÿè>¿öü·ÙÏáüŒtý‡ý˲´ì¿êƯÇÏßþ˜æ^û?øÿ‰üçöXÿ£ìÿmÉ?ëþ]üøÿðÿYöÿÉì¿ôú›ætÿó+þÏóË}ûë|þÿêüýýßnÿJùÿ™ö/øƒÿ·âÿYý¯-ÿ¥ú? ÿ³¼‚þÐ_‹þáüK\ïêEÃ0?áï}}¯e9î]8—±¿}¾¿¿vý»¿øùR×—åˆ_ù/…=>¾¾Ÿ£ÿ²äéï]zþýËõ7ÿ¤áÕ⟟û•ÕL× óRSp”ú:üÿ=ò¯mýÇóÖcþSó»Ÿÿ˜,Ë?ìõø3ãÿÇþÿžý_Qþ¾ùºöú·®ÿ´ég}ý=Gþ÷‹ÿkÇ‘ÿÐ,øØØøÿ¡ÿçý_õ¿ž^ÿJZÿT¿þ§6ý­ã¯½þ¥þï}éï÷üù~¿õ÷{×ÿÿîúÏeüSñʿ߾þÿýýîÂOÍ<~žÒtéáÿ—Ê¿’ÿ"õ~ž>åÿo[wìäú ú·ÅŸ¥ôGþ§ð/¯¿~ò_[ÿcÿ!ÿìÉ?äÿÑ>ïaÞ±ÿÇYÿ×öfÎþìG)ü¶ï÷ÛÿIõ¿Žýþ×åÿï‘Rý¯³ÿ·.ÿÐÿºþ¿|þs›üí™ÿ_¯¤þô?úÿ?þüÿøÿéDÿwðú¿ÓÿúCúÓÿû=þÙùW9þºû?øþ·ÍÿôÿµlÿoþÂ{ý'Ïý?Χæú׿äòûßnÿ¿§ãÿ}ý¿±ÿéÿ ÿÛå[ø£ÿñÿáÿCÿ£ÿáøþ·ÆÿäÃóžóÿœÿoÍŸ”®'íüOò¿ ¿&ügžéwþG?ÿÙúùß–úÿ=Ï´Ôߪ_®¿Eþ¿fýûοpþóÿìØßZ|ÏùêÿX>ýÏùä?þüÐߢÿûþ‡þvéOý?ÛïÛæ¿Ÿÿó™ë¿þ#Õÿk‰ÿHã#Ô’ôêqþO×ÿ/‹ŸÉ÷ÿºñ?ëö?úßvü‡ú¶ãÿضí?âßÈòÿìÆ¿Úöý꿎Ðÿ•úÿÔÿ'ÿø¿Õúÿšþ?íý—´ÿ³üü+ùÿäÿ‘ÿßbÿIóÿG¨ÿÿŸþŸ–û¿lü¼_¿ÇúaþÎü¿Íi|Xÿñþ øÀþ8ð_¯¡fÊñïøûŸ‚_z|¨¿|¬3|èý5è|ÝìÊ`_[qûÞ~~üþóí~óôMø?}þ¯Ë’þ½ú^oüc¸wñ¿zîk|àøþ·‹?öÿ~|ðKÅ×ð¿u¼õýß™/§¹î½tþǰÿËøçŸ_oþZÇŸ_?{},ý/}þçÍ?úù?Žüד¿øÿÐÿõ?ô‡þøÿ-ÊIþO ü}ÿÓsþÕ)üTþøÿ~ný}ú§ìóÃJñŸëý×þþ!_øjÿ•ëÿR'Sý_ÊòW’ʽýoúKåß}øWøÇãKñ¿uí»þbúû‡ãÓ<¶þûûM]¿oÆã÷çrø·ÂÇãÿ¿CÿiN˃öýË=ú^þ·á_¿ÿKã=#¬ëñ7âŸØßÖíÿØ~oµ?ïÙÿZöÿþöoëüÇãÉÿ#ÿþ'ÿïîþߊüÃÿÿÿþ?«þ¿>ö_¯ü+-ûË.ÿcÿ“ÿ|àøä‘ÿ ý9ÿ«}þGûü“õó¿÷_ûο¶ýÏù?Îÿqþóöò¿Èÿ·ÿýOüŸø?ñâÿ6õ_mü³^þßÃ_+þÏùO«ô'þý‡ÿú[¥Übó ½ÞÇ×ý'¾uü<¥úçÔõßH¿ê¿1*|ëóoiýKýÇÒ×kùW¦ÿ'üÿ-ÏÇÿ¯ý*ñ?ôà¿üø7~þ÷úÿ?³þèMø}ä—TÿhËÿþíÏÿÉùƒÿÈ?àËàk¿j¯ÿãk­ýù®ù¿??>÷yŸý_ßý§¶ýoOÿÅÿÏ“OŸ»òýßxþ¿OÊß>úGêÿAÿ£ÿñÿãÿÇÿÿÿð|½øOmþÑ{áëÅ,ÉèþÇÿ‚ÿûþ‡ÿ­ú¿ñÿ[µÿ×õ8~]þÃu•ùãñëš/…¿®÷üŸWøoó·]oÿpÿíý?×ô—ÂÇ“ÿGþ_yý{WûþîkÝýôÖ¿õøÿ}â3ò­ú¿NþIá_/éëò_ÚÿOªÿ¯û—Õéÿ÷õÿ³±ÿ•þ5ëÿ½ý/ÛÖßÝþ‡Úö/öùøÿ‰ÿøÀ'ÿ·-þ#?•ÿg=ÿ—øçÿ9ÿÊùöœÿçü?óýmëü?ù?äÿaÿ“ÿÿ“ÿGþþ?üøÿÐÿß|þ þ‡ÿá{üÿóóÊÇÚç?mýYþ=ÿ+W1ôùù þË×õi>Žá¹¿]}~ìÿòïÿ¾ðãñÓ|„ÿúü¯àÇÏFµáü‘áOó¹ÿÑÖŸèõïØ¯hßç¤Çúû&ÇðKëÿü\ñó‡ëûÏRø¤¾Wšÿ«y©…ýµé¿®}áÇpŽý¿âùÔ–ÿòüoYþs -ÿãõX?{woü™¿¼ë“ÿÚƒÿÆíÿw¤W®_}ž>gû*7ÿŸîÿ—âÿ˜rø¥ôGî~çû¸þ¥çgêÇkë¿w<ÿ“æßºücÿÁþß2þ¥ýOn¿Ôgÿ¡»ÿ²¾ÿÓÿÁþo¥ù§Ýÿùÿÿþ?«þ?ì?ëüý-ӿ䟽ï¼çÿÕöâÿù/ßq]Ûÿ¦ÿ'¯Kã?ÒøŸ¶ýwŽ?¥û]ùÏËñŸü«¾ÿ][âo½ìÿã–ìô?ù_wâÕÓÜ7þ?âþßRüû϶ýGüÛ6|òÿlÇ¿Z÷?õúÿ^þÓëõ…WKü3=>gÿ{'±o¤û¿Ñöÿ#ð¿~üßRþñËþßý²ý׺JüowôOøùÿäÿ”ÿ×þ“êíø+þÿù·çžñï¼ón]§Ù;ïÖuš½ónY¼[–ižfï–Å»yšæiön]½óλuýùùûõnY¼[ïÖuš½ón]§Ù;ï–Å»e™æiönY¼[×iönš§Ù»²ýo%þ¿õ ùû=öÙú½~Âûã÷^õrŸoãŸ_߯üxüÏOú¹Àümã/ÝÿHñ/íJø¿ûüOüúýô‡þÚô×ìøtü{¬ÿqû?–ýo}ð×íÿÿÃÿð¿MüÙÿœð¯x÷õîý¤ð¥ßgÿWë–ÒTûß»ºõ$h¯ÿ¼üoí?\ßÿylý_Æ¿Çú×ïÿŒþGþ%ÿeò·ßù?«þ?ô¿ýý¡?þä=ýÃúñ»ŸÏþ³àSÿÑFþïUþåþûËR?J×ÿ»þú¸þkêWåÎ_·žïuþ[ÿüO;ý{ÈŸVøÿÚñ[þ_\ÏLwý(ÿïßÿ¾ëÖë?ÞË_—Í¿6ÿIñÓž¿Ï_ýêŸPÿ û_»ÿÏ<µØ_wímûG‚¿6üóOý/úÁÿ–ëØ–Öý¿øÿðÿáÿ³ëÿ“Ø=úÿè×ÿ…ÿ±ÿ©ÿ‹ÿüÁŸøýŸ¬õ‚þøÿ¨ÿ‹ÿú6ëÿY¯ÿ+ÿ÷ú—Ï<žú¿Ôÿí¹ÿ!ÿþ›àcÿcÿÿÇþ'þü¯“ÿ}ã¿#æãÿƒþVâÿØð?ô·IêÿQÿqDúSÿòóõÿÚýÏíõÿF¨ÿ’ÿ¦þžÜÿ?Fý?êÛ«ÿƒþ§þ#õßìÖÃþCþ±ÿ±-ÿG¬ÿ=FýsëýÊû¿>õÏdzÿ©ÿOýêÿSÿß’þÉÿ÷Éúÿ9ÿWiýõÉÿAÿ£ÿñÿãÿÇÿÿÿÓúžöó»Á»šÿ³þØôOølÿyzüžþ©ñRø)ýwþàþ/Y¸—ï›|º’ÿgù)Å“ßó”‚_Æ??>ÈÿyJ?ÿ6øÓœ®4ÍçüsèýÇû½dþýÝߺû=©üï7ÿw¾Öÿ¶ŽãS×—¥þÒðKø”Ƨ®ïŸþ‡ÿ-ó?øÛ¶ÿ[â?{ÿÝ<ÕßüϱÿG~ ý¿i¼Ìÿ—Ž?„ÏËó¯mÿËâ?=êߎÿ‰ýýiyžêÇÇߟ§‘Ö=þ{¿»týÇ÷k‡=~½‡þýz?ϧŸßŽüßǯúéÿzù»×ÿÒúÖ÷Úôo™ÿúñåù×^ãØßØí?üÿÄ$ô—â_C¿»ðûÑüÁß -þ{]–Ÿú-ÇWòñ™P“9WÿùÿÜøãõøï{ø§ð‹áaŸ?î?U¿ª/Ié/[ÿË"ÿ{Ï{þ~¿õ×Fþ—Úÿ=ì_Íú—Öå¿vÿ7mù/ëÿ–î?楦ÿàóê¿öääòûû¿‡ýÙbÿ?)ý±ÿ±ÿáø_—ÿíâþÇÿ‡ÿýo[ÿÃÿð?üo‡ÿ­ç?2žóÿœÿoÏŸ”®?íüOò¿ ¿&ü'žéyþgœó6Ï¿îéuìÏžÞ\Ó_šÿ_þ¿´?ºsüÿ^çßҟלÿãü çÿ8ÿÏþ‡ý¯­ñœÿ¡þç¯ÑœÿGþãÿÁÿýmùÿ°ÿàèOýêÿY¯ÿÔ¯þÈÿç×OüGªÿ'‹ÿ´ÅÿÆ©ÿ”Æ¿äïWÿGÇÿ/Ÿõ³?uâÄÿÑÿÔ¦þñì?‹öñoä?ùvã_-û¿í{}ë¿êôÿ¡þ?õÿÉÿ#þÿWÇÿ7Ný©þ‘ÆÈÿ'ÿ_7ÿ_fÿµåÿSÿÿ?ý?­Åÿ_Oô¢ÇÿíùÒ×·×í¯ðiúzéþñx)üÒýï>øƒÿ÷âÿªEr¬’ü'Åÿü﯄i|ù_ßûðïÞúCúk×?|:þÒõ?^ýëRý«cý´~øëÔƒÿáøß.þÖíÿÍó÷{ô_^Áþ­—?q»ÿq¼w1þÛõ3ý_ßï ÿŒÿ>û¿=ý§ùÜÿæJ_Å}n¤ô×¶ÿkð/­¿«y‰í‘ðùq>5׿vÿ›Ö¿ÿòïÉýÐÿÈéú?öMë!Ïò?-—Ùÿ¡ÿÑÿÐß.ýñÿÿ)Ú?\ç:ñÿ/µÿ[â?qÿ’öó—mò÷Þø¼=#ëÿ"•ÿÏŒÿÝ£Oyÿwþ%ãÏϯ¹þ´å{›ÿ?äÇöýÕø¼ÿ_>ò¿eÿwÜÏHç_Wþ·ìÿŽë¯fþòû¿§ñ_?ÿ7ñOâŸØÿOË©¯ŸZ—ÿ£iÿè>¿öü“ÿGþüOþŸUùgÝ¿‹ÿÿþ?Ëþ?™ý×#ÿ_7þÿcÿcÿkÿyúùðÿïÂÿ³ú_[þKõþfyÿý¡¿ý¥õ¿–åü¹wéúRÞ¥ëYqþ¥­þU?ù/…/­{¦ÿ²äéï¼þYàŸ4¼Züsãs¿çó_9þ¯Y¯×ÿ{wæíõ¯Íÿß#ÿÚëÿy×wþSó»Ÿÿtý;›òû_=þÌøÇÆÿ±ÿ¿gÿ'íŸöŽþkŸ\ÿÖõŸ6ý¬¯¿çÈÿ~ñíø/òúûûÿ?ôÿ¼ÿ‹þ—¶û?ÒÿÕâú§ÿýèÿcµÿòý/«ÿÚ¯ÿ¯¶ü·ÞÿûùgOþ!ÿ{õ¿n³ÿÇYÿÒþ»Rú?§ÿozÿ'Õÿ:ö?ú_—ÿ¿GþIõ¿ÎþߺüCÿëúÿòùÏmò·gþ½þ‘úÐÿèüÿøÿñÿãÿÇÿþàþïÇ_zþ©Ÿü×ÑÿÖå?ôGÿ÷ñÿÔïGGòÿY÷aÿÃÿð?þoð'ÿ»Öÿ¸®Gÿcíø«ø—&üúÓxòÿðÿß_ùóKã¯âÿc¬âÿ²÷Rúõ~žO?¿ùÖsOý_/÷úYêŸÿªþç?ôèß2ÿõãËó¯½þƱ¿±ÿ,Úøÿñÿÿð·ÿ—ÆÚüËãÈ›ù¿ÄÿØÿqþ•øû?Îÿsþù‡ýoòÈÿÃþ'ÿþ'ÿü?üøÿðÿ¡ÿíœÿ‚ÿáøßÿ¿žèE=þÛóqëçëÛëöWø4}½tÿx¼~éþwŸï»ñõ"9ö?¹ó^º¾¤÷—>ÿ}øñü•þ•îýŸEÿ¾ð5å»<ÿ[žÿüóóÊgÞ¿zþýýÿÁß®—Æo×ÏøËò_¥ò¤þO¡ýuÿ«øûýçÿÓý÷¾{ü¯ø3µþJã÷×cþ×_ÿÒüYþƒ¶þ“â¿Ýÿ8ÿÛ<×οw}ç¿­þ©Eù‡ýÏþÖúõûöëñŸt}•öK÷÷_ù罿?ûÞýŸvÿaýýuû_—~Ö×ß3å?þ?üøÿ¾Áÿ‡ýÿCËö¿¾ÿQ¾uû¯mþûù?Ÿ¹þûúÿýßþÿ#üiîÿ‘Æÿ´í¯6üóâHÁËÿ\üg,ÿÿ½øYÿýÿgãÄÿÑÿ–ã?5ñïX^ÅòL:ÿÚòßzüûÏ®ýGüùOþŸÝø—dÿô¿Dþmû—e©·ÿSñÏÜøãõãß-ú¿ïþo´ýÿ'ùÿ™ùÏÖóÿˆÿ“ÿWÓÿ§¿ÿjñ?-K¯øùÿäÿ–ÿÇþë‘ÿ¯ÿÅÿßÂ?{[»Wþã'íÿãó[Žÿou$ãן‹Ÿ«ï•Æ—>>ðÿyøiÿƒwWò%ö?¼~ ÿºýwÞÿ¡ úCmúŸëOÇõ«Ãßmõ¯¯ëO?ÿ§Ïzÿïß‚ÿ ÞôÁÿ~ÿšýgnÿÿÃÿÖùß.þì?Òð­¿ZßÿÿbþºtžGµÿkñÓž¿óŸ–¿AÎÆ×½ë7~\ý/{þ§Ì?úù?¢üÿ”üeÿ‡þ·®ÿ¡?ôÇÿoYþÛ>ÿ þíüÿnþþûákæÿÅys}Î_œóÿÒyyéü»=^¥øW]þß=øwâo=â_ºçRó_Ÿ™Â?ÿž—ó?eýw´_×U¶¿.Ýß»¾ð×µ×þß‚ü?­ÿâû³¼’Ð_[þ—ð-­¿«y©Ï׿öumþ{úü!ÿ€ÿ¾ó¿ýú<óüó7ÿ­Ýÿ,K»ý_šÿöýWÚþOÏÙÿgøWç›Úìÿ¼ýÿkóûþûë_{ÿoMþQÿÿþ?üvëÿ´Û=ÖŸ¶ýÿcÿÛ¶ÿÕ×ðüÊÿÏÁŸü >ô‡þô?¿þý~òzŸºº~Ä¿ßøãëv®$Ô× µ²ö÷×ü߇Ÿ¿ÿ|Yöçf.ésóµïü‡º^møÇãKŸŸ÷Wø•Ö_íø«÷c¬mþžü{úü[—víÝøŸ~üÛ:þØÿ¶íÿu=Êϰ~öõaÛåïþþót¼ÿ8ëß®þëC©üë·þâñuø£ÿtâÿÚñ_ä¿uú·×¯£ÿ1þ÷ÀþÃþÃÿýõè?bý©gÔ¿Ò®¿ù>øÖçßÒú—ú¥¯ºõŸåøIýÿÚ¯ÿC¿úãiøñoüüïõÿfý!ÿÐ?£Õÿ¿/¿¤úG[þ§ðoþOÎü‡üCþ__ûU{ý_kíÏwÍÿ}øùñ¹Ïûìÿúî?µí{ú,þžü{úüÛ•ìÿÆóÿ}RþöÑ?Rÿúýÿÿ?þüÿô?>ðOÿwú¿@èOÿoú6þ_—Ú]ûþ‡ÿmó?ýmï?Öõ8¾ôþîëÝûIáK¿¿ýn?á}Ûü‡û—î×~<žþ¿ôÍõŸý‚¶õsŒ¬«,þ/óÿ'׿$~Ògþµã?Wôßôçv½Uÿ_Ë¿ôó×ÃOëÿx|Iÿ[—ÿíýÿ¤ú¿Ô¿¬¤ÏßÝÿÏjÿgmúOsÝúwÿ˶õWßÿPÛþÅþÃþÃÿOü‡þ‹À¾ÕþŸôÿ¡ÿý¬öÿ¡ÿµmù_î_Ÿ•ο6ÿIñÓž?øù‡üþSûÿ=ÿo쿈ýOÿOøß.ÿ[ÃýÿÿúýÿÃÿð¿%þ·žÿþœáüÿºæó'·ÏZó¿òùßúùŸäÿÚ¦ÿºö…Ó]ðÃýÇ8ÿ2ÞùŸOæ?sþ÷ªÿåñ|Pª~Yüÿ\ÿ»òùyÿ;ëùÿšçÏÆ=ÿoéüçÿ9ÿÏþŸóÿœÿ±Yÿ§ýüwü ÷ßÛ\ãì°ÿ9ÿÏùüøÿðÿÙóÿaÿqþúÛ¤?õÿðŒP‡d4ÿ›•WiüGÿÁþ“ö’ž¿¥þßuül»ÞZÿ»´ÿ/þgÅþGÿ“ÿEý?»ñì?Ûöñoä?ùvã_Òþ¥}öŸãõÿ¡þ?õÿ©ÿOüßBüDÿß'ëÿKôOŸó¯äÿ“ÿ¯iÿöé_ߪ´ã¿øÿéÿi7ÿcYöôÝžïŠþçùc<ãÿüñ¡&ʹæËñzü÷gà¿ûùµáCè¯+?ίóôÉëOÇÿÙó/ý•óéþï}~øþ·ÌÿàoÓþvýi9|è¯[ÿU[ÿê×…ÿޝWòsÿ½#üüøýç#Éß~ø?}þÑÿÈúߺò×úþýþ‡þvéÿÿ_8ß¹O¼:ÿÙ?Îg¥ÇKá§ò¿ÀŸø7ãsëÿ¸W̽¿ŸÙå¢në3-?Ã÷ë×n|ü—ÆŸ¤ò_oÿÛ‡þ2ù·,uðkâ5Ï{þ~¿õ—²™Ãý7ü¯õÿ'忬þCýî¦>ÿ» þüoü?1ýsë¿mÿ—£¿¶üoÇ¿~ÿ·Ç?æíõo=þFüûû?oŸ×Ø_Rû_ÿ/Å_ºÿï7ÿéù%ÿü?øŸü¿ûôùvù‡ÿÿþ?üýýì?éùíø¯]þÇþçüãÏxÎÿ“ÿÅùèo1ÿ[çüÉ8ñ/›þ¿+úçöÊ©ïÉóuìòÿ9ÿÇù?Îÿÿ'ÿßrþ?ö?ñâÿÄÿ‰ÿÛÖ¥øg‹üª‹ÿjÇÿ9ÿi•þÄÿ±ÿðÿC«þíþ3šð·ñá³f|ý»Æ[Ÿëë_êÞÇ‘öýh]Ž×ãÏóò«L¿wûÿ¯ðèéÿÿû-Ï_ižåóßæ?ò_ýýÓ¿ïõß¼ý!ÿÐÿÚô—ÄŸ¥ó?Žü×ê?ÿ!ÿŒ×^ÿ:öç8ë_ú+¥ŸÎo¿ýŸTÿëØÿè]þÿù÷ôù·)ÿÐÿºþ?mùÛOÿHý?èô?þüÿøÿñÿãÿ>ðÿIý¯ÿÁþÂþƒþøÿlúÿ­ûÿ´÷ÿýö_ï¨?ÿÃÿßÏÿàoÛþ_×ãøí³×ûøúþÕóçÆ¯k~¼~<þï7?þ -ÿmþ¶ë­óÿãšþRøñøû{ÏOÇëGû¿†þ¥ùÑþ—>ÿ'çO:>ðKÝû»¯u÷Ó[ÿ­xõ¥ŸÞë}æé|ž¾Eÿ×É?)üëñ%ýo]þ_õÿ;Îg»ü*éÿ«þgµúÿz|üµ¾ÿ•þ5ë¿Gÿ»uí»þ¼ËÏ_¸ßö/öŸmûÿ?þ?àøœÿ·–ÿk=ÿøú_Ûþq¼õü/övöðóým>ù?äÿaÿ“ÿÿ“ÿGþþ?üøÿÐÿœÿ‡ÿáøÿ{ùÿç畵ÏÚú³¼*lŸMóÞ¿ùï~¯ëÓ|ÿÂs?~»¾õ' ý_^ßï ?®oõöóþÞåŸ?ŒjÃø#Ãßú…þÅ¡?ÑÖ)ô+:ö9î±þ}“ÏðKëÿü\ñó‡ëûÏRø¤¾Wšÿ«y©…ýµé¿®}áÇpÂýSó©-ÿåùß²üçþÇë±~öîÞø3y×'ÿµÿé÷?¯ÿ£=¦ÿ^ž>gû*7ÿ¹þ{5ø§ûÿþ;ößJóÌ9üRú#w¿óýG\ÿÒó3õãµõß;žÿIóo]þ±ÿ`ÿoÿÒþ'·_ê³ÿÐÝYßÿ]ÛÿçþÃmòw¿ÿ‰û?°ÿÁþo¥ù—;ÿÛ¶þîÿEþãÿÃÿ‡ÿϪÿûÏ:ÿCËô/ùgïûïùµýŸø?dþËw\×ö¿iãÿÉëÒø4þ§mÿãO©|´kÿy9þ“Õ÷ÿ¯kKü­—ý?büÏ’ýþ'ÿëN¼zšûÆÿGÜÿ[ŠÿcÿÙ¶ÿˆÛ†OþŸíøWëþ§^ÿßËz½¾ðj‰¦Ççìï$ötÿ7Úþþ×ÿ[Êÿ#þoÙÿ;¢ÿO¶ÿZW‰ÿíŽþéÿ!ÿŸüÿ‘òÿïÚRý£Åÿ_#ÿö¼Ø7þïwÞ­ë4{çݺN³wÞ-‹wË2ÍÓìݲx7OÓ<ÍÞ­«wÞy·®??¿Þ-‹wËâݺN³wÞ­ë4{çݲx·,Ó<ÍÞ-‹wë:ÍÞMó4{W¶ÿ­Äÿ·~!¿Çþ![¢×OxüÞ«ž@îómüñóëûõÿùI?øƒ¿mü¥û)þ¥ýO ÿwŸÿiƒ_¿ÿƒþÐ_›þšýŸŽõ?nÿDzÿ­þºýÿàøþ·‰?ûŸþïï¾Þ½Ÿ¾ôûìÿjýÏRújÿ{W·ž¤ñíõŸ—ÿ­ý‡ëû?­ÿËø÷XÿúýŸÑÿÈÿ±ä¿Lþö;ÿgÕÿ‡þ·£ÿ¡?ôÇÿü¯§X¿1~WãóùÀ|ê?ÚÈÿ½Ê¿ÜYêãGéú÷Ï_×MýªÜùëÖóï½ÎëŸÿi§ùÓ -?à_;~Ëÿ‹ë™é®¿åÿ½óûßwÝzýÇ{ùë²ù׿?)~Úó÷ùëï¯ÿAýêŸaÿk÷ÿ™§ûë®ý¯mÿHð׆ßcþ©ÿEÿ/øßrýÛòϺÿÿþ?üvýû¯Gÿýú¿ð?ö?õñÿ€?øÿ¡ÿ“µþOÐÿõñÿQÿÏfý?ëõeø÷^ÿòùÇSÿ—ú¿=÷?äß|ììâÿØÿÄÿ‘ÿuò¿oüwÄüoüÐßJüûþ‡þ6éOý?ê?ŽHê_~¾þ_»ÿ¹½þßõ_rø×Ôß“ûÿǨÿGýo{õÐÿÔ¤þ›ÝúoØÈ?ö?¶åÿˆõ¿Ç¨n½ÿOyÿ×§þùxö?õÿ©ÿOýêÿ[Òÿ#ùÿ>Yÿ?çÿ*­¿>ù?èô?þüÿøÿñÿZÿÏÓ~~7xWóÖ›þ Ÿí?OßÓ?5^ -?¥ÿŽcÀüÁÿ% ÷ò}“OWòÿ,?¥øoò{žRðËøçÇù?OéçÏãßšÓõ¦ùœý¡ÿòo¿—Ì¿¿û[w¿§ã/•ÿýæÿÎ÷ÃúßÖñq|êú²ôÃ?ðO~ ŸÒøÔõýóÃÿð¿eþÛöKügï¿›§úñ›ÿ9öÿhÂo¡ÿ7—ùÿÒñ‡ðyyþµíYü§GýÛQâ?±¿?-OãïÏSýøøûó4Òú¯Çïw—®ÿø~íð¯Çï¯÷Ðÿï¡_ïçùôóÛ‘ÿûøU?ý_/÷ú_ZÿÁúþO›þ-ó_?¾<ÿÚëoûûÏ¢ý‡ÿŸø„þRükèw~?úƒ?ø[Á¯ËòïS¿åøJ>>j2çê?_㟼ÿ}ÿ~1ü#ÌãóÇý§jâW5ðåñ/)ýeëY¤óïyÏßï·þÚè¯ÃÿRû¿‡ý«YÿÒºü×îÿ¦-ÿeýßÒý¼Ôô|^ýמüüCþaÿcÿ÷°?[ìÿçã/¥?ö?ö?üÿëò¿]üÑÿøÿðÿ¡ÿmëøþ‡ÿíð¿õüGÆsþŸóÿíù“Òõ§ÿIþôׄÿÄó/=ÏÿŒsþÏæù×=½ŽýÙÓûƒkúKóÿëÏÿ—öGw®“ÿßëü[úóšócœáüçÿÙÿ°ÿµ5žó?Ôÿáü5úóÿÈü?øÿ ¿-ÿöüý©ÿBý?ëõŸúÕ¹ãÿ|âúï‰ÿHõÿdñŸ¶øß8õŸÒø—üïýêÿèøÿ¥ñ³~ö§Nüø?úŸúÏÔÿ#þýgÑþ#þü'ÿÏnü«eÿ·}¯oýWþ?Ôÿ§þ?ùÄÿñÿêøÿÆ©ÿ/Õ?ÒøùÿäÿëæÿËì¿¶üÿqêÿãÿ§ÿ§µøÿ뉶§Ï¿ñ×¹Îõï¾.ý÷nøï~~møÐúkÑ¿Î~)åO¶:þOŸÿºúU×õÓúá_‚ÿ¾ç‡ÿáøß&þÖíÿÍ_õ÷{ô_]þ­—?q»^¿] >ôûÖ„>5©©ïIç_SÿÖà_ZWó’‚“ú\›ÿÎýg¼»’Ÿmýo®ûÏŒ°þ%ø?}þÑÿÈMù¯-Ùÿ¡ÿ­ëèo—þøÿ‰ÿ¼r1Žù[~BúzïûÇã¥ðK÷ì_®§ÏO–úŸ¤úç´ç?¥%bèR³þKãóú_’Û#øÿÛé/•ÚýŸÒëEºþ¦ùÞýõäÿ–‹y´¯á·ÙŸáþgú§ì_)ü3þøÿsûÿcþzn½¶íÿ®é¯/ÿËø—Ö_yÿ·Ïÿ>ϧæú·#þ‰}Œý¯×ÿXßþ‘áßÏþÕìÿJþŸíü?ëüo=ÿÏ®ü³îÿÅÿ‡ÿÿŸeÿŸÌ~ê¡?uãÿð?ö?çžzþ„ñŒg¼žüÿüw?¿6|èý5èÿ¿ºWÑëU}¥¸þW8’¿ÿ<®¿:Æù—ëúPu×¥ô“Âo»~EÿeIÿ^}O:ÿ¥ß~­¿çõ÷zMóÍúKñÿ#ÿk¯mþÿù÷ôù·)ÿ°ÿ5ãcÄ¿­ãýo{ÿ'©ÿZ__µTŸUwý[Ö}è/•ýÖ_¿ú¿öôßgãÿÚñ_ä?ô¿‡ ýãùÛçÿcÿaÿáÿ‡þšþ¯¿ß|ÿªðw[ÿËRÿ1Mø5ý+Jý#Ÿ<Þúü[_ÿRÿsMÿŸRÿ™kùU¦ß»ýÿWxôôÿÇý®úôÕöÿi›ÿ6ÿ”ÿêï_ßÿ§Ÿÿæýëù‡þצ¿$þ,ÿqä -ÿòúë'ÿá?äòñZë_ÇþgýK¥ôÓùí·ÿ“êûý¯Ëÿß#ÿž>ÿ6åú_×ÿ§-ûé©ÿýþÇÿÿÿ?þü_À>ð?©ÿuâ?#Ø_ØÐÿŸMÿ¿uÿŸöþ¿ßþëõ'àøÿûùümÛÿëz¿}öz_?¿zþÜøuÍ—ÂÇÿýæÇ_á¿Íßv½uþÃý÷=—®é/…o±¿÷üt¼~´ÿkè_šÿíéórþ¤ã¿Ô½¿ûZw?½õߊW_úé½^ÑgžÎçé[ôü“¿_ÒÿÖåÿ±ÿÙ^¦®ß—_%ýËÏ»úÿz|üµ¾ÿ•þ5ë?5ÿ©óï¹ù_×¾ëÏ»üü…ûaÿbÿÙ¶ÿðÿãÿ>ðÏùkù¿Öóÿˆÿ¡ÿµíÏÇ[Ïÿbÿggÿÿ1ÿØßÖá“ÿCþö?ùð?ùäÿáÿÃÿ‡ÿýÏùøþ‡ÿ¿—ÿ~^ùXûü§­?Ë«bÁöÙ4ïý›ÿî÷º>ÍÇñ/<÷ã·ë[’Ðÿåõý¾ðãñáúVŸa?ÿàï]þùè6ü?2ü­ßQè_úmýB¿¢cŸãëÿØ7ù ¿´þÏÏ?¸¾ÿ,…Oê{¥ù¿š—ZøÐ_›þëÚ~ 'Ü?5ŸÚò_žÿ-ËNá¼ëgïî?ó—w}ò_{ðŸ~ÿ÷óú?ÚÓiúïáåés¶¯róŸë¿Wƒºÿ_à¿cÿ­4ÿÇüÃ/¥?r÷;ßÄõ/=?S?^[ÿ½ãùŸ4ÿÖåûöÿ–ñ/írû¥>ûÝý—õýßµýî?Ü&÷ûŸ¸ÿóûìÿVú÷¹ó¿mëïÞù_ä?þ?üøÿ¬úÿ°ÿ¬ó?ô·Lÿ’ö¾ÿñžÿWÛÿ‰ÿCæ¿|Çumÿ›6þŸ¼.ÿHãÚöß9þ”ÊG»öŸ—ã?ùW}ÿÿº¶ÄßzÙÿ#Æÿ,Ùÿèò¿îÄ«§¹oüÄý¿¥ø?öŸmûø·møäÿÙŽµîêõÿ½ü§×ë ¯–øgz|Îþ÷NbßH÷£íÿGàýø¿¥ü?âÿ–ý¿#úÿdû¯u•øßîèŸñòÿÉÿ)ÿÿ®ý'Õ?ÚñWüÿ5òoÏ‹}ãÿÞyçݺN³wÞ­ë4{çݲx·,Ó<ÍÞ-‹wó4ÍÓìݺzçwëúóó÷ëݲx·,Þ­ë4{çݺN³wÞ-‹wË2ÍÓìݲx·®ÓìÝ4O³weûßJüŸ~ø±ûË—X>”®¿þ»Ÿ_>ô‡þš?ûÚJ©Ïã¿Ïõƒd㟎ÿÓç_ßk¿>¯ü±ÿ@Žþ»Ÿþ‡ÿmó¿mü­ÿlõã×Úï—>¯ßúÔÿ$mý[¿´þ¤þ7íõ¯]t„õ/ÁÿéóþGþkÊmùËþýo]ÿC»ôÇÿOügŸ_ç'¦¯ßßÒýãñRø¥ûß}¾oÇŸëV¯‡Þ(ÇzOWù—çü©šøË~ü±þ_ºÊÌõùÏ~¥ñ¹áùN眷|üHòO¿ê3¾þRù—žÿü+üsã×ãçÏÕ;k[Ó|ïþzòßúùä¿ný?}ùOýÍüãÖ¿åóßØÇØÿ±}•;Ùfæí]ûG†?ûwžúÍêükiÿPÚÿ\ÛÏòõ×¾ÿêñü¥%ü¤ÿàmþ_þè»á÷ßÿÛ’Öý¿øÿðÿáÿ³ìÿ“ÙO=ô§¦ýÿcÿcÿ«¯?Æ3žñ”ÿŸƒÿîç׆ý¡¿ýÏu®^¯Û¹Špÿ°WÜ×— -õ—òã÷Ÿ/ËþÜŠný»¿øùê¯Ké'…ßvýŠþË’þ½úžtþK¿%üZõëé×Ôäÿï‘OŸ›òû_3þ7FüÛ:þØÿ¶÷!^lÂ×úI_¿+_K÷aý[Ö}è/•ýÖ_z}•ðGÿ}>þ¯ÿEþCÿ{ø·Ð?ž¿}þ?ööþè¯éÿÒ¬?õìúWÏo}þ­¯©ÿyGúû=_?×­ÿ\Æÿ -žþÿ¿ßòü•æY>ÿmþƒ~õÇK÷Oÿ¾×óþõ‡üCÿkÓ_–Îÿ8ò?…yýõ“ÿðòùÇx­õ¯c޳þ¥¿RúéüöÛÿIõ¿Žýþ×åÿï‘OŸ›òý¯ëÿÓ–¿ýôÔÿƒþGÿãÿÇÿÿÿ?ýøá‡ŸÏôÿ ÿ‹íþ/Пþßôÿ¶Ùÿ[f¿Êñ×µ¿áøß6ÿÓÿ×òÏßoèÿü‡ÛïöÞ·õŸ ÷/ݯüxüuÿËøþuïïþܽŸ~ý÷éÿJÿßíwÏ?ÛùÁýwÚãáþûžc£¬Iü¥Ïükç?únówEÿ6ýyMÏ´þ®‡_7¾¤ÿ­ËÿöþRý_êVÒÿïîÿ÷ýû?]ú—ê×—Öó»û_¶­¿úþ‡Úö/öŸmûÿ?ñú#rë–ûÒÿ‡þ?ôÿ±Ùÿ‡þ×¶å\·>Õ¿~šs}î¥ó¯+ÿËø—ÖßÕ¼¤à¤>‡ÿÈ?®[ìÿ÷tü¿§ÿ"ö?ý?á»üoô?þ?üèô?üÿÃÿÖøßzþ#øóÃùÿߙΟŒ¯ßÍ_º^ÏÚùŸäAÿþmðïÞ_ûü‹Þùýügëçý÷ùïWýçâúÿòóùþuåó?Òþwäÿkž?áü çÿ8ÿoû‡ý¿Uü9ÿCýÉùï:ùéü3õ8ÿo]þãÿÃÿ‡ÿÏ¢ÿûþ‡þvéOý?ÛöŸvý‘1Ö¿þ#Õÿk‰ÿHã#Ô’ôêqþO×ÿ¿õt:Ú§Wôo«ÿÛÿëÆÿ¬ÛÿèÛ?Ôÿ³ÿÇþ³mÿñƒü'ÿÏnü«´ÿ‰íç¶ü¿Üüë÷¥þ?õÿ©ÿOüߢÿWÛÿ§]ÿ_ªäç_Éÿ'ÿ_;ÿ¿Ýþ“êŸêÿãÿ§ÿ§Ýü_©þßæ?'?Âý_óä_šÿ¤ðSòÿ(ÿÁüÁ_¿xûlYrð_ßï-ü+üÏã÷øÇõ‹Úñ¿†æåŒÿV új>¡?ôסÿvßð;Oûüð÷ö½#üðy ÿqüöùþþ߃¿tý÷›ÿxüþúöYØ7\ã¿,yø}ùÿ>üþ¡6Øùyã{Ãÿð?üoìÿxüßoêúþ•ÿ,7>Äòø·ÂÇ{—ýÓúÏ»Üü_½—Òû?ÿõó§åYŒÿõüé¬ÿ³ü¼ºÓ7þõüŸ¼.Éí!ÿÇíÿU׿¾÷üºÿ^ŠïàW/½¿Þú¯Íÿå?hë?)þçç÷îÞü{×wþÛêŸZ•ìØÿZ†ßþ?îs¤ëÿØ7³Çþ+~þiNïËØÿÐxÜýMûÿýuæÿ»Ößóä?þ?üøÿ¾Åÿ‡ýÿC»ô×ö?Žxݺÿ!??}ýŸÏ[ÿïÇ_¿tÿ¼ÿ÷nüGÿÓ¶¿î㜿³þòîNüg4ÿmü­—ý?büÏ’ýþ'ÿK3~=âþßRüû϶ýGüÛ6þäÿÙŽµîöë½gþSÙþÏÇ?Ïã÷ñÏ×û’ÿ/¯ŸûîÿFÛÿÀÿcç?[Ïÿ#þÿMþßýŸÜÝ÷?õÿÿOþÿHöï]ûOšÿ¯ÿÅÿß&ÿzÅÿ½óλufï¼[×i^WïÖÕ»e™æiön]½[×ižfïÖÕ;ï¼[ןŸ¿_ï–Å»eñn]§Ù;ïÖuš×Õ»uõnY¦yš½[ïÖu𽛿iö®lÿ[‰ÿoõþ~õ¶ú ¯Ÿðþø½W=ÜçÛøãç×÷ë?ÿó“~.ðÛøKýŸRüKò¯„ÿ»ý¿mðëõô‡þÚô׬øtü{¬ÿqëÿ—ý}ð×­ÿÿÃÿð¿MüÙÿœð¯x÷õîý¤ð¥ßgÿW–ÒTûß»ºõ$ÿj¯íþ7cëÿ2þ=Öÿ“ûÿ ÿ‘ÿïÿ2ùÛ/ÿÕªÿýoGÿCèÿùÏùwàsþ‡ó?wÎ÷È¿÷ü¿õü_ÎÿsþŸóÿœÿçü?çÿ9ÿÏùì[çÿ©ÿmûü?ç¨ÿÿSÿŸóÿ6ÏÿãÿÃÿ‡ÿÏZÿÏ;ö_þçãžÿ‡ÿ±ÿmÖÿÇÿþào7þCÿúÿ@ëþ?½þßcÔ?µéÿ£þ/õµùÿIòÏ^ýßï’ìȧÿ3ö?ö?ñìâÿÈú¿ãÿƒþVâÿØð?ô§þ?õÿ¨ÿ8 -ý©ùùúíþçöú#ÔÉá_SOîÿ£þõ¿íÕÿAÿSÿ‘úovë¿aÿ!ÿØÿØ–ÿ#Öÿ£þ¹õþ?åý_ŸúçãÙÿÔÿ§þ?õÿ©ÿoIÿäÿûdýÿœÿ«´þúäÿ ÿÑÿøÿñÿãÿÇÿÿiý?OûùÝà]ÍÿYlú'|¶ÿ<=~OÿÔx)ü”þ;Žðÿ—,ÜË÷M>]Éÿ³ü”â¿ÉïyJÁ/ãŸäÿ<¥Ÿ?üiN×?šæsþ9ô‡þcÈ¿ý^2ÿþîoÝýžŽ¿Tþ÷›ÿ;ßë[ÇÇñ©ëËÒÿÀ?iø%|JãS×÷ÏÿÃÿ–ùümÛÿ-ñŸ½ÿnžêÇoþçØÿ£ ¿…þß4^æÿKÇÂçåù×¶ÿeñŸõoG‰ÿÄþþ´<¿?OõããïÏÓHë¿ÿ½ß]ºþãûµÃ¿¿¿ÞCÿ¿‡~½ŸçÓÏoGþïãWýô½üÝëiýëû?mú·Ìýøòük¯¿qìoì?‹öþâ?úKñ¯¡ß]øýèþàoÿ½.Ë¿Oý–ã+ùøL¨Éœ«ÿ|nüñzü÷=üSøÅð0Ï÷Ÿª‰_ÕÀ—Ç¿¤ô—­ÿe‘Îÿ½ç=¿ßúk£¿ÿKíÿö¯fýKëò_»ÿ›¶ü—õK÷óRÓðyõ_{ò?òù‡ý?ŽýßÃþl±ÿŸ¿”þØÿØÿð?ü¯ËÿvñGÿãÿÃÿ‡þ·­ÿáøþ·ÃÿÖóÏùÎÿ·çOJןvþ'ù_Ð_þÏ¿ô<ÿ3Îù?›ç_÷ô:ögOï®é/Íÿ¯?ÿ_ÚݹNþ¯óoéÏkÎÿqþ…óœÿgÿÃþ×ÖxÎÿPÿ‡ó×è?Îÿ#ÿñÿàÿƒþ¶üØð?ô§þ õÿ¬×êWäŽÿó‰ë¿'þ#Õÿ“ÅÚâãÔJã_ò¿÷«ÿ£ãÿ—ÆÏúÙŸ:ñ?âÿèê?Sÿø?öŸEûø7òŸü?»ñ¯–ýßö½¾õ_uúÿPÿŸúÿäÿÿÇÿ«ãÿ§þ¿TÿHã?äÿ“ÿ¯›ÿ/³ÿÚòÿÇ©ÿÿŸþŸÖâÿ¯'zÑcÿö|éëÛëöWø4}½tÿx¼~éþwŸüÁÿ{ñÕ"9Ö?É¿?þ“âþw„W¿4¾ü/ï}øwïý¡¿ýµë>éú¯þu©þÕ±~Z?üuê¿Áÿð?üoëöÿæ‹ùû=ú/¯àÿÖËŸ¸Ýÿ8Þ»ÿíú™þ¯ï÷…ÆÿŸýßžþÓ|îs¥¯â>7RúkÛÿ5ø—ÖßÕ¼ÄöHøü8Ÿšë_»ÿÍë_‚ù÷äþ?èä¿týû¦õ¿gùŸ–ËìÿÐÿèèo—þøÿ‰ÿí®søÿ—Úÿ-ñŸ¸IûùË6ù{o|Þž‘õ‘ÊÿgÆÿîѧ¼ÿ¿;ÿ’ñçç×\Úò½Íÿò‰cûþj|Þÿ¯ùß²ÿ;îg¤ó¯+ÿ[öÇõW3ùýßÓø¯Ÿÿ›ø'ñOìÿ§å¿Ô×O­ËÿÑ´tŸ_{þÉÿ#ÿþ'ÿϪü³îßÅÿ‡ÿÿŸeÿŸÌþë‘ÿ¯ÿ‡ÿ±ÿ±ÿµÎÿ<ýü øƒÿwáÿYý¯-ÿ¥ú? ÿ³¼‚þÐ_‹þÒú_ËrþÜ»t})ïÒõ¬Æ8ÿÒVÿªŸü——ֿ=ÓYòô÷N^ÿ,ðO^-þ¹ñ¹ßóù¯ÿ׬¿×kŠÿ½;ó¿öú׿ÿï‘íõÿ¼ë;ÿ©ùÝϺþMù‡ý¯fücãÿØÿß³ÿ“öO{GÿµO®ëúO›~Ö×ßsä¿ø¿vüùýÇ‚ý‡ý‡ÿúÞÿEÿKÛýéÿjqýÓÿ‡þ?ôÿ±Úÿù‡þ—Õí×ÿW[þ[ïÿ‹ý‡ü³'ÿÿ½ú_·Ùÿã¬iÿ])ýŸÓÿ7½ÿ“êûý¯Ëÿß#ÿ¤ú_gÿo]þ¡ÿuýùüç6ùÛ3ÿ¿^ÿHý?èô?þüÿøÿñÿãÿðÿ÷ã/=ÿÔOþëèëòú£ÿûøê÷£#ùÿ¬û¿°ÿáøÿ7ø“ÿ]ë\×£ÿ±vüUüK~ ý¿i<ùøÿïÆ¿¯üù¥ñWñÿ1Ö?ñÙ{)ýz?ϧŸßŽüë¹§þ¯—¿{ý¿,õÏUŽózôo™ÿúñåù×^ãØßØí?üÿøÿˆÿ‚?ø[ÿKã?mþåqä¿Íü_âìÿ8ÿJü‡ýçÿ9ÿüÃþ·Š?ù?äÿaÿ“ÿÿ“ÿGþþ?üøÿÐÿvÎÁÿð?üo‹ÿ_Oô¢Çÿíù¸Îõóõíuû+|š¾^º<^ -¿tÿ»Ï÷Ýø¿z‘ûŸÜy/]_ÒûKŸÿ>üxþJÿJ÷‡þÏ¢_øšò]žÿ-Ïþùyå3ïÇ_=ÿþþÿào×Kã·ëgüeù¯Rù?Rÿ§Ð¿þºÿUüýþóÿéþ{ß=þWü™Z¥ñûë1ÿë¯iþ‡,ÿA[ÿIñßîœÿmžkçß»¾óßVÿÔ¢üÃþgkýú}ûõøOº¾Jû¥ûû¯üóÞߟ}ïþO»ÿ°þþǺý¯K?ëëï™òÿþ?üßàÿÃþƒÿ¡¿eû_ßÿ¨ ߺý×6ÿýüŸÏ\ÿ}ý¿ÿþï ÿŒÿþ4÷ŠÿHãÚöWþÇùq¤àÇå.þ3–ÿÿ^ü¬ÿþÿ³ñ?âÿèËñŸšøw,¯by&mùo=þýg×þ#þü'ÿÏnüK²ÿ ú_"ÿ¶ý˲ÔÛÿ©øgnüñúñïýßwÿ7Úþÿ“üÿÌügëùÄÿ¿Éÿ«éÿÓßµøŸ–¥Wü‡üòÿGËÿ¿cÿõÈÿ׌ÿâÿo៽­Ý+ÿñ“öÿñù-Çÿ·:’ñëÏÅÏÕ÷JãKŸøÀÿ<ü´ÿÁ»+ùûÞ ¿„Ýþ;ïÿЄý¡¿6ýÏõ§ãúÕáï¶ú××õ§ŸŽÿÓç?½ÿˆ÷oÁï?úà ¿ŒÍþ3·ÿÿáëüoöiøÖ_­ïÿ‚1]:Ï£ÚÿµøiÏ_ùOËß gãëÞõ?®þ—=ÿSæýüQþJþ²ÿCÿ[×ÿÐúãÿ·,ÿmŸÿvþ7ÿÿýð5óÿâ¼¹>ç/Îùé¼¼tþݯRü«.ÿïü;ñ·ñ/Ýó?©ù¯Ï¿LáŸÎÿ ÏËùŸ²þ;Ú¯ë*Û_—îï]_øëÚkÿoAþŸÖñýY^Iè¯-ÿKø–ÖßÕ¼ÔÎçˆë_ûº6ÿ=}þÀßùß~ý?žyþù›ÎÿÖî–¥Ýþ/Íûþ+mÿ§Æçìÿ3ü«óMmöÞþ€ÿµù¿}ÿýŽõ¯½ÿ·&ÿ¨ÿ‰ÿÿþ?»õÚí¿ëOÛþ‚ÿ±ÿmÛÿêëøÀþåÿçà¿OþúC úŸ_ÿ~?y=ŽO]]?âßoüñu;Wêë…ZYûû¿kþïÃÏß¾,ûs3—ô¹ùÚwþC]¯6üãñ¥ÏÏû€+üJë¯vüÕû1Ö¿6ÿ?Oþ=}þ­Ë?»ö¿nüO?þmìÛöÿºågX?ûú°íòwÿy:ÞœõoWÿõ¡¿Tþõ[ñø:üÑ:ñíø/òß:ýÛë¿×Ñÿÿû`ÿaÿáÿ‡þzô±þÔ3ê_i×ß||ëóoiýKýÇÒWÝúÏrü¤þíW‰ÿ¡_ýñ4üø7~þ÷úÿ?³þèŸÑêÿß—_Rý£-ÿSø·?ÿ'çþCþ!ÿ€/ƒ¯ýª½þ¯µöç»æÿ>üüøÜç}ö}÷ŸÚö¿=ý?ÿ?Oþ=}þíÊ?öãùÿ>)ûè©ÿýþÇÿÿÿ?þúøÀ§ÿ;ý_ ?ô§ÿ7ý¿?ÿ¯Ë?탿®ý ÿÃÿ¶ùŸþ¿¶÷ëz_z÷õîý¤ð¥ßß~·Ÿð¾mþÃýK÷ë?Oÿ_ú¿æúχ~AÛú9ÆÖUˆÇ—ùÿ“ë_?é3ÿÚñŸ+úoús»Þªÿ¯å_úùëá§õ<¾¤ÿ­ËÿöþRý_ê_VÒçïîÿgµÿ³6ý§¹ný¿»ÿeÛú«ï¨mÿbÿaÿáÿ'þCÿEàßjÿOúÿÐÿ‡þ?VûÿÐÿÚ¶ü/÷¯Ï¿Jç_›ÿ¤øiÏü‡üCþÿ©ýÿžŒÿ7ö_Äþ§ÿ'üo—ÿ­áþÇÿ‡ÿýþ‡ÿáøßÿ[Ïοpþ]óù“Ûg­ù_ùüoýüOòmÓ]ûÂé¿®GøáþcœïüÏ'óŸ9ÿ{Õÿòx>(U¿¬Gþ®ÿ]ùü¼ÿõüÍógãžÿ·tþóÿœÿgÿÏùÎÿجÿÓ~þ»Nþ†ûïm®qö?Øÿœÿçü?þ?üøÿìùÿ°ÿ8ÿ ýmÒŸúø?F¨C2šÿÍÊ«4þ#ÿ`ÿIû?IÏßRÿï:~¶]o­ÿ]Úÿÿ³bÿ£ÿÉÿ¢þŸÝø?öŸmûø7òŸü?»ñ/iÿÒ>ûÏñúÿPÿŸúÿÔÿ'þo!þ?¢ÿï“õÿ%ú§ÏùWòÿÉÿ×´ûô¯oÕ?Úñ_üÿôÿ´›ÿ±,{únÏwEÿóü1žñŒþøPå\óåx=þû3ðßýüÚð¡?ôוç×yúäõ§ãÿìù—þÊù¿tÿ÷>?üÿ[æð·iÿ?»þ´>ô×­ÿª­õëŽÂÇ×+ù¹ÿÞ~~üþó‘äo?üŸ>ÿèä¿Fýo]ùk}ÿ‡þGÿC»ôÇÿÿ/œïÜÎ'^ÿlƒç³Òã¥ðSù_àOü›ñ¹õÜ+æÞßÏìÇ¿rQ·õ™–Ÿáûõë?7¾NþKãORù¯·ÿíC™ü[–:ø5ñ¿šç=¿ßúKÙÌáþþ×úÿ“ò_Vÿ¡Îþ ÷?Ó?ŸÿÝÿNþ7þŸ˜þ¹õß¶ÿËÑ_[þ·ã_¿ÿÛãó¿öú·#þ‰ý‹ýŸ·Ïkì/©ý¯¿ÿ—â/Ýÿ÷›ÿôü’ÿGþüOþß}ú|»üÃÿÿÿþ?‹þ¿~öŸôü‰vü×.ÿcÿsþ‡ñŒg<çÿÉÿâü?ô·˜ÿ­sþdœø—Mÿßýs{åÔ÷äùÇ:ö?ùÿœÿãüçÿˆÿ“ÿo9ÿûŸø?ñâÿÄÿmë¿Rü³E~Õŵãÿœÿ´JâÿØøÿ¡¿Uÿ¿vÿMøÛøðY 3¾þ]ã­Ï¿õõ/õ?ïãHû~4.ÇëñçyùU¦ß»ýÿWxôôÿÿý–ç¯4ÏòùoóHù¯þþéß÷úoÞ¿þèmúKâÏÒùGþkõƒÿÈ?Æk¯ûsœõ/ý•ÒOç·ßþOªÿuìô¿.ÿü{úüÛ”è]ÿŸ¶üí§¤þô?úÿ?þüÿøÿñøÀÿ¤þ׉ÿŒ`aÿAü6ýÿÖýÚûÿ~û¯wÔŸ€ÿáÿïçð·mÿ¯ëqüöÙë}|ýÿêùsã×5?^ -?ÿ÷›…ÿ6ÛõÖù÷ßÞÿƒqM)üx|‹ý½ç§ãõ£ý_CÿÒühÿKŸÿ“ó'ø¥îýÝ׺ûé­ÿV¼úÒOïõŠ>ót>OߢÿëäŸþõø’þ·.ÿ¯úÿç³]~•ôÿUÿ³Zý=¾NþZßÿJÿšõߣÿݺö]Þåç/Üo ûû϶ý‡ÿÿð|Îÿ[ËÿµžÿGüý¯mŽ8Þzþû?;û?øùÇþ¶Ÿüòÿ°ÿÉÿƒÿÉÿ#ÿÿþ?üèÎÿÃÿð?üÿ½üÿóóÊÇÚç?mýY^ ¶Ï¦yïßüw¿×õi>Žá¹¿]ßú“„þ/¯ï÷…×·ú ûùïòÏFµáü‘áoýŽBÿâПhë‡úû÷XÿǾÉgø¥õ~®øùÃõýg)|Rß+ÍÿÕ¼Ô‡þÚô_×¾ðc8áþ©ùÔ–ÿòüoYþs -ÿãõX?{woü™¿¼ë“ÿÚƒÿôû¿Ÿ×ÿÑžNÓ/OŸ³}•›ÿ\ÿ½üÓýÿÿûo¥ù?æ‡~)ý‘»ßùþ#®éù™úñÚúïÏÿ¤ù·.ÿذÿ·Œiÿ“Û/õÙèïÿ®íÿsÿá6ù»ßÿÄýŸGØÿ`ÿ·Ò¿‡üËÿm[÷Îÿ"ÿñÿáÿÃÿgÕÿ‡ýgÿ¡¿eú—ü³÷ý÷ü¿ÚþOü2ÿå;®kûß´ñÿäuiüGÿÓ¶ÿÎñ§T>Úµÿ¼ÿÉ¿êûÿ×µ%þÖËþ1þgÉþGÿ“ÿu'^=Í}ãÿ#îÿ-Åÿ±ÿlÛÄ¿mÃ'ÿÏvü«uÿS¯ÿïå?½^_xµÄ?Óãsö¿wûFºÿmÿ?ÿëÇÿ-åÿÿ·ìÿÑÿ'Û­«ÄÿvGÿôˆÿÿOþÿHùÿwí?©þÑŽ¿âÿ¯‘{^ìÿ÷Î;ïÖuš½ón]§Ù;ï–Å»e™æiönY¼›§ižfïÖÕ;ï¼[ןŸ¿_ï–Å»eñn]§Ù;ïÖuš½ónY¼[–ižfï–Å»ufï¦yš½+ÛÿVâÿ[½€øõçâçê{¥ñ¥Ï|à¾Tþ¼~ ÿwû_ß úCmúkÖz:þOŸ©ÿ¡þºõ·àøß6ÿÛÅŸýG¾õWëû¿Zÿ±tžGµÿkñÓž¿ó¯Ùf\ý/{þ§Ì?úù?¢üÿ”üeÿ‡þ·®ÿ¡?ôÇÿoYþSÿóÿœ¿áüÏýóß=êÿyþŸü_ÎÿsþŸóÿœÿçü?çÿ9ÿÏùìokçÿ­Ôÿæü?ç¨ÿOýêÿsþŸóÿøÿðÿáÿ³Ôÿ³Ýþë±þÆ<ÿo‰ÿ±ÿm×ÿ>ðo7þCÿúÿ@»þ¿ñú¶þ©uÿõm×ÿÿŸ$ÿž_ÿ×¶ücÿAþ¿íþÏØÿÄÿ‰ÿÿ'þoSþ[ïÿnÝÿgþ¶ãÿØøÿ¡?õÿy¥þ#óoëµÿXVN»þKÿÖç¿çÿ×®ÿGýo«õÐ÷Ô¤þ›ÝúoðóÍþǶü±þ·~ýsëýêöïÛêÚÿÔÿ§þ?õÿ©ÿoCÿçÿûdý‰þéãDÿ£ÿñÿãÿÇÿÿÿÓúÓA'Äs_ÿf<ãÿÔñ˲—ï›|º’ÿgùù^øï~møÐú!?´ŸŽÿ3ç?¬ßókÍõ~ü_ºÿ{žþ‡ÿ-ó?øÛ¶ÿÃùÏà?ç'÷ßi÷?‡ûïÏ\^û¿¥ðãñ9ÿ÷<íïÿú¹†ß6ÿñø=þ©ñRø)üsô—œ?–Æ´õ¯¾ÿQ?þ³®GX?{þïýÎó”ÿ|?~û<¾¿öúÿûÍ?ŒKÿöùï??>wß½¯éU¯?ë䟾ôûv忤þGý]ÿ¡¬ÿ¥õ¬ïÿ´éŸš¿;ë??¾Nÿ¯kßõw¯þ®ý‹ýgÛþÃÿOüG<Œg<ã=^ú+¿„šÌçž3uÏŸ¿¯ù|ü»~Røòø•tþ¥ôïú{÷ók¯?-þ¯þügá[—ÿÚýß´ùO¿ÿü‡üCþ1^{¼®ýù|üŸ=ÿØÿ6íøþô?þ?üè»úþ‡ÿá{üo=ÿü9?oýüÈïLçO¯ßÏ_Ê­íüOò¿ ÿ5þmðcúÇó·Ïÿ'ÿ_çüÏçÿ,ŸÝÓÛ»3ý„¿÷õáúåÿ‡×;çJãKûòÿõÏŸiŸ±~þóÿ¶÷ìÿíâÏùêÿô9ÿ]{¤óÿè?Îÿ[—ÿøÿðÿáÿ³éÿÃþƒÿ¡?õ_¨ÿg·þ“fý‘qü¿zõ÷F©ÿ'‹ÿ´ÅÿF¨ÿäÝùµÖÿÞ¯þŽÿ?¦oŠ>ñõ»õ¿ëìøñô?õŸ©ÿGüûÏ¢ýGüùo=ÿÏrü«´ÿ‰íç–ü¿ºú£:ý¨ÿOýêÿÿ§þ¿ŽÿoœúÿRý#ÿÿOþ¿fý©ý×î£þ¿]ÿ?ý?­Æÿ_Oô’{ÿé&ŸÒ×·×í¯ðiúzéþñx)üÒýï>øƒÿ÷âÿﻯßi®{ü'Åÿü﯄i|ù_ßûðïÞúCúËó¿eùOÇ_ºþëâ×wç_’ÿþZŸÛ~ÿ ÿX¿ªþËR¿¦þV<þºþüÿÃÿvñ·nÿoþοߣÿó -~ðo½ü‰Ûý㽋ñß®Ÿéÿú~_øgüðÙÿíé¿éËпæZ_Å}n¤ô×¶ÿkð/­¿«y‰í‘ðùq>5׿<ÿSÿaýKðï!ÿrñ϶ù¿ÿDÿ#ÿuäÿ¹oZù{–ÿi¹Ìþýþ‡þvéÿŸøOÑþá:׉ÿ©ýßÿÙ믖ýc,ÿïÊß{ãóöÌ]üÏûG‰üfüï}Êûÿ»ó/~~Íõ§-ßÛüÿ!Ÿ;¶ï¯Æçýÿzð‘ÿ-û¿ã~F:ÿºò¿eÿw\5ó—ßÿ=ÿúù¿‰ÿÄþZþKÎþºoÿëÚ?ºÏ¯=ÿäÿ‘ÿÿ“ÿgUþY÷ïâÿÃÿ‡ÿϲÿOfÿõÈÿ×ÿÃÿØÿØÿZçž~þüÁÿ»ðÿ¬þ×–ÿRýŸ†„YÞ?Aè¯Eiý·pþäº~Øþþ÷êÿ}òüK[ÿ‹~ò_ -_ZÿîLÿeÉÓß;yý»À?ixµøçÆç~Ïç¿rü_³þ^¯)þ÷îÌÿÚë_›ÿ¿Gþµ×ô®ïü§æw?ÿéþ76åö¿zü™ñÿcÿÏþ¯(ß|]{ý[×Úô³¾þž#ÿûÅÿµã¿Èè?|ì?ì?üÿÐÿóþ/»ýéÿ¤Gú_ë÷ÿÑìÿ5Nÿç4þ¥þ‡ýú?õ뿘ꗕëÿ#ñHåŸvÿ¯¼ýܶþîØ?È?ôÿôo‹?÷ëÿ§-ÿíöÿÃþCþY•ÈÝþß㬛ý¯éÿ‹þ×äÿï‘Rý¯³ÿ·.ÿÐÿºþ¿|þs›üí™ÿ_¯¤þô?úÿ?þüÿøÿñYñ‚?ø¿NüGÛþÇþƒþÐß®ÿߺÿO{ÿ_:ÿ\¿ÿj;ÿ ÿÃÿð?øcÿŸÇ¿ÞÇ×ÿýàóø«ùߟ§úñWôþYÿýý¦®íÿÔúýû½7ÿ£ÚÿWÏÿ÷›~ïòóî—çÿZø¥ñ¿ùñWòÿ³ïµ×ýó¦_Û×ÿßoøý¾_Ò¿i{®ÿü߃_e"ÿïÉÿX~õÑ¿õò·~üçÇÿ7ýkÖÿ²Ôû/¯æŒõ§mÿbÿÙ¶ÿðÿsþÿøƒ?çÿíäÿZÏÿ#þ‡þ_×¾ög›ÿKÛþ%ÿ‹ýŸåýßxüüCþaÿ“ÿCþö?ö?üÿ“ÿGþþ?üèô?üÿÃÿð¿”ÿ~^þ¨=þÛó½*lŸMó~~þÝo»^¿]ßê+ìñþÓà{w„?ÍÇñœZøÞõ…×·ú{ùoÿi>÷?žæc?”}¿âý÷{¬¿üÒú¯yþýóæð©ƒœÿpŸ`Çì{Á”àCÿ§Ñ¿/|mùÿ¾üùºñ©çÿäuIþkù?Jÿ÷ýúMÙÓ1ýöðzήÿÖyý,KýxïÎý·Òü¿ÒxéýõÖmþ‡,ÿA[ÿIñ??¿w÷æß»¾ó÷.?Þ¶ücÿÃþ×2üûöÿqŸ#]ÿûûõÙÅÏ?Íé}û¿6ùŸ·¿îž¿wÿcÓþ¿Cùÿ®õ÷<ùÿÿþ¿oñÿaÿÁÿÐß.ýµý#^·îÈÏO_ÿçóÖÿûñ—Á/Ý?ïÿ½ÿ‘Æÿ´í¯ûøç﬿¼»ÿÍÿ_ëeÿÿ³dÿ£ÿÉÿÒŒ_¸ÿ·ÿÇþ³mÿÿ¶?ù¶ã_­ûŸýzï™ÿT¶ÿóñÏóø}üóõ¾äÿËëç¾û¿Ñöÿ#ðÿØùÏÖóÿˆÿ“ÿwDÿß'÷_÷ýO}ã?äÿ“ÿ?’ý{×þ“æÿkÇñÿ·É¿^ñï¼ón]§Ù;ïÖuš×Õ»uõnY¦yš½[WïÖuš§Ù»uõÎ;ïÖõççï×»eñnY¼[×iöλuæuõn]½[–ižfï–Å»ufï¦yš½+ÛÿVâÿ¯ŸP¡îýÝŸ»÷“—~üÁßþ±|‰åsúz,?ÚñßäÓöw ¿„Oi|úzxþþmðïÞúCúû†ñWõ‡ÎõƒB-©ó}¯Æ#ÿ¤øK×zþ¤óŸªÿ4OéñûýsXŸWþ‡Ø dzßç)¿Œ~|°ÿç)õüð?üo›ÿmãoÝþßêþýë^Á?~ïUO0÷ù6þøùõýúÀ?ãŸ~.è/Í‘Ò_Ûþ/á_ZRÿ§öú×®>Âú—à/]ÿúõ_ÑÿÈ=ù_Š´Éßúøû?ô¿uýýíÒÿ?ñŸ"ý¹Îõ þ—®ÿ:þ½ ¿ÿ;þçøÏ4çò¯Îù“-ñ£ãóåêÍÔÌ_i|¾žÍ]üÏñ£ò¿üRüê¾4þ%¥¿T¾´Í¿düùù5ן¶|·~þù¯[ÿO_þSÿCóüóëßòùoìì‰ýÞÃþ×µtŸ_{þÛìçp~FºþÃþeYZö_uã×ãç¿oLs¯ýüÿDþóG{¬ÿQöÿ¶äŸuÿ.þ?üøÿ,ûÿdö_zýMsºÿùÿçùå¾ýu>ÿõþÇþÇþo·¥üÿLûüÁÿ[ñÿ¬þ×–ÿRýŸ†„YÞ?Aè¯Eÿpþ%®wõ¢a˜Ÿð÷¾¾×²œ?÷.œËØß>ßß_»þ]Œ_ü|©ëËrįü—¿_ßÏÑYòô÷.=ÿþåú›ÒðjñÏÏýÊê?¦ë…y©©?8JýGþÿù×¶þãyë1ÿ©ùÝÏÌ?–åö¿zü™ñÿcÿÏþ¯(ß|]{ý[×Úô³¾þž#ÿûÅÿµã¿Èè?|ì?ì?üÿÐÿóþ/ú_O¯%­ª_ÿS›þÖñ×^ÿRÿ÷>Žô÷{þ|¿ßúû½ëÿwýç2þ©xåßo_ÿÿþ~wá§æ??OiºôðÿKå_É‘z?OŸòÿ·­¿;öòý?ýÛâÏRú#ÿSø—×_?ù¯­ÿ±ÿöäòÿhŸ÷°?ïØÿã¬ÿk{3gö£¿~Û÷ûíÿ¤ú_ÇþGÿëòÿ÷È?©þ×Ùÿ[—è]ÿ_>ÿ¹MþöÌÿ¯×?Rÿúýÿÿ?þüÿô?¢ÿ;øƒ?ýßéÿý¡?ý¿éÿýÿìü«ÝýüÿÛæúÿZ¶ÿ7á½þ“ç~ž¥ñWý?µá[OÿWúÿÞÏ ô<êÒøsüg„õ/ÉÿëÑÿüyù=ç__ûùmÊÿ#?Kôo›ü ÷{wÿ¿ïßÿéÒ¿mþëÇKû_¾{ýiۿضí?üÿÄèÿþàOÿOúÿÐÿ‡þ?ÖúÿÐÿÚ¶ü_ךþõûzõû:÷=ú¿ëÊÿ2þ¥õw5/±< -ŸçSsýkó?òù‡ýo·ÿßÓñÿ¾þߨÿôÿ„ÿíò¿-üÑÿøÿðÿ¡ÿÑÿð?üÿ[ãòáyÏùÎÿ·æOJדvþ'ù_Ð_þ3Ï¿ô;ÿ£ŸÿlýüoKýÿžç?ZêoÕ/×ß"ÿ_³þýç_8ÿÇùö?ìo-¾çüõ,Ÿ¿Æþçü?òÿþ?èoÑÿ‡ýÿC»ô§þŸí÷móßÏÿùÌõßÿ‘êÿµÄ¤ñ¿ê?Iú?õ8ÿ§ëÿ—ÅÏäûÝøŸuûýo;þCý?Ûñì?Ûöñoä?ùvã_mû¿~õ_GèÿJýêÿ“ÿGüßjýMÿŸöþKÚÿY~þ•üòÿÇÈÿo±ÿ¤ùÿ#ÔÿÇÿOÿOËý_6~Þ¯ßcýŽ0gþßæ¿4>¬ÿxÿ|àø¯×P3åøwüýOÁ¯Ç?=>Ô_>Ö‚>ô‡þô?¾nve°¯‚­¸}ï??~ÿùv¿yú&üŸ>ÿÇ×eIÿ^}¯7þ1Ü»ø_=÷5>ð?üÿÛÅû?>ø¥âëGøß:ÞúþïÌ—Ó\÷^:ÿcØÿeüóϯ7­ãϯŸ½>–þ—>ÿóæýüGþëÉ_üè‹úúCüÿå¿$ÿ§þ¾ÿé9ÿꌿ~*ÿü‰?·þƒ¾ -ýSöùa¥øÏõþkÿ/|µÿÊõ©“¿©þ/eù+?Iå¿Þþ·ý¥òï>ü+üãñ¥øßºö]1ýý¿Cñi[ÿýý¦®ß·?ãñûó9ü[áÇãñÿß¡ÿ4§åAûþåý?/ÿÛð¯ßÿ¥ñ¿ž¿Ö¿õøñOìoëöl¿·ÚŸ÷ì-ûGŠû·uþãñäÿ‘ÿÿ“ÿwwÿoEþáÿÆÿ‡ÿÿŸUÿ_û¯Wþ•–ýe—ÿ±ÿÉÿ>ð|ò¿Èÿ…þœÿÕ>ÿ£}þÉúùßû¯}ç_Ûþçüçÿ8ÿÇù?{ù_äÿÛÎÿÇþ'þOüŸø?ñ›ú¯6þY/ÿïá¯ÿçü§UúÿÇþÃÿ ý­Ò?î?±ù…^ïãëÇþß:~žRýsêúo¤Æ_õß¾õù·´þ¥þcéëµü+Óÿþÿ–ç¿ãÿ×~•øzð_~ü?ÿ{ýÿŸYÈ?ô&ü>òKª´å -ÿöçÿäüÁÈ?äðeðµ_µ×ÿñµÖþ|×ü߇ŸŸû¼Ïþ¯ïþSÛþ·§ÿÇâÿçÉ¿§Ï¿]ùÇþo<ÿß'åoý#õÿ ÿÑÿøÿñÿãÿÇÿÿøÀ¾^ü§6ÿè½ðõâ?–ä?ôGÿãÁÿýÿÃÿVýßøÿ­Úÿëz¿®GÿáºÊüñøuÍ—Â_×{þÏ+ü·ùÛ®·Î¸ÿöþŒkúKáÇãÉÿ#ÿ¯¼þ½«}÷µî~zëßzüÿŠ>ñùVý_'ÿ¤ð¯Ç—ô¿uù/íÿ'Õÿ×ýËêôÿûúÿÙØÿJÿšõÿÞþ—mëïnÿCmûûüüÿÄÿ|à“ÿÛÿ‘ÆŸÆÊÿ³žÿKüóÿœåü?û?ÎÿsþŸùÇþ¶uþŸüòÿ°ÿÉÿƒÿÉÿ#ÿÿþ?üèÿo>ÿÿÃÿð¿=þÿùyåcíóŸ¶þ,ÿžÿ•«úüüÿåëú4Ç¿ðÜß®¿>?öù÷_øñøi>Â} -þWðãç£ÚðþÈð§ùÜÿhëOôúwìW´ïsÒcýÇ}“cø¥õ~®øùÃõýg)|Rß+ÍÿÕ¼Ô‡þÚô_×¾ðc8Çþ_ñ|jËyþ·,ÿ9…ÿñz¬Ÿ½»7þÌ_ÞõÉíÁãöÿ;Ò+ׯ>OŸ³}•›ÿO÷ÿKñÌ9üRú#w¿óýG\ÿÒó3õãµõß;žÿIóo]þ±ÿ`ÿoÿÒþ'·_ê³ÿÐÝYßÿi÷?×ßÿ`ÿ·Ò¿‡üÓîüÇÿ‡ÿÿŸUÿöŸuþ‡þ–é_òÏÞ÷?Þóÿjû?ñÈü—︮íÓÆÿ“×¥ñiüOÛþ;ÇŸÒý€®üçåøOþUßÿ¿®-ñ·^öÿˆñ?Kö?úŸü¯;ñêiîÿqÿo)þýgÛþ#þm>ù¶ã_­ûŸzý/ÿéõú«%þ™Ÿ³ÿ½“Ø7Òýßhûÿø_?þo)ÿø¿eÿïˆþ?Ùþk]%þ·;ú§Gü‡üòÿGÊÿ¿kÿIõvüÿüÛóbßø¿wÞy·®Óìwë:ÍÞy·,Þ-Ë4O³wËâÝøëöÿƒÿáøß&þìNøW¼¿ûz÷~RøÒï³ÿ«õ?Ké?ªýï]Ýz’Æ?´×^þ·ö®ïÿ<¶þ/ãßcýë÷Fÿ#ÿÇ’ÿ2ùÛïüŸUÿúߎþ‡þÐÿ?ò¿žþaýÆø]Ïç?ÿYð©ÿh#ÿ÷*ÿrÿýe©¥ëÿÝ?}\ÿ5õ«rç¯[Ï¿÷:ÿ­þ§þ=äO+ü€íø-ÿ/®g¦»þF”ÿ÷Îïßuëõïå¯Ëæ_›ÿ¤øiÏß篿¿þõO¨†ý¯ÝÿgžZ쯻ö¿¶ý#Á_~ù§þý¿àËõ?lË?ëþ_üøÿðÿÙõÿIì¿ýôëÿÂÿØÿÔÿÅÿþàOü‡þOÖú?AüÔÿÅÿGý?›õÿ¬×ÿ•áß{ýËç?Oý_êÿöÜÿÿMð±ÿ±ÿ‰ÿcÿÿGþ×Éÿ¾ñßó¿ñÿA+ñì?øúÛ¤?õÿ¨ÿ8"ý©ùùúíþçöú#ÔÉá_SOîÿ£þõ¿íÕÿAÿSÿ‘úovë¿aÿ!ÿØÿØ–ÿ#Öÿ£þ¹õþ?åý_ŸúçãÙÿÔÿ§þ?õÿ©ÿoIÿäÿûdýÿœÿ«´þúäÿ ÿÑÿøÿñÿãÿÇÿÿiý?OûùÝà]ÍÿYlú'|¶ÿ<=~OÿÔx)ü”þ;Žðÿ—,ÜË÷M>]Éÿ³ü”â¿ÉïyJÁ/ãŸäÿ<¥Ÿ?üiN×?šæsþ9ô‡þcÈ¿ý^2ÿþîoÝýžŽ¿Tþ÷›ÿ;ßë[ÇÇñ©ëËÒÿÀ?iø%|JãS×÷ÏÿÃÿ–ùümÛÿ-ñŸ½ÿnžêÇoþçØÿ£ ¿…þß4^æÿKÇÂçåù×¶ÿeñŸõoG‰ÿÄþþ´<¿?OõããïÏÓHë¿ÿ½ß]ºþãûµÃ¿¿¿ÞCÿ¿‡~½ŸçÓÏoGþïãWýô½üÝëiýëû?mú·Ìýøòük¯¿qìoì?‹öþâ?úKñ¯¡ß]øýèþàoÿ½.Ë¿Oý–ã+ùøL¨Éœ«ÿ|nüñzü÷=üSøÅð0Ï÷Ÿª‰_ÕÀ—Ç¿¤ô—­ÿe‘Îÿ½ç=¿ßúk£¿ÿKíÿö¯fýKëò_»ÿ›¶ü—õK÷óRÓðyõ_{ò?òù‡ý?ŽýßÃþl±ÿŸ¿”þØÿØÿð?ü¯ËÿvñGÿãÿÃÿ‡þ·­ÿáøþ·ÃÿÖóÏùÎÿ·çOJןvþ'ù_Ð_þÏ¿ô<ÿ3Îù?›ç_÷ô:ögOï®é/Íÿ¯?ÿ_ÚݹNþ¯óoéÏkÎÿqþ…óœÿgÿÃþ×ÖxÎÿPÿ‡ó×è?Îÿ#ÿñÿàÿƒþ¶üØð?ô§þ õÿ¬×êWäŽÿó‰ë¿'þ#Õÿ“ÅÚâãÔJã_ò¿÷«ÿ£ãÿ—ÆÏúÙŸ:ñ?âÿèê?Sÿø?öŸEûø7òŸü?»ñ¯–ýßö½¾õ_uúÿPÿŸúÿäÿÿÇÿ«ãÿ§þ¿TÿHã?äÿ“ÿ¯›ÿ/³ÿÚòÿÇ©ÿÿŸþŸÖâÿ¯'zÑcÿö|éëÛëöWø4}½tÿx¼~éþwŸüÁÿ{ñÕ"9Ö?É¿?þ“âþw„W¿4¾ü/ï}øwïý¡¿ýµë>éú¯þu©þÕ±~Z?üuê¿Áÿð?üoëöÿæ‹ùû=ú/¯àÿÖËŸ¸Ýÿ8Þ»ÿíú™þ¯ï÷…ÆÿŸýßžþÓ|îs¥¯â>7RúkÛÿ5ø—ÖßÕ¼ÄöHøü8Ÿšë_»ÿÍë_‚ù÷äþ?èä¿týû¦õ¿gùŸ–ËìÿÐÿèèo—þøÿ‰ÿí®søÿ—Úÿ-ñŸ¸IûùË6ù{o|Þž‘õ‘ÊÿgÆÿîѧ¼ÿ¿;ÿ’ñçç×\Úò½Íÿò‰cûþj|Þÿ¯ùß²ÿ;îg¤ó¯+ÿ[öÇõW3ùýßÓø¯Ÿÿ›ø'ñOìÿ§å¿Ô×O­ËÿÑ´tŸ_{þÉÿ#ÿþ'ÿϪü³îßÅÿ‡ÿÿŸeÿŸÌþë‘ÿ¯ÿ‡ÿ±ÿ±ÿµÎÿ<ýü øƒÿwáÿYý¯-ÿ¥ú? ÿ³¼‚þÐ_‹þÒú_ËrþÜ»t})ïÒõ¬Æ8ÿÒVÿªŸü——ֿ=ÓYòô÷N^ÿ,ðO^-þ¹ñ¹ßóù¯ÿ׬¿×kŠÿ½;ó¿öú׿ÿï‘íõÿ¼ë;ÿ©ùÝϺþMù‡ý¯fücãÿØÿß³ÿ“öO{GÿµO®ëúO›~Ö×ßsä¿ø¿vüùýÇ‚ý‡ý‡ÿúÞÿEÿKÛýéÿjqýÓÿ‡þ?ôÿ±Úÿù‡þ—Õí×ÿW[þ[ïÿ‹ý‡ü³'ÿÿ½ú_·Ùÿã¬iÿ])ýŸÓÿ7½ÿ“êûý¯Ëÿß#ÿ¤ú_gÿo]þ¡ÿuýùüç6ùÛ3ÿ¿^ÿHý?èô?þüÿøÿñÿãÿðÿ÷ã/=ÿÔOþëèëòú£ÿûøê÷£#ùÿ¬û¿°ÿáøÿ7ø“ÿ]ë\×£ÿ±vüUüK~ ý¿i<ùøÿïÆ¿¯üù¥ñWñÿ1Ö?ñÙ{)ýz?ϧŸßŽüë¹§þ¯—¿{ý¿,õÏUŽózôo™ÿúñåù×^ãØßØí?üÿøÿˆÿ‚?ø[ÿKã?mþåqä¿Íü_âìÿ8ÿJü‡ýçÿ9ÿüÃþ·Š?ù?äÿaÿ“ÿÿ“ÿGþþ?üøÿÐÿvÎÁÿð?üo‹ÿ_Oô¢Çÿíù¸Îõóõíuû+|š¾^º<^ -¿tÿ»Ï÷Ýø¿z‘ûŸÜy/]_ÒûKŸÿ>üxþJÿJ÷‡þÏ¢_øšò]žÿ-Ïþùyå3ïÇ_=ÿþþÿào×Kã·ëgüeù¯Rù?Rÿ§Ð¿þºÿUüýþóÿéþ{ß=þWü™Z¥ñûë1ÿë¯iþ‡,ÿA[ÿIñßîœÿmžkçß»¾óßVÿÔ¢üÃþgkýú}ûõøOº¾Jû¥ûû¯üóÞߟ}ïþO»ÿ°þþǺý¯K?ëëï™òÿþ?üßàÿÃþƒÿ¡¿eû_ßÿ¨ ߺý×6ÿýüŸÏ\ÿ}ý¿ÿþï ÿŒÿþ4÷ŠÿHãÚöWþÇùq¤àÇå.þ3–ÿÿ^ü¬ÿþÿ³ñ?âÿèËñŸšøw,¯by&mùo=þýg×þ#þü'ÿÏnüK²ÿ ú_"ÿ¶ý˲ÔÛÿ©øgnüñúñïýßwÿ7Úþÿ“üÿÌügëùÄÿ¿Éÿ«éÿÓßµøŸ–¥Wü‡üòÿGËÿ¿cÿõÈÿ׌ÿâÿo៽­Ý+ÿñ“öÿñù-Çÿ·:’ñëÏÅÏÕ÷JãKŸøÀÿ<ü´ÿÁ»+ùûÞ ¿„Ýþ;ïÿЄý¡¿6ýÏõ§ãúÕáï¶ú××õ§ŸŽÿÓç?½ÿˆ÷oÁï?úà ¿ŒÍþ3·ÿÿáëüoöiøÖ_­ïÿ‚1]:Ï£ÚÿµøiÏ_ùOËß gãëÞõ?®þ—=ÿSæýüQþJþ²ÿCÿ[×ÿÐúãÿ·,ÿmŸÿvþ7ÿÿýð5óÿâ¼¹>ç/Îùé¼¼tþݯRü«.ÿïü;ñ·ñ/Ýó?©ù¯Ï¿LáŸÎÿ ÏËùŸ²þ;Ú¯ë*Û_—îï]_øëÚkÿoAþŸÖñýY^Iè¯-ÿKø–ÖßÕ¼ÔÎçˆë_ûº6ÿ=}þÀßùß~ý?žyþù›ÎÿÖî–¥Ýþ/Íûþ+mÿ§Æçìÿ3ü«óMmöÞþ€ÿµù¿}ÿýŽõ¯½ÿ·&ÿ¨ÿ‰ÿÿþ?»õÚí¿ëOÛþ‚ÿ±ÿmÛÿêëøÀþåÿçà¿OþúC úŸ_ÿ~?y=ŽO]]?âßoüñu;Wêë…ZYûû¿kþïÃÏß¾,ûs3—ô¹ùÚwþC]¯6üãñ¥ÏÏû€+üJë¯vüÕû1Ö¿6ÿ?Oþ=}þ­Ë?»ö¿nüO?þmìÛöÿºågX?ûú°íòwÿy:ÞœõoWÿõ¡¿Tþõ[ñø:üÑ:ñíø/òß:ýÛë¿×Ñÿÿû`ÿaÿáÿ‡þzô±þÔ3ê_i×ß||ëóoiýKýÇÒWÝúÏrü¤þíW‰ÿ¡_ýñ4üø7~þ÷úÿ?³þèŸÑêÿß—_Rý£-ÿSø·?ÿ'çþCþ!ÿ€/ƒ¯ýª½þ¯µöç»æÿ>üüøÜç}ö}÷ŸÚö¿=ý?ÿ?Oþ=}þíÊ?öãùÿ>)ûè©ÿýþÇÿÿÿ?þúøÀ§ÿ;ý_ ?ô§ÿ7ý¿?ÿ¯Ë?탿®ý ÿÃÿ¶ùŸþ¿¶÷ëz_z÷õîý¤ð¥ßß~·Ÿð¾mþÃýK÷ë?Oÿ_ú¿æúχ~AÛú9ÆÖUˆÇ—ùÿ“ë_?é3ÿÚñŸ+úoús»Þªÿ¯å_úùëá§õ<¾¤ÿ­ËÿöþRý_ê_VÒçïîÿgµÿ³6ý§¹ný¿»ÿeÛú«ï¨mÿbÿaÿáÿ'þCÿEàßjÿOúÿÐÿ‡þ?VûÿÐÿÚ¶ü/÷¯Ï¿Jç_›ÿ¤øiÏü‡üCþÿ©ýÿžŒÿ7ö_Äþ§ÿ'üo—ÿ­áþÇÿ‡ÿýþ‡ÿáøßÿ[Ïοpþ]óù“Ûg­ù_ùüoýüOòmÓ]ûÂé¿®GøáþcœïüÏ'óŸ9ÿ{Õÿòx>(U¿¬Gþ®ÿ]ùü¼ÿõüÍógãžÿ·tþóÿœÿgÿÏùÎÿجÿÓ~þ»Nþ†ûïm®qö?Øÿœÿçü?þ?üøÿìùÿ°ÿ8ÿ ýmÒŸúø?F¨C2šÿÍÊ«4þ#ÿ`ÿIû?IÏßRÿï:~¶]o­ÿ]Úÿÿ³bÿ£ÿÉÿ¢þŸÝø?öŸmûø7òŸü?»ñ/iÿÒ>ûÏñúÿPÿŸúÿÔÿ'þo!þ?¢ÿï“õÿ%ú§ÏùWòÿÉÿ×´ûô¯oÕ?Úñ_üÿôÿ´›ÿ±,{únÏwEÿóü1žñŒþøPå\óåx=þû3ðßýüÚð¡?ôוç×yúäõ§ãÿìù—þÊù¿tÿ÷>?üÿ[æð·iÿ?»þ´>ô×­ÿª­õëŽÂÇ×+ù¹ÿÞ~~üþó‘äo?üŸ>ÿèä¿Fýo]ùk}ÿ‡þGÿC»ôÇÿÿ/œïÜÎ'^ÿlƒç³Òã¥ðSù_àOü›ñ¹õÜ+æÞßÏìÇ¿rQ·õ™–Ÿáûõë?7¾NþKãORù¯·ÿíC™ü[–:ø5ñ¿šç=¿ßúKÙÌáþþ×úÿ“ò_Vÿ¡Îþ ÷?Ó?ŸÿÝÿNþ7þŸ˜þ¹õß¶ÿËÑ_[þ·ã_¿ÿÛãó¿öú·#þ‰ý‹ýŸ·Ïkì/©ý¯¿ÿ—â/Ýÿ÷›ÿôü’ÿGþüOþß}ú|»üÃÿÿÿþ?‹þ¿~öŸôü‰vü×.ÿcÿsþ‡ñŒg<çÿÉÿâü?ô·˜ÿ­sþdœø—Mÿßýs{åÔ÷äùÇ:ö?ùÿœÿãüçÿˆÿ“ÿo9ÿûŸø?ñâÿÄÿmë¿Rü³E~Õŵãÿœÿ´JâÿØøÿ¡¿Uÿ¿vÿMøÛøðY 3¾þ]ã­Ï¿õõ/õ?ïãHû~4.ÇëñçyùU¦ß»ýÿWxôôÿÿý–ç¯4ÏòùoóHù¯þþéß÷úoÞ¿þèmúKâÏÒùGþkõƒÿÈ?Æk¯ûsœõ/ý•ÒOç·ßþOªÿuìô¿.ÿü{úüÛ”è]ÿŸ¶üí§¤þô?úÿ?þüÿøÿñøÀÿ¤þ׉ÿŒ`aÿAü6ýÿÖýÚûÿ~û¯wÔŸ€ÿáÿïçð·mÿ¯ëqüöÙë}|ýÿêùsã×5?^ -?ÿ÷›…ÿ6ÛõÖù÷ßÞÿƒqM)üx|‹ý½ç§ãõ£ý_CÿÒühÿKŸÿ“ó'ø¥îýÝ׺ûé­ÿV¼úÒOïõŠ>ót>OߢÿëäŸþõø’þ·.ÿ¯úÿç³]~•ôÿUÿ³Zý=¾NþZßÿJÿšõߣÿݺö]Þåç/Üo ûû϶ý‡ÿÿð|Îÿ[ËÿµžÿGüý¯mŽ8Þzþû?;û?øùÇþ¶Ÿüòÿ°ÿÉÿƒÿÉÿ#ÿÿþ?üèÎÿÃÿð?üÿ½üÿóóÊÇÚç?mýY^ ¶Ï¦yïßüw¿×õi>Žá¹¿]ßú“„þ/¯ï÷…×·ú ûùïòÏFµáü‘áoýŽBÿâПhë‡úû÷XÿǾÉgø¥õ~®øùÃõýg)|Rß+ÍÿÕ¼Ô‡þÚô_×¾ðc8áþ©ùÔ–ÿòüoYþs -ÿãõX?{woü™¿¼ë“ÿÚƒÿôû¿Ÿ×ÿÑžNÓ/OŸ³}•›ÿ\ÿ½üÓýÿÿûo¥ù?æ‡~)ý‘»ßùþ#®éù™úñÚúïÏÿ¤ù·.ÿذÿ·Œiÿ“Û/õÙèïÿ®íÿsÿá6ù»ßÿÄýŸGØÿ`ÿ·Ò¿‡üËÿm[÷Îÿ"ÿñÿáÿÃÿgÕÿ‡ýgÿ¡¿eú—ü³÷ý÷ü¿ÚþOü2ÿå;®kûß´ñÿäuiüGÿÓ¶ÿÎñ§T>Úµÿ¼ÿÉ¿êûÿ×µ%þÖËþ1þgÉþGÿ“ÿu'^=Í}ãÿ#îÿ-Åÿ±ÿlÛÄ¿mÃ'ÿÏvü«uÿS¯ÿïå?½^_xµÄ?Óãsö¿wûFºÿmÿ?ÿëÇÿ-åÿÿ·ìÿÑÿ'Û­«ÄÿvGÿôˆÿÿOþÿHùÿwí?©þÑŽ¿âÿ¯‘{^ìÿ÷Î;ïÖuš½ón]§Ù;ï–Å»e™æiönY¼›§ižfïÖÕ;ï¼[ןŸ¿_ï–Å»eñn]§Ù;ïÖuš½ónY¼[–ižfï–Å»ufï¦yš½+ÛÿVâÿ[¿¿ßcÿ­?Ñë'¼?~ïUO ÷ù6þøùõýúÀÇÿü¤Ÿ üÁß6þÒýÿÒþ§„ÿ»Ïÿ´Á¯ßÿAè¯MÍþ‡OÇ¿Çú·ÿcÙÿÖÝþð?üÿÛÄŸýÏ ÿŠ÷w_ïÞO -_ú}öµþg)ýGµÿ½«[OÒø‡öúÏËÿÖþÃõýŸÇÖÿeü{¬ýþÏèäÿXò_&ûÿ³êÿCÿÛÑÿÐúãÿGþ×Ó?¬ß¿«ñùüGà? >õmäÿ^å_î¿¿,õñ£tý¿ûç¯ë¿¦~Uîüuëù÷^ç¿õÏÿ´Ó¿‡üi…ð¯¿åÿÅõÌt×߈òÿÞùýï»n½þã½üuÙükóŸ?íùûüõ÷×ÿ þ õϰÿµûÿÌS‹ýu×þ×¶$økÃï1ÿÔÿ¢ÿüo¹þ‡mùgÝÿ‹ÿÿþ?»þ?‰ý×£ÿ~ý_øûŸú¿øÀü‰ÿÐÿÉZÿ'èÿú¿øÿ¨ÿg³þŸõú¿2ü{¯ùüÇã©ÿKýßžûòï¿ >ö?ö?ñìâÿÈÿ:ùß7þ;bþ7þ?èo%þýÿC›ô§þõG¤?õ/?_ÿ¯ÝÿÜ^ÿo„ú/9ükêïÉýÿcÔÿ£þ·½ú?èê?RÿÍný7ì?äûÛòÄúßcÔ?·Þÿ§¼ÿëSÿ|<ûŸúÿÔÿ§þ?õÿ-éÿ‘üŸ¬ÿŸó•Ö_Ÿüô?úÿ?þüÿøÿ?­ÿçi?¿¼«ù?ëMÿ„ÏöŸ§ÇïéŸ/…ŸÒÇ1àþàÿ’…{ù¾É§+ù–ŸRü7ù=O)øeüóãƒüŸ§ôóçñoƒ?ÍéúGÓ|Î?‡þÐ ù·ßKæßßý­»ßÓñ—Êÿ~óçûaýoëø8>u}Yúáø' ¿„Oi|êúþùáøß2ÿƒ¿mû¿%þ³÷ßÍSýøÍÿû4á·Ðÿ›ÆËüéøCø¼<ÿÚö¿,þÓ£þí(ñŸØßŸ–§ñ÷ç©~|üýyiý×ã¿÷»K×|¿vø×ã÷×{èÿ÷Я÷ó|úùíÈÿ}üªŸþ¯—¿{ý/­ÿ`}ÿ§Mÿ–ù¯_žíõ7ŽýýgÑþÃÿOüGB)þ5ô» ¿ýÁü­à¿×eù÷©ßr|%Ÿ 5™sõŸ¯ñÏ?^ÿ¾‡ -¿þæñùãþS5ñ«øòø—”þ²õ¿,Òù¿÷¼çï÷[mô×á©ýßÃþÕ¬i]þk÷Ó–ÿ²þoéþa^jú>¯þkOþGþ!ÿ°ÿDZÿ{ØŸ-öÿóñ—Òûûþ‡ÿuùß.þèüøÿÐÿ¶õ?üÿÃÿvøßzþ#ã9ÿÏùÿöüIéúÓÎÿ$ÿ úkÂâù—žçÆ9ÿgóüëž^ÇþìéýÁ5ý¥ùÿõçÿKû£;×Éÿïuþ-ýyÍù¿1οpþóÿìØÿÚÏùêÿpþýÇùä?þüÐß–ÿûþ‡þÔ¡þŸõúOýêÜñ>qý÷Ĥú²øO[üoœúOiüKþ÷~õtüÿÒøY?ûS'þGüýOýgêÿÿÇþ³hÿÿFþ“ÿg7þÕ²ÿÛ¾×·þ«NÿêÿSÿŸü?âÿøuüãÔÿ—êiü‡üòÿuóÿeö_[þÿ8õÿñÿÓÿÓZüÿõDÛS‡çßøƒë\çúw_—þ{7üw?¿6|èýµè_g¿”ò'ÛÇ?ÿ§Ï]ýªëúiýð/ÁßóÃÿð?üoëöÿæ¯úû=ú¯®ÆÿÖËŸ¸]/ß®úÇ}kBŸšÔ¿Ô÷¤ó¯©kð/­¿«yIÁI}®Íçþ3Þ]É϶þ7×ýgFXÿüŸ>ÿè俦ü×–¿ìÿÐÿÖõ?ô·KüÿÄ^¹Çü‡-?!}½÷ýãñRø¥ûƒ?ö/×Óç'KýORýsÚóŸÒ1ôG©Yÿ¥ñyý/‹?Éíüÿíô—Ê?íþOéõ"]Ó|ïþzòËÅ<Ú×ðÛìÏpÿ3ýSö¯þüÿ¹ýÿ1=·^Ûö×ô×—ÿeüK민ÿÛçŸçSsý[¿ÿÄ>Æþ×ë¬oÿÈðïgÿjö%ÿÏvþŸuþ·žÿgWþY÷ÿâÿÃÿ‡ÿϲÿOf?õПºñøûŸó?O=ÂxÆ3^Oþþ»Ÿ_>ô‡þôÿ_Ý«èõª¾R\ÿ+œ?Éß×_ãüËu}¨ºëRúIá·]¿¢ÿ²¤¯¾'ÿÒo ¿Ößóú{½¦ù¿fý¥Ç‡øÿ‘ÿµ×¿6ÿü{úüÛ”Øÿšñ¿1âßÖñÇþ·½ÿ“Ô­¯¯ZªÏª»þ-ë¿>ô—Ê¿~ë¯_ý_{úï³ñíø/òúßÿ…þñüíóÿ±ÿ°ÿðÿCMÿ×ßo¾Uø»­ÿe©ÿ˜&üšþ¥þ‘Oo}þ­¯©ÿ¹¦ÿO©ÿ̵ü*ÓïÝþÿ+{½¯á_=nüºæÇKáÇãÿ~óã¯ðßæo»Þ:ÿáþûžK×ô—ÂÇ·Øß{~:^?Úÿ5ô/Íÿˆö¿ôù?9Òñ_êÞß}­»ŸÞúoÅ«/ýô^¯è3Oçóô-ú¿NþIá_/éëòÿØÿl¯?S×ï˯’þåç]ý=¾NþZßÿJÿšõŸšÿÔù÷Üü¯kßõç]~þÂýư±ÿlÛøÿñÿøÀçü¿µü_ëùÄÿÐÿÚöçˆã­ç±ÿ³³ÿƒÿ˜ìoëðÉÿ!ÿûŸü?øŸü?òÿðÿáÿÃÿ‡þçü?üÿÃÿßËÿ??¯|¬}þÓÖŸåU±`ûlš÷þÍ÷{]ŸæãøžûñÛõ­?Ièÿòú~_øñøp}«Ï°Ÿð÷.ÿüaTþÀþÖï(ô/ý‰¶~H¡_ѱÏqõì›|†_Zÿç犟?\ß–Â'õ½Òü_ÍK-|è¯Mÿuí ?†Omù/Ïÿ–å?§ð?^õ³w÷ÆŸùË»>ù¯=øO¿ÿûyýíé4ý÷ðòô9ÛW¹ùÏõß«Á?Ýÿ/ðß±ÿVšÿc~Èá—Ò¹ûï?âú—žŸ©¯­ÿÞñüOšëòýûËø—ö?¹ýRŸý‡îþËúþïÚþ?÷n“¿ûýOÜÿy„ýö+ý{È¿Üùß¶õwïü/òÿþ?üVýØÖùú[¦É?{ßÿxÏÿ«íÿÄÿ!ó_¾ãº¶ÿMÿO^—Ƥñ?mûïJå£]ûÏËñŸü«¾ÿ][âo½ìÿã–ìô?ù_wâÕÓÜ7þ?âþßRüû϶ýGüÛ6|òÿlÇ¿Z÷?õúÿ^þÓëõ…WKü3=>gÿ{'±o¤û¿Ñöÿ#ð¿~üßRþñËþßý²ý׺JüowôOøùÿäÿ”ÿ×þ“êíø+þÿù·çžñï¼ón]§Ù;ïÖuš½ónY¼[–ižfï–Å»yšæiön]½óλuýùùûõnY¼[ïÖuš½ón]§Ù;ï–Å»e™æiönY¼[×iönš§Ù»²ýo%þÏ?üØý‰åK,J×ß ÿÝϯ úCÍŸ}m¥ÔçñßçúA²ñOÇÿéó¿¯ïµ_ŸWþ‡Ø Ç?ÿÝÏÿÃÿ¶ùß6þÖ¶zñkí÷KŸÇ×GƒoýGê’ο¶þ-á_ZRÿ›öú×®?:Âú—àÿôùGÿ#ÿ5å¿¶üeÿ‡þ·®ÿ¡¿]úãÿ'þ³Ï/ŒóÓ×ïÎoéþñx)üÒýï>ß·ãÏu«×Co”c½§«üËsþTMüe?þXÿ/]eæúüg -¿ÒøÜ¿ðü§sÎ[>~$ù'_õßN©üKÏþþ¹ñÇëñóçêµ­¿i¾w=ùoýüò_·þŸ¾ü§þ‡fþñëßòùoìcìÿؾʿl³?óö¿®ý#ÿŸý;Oýæ?uþµ´(í®ígùúkßõxþÒ¿~Òð¿6ÿ¿/ôÝðûïÿmÉ?ëþ_üøÿðÿYöÿÉì§úSÓþ‚ÿ±ÿ±ÿÕ×ãÏøÊÿÏÁ÷ókÇþÐ_ƒþç:W¯×í\E¸Ø+îëK…úKùñûÏ—enE·þ]Œ_ü|õ×¥ô“Âo»~EÿeIÿ^}O:ÿ¥ß~­¿úõÇôë?jòÿ÷È¿§Ï¿Mù‡ý¯ÿ#þmìÛû¿/ 6áký¤¯ß•¯¥û°þ-ë¿>ô—Ê¿~ë/½¾Jø£ÿ>ÿ׎ÿ"ÿ¡ÿ=ü[èÏß>ÿûûÿ?ô×ôiÖŸzvý«ç·>ÿÖ׿Ôÿ¼#ýýž?¯ÇŸëÖ.ã…GOÿÿßoyþJó,Ÿÿ6ÿA¿úã¥û§ßë¿yÿúCþ¡ÿµé/‰?KçùŸÂ¿¼þúÉøù‡üc¼Öú×±?ÇYÿÒ_)ýt~ûíÿ¤ú_ÇþGÿëòÿ÷È¿§Ï¿Mù‡þ×õÿiËß~úGêÿAÿ£ÿñÿãÿÇÿÿŸþGüðÃÏgúÐÿÅvÿèOÿoúÛìÿ-³_åøëÚßð?üo›ÿéÿkùçï7ôÿ þÃíwû ïÛúO†û—î×~<þºÿe|ÿº÷wîÞO -¿þûô¥ÿïö»çŸíüàþ;íñ‡pÿ}ϱQÖ¿$þÒgþµóŸ}·ù»¢›þ¼¦gZ×ï_ÒÿÖå{ÿ?©þ/õ?+éÿw÷ÿûþýŸ.ýKõëKëùÝý/ÛÖ_}ÿCmûû϶ý‡ÿŸøý¹ÎuËý?éÿCÿúÿØìÿCÿkÛò?®[Ÿê_?͹>÷ÒùוÿeüKëïj^RpRŸÃÈ?ä×-öÿ{:þßÓûŸþŸð¿]þ·‰?úÿþ?ô?úþ‡ÿáküo=ÿüùáüÈïLçOÆ×ïæ/]¯gíüOò¿ ÿ6øwï¯}þEïü~þ³õó¿þûü÷«þsqýùù|ÿºòùiÿ;òÿ5ÏŸpþ…óœÿ·ýÃþß*þœÿ¡þäüwüÇtþ™ú?œÿ·.ÿñÿáÿÃÿgÑÿ‡ýÿC»ô§þŸmûO»þÈë_ÿ‘êÿµÄ¤ñ¿ê?Iú?õ8ÿ§ëÿßz:íÓ+ú·ÕÿÎíÿuãÖíô¿íêÿÙŽÿcÿÙ¶ÿøAþ“ÿg7þUÚÿÄös[þ_nþõû¿RÿŸúÿÔÿ'þoÑÿ«íÿÓ®ÿ/Õ?òó¯äÿ“ÿ¯ÿßnÿIõÏõÿñÿÓÿÓjüÿ¿ñ£# \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_167_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_167_states.bin.bz2 new file mode 100644 index 000000000..bb2c8cc48 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_167_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_167_states.bin.z b/client/resources/hardnested_tables/bitflip_0_167_states.bin.z deleted file mode 100644 index 8aae9133c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_167_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_169_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_169_states.bin.bz2 new file mode 100644 index 000000000..bbec52e26 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_169_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_169_states.bin.z b/client/resources/hardnested_tables/bitflip_0_169_states.bin.z deleted file mode 100644 index a42857b5a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_169_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_16b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_16b_states.bin.bz2 new file mode 100644 index 000000000..0a34da2f6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_16b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_16b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16b_states.bin.z deleted file mode 100644 index 426210add..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_16b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_16d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_16d_states.bin.bz2 new file mode 100644 index 000000000..c6758b6a2 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_16d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_16d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16d_states.bin.z deleted file mode 100644 index 5640076fd..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_16d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_16f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_16f_states.bin.bz2 new file mode 100644 index 000000000..fe936f3bf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_16f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_16f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16f_states.bin.z deleted file mode 100644 index 39d0d0801..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_16f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_170_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_170_states.bin.bz2 new file mode 100644 index 000000000..5180aae93 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_170_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_170_states.bin.z b/client/resources/hardnested_tables/bitflip_0_170_states.bin.z deleted file mode 100644 index f49f4d249..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_170_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_174_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_174_states.bin.bz2 new file mode 100644 index 000000000..00e4f95b4 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_174_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_174_states.bin.z b/client/resources/hardnested_tables/bitflip_0_174_states.bin.z deleted file mode 100644 index 66acfea97..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_174_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_17c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_17c_states.bin.bz2 new file mode 100644 index 000000000..01c02bb2b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_17c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_17c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_17c_states.bin.z deleted file mode 100644 index c8f72c15f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_17c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_184_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_184_states.bin.bz2 new file mode 100644 index 000000000..5da967674 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_184_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_184_states.bin.z b/client/resources/hardnested_tables/bitflip_0_184_states.bin.z deleted file mode 100644 index caa5e8bd4..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_184_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_18c_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_18c_states.bin.bz2 new file mode 100644 index 000000000..88f05ef65 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_18c_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_18c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_18c_states.bin.z deleted file mode 100644 index da5c55a2d..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_18c_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_191_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_191_states.bin.bz2 new file mode 100644 index 000000000..7303065d9 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_191_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_191_states.bin.z b/client/resources/hardnested_tables/bitflip_0_191_states.bin.z deleted file mode 100644 index 5a4b9aef1..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_191_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_193_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_193_states.bin.bz2 new file mode 100644 index 000000000..b9e3297c5 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_193_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_193_states.bin.z b/client/resources/hardnested_tables/bitflip_0_193_states.bin.z deleted file mode 100644 index 5f7e0b484..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_193_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_195_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_195_states.bin.bz2 new file mode 100644 index 000000000..fa5060af8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_195_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_195_states.bin.z b/client/resources/hardnested_tables/bitflip_0_195_states.bin.z deleted file mode 100644 index e15df41f5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_195_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_197_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_197_states.bin.bz2 new file mode 100644 index 000000000..5de558643 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_197_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_197_states.bin.z b/client/resources/hardnested_tables/bitflip_0_197_states.bin.z deleted file mode 100644 index d4b5fd31c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_197_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_199_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_199_states.bin.bz2 new file mode 100644 index 000000000..c4f58b53d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_199_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_199_states.bin.z b/client/resources/hardnested_tables/bitflip_0_199_states.bin.z deleted file mode 100644 index 9117c86da..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_199_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_19b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_19b_states.bin.bz2 new file mode 100644 index 000000000..9ad820f8c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_19b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_19b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19b_states.bin.z deleted file mode 100644 index ae144de8c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_19b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_19d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_19d_states.bin.bz2 new file mode 100644 index 000000000..54371d652 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_19d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_19d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19d_states.bin.z deleted file mode 100644 index 1b7f08b3d..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_19d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_19f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_19f_states.bin.bz2 new file mode 100644 index 000000000..b4a434889 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_19f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_19f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19f_states.bin.z deleted file mode 100644 index 81ef023c3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_19f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.bz2 new file mode 100644 index 000000000..ca79aa9b0 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.z deleted file mode 100644 index af0f72086..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.bz2 new file mode 100644 index 000000000..944d52e07 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.z deleted file mode 100644 index 5b2ddbf57..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.bz2 new file mode 100644 index 000000000..860f486bf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.z deleted file mode 100644 index 61ce91072..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.bz2 new file mode 100644 index 000000000..8afe0ffb9 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.z deleted file mode 100644 index 3825cf8b8..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.bz2 new file mode 100644 index 000000000..804b581f8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.z deleted file mode 100644 index 7750ad78f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.bz2 new file mode 100644 index 000000000..8d541ff7d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.z deleted file mode 100644 index 1663d7a5e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.bz2 new file mode 100644 index 000000000..42269c116 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.z deleted file mode 100644 index f6b102d9a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.bz2 new file mode 100644 index 000000000..f1f353e41 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.z deleted file mode 100644 index 0e6675818..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.bz2 new file mode 100644 index 000000000..ce30db7be Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.z deleted file mode 100644 index 8e991fcba..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.bz2 new file mode 100644 index 000000000..43164354d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.z deleted file mode 100644 index 9fe373bd8..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.bz2 new file mode 100644 index 000000000..a805bf22a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.z deleted file mode 100644 index 1d6e2df38..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.bz2 new file mode 100644 index 000000000..5ef2b8efa Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.z deleted file mode 100644 index c47845644..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.bz2 new file mode 100644 index 000000000..abc9ef501 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.z deleted file mode 100644 index fd67e955c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.bz2 new file mode 100644 index 000000000..6d8d002e6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.z deleted file mode 100644 index 88ab2a968..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.bz2 new file mode 100644 index 000000000..e9caa94a6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.z deleted file mode 100644 index 31bd47cc6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.bz2 new file mode 100644 index 000000000..26a43e303 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.z deleted file mode 100644 index 8ac5e4099..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.bz2 new file mode 100644 index 000000000..15911b954 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.z deleted file mode 100644 index ad91ddea9..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.bz2 new file mode 100644 index 000000000..ab5149491 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.z deleted file mode 100644 index f5b1dbb10..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.bz2 new file mode 100644 index 000000000..7e4c4e5a8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.z deleted file mode 100644 index d475d9778..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.bz2 new file mode 100644 index 000000000..887da78ed Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.z deleted file mode 100644 index 64884ba56..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.bz2 new file mode 100644 index 000000000..43b2cee21 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.z deleted file mode 100644 index cd80ef830..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.bz2 new file mode 100644 index 000000000..89ebe72a9 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.z deleted file mode 100644 index 42483bdd5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.bz2 new file mode 100644 index 000000000..64ab8f4ce Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.z deleted file mode 100644 index d133b27a2..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.bz2 new file mode 100644 index 000000000..d76993719 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.z deleted file mode 100644 index 7a3b347bb..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.bz2 new file mode 100644 index 000000000..8574c08f7 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.z deleted file mode 100644 index db5d216aa..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.bz2 new file mode 100644 index 000000000..7a9012f47 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.z deleted file mode 100644 index 15eeba048..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.bz2 new file mode 100644 index 000000000..058cbfd82 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.z deleted file mode 100644 index fb3df75b7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.bz2 new file mode 100644 index 000000000..69262a53f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.z deleted file mode 100644 index fe2d56c90..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.bz2 new file mode 100644 index 000000000..c3d550787 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.z deleted file mode 100644 index 791352bfd..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_210_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_210_states.bin.bz2 new file mode 100644 index 000000000..fe85775bf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_210_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_210_states.bin.z b/client/resources/hardnested_tables/bitflip_0_210_states.bin.z deleted file mode 100644 index 479bacb03..000000000 --- a/client/resources/hardnested_tables/bitflip_0_210_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÛMnãF„aÝÀWÑtï½Ñ‰|5o}4¢Á–L‰”«êg‚ ™ÌObOj¾ªz»ߟ‡óð1$Ž_¦¿Ÿ¾ÌÝþíKß¿þrùýÒßþãKþý->É··øõ¯Þ¥/÷~ýÒÏ»ÿþ}þÿK?ÏþüÓÿkëÿxzûIþ,×ñtûã_ú~[þùû–׿¿ûïÿüõúŸ¯ý÷?þãÛ~þžýùO}Ö¾}ïÏúñ¥ÿþôó—~;ý÷­ÿ÷¯ìñçœÿnæ¿nûör‡ê¯×ÿ¼|ßóð¿ýõÖ_úïO?é··øõŸ>®ÛþãÞ¯_úùOÿØûÿ¿ôó—þøCøeþ9ÊÏwùó®}{ù}¨þzýÏÇaúúôñ<ú㯿ÞúãKÿýéç¯Å·Ó¿úwÿû¾ÿéïÿÅK–ßIÆß§§¿nûý;ýý7ý²÷ýI?é—ÿûÎÿúÿ¾ûú×ÿéÿôü¿þOþï/ÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿ¯ëÿÝ÷ßýçÿé¿Oý{ÿ×÷û?þßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñüÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúû÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§ûûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?ýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùþŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿù÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûÿÞßÿý[‘Ôß \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_225_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_225_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_225_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_225_states.bin.z b/client/resources/hardnested_tables/bitflip_0_225_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_225_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_227_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_227_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_227_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_227_states.bin.z b/client/resources/hardnested_tables/bitflip_0_227_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_227_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_22d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_22d_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_22d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_22d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_22d_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_22d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_22f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_22f_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_22f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_22f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_22f_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_22f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_240_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_240_states.bin.bz2 new file mode 100644 index 000000000..6d1908e79 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_240_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_240_states.bin.z b/client/resources/hardnested_tables/bitflip_0_240_states.bin.z deleted file mode 100644 index e4f4b6ac6..000000000 --- a/client/resources/hardnested_tables/bitflip_0_240_states.bin.z +++ /dev/null @@ -1,2 +0,0 @@ -xÚí×AŠ­P á,Õ;w!щG -! ‡¯{ð4܆.Rˆ-ö£÷×Wý/³þýöóîçOOÿþîßoúï?þø¯Ë?š_õ÷ç=?÷íçÝÏŸþšþýÝ¿ßôßüñ_—¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí?þúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõŸþãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡?ÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó?þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷Ÿýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó?þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿ý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸþÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì?þøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí?þúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõŸþãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡?ÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó?þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷Ÿýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó?þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿ý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸþÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì?þøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùÿ¿ò?š;Õm \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_275_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_275_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_275_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_275_states.bin.z b/client/resources/hardnested_tables/bitflip_0_275_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_275_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_277_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_277_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_277_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_277_states.bin.z b/client/resources/hardnested_tables/bitflip_0_277_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_277_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_27f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_27f_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_27f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_27f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_27f_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_27f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_294_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_294_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_294_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_294_states.bin.z b/client/resources/hardnested_tables/bitflip_0_294_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_0_294_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_335_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_335_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_335_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_335_states.bin.z b/client/resources/hardnested_tables/bitflip_0_335_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_335_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_337_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_337_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_337_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_337_states.bin.z b/client/resources/hardnested_tables/bitflip_0_337_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_337_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_33d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_33d_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_33d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_33d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_33d_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_33d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_33f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_33f_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_33f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_33f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_33f_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_33f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_350_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_350_states.bin.bz2 new file mode 100644 index 000000000..fe85775bf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_350_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_350_states.bin.z b/client/resources/hardnested_tables/bitflip_0_350_states.bin.z deleted file mode 100644 index 479bacb03..000000000 --- a/client/resources/hardnested_tables/bitflip_0_350_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÛMnãF„aÝÀWÑtï½Ñ‰|5o}4¢Á–L‰”«êg‚ ™ÌObOj¾ªz»ߟ‡óð1$Ž_¦¿Ÿ¾ÌÝþíKß¿þrùýÒßþãKþý->É··øõ¯Þ¥/÷~ýÒÏ»ÿþ}þÿK?ÏþüÓÿkëÿxzûIþ,×ñtûã_ú~[þùû–׿¿ûïÿüõúŸ¯ý÷?þãÛ~þžýùO}Ö¾}ïÏúñ¥ÿþôó—~;ý÷­ÿ÷¯ìñçœÿnæ¿nûör‡ê¯×ÿ¼|ßóð¿ýõÖ_úïO?é··øõŸ>®ÛþãÞ¯_úùOÿØûÿ¿ôó—þøCøeþ9ÊÏwùó®}{ù}¨þzýÏÇaúúôñ<ú㯿ÞúãKÿýéç¯Å·Ó¿úwÿû¾ÿéïÿÅK–ßIÆß§§¿nûý;ýý7ý²÷ýI?é—ÿûÎÿúÿ¾ûú×ÿéÿôü¿þOþï/ÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿ¯ëÿÝ÷ßýçÿé¿Oý{ÿ×÷û?þßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñüÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúû÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§ûûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?ýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùþŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿù÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûÿÞßÿý[‘Ôß \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_365_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_365_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_365_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_365_states.bin.z b/client/resources/hardnested_tables/bitflip_0_365_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_365_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_367_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_367_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_367_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_367_states.bin.z b/client/resources/hardnested_tables/bitflip_0_367_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_367_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_36d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_36d_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_36d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_36d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_36d_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_36d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_36f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_36f_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_36f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_36f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_36f_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_36f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_384_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_384_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_384_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_384_states.bin.z b/client/resources/hardnested_tables/bitflip_0_384_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_0_384_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_002_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_002_states.bin.bz2 new file mode 100644 index 000000000..4c9093b38 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_002_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_002_states.bin.z b/client/resources/hardnested_tables/bitflip_1_002_states.bin.z deleted file mode 100644 index 226c37a2f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_002_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_008_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_008_states.bin.bz2 new file mode 100644 index 000000000..89d88b572 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_008_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_008_states.bin.z b/client/resources/hardnested_tables/bitflip_1_008_states.bin.z deleted file mode 100644 index 209bf5e9e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_008_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_00a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_00a_states.bin.bz2 new file mode 100644 index 000000000..38af88dff Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_00a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_00a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_00a_states.bin.z deleted file mode 100644 index 63f0a7a5e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_00a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_012_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_012_states.bin.bz2 new file mode 100644 index 000000000..492261923 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_012_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_012_states.bin.z b/client/resources/hardnested_tables/bitflip_1_012_states.bin.z deleted file mode 100644 index 659e697f2..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_012_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_018_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_018_states.bin.bz2 new file mode 100644 index 000000000..c0a592378 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_018_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_018_states.bin.z b/client/resources/hardnested_tables/bitflip_1_018_states.bin.z deleted file mode 100644 index b825cfd6c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_018_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_01a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_01a_states.bin.bz2 new file mode 100644 index 000000000..98093a999 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_01a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_01a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_01a_states.bin.z deleted file mode 100644 index 61d252b20..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_01a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_020_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_020_states.bin.bz2 new file mode 100644 index 000000000..333dab4c5 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_020_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_020_states.bin.z b/client/resources/hardnested_tables/bitflip_1_020_states.bin.z deleted file mode 100644 index cc78af68f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_020_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_028_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_028_states.bin.bz2 new file mode 100644 index 000000000..7f2e66c32 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_028_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_028_states.bin.z b/client/resources/hardnested_tables/bitflip_1_028_states.bin.z deleted file mode 100644 index 1137886b1..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_028_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_02a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_02a_states.bin.bz2 new file mode 100644 index 000000000..18c04fa47 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_02a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_02a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_02a_states.bin.z deleted file mode 100644 index 12829c1bf..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_02a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_02e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_02e_states.bin.bz2 new file mode 100644 index 000000000..2ecb621b3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_02e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_02e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_02e_states.bin.z deleted file mode 100644 index 44fb65c0d..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_02e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_032_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_032_states.bin.bz2 new file mode 100644 index 000000000..083f1f0a5 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_032_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_032_states.bin.z b/client/resources/hardnested_tables/bitflip_1_032_states.bin.z deleted file mode 100644 index a8350cc17..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_032_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_036_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_036_states.bin.bz2 new file mode 100644 index 000000000..7fa414bd8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_036_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_036_states.bin.z b/client/resources/hardnested_tables/bitflip_1_036_states.bin.z deleted file mode 100644 index c14426d0b..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_036_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_038_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_038_states.bin.bz2 new file mode 100644 index 000000000..15f739f1b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_038_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_038_states.bin.z b/client/resources/hardnested_tables/bitflip_1_038_states.bin.z deleted file mode 100644 index ec0b39af2..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_038_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_03a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_03a_states.bin.bz2 new file mode 100644 index 000000000..61ef02268 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_03a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_03a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_03a_states.bin.z deleted file mode 100644 index e301254b9..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_03a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_03e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_03e_states.bin.bz2 new file mode 100644 index 000000000..7dd251575 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_03e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_03e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_03e_states.bin.z deleted file mode 100644 index 9e5c059f5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_03e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_040_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_040_states.bin.bz2 new file mode 100644 index 000000000..87d8693df Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_040_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_040_states.bin.z b/client/resources/hardnested_tables/bitflip_1_040_states.bin.z deleted file mode 100644 index d3f655b04..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_040_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_042_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_042_states.bin.bz2 new file mode 100644 index 000000000..b757bce02 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_042_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_042_states.bin.z b/client/resources/hardnested_tables/bitflip_1_042_states.bin.z deleted file mode 100644 index d324368a6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_042_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_046_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_046_states.bin.bz2 new file mode 100644 index 000000000..b1454b4e8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_046_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_046_states.bin.z b/client/resources/hardnested_tables/bitflip_1_046_states.bin.z deleted file mode 100644 index ff59e7409..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_046_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_048_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_048_states.bin.bz2 new file mode 100644 index 000000000..99563f5db Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_048_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_048_states.bin.z b/client/resources/hardnested_tables/bitflip_1_048_states.bin.z deleted file mode 100644 index e21985aa3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_048_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_04a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_04a_states.bin.bz2 new file mode 100644 index 000000000..b31851187 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_04a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_04a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_04a_states.bin.z deleted file mode 100644 index 45c58fce2..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_04a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_04e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_04e_states.bin.bz2 new file mode 100644 index 000000000..d0a946c4e Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_04e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_04e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_04e_states.bin.z deleted file mode 100644 index 3966d1b10..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_04e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_052_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_052_states.bin.bz2 new file mode 100644 index 000000000..95d0d7af7 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_052_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_052_states.bin.z b/client/resources/hardnested_tables/bitflip_1_052_states.bin.z deleted file mode 100644 index f0be53efc..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_052_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_056_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_056_states.bin.bz2 new file mode 100644 index 000000000..92dee0efa Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_056_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_056_states.bin.z b/client/resources/hardnested_tables/bitflip_1_056_states.bin.z deleted file mode 100644 index e92d411b7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_056_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_058_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_058_states.bin.bz2 new file mode 100644 index 000000000..ca2fe1a7a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_058_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_058_states.bin.z b/client/resources/hardnested_tables/bitflip_1_058_states.bin.z deleted file mode 100644 index 005459173..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_058_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_05a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_05a_states.bin.bz2 new file mode 100644 index 000000000..2771dced1 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_05a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_05a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_05a_states.bin.z deleted file mode 100644 index 1dfa63c70..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_05a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_05e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_05e_states.bin.bz2 new file mode 100644 index 000000000..94c8612fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_05e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_05e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_05e_states.bin.z deleted file mode 100644 index dc0789685..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_05e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_060_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_060_states.bin.bz2 new file mode 100644 index 000000000..edc274c4b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_060_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_060_states.bin.z b/client/resources/hardnested_tables/bitflip_1_060_states.bin.z deleted file mode 100644 index 72477c138..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_060_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_062_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_062_states.bin.bz2 new file mode 100644 index 000000000..5b50711b3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_062_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_062_states.bin.z b/client/resources/hardnested_tables/bitflip_1_062_states.bin.z deleted file mode 100644 index 53e85964a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_062_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_066_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_066_states.bin.bz2 new file mode 100644 index 000000000..e599d5318 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_066_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_066_states.bin.z b/client/resources/hardnested_tables/bitflip_1_066_states.bin.z deleted file mode 100644 index de23de8b3..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_066_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_068_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_068_states.bin.bz2 new file mode 100644 index 000000000..d52f1573d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_068_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_068_states.bin.z b/client/resources/hardnested_tables/bitflip_1_068_states.bin.z deleted file mode 100644 index 08b3e5439..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_068_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_06a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_06a_states.bin.bz2 new file mode 100644 index 000000000..05cdc3556 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_06a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_06a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_06a_states.bin.z deleted file mode 100644 index 052898c7f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_06a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_06e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_06e_states.bin.bz2 new file mode 100644 index 000000000..f1087952d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_06e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_06e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_06e_states.bin.z deleted file mode 100644 index 5e678bd47..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_06e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_072_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_072_states.bin.bz2 new file mode 100644 index 000000000..138c17c0f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_072_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_072_states.bin.z b/client/resources/hardnested_tables/bitflip_1_072_states.bin.z deleted file mode 100644 index 404b482d8..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_072_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_076_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_076_states.bin.bz2 new file mode 100644 index 000000000..db0df90a6 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_076_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_076_states.bin.z b/client/resources/hardnested_tables/bitflip_1_076_states.bin.z deleted file mode 100644 index ac58f16e5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_076_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_078_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_078_states.bin.bz2 new file mode 100644 index 000000000..2c6f9cd4d Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_078_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_078_states.bin.z b/client/resources/hardnested_tables/bitflip_1_078_states.bin.z deleted file mode 100644 index 47474d218..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_078_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_07a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_07a_states.bin.bz2 new file mode 100644 index 000000000..ea2f8386b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_07a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_07a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_07a_states.bin.z deleted file mode 100644 index 8b4d446d6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_07a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_07e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_07e_states.bin.bz2 new file mode 100644 index 000000000..00d59bf75 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_07e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_07e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_07e_states.bin.z deleted file mode 100644 index dff5034c5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_07e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_080_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_080_states.bin.bz2 new file mode 100644 index 000000000..54b71e2ce Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_080_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_080_states.bin.z b/client/resources/hardnested_tables/bitflip_1_080_states.bin.z deleted file mode 100644 index 372d2d4ad..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_080_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_082_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_082_states.bin.bz2 new file mode 100644 index 000000000..9937ecd2a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_082_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_082_states.bin.z b/client/resources/hardnested_tables/bitflip_1_082_states.bin.z deleted file mode 100644 index 5d688299c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_082_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_086_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_086_states.bin.bz2 new file mode 100644 index 000000000..30d232f69 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_086_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_086_states.bin.z b/client/resources/hardnested_tables/bitflip_1_086_states.bin.z deleted file mode 100644 index e640e39c6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_086_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_088_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_088_states.bin.bz2 new file mode 100644 index 000000000..cf826e416 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_088_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_088_states.bin.z b/client/resources/hardnested_tables/bitflip_1_088_states.bin.z deleted file mode 100644 index 07dae4760..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_088_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_08a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_08a_states.bin.bz2 new file mode 100644 index 000000000..b708bd851 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_08a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_08a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_08a_states.bin.z deleted file mode 100644 index 449c46f3c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_08a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_08e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_08e_states.bin.bz2 new file mode 100644 index 000000000..79c5eec83 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_08e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_08e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_08e_states.bin.z deleted file mode 100644 index bdea7a0f1..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_08e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_092_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_092_states.bin.bz2 new file mode 100644 index 000000000..917b8cc2f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_092_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_092_states.bin.z b/client/resources/hardnested_tables/bitflip_1_092_states.bin.z deleted file mode 100644 index 6147f3fdd..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_092_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_096_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_096_states.bin.bz2 new file mode 100644 index 000000000..f5b0d1e39 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_096_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_096_states.bin.z b/client/resources/hardnested_tables/bitflip_1_096_states.bin.z deleted file mode 100644 index 575a38314..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_096_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_098_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_098_states.bin.bz2 new file mode 100644 index 000000000..648c9f2b9 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_098_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_098_states.bin.z b/client/resources/hardnested_tables/bitflip_1_098_states.bin.z deleted file mode 100644 index dee21c52a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_098_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_09a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_09a_states.bin.bz2 new file mode 100644 index 000000000..261c672de Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_09a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_09a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_09a_states.bin.z deleted file mode 100644 index c4d76b453..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_09a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_09e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_09e_states.bin.bz2 new file mode 100644 index 000000000..bddf5c91f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_09e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_09e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_09e_states.bin.z deleted file mode 100644 index dd57c590e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_09e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.bz2 new file mode 100644 index 000000000..fe09d19cb Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.z deleted file mode 100644 index 32880a5cd..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.bz2 new file mode 100644 index 000000000..8aa9c2542 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.z deleted file mode 100644 index 25d53d5f6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.bz2 new file mode 100644 index 000000000..aa6ec2408 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.z deleted file mode 100644 index ca1f5f93e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.bz2 new file mode 100644 index 000000000..6d8970c2e Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.z deleted file mode 100644 index c7d501ca4..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.bz2 new file mode 100644 index 000000000..e23808553 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.z deleted file mode 100644 index 5c194d179..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.bz2 new file mode 100644 index 000000000..bfc6848dd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.z deleted file mode 100644 index 2ce45b017..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.bz2 new file mode 100644 index 000000000..05a4d0fd5 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.z deleted file mode 100644 index d81106d05..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.bz2 new file mode 100644 index 000000000..34fd067ec Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.z deleted file mode 100644 index e8c99c170..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.bz2 new file mode 100644 index 000000000..f638e4e1b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.z deleted file mode 100644 index 25e777872..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.bz2 new file mode 100644 index 000000000..7be7169f4 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.z deleted file mode 100644 index 240130a6c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0be_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0be_states.bin.bz2 new file mode 100644 index 000000000..91e544e4c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0be_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0be_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0be_states.bin.z deleted file mode 100644 index 05aca3b6c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0be_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.bz2 new file mode 100644 index 000000000..87d8693df Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.z deleted file mode 100644 index d3f655b04..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.bz2 new file mode 100644 index 000000000..05f424f30 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.z deleted file mode 100644 index cbbb63701..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.bz2 new file mode 100644 index 000000000..c104fb1de Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.z deleted file mode 100644 index 95d162000..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.bz2 new file mode 100644 index 000000000..6548e5270 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.z deleted file mode 100644 index 5eca50e2e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.bz2 new file mode 100644 index 000000000..8ceab191a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.z deleted file mode 100644 index 500be7d66..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.bz2 new file mode 100644 index 000000000..26fc3dcd4 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.z deleted file mode 100644 index 583dc35e1..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.bz2 new file mode 100644 index 000000000..9d6eaefdd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.z deleted file mode 100644 index a2395d9d7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.bz2 new file mode 100644 index 000000000..d6b205973 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.z deleted file mode 100644 index b2cc698ad..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.bz2 new file mode 100644 index 000000000..3a4e9b14c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.z deleted file mode 100644 index 4188dbd10..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0da_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0da_states.bin.bz2 new file mode 100644 index 000000000..f59ffec93 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0da_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0da_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0da_states.bin.z deleted file mode 100644 index f4115044a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0da_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0de_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0de_states.bin.bz2 new file mode 100644 index 000000000..62759b5d1 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0de_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0de_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0de_states.bin.z deleted file mode 100644 index 42dfcc794..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0de_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.bz2 new file mode 100644 index 000000000..904ba404c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.z deleted file mode 100644 index 4af74d9a0..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.bz2 new file mode 100644 index 000000000..e969ed97c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.z deleted file mode 100644 index 4ff8482ff..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.bz2 new file mode 100644 index 000000000..ebb53232e Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.z deleted file mode 100644 index 11466136f..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_108_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_108_states.bin.bz2 new file mode 100644 index 000000000..2b87ca8f2 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_108_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_108_states.bin.z b/client/resources/hardnested_tables/bitflip_1_108_states.bin.z deleted file mode 100644 index 31234583d..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_108_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_111_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_111_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_111_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_111_states.bin.z b/client/resources/hardnested_tables/bitflip_1_111_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_111_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_113_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_113_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_113_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_113_states.bin.z b/client/resources/hardnested_tables/bitflip_1_113_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_113_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_115_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_115_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_115_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_115_states.bin.z b/client/resources/hardnested_tables/bitflip_1_115_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_115_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_117_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_117_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_117_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_117_states.bin.z b/client/resources/hardnested_tables/bitflip_1_117_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_117_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_118_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_118_states.bin.bz2 new file mode 100644 index 000000000..2b2bf5915 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_118_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_118_states.bin.z b/client/resources/hardnested_tables/bitflip_1_118_states.bin.z deleted file mode 100644 index 10afd75a4..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_118_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_11a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_11a_states.bin.bz2 new file mode 100644 index 000000000..f7e2d1674 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_11a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_11a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_11a_states.bin.z deleted file mode 100644 index e0e985fcf..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_11a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_11b_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_11b_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_11b_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_11b_states.bin.z b/client/resources/hardnested_tables/bitflip_1_11b_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_11b_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_120_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_120_states.bin.bz2 new file mode 100644 index 000000000..fed958a7f Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_120_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_120_states.bin.z b/client/resources/hardnested_tables/bitflip_1_120_states.bin.z deleted file mode 100644 index 750af05d7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_120_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_122_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_122_states.bin.bz2 new file mode 100644 index 000000000..0e406a019 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_122_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_122_states.bin.z b/client/resources/hardnested_tables/bitflip_1_122_states.bin.z deleted file mode 100644 index 6d04a3c05..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_122_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_128_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_128_states.bin.bz2 new file mode 100644 index 000000000..e02d0729a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_128_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_128_states.bin.z b/client/resources/hardnested_tables/bitflip_1_128_states.bin.z deleted file mode 100644 index 18d333145..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_128_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_131_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_131_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_131_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_131_states.bin.z b/client/resources/hardnested_tables/bitflip_1_131_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_131_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_135_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_135_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_135_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_135_states.bin.z b/client/resources/hardnested_tables/bitflip_1_135_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_135_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_138_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_138_states.bin.bz2 new file mode 100644 index 000000000..c12c2219a Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_138_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_138_states.bin.z b/client/resources/hardnested_tables/bitflip_1_138_states.bin.z deleted file mode 100644 index bc154b4f7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_138_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_145_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_145_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_145_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_145_states.bin.z b/client/resources/hardnested_tables/bitflip_1_145_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_145_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_147_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_147_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_147_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_147_states.bin.z b/client/resources/hardnested_tables/bitflip_1_147_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_147_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_148_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_148_states.bin.bz2 new file mode 100644 index 000000000..f9760f6b2 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_148_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_148_states.bin.z b/client/resources/hardnested_tables/bitflip_1_148_states.bin.z deleted file mode 100644 index ec5b774c7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_148_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_158_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_158_states.bin.bz2 new file mode 100644 index 000000000..ceb8298d8 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_158_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_158_states.bin.z b/client/resources/hardnested_tables/bitflip_1_158_states.bin.z deleted file mode 100644 index 631b39af0..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_158_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_160_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_160_states.bin.bz2 new file mode 100644 index 000000000..6264a1abb Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_160_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_160_states.bin.z b/client/resources/hardnested_tables/bitflip_1_160_states.bin.z deleted file mode 100644 index 32fb4f59a..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_160_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_161_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_161_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_161_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_161_states.bin.z b/client/resources/hardnested_tables/bitflip_1_161_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_161_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_163_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_163_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_163_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_163_states.bin.z b/client/resources/hardnested_tables/bitflip_1_163_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_163_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_165_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_165_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_165_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_165_states.bin.z b/client/resources/hardnested_tables/bitflip_1_165_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_165_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_168_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_168_states.bin.bz2 new file mode 100644 index 000000000..e4ee8cdbb Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_168_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_168_states.bin.z b/client/resources/hardnested_tables/bitflip_1_168_states.bin.z deleted file mode 100644 index af6bf431e..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_168_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_178_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_178_states.bin.bz2 new file mode 100644 index 000000000..ce03d40d3 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_178_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_178_states.bin.z b/client/resources/hardnested_tables/bitflip_1_178_states.bin.z deleted file mode 100644 index 17eec3aa5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_178_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_180_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_180_states.bin.bz2 new file mode 100644 index 000000000..87d8693df Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_180_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_180_states.bin.z b/client/resources/hardnested_tables/bitflip_1_180_states.bin.z deleted file mode 100644 index d3f655b04..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_180_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_188_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_188_states.bin.bz2 new file mode 100644 index 000000000..e6392a033 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_188_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_188_states.bin.z b/client/resources/hardnested_tables/bitflip_1_188_states.bin.z deleted file mode 100644 index d5012b1d5..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_188_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_191_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_191_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_191_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_191_states.bin.z b/client/resources/hardnested_tables/bitflip_1_191_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_191_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_198_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_198_states.bin.bz2 new file mode 100644 index 000000000..f8e066f82 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_198_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_198_states.bin.z b/client/resources/hardnested_tables/bitflip_1_198_states.bin.z deleted file mode 100644 index ca490c4fc..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_198_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_199_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_199_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_199_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_199_states.bin.z b/client/resources/hardnested_tables/bitflip_1_199_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_199_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_19d_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_19d_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_19d_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_19d_states.bin.z b/client/resources/hardnested_tables/bitflip_1_19d_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_19d_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_19f_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_19f_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_19f_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_19f_states.bin.z b/client/resources/hardnested_tables/bitflip_1_19f_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_19f_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.bz2 new file mode 100644 index 000000000..da20250ec Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.z deleted file mode 100644 index d6041407c..000000000 --- a/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝMr,Inྚn¢£ê<‚ŽÀÕ¬%ÊHÕ¼™Eå‰ò/hiÖh03ÒÓ?ÿý_ÿñ×þãã}~]Ÿÿûû×Ï_ýõ¿}þõóßþMþùñýÿ}ýŸôéÓ߬ÿ¸þùçŸÿÛòûýôýO?úþð‡ÿ=ìÇÇ·ÞÏ¿Ÿ/–oïÿÎ÷?½®ãÿ³¿æùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðo‰ÿéÓ§ßÿOë?ÓúSÚþOëOSû¯þ§þÇ~Ñÿ‹ÿ}¿ôéÓWÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñŸ>}úôÕÔàùù?ñ¿øÿñ_þ_þŸ>}ñ¿øŸýåÿùþŸýgÿáøÃþíøý÷ÿ¿þ¹ýóûWù¿þNŸ>ý•úÓñÓôzf¿~÷ü×?§Ïÿ+û¸.ÅÿÀ÷wúùÓßûEÿ>öÿõßï½ì?þÓ§O¿T?}mïÿÂ÷/þçÿñ¿—ÿúoü'ÿ'ÿÇÿwúüÇüÿÓ§O_ýGý§9þƒ¿üŸüŸü¿øÿñ_þ_þßø¾ñŸøŸÿçÿùþŸýgÿåÿàøÃþêÿôéÓ7ÿ×ü?óÿÔÿøúò?âü§OŸ¾õÿêæÿ‰ÿÕÿñ_ýß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿyþ=Éã©¿‘““7ȧ?§ïúùÓ÷‡?üsø§ÏŸÚÞÿíïz~Õ¼ÿÙó·ðÿ»ùßÝñ?¹ñŸøŸÿçÿùþŸýgÿåÿàøÃþï?99y«|Z?™¿²öwZšß_ýOý}"ÿ‹ÿ}Ÿäääêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ_%×4­·¥íÇôï§íãvû ÿnüãûnïÿò÷?Þ¿jÌÿôþoøÿ½ü¯ï¿¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üárrróÍÿ3ÿÏü?ëÉ­ÿ·þÿÉÉÉ­ÿ·þ×úñ¿õÿøoý¿ïOþOþOþÿ·þÿñÿåÿÈÉÉÕÔœÿù?ù?ùñ?þã¿ü¿ïœ\ü/þçÿùþŸÿgÿÙøÃþð‡?üíÿ¯iÚ±ý?†û?÷ŸNïÿ2ÝzhíÿmÿoM³ÿ—ý¿4MÓ6ímÿïÕï_üoÿüïå¿ýÿåÿäÿäÿøÿÖý¿ñÿñ_ü¿4þ¤OŸ~Îþ¾ÿyûŸ½?üáû‘¾¶÷áûÿóûýøþnþ}.¿–ÿOþþçÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþ÷ÞŠ>}ú×ìÿü÷®iý%»ÿó¼ן4­_Mßÿÿ3ßßéçOìý½ûÿŸ¿ÿëì?þÓ§O¿U?¾Oÿw¾ñ?ÿÿ½ü×ã?ù?ù?þ¿Óÿã?þã'ÿÍŸ§Oßü_ó¿Ìÿ‚¿õ?ÖÿXÿoý?þã¿õÖÿ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ý>}úïÿë?ãúSÚþOëOCû¯þ§þÇ~Ñÿ‹ÿ}¿ôéÓWÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñüþ¿žäñÔßÈÉÉäÓŸÓ÷?ýüéûÃþ9üÓûmïÿö÷?Ý¿jÞÿìþ[øÿÝüïî¿øŸÜøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÇŸœœ¼Už>¿$m§õ§ùýÕÿÔÿØ'rñ¿øß÷INN®þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þã¿ø“>}úyûþþ§Ÿ?}øÃÿöcºÒõû/íêÿÎ÷?½®ãÿ³¿æùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð_üHŸ¾ó¿œÿãüçÿ8ÿ›~³ýý÷{/ûÿôéÓ/ÕwþwÝù×âþÿ{ù¯ÿÆòòüëùßøÿø/þ§OŸ¾úúOoüù?ù?ùñ?þã¿ü¿ü¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕÿéÓ§oþ¯ùæÿ©ÿñÿôåÄÿøOŸ>}ëÿÕÿÌÿÿ«ÿã¿ú¿ïOþOþOþÿ·þÿñÿóüÿz’ÇS?~#''oONßÿôó§ïøçðOŸ?µ½ÿÛßÿôüªyÿ³çoá?þwó¿»ÿârã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßrròVù´~2eíï´þ4¿¿úŸúûD.þÿû>ÉÉÉÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿J®iZoKÛéßOÛÇíöþÝøÇ÷/ÜÞÿåï¼Õ˜ÿéýßðÿ{ù_ßM3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþäääæÿšÿgþŸùÖÿ’[ÿoý?þ“““[ÿoý¯õÿâëÿñßúߟüŸüŸüÿoý?þã?þ‹ÿéÓ§cý¬ÿOÛÿüýáÿ{Øo½Ÿ?_,ßÞÿïz]ÇÿgÿÌóã?þ7ó_ÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿ¾ø¯ßŠ>}úíÿüûñÓôÊïÿ<ëߥö7p]Šÿïïôó§¿?ö‹þêýÿßÿµöÿéÓ§_ªŸ¾¶÷áûÿóÿøßËý7þ“ÿ“ÿãÿ;ý?þã?þÇÿš¦9ÿËù/οó?Ûâòó/Çñë˜ÿéñþã/ÿÿ«iÆâþŸÿçÿùöŸý—ÿƒ?üáøÃŸœœÜù_Îÿqþó®þþØ'ò¬<ýý¦ù‡ÿäää­ñ¿ó¿»Ïÿÿ;ÿÿ{ùßÝþ_þOþÿïõÿøÿøßÉMÓÌÿ5ÿËü/ø[ÿcýõÿÖÿã?þ[ÿgýŸ¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þ®iÚæø?}þsÚþOëOCû¯þ§þ§iâñ¿¦išúŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿ7â?}úôwëg÷ÿIïÿ’¿?üáûññ­÷óïç‹åÛû¿óýO¯ëøÿìïŸy~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?ü[âúôé÷ÆÿÓúÏ´þ”¶ÿÓúÓÔþ«ÿ©ÿ±_ôÅÿâß/}úôÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü§OŸ>}õõøÃ_þEþOü/þÇü—ÿ—ÿ§O_ü/þgùþŸÿgÿÙøÃþð‡;þëÏŸ¢OŸþEç¿ü~ü4½òç¿Ìúw©ý \—âàû;ýüéïý¢¿úü¯Ã÷­ýÇúôé—ꧯíý_øþÅÿü?þ÷ò_ÿÿäÿäÿøÿNÿÿøÿâúôé«ÿ¨ÿ4Çð—ÿ“ÿ“ÿÿã?þËÿËÿ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ýŸ>}úæÿšÿgþŸúÿO_þGüÿôéÓ·þ_ýÏü?ñ¿ú?þ«ÿûþäÿäÿäÿøëÿñÿñ?Ïÿ¯'y<õã7rròùôçôýO?úþð‡ÿôùSÛû¿ýýOϯš÷?{þþã7ÿ»û/þ'7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿýñ'''o•Oë'óñWÖþNëOóû«ÿ©ÿ±Oäâñ¿ï“œœ\ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿ«äš¦õ¶´ý˜þý´}Ünáß|ÿÂíý_þþÇûWùŸÞÿ ÿñ¿—ÿõý×4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáONNnþ¯ùæÿ™ÿgý/¹õÿÖÿã?99¹õÿÖÿZÿ/þ·þÿ­ÿ÷ýÉÿÉÿÉÿñÿÖÿã?þã¿ü99¹úúóà/ÿ'ÿ'ÿ/þÇü—ÿ÷ý‘“‹ÿÅÿü?ÿÏÿóÿì?ûøÃþð‡¿ýÿ5M;¶ÿÇpÿçñþÓéý_¦ûOí¯ý¿íÿ­iöÿ²ÿ—¦iÚ¦ý¯íÿ½úý‹ÿíÿÿ½ü·ÿ¿üŸüŸüÿߺÿ7þã?þ‹ÿ—ÆŸôéÓÏÙÿÃ÷?oÿ³÷‡?üoc?Ò×öþ/|ÿ~¿ßßíÏ¿Ïå×òÿÉß?ðüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáøÃÿÞûOѧOÿšýŸÿÞ5­¿d÷ž÷ïºó“¦õ«éûŸâæû;ýüéïý¢¿wÿÿó÷ýÇúôé·êgâÏ÷éÿÎ÷/þçÿñ¿—ÿúoü'ÿ'ÿÇÿwúüÇüïä¿ùóôé›ÿkþ—ù_ð·þÇúëÿ­ÿÇü·þÏú?ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø«¿Ó§Oÿ]âÿaýg\JÛÿiýihÿÕÿÔÿØ/úâñ¿ï—>}úêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þßÿד<žúñ99yƒ|úsúþ§Ÿ?}øÃ?‡zÿ±íýßþþ§ûWÍûŸÝ ÿñ¿›ÿÝýÿ“ÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿþø“““·ÊÓç—¤íï´þ4¿¿úŸúûD.þÿû>ÉÉÉÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇüÒ§O?oÿÏßÿôó§ïøßÃ~L÷Oº~ÿ¥]ýßùþ§×uüö÷Ï}ú¥úÎÿ®;ÿZüÏÿã/ÿõßøOþOþÿo=ÿÿñÿÅÿôéÓWÿQÿéÿà/ÿ'ÿ'ÿ/þÇü—ÿ—ÿ7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú?}úôÍÿ5ÿÏü?õ?þŸ¾üøÿéÓ§oý¿úŸùâõüWÿ÷ýÉÿÉÿÉÿñÿÖÿã?þãžÿ_OòxêÇoäää òéÏéûŸ~þôýáÿþéó§¶÷ûûŸž_5ïöü-üÇÿnþw÷_üOnü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûãONNÞ*ŸÖOæã¯¬ýÖŸæ÷WÿSÿcŸÈÅÿâß'99¹úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿWÉ5Mëmiû1ýûiû¸Ýþ¿ÿøþ…Ûû¿üý÷¯ó?½ÿþã/ÿëû¯iÆâþŸÿçÿùöŸý—ÿƒ?üáøÃŸœœÜü_óÿÌÿ3ÿÏú_rëÿ­ÿÇrrrëÿ­ÿµþ_üoý?þ[ÿïû“ÿ“ÿ“ÿãÿ­ÿÇüÇñ?}úôo¬ŸõÿiûŸ¿?üáûññ­÷óïç‹åÛû¿óýO¯ëøÿìïŸy~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßÿõûOѧOÿ¢ýŸ?~š^ùýŸgý»Ôþ®Kñ?ðý~þô÷Ç~Ñ_½ÿÿáû¿Öþã?}úôKõÓ×öþ/|ÿâþÿ{ù¯ÿÆòòü§ÿÇüÇÿâø_Ó4ç9ÿÅù/ðwþg[üQ~þå8~ó?=þÃüïå¿ó5ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáø“““;ÿËù?ÎÿqþÏÕßûDž•§¿ß4ÿ🜜¼5þwþw÷ùßâçâ/ÿ»ûÏÿËÿÉÿñÿ½þÿñÿ;ù¯išù¿æ™ÿë¬ÿ±þßúüÇëÿ¬ÿÓ4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕß5MÛÿ§ÏNÛÿiýihÿÕÿÔÿ4Mü/þ×4MSÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñÿFü§OŸþnýìþ?éý_ò÷‡?üïa?>¾õ~þý|±|{ÿw¾ÿéuÿŸýý3ÏÿøßÌý7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡KüOŸ>ýÞøZÿ™ÖŸÒöZšÚõ?õ?ö‹¾ø_üïû¥OŸ¾úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿôéÓ§¯þ£þøË¿Èÿ‰ÿÅÿøÿòÿòÿôé‹ÿÅÿì/ÿÏÿóÿì?ûøÃþðoÇýùSôéÓ¿èü—ߟ¦Wþü—Yÿ.µ¿ëRü|§Ÿ?ýý±_ôWŸÿuøþ¯µÿøOŸ>ýRýôµ½ÿ ß¿øŸÿÇÿ^þë¿ñŸüŸüÿßéÿñÿñ_üOŸ>}õõŸæøþòòòÿâüÇùùãúÆâþŸÿçÿùöŸý—ÿƒ?üáø«ÿÓ§Oßü_óÿÌÿSÿãÿéËÿˆÿñŸ>}úÖÿ«ÿ™ÿ'þWÿÇõߟüŸüŸüÿoý?þã?þçùÿõ$§~üFNNÞ Ÿþœ¾ÿéçOßþðÏáŸ>j{ÿ·¿ÿéùUóþgÏßÂüïæwÿÅÿäÆâþŸÿçÿùöŸý—ÿƒ?üáø¿?þäää­òiýd>þÊÚßiýi~õ?õ?ö‰\ü/þ÷}’““«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø•\Ó´Þ–¶Ó¿Ÿ¶Ûí/ü»ñï_¸½ÿËßÿxÿª1ÿÓû¿á?þ÷ò¿¾ÿšfü'þçÿùþŸÿgÿÙù?øÃþð‡?üÉÉÉÍÿ5ÿÏü?óÿ¬ÿ%·þßúü'''·þßú_ëÿÅÿÖÿã¿õÿ¾?ù?ù?ù?þßúüÇü—ÿ#''WÿQÿqþüåÿäÿäÿÅÿøÿòÿ¾?rrñ¿øŸÿçÿùþŸýgÿáøÃþð·ÿ¿¦iÇöÿîÿ<Þ:½ÿËtÿé¡ýµÿ·ý¿5Íþ_öÿÒ4MÛ´ÿµý¿W¿ñ¿ýÿñ¿—ÿöÿ—ÿ“ÿ“ÿãÿ[÷ÿÆüÇñÿÒø“>}ú9ûøþçíöþð‡ÿmìGúÚÞÿ…ïÿÏï÷ãû»ýù÷¹üZþ?ùûžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáøß{ÿ)úôé_³ÿóß»¦õ—ìþÏóþ]w~Ò´~5}ÿSüÏ|§Ÿ?ýý±_ô÷îÿþþ¯³ÿøOŸ>ýVýLüù>ýßùþÅÿü?þ÷ò_ÿÿäÿäÿøÿNÿÿøÿü7ž>}óÍÿ2ÿ þÖÿXÿcý¿õÿøÿÖÿYÿgü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõwúôé¿Kü?¬ÿŒëOiû?­? í¿úŸúûE_ü/þ÷ýÒ§O_ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿñûÿz’ÇS?~#''oONßÿôó§ïøçðOï?¶½ÿÛßÿtÿªyÿ³ûoá?þwó¿»ÿârã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßrròVyúü’´ýÖŸæ÷WÿSÿcŸÈÅÿâß'99¹úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿâOúôéçíÿùûŸ~þôýáÿ{ØéþI×ï¿´«ÿ;ßÿôºŽÿÏþþ™çÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿ}ñwþ!}úÎÿrþóœÿãüoúÍöÿõßï½ì?þÓ§O¿Tßùßuç_‹ÿùüïå¿þÿÉÿÉÿñÿ­çã?þã¿øŸ>}úê?ê?½ñüåÿäÿäÿÅÿøÿòÿòÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðWÿ§OŸ¾ù¿æÿ™ÿ§þÇÿÓ—ÿÿã?}úô­ÿWÿ3ÿOü¯þÿêÿ¾?ù?ù?ù?þßúüÇüÏóÿëIOýøœœ¼A>ý9}ÿÓÏŸ¾?üáŸÃ?}þÔöþoÿÓó«æýÏž¿…ÿøßÍÿîþ‹ÿÉÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðüÉÉÉ[åÓúÉ|ü•µ¿ÓúÓüþêêì¹ø_üïû$''WÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñÿ*¹¦i½-m?¦?m·Û_øwãß¿p{ÿ—¿ÿñþUcþ§÷Ãüïå}ÿ5ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáø“““›ÿkþŸùæÿYÿKný¿õÿøONNný¿õ¿Öÿ‹ÿ­ÿÇëÿ}òòòü¿õÿøÿø/þ§OŸþõ³þ?mÿó÷‡?üïa?>¾õ~þý|±|{ÿw¾ÿéuÿŸýý3ÏÿøßÌý7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûâ¿~ÿ)úôé_´ÿóïÇOÓ+¿ÿó¬—ÚßÀu)þ¾¿ÓÏŸþþØ/ú«÷ÿ?|ÿ×Úü§OŸ~©~úÚÞÿ…ï_üÏÿã/ÿõßøOþOþÿïôÿøÿø_ÿkšæü/ç¿8ÿþÎÿl‹?ÊÏ¿ǯcþ§Çøÿ½üwþ¯¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üárrrç9ÿÇù?Îÿ¹úûcŸÈ³òô÷›æþ“““·ÆÿÎÿî>ÿ[üïüOüïåwÿùù?ù?þ¿×ÿã?þã'ÿ5M3ÿ×ü/ó¿àoýõ?Öÿ[ÿÿøoýŸõšfü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú»¦i›ãÿôùÏiû?­? í¿úŸúŸ¦‰ÿÅÿš¦iêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ߈ÿôéÓß­ŸÝÿ'½ÿKþþð‡ÿ=ìÇÇ·ÞÏ¿Ÿ/–oïÿÎ÷?½®ãÿ³¿æùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðo‰ÿéÓ§ßÿOë?ÓúSÚþOëOSû¯þ§þÇ~Ñÿ‹ÿ}¿ôéÓWÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñŸ>}úôÕÔàùù?ñ¿øÿñ_þ_þŸ>}ñ¿øŸýåÿùþŸýgÿáøÃþíø¯?Š>}úÿòûñÓôÊŸÿ2ëߥö7p]Šÿïïôó§¿?ö‹þêó¿ßÿµöÿéÓ§_ªŸ¾¶÷áûÿóÿøßËý7þ“ÿ“ÿãÿ;ý?þã?þ‹ÿéÓ§¯þ£þÓÿÁ_þOþOþ_üÿø/ÿ/ÿoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõúôé›ÿkþŸùêü?}ùñ?þÓ§Oßúõ?óÿÄÿêÿø¯þïû“ÿ“ÿ“ÿãÿ­ÿÇüÇÿ<ÿ¿žäñÔßÈÉÉäÓŸÓ÷?ýüéûÃþ9üÓçOmïÿö÷?=¿jÞÿìù[øÿÝüïî¿øŸÜøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÇŸœœ¼U>­ŸÌÇ_Yû;­?Íï¯þ§þÇ>‘‹ÿÅÿ¾Orrrõ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿ¯’kšÖÛÒöcú÷Óöq»ý…7þñý ·÷ùûï_5æzÿ7üÇÿ^þ×÷_ÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡?99¹ù¿æÿ™ÿgþŸõ¿äÖÿ[ÿÿäääÖÿ[ÿký¿øßúü·þß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿòäääê?ê?Îÿ¿üŸüŸü¿øÿñ_þß÷GN.þÿóÿü?ÿÏÿ³ÿì?üáøÃþöÿ×4íØþÃýŸÇûO§÷™î?=´¿öÿ¶ÿ·¦ÙÿËþ_š¦i›ö¿¶ÿ÷ê÷/þ·ÿ?þ÷òßþÿòòòüëþßøÿø/þ_Ò§O?gÿßÿ¼ýÏÞþð¿ýH_Ûû¿ðýÿùý~|·?ÿ>—_Ëÿ'ÿÀóã?þ7ó_ÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿ{ï?EŸ>ýköþ{×´þ’ÝÿyÞ¿ëÎOšÖ¯¦ïŠÿ™ïïôó§¿?ö‹þÞýÿÏßÿuöÿéӧߪŸ‰?ß§ÿ;ß¿øŸÿÇÿ^þë¿ñŸüŸüÿßéÿñÿñ¿“ÿæÏÓ§oþ¯ù_æÁßúë¬ÿ·þÿñßú?ëÿŒèÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þNŸ>ýw‰ÿ‡õŸqý)mÿ§õ§¡ýWÿSÿc¿è‹ÿÅÿ¾_úôé«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø?~ÿ_OòxêÇoäää òéÏéûŸ~þôýáÿþéýǶ÷ûûŸî_5ïvÿ-üÇÿnþw÷_üOnü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûãONNÞ*OŸ_’¶¿ÓúÓüþêêì¹ø_üïû$''WÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñ_üIŸ>ý¼ý?ÿÓÏŸ¾?üáû1Ý?éúý—võçûŸ^×ñÿÙß?óüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø¿/þÎ?¤Oßù_ÎÿqþóœÿM¿Ùþ¿þû½—ýÇúôé—ê;ÿ»îükñ?ÿÿ½ü×ã?ù?ù?þ¿õüoüÇüÿÓ§O_ýGý§7þƒ¿üŸüŸü¿øÿñ_þ_þßø¾ñŸøŸÿçÿùþŸýgÿåÿàøÃþêÿôéÓ7ÿ×ü?óÿÔÿøúò?âü§OŸ¾õÿêæÿ‰ÿÕÿñ_ýß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿyþ=Éã©¿‘““7ȧ?§ïúùÓ÷‡?üsø§ÏŸÚÞÿíïz~Õ¼ÿÙó·ðÿ»ùßÝñ?¹ñŸøŸÿçÿùþŸýgÿåÿàøÃþï?99y«|Z?™¿²öwZšß_ýOý}"ÿ‹ÿ}Ÿäääêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ_%×4­·¥íÇôï§íãvû ÿnüãûnïÿò÷?Þ¿jÌÿôþoøÿ½ü¯ï¿¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üárrróÍÿ3ÿÏü?ëÉ­ÿ·þÿÉÉÉ­ÿ·þ×úñ¿õÿøoý¿ïOþOþOþÿ·þÿñÿÅÿôéÓ¿±~Öÿ§íþþð‡ÿ=ìÇÇ·ÞÏ¿Ÿ/–oïÿÎ÷?½®ãÿ³¿æùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð_ü×ï?EŸ>ý‹öþýøizå÷žõïRû¸.ÅÿÀ÷wúùÓßûEõþÿ‡ïÿZûÿôéÓ/ÕO_Ûû¿ðý‹ÿùüïå¿þÿÉÿÉÿñÿþÿñÿ‹ãMÓœÿåüç¿ÀßùŸmñGùù—ãøuÌÿôøÿñ¿—ÿÎÿÕ4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáONNîü/çÿ8ÿÇù?WìyVžþ~ÓüÃrròÖøßùßÝç‹ÿÿ‰ÿ½üïî?ÿ/ÿ'ÿÇÿ÷úüÇüï俦iæÿšÿeþü­ÿ±þÇúëÿñÿ­ÿ³þOÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðW×4msüŸ>ÿ9mÿ§õ§¡ýWÿSÿÓ4ñ¿ø_Ó4MýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿñŸ>}ú»õ³ûÿ¤÷Éßþð¿‡ýøøÖûù÷óÅòíýßùþ§×uüö÷Ï}úêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þÓ§OŸ¾úúüá/ÿ"ÿ'þÿã?þËÿËÿÓ§/þÿ³¿ü?ÿÏÿ³ÿì?üáøÃ¿ÿõçOѧOÿ¢ó_~?~š^ùó_fý»Ôþ®Kñ?ðý~þô÷Ç~Ñ_}þ×áû¿Öþã?}úôKõÓ×öþ/|ÿâþÿ{ù¯ÿÆòòü§ÿÇüÇñ?}úôÕÔšã?øËÿÉÿÉÿ‹ÿñÿåÿåÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þOŸ>}óÍÿ3ÿOýÿ§/ÿ#þÇúôé[ÿ¯þgþŸø_ýÿÕÿ}òòòü¿õÿøÿøŸçÿד<žúñ99yƒ|úsúþ§Ÿ?}øÃ?‡úü©íýßþþ§çWÍûŸ= ÿñ¿›ÿÝýÿ“ÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿþø“““·Ê§õ“ùø+k§õ§ùýÕÿÔÿØ'rñ¿øß÷INN®þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿUrMÓz[Ú~Lÿ~Ú>n·¿ðïÆ?¾áöþ/ÿãý«ÆüOïÿ†ÿøßËÿúþkšñŸøŸÿçÿùþŸýgÿåÿàøÃþð'''7ÿ×ü?óÿÌÿ³þ—ÜúëÿñŸœœÜúë­ÿÿ[ÿÿÖÿûþäÿäÿäÿøëÿñÿñ_þœœ\ýGýÇù?ð—ÿ“ÿ“ÿÿã?þËÿûþÈÉÅÿâþŸÿçÿùöŸý‡?üáøÃßþÿš¦Ûÿc¸ÿóxÿéôþ/Óý§‡ö×þßöÿÖ4ûÙÿKÓ4mÓþ×öÿ^ýþÅÿöÿÇÿ^þÛÿ_þOþOþÿoÝÿÿñÿÅÿKãOúôéçìÿáûŸ·ÿÙûÃþ·±ék{ÿ¾ÿ?¿ßïïöçßçòkùÿäïx~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáïý§èÓ§ÍþÏïšÖ_²û?ÏûwÝùIÓúÕôýOñ?óý~þô÷Ç~Ñß»ÿÿùû¿Îþã?}úô[õ3ñçûôçûÿóÿøßËý7þ“ÿ“ÿãÿ;ý?þã?þwòßüyúôÍÿ5ÿËü/ø[ÿcýõÿÖÿã?þ[ÿgýŸñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕßéÓ§ÿ.ñÿ°þ3®?¥íÿ´þ4´ÿêêì}ñ¿øß÷KŸ>}õ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿÇïÿëIOýøœœ¼A>ý9}ÿÓÏŸ¾?üáŸÃ?½ÿØöþoÿÓý«æýÏî¿…ÿøßÍÿîþ‹ÿÉÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðüÉÉÉ[åéóKÒöwZšß_ýOý}"ÿ‹ÿ}Ÿäääêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ‹?éÓ§Ÿ·ÿçïúùÓ÷‡?üïa?¦û']¿ÿÒ®þï|ÿÓë:þ?ûûgžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷Åßù‡ôé;ÿËù?Îÿqþó¿é7Ûÿ׿÷²ÿøOŸ>ýR}ç×-þçÿñ¿—ÿúoü'ÿ'ÿÇÿ·žÿÿøÿâúôé«ÿ¨ÿôÆð—ÿ“ÿ“ÿÿã?þËÿËÿ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ýŸ>}úæÿšÿgþŸúÿO_þGüÿôéÓ·þ_ýÏü?ñ¿ú?þ«ÿûþäÿäÿäÿøëÿñÿñ?Ïÿ¯'y<õã7rròùôçôýO?úþð‡ÿôùSÛû¿ýýOϯš÷?{þþã7ÿ»û/þ'7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿýñ'''o•Oë'óñWÖþNëOóû«ÿ©ÿ±Oäâñ¿ï“œœ\ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿ«äš¦õ¶´ý˜þý´}Ünáß|ÿÂíý_þþÇûWùŸÞÿ ÿñ¿—ÿõý×4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáONNnþ¯ùæÿ™ÿgý/¹õÿÖÿã?99¹õÿÖÿZÿ/þ·þÿ­ÿ÷ýÉÿÉÿÉÿñÿÖÿã?þã¿øŸ>}ú7ÖÏúÿ´ýÏßþð¿‡ýøøÖûù÷óÅòíýßùþ§×uüö÷Ï}ú¥úék{ÿ¾ñ?ÿÿ½ü×ã?ù?ù?þ¿Óÿã?þãqü¯išó¿œÿâüø;ÿ³-þ(?ÿr¿ŽùŸÿá?þ÷òßù¿šfü'þçÿùþŸÿgÿÙù?øÃþð‡?üÉÉÉÿåüçÿ8ÿçêï}"ÏÊÓßošøONNÞÿ;ÿ»ûüoñ¿ó?ñ¿—ÿÝýçÿåÿäÿøÿ^ÿÿøÿü×4Íü_ó¿Ìÿ‚¿õ?ÖÿXÿoý?þã¿õÖÿišñŸøŸÿçÿùþŸýgÿåÿàøÃþêmŽÿÓç?§íÿ´þ4´ÿêêš&þÿkš¦©ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø#þÓ§O·~vÿŸôþ/ùûÃþ÷°ßz?ÿ~¾X¾½ÿ;ßÿôºŽÿÏþþ™çÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ¿%þ§OŸ~oü?­ÿLëOiû?­?Mí¿úŸúûE_ü/þ÷ýÒ§O_ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇúôéÓWÿQÿ?üå_äÿÄÿâüÇùùúôÅÿâö—ÿçÿùöŸý‡?üáø·ã¿þü)úôé_tþËïÇOÓ+þˬ—ÚßÀu)þ¾¿ÓÏŸþþØ/ú«Ïÿ:|ÿ×Úü§OŸ~©~úÚÞÿ…ï_üÏÿã/ÿõßøOþOþÿïôÿøÿø/þ§OŸ¾úúOsüù?ù?ùñ?þã¿ü¿ü¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕÿéÓ§oþ¯ùæÿ©ÿñÿôåÄÿøOŸ>}ëÿÕÿÌÿÿ«ÿã¿ú¿ïOþOþOþÿ·þÿñÿóüÿz’ÇS?~#''oONßÿôó§ïøçðOŸ?µ½ÿÛßÿôüªyÿ³çoá?þwó¿»ÿârã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßrròVù´~2eíï´þ4¿¿úŸúûD.þÿû>ÉÉÉÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿J®iZoKÛéßOÛÇíöþÝøÇ÷/ÜÞÿåï¼Õ˜ÿéýßðÿ{ù_ßM3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþäääæÿšÿgþŸùÖÿ’[ÿoý?þ“““[ÿoý¯õÿâëÿñßúߟüŸüŸüÿoý?þã?þËÿ‘““«ÿ¨ÿ8ÿþòòòÿâüÇùß9¹ø_üÏÿóÿü?ÿÏþ³ÿð‡?üáøÛÿ_Ó´cû ÷ï?ÞÿeºÿôÐþÚÿÛþßšfÿ/ûiš¦mÚÿÚþ߫߿øßþÿøßËûÿËÿÉÿÉÿñÿ­ûã?þã¿øiüIŸ>ýœý?|ÿóö?{øÃÿ6ö#}mïÿÂ÷ÿç÷ûñýÝþüû\~-ÿŸüýÏÿøßÌý7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡?üï½ÿ}úô¯Ùÿùï]ÓúKvÿçyÿ®;?iZ¿š¾ÿ)þg¾¿ÓÏŸþþØ/ú{÷ÿ?ÿ×Ùü§OŸ~«~&þ|Ÿþï|ÿâþÿ{ù¯ÿÆòòü§ÿÇüÇÿNþ›?OŸ¾ù¿æ™ÿë¬ÿ±þßúüÇëÿ¬ÿ3~ oü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú;}úôß%þÖÆõ§´ýŸÖŸ†ö_ýOýý¢/þÿû~éÓ§¯þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿøý=Éã©¿‘““7ȧ?§ïúùÓ÷‡?üsø§÷ÛÞÿíïºÕ¼ÿÙý·ðÿ»ùßÝñ?¹ñŸøŸÿçÿùþŸýgÿåÿàøÃþï?99y«<}~IÚþNëOóû«ÿ©ÿ±Oäâñ¿ï“œœ\ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇñ'}úôóöÿüýO?úþð‡ÿ=ìÇtÿ¤ë÷_ÚÕÿïz]ÇÿgÿÌóã?þ7ó_ÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿ¾ø;ÿ>}ç9ÿÇù?Îÿqþ7ýfûÿúï÷^öÿéÓ§_ªïüïºó¯Åÿü?þ÷ò_ÿÿäÿäÿøÿÖó¿ñÿñ_üOŸ>}õõŸÞøþòòòÿâüÇùùãúÆâþŸÿçÿùöŸý—ÿƒ?üáø«ÿÓ§Oßü_óÿÌÿSÿãÿéËÿˆÿñŸ>}úÖÿ«ÿ™ÿ'þWÿÇõߟüŸüŸüÿoý?þã?þçùÿõ$§~üFNNÞ Ÿþœ¾ÿéçOßþðÏáŸ>j{ÿ·¿ÿéùUóþgÏßÂüïæwÿÅÿäÆâþŸÿçÿùöŸý—ÿƒ?üáø¿?þäää­òiýd>þÊÚßiýi~õ?õ?ö‰\ü/þ÷}’““«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø•\Ó´Þ–¶Ó¿Ÿ¶Ûí/ü»ñï_¸½ÿËßÿxÿª1ÿÓû¿á?þ÷ò¿¾ÿšfü'þçÿùþŸÿgÿÙù?øÃþð‡?üÉÉÉÍÿ5ÿÏü?óÿ¬ÿ%·þßúü'''·þßú_ëÿÅÿÖÿã¿õÿ¾?ù?ù?ù?þßúüÇüÿÓ§OÿÆúYÿŸ¶ÿùûÃþ÷°ßz?ÿ~¾X¾½ÿ;ßÿôºŽÿÏþþ™çÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿ}ñ_¿ÿ}úô/Úÿù÷ã§é•ßÿyÖ¿KíoàºÿßßéçOìýÕûÿ¾ÿkí?þÓ§O¿T?}mïÿÂ÷/þçÿñ¿—ÿúoü'ÿ'ÿÇÿwúüÇü/Žÿ5Msþ—ó_œÿç¶Ååç_Žã×1ÿÓã?üÇÿ^þ;ÿWÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡?99¹ó¿œÿãüçÿ\ýý±OäYyúûMóÿÉÉÉ[ãçwŸÿ-þwþ'þ÷ò¿»ÿü¿üŸüÿßëÿñÿñ¿“ÿš¦™ÿkþ—ù_ð·þÇúëÿ­ÿÇü·þÏú?M3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ý]Ó´Íñúüç´ýŸÖŸ†ö_ýOýOÓÄÿâMÓ4õ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿoÄúôéïÖÏîÿ“Þÿ%øÃÿöãã[ïçßÏË·÷çûŸ^×ñÿÙß?óüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø·ÄÿôéÓïÿ§õŸiý)mÿ§õ§©ýWÿSÿc¿è‹ÿÅÿ¾_úôé«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿøOŸ>}úê?ê?ð‡¿ü‹üŸø_üÿø/ÿ/ÿOŸ¾ø_üÏþòÿü?ÿÏþ³ÿð‡?üáÿvüן?EŸ>ý‹ÎùýøizåÏ™õïRû¸.ÅÿÀ÷wúùÓßûEõù_‡ïÿZûÿôéÓ/ÕO_Ûû¿ðý‹ÿùüïå¿þÿÉÿÉÿñÿþÿñÿÅÿôéÓWÿQÿiŽÿà/ÿ'ÿ'ÿ/þÇü—ÿ—ÿ7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú?}úôÍÿ5ÿÏü?õ?þŸ¾üøÿéÓ§oý¿úŸùâõüWÿ÷ýÉÿÉÿÉÿñÿÖÿã?þãžÿ_OòxêÇoäää òéÏéûŸ~þôýáÿþéó§¶÷ûûŸž_5ïöü-üÇÿnþw÷_üOnü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûãONNÞ*ŸÖOæã¯¬ýÖŸæ÷WÿSÿcŸÈÅÿâß'99¹úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿWÉ5Mëmiû1ýûiû¸Ýþ¿ÿøþ…Ûû¿üý÷¯ó?½ÿþã/ÿëû¯iÆâþŸÿçÿùöŸý—ÿƒ?üáøÃŸœœÜü_óÿÌÿ3ÿÏú_rëÿ­ÿÇrrrëÿ­ÿµþ_üoý?þ[ÿïû“ÿ“ÿ“ÿãÿ­ÿÇüÇù?rrrõõçÿÀ_þOþOþ_üÿø/ÿïû#'ÿ‹ÿùþŸÿçÿÙöþð‡?üáûÿkšvlÿáþÏãý§Óû¿L÷ŸÚ_ûÛÿ[Óìÿeÿ/MÓ´Mû_Ûÿ{õûÿÛÿÿ{ùoÿù?ù?ù?þ¿uÿoüÇüÿ/?éÓ§Ÿ³ÿ‡ïÞþgïøßÆ~¤¯íý_øþÿü~?¾¿ÛŸŸË¯åÿ“¿àùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡ÿ½÷Ÿ¢OŸþ5û?ÿ½kZÉîÿ<ïßuç'MëWÓ÷?ÅÿÌ÷wúùÓßûEïþÿçïÿ:ûÿôéÓoÕÏÄŸïÓÿï_üÏÿã/ÿõßøOþOþÿïôÿøÿøßÉóçéÓ7ÿ×ü/ó¿àoýõ?Öÿ[ÿÿøoýŸõÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðW§OŸþ»ÄÿÃúϸþ”¶ÿÓúÓÐþ«ÿ©ÿ±_ôÅÿâß/}úôÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿ÿ¯'y<õã7rròùôçôýO?úþð‡ÿôþcÛû¿ýýO÷¯š÷?»ÿþã7ÿ»û/þ'7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿýñ'''o•§Ï/IÛßiýi~õ?õ?ö‰\ü/þ÷}’““«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø/þ¤OŸ~ÞþŸ¿ÿéçOßþð¿‡ý˜îŸtýþK»ú¿óýO¯ëøÿìïŸy~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßçÒ§ïü/çÿ8ÿÇù?Îÿ¦ßlÿ_ÿýÞËþã?}úôKõÿ]wþµøŸÿÇÿ^þë¿ñŸüŸüÿßzþ7þã?þ‹ÿéÓ§¯þ£þÓÿÁ_þOþOþ_üÿø/ÿ/ÿoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõúôé›ÿkþŸùêü?}ùñ?þÓ§Oßúõ?óÿÄÿêÿø¯þïû“ÿ“ÿ“ÿãÿ­ÿÇüÇÿ<ÿ¿žäñÔßÈÉÉäÓŸÓ÷?ýüéûÃþ9üÓçOmïÿö÷?=¿jÞÿìù[øÿÝüïî¿øŸÜøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÇŸœœ¼U>­ŸÌÇ_Yû;­?Íï¯þ§þÇ>‘‹ÿÅÿ¾Orrrõ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿ¯’kšÖÛÒöcú÷Óöq»ý…7þñý ·÷ùûï_5æzÿ7üÇÿ^þ×÷_ÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡?99¹ù¿æÿ™ÿgþŸõ¿äÖÿ[ÿÿäääÖÿ[ÿký¿øßúü·þß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿâúôéßX?ëÿÓö?øÃÿöãã[ïçßÏË·÷çûŸ^×ñÿÙß?óüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø¿/þë÷Ÿ¢OŸþEû?ÿ~ü4½òû?Ïúw©ý \—âàû;ýüéïý¢¿zÿÿÃ÷­ýÇúôé—ꧯíý_øþÅÿü?þ÷ò_ÿÿäÿäÿøÿNÿÿøÿÅñ¿¦iÎÿrþ‹ó_àïü϶ø£üüËqü:æzü‡ÿøßËçÿjšñŸøŸÿçÿùþŸýgÿåÿàøÃþð'''wþ—óœÿãüŸ«¿?ö‰<+O¿iþá?99yküïüïîó¿ÅÿÎÿÄÿ^þw÷Ÿÿ—ÿ“ÿãÿ{ý?þã?þwò_Ó4óÍÿ2ÿ þÖÿXÿcý¿õÿøÿÖÿYÿ§iÆâþŸÿçÿùöŸý—ÿƒ?üáø«¿kš¶9þOŸÿœ¶ÿÓúÓÐþ«ÿ©ÿišø_ü¯iš¦þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿøOŸ>ýÝúÙýÒû¿äïøßÃ~||ëýüûùbùöþï|ÿÓë:þ?ûûgžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ–øŸ>}ú½ñÿ´þ3­?¥íÿ´þ4µÿêêì}ñ¿øß÷KŸ>}õ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿéÓ§O_ýGýþð—‘ÿÿ‹ÿñÿåÿåÿéÓÿ‹ÿÙ_þŸÿçÿÙöþð‡?üáߎÿúó§èÓ§Ñù/¿?M¯üù/³þ]j×¥øøþN?úûc¿è¯>ÿëðý_kÿñŸ>}ú¥úék{ÿ¾ñ?ÿÿ½ü×ã?ù?ù?þ¿Óÿã?þã¿øŸ>}úê?ê?ÍñüåÿäÿäÿÅÿøÿòÿòÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðWÿ§OŸ¾ù¿æÿ™ÿ§þÇÿÓ—ÿÿã?}úô­ÿWÿ3ÿOü¯þÿêÿ¾?ù?ù?ù?þßúüÇüÏóÿëIOýøœœ¼A>ý9}ÿÓÏŸ¾?üáŸÃ?}þÔöþoÿÓó«æýÏž¿…ÿøßÍÿîþ‹ÿÉÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðüÉÉÉ[åÓúÉ|ü•µ¿ÓúÓüþêêì¹ø_üïû$''WÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñÿ*¹¦i½-m?¦?m·Û_øwãß¿p{ÿ—¿ÿñþUcþ§÷Ãüïå}ÿ5ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáø“““›ÿkþŸùæÿYÿKný¿õÿøONNný¿õ¿Öÿ‹ÿ­ÿÇëÿ}òòòü¿õÿøÿø/ÿGNN®þ£þãüøËÿÉÿÉÿ‹ÿñÿåÿ}ääâñ?ÿÏÿóÿü?ûÏþÃþð‡?üáoÿMÓŽíÿ1Üÿy¼ÿtzÿ—éþÓCûkÿoûkšý¿ìÿ¥iš¶iÿkû¯~ÿâûÿã/ÿíÿ/ÿ'ÿ'ÿÇÿ·îÿÿøÿâÿ¥ñ'}úôsöÿðýÏÛÿìýáÿÛØôµ½ÿ ßÿŸßïÇ÷wûóïsùµüò÷}ú­ú™øó}ú¿óý‹ÿùüïå¿þÿÉÿÉÿñÿþÿñÿ;ùoþ<}úæÿšÿeþü­ÿ±þÇúëÿñÿ­ÿ³þÏø¾ñŸøŸÿçÿùþŸýgÿåÿàøÃþêïôéÓ—øXÿןÒöZÚõ?õ?ö‹¾ø_üïû¥OŸ¾úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿã÷ÿõ$§~üFNNÞ Ÿþœ¾ÿéçOßþðÏáŸÞl{ÿ·¿ÿéþUóþg÷ßÂüïæwÿÅÿäÆâþŸÿçÿùöŸý—ÿƒ?üáø¿?þäää­òôù%iû;­?Íï¯þ§þÇ>‘‹ÿÅÿ¾Orrrõ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿÅŸôéÓÏÛÿó÷?ýüéûÃþ÷°Óý“®ßiWÿw¾ÿéuÿŸýý3ÏÿøßÌý7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûâïüCúôÿåüçÿ8ÿÇùßô›íÿë¿ß{Ùü§OŸ~©¾ó¿ëοÿóÿøßËý7þ“ÿ“ÿãÿ[ÏÿÆüÇñ?}úôÕÔzã?øËÿÉÿÉÿ‹ÿñÿåÿåÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þOŸ>}óÍÿ3ÿOýÿ§/ÿ#þÇúôé[ÿ¯þgþŸø_ýÿÕÿ}òòòü¿õÿøÿøŸçÿד<žúñ99yƒ|úsúþ§Ÿ?}øÃ?‡úü©íýßþþ§çWÍûŸ= ÿñ¿›ÿÝýÿ“ÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿþø“““·Ê§õ“ùø+k§õ§ùýÕÿÔÿØ'rñ¿øß÷INN®þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿUrMÓz[Ú~Lÿ~Ú>n·¿ðïÆ?¾áöþ/ÿãý«ÆüOïÿ†ÿøßËÿúþkšñŸøŸÿçÿùþŸýgÿåÿàøÃþð'''7ÿ×ü?óÿÌÿ³þ—ÜúëÿñŸœœÜúë­ÿÿ[ÿÿÖÿûþäÿäÿäÿøëÿñÿñ_üOŸ>ýëgýÚþçïøßÃ~||ëýüûùbùöþï|ÿÓë:þ?ûûgžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÅýþSôéÓ¿hÿçߟ¦W~ÿçYÿ.µ¿ëRü|§Ÿ?ýý±_ôWïÿøþ¯µÿøOŸ>ýRýôµ½ÿ ß¿øŸÿÇÿ^þë¿ñŸüŸüÿßéÿñÿñ¿8þ×4Íù_Îqþ üÿÙ”Ÿ9Ž_ÇüOÿðÿ{ùïü_M3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþäääÎÿrþóœÿsõ÷Ç>‘gåéï7Í?ü'''oÿÿÝ}þ·øßùŸøßËÿîþóÿòòü¯ÿÇüÇÿNþkšfþ¯ù_æÁßúë¬ÿ·þÿñßú?ëÿ4ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõwMÓ6ÇÿéóŸÓöZÚõ?õ?Mÿ‹ÿ5MÓÔÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿°ý˜!¯ \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.bz2 new file mode 100644 index 000000000..034c96abd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.z deleted file mode 100644 index 10dd5e6b1..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.bz2 new file mode 100644 index 000000000..c57b7929b Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.z deleted file mode 100644 index add474d02..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.bz2 new file mode 100644 index 000000000..6ced4a199 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.z deleted file mode 100644 index 3a748e8d0..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.bz2 new file mode 100644 index 000000000..bbc7f1d82 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.z deleted file mode 100644 index 806157d21..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.bz2 new file mode 100644 index 000000000..d701fc285 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.z deleted file mode 100644 index b7f699728..000000000 --- a/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝmn4In`ß@WðM|$Ù€ï±C†äÞw÷GCÃÊŽbÇ“Bá†CUeEÉ$óã?ÿëþã¿ÿñù¿>¾®¿þû_?ýõ×ÿýöñ×Ïû7ùÇç÷ÿ÷õÒ§O³þãúçŸþoÈÿí÷Ó÷?ýüéûÃþ÷°Ÿßz?ÿ~¼X¾½ÿ;ßÿôºŽÿÏþþ™çÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ¿%þ§OŸ~oü?­ÿLëOiû?­?Mí¿úŸúûE_ü/þ÷ýÒ§O_ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇúôéÓWÿQÿ?üå_äÿÄÿâüÇùùúôÅÿâö—ÿçÿùöŸý‡?üáø·ãÿõßÿÿúçöÏÿí_åÿú;}úôWêOÇOÓë™ýúÝó_?þœ>ÿ¯ìoàºÿßßéçOìýûØÿ׿÷²ÿøOŸ>ýRýôµ½ÿ ß¿øŸÿÇÿ^þë¿ñŸüŸüÿßéÿñÿñ_üOŸ>}õõŸæøþòòòÿâüÇùùãúÆâþŸÿçÿùöŸý—ÿƒ?üáø«ÿÓ§Oßü_óÿÌÿSÿãÿéËÿˆÿñŸ>}úÖÿ«ÿ™ÿ'þWÿÇõߟüŸüŸüÿoý?þã?þçùÿõ$§~üFNNÞ Ÿþœ¾ÿéçOßþðÏáŸ>j{ÿ·¿ÿéùUóþgÏßÂüïæwÿÅÿäÆâþŸÿçÿùöŸý—ÿƒ?üáø¿?þäää­òiýd>þÊÚßiýi~õ?õ?ö‰\ü/þ÷}’““«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø•\Ó´Þ–¶Ó¿Ÿ¶Ûí/ü»ñï_¸½ÿËßÿxÿª1ÿÓû¿á?þ÷ò¿¾ÿšfü'þçÿùþŸÿgÿÙù?øÃþð‡?üÉÉÉÍÿ5ÿÏü?óÿ¬ÿ%·þßúü'''·þßú_ëÿÅÿÖÿã¿õÿ¾?ù?ù?ù?þßúüÇü—ÿ#''WÿQÿqþüåÿäÿäÿÅÿøÿòÿ¾?rrñ¿øŸÿçÿùþŸýgÿáøÃþð·ÿ¿¦iÇöÿîÿ<Þ:½ÿËtÿé¡ýµÿ·ý¿5Íþ_öÿÒ4MÛ´ÿµý¿W¿ñ¿ýÿñ¿—ÿöÿ—ÿ“ÿ“ÿãÿ[÷ÿÆüÇñÿÒø“>}ú9ûøþçíöþð‡ÿmìGúÚÞÿ…ïÿÏï÷óû»ýù÷¹üZþ?ùûžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáøß{ÿ)úôé_³ÿóß»¦õ—ìþÏóþ]w~Ò´~5}ÿSüÏ|§Ÿ?ýý±_ô÷îÿþþ¯³ÿøOŸ>ýVýLüù>ýßùþÅÿü?þ÷ò_ÿÿäÿäÿøÿNÿÿøÿü7ž>}óÍÿ2ÿ þÖÿXÿcý¿õÿøÿÖÿYÿgü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõwúôé¿Kü?¬ÿŒëOiû?­? í¿úŸúûE_ü/þ÷ýÒ§O_ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿñûÿz’ÇS?~#''oONßÿôó§ïøçðOï?¶½ÿÛßÿtÿªyÿ³ûoá?þwó¿»ÿârã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßrròVyúü’´ýÖŸæ÷WÿSÿcŸÈÅÿâß'99¹úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿâOúôéçíÿùûŸ~þôýáÿ{ØéþI×ï¿´«ÿ;ßÿôºŽÿÏþþ™çÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿ}ñwþ!}úÎÿrþóœÿãüoúÍöÿõßï½ì?þÓ§O¿Tßùßuç_‹ÿùüïå¿þÿÉÿÉÿñÿ­çã?þã¿øŸ>}úê?ê?½ñüåÿäÿäÿÅÿøÿòÿòÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðWÿ§OŸ¾ù¿æÿ™ÿ§þÇÿÓ—ÿÿã?}úô­ÿWÿ3ÿOü¯þÿêÿ¾?ù?ù?ù?þßúüÇüÏóÿëIOýøœœ¼A>ý9}ÿÓÏŸ¾?üáŸÃ?}þÔöþoÿÓó«æýÏž¿…ÿøßÍÿîþ‹ÿÉÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðüÉÉÉ[åÓúÉ|ü•µ¿ÓúÓüþêêì¹ø_üïû$''WÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñÿ*¹¦i½-m?¦?m·Û_øwãß¿p{ÿ—¿ÿñþUcþ§÷Ãüïå}ÿ5ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáø“““›ÿkþŸùæÿYÿKný¿õÿøONNný¿õ¿Öÿ‹ÿ­ÿÇëÿ}òòòü¿õÿøÿø/þ§OŸþõ³þ?mÿó÷‡?üïa?>¿õ~þýx±|{ÿw¾ÿéuÿŸýý3ÏÿøßÌý7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûâ¿~ÿ)úôé_´ÿóïÇOÓ+¿ÿó¬—ÚßÀu)þ¾¿ÓÏŸþþØ/ú«÷ÿ?|ÿ×Úü§OŸ~©~úÚÞÿ…ï_üÏÿã/ÿõßøOþOþÿïôÿøÿø_ÿkšæü/ç¿8ÿþÎÿl‹?ÊÏ¿ǯcþ§Çøÿ½üwþ¯¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üárrrç9ÿÇù?Îÿ¹úûcŸÈ³òô÷›æþ“““·ÆÿÎÿî>ÿ[üïüOüïåwÿùù?ù?þ¿×ÿã?þã'ÿ5M3ÿ×ü/ó¿àoýõ?Öÿ[ÿÿøoýŸõšfü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú»¦i›ãÿôùÏiû?­? í¿úŸúŸ¦‰ÿÅÿš¦iêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ߈ÿôéÓß­ŸÝÿ'½ÿKþþð‡ÿ=ìÇç·ÞÏ¿/–oïÿÎ÷?½®ãÿ³¿æùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðo‰ÿéÓ§ßÿOë?ÓúSÚþOëOSû¯þ§þÇ~Ñÿ‹ÿ}¿ôéÓWÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñŸ>}úôÕÔàùù?ñ¿øÿñ_þ_þŸ>}ñ¿øŸýåÿùþŸýgÿáøÃþíø¯?Š>}úÿòûñÓôÊŸÿ2ëߥö7p]Šÿïïôó§¿?ö‹þêó¿ßÿµöÿéÓ§_ªŸ¾¶÷áûÿóÿøßËý7þ“ÿ“ÿãÿ;ý?þã?þ‹ÿéÓ§¯þ£þÓÿÁ_þOþOþ_üÿø/ÿ/ÿoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõúôé›ÿkþŸùêü?}ùñ?þÓ§Oßúõ?óÿÄÿêÿø¯þïû“ÿ“ÿ“ÿãÿ­ÿÇüÇÿ<ÿ¿žäñÔßÈÉÉäÓŸÓ÷?ýüéûÃþ9üÓçOmïÿö÷?=¿jÞÿìù[øÿÝüïî¿øŸÜøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÇŸœœ¼U>­ŸÌÇ_Yû;­?Íï¯þ§þÇ>‘‹ÿÅÿ¾Orrrõ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿ¯’kšÖÛÒöcú÷Óöq»ý…7þñý ·÷ùûï_5æzÿ7üÇÿ^þ×÷_ÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡?99¹ù¿æÿ™ÿgþŸõ¿äÖÿ[ÿÿäääÖÿ[ÿký¿øßúü·þß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿòäääê?ê?Îÿ¿üŸüŸü¿øÿñ_þß÷GN.þÿóÿü?ÿÏÿ³ÿì?üáøÃþöÿ×4íØþÃýŸÇûO§÷™î?=´¿öÿ¶ÿ·¦ÙÿËþ_š¦i›ö¿¶ÿ÷ê÷/þ·ÿ?þ÷òßþÿòòòüëþßøÿø/þ_Ò§O?gÿßÿ¼ýÏÞþð¿ýH_Ûû¿ðýÿùý~~·?ÿ>—_Ëÿ'ÿÀóã?þ7ó_ÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿ{ï?EŸ>ýköþ{×´þ’ÝÿyÞ¿ëÎOšÖ¯¦ïŠÿ™ïïôó§¿?ö‹þÞýÿÏßÿuöÿéӧߪŸ‰?ß§ÿ;ß¿øŸÿÇÿ^þë¿ñŸüŸüÿßéÿñÿñ¿“ÿæÏÓ§oþ¯ù_æÁßúë¬ÿ·þÿñßú?ëÿŒèÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þNŸ>ýw‰ÿ‡õŸqý)mÿ§õ§¡ýWÿSÿc¿è‹ÿÅÿ¾_úôé«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø?~ÿ_OòxêÇoäää òéÏéûŸ~þôýáÿþéýǶ÷ûûŸî_5ïvÿ-üÇÿnþw÷_üOnü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûãONNÞ*OŸ_’¶¿ÓúÓüþêêì¹ø_üïû$''WÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñ_üIŸ>ý¼ý?ÿÓÏŸ¾?üáû1Ý?éúý—võçûŸ^×ñÿÙß?óüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø¿/þÎ?¤Oßù_ÎÿqþóœÿM¿Ùþ¿þû½—ýÇúôé—ê;ÿ»îükñ?ÿÿ½ü×ã?ù?ù?þ¿õüoüÇüÿÓ§O_ýGý§7þƒ¿üŸüŸü¿øÿñ_þ_þßø¾ñŸøŸÿçÿùþŸýgÿåÿàøÃþêÿôéÓ7ÿ×ü?óÿÔÿøúò?âü§OŸ¾õÿêæÿ‰ÿÕÿñ_ýß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿyþ=Éã©¿‘““7ȧ?§ïúùÓ÷‡?üsø§ÏŸÚÞÿíïz~Õ¼ÿÙó·ðÿ»ùßÝñ?¹ñŸøŸÿçÿùþŸýgÿåÿàøÃþï?99y«|Z?™¿²öwZšß_ýOý}"ÿ‹ÿ}Ÿäääêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ_%×4­·¥íÇôï§íãvû ÿnüãûnïÿò÷?Þ¿jÌÿôþoøÿ½ü¯ï¿¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üárrróÍÿ3ÿÏü?ëÉ­ÿ·þÿÉÉÉ­ÿ·þ×úñ¿õÿøoý¿ïOþOþOþÿ·þÿñÿÅÿôéÓ¿±~Öÿ§íþþð‡ÿ=ìÇç·ÞÏ¿/–oïÿÎ÷?½®ãÿ³¿æùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð_ü×ï?EŸ>ý‹öþýøizå÷žõïRû¸.ÅÿÀ÷wúùÓßûEõþÿ‡ïÿZûÿôéÓ/ÕO_Ûû¿ðý‹ÿùüïå¿þÿÉÿÉÿñÿþÿñÿ‹ãMÓœÿåüç¿ÀßùŸmñGùù—ãøuÌÿôøÿñ¿—ÿÎÿÕ4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáONNîü/çÿ8ÿÇù?WìyVžþ~ÓüÃrròÖøßùßÝç‹ÿÿ‰ÿ½üïî?ÿ/ÿ'ÿÇÿ÷úüÇüï俦iæÿšÿeþü­ÿ±þÇúëÿñÿ­ÿ³þOÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðW×4msüŸ>ÿ9mÿ§õ§¡ýWÿSÿÓ4ñ¿ø_Ó4MýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿñŸ>}ú»õ³ûÿ¤÷Éßþð¿‡ýøüÖûù÷ãÅòíýßùþ§×uüö÷Ï}úêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þÓ§OŸ¾úúüá/ÿ"ÿ'þÿã?þËÿËÿÓ§/þÿ³¿ü?ÿÏÿ³ÿì?üáøÃ¿ÿõçOѧOÿ¢ó_~?~š^ùó_fý»Ôþ®Kñ?ðý~þô÷Ç~Ñ_}þ×áû¿Öþã?}úôKõÓ×öþ/|ÿâþÿ{ù¯ÿÆòòü§ÿÇüÇñ?}úôÕÔšã?øËÿÉÿÉÿ‹ÿñÿåÿåÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þOŸ>}óÍÿ3ÿOýÿ§/ÿ#þÇúôé[ÿ¯þgþŸø_ýÿÕÿ}òòòü¿õÿøÿøŸçÿד<žúñ99yƒ|úsúþ§Ÿ?}øÃ?‡úü©íýßþþ§çWÍûŸ= ÿñ¿›ÿÝýÿ“ÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿþø“““·Ê§õ“ùø+k§õ§ùýÕÿÔÿØ'rñ¿øß÷INN®þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿUrMÓz[Ú~Lÿ~Ú>n·¿ðïÆ?¾áöþ/ÿãý«ÆüOïÿ†ÿøßËÿúþkšñŸøŸÿçÿùþŸýgÿåÿàøÃþð'''7ÿ×ü?óÿÌÿ³þ—ÜúëÿñŸœœÜúë­ÿÿ[ÿÿÖÿûþäÿäÿäÿøëÿñÿñ_þœœ\ýGýÇù?ð—ÿ“ÿ“ÿÿã?þËÿûþÈÉÅÿâþŸÿçÿùöŸý‡?üáøÃßþÿš¦Ûÿc¸ÿóxÿéôþ/Óý§‡ö×þßöÿÖ4ûÙÿKÓ4mÓþ×öÿ^ýþÅÿöÿÇÿ^þÛÿ_þOþOþÿoÝÿÿñÿÅÿKãOúôéçìÿáûŸ·ÿÙûÃþ·±ék{ÿ¾ÿ?¿ßÏïïöçßçòkùÿäïx~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáïý§èÓ§ÍþÏïšÖ_²û?ÏûwÝùIÓúÕôýOñ?óý~þô÷Ç~Ñß»ÿÿùû¿Îþã?}úô[õ3ñçûôçûÿóÿøßËý7þ“ÿ“ÿãÿ;ý?þã?þwòßüyúôÍÿ5ÿËü/ø[ÿcýõÿÖÿã?þ[ÿgýŸñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕßéÓ§ÿ.ñÿ°þ3®?¥íÿ´þ4´ÿêêì}ñ¿øß÷KŸ>}õ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿÇïÿëIOýøœœ¼A>ý9}ÿÓÏŸ¾?üáŸÃ?½ÿØöþoÿÓý«æýÏî¿…ÿøßÍÿîþ‹ÿÉÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðüÉÉÉ[åéóKÒöwZšß_ýOý}"ÿ‹ÿ}Ÿäääêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ‹?éÓ§Ÿ·ÿçïúùÓ÷‡?üïa?¦û']¿ÿÒ®þï|ÿÓë:þ?ûûgžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷Åßù‡ôé;ÿËù?Îÿqþó¿é7Ûÿ׿÷²ÿøOŸ>ýR}ç×-þçÿñ¿—ÿúoü'ÿ'ÿÇÿ·žÿÿøÿâúôé«ÿ¨ÿôÆð—ÿ“ÿ“ÿÿã?þËÿËÿ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ýŸ>}úæÿšÿgþŸúÿO_þGüÿôéÓ·þ_ýÏü?ñ¿ú?þ«ÿûþäÿäÿäÿøëÿñÿñ?Ïÿ¯'y<õã7rròùôçôýO?úþð‡ÿôùSÛû¿ýýOϯš÷?{þþã7ÿ»û/þ'7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿýñ'''o•Oë'óñWÖþNëOóû«ÿ©ÿ±Oäâñ¿ï“œœ\ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿ«äš¦õ¶´ý˜þý´}Ünáß|ÿÂíý_þþÇûWùŸÞÿ ÿñ¿—ÿõý×4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáONNnþ¯ùæÿ™ÿgý/¹õÿÖÿã?99¹õÿÖÿZÿ/þ·þÿ­ÿ÷ýÉÿÉÿÉÿñÿÖÿã?þã¿øŸ>}ú7ÖÏúÿ´ýÏßþð¿‡ýøüÖûù÷ãÅòíýßùþ§×uüö÷Ï}ú¥úék{ÿ¾ñ?ÿÿ½ü×ã?ù?ù?þ¿Óÿã?þãqü¯išó¿œÿâüø;ÿ³-þ(?ÿr¿ŽùŸÿá?þ÷òßù¿šfü'þçÿùþŸÿgÿÙù?øÃþð‡?üÉÉÉÿåüçÿ8ÿçêï}"ÏÊÓßošøONNÞÿ;ÿ»ûüoñ¿ó?ñ¿—ÿÝýçÿåÿäÿøÿ^ÿÿøÿü×4Íü_ó¿Ìÿ‚¿õ?ÖÿXÿoý?þã¿õÖÿišñŸøŸÿçÿùþŸýgÿåÿàøÃþêmŽÿÓç?§íÿ´þ4´ÿêêš&þÿkš¦©ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø#þÓ§O·~vÿŸôþ/ùûÃþ÷°Ÿßz?ÿ~¼X¾½ÿ;ßÿôºŽÿÏþþ™çÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ¿%þ§OŸ~oü?­ÿLëOiû?­?Mí¿úŸúûE_ü/þ÷ýÒ§O_ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇúôéÓWÿQÿ?üå_äÿÄÿâüÇùùúôÅÿâö—ÿçÿùöŸý‡?üáø·ã¿þü)úôé_tþËïÇOÓ+þˬ—ÚßÀu)þ¾¿ÓÏŸþþØ/ú«Ïÿ:|ÿ×Úü§OŸ~©~úÚÞÿ…ï_üÏÿã/ÿõßøOþOþÿïôÿøÿø/þ§OŸ¾úúOsüù?ù?ùñ?þã¿ü¿ü¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕÿéÓ§oþ¯ùæÿ©ÿñÿôåÄÿøOŸ>}ëÿÕÿÌÿÿ«ÿã¿ú¿ïOþOþOþÿ·þÿñÿóüÿz’ÇS?~#''oONßÿôó§ïøçðOŸ?µ½ÿÛßÿôüªyÿ³çoá?þwó¿»ÿârã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßrròVù´~2eíï´þ4¿¿úŸúûD.þÿû>ÉÉÉÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿J®iZoKÛéßOÛÇíöþÝøÇ÷/ÜÞÿåï¼Õ˜ÿéýßðÿ{ù_ßM3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþäääæÿšÿgþŸùÖÿ’[ÿoý?þ“““[ÿoý¯õÿâëÿñßúߟüŸüŸüÿoý?þã?þËÿ‘““«ÿ¨ÿ8ÿþòòòÿâüÇùß9¹ø_üÏÿóÿü?ÿÏþ³ÿð‡?üáøÛÿ_Ó´cû ÷ï?ÞÿeºÿôÐþÚÿÛþßšfÿ/ûiš¦mÚÿÚþ߫߿øßþÿøßËûÿËÿÉÿÉÿñÿ­ûã?þã¿øiüIŸ>ýœý?|ÿóö?{øÃÿ6ö#}mïÿÂ÷ÿç÷ûùýÝþüû\~-ÿŸüýÏÿøßÌý7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡?üï½ÿ}úô¯Ùÿùï]ÓúKvÿçyÿ®;?iZ¿š¾ÿ)þg¾¿ÓÏŸþþØ/ú{÷ÿ?ÿ×Ùü§OŸ~«~&þ|Ÿþï|ÿâþÿ{ù¯ÿÆòòü§ÿÇüÇÿNþ›?OŸ¾ù¿æ™ÿë¬ÿ±þßúüÇëÿ¬ÿ3~ oü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú;}úôß%þÖÆõ§´ýŸÖŸ†ö_ýOýý¢/þÿû~éÓ§¯þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿøý=Éã©¿‘““7ȧ?§ïúùÓ÷‡?üsø§÷ÛÞÿíïºÕ¼ÿÙý·ðÿ»ùßÝñ?¹ñŸøŸÿçÿùþŸýgÿåÿàøÃþï?99y«<}~IÚþNëOóû«ÿ©ÿ±Oäâñ¿ï“œœ\ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇñ'}úôóöÿüýO?úþð‡ÿ=ìÇtÿ¤ë÷_ÚÕÿïz]ÇÿgÿÌóã?þ7ó_ÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿ¾ø;ÿ>}ç9ÿÇù?Îÿqþ7ýfûÿúï÷^öÿéÓ§_ªïüïºó¯Åÿü?þ÷ò_ÿÿäÿäÿøÿÖó¿ñÿñ_üOŸ>}õõŸÞøþòòòÿâüÇùùãúÆâþŸÿçÿùöŸý—ÿƒ?üáø«ÿÓ§Oßü_óÿÌÿSÿãÿéËÿˆÿñŸ>}úÖÿ«ÿ™ÿ'þWÿÇõߟüŸüŸüÿoý?þã?þçùÿõ$§~üFNNÞ Ÿþœ¾ÿéçOßþðÏáŸ>j{ÿ·¿ÿéùUóþgÏßÂüïæwÿÅÿäÆâþŸÿçÿùöŸý—ÿƒ?üáø¿?þäää­òiýd>þÊÚßiýi~õ?õ?ö‰\ü/þ÷}’““«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø•\Ó´Þ–¶Ó¿Ÿ¶Ûí/ü»ñï_¸½ÿËßÿxÿª1ÿÓû¿á?þ÷ò¿¾ÿšfü'þçÿùþŸÿgÿÙù?øÃþð‡?üÉÉÉÍÿ5ÿÏü?óÿ¬ÿ%·þßúü'''·þßú_ëÿÅÿÖÿã¿õÿ¾?ù?ù?ù?þßúüÇüÿÓ§OÿÆúYÿŸ¶ÿùûÃþ÷°Ÿßz?ÿ~¼X¾½ÿ;ßÿôºŽÿÏþþ™çÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿ}ñ_¿ÿ}úô/Úÿù÷ã§é•ßÿyÖ¿KíoàºÿßßéçOìýÕûÿ¾ÿkí?þÓ§O¿T?}mïÿÂ÷/þçÿñ¿—ÿúoü'ÿ'ÿÇÿwúüÇü/Žÿ5Msþ—ó_œÿç¶Ååç_Žã×1ÿÓã?üÇÿ^þ;ÿWÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡?99¹ó¿œÿãüçÿ\ýý±OäYyúûMóÿÉÉÉ[ãçwŸÿ-þwþ'þ÷ò¿»ÿü¿üŸüÿßëÿñÿñ¿“ÿš¦™ÿkþ—ù_ð·þÇúëÿ­ÿÇü·þÏú?M3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ý]Ó´Íñúüç´ýŸÖŸ†ö_ýOýOÓÄÿâMÓ4õ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿoÄúôéïÖÏîÿ“Þÿ%øÃÿöãó[ïçßË·÷çûŸ^×ñÿÙß?óüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø·ÄÿôéÓïÿ§õŸiý)mÿ§õ§©ýWÿSÿc¿è‹ÿÅÿ¾_úôé«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿøOŸ>}úê?ê?ð‡¿ü‹üŸø_üÿø/ÿ/ÿOŸ¾ø_üÏþòÿü?ÿÏþ³ÿð‡?üáÿvüן?EŸ>ý‹ÎùýøizåÏ™õïRû¸.ÅÿÀ÷wúùÓßûEõù_‡ïÿZûÿôéÓ/ÕO_Ûû¿ðý‹ÿùüïå¿þÿÉÿÉÿñÿþÿñÿÅÿôéÓWÿQÿiŽÿà/ÿ'ÿ'ÿ/þÇü—ÿ—ÿ7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú?}úôÍÿ5ÿÏü?õ?þŸ¾üøÿéÓ§oý¿úŸùâõüWÿ÷ýÉÿÉÿÉÿñÿÖÿã?þãžÿ_OòxêÇoäää òéÏéûŸ~þôýáÿþéó§¶÷ûûŸž_5ïöü-üÇÿnþw÷_üOnü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûãONNÞ*ŸÖOæã¯¬ýÖŸæ÷WÿSÿcŸÈÅÿâß'99¹úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿWÉ5Mëmiû1ýûiû¸Ýþ¿ÿøþ…Ûû¿üý÷¯ó?½ÿþã/ÿëû¯iÆâþŸÿçÿùöŸý—ÿƒ?üáøÃŸœœÜü_óÿÌÿ3ÿÏú_rëÿ­ÿÇrrrëÿ­ÿµþ_üoý?þ[ÿïû“ÿ“ÿ“ÿãÿ­ÿÇüÇù?rrrõõçÿÀ_þOþOþ_üÿø/ÿïû#'ÿ‹ÿùþŸÿçÿÙöþð‡?üáûÿkšvlÿáþÏãý§Óû¿L÷ŸÚ_ûÛÿ[Óìÿeÿ/MÓ´Mû_Ûÿ{õûÿÛÿÿ{ùoÿù?ù?ù?þ¿uÿoüÇüÿ/?éÓ§Ÿ³ÿ‡ïÞþgïøßÆ~¤¯íý_øþÿü~?¿¿ÛŸŸË¯åÿ“¿àùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡ÿ½÷Ÿ¢OŸþ5û?ÿ½kZÉîÿ<ïßuç'MëWÓ÷?ÅÿÌ÷wúùÓßûEïþÿçïÿ:ûÿôéÓoÕÏÄŸïÓÿï_üÏÿã/ÿõßøOþOþÿïôÿøÿøßÉóçéÓ7ÿ×ü/ó¿àoýõ?Öÿ[ÿÿøoýŸõÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðW§OŸþ»ÄÿÃúϸþ”¶ÿÓúÓÐþ«ÿ©ÿ±_ôÅÿâß/}úôÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿ÿ¯'y<õã7rròùôçôýO?úþð‡ÿôþcÛû¿ýýO÷¯š÷?»ÿþã7ÿ»û/þ'7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿýñ'''o•§Ï/IÛßiýi~õ?õ?ö‰\ü/þ÷}’““«ÿ©ÿ‰ÿÅÿøÿêÿêÿòòü?ÿÿøÿø/þ¤OŸ~ÞþŸ¿ÿéçOßþð¿‡ý˜îŸtýþK»ú¿óýO¯ëøÿìïŸy~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßçÒ§ïü/çÿ8ÿÇù?Îÿ¦ßlÿ_ÿýÞËþã?}úôKõÿ]wþµøŸÿÇÿ^þë¿ñŸüŸüÿßzþ7þã?þ‹ÿéÓ§¯þ£þÓÿÁ_þOþOþ_üÿø/ÿ/ÿoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõúôé›ÿkþŸùêü?}ùñ?þÓ§Oßúõ?óÿÄÿêÿø¯þïû“ÿ“ÿ“ÿãÿ­ÿÇüÇÿ<ÿ¿žäñÔßÈÉÉäÓŸÓ÷?ýüéûÃþ9üÓçOmïÿö÷?=¿jÞÿìù[øÿÝüïî¿øŸÜøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÇŸœœ¼U>­ŸÌÇ_Yû;­?Íï¯þ§þÇ>‘‹ÿÅÿ¾Orrrõ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿ¯’kšÖÛÒöcú÷Óöq»ý…7þñý ·÷ùûï_5æzÿ7üÇÿ^þ×÷_ÓŒÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð‡?99¹ù¿æÿ™ÿgþŸõ¿äÖÿ[ÿÿäääÖÿ[ÿký¿øßúü·þß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿâúôéßX?ëÿÓö?øÃÿöãó[ïçßË·÷çûŸ^×ñÿÙß?óüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø¿/þë÷Ÿ¢OŸþEû?ÿ~ü4½òû?Ïúw©ý \—âàû;ýüéïý¢¿zÿÿÃ÷­ýÇúôé—ꧯíý_øþÅÿü?þ÷ò_ÿÿäÿäÿøÿNÿÿøÿÅñ¿¦iÎÿrþ‹ó_àïü϶ø£üüËqü:æzü‡ÿøßËçÿjšñŸøŸÿçÿùþŸýgÿåÿàøÃþð'''wþ—óœÿãüŸ«¿?ö‰<+O¿iþá?99yküïüïîó¿ÅÿÎÿÄÿ^þw÷Ÿÿ—ÿ“ÿãÿ{ý?þã?þwò_Ó4óÍÿ2ÿ þÖÿXÿcý¿õÿøÿÖÿYÿ§iÆâþŸÿçÿùöŸý—ÿƒ?üáø«¿kš¶9þOŸÿœ¶ÿÓúÓÐþ«ÿ©ÿišø_ü¯iš¦þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿøOŸ>ýÝúÙýÒû¿äïøßÃ~|~ëýüûñbùöþï|ÿÓë:þ?ûûgžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ–øŸ>}ú½ñÿ´þ3­?¥íÿ´þ4µÿêêì}ñ¿øß÷KŸ>}õ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿéÓ§O_ýGýþð—‘ÿÿ‹ÿñÿåÿåÿéÓÿ‹ÿÙ_þŸÿçÿÙöþð‡?üáߎÿúó§èÓ§Ñù/¿?M¯üù/³þ]j×¥øøþN?úûc¿è¯>ÿëðý_kÿñŸ>}ú¥úék{ÿ¾ñ?ÿÿ½ü×ã?ù?ù?þ¿Óÿã?þã¿øŸ>}úê?ê?ÍñüåÿäÿäÿÅÿøÿòÿòÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðWÿ§OŸ¾ù¿æÿ™ÿ§þÇÿÓ—ÿÿã?}úô­ÿWÿ3ÿOü¯þÿêÿ¾?ù?ù?ù?þßúüÇüÏóÿëIOýøœœ¼A>ý9}ÿÓÏŸ¾?üáŸÃ?}þÔöþoÿÓó«æýÏž¿…ÿøßÍÿîþ‹ÿÉÿÄÿü?ÿÏÿóÿì?û/ÿøÃþðüÉÉÉ[åÓúÉ|ü•µ¿ÓúÓüþêêì¹ø_üïû$''WÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñÿ*¹¦i½-m?¦?m·Û_øwãß¿p{ÿ—¿ÿñþUcþ§÷Ãüïå}ÿ5ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáø“““›ÿkþŸùæÿYÿKný¿õÿøONNný¿õ¿Öÿ‹ÿ­ÿÇëÿ}òòòü¿õÿøÿø/ÿGNN®þ£þãüøËÿÉÿÉÿ‹ÿñÿåÿ}ääâñ?ÿÏÿóÿü?ûÏþÃþð‡?üáoÿMÓŽíÿ1Üÿy¼ÿtzÿ—éþÓCûkÿoûkšý¿ìÿ¥iš¶iÿkû¯~ÿâûÿã/ÿíÿ/ÿ'ÿ'ÿÇÿ·îÿÿøÿâÿ¥ñ'}úôsöÿðýÏÛÿìýáÿÛØôµ½ÿ ßÿŸßïç÷wûóïsùµüò÷}ú­ú™øó}ú¿óý‹ÿùüïå¿þÿÉÿÉÿñÿþÿñÿ;ùoþ<}úæÿšÿeþü­ÿ±þÇúëÿñÿ­ÿ³þÏø¾ñŸøŸÿçÿùþŸýgÿåÿàøÃþêïôéÓ—øXÿןÒöZÚõ?õ?ö‹¾ø_üïû¥OŸ¾úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿã÷ÿõ$§~üFNNÞ Ÿþœ¾ÿéçOßþðÏáŸÞl{ÿ·¿ÿéþUóþg÷ßÂüïæwÿÅÿäÆâþŸÿçÿùöŸý—ÿƒ?üáø¿?þäää­òôù%iû;­?Íï¯þ§þÇ>‘‹ÿÅÿ¾Orrrõ?õ?ñ¿øÿñ_ý_ý_þOþÿçÿñÿñÿÅŸôéÓÏÛÿó÷?ýüéûÃþ÷°Óý“®ßiWÿw¾ÿéuÿŸýý3ÏÿøßÌý7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûâïüCúôÿåüçÿ8ÿÇùßô›íÿë¿ß{Ùü§OŸ~©¾ó¿ëοÿóÿøßËý7þ“ÿ“ÿãÿ[ÏÿÆüÇñ?}úôÕÔzã?øËÿÉÿÉÿ‹ÿñÿåÿåÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þOŸ>}óÍÿ3ÿOýÿ§/ÿ#þÇúôé[ÿ¯þgþŸø_ýÿÕÿ}òòòü¿õÿøÿøŸçÿד<žúñ99yƒ|úsúþ§Ÿ?}øÃ?‡úü©íýßþþ§çWÍûŸ= ÿñ¿›ÿÝýÿ“ÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿþø“““·Ê§õ“ùø+k§õ§ùýÕÿÔÿØ'rñ¿øß÷INN®þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þãÿUrMÓz[Ú~Lÿ~Ú>n·¿ðïÆ?¾áöþ/ÿãý«ÆüOïÿ†ÿøßËÿúþkšñŸøŸÿçÿùþŸýgÿåÿàøÃþð'''7ÿ×ü?óÿÌÿ³þ—ÜúëÿñŸœœÜúë­ÿÿ[ÿÿÖÿûþäÿäÿäÿøëÿñÿñ_üOŸ>ýëgýÚþçïøßÃ~|~ëýüûñbùöþï|ÿÓë:þ?ûûgžÿñ¿™ÿúoü@ßøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÅýþSôéÓ¿hÿçߟ¦W~ÿçYÿ.µ¿ëRü|§Ÿ?ýý±_ôWïÿøþ¯µÿøOŸ>ýRýôµ½ÿ ß¿øŸÿÇÿ^þë¿ñŸüŸüÿßéÿñÿñ¿8þ×4Íù_Îqþ üÿÙ”Ÿ9Ž_ÇüOÿðÿ{ùïü_M3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþäääÎÿrþóœÿsõ÷Ç>‘gåéï7Í?ü'''oÿÿÝ}þ·øßùŸøßËÿîþóÿòòü¯ÿÇüÇÿNþkšfþ¯ù_æÁßúë¬ÿ·þÿñßú?ëÿ4ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáõwMÓ6ÇÿéóŸÓöZÚõ?õ?Mÿ‹ÿ5MÓÔÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿ÿéÓ§¿[?»ÿOzÿ—üýáÿ{ØÏo½Ÿ?^,ßÞÿïz]ÇÿgÿÌóã?þ7ó_ÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üáßÿÓ§O¿7þŸÖ¦õ§´ýŸÖŸ¦ö_ýOýý¢/þÿû~éÓ§¯þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þã?}úôé«ÿ¨ÿÀþò/òâñ?þã¿ü¿ü?}úâñ?ûËÿóÿü?ûÏþÃþð‡?üÛñ_þ}úô/:ÿå÷ã§é•?ÿeÖ¿KíoàºÿßßéçOìýÕç¾ÿkí?þÓ§O¿T?}mïÿÂ÷/þçÿñ¿—ÿúoü'ÿ'ÿÇÿwúüÇüÿÓ§O_ýGý§9þƒ¿üŸüŸü¿øÿñ_þ_þßø¾ñŸøŸÿçÿùþŸýgÿåÿàøÃþêÿôéÓ7ÿ×ü?óÿÔÿøúò?âü§OŸ¾õÿêæÿ‰ÿÕÿñ_ýß÷'ÿ'ÿ'ÿÇÿ[ÿÿøÿyþ=Éã©¿‘““7ȧ?§ïúùÓ÷‡?üsø§ÏŸÚÞÿíïz~Õ¼ÿÙó·ðÿ»ùßÝñ?¹ñŸøŸÿçÿùþŸýgÿåÿàøÃþï?99y«|Z?™¿²öwZšß_ýOý}"ÿ‹ÿ}Ÿäääêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þ_%×4­·¥íÇôï§íãvû ÿnüãûnïÿò÷?Þ¿jÌÿôþoøÿ½ü¯ï¿¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üárrróÍÿ3ÿÏü?ëÉ­ÿ·þÿÉÉÉ­ÿ·þ×úñ¿õÿøoý¿ïOþOþOþÿ·þÿñÿåÿÈÉÉÕÔœÿù?ù?ùñ?þã¿ü¿ïœ\ü/þçÿùþŸÿgÿÙøÃþð‡?üíÿ¯iÚ±ý?†û?÷ŸNïÿ2ÝzhíÿmÿoM³ÿ—ý¿4MÓ6ímÿïÕï_üoÿüïå¿ýÿåÿäÿäÿøÿÖý¿ñÿñ_ü¿4þ¤OŸ~Îþ¾ÿyûŸ½?üáû‘¾¶÷áûÿóûýüþnþ}.¿–ÿOþþçÇüoæ¿þ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþ÷ÞŠ>}ú×ìÿü÷®iý%»ÿó¼ן4­_Mßÿÿ3ßßéçOìý½ûÿŸ¿ÿëì?þÓ§O¿U?¾Oÿw¾ñ?ÿÿ½ü×ã?ù?ù?þ¿Óÿã?þã'ÿÍŸ§Oßü_ó¿Ìÿ‚¿õ?ÖÿXÿoý?þã¿õÖÿ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ý>}úïÿë?ãúSÚþOëOCû¯þ§þÇ~Ñÿ‹ÿ}¿ôéÓWÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñüþ¿žäñÔßÈÉÉäÓŸÓ÷?ýüéûÃþ9üÓûmïÿö÷?Ý¿jÞÿìþ[øÿÝüïî¿øŸÜøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáÿ÷ÇŸœœ¼Už>¿$m§õ§ùýÕÿÔÿØ'rñ¿øß÷INN®þ§þ'þÿã?þ«ÿ«ÿËÿÉÿñÿü?þã?þã¿ø“>}úyûþþ§Ÿ?}øÃÿöcºÒõû/íêÿÎ÷?½®ãÿ³¿æùñÿ›ù¯ÿÆôÿÄÿü?ÿÏÿóÿì?û/ÿøÃþð_üHŸ¾ó¿œÿãüçÿ8ÿ›~³ýý÷{/ûÿôéÓ/ÕwþwÝù×âþÿ{ù¯ÿÆòòüëùßøÿø/þ§OŸ¾úúOoüù?ù?ùñ?þã¿ü¿ü¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕÿéÓ§oþ¯ùæÿ©ÿñÿôåÄÿøOŸ>}ëÿÕÿÌÿÿ«ÿã¿ú¿ïOþOþOþÿ·þÿñÿóüÿz’ÇS?~#''oONßÿôó§ïøçðOŸ?µ½ÿÛßÿôüªyÿ³çoá?þwó¿»ÿârã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßrròVù´~2eíï´þ4¿¿úŸúûD.þÿû>ÉÉÉÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü¿J®iZoKÛéßOÛÇíöþÝøÇ÷/ÜÞÿåï¼Õ˜ÿéýßðÿ{ù_ßM3þÿóÿü?ÿÏÿ³ÿì¿üüáøÃþäääæÿšÿgþŸùÖÿ’[ÿoý?þ“““[ÿoý¯õÿâëÿñßúߟüŸüŸüÿoý?þã?þ‹ÿéÓ§cý¬ÿOÛÿüýáÿ{ØÏo½Ÿ?^,ßÞÿïz]ÇÿgÿÌóã?þ7ó_ÿèÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿ¾ø¯ßŠ>}úíÿüûñÓôÊïÿ<ëߥö7p]Šÿïïôó§¿?ö‹þêýÿßÿµöÿéÓ§_ªŸ¾¶÷áûÿóÿøßËý7þ“ÿ“ÿãÿ;ý?þã?þÇÿš¦9ÿËù/οó?Ûâòó/Çñë˜ÿéñþã/ÿÿ«iÆâþŸÿçÿùöŸý—ÿƒ?üáøÃŸœœÜù_Îÿqþó®þþØ'ò¬<ýý¦ù‡ÿäää­ñ¿ó¿»Ïÿÿ;ÿÿ{ùßÝþ_þOþÿïõÿøÿøßÉMÓÌÿ5ÿËü/ø[ÿcýõÿÖÿã?þ[ÿgýŸ¦ÿ‰ÿùþŸÿçÿÙö_þþð‡?üá¯þ®iÚæø?}þsÚþOëOCû¯þ§þ§iâñ¿¦išúŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿ7â?}úôwëg÷ÿIïÿ’¿?üáûñù­÷óïÇ‹åÛû¿óýO¯ëøÿìïŸy~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?ü[âúôé÷ÆÿÓúÏ´þ”¶ÿÓúÓÔþ«ÿ©ÿ±_ôÅÿâß/}úôÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇü§OŸ>}õõøÃ_þEþOü/þÇü—ÿ—ÿ§O_ü/þgùþŸÿgÿÙøÃþð‡;þëÏŸ¢OŸþEç¿ü~ü4½òç¿Ìúw©ý \—âàû;ýüéïý¢¿úü¯Ã÷­ýÇúôé—ꧯíý_øþÅÿü?þ÷ò_ÿÿäÿäÿøÿNÿÿøÿâúôé«ÿ¨ÿ4Çð—ÿ“ÿ“ÿÿã?þËÿËÿ?Ð7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃ_ýŸ>}úæÿšÿgþŸúÿO_þGüÿôéÓ·þ_ýÏü?ñ¿ú?þ«ÿûþäÿäÿäÿøëÿñÿñ?Ïÿ¯'y<õã7rròùôçôýO?úþð‡ÿôùSÛû¿ýýOϯš÷?{þþã7ÿ»û/þ'7þÿóÿü?ÿÏÿ³ÿì¿üüáøÃÿýñ'''o•Oë'óñWÖþNëOóû«ÿ©ÿ±Oäâñ¿ï“œœ\ýOýOü/þÇüWÿWÿ—ÿ“ÿãÿùüÇüÇÿ«äš¦õ¶´ý˜þý´}Ünáß|ÿÂíý_þþÇûWùŸÞÿ ÿñ¿—ÿõý×4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üáONNnþ¯ùæÿ™ÿgý/¹õÿÖÿã?99¹õÿÖÿZÿ/þ·þÿ­ÿ÷ýÉÿÉÿÉÿñÿÖÿã?þã¿ü99¹úúóà/ÿ'ÿ'ÿ/þÇü—ÿ÷ý‘“‹ÿÅÿü?ÿÏÿóÿì?ûøÃþð‡¿ýÿ5M;¶ÿÇpÿçñþÓéý_¦ûOí¯ý¿íÿ­iöÿ²ÿ—¦iÚ¦ý¯íÿ½úý‹ÿíÿÿ½ü·ÿ¿üŸüŸüÿߺÿ7þã?þ‹ÿ—ÆŸôéÓÏÙÿÃ÷?oÿ³÷‡?üoc?Ò×öþ/|ÿ~¿ŸßßíÏ¿Ïå×òÿÉß?ðüøÿÍü×ãúÆâþŸÿçÿùöŸý—ÿƒ?üáøÃÿÞûOѧOÿšýŸÿÞ5­¿d÷ž÷ïºó“¦õ«éûŸâæû;ýüéïý¢¿wÿÿó÷ýÇúôé·êgâÏ÷éÿÎ÷/þçÿñ¿—ÿúoü'ÿ'ÿÇÿwúüÇüïä¿ùóôé›ÿkþ—ù_ð·þÇúëÿ­ÿÇü·þÏú?ãúÆâþŸÿçÿùöŸý—ÿƒ?üáø«¿Ó§Oÿ]âÿaýg\JÛÿiýihÿÕÿÔÿØ/úâñ¿ï—>}úêêâñ?þã¿ú¿ú¿üŸüÿÏÿã?þã?þßÿד<žúñ99yƒ|úsúþ§Ÿ?}øÃ?‡zÿ±íýßþþ§ûWÍûŸÝ ÿñ¿›ÿÝýÿ“ÿ‰ÿùþŸÿçÿÙö_þþð‡?üáÿþø“““·ÊÓç—¤íï´þ4¿¿úŸúûD.þÿû>ÉÉÉÕÿÔÿÄÿâüÇõõù?ù?þŸÿÇüÇüÒ§O?oÿÏßÿôó§ïøßÃ~L÷Oº~ÿ¥]ýßùþ§×uüö÷Ï}ú¥úÎÿ®;ÿZüÏÿã/ÿõßøOþOþÿo=ÿÿñÿÅÿôéÓWÿQÿéÿà/ÿ'ÿ'ÿ/þÇü—ÿ—ÿ7~ oü'þçÿùþŸÿgÿÙù?øÃþð‡¿ú?}úôÍÿ5ÿÏü?õ?þŸ¾üøÿéÓ§oý¿úŸùâõüWÿ÷ýÉÿÉÿÉÿñÿÖÿã?þãžÿ_OòxêÇoäää òéÏéûŸ~þôýáÿþéó§¶÷ûûŸž_5ïöü-üÇÿnþw÷_üOnü'þçÿùþŸÿgÿÙù?øÃþð‡ÿûãONNÞ*ŸÖOæã¯¬ýÖŸæ÷WÿSÿcŸÈÅÿâß'99¹úŸúŸø_üÿø¯þ¯þ/ÿ'ÿÇÿóÿøÿøÿWÉ5Mëmiû1ýûiû¸Ýþ¿ÿøþ…Ûû¿üý÷¯ó?½ÿþã/ÿëû¯iÆâþŸÿçÿùöŸý—ÿƒ?üáøÃŸœœÜü_óÿÌÿ3ÿÏú_rëÿ­ÿÇrrrëÿ­ÿµþ_üoý?þ[ÿïû“ÿ“ÿ“ÿãÿ­ÿÇüÇñ?}úôo¬ŸõÿiûŸ¿?üáûñù­÷óïÇ‹åÛû¿óýO¯ëøÿìïŸy~üÇÿfþë¿ñ}ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üßÿõûOѧOÿ¢ýŸ?~š^ùýŸgý»Ôþ®Kñ?ðý~þô÷Ç~Ñ_½ÿÿáû¿Öþã?}úôKõÓ×öþ/|ÿâþÿ{ù¯ÿÆòòü§ÿÇüÇÿâø_Ó4ç9ÿÅù/ðwþg[üQ~þå8~ó?=þÃüïå¿ó5ÍøOüÏÿóÿü?ÿÏþ³ÿòð‡?üáø“““;ÿËù?ÎÿqþÏÕßûDž•§¿ß4ÿ🜜¼5þwþw÷ùßâçâ/ÿ»ûÏÿËÿÉÿñÿ½þÿñÿ;ù¯išù¿æ™ÿë¬ÿ±þßúüÇëÿ¬ÿÓ4ã?ñ?ÿÏÿóÿü?ûÏþËÿÁþð‡?üÕß5MÛÿ§ÏNÛÿiýihÿÕÿÔÿ4Mü/þ×4MSÿSÿÿ‹ÿñÿÕÿÕÿåÿäÿøþÿñÿñÿÂö¿à{+û \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.bz2 new file mode 100644 index 000000000..19bb1cdac Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.z deleted file mode 100644 index a68398e45..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.bz2 new file mode 100644 index 000000000..646198900 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.z deleted file mode 100644 index 9840a5ebe..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.bz2 new file mode 100644 index 000000000..b3ff47017 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.z deleted file mode 100644 index dc0f16fc4..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_208_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_208_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_208_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_208_states.bin.z b/client/resources/hardnested_tables/bitflip_1_208_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_1_208_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_220_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_220_states.bin.bz2 new file mode 100644 index 000000000..fe85775bf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_220_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_220_states.bin.z b/client/resources/hardnested_tables/bitflip_1_220_states.bin.z deleted file mode 100644 index 479bacb03..000000000 --- a/client/resources/hardnested_tables/bitflip_1_220_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÛMnãF„aÝÀWÑtï½Ñ‰|5o}4¢Á–L‰”«êg‚ ™ÌObOj¾ªz»ߟ‡óð1$Ž_¦¿Ÿ¾ÌÝþíKß¿þrùýÒßþãKþý->É··øõ¯Þ¥/÷~ýÒÏ»ÿþ}þÿK?ÏþüÓÿkëÿxzûIþ,×ñtûã_ú~[þùû–׿¿ûïÿüõúŸ¯ý÷?þãÛ~þžýùO}Ö¾}ïÏúñ¥ÿþôó—~;ý÷­ÿ÷¯ìñçœÿnæ¿nûör‡ê¯×ÿ¼|ßóð¿ýõÖ_úïO?é··øõŸ>®ÛþãÞ¯_úùOÿØûÿ¿ôó—þøCøeþ9ÊÏwùó®}{ù}¨þzýÏÇaúúôñ<ú㯿ÞúãKÿýéç¯Å·Ó¿úwÿû¾ÿéïÿÅK–ßIÆß§§¿nûý;ýý7ý²÷ýI?é—ÿûÎÿúÿ¾ûú×ÿéÿôü¿þOþï/ÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿ¯ëÿÝ÷ßýçÿé¿Oý{ÿ×÷û?þßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñüÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúû÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§ûûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?ýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùþŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿù÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûÿÞßÿý[‘Ôß \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_24a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_24a_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_24a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_24a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_24a_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_24a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_24e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_24e_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_24e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_24e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_24e_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_24e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_25a_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_25a_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_25a_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_25a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_25a_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_25a_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_25e_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_25e_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_25e_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_25e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_25e_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_25e_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_262_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_262_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_262_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_262_states.bin.z b/client/resources/hardnested_tables/bitflip_1_262_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_262_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_266_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_266_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_266_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_266_states.bin.z b/client/resources/hardnested_tables/bitflip_1_266_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_266_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_272_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_272_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_272_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_272_states.bin.z b/client/resources/hardnested_tables/bitflip_1_272_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_272_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_276_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_276_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_276_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_276_states.bin.z b/client/resources/hardnested_tables/bitflip_1_276_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_276_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_280_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_280_states.bin.bz2 new file mode 100644 index 000000000..6d1908e79 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_280_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_280_states.bin.z b/client/resources/hardnested_tables/bitflip_1_280_states.bin.z deleted file mode 100644 index e4f4b6ac6..000000000 --- a/client/resources/hardnested_tables/bitflip_1_280_states.bin.z +++ /dev/null @@ -1,2 +0,0 @@ -xÚí×AŠ­P á,Õ;w!щG -! ‡¯{ð4܆.Rˆ-ö£÷×Wý/³þýöóîçOOÿþîßoúï?þø¯Ë?š_õ÷ç=?÷íçÝÏŸþšþýÝ¿ßôßüñ_—¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí?þúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõŸþãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡?ÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó?þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷Ÿýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó?þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿ý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸþÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì?þøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí?þúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõŸþãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡?ÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó?þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷Ÿýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó?þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì¿þÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿ý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸþÃüõ¿ý×øë?þç÷Ïÿøó?ÿ{ÿáoÿùŸÿÝ?ÿãÏÿüïý‡?þøë?û¯ÿðÇýoÿõþúÿùßýó?þüÏÿÞøÛþç÷Ïÿøó?ÿ{ÿá?þúÏþë?üñÇ_ÿÛý‡¿þãþwÿü?ÿó¿÷þöŸÿùßýó?þüÏÿÞøã¿þ³ÿúüñ×ÿö_ÿá¯ÿøŸÿÝ?ÿãÏÿüïý‡¿ýçþwÿü?ÿó¿÷þøã¯ÿì?þøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þúßþë?üõÿó¿ûçüùŸÿ½ÿð·ÿüÏÿîŸÿñçþ÷þÃüõŸý×øã¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùþçï?üñÇ_ÿÙý‡?þøëû¯ÿð×üÏÿîŸÿñçþ÷þÃßþó?ÿ»þÇŸÿùßûüñ×ö_ÿá¿þ·ÿúýÇÿüïþùþçï?üí?ÿó¿ûçüùŸÿ½ÿðÇýgÿõþøã¯ÿí¿þÃ_ÿñ?ÿ»þÇŸÿùßûûÏÿüïþùÿ¿ò?š;Õm \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.bz2 new file mode 100644 index 000000000..15195d213 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.z deleted file mode 100644 index a4cc5d58c..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.bz2 new file mode 100644 index 000000000..18a6d4987 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.z deleted file mode 100644 index f7bb63eb7..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.bz2 new file mode 100644 index 000000000..fa1be58fd Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.z deleted file mode 100644 index 4e5b2ff27..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.bz2 new file mode 100644 index 000000000..b6c1eb54c Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.z deleted file mode 100644 index f8686dba6..000000000 Binary files a/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.z and /dev/null differ diff --git a/client/resources/hardnested_tables/bitflip_1_328_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_328_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_328_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_328_states.bin.z b/client/resources/hardnested_tables/bitflip_1_328_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_1_328_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_388_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_388_states.bin.bz2 new file mode 100644 index 000000000..b01f02208 Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_388_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_388_states.bin.z b/client/resources/hardnested_tables/bitflip_1_388_states.bin.z deleted file mode 100644 index c8a8cf4a0..000000000 --- a/client/resources/hardnested_tables/bitflip_1_388_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÝO’ÄÊuåé3ªio%Vk©LSMd9¬Eõ¤§½ ´‰¶b‹Jù!àÒHÿHK{|á ü¹øu÷s~~ÿßÿçÿÎןþåOÿúÿè?ÿüŸïÿþÏßþy¾}ïÿÿÇÿüýÿ¯ýþ½íßöþ¾Þ\ÿ×›óý7Îtü³çµÅÿŠßÿÇÝûÏÑïׯï{GÇ{ýsž¿6~WÄÿ.ïÿ×›øýý{víûwÅýµ¿¿¦ýëÿËÿù»¿Ïù?ÿóÿÜ~¾ùÿÿõ¾>ßÇÿãþ×ÿß»ãý—ó¿®ñó¯×û§¯£ëoóÏ¿^×î矿Úþð¿ÿîü¸¯¿ïŸïÜÿ»ó¿þÏÿ‹ûÏÿ8Ö_þýuÜ¿?þ }/~Ûø]ÿ?ðýýçû|þÚßÿÇúÓ×›ø>ÿ'ÚŸòŸ{Ïß¿>ñýŸôüµñk¿ÿÏÿöOÿþçÿþ£ÿüó1¿ÿýûøûç¹öWÿçÿþïŸÿ÷ëó×}|þ—ïýûëŸûÿÿç÷ÿp¼?~¾=ÞÕ÷·=îö|£ó·ñkÛÿyûßm¶ŸoþûÊ7ÿüoïÇgß÷ÿÿ¯¿õ¿íÿþ£ëý¾³Ÿ¿¿ÆïßßߎÎ_Ç?ÿëŸó?þ×ÿø‡ÿùÇùþ÷×ñ6Ç´ÿµúÿÿñó?ßÃ_þý;~ÿÝïoþý¿\ÿö?Ûö?Gù??ÿËyÿù/‘ÿË^yæ¯çÿóÿþÃçÃóÿíXßÇÝÆopþaû‰ß§íÿ¿Ÿë÷ÏïÝßÿ£þ{týWôÿMüêøËÿkçÿQÿ·ý|óŸ×XüÕ¯|ýï¿Äÿó£þ»íG×7Ê_í¿_÷³“þòù÷õ_Üÿÿ5~9î×ç_ž—³ç/ãÿñùýÍߟùý¿¿ÿ·žkÿëåÿþÇÏ·ÿÞÿï¯;û/í™? Ö/þîüÛùßÑù7óóíýÎ?j?óû4[ã<·þüúÿýë›õÖ½ãÿïãõë³Ç{ýçÖo·×ÿßÿþµñk¿—÷ÿïÖO¶ïï‰õôýkï¯íÚøµíÃþoóù»õ«£õ§ƒþ»íG×7ú}g?W­ÿý£ñÿ§ëþûŸãË¿þ¯?ýéoÿ<×þê‡þøïüüõÿý×?ýcßßþûöú·ãñÝûûÏÏÇÿ¯ÿÿv¼?:ÿv|¾¿ƒóŸj?ˆÿ¿ÿ÷}½ÏOG¿_ÿí÷FÇÛþwöóׯ¯ýþã¿?ŽÏöÎ?j¿ÂñŽ¿®¸¿vüׯ¯i—ÿ×ÎÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü¿]ßýçç?3þnïïŠñ_¿¶}4^¯·ãÏ]ýéÆãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöíñùÿÖöÿÑÿéÿôÿuõü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿyúÊÿüyñ·ÿõOÿö·žkCþøïüüÏ1øþ÷ïxüw¿¿ý÷íõoõ˜ÿÒþýüuÞwþƒ×ÿ«÷ Ï¿Ñç·÷7:ÿ¨ýÌïcþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷ë‹Ú¾//ÿÒëý¿úýkï¯íÚøµíÃþoóùží;þÑ?7þµQÿÝö¿£ëý¾³Ÿ¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿ;íÿ5£þz[¾ÝìèøgÏ?j?Üÿë‚ß¿­?ßÄï{GÇ{ýsž¿6~WÄßþöÿ³ÿßšûÿÑÿéÿôú?ýŸþOÿÇÿãÿñÿøü¿üÿÇÿãÿñÿøü?þÿÿçÿÃÿãÿñÿüüÿüÿüÿòÿóó¿ùÿÚóÿöï·¼ÿ³ž¿6~OÿÏ®¿ÞÞßã¿&~mûh¼<_×õç'ÿg?[ýnwü~pþ:þôú?ýYýŸÿŸÿŸÿ]ÿ¿ü/ÿËÿ ûÿf¿ÿ“ýWíýÕýO¿ºÿoiÿß]ô¿Yþ«Öv•þ÷u2~ïÆ÷gÛ¢þ;ÿßsýôú?ýßþÿøü?þÿÿÃÿãÿñÿÖÿ­ÿ[ÿÇÿËÿøëÿøþü¿õü?þÿoýÿÿÇÿãÿñÿôú¿üOÿ§ÿÓÿéÿôëÿôúÿsôõÕÿ5ÿ7ÿ7ÿ7ÿ7ÿ_oþ/ÿËÿòÿºùöû?»þz{mÿÓÆ¯mö›Ï÷ükMýù¶ÿ]_’$I’$I’$É]ž¿Wü^Çýøüî#NŸ¿ŒÿöÿšQ½­?ßî?vtü³çµîÿuÁïßÖŸoâ¿÷½£ã½¿þ9Ï_¿+âoÿ?ûÿÙÿoÍýÿèÿôú?ýŸþOÿ§ÿãÿñÿøü?þ_þÇÿãÿñÿøü?þÿÿÇÿóÿáÿñÿøþ?þþþùÿùùßüíùû÷[ÞÿYÏ_¿§ÿg×_oïïŠñ_¿¶}4^¯ëúó“Çÿ³Ÿ¿­~·;~?8ú?ýŸþ¿¬þÏÿÏÿÏÿ¿®ÿ_þ—ÿåÿ…ý³ßÿÉþ«öþêþ§Œ_ÝÎÿ·´ÿï.úß,ÿUë?»Jÿû:¿wãû³í?Qÿÿï¹þ?ú?ýŸþoÿü?þÿÿÇÿáÿñÿøëÿÖÿ­ÿãÿåü¿õü?ÿ?þßú?þÿÿ·þÿÇÿãÿñÿøú?ý_þ§ÿÓÿéÿôú¿õú?ýÿ9ú¿ú¿êÿšÿ›ÿ›ÿ›ÿ›ÿ¯7ÿ—ÿåùÝü?ûýŸ]½½¿¶ÿiã×¶û¿Íç{þµ¦þ|ÛÿŽ®/I’$I’$I’ä.Ïß+~¯ã~|~÷§Ï_ÆÿNûͨ¿ÞÖŸo÷;:þÙóÚ÷ÿºà÷oëÏ7ñßûÞÑñÞ_ÿœç¯ßñ·ÿŸýÿìÿ·æþôú?ýŸþOÿ§ÿÓÿñÿøü?þÿ/ÿãÿñÿøü?þÿÿÇÿãÿùÿðÿøü?ÿÿ?ÿ?ÿ¿üÿüüoþ¿öü¿ýû-ïÿ¬ç¯ßÓÇÿ³ë¯·÷wÅø¯‰_Û>/Æ×uýùÉãÿÙÏßV¿Û¿œ¿Ž?ýŸþOÿ_Vÿçÿçÿçÿ_×ÿ/ÿËÿòÿÂþ¿ÙïÿdÿU{uÿSƯnçÿ[Úÿwýo–ÿªõŸ]¥ÿ}Œß»ñýÙöŸ¨ÿÎÿ÷\ÿýŸþOÿ·ÿ?þÿÿÇÿãÿðÿøü¿õëÿÖÿñÿò?þßú?þŸÿÿoýÿÿÇÿ[ÿÇÿãÿñÿøü?ýŸþ/ÿÓÿéÿôú?ýßú?ýŸþÿý_ý_õÍÿÍÿÍÿÍÿÍÿ×›ÿËÿò¿ü¿nþŸýþÏ®¿ÞÞ_Ûÿ´ñkÛ‡ýßæó=ÿZS¾íG×—$I’$I’$Ir—çï¿×q?>¿ûˆÓç/ã§ý¿fÔ_oëÏ·ûÿìùGí‡û]ðû·õç›øï}ïèxï¯Îó×ÆïŠøÛÿÏþöÿ[sÿ?ú?ýŸþOÿ§ÿÓÿéÿøü?þÿÿ—ÿñÿøü?þÿÿÇÿãÿñÿüøü?þŸÿÿŸÿŸÿ_þ~þ7ÿ_{þßþý–÷ÖóׯïéãÿÙõ×Ûû»bü×įm—Gãëºþüäñÿìço«ßíŽßÎ_ÇŸþOÿ§ÿ/«ÿóÿóÿóÿ¯ëÿ—ÿåùaÿßì÷²ÿª½¿ºÿ)ãW·óÿ-íÿ»‹þ7ËÕúÏ®Òÿ¾NÆïÝøþlûOÔçÿ{®ÿþOÿ§ÿÛÿÿÿÇÿãÿñøü?þßú¿õëÿøùÿoýÿÏÿÿ·þÿÇÿãÿ­ÿãÿñÿøü?þŸþOÿ—ÿéÿôú?ýŸþoýŸþOÿŽþ¯þ¯ú¿æÿæÿæÿæÿæÿëÍÿåù_þ_7ÿÏ~ÿg×_oï¯íÚøµíÃþoóùž­©?ßö¿£ëK’$I’$I’$¹Ëó÷Šß븟ß}Äéó—ñ¿Óþ_3꯷õçÛýÇŽŽöü£öÃý¿.øýÛúóMü÷¾wt¼÷×?çùkãwEüíÿgÿ?ûÿ­¹ÿýŸþOÿ§ÿÓÿéÿôü?þÿÿÇÿËÿøü?þÿÿÇÿãÿñÿøþ?ü?þÿÏÿÇÿÏÿÏÿ/ÿ??ÿ›ÿ¯=ÿoÿ~Ëû?ëùkã÷ôñÿìúëíý]1þkâ×¶ÆË£ñu]~òøöó·ÕïvÇïç¯ãOÿ§ÿÓÿ—Õÿùÿùÿùÿ×õÿËÿò¿ü¿°ÿoöû?ÙÕÞ_Ýÿ”ñ«Ûùÿ–öÿÝEÿ›å¿jýgWé_'ã÷n|¶ý'ê¿óÿ=×ÿGÿ§ÿÓÿíÿÿÇÿãÿñÿø?ü?þÿoýßú¿õü¿üÿ·þÿçÿÇÿ[ÿÇÿãÿñÿÖÿñÿøü?þÿOÿ§ÿËÿôú?ýŸþOÿ·þOÿ§ÿ?GÿWÿWý_óóóóóÿõæÿò¿ü/ÿ¯›ÿg¿ÿ³ë¯·÷×ö?müÚöaÿ·ù|Ï¿ÖÔŸoûßÑõ%I’$I’$I’Üåù{ÅïuÜÏï>âôùËøßiÿ¯õ×ÛúóíþcGÇ?{þQûáþ_üþmýù&þ{ß;:ÞûëŸóüµñ»"þöÿ³ÿŸýÿÖÜÿþOÿ§ÿÓÿéÿôú?þÿÿÇÿãÿåü?þÿÿÇÿãÿñÿøü?ÿþÿÿçÿãÿçÿçÿ—ÿŸŸÿÍÿמÿ·¿åýŸõüµñ{úøvýõöþ®ÿ5ñkÛGãåÑøº®??yü?ûùÛêw»ã÷ƒó×ñ§ÿÓÿéÿËêÿüÿüÿüÿëúÿåù_þ_Øÿ7ûýŸì¿jï¯îÊøÕíüKûÿî¢ÿÍò_µþ³«ô¿¯“ñ{7¾?Ûþõßùÿžëÿ£ÿÓÿéÿöÿÇÿãÿñÿøüþÿÿ·þoýßú?þ_þÇÿ[ÿÇÿóÿãÿ­ÿãÿñÿøëÿøü?þÿÿ§ÿÓÿåú?ýŸþOÿ§ÿ[ÿ§ÿÓÿŸ£ÿ«ÿ«þ¯ù¿ù¿ù¿ù¿ùÿzóù_þ—ÿ×Íÿ³ßÿÙõ×ÛûkûŸ6~mû°ÿÛ|¾ç_kêÏ·ýïèú’$I’$I’$Iîòü½â÷:îÇçwqúüeüï´ÿ׌úëmýùvÿ±£ãŸ=ÿ¨ýpÿ¯ ~ÿ¶þ|ÿ½ïïýõÏyþÚø]ûÿÙÿÏþkîÿGÿ§ÿÓÿéÿôú?ýÿÿÇÿãÿñÿò?þÿÿÇÿãÿñÿøü?þŸÿÿÿÇÿóÿñÿóÿóÿËÿÏÏÿæÿkÏÿÛ¿ßòþÏzþÚø=}ü?»þz{WŒÿšøµí£ñòh|]ןŸ<þŸýümõ»ÝñûÁùëøÓÿéÿôÿeõþþþÿuýÿò¿ü/ÿ/ìÿ›ýþOö_µ÷W÷?eüêvþ¿¥ýwÑÿfù¯ZÿÙUúß×Éø½ߟmÿ‰úïüÏõÿÑÿéÿôûÿãÿñÿøü?þÿÿÇÿ[ÿ·þoýÿ/ÿãÿ­ÿãÿùÿñÿÖÿñÿøü¿õü?þÿÿÇÿÓÿéÿò?ýŸþOÿ§ÿÓÿ­ÿÓÿéÿÏÑÿÕÿUÿ×üßüßüßüßü½ù¿ü/ÿËÿëæÿÙïÿìúëíýµýO¿¶}Øÿm>ßó¯5õçÛþwt}I’$I’$I’$wyþ^ñ{÷ãó»8}þ2þwÚÿkFýõ¶þ|»ÿØÑñÏžÔ~¸ÿ׿[¾‰ÿÞ÷ŽŽ÷þúç<mü®ˆ¿ýÿìÿgÿ¿5÷ÿ£ÿÓÿéÿôú?ýŸþÿÇÿãÿñÿøùÿÿÇÿãÿñÿøü?þÿÏÿ‡ÿÇÿãÿùÿøÿùÿùÿåÿççóÿµçÿíßoyÿg=müž>þŸ]½½¿+ÆMüÚöÑxy4¾®ëÏOÿÏ~þ¶úÝîøýàüuüéÿôúÿ²ú?ÿ?ÿ?ÿÿºþù_þ—ÿöÿÍ~ÿ'û¯Úû«ûŸ2~u;ÿßÒþ¿»è³üW­ÿì*ýïëdüÞï϶ÿDýwþ¿çúÿèÿôú¿ýÿñÿøü?þÿ‡ÿÇÿãÿ­ÿ[ÿ·þÿ—ÿñÿÖÿñÿüÿøëÿøü?þßú?þÿÿÇÿãÿéÿôùŸþOÿ§ÿÓÿéÿÖÿéÿôÿçèÿêÿªÿkþoþoþoþoþ¿Þü_þ—ÿåÿuóÿì÷výõöþÚþ§_Û>ìÿ6Ÿïùךúómÿ;º¾$I’$I’$I’»<¯ø½ŽûñùÝGœ>ÿÿ±¡} \ No newline at end of file diff --git a/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.bz2 b/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.bz2 new file mode 100644 index 000000000..fe85775bf Binary files /dev/null and b/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.bz2 differ diff --git a/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.z deleted file mode 100644 index 479bacb03..000000000 --- a/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.z +++ /dev/null @@ -1 +0,0 @@ -xÚíÛMnãF„aÝÀWÑtï½Ñ‰|5o}4¢Á–L‰”«êg‚ ™ÌObOj¾ªz»ߟ‡óð1$Ž_¦¿Ÿ¾ÌÝþíKß¿þrùýÒßþãKþý->É··øõ¯Þ¥/÷~ýÒÏ»ÿþ}þÿK?ÏþüÓÿkëÿxzûIþ,×ñtûã_ú~[þùû–׿¿ûïÿüõúŸ¯ý÷?þãÛ~þžýùO}Ö¾}ïÏúñ¥ÿþôó—~;ý÷­ÿ÷¯ìñçœÿnæ¿nûör‡ê¯×ÿ¼|ßóð¿ýõÖ_úïO?é··øõŸ>®ÛþãÞ¯_úùOÿØûÿ¿ôó—þøCøeþ9ÊÏwùó®}{ù}¨þzýÏÇaúúôñ<ú㯿ÞúãKÿýéç¯Å·Ó¿úwÿû¾ÿéïÿÅK–ßIÆß§§¿nûý;ýý7ý²÷ýI?é—ÿûÎÿúÿ¾ûú×ÿéÿôü¿þOþï/ÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿ¯ëÿÝ÷ßýçÿé¿Oý{ÿ×÷û?þßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñüÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúû÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§ûûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûûý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåý¿ý?ýëÿôú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?þ_ÿ'ÿ{ÿÿãÿî?þÏÿóÿôÏÿóÿü?ÿÿãÿø?ýËÿò¿üÏÿÛÿ»ÿî¿ûÏÿÓ¿ý¿÷öÿü¿ý¿÷öÿô/ÿËÿø?þÿÓ?þÿãÿú?ýŸþOÿOÿöÿî¿ý¿þßþ_þ·ÿ×ÿÛÿÓ¿þOÿ§ÿãÿõò¿÷ÿø?þïþãÿü?ÿOÿü?ÿÏÿóÿø?þÿÓ¿ü/ÿËÿü¿ý¿ûïþ»ÿü?ýÛÿ{ÿgÿÏÿÛÿ{ÿgÿOÿò¿üÿãÿø?ýãÿø?þ¯ÿÓÿéÿôÿôoÿïþÛÿëÿíÿåûý¿ý?ýëÿôú?ýŸüïý?þÿ»ÿø?ÿÏÿÓ?ÿÏÿóÿü?þÿãÿô/ÿËÿò?ÿoÿïþ»ÿî?ÿOÿöÿÞÿÙÿóÿöÿÞÿÙÿÓ¿ü/ÿãÿø?þOÿø?þÿëÿôú?ý?ýÛÿ»ÿöÿúûùßþ_ÿoÿOÿú?ýŸþÿ×ÿÉÿÞÿãÿø¿ûÿóÿü?ýóÿü?ÿÏÿãÿø?þOÿò¿ü/ÿóÿöÿî¿ûïþóÿôoÿïýŸý?ÿoÿïýŸý?ýËÿò?þÿãÿôÿãÿø¿þOÿ§ÿÓÿÓ¿ý¿ûoÿ¯ÿ·ÿ—ÿíÿõÿöÿô¯ÿÓÿéÿøùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùþŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿù÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝþŸþíÿ½ÿ³ÿçÿíÿ½ÿ³ÿ§ù_þÇÿñüŸþñüÿ×ÿéÿôúú·ÿwÿíÿõÿöÿò¿ý¿þßþŸþõú?ýÿ¯ÿ“ÿ½ÿÇÿñ÷ÿçÿùúçÿùþŸÿÇÿñüŸþåù_þçÿíÿÝ÷ßýçÿéßþßû?ûþßþßû?ûú—ÿåüÿÇÿéÿÇÿñýŸþOÿ§ÿ§û÷ßþ_ÿoÿ/ÿÛÿëÿíÿé_ÿ§ÿÓÿñÿú?ùßûüÿwÿñþŸÿ§þŸÿçÿùüÿÇÿé_þ—ÿåþßþßýwÿÝú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùûïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ïÿìÿùûïÿìÿé_þ—ÿñüÿ§üÿÇÿõú?ýŸþŸþíÿÝûý¿ý¿üoÿ¯ÿ·ÿ§ýŸþOÿÇÿëÿäïÿñüßýÇÿùþŸþùþŸÿçÿñüÿ§ù_þ—ÿùû÷ßýwÿùú·ÿ÷þÏþŸÿ·ÿ÷þÏþŸþåùÿÇÿñúÇÿñü_ÿ§ÿÓÿéÿéßþßý·ÿ×ÿÛÿËÿöÿúûú×ÿéÿôü¿þOþ÷þÿÇÿÝüŸÿçÿéŸÿçÿùþÿÇÿñú—ÿåùŸÿ·ÿwÿÝ÷Ÿÿ§ûÿÞßÿý[‘Ôß \ No newline at end of file diff --git a/client/resources/mad.json b/client/resources/mad.json new file mode 100644 index 000000000..535407ab4 --- /dev/null +++ b/client/resources/mad.json @@ -0,0 +1,13547 @@ +[ + { + "application": "Card holders personal data", + "company": "Rosan Finance", + "mad": "0x0004", + "service_provider": "", + "system_integrator": "Rosan Finance" + }, + { + "application": "Card ID: ISO No., expiry date and other identification data", + "company": "Rosan Finance", + "mad": "0x0005", + "service_provider": "Rosan Finance", + "system_integrator": "Rosan Finance" + }, + { + "application": "Private Rovalty programs, discount programs for card holders", + "company": "Rosan Finance", + "mad": "0x0006", + "service_provider": "Retail Trade and Service Org.", + "system_integrator": "Rosan Finance" + }, + { + "application": "Card Holder Data/ Card Management Data/ Access Control & Security", + "company": "House of Representatives of States General", + "mad": "0x0007", + "service_provider": "House of Representatives of States General", + "system_integrator": "Paul Sas" + }, + { + "application": "Card Holder Data/ Card Management Data/ Access Control & Security", + "company": "House of Representatives of States General", + "mad": "0x0008", + "service_provider": "House of Representatives of States General", + "system_integrator": "Paul Sas" + }, + { + "application": "Card and Reader Configuration", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x0009", + "service_provider": "PBV Kaufmann AG", + "system_integrator": "PBV Kaufmann AG" + }, + { + "application": "Card and Reader Configuration", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x000A", + "service_provider": "PBV Kaufmann AG", + "system_integrator": "PBV Kaufmann AG" + }, + { + "application": "Card and Reader Configuration", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x000B", + "service_provider": "PBV Kaufmann AG", + "system_integrator": "PBV Kaufmann AG" + }, + { + "application": "Card and Reader Configuration", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x000C", + "service_provider": "PBV Kaufmann AG", + "system_integrator": "PBV Kaufmann AG" + }, + { + "application": "Access Control, payment, ID, time registration", + "company": "Sagio A/S", + "mad": "0x000F", + "service_provider": "Sagio A/S", + "system_integrator": "Sagio A/S" + }, + { + "application": "Card administration", + "company": "Emcard a.s.", + "mad": "0x0010", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Card publisher data", + "company": "Haguess s.r.o.", + "mad": "0x0011", + "service_provider": "Haguess", + "system_integrator": "Haguess" + }, + { + "application": "Card publisher data", + "company": "Haguess s.r.o.", + "mad": "0x0012", + "service_provider": "Haguess", + "system_integrator": "Haguess" + }, + { + "application": "Card publisher data", + "company": "Haguess s.r.o.", + "mad": "0x0013", + "service_provider": "Haguess", + "system_integrator": "Haguess" + }, + { + "application": "Card publisher data", + "company": "Haguess s.r.o.", + "mad": "0x0014", + "service_provider": "Haguess", + "system_integrator": "Haguess" + }, + { + "application": "Card publisher information", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x0015", + "service_provider": "MIKROELEKTRONIKA spol.s.v.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.v.o." + }, + { + "application": "Issuer information", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x0016", + "service_provider": "Mikroelektronika spol.s.r.o., Kpt. Poplera 55, Vysoke Myto 566 01, Czech Republic", + "system_integrator": "Mikroelektronika spol.s.r.o., Kpt. Poplera 55, Vysoke Myto 566 01, Czech Republic" + }, + { + "application": "Personal information", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x0017", + "service_provider": "Transmetro Guatemala", + "system_integrator": "SIEMENS Itron Business services S.A. - Cordoba, Rep. Argentina" + }, + { + "application": "Customer profile - card holder information", + "company": "CSAD SVT Praha", + "mad": "0x0018", + "service_provider": "", + "system_integrator": "Mikroelektronika, EMTEST" + }, + { + "application": "Card information - provider, status, validity", + "company": "CSAD SVT Praha", + "mad": "0x0019", + "service_provider": "", + "system_integrator": "Mikroelektronika, EMTEST" + }, + { + "application": "Access control", + "company": "Custom Micro Products Ltd.", + "mad": "0x001B", + "service_provider": "Custom Micro Products", + "system_integrator": "Custom Micro Products" + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Arava Province and the city of Vitoria-Gasteiz", + "company": "Eusko Tren", + "mad": "0x001D", + "service_provider": "Idom Ingeniera y Consultoria, S.A.", + "system_integrator": "Idom Ingeniera y Consultoria, S.A." + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Arava Province and the city of Vitoria-Gasteiz", + "company": "Eusko Tren", + "mad": "0x001E", + "service_provider": "Idom Ingeniera y Consultoria, S.A.", + "system_integrator": "Idom Ingeniera y Consultoria, S.A." + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Arava Province and the city of Vitoria-Gasteiz", + "company": "Eusko Tren", + "mad": "0x001F", + "service_provider": "Idom Ingeniera y Consultoria, S.A.", + "system_integrator": "Idom Ingeniera y Consultoria, S.A." + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Arava Province and the city of Vitoria-Gasteiz", + "company": "Eusko Tren", + "mad": "0x0020", + "service_provider": "Idom Ingeniera y Consultoria, S.A.", + "system_integrator": "Idom Ingeniera y Consultoria, S.A." + }, + { + "application": "Card certificate", + "company": "Tidomat AB", + "mad": "0x0021", + "service_provider": "Tidomat AB", + "system_integrator": "Tidomat AB" + }, + { + "application": "Card administration", + "company": "Emcard a.s.", + "mad": "0x0022", + "service_provider": "Emcard", + "system_integrator": "Emcard" + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Bizkaia Province", + "company": "BISCAY TRANSPORT CONSORTIUM - Consorcio de transportes de Bizkaia", + "mad": "0x0023", + "service_provider": "Idom Ingenieria y Consultoria, S.A.", + "system_integrator": "Idom Ingenieria y Consultoria, S.A." + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Bizkaia Province", + "company": "BISCAY TRANSPORT CONSORTIUM - Consorcio de transportes de Bizkaia", + "mad": "0x0024", + "service_provider": "Idom Ingenieria y Consultoria, S.A.", + "system_integrator": "Idom Ingenieria y Consultoria, S.A." + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Bizkaia Province", + "company": "BISCAY TRANSPORT CONSORTIUM - Consorcio de transportes de Bizkaia", + "mad": "0x0025", + "service_provider": "Idom Ingenieria y Consultoria, S.A.", + "system_integrator": "Idom Ingenieria y Consultoria, S.A." + }, + { + "application": "Interoperable Contactless Card for multimode transport in the area of Bizkaia Province", + "company": "BISCAY TRANSPORT CONSORTIUM - Consorcio de transportes de Bizkaia", + "mad": "0x0026", + "service_provider": "Idom Ingenieria y Consultoria, S.A.", + "system_integrator": "Idom Ingenieria y Consultoria, S.A." + }, + { + "application": "Card publisher data, card holder profile", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x0027", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Card administration for municipal chip card - card issuer (information)", + "company": "Plzeňské MÄ›stské Dopravní Podniky A.S.", + "mad": "0x0028", + "service_provider": "Plzeňské MÄ›stské Dopravní Podniky A.S.", + "system_integrator": "Plzeňské MÄ›stské Dopravní Podniky A.S." + }, + { + "application": "Card information", + "company": "BULL POLSKA Sp. z o.o.", + "mad": "0x0029", + "service_provider": "BULL POLSKA", + "system_integrator": "BULL POLSKA" + }, + { + "application": "Card administration", + "company": "Sportdata SP. Z.0.0.", + "mad": "0x002A", + "service_provider": "Sportdata SP. 2 0.0.", + "system_integrator": "Sportdata SP. 2 0.0." + }, + { + "application": "Card administration; Issuer information", + "company": "ODP-software s.r.o.", + "mad": "0x002B", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Card administration; Issuer information", + "company": "ODP-software s.r.o.", + "mad": "0x002C", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Card publisher data, card holder profile", + "company": "OREDO s.r.o", + "mad": "0x002D", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Card publisher data, card holder profile", + "company": "Ústecky kraj", + "mad": "0x002E", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Internal use (Tests, Demos...)", + "company": "Ascom Monétel", + "mad": "0x0101", + "service_provider": "Monétel R&D Fare Collection Systems Departement", + "system_integrator": "Monétel S.A." + }, + { + "application": "Benefit services", + "company": "Scheidt & Bachmann", + "mad": "0x0102", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Benefit services", + "company": "Scheidt & Bachmann", + "mad": "0x0103", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Benefit services", + "company": "Scheidt & Bachmann", + "mad": "0x0104", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Shipping company", + "company": "Scheidt & Bachmann", + "mad": "0x0105", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Shipping company", + "company": "Scheidt & Bachmann", + "mad": "0x0106", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Shipping company", + "company": "Scheidt & Bachmann", + "mad": "0x0107", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Shipping company", + "company": "Scheidt & Bachmann", + "mad": "0x0108", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Cure management", + "company": "Scheidt & Bachmann", + "mad": "0x0109", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Cure management", + "company": "Scheidt & Bachmann", + "mad": "0x010A", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "MIFARE Micro Module (MMM) easy test card for antenna calibration", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x010B", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "MIFARE Windows Application Demo", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x010C", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "MIFARE Windows Application Demo", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x010D", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "MIFARE Windows Application Demo", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x010E", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "MIFARE Windows Application Demo", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x010F", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "MIFARE Windows Application Demo", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x0110", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "MIFARE Windows Application Demo", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x0111", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "MIFARE Windows Application Demo", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x0112", + "service_provider": "Mikron GmbH", + "system_integrator": "Mikron GmbH" + }, + { + "application": "Employer indentification card", + "company": "VFJ Technology Pty Ltd", + "mad": "0x0113", + "service_provider": "VFJ Electronics Pty Ltd.", + "system_integrator": "VFJ Electronics PTy Ltd." + }, + { + "application": "City Transport (Metro ticketing, bus ticket)", + "company": "VFJ Technology Pty Ltd", + "mad": "0x0114", + "service_provider": "VFJ Electronic Pty Ltd.", + "system_integrator": "Cubic - VFJ" + }, + { + "application": "Card Administratin, cardholder adminstration, access control & security, company services, miscellaneous applications", + "company": "Ministry of Defense", + "mad": "0x0115", + "service_provider": "Ministry of Defence", + "system_integrator": "" + }, + { + "application": "City transport bus, ferry, administration", + "company": "VFJ Technology Pty Ltd", + "mad": "0x0116", + "service_provider": "VFJ Technology", + "system_integrator": "Cubic - VFJ" + }, + { + "application": "Busticketing System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x0117", + "service_provider": "King Man County Public Traffic", + "system_integrator": "Barouh Electronic Co." + }, + { + "application": "", + "company": "Reserved for MAD", + "mad": "0x0118", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x0119", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x011A", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x011B", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x011C", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x011D", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x011E", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x011F", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Weighbridge for trucks", + "company": "VFJ Technology Pty Ltd", + "mad": "0x0130", + "service_provider": "Hardware Systems Sales", + "system_integrator": "" + }, + { + "application": "Bus services, access control, diverse (service)", + "company": "IEM - Intenierie Electronique Mecanique S.A.", + "mad": "0x0131", + "service_provider": "IEM SA", + "system_integrator": "IEM SA" + }, + { + "application": "Miscellaneous Application", + "company": "BOSCH Telecom GmbH", + "mad": "0x0140", + "service_provider": "Bosch Telecom GmbH", + "system_integrator": "Bosch Telecom GmbH" + }, + { + "application": "Configuration Master Card for MIFARE reader/writers", + "company": "Integrated Engineering", + "mad": "0x0141", + "service_provider": "IE Holding", + "system_integrator": "IE Holding" + }, + { + "application": "Photo copier controll, access controll, time & attendance", + "company": "Beka Elektronik", + "mad": "0x014B", + "service_provider": "BEKA Elektronik", + "system_integrator": "BEKA Elektronik" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0x014C", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "E-ticketing", + "company": "highQ Computerlösungen GmbH", + "mad": "0x014D", + "service_provider": "", + "system_integrator": "high Q" + }, + { + "application": "E-ticketing", + "company": "highQ Computerlösungen GmbH", + "mad": "0x014E", + "service_provider": "", + "system_integrator": "high Q" + }, + { + "application": "E-ticketing", + "company": "highQ Computerlösungen GmbH", + "mad": "0x014F", + "service_provider": "", + "system_integrator": "high Q" + }, + { + "application": "E-ticketing", + "company": "highQ Computerlösungen GmbH", + "mad": "0x0150", + "service_provider": "", + "system_integrator": "high Q" + }, + { + "application": "E-ticketing", + "company": "highQ Computerlösungen GmbH", + "mad": "0x0151", + "service_provider": "", + "system_integrator": "high Q" + }, + { + "application": "Admin profile", + "company": "KORID LK, spol. s r.o", + "mad": "0x0153", + "service_provider": "KORID LK, spol.s.r.o.", + "system_integrator": "KORID LK, spol.s.r.o." + }, + { + "application": "Details of the card issuer", + "company": "Scheidt & Bachmann", + "mad": "0x0201", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Details of the card issuer", + "company": "Scheidt & Bachmann", + "mad": "0x0202", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "MIFARE Demonstration Software, G&D - F&E Dept.", + "company": "*Giesecke & Devrient GmbH", + "mad": "0x0203", + "service_provider": "G&D", + "system_integrator": "G&D" + }, + { + "application": "MIFARE Demonstration Software, G&D - F&E Dept.", + "company": "*Giesecke & Devrient GmbH", + "mad": "0x0204", + "service_provider": "G&D", + "system_integrator": "G&D" + }, + { + "application": "MIFARE Demonstration Software, G&D - F&E Dept.", + "company": "*Giesecke & Devrient GmbH", + "mad": "0x0205", + "service_provider": "G&D", + "system_integrator": "G&D" + }, + { + "application": "MIFARE Demonstration Software, G&D - F&E Dept.", + "company": "*Giesecke & Devrient GmbH", + "mad": "0x0206", + "service_provider": "G&D", + "system_integrator": "G&D" + }, + { + "application": "Watch service, owner id, electronical service book, messaging system for news", + "company": "Junghans Uhren GmbH", + "mad": "0x0207", + "service_provider": "Junghans Uhren GmbH", + "system_integrator": "" + }, + { + "application": "Card Touch Smart Card Applications", + "company": "Touch Technology International Inc.", + "mad": "0x0208", + "service_provider": "Touch Technology International", + "system_integrator": "Touch Technology International" + }, + { + "application": "Miscellaneous application, city traffic, access controll & security entertainment, car parking, electronic trade", + "company": "KFAP S.A.", + "mad": "0x0209", + "service_provider": "KFPA", + "system_integrator": "KFPA" + }, + { + "application": "Computer, car parking, elec. purse, access control & security", + "company": "DECA Engineering", + "mad": "0x020A", + "service_provider": "Deca Engineering", + "system_integrator": "Deca Engineering" + }, + { + "application": "Social identification no. of card holder", + "company": "Rosan Finance", + "mad": "0x0301", + "service_provider": "Social Protection Org.", + "system_integrator": "Rosan Finance" + }, + { + "application": "Miscellaneous applications: customer profile, card administration", + "company": "ODP-software s.r.o.", + "mad": "0x0302", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Miscellaneous applications: customer profile, card administration", + "company": "ODP-software s.r.o.", + "mad": "0x0303", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Access Control, payment, ID, time registration", + "company": "Sagio A/S", + "mad": "0x0401", + "service_provider": "Sagio A/S", + "system_integrator": "Sagio A/S" + }, + { + "application": "Multifunctional appplications", + "company": "Braincon Technologies GmbH", + "mad": "0x054D", + "service_provider": "Braincon", + "system_integrator": "Braincon" + }, + { + "application": "Miscellaneous application", + "company": "Ústecky kraj", + "mad": "0x054E", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Miscellaneous application", + "company": "Ústecky kraj", + "mad": "0x054F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Miscellaneous application", + "company": "Ústecky kraj", + "mad": "0x0550", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Miscellaneous application", + "company": "Ústecky kraj", + "mad": "0x0551", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Miscellaneous application", + "company": "Ústecky kraj", + "mad": "0x0552", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Miscellaneous application", + "company": "BULL POLSKA Sp. z o.o.", + "mad": "0x0601", + "service_provider": "BULL POLSKA", + "system_integrator": "BULL POLSKA" + }, + { + "application": "Miscellaneous application", + "company": "BULL POLSKA Sp. z o.o.", + "mad": "0x0602", + "service_provider": "BULL POLSKA", + "system_integrator": "BULL POLSKA" + }, + { + "application": "Card administration", + "company": "MCF RF TECH SRL", + "mad": "0x0701", + "service_provider": "MCF", + "system_integrator": "MCF" + }, + { + "application": "City traffic, electronic purse, micellaneous applications", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x0702", + "service_provider": "Koordinator", + "system_integrator": "PVT" + }, + { + "application": "Access control, electronic purse, parking, city cards", + "company": "ARD", + "mad": "0x0703", + "service_provider": "ARD", + "system_integrator": "ARD" + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0x0704", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Application containing card holder information", + "company": "DOPRAVNI PODNIK mest Mostu a Litvinova, a.s.", + "mad": "0x0705", + "service_provider": "Dopravni Podnik mest Mostu a Litvinova, a.s.", + "system_integrator": "Mikroelektronika, spol. sr. o., Kpt. Poplera 55, 565 01 Vysoké Mýto, CZ" + }, + { + "application": "Service Application containing information about driver and inspector", + "company": "DOPRAVNI PODNIK mest Mostu a Litvinova, a.s.", + "mad": "0x0706", + "service_provider": "Dopravni Podnik mest Mostu a Litvinova, a.s.", + "system_integrator": "Mikroelektronika, spol. sr. o., Kpt. Poplera 55, 565 01 Vysoké Mýto, CZ" + }, + { + "application": "Bonus counter", + "company": "DOPRAVNI PODNIK mest Mostu a Litvinova, a.s.", + "mad": "0x0707", + "service_provider": "Dopravni Podnik mest Mostu a Litvinova, a.s.", + "system_integrator": "Mikroelektronika, spol. sr.o. Kpt. Poplera 55, 565 01 Vysoké Mýto, CZ" + }, + { + "application": "Liberec City Card - loyalty check", + "company": "Liberecká IS, a.s.", + "mad": "0x0708", + "service_provider": "Liverecká IS, a.s.", + "system_integrator": "Accenture Central Europe" + }, + { + "application": "Electronic purse, city traffic, customer profile, service application, check-in/out application", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x0709", + "service_provider": "Mikroelektronika", + "system_integrator": "Mikroelektronika" + }, + { + "application": "Electronic purse, city traffic, customer profile, service application, check-in/out application", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x070A", + "service_provider": "Mikroelektronika", + "system_integrator": "Mikroelektronika" + }, + { + "application": "Bonus Counter", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x070B", + "service_provider": "Mikroelektronika spol s.r.o.", + "system_integrator": "Mikroelektronika spol s.r.o." + }, + { + "application": "Card Administration", + "company": "MCF RF TECH SRL", + "mad": "0x070C", + "service_provider": "MCF RF TECH S.R.L.", + "system_integrator": "MCF RF TECH S.R.L." + }, + { + "application": "Loyalty/Gift Card application for Cinemas, Resorts, Retails chains", + "company": "VERIFONE ITALIA SRL", + "mad": "0x070D", + "service_provider": "VeriFone Italia", + "system_integrator": "VeriFone Italia" + }, + { + "application": "Transaction log 3S", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x070E", + "service_provider": "Transmetro Guatemala", + "system_integrator": "SIEMENS Itron Business services S.A. - Cordoba, Rep. Argentina" + }, + { + "application": "Multifunctional ID card", + "company": "Micros-Fidelio GmbH", + "mad": "0x070F", + "service_provider": "Micros-Fidelio GmbH", + "system_integrator": "Micros-Fidelio GmbH" + }, + { + "application": "Multifunctional ID card", + "company": "Micros-Fidelio GmbH", + "mad": "0x0710", + "service_provider": "Micros-Fidelio GmbH", + "system_integrator": "Micros-Fidelio GmbH" + }, + { + "application": "Multifunctional ID card", + "company": "Micros-Fidelio GmbH", + "mad": "0x0711", + "service_provider": "Micros-Fidelio GmbH", + "system_integrator": "Micros-Fidelio GmbH" + }, + { + "application": "Dedicated to marina users, to improve data consistancy", + "company": "MARINAPASS", + "mad": "0x0712", + "service_provider": "MARINAPASS", + "system_integrator": "Philippe FONTENOY" + }, + { + "application": "Customer profile", + "company": "KORID LK, spol. s r.o", + "mad": "0x0713", + "service_provider": "KORID LK, spol.s.r.o.", + "system_integrator": "KORID LK, spol.s.r.o." + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x0714", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x0715", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x0716", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x0717", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x0718", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x0719", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x071A", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Cashless Payment; access and time control", + "company": "EVIS AG", + "mad": "0x071B", + "service_provider": "EVIS AG", + "system_integrator": "EVIS AG" + }, + { + "application": "Customer profile", + "company": "Mikroelektronika GmbH", + "mad": "0x071C", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o., Draby 849, Vysoke Myto 56601, Czech Republic", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o., Draby 849, Vysoke Myto 56601, Czech Republic" + }, + { + "application": "Customer profile", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x071D", + "service_provider": "ZAGREBACKI Holding d.o.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Bonus counter", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x071E", + "service_provider": "ZAGREBACKI Holding d.o.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Authentication of Casino Staff members", + "company": "Atronic Austria GmbH", + "mad": "0x071F", + "service_provider": "ATRONIC Austria GmBH", + "system_integrator": "ATRONIC Austria GmBH" + }, + { + "application": "Authentication of Casino Staff members", + "company": "Atronic Austria GmbH", + "mad": "0x0720", + "service_provider": "ATRONIC Austria GmBH", + "system_integrator": "ATRONIC Austria GmBH" + }, + { + "application": "Operator Card for Automated-Fare Collection System", + "company": "ACS Solutions Switzerland Ltd. a Xerox Company", + "mad": "0x0721", + "service_provider": "ACS Solutions Switzerland Ltd.", + "system_integrator": "ACS Solutions Switzerland Ltd." + }, + { + "application": "Multi-application Card-Access Control, Ticketing payment", + "company": "APPLICAM", + "mad": "0x0722", + "service_provider": "APPLICAM", + "system_integrator": "APPLICAM" + }, + { + "application": "Multi-application Card-Access Control, Ticketing payment", + "company": "APPLICAM", + "mad": "0x0723", + "service_provider": "APPLICAM", + "system_integrator": "APPLICAM" + }, + { + "application": "Multi-application Card-Access Control, Ticketing payment", + "company": "APPLICAM", + "mad": "0x0724", + "service_provider": "APPLICAM", + "system_integrator": "APPLICAM" + }, + { + "application": "Multi-application Card-Access Control, Ticketing payment", + "company": "APPLICAM", + "mad": "0x0725", + "service_provider": "APPLICAM", + "system_integrator": "APPLICAM" + }, + { + "application": "Multi-application Card-Access Control, Ticketing payment", + "company": "APPLICAM", + "mad": "0x0726", + "service_provider": "APPLICAM", + "system_integrator": "APPLICAM" + }, + { + "application": "Multi-application Card-Access Control, Ticketing payment", + "company": "APPLICAM", + "mad": "0x0727", + "service_provider": "APPLICAM", + "system_integrator": "APPLICAM" + }, + { + "application": "Bonus Counter", + "company": "Mikroelektronika GmbH", + "mad": "0x0728", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Info-Customer profile", + "company": "Mikroelektronika GmbH", + "mad": "0x0729", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Micropayments, access control and gift control", + "company": "METAPAY LTD.", + "mad": "0x072A", + "service_provider": "METAPAY LTD.", + "system_integrator": "EPAM Systems Ltd." + }, + { + "application": "Customer profile", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x072B", + "service_provider": "Mikroelektronika spol.s r.o", + "system_integrator": "Mikroelektronika spol.s r.o" + }, + { + "application": "Biometric data", + "company": "Alphatronics", + "mad": "0x072C", + "service_provider": "", + "system_integrator": "Alphatronics" + }, + { + "application": "Hotel, Access control, entertainement, NFC, Academic, Comoany Service, Healt service", + "company": "USSEN Limited", + "mad": "0x072D", + "service_provider": "Ussen Limited", + "system_integrator": "Ussen Limited" + }, + { + "application": "Gangway Access Control for ships", + "company": "LabelCraft AS", + "mad": "0x072E", + "service_provider": "LabelCraft AS", + "system_integrator": "LabelCraft AS" + }, + { + "application": "Gangway Access Control for ships", + "company": "LabelCraft AS", + "mad": "0x072F", + "service_provider": "LabelCraft AS", + "system_integrator": "LabelCraft AS" + }, + { + "application": "E-ticketing ID card", + "company": "Monet+ a.s.", + "mad": "0x0730", + "service_provider": "Monet+ a.s.", + "system_integrator": "Monet+ a.s." + }, + { + "application": "Europe", + "company": "Monet+ a.s.", + "mad": "0x0731", + "service_provider": "Monet+ a.s.", + "system_integrator": "Monet+ a.s." + }, + { + "application": "Identification card", + "company": "Monet+ a.s.", + "mad": "0x0732", + "service_provider": "Monet+ a.s.", + "system_integrator": "Monet+ a.s." + }, + { + "application": "Access control with point store systems for facility integration purpose", + "company": "Unicard S.A.", + "mad": "0x0733", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Configuration, control and initialization", + "company": "INID BV", + "mad": "0x0734", + "service_provider": "INID", + "system_integrator": "INID" + }, + { + "application": "Public transport sytems. Parking systems. Catering. Electronic wallet. Reservation system. Access services. Attendance services. Industrial identification. City card.", + "company": "Duha systém s.r.o.", + "mad": "0x0735", + "service_provider": "DUHA systém s.r.o.", + "system_integrator": "DUHA systém s.r.o." + }, + { + "application": "Public transport sytems. Parking systems. Catering. Electronic wallet. Reservation system. Access services. Attendance services. Industrial identification. City card.", + "company": "Duha systém s.r.o.", + "mad": "0x0736", + "service_provider": "DUHA systém s.r.o.", + "system_integrator": "DUHA systém s.r.o." + }, + { + "application": "Public transport sytems. Parking systems. Catering. Electronic wallet. Reservation system. Access services. Attendance services. Industrial identification. City card.", + "company": "Duha systém s.r.o.", + "mad": "0x0737", + "service_provider": "DUHA systém s.r.o.", + "system_integrator": "DUHA systém s.r.o." + }, + { + "application": "Public transport sytems. Parking systems. Catering. Electronic wallet. Reservation system. Access services. Attendance services. Industrial identification. City card.", + "company": "Duha systém s.r.o.", + "mad": "0x0738", + "service_provider": "DUHA systém s.r.o.", + "system_integrator": "DUHA systém s.r.o." + }, + { + "application": "Customer profile", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x0739", + "service_provider": "Jamaica Urban Transit Company Ltd", + "system_integrator": "Mikroelektronika spol.s r.o." + }, + { + "application": "Card Holder Information", + "company": "BULL POLSKA Sp. z o.o.", + "mad": "0x073A", + "service_provider": "BULL POLSKA", + "system_integrator": "BULL POLSKA" + }, + { + "application": "PAAC transit services", + "company": "Scheidt & Bachmann GmbH", + "mad": "0x073B", + "service_provider": "Scheidt & Bachmann GmbH", + "system_integrator": "Scheidt & Bachmann GmbH" + }, + { + "application": "Customer loyalty", + "company": "K-Plus Oy", + "mad": "0x073C", + "service_provider": "K-Plus Oy", + "system_integrator": "" + }, + { + "application": "Customer loyalty", + "company": "K-Plus Oy", + "mad": "0x073D", + "service_provider": "K-Plus Oy", + "system_integrator": "" + }, + { + "application": "Customer loyalty", + "company": "K-Plus Oy", + "mad": "0x073E", + "service_provider": "K-Plus Oy", + "system_integrator": "" + }, + { + "application": "Bonus counter", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x073F", + "service_provider": "Jamaica Urban Transit Company Ltd", + "system_integrator": "Mikroelektronika spol.s r.o." + }, + { + "application": "Transaction log 2S", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x0740", + "service_provider": "Mikroelektronika spol.s r.o.", + "system_integrator": "Mikroelektronika spol.s r.o." + }, + { + "application": "JIS", + "company": "eko TIP ID s.r.o", + "mad": "0x0741", + "service_provider": "University of West Bohemia in Pilsen", + "system_integrator": "eko TIP ID s.r.o" + }, + { + "application": "Mobile Ticket/Picticket", + "company": "MATRIX Solutions GmbH & Co.KG", + "mad": "0x0742", + "service_provider": "MATRIX Solutions GmbH & Co.KG", + "system_integrator": "MATRIX Solutions GmbH & Co.KG" + }, + { + "application": "Miscellaneous applications", + "company": "OREDO s.r.o", + "mad": "0x0743", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Miscellaneous applications", + "company": "OREDO s.r.o", + "mad": "0x0744", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Miscellaneous applications", + "company": "OREDO s.r.o", + "mad": "0x0745", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Miscellaneous applications", + "company": "OREDO s.r.o", + "mad": "0x0746", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Miscellaneous applications", + "company": "OREDO s.r.o", + "mad": "0x0747", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Public Library User Identification", + "company": "Plasticard-ZFT GmbH", + "mad": "0x0748", + "service_provider": "Plasticard-ZFT GmbH", + "system_integrator": "Bibliotheca RFID Library Systems GmbH" + }, + { + "application": "Multiapplication", + "company": "IMA s.r.o.", + "mad": "0x0749", + "service_provider": "Ima Ltd", + "system_integrator": "" + }, + { + "application": "Supplementary information for other applications - bonus counters, logs", + "company": "TELMAX s.r.o.", + "mad": "0x074A", + "service_provider": "TELMAX s.r.o.", + "system_integrator": "TELMAX s.r.o." + }, + { + "application": "Cafeteria services", + "company": "Netlock Kft.", + "mad": "0x074B", + "service_provider": "Netlock Kft.", + "system_integrator": "Netlock Kft." + }, + { + "application": "Loyalty services", + "company": "Netlock Kft.", + "mad": "0x074C", + "service_provider": "Netlock Kft.", + "system_integrator": "Netlock Kft." + }, + { + "application": "Access control, miscellaneous applications", + "company": "TAGGER SYSTEMS Co Ltd", + "mad": "0x074D", + "service_provider": "TAGGER SYSTEMS Co Ltd", + "system_integrator": "" + }, + { + "application": "Fuel card for International Diesel Sevice", + "company": "Kuwait Petroleum Belgium", + "mad": "0x074E", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Fuel card for International Diesel Sevice", + "company": "Kuwait Petroleum Belgium", + "mad": "0x074F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Fuel card for International Diesel Sevice", + "company": "Kuwait Petroleum Belgium", + "mad": "0x0750", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Identification for airline related services", + "company": "Lufthansa German Airlines", + "mad": "0x0801", + "service_provider": "Deutsche Lufthansa AG", + "system_integrator": "Deutsche Lufthansa AG" + }, + { + "application": "Airlines", + "company": "KLM-Royal Dutch Airlines", + "mad": "0x0803", + "service_provider": "KLM", + "system_integrator": "KLM" + }, + { + "application": "Ticketing for ferry trafic", + "company": "Pay Vend Solutions", + "mad": "0x0901", + "service_provider": "Payvend Solutions", + "system_integrator": "Payvend Solutions" + }, + { + "application": "Bus services with extension to rail and taxi", + "company": "Questek Marketing", + "mad": "0x1001", + "service_provider": "Questek Marketing", + "system_integrator": "Questek Marketing" + }, + { + "application": "Railway Transit in Moscow region", + "company": "Moscow Railway Federal State Unitary Enterprize", + "mad": "0x1003", + "service_provider": "Moscow railway", + "system_integrator": "Express Card" + }, + { + "application": "Fare collection", + "company": "Tehran Urban & Suburban Railway Co.", + "mad": "0x1004", + "service_provider": "Processing World Corp", + "system_integrator": "Processing World Corp" + }, + { + "application": "Fare collection", + "company": "Ascom", + "mad": "0x1005", + "service_provider": "TUSRC", + "system_integrator": "Ascom Monetel" + }, + { + "application": "Mass Transportation Ticketing", + "company": "Omnifare", + "mad": "0x1006", + "service_provider": "MBS", + "system_integrator": "MBS" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1007", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1008", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1009", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x100A", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x100B", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x100C", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x100D", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x100E", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x100F", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1010", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1011", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1012", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1013", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1014", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1015", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1016", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1017", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1018", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1019", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x101A", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x101B", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x101C", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x101D", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway pass, univers pass, library", + "company": "Emcard a.s.", + "mad": "0x101E", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x101F", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1020", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1021", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1022", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1023", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1024", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1025", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1026", + "service_provider": "Zeleznicna Spolocnost", + "system_integrator": "Prosoft SPDL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1027", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft SPOL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1028", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft SPOL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1029", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft SPOL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x102A", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft SPOL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x102B", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft SPOL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x102C", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft SPOL" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x102D", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x102E", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x102F", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1030", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1031", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft" + }, + { + "application": "Railway services", + "company": "Prosoft Zilina", + "mad": "0x1032", + "service_provider": "Zeleznicna", + "system_integrator": "Prosoft" + }, + { + "application": "Railway services, fare collection", + "company": "ODP-software s.r.o.", + "mad": "0x1033", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Railway services, fare collection", + "company": "ODP-software s.r.o.", + "mad": "0x1034", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Ticketing and reservation for Egyptian Railways", + "company": "ENR Egyptian National Railways", + "mad": "0x1035", + "service_provider": "ENR Egyptian National Railways", + "system_integrator": "TransIT- Transportation Information Technology system, Elsag Datamat" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1103", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1104", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Transport ticketing", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1105", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Transport ticketing", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1106", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Transport ticketing", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1107", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Miscellaneous applications", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1108", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Miscellaneous applications", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1109", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Miscellaneous applications", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x110A", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Digital registration of attendance of persons", + "company": "Simac QUADCORE", + "mad": "0x110B", + "service_provider": "Simac QUADCORE B.V.", + "system_integrator": "Simac QUADCORE B.V." + }, + { + "application": "Transport ticketing", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1201", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Transport ticketing", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1202", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Transport ticketing", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x1203", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "ACS - Almex Card Scheme", + "company": "Höft & Wessel AG", + "mad": "0x1204", + "service_provider": "", + "system_integrator": "Höft & Wessel AG" + }, + { + "application": "Public transport ticket", + "company": "MENNICA POLSKA s.a.", + "mad": "0x1205", + "service_provider": "MPK LODZ", + "system_integrator": "MENNICA POLSKA s.a." + }, + { + "application": "Transport ticketing", + "company": "OREDO s.r.o", + "mad": "0x1206", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Transport ticketing", + "company": "OREDO s.r.o", + "mad": "0x1207", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Transport ticketing", + "company": "OREDO s.r.o", + "mad": "0x1208", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Transport ticketing", + "company": "Ústecky kraj", + "mad": "0x1209", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Transport ticketing", + "company": "Ústecky kraj", + "mad": "0x120A", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Transport ticketing", + "company": "Ústecky kraj", + "mad": "0x120B", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Public Transportation System ticketing e-wallet", + "company": "Ministry of Justice of Georgia", + "mad": "0x120C", + "service_provider": "Ministry of Justice of Georgia", + "system_integrator": "" + }, + { + "application": "Electronic tickets for public transpor", + "company": "TELMAX s.r.o.", + "mad": "0x120D", + "service_provider": "TELMAX s.r.o.", + "system_integrator": "TELMAX s.r.o." + }, + { + "application": "City transportation card for Subway, Bus & Minibus", + "company": "AzRy LLC", + "mad": "0x120E", + "service_provider": "Metro service LLC", + "system_integrator": "AzRy LLC" + }, + { + "application": "Interoperable fare management system for transport in Basque Country", + "company": "IDOM INGENIERIA Y CONSULTORIA", + "mad": "0x120F", + "service_provider": "Mugitu", + "system_integrator": "Mugitu" + }, + { + "application": "City Transport (Metro ticketing, bus ticket)", + "company": "VFJ Technology Pty Ltd", + "mad": "0x1801", + "service_provider": "VFJ Electronic Pty Ltd.", + "system_integrator": "Cubic - VFJ" + }, + { + "application": "Public transport fare collection", + "company": "Buscom Oy", + "mad": "0x1802", + "service_provider": "City of Vaasa", + "system_integrator": "Buscom" + }, + { + "application": "Busticketing System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x1803", + "service_provider": "King Man County Public Traffic", + "system_integrator": "Barouh Electronic Co." + }, + { + "application": "Payment for transit by metro", + "company": "Moscow Metro", + "mad": "0x1808", + "service_provider": "Moscow Metro", + "system_integrator": "Express Card" + }, + { + "application": "Transit/public transport", + "company": "Rosan Finance", + "mad": "0x1809", + "service_provider": "Moscow street public transport org.", + "system_integrator": "Rosan Finance" + }, + { + "application": "Multiapplication car for industry & trafic, parking, swimming pool", + "company": "ASEC S.A.", + "mad": "0x180A", + "service_provider": "ASEC S.A", + "system_integrator": "ASEC S.A" + }, + { + "application": "Miscellaneous application, city traffic, access control & security, entertainment, car parking, electronic trade", + "company": "KFAP S.A.", + "mad": "0x180B", + "service_provider": "KFPA", + "system_integrator": "KFPA" + }, + { + "application": "Electronic purse, city traffic", + "company": "Plzeňské MÄ›stské Dopravní Podniky A.S.", + "mad": "0x180C", + "service_provider": "Plzenske Mestske", + "system_integrator": "Plzenske Mestske" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x180D", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x180E", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x180F", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1810", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1811", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1812", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1813", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1814", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1815", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1816", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1817", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1818", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x1819", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Subway payment system", + "company": "LOT Ltd", + "mad": "0x181A", + "service_provider": "LOT", + "system_integrator": "LOT" + }, + { + "application": "Subway payment system", + "company": "LOT Ltd", + "mad": "0x181B", + "service_provider": "LOT", + "system_integrator": "LOT" + }, + { + "application": "City traffic, electronic purse, micellaneous applications", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x181C", + "service_provider": "Koordinator", + "system_integrator": "PVT" + }, + { + "application": "City traffic, electronic purse, micellaneous applications", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x181D", + "service_provider": "Koordinator", + "system_integrator": "PVT" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0x181F", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "Electronic purse, car-parking system, single use ticket, period pass", + "company": "Emcard a.s.", + "mad": "0x1820", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Electronic purse, car-parking system, single use ticket, period pass", + "company": "Emcard a.s.", + "mad": "0x1821", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Liberec City Card - Public transport application", + "company": "Liberecká IS, a.s.", + "mad": "0x1822", + "service_provider": "Liberecká IS, a.s.", + "system_integrator": "Accenture Central Europe" + }, + { + "application": "Season ticket", + "company": "DOPRAVNI PODNIK mest Mostu a Litvinova, a.s.", + "mad": "0x1823", + "service_provider": "Dopravni Pdnik mest Mostu a Litvinova, a.s.", + "system_integrator": "Mikroelectronika, spol. sr. o., Kpt. Poplera 55, 565 01 Vysoké Mýto, CZ" + }, + { + "application": "Check in/out application", + "company": "DOPRAVNI PODNIK mest Mostu a Litvinova, a.s.", + "mad": "0x1824", + "service_provider": "Dopravni Podnik mest Mostu a Litvinova, a.s.", + "system_integrator": "Mikroelektronika, spol. sr.o., Kpt. Poplera 55, 565 01 Vysoké Mýto, CZ" + }, + { + "application": "Car Parking, Electronic Purse", + "company": "Haguess s.r.o.", + "mad": "0x1825", + "service_provider": "Haguess, s.r.o.", + "system_integrator": "Haguess, s.r.o." + }, + { + "application": "EFC-single-use ticket", + "company": "Emcard a.s.", + "mad": "0x1826", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "EFC period pass", + "company": "Emcard a.s.", + "mad": "0x1827", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Liberec City Card - Season Pass Transport Tariffs", + "company": "Liberecká IS, a.s.", + "mad": "0x1828", + "service_provider": "Liberecká IS, a.s.", + "system_integrator": "Accenture Central Europe" + }, + { + "application": "Liberec City Card - Pre-pay Transport Tariffs", + "company": "Liberecká IS, a.s.", + "mad": "0x1829", + "service_provider": "Liberecká IS, a.s.", + "system_integrator": "Accenture Central Europe" + }, + { + "application": "Electronic purse, city traffic, customer profile, service applic, check-in/out applic", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x182A", + "service_provider": "Mikroelektronika", + "system_integrator": "Mikroelektronika" + }, + { + "application": "Prepaid ticket", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x182B", + "service_provider": "S.C. TRANSPORT PUBLICS A., Bacau, Romania", + "system_integrator": "MIKROELEKTRONIKA spol. s.r.i." + }, + { + "application": "Credit 2S", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x182C", + "service_provider": "Transmetro Guatemala", + "system_integrator": "SIEMENS Itron Business Services S.A. - Cordoba, Republica Argentina" + }, + { + "application": "Prepaid coupon 1S", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x182D", + "service_provider": "Transmetro Guatemala", + "system_integrator": "SIEMENS Itron Business services S.A. - Cordoba, Rep. Argentina" + }, + { + "application": "Prepaid ticket", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x182E", + "service_provider": "Panturist d.d., Croatia", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o., Vysoke Myto, Czech Republic" + }, + { + "application": "Prepaid coupon", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x182F", + "service_provider": "Mikroelektronika spol.s r.o.", + "system_integrator": "Mikroelektronika spol.s r.o." + }, + { + "application": "City traffic", + "company": "MENNICA POLSKA S.A.", + "mad": "0x1830", + "service_provider": "MENNICA POLSKA S.A.", + "system_integrator": "MENNICA POLSKA S.A." + }, + { + "application": "City traffic", + "company": "MENNICA POLSKA S.A.", + "mad": "0x1831", + "service_provider": "MENNICA POLSKA S.A.", + "system_integrator": "MENNICA POLSKA S.A." + }, + { + "application": "Prepaid coupon", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x1832", + "service_provider": "Mikroelektronika spol.s r.o.", + "system_integrator": "Mikroelektronika spol.s r.o." + }, + { + "application": "Prepaid coupon", + "company": "KORID LK, spol. s r.o", + "mad": "0x1834", + "service_provider": "KORID LK, spol.s.r.o.", + "system_integrator": "KORID LK, spol.s.r.o." + }, + { + "application": "Eticket", + "company": "KORID LK, spol. s r.o", + "mad": "0x1835", + "service_provider": "KORID LK, spol.s.r.o.", + "system_integrator": "KORID LK, spol.s.r.o." + }, + { + "application": "Prepaid coupon 1S", + "company": "Mikroelektronika GmbH", + "mad": "0x1836", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o., Draby 849, Vysoke Myto 56601, Czech Republic", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o., Draby 849, Vysoke Myto 56601, Czech Republic" + }, + { + "application": "Prepaid coupon", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x1837", + "service_provider": "ZAGREBACKI Holding d.o.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Prepaid coupon", + "company": "Mikroelektronika GmbH", + "mad": "0x1838", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Prepaid coupon", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x1839", + "service_provider": "Mikroelektronika spol.s r.o", + "system_integrator": "Mikroelektronika spol.s r.o" + }, + { + "application": "City traffic services - ticket control, city card for Polish municipal services", + "company": "Unicard S.A.", + "mad": "0x183B", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "City traffic services - ticket control, city card for Polish municipal services", + "company": "Unicard S.A.", + "mad": "0x183C", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "City traffic services - ticket control, city card for Polish municipal services", + "company": "Unicard S.A.", + "mad": "0x183D", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "City traffic services - ticket control, city card for Polish municipal services", + "company": "Unicard S.A.", + "mad": "0x183E", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Public transportation", + "company": "OY MATKAHUOLTO AB", + "mad": "0x183F", + "service_provider": "OY MATKAHUOLTO AB", + "system_integrator": "OY MATKAHUOLTO AB" + }, + { + "application": "Public transportation", + "company": "OY MATKAHUOLTO AB", + "mad": "0x1840", + "service_provider": "OY MATKAHUOLTO AB", + "system_integrator": "OY MATKAHUOLTO AB" + }, + { + "application": "City traffic, prepaid ticket, check in/out", + "company": "ODP-software s.r.o.", + "mad": "0x1841", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "City traffic, prepaid ticket, check in/out", + "company": "ODP-software s.r.o.", + "mad": "0x1842", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Car authentication for telematics", + "company": "NXP Semiconductors", + "mad": "0x1843", + "service_provider": "NXP Semiconductors", + "system_integrator": "NXP Semiconductors" + }, + { + "application": "Public transport ticketing services", + "company": "Netlock Ltd", + "mad": "0x1844", + "service_provider": "Netlock Kft.", + "system_integrator": "Netlock Kft." + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1903", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services", + "company": "Czech Railways", + "mad": "0x1904", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Bus fare collection", + "company": "Ascom Monétel", + "mad": "0x2001", + "service_provider": "C.T.A.V.", + "system_integrator": "Monétel S.A." + }, + { + "application": "Bus fare collection", + "company": "Ascom Monétel", + "mad": "0x2002", + "service_provider": "Conseil Général du TARN", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus service, ÖPNV", + "company": "Scheidt & Bachmann", + "mad": "0x2003", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Bus service, ÖPNV", + "company": "Scheidt & Bachmann", + "mad": "0x2004", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2005", + "service_provider": "Forbus Intercity", + "system_integrator": "Ascom Monétel S.A." + }, + { + "application": "Public transport", + "company": "Scan Coin AB", + "mad": "0x2006", + "service_provider": "Scan Coin AB", + "system_integrator": "" + }, + { + "application": "Ticketing system for public transport in Sweden, used primarily on buses", + "company": "CPT Nordic AB", + "mad": "0x2007", + "service_provider": "Country traffic in Sweden", + "system_integrator": "CPI Nordic AB" + }, + { + "application": "Bus Fare collection", + "company": "Ascom Monétel", + "mad": "0x2008", + "service_provider": "Setrans P", + "system_integrator": "As om Monetél SA" + }, + { + "application": "Automatic Fare Collection city and intercity bus traffic electronic purse", + "company": "Trgovina in Informatika d.o.o.", + "mad": "0x2009", + "service_provider": "Fourth Way - Alpetour", + "system_integrator": "Fourth Way" + }, + { + "application": "", + "company": "Reserved for MAD", + "mad": "0x200A", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Transport Ticketing, E-Purse, Citycard", + "company": "CJS Consultancy Ltd", + "mad": "0x200B", + "service_provider": "", + "system_integrator": "Transmo Citycard Ltd." + }, + { + "application": "Bus fare collection", + "company": "Ascom Monétel", + "mad": "0x200C", + "service_provider": "Maybus", + "system_integrator": "Ascom Monetel" + }, + { + "application": "Bus services with extension to rail and taxi", + "company": "Questek Marketing", + "mad": "0x200D", + "service_provider": "Questek Marketing", + "system_integrator": "Questek Marketing" + }, + { + "application": "Bus fare colection", + "company": "Ascom Monétel", + "mad": "0x200E", + "service_provider": "Oestfold", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x200F", + "service_provider": "SATAR", + "system_integrator": "Ascom Monetel S.A." + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2010", + "service_provider": "Atam Arezzo", + "system_integrator": "Ascom Monetel - SA" + }, + { + "application": "Collect fare system for transit authority", + "company": "Soprin ADS", + "mad": "0x2011", + "service_provider": "Soprin ADS - Ascom Monetel", + "system_integrator": "Soprin ADS" + }, + { + "application": "Busticketing System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x2012", + "service_provider": "King Man County Public Traffic", + "system_integrator": "Barouh Electronic Co." + }, + { + "application": "Bus, Tramway, Underground Services", + "company": "Ascom Monétel", + "mad": "0x2013", + "service_provider": "ZTM (Transport Company of Marsaw)", + "system_integrator": "Ascom Monetel (porject leader Mr. Pascal Valette)" + }, + { + "application": "Electronic transportation voucher", + "company": "GRUPO VR", + "mad": "0x2014", + "service_provider": "Grupo VR", + "system_integrator": "" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2015", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2016", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2017", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2018", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2019", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x201A", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x201B", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x201C", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x201D", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x201E", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x201F", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2020", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2021", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2022", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Electronic fee collection", + "company": "EFKON AG", + "mad": "0x2023", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Bus & tramway fare collection", + "company": "Ascom", + "mad": "0x2030", + "service_provider": "SMTU - Montpellier", + "system_integrator": "Ascom Monétel" + }, + { + "application": "City transport bus, ferry, administration", + "company": "VFJ Technology Pty Ltd", + "mad": "0x2031", + "service_provider": "VFJ Technology", + "system_integrator": "Cubic - VFJ" + }, + { + "application": "Bus fare collection", + "company": "Ascom Monétel", + "mad": "0x2032", + "service_provider": "", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus fare collection", + "company": "Ascom Monétel", + "mad": "0x2035", + "service_provider": "TCL", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2036", + "service_provider": "TCL", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x2037", + "service_provider": "Tarragone (Spain)", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x2038", + "service_provider": "Tarragone (Spain)", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x2039", + "service_provider": "Tarragone (Spain)", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x203A", + "service_provider": "Tarragone (Spain)", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x203F", + "service_provider": "Salineira Ltda", + "system_integrator": "Ascom Monetel" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2040", + "service_provider": "Ascom Monétel", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2041", + "service_provider": "Ascom Monétel", + "system_integrator": "Ascom Meonétel" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2042", + "service_provider": "Ascom Monétel", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2043", + "service_provider": "Systas", + "system_integrator": "Ascom Monétel" + }, + { + "application": "Bus Fare Collection", + "company": "Ascom Monétel", + "mad": "0x2044", + "service_provider": "Systas", + "system_integrator": "Ascom Moétel" + }, + { + "application": "Access control, time attendance, bus ticket, hotel room card, VIP card f. club", + "company": "Giga-TMS Inc", + "mad": "0x2045", + "service_provider": "Giga TMS", + "system_integrator": "Giga TMS" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x2046", + "service_provider": "Burulas", + "system_integrator": "Burulas" + }, + { + "application": "Mass Transportation Ticketing", + "company": "Omnifare", + "mad": "0x2047", + "service_provider": "MBS", + "system_integrator": "MBS" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x2048", + "service_provider": "Eskisehir", + "system_integrator": "EAS" + }, + { + "application": "Bus fare collection", + "company": "Ascom", + "mad": "0x2049", + "service_provider": "Metro Ciudad Mexico", + "system_integrator": "Ascom" + }, + { + "application": "Elec ticketing, access control, electronic purse", + "company": "Empresa 1 Sistemas de Automacao e Comercio", + "mad": "0x204D", + "service_provider": "Empresa 1", + "system_integrator": "Empresa 1" + }, + { + "application": "City card, prepaid ticket, cardholder, servicespass", + "company": "Emcard a.s.", + "mad": "0x204E", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Fidelity, student, period pass, single-use ticket", + "company": "Emcard a.s.", + "mad": "0x204F", + "service_provider": "emcard", + "system_integrator": "emtest" + }, + { + "application": "Fidelity, student, period pass, single-use ticket", + "company": "Emcard a.s.", + "mad": "0x2050", + "service_provider": "emcard", + "system_integrator": "emtest" + }, + { + "application": "Fidelity, student, period pass, single-use ticket", + "company": "Emcard a.s.", + "mad": "0x2051", + "service_provider": "emcard", + "system_integrator": "emtest" + }, + { + "application": "Fidelity, student, period pass, single-use ticket", + "company": "Emcard a.s.", + "mad": "0x2052", + "service_provider": "emcard", + "system_integrator": "emtest" + }, + { + "application": "Bus, Underground", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2053", + "service_provider": "Tisseo", + "system_integrator": "ACS" + }, + { + "application": "Bus Fare Collection", + "company": "A.C.S. SAS France", + "mad": "0x2054", + "service_provider": "ACS", + "system_integrator": "MetropolitanTransitAuthority of Harris Country" + }, + { + "application": "Public Transport Fare Collection", + "company": "Dublin Bus", + "mad": "0x2055", + "service_provider": "Dublin Bus", + "system_integrator": "Dublin Bus" + }, + { + "application": "Fidelity pass", + "company": "Emcard a.s.", + "mad": "0x2056", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Service pass", + "company": "Emcard a.s.", + "mad": "0x2057", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "EFC-single-use ticket", + "company": "Emcard a.s.", + "mad": "0x2058", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "EFC-time ticket", + "company": "Emcard a.s.", + "mad": "0x2059", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Bus Ticketing", + "company": "Krauth Technology", + "mad": "0x205A", + "service_provider": "Prof.A.Krauth Apparatebau", + "system_integrator": "Prof.A.Krauth Apparatebau" + }, + { + "application": "Transit SmartCard System, City E-purse System", + "company": "Intelligent Transaction Systems de Mexico S.A. de C.V.", + "mad": "0x205B", + "service_provider": "St. John's Transportation Commission", + "system_integrator": "Intelligent Transaction Systems de Mexico" + }, + { + "application": "Bus fare collection system", + "company": "PENTA d.o.o.", + "mad": "0x205C", + "service_provider": "PENTA", + "system_integrator": "PENTA" + }, + { + "application": "Bus fare collection system", + "company": "PENTA d.o.o.", + "mad": "0x205D", + "service_provider": "PENTA", + "system_integrator": "PENTA" + }, + { + "application": "Bus fare collection system", + "company": "PENTA d.o.o.", + "mad": "0x205E", + "service_provider": "PENTA", + "system_integrator": "PENTA" + }, + { + "application": "Bus e-ticketing system for different provinces of Iran", + "company": "Processing World Co.", + "mad": "0x205F", + "service_provider": "Processing world co.", + "system_integrator": "Processing world co." + }, + { + "application": "Bus", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2060", + "service_provider": "ACS", + "system_integrator": "ACS" + }, + { + "application": "Electronic ticket", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x2061", + "service_provider": "Mikroelektronika spol.s r.o.", + "system_integrator": "Mikroelektronika spol.s r.o." + }, + { + "application": "Electronic tiicket", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x2062", + "service_provider": "ZAGREBACKI Holding d.o.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o" + }, + { + "application": "Electronic ticket", + "company": "Mikroelektronika GmbH", + "mad": "0x2063", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "BUS", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2064", + "service_provider": "ACS", + "system_integrator": "ACS" + }, + { + "application": "Transit ridership", + "company": "FARE Logistics", + "mad": "0x2065", + "service_provider": "", + "system_integrator": "Fare Logistics" + }, + { + "application": "BUS FARE COLLECTION", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2066", + "service_provider": "BRESCIATRASPORTI", + "system_integrator": "ACS" + }, + { + "application": "Bus", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2067", + "service_provider": "ACS", + "system_integrator": "ACS" + }, + { + "application": "Electronic ticket", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x2068", + "service_provider": "Jamaica Urban Transit Company Ltd", + "system_integrator": "Mikroelektronika spol.s r.o." + }, + { + "application": "Electronic couponticket for public transport", + "company": "BULL POLSKA Sp. z o.o.", + "mad": "0x2069", + "service_provider": "BULL POLSKA", + "system_integrator": "BULL POLSKA" + }, + { + "application": "Electronic ticket for public transport", + "company": "BULL POLSKA Sp. z o.o.", + "mad": "0x206A", + "service_provider": "BULL POLSKA", + "system_integrator": "BULL POLSKA" + }, + { + "application": "Bus Rail Fare Collection", + "company": "ACS - Affiliated Computer Services", + "mad": "0x206B", + "service_provider": "DTEI", + "system_integrator": "ACS" + }, + { + "application": "Bus", + "company": "ACS - Affiliated Computer Services", + "mad": "0x206C", + "service_provider": "STO", + "system_integrator": "ACS" + }, + { + "application": "Bus services, bus fare collection", + "company": "ODP-software s.r.o.", + "mad": "0x206D", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Bus services, bus fare collection", + "company": "ODP-software s.r.o.", + "mad": "0x206E", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Automatic Fare Collection System", + "company": "ACS Solution France", + "mad": "0x206F", + "service_provider": "Briansk", + "system_integrator": "ACS" + }, + { + "application": "Bus fare collection", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2070", + "service_provider": "DOT", + "system_integrator": "ACS" + }, + { + "application": "Bus", + "company": "Xerox", + "mad": "0x2071", + "service_provider": "SEMITAN", + "system_integrator": "TAN" + }, + { + "application": "Card Touch Smart Card Applications", + "company": "Touch Technology International Inc.", + "mad": "0x2101", + "service_provider": "Touch Technology International", + "system_integrator": "Touch Technology International" + }, + { + "application": "Transport Ticketing", + "company": "Ascom", + "mad": "0x2102", + "service_provider": "SBME Milano", + "system_integrator": "A.I.I." + }, + { + "application": "Multi-Modal Transit", + "company": "ERG Transit Systems", + "mad": "0x2103", + "service_provider": "ERG Transit Systems", + "system_integrator": "ERG Transit Systems" + }, + { + "application": "Multi-Modal Transit", + "company": "ERG Transit Systems", + "mad": "0x2104", + "service_provider": "ERG Transit Systems", + "system_integrator": "ERG Transit Systems" + }, + { + "application": "Mass Transportation Ticketing", + "company": "Omnifare", + "mad": "0x2108", + "service_provider": "MBS", + "system_integrator": "MBS" + }, + { + "application": "Pre-paid bus card, passanger ID bus card", + "company": "Intelligent Transaction Systems de Mexico S.A. de C.V.", + "mad": "0x2109", + "service_provider": "Intelligent Transaction", + "system_integrator": "Intelligent Transcation" + }, + { + "application": "Pre-paid bus card, passanger ID bus card", + "company": "Intelligent Transaction Systems de Mexico S.A. de C.V.", + "mad": "0x210A", + "service_provider": "Intelligent Transaction", + "system_integrator": "Intelligent Transcation" + }, + { + "application": "Pre-paid bus card, passanger ID bus card", + "company": "Intelligent Transaction Systems de Mexico S.A. de C.V.", + "mad": "0x210B", + "service_provider": "Intelligent Transaction", + "system_integrator": "Intelligent Transcation" + }, + { + "application": "City card, prepaid ticket, cardholder, servicespass", + "company": "Emcard a.s.", + "mad": "0x210C", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "City card, prepaid ticket, cardholder, servicespass", + "company": "Emcard a.s.", + "mad": "0x210D", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Integrated multi-modal transport ticketing system", + "company": "Keane Australia PTY Limited", + "mad": "0x210F", + "service_provider": "TTA", + "system_integrator": "KAMCO" + }, + { + "application": "Integrated multi-modal transport ticketing system", + "company": "Keane Australia PTY Limited", + "mad": "0x2110", + "service_provider": "TTA", + "system_integrator": "KAMCO" + }, + { + "application": "Card holder", + "company": "Emcard a.s.", + "mad": "0x2111", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Prepaid ticket", + "company": "Emcard a.s.", + "mad": "0x2112", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Electronic purse, city traffic, customer profile, service applic, check-in/out applic", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x2113", + "service_provider": "Mikroelektronika", + "system_integrator": "Mikroelektronika" + }, + { + "application": "Electronic ticketing for city of Friedrichshafen", + "company": "T-Systems GEI GmbH", + "mad": "0x2114", + "service_provider": "T-Systems GEI", + "system_integrator": "T-Systems GEI" + }, + { + "application": "Transportation ticket", + "company": "Haguess s.r.o.", + "mad": "0x2115", + "service_provider": "HAGUESS, a.s.", + "system_integrator": "HAGUESS, a.s" + }, + { + "application": "Bus and rail fare collection", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2116", + "service_provider": "GCRTA", + "system_integrator": "ACS" + }, + { + "application": "Prepaid coupon - prepaid ticket for multimodal transport", + "company": "CSAD SVT Praha", + "mad": "0x2117", + "service_provider": "", + "system_integrator": "Mikroelektronika, EMTEST" + }, + { + "application": "Epurse - electronic purse intended for payment of fare in multimodal public transport", + "company": "CSAD SVT Praha", + "mad": "0x2118", + "service_provider": "", + "system_integrator": "Mikroelektronika, EMTEST" + }, + { + "application": "Automatic fare payment system for multi-modal transit", + "company": "Cubic Corporation", + "mad": "0x2119", + "service_provider": "", + "system_integrator": "Cubic Transportation Systems" + }, + { + "application": "Public transport smartcard integrated ticketing scheme for the Republic of Ireland", + "company": "Railway Procurement Agency", + "mad": "0x211A", + "service_provider": "Dublin Bus, Irish Rail, Bus Eireann, private-bus-operators", + "system_integrator": "RPA" + }, + { + "application": "General Ticketing Solution for Mas Transit", + "company": "Parkeon", + "mad": "0x211B", + "service_provider": "PARKEON", + "system_integrator": "PARKEON" + }, + { + "application": "General Ticketing Solution for Mas Transit", + "company": "Parkeon", + "mad": "0x211C", + "service_provider": "PARKEON", + "system_integrator": "PARKEON" + }, + { + "application": "Multi-modal Transit", + "company": "Västra Götalandsregionen", + "mad": "0x211D", + "service_provider": "Västtrafik AB", + "system_integrator": "Vix ERG" + }, + { + "application": "Transport application", + "company": "Unicard Limited UK", + "mad": "0x211E", + "service_provider": "Unicard Limited", + "system_integrator": "Unicard Limited" + }, + { + "application": "Transit fare collection, transit purse, transit ID", + "company": "GFI Genfare", + "mad": "0x211F", + "service_provider": "", + "system_integrator": "GFI Genfare, an SPX Division" + }, + { + "application": "Transit fare collection, transit purse, transit ID", + "company": "GFI Genfare", + "mad": "0x2120", + "service_provider": "", + "system_integrator": "GFI Genfare, an SPX Division" + }, + { + "application": "Transit fare collection, transit purse, transit ID", + "company": "GFI Genfare", + "mad": "0x2121", + "service_provider": "", + "system_integrator": "GFI Genfare, an SPX Division" + }, + { + "application": "Bus and rail fare collection", + "company": "ACS - Affiliated Computer Services", + "mad": "0x2122", + "service_provider": "RTD", + "system_integrator": "ACS" + }, + { + "application": "Bus services with extension to rail and taxi", + "company": "Questek Marketing", + "mad": "0x2801", + "service_provider": "Questek Marketing", + "system_integrator": "Questek Marketing" + }, + { + "application": "Mass Transportation Ticketing", + "company": "Omnifare", + "mad": "0x2803", + "service_provider": "MBS", + "system_integrator": "MBS" + }, + { + "application": "Tollway system", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3001", + "service_provider": "VFJ Technology Pty Ltd", + "system_integrator": "Chendu Shuguang Optical Fibre Network (Ltd. China)" + }, + { + "application": "Tollway system", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3002", + "service_provider": "VFJ Technology Pty Ltd", + "system_integrator": "Chendu Shuguang Optical Fibre Network (Ltd. China)" + }, + { + "application": "Toll collection", + "company": "Philips Projects", + "mad": "0x3003", + "service_provider": "Concepa (Concecionaria da Rodovia Oso Rio - Porto Alegre)", + "system_integrator": "Philips Projects Brazil" + }, + { + "application": "Toll collection", + "company": "Philips Projects", + "mad": "0x3004", + "service_provider": "Concepa (Concecionaria da Rodovia Oso Rio - Porto Alegre)", + "system_integrator": "Philips Projects Brazil" + }, + { + "application": "Toll collection", + "company": "Philips Projects", + "mad": "0x3005", + "service_provider": "Concepa (Concecionaria da Rodovia Oso Rio - Porto Alegre)", + "system_integrator": "Philips Projects Brazil" + }, + { + "application": "Toll collection", + "company": "Philips Projects", + "mad": "0x3006", + "service_provider": "Concepa (Concecionaria da Rodovia Oso Rio - Porto Alegre)", + "system_integrator": "Philips Projects Brazil" + }, + { + "application": "Toll collection", + "company": "Philips Projects", + "mad": "0x3007", + "service_provider": "Concepa (Concecionaria da Rodovia Oso Rio - Porto Alegre)", + "system_integrator": "Philips Projects Brazil" + }, + { + "application": "Road Tolling Application", + "company": "EFKON AG", + "mad": "0x3008", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Tolling Application", + "company": "EFKON AG", + "mad": "0x3009", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Tolling Application", + "company": "EFKON AG", + "mad": "0x300A", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Tolling Application", + "company": "EFKON AG", + "mad": "0x300B", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Tolling Application", + "company": "EFKON AG", + "mad": "0x300C", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Tolling Application", + "company": "EFKON AG", + "mad": "0x300D", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road toll application", + "company": "EFKON AG", + "mad": "0x300E", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x300F", + "service_provider": "VFJ HK", + "system_integrator": "" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3010", + "service_provider": "Xiamto Lintong Tollway", + "system_integrator": "" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3011", + "service_provider": "Xiamto Lintong Tollway", + "system_integrator": "" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3012", + "service_provider": "Xiamto Lintong Tollway", + "system_integrator": "" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3013", + "service_provider": "Xiamto Lintong Tollway", + "system_integrator": "" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3014", + "service_provider": "Austream", + "system_integrator": "Austream" + }, + { + "application": "Road toll application", + "company": "EFKON AG", + "mad": "0x3015", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll application", + "company": "EFKON AG", + "mad": "0x3016", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll application", + "company": "EFKON AG", + "mad": "0x3017", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll application", + "company": "EFKON AG", + "mad": "0x3018", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll application", + "company": "EFKON AG", + "mad": "0x3019", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll application", + "company": "EFKON AG", + "mad": "0x301A", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x301B", + "service_provider": "Efkon", + "system_integrator": "Philips Projects" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x301C", + "service_provider": "Efkon", + "system_integrator": "Philips Projects" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x301D", + "service_provider": "Efkon", + "system_integrator": "Philips Projects" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x301E", + "service_provider": "Efkon", + "system_integrator": "Philips Projects" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x301F", + "service_provider": "Efkon", + "system_integrator": "Philips Projects" + }, + { + "application": "Weighbridge for trucks", + "company": "VFJ Technology Pty Ltd", + "mad": "0x3020", + "service_provider": "Hardware Systems Sales", + "system_integrator": "" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3021", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3022", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3023", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3024", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3025", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3026", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3027", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x3028", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x3029", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x302A", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x302B", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x302C", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x302D", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x302E", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x302F", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3030", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road toll", + "company": "EFKON AG", + "mad": "0x3031", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3032", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3033", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3034", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3035", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3036", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3037", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3038", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x3039", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x303A", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x303B", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road Toll Application", + "company": "EFKON AG", + "mad": "0x303C", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Road Toll Application", + "company": "Compsis Comp. Sist. Ind. Com. LTDA", + "mad": "0x303E", + "service_provider": "Compsis", + "system_integrator": "Compsis" + }, + { + "application": "Road Toll Application", + "company": "Compsis Comp. Sist. Ind. Com. LTDA", + "mad": "0x303F", + "service_provider": "Compsis", + "system_integrator": "Compsis" + }, + { + "application": "Road Toll Application", + "company": "Compsis Comp. Sist. Ind. Com. LTDA", + "mad": "0x3040", + "service_provider": "Compsis", + "system_integrator": "Compsis" + }, + { + "application": "Road Toll Application", + "company": "Compsis Comp. Sist. Ind. Com. LTDA", + "mad": "0x3041", + "service_provider": "Compsis", + "system_integrator": "Compsis" + }, + { + "application": "Road Toll Application", + "company": "Compsis Comp. Sist. Ind. Com. LTDA", + "mad": "0x3042", + "service_provider": "Compsis", + "system_integrator": "Compsis" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x3043", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x3046", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Road Toll", + "company": "EFKON AG", + "mad": "0x3047", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Toll payment", + "company": "GPS Tecnologia Ltda.", + "mad": "0x3048", + "service_provider": "GPS", + "system_integrator": "GPS" + }, + { + "application": "Electronic toll collection", + "company": "Cetrta Pot d.o.o.", + "mad": "0x3049", + "service_provider": "Dars d.d.", + "system_integrator": "Cetrta POT d.o.o." + }, + { + "application": "Road toll", + "company": "Diners Club Adriatic d.d.", + "mad": "0x305A", + "service_provider": "Diners Club", + "system_integrator": "Diners Club" + }, + { + "application": "Road toll", + "company": "Diners Club Adriatic d.d.", + "mad": "0x305B", + "service_provider": "Diners Club", + "system_integrator": "Diners Club" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3102", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3103", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3104", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3105", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3106", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3107", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3108", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x3109", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x310A", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Intelligent Transport Services", + "company": "EFKON AG", + "mad": "0x310B", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Stored value card payment system", + "company": "GiroVend Cashless Systems PLC", + "mad": "0x3801", + "service_provider": "GiroVend", + "system_integrator": "GiroVend" + }, + { + "application": "Card Administratin, cardholder adminstration, access control & security, company services, miscellaneous applications", + "company": "Ministry of Defense", + "mad": "0x3802", + "service_provider": "Ministry of Defence", + "system_integrator": "" + }, + { + "application": "Company Payment System, Company Facility Services, Company Identification Services", + "company": "Maas Systems B.V.", + "mad": "0x3803", + "service_provider": "Maas Systems B.V.", + "system_integrator": "Mass Systems B.V." + }, + { + "application": "Company Payment System, Company Facility Services, Company Identification Services", + "company": "Maas Systems B.V.", + "mad": "0x3804", + "service_provider": "Maas Systems B.V.", + "system_integrator": "Mass Systems B.V." + }, + { + "application": "Company Payment System, Company Facility Services, Company Identification Services", + "company": "Maas Systems B.V.", + "mad": "0x3805", + "service_provider": "Maas Systems B.V.", + "system_integrator": "Mass Systems B.V." + }, + { + "application": "Access control, company service", + "company": "Automaten Seitz GmbH", + "mad": "0x3807", + "service_provider": "Automaten Seitz", + "system_integrator": "Automaten Seitz" + }, + { + "application": "Access controll security payment", + "company": "Matsushita Communication Industrial", + "mad": "0x3808", + "service_provider": "Matsushita Communication", + "system_integrator": "Matsushita Communication" + }, + { + "application": "Multi functional badge, private application", + "company": "Microtronic AG", + "mad": "0x3809", + "service_provider": "Microtronic AG", + "system_integrator": "Microtronic AG" + }, + { + "application": "", + "company": "InterCard GmbH Kartensysteme", + "mad": "0x380A", + "service_provider": "Inter Card GmbH", + "system_integrator": "Inter Card GmbH" + }, + { + "application": "", + "company": "InterCard GmbH Kartensysteme", + "mad": "0x380B", + "service_provider": "Inter Card GmbH", + "system_integrator": "Inter Card GmbH" + }, + { + "application": "", + "company": "InterCard GmbH Kartensysteme", + "mad": "0x380C", + "service_provider": "Inter Card GmbH", + "system_integrator": "Inter Card GmbH" + }, + { + "application": "Identification service", + "company": "Pink Roccade", + "mad": "0x380D", + "service_provider": "Pink Roccade", + "system_integrator": "Pink Roccade" + }, + { + "application": "Multiapplication car for industry & trafic, parking, swimming pool", + "company": "ASEC S.A.", + "mad": "0x380E", + "service_provider": "ASEC S.A", + "system_integrator": "ASEC S.A" + }, + { + "application": "Payment and registration system", + "company": "Magna Carta B.U.", + "mad": "0x380F", + "service_provider": "Magna Carta", + "system_integrator": "Magna Carta" + }, + { + "application": "Identification service", + "company": "Pink Roccade", + "mad": "0x3810", + "service_provider": "Pink Roccade", + "system_integrator": "Pink Roccade" + }, + { + "application": "Company Facility Service", + "company": "Deister Electronic", + "mad": "0x3811", + "service_provider": "Deister Electronic GmbH", + "system_integrator": "Deister Electronic GmbH" + }, + { + "application": "Company Facility Service", + "company": "Deister Electronic", + "mad": "0x3812", + "service_provider": "Deister Electronic GmbH", + "system_integrator": "Deister Electronic GmbH" + }, + { + "application": "Multi functional badge for private application", + "company": "Microtronic AG", + "mad": "0x3813", + "service_provider": "Microtronic", + "system_integrator": "Microtronic" + }, + { + "application": "Multi functional badge for private application", + "company": "Microtronic AG", + "mad": "0x3814", + "service_provider": "Microtronic", + "system_integrator": "Microtronic" + }, + { + "application": "Multi functional badge for private application", + "company": "Microtronic AG", + "mad": "0x3815", + "service_provider": "Microtronic", + "system_integrator": "Microtronic" + }, + { + "application": "Multi functional badge for private application", + "company": "Microtronic AG", + "mad": "0x3816", + "service_provider": "Microtronic", + "system_integrator": "Microtronic" + }, + { + "application": "Multi functional badge for private application", + "company": "Microtronic AG", + "mad": "0x3817", + "service_provider": "Microtronic", + "system_integrator": "Microtronic" + }, + { + "application": "Multi functional badge for private application", + "company": "Microtronic AG", + "mad": "0x3818", + "service_provider": "Microtronic", + "system_integrator": "Microtronic" + }, + { + "application": "Multi functional badge for private application", + "company": "Microtronic AG", + "mad": "0x3819", + "service_provider": "Microtronic", + "system_integrator": "Microtronic" + }, + { + "application": "Cashless payment and others", + "company": "GPI GmbH", + "mad": "0x3827", + "service_provider": "GPI GmbH", + "system_integrator": "GPI GmbH" + }, + { + "application": "Company services", + "company": "Deutsche Lufthansa AG FFM", + "mad": "0x3828", + "service_provider": "Deutsche Lufthansa AG", + "system_integrator": "Deutsche Lufthansa AG" + }, + { + "application": "Access control, time management, electronic wallet", + "company": "Universitaire Ziekenhuizen Leuven", + "mad": "0x3829", + "service_provider": "", + "system_integrator": "GET NV" + }, + { + "application": "Company services", + "company": "Card3 GmbH", + "mad": "0x382A", + "service_provider": "Card3 GmbH", + "system_integrator": "Card3 GmbH" + }, + { + "application": "Computer, car parking, elec. purse, access control & security", + "company": "DECA Engineering", + "mad": "0x382B", + "service_provider": "Deca Engineering", + "system_integrator": "Deca Engineering" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0x382C", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0x382D", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0x382E", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0x382F", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0x3830", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "Road toll", + "company": "Diners Club Adriatic d.d.", + "mad": "0x3831", + "service_provider": "Diners Club", + "system_integrator": "Diners Club" + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0x3832", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Company services", + "company": "Cash Card Automaten GmbH", + "mad": "0x3833", + "service_provider": "Cash Card", + "system_integrator": "Cash Card" + }, + { + "application": "Access control, computer application, company services", + "company": "Volvo Car Corporation", + "mad": "0x3834", + "service_provider": "Volvo Car", + "system_integrator": "Volvo Car" + }, + { + "application": "Time attendnace, fuel, access control", + "company": "Emcard a.s.", + "mad": "0x3835", + "service_provider": "Emtest", + "system_integrator": "Emtest" + }, + { + "application": "Company services", + "company": "Emcard a.s.", + "mad": "0x3836", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Multiple Company Services", + "company": "Viessmann Werke GmbH & Co KG", + "mad": "0x3837", + "service_provider": "Viessmann Werke", + "system_integrator": "Viessmann Werke" + }, + { + "application": "E.purse", + "company": "GTI", + "mad": "0x3839", + "service_provider": "Mr. Eric Houri", + "system_integrator": "Mr. Francois Bodard" + }, + { + "application": "Company services", + "company": "MENNICA POLSKA S.A.", + "mad": "0x383A", + "service_provider": "MENNICA POLSKA S.A.", + "system_integrator": "MENNICA POLSKA S.A." + }, + { + "application": "Company Services", + "company": "Scheidt & Bachmann GmbH", + "mad": "0x383B", + "service_provider": "Scheidt & Bachmann GmbH", + "system_integrator": "Scheidt & Bachmann GmbH" + }, + { + "application": "", + "company": "Reac BV", + "mad": "0x383C", + "service_provider": "", + "system_integrator": "REAC" + }, + { + "application": "Follow me printing system", + "company": "N.V. EPZ", + "mad": "0x383D", + "service_provider": "EPZ", + "system_integrator": "Xerox Corporation" + }, + { + "application": "Registration of received radiation dose in nuclear power plant", + "company": "N.V. EPZ", + "mad": "0x383E", + "service_provider": "EPZ", + "system_integrator": "Mirion Technologies/MGP" + }, + { + "application": "Access control, identification", + "company": "Swedish Social Isurance Agency", + "mad": "0x383F", + "service_provider": "Swedish Social Isurance Agency", + "system_integrator": "Swedish Social Isurance Agency" + }, + { + "application": "Payment and registration", + "company": "PAYCULT GMBH", + "mad": "0x3840", + "service_provider": "PAYCULT", + "system_integrator": "PAYCULT" + }, + { + "application": "City transport bus, ferry, administration", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4001", + "service_provider": "VFJ Technology", + "system_integrator": "Cubic - VFJ" + }, + { + "application": "Transport Ticketing, E-Purse, Citycard", + "company": "CJS Consultancy Ltd", + "mad": "0x4002", + "service_provider": "", + "system_integrator": "Transmo Citycard Ltd." + }, + { + "application": "Combined application for access control, ferry and rail ticketing for the Island of Langegeoog", + "company": "Companion GmbH", + "mad": "0x4003", + "service_provider": "Companion GmbH", + "system_integrator": "Companion GmbH, Krups Consultants GmbH, Gemplus GmbH" + }, + { + "application": "User needs and preference", + "company": "University of Newcastle", + "mad": "0x4004", + "service_provider": "Distinct", + "system_integrator": "University of Newcastle" + }, + { + "application": "User needs and preference", + "company": "University of Newcastle", + "mad": "0x4005", + "service_provider": "Distinct", + "system_integrator": "University of Newcastle" + }, + { + "application": "User needs and preference", + "company": "University of Newcastle", + "mad": "0x4006", + "service_provider": "Distinct", + "system_integrator": "University of Newcastle" + }, + { + "application": "User needs and preference", + "company": "University of Newcastle", + "mad": "0x4007", + "service_provider": "Distinct", + "system_integrator": "University of Newcastle" + }, + { + "application": "User needs and preference", + "company": "University of Newcastle", + "mad": "0x4008", + "service_provider": "Distinct", + "system_integrator": "University of Newcastle" + }, + { + "application": "City card services", + "company": "Rosan Finance", + "mad": "0x4009", + "service_provider": "Retail Trade and Services in Moscow", + "system_integrator": "Express card" + }, + { + "application": "City card services", + "company": "Moscow Government Department For Retail Trade and Services", + "mad": "0x400B", + "service_provider": "Retail Trade and Service", + "system_integrator": "Express Card" + }, + { + "application": "Identification of cardholder", + "company": "Rosan Finance", + "mad": "0x400C", + "service_provider": "Retail Trade and Services", + "system_integrator": "Rosan Finance" + }, + { + "application": "Mass Transportation Ticketing", + "company": "Omnifare", + "mad": "0x400D", + "service_provider": "MBS", + "system_integrator": "MBS" + }, + { + "application": "Access control", + "company": "Connex Solutions Limited", + "mad": "0x400E", + "service_provider": "Connex", + "system_integrator": "Connex" + }, + { + "application": "Acess Control, Time and Attendance", + "company": "Milenio 3 Systemas Electonicos", + "mad": "0x400F", + "service_provider": "Milenio3", + "system_integrator": "Milenio3" + }, + { + "application": "City card services", + "company": "Axess AG", + "mad": "0x4010", + "service_provider": "Axess", + "system_integrator": "Axess" + }, + { + "application": "Provision of citizen services", + "company": "UK National Smartcard Project", + "mad": "0x4011", + "service_provider": "English Local Authorities", + "system_integrator": "" + }, + { + "application": "Provision of citizen services", + "company": "UK National Smartcard Project", + "mad": "0x4012", + "service_provider": "English Local Authorities", + "system_integrator": "" + }, + { + "application": "Provision of citizen services", + "company": "UK National Smartcard Project", + "mad": "0x4013", + "service_provider": "English Local Authorities", + "system_integrator": "" + }, + { + "application": "City card, prepaid ticket, cardholder, servicespass", + "company": "Emcard a.s.", + "mad": "0x4014", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Liberec City Car, Card manag center", + "company": "Liberecká IS, a.s.", + "mad": "0x4015", + "service_provider": "Liberecka", + "system_integrator": "Accenture Central Europe" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x4016", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x4017", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x4018", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x4019", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x401A", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x401B", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x401C", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x401D", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x401E", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City Card Services", + "company": "Centro Informatico Municipal", + "mad": "0x401F", + "service_provider": "Donostiako Udala/Ayuntamiento de San Sebastian", + "system_integrator": "Centro Informatico Municipal" + }, + { + "application": "City card", + "company": "Emcard a.s.", + "mad": "0x4020", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Programa Informatico para Fidelazcion Clientes", + "company": "LAI Sistemas Informaticos S.L.", + "mad": "0x4021", + "service_provider": "LAI Sistemas Informaticos S.L.", + "system_integrator": "Luis Maria Ortiz Gorraiz" + }, + { + "application": "Programa Informatico para Fidelazcion Clientes", + "company": "LAI Sistemas Informaticos S.L.", + "mad": "0x4022", + "service_provider": "LAI Sistemas Informaticos S.L.", + "system_integrator": "Luis Maria Ortiz Gorraiz" + }, + { + "application": "Programa Informatico para Fidelazcion Clientes", + "company": "LAI Sistemas Informaticos S.L.", + "mad": "0x4023", + "service_provider": "LAI Sistemas Informaticos S.L.", + "system_integrator": "Luis Maria Ortiz Gorraiz" + }, + { + "application": "Programa Informatico para Fidelazcion Clientes", + "company": "LAI Sistemas Informaticos S.L.", + "mad": "0x4024", + "service_provider": "LAI Sistemas Informaticos S.L.", + "system_integrator": "Luis Maria Ortiz Gorraiz" + }, + { + "application": "Programa Informatico para Fidelazcion Clientes", + "company": "LAI Sistemas Informaticos S.L.", + "mad": "0x4025", + "service_provider": "LAI Sistemas Informaticos S.L.", + "system_integrator": "Luis Maria Ortiz Gorraiz" + }, + { + "application": "City card services", + "company": "Monet+ a.s.", + "mad": "0x4026", + "service_provider": "MONET+, a.s.", + "system_integrator": "MONET+, a.s." + }, + { + "application": "Fare collection & access control", + "company": "Pusatec Oy", + "mad": "0x4027", + "service_provider": "PUSATEC", + "system_integrator": "PUSATEC" + }, + { + "application": "Security management; card management; access control", + "company": "NISCAYAH B.V.", + "mad": "0x4028", + "service_provider": "NISCAYAH", + "system_integrator": "NISCAYAH" + }, + { + "application": "Security management; card management; access control", + "company": "NISCAYAH B.V.", + "mad": "0x4029", + "service_provider": "NISCAYAH", + "system_integrator": "NISCAYAH" + }, + { + "application": "City card services", + "company": "Gantner Electronic GmbH", + "mad": "0x402A", + "service_provider": "GANTNER Electronic", + "system_integrator": "GANTNER Electronic" + }, + { + "application": "National ID Card for Bogota City", + "company": "Bogota Distrito Capital", + "mad": "0x402B", + "service_provider": "Tarjeta Ciudadana Bogota Capital - TCBC", + "system_integrator": "SMARTCHIP S.A." + }, + { + "application": "City card services", + "company": "SIT Solution for IT Payment GmbH", + "mad": "0x402C", + "service_provider": "SIT Solution for IT Payment GmbH", + "system_integrator": "SIT Solution for IT Payment GmbH" + }, + { + "application": "Access control, Time attendanc, job control", + "company": "EM Group", + "mad": "0x4701", + "service_provider": "EM Group", + "system_integrator": "EM Group" + }, + { + "application": "Access control", + "company": "One Security PTY Ltd", + "mad": "0x4702", + "service_provider": "One Security", + "system_integrator": "One Security" + }, + { + "application": "Access control & security, entertainment and sports", + "company": "Giga-TMS Inc", + "mad": "0x4703", + "service_provider": "Giga", + "system_integrator": "Giga" + }, + { + "application": "Various Access Control Applications", + "company": "Honeywell Access Systems", + "mad": "0x4707", + "service_provider": "", + "system_integrator": "HAS - Reston, VA; HAS - Oak Creek; HAS - Austin Texas" + }, + { + "application": "Various Access Control Applications", + "company": "Honeywell Access Systems", + "mad": "0x4708", + "service_provider": "", + "system_integrator": "HAS - Reston, VA; HAS - Oak Creek; HAS - Austin Texas" + }, + { + "application": "Various Access Control Applications", + "company": "Honeywell Access Systems", + "mad": "0x4709", + "service_provider": "", + "system_integrator": "HAS - Reston, VA; HAS - Oak Creek; HAS - Austin Texas" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x470A", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x470B", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x470C", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x470D", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x470E", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x470F", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4710", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4711", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4712", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4713", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4714", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4715", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4716", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4717", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4718", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4719", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x471A", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x471B", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x471C", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x471D", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x471E", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x471F", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4720", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4721", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Access Control", + "company": "IOLAN BV", + "mad": "0x4722", + "service_provider": "IOLAN BV", + "system_integrator": "IOLAN BV" + }, + { + "application": "Application COBALT access control ", + "company": "TECHNICOB", + "mad": "0x4723", + "service_provider": "TECHNICOB", + "system_integrator": "TECHNICOB" + }, + { + "application": "Access control, benefits", + "company": "Ústecky kraj", + "mad": "0x4724", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access control", + "company": "ASCOM", + "mad": "0x4725", + "service_provider": "ASCOM", + "system_integrator": "ASCOM" + }, + { + "application": "Lockers, access control and switch system integration", + "company": "ENKOA System", + "mad": "0x4726", + "service_provider": "Enkoa", + "system_integrator": "Juan Cruz Iriondo" + }, + { + "application": "Lockers, access control and switch system integration", + "company": "ENKOA System", + "mad": "0x4727", + "service_provider": "Enkoa", + "system_integrator": "Juan Cruz Iriondo" + }, + { + "application": "Lockers, access control and switch system integration", + "company": "ENKOA System", + "mad": "0x4728", + "service_provider": "Enkoa", + "system_integrator": "Juan Cruz Iriondo" + }, + { + "application": "Trade fair card Deutsche Messe AG, Hannover", + "company": "Systemform GmbH", + "mad": "0x4801", + "service_provider": "Systemform", + "system_integrator": "Systemform" + }, + { + "application": "Scheidt & Bachmann basis dutes", + "company": "Scheidt & Bachmann", + "mad": "0x4802", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Scheidt & Bachmann basis dutes", + "company": "Scheidt & Bachmann", + "mad": "0x4803", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Scheidt & Bachmann basis dutes", + "company": "Scheidt & Bachmann", + "mad": "0x4804", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Access control & security time management", + "company": "Gelma", + "mad": "0x4805", + "service_provider": "Gelma Industrieelektronik GmbH", + "system_integrator": "" + }, + { + "application": "", + "company": "Systemform GmbH", + "mad": "0x4806", + "service_provider": "Systemform", + "system_integrator": "Systemform" + }, + { + "application": "Zutritt, Zeit- u. Betriebsdatenerfassung", + "company": "Interflex Datensysteme GmbH", + "mad": "0x4807", + "service_provider": "", + "system_integrator": "Interflex Datensysteme GmbH" + }, + { + "application": "Employer indentification card", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4808", + "service_provider": "VFJ Electronics Pty Ltd.", + "system_integrator": "VFJ Electronics PTy Ltd." + }, + { + "application": "City Transport (Metro ticketing, bus ticket)", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4809", + "service_provider": "VFJ Electronic Pty Ltd.", + "system_integrator": "Cubic - VFJ" + }, + { + "application": "Access control & security", + "company": "Ing. Büro Schrick", + "mad": "0x480A", + "service_provider": "Büro Schrick", + "system_integrator": "Büro Schrick" + }, + { + "application": "Michronos Time Attendance System", + "company": "MICOS GmbH", + "mad": "0x480B", + "service_provider": "Micos GmbH", + "system_integrator": "Micos GmbH" + }, + { + "application": "Access control system", + "company": "MICOS GmbH", + "mad": "0x480C", + "service_provider": "Micos", + "system_integrator": "Micos" + }, + { + "application": "Access Controll, Security Electronic Purse, Ski-Ticketing, Ticketing", + "company": "*Siemens ANL", + "mad": "0x480D", + "service_provider": "", + "system_integrator": "Siemens AG" + }, + { + "application": "Card Administratin, cardholder adminstration, access control & security, company services, miscellaneous applications", + "company": "Ministry of Defense", + "mad": "0x480E", + "service_provider": "Ministry of Defence", + "system_integrator": "" + }, + { + "application": "Academic Services, Electronic Purse, Access control & security", + "company": "CNA Limited/Rax-Comm Systems Ltd.", + "mad": "0x480F", + "service_provider": "CNA Limited", + "system_integrator": "CNA Limited" + }, + { + "application": "Time attandence, access control + security, electronic purse, plant data collection", + "company": "LNI Ingenieurgesellschaft für Kommunikationstechnik mbH", + "mad": "0x4810", + "service_provider": "LNI GmbH", + "system_integrator": "LNI GmbH" + }, + { + "application": "Security and Access Control", + "company": "PEC (New Zealand) Ltd.", + "mad": "0x4811", + "service_provider": "Cardax", + "system_integrator": "" + }, + { + "application": "Security and Access Control", + "company": "PEC (New Zealand) Ltd.", + "mad": "0x4812", + "service_provider": "Cardax", + "system_integrator": "" + }, + { + "application": "University & Staff identification", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4813", + "service_provider": "VFJ Hong Kong", + "system_integrator": "" + }, + { + "application": "University & Staff identification", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4814", + "service_provider": "VFJ Hong Kong", + "system_integrator": "" + }, + { + "application": "University & Staff identification", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4815", + "service_provider": "VFJ Hong Kong", + "system_integrator": "" + }, + { + "application": "University & Staff identification", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4816", + "service_provider": "VFJ Hong Kong", + "system_integrator": "" + }, + { + "application": "University & Staff identification", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4817", + "service_provider": "VFJ Hong Kong", + "system_integrator": "" + }, + { + "application": "University & Staff identification", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4818", + "service_provider": "VFJ Hong Kong", + "system_integrator": "" + }, + { + "application": "University & Staff identification", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4819", + "service_provider": "VFJ Hong Kong", + "system_integrator": "" + }, + { + "application": "", + "company": "Reserved for MAD", + "mad": "0x481A", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access control/security", + "company": "VFJ Technology Pty Ltd", + "mad": "0x481B", + "service_provider": "Taiwan Microcode Co Ltd.", + "system_integrator": "Taiwan Microcode Co Ltd." + }, + { + "application": "Access control/security", + "company": "VFJ Technology Pty Ltd", + "mad": "0x481C", + "service_provider": "Taiwan Microcode Co Ltd.", + "system_integrator": "Taiwan Microcode Co Ltd." + }, + { + "application": "DEM Komponenten für Zutrittskontrolle, Zeiterfassung, Betribsdatenerfassung, Kantine, Automaten, Tankdatenerf.", + "company": "Phg Peter Hengstler GmbH", + "mad": "0x481D", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x481E", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x481F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x4820", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x4821", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x4822", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access control, time management, high security, time attendence", + "company": "Winkhaus Intras Datensysteme GmbH", + "mad": "0x4823", + "service_provider": "Winkhaus Intras Datensysteme GmbH", + "system_integrator": "Winkhaus Intras Datensysteme GmbH" + }, + { + "application": "Access control system, time & attendance system", + "company": "Custom Micro Products Ltd.", + "mad": "0x4824", + "service_provider": "Custom Micro Products Ltd", + "system_integrator": "Custom Micro Products Ltd" + }, + { + "application": "Acess Control", + "company": "CYNAPS", + "mad": "0x4825", + "service_provider": "Cynaps", + "system_integrator": "" + }, + { + "application": "Access control and time managemnet", + "company": "Primion Technology GmbH", + "mad": "0x4826", + "service_provider": "BEL Computer Systems GmbH", + "system_integrator": "BEL Computer Systems GmbH" + }, + { + "application": "Access control and time managemnet", + "company": "Primion Technology GmbH", + "mad": "0x4827", + "service_provider": "BEL Computer Systems GmbH", + "system_integrator": "BEL Computer Systems GmbH" + }, + { + "application": "Access control and time managemnet", + "company": "Primion Technology GmbH", + "mad": "0x4828", + "service_provider": "BEL Computer Systems GmbH", + "system_integrator": "BEL Computer Systems GmbH" + }, + { + "application": "Access control and time managemnet", + "company": "Primion Technology GmbH", + "mad": "0x4829", + "service_provider": "BEL Computer Systems GmbH", + "system_integrator": "BEL Computer Systems GmbH" + }, + { + "application": "Access Control, Time and Attendance, Paid parking, cards and tags", + "company": "Integrated Engineering", + "mad": "0x482A", + "service_provider": "Intesraten Engineering, IE Keyprocessor", + "system_integrator": "IE Keyprocessor" + }, + { + "application": "Access Control", + "company": "Deister Electronic", + "mad": "0x482B", + "service_provider": "Deister Electronic GmbH", + "system_integrator": "Deister Electronic GmbH" + }, + { + "application": "Zutrittskontrolle, Zeiterfassung", + "company": "ZHS Zeitmanagementsysteme GmbH", + "mad": "0x482C", + "service_provider": "", + "system_integrator": "ZHS" + }, + { + "application": "Various", + "company": "BALTECH AG", + "mad": "0x482D", + "service_provider": "PCS GmbH", + "system_integrator": "PCS GmbH, Baltech AG" + }, + { + "application": "Access Control", + "company": "Deister Electronic", + "mad": "0x482E", + "service_provider": "Deister Electronic GmbH", + "system_integrator": "Deister Electronic GmbH" + }, + { + "application": "Access Control & Time Attendence", + "company": "Gelma", + "mad": "0x482F", + "service_provider": "MBB Gelma Industrieelektronik GmbH", + "system_integrator": "MBB Gelma" + }, + { + "application": "Building Management System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x4830", + "service_provider": "VFJ Hong Kong", + "system_integrator": "VFJ Hong Kong" + }, + { + "application": "Combined application for access control, ferry and rail ticketing for the Island of Langegeoog", + "company": "Companion GmbH", + "mad": "0x4831", + "service_provider": "Companion GmbH", + "system_integrator": "Companion GmbH, Krups Consultants GmbH, Gemplus GmbH" + }, + { + "application": "Access control & Security", + "company": "MADA Marx Datentechnik GmbH", + "mad": "0x4832", + "service_provider": "MADA", + "system_integrator": "MADA" + }, + { + "application": "Access Control, time attendance", + "company": "Saubermacher Dienstleistungs GmbH", + "mad": "0x4833", + "service_provider": "AZS Technology AG", + "system_integrator": "AZS Technology AG" + }, + { + "application": "Access control", + "company": "Deister Electronic", + "mad": "0x4834", + "service_provider": "deister electronic GmbH", + "system_integrator": "deister electronic GmbH" + }, + { + "application": "Access control", + "company": "Deister Electronic", + "mad": "0x4835", + "service_provider": "deister electronic GmbH", + "system_integrator": "deister electronic GmbH" + }, + { + "application": "Access control", + "company": "Deister Electronic", + "mad": "0x4836", + "service_provider": "deister electronic GmbH", + "system_integrator": "deister electronic GmbH" + }, + { + "application": "Access control, time & attendance systems", + "company": "Cotag International", + "mad": "0x4837", + "service_provider": "Bewator Cotag Ltd", + "system_integrator": "Bewator Cotag Ltd" + }, + { + "application": "XSkey providing secure access in Rottermdam harbour", + "company": "Secure Logistics", + "mad": "0x4838", + "service_provider": "Secure Logistics", + "system_integrator": "Secure Logistics" + }, + { + "application": "Access control, time attendance, bus ticket, hotel room card, VIP card f. club", + "company": "Giga-TMS Inc", + "mad": "0x4839", + "service_provider": "Giga TMS", + "system_integrator": "Giga TMS" + }, + { + "application": "Access contr, time & attendance, multifunc card", + "company": "Horoquartz Gestion des Temps", + "mad": "0x4840", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "Access controll", + "company": "GRUPO VR", + "mad": "0x4841", + "service_provider": "Grupo VR", + "system_integrator": "" + }, + { + "application": "Access control & security", + "company": "Tyco Integrated Systems B.V.", + "mad": "0x4842", + "service_provider": "Tyco Integrated Systems", + "system_integrator": "Tyco Integrated Systems" + }, + { + "application": "Access controll & security", + "company": "Hi Sec International A/S", + "mad": "0x4843", + "service_provider": "", + "system_integrator": "Hi Sec International A/S" + }, + { + "application": "Access Control, Time & Attendance, E-Purse", + "company": "BALTECH AG", + "mad": "0x4844", + "service_provider": "Baltech", + "system_integrator": "Baltech" + }, + { + "application": "Access Control, Time & Attendance, E-Purse", + "company": "BALTECH AG", + "mad": "0x4845", + "service_provider": "Baltech", + "system_integrator": "Baltech" + }, + { + "application": "Access Control, Time & Attendance, E-Purse", + "company": "BALTECH AG", + "mad": "0x4846", + "service_provider": "Baltech", + "system_integrator": "Baltech" + }, + { + "application": "Access Control, Time & Attendance, E-Purse", + "company": "BALTECH AG", + "mad": "0x4847", + "service_provider": "Baltech", + "system_integrator": "Baltech" + }, + { + "application": "Access Control, Time & Attendance, E-Purse", + "company": "BALTECH AG", + "mad": "0x4848", + "service_provider": "Baltech", + "system_integrator": "Baltech" + }, + { + "application": "Access Control, Time & Attendance, E-Purse", + "company": "BALTECH AG", + "mad": "0x4849", + "service_provider": "Baltech", + "system_integrator": "Baltech" + }, + { + "application": "Access control, payment system", + "company": "Maas Systems B.V.", + "mad": "0x484A", + "service_provider": "Maas Systems B.V.", + "system_integrator": "Maas Systems B.V." + }, + { + "application": "Access control & security", + "company": "BOSCH Telecom GmbH", + "mad": "0x484B", + "service_provider": "Bosch Telecom", + "system_integrator": "Bosch Telecom" + }, + { + "application": "Biometric - access controll & security", + "company": "BOSCH Telecom GmbH", + "mad": "0x484C", + "service_provider": "Bosch Telecom", + "system_integrator": "Bosch Telecom" + }, + { + "application": "Access Control", + "company": "HID Global", + "mad": "0x484D", + "service_provider": "HID Corporation", + "system_integrator": "HID Corporation" + }, + { + "application": "Access Control", + "company": "HID Global", + "mad": "0x484E", + "service_provider": "HID Corporation", + "system_integrator": "HID Corporation" + }, + { + "application": "Access control & security", + "company": "AIE Etudes", + "mad": "0x484F", + "service_provider": "AIE - ID", + "system_integrator": "AIE Etudes" + }, + { + "application": "Access control & security", + "company": "AIE Etudes", + "mad": "0x4850", + "service_provider": "AIE - ID", + "system_integrator": "AIE Etudes" + }, + { + "application": "Access control, company service", + "company": "Automaten Seitz GmbH", + "mad": "0x4851", + "service_provider": "Automaten Seitz", + "system_integrator": "Automaten Seitz" + }, + { + "application": "Access control and securitiy", + "company": "Hitachi Information Technology Co. Ltd.", + "mad": "0x4852", + "service_provider": "Hitachi Information", + "system_integrator": "Hitachi Information" + }, + { + "application": "Access control", + "company": "Petroleos Mexicanos", + "mad": "0x4853", + "service_provider": "Intraproc de Mexico", + "system_integrator": "" + }, + { + "application": "Access controll security payment", + "company": "Matsushita Communication Industrial", + "mad": "0x4854", + "service_provider": "Matsushita Communication", + "system_integrator": "Matsushita Communication" + }, + { + "application": "Storing Resident Info Access Control", + "company": "ITE Smartcard Solutions Limited", + "mad": "0x4855", + "service_provider": "ITE Smartcard", + "system_integrator": "ITE Smartcard" + }, + { + "application": "Storing Resident Info Access Control", + "company": "ITE Smartcard Solutions Limited", + "mad": "0x4856", + "service_provider": "ITE Smartcard", + "system_integrator": "ITE Smartcard" + }, + { + "application": "Access control biometric reader", + "company": "Precise Biometrics AB", + "mad": "0x4857", + "service_provider": "Precise Biometrics AB", + "system_integrator": "Precise Biometrics AB" + }, + { + "application": "Contactless Smartcard Access Controll", + "company": "BQT Solutions Limited", + "mad": "0x4858", + "service_provider": "Banque-Tec", + "system_integrator": "Banque-Tec" + }, + { + "application": "Access control", + "company": "OASys GmbH", + "mad": "0x4859", + "service_provider": "Oasys GmbH", + "system_integrator": "Oasys GmbH" + }, + { + "application": "Access control", + "company": "OASys GmbH", + "mad": "0x486A", + "service_provider": "Oasys GmbH", + "system_integrator": "Oasys GmbH" + }, + { + "application": "Access control & security", + "company": "Third Millennium Systems Ltd", + "mad": "0x486B", + "service_provider": "Third Millenium", + "system_integrator": "Third Millenium" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x486C", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x486D", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x486E", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x486F", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4870", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4871", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4872", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4873", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4874", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4875", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4876", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4877", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4878", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4879", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x487A", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x487B", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x487C", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x487E", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x487F", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4880", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4881", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4882", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4883", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control", + "company": "IoLAN", + "mad": "0x4884", + "service_provider": "Iolan BV", + "system_integrator": "Iolan BV" + }, + { + "application": "Access control & security", + "company": "TechID Engineering bv", + "mad": "0x4885", + "service_provider": "TechID", + "system_integrator": "TechID" + }, + { + "application": "Access control & security", + "company": "N.V. Luchthaven", + "mad": "0x4886", + "service_provider": "N.V. Luchthaven Schiphol", + "system_integrator": "" + }, + { + "application": "Access control & security", + "company": "N.V. Luchthaven", + "mad": "0x4887", + "service_provider": "N.V. Luchthaven Schiphol", + "system_integrator": "" + }, + { + "application": "Access control & security", + "company": "N.V. Luchthaven", + "mad": "0x4888", + "service_provider": "N.V. Luchthaven Schiphol", + "system_integrator": "" + }, + { + "application": "Multi functional badge, private application", + "company": "Microtronic AG", + "mad": "0x4889", + "service_provider": "Microtronic AG", + "system_integrator": "Microtronic AG" + }, + { + "application": "Fingerprint infos compared to user's fingerprint for authentication", + "company": "Biocentric Solutions Inc.", + "mad": "0x489A", + "service_provider": "Biocentric Solutions Inc.", + "system_integrator": "Biocentric Solutions Inc." + }, + { + "application": "Access control application", + "company": "Lenel Systems International", + "mad": "0x489B", + "service_provider": "Lenel Systems International Inc.", + "system_integrator": "Lenel Systems International Inc." + }, + { + "application": "Access control application", + "company": "Lenel Systems International", + "mad": "0x489C", + "service_provider": "Lenel Systems International Inc.", + "system_integrator": "Lenel Systems International Inc." + }, + { + "application": "Access control", + "company": "Interlogix B.V.", + "mad": "0x489D", + "service_provider": "Ge Interlogix", + "system_integrator": "Ge Interlogix" + }, + { + "application": "Biometrial and specific access control data storage", + "company": "Tecisa74", + "mad": "0x489E", + "service_provider": "Tecisa74", + "system_integrator": "Tecisa74" + }, + { + "application": "Biometrial and specific access control data storage", + "company": "Tecisa74", + "mad": "0x489F", + "service_provider": "Tecisa74", + "system_integrator": "Tecisa74" + }, + { + "application": "Biometrial and specific access control data storage", + "company": "Tecisa74", + "mad": "0x48A0", + "service_provider": "Tecisa74", + "system_integrator": "Tecisa74" + }, + { + "application": "Card Holder Data/Card Management Data/Access Control & Security", + "company": "House of Representatives of States General", + "mad": "0x48A1", + "service_provider": "House of Representatives of States General", + "system_integrator": "Paul Sas" + }, + { + "application": "Book and pay system, Access control", + "company": "ADC Systems AB", + "mad": "0x48A2", + "service_provider": "ADC Systems", + "system_integrator": "ADC Systems" + }, + { + "application": "Access contr, time & attendance, multifunc card", + "company": "Horoquartz Gestion des Temps", + "mad": "0x48A3", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "Multiapplication car for industry & trafic, parking, swimming pool", + "company": "ASEC S.A.", + "mad": "0x48A4", + "service_provider": "ASEC S.A", + "system_integrator": "ASEC S.A" + }, + { + "application": "Access control", + "company": "Miditec Datensysteme GmbH", + "mad": "0x48A5", + "service_provider": "Miditec", + "system_integrator": "Miditec" + }, + { + "application": "Acess control", + "company": "Miditec Datensysteme GmbH", + "mad": "0x48A6", + "service_provider": "Miditec", + "system_integrator": "Miditec" + }, + { + "application": "Access control, time & attendence, job control", + "company": "Captor N.V.", + "mad": "0x48A7", + "service_provider": "Captor NV", + "system_integrator": "Captor NV" + }, + { + "application": "Access contr, time & attendance, multifunc card", + "company": "Horoquartz Gestion des Temps", + "mad": "0x48A8", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "Access control & security", + "company": "DATASEC Electronic GmbH", + "mad": "0x48A9", + "service_provider": "Datasec Electronic", + "system_integrator": "Datasec Electronic" + }, + { + "application": "Miscellaneous application, city traffic, access controll & security entertainment, car parking, electronic trade", + "company": "KFAP S.A.", + "mad": "0x48AA", + "service_provider": "KFPA", + "system_integrator": "KFPA" + }, + { + "application": "Access control", + "company": "Electronic Application Laboratory", + "mad": "0x48AB", + "service_provider": "EAL", + "system_integrator": "EAL" + }, + { + "application": "Access control, time management, electronic wallet", + "company": "Universitaire Ziekenhuizen Leuven", + "mad": "0x48AC", + "service_provider": "", + "system_integrator": "GET NV" + }, + { + "application": "Access control, Time and hendance", + "company": "Kaba Benzing GmbH", + "mad": "0x48AD", + "service_provider": "Kaba Benzing", + "system_integrator": "Kaba Benzing" + }, + { + "application": "Attendance-time rading, access control", + "company": "PDTS Gesellschaft für industrielle Datenverarbeitung Ges.mbH", + "mad": "0x48AE", + "service_provider": "PDTS", + "system_integrator": "PDTS" + }, + { + "application": "Access control, Time and attendance", + "company": "Vicking Electronics", + "mad": "0x48AF", + "service_provider": "Vicking Electronics", + "system_integrator": "Vicking Electronics" + }, + { + "application": "", + "company": "Gemplus Nv", + "mad": "0x48B0", + "service_provider": "ING Bank", + "system_integrator": "" + }, + { + "application": "Belgium", + "company": "Gemplus Nv", + "mad": "0x48B1", + "service_provider": "ING Bank", + "system_integrator": "" + }, + { + "application": "Belgium", + "company": "Gemplus Nv", + "mad": "0x48B2", + "service_provider": "ING Bank", + "system_integrator": "" + }, + { + "application": "Access Control", + "company": "IDESCO OY", + "mad": "0x48B3", + "service_provider": "Idesco Oy", + "system_integrator": "Idesco Oy" + }, + { + "application": "Access contr, time & attendance, multifunc card", + "company": "Horoquartz Gestion des Temps", + "mad": "0x48B4", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "Access contr, time & attendance, multifunc card", + "company": "Horoquartz Gestion des Temps", + "mad": "0x48B5", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "Storage of identification data", + "company": "SDS - Security Data Systems", + "mad": "0x48CF", + "service_provider": "SDS", + "system_integrator": "SDS" + }, + { + "application": "Storage of biometric data f. access contr. purposes", + "company": "SDS - Security Data Systems", + "mad": "0x48D0", + "service_provider": "SDS", + "system_integrator": "SDS" + }, + { + "application": "Storage of biometric data f. access contr. purposes", + "company": "SDS - Security Data Systems", + "mad": "0x48D1", + "service_provider": "SDS", + "system_integrator": "SDS" + }, + { + "application": "Storage of biometric data f. access contr. purposes", + "company": "SDS - Security Data Systems", + "mad": "0x48D2", + "service_provider": "SDS", + "system_integrator": "SDS" + }, + { + "application": "Storage of biometric data f. access contr. purposes", + "company": "SDS - Security Data Systems", + "mad": "0x48D3", + "service_provider": "SDS", + "system_integrator": "SDS" + }, + { + "application": "Storage of biometric data f. access contr. purposes", + "company": "SDS - Security Data Systems", + "mad": "0x48D4", + "service_provider": "SDS", + "system_integrator": "SDS" + }, + { + "application": "Storage of biometric data f. access contr. purposes", + "company": "SDS - Security Data Systems", + "mad": "0x48D5", + "service_provider": "SDS", + "system_integrator": "SDS" + }, + { + "application": "Access control & security", + "company": "Hi Sec International A/S", + "mad": "0x48D6", + "service_provider": "HI SEC International", + "system_integrator": "HI SEC International" + }, + { + "application": "Identification for access control", + "company": "Quality Equipment Benelux B.V.", + "mad": "0x48D7", + "service_provider": "Quality Equipment", + "system_integrator": "Quality Equipment" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48D8", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48D9", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48DA", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48DB", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48DC", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48DD", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48DE", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48DF", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48E0", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48E1", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48E2", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48E3", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48E4", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48E5", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Physical access conrtol, biometrics, point of sale", + "company": "Procter and Gamble Company", + "mad": "0x48E6", + "service_provider": "Procter and Gamble Company", + "system_integrator": "Procter and Gamble Company" + }, + { + "application": "Finger Print Application", + "company": "Rexroth the identity company GmbH", + "mad": "0x48E7", + "service_provider": "Rexroth", + "system_integrator": "Rexroth" + }, + { + "application": "Finger Print Application", + "company": "Rexroth the identity company GmbH", + "mad": "0x48E8", + "service_provider": "Rexroth", + "system_integrator": "Rexroth" + }, + { + "application": "Access control and identification", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x48E9", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Access control and identification", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x48EA", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Access control and identification", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x48EB", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Access control and identification", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x48EC", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Computer, car parking, elec. purse, access control & security", + "company": "DECA Engineering", + "mad": "0x48ED", + "service_provider": "Deca Engineering", + "system_integrator": "Deca Engineering" + }, + { + "application": "Computer, car parking, elec. purse, access control & security", + "company": "DECA Engineering", + "mad": "0x48EE", + "service_provider": "Deca Engineering", + "system_integrator": "Deca Engineering" + }, + { + "application": "Access Control", + "company": "Salto Systems", + "mad": "0x48EF", + "service_provider": "Salto Systems", + "system_integrator": "Salto Systems" + }, + { + "application": "Electronic locks", + "company": "IR Security & Safety GmbH", + "mad": "0x48F0", + "service_provider": "IR Security & Safety", + "system_integrator": "IR Security & Safety" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F1", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F2", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F3", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F4", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F5", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F6", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F7", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F8", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48F9", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access Control & Security", + "company": "CDV International", + "mad": "0x48FA", + "service_provider": "CDV", + "system_integrator": "CDV" + }, + { + "application": "Access control, card contains, biometric data", + "company": "Spica International", + "mad": "0x48FB", + "service_provider": "Spica", + "system_integrator": "Spica" + }, + { + "application": "Access control & scecurity", + "company": "Adasoft AG", + "mad": "0x48FC", + "service_provider": "Adasoft AG", + "system_integrator": "Adasoft AG" + }, + { + "application": "Access control & scecurity", + "company": "Adasoft AG", + "mad": "0x48FD", + "service_provider": "Adasoft AG", + "system_integrator": "Adasoft AG" + }, + { + "application": "Access control & scecurity", + "company": "Adasoft AG", + "mad": "0x48FE", + "service_provider": "Adasoft AG", + "system_integrator": "Adasoft AG" + }, + { + "application": "Access control & scecurity", + "company": "Adasoft AG", + "mad": "0x48FF", + "service_provider": "Adasoft AG", + "system_integrator": "Adasoft AG" + }, + { + "application": "VIGIK", + "company": "Immotec Systemes", + "mad": "0x4902", + "service_provider": "Immotec", + "system_integrator": "Immotec" + }, + { + "application": "VIGIK", + "company": "Immotec Systemes", + "mad": "0x4903", + "service_provider": "Immotec", + "system_integrator": "Immotec" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4904", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4905", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4906", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4907", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4908", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4909", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x490A", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x490B", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x490C", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x490D", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x490E", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x490F", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4910", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4911", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4912", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4913", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "Card Administratin, cardholder adminstration, access control & security, company services, miscellaneous applications", + "company": "Ministry of Defense", + "mad": "0x4A01", + "service_provider": "Ministry of Defence", + "system_integrator": "" + }, + { + "application": "Card Administratin, cardholder adminstration, access control & security, company services, miscellaneous applications", + "company": "Ministry of Defense", + "mad": "0x4A02", + "service_provider": "Ministry of Defence", + "system_integrator": "" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C01", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C02", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C03", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C04", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C05", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C06", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C07", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C08", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C09", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C0A", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C0B", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C0C", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C0D", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C0E", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C0F", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C10", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C11", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C12", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C13", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C14", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C15", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C16", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C17", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C18", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C19", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C1A", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C1B", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C1C", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C1D", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C1E", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C1F", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C20", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C21", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C22", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C23", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C24", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C25", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C26", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C27", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Physical Access Control Systems (PACS) of the major European Union Institues", + "company": "European Commission", + "mad": "0x4C28", + "service_provider": "Various", + "system_integrator": "Various" + }, + { + "application": "Ski ticketing", + "company": "ADI Ltd.", + "mad": "0x5001", + "service_provider": "BO RROC Sigulda", + "system_integrator": "ADI Ltd." + }, + { + "application": "Ski ticketing, member card, ski association, discounts", + "company": "Cetrta Pot d.o.o.", + "mad": "0x5002", + "service_provider": "Slovenian Ski Association", + "system_integrator": "Cetrta Pot" + }, + { + "application": "Ski ticketing system based on electronic purse", + "company": "ADI Ltd.", + "mad": "0x5003", + "service_provider": "Ramkalni Ltd", + "system_integrator": "ADI Ltd" + }, + { + "application": "Ski ticketing", + "company": "ADI Ltd.", + "mad": "0x5004", + "service_provider": "K-Kalins Ltd.", + "system_integrator": "ADI Ltd" + }, + { + "application": "Entertainment and Sports, Stadiums, Parking, Ski Ticketing", + "company": "Axess AG", + "mad": "0x5005", + "service_provider": "Axess", + "system_integrator": "Axess" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0x5006", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "Ski ticketing", + "company": "ADI Ltd", + "mad": "0x5007", + "service_provider": "FROKS Ltd", + "system_integrator": "ADI" + }, + { + "application": "Ski ticketing", + "company": "ADI Ltd", + "mad": "0x5008", + "service_provider": "Kalnzaki", + "system_integrator": "ADI" + }, + { + "application": "Local Ski Ticketing Sysem based on electronic purse", + "company": "ADI Ltd", + "mad": "0x5009", + "service_provider": "Mezezers Ltd.", + "system_integrator": "ADI Ltd." + }, + { + "application": "Access Control", + "company": "NEDAP NV", + "mad": "0x5101", + "service_provider": "Nedap Ideas", + "system_integrator": "Nedap Ideas" + }, + { + "application": "Access Control & Security", + "company": "NOVO GmbH", + "mad": "0x5102", + "service_provider": "1. FC Köln GmbH&Co KG", + "system_integrator": "" + }, + { + "application": "Access control and security", + "company": "GPS Tecnologia Ltda.", + "mad": "0x5103", + "service_provider": "GPS Tec", + "system_integrator": "GPS Tec" + }, + { + "application": "Access control and security", + "company": "GPS Tecnologia Ltda.", + "mad": "0x5104", + "service_provider": "GPS Tec", + "system_integrator": "GPS Tec" + }, + { + "application": "Access control", + "company": "Custom Micro Products Ltd.", + "mad": "0x5105", + "service_provider": "Custom Micro Products", + "system_integrator": "Custom Micro Products" + }, + { + "application": "Biometric Access Control", + "company": "CYNAPS", + "mad": "0x5106", + "service_provider": "Cynaps", + "system_integrator": "Cynaps" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5107", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5108", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5109", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x510A", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x510B", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x510C", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x510D", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x510E", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x510F", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5110", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5111", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5112", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5113", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5114", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5115", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5116", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5117", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5118", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x5119", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x511A", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x511B", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x511C", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x511D", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x511E", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control and security", + "company": "Alfapass", + "mad": "0x511F", + "service_provider": "Alfapass", + "system_integrator": "Alfapass" + }, + { + "application": "Access control", + "company": "Tyco Software House", + "mad": "0x5120", + "service_provider": "Tyco Software House", + "system_integrator": "Tyco Software House" + }, + { + "application": "Access control", + "company": "Connex Solutions Limited", + "mad": "0x5121", + "service_provider": "Connex", + "system_integrator": "Connex" + }, + { + "application": "Acess Control, Time and Attendance", + "company": "Milenio 3 Systemas Electonicos", + "mad": "0x5122", + "service_provider": "Milenio3", + "system_integrator": "Milenio3" + }, + { + "application": "Access control & security", + "company": "CORESTREET", + "mad": "0x5123", + "service_provider": "Corestreet", + "system_integrator": "Corestreet" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x5124", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x5125", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x5126", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x5127", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x5128", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x5129", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x512A", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Access control & security", + "company": "Honeywell", + "mad": "0x512B", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Biometrics strong authentication", + "company": "LabCal", + "mad": "0x512C", + "service_provider": "Labcal", + "system_integrator": "Labcal" + }, + { + "application": "Access control & security", + "company": "GOB Software&System GmbH Co. KG", + "mad": "0x512D", + "service_provider": "GOB", + "system_integrator": "GOB" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x512E", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x512F", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x5130", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x5131", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x5132", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x5133", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x5134", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Access control & security", + "company": "Suprema Inc", + "mad": "0x5135", + "service_provider": "Suprema", + "system_integrator": "Suprema" + }, + { + "application": "Compelete system for lockers, access control & electr. payment", + "company": "Ojmar S. A.", + "mad": "0x5136", + "service_provider": "", + "system_integrator": "Enkoa System S.L." + }, + { + "application": "Access control", + "company": "Honeywell Building Solutions", + "mad": "0x5137", + "service_provider": "Honeywell", + "system_integrator": "Honeywell" + }, + { + "application": "Electronic purse, access control for buliding automation", + "company": "CDE Communication Data Engineering GmbH", + "mad": "0x5138", + "service_provider": "CDE", + "system_integrator": "CDE" + }, + { + "application": "Electronic purse, access control for buliding automation", + "company": "CDE Communication Data Engineering GmbH", + "mad": "0x5139", + "service_provider": "CDE", + "system_integrator": "CDE" + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0x513A", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Access control, card management", + "company": "ID-WARE", + "mad": "0x513B", + "service_provider": "ID-WARE b.v.", + "system_integrator": "" + }, + { + "application": "Access control, card management", + "company": "ID-WARE", + "mad": "0x513C", + "service_provider": "ID-WARE b.v.", + "system_integrator": "" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0x513D", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "Access control, computer application, company services", + "company": "Volvo Car Corporation", + "mad": "0x513E", + "service_provider": "Volvo Car", + "system_integrator": "Volvo Car" + }, + { + "application": "Access contr, time and attendance", + "company": "Nisus nv", + "mad": "0x513F", + "service_provider": "Nisus NV", + "system_integrator": "NIsus NV" + }, + { + "application": "Time & attendance", + "company": "Flora Holland", + "mad": "0x5140", + "service_provider": "Interflex Datasystems", + "system_integrator": "Interflex Datasystems" + }, + { + "application": "Elec ticketing, access control, electronic purse", + "company": "Empresa 1 Sistemas de Automacao e Comercio", + "mad": "0x5141", + "service_provider": "Empresa 1", + "system_integrator": "Empresa 1" + }, + { + "application": "Biometric Terminal", + "company": "Recognition Systems LLC", + "mad": "0x5142", + "service_provider": "Recognition Systems", + "system_integrator": "" + }, + { + "application": "Access control & security", + "company": "Evotech B.V.", + "mad": "0x5143", + "service_provider": "Evotech B.V., GTI NV", + "system_integrator": "Evotech B.V." + }, + { + "application": "Time attendnace, fuel, access control", + "company": "Emcard a.s.", + "mad": "0x5144", + "service_provider": "Emtest", + "system_integrator": "Emtest" + }, + { + "application": "Access control and security", + "company": "Scotcomms Technology Group Ltd.", + "mad": "0x5145", + "service_provider": "Various", + "system_integrator": "Scotcomms Technology Group Ltd." + }, + { + "application": "Debit Card, Door Acces Control, Computer Identification", + "company": "Netcard", + "mad": "0x5146", + "service_provider": "Netcard", + "system_integrator": "Netcard" + }, + { + "application": "MES Manufactoring Execution System", + "company": "gbo datacomp GmbH", + "mad": "0x5148", + "service_provider": "Gbo datacomp GmbH", + "system_integrator": "gbo datacomp GmbH" + }, + { + "application": "MES Manufactoring Execution System", + "company": "gbo datacomp GmbH", + "mad": "0x5149", + "service_provider": "Gbo datacomp GmbH", + "system_integrator": "gbo datacomp GmbH" + }, + { + "application": "Access control & security", + "company": "Farpointe Data Inc", + "mad": "0x514A", + "service_provider": "Farpointe", + "system_integrator": "" + }, + { + "application": "Fingerprint Recognition Application", + "company": "ESCO Biometric BVBA", + "mad": "0x514B", + "service_provider": "ESCO Biometric", + "system_integrator": "ESCO Biometric" + }, + { + "application": "Access Control", + "company": "Interflex Datensysteme GmbH", + "mad": "0x514C", + "service_provider": "", + "system_integrator": "Interflex Datensysteme GmbH & CoKG" + }, + { + "application": "Access Control", + "company": "Interflex Datensysteme GmbH", + "mad": "0x514D", + "service_provider": "", + "system_integrator": "Interflex Datensysteme GmbH & CoKG" + }, + { + "application": "Access Control", + "company": "Interflex Datensysteme GmbH", + "mad": "0x514E", + "service_provider": "", + "system_integrator": "Interflex Datensysteme GmbH & CoKG" + }, + { + "application": "Access Control", + "company": "Interflex Datensysteme GmbH", + "mad": "0x514F", + "service_provider": "", + "system_integrator": "Interflex Datensysteme GmbH & CoKG" + }, + { + "application": "Fidelity Card", + "company": "Sogedex", + "mad": "0x5150", + "service_provider": "Sogedex", + "system_integrator": "Sogedex" + }, + { + "application": "Fidelity Card", + "company": "Sogedex", + "mad": "0x5151", + "service_provider": "Sogedex", + "system_integrator": "Sogedex" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x5152", + "service_provider": "Sogedex", + "system_integrator": "Sogedex" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x5153", + "service_provider": "Sogedex", + "system_integrator": "Sogedex" + }, + { + "application": "Access Control, Time Attendance, Job Costing, Ticketing", + "company": "Hectrix Limited", + "mad": "0x5154", + "service_provider": "Hectrix Ltd.", + "system_integrator": "Hectrix. Ltd." + }, + { + "application": "Access Control, Time Attendance, Job Costing, Ticketing", + "company": "Hectrix Limited", + "mad": "0x5155", + "service_provider": "Hectrix Ltd.", + "system_integrator": "Hectrix. Ltd." + }, + { + "application": "Access control & security", + "company": "Roger Dariusz Wensker", + "mad": "0x5156", + "service_provider": "Roger", + "system_integrator": "Roger" + }, + { + "application": "Access control & security", + "company": "Roger Dariusz Wensker", + "mad": "0x5157", + "service_provider": "Roger", + "system_integrator": "Roger" + }, + { + "application": "Access control & security", + "company": "Roger Dariusz Wensker", + "mad": "0x5158", + "service_provider": "Roger", + "system_integrator": "Roger" + }, + { + "application": "Access control & security", + "company": "Roger Dariusz Wensker", + "mad": "0x5159", + "service_provider": "Roger", + "system_integrator": "Roger" + }, + { + "application": "Access & parking control, electronic purse", + "company": "General Meters Corp", + "mad": "0x515A", + "service_provider": "General Meters", + "system_integrator": "General Meters" + }, + { + "application": "Car parking, sport applic, hotel, access control systems", + "company": "DATASEC Electronic GmbH", + "mad": "0x515B", + "service_provider": "Datasec", + "system_integrator": "Datatsec" + }, + { + "application": "Car parking, sport applic, hotel, access control systems", + "company": "DATASEC Electronic GmbH", + "mad": "0x515C", + "service_provider": "Datasec", + "system_integrator": "Datatsec" + }, + { + "application": "Access & Inventory conrtol", + "company": "Shockfish SA", + "mad": "0x515D", + "service_provider": "Shockfish", + "system_integrator": "Shockfish" + }, + { + "application": "Access & Inventory conrtol", + "company": "Shockfish SA", + "mad": "0x515E", + "service_provider": "Shockfish", + "system_integrator": "Shockfish" + }, + { + "application": "Access & Inventory conrtol", + "company": "Shockfish SA", + "mad": "0x515F", + "service_provider": "Shockfish", + "system_integrator": "Shockfish" + }, + { + "application": "Access & Inventory conrtol", + "company": "Shockfish SA", + "mad": "0x5160", + "service_provider": "Shockfish", + "system_integrator": "Shockfish" + }, + { + "application": "Access control", + "company": "EAL Apeldoorn B.V.", + "mad": "0x5161", + "service_provider": "EAL", + "system_integrator": "EAL" + }, + { + "application": "Access Control, E-purse", + "company": "Gemalto", + "mad": "0x5162", + "service_provider": "Gemplus", + "system_integrator": "Gemplus" + }, + { + "application": "Access Control, E-purse", + "company": "Gemalto", + "mad": "0x5163", + "service_provider": "Gemplus", + "system_integrator": "Gemplus" + }, + { + "application": "Ausweiskarte", + "company": "Allgemeine Unfallversicherungsanstalt (AUVA)", + "mad": "0x5164", + "service_provider": "AUVA", + "system_integrator": "AUVA" + }, + { + "application": "Ausweiskarte", + "company": "Allgemeine Unfallversicherungsanstalt (AUVA)", + "mad": "0x5165", + "service_provider": "AUVA", + "system_integrator": "AUVA" + }, + { + "application": "Ausweiskarte", + "company": "Allgemeine Unfallversicherungsanstalt (AUVA)", + "mad": "0x5166", + "service_provider": "AUVA", + "system_integrator": "AUVA" + }, + { + "application": "Access Control & Security", + "company": "Nsecure B.V.", + "mad": "0x5167", + "service_provider": "Nsecure", + "system_integrator": "Nsecure" + }, + { + "application": "Fingerprint application, access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x5168", + "service_provider": "Shenzhen Ideal Microelectronics Co. Ltd.", + "system_integrator": "Shenzhen Ideal Microelectronics Co. Ltd." + }, + { + "application": "Fingerprint application, access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x5169", + "service_provider": "Shenzhen Ideal Microelectronics Co. Ltd.", + "system_integrator": "Shenzhen Ideal Microelectronics Co. Ltd." + }, + { + "application": "Fingerprint application, access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x516A", + "service_provider": "Shenzhen Ideal Microelectronics Co. Ltd.", + "system_integrator": "Shenzhen Ideal Microelectronics Co. Ltd." + }, + { + "application": "Fingerprint application, access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x516B", + "service_provider": "Shenzhen Ideal Microelectronics Co. Ltd.", + "system_integrator": "Shenzhen Ideal Microelectronics Co. Ltd." + }, + { + "application": "Access Control Reader", + "company": "Access Control Technology", + "mad": "0x516C", + "service_provider": "ACT", + "system_integrator": "ACT" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x516D", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x516E", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x516F", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x5170", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x5171", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x5172", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x5173", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x5174", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x5175", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Access control", + "company": "Cogelec", + "mad": "0x5176", + "service_provider": "Cogelec", + "system_integrator": "Cogelec" + }, + { + "application": "Uhlmann & Zacher Clex prime, online and offline electronic locking and access control systems", + "company": "Uhlmann & Zacher GmbH", + "mad": "0x5177", + "service_provider": "Uhlmann & Zacher GmbH", + "system_integrator": "" + }, + { + "application": "Hotel, acces control & security", + "company": "Talleres De Escoriaza S.A.", + "mad": "0x5178", + "service_provider": "Talleres", + "system_integrator": "Talleres" + }, + { + "application": "Energy Saving System For Hotels, Access Control", + "company": "ENKOA System", + "mad": "0x5179", + "service_provider": "Enkoa System S.L.", + "system_integrator": "Enkoa System S.L." + }, + { + "application": "Access conrol function & security", + "company": "Tyco Fire & Security", + "mad": "0x517A", + "service_provider": "Tyco", + "system_integrator": "Tyco" + }, + { + "application": "Logical & Physical access control", + "company": "Pin Cash International B.V.", + "mad": "0x517B", + "service_provider": "PinCash", + "system_integrator": "PinCash" + }, + { + "application": "VIGIK", + "company": "Immotec Systemes", + "mad": "0x517C", + "service_provider": "Immotec", + "system_integrator": "Immotec" + }, + { + "application": "VIGIK", + "company": "Immotec Systemes", + "mad": "0x517D", + "service_provider": "Immotec", + "system_integrator": "Immotec" + }, + { + "application": "VIGIK", + "company": "Immotec Systemes", + "mad": "0x517E", + "service_provider": "Immotec", + "system_integrator": "Immotec" + }, + { + "application": "MIFARE Booster config", + "company": "NEDAP NV", + "mad": "0x517F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "MIFARE Booster config", + "company": "NEDAP NV", + "mad": "0x5180", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access control for centrally managed waste treatment", + "company": "Alphatronics", + "mad": "0x5181", + "service_provider": "Alphatronics", + "system_integrator": "Alphatronics" + }, + { + "application": "Access control and identification", + "company": "CEM Systems", + "mad": "0x5182", + "service_provider": "CEM Systems Ltd", + "system_integrator": "CEM Systems Ltd" + }, + { + "application": "Access control and identification", + "company": "CEM Systems", + "mad": "0x5183", + "service_provider": "CEM Systems Ltd", + "system_integrator": "CEM Systems Ltd" + }, + { + "application": "Access control and identification", + "company": "CEM Systems", + "mad": "0x5184", + "service_provider": "CEM Systems Ltd", + "system_integrator": "CEM Systems Ltd" + }, + { + "application": "Hotel, access contr. & sec", + "company": "Vingcard a.s.", + "mad": "0x5185", + "service_provider": "Vingcard", + "system_integrator": "Vingcard" + }, + { + "application": "Hotel, access contr. & sec", + "company": "Vingcard a.s.", + "mad": "0x5186", + "service_provider": "Vingcard", + "system_integrator": "Vingcard" + }, + { + "application": "Zeiterfassung, Werks- bzw. Gebäudezutritt", + "company": "Voestalpine Informationstechnologie GmbH", + "mad": "0x5187", + "service_provider": "Voestalpine Informationstechnologie GmbH", + "system_integrator": "Voestalpine Informationstechnologie GmbH" + }, + { + "application": "Admiral Ausweiskarte (ID-Card)", + "company": "PDTS Gesellschaft für industrielle Datenverarbeitung Ges.mbH", + "mad": "0x5188", + "service_provider": "Admiral Sportwetten GmbH", + "system_integrator": "" + }, + { + "application": "Personal ID and Reporting of Attendance", + "company": "The Swedish Construction Federation", + "mad": "0x5189", + "service_provider": "Sveriges Byggindustrier", + "system_integrator": "" + }, + { + "application": "Personal ID and Reporting of Attendance", + "company": "The Swedish Construction Federation", + "mad": "0x518A", + "service_provider": "Sveriges Byggindustrier", + "system_integrator": "" + }, + { + "application": "Personal ID and Reporting of Attendance", + "company": "The Swedish Construction Federation", + "mad": "0x518B", + "service_provider": "Sveriges Byggindustrier", + "system_integrator": "" + }, + { + "application": "Personal ID and Reporting of Attendance", + "company": "The Swedish Construction Federation", + "mad": "0x518C", + "service_provider": "Sveriges Byggindustrier", + "system_integrator": "" + }, + { + "application": "Personal identification & reporting of attendance", + "company": "The Swedish Construction Federation", + "mad": "0x518D", + "service_provider": "Swedish Construction Fed", + "system_integrator": "" + }, + { + "application": "Personal identification & reporting of attendance", + "company": "The Swedish Construction Federation", + "mad": "0x518E", + "service_provider": "Swedish Construction Fed", + "system_integrator": "" + }, + { + "application": "Security", + "company": "Telenot Electronic GmbH", + "mad": "0x518F", + "service_provider": "Telenot Electronic GmbH", + "system_integrator": "" + }, + { + "application": "Access Control & Security", + "company": "Kaba-Ilco, Inc.", + "mad": "0x5190", + "service_provider": "Kaba Ilco", + "system_integrator": "Kaba Ilco" + }, + { + "application": "Access Control & Security", + "company": "Blue Systems International", + "mad": "0x5191", + "service_provider": "Blue Products.com", + "system_integrator": "Blue Systems International" + }, + { + "application": "Access Control & Security", + "company": "XceedID Corporation", + "mad": "0x5192", + "service_provider": "Xceed ID Corporation", + "system_integrator": "Xceed ID Corporation" + }, + { + "application": "Access Control & Security", + "company": "XceedID Corporation", + "mad": "0x5193", + "service_provider": "Xceed ID Corporation", + "system_integrator": "Xceed ID Corporation" + }, + { + "application": "Arcelor", + "company": "EM Group", + "mad": "0x5194", + "service_provider": "EMGROUP", + "system_integrator": "EMGROUP" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x5195", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x5196", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x5197", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x5198", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x5199", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x519A", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x519B", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x519C", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x519D", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Identification and authentification system", + "company": "Sogedex", + "mad": "0x519E", + "service_provider": "SOGEDEX", + "system_integrator": "SOGEDEX" + }, + { + "application": "Electronic ticketing system", + "company": "CDE Communication Data Engineering GmbH", + "mad": "0x519F", + "service_provider": "CDE-Competence Center for embedded solutions", + "system_integrator": "CDE - Competence Center for embedded solutions" + }, + { + "application": "Electronic ticketing system", + "company": "CDE Communication Data Engineering GmbH", + "mad": "0x51A0", + "service_provider": "CDE-Competence Center for embedded solutions", + "system_integrator": "CDE - Competence Center for embedded solutions" + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A1", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A2", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A3", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A4", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A5", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A6", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A7", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "Access control & security", + "company": "Shenzhen Ideal Microelectronics Co. Ltd.", + "mad": "0x51A8", + "service_provider": "Shenzen IDEAL Microelectronics Co., Ltd.", + "system_integrator": "Shenzen IDEAL Microelectronics Co., Ltd." + }, + { + "application": "TIME AND ATTENDANCE, ACCESS CONTROL", + "company": "Pyrescom", + "mad": "0x51A9", + "service_provider": "PYRESCOM", + "system_integrator": "PYRESCOM" + }, + { + "application": "Attendance registration and access control", + "company": "Simac QUADCORE", + "mad": "0x51AA", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access services (to all buildings of Belgian regional and federal political assembles) and Time and Attendances Services", + "company": "Vlaams Parlement", + "mad": "0x51AB", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Physical Access Control", + "company": "General Motors", + "mad": "0x51AC", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access Control", + "company": "BEKA Elektronik", + "mad": "0x51AD", + "service_provider": "BEKA Electronik", + "system_integrator": "BEKA Electronik" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51AE", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51AF", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B0", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B1", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B2", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B3", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B4", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B5", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B6", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B7", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B8", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51B9", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access Control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x51BA", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": "Coor Service Management AB, PAS, Card and Know IT" + }, + { + "application": "Access control, Time and Attendance", + "company": "Bodet S.A.", + "mad": "0x51BB", + "service_provider": "Bodet SA", + "system_integrator": "Bodet SA" + }, + { + "application": "Access control and security", + "company": "STid Electronic Identification", + "mad": "0x51BC", + "service_provider": "STid", + "system_integrator": "STid" + }, + { + "application": "Access Control- Time stamping", + "company": "MCF RF TECH SRL", + "mad": "0x51BD", + "service_provider": "MCF RF TECH S.R.L.", + "system_integrator": "MCF RF TECH S.R.L." + }, + { + "application": "ID-cards for logistic company", + "company": "PNL - Pan Nordic Logistics", + "mad": "0x51BE", + "service_provider": "Combiport AB", + "system_integrator": "DAS Card AB" + }, + { + "application": "ID-cards for logistic company", + "company": "PNL - Pan Nordic Logistics", + "mad": "0x51BF", + "service_provider": "Combiport AB", + "system_integrator": "DAS Card AB" + }, + { + "application": "Accesss Control; biometric Identification", + "company": "SYTEL", + "mad": "0x51C0", + "service_provider": "SYTEL", + "system_integrator": "SYTEL" + }, + { + "application": "Accesss Control; biometric Identification", + "company": "SYTEL", + "mad": "0x51C1", + "service_provider": "SYTEL", + "system_integrator": "SYTEL" + }, + { + "application": "Accesss Control; biometric Identification", + "company": "SYTEL", + "mad": "0x51C2", + "service_provider": "SYTEL", + "system_integrator": "SYTEL" + }, + { + "application": "Access control and security application - physical security", + "company": "INID BV", + "mad": "0x51C3", + "service_provider": "INID", + "system_integrator": "INID" + }, + { + "application": "Access control Telectronic locks", + "company": "Deister electronic GmbH", + "mad": "0x51C4", + "service_provider": "Deister electronic GmbH", + "system_integrator": "Deister electronic GmbH" + }, + { + "application": "Access control Telectronic locks", + "company": "Deister electronic GmbH", + "mad": "0x51C5", + "service_provider": "Deister electronic GmbH", + "system_integrator": "Deister electronic GmbH" + }, + { + "application": "Access control", + "company": "INSYS MICROELECTRONICS GmbH", + "mad": "0x51C6", + "service_provider": "INSYS MICROELECTRONICS GmbH", + "system_integrator": "INSYS MICROELECTRONICS GmbH" + }, + { + "application": "Access control", + "company": "INSYS MICROELECTRONICS GmbH", + "mad": "0x51C7", + "service_provider": "INSYS MICROELECTRONICS GmbH", + "system_integrator": "INSYS MICROELECTRONICS GmbH" + }, + { + "application": "Access control", + "company": "INSYS MICROELECTRONICS GmbH", + "mad": "0x51C8", + "service_provider": "INSYS MICROELECTRONICS GmbH", + "system_integrator": "INSYS MICROELECTRONICS GmbH" + }, + { + "application": "Access control", + "company": "INSYS MICROELECTRONICS GmbH", + "mad": "0x51C9", + "service_provider": "INSYS MICROELECTRONICS GmbH", + "system_integrator": "INSYS MICROELECTRONICS GmbH" + }, + { + "application": "Access control", + "company": "INSYS MICROELECTRONICS GmbH", + "mad": "0x51CA", + "service_provider": "INSYS MICROELECTRONICS GmbH", + "system_integrator": "INSYS MICROELECTRONICS GmbH" + }, + { + "application": "Access control, security and monitoring", + "company": "Atelei Engineering SLU", + "mad": "0x51CB", + "service_provider": "Atelei Engineering", + "system_integrator": "Atelei Engineering" + }, + { + "application": "Access & biometrics application", + "company": "Manufacture Francaise des Pneumatiques MICHELIN", + "mad": "0x5202", + "service_provider": "MICHELIN", + "system_integrator": "" + }, + { + "application": "Access & biometrics application", + "company": "Manufacture Francaise des Pneumatiques MICHELIN", + "mad": "0x5203", + "service_provider": "MICHELIN", + "system_integrator": "" + }, + { + "application": "Access & biometrics application", + "company": "Manufacture Francaise des Pneumatiques MICHELIN", + "mad": "0x5204", + "service_provider": "MICHELIN", + "system_integrator": "" + }, + { + "application": "Access & biometrics application", + "company": "Manufacture Francaise des Pneumatiques MICHELIN", + "mad": "0x5205", + "service_provider": "MICHELIN", + "system_integrator": "" + }, + { + "application": "Access & biometrics application", + "company": "Manufacture Francaise des Pneumatiques MICHELIN", + "mad": "0x5206", + "service_provider": "MICHELIN", + "system_integrator": "" + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x5207", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x5208", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x5209", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x520A", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x520B", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x520C", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x520D", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "Access Control", + "company": "Triple Eye BV", + "mad": "0x520E", + "service_provider": "Triple Eye B.V.", + "system_integrator": "Triple Eye B.V." + }, + { + "application": "A ticketing application for transport systems", + "company": "VERIFONE ITALIA SRL", + "mad": "0x520F", + "service_provider": "VeriFone Italia", + "system_integrator": "VeriFone Italia" + }, + { + "application": "Access control", + "company": "KABA", + "mad": "0x5210", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control", + "company": "KABA", + "mad": "0x5211", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control", + "company": "KABA", + "mad": "0x5212", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control", + "company": "KABA", + "mad": "0x5213", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control", + "company": "KABA", + "mad": "0x5214", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control", + "company": "KABA", + "mad": "0x5215", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control", + "company": "KABA", + "mad": "0x5216", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control & security", + "company": "Keyprocessor B.V.", + "mad": "0x5217", + "service_provider": "Keyprocessor", + "system_integrator": "" + }, + { + "application": "Access control & Security for Ericsson world wide", + "company": "Coor Service Management AB", + "mad": "0x5218", + "service_provider": "Telefonaktiebolaget LM Ericsson", + "system_integrator": " Coor Service Management AB, PAS CARD and Know IT" + }, + { + "application": "Access control", + "company": "MBB Gelma GmbH", + "mad": "0x5229", + "service_provider": "MBB Gelma GmbH", + "system_integrator": "MBB Gelma" + }, + { + "application": "Access control", + "company": "MBB Gelma GmbH", + "mad": "0x522A", + "service_provider": "MBB Gelma GmbH", + "system_integrator": "MBB Gelma" + }, + { + "application": "Access Control, Time & Attendance", + "company": "GRUPO SPEC", + "mad": "0x522B", + "service_provider": "GRUPO SPEC", + "system_integrator": "GRUPO SPEC" + }, + { + "application": "Access Control & Security", + "company": "AB Angpanneföreningen", + "mad": "0x522D", + "service_provider": "AB Angpanneföreningen", + "system_integrator": "AB Angpanneföreningen" + }, + { + "application": "Access control & security", + "company": "Scheidt & Bachmann GmbH", + "mad": "0x522E", + "service_provider": "Scheidt & Bachmann GmbH", + "system_integrator": "Scheidt & Bachmann GmbH" + }, + { + "application": "Access control", + "company": "AMS ENGINEERING Sticht GmbH", + "mad": "0x522F", + "service_provider": "AMS-Engineering", + "system_integrator": "AMS-Engineering" + }, + { + "application": "Access control", + "company": "AMS ENGINEERING Sticht GmbH", + "mad": "0x5230", + "service_provider": "AMS-Engineering", + "system_integrator": "AMS-Engineering" + }, + { + "application": "Security and Access Control", + "company": "Integrated Control Technology Limited", + "mad": "0x5231", + "service_provider": "Integrated Control Technology Limited", + "system_integrator": "Integrated Control Technology Limited" + }, + { + "application": "Centralized access control system", + "company": "National Control Systems S.A.", + "mad": "0x5232", + "service_provider": "National Control Systems S.A.", + "system_integrator": "National Control Systems S.A." + }, + { + "application": "Access control for Pas Card AB and our customers", + "company": "PAS Card AB", + "mad": "0x5233", + "service_provider": "Pas Card AB", + "system_integrator": "Pas Card AB" + }, + { + "application": "Access control for Pas Card AB and our customers", + "company": "PAS Card AB", + "mad": "0x5234", + "service_provider": "Pas Card AB", + "system_integrator": "Pas Card AB" + }, + { + "application": "Access control for Pas Card AB and our customers", + "company": "PAS Card AB", + "mad": "0x5235", + "service_provider": "Pas Card AB", + "system_integrator": "Pas Card AB" + }, + { + "application": "Access control for Pas Card AB and our customers", + "company": "PAS Card AB", + "mad": "0x5236", + "service_provider": "Pas Card AB", + "system_integrator": "Pas Card AB" + }, + { + "application": "Access control for Pas Card AB and our customers", + "company": "PAS Card AB", + "mad": "0x5237", + "service_provider": "Pas Card AB", + "system_integrator": "Pas Card AB" + }, + { + "application": "Access services (to all buildings of Belgian and federal political assemblees) and time and attendance services", + "company": "Vlaams Parlement", + "mad": "0x5238", + "service_provider": "", + "system_integrator": "None" + }, + { + "application": "Access Control & Security Fabricom (GDF SUEZ)", + "company": "Fabricom (GDF SUEZ)", + "mad": "0x5239", + "service_provider": "Fabricom (GDF SUEZ)/Belgian Operations/Communication & Security/Security", + "system_integrator": "Fabricom (GDF SUEZ)/Belgian Operations/Communication & Security/Security" + }, + { + "application": "Access Control & Security Fabricom (GDF SUEZ)", + "company": "Fabricom (GDF SUEZ)", + "mad": "0x523A", + "service_provider": "Fabricom (GDF SUEZ)/Belgian Operations/Communication & Security/Security", + "system_integrator": "Fabricom (GDF SUEZ)/Belgian Operations/Communication & Security/Security" + }, + { + "application": "Access control and security", + "company": "ESTIS", + "mad": "0x523B", + "service_provider": "ESTIS", + "system_integrator": "ESTIS" + }, + { + "application": "Key diversification container", + "company": "KABA", + "mad": "0x523C", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Key diversification container", + "company": "KABA", + "mad": "0x523D", + "service_provider": "Kaba AG", + "system_integrator": "Kaba AG" + }, + { + "application": "Access control, security and monitoring", + "company": "Atelei Engineering SLU", + "mad": "0x523D", + "service_provider": "Atelei Engineering", + "system_integrator": "Atelei Engineering" + }, + { + "application": "", + "company": "Bombardier Transportation", + "mad": "0x5306", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access control & security", + "company": "BTICINO s.p.a.", + "mad": "0x5307", + "service_provider": "BTICINO", + "system_integrator": "BTICINO" + }, + { + "application": "Access control & security", + "company": "BTICINO s.p.a.", + "mad": "0x5308", + "service_provider": "BTICINO", + "system_integrator": "BTICINO" + }, + { + "application": "Access control & security", + "company": "BTICINO s.p.a.", + "mad": "0x5309", + "service_provider": "BTICINO", + "system_integrator": "BTICINO" + }, + { + "application": "Access control & security", + "company": "BTICINO s.p.a.", + "mad": "0x530A", + "service_provider": "BTICINO", + "system_integrator": "BTICINO" + }, + { + "application": "Access control & security", + "company": "BTICINO s.p.a.", + "mad": "0x530B", + "service_provider": "BTICINO", + "system_integrator": "BTICINO" + }, + { + "application": "Access Control & Security", + "company": "BSB Electronics Ltd.", + "mad": "0x530C", + "service_provider": "BSB Electronics Ltd.", + "system_integrator": "BSB Electronics Ltd." + }, + { + "application": "Access control security for Uppsala University", + "company": "Uppsala University", + "mad": "0x530D", + "service_provider": "Uppsala University", + "system_integrator": "Uppsala University" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x530E", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x530F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5310", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5311", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5312", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5313", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5314", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5315", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5316", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Corporate Access Control application", + "company": "NXP Semiconductors Eindhoven", + "mad": "0x5317", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access Control", + "company": "EAL Apeldoorn B.V.", + "mad": "0x5318", + "service_provider": "EAL (Apeldoorn) BV", + "system_integrator": "EAL (Apeldoorn) BV" + }, + { + "application": "Access Control reader", + "company": "TIL Technologies", + "mad": "0x5319", + "service_provider": "TIL Technologies", + "system_integrator": "TIL Technologies" + }, + { + "application": "Access Control reader", + "company": "TIL Technologies", + "mad": "0x531A", + "service_provider": "TIL Technologies", + "system_integrator": "TIL Technologies" + }, + { + "application": "Access control", + "company": "BECKMANN GmbH", + "mad": "0x531B", + "service_provider": "BECKMANN GmbH", + "system_integrator": "BECKMANN GmbH" + }, + { + "application": "Access Control using DESFire EV1", + "company": "SIEMENS BT FSP SP PLAC", + "mad": "0x531C", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "", + "company": "DE NEDERLANDSCHE BANK", + "mad": "0x531D", + "service_provider": "AET Europe", + "system_integrator": "EAL NL" + }, + { + "application": "", + "company": "DE NEDERLANDSCHE BANK", + "mad": "0x531E", + "service_provider": "AET Europe", + "system_integrator": "EAL NL" + }, + { + "application": "Standalone Access Control", + "company": "Kimaldi Electronics s.l.", + "mad": "0x531F", + "service_provider": "", + "system_integrator": "KIMALDI Electronics" + }, + { + "application": "Access control & security system", + "company": "Haguess s.r.o.", + "mad": "0x5320", + "service_provider": "Haguess", + "system_integrator": "Haguess" + }, + { + "application": "Centralized access control system", + "company": "National Control Systems S.A", + "mad": "0x5321", + "service_provider": "National Control Systems S.A", + "system_integrator": "National Control Systems S.A" + }, + { + "application": "Centralized access control system", + "company": "National Control Systems S.A", + "mad": "0x5322", + "service_provider": "National Control Systems S.A", + "system_integrator": "National Control Systems S.A" + }, + { + "application": "Access/security", + "company": "ANTWERP WORLD DIAMOND CENTRE", + "mad": "0x5323", + "service_provider": "ANTWERP WORLD DIAMOND CENTRE", + "system_integrator": "Deister + Card Solutions Group" + }, + { + "application": "Acccess Control & security, Resource Acceptability and personnel identity verification", + "company": "Salamander Technologies, Inc.", + "mad": "0x5324", + "service_provider": "N/a", + "system_integrator": "n/a" + }, + { + "application": "High performance physical Accesss Control (reacting and writing on ccard in real time)", + "company": "Qontinuum Plus", + "mad": "0x5325", + "service_provider": "the users themselves", + "system_integrator": "Qontinuum Plus" + }, + { + "application": "Physical access control system", + "company": "Kaba-Ilco, Inc.", + "mad": "0x5327", + "service_provider": "KABA ILCO INC", + "system_integrator": "KABA ILCO INC" + }, + { + "application": "Physical access control system", + "company": "Kaba-Ilco, Inc.", + "mad": "0x5328", + "service_provider": "KABA ILCO INC", + "system_integrator": "KABA ILCO INC" + }, + { + "application": "Physical access control system", + "company": "Kaba-Ilco, Inc.", + "mad": "0x5329", + "service_provider": "KABA ILCO INC", + "system_integrator": "KABA ILCO INC" + }, + { + "application": "Physical access control system", + "company": "Kaba-Ilco, Inc.", + "mad": "0x532A", + "service_provider": "KABA ILCO INC", + "system_integrator": "KABA ILCO INC" + }, + { + "application": "Access Control, Biometrics, Time & attendance, network on card", + "company": "XceedID Corporation", + "mad": "0x532B", + "service_provider": "Ingersoll Rand", + "system_integrator": "Ingersoll Rand, Geoffrey Industries, Schlage, Recognition Systems" + }, + { + "application": "Access Control, Biometrics, Time & attendance, network on card", + "company": "XceedID Corporation", + "mad": "0x532C", + "service_provider": "Ingersoll Rand", + "system_integrator": "Ingersoll Rand, Geoffrey Industries, Schlage, Recognition Systems" + }, + { + "application": "Access Control, Biometrics, Time & attendance, network on card", + "company": "XceedID Corporation", + "mad": "0x532D", + "service_provider": "Ingersoll Rand", + "system_integrator": "Ingersoll Rand, Geoffrey Industries, Schlage, Recognition Systems" + }, + { + "application": "Access control & security", + "company": "Gantner Electronic GmbH", + "mad": "0x532E", + "service_provider": "GANTNER Electronic", + "system_integrator": "GANTNER Electronic" + }, + { + "application": "Standard physical access", + "company": "NXP Semiconductors Columbia PA", + "mad": "0x532F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access Control & Electronic security", + "company": "Gunnebo Electronic Security", + "mad": "0x5330", + "service_provider": "Competence Center", + "system_integrator": "GUNNEBO GES" + }, + { + "application": "Access Control & Electronic security", + "company": "Gunnebo Electronic Security", + "mad": "0x5331", + "service_provider": "Competence Center", + "system_integrator": "GUNNEBO GES" + }, + { + "application": "Access Control & Electronic security", + "company": "Gunnebo Electronic Security", + "mad": "0x5332", + "service_provider": "Competence Center", + "system_integrator": "GUNNEBO GES" + }, + { + "application": "Access Control ID", + "company": "EM Group", + "mad": "0x5333", + "service_provider": "EM GROUP", + "system_integrator": "EM GROUP" + }, + { + "application": "Access Control", + "company": "DOM Sicherheitstechnik GmbH & Co. KG", + "mad": "0x5334", + "service_provider": "DOM Sicherheitstechnik GmbH & Co.KG", + "system_integrator": "DOM Sicherheitstechnik GmbH & Co.KG" + }, + { + "application": "Access Control", + "company": "DOM Sicherheitstechnik GmbH & Co. KG", + "mad": "0x5335", + "service_provider": "DOM Sicherheitstechnik GmbH & Co.KG", + "system_integrator": "DOM Sicherheitstechnik GmbH & Co.KG" + }, + { + "application": "Access Control", + "company": "DOM Sicherheitstechnik GmbH & Co. KG", + "mad": "0x5336", + "service_provider": "DOM Sicherheitstechnik GmbH & Co.KG", + "system_integrator": "DOM Sicherheitstechnik GmbH & Co.KG" + }, + { + "application": "Access Control", + "company": "DOM Sicherheitstechnik GmbH & Co. KG", + "mad": "0x5337", + "service_provider": "DOM Sicherheitstechnik GmbH & Co.KG", + "system_integrator": "DOM Sicherheitstechnik GmbH & Co.KG" + }, + { + "application": "Access Control", + "company": "DOM Sicherheitstechnik GmbH & Co. KG", + "mad": "0x5338", + "service_provider": "DOM Sicherheitstechnik GmbH & Co.KG", + "system_integrator": "DOM Sicherheitstechnik GmbH & Co.KG" + }, + { + "application": "Access Control", + "company": "WIGOTEK, Hardware Software Beratung", + "mad": "0x5339", + "service_provider": "WIGOTEK", + "system_integrator": "WIGOTEK" + }, + { + "application": "Access Control", + "company": "WIGOTEK, Hardware Software Beratung", + "mad": "0x533A", + "service_provider": "WIGOTEK", + "system_integrator": "WIGOTEK" + }, + { + "application": "ZKS, Personalnummer, IDs, Nutzerdaten", + "company": "Primion Technology AG", + "mad": "0x533B", + "service_provider": "HDW", + "system_integrator": "Primion" + }, + { + "application": "ZKS, Personalnummer, IDs, Nutzerdaten", + "company": "Primion Technology AG", + "mad": "0x533C", + "service_provider": "HDW", + "system_integrator": "Primion" + }, + { + "application": "ZKS, Personalnummer, IDs, Nutzerdaten", + "company": "Primion Technology AG", + "mad": "0x533D", + "service_provider": "HDW", + "system_integrator": "Primion" + }, + { + "application": "ZKS, Personalnummer, IDs, Nutzerdaten", + "company": "Primion Technology AG", + "mad": "0x533E", + "service_provider": "HDW", + "system_integrator": "Primion" + }, + { + "application": "", + "company": "EVVA-Werk Gesellschaft m.b.H. & Co. KG", + "mad": "0x533F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access control and time attendance systems", + "company": "Unicard S.A.", + "mad": "0x5340", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Access control and time attendance systems", + "company": "Unicard S.A.", + "mad": "0x5341", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Access control and time attendance systems", + "company": "Unicard S.A.", + "mad": "0x5342", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Access control", + "company": "TNO ICT", + "mad": "0x5343", + "service_provider": "TNO", + "system_integrator": "TNO" + }, + { + "application": "Access control", + "company": "TNO ICT", + "mad": "0x5344", + "service_provider": "TNO", + "system_integrator": "TNO" + }, + { + "application": "Access control", + "company": "REMSDAQ LIMITED", + "mad": "0x5345", + "service_provider": "", + "system_integrator": "REMSDAQ Limited" + }, + { + "application": "Access control benefits", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x5346", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Access control & security", + "company": "Coor Service Management AB", + "mad": "0x5347", + "service_provider": "SKANDINAVISKA ENSKILDA BANKEN AB", + "system_integrator": "Coor Service Management AB" + }, + { + "application": "Access control & security", + "company": "Coor Service Management AB", + "mad": "0x5348", + "service_provider": "SKANDINAVISKA ENSKILDA BANKEN AB", + "system_integrator": "Coor Service Management AB" + }, + { + "application": "Access control & security", + "company": "Coor Service Management AB", + "mad": "0x5349", + "service_provider": "SKANDINAVISKA ENSKILDA BANKEN AB", + "system_integrator": "Coor Service Management AB" + }, + { + "application": "Access control & security", + "company": "Coor Service Management AB", + "mad": "0x534A", + "service_provider": "SKANDINAVISKA ENSKILDA BANKEN AB", + "system_integrator": "Coor Service Management AB" + }, + { + "application": "Access control & security", + "company": "Coor Service Management AB", + "mad": "0x534B", + "service_provider": "SKANDINAVISKA ENSKILDA BANKEN AB", + "system_integrator": "Coor Service Management AB" + }, + { + "application": "Access control & security", + "company": "Coor Service Management AB", + "mad": "0x534C", + "service_provider": "SKANDINAVISKA ENSKILDA BANKEN AB", + "system_integrator": "Coor Service Management AB" + }, + { + "application": "Access control, user identification, access counter", + "company": "Nordic Alarm AB", + "mad": "0x534D", + "service_provider": "Nordic Alarm AB", + "system_integrator": "Nordic Alarm AB" + }, + { + "application": "Access control, user identification, access counter", + "company": "Nordic Alarm AB", + "mad": "0x534E", + "service_provider": "Nordic Alarm AB", + "system_integrator": "Nordic Alarm AB" + }, + { + "application": "Access control security", + "company": "Mobotix AG Security Vision Systems", + "mad": "0x534F", + "service_provider": "Mobotix AG Security Vision Systems", + "system_integrator": "Mobotix AG Security Vision Systems" + }, + { + "application": "Access Control + Security", + "company": "PKE Electronics AG", + "mad": "0x5350", + "service_provider": "PKE Electronics AG", + "system_integrator": "PKE Electronics AG" + }, + { + "application": "Access Control + Security", + "company": "PKE Electronics AG", + "mad": "0x5351", + "service_provider": "PKE Electronics AG", + "system_integrator": "PKE Electronics AG" + }, + { + "application": "Access Control + Security", + "company": "PKE Electronics AG", + "mad": "0x5352", + "service_provider": "PKE Electronics AG", + "system_integrator": "PKE Electronics AG" + }, + { + "application": "Corporate ID Card BASF", + "company": "Cosmo.id GmbH", + "mad": "0x5353", + "service_provider": "Cosmo.ID", + "system_integrator": "Cosmo.ID" + }, + { + "application": "Corporate ID Crad Daimler", + "company": "Cosmo.id GmbH", + "mad": "0x5354", + "service_provider": "Cosmo.ID", + "system_integrator": "Cosmo.ID" + }, + { + "application": "Access control; Biometric template storage; Offline access control authorization storage; Cash-on card", + "company": "Siemens Building Technologies - Security Solutions - International Headquarters", + "mad": "0x5355", + "service_provider": "Siemens Building Technologies - Security Solutions -worldwide", + "system_integrator": "Siemens Building Technologies - Security Solutions -worldwide" + }, + { + "application": "Access control; Biometric template storage; Offline access control authorization storage; Cash-on card", + "company": "Siemens Building Technologies - Security Solutions - International Headquarters", + "mad": "0x5356", + "service_provider": "Siemens Building Technologies - Security Solutions -worldwide", + "system_integrator": "Siemens Building Technologies - Security Solutions -worldwide" + }, + { + "application": "Access control; Biometric template storage; Offline access control authorization storage; Cash-on card", + "company": "Siemens Building Technologies - Security Solutions - International Headquarters", + "mad": "0x5357", + "service_provider": "Siemens Building Technologies - Security Solutions -worldwide", + "system_integrator": "Siemens Building Technologies - Security Solutions -worldwide" + }, + { + "application": "Access control; Biometric template storage; Offline access control authorization storage; Cash-on card", + "company": "Siemens Building Technologies - Security Solutions - International Headquarters", + "mad": "0x5358", + "service_provider": "Siemens Building Technologies - Security Solutions -worldwide", + "system_integrator": "Siemens Building Technologies - Security Solutions -worldwide" + }, + { + "application": "Access control, security", + "company": "Westec AS", + "mad": "0x5359", + "service_provider": "Westec AS", + "system_integrator": "Westec" + }, + { + "application": "Access control, security", + "company": "Westec AS", + "mad": "0x535A", + "service_provider": "Westec AS", + "system_integrator": "Westec" + }, + { + "application": "Access control, security", + "company": "Westec AS", + "mad": "0x535B", + "service_provider": "Westec AS", + "system_integrator": "Westec" + }, + { + "application": "Access control, security", + "company": "Westec AS", + "mad": "0x535C", + "service_provider": "Westec AS", + "system_integrator": "Westec" + }, + { + "application": "Access control, security", + "company": "Avinor AS", + "mad": "0x535D", + "service_provider": "Avinor AS", + "system_integrator": "Westec AS" + }, + { + "application": "Access Control", + "company": "AMC - Academic Hospital", + "mad": "0x535E", + "service_provider": "EAL (Apeldoorn) B.V.", + "system_integrator": "EAL (Apeldoorn) B.V." + }, + { + "application": "Access control & security", + "company": "Axel Springer AG", + "mad": "0x535F", + "service_provider": "Axel Springer AG", + "system_integrator": "Axel Springer AG" + }, + { + "application": "Access control & security", + "company": "Axel Springer AG", + "mad": "0x5360", + "service_provider": "Axel Springer AG", + "system_integrator": "Axel Springer AG" + }, + { + "application": "Access control & security", + "company": "Axel Springer AG", + "mad": "0x5361", + "service_provider": "Axel Springer AG", + "system_integrator": "Axel Springer AG" + }, + { + "application": "Access Control", + "company": "Universite de Luxembourg", + "mad": "0x5362", + "service_provider": "EAL (Apeldoorn) B.V.", + "system_integrator": "EAL (Apeldoorn) B.V." + }, + { + "application": "Access control, intruder alarm, time & attendance", + "company": "Novar GmbH- Honeywell Security", + "mad": "0x5363", + "service_provider": "NOVAR, HONEYWELL", + "system_integrator": "" + }, + { + "application": "Access Control & Security", + "company": "Vattenfall Research & Development AB", + "mad": "0x5364", + "service_provider": "Vattenfall AB", + "system_integrator": "Coor Service Vattenfall AB" + }, + { + "application": "Access control system", + "company": "ISEO/ATG", + "mad": "0x5365", + "service_provider": "ISEO/ATG", + "system_integrator": "ISEO/ATG" + }, + { + "application": "Access control system", + "company": "ISEO/ATG", + "mad": "0x5366", + "service_provider": "ISEO/ATG", + "system_integrator": "ISEO/ATG" + }, + { + "application": "Access control system", + "company": "ISEO/ATG", + "mad": "0x5367", + "service_provider": "ISEO/ATG", + "system_integrator": "ISEO/ATG" + }, + { + "application": "Access Control, ID Badge, Payment", + "company": "Danfoss A/S", + "mad": "0x5368", + "service_provider": "Vitani A/S", + "system_integrator": "Vitani A/S" + }, + { + "application": "Access control, security and monitoring", + "company": "Atelei Engineering SLU", + "mad": "0x5369", + "service_provider": "Atelei Engineering", + "system_integrator": "Atelei Engineering" + }, + { + "application": "Access Control", + "company": "Teratron GmbH", + "mad": "0x536A", + "service_provider": "Teratron GmbH", + "system_integrator": "Teratron GmbH" + }, + { + "application": "Access Control", + "company": "Assa Abloy (Switzerland)", + "mad": "0x536B", + "service_provider": "Assa Abloy (Switzerland)", + "system_integrator": "Assa Abloy (Switzerland)" + }, + { + "application": "Servicios de Identificacion/Presenncia Corporation; control de Accesos y seguridad", + "company": "IZENPE", + "mad": "0x5401", + "service_provider": "IZENPE", + "system_integrator": "IZENPE" + }, + { + "application": "Servicios de Identificacion/Presenncia Corporation; control de Accesos y seguridad", + "company": "IZENPE", + "mad": "0x5402", + "service_provider": "IZENPE", + "system_integrator": "IZENPE" + }, + { + "application": "Servicios de Identificacion/Presenncia Corporation; control de Accesos y seguridad", + "company": "IZENPE", + "mad": "0x5403", + "service_provider": "IZENPE", + "system_integrator": "IZENPE" + }, + { + "application": "Servicios de Identificacion/Presenncia Corporation; control de Accesos y seguridad", + "company": "IZENPE", + "mad": "0x5404", + "service_provider": "IZENPE", + "system_integrator": "IZENPE" + }, + { + "application": "Corporate ID Card BASF", + "company": "Cosmo.id GmbH", + "mad": "0x5405", + "service_provider": "Cosmo.id", + "system_integrator": "Cosmo.id" + }, + { + "application": "Electrical vehicle charging", + "company": "EnBW Energie Baden-Württemberg AG", + "mad": "0x5406", + "service_provider": "EnBW Systeme Infrastruktur Support GmbH", + "system_integrator": "EnBW Systeme Infrastruktur Support GmbH" + }, + { + "application": "Electronic Access Control Systems EZK", + "company": "Franz Schneider Brakel GmbH + Co KG", + "mad": "0x5407", + "service_provider": "", + "system_integrator": "Franz Schneider Brakel GmbH + Co KG" + }, + { + "application": "Access control & security", + "company": "SCM Microsystems Gmbh", + "mad": "0x5408", + "service_provider": "SCM Microsystems Gmbh", + "system_integrator": "" + }, + { + "application": "Access control and key management system", + "company": "ALCEA", + "mad": "0x5409", + "service_provider": "ALCEA", + "system_integrator": "ALCEA" + }, + { + "application": "Access control and key management system", + "company": "ALCEA", + "mad": "0x540A", + "service_provider": "ALCEA", + "system_integrator": "ALCEA" + }, + { + "application": "Smart City Card \\Schwabencard\"\"", + "company": "Cosmo.id GmbH", + "mad": "0x540B", + "service_provider": "Cosmo.id", + "system_integrator": "Cosmo.id" + }, + { + "application": "Physical access control; Photo; Biometrics data; hourly management; Canteen", + "company": "France Telecom SA", + "mad": "0x540C", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Physical access control; Photo; Biometrics data; hourly management; Canteen", + "company": "France Telecom SA", + "mad": "0x540D", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Physical access control; Photo; Biometrics data; hourly management; Canteen", + "company": "France Telecom SA", + "mad": "0x540E", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Physical access control; Photo; Biometrics data; hourly management; Canteen", + "company": "France Telecom SA", + "mad": "0x540F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Physical access control; Photo; Biometrics data; hourly management; Canteen", + "company": "France Telecom SA", + "mad": "0x5410", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Access control", + "company": "Medisch Centrum Alkmaar", + "mad": "0x5411", + "service_provider": "EAL (Apeldoorn) B.V.", + "system_integrator": "EAL (Apeldoorn) B.V." + }, + { + "application": "Access control, benefits", + "company": "OREDO s.r.o", + "mad": "0x5412", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Access control", + "company": "Synchronic", + "mad": "0x5413", + "service_provider": "R&D Synchronic", + "system_integrator": "SYNCHRONIC" + }, + { + "application": "Access Control System", + "company": "Glutz AG, Swiss Access Systems", + "mad": "0x5414", + "service_provider": "Glutz AG", + "system_integrator": "Glutz AG" + }, + { + "application": "Access Control System", + "company": "Glutz AG, Swiss Access Systems", + "mad": "0x5415", + "service_provider": "Glutz AG", + "system_integrator": "Glutz AG" + }, + { + "application": "Access control, security, identification and business services", + "company": "Amtac Professional Services Ptv Ltd", + "mad": "0x5416", + "service_provider": "Amtac Professional Services Ptv Ltd", + "system_integrator": "Amtac Professional Services Ptv Ltd" + }, + { + "application": "Access control, security, identification and business services", + "company": "Amtac Professional Services Ptv Ltd", + "mad": "0x5417", + "service_provider": "Amtac Professional Services Ptv Ltd", + "system_integrator": "Amtac Professional Services Ptv Ltd" + }, + { + "application": "Identification services", + "company": "EasyCheck GmbH", + "mad": "0x5418", + "service_provider": "Stadt Duisburg", + "system_integrator": "Stadt Duisburg" + }, + { + "application": "Access Control, ID Badge, Payment & Hotel", + "company": "Danish Defence", + "mad": "0x5419", + "service_provider": "Vitani A/S", + "system_integrator": "Vitani A/S" + }, + { + "application": "Access control, security and monitoring", + "company": "Atelei Engineering SLU", + "mad": "0x541A", + "service_provider": "Atelei Engineering", + "system_integrator": "Atelei Engineering" + }, + { + "application": "Access to datacenter, cass, rows, disable alarm+security system, employee ID-card", + "company": "VegaSystems", + "mad": "0x541B", + "service_provider": "VegaSystems", + "system_integrator": "VegaSystems" + }, + { + "application": "Academic Services, Electronic Purse, Access control & security", + "company": "CNA Limited/Rax-Comm Systems Ltd.", + "mad": "0x5801", + "service_provider": "CNA Limited", + "system_integrator": "CNA Limited" + }, + { + "application": "Universitz Student & Staff Identification", + "company": "CNA Limited/Rax-Comm Systems Ltd.", + "mad": "0x5802", + "service_provider": "CNA Limited", + "system_integrator": "CNA Limited" + }, + { + "application": "Student/stuff ID Card Travel Pass, Library Card, Photocopy Control & Meal Payment", + "company": "University of Warwick", + "mad": "0x5803", + "service_provider": "University of Warwick", + "system_integrator": "University of Warwick" + }, + { + "application": "Student/stuff ID Card Travel Pass, Library Card, Photocopy Control & Meal Payment", + "company": "University of Warwick", + "mad": "0x5804", + "service_provider": "University of Warwick", + "system_integrator": "University of Warwick" + }, + { + "application": "Student/stuff ID Card Travel Pass, Library Card, Photocopy Control & Meal Payment", + "company": "University of Warwick", + "mad": "0x5805", + "service_provider": "University of Warwick", + "system_integrator": "University of Warwick" + }, + { + "application": "Student/stuff ID Card Travel Pass, Library Card, Photocopy Control & Meal Payment", + "company": "University of Warwick", + "mad": "0x5806", + "service_provider": "University of Warwick", + "system_integrator": "University of Warwick" + }, + { + "application": "Student/stuff ID Card Travel Pass, Library Card, Photocopy Control & Meal Payment", + "company": "University of Warwick", + "mad": "0x5807", + "service_provider": "University of Warwick", + "system_integrator": "University of Warwick" + }, + { + "application": "Accademic services", + "company": "Innolab Private Ltd", + "mad": "0x5809", + "service_provider": "National University of Singapore", + "system_integrator": "Innolab Private Ltd" + }, + { + "application": "Accademic services", + "company": "Innolab Private Ltd", + "mad": "0x580A", + "service_provider": "National University of Singapore", + "system_integrator": "Innolab Private Ltd" + }, + { + "application": "Accademic services", + "company": "Innolab Private Ltd", + "mad": "0x580B", + "service_provider": "National University of Singapore", + "system_integrator": "Innolab Private Ltd" + }, + { + "application": "Accademic services", + "company": "Innolab Private Ltd", + "mad": "0x580C", + "service_provider": "National University of Singapore", + "system_integrator": "Innolab Private Ltd" + }, + { + "application": "Accademic services", + "company": "Innolab Private Ltd", + "mad": "0x580D", + "service_provider": "National University of Singapore", + "system_integrator": "Innolab Private Ltd" + }, + { + "application": "Accademic services", + "company": "Innolab Private Ltd", + "mad": "0x580E", + "service_provider": "National University of Singapore", + "system_integrator": "Innolab Private Ltd" + }, + { + "application": "Academic identity cards", + "company": "Maximus", + "mad": "0x580F", + "service_provider": "Maximus Inc", + "system_integrator": "Maximus Inc" + }, + { + "application": "Basic cardholder info", + "company": "Cambridge University - Institute for Manufacturing", + "mad": "0x5810", + "service_provider": "Cambridge University", + "system_integrator": "Cambridge University" + }, + { + "application": "Basic cardholder info", + "company": "Cambridge University - Institute for Manufacturing", + "mad": "0x5811", + "service_provider": "Cambridge University", + "system_integrator": "Cambridge University" + }, + { + "application": "Basic cardholder info", + "company": "Cambridge University - Institute for Manufacturing", + "mad": "0x5812", + "service_provider": "Cambridge University", + "system_integrator": "Cambridge University" + }, + { + "application": "Basic cardholder info", + "company": "Cambridge University - Institute for Manufacturing", + "mad": "0x5813", + "service_provider": "Cambridge University", + "system_integrator": "Cambridge University" + }, + { + "application": "Academic services", + "company": "Invest Solutions Limited", + "mad": "0x5814", + "service_provider": "Invest Solutions", + "system_integrator": "Invest Solutions" + }, + { + "application": "Academic services", + "company": "Invest Solutions Limited", + "mad": "0x5815", + "service_provider": "Invest Solutions", + "system_integrator": "Invest Solutions" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0x5816", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "Student, staff ID card", + "company": "University of Bolton", + "mad": "0x5817", + "service_provider": "University of Bolton", + "system_integrator": "University of Bolton" + }, + { + "application": "Student, staff ID card", + "company": "University of Bolton", + "mad": "0x5818", + "service_provider": "University of Bolton", + "system_integrator": "University of Bolton" + }, + { + "application": "Student, staff ID card", + "company": "University of Bolton", + "mad": "0x5819", + "service_provider": "University of Bolton", + "system_integrator": "University of Bolton" + }, + { + "application": "Student, staff ID card", + "company": "University of Bolton", + "mad": "0x581A", + "service_provider": "University of Bolton", + "system_integrator": "University of Bolton" + }, + { + "application": "Railway pass, univers pass, library", + "company": "Emcard a.s.", + "mad": "0x581B", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Railway pass, univers pass, library", + "company": "Emcard a.s.", + "mad": "0x581C", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "University Card", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x581D", + "service_provider": "Faculty of EE & Computing, Ministry of Science, Technolgoy and Education", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "University Card", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x581E", + "service_provider": "Faculty of EE & Computing, Ministry of Science, Technolgoy and Education", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "University Card", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x581F", + "service_provider": "Faculty of EE & Computing, Ministry of Science, Technolgoy and Education", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "University Campus Card", + "company": "Smartchip S.A.", + "mad": "0x5820", + "service_provider": "Universidad U.P.B.", + "system_integrator": "Smartchip S.A." + }, + { + "application": "High school pass", + "company": "Emcard a.s.", + "mad": "0x5821", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Academic services", + "company": "University of Bath", + "mad": "0x5822", + "service_provider": "University Bath", + "system_integrator": "Royall Security Systems" + }, + { + "application": "Student/stuff ID, library ID, access control, purse 1, purse 2, electroral rights indicator", + "company": "Universität Ulm", + "mad": "0x5823", + "service_provider": "University of Ulm", + "system_integrator": "University of Ulm" + }, + { + "application": "Student/stuff ID, library ID, access control, purse 1, purse 2, electroral rights indicator", + "company": "Universität Ulm", + "mad": "0x5824", + "service_provider": "University of Ulm", + "system_integrator": "University of Ulm" + }, + { + "application": "Student/stuff ID, library ID, access control, purse 1, purse 2, electroral rights indicator", + "company": "Universität Ulm", + "mad": "0x5825", + "service_provider": "University of Ulm", + "system_integrator": "University of Ulm" + }, + { + "application": "Student/stuff ID, library ID, access control, purse 1, purse 2, electroral rights indicator", + "company": "Universität Ulm", + "mad": "0x5826", + "service_provider": "University of Ulm", + "system_integrator": "University of Ulm" + }, + { + "application": "Student/stuff ID, library ID, access control, purse 1, purse 2, electroral rights indicator", + "company": "Universität Ulm", + "mad": "0x5827", + "service_provider": "University of Ulm", + "system_integrator": "University of Ulm" + }, + { + "application": "Student/stuff ID, library ID, access control, purse 1, purse 2, electroral rights indicator", + "company": "Universität Ulm", + "mad": "0x5828", + "service_provider": "University of Ulm", + "system_integrator": "University of Ulm" + }, + { + "application": "University Card (Academic Applications)", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x5829", + "service_provider": "Faculty of EE & Computing", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "University Card (Academic Applications)", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x582A", + "service_provider": "Faculty of EE & Computing", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "University Card (Academic Applications)", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x582B", + "service_provider": "Faculty of EE & Computing", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "University Card (Academic Applications)", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x582C", + "service_provider": "Faculty of EE & Computing", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "University Card (Academic Applications)", + "company": "Faculty of Electrical Engineering and Computing", + "mad": "0x582D", + "service_provider": "Faculty of EE & Computing", + "system_integrator": "Faculty of EE & Computing" + }, + { + "application": "Academic services, food", + "company": "FH Studienbetriebs GmbH", + "mad": "0x582E", + "service_provider": "FH 00E Studienbetriebs GmbH, HSSE", + "system_integrator": "FH 00E Studienbetriebs GmbH, HSSE" + }, + { + "application": "Library card", + "company": "Technical University Of Szczecin", + "mad": "0x582F", + "service_provider": "techn University Szczecin", + "system_integrator": "techn University Szczecin" + }, + { + "application": "Student/Staff IC Card", + "company": "University of Chester", + "mad": "0x5830", + "service_provider": "University of Chester", + "system_integrator": "University of Chester" + }, + { + "application": "Student/Staff IC Card", + "company": "University of Chester", + "mad": "0x5831", + "service_provider": "University of Chester", + "system_integrator": "University of Chester" + }, + { + "application": "Student/Staff IC Card", + "company": "University of Chester", + "mad": "0x5832", + "service_provider": "University of Chester", + "system_integrator": "University of Chester" + }, + { + "application": "Student/Staff IC Card", + "company": "University of Chester", + "mad": "0x5833", + "service_provider": "University of Chester", + "system_integrator": "University of Chester" + }, + { + "application": "Student/Staff IC Card", + "company": "University of Chester", + "mad": "0x5834", + "service_provider": "University of Chester", + "system_integrator": "University of Chester" + }, + { + "application": "University Campus Card", + "company": "Smartchip S.A.", + "mad": "0x5835", + "service_provider": "Universidad EAFIT", + "system_integrator": "Smartchip S.A." + }, + { + "application": "Online Activity Registration and Ticketing (education)", + "company": "PinCash International", + "mad": "0x5836", + "service_provider": "Pincash international BV", + "system_integrator": "Pincash international BV" + }, + { + "application": "University Card, Library Card, Studen/Staff ID, Academic services", + "company": "Stockholm University", + "mad": "0x5837", + "service_provider": "Stockholm University", + "system_integrator": "Stockholm University" + }, + { + "application": "University Card, Library Card, Studen/Staff ID, Academic services", + "company": "Stockholm University", + "mad": "0x5838", + "service_provider": "Stockholm University", + "system_integrator": "Stockholm University" + }, + { + "application": "University Card, Library Card, Studen/Staff ID, Academic services", + "company": "Stockholm University", + "mad": "0x5839", + "service_provider": "Stockholm University", + "system_integrator": "Stockholm University" + }, + { + "application": "University Card, Library Card, Studen/Staff ID, Academic services", + "company": "Stockholm University", + "mad": "0x583A", + "service_provider": "Stockholm University", + "system_integrator": "Stockholm University" + }, + { + "application": "University Campus Card", + "company": "Smartchip S.A.", + "mad": "0x583B", + "service_provider": "Colegiatura Colombiana", + "system_integrator": "SMARTCHIP S.A." + }, + { + "application": "Student/personnel authentication & identification card", + "company": "Hogeschool Gent", + "mad": "0x583C", + "service_provider": "Associatie Universiteit Gent", + "system_integrator": "Universiteit Gent, Hogeschool Gent, Arteveldeschool, Hogeschool West-Vlaanderen" + }, + { + "application": "Student/personnel authentication & identification card", + "company": "Hogeschool Gent", + "mad": "0x583D", + "service_provider": "Associatie Universiteit Gent", + "system_integrator": "Universiteit Gent, Hogeschool Gent, Arteveldeschool, Hogeschool West-Vlaanderen" + }, + { + "application": "Student/personnel authentication & identification card", + "company": "Hogeschool Gent", + "mad": "0x583E", + "service_provider": "Associatie Universiteit Gent", + "system_integrator": "Universiteit Gent, Hogeschool Gent, Arteveldeschool, Hogeschool West-Vlaanderen" + }, + { + "application": "Student/personnel authentication & identification card", + "company": "Hogeschool Gent", + "mad": "0x583F", + "service_provider": "Associatie Universiteit Gent", + "system_integrator": "Universiteit Gent, Hogeschool Gent, Arteveldeschool, Hogeschool West-Vlaanderen" + }, + { + "application": "Studen/personnel authentication & identification card", + "company": "Hogeschool Gent", + "mad": "0x5840", + "service_provider": "Associatie Universiteit Gent", + "system_integrator": "Associatie Universiteit Gent" + }, + { + "application": "Academic services", + "company": "Group Capmonetique", + "mad": "0x5841", + "service_provider": "MONECARTE", + "system_integrator": "MONECARTE" + }, + { + "application": "Academic services", + "company": "Group Capmonetique", + "mad": "0x5842", + "service_provider": "MONECARTE", + "system_integrator": "MONECARTE" + }, + { + "application": "Academic services", + "company": "Group Capmonetique", + "mad": "0x5843", + "service_provider": "MONECARTE", + "system_integrator": "MONECARTE" + }, + { + "application": "Academic services", + "company": "Group Capmonetique", + "mad": "0x5844", + "service_provider": "MONECARTE", + "system_integrator": "MONECARTE" + }, + { + "application": "Multifunctional IT", + "company": "InterCard AG Informationssysteme", + "mad": "0x5845", + "service_provider": "InterCard", + "system_integrator": "InterCard" + }, + { + "application": "Multifunctional IT", + "company": "InterCard AG Informationssysteme", + "mad": "0x5846", + "service_provider": "InterCard", + "system_integrator": "InterCard" + }, + { + "application": "Multifunctional IT", + "company": "InterCard AG Informationssysteme", + "mad": "0x5847", + "service_provider": "InterCard", + "system_integrator": "InterCard" + }, + { + "application": "Multifunctional IT", + "company": "InterCard AG Informationssysteme", + "mad": "0x5848", + "service_provider": "InterCard", + "system_integrator": "InterCard" + }, + { + "application": "Student and staff identification, access control, attendance monitoring, cashless vending", + "company": "Computer Centre, Lancaster University", + "mad": "0x5849", + "service_provider": "Lancaster University", + "system_integrator": "Lancaster University" + }, + { + "application": "Student and staff identification, access control, attendance monitoring, cashless vending", + "company": "Computer Centre, Lancaster University", + "mad": "0x584A", + "service_provider": "Lancaster University", + "system_integrator": "Lancaster University" + }, + { + "application": "Student and staff identification, access control, attendance monitoring, cashless vending", + "company": "Computer Centre, Lancaster University", + "mad": "0x584B", + "service_provider": "Lancaster University", + "system_integrator": "Lancaster University" + }, + { + "application": "Student and staff identification, access control, attendance monitoring, cashless vending", + "company": "Computer Centre, Lancaster University", + "mad": "0x584C", + "service_provider": "Lancaster University", + "system_integrator": "Lancaster University" + }, + { + "application": "Academic services", + "company": "Gantner Electronic GmbH", + "mad": "0x584D", + "service_provider": "GANTNER Electronic", + "system_integrator": "GANTNER Electronic" + }, + { + "application": "Library card", + "company": "Vienna University of Economics", + "mad": "0x584E", + "service_provider": "Vienna University of Economics", + "system_integrator": "Vienna University of Economics" + }, + { + "application": "University campus card", + "company": "Smartchip S.A.", + "mad": "0x584F", + "service_provider": "Universidad de Antioquia - UedA", + "system_integrator": "Smartchip SA" + }, + { + "application": "Sttuden/personnel access control", + "company": "Caja General de Ahorros de Canarias", + "mad": "0x5850", + "service_provider": "Universidad de La laguna-ULL", + "system_integrator": "CajaCanarias" + }, + { + "application": "Academic services", + "company": "Emtest a.s.", + "mad": "0x5851", + "service_provider": "Ministry of Education of Slovak republic", + "system_integrator": "EMtest-SK, s.r.o." + }, + { + "application": "Internal identification", + "company": "HUB-EHSAL VZW", + "mad": "0x5852", + "service_provider": "HUB", + "system_integrator": "" + }, + { + "application": "University/Campus applications", + "company": "Burall InfoSmart Ltd", + "mad": "0x5853", + "service_provider": "Burall InfoSmart Ltd", + "system_integrator": "Burall InfoSmart Ltd" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x5854", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x5855", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x5856", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x5857", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x5858", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x5859", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x585A", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "University student identification", + "company": "Pro Active", + "mad": "0x585B", + "service_provider": "CNOUS", + "system_integrator": "Pro Active SAS" + }, + { + "application": "Wittenborg Caterchip 2002", + "company": "Ing. Büro Schrick", + "mad": "0x6001", + "service_provider": "Wittenborg Automaten GmbH", + "system_integrator": "Ing. Büro Schrick" + }, + { + "application": "Elecronic food voucher", + "company": "GRUPO VR", + "mad": "0x6002", + "service_provider": "Grupo VR", + "system_integrator": "" + }, + { + "application": "Elecronic supermarket voucher", + "company": "GRUPO VR", + "mad": "0x6003", + "service_provider": "Gruop VR", + "system_integrator": "" + }, + { + "application": "Access controll security payment", + "company": "Matsushita Communication Industrial", + "mad": "0x6004", + "service_provider": "Matsushita Communication", + "system_integrator": "Matsushita Communication" + }, + { + "application": "Electronic food voucher", + "company": "Smart Net Brasil LTDA", + "mad": "0x6005", + "service_provider": "Smart.net Brasil LTDA", + "system_integrator": "Smart.net Brasil LTDA" + }, + { + "application": "Electronic food voucher", + "company": "Smart Net Brasil LTDA", + "mad": "0x6006", + "service_provider": "Smart.net Brasil LTDA", + "system_integrator": "Smart.net Brasil LTDA" + }, + { + "application": "Electronic food voucher", + "company": "Smart Net Brasil LTDA", + "mad": "0x6007", + "service_provider": "Smart.net Brasil LTDA", + "system_integrator": "Smart.net Brasil LTDA" + }, + { + "application": "Electronic food voucher", + "company": "Smart Net Brasil LTDA", + "mad": "0x6008", + "service_provider": "Smart.net Brasil LTDA", + "system_integrator": "Smart.net Brasil LTDA" + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0x6009", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Cshless Payment f. catering/vending", + "company": "VMC House", + "mad": "0x600A", + "service_provider": "VMC", + "system_integrator": "VMC" + }, + { + "application": "Food services", + "company": "Emcard a.s.", + "mad": "0x600B", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "Academic services, food", + "company": "FH Studienbetriebs GmbH", + "mad": "0x600C", + "service_provider": "FH 00E Studienbetriebs GmbH, HSSE", + "system_integrator": "FH 00E Studienbetriebs GmbH, HSSE" + }, + { + "application": "Academic services, food", + "company": "FH Studienbetriebs GmbH", + "mad": "0x600D", + "service_provider": "FH 00E Studienbetriebs GmbH, HSSE", + "system_integrator": "FH 00E Studienbetriebs GmbH, HSSE" + }, + { + "application": "Menue@web", + "company": "Hofmann Menü-Manufaktur GmbH", + "mad": "0x600F", + "service_provider": "Hofmann Menü-Manufaktur GmbH", + "system_integrator": "Hofmann Menü-Manufaktur GmbH" + }, + { + "application": "Food, Payment in restaurant for employees", + "company": "AB Angpanneföreningen", + "mad": "0x6010", + "service_provider": "AB Angpanneföreningen", + "system_integrator": "AB Angpanneföreningen" + }, + { + "application": "Vending", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x6011", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Vending", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x6012", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Vending", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x6013", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Vending", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x6014", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Food Vending and control", + "company": "N&W Innovative Solutions", + "mad": "0x6015", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Food Vending and control", + "company": "N&W Innovative Solutions", + "mad": "0x6016", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Food Vending and control", + "company": "N&W Innovative Solutions", + "mad": "0x6017", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Food Vending and control", + "company": "N&W Innovative Solutions", + "mad": "0x6018", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Retail identification and customer loyalty", + "company": "Unisys New Zealand Ltd", + "mad": "0x6801", + "service_provider": "Unisys", + "system_integrator": "Unisys" + }, + { + "application": "Access control, time attendance, bus ticket, hotel room card, VIP card f. club", + "company": "Giga-TMS Inc", + "mad": "0x7001", + "service_provider": "Giga TMS", + "system_integrator": "Giga TMS" + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0x7002", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Car parking, sport applic, hotel, access control systems", + "company": "DATASEC Electronic GmbH", + "mad": "0x7003", + "service_provider": "Datasec", + "system_integrator": "Datatsec" + }, + { + "application": "Hotel, acces control & security", + "company": "Talleres De Escoriaza S.A.", + "mad": "0x7004", + "service_provider": "Talleres", + "system_integrator": "Talleres" + }, + { + "application": "Energy Saving System For Hotels, Access Control", + "company": "ENKOA System", + "mad": "0x7005", + "service_provider": "Enkoa System S.L.", + "system_integrator": "Enkoa System S.L." + }, + { + "application": "Hotel, access contr. & sec", + "company": "Vingcard a.s.", + "mad": "0x7006", + "service_provider": "Vingcard", + "system_integrator": "Vingcard" + }, + { + "application": "Hotel, access contr. & sec", + "company": "Vingcard a.s.", + "mad": "0x7007", + "service_provider": "Vingcard", + "system_integrator": "Vingcard" + }, + { + "application": "Multi Application Purse - Access-Parking", + "company": "MCF RF TECH SRL", + "mad": "0x7008", + "service_provider": "MCF RF TECH S.R.L.", + "system_integrator": "MCF RF TECH S.R.L." + }, + { + "application": "Access control data for electronic locks", + "company": "Timelox AB", + "mad": "0x7009", + "service_provider": "Timelox AB", + "system_integrator": "Timelox AB" + }, + { + "application": "Energy Saving System", + "company": "ENKOA System", + "mad": "0x700A", + "service_provider": "ENKOA System S.L.", + "system_integrator": "ENKOA System S.L." + }, + { + "application": "Energy Saving System", + "company": "ENKOA System", + "mad": "0x700B", + "service_provider": "ENKOA System S.L.", + "system_integrator": "ENKOA System S.L." + }, + { + "application": "Energy Saving System", + "company": "ENKOA System", + "mad": "0x700C", + "service_provider": "ENKOA System S.L.", + "system_integrator": "ENKOA System S.L." + }, + { + "application": "Hotel", + "company": "SIT Solution for IT Payment GmbH", + "mad": "0x700D", + "service_provider": "SIT Solution for IT Payment GmbH", + "system_integrator": "SIT Solution for IT Payment GmbH" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7502", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7503", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7504", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7505", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7506", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7507", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7508", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7509", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x750A", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x750B", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x750C", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x750D", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x750E", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x750F", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7510", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7511", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7512", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7513", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7514", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7515", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7516", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7517", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7518", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7519", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x751A", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x751B", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x751C", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x751D", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x751E", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x751F", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7520", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional id card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7521", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7522", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7523", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7524", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7525", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7526", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7527", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7528", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7529", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x752A", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x752B", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x752C", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x752D", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x752E", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x752F", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7530", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7531", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7532", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7533", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7534", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7535", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7536", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7537", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7538", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7539", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x753A", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x753B", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x753C", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x753D", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x753E", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x753F", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7540", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Multifunctional ID Card", + "company": "Fraport AG - Frankfurt Airport Services Worldwide", + "mad": "0x7541", + "service_provider": "Fraport AG", + "system_integrator": "Fraport AG" + }, + { + "application": "Access and tiketting system for car sharing", + "company": "Mobility Car Sharing", + "mad": "0x7801", + "service_provider": "Bw-digitronik ag", + "system_integrator": "bw-digitronik ag" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7901", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7902", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7903", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7904", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7905", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7906", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7907", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7908", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7909", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x790A", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x790B", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x790C", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x790D", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x790E", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x790F", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Rijkspas an accescard for Dutch governemental ministries and agencies", + "company": "ICTU", + "mad": "0x7910", + "service_provider": "ICTU", + "system_integrator": "ICTU" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8001", + "service_provider": "Austream", + "system_integrator": "Austream" + }, + { + "application": "Access control system, time & attendance system", + "company": "Custom Micro Products Ltd.", + "mad": "0x8002", + "service_provider": "Custom Micro Products Ltd", + "system_integrator": "Custom Micro Products Ltd" + }, + { + "application": "Busticketing System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8003", + "service_provider": "King Man County Public Traffic", + "system_integrator": "Barouh Electronic Co." + }, + { + "application": "Building Management System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8004", + "service_provider": "VFJ Hong Kong", + "system_integrator": "VFJ Hong Kong" + }, + { + "application": "Security and safty services", + "company": "Staat der Nederlanden, Ministerie van Financien Belastingdienst/Centrum voor facilitaire dienstverlening", + "mad": "0x8006", + "service_provider": "Siemens Nederland BV", + "system_integrator": "Siemens Nederland BV" + }, + { + "application": "Zeiterfassung, Werks- bzw. Gebäudezutritt", + "company": "Voestalpine Informationstechnologie GmbH", + "mad": "0x8007", + "service_provider": "Voestalpine Informationstechnologie GmbH", + "system_integrator": "Voestalpine Informationstechnologie GmbH" + }, + { + "application": "Accesss control in sport stadiums and e-purse", + "company": "FortressGb", + "mad": "0x8008", + "service_provider": "FORTRESSGB", + "system_integrator": "FORTRESSGB" + }, + { + "application": "Personal social status information", + "company": "Civil Registry Agency of the Ministry of Justice of Georgia", + "mad": "0x8009", + "service_provider": "Civil Registry Agency of the Ministry of Justice of Georgia", + "system_integrator": "" + }, + { + "application": "Bargeldlose Abrechnungs-Systeme für Casino- u. Gemeinschaftsverpflegung", + "company": "EKS GmbH", + "mad": "0x8801", + "service_provider": "", + "system_integrator": "EKS GmbH" + }, + { + "application": "Tollway system", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8802", + "service_provider": "VFJ Technology Pty Ltd", + "system_integrator": "Chendu Shuguang Optical Fibre Network (Ltd. China)" + }, + { + "application": "Tollway system", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8803", + "service_provider": "VFJ Technology Pty Ltd", + "system_integrator": "Chendu Shuguang Optical Fibre Network (Ltd. China)" + }, + { + "application": "Automatic Fare Collection city and intercity bus traffic electronic purse", + "company": "Trgovina in Informatika d.o.o.", + "mad": "0x8804", + "service_provider": "Fourth Way - Alpetour", + "system_integrator": "Fourth Way" + }, + { + "application": "Employer indentification card", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8805", + "service_provider": "VFJ Electronics Pty Ltd.", + "system_integrator": "VFJ Electronics PTy Ltd." + }, + { + "application": "City Transport (Metro ticketing, bus ticket)", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8806", + "service_provider": "VFJ Electronic Pty Ltd.", + "system_integrator": "Cubic - VFJ" + }, + { + "application": "Time attandence, access control + security, electronic purse, plant data collection", + "company": "LNI Ingenieurgesellschaft für Kommunikationstechnik mbH", + "mad": "0x8807", + "service_provider": "LNI GmbH", + "system_integrator": "LNI GmbH" + }, + { + "application": "Intelligent Estate Management System", + "company": "Rax Comm Systems Limited", + "mad": "0x8808", + "service_provider": "Rax Comm Systems Limited", + "system_integrator": "Rax Comm Systems Limited" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8809", + "service_provider": "Xiamto Lintong Tollway", + "system_integrator": "" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x880A", + "service_provider": "Xiamto Lintong Tollway", + "system_integrator": "" + }, + { + "application": "Access Controll, Security Electronic Purse, Ski-Ticketing, Ticketing", + "company": "*Siemens ANL", + "mad": "0x880B", + "service_provider": "", + "system_integrator": "Siemens AG" + }, + { + "application": "DEM Komponenten für Zutrittskontrolle, Zeiterfassung, Betribsdatenerfassung, Kantine, Automaten, Tankdatenerf.", + "company": "Phg Peter Hengstler GmbH", + "mad": "0x880C", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Electronic Purse for Casino and comon catering", + "company": "EKS GmbH", + "mad": "0x880D", + "service_provider": "", + "system_integrator": "EKS" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x880E", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x880F", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x8810", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x8811", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "OEM-Komponenten für Zutrittskontrolle, Zeiterfassung, elektr. Geldbörse,...", + "company": "Peter Hengstler GmbH + Co KG", + "mad": "0x8812", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Tollway", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8813", + "service_provider": "Austream", + "system_integrator": "Austream" + }, + { + "application": "Transport Ticketing, E-Purse, Citycard", + "company": "CJS Consultancy Ltd", + "mad": "0x8814", + "service_provider": "", + "system_integrator": "Transmo Citycard Ltd." + }, + { + "application": "Academic Services, Electronic Purse, Access control & security", + "company": "CNA Limited/Rax-Comm Systems Ltd.", + "mad": "0x8815", + "service_provider": "CNA Limited", + "system_integrator": "CNA Limited" + }, + { + "application": "Busticketing System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8816", + "service_provider": "King Man County Public Traffic", + "system_integrator": "Barouh Electronic Co." + }, + { + "application": "Electronic Purse", + "company": "Counter Solutions Ltd.", + "mad": "0x8817", + "service_provider": "Counter Solutions", + "system_integrator": "Counter Solutions" + }, + { + "application": "Building Management System", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8818", + "service_provider": "VFJ Hong Kong", + "system_integrator": "VFJ Hong Kong" + }, + { + "application": "Weighbridge for trucks", + "company": "VFJ Technology Pty Ltd", + "mad": "0x8819", + "service_provider": "Hardware Systems Sales", + "system_integrator": "" + }, + { + "application": "Access Control, Time & Attendance, E-Purse", + "company": "BALTECH AG", + "mad": "0x881A", + "service_provider": "Baltech", + "system_integrator": "Baltech" + }, + { + "application": "Access control, payment system", + "company": "Maas Systems B.V.", + "mad": "0x881B", + "service_provider": "Maas Systems B.V.", + "system_integrator": "Maas Systems B.V." + }, + { + "application": "Access controll security payment", + "company": "Matsushita Communication Industrial", + "mad": "0x881C", + "service_provider": "Matsushita Communication", + "system_integrator": "Matsushita Communication" + }, + { + "application": "Electronic Purse", + "company": "ITE Smartcard Solutions Limited", + "mad": "0x881D", + "service_provider": "ITE Smartcard", + "system_integrator": "ITE Smartcard" + }, + { + "application": "Electronic purse", + "company": "ADI Ltd.", + "mad": "0x881E", + "service_provider": "Kakitis Ltd", + "system_integrator": "ADI Ltd" + }, + { + "application": "Contactless e-purse", + "company": "Banrisul Processamento de Dados Ltda.", + "mad": "0x881F", + "service_provider": "Banco do Estado do Rio Grande do Sul S/A", + "system_integrator": "Banco do Estado do Rio Grande do Sul S/A" + }, + { + "application": "Contactless e-purse", + "company": "Banrisul Processamento de Dados Ltda.", + "mad": "0x8820", + "service_provider": "Banco do Estado do Rio Grande do Sul S/A", + "system_integrator": "Banco do Estado do Rio Grande do Sul S/A" + }, + { + "application": "Multi functional badge, private application", + "company": "Microtronic AG", + "mad": "0x8821", + "service_provider": "Microtronic AG", + "system_integrator": "Microtronic AG" + }, + { + "application": "Prepaid Electronic Purse", + "company": "Rosan Finance", + "mad": "0x8822", + "service_provider": "Retail Trade & services, Entertainments, Fastfoods, Gazolines etc", + "system_integrator": "Rosan Finance" + }, + { + "application": "Payment Catering", + "company": "Pecusoft Software-Entwicklungsgesellschaft mbH", + "mad": "0x8823", + "service_provider": "Pecusoft GmbH", + "system_integrator": "Pecusoft GmbH" + }, + { + "application": "Access control, time management, electronic wallet", + "company": "Universitaire Ziekenhuizen Leuven", + "mad": "0x8825", + "service_provider": "", + "system_integrator": "GET NV" + }, + { + "application": "Vending cashless prepaid", + "company": "MCF RF TECH SRL", + "mad": "0x8826", + "service_provider": "MCF", + "system_integrator": "MCF" + }, + { + "application": "Electronic purse", + "company": "IPC Systems BV", + "mad": "0x8827", + "service_provider": "IPC", + "system_integrator": "IPC" + }, + { + "application": "Vending System", + "company": "Quality Equipment Benelux B.V.", + "mad": "0x8828", + "service_provider": "Quality Equipment", + "system_integrator": "Quality Equipment" + }, + { + "application": "Electronic purse", + "company": "Hör GmbH & Co.", + "mad": "0x8829", + "service_provider": "Hör GmbH", + "system_integrator": "Hör GmbH" + }, + { + "application": "Electronic purse", + "company": "Tietoenator Energy Components", + "mad": "0x882A", + "service_provider": "Tietoenator", + "system_integrator": "Tietoenator" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x882B", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x882C", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x882D", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x882E", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x882F", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x8830", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x8831", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x8832", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x8833", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Electronic purse", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x8834", + "service_provider": "PBV Kaufmann", + "system_integrator": "PBV Kaufmann" + }, + { + "application": "Computer, car parking, elec. purse, access control & security", + "company": "DECA Engineering", + "mad": "0x8835", + "service_provider": "Deca Engineering", + "system_integrator": "Deca Engineering" + }, + { + "application": "Electronic purse, city traffic", + "company": "Plzeňské MÄ›stské Dopravní Podniky A.S.", + "mad": "0x8836", + "service_provider": "Plzenske Mestske", + "system_integrator": "Plzenske Mestske" + }, + { + "application": "", + "company": "TechID Engineering bv", + "mad": "0x8837", + "service_provider": "Tech ID", + "system_integrator": "Tech ID" + }, + { + "application": "Access control, Time attendanc, job control", + "company": "EM Group", + "mad": "0x8838", + "service_provider": "EM Group", + "system_integrator": "EM Group" + }, + { + "application": "Mass Transportation Ticketing", + "company": "Omnifare", + "mad": "0x8839", + "service_provider": "MBS", + "system_integrator": "MBS" + }, + { + "application": "Electronic purse", + "company": "Copie Monnaie France", + "mad": "0x883A", + "service_provider": "Copie Monnaie France", + "system_integrator": "Copie Monnaie France" + }, + { + "application": "Electronic purse", + "company": "Monet+ a.s.", + "mad": "0x883B", + "service_provider": "Monet+", + "system_integrator": "Monet+" + }, + { + "application": "LUAS - light rail", + "company": "Scheidt & Bachmann", + "mad": "0x883C", + "service_provider": "Scheidt & Bachmann", + "system_integrator": "Scheidt & Bachmann" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x883D", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Railway services, city traffic, electronic purse", + "company": "Czech Railways", + "mad": "0x883E", + "service_provider": "Czech Railways", + "system_integrator": "Czech Railways" + }, + { + "application": "Electronic purse, washing card", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x883F", + "service_provider": "BICA AG", + "system_integrator": "BICA AG" + }, + { + "application": "Electronic purse, washing card", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0x8840", + "service_provider": "BICA AG", + "system_integrator": "BICA AG" + }, + { + "application": "Compelete system for lockers, access control & electr. payment", + "company": "Ojmar S. A.", + "mad": "0x8841", + "service_provider": "", + "system_integrator": "Enkoa System S.L." + }, + { + "application": "City traffic, electronic purse, micellaneous applications", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x8842", + "service_provider": "Koordinator", + "system_integrator": "PVT" + }, + { + "application": "Electronic purse, access control for buliding automation", + "company": "CDE Communication Data Engineering GmbH", + "mad": "0x8843", + "service_provider": "CDE", + "system_integrator": "CDE" + }, + { + "application": "Electronic purse, access control for buliding automation", + "company": "CDE Communication Data Engineering GmbH", + "mad": "0x8844", + "service_provider": "CDE", + "system_integrator": "CDE" + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0x8845", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Cashless payment", + "company": "Contidata Datensysteme GmbH", + "mad": "0x8847", + "service_provider": "Contidata", + "system_integrator": "Contidata" + }, + { + "application": "Electronic purse", + "company": "ADE S.r.l.", + "mad": "0x8848", + "service_provider": "ADE", + "system_integrator": "ADE" + }, + { + "application": "Electronic purse", + "company": "ADE S.r.l.", + "mad": "0x8849", + "service_provider": "ADE", + "system_integrator": "ADE" + }, + { + "application": "Electronic purse", + "company": "ADE S.r.l.", + "mad": "0x884A", + "service_provider": "ADE", + "system_integrator": "ADE" + }, + { + "application": "Electronic purse", + "company": "ADE S.r.l.", + "mad": "0x884B", + "service_provider": "ADE", + "system_integrator": "ADE" + }, + { + "application": "Electronic purse", + "company": "Vesiel SPA", + "mad": "0x884C", + "service_provider": "Vesiel", + "system_integrator": "Vesiel" + }, + { + "application": "Electronic purse", + "company": "Vesiel SPA", + "mad": "0x884D", + "service_provider": "Vesiel", + "system_integrator": "Vesiel" + }, + { + "application": "Electronic purse", + "company": "Vesiel SPA", + "mad": "0x884E", + "service_provider": "Vesiel", + "system_integrator": "Vesiel" + }, + { + "application": "Elec ticketing, access control, electronic purse", + "company": "Empresa 1 Sistemas de Automacao e Comercio", + "mad": "0x884F", + "service_provider": "Empresa 1", + "system_integrator": "Empresa 1" + }, + { + "application": "Electronic purse/loyalty", + "company": "Premier Retail Services LTD", + "mad": "0x8850", + "service_provider": "Premier Retail", + "system_integrator": "Premier Retail" + }, + { + "application": "Electronic purse/loyalty", + "company": "Premier Retail Services LTD", + "mad": "0x8851", + "service_provider": "Premier Retail", + "system_integrator": "Premier Retail" + }, + { + "application": "Electronic purse, carparking system, single use ticket, period pass", + "company": "Emcard a.s.", + "mad": "0x8852", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Access & parking control, electronic purse", + "company": "General Meters Corp", + "mad": "0x8853", + "service_provider": "General Meters", + "system_integrator": "General Meters" + }, + { + "application": "Electronic purse", + "company": "DOPRAVNI PODNIK mest Mostu a Litvinova, a.s.", + "mad": "0x8854", + "service_provider": "Dopravni Podnik mest Mostu a Litvinova, a.s.", + "system_integrator": "Mikroelektronika, spol. sr.o., Kpt. Poplera 55, 565 01 Vysoké Myto, CZ" + }, + { + "application": "Privateive Payment System", + "company": "Aztek", + "mad": "0x8855", + "service_provider": "Aztek", + "system_integrator": "Aztek" + }, + { + "application": "Car Parking, Electronic Purse", + "company": "Haguess s.r.o.", + "mad": "0x8856", + "service_provider": "Haguess, s.r.o.", + "system_integrator": "Haguess, s.r.o." + }, + { + "application": "Electronic purse", + "company": "Emcard a.s.", + "mad": "0x8857", + "service_provider": "EMCARD, a.s.", + "system_integrator": "EMTEST, a.s." + }, + { + "application": "MulitApplicaton Purse", + "company": "MCF RF TECH SRL", + "mad": "0x8858", + "service_provider": "MCF Vending", + "system_integrator": "MCF Vending" + }, + { + "application": "Electr purse f. health services", + "company": "QSI", + "mad": "0x8859", + "service_provider": "QSI", + "system_integrator": "QSI" + }, + { + "application": "Closed elc. purse", + "company": "Siemens AG Österreich", + "mad": "0x885A", + "service_provider": "Siemens", + "system_integrator": "Siemens" + }, + { + "application": "Copy machine", + "company": "BCM Bureautique", + "mad": "0x885B", + "service_provider": "BCM Bureautique", + "system_integrator": "BCM Bureautique, Mr. Larbi Seridj" + }, + { + "application": "Transit SmartCard System, City E-purse System", + "company": "Intelligent Transaction Systems de Mexico S.A. de C.V.", + "mad": "0x885C", + "service_provider": "St. John's Transportation Commission", + "system_integrator": "Intelligent Transaction Systems de Mexico" + }, + { + "application": "Electronic purse, city traffic, customer profile, service applic, check-in/out applic", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x885D", + "service_provider": "Mikroelektronika", + "system_integrator": "Mikroelektronika" + }, + { + "application": "Payment, payment OEM, payment partner, entertainment, OEM data", + "company": "Payment Solution AG", + "mad": "0x885E", + "service_provider": "Payment Solution AG", + "system_integrator": "Payment Solution AG" + }, + { + "application": "Payment, payment OEM, payment partner, entertainment, OEM data", + "company": "Payment Solution AG", + "mad": "0x885F", + "service_provider": "Payment Solution AG", + "system_integrator": "Payment Solution AG" + }, + { + "application": "Payment, payment OEM, payment partner, entertainment, OEM data", + "company": "Payment Solution AG", + "mad": "0x8860", + "service_provider": "Payment Solution AG", + "system_integrator": "Payment Solution AG" + }, + { + "application": "E-Purse", + "company": "PT Visionet Internasional", + "mad": "0x8861", + "service_provider": "Visionet", + "system_integrator": "Multipolar" + }, + { + "application": "E-Purse", + "company": "PT Visionet Internasional", + "mad": "0x8862", + "service_provider": "Visionet", + "system_integrator": "Multipolar" + }, + { + "application": "E-Purse", + "company": "PT Visionet Internasional", + "mad": "0x8863", + "service_provider": "Visionet", + "system_integrator": "Multipolar" + }, + { + "application": "Electronic purse", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x8864", + "service_provider": "Siemens Itron Business Services S.A. - Cordoba, Republica Argentina", + "system_integrator": "Siemens Itron Business Services S.A. - Cordoba, Republica Argentina" + }, + { + "application": "Cashless Payment System", + "company": "Infineer", + "mad": "0x8865", + "service_provider": "Infineer", + "system_integrator": "" + }, + { + "application": "Cashless Payment System", + "company": "Infineer", + "mad": "0x8866", + "service_provider": "Infineer", + "system_integrator": "" + }, + { + "application": "Self service kiosk application (ordering and printing photos)", + "company": "CeWe Color AG & Co OHG", + "mad": "0x8867", + "service_provider": "CeWe Color AG & Co OHG", + "system_integrator": "CeWe Color AG & Co OHG" + }, + { + "application": "Self service kiosk application (ordering and printing photos)", + "company": "CeWe Color AG & Co OHG", + "mad": "0x8868", + "service_provider": "CeWe Color AG & Co OHG", + "system_integrator": "CeWe Color AG & Co OHG" + }, + { + "application": "Multiapplication Purse", + "company": "MCF RF TECH SRL", + "mad": "0x8869", + "service_provider": "MCF RF TECH S.R.L.", + "system_integrator": "MCF RF TECH S.R.L." + }, + { + "application": "Vending-Cashless_prepaid", + "company": "MCF RF TECH SRL", + "mad": "0x886A", + "service_provider": "MCF RF TECH S.R.L.", + "system_integrator": "MCF RF TECH S.R.L." + }, + { + "application": "Online Electronic Payment System", + "company": "PinCash International", + "mad": "0x886B", + "service_provider": "Pincash international BV", + "system_integrator": "Pincash international BV" + }, + { + "application": "E-Money Application", + "company": "SQuidcard Ltd", + "mad": "0x886C", + "service_provider": "Squidcard Limited", + "system_integrator": "Applied Card Technologies Ltd" + }, + { + "application": "E-purse", + "company": "Asdion Berhad", + "mad": "0x886D", + "service_provider": "Asdion Berhad", + "system_integrator": "Asdion Berhad" + }, + { + "application": "MIFARE based payment system", + "company": "supercard as", + "mad": "0x886E", + "service_provider": "Supercard as", + "system_integrator": "supercard as" + }, + { + "application": "Electronic purse", + "company": "Group Capmonetique", + "mad": "0x886F", + "service_provider": "CARTAX", + "system_integrator": "MONECARTE" + }, + { + "application": "Electronic purse", + "company": "Group Capmonetique", + "mad": "0x8870", + "service_provider": "SEDECO", + "system_integrator": "MONECARTE" + }, + { + "application": "Electronic purse", + "company": "Group Capmonetique", + "mad": "0x8871", + "service_provider": "MONECARTE", + "system_integrator": "MONECARTE" + }, + { + "application": "Eectronic purse for CROUS", + "company": "Group Capmonetique", + "mad": "0x8872", + "service_provider": "MONECARTE", + "system_integrator": "MONECARTE" + }, + { + "application": "Copier vending Follow-Me Printing", + "company": "Xafax Nederland BV", + "mad": "0x8873", + "service_provider": "Xafax Nederland", + "system_integrator": "Xafax Nederland" + }, + { + "application": "Copier vending Follow-Me Printing", + "company": "Xafax Nederland BV", + "mad": "0x8874", + "service_provider": "Xafax Nederland", + "system_integrator": "Xafax Nederland" + }, + { + "application": "Epurse", + "company": "KORID LK, spol. s r.o", + "mad": "0x8875", + "service_provider": "KORID LK, spol.s.r.o.", + "system_integrator": "KORID LK, spol.s.r.o." + }, + { + "application": "Electronic purse", + "company": "Mikroelektronika GmbH", + "mad": "0x8876", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o., Draby 849, Vysoke Myto 56601, Czech Republic", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o., Draby 849, Vysoke Myto 56601, Czech Republic" + }, + { + "application": "Electronic payment", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x8877", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Electronic payment", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x8878", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Electronic payment", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x8879", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Electronic payment", + "company": "Dallmayr Card Systeme Gmbh", + "mad": "0x887A", + "service_provider": "Dallmayr Card Systeme Gmbh", + "system_integrator": "Dallmayr Card Systeme Gmbh" + }, + { + "application": "Electronic purse", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x887B", + "service_provider": "ZAGREBACKI Holding d.o.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Electronic purse", + "company": "Mikroelektronika GmbH", + "mad": "0x887C", + "service_provider": "MIKROELEKTRONIKA spol.s.r.o.", + "system_integrator": "MIKROELEKTRONIKA spol.s.r.o." + }, + { + "application": "Electronic purse", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x887D", + "service_provider": "Mikroelektronika spol.s r.o", + "system_integrator": "Mikroelektronika spol.s r.o" + }, + { + "application": "Electronic Purse", + "company": "Electronic and Software Engineering Limited (EASEL)", + "mad": "0x887E", + "service_provider": "EASEL", + "system_integrator": "EASEL" + }, + { + "application": "Contactless payment", + "company": "Chess embedded Technology", + "mad": "0x887F", + "service_provider": "Chess", + "system_integrator": "Chess" + }, + { + "application": "Electronic purse", + "company": "WIGOTEK, Hardware Software Beratung", + "mad": "0x8880", + "service_provider": "WIGOTEK", + "system_integrator": "WIGOTEK" + }, + { + "application": "Electronic purse", + "company": "WIGOTEK, Hardware Software Beratung", + "mad": "0x8881", + "service_provider": "WIGOTEK", + "system_integrator": "WIGOTEK" + }, + { + "application": "Electronic purse", + "company": "ENKOA System", + "mad": "0x8882", + "service_provider": "ENKOA System S.L.", + "system_integrator": "ENKOA System S.L." + }, + { + "application": "Electronic payment", + "company": "Alcatel-Lucent Bell NV", + "mad": "0x8883", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Electronic payment", + "company": "Alcatel-Lucent Bell NV", + "mad": "0x8884", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Electronic payment", + "company": "Alcatel-Lucent Bell NV", + "mad": "0x8885", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Vending control systems - point, cash purse", + "company": "Unicard S.A.", + "mad": "0x8886", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Vending control systems - point, cash purse", + "company": "Unicard S.A.", + "mad": "0x8887", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Vending control systems - point, cash purse", + "company": "Unicard S.A.", + "mad": "0x8888", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x8889", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x888A", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x888B", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x888C", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x888D", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x888E", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x888F", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x8890", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x8891", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Inepro BV", + "mad": "0x8892", + "service_provider": "Inepro BV", + "system_integrator": "" + }, + { + "application": "Electronic purse for use in proprietary closed system", + "company": "Absec Malaysia SDN BHD", + "mad": "0x8893", + "service_provider": "Absec Malaysia SDN BHD", + "system_integrator": "MLGN Solutions Ltd" + }, + { + "application": "Electronic purse for use in proprietary closed system", + "company": "Absec Malaysia SDN BHD", + "mad": "0x8894", + "service_provider": "Absec Malaysia SDN BHD", + "system_integrator": "MLGN Solutions Ltd" + }, + { + "application": "Electronic purse", + "company": "Koordinator ODIS s.r.o.", + "mad": "0x8895", + "service_provider": "KOORDINATOR ODIS s.r.o.", + "system_integrator": "KOORDINATOR ODIS s.r.o." + }, + { + "application": "Service application for municipal chip card - customer profile (registration) - validity of card (registration)", + "company": "Plzeňské MÄ›stské Dopravní Podniky A.S.", + "mad": "0x8896", + "service_provider": "Plzeňské MÄ›stské Dopravní Podniky A.S.", + "system_integrator": "Plzeňské MÄ›stské Dopravní Podniky A.S." + }, + { + "application": "Electronic purse", + "company": "Mikroelektronika spol.s r.o.", + "mad": "0x8897", + "service_provider": "Jamaica Urban Transit Company Ltd", + "system_integrator": "Mikroelektronika spol.s r.o" + }, + { + "application": "Open cashfile electronic purse", + "company": "Ingenieurbüro Ludwig - Ib Ludwig", + "mad": "0x8898", + "service_provider": "OCF open Cashfile", + "system_integrator": "OCF open Cashfile members" + }, + { + "application": "Open cashfile electronic purse", + "company": "Ingenieurbüro Ludwig - Ib Ludwig", + "mad": "0x8899", + "service_provider": "OCF open Cashfile", + "system_integrator": "OCF open Cashfile members" + }, + { + "application": "Open cashfile electronic purse", + "company": "Ingenieurbüro Ludwig - Ib Ludwig", + "mad": "0x889A", + "service_provider": "OCF open Cashfile", + "system_integrator": "OCF open Cashfile members" + }, + { + "application": "Open cashfile electronic purse", + "company": "Ingenieurbüro Ludwig - Ib Ludwig", + "mad": "0x889B", + "service_provider": "OCF open Cashfile", + "system_integrator": "OCF open Cashfile members" + }, + { + "application": "Open cashfile electronic purse", + "company": "Ingenieurbüro Ludwig - Ib Ludwig", + "mad": "0x889C", + "service_provider": "OCF open Cashfile", + "system_integrator": "OCF open Cashfile members" + }, + { + "application": "Open cashfile electronic purse", + "company": "Ingenieurbüro Ludwig - Ib Ludwig", + "mad": "0x889D", + "service_provider": "OCF open Cashfile", + "system_integrator": "OCF open Cashfile members" + }, + { + "application": "Payment system - electronic purse", + "company": "N&W Innovative Solutions", + "mad": "0x889E", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Payment system - electronic purse", + "company": "N&W Innovative Solutions", + "mad": "0x889F", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Payment system - electronic purse", + "company": "N&W Innovative Solutions", + "mad": "0x88A0", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Payment system - electronic purse", + "company": "N&W Innovative Solutions", + "mad": "0x88A1", + "service_provider": "N&W", + "system_integrator": "N&W" + }, + { + "application": "Contactless payment", + "company": "Rabobank International", + "mad": "0x88A2", + "service_provider": "Rabobank", + "system_integrator": "Rabobank" + }, + { + "application": "Contactless payment", + "company": "Amsterdam Arena", + "mad": "0x88A3", + "service_provider": "Amsterdam Arena", + "system_integrator": "Amsterdam Arena" + }, + { + "application": "Contactless payment", + "company": "Multicard", + "mad": "0x88A4", + "service_provider": "MULTICARD", + "system_integrator": "MULTICARD" + }, + { + "application": "Electronic purse", + "company": "ODP-software s.r.o.", + "mad": "0x88A5", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Electronic purse", + "company": "ODP-software s.r.o.", + "mad": "0x88A6", + "service_provider": "ODP-software", + "system_integrator": "ODP-software" + }, + { + "application": "Electronic purse", + "company": "SIT Solution for IT Payment GmbH", + "mad": "0x88A7", + "service_provider": "SIT Solution for IT Payment GmbH", + "system_integrator": "SIT Solution for IT Payment GmbH" + }, + { + "application": "Accesss control in sport stadiums and e-purse", + "company": "FortressGb", + "mad": "0x88AB", + "service_provider": "FORTRESSGB", + "system_integrator": "FORTRESSGB" + }, + { + "application": "Smart City Card \\Schwabencard\"\"", + "company": "Cosmo.id GmbH", + "mad": "0x88AC", + "service_provider": "Cosmo.id", + "system_integrator": "Cosmo.id" + }, + { + "application": "Electronic purse", + "company": "OREDO s.r.o", + "mad": "0x88AD", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Electronic purse", + "company": "OREDO s.r.o", + "mad": "0x88AE", + "service_provider": "OREDO s.r.o", + "system_integrator": "OREDO s.r.o" + }, + { + "application": "Electronic purse", + "company": "Ústecky kraj", + "mad": "0x88AF", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "Ústecky kraj", + "mad": "0x88B0", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Electronic purse", + "company": "TELMAX s.r.o.", + "mad": "0x88B1", + "service_provider": "TELMAX s.r.o.", + "system_integrator": "TELMAX s.r.o." + }, + { + "application": "Contactless Card for payment operations in Kiosk Payment system", + "company": "Sistemas Tecnicos de Cobro S.L.", + "mad": "0x88B2", + "service_provider": "Sistemas Tecnicos de Cobro S.L.", + "system_integrator": "Sistemas Tecnicos de Cobro S.L." + }, + { + "application": "Access control, canteen functionality", + "company": "Elektroniske Betalings Systemer AS", + "mad": "0x88B3", + "service_provider": "Elektroniske Betalings Systemer AS", + "system_integrator": "Elektroniske Betalings Systemer AS" + }, + { + "application": "Electronic purse", + "company": "HUG-Witschi AG", + "mad": "0x88B4", + "service_provider": "HUG-Witschi AG", + "system_integrator": "HUG-Witschi AG" + }, + { + "application": "Electronic purse", + "company": "HUG-Witschi AG", + "mad": "0x88B5", + "service_provider": "HUG-Witschi AG", + "system_integrator": "HUG-Witschi AG" + }, + { + "application": "Electronic purse", + "company": "HUG-Witschi AG", + "mad": "0x88B6", + "service_provider": "HUG-Witschi AG", + "system_integrator": "HUG-Witschi AG" + }, + { + "application": "Electronic purse", + "company": "HUG-Witschi AG", + "mad": "0x88B7", + "service_provider": "HUG-Witschi AG", + "system_integrator": "HUG-Witschi AG" + }, + { + "application": "FIDELIO CRUISE ship property management system, - materials management system, - meal counting system", + "company": "FIDELIO CRUISE SOFTWARE GMBH", + "mad": "0x9101", + "service_provider": "FIDELIO CRUISE SOFTWARE GMBH", + "system_integrator": "FIDELIO CRUISE SOFTWARE GMBH" + }, + { + "application": "FIDELIO CRUISE ship property management system, - materials management system, - meal counting system", + "company": "FIDELIO CRUISE SOFTWARE GMBH", + "mad": "0x9102", + "service_provider": "FIDELIO CRUISE SOFTWARE GMBH", + "system_integrator": "FIDELIO CRUISE SOFTWARE GMBH" + }, + { + "application": "FIDELIO CRUISE ship property management system, - materials management system, - meal counting system", + "company": "FIDELIO CRUISE SOFTWARE GMBH", + "mad": "0x9103", + "service_provider": "FIDELIO CRUISE SOFTWARE GMBH", + "system_integrator": "FIDELIO CRUISE SOFTWARE GMBH" + }, + { + "application": "General / NXP Test / Graz", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x9502", + "service_provider": "NXP", + "system_integrator": "NXP" + }, + { + "application": "General / NXP Test / Graz", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x9503", + "service_provider": "NXP", + "system_integrator": "NXP" + }, + { + "application": "General / NXP Test / Graz", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0x9504", + "service_provider": "NXP", + "system_integrator": "NXP" + }, + { + "application": "Prepaid Meteringh, service functions of technical systems", + "company": "Engelmann Sensor GmbH", + "mad": "0x9702", + "service_provider": "Engelmann Sensor GmbH", + "system_integrator": "Engelmann Sensor GmbH" + }, + { + "application": "Prepaid Meteringh, service functions of technical systems", + "company": "Engelmann Sensor GmbH", + "mad": "0x9703", + "service_provider": "Engelmann Sensor GmbH", + "system_integrator": "Engelmann Sensor GmbH" + }, + { + "application": "Prepaid Meteringh, service functions of technical systems", + "company": "Engelmann Sensor GmbH", + "mad": "0x9704", + "service_provider": "Engelmann Sensor GmbH", + "system_integrator": "Engelmann Sensor GmbH" + }, + { + "application": "Prepaid Meteringh, service functions of technical systems", + "company": "Engelmann Sensor GmbH", + "mad": "0x9705", + "service_provider": "Engelmann Sensor GmbH", + "system_integrator": "Engelmann Sensor GmbH" + }, + { + "application": "Prepaid Meteringh, service functions of technical systems", + "company": "Engelmann Sensor GmbH", + "mad": "0x9706", + "service_provider": "Engelmann Sensor GmbH", + "system_integrator": "Engelmann Sensor GmbH" + }, + { + "application": "Prepaid Meteringh, service functions of technical systems", + "company": "Engelmann Sensor GmbH", + "mad": "0x9707", + "service_provider": "Engelmann Sensor GmbH", + "system_integrator": "Engelmann Sensor GmbH" + }, + { + "application": "Prepaid Meteringh, service functions of technical systems", + "company": "Engelmann Sensor GmbH", + "mad": "0x9708", + "service_provider": "Engelmann Sensor GmbH", + "system_integrator": "Engelmann Sensor GmbH" + }, + { + "application": "Health services", + "company": "Rosan Finance", + "mad": "0xA001", + "service_provider": "Express Card", + "system_integrator": "Express Card" + }, + { + "application": "Card holders vital medical data", + "company": "Rosan Finance", + "mad": "0xA002", + "service_provider": "Medical Org.", + "system_integrator": "Rosan Finance" + }, + { + "application": "Identification of card holder", + "company": "Rosan Finance", + "mad": "0xA003", + "service_provider": "Hospitals Cllinics Drug Stores", + "system_integrator": "Rosan Finance" + }, + { + "application": "Medical information", + "company": "CYNAPS", + "mad": "0xA004", + "service_provider": "Cynaps", + "system_integrator": "Cynaps" + }, + { + "application": "Medical information", + "company": "CYNAPS", + "mad": "0xA005", + "service_provider": "Cynaps", + "system_integrator": "Cynaps" + }, + { + "application": "Medical information", + "company": "CYNAPS", + "mad": "0xA006", + "service_provider": "Cynaps", + "system_integrator": "Cynaps" + }, + { + "application": "Medical information", + "company": "CYNAPS", + "mad": "0xA007", + "service_provider": "Cynaps", + "system_integrator": "Cynaps" + }, + { + "application": "Medical information", + "company": "CYNAPS", + "mad": "0xA008", + "service_provider": "Cynaps", + "system_integrator": "Cynaps" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0xA009", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "Self service, pharmacy, medicine issue", + "company": "EnzoSystems BV", + "mad": "0xA00A", + "service_provider": "EnzoSystems", + "system_integrator": "EnzoSystems" + }, + { + "application": "Health Services", + "company": "QSI", + "mad": "0xA00B", + "service_provider": "QSI", + "system_integrator": "QSI" + }, + { + "application": "Health services", + "company": "Carelink AB", + "mad": "0xA00C", + "service_provider": "Carelink AB", + "system_integrator": "Carelink AB" + }, + { + "application": "Debit card, door access control, computer identification", + "company": "Netcard", + "mad": "0xB001", + "service_provider": "Netcard", + "system_integrator": "Netcard" + }, + { + "application": "Multiapplication car for industry & trafic, parking, swimming pool", + "company": "ASEC S.A.", + "mad": "0xB002", + "service_provider": "ASEC S.A", + "system_integrator": "ASEC S.A" + }, + { + "application": "Miscellaneous application, city traffic, access controll & securitym entertainment, car parking, electronic trade", + "company": "KFAP S.A.", + "mad": "0xB003", + "service_provider": "KFPA", + "system_integrator": "KFPA" + }, + { + "application": "", + "company": "Reac BV", + "mad": "0xB004", + "service_provider": "", + "system_integrator": "REAC" + }, + { + "application": "Electronic purse", + "company": "BULL POLSKA Sp. z o.o.", + "mad": "0xB005", + "service_provider": "BULL POLSKA", + "system_integrator": "BULL POLSKA" + }, + { + "application": "Electronic trade", + "company": "SIT Solution for IT Payment GmbH", + "mad": "0xB006", + "service_provider": "SIT Solution for IT Payment GmbH", + "system_integrator": "SIT Solution for IT Payment GmbH" + }, + { + "application": "Electronic voucher system, loyalty application, electronic wallet, transport", + "company": "Prosoft SPOL S.R.O", + "mad": "0xB007", + "service_provider": "Prosoft SPOL S.R.O", + "system_integrator": "Prosoft SPOL S.R.O" + }, + { + "application": "Electronic voucher system, loyalty application, electronic wallet, transport", + "company": "Prosoft SPOL S.R.O", + "mad": "0xB008", + "service_provider": "Prosoft SPOL S.R.O", + "system_integrator": "Prosoft SPOL S.R.O" + }, + { + "application": "Electronic voucher system, loyalty application, electronic wallet, transport", + "company": "Prosoft SPOL S.R.O", + "mad": "0xB009", + "service_provider": "Prosoft SPOL S.R.O", + "system_integrator": "Prosoft SPOL S.R.O" + }, + { + "application": "Electronic voucher system, loyalty application, electronic wallet, transport", + "company": "Prosoft SPOL S.R.O", + "mad": "0xB00A", + "service_provider": "Prosoft SPOL S.R.O", + "system_integrator": "Prosoft SPOL S.R.O" + }, + { + "application": "Point of sale", + "company": "VFJ Technology Pty Ltd", + "mad": "0xB801", + "service_provider": "VFJ Technology", + "system_integrator": "" + }, + { + "application": "An electronic purse application for Educational Institutions (Universities etc...)", + "company": "VERIFONE ITALIA SRL", + "mad": "0xB802", + "service_provider": "VeriFone Italy", + "system_integrator": "VeriFone Italy" + }, + { + "application": "Banking electronic purse", + "company": "ETC Electronic Technology Communication Company Limited", + "mad": "0xB803", + "service_provider": "Electronic Technology Communication Co Ltd.", + "system_integrator": "Electronic Technology Communication Co Ltd." + }, + { + "application": "Banking prepaid payment", + "company": "ETC Electronic Technology Communication Company Limited", + "mad": "0xB804", + "service_provider": "Vietnam Joint Stock Commercial Bank for Industry and trade (VietinBank)", + "system_integrator": "Electronic Technology Communication Co Ltd (E.T.C)" + }, + { + "application": "Multichip and Multiapplication Credit Card for banking, electronic purse, access control, payment and identification", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0xB805", + "service_provider": "CCC Credit Card Center AG", + "system_integrator": "" + }, + { + "application": "Gaming industry, cashless operation for slotmachines, tables and other Facilities (ID, cashless, offline, purse)", + "company": "Grips Electronic GmbH", + "mad": "0xC001", + "service_provider": "Sun International", + "system_integrator": "Grips, Sun International" + }, + { + "application": "Gaming industry, cashless operation for slotmachines, tables and other Facilities (ID, cashless, offline, purse)", + "company": "Grips Electronic GmbH", + "mad": "0xC002", + "service_provider": "Sun International", + "system_integrator": "Grips, Sun International" + }, + { + "application": "Gaming industry, cashless operation for slotmachines, tables and other Facilities (ID, cashless, offline, purse)", + "company": "Grips Electronic GmbH", + "mad": "0xC003", + "service_provider": "Sun International", + "system_integrator": "Grips, Sun International" + }, + { + "application": "Gaming industry, cashless operation for slotmachines, tables and other Facilities (ID, cashless, offline, purse)", + "company": "Grips Electronic GmbH", + "mad": "0xC004", + "service_provider": "Sun International", + "system_integrator": "Grips, Sun International" + }, + { + "application": "Access Controll, Security Electronic Purse, Ski-Ticketing, Ticketing", + "company": "*Siemens ANL", + "mad": "0xC005", + "service_provider": "", + "system_integrator": "Siemens AG" + }, + { + "application": "Security and safty services", + "company": "Staat der Nederlanden, Ministerie van Financien Belastingdienst/Centrum voor facilitaire dienstverlening", + "mad": "0xC006", + "service_provider": "Siemens Nederland BV", + "system_integrator": "Siemens Nederland BV" + }, + { + "application": "Event ticketing", + "company": "Just Access", + "mad": "0xC007", + "service_provider": "Just Access Inc.", + "system_integrator": "" + }, + { + "application": "Entertainment & Sports", + "company": "A&A Company", + "mad": "0xC008", + "service_provider": "A&A Company", + "system_integrator": "A&A Company" + }, + { + "application": "Miscellaneous application, city traffic, access control & security, entertainment, car parking, electronic trade", + "company": "KFAP S.A.", + "mad": "0xC009", + "service_provider": "KFPA", + "system_integrator": "KFPA" + }, + { + "application": "Access control, time attendance, bus ticket, hotel room card, VIP card f. club", + "company": "Giga-TMS Inc", + "mad": "0xC01A", + "service_provider": "Giga TMS", + "system_integrator": "Giga TMS" + }, + { + "application": "Access control & security, entertainment and sports", + "company": "Giga-TMS Inc", + "mad": "0xC01B", + "service_provider": "Giga", + "system_integrator": "Giga" + }, + { + "application": "Entertainment and Sports, Stadiums, Parking, Ski Ticketing", + "company": "Axess AG", + "mad": "0xC01C", + "service_provider": "Axess", + "system_integrator": "Axess" + }, + { + "application": "Entertainment and Sports, Stadiums, Parking, Ski Ticketing", + "company": "Axess AG", + "mad": "0xC01D", + "service_provider": "Axess", + "system_integrator": "Axess" + }, + { + "application": "Entertainment and Sports, Stadiums, Parking, Ski Ticketing", + "company": "Axess AG", + "mad": "0xC01E", + "service_provider": "Axess", + "system_integrator": "Axess" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC01F", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC020", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC021", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC022", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC023", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC024", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC025", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC026", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC027", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC028", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC029", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC02A", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC02B", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC02C", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Gaming industry, Retail Loyalty, Access Control, Point of Sale", + "company": "Worldsamrt Technology Pty Ltd", + "mad": "0xC02D", + "service_provider": "", + "system_integrator": "Worldsmart Technology" + }, + { + "application": "Compelete system for lockers, access control & electr. payment", + "company": "Ojmar S. A.", + "mad": "0xC02E", + "service_provider": "", + "system_integrator": "Enkoa System S.L." + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0xC02F", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Entertainment & sports", + "company": "n-tree Solutions Ticketsysteme", + "mad": "0xC030", + "service_provider": "n-tree", + "system_integrator": "n-tree" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0xC031", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "StadiumTicketing & Access Contr", + "company": "T-Systems GEI GmbH", + "mad": "0xC032", + "service_provider": "T-Systems GEI GmbH", + "system_integrator": "T-Systems GEI GmbH" + }, + { + "application": "Car parking, sport applic, hotel, access control systems", + "company": "DATASEC Electronic GmbH", + "mad": "0xC033", + "service_provider": "Datasec", + "system_integrator": "Datatsec" + }, + { + "application": "Gaming Industry", + "company": "Systems in Progress", + "mad": "0xC040", + "service_provider": "Systems in Progress", + "system_integrator": "Systems in Progress" + }, + { + "application": "Gaming Industry", + "company": "Systems in Progress", + "mad": "0xC041", + "service_provider": "Systems in Progress", + "system_integrator": "Systems in Progress" + }, + { + "application": "Gaming Industry", + "company": "Systems in Progress", + "mad": "0xC042", + "service_provider": "Systems in Progress", + "system_integrator": "Systems in Progress" + }, + { + "application": "Gaming Industry", + "company": "Systems in Progress", + "mad": "0xC043", + "service_provider": "Systems in Progress", + "system_integrator": "Systems in Progress" + }, + { + "application": "Payment, payment OEM, payment partner, entertainment, OEM data", + "company": "Payment Solution AG", + "mad": "0xC044", + "service_provider": "Payment Solution AG", + "system_integrator": "Payment Solution AG" + }, + { + "application": "Scorecard for golf, payment solution for golf", + "company": "Gobex", + "mad": "0xC045", + "service_provider": "Gobex", + "system_integrator": "Gobex" + }, + { + "application": "Scorecard for golf, payment solution for golf", + "company": "Gobex", + "mad": "0xC046", + "service_provider": "Gobex", + "system_integrator": "Gobex" + }, + { + "application": "Leisure Management Application. inc. bookings, access control, e-purse and Electronic Point of Sale", + "company": "Gladstone Health & Leisure", + "mad": "0xC047", + "service_provider": "Gladstone", + "system_integrator": "Gladstone" + }, + { + "application": "Leisure Management Application. inc. bookings, access control, e-purse and Electronic Point of Sale", + "company": "Gladstone Health & Leisure", + "mad": "0xC048", + "service_provider": "Gladstone", + "system_integrator": "Gladstone" + }, + { + "application": "Event ticketing", + "company": "IMA ltd.", + "mad": "0xC049", + "service_provider": "IMA LTD.", + "system_integrator": "IMA LTD." + }, + { + "application": "Soccer stadium ticketing and e-purse application", + "company": "Smartchip S.A.", + "mad": "0xC04A", + "service_provider": "Corporacion Dim", + "system_integrator": "Smartchip S.A." + }, + { + "application": "Entertainment & spports", + "company": "Gantner Electronic GmbH", + "mad": "0xC04B", + "service_provider": "GANTNER Electronic", + "system_integrator": "GANTNER Electronic" + }, + { + "application": "Multi-purpose application for sport facilities - access control, purse etc for stadiums, sport centers etc", + "company": "Unicard S.A.", + "mad": "0xC04C", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Multi-purpose application for sport facilities - access control, purse etc for stadiums, sport centers etc", + "company": "Unicard S.A.", + "mad": "0xC04D", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Multi-purpose application for sport facilities - access control, purse etc for stadiums, sport centers etc", + "company": "Unicard S.A.", + "mad": "0xC04E", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "Multi-purpose application for sport facilities - access control, purse etc for stadiums, sport centers etc", + "company": "Unicard S.A.", + "mad": "0xC04F", + "service_provider": "UNICARD S.A.", + "system_integrator": "UNICARD S.A." + }, + { + "application": "", + "company": "Reac BV", + "mad": "0xC050", + "service_provider": "", + "system_integrator": "REAC" + }, + { + "application": "Access control and ticketing for entertainment and sports", + "company": "Mosrir Szczecin", + "mad": "0xC051", + "service_provider": "Mosrir Szczecin", + "system_integrator": "Sportdata Sp. 2 0.0." + }, + { + "application": "Accesss control in sport stadiums and e-purse", + "company": "FortressGb", + "mad": "0xC052", + "service_provider": "FORTRESSGB", + "system_integrator": "FORTRESSGB" + }, + { + "application": "Car parking", + "company": "Scheidt & Bachmann", + "mad": "0xC801", + "service_provider": "Scheidt & Bachmann GmbH", + "system_integrator": "" + }, + { + "application": "Car parking", + "company": "Scheidt & Bachmann", + "mad": "0xC802", + "service_provider": "Scheidt & Bachmann GmbH", + "system_integrator": "" + }, + { + "application": "", + "company": "Reserved for MAD", + "mad": "0xC803", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "Car parking systems", + "company": "Eden", + "mad": "0xC805", + "service_provider": "", + "system_integrator": "Eden" + }, + { + "application": "Car Parking", + "company": "MADA Marx Datentechnik GmbH", + "mad": "0xC806", + "service_provider": "MADA", + "system_integrator": "MADA" + }, + { + "application": "Car parking", + "company": "Scheidt & Bachmann", + "mad": "0xC810", + "service_provider": "Scheidt & Bachmann GmbH", + "system_integrator": "" + }, + { + "application": "Car parking", + "company": "CNA Limited/Rax-Comm Systems Ltd.", + "mad": "0xC811", + "service_provider": "CNA Limited", + "system_integrator": "CNA Limited" + }, + { + "application": "Park access application", + "company": "EFKON AG", + "mad": "0xC812", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Park access application", + "company": "EFKON AG", + "mad": "0xC813", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Park access application", + "company": "EFKON AG", + "mad": "0xC814", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Park access application", + "company": "EFKON AG", + "mad": "0xC815", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Park access application", + "company": "EFKON AG", + "mad": "0xC816", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Park access application", + "company": "EFKON AG", + "mad": "0xC817", + "service_provider": "efkon", + "system_integrator": "efkon" + }, + { + "application": "Security and safty services", + "company": "Staat der Nederlanden, Ministerie van Financien Belastingdienst/Centrum voor facilitaire dienstverlening", + "mad": "0xC819", + "service_provider": "Siemens Nederland BV", + "system_integrator": "Siemens Nederland BV" + }, + { + "application": "Car Parking System", + "company": "Edward Keller Ltd.", + "mad": "0xC81A", + "service_provider": "Edward Keller Ltd", + "system_integrator": "Edward Keller Ltd" + }, + { + "application": "Multiapplication car for industry & trafic, parking, swimming pool", + "company": "ASEC S.A.", + "mad": "0xC81B", + "service_provider": "ASEC S.A", + "system_integrator": "ASEC S.A" + }, + { + "application": "Miscellaneous application, city traffic, access control & security entertainment, car parking, electronic trade", + "company": "KFAP S.A.", + "mad": "0xC81C", + "service_provider": "KFPA", + "system_integrator": "KFPA" + }, + { + "application": "Computer, car parking, elec. purse, access control & security", + "company": "DECA Engineering", + "mad": "0xC81D", + "service_provider": "Deca Engineering", + "system_integrator": "Deca Engineering" + }, + { + "application": "", + "company": "TechID Engineering bv", + "mad": "0xC81E", + "service_provider": "Tech ID", + "system_integrator": "Tech ID" + }, + { + "application": "Entertainment and Sports, Stadiums, Parking, Ski Ticketing", + "company": "Axess AG", + "mad": "0xC81F", + "service_provider": "Axess", + "system_integrator": "Axess" + }, + { + "application": "Road toll", + "company": "Diners Club Adriatic d.d.", + "mad": "0xC820", + "service_provider": "Diners Club", + "system_integrator": "Diners Club" + }, + { + "application": "Company services, access & sec control, electronic purse...", + "company": "Cominfo a.s.", + "mad": "0xC821", + "service_provider": "Cominfo", + "system_integrator": "Cominfo" + }, + { + "application": "Access control & security, city traffic, sports & entertainment", + "company": "IP Core", + "mad": "0xC822", + "service_provider": "IP Core", + "system_integrator": "IP Core" + }, + { + "application": "Electronic purse, carparking system, single use ticket, period pass", + "company": "Emcard a.s.", + "mad": "0xC823", + "service_provider": "Emcard", + "system_integrator": "Emtest" + }, + { + "application": "Car parking, sport applic, hotel, access control systems", + "company": "DATASEC Electronic GmbH", + "mad": "0xC824", + "service_provider": "Datasec", + "system_integrator": "Datatsec" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC825", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC826", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC827", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC828", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC829", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC82A", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC82B", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking", + "company": "Parkeon", + "mad": "0xC82C", + "service_provider": "Parkeon", + "system_integrator": "Parkeon" + }, + { + "application": "Car parking system", + "company": "PENTA d.o.o.", + "mad": "0xC82D", + "service_provider": "PENTA", + "system_integrator": "PENTA" + }, + { + "application": "Car wash", + "company": "Group Capmonetique", + "mad": "0xC82E", + "service_provider": "MONEPARC, Parc Technologique Les moulins 2, 2791 Chemin St. Bernard, 06220 Vallauris, France", + "system_integrator": "MONECARTE" + }, + { + "application": "Car parking system: storage of entrance and payment information", + "company": "DEC S.R.L", + "mad": "0xC82F", + "service_provider": "DEC S.R.L", + "system_integrator": "DEC S.R.L" + }, + { + "application": "Car parking system: storage of subscription data", + "company": "DEC S.R.L", + "mad": "0xC830", + "service_provider": "DEC S.R.L", + "system_integrator": "DEC S.R.L" + }, + { + "application": "Car parking", + "company": "Cards & Devices GmbH", + "mad": "0xC831", + "service_provider": "Cards & Devices GmbH", + "system_integrator": "Cards & Devices GmbH" + }, + { + "application": "RF Loyalty/Fleet Card System", + "company": "Panasonic Industrial Company", + "mad": "0xC902", + "service_provider": "Panasonic Loyalty", + "system_integrator": "Panasonic Industrial Company" + }, + { + "application": "RF Loyalty/Fleet Card System", + "company": "Panasonic Industrial Company", + "mad": "0xC903", + "service_provider": "Panasonic Loyalty", + "system_integrator": "Panasonic Industrial Company" + }, + { + "application": "Payment, loyalty and vehicle card", + "company": "Tokheim", + "mad": "0xD001", + "service_provider": "Retail Petroleum Systems", + "system_integrator": "Retail Petroleum Systems" + }, + { + "application": "Payment, loyalty and vehicle card", + "company": "Tokheim", + "mad": "0xD002", + "service_provider": "Retail Petroleum Systems", + "system_integrator": "Retail Petroleum Systems" + }, + { + "application": "Payment, loyalty and vehicle card", + "company": "Tokheim", + "mad": "0xD003", + "service_provider": "Retail Petroleum Systems", + "system_integrator": "Retail Petroleum Systems" + }, + { + "application": "Driver Vehicle Indentification / fueling", + "company": "Nedap - CTP B.V.", + "mad": "0xD004", + "service_provider": "Nedap CTP B.V.", + "system_integrator": "D.V.I / Nedap - CTP B.V." + }, + { + "application": "Fuel, Gasoline", + "company": "MADA Marx Datentechnik GmbH", + "mad": "0xD005", + "service_provider": "MADA", + "system_integrator": "MADA" + }, + { + "application": "Electronic fuel voucher", + "company": "GRUPO VR", + "mad": "0xD006", + "service_provider": "Grupo VR", + "system_integrator": "" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD007", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD008", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD009", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD00A", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD00B", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD00C", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD00D", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD00E", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD00F", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Attended and unattended operation", + "company": "Postec Data Systems Limited", + "mad": "0xD010", + "service_provider": "Unisys Marconi Commerce", + "system_integrator": "Postec Data Systems" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD038", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD039", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD03A", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD03B", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD03C", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD03D", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD03E", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD03F", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel gasoline", + "company": "R&D Solutionz Ltd.", + "mad": "0xD040", + "service_provider": "", + "system_integrator": "R&D" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD041", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD042", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD043", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD044", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD045", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD046", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD047", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD048", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD049", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD04A", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD04B", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD04C", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD04D", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD04E", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel, Gasoline", + "company": "EFKON AG", + "mad": "0xD04F", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD050", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD051", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD052", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD053", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD054", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD055", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD056", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD057", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD058", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD059", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD05A", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD05B", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD05C", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD05D", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD05E", + "service_provider": "Efkon", + "system_integrator": "Efkon" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD05F", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD060", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD061", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD062", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD063", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD064", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD065", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD066", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD067", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD068", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD069", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD06A", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD06B", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD06C", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Fuel Gasoline India", + "company": "EFKON AG", + "mad": "0xD06D", + "service_provider": "Efkon AG", + "system_integrator": "Efkon AG" + }, + { + "application": "Applications for oil and gas", + "company": "Tietoenator Energy Components", + "mad": "0xD06E", + "service_provider": "Tietoenator", + "system_integrator": "Tietoenator" + }, + { + "application": "Applications for oil and gas", + "company": "Tietoenator Energy Components", + "mad": "0xD06F", + "service_provider": "Tietoenator", + "system_integrator": "Tietoenator" + }, + { + "application": "Applications for oil and gas", + "company": "Tietoenator Energy Components", + "mad": "0xD070", + "service_provider": "Tietoenator", + "system_integrator": "Tietoenator" + }, + { + "application": "Applications for oil and gas", + "company": "Tietoenator Energy Components", + "mad": "0xD071", + "service_provider": "Tietoenator", + "system_integrator": "Tietoenator" + }, + { + "application": "Fuel, gasoline station", + "company": "Hectronic GmbH", + "mad": "0xD072", + "service_provider": "Hectronic GmbH", + "system_integrator": "Hectronic GmbH" + }, + { + "application": "Fuel, gasoline", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0xD073", + "service_provider": "BICA AG", + "system_integrator": "BICA AG" + }, + { + "application": "Fuel, gasoline", + "company": "PBV Kaufmann Systeme GmbH", + "mad": "0xD074", + "service_provider": "BICA AG", + "system_integrator": "BICA AG" + }, + { + "application": "", + "company": "Hectronic GmbH", + "mad": "0xD075", + "service_provider": "", + "system_integrator": "Hectronic GmbH" + }, + { + "application": "", + "company": "Hectronic GmbH", + "mad": "0xD076", + "service_provider": "", + "system_integrator": "Hectronic GmbH" + }, + { + "application": "", + "company": "Hectronic GmbH", + "mad": "0xD077", + "service_provider": "", + "system_integrator": "Hectronic GmbH" + }, + { + "application": "Time attendance, fuel, access control", + "company": "Emcard a.s.", + "mad": "0xD078", + "service_provider": "Emtest", + "system_integrator": "Emtest" + }, + { + "application": "Identification", + "company": "Honeywell Automation India Limited", + "mad": "0xD079", + "service_provider": "Honeywell Automation India Limited", + "system_integrator": "Honeywell Automation India Limited" + }, + { + "application": "Security and safty services", + "company": "Staat der Nederlanden, Ministerie van Financien Belastingdienst/Centrum voor facilitaire dienstverlening", + "mad": "0xD801", + "service_provider": "Siemens Nederland BV", + "system_integrator": "Siemens Nederland BV" + }, + { + "application": "", + "company": "X-Ident GmbH", + "mad": "0xE101", + "service_provider": "", + "system_integrator": "" + }, + { + "application": "NFC applications", + "company": "Philips Semiconductors Gratkorn GmbH", + "mad": "0xE102", + "service_provider": "Philips Semiconductors", + "system_integrator": "Philips Semiconductors" + }, + { + "application": "NFC applications", + "company": "NXP Semiconductors", + "mad": "0xE103", + "service_provider": "Philips SC", + "system_integrator": "Philips SC" + }, + { + "application": "Global purse", + "company": "Microtronic AG", + "mad": "0xE104", + "service_provider": "Microtronic AG", + "system_integrator": "Microtronic AG" + }, + { + "application": "Global purse", + "company": "Microtronic AG", + "mad": "0xE105", + "service_provider": "Microtronic AG", + "system_integrator": "Microtronic AG" + }, + { + "application": "Global purse", + "company": "Microtronic AG", + "mad": "0xE106", + "service_provider": "Microtronic AG", + "system_integrator": "Microtronic AG" + }, + { + "application": "Global purse", + "company": "Microtronic AG", + "mad": "0xE107", + "service_provider": "Microtronic AG", + "system_integrator": "Microtronic AG" + }, + { + "application": "MS-Windows Logon and security facilities", + "company": "Integrated Engineering", + "mad": "0xE801", + "service_provider": "IE Holding", + "system_integrator": "IE Holding" + }, + { + "application": "Security and safty services", + "company": "Staat der Nederlanden, Ministerie van Financien Belastingdienst/Centrum voor facilitaire dienstverlening", + "mad": "0xE802", + "service_provider": "Siemens Nederland BV", + "system_integrator": "Siemens Nederland BV" + }, + { + "application": "Safeguard Security Products Family", + "company": "Utimaco Safeware AG - Österreich", + "mad": "0xE803", + "service_provider": "Utimaco Safeware AG", + "system_integrator": "Ultimaco Safeware AG" + }, + { + "application": "Safeguard Security Products Family", + "company": "Utimaco Safeware AG - Österreich", + "mad": "0xE804", + "service_provider": "Utimaco Safeware AG", + "system_integrator": "Ultimaco Safeware AG" + }, + { + "application": "Safeguard Security Products Family", + "company": "Utimaco Safeware AG - Österreich", + "mad": "0xE805", + "service_provider": "Utimaco Safeware AG", + "system_integrator": "Ultimaco Safeware AG" + }, + { + "application": "Computer, car parking, elec. purse, access control & security", + "company": "DECA Engineering", + "mad": "0xE806", + "service_provider": "Deca Engineering", + "system_integrator": "Deca Engineering" + }, + { + "application": "", + "company": "TechID Engineering bv", + "mad": "0xE807", + "service_provider": "Tech ID", + "system_integrator": "Tech ID" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0xE808", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0xE809", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0xE80A", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0xE80B", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "", + "company": "Horoquartz Gestion des Temps", + "mad": "0xE80C", + "service_provider": "Horoquartz", + "system_integrator": "Horoquartz" + }, + { + "application": "PC log on via MIFARE & DESfire", + "company": "Tx Systems Inc", + "mad": "0xE80D", + "service_provider": "TX Systems", + "system_integrator": "TX Systems" + }, + { + "application": "Access control, computer application, company services", + "company": "Volvo Car Corporation", + "mad": "0xE80E", + "service_provider": "Volvo Car", + "system_integrator": "Volvo Car" + }, + { + "application": "Software Licensing Application", + "company": "OmniCard Group B.V.", + "mad": "0xE80F", + "service_provider": "OmniCard Group B.V.", + "system_integrator": "OmniCard Group B.V." + }, + { + "application": "Computer logon", + "company": "Igel Technology GmbH", + "mad": "0xE810", + "service_provider": "Igel Technology GmbH", + "system_integrator": "Igel Technology GmbH" + }, + { + "application": "MS-Windows PC Logon", + "company": "United Access GmbH", + "mad": "0xE811", + "service_provider": "United Access GmbH", + "system_integrator": "United Access GmbH" + }, + { + "application": "Computer Technical Event - Membercard access control", + "company": "Strawberry AG", + "mad": "0xE812", + "service_provider": "Strawberry AG", + "system_integrator": "" + }, + { + "application": "Payment, payment OEM, payment partner, entertainment, OEM data", + "company": "Payment Solution AG", + "mad": "0xE814", + "service_provider": "Payment Solution AG", + "system_integrator": "Payment Solution AG" + }, + { + "application": "MIFARE PC Logon & Security", + "company": "PinCash International", + "mad": "0xE815", + "service_provider": "Pincash international BV", + "system_integrator": "Pincash international BV" + }, + { + "application": "Logical Access control and software licensing", + "company": "INID BV", + "mad": "0xE816", + "service_provider": "INID", + "system_integrator": "INID" + }, + { + "application": "Miscellaneous applications", + "company": "TechID Engineering bv", + "mad": "0xF001", + "service_provider": "Tech ID", + "system_integrator": "Tech ID" + } +] \ No newline at end of file diff --git a/client/src/aidsearch.c b/client/src/aidsearch.c index 676db4cc7..47c64e77b 100644 --- a/client/src/aidsearch.c +++ b/client/src/aidsearch.c @@ -13,7 +13,7 @@ #include "fileutils.h" #include "pm3_cmd.h" -int openAIDFile(json_t **root, bool verbose) { +static int openAIDFile(json_t **root, bool verbose) { json_error_t error; char *path; @@ -42,8 +42,7 @@ out: return retval; } -int closeAIDFile(json_t *root) { - +static int closeAIDFile(json_t *root) { json_decref(root); return PM3_SUCCESS; } @@ -67,11 +66,10 @@ json_t *AIDSearchGetElm(json_t *root, int elmindx) { } int AIDSearchFree(json_t *root) { - return closeAIDFile(root); } -const char *jsonStrGet(json_t *data, char *name) { +static const char *jsonStrGet(json_t *data, const char *name) { json_t *jstr; jstr = json_object_get(data, name); @@ -88,7 +86,7 @@ const char *jsonStrGet(json_t *data, char *name) { return cstr; } -bool aidCompare(const char *aidlarge, const char *aidsmall) { +static bool aidCompare(const char *aidlarge, const char *aidsmall) { if (strcmp(aidlarge, aidsmall) == 0) return true; @@ -122,8 +120,8 @@ int PrintAIDDescription(json_t *xroot, char *aid, bool verbose) { goto out; json_t *elm = NULL; - int maxaidlen = 0; - for (int elmindx = 0; elmindx < json_array_size(root); elmindx++) { + uint32_t maxaidlen = 0; + for (uint32_t elmindx = 0; elmindx < json_array_size(root); elmindx++) { json_t *data = AIDSearchGetElm(root, elmindx); if (data == NULL) continue; diff --git a/client/src/aidsearch.h b/client/src/aidsearch.h index 00d2b134a..585e173c6 100644 --- a/client/src/aidsearch.h +++ b/client/src/aidsearch.h @@ -15,14 +15,13 @@ #include #include - -#include +#include "jansson.h" int PrintAIDDescription(json_t *xroot, char *aid, bool verbose); int PrintAIDDescriptionBuf(json_t *root, uint8_t *aid, size_t aidlen, bool verbose); json_t *AIDSearchInit(bool verbose); json_t *AIDSearchGetElm(json_t *root, int elmindx); bool AIDGetFromElm(json_t *data, uint8_t *aid, size_t aidmaxlen, int *aidlen); -int AIDSearchFree(); +int AIDSearchFree(json_t *root); #endif diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 9a809f603..007c32c8a 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -18,6 +18,7 @@ #include "commonutil.h" // ARRAYLEN #include "cmdparser.h" // for command_t #include "ui.h" // for show graph controls +#include "proxgui.h" #include "graph.h" // for graph data #include "comms.h" #include "lfdemod.h" // for demod code @@ -287,7 +288,7 @@ static int usage_data_buffclear(void) { PrintAndLogEx(NORMAL, " h This help"); return PM3_SUCCESS; } -static int usage_data_fsktonrz() { +static int usage_data_fsktonrz(void) { PrintAndLogEx(NORMAL, "Usage: data fsktonrz c l f "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); @@ -566,7 +567,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &); - if (!maxLen) maxLen = BIGBUF_SIZE; + if (!maxLen) maxLen = pm3_capabilities.bigbuf_size; if (invert != 0 && invert != 1) { PrintAndLogEx(WARNING, "Invalid argument: %s", Cmd); @@ -1516,16 +1517,18 @@ static int CmdHexsamples(const char *Cmd) { uint32_t offset = 0; char string_buf[25]; char *string_ptr = string_buf; - uint8_t got[BIGBUF_SIZE]; + uint8_t got[pm3_capabilities.bigbuf_size]; sscanf(Cmd, "%u %u", &requested, &offset); /* if no args send something */ if (requested == 0) requested = 8; + if (requested > pm3_capabilities.bigbuf_size) + requested = pm3_capabilities.bigbuf_size; if (offset + requested > sizeof(got)) { - PrintAndLogEx(NORMAL, "Tried to read past end of buffer, + > %d", BIGBUF_SIZE); + PrintAndLogEx(NORMAL, "Tried to read past end of buffer, + > %d", pm3_capabilities.bigbuf_size); return PM3_EINVARG; } @@ -1594,10 +1597,11 @@ int getSamples(uint32_t n, bool verbose) { // we don't have to worry about remaining trash // in the last byte in case the bits-per-sample // does not line up on byte boundaries - uint8_t got[BIGBUF_SIZE - 1] = { 0 }; + uint8_t got[pm3_capabilities.bigbuf_size - 1]; + memset(got, 0x00, sizeof(got)); - if (n == 0 || n > sizeof(got)) - n = sizeof(got); + if (n == 0 || n > pm3_capabilities.bigbuf_size - 1) + n = pm3_capabilities.bigbuf_size - 1; if (verbose) PrintAndLogEx(INFO, "Reading " _YELLOW_("%u") " bytes from device memory", n); @@ -1623,7 +1627,7 @@ int getSamples(uint32_t n, bool verbose) { if (verbose) PrintAndLogEx(INFO, "Unpacking..."); BitstreamOut bout = { got, bits_per_sample * n, 0}; - int j = 0; + uint32_t j = 0; for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) { uint8_t sample = getByte(bits_per_sample, &bout); GraphBuffer[j] = ((int) sample) - 127; @@ -1633,7 +1637,7 @@ int getSamples(uint32_t n, bool verbose) { if (verbose) PrintAndLogEx(INFO, "Unpacked %d samples", j); } else { - for (int j = 0; j < n; j++) { + for (uint32_t j = 0; j < n; j++) { GraphBuffer[j] = ((int)got[j]) - 127; } GraphTraceLen = n; @@ -1670,19 +1674,21 @@ int CmdTuneSamples(const char *Cmd) { RepaintGraphWindow(); int timeout = 0; + int timeout_max = 20; PrintAndLogEx(INFO, "Measuring antenna characteristics, please wait..."); clearCommandBuffer(); SendCommandNG(CMD_MEASURE_ANTENNA_TUNING, NULL, 0); PacketResponseNG resp; - while (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING, &resp, 2000)) { - timeout++; - printf("."); + PrintAndLogEx(INPLACE, "% 3i", timeout_max - timeout); + while (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING, &resp, 500)) { fflush(stdout); - if (timeout > 7) { + if (timeout >= timeout_max) { PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); return PM3_ETIMEOUT; } + timeout++; + PrintAndLogEx(INPLACE, "% 3i", timeout_max - timeout); } if (resp.status != PM3_SUCCESS) { @@ -1727,10 +1733,7 @@ int CmdTuneSamples(const char *Cmd) { else sprintf(judgement, _GREEN_("OK")); - PrintAndLogEx(NORMAL, "%sLF antenna is %s \n" - , (package->peak_v < LF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") - , judgement - ); + PrintAndLogEx((package->peak_v < LF_UNUSABLE_V) ? WARNING : SUCCESS, "LF antenna is %s \n", judgement); // HF evaluation if (package->v_hf > NON_VOLTAGE) @@ -1745,10 +1748,7 @@ int CmdTuneSamples(const char *Cmd) { else sprintf(judgement, _GREEN_("OK")); - PrintAndLogEx(NORMAL, "%sHF antenna is %s" - , (package->v_hf < HF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") - , judgement - ); + PrintAndLogEx((package->v_hf < HF_UNUSABLE_V) ? WARNING : SUCCESS, "HF antenna is %s \n", judgement); // graph LF measurements // even here, these values has 3% error. @@ -1809,7 +1809,7 @@ static int CmdLoad(const char *Cmd) { fclose(f); - PrintAndLogEx(SUCCESS, "loaded %zu samples", GraphTraceLen); + PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " samples", GraphTraceLen); uint8_t bits[GraphTraceLen]; size_t size = getFromGraphBuf(bits); @@ -2295,7 +2295,8 @@ static int CmdDataNDEF(const char *Cmd) { #define MAX_NDEF_LEN 2048 #endif - CLIParserInit("data ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "data ndef", "Prints NFC Data Exchange Format (NDEF)", "Usage:\n\tdata ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n"); @@ -2304,12 +2305,12 @@ static int CmdDataNDEF(const char *Cmd) { arg_strx0("dD", "data", "", "NDEF data to decode"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); int datalen = 0; uint8_t data[MAX_NDEF_LEN] = {0}; - CLIGetHexWithReturn(1, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, data, &datalen); + CLIParserFree(ctx); if (datalen == 0) return PM3_EINVARG; diff --git a/client/src/cmddata.h b/client/src/cmddata.h index a19bead27..abef8fde8 100644 --- a/client/src/cmddata.h +++ b/client/src/cmddata.h @@ -13,6 +13,10 @@ #include "common.h" +#ifdef __cplusplus +extern "C" { +#endif + //#include //size_t int CmdData(const char *Cmd); @@ -75,12 +79,13 @@ int AskEdgeDetect(const int *in, int *out, int len, int threshold); int demodIdteck(void); #define MAX_DEMOD_BUF_LEN (1024*128) -#define BIGBUF_SIZE 40000 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; extern size_t DemodBufferLen; extern int g_DemodClock; extern size_t g_DemodStartIdx; -extern uint8_t g_debugMode; +#ifdef __cplusplus +} +#endif #endif diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index 8d19c3888..e90e6025c 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -18,8 +18,8 @@ #include "comms.h" //getfromdevice #include "cmdflashmemspiffs.h" // spiffs commands -#include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" +#include "rsa.h" +#include "sha1.h" #define MCK 48000000 #define FLASH_MINFAST 24000000 //33000000 @@ -27,8 +27,6 @@ #define FLASH_FASTBAUD MCK #define FLASH_MINBAUD FLASH_FASTBAUD -#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST) - static int CmdHelp(const char *Cmd); static int usage_flashmem_spibaud(void) { @@ -170,7 +168,7 @@ static int CmdFlashMemLoad(const char *Cmd) { return PM3_EINVARG; } size_t datalen = 0; - uint16_t keycount = 0; + uint32_t keycount = 0; int res = 0; uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); @@ -182,6 +180,10 @@ static int CmdFlashMemLoad(const char *Cmd) { free(data); return PM3_EFILE; } + // limited space on flash mem + if (keycount > 0xFFFF) + keycount &= 0xFFFF; + data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; datalen += 2; @@ -193,6 +195,10 @@ static int CmdFlashMemLoad(const char *Cmd) { free(data); return PM3_EFILE; } + // limited space on flash mem + if (keycount > 0xFFFF) + keycount &= 0xFFFF; + data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; datalen += 2; @@ -204,6 +210,10 @@ static int CmdFlashMemLoad(const char *Cmd) { free(data); return PM3_EFILE; } + // limited space on flash mem + if (keycount > 0xFFFF) + keycount &= 0xFFFF; + data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; datalen += 2; diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index fbc99dbd5..6b11a30da 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -37,13 +37,14 @@ #include "cmdhfcryptorf.h" // CryptoRF #include "cmdtrace.h" // trace list #include "ui.h" +#include "proxgui.h" #include "cmddata.h" #include "graph.h" #include "fpga.h" static int CmdHelp(const char *Cmd); -static int usage_hf_search() { +static int usage_hf_search(void) { PrintAndLogEx(NORMAL, "Usage: hf search"); PrintAndLogEx(NORMAL, "Will try to find a HF read out of the unknown tag. Stops when found."); PrintAndLogEx(NORMAL, "Options:"); @@ -52,7 +53,7 @@ static int usage_hf_search() { return PM3_SUCCESS; } -static int usage_hf_sniff() { +static int usage_hf_sniff(void) { PrintAndLogEx(NORMAL, "The high frequence sniffer will assign all available memory on device for sniffed data"); PrintAndLogEx(NORMAL, "Use " _YELLOW_("'data samples'")" command to download from device, and " _YELLOW_("'data plot'")" to look at it"); PrintAndLogEx(NORMAL, "Press button to quit the sniffing.\n"); @@ -68,7 +69,7 @@ static int usage_hf_sniff() { return PM3_SUCCESS; } -static int usage_hf_tune() { +static int usage_hf_tune(void) { PrintAndLogEx(NORMAL, "Continuously measure HF antenna tuning."); PrintAndLogEx(NORMAL, "Press button or Enter to interrupt."); PrintAndLogEx(NORMAL, "Usage: hf tune [h] []"); @@ -253,7 +254,8 @@ int CmdHFSniff(const char *Cmd) { } int CmdHFPlot(const char *Cmd) { - CLIParserInit("hf plot", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf plot", "Plots HF signal after RF signal path and A/D conversion.", "This can be used after any hf command and will show the last few milliseconds of the HF signal.\n" "Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n"); @@ -261,7 +263,8 @@ int CmdHFPlot(const char *Cmd) { arg_param_begin, arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); uint8_t buf[FPGA_TRACE_SIZE]; diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 262e879f4..b41dabb7f 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -296,7 +296,7 @@ static int CmdHF14AReader(const char *Cmd) { break; default: PrintAndLogEx(WARNING, "Unknown command."); - return 1; + return PM3_EINVARG; } cmdp++; } @@ -312,7 +312,7 @@ static int CmdHF14AReader(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed"); DropField(); - return 1; + return PM3_ESOFT; } iso14a_card_select_t card; @@ -329,14 +329,14 @@ static int CmdHF14AReader(const char *Cmd) { if (select_status == 0) { if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed"); DropField(); - return 1; + return PM3_ESOFT; } if (select_status == 3) { PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); PrintAndLogEx(SUCCESS, "ATQA: %02x %02x", card.atqa[1], card.atqa[0]); DropField(); - return 1; + return PM3_ESOFT; } PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); @@ -356,7 +356,7 @@ static int CmdHF14AReader(const char *Cmd) { if (!silent) PrintAndLogEx(INFO, "field dropped."); } - return 0; + return PM3_SUCCESS; } static int CmdHF14AInfo(const char *Cmd) { @@ -364,7 +364,8 @@ static int CmdHF14AInfo(const char *Cmd) { bool do_nack_test = false; bool do_aid_search = false; - CLIParserInit("hf 14a info", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a info", "This command makes more extensive tests against a ISO14443a tag in order to collect information", "Sample:\n\thf 14a info -nsv - shows full information about the card\n"); @@ -375,16 +376,16 @@ static int CmdHF14AInfo(const char *Cmd) { arg_lit0("sS", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - verbose = arg_get_lit(1); - do_nack_test = arg_get_lit(2); - do_aid_search = arg_get_lit(3); + verbose = arg_get_lit(ctx, 1); + do_nack_test = arg_get_lit(ctx, 2); + do_aid_search = arg_get_lit(ctx, 3); - CLIParserFree(); + CLIParserFree(ctx); infoHF14A(verbose, do_nack_test, do_aid_search); - return 0; + return PM3_SUCCESS; } // Collect ISO14443 Type A UIDs @@ -401,7 +402,7 @@ static int CmdHF14ACUIDs(const char *Cmd) { for (int i = 0; i < n; i++) { if (kbd_enter_pressed()) { - PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); + PrintAndLogEx(WARNING, "aborted via keyboard!\n"); break; } @@ -437,6 +438,8 @@ int CmdHF14ASim(const char *Cmd) { bool setEmulatorMem = false; bool verbose = false; bool errors = false; + sector_t *k_sector = NULL; + uint8_t k_sectorsCount = 40; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -520,7 +523,7 @@ int CmdHF14ASim(const char *Cmd) { if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) break; nonces_t *data = (nonces_t *)resp.data.asBytes; - readerAttack(data[0], setEmulatorMem, verbose); + readerAttack(k_sector, k_sectorsCount, data[0], setEmulatorMem, verbose); keypress = kbd_enter_pressed(); } @@ -531,7 +534,7 @@ int CmdHF14ASim(const char *Cmd) { } if (resp.status == PM3_EOPABORTED && ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK)) - showSectorTable(); + showSectorTable(k_sector, k_sectorsCount); PrintAndLogEx(INFO, "Done"); return PM3_SUCCESS; @@ -878,7 +881,8 @@ static int CmdHF14AAPDU(const char *Cmd) { bool extendedAPDU = false; int le = 0; - CLIParserInit("hf 14a apdu", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a apdu", "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013", "Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n" "\thf 14a apdu -sd 00A404000E325041592E5359532E444446303100 - decode apdu\n" @@ -897,27 +901,28 @@ static int CmdHF14AAPDU(const char *Cmd) { arg_strx1(NULL, NULL, "", "data if `m` parameter included"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - activateField = arg_get_lit(1); - leaveSignalON = arg_get_lit(2); - decodeTLV = arg_get_lit(3); - decodeAPDU = arg_get_lit(4); + activateField = arg_get_lit(ctx, 1); + leaveSignalON = arg_get_lit(ctx, 2); + decodeTLV = arg_get_lit(ctx, 3); + decodeAPDU = arg_get_lit(ctx, 4); - CLIGetHexWithReturn(5, header, &headerlen); + CLIGetHexWithReturn(ctx, 5, header, &headerlen); makeAPDU = headerlen > 0; if (makeAPDU && headerlen != 4) { PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen); + CLIParserFree(ctx); return 1; } - extendedAPDU = arg_get_lit(6); - le = arg_get_int_def(7, 0); + extendedAPDU = arg_get_lit(ctx, 6); + le = arg_get_int_def(ctx, 7, 0); if (makeAPDU) { uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0}; int apdudatalen = 0; - CLIGetHexBLessWithReturn(8, apdudata, &apdudatalen, 1 + 2); + CLIGetHexBLessWithReturn(ctx, 8, apdudata, &apdudatalen, 1 + 2); APDUStruct apdu; apdu.cla = header[0]; @@ -933,24 +938,27 @@ static int CmdHF14AAPDU(const char *Cmd) { if (APDUEncode(&apdu, data, &datalen)) { PrintAndLogEx(ERR, "can't make apdu with provided parameters."); + CLIParserFree(ctx); return 2; } } else { if (extendedAPDU) { PrintAndLogEx(ERR, "make mode not set but here `e` option."); + CLIParserFree(ctx); return 3; } if (le > 0) { PrintAndLogEx(ERR, "make mode not set but here `l` option."); + CLIParserFree(ctx); return 3; } // len = data + PCB(1b) + CRC(2b) - CLIGetHexBLessWithReturn(8, data, &datalen, 1 + 2); + CLIGetHexBLessWithReturn(ctx, 8, data, &datalen, 1 + 2); } + CLIParserFree(ctx); - CLIParserFree(); PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen)); if (decodeAPDU) { @@ -1162,7 +1170,8 @@ static int waitCmd(uint8_t iSelect) { static int CmdHF14AAntiFuzz(const char *Cmd) { - CLIParserInit("hf 14a antifuzz", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a antifuzz", "Tries to fuzz the ISO14443a anticollision phase", "Usage:\n" "\thf 14a antifuzz -4\n"); @@ -1174,15 +1183,15 @@ static int CmdHF14AAntiFuzz(const char *Cmd) { arg_lit0(NULL, "10", "10 byte uid"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); uint8_t arg0 = FLAG_4B_UID_IN_DATA; - if (arg_get_lit(2)) + if (arg_get_lit(ctx, 2)) arg0 = FLAG_7B_UID_IN_DATA; - if (arg_get_lit(3)) + if (arg_get_lit(ctx, 3)) arg0 = FLAG_10B_UID_IN_DATA; - CLIParserFree(); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_ANTIFUZZ, arg0, 0, 0, NULL, 0); return 0; @@ -1190,7 +1199,8 @@ static int CmdHF14AAntiFuzz(const char *Cmd) { static int CmdHF14AChaining(const char *Cmd) { - CLIParserInit("hf 14a chaining", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a chaining", "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "Usage:\n" "\thf 14a chaining disable -> disable chaining\n" @@ -1201,10 +1211,10 @@ static int CmdHF14AChaining(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - struct arg_str *str = arg_get_str(1); - int len = arg_get_str_len(1); + struct arg_str *str = arg_get_str(ctx, 1); + int len = arg_get_str_len(ctx, 1); if (len && (!strcmp(str->sval[0], "enable") || !strcmp(str->sval[0], "1"))) APDUInFramingEnable = true; @@ -1212,7 +1222,7 @@ static int CmdHF14AChaining(const char *Cmd) { if (len && (!strcmp(str->sval[0], "disable") || !strcmp(str->sval[0], "0"))) APDUInFramingEnable = false; - CLIParserFree(); + CLIParserFree(ctx); PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled"); @@ -1245,8 +1255,8 @@ int CmdHF14A(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -static void printTag(char *tag) { - PrintAndLogEx(SUCCESS, "POSSIBLE TYPE:" _YELLOW_(" %s"), tag); +static void printTag(const char *tag) { + PrintAndLogEx(SUCCESS, " " _YELLOW_("%s"), tag); } @@ -1261,9 +1271,11 @@ typedef enum { } nxp_mifare_type_t; // According to NXP AN10833 Rev 3.6 MIFARE Type Identification, Table 6 -int detect_nxp_card(uint8_t sak, uint16_t atqa) { +static int detect_nxp_card(uint8_t sak, uint16_t atqa) { int type = MTNONE; + PrintAndLogEx(SUCCESS, "Possible types:"); + if (sak == 0x00) { printTag("NTAG 20x / 21x / 21x TT / I2C plus"); printTag("MIFARE Ultralight / C / EV1 / Nano"); @@ -1274,10 +1286,12 @@ int detect_nxp_card(uint8_t sak, uint16_t atqa) { printTag("TNP3xxx (Activision Game Appliance)"); type = MTCLASSIC; } + if ((sak & 0x04) == 0x04) { printTag("Any MIFARE CL1 / NTAG424DNA"); type |= MTDESFIRE; } + if ((sak & 0x08) == 0x08) { printTag("MIFARE Classic 1K / Classic 1K CL2"); printTag("MIFARE Plus 2K / Plus EV1 2K"); @@ -1285,18 +1299,22 @@ int detect_nxp_card(uint8_t sak, uint16_t atqa) { type |= MTCLASSIC; type |= MTPLUS; } + if ((sak & 0x09) == 0x09) { printTag("MIFARE Mini 0.3K / Mini CL2 0.3K"); type |= MTMINI; } + if ((sak & 0x10) == 0x10) { printTag("MIFARE Plus 2K / Plus CL2 2K"); type |= MTPLUS; } + if ((sak & 0x11) == 0x11) { printTag("MIFARE Plus 4K / Plus CL2 4K"); type |= MTPLUS; } + if ((sak & 0x18) == 0x18) { if (atqa == 0x0042) { printTag("MIFARE Plus 4K / Plus EV1 4K"); @@ -1306,8 +1324,8 @@ int detect_nxp_card(uint8_t sak, uint16_t atqa) { printTag("MIFARE Classic 4K / Classic 4K CL2"); type |= MTCLASSIC; } - } + if ((sak & 0x20) == 0x20) { if (atqa == 0x0344) { printTag("MIFARE DESFire EV1 2K/4K/8K / DESFire EV1 CL2 2K/4K/8K"); @@ -1322,28 +1340,35 @@ int detect_nxp_card(uint8_t sak, uint16_t atqa) { type |= MTPLUS; } } + if ((sak & 0x24) == 0x24) { if (atqa == 0x0344) { printTag("MIFARE DESFire CL1 / DESFire EV1 CL1"); type |= MTDESFIRE; } } + if ((sak & 0x28) == 0x28) { if (atqa == 0x0344) { printTag("MIFARE DESFire CL1 / DESFire EV1 CL1"); type |= MTDESFIRE; } } + + if (type == MTNONE) { + PrintAndLogEx(WARNING, " failed to fingerprint"); + } + return type; } typedef struct { uint8_t uid0; uint8_t uid1; - char *desc; -} uidname; + const char *desc; +} uid_label_name; -const uidname uidmap[] = { +const uid_label_name uid_label_map[] = { // UID0, UID1, TEXT {0x02, 0x84, "M24SR64-Y"}, {0x02, 0xA3, "25TA02KB-P"}, @@ -1355,16 +1380,15 @@ const uidname uidmap[] = { {0x00, 0x00, "None"} }; -void getTagLabel(uint8_t uid0, uint8_t uid1) { +static void getTagLabel(uint8_t uid0, uint8_t uid1) { int i = 0; - while (uidmap[i].uid0 != 0x00) { - if ((uidmap[i].uid0 == uid0) && (uidmap[i].uid1 == uid1)) { - PrintAndLogEx(SUCCESS, _YELLOW_(" %s"), uidmap[i].desc); + while (uid_label_map[i].uid0 != 0x00) { + if ((uid_label_map[i].uid0 == uid0) && (uid_label_map[i].uid1 == uid1)) { + PrintAndLogEx(SUCCESS, _YELLOW_(" %s"), uid_label_map[i].desc); return; } i += 1; } - return; } int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { @@ -1404,7 +1428,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } if (verbose) { - PrintAndLogEx(SUCCESS, "-- ISO14443-a Information -----------------------------------"); + PrintAndLogEx(SUCCESS, "------ " _CYAN_("ISO14443-a Information") "------------------"); PrintAndLogEx(SUCCESS, "-------------------------------------------------------------"); } PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); @@ -1416,7 +1440,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { bool isMifarePlus = false; bool isMifareUltralight = false; int nxptype = MTNONE; - // Double & triple sized UID, can be mapped to a manufacturer. + if (card.uidlen <= 4) { nxptype = detect_nxp_card(card.sak, ((card.atqa[1] << 8) + card.atqa[0])); @@ -1427,9 +1451,12 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if ((nxptype & MTOTHER) == MTOTHER) isMifareClassic = true; - } - if (card.uidlen > 4) { + + } else { + + // Double & triple sized UID, can be mapped to a manufacturer. PrintAndLogEx(SUCCESS, "MANUFACTURER: " _YELLOW_("%s"), getTagInfo(card.uid[0])); + switch (card.uid[0]) { case 0x04: // NXP nxptype = detect_nxp_card(card.sak, ((card.atqa[1] << 8) + card.atqa[0])); @@ -1524,7 +1551,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (select_status == 2) { uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 clearCommandBuffer(); - SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, sizeof(rats)); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, sizeof(rats)); WaitForResponse(CMD_ACK, &resp); memcpy(card.ats, resp.data.asBytes, resp.oldarg[0]); @@ -1746,18 +1773,9 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { PrintAndLogEx(INFO, "proprietary non iso14443-4 card found, RATS not supported"); } - if (isMifareUltralight) { - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu info`")); - } - if (isMifarePlus) { - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfp info`")); - } - if (isMifareDESFire) { - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfdes info`")); - } - + int isMagic = 0; if (isMifareClassic || isMifareUltralight) { - detect_classic_magic(); + isMagic = detect_classic_magic(); if (isMifareClassic) { int res = detect_classic_prng(); @@ -1780,6 +1798,15 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } } + if (isMifareUltralight) + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu info`")); + + if (isMifarePlus && isMagic == 0) + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfp info`")); + + if (isMifareDESFire && isMagic == 0) + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfdes info`")); + DropField(); return select_status; } diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 859df4a23..bfb19323b 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -684,7 +684,7 @@ static bool HF14B_Std_Reader(bool verbose) { } // test for other 14b type tags (mimic another reader - don't have tags to identify) -static bool HF14B_Other_Reader() { +static bool HF14B_Other_Reader(void) { // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80}; // uint8_t datalen = 4; @@ -693,7 +693,7 @@ static bool HF14B_Other_Reader() { // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC; // clearCommandBuffer(); - // SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, datalen, 0, data, datalen); + // SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, datalen, 0, data, datalen); // PacketResponseNG resp; // WaitForResponse(CMD_ACK,&resp); @@ -707,7 +707,7 @@ static bool HF14B_Other_Reader() { // data[0] = ISO14443B_AUTHENTICATE; // clearCommandBuffer(); - // SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1); + // SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1); // PacketResponseNG resp; // WaitForResponse(CMD_ACK, &resp); @@ -721,7 +721,7 @@ static bool HF14B_Other_Reader() { // data[0] = ISO14443B_RESET; // clearCommandBuffer(); - // SendCommandOLD(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1); + // SendCommandMIX(CMD_HF_ISO14443B_COMMAND, flags, 1, 0, data, 1); // PacketResponseNG resp; // WaitForResponse(CMD_ACK, &resp); @@ -913,7 +913,7 @@ static int CmdHF14BDump(const char *Cmd) { req[1] = blocknum; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ISO14443B_COMMAND, ISO14B_APPEND_CRC | ISO14B_RAW, 2, 0, req, sizeof(req)); + SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APPEND_CRC | ISO14B_RAW, 2, 0, req, sizeof(req)); if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 620a75bd7..627e7e4bc 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -263,7 +263,6 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { */ uint8_t i; - int res; bool is_valid = false; for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) { @@ -271,14 +270,14 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { uint8_t key[PUBLIC_ECDA_KEYLEN]; param_gethex_to_eol(nxp_15693_public_keys[i].value, 0, key, PUBLIC_ECDA_KEYLEN, &dl); - res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, false); + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, false); is_valid = (res == 0); if (is_valid) break; } PrintAndLogEx(NORMAL, ""); - if (is_valid == false) { + if (is_valid == false || i == ARRAYLEN(nxp_15693_public_keys)) { PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); return PM3_ESOFT; } @@ -470,8 +469,8 @@ static int usage_15_restore(void) { {"h", "this help"}, {"-2", "use slower '1 out of 256' mode"}, {"-o", "set OPTION Flag (needed for TI)"}, + {"a", "use addressed mode"}, {"r ", "numbers of retries on error, default is 3"}, - {"u ", "load hf-15--dump.bin"}, {"f ", "load "}, {"b ", "block size, default is 4"} }; @@ -746,14 +745,14 @@ static int NxpSysInfo(uint8_t *uid) { if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to NXP systeminfo command"); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } bool support_signature = (recv[5] & 0x01); @@ -855,14 +854,14 @@ static int NxpSysInfo(uint8_t *uid) { if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } uint8_t signature[32] = {0x00}; @@ -916,14 +915,14 @@ static int CmdHF15Info(const char *Cmd) { if (status < 2) { PrintAndLogEx(WARNING, "iso15693 card doesn't answer to systeminfo command"); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } recv = resp.data.asBytes; if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } memcpy(uid, recv + 2, sizeof(uid)); @@ -1090,7 +1089,7 @@ static int CmdHF15WriteAfi(const char *Cmd) { if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } PrintAndLogEx(NORMAL, ""); @@ -1149,7 +1148,7 @@ static int CmdHF15WriteDsfid(const char *Cmd) { if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } PrintAndLogEx(NORMAL, ""); @@ -1273,7 +1272,7 @@ static int CmdHF15Dump(const char *Cmd) { size_t datalen = blocknum * 4; saveFile(filename, ".bin", data, datalen); saveFileEML(filename, data, datalen, 4); - saveFileJSON(filename, jsf15, data, datalen); + saveFileJSON(filename, jsf15, data, datalen, NULL); return PM3_SUCCESS; } @@ -1430,7 +1429,7 @@ static int CmdHF15Readmulti(const char *Cmd) { uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(FAILED, "iso15693 card select failed"); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } recv = resp.data.asBytes; @@ -1442,7 +1441,7 @@ static int CmdHF15Readmulti(const char *Cmd) { if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(FAILED, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } // skip status byte @@ -1512,7 +1511,7 @@ static int CmdHF15Read(const char *Cmd) { uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(ERR, "iso15693 card select failed"); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } recv = resp.data.asBytes; @@ -1524,7 +1523,7 @@ static int CmdHF15Read(const char *Cmd) { if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } // print response @@ -1598,7 +1597,7 @@ static int CmdHF15Write(const char *Cmd) { uint32_t status = resp.oldarg[0]; if (status < 2) { PrintAndLogEx(FAILED, "iso15693 card select failed"); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } recv = resp.data.asBytes; @@ -1610,7 +1609,7 @@ static int CmdHF15Write(const char *Cmd) { if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } PrintAndLogEx(NORMAL, "OK"); @@ -1618,34 +1617,29 @@ static int CmdHF15Write(const char *Cmd) { } static int CmdHF15Restore(const char *Cmd) { - FILE *f; - uint8_t uid[8] = {0x00}; + char newPrefix[60] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00}; - char buff[255] = {0x00}; size_t blocksize = 4; - uint8_t cmdp = 0; - char newCmdPrefix[FILE_PATH_SIZE + 1] = {0x00}, tmpCmd[FILE_PATH_SIZE + 262] = {0x00}; - char param[FILE_PATH_SIZE] = ""; - char hex[255] = ""; - uint8_t retries = 3, i = 0; - int retval = 0; + uint8_t cmdp = 0, retries = 3; + bool addressed_mode = false; while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { - case '-': + case '-': { + char param[3] = ""; param_getstr(Cmd, cmdp, param, sizeof(param)); switch (param[1]) { case '2': case 'o': - strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix) - 1); - strncat(newCmdPrefix, param, sizeof(newCmdPrefix) - strlen(newCmdPrefix) - 1); + sprintf(newPrefix, " %s", param); break; default: - PrintAndLogEx(WARNING, "Unknown parameter '%s'", param); + PrintAndLogEx(WARNING, "11 Unknown parameter " _YELLOW_("'%s'"), param); return usage_15_restore(); } break; + } case 'f': param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE); cmdp++; @@ -1658,15 +1652,13 @@ static int CmdHF15Restore(const char *Cmd) { blocksize = param_get8ex(Cmd, cmdp + 1, 4, 10); cmdp++; break; - case 'u': - param_getstr(Cmd, cmdp + 1, buff, FILE_PATH_SIZE); - cmdp++; - snprintf(filename, sizeof(filename), "hf-15-%s-dump.bin", buff); + case 'a': + addressed_mode = true; break; case 'h': return usage_15_restore(); default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + PrintAndLogEx(WARNING, "Unknown parameter " _YELLOW_("'%c'"), param_getchar(Cmd, cmdp)); return usage_15_restore(); } cmdp++; @@ -1679,62 +1671,65 @@ static int CmdHF15Restore(const char *Cmd) { return usage_15_restore(); } - if ((f = fopen(filename, "rb")) == NULL) { + uint8_t uid[8] = {0x00}; + if (!getUID(uid)) { + PrintAndLogEx(WARNING, "No tag found"); + return PM3_ESOFT; + } - PrintAndLogEx(WARNING, "Could not find file %s", filename); + size_t datalen = 0; + uint8_t *data = NULL; + if (loadFile_safe(filename, ".bin", (void **)&data, &datalen) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), filename); return PM3_EFILE; } - if (!getUID(uid)) { - PrintAndLogEx(WARNING, "No tag found"); - fclose(f); + if ((datalen % blocksize) != 0) { + PrintAndLogEx(WARNING, "Datalen %zu isn't dividable with blocksize %zu", datalen, blocksize); + free(data); return PM3_ESOFT; } PrintAndLogEx(INFO, "Restoring data blocks."); - while (1) { - uint8_t tried = 0; - hex[0] = 0x00; - tmpCmd[0] = 0x00; + int retval = PM3_SUCCESS; + size_t bytes = 0; + uint16_t i = 0; + while (bytes < datalen) { - size_t bytes_read = fread(buff, 1, blocksize, f); - if (bytes_read == 0) { - PrintAndLogEx(SUCCESS, "File reading done `%s`", filename); - fclose(f); - return PM3_SUCCESS; - } else if (bytes_read != blocksize) { - PrintAndLogEx(ERR, "File reading error (%s), %zu bytes read instead of %zu bytes.", filename, bytes_read, blocksize); - fclose(f); - return PM3_EFILE; + uint8_t tried = 0; + char hex[40] = {0x00}; + char tmpCmd[200] = {0x00}; + + if (addressed_mode) { + char uidhex[17] = {0x00}; + hex_to_buffer((uint8_t *)uidhex, uid, sizeof(uid), sizeof(uidhex) - 1, 0, false, true); + hex_to_buffer((uint8_t *)hex, data + i, blocksize, sizeof(hex) - 1, 0, false, true); + snprintf(tmpCmd, sizeof(tmpCmd), "%s %s %u %s", newPrefix, uidhex, i, hex); + } else { + hex_to_buffer((uint8_t *)hex, data + i, blocksize, sizeof(hex) - 1, 0, false, true); + snprintf(tmpCmd, sizeof(tmpCmd), "%s u %u %s", newPrefix, i, hex); } - for (int j = 0; j < blocksize; j++) - snprintf(hex + j * 2, 3, "%02X", buff[j]); - - for (int j = 0; j < ARRAYLEN(uid); j++) - snprintf(buff + j * 2, 3, "%02X", uid[j]); - - //TODO: Addressed mode currently not work - //snprintf(tmpCmd, sizeof(tmpCmd), "%s %s %d %s", newCmdPrefix, buff, i, hex); - snprintf(tmpCmd, sizeof(tmpCmd), "%s u %u %s", newCmdPrefix, i, hex); - PrintAndLogEx(DEBUG, "Command to be sent| %s", tmpCmd); + PrintAndLogEx(DEBUG, "hf 15 write %s", tmpCmd); for (tried = 0; tried < retries; tried++) { if (!(retval = CmdHF15Write(tmpCmd))) { break; } } + if (tried >= retries) { - fclose(f); + free(data); PrintAndLogEx(FAILED, "Restore failed. Too many retries."); return retval; } - + bytes += blocksize; i++; } - fclose(f); - PrintAndLogEx(INFO, "Finish restore"); + free(data); + PrintAndLogEx(INFO, "done"); + PrintAndLogEx(HINT, "Try reading your card to verify with " _YELLOW_("`hf 15 dump`")); return PM3_SUCCESS; } diff --git a/client/src/cmdhfcryptorf.c b/client/src/cmdhfcryptorf.c index 559dc0e35..7f727d4bf 100644 --- a/client/src/cmdhfcryptorf.c +++ b/client/src/cmdhfcryptorf.c @@ -495,7 +495,7 @@ static int CmdHFCryptoRFESave(const char *Cmd) { //needs to change saveFileEML(filename, data, numofbytes, 8); //needs to change - saveFileJSON(filename, jsfRaw, data, numofbytes); + saveFileJSON(filename, jsfRaw, data, numofbytes, NULL); return PM3_SUCCESS; } diff --git a/client/src/cmdhfepa.c b/client/src/cmdhfepa.c index e83ee39bf..b7c49bd83 100644 --- a/client/src/cmdhfepa.c +++ b/client/src/cmdhfepa.c @@ -92,8 +92,8 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { while (Cmd[skip] != ' ' && Cmd[skip] != '\0') { // convert scan_return = sscanf(Cmd + skip, - "%2X%n", - (unsigned int *)(apdus[i] + apdu_lengths[i]), + "%2" SCNx8 "%n", + apdus[i] + apdu_lengths[i], &skip_add ); diff --git a/client/src/cmdhffelica.c b/client/src/cmdhffelica.c index dc3b07a1b..1fcf23fa3 100644 --- a/client/src/cmdhffelica.c +++ b/client/src/cmdhffelica.c @@ -22,7 +22,7 @@ #include "util.h" #include "ui.h" #include "mifare.h" // felica_card_select_t struct -#include "mbedtls/des.h" +#include "des.h" #define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len)) static int CmdHelp(const char *Cmd); @@ -123,7 +123,7 @@ static int usage_hf_felica_request_response(void) { return PM3_SUCCESS; } -static void print_status_flag1_interpretation() { +static void print_status_flag1_interpretation(void) { PrintAndLogEx(NORMAL, "\nStatus Flag1:"); PrintAndLogEx(NORMAL, " - 00h : Indicates the successful completion of a command."); PrintAndLogEx(NORMAL, " - FFh : If an error occurs during the processing of a command that includes no list in the command packet, or if " @@ -133,7 +133,7 @@ static void print_status_flag1_interpretation() { "indicating the location of the error."); } -static void print_status_flag2_interpration() { +static void print_status_flag2_interpration(void) { PrintAndLogEx(NORMAL, "\nStatus Flag2:"); PrintAndLogEx(NORMAL, " - 00h : Indicates the successful completion of a command."); PrintAndLogEx(NORMAL, " - 01h : The calculated result is either less than zero when the purse data is decremented, or exceeds 4" @@ -167,7 +167,7 @@ static void print_status_flag2_interpration() { PrintAndLogEx(NORMAL, " - C2h : Command is disabled already: This is the error that occurs in issuance commands."); } -static void print_block_list_element_constraints() { +static void print_block_list_element_constraints(void) { PrintAndLogEx(NORMAL, " - Each Block List Element shall satisfy the following conditions:"); PrintAndLogEx(NORMAL, " - The value of Service Code List Order shall not exceed Number of Service."); PrintAndLogEx(NORMAL, " - Access Mode shall be 000b."); @@ -177,22 +177,22 @@ static void print_block_list_element_constraints() { PrintAndLogEx(NORMAL, " - Block Number shall be in the range of the number of Blocks assigned to the specified Service."); } -static void print_number_of_service_constraints() { +static void print_number_of_service_constraints(void) { PrintAndLogEx(NORMAL, " - Number of Service: shall be a positive integer in the range of 1 to 16, inclusive."); } -static void print_number_of_block_constraints() { +static void print_number_of_block_constraints(void) { PrintAndLogEx(NORMAL, " - Number of Block: shall be less than or equal to the maximum number of Blocks that can be read simultaneously. " "The maximum number of Blocks that can be read simultaneously can differ, depending on the product being used. Use as default 01"); } -static void print_service_code_list_constraints() { +static void print_service_code_list_constraints(void) { PrintAndLogEx(NORMAL, " - Service Code List: For Service Code List, only Service Code existing in the product shall be specified:"); PrintAndLogEx(NORMAL, " - Even when Service Code exists in the product, Service Code not referenced from Block List shall not be specified to Service Code List."); PrintAndLogEx(NORMAL, " - For existence or nonexistence of Service in a product, please check using the Request Service (or Request Service v2) command."); } -static int usage_hf_felica_read_without_encryption() { +static int usage_hf_felica_read_without_encryption(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to read Block Data from authentication-not-required Service."); PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); print_number_of_service_constraints(); @@ -215,7 +215,7 @@ static int usage_hf_felica_read_without_encryption() { return PM3_SUCCESS; } -static int usage_hf_felica_write_without_encryption() { +static int usage_hf_felica_write_without_encryption(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to write Block Data to authentication-not-required Service."); PrintAndLogEx(NORMAL, " - Mode shall be Mode0."); print_number_of_service_constraints(); @@ -234,7 +234,7 @@ static int usage_hf_felica_write_without_encryption() { return PM3_SUCCESS; } -static int usage_hf_felica_request_system_code() { +static int usage_hf_felica_request_system_code(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to acquire System Code registered to the card."); PrintAndLogEx(NORMAL, " - If a card is divided into more than one System, this command acquires System Code of each System existing in the card."); PrintAndLogEx(NORMAL, "\nUsage: hf felica rqsyscode [-h] [-i]"); @@ -246,7 +246,7 @@ static int usage_hf_felica_request_system_code() { return PM3_SUCCESS; } -static int usage_hf_felica_reset_mode() { +static int usage_hf_felica_reset_mode(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to reset Mode to Mode 0."); print_status_flag1_interpretation(); print_status_flag2_interpration(); @@ -261,7 +261,7 @@ static int usage_hf_felica_reset_mode() { return PM3_SUCCESS; } -static int usage_hf_felica_request_specification_version() { +static int usage_hf_felica_request_specification_version(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to acquire the version of card OS."); PrintAndLogEx(NORMAL, " - Response:"); PrintAndLogEx(NORMAL, " - Format Version: Fixed value 00h. Provided only if Status Flag1 = 00h."); @@ -283,7 +283,7 @@ static int usage_hf_felica_request_specification_version() { return PM3_SUCCESS; } -static int usage_hf_felica_authentication1() { +static int usage_hf_felica_authentication1(void) { PrintAndLogEx(NORMAL, "\nInfo: Initiate mutual authentication. This command must always be executed before Authentication2 command" ", and mutual authentication is achieve only after Authentication2 command has succeeded."); PrintAndLogEx(NORMAL, " - Auth1 Parameters:"); @@ -311,7 +311,7 @@ static int usage_hf_felica_authentication1() { return PM3_SUCCESS; } -static int usage_hf_felica_authentication2() { +static int usage_hf_felica_authentication2(void) { PrintAndLogEx(NORMAL, "\nInfo: Complete mutual authentication. This command can only be executed subsquent to Authentication1" " command."); PrintAndLogEx(NORMAL, " - Auth2 Parameters:"); @@ -551,7 +551,7 @@ static bool check_last_idm(uint8_t *data, uint16_t datalen) { * @param wr_noCry_resp frame in which the response will be saved. * @return success if response was received. */ -int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_status_response_t *wr_noCry_resp) { +static int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_status_response_t *wr_noCry_resp) { clear_and_send_command(flags, datalen, data, verbose); PacketResponseNG resp; if (!waitCmdFelica(0, &resp, verbose)) { @@ -1367,7 +1367,8 @@ static int CmdHFFelicaRequestService(const char *Cmd) { flags |= FELICA_RAW; } - datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; +// Todo activate once datalen isn't hardcoded anymore... +// datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen; if (!custom_IDm && !check_last_idm(data, datalen)) { return PM3_EINVARG; } @@ -1464,7 +1465,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) { return PM3_SUCCESS; } -static void printSep() { +static void printSep(void) { PrintAndLogEx(INFO, "------------------------------------------------------------------------------------"); } @@ -1632,7 +1633,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) { printf("."); fflush(stdout); if (kbd_enter_pressed()) { - PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); + PrintAndLogEx(WARNING, "aborted via keyboard!\n"); DropField(); return PM3_EOPABORTED; } diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index e35479db9..50c1495c8 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -18,14 +18,12 @@ // https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.html //----------------------------------------------------------------------------- - #include "cmdhffido.h" #include #include "cmdparser.h" // command_t #include "commonutil.h" - #include "comms.h" #include "proxmark3.h" #include "emv/emvcore.h" @@ -50,7 +48,7 @@ static int CmdHFFidoInfo(const char *cmd) { infoHF14A(false, false, false); // FIDO info - PrintAndLogEx(NORMAL, "--------------------------------------------"); + PrintAndLogEx(INFO, "-----------" _CYAN_("FIDO Info") "---------------------------------"); SetAPDULogging(false); uint8_t buf[APDU_RES_LEN] = {0}; @@ -70,7 +68,7 @@ static int CmdHFFidoInfo(const char *cmd) { PrintAndLogEx(ERR, "APDU exchange error. Card returns 0x0000."); DropField(); - return 0; + return PM3_SUCCESS; } if (!strncmp((char *)buf, "U2F_V2", 7)) { @@ -92,13 +90,12 @@ static int CmdHFFidoInfo(const char *cmd) { } if (sw != 0x9000) { PrintAndLogEx(ERR, "FIDO2 version doesn't exist (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); - - return 0; + return PM3_SUCCESS; } if (buf[0]) { PrintAndLogEx(ERR, "FIDO2 get version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0])); - return 0; + return PM3_SUCCESS; } if (len > 1) { @@ -107,21 +104,20 @@ static int CmdHFFidoInfo(const char *cmd) { } else { PrintAndLogEx(ERR, "FIDO2 version length error"); } - return 0; + return PM3_SUCCESS; } -static json_t *OpenJson(int paramnum, char *fname, void *argtable[], bool *err) { +static json_t *OpenJson(CLIParserContext *ctx, int paramnum, char *fname, void *argtable[], bool *err) { json_t *root = NULL; json_error_t error; *err = false; - uint8_t jsonname[250] = {0}; + uint8_t jsonname[FILE_PATH_SIZE] = {0}; char *cjsonname = (char *)jsonname; int jsonnamelen = 0; - // CLIGetStrWithReturn(paramnum, jsonname, &jsonnamelen); - if (CLIParamStrToBuf(arg_get_str(paramnum), jsonname, sizeof(jsonname), &jsonnamelen)) { - CLIParserFree(); + // CLIGetStrWithReturn(ctx, paramnum, jsonname, &jsonnamelen); + if (CLIParamStrToBuf(arg_get_str(ctx, paramnum), jsonname, sizeof(jsonname), &jsonnamelen)) { return NULL; } @@ -160,9 +156,9 @@ static int CmdHFFidoRegister(const char *cmd) { uint8_t cdata[250] = {0}; int applen = 0; uint8_t adata[250] = {0}; - json_t *root = NULL; - CLIParserInit("hf fido reg", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido reg", "Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n" "\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters" @@ -179,19 +175,21 @@ static int CmdHFFidoRegister(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); - bool APDULogging = arg_get_lit(1); - bool verbose = arg_get_lit(2); - bool verbose2 = arg_get_lit(2) > 1; - bool paramsPlain = arg_get_lit(3); - bool showDERTLV = arg_get_lit(4); + bool APDULogging = arg_get_lit(ctx, 1); + bool verbose = arg_get_lit(ctx, 2); + bool verbose2 = arg_get_lit(ctx, 2) > 1; + bool paramsPlain = arg_get_lit(ctx, 3); + bool showDERTLV = arg_get_lit(ctx, 4); - char fname[250] = {0}; + char fname[FILE_PATH_SIZE] = {0}; bool err; - root = OpenJson(5, fname, argtable, &err); - if (err) - return 1; + json_t *root = OpenJson(ctx, 5, fname, argtable, &err); + if (err) { + CLIParserFree(ctx); + return PM3_EINVARG; + } if (root) { size_t jlen; JsonLoadBufAsHex(root, "$.ChallengeParam", data, 32, &jlen); @@ -200,16 +198,18 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(cdata, 0x00, 32); - CLIGetStrWithReturn(6, cdata, &chlen); + CLIGetStrWithReturn(ctx, 6, cdata, &chlen); if (chlen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } else { - CLIGetHexWithReturn(6, cdata, &chlen); + CLIGetHexWithReturn(ctx, 6, cdata, &chlen); if (chlen && chlen != 32) { PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only."); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } if (chlen) @@ -218,22 +218,24 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(adata, 0x00, 32); - CLIGetStrWithReturn(7, adata, &applen); + CLIGetStrWithReturn(ctx, 7, adata, &applen); if (applen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } else { - CLIGetHexWithReturn(7, adata, &applen); + CLIGetHexWithReturn(ctx, 7, adata, &applen); if (applen && applen != 32) { PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only."); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } if (applen) memmove(&data[32], adata, 32); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -256,7 +258,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); - return 2; + return PM3_ESOFT; } res = FIDORegister(data, buf, sizeof(buf), &len, &sw); @@ -268,22 +270,24 @@ static int CmdHFFidoRegister(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "ERROR execute register command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); - return 3; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); if (APDULogging) - PrintAndLogEx(NORMAL, "---------------------------------------------------------------"); + PrintAndLogEx(INFO, "---------------------------------------------------------------"); + PrintAndLogEx(NORMAL, "data len: %zu", len); + if (verbose2) { - PrintAndLogEx(NORMAL, "--------------data----------------------"); + PrintAndLogEx(INFO, "------------ " _CYAN_("data") " ----------------------"); dump_buffer((const unsigned char *)buf, len, NULL, 0); - PrintAndLogEx(NORMAL, "--------------data----------------------"); + PrintAndLogEx(INFO, "-------------" _CYAN_("data") " ----------------------"); } if (buf[0] != 0x05) { PrintAndLogEx(ERR, "ERROR: First byte must be 0x05, but it %2x", buf[0]); - return 5; + return PM3_ESOFT; } PrintAndLogEx(SUCCESS, "User public key: %s", sprint_hex(&buf[1], 65)); @@ -337,6 +341,7 @@ static int CmdHFFidoRegister(const char *cmd) { &buf[67], keyHandleLen, // keyHandle &buf[1], 65, // user public key NULL, 0); + (void)res; //PrintAndLogEx(NORMAL, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[hashp], len - hashp, true); if (res) { @@ -354,12 +359,11 @@ static int CmdHFFidoRegister(const char *cmd) { } PrintAndLogEx(INFO, "\nauth command: "); - printf("hf fido auth %s%s", paramsPlain ? "-p " : "", sprint_hex_inrow(&buf[67], keyHandleLen)); + PrintAndLogEx(INFO, "hf fido auth %s%s", paramsPlain ? "-p " : "", sprint_hex_inrow(&buf[67], keyHandleLen)); if (chlen || applen) - printf(" %s", paramsPlain ? (char *)cdata : sprint_hex_inrow(cdata, 32)); + PrintAndLogEx(INFO, " %s", paramsPlain ? (char *)cdata : sprint_hex_inrow(cdata, 32)); if (applen) - printf(" %s", paramsPlain ? (char *)adata : sprint_hex_inrow(adata, 32)); - printf("\n"); + PrintAndLogEx(INFO, " %s", paramsPlain ? (char *)adata : sprint_hex_inrow(adata, 32)); if (root) { JsonSaveBufAsHex(root, "ChallengeParam", data, 32); @@ -372,16 +376,15 @@ static int CmdHFFidoRegister(const char *cmd) { res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { PrintAndLogEx(ERR, "ERROR: can't save the file: %s", fname); - return 200; + return PM3_EFILE; } PrintAndLogEx(SUCCESS, "File " _YELLOW_("`%s`") " saved.", fname); // free json object json_decref(root); } - - return 0; -}; + return PM3_SUCCESS; +} static int CmdHFFidoAuthenticate(const char *cmd) { uint8_t data[512] = {0}; @@ -390,9 +393,9 @@ static int CmdHFFidoAuthenticate(const char *cmd) { uint8_t public_key[65] = {0}; int hdatalen = 0; uint8_t keyHandleLen = 0; - json_t *root = NULL; - CLIParserInit("hf fido auth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido auth", "Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n" "\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f " @@ -413,22 +416,25 @@ static int CmdHFFidoAuthenticate(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); - bool APDULogging = arg_get_lit(1); - bool verbose = arg_get_lit(2); - bool paramsPlain = arg_get_lit(3); + bool APDULogging = arg_get_lit(ctx, 1); + bool verbose = arg_get_lit(ctx, 2); + bool paramsPlain = arg_get_lit(ctx, 3); uint8_t controlByte = 0x08; - if (arg_get_lit(5)) + if (arg_get_lit(ctx, 5)) controlByte = 0x03; - if (arg_get_lit(6)) + if (arg_get_lit(ctx, 6)) controlByte = 0x07; char fname[250] = {0}; bool err; - root = OpenJson(7, fname, argtable, &err); - if (err) - return 1; + json_t *root = OpenJson(ctx, 7, fname, argtable, &err); + if (err) { + CLIParserFree(ctx); + return PM3_EINVARG; + } + if (root) { size_t jlen; JsonLoadBufAsHex(root, "$.ChallengeParam", data, 32, &jlen); @@ -441,21 +447,25 @@ static int CmdHFFidoAuthenticate(const char *cmd) { } // public key - CLIGetHexWithReturn(8, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 8, hdata, &hdatalen); if (hdatalen && hdatalen != 65) { PrintAndLogEx(ERR, "ERROR: public key length must be 65 bytes only."); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } + if (hdatalen) { memmove(public_key, hdata, hdatalen); public_key_loaded = true; } - CLIGetHexWithReturn(9, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 9, hdata, &hdatalen); if (hdatalen > 255) { PrintAndLogEx(ERR, "ERROR: application parameter length must be less than 255."); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } + if (hdatalen) { keyHandleLen = hdatalen; data[64] = keyHandleLen; @@ -464,39 +474,45 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (paramsPlain) { memset(hdata, 0x00, 32); - CLIGetStrWithReturn(9, hdata, &hdatalen); + CLIGetStrWithReturn(ctx, 9, hdata, &hdatalen); if (hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } else { - CLIGetHexWithReturn(10, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen); if (hdatalen && hdatalen != 32) { PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only."); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } + if (hdatalen) memmove(data, hdata, 32); if (paramsPlain) { memset(hdata, 0x00, 32); - CLIGetStrWithReturn(11, hdata, &hdatalen); + CLIGetStrWithReturn(ctx, 11, hdata, &hdatalen); if (hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } else { - CLIGetHexWithReturn(10, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen); if (hdatalen && hdatalen != 32) { PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only."); - return 1; + CLIParserFree(ctx); + return PM3_EINVARG; } } + if (hdatalen) memmove(&data[32], hdata, 32); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -524,7 +540,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); - return 2; + return PM3_ESOFT; } res = FIDOAuthentication(data, datalen, controlByte, buf, sizeof(buf), &len, &sw); @@ -536,7 +552,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "ERROR execute authentication command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); - return 3; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, "---------------------------------------------------------------"); @@ -563,6 +579,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { &buf[1], 4, // counter data, 32, // challenge parameter NULL, 0); + (void)res; //PrintAndLogEx(NORMAL, "--xbuf(%d)[%d]: %s", res, xbuflen, sprint_hex(xbuf, xbuflen)); res = ecdsa_signature_verify(MBEDTLS_ECP_DP_SECP256R1, public_key, xbuf, xbuflen, &buf[5], len - 5, true); if (res) { @@ -591,15 +608,15 @@ static int CmdHFFidoAuthenticate(const char *cmd) { res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { PrintAndLogEx(ERR, "ERROR: can't save the file: %s", fname); - return 200; + return PM3_EFILE; } PrintAndLogEx(SUCCESS, "File " _YELLOW_("`%s`") " saved.", fname); // free json object json_decref(root); } - return 0; -}; + return PM3_ESOFT; +} static void CheckSlash(char *fileName) { if ((fileName[strlen(fileName) - 1] != '/') && @@ -607,6 +624,7 @@ static void CheckSlash(char *fileName) { strcat(fileName, "/"); } +//iceman, todo: use searchfile.. static int GetExistsFileNameJson(const char *prefixDir, const char *reqestedFileName, char *fileName) { fileName[0] = 0x00; strcpy(fileName, get_my_executable_directory()); @@ -628,18 +646,18 @@ static int GetExistsFileNameJson(const char *prefixDir, const char *reqestedFile strcat(fileName, ".json"); if (access(fileName, F_OK) < 0) { - return 1; // file not found + return PM3_EFILE; // file not found } } - return 0; + return PM3_SUCCESS; } static int CmdHFFido2MakeCredential(const char *cmd) { json_error_t error; - json_t *root = NULL; - char fname[300] = {0}; + char fname[FILE_PATH_SIZE] = {0}; - CLIParserInit("hf fido make", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido make", "Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", "Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n" "\thf fido make test.json -> execute command with parameters file `text.json`"); @@ -653,38 +671,38 @@ static int CmdHFFido2MakeCredential(const char *cmd) { arg_str0(NULL, NULL, "", "JSON input / output file name for parameters. Default `fido2.json`"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); - bool APDULogging = arg_get_lit(1); - bool verbose = arg_get_lit(2); - bool verbose2 = arg_get_lit(2) > 1; - bool showDERTLV = arg_get_lit(3); - bool showCBOR = arg_get_lit(4); + bool APDULogging = arg_get_lit(ctx, 1); + bool verbose = arg_get_lit(ctx, 2); + bool verbose2 = arg_get_lit(ctx, 2) > 1; + bool showDERTLV = arg_get_lit(ctx, 3); + bool showCBOR = arg_get_lit(ctx, 4); - uint8_t jsonname[250] = {0}; + uint8_t jsonname[FILE_PATH_SIZE] = {0}; char *cjsonname = (char *)jsonname; int jsonnamelen = 0; - CLIGetStrWithReturn(5, jsonname, &jsonnamelen); + CLIGetStrWithReturn(ctx, 5, jsonname, &jsonnamelen); if (!jsonnamelen) { strcat(cjsonname, "fido2"); jsonnamelen = strlen(cjsonname); } - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); int res = GetExistsFileNameJson("fido", cjsonname, fname); - if (res) { + if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "ERROR: Can't found the json file."); return res; } PrintAndLogEx(NORMAL, "fname: %s\n", fname); - root = json_load_file(fname, 0, &error); + json_t *root = json_load_file(fname, 0, &error); if (!root) { PrintAndLogEx(ERR, "ERROR: json error on line %d: %s", error.line, error.text); - return 1; + return PM3_EFILE; } uint8_t data[2048] = {0}; @@ -695,7 +713,6 @@ static int CmdHFFido2MakeCredential(const char *cmd) { DropField(); res = FIDOSelect(true, true, buf, sizeof(buf), &len, &sw); - if (res) { PrintAndLogEx(ERR, "Can't select authenticator. res=%x. Exit...", res); DropField(); @@ -705,7 +722,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); - return 2; + return PM3_ESOFT; } res = FIDO2CreateMakeCredentionalReq(root, data, sizeof(data), &datalen); @@ -714,9 +731,9 @@ static int CmdHFFido2MakeCredential(const char *cmd) { if (showCBOR) { PrintAndLogEx(INFO, "CBOR make credential request:"); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); TinyCborPrintFIDOPackage(fido2CmdMakeCredential, false, data, datalen); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); } res = FIDO2MakeCredential(data, datalen, buf, sizeof(buf), &len, &sw); @@ -728,20 +745,20 @@ static int CmdHFFido2MakeCredential(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "ERROR execute make credential command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); - return 3; + return PM3_EFILE; } if (buf[0]) { PrintAndLogEx(ERR, "FIDO2 make credential error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0])); - return 0; + return PM3_SUCCESS; } PrintAndLogEx(SUCCESS, "MakeCredential result (%zu b) OK.", len); if (showCBOR) { PrintAndLogEx(SUCCESS, "CBOR make credential response:"); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); TinyCborPrintFIDOPackage(fido2CmdMakeCredential, true, &buf[1], len - 1); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(INFO, "---------------- " _CYAN_("CBOR") " ------------------"); } // parse returned cbor @@ -751,21 +768,21 @@ static int CmdHFFido2MakeCredential(const char *cmd) { res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { PrintAndLogEx(ERR, "ERROR: can't save the file: %s", fname); - return 200; + return PM3_EFILE; } PrintAndLogEx(SUCCESS, "File " _YELLOW_("`%s`") " saved.", fname); } json_decref(root); - return 0; -}; + return PM3_SUCCESS; +} static int CmdHFFido2GetAssertion(const char *cmd) { json_error_t error; - json_t *root = NULL; - char fname[300] = {0}; + char fname[FILE_PATH_SIZE] = {0}; - CLIParserInit("hf fido assert", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido assert", "Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", "Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n" "\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId"); @@ -779,38 +796,38 @@ static int CmdHFFido2GetAssertion(const char *cmd) { arg_str0(NULL, NULL, "", "JSON input / output file name for parameters. Default `fido2.json`"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); - bool APDULogging = arg_get_lit(1); - bool verbose = arg_get_lit(2); - bool verbose2 = arg_get_lit(2) > 1; - bool showCBOR = arg_get_lit(3); - bool createAllowList = arg_get_lit(4); + bool APDULogging = arg_get_lit(ctx, 1); + bool verbose = arg_get_lit(ctx, 2); + bool verbose2 = arg_get_lit(ctx, 2) > 1; + bool showCBOR = arg_get_lit(ctx, 3); + bool createAllowList = arg_get_lit(ctx, 4); - uint8_t jsonname[250] = {0}; + uint8_t jsonname[FILE_PATH_SIZE] = {0}; char *cjsonname = (char *)jsonname; int jsonnamelen = 0; - CLIGetStrWithReturn(5, jsonname, &jsonnamelen); + CLIGetStrWithReturn(ctx, 5, jsonname, &jsonnamelen); if (!jsonnamelen) { strcat(cjsonname, "fido2"); jsonnamelen = strlen(cjsonname); } - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); int res = GetExistsFileNameJson("fido", cjsonname, fname); - if (res) { + if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "ERROR: Can't found the json file."); return res; } PrintAndLogEx(NORMAL, "fname: %s\n", fname); - root = json_load_file(fname, 0, &error); + json_t *root = json_load_file(fname, 0, &error); if (!root) { PrintAndLogEx(ERR, "ERROR: json error on line %d: %s", error.line, error.text); - return 1; + return PM3_EFILE; } uint8_t data[2048] = {0}; @@ -821,9 +838,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) { DropField(); res = FIDOSelect(true, true, buf, sizeof(buf), &len, &sw); - if (res) { - PrintAndLogEx(ERR, "Can't select authenticator. res=%x. Exit...", res); + PrintAndLogEx(ERR, "Can't select authenticator. res=%x. exiting...", res); DropField(); return res; } @@ -831,7 +847,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); - return 2; + return PM3_ESOFT; } res = FIDO2CreateGetAssertionReq(root, data, sizeof(data), &datalen, createAllowList); @@ -840,9 +856,9 @@ static int CmdHFFido2GetAssertion(const char *cmd) { if (showCBOR) { PrintAndLogEx(SUCCESS, "CBOR get assertion request:"); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); TinyCborPrintFIDOPackage(fido2CmdGetAssertion, false, data, datalen); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); } res = FIDO2GetAssertion(data, datalen, buf, sizeof(buf), &len, &sw); @@ -854,20 +870,20 @@ static int CmdHFFido2GetAssertion(const char *cmd) { if (sw != 0x9000) { PrintAndLogEx(ERR, "ERROR execute get assertion command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); - return 3; + return PM3_ESOFT; } if (buf[0]) { PrintAndLogEx(ERR, "FIDO2 get assertion error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0])); - return 0; + return PM3_ESOFT; } PrintAndLogEx(SUCCESS, "GetAssertion result (%zu b) OK.", len); if (showCBOR) { PrintAndLogEx(SUCCESS, "CBOR get assertion response:"); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); TinyCborPrintFIDOPackage(fido2CmdGetAssertion, true, &buf[1], len - 1); - PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); + PrintAndLogEx(NORMAL, "---------------- " _CYAN_("CBOR") " ------------------"); } // parse returned cbor @@ -877,32 +893,32 @@ static int CmdHFFido2GetAssertion(const char *cmd) { res = json_dump_file(root, fname, JSON_INDENT(2)); if (res) { PrintAndLogEx(ERR, "ERROR: can't save the file: %s", fname); - return 200; + return PM3_EFILE; } PrintAndLogEx(SUCCESS, "File " _YELLOW_("`%s`") " saved.", fname); } json_decref(root); - return 0; -}; + return PM3_SUCCESS; +} static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help."}, - {"info", CmdHFFidoInfo, IfPm3Iso14443a, "Info about FIDO tag."}, - {"reg", CmdHFFidoRegister, IfPm3Iso14443a, "FIDO U2F Registration Message."}, - {"auth", CmdHFFidoAuthenticate, IfPm3Iso14443a, "FIDO U2F Authentication Message."}, - {"make", CmdHFFido2MakeCredential, IfPm3Iso14443a, "FIDO2 MakeCredential command."}, - {"assert", CmdHFFido2GetAssertion, IfPm3Iso14443a, "FIDO2 GetAssertion command."}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, AlwaysAvailable, "This help."}, + {"info", CmdHFFidoInfo, IfPm3Iso14443a, "Info about FIDO tag."}, + {"reg", CmdHFFidoRegister, IfPm3Iso14443a, "FIDO U2F Registration Message."}, + {"auth", CmdHFFidoAuthenticate, IfPm3Iso14443a, "FIDO U2F Authentication Message."}, + {"make", CmdHFFido2MakeCredential, IfPm3Iso14443a, "FIDO2 MakeCredential command."}, + {"assert", CmdHFFido2GetAssertion, IfPm3Iso14443a, "FIDO2 GetAssertion command."}, + {NULL, NULL, 0, NULL} }; int CmdHFFido(const char *Cmd) { - (void)WaitForResponseTimeout(CMD_ACK, NULL, 100); + clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index c687e316d..98fd29562 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -18,7 +18,7 @@ #include "cmdtrace.h" #include "util_posix.h" #include "comms.h" -#include "mbedtls/des.h" +#include "des.h" #include "loclass/cipherutils.h" #include "loclass/cipher.h" #include "loclass/ikeys.h" @@ -191,7 +191,7 @@ static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_readtagfile() { +static int usage_hf_iclass_readtagfile(void) { PrintAndLogEx(NORMAL, "Print a iClass tag-dump file\n"); PrintAndLogEx(NORMAL, "Usage: hf iClass readtagfile [f ] [s ] [e ] [v]\n"); PrintAndLogEx(NORMAL, "Options:"); @@ -225,7 +225,7 @@ static int usage_hf_iclass_calc_newkey(void) { PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass calcnewkey o 1122334455667788 n 2233445566778899")); PrintAndLogEx(NORMAL, "\nNOTE: * = required"); PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS;; + return PM3_SUCCESS; } static int usage_hf_iclass_managekeys(void) { PrintAndLogEx(NORMAL, "Manage iClass Keys in client memory:\n"); @@ -315,7 +315,7 @@ static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass chk f dictionaries/iclass_default_keys.dic")); PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass chk f dictionaries/iclass_default_keys.dic e")); PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS;; + return PM3_SUCCESS; } static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, "Lookup keys takes some sniffed trace data and tries to verify what key was used against a dictionary file\n"); @@ -358,11 +358,11 @@ typedef struct { uint8_t mem_config; //[13] uint8_t eas; //[14] uint8_t fuses; //[15] -} picopass_conf_block; +} picopass_conf_block_t; typedef struct { uint8_t csn[8]; - picopass_conf_block conf; + picopass_conf_block_t conf; uint8_t epurse[8]; uint8_t key_d[8]; uint8_t key_c[8]; @@ -388,31 +388,35 @@ static void fuse_config(const picopass_hdr *hdr) { uint8_t fuses = hdr->conf.fuses; if (isset(fuses, FUSE_FPERS)) - PrintAndLogEx(SUCCESS, " Mode: Personalization [Programmable]"); + PrintAndLogEx(SUCCESS, " Mode: " _GREEN_("Personalization [programmable]")); else - PrintAndLogEx(SUCCESS, " Mode: Application [Locked]"); + PrintAndLogEx(SUCCESS, " Mode: " _YELLOW_("Application [locked]")); if (isset(fuses, FUSE_CODING1)) { - PrintAndLogEx(SUCCESS, " Coding: RFU"); + PrintAndLogEx(SUCCESS, "Coding: RFU"); } else { if (isset(fuses, FUSE_CODING0)) - PrintAndLogEx(SUCCESS, " Coding: ISO 14443-2 B/ISO 15693"); + PrintAndLogEx(SUCCESS, "Coding: " _YELLOW_("ISO 14443-2 B / 15693")); else - PrintAndLogEx(SUCCESS, " Coding: ISO 14443B only"); + PrintAndLogEx(SUCCESS, "Coding: " _YELLOW_("ISO 14443-B only")); } // 1 1 - if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Secured page, keys not locked"); + if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Secured page, " _GREEN_("keys not locked")); // 1 0 - if (isset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, " Crypt: Secured page, keys locked"); + if (isset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(INFO, " Crypt: Secured page, keys locked"); // 0 1 - if (notset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Non secured page"); + if (notset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Non secured page"); // 0 0 - if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, " Crypt: No auth possible. Read only if RA is enabled"); + if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(INFO, " Crypt: No auth possible. Read only if RA is enabled"); if (isset(fuses, FUSE_RA)) PrintAndLogEx(SUCCESS, " RA: Read access enabled"); else - PrintAndLogEx(WARNING, " RA: Read access not enabled"); + PrintAndLogEx(INFO, " RA: Read access not enabled"); + + PrintAndLogEx(INFO, " Block write lock 0x%02X", hdr->conf.block_writelock); + PrintAndLogEx(INFO, " EAS 0x%02X", hdr->conf.eas); + } static void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb) { @@ -461,27 +465,28 @@ static void mem_app_config(const picopass_hdr *hdr) { if (applimit < 6) applimit = 26; if (kb == 2 && (applimit > 0x1f)) applimit = 26; - PrintAndLogEx(NORMAL, " Mem: %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem); - PrintAndLogEx(NORMAL, " AA1: blocks 06-%02X", applimit); - PrintAndLogEx(NORMAL, " AA2: blocks %02X-%02X", applimit + 1, max_blk); - PrintAndLogEx(NORMAL, " OTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]); - PrintAndLogEx(NORMAL, " KeyAccess:"); + PrintAndLogEx(INFO, "------ " _CYAN_("Memory") "------"); + PrintAndLogEx(INFO, " %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem); + PrintAndLogEx(INFO, " AA1 blocks 06-%02X", applimit); + PrintAndLogEx(INFO, " AA2 blocks %02X-%02X", applimit + 1, max_blk); + PrintAndLogEx(INFO, " OTP 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]); + PrintAndLogEx(INFO, "------ " _CYAN_("KeyAccess") "------"); uint8_t book = isset(mem, 0x20); if (book) { - PrintAndLogEx(NORMAL, " Read A - Kd"); - PrintAndLogEx(NORMAL, " Read B - Kc"); - PrintAndLogEx(NORMAL, " Write A - Kd"); - PrintAndLogEx(NORMAL, " Write B - Kc"); - PrintAndLogEx(NORMAL, " Debit - Kd or Kc"); - PrintAndLogEx(NORMAL, " Credit - Kc"); + PrintAndLogEx(INFO, " Read A - Kd"); + PrintAndLogEx(INFO, " Read B - Kc"); + PrintAndLogEx(INFO, " Write A - Kd"); + PrintAndLogEx(INFO, " Write B - Kc"); + PrintAndLogEx(INFO, " Debit - Kd or Kc"); + PrintAndLogEx(INFO, " Credit - Kc"); } else { - PrintAndLogEx(NORMAL, " Read A - Kd or Kc"); - PrintAndLogEx(NORMAL, " Read B - Kd or Kc"); - PrintAndLogEx(NORMAL, " Write A - Kc"); - PrintAndLogEx(NORMAL, " Write B - Kc"); - PrintAndLogEx(NORMAL, " Debit - Kd or Kc"); - PrintAndLogEx(NORMAL, " Credit - Kc"); + PrintAndLogEx(INFO, " Read A - Kd or Kc"); + PrintAndLogEx(INFO, " Read B - Kd or Kc"); + PrintAndLogEx(INFO, " Write A - Kc"); + PrintAndLogEx(INFO, " Write B - Kc"); + PrintAndLogEx(INFO, " Debit - Kd or Kc"); + PrintAndLogEx(INFO, " Credit - Kc"); } } @@ -677,7 +682,7 @@ static int CmdHFiClassSim(const char *Cmd) { default: { uint8_t numberOfCSNs = 0; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_SIMULATE, simType, numberOfCSNs, 0, CSN, 8); + SendCommandMIX(CMD_HF_ICLASS_SIMULATE, simType, numberOfCSNs, 0, CSN, 8); break; } } @@ -685,14 +690,14 @@ static int CmdHFiClassSim(const char *Cmd) { } static int CmdHFiClassInfo(const char *Cmd) { - return PM3_SUCCESS; + return readIclass(false, true); } static int CmdHFiClassReader(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_hf_iclass_reader(); - bool findone = (cmdp == '1') ? false : true; - return readIclass(findone, true); + bool loop_read = (cmdp == '1') ? false : true; + return readIclass(loop_read, true); } static int CmdHFiClassReader_Replay(const char *Cmd) { @@ -748,11 +753,9 @@ static int CmdHFiClassELoad(const char *Cmd) { //Validations if (errors || cmdp == 0) { - usage_hf_iclass_eload(); - return PM3_EINVARG; + return usage_hf_iclass_eload(); } - uint8_t *dump = calloc(2048, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(ERR, "error, cannot allocate memory "); @@ -768,14 +771,14 @@ static int CmdHFiClassELoad(const char *Cmd) { break; } case EML: { - res = loadFileEML(filename, dump, &bytes_read); + res = loadFileEML_safe(filename, (void **)&dump, &bytes_read); break; } case JSON: { - res = loadFileJSON(filename, dump, 2048, &bytes_read); + res = loadFileJSON(filename, dump, 2048, &bytes_read, NULL); break; } - default: + case DICTIONARY: PrintAndLogEx(ERR, "No dictionary loaded"); free(dump); return PM3_ESOFT; @@ -962,7 +965,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { saveFile(fptr, ".bin", decrypted, decryptedlen); saveFileEML(fptr, decrypted, decryptedlen, 8); - saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); + saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen, NULL); PrintAndLogEx(INFO, "Following output skips CSN / block0"); printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); @@ -1074,7 +1077,7 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { } else { iClassEncryptBlkData(blk_data, key); } - printvar("encrypted block", blk_data, 8); + PrintAndLogEx(SUCCESS, "encrypted block %s", sprint_hex(blk_data, 8)); return PM3_SUCCESS; } @@ -1320,7 +1323,8 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { printf("."); fflush(stdout); if (kbd_enter_pressed()) { - PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(WARNING, "aborted via keyboard!\n"); DropField(); return PM3_EOPABORTED; } @@ -1428,7 +1432,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { PrintAndLogEx(SUCCESS, "saving dump file - %zu blocks read", gotBytes / 8); saveFile(filename, ".bin", tag_data, gotBytes); saveFileEML(filename, tag_data, gotBytes, 8); - saveFileJSON(filename, jsfIclass, tag_data, gotBytes); + saveFileJSON(filename, jsfIclass, tag_data, gotBytes, NULL); return PM3_SUCCESS; } @@ -1469,7 +1473,7 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c if (resp.status != PM3_SUCCESS) { if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); DropField(); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } if (resp.data.asBytes[0] == 1) @@ -1587,6 +1591,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { bool errors = false; bool verbose = false; uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': @@ -1670,32 +1675,39 @@ static int CmdHFiClassCloneTag(const char *Cmd) { return PM3_EINVARG; } - // file handling and reading - FILE *f = fopen(filename, "rb"); - if (!f) { + uint8_t *dump = NULL; + size_t bytes_read = 0; + if (loadFile_safe(filename, "", (void **)&dump, &bytes_read) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); return PM3_EFILE; } - iclass_block_t tag_data[PM3_CMD_DATA_SIZE / 12]; + if (bytes_read == 0) { + PrintAndLogEx(ERR, "file reading error"); + free(dump); + return PM3_EFILE; + } + + if (bytes_read < sizeof(iclass_block_t) * (endblock - startblock + 1)) { + PrintAndLogEx(ERR, "file wrong size"); + free(dump); + return PM3_EFILE; + } // read data from file from block 6 --- 19 // we will use this struct [data 8 bytes][MAC 4 bytes] for each block calculate all mac number for each data // then copy to usbcommand->asbytes; // max is 32 - 6 = 28 block. 28 x 12 bytes gives 336 bytes - int i; - fseek(f, startblock * 8, SEEK_SET); - size_t bytes_read = fread(tag_data, sizeof(iclass_block_t), endblock - startblock + 1, f); - fclose(f); + iclass_block_t tag_data[PM3_CMD_DATA_SIZE / 12]; - if (bytes_read == 0) { - PrintAndLogEx(ERR, "file reading error."); - return PM3_EFILE; - } + memcpy(tag_data, dump + startblock * 8, sizeof(iclass_block_t) * (endblock - startblock + 1)); + + free(dump); uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + int i; int numberAuthRetries = ICLASS_AUTH_RETRY; do { if (select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) @@ -1724,9 +1736,9 @@ static int CmdHFiClassCloneTag(const char *Cmd) { } if (verbose) { - PrintAndLogEx(NORMAL, "------+--------------------------+-------------"); - PrintAndLogEx(NORMAL, "block | data | mac"); - PrintAndLogEx(NORMAL, "------+--------------------------+-------------"); + PrintAndLogEx(INFO, "------+--------------------------+-------------"); + PrintAndLogEx(INFO, "block | data | mac"); + PrintAndLogEx(INFO, "------+--------------------------+-------------"); uint8_t p[12]; for (i = 0; i <= endblock - startblock; i++) { memcpy(p, data + (i * 12), 12); @@ -1811,7 +1823,7 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, if (resp.status != PM3_SUCCESS) { if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); DropField(); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } result = (struct p *)resp.data.asBytes; @@ -1933,11 +1945,15 @@ static int CmdHFiClass_loclass(const char *Cmd) { } } else if (opt == 't') { char opt2 = tolower(param_getchar(Cmd, 1)); + int errors = testCipherUtils(); errors += testMAC(); - errors += doKeyTests(0); + errors += doKeyTests(); errors += testElite(opt2 == 'l'); - if (errors) PrintAndLogEx(ERR, "There were errors!!!"); + + if (errors != PM3_SUCCESS) + PrintAndLogEx(ERR, "There were errors!!!"); + return PM3_ESOFT; } return PM3_SUCCESS; @@ -2023,30 +2039,12 @@ static int CmdHFiClassReadTagFile(const char *Cmd) { if (errors || (strlen(Cmd) == 0)) return usage_hf_iclass_readtagfile(); - // file handling and reading - FILE *f = fopen(filename, "rb"); - if (!f) { + uint8_t *dump = NULL; + size_t bytes_read = 0; + if (loadFile_safe(filename, "", (void **)&dump, &bytes_read) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); return PM3_EFILE; } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(ERR, "Error, when getting filesize"); - fclose(f); - return PM3_EFILE; - } - - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - fclose(f); - return PM3_EMALLOC; - } - size_t bytes_read = fread(dump, 1, fsize, f); - fclose(f); if (verbose) { PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename); @@ -2054,6 +2052,7 @@ static int CmdHFiClassReadTagFile(const char *Cmd) { PrintAndLogEx(INFO, "Printing blocks from"); PrintAndLogEx(INFO, "start " _YELLOW_("0x%02x") " end " _YELLOW_("0x%02x"), (startblock == 0) ? 6 : startblock, endblock); } + uint8_t *csn = dump; PrintAndLogEx(INFO, "------+--+-------------------------+----------"); PrintAndLogEx(INFO, " CSN |00| " _GREEN_("%s") " |", sprint_hex(csn, 8)); @@ -2071,7 +2070,7 @@ void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite hash2(KEY, keytable); hash1(CSN, key_index); for (uint8_t i = 0; i < 8 ; i++) - key_sel[i] = keytable[key_index[i]] & 0xFF; + key_sel[i] = keytable[key_index[i]]; //Permute from iclass format to standard format permutekey_rev(key_sel, key_sel_p); @@ -2189,30 +2188,14 @@ static int CmdHFiClassCalcNewKey(const char *Cmd) { } static int loadKeys(char *filename) { - FILE *f; - f = fopen(filename, "rb"); - if (!f) { + + uint8_t *dump = NULL; + size_t bytes_read = 0; + if (loadFile_safe(filename, "", (void **)&dump, &bytes_read) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); return PM3_EFILE; } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - if (fsize <= 0) { - PrintAndLogEx(ERR, "Error, when getting filesize"); - fclose(f); - return PM3_EFILE; - } - - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - fclose(f); - return PM3_EMALLOC; - } - size_t bytes_read = fread(dump, 1, fsize, f); - fclose(f); if (bytes_read > ICLASS_KEYS_MAX * 8) { PrintAndLogEx(WARNING, "File is too long to load - bytes: %zu", bytes_read); free(dump); @@ -2402,17 +2385,6 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { } if (errors) return usage_hf_iclass_chk(); - - uint8_t *keyBlock = NULL; - uint16_t keycount = 0; - - // load keys - int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); - if (res != PM3_SUCCESS || keycount == 0) { - free(keyBlock); - return res; - } - // Get CSN / UID and CCNR PrintAndLogEx(SUCCESS, "Reading tag CSN"); for (uint8_t i = 0; i < ICLASS_AUTH_RETRY && !got_csn; i++) { @@ -2427,6 +2399,16 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { return PM3_ESOFT; } + uint8_t *keyBlock = NULL; + uint32_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { + free(keyBlock); + return res; + } + pre = calloc(keycount, sizeof(iclass_premac_t)); if (!pre) { DropField(); @@ -2466,7 +2448,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { uint8_t timeout = 0; if (kbd_enter_pressed()) { - PrintAndLogEx(WARNING, "\n[!] Aborted via keyboard!\n"); + PrintAndLogEx(WARNING, "Aborted via keyboard!\n"); goto out; } @@ -2493,10 +2475,12 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { printf("."); fflush(stdout); if (timeout > 120) { - PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(WARNING, "No response from Proxmark3. Aborting..."); goto out; } } + PrintAndLogEx(NORMAL, ""); found_offset = resp.oldarg[1] & 0xFF; uint8_t isOK = resp.oldarg[0] & 0xFF; @@ -2505,8 +2489,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { switch (isOK) { case 1: { found_debit = true; - - PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] idx [%u] - found key "_YELLOW_("%s") + PrintAndLogEx(INFO, "Chunk [%d/%d]: %.1fs [%s] idx [%u] - found key "_YELLOW_("%s") , key_offset , keycount , (float)(t2 / 1000.0) @@ -2517,7 +2500,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { break; } case 0: { - PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d] : %.1fs [%s]" + PrintAndLogEx(INFO, "Chunk [%d/%d] : %.1fs [%s]" , key_offset , keycount , (float)(t2 / 1000.0) @@ -2542,7 +2525,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { out: t1 = msclock() - t1; - PrintAndLogEx(SUCCESS, "\nTime in iclass checkkeys: %.0f seconds\n", (float)t1 / 1000.0); + PrintAndLogEx(SUCCESS, "Time in iclass checkkeys: %.0f seconds\n", (float)t1 / 1000.0); DropField(); // add to managekeys @@ -2668,7 +2651,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, "MAC_TAG | %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); uint8_t *keyBlock = NULL; - uint16_t keycount = 0; + uint32_t keycount = 0; // load keys int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); @@ -2727,11 +2710,12 @@ static int CmdHFiClassLookUp(const char *Cmd) { } // precalc diversified keys and their MAC -void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list) { +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_premac_t *list) { uint8_t key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - for (int i = 0; i < keycnt; i++) { +//iceman: threading + for (uint32_t i = 0; i < keycnt; i++) { memcpy(key, keys + 8 * i, 8); @@ -2744,11 +2728,12 @@ void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, } } -void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list) { +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_prekey_t *list) { uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - for (int i = 0; i < keycnt; i++) { +//iceman: threading + for (uint32_t i = 0; i < keycnt; i++) { memcpy(list[i].key, keys + 8 * i, 8); @@ -2764,13 +2749,13 @@ void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit } // print diversified keys -void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list) { +void PrintPreCalcMac(uint8_t *keys, uint32_t keycnt, iclass_premac_t *pre_list) { - iclass_prekey_t *b = calloc(keycnt, sizeof(iclass_prekey_t)); + iclass_prekey_t *b = calloc(keycnt, sizeof(iclass_prekey_t)); if (!b) return; - for (int i = 0; i < keycnt; i++) { + for (uint32_t i = 0; i < keycnt; i++) { memcpy(b[i].key, keys + 8 * i, 8); memcpy(b[i].mac, pre_list[i].mac, 4); } @@ -2778,7 +2763,7 @@ void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list) { free(b); } -void PrintPreCalc(iclass_prekey_t *list, int itemcnt) { +void PrintPreCalc(iclass_prekey_t *list, uint32_t itemcnt) { PrintAndLogEx(NORMAL, "-----+------------------+---------"); PrintAndLogEx(NORMAL, "#key | key | mac"); PrintAndLogEx(NORMAL, "-----+------------------+---------"); @@ -2802,7 +2787,7 @@ static void permute(uint8_t *data, uint8_t len, uint8_t *output) { return; } if (len != KEY_SIZE) { - PrintAndLogEx(NORMAL, "[!] wrong key size\n"); + PrintAndLogEx(WARNING, "wrong key size\n"); return; } for (uint8_t i = 0; i < KEY_SIZE; ++i) { @@ -2959,7 +2944,7 @@ int readIclass(bool loop, bool verbose) { if (readStatus & FLAG_ICLASS_READER_CSN) { PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(SUCCESS, " CSN: %s", sprint_hex(data, 8)); + PrintAndLogEx(SUCCESS, " CSN: " _YELLOW_("%s"), sprint_hex(data, 8)); tagFound = true; } @@ -2980,19 +2965,19 @@ int readIclass(bool loop, bool verbose) { bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0); PrintAndLogEx(SUCCESS, " App IA: %s", sprint_hex(data + 8 * 5, 8)); + PrintAndLogEx(INFO, "------ " _CYAN_("fingerprint") " ------"); if (isHidRange) { + PrintAndLogEx(SUCCESS, _YELLOW_("iClass")" (CSN is in HID range)"); + if (legacy) - PrintAndLogEx(SUCCESS, " : Possible iClass - legacy credential tag"); + PrintAndLogEx(SUCCESS, " possible "_YELLOW_("iClass legacy")" credential"); if (se_enabled) - PrintAndLogEx(SUCCESS, " : Possible iClass - SE credential tag"); - } + PrintAndLogEx(SUCCESS, " possible "_YELLOW_("iClass SE")" credential"); - if (isHidRange) { - PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("iClass")", CSN is in HID range"); } else { - PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("PicoPass")", CSN is not in HID range"); + PrintAndLogEx(SUCCESS, _YELLOW_("PicoPass")" (CSN is not in HID range)"); } } diff --git a/client/src/cmdhficlass.h b/client/src/cmdhficlass.h index 73304d4d0..53880d647 100644 --- a/client/src/cmdhficlass.h +++ b/client/src/cmdhficlass.h @@ -33,8 +33,8 @@ int readIclass(bool loop, bool verbose); void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize); void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite); -void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list); -void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list); -void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list); -void PrintPreCalc(iclass_prekey_t *list, int itemcnt); +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_premac_t *list); +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_prekey_t *list); +void PrintPreCalcMac(uint8_t *keys, uint32_t keycnt, iclass_premac_t *pre_list); +void PrintPreCalc(iclass_prekey_t *list, uint32_t itemcnt); #endif diff --git a/client/src/cmdhflegic.c b/client/src/cmdhflegic.c index 7507e326b..f5ba787ad 100644 --- a/client/src/cmdhflegic.c +++ b/client/src/cmdhflegic.c @@ -10,7 +10,11 @@ #include "cmdhflegic.h" #include // for Mingw readline +#include // tolower + +#ifndef ANDROID #include +#endif #include "cmdparser.h" // command_t #include "comms.h" // clearCommandBuffer @@ -69,12 +73,13 @@ static int usage_legic_sim(void) { } static int usage_legic_wrbl(void) { PrintAndLogEx(NORMAL, "Write data to a LEGIC Prime tag. It autodetects tagsize to make sure size\n"); - PrintAndLogEx(NORMAL, "Usage: hf legic wrbl [h] [o ] [d ]\n"); + PrintAndLogEx(NORMAL, "Usage: hf legic wrbl [h] [o ] [d ] [y]\n"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " o : (hex) offset in data array to start writing"); //PrintAndLogEx(NORMAL, " : (optional) Initialization vector to use (ODD and 7bits)"); PrintAndLogEx(NORMAL, " d : (hex symbols) bytes to write "); + PrintAndLogEx(NORMAL, " y : Auto-confirm dangerous operations "); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, _YELLOW_(" hf legic wrbl o 10 d 11223344 - Write 0x11223344 starting from offset 0x10")); @@ -592,6 +597,7 @@ static int CmdLegicWrbl(const char *Cmd) { uint8_t *data = NULL; uint8_t cmdp = 0; bool errors = false; + bool autoconfirm = false; int len = 0, bg, en; uint32_t offset = 0, IV = 0x55; @@ -651,6 +657,10 @@ static int CmdLegicWrbl(const char *Cmd) { errors = true; break; } + case 'y': { + autoconfirm = true; + break; + } default: { PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -689,12 +699,24 @@ static int CmdLegicWrbl(const char *Cmd) { return PM3_EOUTOFBOUND; } - if (offset == 5 || offset == 6) { + if ((offset == 5 || offset == 6) && (! autoconfirm)) { PrintAndLogEx(NORMAL, "############# DANGER ################"); PrintAndLogEx(NORMAL, "# changing the DCF is irreversible #"); PrintAndLogEx(NORMAL, "#####################################"); - char *answer = readline("do you really want to continue? y(es) n(o) : "); - bool overwrite = (answer[0] == 'y' || answer[0] == 'Y'); + const char *confirm = "Do you really want to continue? y(es)/n(o) : "; + bool overwrite = false; +#ifdef HAVE_READLINE + char *answer = readline(confirm); + overwrite = (answer[0] == 'y' || answer[0] == 'Y'); +#else + printf("%s", confirm); + char *answer = NULL; + size_t anslen = 0; + if (getline(&answer, &anslen, stdin) > 0) { + overwrite = (answer[0] == 'y' || answer[0] == 'Y'); + } +#endif + free(answer); if (!overwrite) { PrintAndLogEx(NORMAL, "command cancelled"); return PM3_EOPABORTED; @@ -880,7 +902,7 @@ int legic_get_type(legic_card_select_t *card) { if (!isOK) return PM3_ESOFT; - memcpy(card, (legic_card_select_t *)resp.data.asBytes, sizeof(legic_card_select_t)); + memcpy(card, resp.data.asBytes, sizeof(legic_card_select_t)); return PM3_SUCCESS; } void legic_chk_iv(uint32_t *iv) { @@ -1015,7 +1037,7 @@ static int CmdLegicDump(const char *Cmd) { saveFile(filename, ".bin", data, readlen); saveFileEML(filename, data, readlen, 8); - saveFileJSON(filename, jsfLegic, data, readlen); + saveFileJSON(filename, jsfLegic, data, readlen, NULL); free(data); return PM3_SUCCESS; } @@ -1288,7 +1310,7 @@ static int CmdLegicESave(const char *Cmd) { saveFile(filename, ".bin", data, numofbytes); saveFileEML(filename, data, numofbytes, 8); - saveFileJSON(filename, jsfLegic, data, numofbytes); + saveFileJSON(filename, jsfLegic, data, numofbytes, NULL); return PM3_SUCCESS; } diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 7aeac0bc7..8ade2f7dc 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -37,7 +37,7 @@ enum MifareAuthSeq { static enum MifareAuthSeq MifareAuthState; static TAuthData AuthData; -void ClearAuthData() { +void ClearAuthData(void) { AuthData.uid = 0; AuthData.nt = 0; AuthData.first_auth = true; @@ -509,7 +509,7 @@ void annotateIso15693(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { if (cmd[1] >= 0x2D && cmd[1] <= 0x9F) snprintf(exp, size, "Optional RFU"); else if (cmd[1] >= 0xA0 && cmd[1] <= 0xDF) snprintf(exp, size, "Cust IC MFG dependent"); - else if (cmd[1] >= 0xE0 && cmd[1] <= 0xFF) snprintf(exp, size, "Proprietary IC MFG dependent"); + else if (cmd[1] >= 0xE0) snprintf(exp, size, "Proprietary IC MFG dependent"); else snprintf(exp, size, "?"); } diff --git a/client/src/cmdhflto.c b/client/src/cmdhflto.c index 6434a9e88..c62289108 100644 --- a/client/src/cmdhflto.c +++ b/client/src/cmdhflto.c @@ -109,7 +109,7 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16 arg1 |= len; - SendCommandOLD(CMD_HF_ISO14443A_READER, arg0, arg1, 0, cmd, len); + SendCommandMIX(CMD_HF_ISO14443A_READER, arg0, arg1, 0, cmd, len); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -149,14 +149,14 @@ static int lto_select(uint8_t *id_response, uint8_t id_len, uint8_t *type_respon resp_len = id_len; status = lto_send_cmd_raw(select_sn_cmd, sizeof(select_sn_cmd), id_response, &resp_len, false, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { - return PM3_EWRONGANSVER; // REQUEST SERIAL NUMBER failed + return PM3_EWRONGANSWER; // REQUEST SERIAL NUMBER failed } memcpy(select_cmd + 2, id_response, sizeof(select_cmd) - 2); resp_len = 1; status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), resp, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { - return PM3_EWRONGANSVER; // SELECT failed + return PM3_EWRONGANSWER; // SELECT failed } // tag is now INIT and SELECTED. @@ -222,12 +222,12 @@ static int lto_rdbl(uint8_t blk, uint8_t *block_responce, uint8_t *block_cnt_res int status = lto_send_cmd_raw(rdbl_cmd, sizeof(rdbl_cmd), block_responce, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { - return PM3_EWRONGANSVER; // READ BLOCK failed + return PM3_EWRONGANSWER; // READ BLOCK failed } status = lto_send_cmd_raw(rdbl_cnt_cmd, sizeof(rdbl_cnt_cmd), block_cnt_responce, &resp_len, false, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { - return PM3_EWRONGANSVER; // READ BLOCK CONTINUE failed + return PM3_EWRONGANSWER; // READ BLOCK CONTINUE failed } return PM3_SUCCESS; @@ -334,17 +334,17 @@ static int lto_wrbl(uint8_t blk, uint8_t *data, bool verbose) { int status = lto_send_cmd_raw(wrbl_cmd, sizeof(wrbl_cmd), resp, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { - return PM3_EWRONGANSVER; // WRITE BLOCK failed + return PM3_EWRONGANSWER; // WRITE BLOCK failed } status = lto_send_cmd_raw(wrbl_d00_d15, sizeof(wrbl_d00_d15), resp, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { - return PM3_EWRONGANSVER; // WRITE BLOCK failed + return PM3_EWRONGANSWER; // WRITE BLOCK failed } status = lto_send_cmd_raw(wrbl_d16_d31, sizeof(wrbl_d16_d31), resp, &resp_len, true, false, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) { - return PM3_EWRONGANSVER; // WRITE BLOCK failed + return PM3_EWRONGANSWER; // WRITE BLOCK failed } return PM3_SUCCESS; @@ -566,13 +566,7 @@ static int CmdHfLTRestore(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; - int is_data_loaded = PM3_ESOFT; - char filename[FILE_PATH_SIZE] = {0}; - char extension[FILE_PATH_SIZE] = {0}; - - uint8_t dump_data[CM_MEM_MAX_SIZE] = {0}; - size_t dump_datalen = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -580,8 +574,9 @@ static int CmdHfLTRestore(const char *Cmd) { return usage_lto_restore(); case 'f': param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE); - if (strlen(filename) == 0) + if (strlen(filename) < 5) errors = true; + cmdp += 2; break; default: @@ -591,40 +586,35 @@ static int CmdHfLTRestore(const char *Cmd) { } } - if (errors || (strlen(filename)) == 0) { - usage_lto_restore(); - return PM3_EINVARG; + if (errors || strlen(Cmd) == 0) { + return usage_lto_restore(); } - // split file name into prefix and ext. - int fnLength; + size_t dump_len = 0; + char *lowstr = str_dup(filename); + str_lower(lowstr); - fnLength = strlen(filename); + if (str_endswith(lowstr, ".bin")) { - if (fnLength > 4) { - memcpy(extension, &filename[fnLength - 4], 4); - extension[5] = 0x00; + uint8_t *dump = NULL; + if (loadFile_safe(filename, "", (void **)&dump, &dump_len) == PM3_SUCCESS) { + restoreLTO(dump, true); + } + free(dump); - // check if valid file extension and attempt to load data - if (memcmp(extension, ".bin", 4) == 0) { - filename[fnLength - 4] = 0x00; - is_data_loaded = loadFile(filename, ".bin", dump_data, sizeof(dump_data), &dump_datalen); + } else if (str_endswith(lowstr, ".eml")) { - } else if (memcmp(extension, ".eml", 4) == 0) { - filename[fnLength - 4] = 0x00; - dump_datalen = 12; - is_data_loaded = loadFileEML(filename, (uint8_t *)dump_data, &dump_datalen); + uint8_t *dump = NULL; + if (loadFileEML_safe(filename, (void **)&dump, &dump_len) == PM3_SUCCESS) { + restoreLTO(dump, true); + } + free(dump); - } else - PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")" to restore!\n", filename); - } - - if (is_data_loaded == PM3_SUCCESS) { - return restoreLTO(dump_data, true); } else { - return PM3_EFILE; + PrintAndLogEx(WARNING, "Warning: invalid dump filename " _YELLOW_("%s") " to restore", filename); } - + free(lowstr); + return PM3_SUCCESS; } static command_t CommandTable[] = { diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 8c6247614..1050992f0 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -48,8 +48,8 @@ static int usage_hf14_ice(void) { PrintAndLogEx(NORMAL, " f save nonces to instead of hf-mf--nonces.bin"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf ice"); - PrintAndLogEx(NORMAL, " hf mf ice f nonces.bin"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf ice")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf ice f nonces.bin")); return PM3_SUCCESS; } @@ -60,8 +60,8 @@ static int usage_hf14_dump(void) { PrintAndLogEx(NORMAL, " f : data filename, if no given, UID will be used as filename"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf dump"); - PrintAndLogEx(NORMAL, " hf mf dump 4"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf dump")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf dump 4")); return PM3_SUCCESS; } @@ -72,9 +72,9 @@ static int usage_hf14_mifare(void) { PrintAndLogEx(NORMAL, " (Optional) target other block"); PrintAndLogEx(NORMAL, " (optional) target key type"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf darkside"); - PrintAndLogEx(NORMAL, " hf mf darkside 16"); - PrintAndLogEx(NORMAL, " hf mf darkside 16 B"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf darkside")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf darkside 16")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf darkside 16 B")); return PM3_SUCCESS; } static int usage_hf14_mfsim(void) { @@ -95,10 +95,10 @@ static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, " e (Optional) Fill simulator keys from found keys"); PrintAndLogEx(NORMAL, " v (Optional) Verbose"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf sim u 0a0a0a0a"); - PrintAndLogEx(NORMAL, " hf mf sim u 11223344556677"); - PrintAndLogEx(NORMAL, " hf mf sim u 112233445566778899AA"); - PrintAndLogEx(NORMAL, " hf mf sim u 11223344 i x"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf sim u 0a0a0a0a")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf sim u 11223344556677")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf sim u 112233445566778899AA")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf sim u 11223344 i x")); return PM3_SUCCESS; } /* @@ -112,7 +112,7 @@ static int usage_hf14_mfsim(void) { // PrintAndLogEx(NORMAL, " n/a e decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory"); PrintAndLogEx(NORMAL, " f decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`"); PrintAndLogEx(NORMAL, "Example:"); - PrintAndLogEx(NORMAL, " hf mf sniff l d f"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf sniff l d f")); return PM3_SUCCESS; } */ @@ -127,10 +127,10 @@ static int usage_hf14_nested(void) { PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); - PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A -- one sector key recovery. Use block 0 Key A to find block 4 Key A"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf nested 1 0 A FFFFFFFFFFFF")" -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf nested 1 0 A FFFFFFFFFFFF t")" -- and transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf nested 1 0 A FFFFFFFFFFFF d")" -- or write keys to binary file "); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf nested o 0 A FFFFFFFFFFFF 4 A")" -- one sector key recovery. Use block 0 Key A to find block 4 Key A"); return PM3_SUCCESS; } static int usage_hf14_staticnested(void) { @@ -143,9 +143,9 @@ static int usage_hf14_staticnested(void) { PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf staticnested 1 0 A FFFFFFFFFFFF -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); - PrintAndLogEx(NORMAL, " hf mf staticnested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); - PrintAndLogEx(NORMAL, " hf mf staticnested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf staticnested 1 0 A FFFFFFFFFFFF")" -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf staticnested 1 0 A FFFFFFFFFFFF t")" -- and transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf staticnested 1 0 A FFFFFFFFFFFF d")" -- or write keys to binary file "); return PM3_SUCCESS; } static int usage_hf14_hardnested(void) { @@ -163,43 +163,29 @@ static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, " f read/write instead of default name"); PrintAndLogEx(NORMAL, " t tests?"); PrintAndLogEx(NORMAL, " i set type of SIMD instructions. Without this flag programs autodetect it."); +#if defined(COMPILER_HAS_SIMD_AVX512) PrintAndLogEx(NORMAL, " i 5 = AVX512"); +#endif +#if defined(COMPILER_HAS_SIMD) PrintAndLogEx(NORMAL, " i 2 = AVX2"); PrintAndLogEx(NORMAL, " i a = AVX"); PrintAndLogEx(NORMAL, " i s = SSE2"); PrintAndLogEx(NORMAL, " i m = MMX"); +#endif PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf hardnested 0 A FFFFFFFFFFFF 4 A"); - PrintAndLogEx(NORMAL, " hf mf hardnested 0 A FFFFFFFFFFFF 4 A w"); - PrintAndLogEx(NORMAL, " hf mf hardnested 0 A FFFFFFFFFFFF 4 A f nonces.bin w s"); - PrintAndLogEx(NORMAL, " hf mf hardnested r"); - PrintAndLogEx(NORMAL, " hf mf hardnested r a0a1a2a3a4a5"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf hardnested 0 A FFFFFFFFFFFF 4 A")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf hardnested 0 A FFFFFFFFFFFF 4 A w")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf hardnested 0 A FFFFFFFFFFFF 4 A f nonces.bin w s")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf hardnested r")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf hardnested r a0a1a2a3a4a5")); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Add the known target key to check if it is present in the remaining key space:"); - PrintAndLogEx(NORMAL, " hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF")); return PM3_SUCCESS; } -/* -static int usage_hf14_fixednested(void) { - PrintAndLogEx(NORMAL, "Usage:"); - PrintAndLogEx(NORMAL, " all sectors: hf mf fixed [t,d]"); - PrintAndLogEx(NORMAL, " one sector: hf mf fixed o [t]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h this help"); - PrintAndLogEx(NORMAL, " card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); - PrintAndLogEx(NORMAL, " t transfer keys into emulator memory"); - PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf fixed 1 0 A FFFFFFFFFFFF -- key recovery against 1K, block 0, Key A using key FFFFFFFFFFFF"); - PrintAndLogEx(NORMAL, " hf mf fixed 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); - PrintAndLogEx(NORMAL, " hf mf fixed 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); - PrintAndLogEx(NORMAL, " hf mf fixed o 0 A FFFFFFFFFFFF 4 A -- one sector key recovery. Use block 0 Key A to find block 4 Key A"); - return PM3_SUCCESS; -} -*/ + static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); @@ -222,18 +208,22 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, " * 2 = 2k"); PrintAndLogEx(NORMAL, " * 4 = 4k"); PrintAndLogEx(NORMAL, " i set type of SIMD instructions for hardnested. Default: autodetection."); +#if defined(COMPILER_HAS_SIMD_AVX512) PrintAndLogEx(NORMAL, " i 5 = AVX512"); +#endif +#if defined(COMPILER_HAS_SIMD) PrintAndLogEx(NORMAL, " i 2 = AVX2"); PrintAndLogEx(NORMAL, " i a = AVX"); PrintAndLogEx(NORMAL, " i s = SSE2"); +#endif PrintAndLogEx(NORMAL, " i m = MMX"); PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf autopwn -- target Mifare classic card with default keys"); - PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys -- target Mifare classic card (size 1k) with default dictionary"); - PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF -- target Mifare classic card with Sector0 typeA with known key 'FFFFFFFFFFFF'"); - PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys -- this command combines the two above (reduce the need for nested / hardnested attacks, by using a dictionary)"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf autopwn")" -- target Mifare classic card with default keys"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf autopwn * 1 f mfc_default_keys")" -- target Mifare classic card (size 1k) with default dictionary"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf autopwn k 0 A FFFFFFFFFFFF")" -- target Mifare classic card with Sector0 typeA with known key 'FFFFFFFFFFFF'"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys")" -- this command combines the two above (reduce the need for nested / hardnested attacks, by using a dictionary)"); return PM3_SUCCESS; } static int usage_hf14_chk(void) { @@ -293,7 +283,7 @@ static int usage_hf14_keybrute(void) { PrintAndLogEx(NORMAL, " target key type"); PrintAndLogEx(NORMAL, " candidate key from mf_nonce_brute tool"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf keybrute 1 A 000011223344"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf keybrute 1 A 000011223344")); return 0; } */ @@ -306,10 +296,10 @@ static int usage_hf14_restore(void) { PrintAndLogEx(NORMAL, " f : data filename, specific the full filename of data file"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf restore -- read the UID from tag first, then restore from hf-mf--key.bin and and hf-mf--dump.bin"); - PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 -- restore from hf-mf-12345678-key.bin and hf-mf-12345678-dump.bin"); - PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 k dumpkey.bin -- restore from dumpkey.bin and hf-mf-12345678-dump.bin"); - PrintAndLogEx(NORMAL, " hf mf restore 4 -- read the UID from tag with 4K memory first, then restore from hf-mf--key.bin and and hf-mf--dump.bin"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf restore") " -- read the UID from tag first, then restore from hf-mf--key.bin and and hf-mf--dump.bin"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf restore 1 u 12345678") " -- restore from hf-mf-12345678-key.bin and hf-mf-12345678-dump.bin"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf restore 1 u 12345678 k dumpkey.bin") " -- restore from dumpkey.bin and hf-mf-12345678-dump.bin"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf restore 4") " -- read the UID from tag with 4K memory first, then restore from hf-mf--key.bin and and hf-mf--dump.bin"); return PM3_SUCCESS; } static int usage_hf14_decryptbytes(void) { @@ -322,26 +312,28 @@ static int usage_hf14_decryptbytes(void) { PrintAndLogEx(NORMAL, " encrypted tag response"); PrintAndLogEx(NORMAL, " encrypted data, taken directly after at_enc and forward"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf decrypt b830049b 9248314a 9280e203 41e586f9\n"); - PrintAndLogEx(NORMAL, " this sample decrypts 41e586f9 -> 3003999a Annotated: 30 03 [99 9a] auth block 3 [crc]"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf decrypt b830049b 9248314a 9280e203 41e586f9")); + PrintAndLogEx(NORMAL, "\n this sample decrypts 41e586f9 -> 3003999a Annotated: 30 03 [99 9a] auth block 3 [crc]"); return PM3_SUCCESS; } static int usage_hf14_eget(void) { PrintAndLogEx(NORMAL, "Usage: hf mf eget "); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf eget 0 "); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf eget 0")); return PM3_SUCCESS; } static int usage_hf14_eclr(void) { PrintAndLogEx(NORMAL, "It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n"); PrintAndLogEx(NORMAL, "Usage: hf mf eclr"); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf eclr")); return PM3_SUCCESS; } static int usage_hf14_eset(void) { PrintAndLogEx(NORMAL, "Usage: hf mf eset "); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf eset 1 000102030405060708090a0b0c0d0e0f "); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf eset 1 000102030405060708090a0b0c0d0e0f")); return PM3_SUCCESS; } static int usage_hf14_eload(void) { @@ -350,8 +342,8 @@ static int usage_hf14_eload(void) { PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf eload filename"); - PrintAndLogEx(NORMAL, " hf mf eload 4 filename"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf eload filename")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf eload 4 filename")); return PM3_SUCCESS; } static int usage_hf14_esave(void) { @@ -360,9 +352,9 @@ static int usage_hf14_esave(void) { PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf esave "); - PrintAndLogEx(NORMAL, " hf mf esave 4"); - PrintAndLogEx(NORMAL, " hf mf esave 4 filename"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf esave")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf esave 4")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf esave 4 filename")); return PM3_SUCCESS; } static int usage_hf14_ecfill(void) { @@ -372,8 +364,8 @@ static int usage_hf14_ecfill(void) { PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf ecfill A"); - PrintAndLogEx(NORMAL, " hf mf ecfill A 4"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf ecfill A")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf ecfill A 4")); return PM3_SUCCESS; } static int usage_hf14_ekeyprn(void) { @@ -385,8 +377,8 @@ static int usage_hf14_ekeyprn(void) { PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf ekeyprn 1"); - PrintAndLogEx(NORMAL, " hf mf ekeyprn d"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf ekeyprn 1")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf ekeyprn d")); return PM3_SUCCESS; } @@ -401,8 +393,8 @@ static int usage_hf14_csetuid(void) { PrintAndLogEx(NORMAL, " ATQA 4 hex symbols"); PrintAndLogEx(NORMAL, " SAK 2 hex symbols"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf csetuid 01020304"); - PrintAndLogEx(NORMAL, " hf mf csetuid 01020304 0004 08 w"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csetuid 01020304")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csetuid 01020304 0004 08 w")); return PM3_SUCCESS; } static int usage_hf14_csetblk(void) { @@ -415,8 +407,8 @@ static int usage_hf14_csetblk(void) { PrintAndLogEx(NORMAL, " block number"); PrintAndLogEx(NORMAL, " block data to write (32 hex symbols)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf csetblk 1 01020304050607080910111213141516"); - PrintAndLogEx(NORMAL, " hf mf csetblk 1 01020304050607080910111213141516 w"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csetblk 1 01020304050607080910111213141516")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csetblk 1 01020304050607080910111213141516 w")); return PM3_SUCCESS; } static int usage_hf14_cload(void) { @@ -431,8 +423,8 @@ static int usage_hf14_cload(void) { PrintAndLogEx(NORMAL, " b load card with data from binary file"); PrintAndLogEx(NORMAL, " load card with data from eml file"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf cload mydump"); - PrintAndLogEx(NORMAL, " hf mf cload e"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf cload mydump")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf cload e")); return PM3_SUCCESS; } static int usage_hf14_cgetblk(void) { @@ -443,7 +435,7 @@ static int usage_hf14_cgetblk(void) { PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " block number"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf cgetblk 1"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf cgetblk 1")); return PM3_SUCCESS; } static int usage_hf14_cgetsc(void) { @@ -454,7 +446,7 @@ static int usage_hf14_cgetsc(void) { PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " sector number"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf cgetsc 0"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf cgetsc 0")); return PM3_SUCCESS; } static int usage_hf14_csave(void) { @@ -470,9 +462,9 @@ static int usage_hf14_csave(void) { PrintAndLogEx(NORMAL, " o save data to file"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf csave u 1"); - PrintAndLogEx(NORMAL, " hf mf csave e 1"); - PrintAndLogEx(NORMAL, " hf mf csave 4 o filename"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csave u 1")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csave e 1")); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csave 4 o filename")); return PM3_SUCCESS; } static int usage_hf14_nack(void) { @@ -483,7 +475,7 @@ static int usage_hf14_nack(void) { PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " v verbose"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf nack"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf nack")); return PM3_SUCCESS; } @@ -523,7 +515,6 @@ static char *GenerateFilename(const char *prefix, const char *suffix) { static int32_t initSectorTable(sector_t **src, int32_t items) { - // initialize storage (*src) = calloc(items, sizeof(sector_t)); if (*src == NULL) @@ -620,7 +611,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { memcpy(data, key, 6); memcpy(data + 10, bldata, 16); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFARE_WRITEBL, blockNo, keyType, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFARE_WRITEBL, blockNo, keyType, 0, data, sizeof(data)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -733,7 +724,7 @@ static int CmdHF14AMfRdSc(const char *Cmd) { PrintAndLogEx(NORMAL, "--sector no:%d key type:%c key:%s ", sectorNo, keyType ? 'B' : 'A', sprint_hex(key, 6)); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, key, 6); + SendCommandMIX(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, key, 6); PrintAndLogEx(NORMAL, ""); PacketResponseNG resp; @@ -1076,7 +1067,7 @@ static int CmdHF14AMfDump(const char *Cmd) { saveFile(dataFilename, ".bin", (uint8_t *)carddata, bytes); saveFileEML(dataFilename, (uint8_t *)carddata, bytes, MFBLOCK_SIZE); - saveFileJSON(dataFilename, jsfCardMemory, (uint8_t *)carddata, bytes); + saveFileJSON(dataFilename, jsfCardMemory, (uint8_t *)carddata, bytes, NULL); return PM3_SUCCESS; } @@ -1206,7 +1197,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { memcpy(data + 10, bldata, 16); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFARE_WRITEBL, FirstBlockOfSector(sectorNo) + blockNo, keyType, 0, data, sizeof(data)); + SendCommandMIX(CMD_HF_MIFARE_WRITEBL, FirstBlockOfSector(sectorNo) + blockNo, keyType, 0, data, sizeof(data)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -1805,9 +1796,12 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { SetSIMDInstr(SIMD_AUTO); ctmp = tolower(param_getchar(Cmd, cmdp + 1)); switch (ctmp) { +#if defined(COMPILER_HAS_SIMD_AVX512) case '5': SetSIMDInstr(SIMD_AVX512); break; +#endif +#if defined(COMPILER_HAS_SIMD) case '2': SetSIMDInstr(SIMD_AVX2); break; @@ -1820,6 +1814,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { case 'm': SetSIMDInstr(SIMD_MMX); break; +#endif case 'n': SetSIMDInstr(SIMD_NONE); break; @@ -1866,7 +1861,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { uint64_t foundkey = 0; int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename); - DropField(); + if (tests == 0) DropField(); if (isOK) { switch (isOK) { case 1 : @@ -1892,7 +1887,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { bool calibrate = true; // Attack key storage variables uint8_t *keyBlock = NULL; - uint16_t key_cnt = 0; + uint32_t key_cnt = 0; sector_t *e_sector; uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; int block_cnt = MIFARE_1K_MAXBLOCK; @@ -1986,9 +1981,12 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { SetSIMDInstr(SIMD_AUTO); ctmp = tolower(param_getchar(Cmd, cmdp + 1)); switch (ctmp) { +#if defined(COMPILER_HAS_SIMD_AVX512) case '5': SetSIMDInstr(SIMD_AVX512); break; +#endif +#if defined(COMPILER_HAS_SIMD) case '2': SetSIMDInstr(SIMD_AVX2); break; @@ -2001,6 +1999,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { case 'm': SetSIMDInstr(SIMD_MMX); break; +#endif case 'n': SetSIMDInstr(SIMD_NONE); break; @@ -2153,7 +2152,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { for (int j = 0; j < 2; j++) { // Check if the key is known if (e_sector[i].foundKey[j] == 0) { - for (int k = 0; k < key_cnt; k++) { + for (uint32_t k = 0; k < key_cnt; k++) { printf("."); fflush(stdout); if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) { @@ -2170,13 +2169,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { fflush(stdout); } else { - int chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; + uint32_t chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; bool firstChunk = true, lastChunk = false; for (uint8_t strategy = 1; strategy < 3; strategy++) { PrintAndLogEx(INFO, "running strategy %u", strategy); // main keychunk loop - for (int i = 0; i < key_cnt; i += chunksize) { + for (uint32_t i = 0; i < key_cnt; i += chunksize) { if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); @@ -2518,7 +2517,7 @@ all_found: saveFile(filename, ".bin", dump, bytes); saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); - saveFileJSON(filename, jsfCardMemory, dump, bytes); + saveFileJSON(filename, jsfCardMemory, dump, bytes, NULL); // Generate and show statistics t1 = msclock() - t1; @@ -2897,7 +2896,7 @@ static int CmdHF14AMfChk(const char *Cmd) { } keyBlock = p; } - PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex((keyBlock + 6 * keycnt), 6));; + PrintAndLogEx(NORMAL, "[%2d] key %s", keycnt, sprint_hex((keyBlock + 6 * keycnt), 6)); keycnt++; } else if (clen == 1) { if (ctmp == 't') { transferToEml = 1; continue; } @@ -3129,18 +3128,14 @@ out: return PM3_SUCCESS; } -sector_t *k_sector = NULL; -uint8_t k_sectorsCount = 40; - -void showSectorTable() { +void showSectorTable(sector_t *k_sector, uint8_t k_sectorsCount) { if (k_sector != NULL) { printKeyTable(k_sectorsCount, k_sector); free(k_sector); - k_sector = NULL; } } -void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { +void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, bool setEmulatorMem, bool verbose) { uint64_t key = 0; bool success = false; @@ -3148,6 +3143,7 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { if (k_sector == NULL) { int32_t res = initSectorTable(&k_sector, k_sectorsCount); if (res != k_sectorsCount) { + free(k_sector); return; } } @@ -3179,6 +3175,8 @@ void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) { mfEmlSetMem(memBlock, (sector * 4) + 3, 1); } } + + free(k_sector); } static int CmdHF14AMfSim(const char *Cmd) { @@ -3196,6 +3194,8 @@ static int CmdHF14AMfSim(const char *Cmd) { nonces_t data[1]; char csize[13] = { 0 }; char uidsize[8] = { 0 }; + sector_t *k_sector = NULL; + uint8_t k_sectorsCount = 40; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -3343,173 +3343,14 @@ static int CmdHF14AMfSim(const char *Cmd) { if ((resp.oldarg[0] & 0xffff) != CMD_HF_MIFARE_SIMULATE) break; memcpy(data, resp.data.asBytes, sizeof(data)); - readerAttack(data[0], setEmulatorMem, verbose); + readerAttack(k_sector, k_sectorsCount, data[0], setEmulatorMem, verbose); } - showSectorTable(); + showSectorTable(k_sector, k_sectorsCount); } k_sectorsCount = MIFARE_4K_MAXSECTOR; return PM3_SUCCESS; } -/* -static int CmdHF14AMfSniff(const char *Cmd) { - bool wantLogToFile = false; - bool wantDecrypt = false; - //bool wantSaveToEml = false; TODO - bool wantSaveToEmlFile = false; - - //var - int res = 0, len = 0, blockLen = 0; - int pckNum = 0, num = 0; - uint8_t sak = 0; - uint8_t uid[10]; - uint8_t uid_len = 0; - uint8_t atqa[2] = {0x00, 0x00}; - bool isTag = false; - uint8_t *buf = NULL; - uint16_t bufsize = 0; - uint8_t *bufPtr = NULL; - uint16_t traceLen = 0; - - memset(uid, 0x00, sizeof(uid)); - - char ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_hf14_sniff(); - - for (int i = 0; i < 4; i++) { - ctmp = tolower(param_getchar(Cmd, i)); - if (ctmp == 'l') wantLogToFile = true; - if (ctmp == 'd') wantDecrypt = true; - //if (ctmp == 'e') wantSaveToEml = true; TODO - if (ctmp == 'f') wantSaveToEmlFile = true; - } - - PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n"); - PrintAndLogEx(NORMAL, "Executing mifare sniffing command. \n"); - PrintAndLogEx(NORMAL, "Press the button on the Proxmark3 device to abort both Proxmark3 and client.\n"); - PrintAndLogEx(NORMAL, "Press Enter to abort the client.\n"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n"); - - clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_SNIFF, NULL, 0); - - PacketResponseNG resp; - - // wait cycle - while (true) { - printf("."); - fflush(stdout); - if (kbd_enter_pressed()) { - PrintAndLogEx(INFO, "\naborted via keyboard!\n"); - break; - } - - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - continue; - } - - res = resp.oldarg[0] & 0xff; - traceLen = resp.oldarg[1]; - len = resp.oldarg[2]; - - if (res == 0) { - PrintAndLogEx(SUCCESS, "hf mifare sniff finished"); - free(buf); - return 0; - } - - if (res == 1) { // there is (more) data to be transferred - if (pckNum == 0) { // first packet, (re)allocate necessary buffer - if (traceLen > bufsize || buf == NULL) { - uint8_t *p; - if (buf == NULL) // not yet allocated - p = calloc(traceLen, sizeof(uint8_t)); - else // need more memory - p = realloc(buf, traceLen); - - if (p == NULL) { - PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); - free(buf); - return 2; - } - buf = p; - } - bufPtr = buf; - bufsize = traceLen; - memset(buf, 0x00, traceLen); - } - - // what happens if LEN is bigger then TRACELEN --iceman - memcpy(bufPtr, resp.data.asBytes, len); - bufPtr += len; - pckNum++; - } - - if (res == 2) { // received all data, start displaying - blockLen = bufPtr - buf; - bufPtr = buf; - PrintAndLogEx(NORMAL, ">\n"); - PrintAndLogEx(SUCCESS, "received trace len: %d packages: %d", blockLen, pckNum); - while (bufPtr - buf < blockLen) { - bufPtr += 6; // skip (void) timing information - len = *((uint16_t *)bufPtr); - if (len & 0x8000) { - isTag = true; - len &= 0x7fff; - } else { - isTag = false; - } - bufPtr += 2; - - // the uid identification package - // 0xFF 0xFF xx xx xx xx xx xx xx xx xx xx aa aa cc 0xFF 0xFF - // x = uid, a = atqa, c = sak - if ((len == 17) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[15] == 0xff) && (bufPtr[16] == 0xff)) { - memcpy(uid, bufPtr + 2, 10); - memcpy(atqa, bufPtr + 2 + 10, 2); - switch (atqa[0] & 0xC0) { - case 0x80: - uid_len = 10; - break; - case 0x40: - uid_len = 7; - break; - default: - uid_len = 4; - break; - } - sak = bufPtr[14]; - PrintAndLogEx(SUCCESS, "UID %s | ATQA %02x %02x | SAK 0x%02x", - sprint_hex(uid, uid_len), - atqa[1], - atqa[0], - sak); - if (wantLogToFile || wantDecrypt) { - FillFileNameByUID(logHexFileName, uid, ".log", uid_len); - AddLogCurrentDT(logHexFileName); - PrintAndLogEx(SUCCESS, "Trace saved to %s", logHexFileName); - } - if (wantDecrypt) - mfTraceInit(uid, uid_len, atqa, sak, wantSaveToEmlFile); - } else { - PrintAndLogEx(NORMAL, "%03d| %s |%s", num, isTag ? "TAG" : "RDR", sprint_hex(bufPtr, len)); - if (wantLogToFile) - AddLogHex(logHexFileName, isTag ? "TAG| " : "RDR| ", bufPtr, len); - if (wantDecrypt) - mfTraceDecode(bufPtr, len, wantSaveToEmlFile); - num++; - } - bufPtr += len; - bufPtr += ((len - 1) / 8 + 1); // ignore parity - } - pckNum = 0; - } - } // while (true) - - free(buf); - return PM3_SUCCESS; -} -*/ /* static int CmdHF14AMfKeyBrute(const char *Cmd) { @@ -3688,10 +3529,15 @@ int CmdHF14AMfELoad(const char *Cmd) { return usage_hf14_eload(); uint8_t *data = calloc(4096, sizeof(uint8_t)); + if (data == NULL) { + PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + return PM3_EMALLOC; + } + size_t datalen = 0; //int res = loadFile(filename, ".bin", data, maxdatalen, &datalen); int res = loadFileEML(filename, data, &datalen); - if (res) { + if (res != PM3_SUCCESS) { free(data); return PM3_EFILE; } @@ -3703,14 +3549,35 @@ int CmdHF14AMfELoad(const char *Cmd) { return PM3_ESOFT; } - // convert old mfu format to new + // convert plain or old mfu format to new format if (blockWidth == 4) { - res = convertOldMfuDump(&data, &datalen); - if (res) { + + res = convert_mfu_dump_format(&data, &datalen, true); + if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Failed convert on load to new Ultralight/NTAG format"); free(data); return res; } + + mfu_dump_t *mfu_dump = (mfu_dump_t *)data; + + PrintAndLogEx(INFO, _CYAN_("MFU dump file information")); + PrintAndLogEx(INFO, " version %s", sprint_hex(mfu_dump->version, sizeof(mfu_dump->version))); + PrintAndLogEx(INFO, " tb 0 %s", sprint_hex(mfu_dump->tbo, sizeof(mfu_dump->tbo))); + PrintAndLogEx(INFO, " tb 1 %s", sprint_hex(mfu_dump->tbo1, sizeof(mfu_dump->tbo1))); + for (uint8_t m = 0; m < 3; m++) { + PrintAndLogEx(INFO, " counter %d %s - tearing 0x%02x", m + 1, sprint_hex(mfu_dump->counter_tearing[m], 3), mfu_dump->counter_tearing[m][3]); + } + PrintAndLogEx(INFO, " signature %s", sprint_hex(mfu_dump->signature, sizeof(mfu_dump->signature))); + PrintAndLogEx(INFO, " data %s... (only first 8 bytes showing)", sprint_hex(mfu_dump->data, 8)); + PrintAndLogEx(INFO, " max data page %d, data len %d bytes", mfu_dump->pages, (mfu_dump->pages + 1) * 4); + PrintAndLogEx(INFO, " file header size %d", MFU_DUMP_PREFIX_LENGTH); + PrintAndLogEx(INFO, "----------------------------------------------"); + + // update expected blocks to match converted data. + if (numBlocks != datalen / 4) { + numBlocks = datalen / 4; + } } PrintAndLogEx(INFO, "Uploading to emulator memory"); @@ -3736,24 +3603,27 @@ int CmdHF14AMfELoad(const char *Cmd) { counter += blockWidth; datalen -= blockWidth; } + free(data); PrintAndLogEx(NORMAL, "\n"); - // Ultralight /Ntag if (blockWidth == 4) { + PrintAndLogEx(HINT, "You are ready to simulate. See " _YELLOW_("`hf mfu sim h`")); + // MFU / NTAG if ((blockNum != numBlocks)) { - PrintAndLogEx(FAILED, "Warning, Ultralight/Ntag file content, Loaded %d blocks into emulator memory", blockNum); - free(data); + PrintAndLogEx(WARNING, "Warning, Ultralight/Ntag file content, Loaded %d blocks of expected %d blocks into emulator memory", blockNum, numBlocks); return PM3_SUCCESS; } } else { + PrintAndLogEx(HINT, "You are ready to simulate. See " _YELLOW_("`hf mf sim h`")); + // MFC if ((blockNum != numBlocks)) { - PrintAndLogEx(FAILED, "Error, file content, Only loaded %d blocks, must be %d blocks into emulator memory", blockNum, numBlocks); - free(data); + PrintAndLogEx(WARNING, "Error, file content, Only loaded %d blocks, must be %d blocks into emulator memory", blockNum, numBlocks); + return PM3_SUCCESS; } + } PrintAndLogEx(SUCCESS, "Done"); - free(data); return PM3_SUCCESS; } @@ -3803,7 +3673,7 @@ static int CmdHF14AMfESave(const char *Cmd) { saveFile(filename, ".bin", dump, bytes); saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); - saveFileJSON(filename, jsfCardMemory, dump, bytes); + saveFileJSON(filename, jsfCardMemory, dump, bytes, NULL); free(dump); return PM3_SUCCESS; } @@ -3996,7 +3866,8 @@ static int CmdHF14AMfCWipe(const char *cmd) { uint8_t sak[1] = {0x00}; int sakLen = 0; - CLIParserInit("hf mf cwipe", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf cwipe", "Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.", "Usage:\n\thf mf cwipe -> wipe card.\n" "\thf mf cwipe -u 09080706 -a 0004 -s 18 -- set UID, ATQA and SAK and wipe card."); @@ -4008,12 +3879,12 @@ static int CmdHF14AMfCWipe(const char *cmd) { arg_str0("sS", "sak", "", "SAK for card"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); - CLIGetHexWithReturn(1, uid, &uidLen); - CLIGetHexWithReturn(2, atqa, &atqaLen); - CLIGetHexWithReturn(3, sak, &sakLen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, uid, &uidLen); + CLIGetHexWithReturn(ctx, 2, atqa, &atqaLen); + CLIGetHexWithReturn(ctx, 3, sak, &sakLen); + CLIParserFree(ctx); if (uidLen && uidLen != 4) { PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen); @@ -4120,7 +3991,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) { res = loadFile(fileName, ".bin", data, maxdatalen, &datalen); } else { if (fillFromJson) { - res = loadFileJSON(fileName, data, maxdatalen, &datalen); + res = loadFileJSON(fileName, data, maxdatalen, &datalen, NULL); } else { res = loadFileEML(Cmd, data, &datalen); } @@ -4337,6 +4208,7 @@ static int CmdHF14AMfCSave(const char *Cmd) { if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); + free(dump); return select_status; } @@ -4381,7 +4253,7 @@ static int CmdHF14AMfCSave(const char *Cmd) { saveFile(filename, ".bin", dump, bytes); saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); - saveFileJSON(filename, jsfCardMemory, dump, bytes); + saveFileJSON(filename, jsfCardMemory, dump, bytes, NULL); free(dump); return PM3_SUCCESS; } @@ -4581,7 +4453,8 @@ static int CmdHF14AMfAuth4(const char *Cmd) { uint8_t key[16] = {0}; int keylen = 0; - CLIParserInit("hf mf auth4", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf auth4", "Executes AES authentication command in ISO14443-4", "Usage:\n\thf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n" "\thf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n"); @@ -4592,11 +4465,11 @@ static int CmdHF14AMfAuth4(const char *Cmd) { arg_str1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - CLIGetHexWithReturn(1, keyn, &keynlen); - CLIGetHexWithReturn(2, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, keyn, &keynlen); + CLIGetHexWithReturn(ctx, 2, key, &keylen); + CLIParserFree(ctx); if (keynlen != 2) { PrintAndLogEx(ERR, " must be 2 bytes long instead of: %d", keynlen); @@ -4614,124 +4487,178 @@ static int CmdHF14AMfAuth4(const char *Cmd) { // https://www.nxp.com/docs/en/application-note/AN10787.pdf static int CmdHF14AMfMAD(const char *Cmd) { - CLIParserInit("hf mf mad", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf mad", "Checks and prints Mifare Application Directory (MAD)", - "Usage:\n\thf mf mad -> shows MAD if exists\n" - "\thf mf mad -a 03e1 -k ffffffffffff -b -> shows NDEF data if exists. read card with custom key and key B\n"); + "Usage:\n" + "\thf mf mad -> shows MAD if exists\n" + "\thf mf mad --aid e103 -k ffffffffffff -b -> shows NDEF data if exists. read card with custom key and key B\n" + "\thf mf mad --dch -k ffffffffffff -> decode CardHolder information\n"); void *argtable[] = { arg_param_begin, arg_lit0("vV", "verbose", "show technical data"), - arg_str0("aA", "aid", "print all sectors with aid", NULL), - arg_str0("kK", "key", "key for printing sectors", NULL), + arg_str0("", "aid", "", "print all sectors with specified aid"), + arg_str0("kK", "key", "", "key for printing sectors"), arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), + arg_lit0("", "be", "(optional, BigEndian)"), + arg_lit0("", "dch", "decode Card Holder information"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); - bool verbose = arg_get_lit(1); + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool verbose = arg_get_lit(ctx, 1); uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[6] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); - bool keyB = arg_get_lit(4); + CLIGetHexWithReturn(ctx, 3, key, &keylen); + bool keyB = arg_get_lit(ctx, 4); + bool swapmad = arg_get_lit(ctx, 5); + bool decodeholder = arg_get_lit(ctx, 6); - CLIParserFree(); + CLIParserFree(ctx); - if (aidlen != 2 && keylen > 0) { - PrintAndLogEx(WARNING, "do not need a key without aid."); + if (aidlen != 2 && !decodeholder && keylen > 0) { + PrintAndLogEx(WARNING, "Using default MAD keys instead"); } uint8_t sector0[16 * 4] = {0}; uint8_t sector10[16 * 4] = {0}; if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector0)) { - PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); + PrintAndLogEx(ERR, "error, read sector 0. card don't have MAD or don't have MAD on default keys"); return PM3_ESOFT; } - if (verbose) { - for (int i = 0; i < 4; i ++) - PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or0[i * 16], 16)); - } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Mifare App Directory Information") " ----------------"); + PrintAndLogEx(INFO, "-----------------------------------------------------"); bool haveMAD2 = false; - MAD1DecodeAndPrint(sector0, verbose, &haveMAD2); + MAD1DecodeAndPrint(sector0, swapmad, verbose, &haveMAD2); if (haveMAD2) { if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10)) { - PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); + PrintAndLogEx(ERR, "error, read sector 0x10. card don't have MAD or don't have MAD on default keys"); return PM3_ESOFT; } - MAD2DecodeAndPrint(sector10, verbose); + MAD2DecodeAndPrint(sector10, swapmad, verbose); } - if (aidlen == 2) { - uint16_t aaid = (aid[0] << 8) + aid[1]; - PrintAndLogEx(NORMAL, "\n-------------- AID 0x%04x ---------------", aaid); - + if (aidlen == 2 || decodeholder) { uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; - if (MADDecode(sector0, sector10, mad, &madlen)) { - PrintAndLogEx(ERR, "can't decode mad."); + if (MADDecode(sector0, sector10, mad, &madlen, swapmad)) { + PrintAndLogEx(ERR, "can't decode MAD"); return PM3_ESOFT; } + // copy default NDEF key uint8_t akey[6] = {0}; memcpy(akey, g_mifare_ndef_key, 6); + + // user specified key if (keylen == 6) { memcpy(akey, key, 6); } - for (int i = 0; i < madlen; i++) { - if (aaid == mad[i]) { - uint8_t vsector[16 * 4] = {0}; - if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector)) { - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(ERR, "read sector %d error.", i + 1); - return PM3_ESOFT; - } + uint16_t aaid = 0x0004; + if (aidlen == 2) { - for (int j = 0; j < (verbose ? 4 : 3); j ++) - PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + aaid = (aid[0] << 8) + aid[1]; + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-------------- " _CYAN_("AID 0x%04x") " ---------------", aaid); + + for (int i = 0; i < madlen; i++) { + if (aaid == mad[i]) { + uint8_t vsector[16 * 4] = {0}; + if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "error, read sector %d", i + 1); + return PM3_ESOFT; + } + + for (int j = 0; j < (verbose ? 4 : 3); j ++) + PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + } } } + + if (decodeholder) { + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-------- " _CYAN_("Card Holder Info 0x%04x") " --------", aaid); + + uint8_t data[4096] = {0}; + int datalen = 0; + + for (int i = 0; i < madlen; i++) { + if (aaid == mad[i]) { + + uint8_t vsector[16 * 4] = {0}; + if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "error, read sector %d", i + 1); + return PM3_ESOFT; + } + + memcpy(&data[datalen], vsector, 16 * 3); + datalen += 16 * 3; + } + } + + if (!datalen) { + PrintAndLogEx(WARNING, "no Card Holder Info data"); + return PM3_SUCCESS; + } + MADCardHolderInfoDecode(data, datalen, verbose); + } } + if (verbose) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------ " _CYAN_("MAD sector raw") " -------------"); + for (int i = 0; i < 4; i ++) + PrintAndLogEx(INFO, "[%d] %s", i, sprint_hex(§or0[i * 16], 16)); + } + return PM3_SUCCESS; } static int CmdHFMFNDEF(const char *Cmd) { - CLIParserInit("hf mf ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf ndef", "Prints NFC Data Exchange Format (NDEF)", - "Usage:\n\thf mf ndef -> shows NDEF data\n" - "\thf mf ndef -a 03e1 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B\n"); + "Usage:\n\thf mf ndef -> shows NDEF parsed data\n" + "\thf mf ndef -vv -> shows NDEF parsed and raw data\n" + "\thf mf ndef --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B\n"); void *argtable[] = { arg_param_begin, arg_litn("vV", "verbose", 0, 2, "show technical data"), - arg_str0("aA", "aid", "replace default aid for NDEF", NULL), - arg_str0("kK", "key", "replace default key for NDEF", NULL), + arg_str0("", "aid", "", "replace default aid for NDEF"), + arg_str0("kK", "key", "", "replace default key for NDEF"), arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(1); - bool verbose2 = arg_get_lit(1) > 1; + bool verbose = arg_get_lit(ctx, 1); + bool verbose2 = arg_get_lit(ctx, 1) > 1; uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[6] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); - bool keyB = arg_get_lit(4); + CLIGetHexWithReturn(ctx, 3, key, &keylen); + bool keyB = arg_get_lit(ctx, 4); - CLIParserFree(); + CLIParserFree(ctx); - uint16_t ndefAID = 0x03e1; + uint16_t ndefAID = 0xe103; if (aidlen == 2) ndefAID = (aid[0] << 8) + aid[1]; @@ -4746,69 +4673,79 @@ static int CmdHFMFNDEF(const char *Cmd) { uint8_t data[4096] = {0}; int datalen = 0; - PrintAndLogEx(NORMAL, ""); + if (verbose) + PrintAndLogEx(INFO, "reading MAD v1 sector"); if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector0)) { - PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); + PrintAndLogEx(ERR, "error, read sector 0. card don't have MAD or don't have MAD on default keys"); + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndef -k `") " with your custom key"); return PM3_ESOFT; } - + bool haveMAD2 = false; int res = MADCheck(sector0, NULL, verbose, &haveMAD2); - if (res) { - PrintAndLogEx(ERR, "MAD error %d.", res); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "MAD error %d", res); return res; } if (haveMAD2) { + if (verbose) + PrintAndLogEx(INFO, "reading MAD v2 sector"); + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10)) { - PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); + PrintAndLogEx(ERR, "error, read sector 0x10. card don't have MAD or don't have MAD on default keys"); + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndef -k `") " with your custom key"); return PM3_ESOFT; } } uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; - if (MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen)) { - PrintAndLogEx(ERR, "can't decode mad."); - return PM3_ESOFT; + res = MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen, false); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "can't decode MAD"); + return res; } - printf("data reading:"); + PrintAndLogEx(INFO, "reading data from tag"); for (int i = 0; i < madlen; i++) { if (ndefAID == mad[i]) { uint8_t vsector[16 * 4] = {0}; if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector)) { - PrintAndLogEx(ERR, "read sector %d error.", i + 1); + PrintAndLogEx(ERR, "error, reading sector %d ", i + 1); return PM3_ESOFT; } memcpy(&data[datalen], vsector, 16 * 3); datalen += 16 * 3; - printf("."); + PrintAndLogEx(INPLACE, "%d", i); } } - printf(" OK\n"); + PrintAndLogEx(NORMAL, ""); if (!datalen) { - PrintAndLogEx(ERR, "no NDEF data."); + PrintAndLogEx(WARNING, "no NDEF data"); return PM3_SUCCESS; } if (verbose2) { - PrintAndLogEx(NORMAL, "NDEF data:"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------"); dump_buffer(data, datalen, stdout, 1); } NDEFDecodeAndPrint(data, datalen, verbose); + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndef -vv`") " for more details"); return PM3_SUCCESS; } -int CmdHFMFPersonalize(const char *cmd) { +static int CmdHFMFPersonalize(const char *cmd) { - CLIParserInit("hf mf personalize", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf personalize", "Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.", "Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n" "\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n" @@ -4823,17 +4760,17 @@ int CmdHFMFPersonalize(const char *cmd) { arg_str1(NULL, NULL, "", "Personalization Option"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); char keytypestr[2] = "a"; uint8_t keytype = 0x00; int keytypestr_len; - int res = CLIParamStrToBuf(arg_get_str(1), (uint8_t *)keytypestr, 1, &keytypestr_len); + int res = CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)keytypestr, 1, &keytypestr_len); str_lower(keytypestr); if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'b')) { PrintAndLogEx(ERR, "ERROR: not a valid key type. Key type must be A or B"); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (keytypestr[0] == 'b') { @@ -4842,23 +4779,23 @@ int CmdHFMFPersonalize(const char *cmd) { uint8_t key[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; int key_len; - res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len); + res = CLIParamHexToBuf(arg_get_str(ctx, 2), key, 6, &key_len); if (res || (!res && key_len > 0 && key_len != 6)) { PrintAndLogEx(ERR, "ERROR: not a valid key. Key must be 12 hex digits"); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } char pers_optionstr[6]; int opt_len; uint8_t pers_option; - res = CLIParamStrToBuf(arg_get_str(3), (uint8_t *)pers_optionstr, 5, &opt_len); + res = CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)pers_optionstr, 5, &opt_len); str_lower(pers_optionstr); if (res || (!res && opt_len > 0 && opt_len != 5) || (strncmp(pers_optionstr, "uidf0", 5) && strncmp(pers_optionstr, "uidf1", 5) && strncmp(pers_optionstr, "uidf2", 5) && strncmp(pers_optionstr, "uidf3", 5))) { PrintAndLogEx(ERR, "ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3"); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (!strncmp(pers_optionstr, "uidf0", 5)) { @@ -4871,7 +4808,7 @@ int CmdHFMFPersonalize(const char *cmd) { pers_option = MIFARE_EV1_UIDF3; } - CLIParserFree(); + CLIParserFree(ctx); clearCommandBuffer(); diff --git a/client/src/cmdhfmf.h b/client/src/cmdhfmf.h index c650b90f9..5325a7956 100644 --- a/client/src/cmdhfmf.h +++ b/client/src/cmdhfmf.h @@ -19,8 +19,8 @@ int CmdHFMF(const char *Cmd); int CmdHF14AMfELoad(const char *Cmd); // used by cmd hf mfu eload int CmdHF14AMfDbg(const char *Cmd); // used by cmd hf mfu dbg -void showSectorTable(void); -void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose); +void showSectorTable(sector_t *k_sector, uint8_t k_sectorsCount); +void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, bool setEmulatorMem, bool verbose); void printKeyTable(uint8_t sectorscnt, sector_t *e_sector); void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector); void printKeyTable_fast(uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo); diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 65b02b5f8..d1c38373a 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -17,7 +17,7 @@ #include "comms.h" #include "ui.h" #include "cmdhf14a.h" -#include "mbedtls/aes.h" +#include "aes.h" #include "crypto/libpcrypto.h" #include "protocols.h" #include "cmdtrace.h" @@ -32,13 +32,13 @@ #define MAX_KEY_LEN 24 #define MAX_KEYS_LIST_LEN 1024 -struct desfire_key defaultkey = {0}; +static struct desfire_key defaultkey = {0}; static desfirekey_t sessionkey = &defaultkey; -uint8_t key_zero_data[16] = { 0x00 }; -uint8_t key_ones_data[16] = { 0x01 }; -uint8_t key_defa_data[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; -uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }; +//uint8_t key_zero_data[16] = { 0x00 }; +//uint8_t key_ones_data[16] = { 0x01 }; +//uint8_t key_defa_data[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; +//uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }; typedef struct { uint8_t mode; @@ -170,7 +170,7 @@ typedef enum { CL_AMISC7 = 0xFF, } aidcluster_h; -static char *cluster_to_text(uint8_t cluster) { +static const char *cluster_to_text(uint8_t cluster) { switch (cluster) { case CL_ADMIN: return "card administration"; @@ -375,7 +375,7 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { } -int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, uint8_t *result, int max_result_len, int *result_len, uint16_t *sw) { +static int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, uint8_t *result, int max_result_len, int *result_len, uint16_t *sw) { *result_len = 0; if (sw) *sw = 0; @@ -433,7 +433,7 @@ int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, uint8_t return PM3_SUCCESS; } -static char *getstatus(uint16_t *sw) { +static const char *getstatus(uint16_t *sw) { if (sw == NULL) return "--> sw argument error. This should never happen !"; if (((*sw >> 8) & 0xFF) == 0x91) { switch (*sw & 0xFF) { @@ -500,7 +500,7 @@ static char *getstatus(uint16_t *sw) { return "Unknown error"; } -static char *GetErrorString(int res, uint16_t *sw) { +static const char *GetErrorString(int res, uint16_t *sw) { switch (res) { case PM3_EAPDU_FAIL: return getstatus(sw); @@ -534,7 +534,7 @@ static char *GetErrorString(int res, uint16_t *sw) { return "Generic TTY error"; case PM3_EINIT: return "Initialization error"; - case PM3_EWRONGANSVER: + case PM3_EWRONGANSWER: return "Expected a different answer error"; case PM3_EOUTOFBOUND: return "Memory out-of-bounds error"; @@ -642,7 +642,7 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) { return DESFIRE_UNKNOWN; } -int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, bool defaultkey) { +static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, bool def_key) { // 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) // 4 different crypto arg1 DES, 3DES, 3K3DES, AES // 3 different communication modes, PLAIN,MAC,CRYPTO @@ -679,7 +679,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, // Part 1 - if (defaultkey) { + if (def_key) { if (payload->algo == MFDES_AUTH_DES) { memcpy(keybytes, PICC_MASTER_KEY8, 8); } else if (payload->algo == MFDES_ALGO_AES || payload->algo == MFDES_ALGO_3DES) { @@ -913,7 +913,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, return PM3_SUCCESS; } -void AuthToError(int error) { +static void AuthToError(int error) { switch (error) { case 1: PrintAndLogEx(SUCCESS, "Sending auth command failed"); @@ -925,7 +925,7 @@ void AuthToError(int error) { PrintAndLogEx(ERR, "Authentication failed. Invalid key number."); break; case 4: - PrintAndLogEx(ERR, "Authentication failed. Length of answer %d doesn't match algo length %d."); + PrintAndLogEx(ERR, "Authentication failed. Length of answer doesn't match algo length"); break; case 5: PrintAndLogEx(ERR, "mbedtls_aes_setkey_dec failed"); @@ -953,7 +953,7 @@ void AuthToError(int error) { } } // -- test if card supports 0x0A -static int test_desfire_authenticate() { +static int test_desfire_authenticate(void) { uint8_t data[] = {0x00}; sAPDU apdu = {0x90, MFDES_AUTHENTICATE, 0x00, 0x00, 0x01, data}; // 0x0A, KEY 0 int recv_len = 0; @@ -968,7 +968,7 @@ static int test_desfire_authenticate() { } // -- test if card supports 0x1A -static int test_desfire_authenticate_iso() { +static int test_desfire_authenticate_iso(void) { uint8_t data[] = {0x00}; sAPDU apdu = {0x90, MFDES_AUTHENTICATE_ISO, 0x00, 0x00, 0x01, data}; // 0x1A, KEY 0 int recv_len = 0; @@ -983,7 +983,7 @@ static int test_desfire_authenticate_iso() { } // -- test if card supports 0xAA -static int test_desfire_authenticate_aes() { +static int test_desfire_authenticate_aes(void) { uint8_t data[] = {0x00}; sAPDU apdu = {0x90, MFDES_AUTHENTICATE_AES, 0x00, 0x00, 0x01, data}; // 0xAA, KEY 0 int recv_len = 0; @@ -1050,7 +1050,6 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign }; uint8_t i; - int res; bool is_valid = false; for (i = 0; i < ARRAYLEN(nxp_desfire_public_keys); i++) { @@ -1059,12 +1058,12 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign uint8_t key[PUBLIC_DESFIRE_ECDA_KEYLEN]; param_gethex_to_eol(nxp_desfire_public_keys[i].value, 0, key, PUBLIC_DESFIRE_ECDA_KEYLEN, &dl); - res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, key, uid, 7, signature, signature_len, false); + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, key, uid, 7, signature, signature_len, false); is_valid = (res == 0); if (is_valid) break; } - if (is_valid == false) { + if (is_valid == false || i == ARRAYLEN(nxp_desfire_public_keys)) { PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); return PM3_ESOFT; } @@ -1210,7 +1209,7 @@ static int handler_desfire_keyversion(uint8_t curr_key, uint8_t *num_versions) { return res; } -static int handler_desfire_commit_transaction() { +static int handler_desfire_commit_transaction(void) { sAPDU apdu = {0x90, MFDES_COMMIT_TRANSACTION, 0x00, 0x00, 0x00, NULL}; //0xC7 int recv_len = 0; uint16_t sw = 0; @@ -1225,7 +1224,7 @@ static int handler_desfire_commit_transaction() { return res; } -/*static int handler_desfire_abort_transaction() { +/*static int handler_desfire_abort_transaction(void) { sAPDU apdu = {0x90, MFDES_ABORT_TRANSACTION, 0x00, 0x00, 0x00, NULL}; //0xA7 int recv_len = 0; uint16_t sw = 0; @@ -1272,15 +1271,21 @@ static int handler_desfire_dfnames(dfname_t *dest, uint8_t *dfname_count) { if (dest == NULL) PrintAndLogEx(ERR, "DEST=NULL"); if (dfname_count == NULL) PrintAndLogEx(ERR, "DFNAME_COUNT=NULL"); } + if (dest == NULL || dfname_count == NULL) return PM3_EINVARG; + + *dfname_count = 0; + sAPDU apdu = {0x90, MFDES_GET_DF_NAMES, 0x00, 0x00, 0x00, NULL}; //0x6d int recv_len = 0; uint16_t sw = 0; int res = send_desfire_cmd(&apdu, true, (uint8_t *)dest, &recv_len, &sw, sizeof(dfname_t), true); if (res != PM3_SUCCESS) return res; + if (sw != status(MFDES_S_OPERATION_OK)) return PM3_ESOFT; + *dfname_count = recv_len; return res; } @@ -1476,8 +1481,8 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type) */ if (data->fileno > 0x1F) return PM3_EINVARG; - int datatowrite = le24toh(data->length); - int offset = le24toh(data->offset); + uint32_t datatowrite = le24toh(data->length); + uint32_t offset = le24toh(data->offset); int datasize; int pos = 0; int recvlen = 0; @@ -1490,7 +1495,8 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type) apdu.data = tmp; if (type == MFDES_RECORD_FILE) apdu.INS = MFDES_WRITE_RECORD; - while (datatowrite > 0) { + while (datatowrite) { + if (datatowrite > 52) datasize = 52; else @@ -1641,7 +1647,7 @@ static int handler_desfire_create_backup_file(mfdes_file_t *file) { return res; } -int getKeySettings(uint8_t *aid) { +static int getKeySettings(uint8_t *aid) { if (aid == NULL) return PM3_EINVARG; int res = 0; @@ -1776,7 +1782,8 @@ static void swap16(uint8_t *data) { static int CmdHF14ADesCreateApp(const char *Cmd) { - CLIParserInit("hf mfdes createaid", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createaid", "Create Application ID", "Usage:\n\thf mfdes createaid -a 123456 -f 1111 -k 0E -l 2E -n Test\n" ); @@ -1790,7 +1797,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { arg_str0("nN", "name", "", "App ISO-4 Name (optional)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); /* KeySetting 1 (AMK Setting): 0: Allow change master key 1: Free Directory list access without master key @@ -1824,17 +1831,17 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { uint8_t aid[3] = {0}; uint8_t fid[2] = {0}; uint8_t name[16] = {0}; - uint8_t keysetting1 = 0; - uint8_t keysetting2 = 0; + uint8_t keysetting1[1] = {0}; + uint8_t keysetting2[1] = {0}; int keylen1 = 1; int keylen2 = 1; int namelen = 16; - CLIGetHexWithReturn(1, aid, &aidlength); - CLIGetHexWithReturn(2, fid, &fidlength); - CLIGetHexWithReturn(3, &keysetting1, &keylen1); - CLIGetHexWithReturn(4, &keysetting2, &keylen2); - CLIGetStrWithReturn(5, name, &namelen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 2, fid, &fidlength); + CLIGetHexWithReturn(ctx, 3, keysetting1, &keylen1); + CLIGetHexWithReturn(ctx, 4, keysetting2, &keylen2); + CLIGetStrWithReturn(ctx, 5, name, &namelen); + CLIParserFree(ctx); swap24(aid); swap16(fid); @@ -1882,8 +1889,8 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { aidhdr_t aidhdr; memcpy(aidhdr.aid, aid, sizeof(aid)); - aidhdr.keysetting1 = keysetting1; - aidhdr.keysetting2 = keysetting2; + aidhdr.keysetting1 = keysetting1[0]; + aidhdr.keysetting2 = keysetting2[0]; if (usefid) memcpy(aidhdr.fid, fid, sizeof(fid)); @@ -1894,7 +1901,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { if (res != PM3_SUCCESS) { DropField(); return res; - } + } res = handler_desfire_createapp(&aidhdr, usename, usefid); DropField(); @@ -1902,7 +1909,8 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { } static int CmdHF14ADesDeleteApp(const char *Cmd) { - CLIParserInit("hf mfdes deleteaid", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes deleteaid", "Delete Application ID", "Usage:\n\t-a aid (3 hex bytes, big endian)\n\n" "Example:\n\thf mfdes deleteaid -a 123456\n" @@ -1913,11 +1921,11 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { arg_strx0("aA", "aid", "", "App ID to delete"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 3; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); + CLIParserFree(ctx); swap24(aid); if (aidlength != 3) { PrintAndLogEx(ERR, "AID must have 3 bytes length."); @@ -1939,7 +1947,8 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { static int CmdHF14ADesClearRecordFile(const char *Cmd) { - CLIParserInit("hf mfdes clearrecord", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes clearrecord", "Clear record file", "Usage:\n\t" "hf mfdes clearrecord -a 123456 -n 01\n" @@ -1951,26 +1960,26 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { arg_strx0("nN", "fileno", "", "File Number (1 hex byte, 0x00 - 0x1F)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIParamHexToBuf(arg_get_str(3), fid, 2, &fidlength); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); + CLIParserFree(ctx); if (filenolen != 1) { PrintAndLogEx(ERR, "Fileno must have 1 bytes length."); return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "Fileno must be lower 0x1F."); return PM3_EINVARG; } @@ -1988,7 +1997,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { return res; } - res = handler_desfire_clearrecordfile(fileno[0]); + res = handler_desfire_clearrecordfile(_fileno[0]); if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Successfully cleared record file."); } else { @@ -1999,7 +2008,8 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { } static int CmdHF14ADesDeleteFile(const char *Cmd) { - CLIParserInit("hf mfdes deletefile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes deletefile", "Delete File", "Usage:\n\t" "hf mfdes deletefile -a 123456 -n 01\n" @@ -2011,26 +2021,26 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { arg_strx0("nN", "fileno", "", "File Number (1 hex byte, 0x00 - 0x1F)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIParamHexToBuf(arg_get_str(3), fid, 2, &fidlength); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); + CLIParserFree(ctx); if (filenolen != 1) { PrintAndLogEx(ERR, "Fileno must have 1 bytes length."); return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "Fileno must be lower 0x1F."); return PM3_EINVARG; } @@ -2048,7 +2058,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { return res; } - res = handler_desfire_deletefile(fileno[0]); + res = handler_desfire_deletefile(_fileno[0]); if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Successfully deleted file.."); } else { @@ -2059,7 +2069,8 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { } static int CmdHF14ADesCreateFile(const char *Cmd) { - CLIParserInit("hf mfdes createfile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createfile", "Create Standard/Backup File", "Usage:" "\n\thf mfdes createfile -a 123456 -f 1111 -n 01 -c 0 -r EEEE -s 000100\n" @@ -2076,30 +2087,30 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { arg_lit0("bB", "backup", "Create backupfile instead of standard file"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIParamHexToBuf(arg_get_str(3), fid, 2, &fidlength); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); - uint8_t comset = arg_get_int(4); + uint8_t comset = arg_get_int(ctx, 4); int arlength = 0; uint8_t ar[2] = {0}; - CLIGetHexWithReturn(5, ar, &arlength); + CLIGetHexWithReturn(ctx, 5, ar, &arlength); int fsizelen = 0; uint8_t filesize[3] = {0}; - CLIGetHexWithReturn(6, filesize, &fsizelen); + CLIGetHexWithReturn(ctx, 6, filesize, &fsizelen); - bool isbackup = arg_get_lit(7); - CLIParserFree(); + bool isbackup = arg_get_lit(ctx, 7); + CLIParserFree(ctx); swap24(aid); swap16(fid); @@ -2110,7 +2121,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)."); return PM3_EINVARG; } @@ -2150,24 +2161,27 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { mfdes_file_t ft; memcpy(ft.fid, fid, 2); memcpy(ft.filesize, filesize, 3); - ft.fileno = fileno[0]; + ft.fileno = _fileno[0]; ft.comset = comset; memcpy(ft.access_rights, ar, 2); - if (isbackup) res = handler_desfire_create_backup_file(&ft); - else res = handler_desfire_create_std_file(&ft); + if (isbackup) + res = handler_desfire_create_backup_file(&ft); + else + res = handler_desfire_create_std_file(&ft); - if (res == PM3_SUCCESS) { + if (res == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "Successfully created standard/backup file."); - } else { + else PrintAndLogEx(ERR, "Couldn't create standard/backup file. Error %d", res); - } + DropField(); return res; } static int CmdHF14ADesGetValueData(const char *Cmd) { - CLIParserInit("hf mfdes getvalue", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes getvalue", "Get value from value file", "Usage:" "\n\thf mfdes getvalue -a 123456 -n 03\n" @@ -2179,23 +2193,23 @@ static int CmdHF14ADesGetValueData(const char *Cmd) { arg_strx0("nN", "fileno", "", "File Number (1 hex byte, 0x00 - 0x1F)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); - CLIParserFree(); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); + CLIParserFree(ctx); if (filenolen != 1) { PrintAndLogEx(ERR, "File number is missing"); return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)"); return PM3_EINVARG; } @@ -2215,12 +2229,12 @@ static int CmdHF14ADesGetValueData(const char *Cmd) { return res; } mfdes_value_t value; - value.fileno = fileno[0]; + value.fileno = _fileno[0]; int len = 0; res = handler_desfire_getvalue(&value, &len); if (res == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Successfully read value from File %u:", fileno[0]); + PrintAndLogEx(SUCCESS, "Successfully read value from File %u:", _fileno[0]); PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii"); PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); for (int i = 0; i < len; i += 16) { @@ -2233,9 +2247,9 @@ static int CmdHF14ADesGetValueData(const char *Cmd) { return res; } - static int CmdHF14ADesReadData(const char *Cmd) { - CLIParserInit("hf mfdes readdata", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes readdata", "Read data from File", "Usage:" "\n\thf mfdes readdata -a 123456 -n 01 -t 0 -o 000000 -l 000000\n" @@ -2250,25 +2264,25 @@ static int CmdHF14ADesReadData(const char *Cmd) { arg_int0("type", "type", "", "File Type (0=Standard/Backup, 1=Record)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int offsetlength = 0; uint8_t offset[3] = {0}; - CLIParamHexToBuf(arg_get_str(3), offset, 3, &offsetlength); + CLIGetHexWithReturn(ctx, 3, offset, &offsetlength); int flength = 0; uint8_t filesize[3] = {0}; - CLIParamHexToBuf(arg_get_str(4), filesize, 3, &flength); + CLIGetHexWithReturn(ctx, 4, filesize, &flength); - int type = arg_get_int(5); - CLIParserFree(); + int type = arg_get_int(ctx, 5); + CLIParserFree(ctx); if (type > 1) { PrintAndLogEx(ERR, "Invalid file type (0=Standard/Backup, 1=Record)"); @@ -2285,7 +2299,7 @@ static int CmdHF14ADesReadData(const char *Cmd) { return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)"); return PM3_EINVARG; } @@ -2310,11 +2324,13 @@ static int CmdHF14ADesReadData(const char *Cmd) { mfdes_data_t ft; memcpy(ft.offset, offset, 3); memcpy(ft.length, filesize, 3); - ft.fileno = fileno[0]; + ft.fileno = _fileno[0]; - int bytestoread = le24toh(filesize); + uint32_t bytestoread = le24toh(filesize); + bytestoread &= 0xFFFFFF; - if (bytestoread == 0) bytestoread = 0xFFFFFF; + if (bytestoread == 0) + bytestoread = 0xFFFFFF; uint8_t *data = (uint8_t *)calloc(bytestoread, sizeof(uint8_t)); if (data != NULL) { @@ -2324,8 +2340,8 @@ static int CmdHF14ADesReadData(const char *Cmd) { PrintAndLogEx(SUCCESS, "Successfully read data from file %d:", ft.fileno); PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii"); PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); - int len = le24toh(ft.length); - for (int i = 0; i < len; i += 16) { + uint32_t len = le24toh(ft.length); + for (uint32_t i = 0; i < len; i += 16) { PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", i, i, sprint_hex(&ft.data[i], len > 16 ? 16 : len), sprint_ascii(&ft.data[i], len > 16 ? 16 : len)); } } else { @@ -2338,7 +2354,8 @@ static int CmdHF14ADesReadData(const char *Cmd) { } static int CmdHF14ADesChangeValue(const char *Cmd) { - CLIParserInit("hf mfdes changevalue", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes changevalue", "Change value (credit/limitedcredit/debit)", "Usage:" "\n\thf mfdes changevalue -a 123456 -n 03 -m 0 -d 00000001\n" @@ -2354,22 +2371,22 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { }; mfdes_value_t value; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); - value.fileno = fileno[0]; + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); + value.fileno = _fileno[0]; int vlength = 0x0; - CLIParamHexToBuf(arg_get_str(3), value.value, 4, &vlength); + CLIGetHexWithReturn(ctx, 3, value.value, &vlength); - int mode = arg_get_int(4); - CLIParserFree(); + int mode = arg_get_int(ctx, 4); + CLIParserFree(ctx); swap24(aid); if (mode > 2) { @@ -2430,7 +2447,8 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { static int CmdHF14ADesWriteData(const char *Cmd) { - CLIParserInit("hf mfdes writedata", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes writedata", "Write data to File", "Usage:" "\n\thf mfdes writedata -a 123456 -n 01 -t 0 -o 000000 -d 3132333435363738\n" @@ -2446,31 +2464,36 @@ static int CmdHF14ADesWriteData(const char *Cmd) { arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int offsetlength = 0; uint8_t offset[3] = {0}; - CLIParamHexToBuf(arg_get_str(3), offset, 3, &offsetlength); + CLIGetHexWithReturn(ctx, 3, offset, &offsetlength); int dlength = 0xFFFF; - uint8_t *data = (uint8_t *)calloc(0xFFFF, sizeof(uint8_t)); + uint8_t *data = (uint8_t *)calloc(dlength, sizeof(uint8_t)); if (data == NULL) { PrintAndLogEx(ERR, "failed to allocate memory"); + CLIParserFree(ctx); return PM3_EMALLOC; } - CLIParamHexToBuf(arg_get_str(4), data, 0xFFFF, &dlength); + if (CLIParamHexToBuf(arg_get_str(ctx, 4), data, dlength, &dlength)) { + free(data); + CLIParserFree(ctx); + return PM3_ESOFT; + } - int type = arg_get_int(5); + int type = arg_get_int(ctx, 5); - CLIParserFree(); + CLIParserFree(ctx); swap24(aid); swap24(offset); @@ -2499,7 +2522,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)"); if (data) free(data); return PM3_EINVARG; @@ -2524,7 +2547,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { memcpy(ft.offset, offset, 3); htole24(dlength, ft.length); - ft.fileno = fileno[0]; + ft.fileno = _fileno[0]; if (data != NULL) { ft.data = data; @@ -2542,7 +2565,8 @@ static int CmdHF14ADesWriteData(const char *Cmd) { static int CmdHF14ADesCreateRecordFile(const char *Cmd) { - CLIParserInit("hf mfdes createrecordfile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createrecordfile", "Create Linear/Cyclic Record File", "Usage:" "\n\thf mfdes createrecordfile -a 123456 -f 1122 -n 02 -c 0 -r EEEE -s 000010 -m 000005\n" @@ -2560,34 +2584,34 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { arg_lit0("bB", "cyclic", "Create cyclic record file instead of linear record file"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIParamHexToBuf(arg_get_str(3), fid, 2, &fidlength); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); - uint8_t comset = arg_get_int(4); + uint8_t comset = arg_get_int(ctx, 4); int arlength = 0; uint8_t ar[2] = {0}; - CLIGetHexWithReturn(5, ar, &arlength); + CLIGetHexWithReturn(ctx, 5, ar, &arlength); int rsizelen = 0; uint8_t recordsize[3] = {0}; - CLIGetHexWithReturn(6, recordsize, &rsizelen); + CLIGetHexWithReturn(ctx, 6, recordsize, &rsizelen); int msizelen = 0; uint8_t maxnumrecords[3] = {0}; - CLIGetHexWithReturn(7, maxnumrecords, &msizelen); + CLIGetHexWithReturn(ctx, 7, maxnumrecords, &msizelen); - bool cyclic = arg_get_lit(8); - CLIParserFree(); + bool cyclic = arg_get_lit(ctx, 8); + CLIParserFree(ctx); swap24(aid); swap16(fid); @@ -2609,7 +2633,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)."); return PM3_EINVARG; } @@ -2648,15 +2672,20 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { } mfdes_linear_t ft; - ft.fileno = fileno[0]; + + ft.fileno = _fileno[0]; memcpy(ft.fid, fid, 2); ft.comset = comset; memcpy(ft.access_rights, ar, 2); memcpy(ft.recordsize, recordsize, 3); memcpy(ft.maxnumrecords, maxnumrecords, 3); - if (cyclic) res = handler_desfire_create_cyclicrecordfile(&ft); - else res = handler_desfire_create_linearrecordfile(&ft); + if (cyclic) { + res = handler_desfire_create_cyclicrecordfile(&ft); + } else { + res = handler_desfire_create_linearrecordfile(&ft); + } + if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Successfully created linear/cyclic record file."); } else { @@ -2667,7 +2696,8 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { } static int CmdHF14ADesCreateValueFile(const char *Cmd) { - CLIParserInit("hf mfdes createvaluefile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createvaluefile", "Create Value File", "Usage:" "\n\thf mfdes createvaluefile -a 123456 -n 03 -c 0 -r EEEE -l 00000000 -u 00002000 -v 00000001 -m 02\n" @@ -2685,37 +2715,37 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { arg_strx0("mM", "limitcredit", "", "Limited Credit enabled (1 hex byte [Bit 0=LimitedCredit, 1=FreeValue])"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; - uint8_t fileno[1] = {0}; - CLIGetHexWithReturn(2, fileno, &filenolen); + uint8_t _fileno[1] = {0}; + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); - uint8_t comset = arg_get_int(3); + uint8_t comset = arg_get_int(ctx, 3); int arlength = 0; uint8_t ar[2] = {0}; - CLIGetHexWithReturn(4, ar, &arlength); + CLIGetHexWithReturn(ctx, 4, ar, &arlength); int lllen = 0; uint8_t lowerlimit[4] = {0}; - CLIGetHexWithReturn(5, lowerlimit, &lllen); + CLIGetHexWithReturn(ctx, 5, lowerlimit, &lllen); int ullen = 0; uint8_t upperlimit[4] = {0}; - CLIGetHexWithReturn(6, upperlimit, &ullen); + CLIGetHexWithReturn(ctx, 6, upperlimit, &ullen); int vllen = 0; uint8_t value[4] = {0}; - CLIGetHexWithReturn(7, value, &vllen); + CLIGetHexWithReturn(ctx, 7, value, &vllen); int limitedlen = 0; uint8_t limited[1] = {0}; - CLIGetHexWithReturn(8, limited, &limitedlen); + CLIGetHexWithReturn(ctx, 8, limited, &limitedlen); - CLIParserFree(); + CLIParserFree(ctx); swap24(aid); swap32(lowerlimit); @@ -2727,7 +2757,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { return PM3_EINVARG; } - if (fileno[0] > 0x1F) { + if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)"); return PM3_EINVARG; } @@ -2775,7 +2805,8 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { } mfdes_value_file_t ft; - ft.fileno = fileno[0]; + + ft.fileno = _fileno[0]; ft.comset = comset; memcpy(ft.access_rights, ar, 2); memcpy(ft.lowerlimit, lowerlimit, 4); @@ -2794,7 +2825,8 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { } static int CmdHF14ADesFormatPICC(const char *Cmd) { - CLIParserInit("hf mfdes formatpicc", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes formatpicc", "Formats MIFARE DESFire PICC to factory state", "Usage:\n\t-k PICC key (8 bytes)\n\n" "Example:\n\thf mfdes formatpicc -k 0000000000000000\n" @@ -2805,12 +2837,12 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) { arg_str0("kK", "key", "", "Key for checking (HEX 16 bytes)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); uint8_t key[8] = {0}; int keylen = 8; - CLIGetHexWithReturn(1, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, key, &keylen); + CLIParserFree(ctx); if ((keylen < 8) || (keylen > 8)) { PrintAndLogEx(ERR, "Specified key must have 8 bytes length"); @@ -2954,7 +2986,7 @@ static int CmdHF14ADesInfo(const char *Cmd) { if (major == 1 && minor == 3) PrintAndLogEx(INFO, "\t1.3 - DESFire Ev1 MF3ICD21/41/81, Support extended APDU commands, EAL4+"); if (major == 1 && minor == 4) - PrintAndLogEx(INFO, "\t1.4 - DESFire Ev1 MF3ICD21/41/81, EAL4+, N/A (report to iceman!)"); + PrintAndLogEx(INFO, "\t1.4 - DESFire Ev1 MF3ICD21/41/81, EAL4+"); if (major == 2 && minor == 0) PrintAndLogEx(INFO, "\t2.0 - DESFire Ev2, Originality check, proximity check, EAL5"); // if (major == 3 && minor == 0) @@ -3081,13 +3113,25 @@ static void DecodeAccessRights(uint16_t accrights) { if (car == NULL) return; char *rwa = DecodeAccessValue(read_write_access); - if (rwa == NULL) return; + if (rwa == NULL) { + free(car); + return; + } char *wa = DecodeAccessValue(write_access); - if (wa == NULL) return; + if (wa == NULL) { + free(car); + free(rwa); + return; + } char *ra = DecodeAccessValue(read_access); - if (ra == NULL) return; + if (ra == NULL) { + free(car); + free(rwa); + free(wa); + return; + } PrintAndLogEx(INFO, " Access Rights: 0x%04X - Change %s - RW %s - W %s - R %s", accrights, car, rwa, wa, ra); free(car); @@ -3134,6 +3178,7 @@ static int DecodeFileSettings(uint8_t *src, int src_len, int maclen) { static int CmdHF14ADesDump(const char *Cmd) { (void)Cmd; // Cmd is not used so far DropField(); + uint8_t aid[3] = {0}; uint8_t app_ids[78] = {0}; uint8_t app_ids_len = 0; @@ -3154,8 +3199,6 @@ static int CmdHF14ADesDump(const char *Cmd) { if (handler_desfire_dfnames(dfnames, &dfname_count) != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_("Can't get DF Names")); - DropField(); - return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); @@ -3180,106 +3223,120 @@ static int CmdHF14ADesDump(const char *Cmd) { uint8_t num_keys = 0; uint8_t key_setting = 0; res = handler_desfire_keysettings(&key_setting, &num_keys); - if (res != PM3_SUCCESS) return res; + if (res != PM3_SUCCESS) continue; res = handler_desfire_select_application(aid); + if (res != PM3_SUCCESS) continue; - if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) { - for (int j = file_ids_len - 1; j >= 0; j--) { - PrintAndLogEx(SUCCESS, "\n\n Fileid %d (0x%02x)", file_ids[j], file_ids[j]); + res = handler_desfire_fileids(file_ids, &file_ids_len); + if (res != PM3_SUCCESS) continue; - uint8_t filesettings[20] = {0}; - int fileset_len = 0; + for (int j = file_ids_len - 1; j >= 0; j--) { + PrintAndLogEx(SUCCESS, "\n\n Fileid %d (0x%02x)", file_ids[j], file_ids[j]); - res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len); - int maclen = 0; // To be implemented + uint8_t filesettings[20] = {0}; + int fileset_len = 0; + res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len); + if (res != PM3_SUCCESS) continue; + + int maclen = 0; // To be implemented + + if (fileset_len == 1 + 1 + 2 + 3 + maclen) { + int filesize = (filesettings[6] << 16) + (filesettings[5] << 8) + filesettings[4]; + mfdes_data_t fdata; + fdata.fileno = file_ids[j]; + memset(fdata.offset, 0, 3); + memset(fdata.length, 0, 3); + + uint8_t *data = (uint8_t *)calloc(filesize, sizeof(uint8_t)); + if (data == NULL) { + DropField(); + return PM3_EMALLOC; + } + + fdata.data = data; + res = handler_desfire_readdata(&fdata, MFDES_DATA_FILE); if (res == PM3_SUCCESS) { - //if (DecodeFileSettings(filesettings, fileset_len, maclen) != PM3_SUCCESS) { - if (fileset_len == 1 + 1 + 2 + 3 + maclen) { - int filesize = (filesettings[6] << 16) + (filesettings[5] << 8) + filesettings[4]; - mfdes_data_t fdata; - fdata.fileno = file_ids[j]; - memset(fdata.offset, 0, 3); - //memcpy(fdata.length,&filesettings[4],3); - memset(fdata.length, 0, 3); - uint8_t *data = (uint8_t *)malloc(filesize); - fdata.data = data; - if (data) { - res = handler_desfire_readdata(&fdata, MFDES_DATA_FILE); - if (res == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii"); - PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); - int len = le24toh(fdata.length); - for (int n = 0; n < len; n += 16) { - PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", n, n, sprint_hex(&fdata.data[n], len > 16 ? 16 : len), sprint_ascii(&fdata.data[n], len > 16 ? 16 : len)); - } - free(data); - } else { - PrintAndLogEx(ERR, "Couldn't read value. Error %d", res); - res = handler_desfire_select_application(aid); - } - } - } else if (fileset_len == 1 + 1 + 2 + 4 + 4 + 4 + 1 + maclen) { - PrintAndLogEx(NORMAL, "\n\nValue file: 0x%0x", file_ids[j]); - mfdes_value_t value; - value.fileno = file_ids[j]; - int len = 0; - res = handler_desfire_getvalue(&value, &len); - if (res == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, "\nOffset | Value | Ascii"); - PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); - for (int n = 0; n < len; n += 16) { - PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", n, n, sprint_hex(&value.value[n], len > 16 ? 16 : len), sprint_ascii(&value.value[n], len > 16 ? 16 : len)); - } - } else { - PrintAndLogEx(ERR, "Couldn't read value. Error %d", res); - res = handler_desfire_select_application(aid); - } - } else if (fileset_len == 1 + 1 + 2 + 3 + 3 + 3 + maclen) { - int maxrecords = (filesettings[9] << 16) + (filesettings[8] << 8) + filesettings[7]; - int filesize = (filesettings[6] << 16) + (filesettings[5] << 8) + filesettings[4]; - mfdes_data_t fdata; - fdata.fileno = file_ids[j]; - memset(fdata.length, 0, 3); - //memcpy(fdata.length,&filesettings[4],3); - uint8_t *data = (uint8_t *)malloc(filesize); - fdata.data = data; - if (data) { - for (int offset = 0; offset < maxrecords; offset++) { - PrintAndLogEx(NORMAL, "\n\nRecord offset: %024x", offset); - memset(data, 0, filesize); - fdata.offset[0] = offset & 0xFF; - fdata.offset[1] = (offset >> 8) & 0xFF; - fdata.offset[2] = (offset >> 16) & 0xFF; - res = handler_desfire_readdata(&fdata, MFDES_RECORD_FILE); - if (res == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii"); - PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); - int len = le24toh(fdata.length); - for (int n = 0; n < len; n += 16) { - PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", n, n, sprint_hex(&fdata.data[n], len > 16 ? 16 : len), sprint_ascii(&fdata.data[n], len > 16 ? 16 : len)); - } - } else { - res = handler_desfire_select_application(aid); - } - } - free(data); + PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii"); + PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); + uint32_t len = le24toh(fdata.length); + for (uint32_t n = 0; n < len; n += 16) { + PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", n, n, sprint_hex(&fdata.data[n], len > 16 ? 16 : len), sprint_ascii(&fdata.data[n], len > 16 ? 16 : len)); + } + } else { + PrintAndLogEx(ERR, "Couldn't read value. Error %d", res); + res = handler_desfire_select_application(aid); + if (res != PM3_SUCCESS) continue; + } + + free(data); + + } else if (fileset_len == 1 + 1 + 2 + 4 + 4 + 4 + 1 + maclen) { + PrintAndLogEx(NORMAL, "\n\nValue file: 0x%0x", file_ids[j]); + mfdes_value_t value; + value.fileno = file_ids[j]; + int len = 0; + res = handler_desfire_getvalue(&value, &len); + if (res == PM3_SUCCESS) { + PrintAndLogEx(NORMAL, "\nOffset | Value | Ascii"); + PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); + for (int n = 0; n < len; n += 16) { + PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", n, n, sprint_hex(&value.value[n], len > 16 ? 16 : len), sprint_ascii(&value.value[n], len > 16 ? 16 : len)); + } + } else { + PrintAndLogEx(ERR, "Couldn't read value. Error %d", res); + res = handler_desfire_select_application(aid); + if (res != PM3_SUCCESS) continue; + } + + } else if (fileset_len == 1 + 1 + 2 + 3 + 3 + 3 + maclen) { + int maxrecords = (filesettings[9] << 16) + (filesettings[8] << 8) + filesettings[7]; + int filesize = (filesettings[6] << 16) + (filesettings[5] << 8) + filesettings[4]; + mfdes_data_t fdata; + fdata.fileno = file_ids[j]; + memset(fdata.length, 0, 3); + uint8_t *data = (uint8_t *)calloc(filesize, sizeof(uint8_t)); + if (data == NULL) { + DropField(); + return PM3_EMALLOC; + } + + fdata.data = data; + for (int offset = 0; offset < maxrecords; offset++) { + PrintAndLogEx(NORMAL, "\n\nRecord offset: %024x", offset); + memset(data, 0, filesize); + fdata.offset[0] = offset & 0xFF; + fdata.offset[1] = (offset >> 8) & 0xFF; + fdata.offset[2] = (offset >> 16) & 0xFF; + res = handler_desfire_readdata(&fdata, MFDES_RECORD_FILE); + if (res == PM3_SUCCESS) { + PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii"); + PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------"); + uint32_t len = le24toh(fdata.length); + for (uint32_t n = 0; n < len; n += 16) { + PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", n, n, sprint_hex(&fdata.data[n], len > 16 ? 16 : len), sprint_ascii(&fdata.data[n], len > 16 ? 16 : len)); } + } else { + res = handler_desfire_select_application(aid); + if (res != PM3_SUCCESS) continue; } } + free(data); } } } + PrintAndLogEx(INFO, "-------------------------------------------------------------"); DropField(); return PM3_SUCCESS; } static int CmdHF14ADesEnumApplications(const char *Cmd) { + (void)Cmd; // Cmd is not used so far DropField(); -// uint8_t isOK = 0x00; + uint8_t aid[3] = {0}; uint8_t app_ids[78] = {0}; uint8_t app_ids_len = 0; @@ -3290,8 +3347,6 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { dfname_t dfnames[255]; uint8_t dfname_count = 0; - int res = 0; - if (handler_desfire_appids(app_ids, &app_ids_len) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Can't get list of applications on tag"); DropField(); @@ -3300,8 +3355,6 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { if (handler_desfire_dfnames(dfnames, &dfname_count) != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_("Can't get DF Names")); - DropField(); - return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); @@ -3333,53 +3386,31 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { } } - res = getKeySettings(aid); - if (res != PM3_SUCCESS) return res; + int res = getKeySettings(aid); + if (res != PM3_SUCCESS) continue; res = handler_desfire_select_application(aid); + if (res != PM3_SUCCESS) continue; + res = handler_desfire_fileids(file_ids, &file_ids_len); + if (res != PM3_SUCCESS) continue; - // Get File IDs - if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") " file%c", file_ids_len, (file_ids_len == 1) ? ' ' : 's'); - for (int j = file_ids_len - 1; j >= 0; j--) { - PrintAndLogEx(SUCCESS, " Fileid %d (0x%02x)", file_ids[j], file_ids[j]); + PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") " file%c", file_ids_len, (file_ids_len == 1) ? ' ' : 's'); + for (int j = file_ids_len - 1; j >= 0; j--) { + PrintAndLogEx(SUCCESS, " Fileid %d (0x%02x)", file_ids[j], file_ids[j]); - uint8_t filesettings[20] = {0}; - int fileset_len = 0; - int maclen = 0; // To be implemented + uint8_t filesettings[20] = {0}; + int fileset_len = 0; + int maclen = 0; // To be implemented - res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len); - if (res == PM3_SUCCESS) { - if (DecodeFileSettings(filesettings, fileset_len, maclen) != PM3_SUCCESS) { - PrintAndLogEx(INFO, " Settings [%u] %s", fileset_len, sprint_hex(filesettings, fileset_len)); - } - } + res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len); + if (res != PM3_SUCCESS) continue; + + if (DecodeFileSettings(filesettings, fileset_len, maclen) != PM3_SUCCESS) { + PrintAndLogEx(INFO, " Settings [%u] %s", fileset_len, sprint_hex(filesettings, fileset_len)); } } - /* - // Get ISO File IDs - { - uint8_t data[] = {GET_ISOFILE_IDS, 0x00, 0x00, 0x00}; // 0x61 - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data)); - } - - if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) { - PrintAndLogEx(WARNING, _RED_(" Timed-out")); - continue; - } else { - isOK = respFiles.data.asBytes[2] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, _RED_(" Can't get ISO file ids")); - } else { - int respfileLen = resp.oldarg[1] - 3 - 2; - for (int j = 0; j < respfileLen; ++j) { - PrintAndLogEx(SUCCESS, " ISO Fileid %d :", resp.data.asBytes[j + 3]); - } - } - } - */ } PrintAndLogEx(INFO, "-------------------------------------------------------------"); DropField(); @@ -3401,7 +3432,8 @@ static int CmdHF14ADesAuth(const char *Cmd) { uint8_t keylength = 8; bool usedefaultkey = false; - CLIParserInit("hf mfdes auth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes auth", "Authenticates Mifare DESFire using Key", "Usage:" "\n\thf mfdes auth -m 3 -t 4 -a 808301 -n 0 -k 00000000000000000000000000000000 (AES)" @@ -3418,21 +3450,21 @@ static int CmdHF14ADesAuth(const char *Cmd) { arg_str0("kK", "key", "", "Key for checking (HEX 8-24 bytes)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - uint8_t cmdAuthMode = arg_get_int_def(1, 0); - uint8_t cmdAuthAlgo = arg_get_int_def(2, 0); + uint8_t cmdAuthMode = arg_get_int_def(ctx, 1, 0); + uint8_t cmdAuthAlgo = arg_get_int_def(ctx, 2, 0); int aidlength = 3; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(3, aid, &aidlength); + CLIGetHexWithReturn(ctx, 3, aid, &aidlength); swap24(aid); - uint8_t cmdKeyNo = arg_get_int_def(4, 0); + uint8_t cmdKeyNo = arg_get_int_def(ctx, 4, 0); uint8_t key[24] = {0}; int keylen = 0; - CLIParamHexToBuf(arg_get_str(5), key, 24, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 5, key, &keylen); + CLIParserFree(ctx); if (keylen == 0) { usedefaultkey = true; @@ -3544,7 +3576,11 @@ static int CmdHF14ADesAuth(const char *Cmd) { return PM3_SUCCESS; } -void DesFill2bPattern(uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t *deskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], size_t *aeskeyListLen, uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], size_t *k3kkeyListLen, uint32_t *startPattern) { +static void DesFill2bPattern( + uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], uint32_t *deskeyListLen, + uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], uint32_t *aeskeyListLen, + uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], uint32_t *k3kkeyListLen, uint32_t *startPattern) { + for (uint32_t pt = *startPattern; pt < 0x10000; pt++) { if (*deskeyListLen != MAX_KEYS_LIST_LEN) { deskeyList[*deskeyListLen][0] = (pt >> 8) & 0xff; @@ -3572,16 +3608,26 @@ void DesFill2bPattern(uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t *deskeyLi } *startPattern = pt; - if ((*deskeyListLen == MAX_KEYS_LIST_LEN) && (*aeskeyListLen == MAX_KEYS_LIST_LEN) && (*k3kkeyListLen == MAX_KEYS_LIST_LEN)) + if ((*deskeyListLen == MAX_KEYS_LIST_LEN) && + (*aeskeyListLen == MAX_KEYS_LIST_LEN) && + (*k3kkeyListLen == MAX_KEYS_LIST_LEN)) { break; + } } (*startPattern)++; } -static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t deskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], size_t aeskeyListLen, uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], size_t k3kkeyListLen, uint8_t foundKeys[4][0xE][24 + 1], bool *result) { +static int AuthCheckDesfire(uint8_t *aid, + uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], uint32_t deskeyListLen, + uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], uint32_t aeskeyListLen, + uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], uint32_t k3kkeyListLen, + uint8_t foundKeys[4][0xE][24 + 1], bool *result) { + + uint32_t curaid = (aid[0] & 0xFF) + ((aid[1] & 0xFF) << 8) + ((aid[2] & 0xFF) << 16); + int res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "AID %X does not exist."); + PrintAndLogEx(ERR, "AID 0x%06X does not exist.", curaid); return res; } @@ -3596,24 +3642,31 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ uint8_t file_ids_len = 0; // Get File IDs if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) { + for (int j = file_ids_len - 1; j >= 0; j--) { + uint8_t filesettings[20] = {0}; int fileset_len = 0; + res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len); if (res == PM3_SUCCESS) { + uint16_t accrights = (filesettings[3] << 8) + filesettings[2]; int change_access_rights = accrights & 0xF; int read_write_access = (accrights >> 4) & 0xF; int write_access = (accrights >> 8) & 0xF; int read_access = (accrights >> 12) & 0xF; + if (change_access_rights == 0xE) change_access_rights = 0x0; if (read_write_access == 0xE) read_write_access = 0x0; if (write_access == 0xE) write_access = 0x0; if (read_access == 0xE) read_access = 0x0; + usedkeys[change_access_rights] = 1; usedkeys[read_write_access] = 1; usedkeys[write_access] = 1; usedkeys[read_access] = 1; + if (res == PM3_SUCCESS) { switch (fileset_len >> 6) { case 0: @@ -3632,6 +3685,7 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ } } } + if (file_ids_len == 0) { for (int z = 0; z < 0xE; z++) { usedkeys[z] = 1; @@ -3642,24 +3696,33 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ } } } - } else des = true; + } else { + des = true; + } + int error = PM3_SUCCESS; bool badlen = false; + mfdes_authinput_t payload; - uint32_t curaid = (aid[0] & 0xFF) + ((aid[1] & 0xFF) << 8) + ((aid[2] & 0xFF) << 16); + mfdes_auth_res_t payload_res; + if (des) { - for (int keyno = 0; keyno < 0xE; keyno++) + + for (uint8_t keyno = 0; keyno < 0xE; keyno++) { + if (usedkeys[keyno] == 1 && foundKeys[0][keyno][0] == 0) { - for (int curkey = 0; curkey < deskeyListLen; curkey++) { + + for (uint32_t curkey = 0; curkey < deskeyListLen; curkey++) { + payload.keylen = 8; memcpy(payload.key, deskeyList[curkey], 8); payload.mode = MFDES_AUTH_DES; payload.algo = MFDES_ALGO_DES; payload.keyno = keyno; - mfdes_auth_res_t rpayload; - error = handler_desfire_auth(&payload, &rpayload, false); + + error = handler_desfire_auth(&payload, &payload_res, false); if (error == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "AID 0x%06X, Found DES Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(deskeyList[curkey], 8)); + PrintAndLogEx(SUCCESS, "AID 0x%06X, Found DES Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(deskeyList[curkey], 8)); foundKeys[0][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[0][keyno][1], deskeyList[curkey], 8); @@ -3669,7 +3732,6 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ DropField(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "AID 0x%06X does not exist", curaid); return res; } break; @@ -3680,20 +3742,26 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ break; } } + } } + if (tdes) { - for (int keyno = 0; keyno < 0xE; keyno++) + + for (uint8_t keyno = 0; keyno < 0xE; keyno++) { + if (usedkeys[keyno] == 1 && foundKeys[1][keyno][0] == 0) { - for (int curkey = 0; curkey < aeskeyListLen; curkey++) { + + for (uint32_t curkey = 0; curkey < aeskeyListLen; curkey++) { + payload.keylen = 16; memcpy(payload.key, aeskeyList[curkey], 16); payload.mode = MFDES_AUTH_DES; payload.algo = MFDES_ALGO_3DES; payload.keyno = keyno; - mfdes_auth_res_t rpayload; - error = handler_desfire_auth(&payload, &rpayload, false); + + error = handler_desfire_auth(&payload, &payload_res, false); if (error == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3DES Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16)); + PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3DES Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16)); foundKeys[1][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[1][keyno][1], aeskeyList[curkey], 16); @@ -3703,7 +3771,6 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ DropField(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "AID %X does not exist."); return res; } break; @@ -3714,21 +3781,26 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ break; } } + } } if (aes) { - for (int keyno = 0; keyno < 0xE; keyno++) + + for (uint8_t keyno = 0; keyno < 0xE; keyno++) { + if (usedkeys[keyno] == 1 && foundKeys[2][keyno][0] == 0) { - for (int curkey = 0; curkey < aeskeyListLen; curkey++) { + + for (uint32_t curkey = 0; curkey < aeskeyListLen; curkey++) { + payload.keylen = 16; memcpy(payload.key, aeskeyList[curkey], 16); payload.mode = MFDES_AUTH_AES; payload.algo = MFDES_ALGO_AES; payload.keyno = keyno; - mfdes_auth_res_t rpayload; - error = handler_desfire_auth(&payload, &rpayload, false); + + error = handler_desfire_auth(&payload, &payload_res, false); if (error == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16)); + PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16)); foundKeys[2][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[2][keyno][1], aeskeyList[curkey], 16); @@ -3738,7 +3810,6 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ DropField(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "AID %X does not exist."); return res; } break; @@ -3749,21 +3820,25 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ break; } } + } } if (k3kdes) { - for (int keyno = 0; keyno < 0xE; keyno++) + + for (uint8_t keyno = 0; keyno < 0xE; keyno++) { + if (usedkeys[keyno] == 1 && foundKeys[3][keyno][0] == 0) { - for (int curkey = 0; curkey < k3kkeyListLen; curkey++) { + + for (uint32_t curkey = 0; curkey < k3kkeyListLen; curkey++) { payload.keylen = 24; memcpy(payload.key, k3kkeyList[curkey], 24); payload.mode = MFDES_AUTH_ISO; payload.algo = MFDES_ALGO_3K3DES; payload.keyno = keyno; - mfdes_auth_res_t rpayload; - error = handler_desfire_auth(&payload, &rpayload, false); + + error = handler_desfire_auth(&payload, &payload_res, false); if (error == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3K3 Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(k3kkeyList[curkey], 24)); + PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3K3 Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(k3kkeyList[curkey], 24)); foundKeys[3][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[3][keyno][1], k3kkeyList[curkey], 16); @@ -3773,17 +3848,17 @@ static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][ DropField(); res = handler_desfire_select_application(aid); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "AID %X does not exist."); return res; } break; } } + if (badlen == true) { - badlen = false; break; } } + } } DropField(); return PM3_SUCCESS; @@ -3794,12 +3869,13 @@ static int CmdHF14aDesChk(const char *Cmd) { uint8_t deskeyList[MAX_KEYS_LIST_LEN][8] = {{0}}; uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16] = {{0}}; uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][MAX_KEY_LEN] = {{0}}; - size_t deskeyListLen = 0; - size_t aeskeyListLen = 0; - size_t k3kkeyListLen = 0; + uint32_t deskeyListLen = 0; + uint32_t aeskeyListLen = 0; + uint32_t k3kkeyListLen = 0; uint8_t foundKeys[4][0xE][24 + 1] = {{{0}}}; - CLIParserInit("hf mfdes chk", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes chk", "Checks keys with Mifare Desfire card.", "Usage:\n" " hf mfdes chk -a 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n" @@ -3820,15 +3896,15 @@ static int CmdHF14aDesChk(const char *Cmd) { arg_lit0("vV", "verbose", "Verbose mode."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); swap24(aid); uint8_t vkey[16] = {0}; int vkeylen = 0; - CLIGetHexWithReturn(2, vkey, &vkeylen); + CLIGetHexWithReturn(ctx, 2, vkey, &vkeylen); if (vkeylen > 0) { if (vkeylen == 8) { @@ -3842,44 +3918,44 @@ static int CmdHF14aDesChk(const char *Cmd) { k3kkeyListLen++; } else { PrintAndLogEx(ERR, "Specified key must have 8, 16 or 24 bytes length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } } uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0}; int dict_filenamelen = 0; - if (CLIParamStrToBuf(arg_get_str(3), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { + if (CLIParamStrToBuf(arg_get_str(ctx, 3), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { PrintAndLogEx(FAILED, "File name too long or invalid."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } - bool pattern1b = arg_get_lit(4); - bool pattern2b = arg_get_lit(5); + bool pattern1b = arg_get_lit(ctx, 4); + bool pattern2b = arg_get_lit(ctx, 5); if (pattern1b && pattern2b) { PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (dict_filenamelen && (pattern1b || pattern2b)) { PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } uint32_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; - CLIGetHexWithReturn(6, vpattern, &vpatternlen); + CLIGetHexWithReturn(ctx, 6, vpattern, &vpatternlen); if (vpatternlen > 0) { if (vpatternlen > 0 && vpatternlen <= 2) { startPattern = (vpattern[0] << 8) + vpattern[1]; } else { PrintAndLogEx(ERR, "Pattern must be 2-byte length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (!pattern2b) @@ -3888,16 +3964,16 @@ static int CmdHF14aDesChk(const char *Cmd) { uint8_t jsonname[250] = {0}; int jsonnamelen = 0; - if (CLIParamStrToBuf(arg_get_str(7), jsonname, sizeof(jsonname), &jsonnamelen)) { + if (CLIParamStrToBuf(arg_get_str(ctx, 7), jsonname, sizeof(jsonname), &jsonnamelen)) { PrintAndLogEx(ERR, "Invalid json name."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } jsonname[jsonnamelen] = 0; - bool verbose = arg_get_lit(8); + bool verbose = arg_get_lit(ctx, 8); - CLIParserFree(); + CLIParserFree(ctx); // 1-byte pattern search mode if (pattern1b) { @@ -3920,46 +3996,43 @@ static int CmdHF14aDesChk(const char *Cmd) { // dictionary mode size_t endFilePosition = 0; if (dict_filenamelen) { - uint16_t keycnt = 0; - res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 8, &keycnt, 0, &endFilePosition, true); - deskeyListLen = keycnt; - if (endFilePosition) - PrintAndLogEx(SUCCESS, "First part of des dictionary successfully loaded."); - endFilePosition = 0; - res = loadFileDICTIONARYEx((char *)dict_filename, aeskeyList, sizeof(aeskeyList), NULL, 16, &keycnt, 0, &endFilePosition, true); - aeskeyListLen = keycnt; - if (endFilePosition) - PrintAndLogEx(SUCCESS, "First part of aes dictionary successfully loaded."); - endFilePosition = 0; - res = loadFileDICTIONARYEx((char *)dict_filename, k3kkeyList, sizeof(k3kkeyList), NULL, 24, &keycnt, 0, &endFilePosition, true); - k3kkeyListLen = keycnt; - if (endFilePosition) - PrintAndLogEx(SUCCESS, "First part of k3kdes dictionary successfully loaded."); - endFilePosition = 0; - if (endFilePosition) - PrintAndLogEx(SUCCESS, "First part of dictionary successfully loaded."); + res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 8, &deskeyListLen, 0, &endFilePosition, true); + if (res == PM3_SUCCESS && endFilePosition) + PrintAndLogEx(SUCCESS, "First part of des dictionary successfully loaded."); + + endFilePosition = 0; + res = loadFileDICTIONARYEx((char *)dict_filename, aeskeyList, sizeof(aeskeyList), NULL, 16, &aeskeyListLen, 0, &endFilePosition, true); + if (res == PM3_SUCCESS && endFilePosition) + PrintAndLogEx(SUCCESS, "First part of aes dictionary successfully loaded."); + + endFilePosition = 0; + res = loadFileDICTIONARYEx((char *)dict_filename, k3kkeyList, sizeof(k3kkeyList), NULL, 24, &k3kkeyListLen, 0, &endFilePosition, true); + if (res == PM3_SUCCESS && endFilePosition) + PrintAndLogEx(SUCCESS, "First part of k3kdes dictionary successfully loaded."); + + endFilePosition = 0; } if (aeskeyListLen == 0) { PrintAndLogEx(ERR, "Aes key list is empty. Nothing to check."); return PM3_EINVARG; } else { - PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " aes keys", aeskeyListLen); + PrintAndLogEx(INFO, "Loaded " _YELLOW_("%"PRIu32) " aes keys", aeskeyListLen); } if (deskeyListLen == 0) { PrintAndLogEx(ERR, "Des key list is empty. Nothing to check."); return PM3_EINVARG; } else { - PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " des keys", deskeyListLen); + PrintAndLogEx(INFO, "Loaded " _YELLOW_("%"PRIu32) " des keys", deskeyListLen); } if (k3kkeyListLen == 0) { PrintAndLogEx(ERR, "K3k key list is empty. Nothing to check."); return PM3_EINVARG; } else { - PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " k3kdes keys", k3kkeyListLen); + PrintAndLogEx(INFO, "Loaded " _YELLOW_("%"PRIu32) " k3kdes keys", k3kkeyListLen); } if (!verbose) @@ -4000,15 +4073,22 @@ static int CmdHF14aDesChk(const char *Cmd) { if (dict_filenamelen && endFilePosition) { if (!verbose) printf("d"); - uint16_t keycnt = 0; + + uint32_t keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false); - deskeyListLen = keycnt; + if (res == PM3_SUCCESS && endFilePosition) + deskeyListLen = keycnt; + keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, aeskeyList, sizeof(aeskeyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false); - aeskeyListLen = keycnt; + if (res == PM3_SUCCESS && endFilePosition) + aeskeyListLen = keycnt; + keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, k3kkeyList, sizeof(k3kkeyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false); - k3kkeyListLen = keycnt; + if (res == PM3_SUCCESS && endFilePosition) + k3kkeyListLen = keycnt; + continue; } } @@ -4042,7 +4122,7 @@ static int CmdHF14aDesChk(const char *Cmd) { // length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1] memcpy(&data[14 + atslen], foundKeys, 4 * 0xE * (24 + 1)); - saveFileJSON((char *)jsonname, jsfMfDesfireKeys, data, 0xE); + saveFileJSON((char *)jsonname, jsfMfDesfireKeys, data, 0xE, NULL); } return PM3_SUCCESS; diff --git a/client/src/cmdhfmfdesfire_disabled.c b/client/src/cmdhfmfdesfire_disabled.c index e2d43630f..e2de33485 100644 --- a/client/src/cmdhfmfdesfire_disabled.c +++ b/client/src/cmdhfmfdesfire_disabled.c @@ -14,8 +14,8 @@ #include "cmdhfmf.h" #include "util.h" -#include "mbedtls/des.h" -#include "mbedtls/aes.h" +#include "des.h" +#include "aes.h" static int CmdHelp(const char *Cmd); diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index 6fc146164..15eb15ab0 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -23,6 +23,7 @@ #include #include #include // MingW +#include #include "commonutil.h" // ARRAYLEN #include "comms.h" @@ -35,7 +36,6 @@ #include "hardnested_bruteforce.h" #include "hardnested_bf_core.h" #include "hardnested_bitarray_core.h" -#include "zlib/zlib.h" #include "fileutils.h" #define NUM_CHECK_BITFLIPS_THREADS (num_CPUs()) @@ -44,7 +44,7 @@ #define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states #define STATE_FILES_DIRECTORY "hardnested_tables/" -#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z" +#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.bz2" #define DEBUG_KEY_ELIMINATION // #define DEBUG_REDUCTION @@ -75,9 +75,12 @@ static float brute_force_per_second; static void get_SIMD_instruction_set(char *instruction_set) { switch (GetSIMDInstrAuto()) { +#if defined(COMPILER_HAS_SIMD_AVX512) case SIMD_AVX512: strcpy(instruction_set, "AVX512F"); break; +#endif +#if defined(COMPILER_HAS_SIMD) case SIMD_AVX2: strcpy(instruction_set, "AVX2"); break; @@ -90,7 +93,9 @@ static void get_SIMD_instruction_set(char *instruction_set) { case SIMD_MMX: strcpy(instruction_set, "MMX"); break; - default: +#endif + case SIMD_AUTO: + case SIMD_NONE: strcpy(instruction_set, "no"); break; } @@ -202,32 +207,23 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2) { } -static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) { - return calloc(items * size, sizeof(uint8_t)); -} - - -static void inflate_free(voidpf opaque, voidpf address) { - free(address); -} - #define OUTPUT_BUFFER_LEN 80 #define INPUT_BUFFER_LEN 80 //---------------------------------------------------------------------------- -// Initialize decompression of the respective (HF or LF) FPGA stream +// Initialize decompression of the respective bitflip_bitarray stream //---------------------------------------------------------------------------- -static void init_inflate(z_streamp compressed_stream, uint8_t *input_buffer, uint32_t insize, uint8_t *output_buffer, uint32_t outsize) { +static void init_bunzip2(bz_stream *compressed_stream, char *input_buffer, uint32_t insize, char *output_buffer, uint32_t outsize) { - // initialize z_stream structure for inflate: + // initialize bz_stream structure for bunzip2: compressed_stream->next_in = input_buffer; compressed_stream->avail_in = insize; compressed_stream->next_out = output_buffer; compressed_stream->avail_out = outsize; - compressed_stream->zalloc = &inflate_malloc; - compressed_stream->zfree = &inflate_free; + compressed_stream->bzalloc = NULL; + compressed_stream->bzfree = NULL; - inflateInit2(compressed_stream, 0); + BZ2_bzDecompressInit(compressed_stream, 0, 0); } @@ -237,7 +233,7 @@ static void init_bitflip_bitarrays(void) { uint8_t line = 0; #endif - z_stream compressed_stream; + bz_stream compressed_stream; char state_files_path[strlen(get_my_executable_directory()) + strlen(STATE_FILES_DIRECTORY) + strlen(STATE_FILE_TEMPLATE) + 1]; char state_file_name[strlen(STATE_FILE_TEMPLATE) + 1]; @@ -271,36 +267,36 @@ static void init_bitflip_bitarrays(void) { } uint32_t filesize = (uint32_t)fsize; rewind(statesfile); - uint8_t input_buffer[filesize]; + char input_buffer[filesize]; size_t bytesread = fread(input_buffer, 1, filesize, statesfile); if (bytesread != filesize) { PrintAndLogEx(ERR, "File read error with %s. Aborting...\n", state_file_name); fclose(statesfile); - //inflateEnd(&compressed_stream); + //BZ2_bzDecompressEnd(&compressed_stream); exit(5); } fclose(statesfile); uint32_t count = 0; - init_inflate(&compressed_stream, input_buffer, filesize, (uint8_t *)&count, sizeof(count)); - int res = inflate(&compressed_stream, Z_SYNC_FLUSH); - if (res != Z_OK) { - PrintAndLogEx(ERR, "Inflate error. Aborting...\n"); - inflateEnd(&compressed_stream); + init_bunzip2(&compressed_stream, input_buffer, filesize, (char *)&count, sizeof(count)); + int res = BZ2_bzDecompress(&compressed_stream); + if (res != BZ_OK) { + PrintAndLogEx(ERR, "Bunzip2 error. Aborting...\n"); + BZ2_bzDecompressEnd(&compressed_stream); exit(4); } if ((float)count / (1 << 24) < IGNORE_BITFLIP_THRESHOLD) { uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19)); if (bitset == NULL) { PrintAndLogEx(ERR, "Out of memory error in init_bitflip_statelists(). Aborting...\n"); - inflateEnd(&compressed_stream); + BZ2_bzDecompressEnd(&compressed_stream); exit(4); } - compressed_stream.next_out = (uint8_t *)bitset; + compressed_stream.next_out = (char *)bitset; compressed_stream.avail_out = sizeof(uint32_t) * (1 << 19); - res = inflate(&compressed_stream, Z_SYNC_FLUSH); - if (res != Z_OK && res != Z_STREAM_END) { - PrintAndLogEx(ERR, "Inflate error. Aborting...\n"); - inflateEnd(&compressed_stream); + res = BZ2_bzDecompress(&compressed_stream); + if (res != BZ_OK && res != BZ_STREAM_END) { + PrintAndLogEx(ERR, "Bunzip2 error. Aborting...\n"); + BZ2_bzDecompressEnd(&compressed_stream); exit(4); } effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip; @@ -315,7 +311,7 @@ static void init_bitflip_bitarrays(void) { } #endif } - inflateEnd(&compressed_stream); + BZ2_bzDecompressEnd(&compressed_stream); } } effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker @@ -494,7 +490,7 @@ static void free_sum_bitarrays(void) { #ifdef DEBUG_KEY_ELIMINATION -char failstr[250] = ""; +static char failstr[250] = ""; #endif static const float p_K0[NUM_SUMS] = { // the probability that a random nonce has a Sum Property K @@ -793,7 +789,8 @@ static void update_p_K(void) { } for (uint8_t sum_a8_idx = 0; sum_a8_idx < NUM_SUMS; sum_a8_idx++) { uint16_t sum_a8 = sums[sum_a8_idx]; - my_p_K[sum_a8_idx] = (float)estimated_num_states_coarse(sum_a0, sum_a8) / total_count; + float f = estimated_num_states_coarse(sum_a0, sum_a8); + my_p_K[sum_a8_idx] = f / total_count; } // PrintAndLogEx(NORMAL, "my_p_K = ["); // for (uint8_t sum_a8_idx = 0; sum_a8_idx < NUM_SUMS; sum_a8_idx++) { @@ -1229,7 +1226,8 @@ static void check_for_BitFlipProperties(bool time_budget) { args[i][1] = MIN(args[i][0] + bytes_per_thread - 1, 255); args[i][2] = time_budget; } - args[NUM_CHECK_BITFLIPS_THREADS - 1][1] = MAX(args[NUM_CHECK_BITFLIPS_THREADS - 1][1], 255); + // args[][] is uint8_t so max 255, no need to check it + // args[NUM_CHECK_BITFLIPS_THREADS - 1][1] = MAX(args[NUM_CHECK_BITFLIPS_THREADS - 1][1], 255); // start threads for (uint8_t i = 0; i < NUM_CHECK_BITFLIPS_THREADS; i++) { @@ -1302,7 +1300,7 @@ static void simulate_MFplus_RNG(uint32_t test_cuid, uint64_t test_key, uint32_t } -static void simulate_acquire_nonces() { +static void simulate_acquire_nonces(void) { time_t time1 = time(NULL); last_sample_clock = 0; sample_period = 1000; // for simulation @@ -1739,24 +1737,24 @@ static void bitarray_to_list(uint8_t byte, uint32_t *bitarray, uint32_t *state_l } -static void add_cached_states(statelist_t *candidates, uint16_t part_sum_a0, uint16_t part_sum_a8, odd_even_t odd_even) { - candidates->states[odd_even] = sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].sl; - candidates->len[odd_even] = sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].len; +static void add_cached_states(statelist_t *cands, uint16_t part_sum_a0, uint16_t part_sum_a8, odd_even_t odd_even) { + cands->states[odd_even] = sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].sl; + cands->len[odd_even] = sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].len; return; } -static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, uint8_t part_sum_a8, odd_even_t odd_even) { +static void add_matching_states(statelist_t *cands, uint8_t part_sum_a0, uint8_t part_sum_a8, odd_even_t odd_even) { const uint32_t worstcase_size = 1 << 20; - candidates->states[odd_even] = (uint32_t *)malloc(sizeof(uint32_t) * worstcase_size); - if (candidates->states[odd_even] == NULL) { + cands->states[odd_even] = (uint32_t *)malloc(sizeof(uint32_t) * worstcase_size); + if (cands->states[odd_even] == NULL) { PrintAndLogEx(ERR, "Out of memory error in add_matching_states() - statelist.\n"); exit(4); } - uint32_t *candidates_bitarray = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * worstcase_size); - if (candidates_bitarray == NULL) { + uint32_t *cands_bitarray = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * worstcase_size); + if (cands_bitarray == NULL) { PrintAndLogEx(ERR, "Out of memory error in add_matching_states() - bitarray.\n"); - free(candidates->states[odd_even]); + free(cands->states[odd_even]); exit(4); } @@ -1764,21 +1762,21 @@ static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, ui uint32_t *bitarray_a8 = part_sum_a8_bitarrays[odd_even][part_sum_a8 / 2]; uint32_t *bitarray_bitflips = nonces[best_first_bytes[0]].states_bitarray[odd_even]; - bitarray_AND4(candidates_bitarray, bitarray_a0, bitarray_a8, bitarray_bitflips); + bitarray_AND4(cands_bitarray, bitarray_a0, bitarray_a8, bitarray_bitflips); - bitarray_to_list(best_first_bytes[0], candidates_bitarray, candidates->states[odd_even], &(candidates->len[odd_even]), odd_even); + bitarray_to_list(best_first_bytes[0], cands_bitarray, cands->states[odd_even], &(cands->len[odd_even]), odd_even); - if (candidates->len[odd_even] == 0) { - free(candidates->states[odd_even]); - candidates->states[odd_even] = NULL; - } else if (candidates->len[odd_even] + 1 < worstcase_size) { - candidates->states[odd_even] = realloc(candidates->states[odd_even], sizeof(uint32_t) * (candidates->len[odd_even] + 1)); + if (cands->len[odd_even] == 0) { + free(cands->states[odd_even]); + cands->states[odd_even] = NULL; + } else if (cands->len[odd_even] + 1 < worstcase_size) { + cands->states[odd_even] = realloc(cands->states[odd_even], sizeof(uint32_t) * (cands->len[odd_even] + 1)); } - free_bitarray(candidates_bitarray); + free_bitarray(cands_bitarray); pthread_mutex_lock(&statelist_cache_mutex); - sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].sl = candidates->states[odd_even]; - sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].len = candidates->len[odd_even]; + sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].sl = cands->states[odd_even]; + sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].len = cands->len[odd_even]; sl_cache[part_sum_a0 / 2][part_sum_a8 / 2][odd_even].cache_status = COMPLETED; pthread_mutex_unlock(&statelist_cache_mutex); return; @@ -2108,7 +2106,7 @@ static uint16_t SumProperty(struct Crypto1State *s) { return (sum_odd * (16 - sum_even) + (16 - sum_odd) * sum_even); } -static void Tests() { +static void Tests(void) { if (known_target_key == -1) return; diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 728101ce7..7fc0f0bf7 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -168,7 +168,6 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature }; uint8_t i; - int res; bool is_valid = false; for (i = 0; i < ARRAYLEN(nxp_plus_public_keys); i++) { @@ -177,7 +176,7 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature uint8_t key[PUBLIC_PLUS_ECDA_KEYLEN]; param_gethex_to_eol(nxp_plus_public_keys[i].value, 0, key, PUBLIC_PLUS_ECDA_KEYLEN, &dl); - res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, key, uid, uidlen, signature, signature_len, false); + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, key, uid, uidlen, signature, signature_len, false); is_valid = (res == 0); if (is_valid) break; @@ -186,7 +185,7 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); - if (is_valid == false) { + if (is_valid == false || i == ARRAYLEN(nxp_plus_public_keys)) { PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); return PM3_ESOFT; } @@ -425,7 +424,8 @@ static int CmdHFMFPWritePerso(const char *Cmd) { uint8_t key[64] = {0}; int keyLen = 0; - CLIParserInit("hf mfp wrp", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp wrp", "Executes Write Perso command. Can be used in SL0 mode only.", "Usage:\n\thf mfp wrp 4000 000102030405060708090a0b0c0d0e0f -> write key (00..0f) to key number 4000 \n" "\thf mfp wrp 4000 -> write default key(0xff..0xff) to key number 4000"); @@ -437,12 +437,12 @@ static int CmdHFMFPWritePerso(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(1); - CLIGetHexWithReturn(2, keyNum, &keyNumLen); - CLIGetHexWithReturn(3, key, &keyLen); - CLIParserFree(); + bool verbose = arg_get_lit(ctx, 1); + CLIGetHexWithReturn(ctx, 2, keyNum, &keyNumLen); + CLIGetHexWithReturn(ctx, 3, key, &keyLen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -491,7 +491,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) { uint8_t data[250] = {0}; int datalen = 0; - CLIParserInit("hf mfp initp", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp initp", "Executes Write Perso command for all card's keys. Can be used in SL0 mode only.", "Usage:\n\thf mfp initp 000102030405060708090a0b0c0d0e0f -> fill all the keys with key (00..0f)\n" "\thf mfp initp -vv -> fill all the keys with default key(0xff..0xff) and show all the data exchange"); @@ -502,12 +503,12 @@ static int CmdHFMFPInitPerso(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(1); - bool verbose2 = arg_get_lit(1) > 1; - CLIGetHexWithReturn(2, key, &keyLen); - CLIParserFree(); + bool verbose = arg_get_lit(ctx, 1); + bool verbose2 = arg_get_lit(ctx, 1) > 1; + CLIGetHexWithReturn(ctx, 2, key, &keyLen); + CLIParserFree(ctx); if (keyLen && keyLen != 16) { PrintAndLogEx(ERR, "Key length must be 16 bytes instead of: %d", keyLen); @@ -558,7 +559,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) { } static int CmdHFMFPCommitPerso(const char *Cmd) { - CLIParserInit("hf mfp commitp", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp commitp", "Executes Commit Perso command. Can be used in SL0 mode only.", "Usage:\n\thf mfp commitp -> \n"); @@ -568,10 +570,10 @@ static int CmdHFMFPCommitPerso(const char *Cmd) { arg_int0(NULL, NULL, "SL mode", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(1); - CLIParserFree(); + bool verbose = arg_get_lit(ctx, 1); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -604,7 +606,8 @@ static int CmdHFMFPAuth(const char *Cmd) { uint8_t key[250] = {0}; int keylen = 0; - CLIParserInit("hf mfp auth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp auth", "Executes AES authentication command for Mifare Plus card", "Usage:\n\thf mfp auth 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n" "\thf mfp auth 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data\n"); @@ -616,12 +619,12 @@ static int CmdHFMFPAuth(const char *Cmd) { arg_str1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(1); - CLIGetHexWithReturn(2, keyn, &keynlen); - CLIGetHexWithReturn(3, key, &keylen); - CLIParserFree(); + bool verbose = arg_get_lit(ctx, 1); + CLIGetHexWithReturn(ctx, 2, keyn, &keynlen); + CLIGetHexWithReturn(ctx, 3, key, &keylen); + CLIParserFree(ctx); if (keynlen != 2) { PrintAndLogEx(ERR, "ERROR: must be 2 bytes long instead of: %d", keynlen); @@ -641,7 +644,8 @@ static int CmdHFMFPRdbl(const char *Cmd) { uint8_t key[250] = {0}; int keylen = 0; - CLIParserInit("hf mfp rdbl", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp rdbl", "Reads several blocks from Mifare Plus card.", "Usage:\n\thf mfp rdbl 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data\n" "\thf mfp rdbl 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n"); @@ -656,15 +660,15 @@ static int CmdHFMFPRdbl(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - bool verbose = arg_get_lit(1); - int blocksCount = arg_get_int_def(2, 1); - bool keyB = arg_get_lit(3); - int plain = arg_get_lit(4); - uint32_t blockn = arg_get_int(5); - CLIGetHexWithReturn(6, key, &keylen); - CLIParserFree(); + bool verbose = arg_get_lit(ctx, 1); + int blocksCount = arg_get_int_def(ctx, 2, 1); + bool keyB = arg_get_lit(ctx, 3); + int plain = arg_get_lit(ctx, 4); + uint32_t blockn = arg_get_int(ctx, 5); + CLIGetHexWithReturn(ctx, 6, key, &keylen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -753,7 +757,8 @@ static int CmdHFMFPRdsc(const char *Cmd) { uint8_t key[250] = {0}; int keylen = 0; - CLIParserInit("hf mfp rdsc", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp rdsc", "Reads one sector from Mifare Plus card.", "Usage:\n\thf mfp rdsc 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read sector 0 data\n" "\thf mfp rdsc 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n"); @@ -767,14 +772,14 @@ static int CmdHFMFPRdsc(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - bool verbose = arg_get_lit(1); - bool keyB = arg_get_lit(2); - bool plain = arg_get_lit(3); - uint32_t sectorNum = arg_get_int(4); - CLIGetHexWithReturn(5, key, &keylen); - CLIParserFree(); + bool verbose = arg_get_lit(ctx, 1); + bool keyB = arg_get_lit(ctx, 2); + bool plain = arg_get_lit(ctx, 3); + uint32_t sectorNum = arg_get_int(ctx, 4); + CLIGetHexWithReturn(ctx, 5, key, &keylen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -851,7 +856,8 @@ static int CmdHFMFPWrbl(const char *Cmd) { uint8_t datain[250] = {0}; int datainlen = 0; - CLIParserInit("hf mfp wrbl", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp wrbl", "Writes one block to Mifare Plus card.", "Usage:\n\thf mfp wrbl 1 ff0000000000000000000000000000ff 000102030405060708090a0b0c0d0e0f -> writes block 1 data\n" "\thf mfp wrbl 2 ff0000000000000000000000000000ff -v -> writes block 2 data with default key 0xFF..0xFF and some additional data\n"); @@ -865,14 +871,14 @@ static int CmdHFMFPWrbl(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - bool verbose = arg_get_lit(1); - bool keyB = arg_get_lit(2); - uint32_t blockNum = arg_get_int(3); - CLIGetHexWithReturn(4, datain, &datainlen); - CLIGetHexWithReturn(5, key, &keylen); - CLIParserFree(); + bool verbose = arg_get_lit(ctx, 1); + bool keyB = arg_get_lit(ctx, 2); + uint32_t blockNum = arg_get_int(ctx, 3); + CLIGetHexWithReturn(ctx, 4, datain, &datainlen); + CLIGetHexWithReturn(ctx, 5, key, &keylen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -949,9 +955,9 @@ static int CmdHFMFPWrbl(const char *Cmd) { #define AES_KEY_LEN 16 #define MAX_KEYS_LIST_LEN 1024 -int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, - uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], - bool verbose) { +static int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, + uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], + bool verbose) { int res; bool selectCard = true; uint8_t keyn[2] = {0}; @@ -1027,7 +1033,7 @@ int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint return PM3_SUCCESS; } -void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyListLen, uint32_t *startPattern) { +static void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], uint32_t *keyListLen, uint32_t *startPattern) { for (uint32_t pt = *startPattern; pt < 0x10000; pt++) { keyList[*keyListLen][0] = (pt >> 8) & 0xff; keyList[*keyListLen][1] = pt & 0xff; @@ -1045,10 +1051,11 @@ void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyL static int CmdHFMFPChk(const char *Cmd) { int res; uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}}; - size_t keyListLen = 0; + uint32_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}}; - CLIParserInit("hf mfp chk", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp chk", "Checks keys with Mifare Plus card.", "Usage:\n" " hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n" @@ -1072,60 +1079,60 @@ static int CmdHFMFPChk(const char *Cmd) { arg_lit0("vV", "verbose", "verbose mode."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool keyA = arg_get_lit(1); - bool keyB = arg_get_lit(2); - uint8_t startSector = arg_get_int_def(3, 0); - uint8_t endSector = arg_get_int_def(4, 0); + bool keyA = arg_get_lit(ctx, 1); + bool keyB = arg_get_lit(ctx, 2); + uint8_t startSector = arg_get_int_def(ctx, 3, 0); + uint8_t endSector = arg_get_int_def(ctx, 4, 0); uint8_t vkey[16] = {0}; int vkeylen = 0; - CLIGetHexWithReturn(5, vkey, &vkeylen); + CLIGetHexWithReturn(ctx, 5, vkey, &vkeylen); if (vkeylen > 0) { if (vkeylen == 16) { memcpy(&keyList[keyListLen], vkey, 16); keyListLen++; } else { PrintAndLogEx(ERR, "Specified key must have 16 bytes length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } } uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0}; int dict_filenamelen = 0; - if (CLIParamStrToBuf(arg_get_str(6), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { + if (CLIParamStrToBuf(arg_get_str(ctx, 6), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { PrintAndLogEx(FAILED, "File name too long or invalid."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } - bool pattern1b = arg_get_lit(7); - bool pattern2b = arg_get_lit(8); + bool pattern1b = arg_get_lit(ctx, 7); + bool pattern2b = arg_get_lit(ctx, 8); if (pattern1b && pattern2b) { PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (dict_filenamelen && (pattern1b || pattern2b)) { PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } uint32_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; - CLIGetHexWithReturn(9, vpattern, &vpatternlen); + CLIGetHexWithReturn(ctx, 9, vpattern, &vpatternlen); if (vpatternlen > 0) { if (vpatternlen > 0 && vpatternlen <= 2) { startPattern = (vpattern[0] << 8) + vpattern[1]; } else { PrintAndLogEx(ERR, "Pattern must be 2-byte length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (!pattern2b) @@ -1134,21 +1141,22 @@ static int CmdHFMFPChk(const char *Cmd) { uint8_t jsonname[250] = {0}; int jsonnamelen = 0; - if (CLIParamStrToBuf(arg_get_str(10), jsonname, sizeof(jsonname), &jsonnamelen)) { + if (CLIParamStrToBuf(arg_get_str(ctx, 10), jsonname, sizeof(jsonname), &jsonnamelen)) { PrintAndLogEx(ERR, "Invalid json name."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } jsonname[jsonnamelen] = 0; - bool verbose = arg_get_lit(11); + bool verbose = arg_get_lit(ctx, 11); - CLIParserFree(); + CLIParserFree(ctx); uint8_t startKeyAB = 0; uint8_t endKeyAB = 1; if (keyA && !keyB) endKeyAB = 0; + if (!keyA && keyB) startKeyAB = 1; @@ -1170,7 +1178,7 @@ static int CmdHFMFPChk(const char *Cmd) { // dictionary mode size_t endFilePosition = 0; if (dict_filenamelen) { - uint16_t keycnt = 0; + uint32_t keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition, true); keyListLen = keycnt; if (endFilePosition) @@ -1190,7 +1198,7 @@ static int CmdHFMFPChk(const char *Cmd) { PrintAndLogEx(ERR, "Key list is empty. Nothing to check."); return PM3_EINVARG; } else { - PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " keys", keyListLen); + PrintAndLogEx(INFO, "Loaded " _YELLOW_("%"PRIu32) " keys", keyListLen); } if (!verbose) @@ -1210,7 +1218,7 @@ static int CmdHFMFPChk(const char *Cmd) { if (dict_filenamelen && endFilePosition) { if (!verbose) printf("d"); - uint16_t keycnt = 0; + uint32_t keycnt = 0; res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false); keyListLen = keycnt; continue; @@ -1269,7 +1277,7 @@ static int CmdHFMFPChk(const char *Cmd) { // length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1] memcpy(&data[14 + atslen], foundKeys, 2 * 64 * (AES_KEY_LEN + 1)); - saveFileJSON((char *)jsonname, jsfMfPlusKeys, data, 64); + saveFileJSON((char *)jsonname, jsfMfPlusKeys, data, 64, NULL); } return PM3_SUCCESS; @@ -1277,34 +1285,39 @@ static int CmdHFMFPChk(const char *Cmd) { static int CmdHFMFPMAD(const char *Cmd) { - CLIParserInit("hf mfp mad", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp mad", "Checks and prints Mifare Application Directory (MAD)", - "Usage:\n\thf mfp mad -> shows MAD if exists\n" - "\thf mfp mad -a 03e1 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data if exists\n"); + "Usage:\n\thf mfp mad -> shows MAD if exists\n" + "\thf mfp mad -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data if exists\n"); void *argtable[] = { arg_param_begin, arg_lit0("vV", "verbose", "show technical data"), - arg_str0("aA", "aid", "print all sectors with aid", NULL), - arg_str0("kK", "key", "key for printing sectors", NULL), + arg_str0("", "aid", "", "print all sectors with aid"), + arg_str0("kK", "key", "", "key for printing sectors"), arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), + arg_lit0("", "be", "(optional, BigEndian)"), + arg_lit0("", "dch", "decode Card Holder information"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(1); + bool verbose = arg_get_lit(ctx, 1); uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[16] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); - bool keyB = arg_get_lit(4); + CLIGetHexWithReturn(ctx, 3, key, &keylen); + bool keyB = arg_get_lit(ctx, 4); + bool swapmad = arg_get_lit(ctx, 5); + bool decodeholder = arg_get_lit(ctx, 6); - CLIParserFree(); + CLIParserFree(ctx); - if (aidlen != 2 && keylen > 0) { - PrintAndLogEx(WARNING, "do not need a key without aid."); + if (aidlen != 2 && !decodeholder && keylen > 0) { + PrintAndLogEx(WARNING, "Using default MAD keys instead"); } uint8_t sector0[16 * 4] = {0}; @@ -1312,93 +1325,137 @@ static int CmdHFMFPMAD(const char *Cmd) { if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector0, verbose)) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); + PrintAndLogEx(ERR, "error, read sector 0. card don't have MAD or don't have MAD on default keys"); return 2; } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Mifare App Directory Information") " ----------------"); + PrintAndLogEx(INFO, "-----------------------------------------------------"); + if (verbose) { + PrintAndLogEx(SUCCESS, "Raw:"); for (int i = 0; i < 4; i ++) - PrintAndLogEx(NORMAL, "[%d] %s", i, sprint_hex(§or0[i * 16], 16)); + PrintAndLogEx(INFO, "[%d] %s", i, sprint_hex(§or0[i * 16], 16)); } bool haveMAD2 = false; - MAD1DecodeAndPrint(sector0, verbose, &haveMAD2); + MAD1DecodeAndPrint(sector0, swapmad, verbose, &haveMAD2); if (haveMAD2) { if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector10, verbose)) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); + PrintAndLogEx(ERR, "error, read sector 0x10. card don't have MAD or don't have MAD on default keys"); return 2; } - MAD2DecodeAndPrint(sector10, verbose); + MAD2DecodeAndPrint(sector10, swapmad, verbose); } - if (aidlen == 2) { - uint16_t aaid = (aid[0] << 8) + aid[1]; - PrintAndLogEx(NORMAL, "\n-------------- AID 0x%04x ---------------", aaid); - + if (aidlen == 2 || decodeholder) { uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; - if (MADDecode(sector0, sector10, mad, &madlen)) { - PrintAndLogEx(ERR, "can't decode mad."); + if (MADDecode(sector0, sector10, mad, &madlen, swapmad)) { + PrintAndLogEx(ERR, "can't decode MAD"); return 10; } + // copy default NDEF key uint8_t akey[16] = {0}; memcpy(akey, g_mifarep_ndef_key, 16); + + // user specified key if (keylen == 16) { memcpy(akey, key, 16); } - for (int i = 0; i < madlen; i++) { - if (aaid == mad[i]) { - uint8_t vsector[16 * 4] = {0}; - if (mfpReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector, false)) { - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(ERR, "read sector %d error.", i + 1); - return 2; - } + uint16_t aaid = 0x0004; + if (aidlen == 2) { + aaid = (aid[0] << 8) + aid[1]; + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-------------- " _CYAN_("AID 0x%04x") " ---------------", aaid); - for (int j = 0; j < (verbose ? 4 : 3); j ++) - PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + for (int i = 0; i < madlen; i++) { + if (aaid == mad[i]) { + uint8_t vsector[16 * 4] = {0}; + if (mfpReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector, false)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "error, read sector %d error", i + 1); + return PM3_ESOFT; + } + + for (int j = 0; j < (verbose ? 4 : 3); j ++) + PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + } } } - } + if (decodeholder) { + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-------- " _CYAN_("Card Holder Info 0x%04x") " --------", aaid); + + uint8_t data[4096] = {0}; + int datalen = 0; + + for (int i = 0; i < madlen; i++) { + if (aaid == mad[i]) { + + uint8_t vsector[16 * 4] = {0}; + if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(ERR, "error, read sector %d", i + 1); + return PM3_ESOFT; + } + + memcpy(&data[datalen], vsector, 16 * 3); + datalen += 16 * 3; + } + } + + if (!datalen) { + PrintAndLogEx(WARNING, "no Card Holder Info data"); + return PM3_SUCCESS; + } + MADCardHolderInfoDecode(data, datalen, verbose); + } + } return PM3_SUCCESS; } static int CmdHFMFPNDEF(const char *Cmd) { - CLIParserInit("hf mfp ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp ndef", "Prints NFC Data Exchange Format (NDEF)", - "Usage:\n\thf mfp ndef -> shows NDEF data\n" - "\thf mfp ndef -a 03e1 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key\n"); + "Usage:\n" + "\thf mfp ndef -> shows NDEF data\n" + "\thf mfp ndef -vv -> shows NDEF parsed and raw data\n" + "\thf mfp ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key\n"); void *argtable[] = { arg_param_begin, arg_litn("vV", "verbose", 0, 2, "show technical data"), - arg_str0("aA", "aid", "replace default aid for NDEF", NULL), - arg_str0("kK", "key", "replace default key for NDEF", NULL), + arg_str0("", "aid", "", "replace default aid for NDEF"), + arg_str0("kK", "key", "", "replace default key for NDEF"), arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(1); - bool verbose2 = arg_get_lit(1) > 1; + bool verbose = arg_get_lit(ctx, 1); + bool verbose2 = arg_get_lit(ctx, 1) > 1; uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[16] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); - bool keyB = arg_get_lit(4); + CLIGetHexWithReturn(ctx, 3, key, &keylen); + bool keyB = arg_get_lit(ctx, 4); - CLIParserFree(); + CLIParserFree(ctx); - uint16_t ndefAID = 0x03e1; + uint16_t ndefAID = 0xe103; if (aidlen == 2) ndefAID = (aid[0] << 8) + aid[1]; @@ -1413,63 +1470,72 @@ static int CmdHFMFPNDEF(const char *Cmd) { uint8_t data[4096] = {0}; int datalen = 0; - PrintAndLogEx(NORMAL, ""); - + if (verbose) + PrintAndLogEx(INFO, "reading MAD v1 sector"); + if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector0, verbose)) { - PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); - return 2; + PrintAndLogEx(ERR, "error, read sector 0. card don't have MAD or don't have MAD on default keys"); + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfp ndef -k `") " with your custom key"); + return PM3_ESOFT; } bool haveMAD2 = false; int res = MADCheck(sector0, NULL, verbose, &haveMAD2); - if (res) { - PrintAndLogEx(ERR, "MAD error %d.", res); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "MAD error %d", res); return res; } if (haveMAD2) { + + if (verbose) + PrintAndLogEx(INFO, "reading MAD v2 sector"); + if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector10, verbose)) { - PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); - return 2; + PrintAndLogEx(ERR, "error, read sector 0x10. card don't have MAD or don't have MAD on default keys"); + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndef -k `") " with your custom key"); + return PM3_ESOFT; } } uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; - if (MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen)) { - PrintAndLogEx(ERR, "can't decode mad."); - return 10; + res = MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen, false); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "can't decode MAD"); + return res; } - printf("data reading:"); + PrintAndLogEx(INFO, "reading data from tag"); for (int i = 0; i < madlen; i++) { if (ndefAID == mad[i]) { uint8_t vsector[16 * 4] = {0}; if (mfpReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector, false)) { - PrintAndLogEx(ERR, "read sector %d error.", i + 1); - return 2; + PrintAndLogEx(ERR, "error, reading sector %d", i + 1); + return PM3_ESOFT; } memcpy(&data[datalen], vsector, 16 * 3); datalen += 16 * 3; - printf("."); + PrintAndLogEx(INPLACE, "%d", i); } } - printf(" OK\n"); + PrintAndLogEx(NORMAL, ""); if (!datalen) { - PrintAndLogEx(ERR, "no NDEF data."); - return 11; + PrintAndLogEx(ERR, "no NDEF data"); + return PM3_SUCCESS; } if (verbose2) { - PrintAndLogEx(NORMAL, "NDEF data:"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------"); dump_buffer(data, datalen, stdout, 1); } NDEFDecodeAndPrint(data, datalen, verbose); - + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndef -vv`") " for more details"); return PM3_SUCCESS; } @@ -1496,7 +1562,7 @@ static int CmdHelp(const char *Cmd) { } int CmdHFMFP(const char *Cmd) { - (void)WaitForResponseTimeout(CMD_ACK, NULL, 100); + clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index f70c3887e..2a361cbb7 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -12,7 +12,7 @@ #include "cmdparser.h" #include "commonutil.h" #include "crypto/libpcrypto.h" -#include "mbedtls/des.h" +#include "des.h" #include "cmdhfmf.h" #include "cmdhf14a.h" #include "comms.h" @@ -347,8 +347,7 @@ static int ul_select(iso14a_card_select_t *card) { ul_switch_on_field(); PacketResponseNG resp; - bool ans = false; - ans = WaitForResponseTimeout(CMD_ACK, &resp, 1500); + bool ans = WaitForResponseTimeout(CMD_ACK, &resp, 1500); if (!ans || resp.oldarg[0] < 1) { PrintAndLogEx(WARNING, "iso14443a card select failed"); @@ -486,7 +485,7 @@ static int ul_fudan_check(void) { uint8_t cmd[4] = {0x30, 0x00, 0x02, 0xa7}; //wrong crc on purpose should be 0xa8 clearCommandBuffer(); - SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 4, 0, cmd, sizeof(cmd)); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 4, 0, cmd, sizeof(cmd)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return UL_ERROR; if (resp.oldarg[0] != 1) return UL_ERROR; @@ -541,7 +540,7 @@ static int ul_print_default(uint8_t *data) { sprint_bin(data + 10, 2) ); - PrintAndLogEx(SUCCESS, "OneTimePad: %s - %s\n", + PrintAndLogEx(SUCCESS, "OneTimePad: %s - %s", sprint_hex(data + 12, 4), sprint_bin(data + 12, 4) ); @@ -653,66 +652,60 @@ static int ndef_print_CC(uint8_t *data) { int ul_print_type(uint32_t tagtype, uint8_t spaces) { - char spc[11] = " "; - spc[10] = 0x00; - if (spaces > 10) spaces = 10; - - char *spacer = spc + (10 - spaces); - if (tagtype & UL) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight (MF0ICU1) %s"), spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("MIFARE Ultralight (MF0ICU1) %s"), spaces, "", (tagtype & MAGIC) ? "" : ""); else if (tagtype & UL_C) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight C (MF0ULC) %s"), spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("MIFARE Ultralight C (MF0ULC) %s"), spaces, "", (tagtype & MAGIC) ? "" : ""); else if (tagtype & UL_NANO_40) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight Nano 40bytes (MF0UNH00)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("MIFARE Ultralight Nano 40bytes (MF0UNH00)"), spaces, ""); else if (tagtype & UL_EV1_48) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight EV1 48bytes (MF0UL1101)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("MIFARE Ultralight EV1 48bytes (MF0UL1101)"), spaces, ""); else if (tagtype & UL_EV1_128) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("MIFARE Ultralight EV1 128bytes (MF0UL2101)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("MIFARE Ultralight EV1 128bytes (MF0UL2101)"), spaces, ""); else if (tagtype & UL_EV1) - PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("MIFARE Ultralight EV1 UNKNOWN"), spacer); + PrintAndLogEx(NORMAL, "%*sTYPE: " _YELLOW_("MIFARE Ultralight EV1 UNKNOWN"), spaces, ""); else if (tagtype & NTAG) - PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("NTAG UNKNOWN"), spacer); + PrintAndLogEx(NORMAL, "%*sTYPE: " _YELLOW_("NTAG UNKNOWN"), spaces, ""); else if (tagtype & NTAG_203) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 203 144bytes (NT2H0301F0DT)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 203 144bytes (NT2H0301F0DT)"), spaces, ""); else if (tagtype & NTAG_210) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 210 48bytes (NT2L1011G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 210 48bytes (NT2L1011G0DU)"), spaces, ""); else if (tagtype & NTAG_212) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 212 128bytes (NT2L1211G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 212 128bytes (NT2L1211G0DU)"), spaces, ""); else if (tagtype & NTAG_213) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 213 144bytes (NT2H1311G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213 144bytes (NT2H1311G0DU)"), spaces, ""); else if (tagtype & NTAG_213_F) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spaces, ""); else if (tagtype & NTAG_215) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 215 504bytes (NT2H1511G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 215 504bytes (NT2H1511G0DU)"), spaces, ""); else if (tagtype & NTAG_216) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 216 888bytes (NT2H1611G0DU)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 216 888bytes (NT2H1611G0DU)"), spaces, ""); else if (tagtype & NTAG_216_F) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG 216F 888bytes (NT2H1611F0DTL)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 216F 888bytes (NT2H1611F0DTL)"), spaces, ""); else if (tagtype & NTAG_I2C_1K) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C 888bytes (NT3H1101FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG I2C 888bytes (NT3H1101FHK)"), spaces, ""); else if (tagtype & NTAG_I2C_2K) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C 1904bytes (NT3H1201FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG I2C 1904bytes (NT3H1201FHK)"), spaces, ""); else if (tagtype & NTAG_I2C_1K_PLUS) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C plus 888bytes (NT3H2111FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG I2C plus 888bytes (NT3H2111FHK)"), spaces, ""); else if (tagtype & NTAG_I2C_2K_PLUS) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("NTAG I2C plus 1912bytes (NT3H2211FHK)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG I2C plus 1912bytes (NT3H2211FHK)"), spaces, ""); else if (tagtype & MY_D) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 (SLE 66RxxS)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 (SLE 66RxxS)"), spaces, ""); else if (tagtype & MY_D_NFC) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 NFC (SLE 66RxxP)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 NFC (SLE 66RxxP)"), spaces, ""); else if (tagtype & MY_D_MOVE) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 move (SLE 66R01P)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 move (SLE 66R01P)"), spaces, ""); else if (tagtype & MY_D_MOVE_NFC) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 move NFC (SLE 66R01P)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 move NFC (SLE 66R01P)"), spaces, ""); else if (tagtype & MY_D_MOVE_LEAN) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("INFINEON my-d\x99 move lean (SLE 66R01L)"), spacer); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 move lean (SLE 66R01L)"), spaces, ""); else if (tagtype & FUDAN_UL) - PrintAndLogEx(SUCCESS, "%sTYPE: " _YELLOW_("FUDAN Ultralight Compatible (or other compatible) %s"), spacer, (tagtype & MAGIC) ? "" : ""); + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("FUDAN Ultralight Compatible (or other compatible) %s"), spaces, "", (tagtype & MAGIC) ? "" : ""); else - PrintAndLogEx(NORMAL, "%sTYPE: " _YELLOW_("Unknown %06x"), spacer, tagtype); + PrintAndLogEx(NORMAL, "%*sTYPE: " _YELLOW_("Unknown %06x"), spaces, "", tagtype); return PM3_SUCCESS; } @@ -754,11 +747,13 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, "--- " _CYAN_("Tag Configuration")); bool strg_mod_en = (data[0] & 2); + uint8_t authlim = (data[4] & 0x07); - bool nfc_cnf_en = (data[4] & 0x08); - bool nfc_cnf_prot_pwd = (data[4] & 0x10); - bool cfglck = (data[4] & 0x40); - bool prot = (data[4] & 0x80); + bool nfc_cnf_prot_pwd = ((data[4] & 0x08) == 0x08); + bool nfc_cnf_en = ((data[4] & 0x10) == 0x10); + bool cfglck = ((data[4] & 0x40) == 0x40); + bool prot = ((data[4] & 0x80) == 0x80); + uint8_t vctid = data[5]; PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4)); @@ -844,7 +839,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, " - Max number of password attempts is " _YELLOW_("%d"), authlim); PrintAndLogEx(INFO, " - NFC counter %s", (nfc_cnf_en) ? "enabled" : "disabled"); - PrintAndLogEx(INFO, " - NFC counter %s", (nfc_cnf_prot_pwd) ? "not protected" : "password protection enabled"); + PrintAndLogEx(INFO, " - NFC counter %s", (nfc_cnf_prot_pwd) ? "password protection enabled" : "not protected"); PrintAndLogEx(INFO, " - user configuration %s", cfglck ? "permanently locked" : "writeable"); PrintAndLogEx(INFO, " - %s access is protected with password", prot ? "read and write" : "write"); @@ -855,7 +850,8 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st return PM3_SUCCESS; } -static int ulev1_print_counters() { +static int ulev1_print_counters(void) { + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Counters")); uint8_t tear[1] = {0}; uint8_t counter[3] = {0, 0, 0}; @@ -865,7 +861,7 @@ static int ulev1_print_counters() { len = ulev1_readCounter(i, counter, sizeof(counter)); if (len == 3) { PrintAndLogEx(INFO, " [%0d]: %s", i, sprint_hex(counter, 3)); - PrintAndLogEx(SUCCESS, " - %02X tearing %s", tear[0], (tear[0] == 0xBD) ? "Ok" : "failure"); + PrintAndLogEx(SUCCESS, " - %02X tearing (" _GREEN_("%s") ")", tear[0], (tear[0] == 0xBD) ? "ok" : "failure"); } } return len; @@ -934,7 +930,6 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig }; */ uint8_t i; - int res; bool is_valid = false; for (i = 0; i < ARRAYLEN(nxp_mfu_public_keys); i++) { @@ -942,7 +937,7 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig uint8_t key[PUBLIC_ECDA_KEYLEN]; param_gethex_to_eol(nxp_mfu_public_keys[i].value, 0, key, PUBLIC_ECDA_KEYLEN, &dl); - res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 7, signature, signature_len, false); + int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 7, signature, signature_len, false); is_valid = (res == 0); if (is_valid) @@ -950,7 +945,7 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig } PrintAndLogEx(NORMAL, ""); - if (is_valid == false) { + if (is_valid == false || i == ARRAYLEN(nxp_mfu_public_keys)) { PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); return PM3_ESOFT; } @@ -978,6 +973,22 @@ static int ulev1_print_version(uint8_t *data) { return PM3_SUCCESS; } +static int ntag_print_counter(void) { + // NTAG has one counter/tearing. At address 0x02. + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Counter")); + uint8_t tear[1] = {0}; + uint8_t counter[3] = {0, 0, 0}; + uint16_t len; + len = ulev1_readTearing(0x02, tear, sizeof(tear)); + (void)len; + len = ulev1_readCounter(0x02, counter, sizeof(counter)); + (void)len; + PrintAndLogEx(INFO, " [02]: %s", sprint_hex(counter, 3)); + PrintAndLogEx(SUCCESS, " - %02X tearing (" _GREEN_("%s")")", tear[0], (tear[0] == 0xBD) ? "ok" : "failure"); + return len; +} + /* static int ulc_magic_test(){ // Magic Ultralight test @@ -1005,7 +1016,7 @@ static int ulc_magic_test(){ return returnValue; } */ -static int ul_magic_test() { +static int ul_magic_test(void) { // Magic Ultralight tests // 1) take present UID, and try to write it back. OBSOLETE // 2) make a wrong length write to page0, and see if tag answers with ACK/NACK: @@ -1042,6 +1053,42 @@ uint32_t GetHF14AMfU_Type(void) { switch (len) { case 0x0A: { + /* + MF0UL1001DUx 0004030100000B03 + MF0UL1101DUx 0004030101000B03 + MF0ULH1101DUx 0004030201000B03 + MF0UL1141DUF 0004030301000B03 + MF0UL2101Dxy 0004030101000E03 + MF0UL2101DUx 0004030201000E03 + MF0UL3101DUx 0004030101001103 + MF0ULH3101DUx 0004030201001103 + MF0UL5101DUx 0004030101001303 + NT2L1011F0DUx 0004040101000B03 + NT2H1011G0DUD 0004040201000B03 + NT2L1211F0DUx 0004040101000E03 + NT2H1311G0DUx 0004040201000F03 + NT2H1311F0Dxy 0004040401000F03 + NT2H1411G0DUx 0004040201011103 + NT2H1511G0DUx 0004040201001103 + NT2H1511F0Dxy 0004040401001103 + NT2H1611G0DUx 0004040201001303 + NT2H1611F0Dxy 0004040401001303 + NT2H1311C1DTL 0004040201010F03 + NT2H1311TTDUx 0004040203000F03 + NT3H1101W0FHK 0004040502001303 + NT3H1201W0FHK 0004040502001503 + NT3H1101W0FHK_Variant 0004040502011303 + NT3H1201 0004040502011503 + NT3H2111 0004040502021303 + NT3H2211 0004040502021503 + nhs 0004040600001303 + MF0UN0001DUx 0004030102000B03 + MF0UNH0001DUx 0004030202000B03 + MF0UN1001DUx 0004030103000B03 + MF0UNH1001DUx 0004030203000B03 + NT2L1001G0DUx 0004040102000B03 + NT2H1001G0DUx 0004040202000B03 + */ if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0B", 7) == 0) { tagtype = UL_EV1_48; break; } else if (memcmp(version, "\x00\x04\x03\x01\x02\x00\x0B", 7) == 0) { tagtype = UL_NANO_40; break; } @@ -1278,6 +1325,12 @@ static int CmdHF14AMfUInfo(const char *Cmd) { } // NTAG counters? + if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) { + if (ntag_print_counter()) { + // failed - re-select + if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; + } + } // Read signature if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) { @@ -1294,10 +1347,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) { // re-select if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; } - } - // Get Version - if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) { + // Get Version uint8_t version[10] = {0x00}; status = ulev1_getVersion(version, sizeof(version)); if (status == -1) { @@ -1520,7 +1571,7 @@ static int CmdHF14AMfUWrBl(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, blockNo, keytype, 0, cmddata, datalen); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, blockNo, keytype, 0, cmddata, datalen); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -1625,7 +1676,7 @@ static int CmdHF14AMfURdBl(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_READBL, blockNo, keytype, 0, authKeyPtr, datalen); + SendCommandMIX(CMD_HF_MIFAREU_READBL, blockNo, keytype, 0, authKeyPtr, datalen); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -1893,7 +1944,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_READCARD, startPage, pages, keytype, authKeyPtr, dataLen); + SendCommandMIX(CMD_HF_MIFAREU_READCARD, startPage, pages, keytype, authKeyPtr, dataLen); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { @@ -1951,16 +2002,42 @@ static int CmdHF14AMfUDump(const char *Cmd) { if (hasAuthKey) { uint8_t dummy_pack[] = {0, 0}; ul_auth_select(&card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack)); - } else + } else { ul_select(&card); + } ulev1_getVersion(get_version, sizeof(get_version)); - for (uint8_t n = 0; n < 3; ++n) { - ulev1_readTearing(n, &get_counter_tearing[n][3], 1); + + // ULEV-1 has 3 counters + uint8_t n = 0; + + // NTAG has 1 counter, at 0x02 + if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) { + n = 2; + } + + // NTAG can have nfc counter pwd protection enabled + for (; n < 3; n++) { + + if (hasAuthKey) { + uint8_t dummy_pack[] = {0, 0}; + ul_auth_select(&card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack)); + } else { + ul_select(&card); + } ulev1_readCounter(n, &get_counter_tearing[n][0], 3); + + if (hasAuthKey) { + uint8_t dummy_pack[] = {0, 0}; + ul_auth_select(&card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack)); + } else { + ul_select(&card); + } + ulev1_readTearing(n, &get_counter_tearing[n][3], 1); } DropField(); + if (hasAuthKey) { uint8_t dummy_pack[] = {0, 0}; ul_auth_select(&card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack)); @@ -2013,7 +2090,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { } uint16_t datalen = pages * 4 + MFU_DUMP_PREFIX_LENGTH; saveFile(filename, ".bin", (uint8_t *)&dump_file_data, datalen); - saveFileJSON(filename, jsfMfuMemory, (uint8_t *)&dump_file_data, datalen); + saveFileJSON(filename, jsfMfuMemory, (uint8_t *)&dump_file_data, datalen, NULL); if (is_partial) PrintAndLogEx(WARNING, "Partial dump created. (%d of %d blocks)", pages, card_mem_size); @@ -2048,8 +2125,8 @@ static int CmdHF14AMfURestore(const char *Cmd) { bool write_special = false; bool write_extra = false; bool read_key = false; + bool verbose = false; size_t filelen = 0; - FILE *f; memset(authkey, 0x00, sizeof(authkey)); @@ -2096,6 +2173,10 @@ static int CmdHF14AMfURestore(const char *Cmd) { cmdp++; read_key = true; break; + case 'v': + cmdp++; + verbose = true; + break; default: PrintAndLogEx(WARNING, "Unknown parameter: " _RED_("'%c'"), param_getchar(Cmd, cmdp)); errors = true; @@ -2106,41 +2187,22 @@ static int CmdHF14AMfURestore(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_hf_mfu_restore(); - if ((f = fopen(filename, "rb")) == NULL) { + uint8_t *dump = NULL; + size_t bytes_read = 0; + if (loadFile_safe(filename, "", (void **)&dump, &bytes_read) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), filename); - return 1; + return PM3_EIO; } - // get filesize to know how memory to allocate - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - if (fsize <= 0) { - PrintAndLogEx(ERR, "Error, when getting filesize"); - fclose(f); - return 1; - } - - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - fclose(f); - return 1; - } - - // read all data - size_t bytes_read = fread(dump, 1, fsize, f); - fclose(f); if (bytes_read < MFU_DUMP_PREFIX_LENGTH) { PrintAndLogEx(ERR, "Error, dump file is too small"); free(dump); - return 1; + return PM3_ESOFT; } - // convert old format to new format, if need - int res = convertOldMfuDump(&dump, &bytes_read); + int res = convert_mfu_dump_format(&dump, &bytes_read, verbose); if (res != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format"); + PrintAndLogEx(FAILED, "Failed convert on load to new Ultralight/NTAG format"); free(dump); return res; } @@ -2151,7 +2213,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { if (pages - 1 != mem->pages) { PrintAndLogEx(ERR, "Error, invalid dump, wrong page count"); free(dump); - return 1; + return PM3_ESOFT; } PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", filename); @@ -2769,7 +2831,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { PrintAndLogEx(INFO, "Reading block BEFORE attack"); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_READBL, blockNoUint, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_MIFAREU_READBL, blockNoUint, 0, 0, NULL, 0); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -2785,7 +2847,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { PrintAndLogEx(INFO, "....."); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MFU_OTP_TEAROFF, blockNoUint, actualTime, 0, teardata, 8); + SendCommandMIX(CMD_HF_MFU_OTP_TEAROFF, blockNoUint, actualTime, 0, teardata, 8); if (!WaitForResponseTimeout(CMD_HF_MFU_OTP_TEAROFF, &resp, 4000)) { PrintAndLogEx(WARNING, "Failed"); return PM3_ESOFT; @@ -2794,7 +2856,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { PrintAndLogEx(INFO, "Reading block AFTER attack"); clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFAREU_READBL, blockNoUint, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_MIFAREU_READBL, blockNoUint, 0, 0, NULL, 0); if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; if (isOK) { @@ -2835,7 +2897,8 @@ static int CmdHF14MfuNDEF(const char *Cmd) { uint8_t *p_key = key; uint8_t pack[4] = {0, 0, 0, 0}; - CLIParserInit("hf mfu ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfu ndef", "Prints NFC Data Exchange Format (NDEF)", "Usage:\n\thf mfu ndef -> shows NDEF data\n" "\thf mfu ndef -k ffffffff -> shows NDEF data with key\n"); @@ -2846,10 +2909,10 @@ static int CmdHF14MfuNDEF(const char *Cmd) { arg_lit0("lL", "key", "(optional) swap entered key's endianness"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); - CLIGetHexWithReturn(1, key, &keylen); - swapEndian = arg_get_lit(2); - CLIParserFree(); + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIGetHexWithReturn(ctx, 1, key, &keylen); + swapEndian = arg_get_lit(ctx, 2); + CLIParserFree(ctx); switch (keylen) { case 0: diff --git a/client/src/cmdhfmfu.h b/client/src/cmdhfmfu.h index 85f6a8475..eb81c8dea 100644 --- a/client/src/cmdhfmfu.h +++ b/client/src/cmdhfmfu.h @@ -18,28 +18,16 @@ typedef struct { uint8_t signature[32]; //uint8_t counter[3]; uint8_t data[1024]; -} old_mfu_dump_t; - +} PACKED old_mfu_dump_t; uint32_t GetHF14AMfU_Type(void); int ul_print_type(uint32_t tagtype, uint8_t spaces); - void printMFUdump(mfu_dump_t *card); void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage); int CmdHFMFUltra(const char *Cmd); -uint32_t ul_ev1_pwdgenA(uint8_t *uid); -uint32_t ul_ev1_pwdgenA(uint8_t *uid); -uint32_t ul_ev1_pwdgenC(uint8_t *uid); -uint32_t ul_ev1_pwdgenD(uint8_t *uid); - -uint16_t ul_ev1_packgenA(uint8_t *uid); -uint16_t ul_ev1_packgenB(uint8_t *uid); -uint16_t ul_ev1_packgenC(uint8_t *uid); -uint16_t ul_ev1_packgenD(uint8_t *uid); uint16_t ul_ev1_packgen_VCNEW(uint8_t *uid, uint32_t pwd); - uint32_t ul_ev1_otpgenA(uint8_t *uid); typedef enum TAGTYPE_UL { diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 1408a6e46..6410d67bc 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -109,7 +109,7 @@ static int topaz_select(uint8_t *atqa, uint8_t atqa_len, uint8_t *rid_response, status = topaz_send_cmd(rid_cmd, sizeof(rid_cmd), rid_response, &resp_len, verbose); if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { topaz_switch_off_field(); - return PM3_EWRONGANSVER; // RID failed + return PM3_EWRONGANSWER; // RID failed } return PM3_SUCCESS; @@ -529,7 +529,7 @@ int readTopazUid(bool verbose) { return PM3_ESOFT; } - if (status == PM3_EWRONGANSVER) { + if (status == PM3_EWRONGANSWER) { if (verbose) PrintAndLogEx(ERR, "Error: tag didn't answer to RID"); topaz_switch_off_field(); return PM3_ESOFT; diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index cb48188a0..487d5eb2b 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -20,6 +20,7 @@ #include "ui.h" #include "cmdhw.h" #include "cmddata.h" +#include "commonutil.h" static int CmdHelp(const char *Cmd); @@ -579,7 +580,7 @@ static int CmdConnect(const char *Cmd) { // default back to previous used serial port if (strlen(port) == 0) { - if (strlen((char *)conn.serial_port_name) == 0) { + if (strlen(conn.serial_port_name) == 0) { return usage_hw_connect(); } memcpy(port, conn.serial_port_name, sizeof(port)); @@ -661,10 +662,10 @@ void pm3_version(bool verbose, bool oneliner) { # define PM3HOSTOS " OS:OpenBSD" #elif defined(__CYGWIN__) # define PM3HOSTOS " OS:Cygwin" -#elif defined(_WIN64) | defined(__WIN64__) +#elif defined(_WIN64) || defined(__WIN64__) // must be tested before _WIN32 # define PM3HOSTOS " OS:Windows (64b)" -#elif defined(_WIN32) | defined(__WIN32__) +#elif defined(_WIN32) || defined(__WIN32__) # define PM3HOSTOS " OS:Windows (32b)" #else # define PM3HOSTOS " OS:unknown" @@ -688,7 +689,9 @@ void pm3_version(bool verbose, bool oneliner) { if (oneliner) { // For "proxmark3 -v", simple printf, avoid logging - printf("Client: RRG/Iceman compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH "\n"); + char temp[PM3_CMD_DATA_SIZE - 12]; // same limit as for ARM image + FormatVersionInformation(temp, sizeof(temp), "Client: ", &version_information); + printf("%s compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH "\n", temp); return; } @@ -701,9 +704,11 @@ void pm3_version(bool verbose, bool oneliner) { SendCommandNG(CMD_VERSION, NULL, 0); if (WaitForResponseTimeout(CMD_VERSION, &resp, 1000)) { + char temp[PM3_CMD_DATA_SIZE - 12]; // same limit as for ARM image PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ Proxmark3 RFID instrument ]")); PrintAndLogEx(NORMAL, "\n " _YELLOW_("[ CLIENT ]")); - PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? + FormatVersionInformation(temp, sizeof(temp), " client: ", &version_information); + PrintAndLogEx(NORMAL, "%s", temp); PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH); if (IfPm3Flash() == false && IfPm3Smartcard() == false && IfPm3FpcUsartHost() == false) { diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 1443a5d6a..9403dc208 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -25,6 +25,7 @@ #include "lfdemod.h" // device/client demods of LF signals #include "ui.h" // for show graph controls +#include "proxgui.h" #include "graph.h" // for graph data #include "cmddata.h" // for `lf search` #include "cmdlfawid.h" // for awid menu @@ -54,7 +55,7 @@ #include "cmdlfmotorola.h" // for Motorola menu #include "cmdlfgallagher.h" // for GALLAGHER menu -bool g_lf_threshold_set = false; +static bool g_lf_threshold_set = false; static int CmdHelp(const char *Cmd); @@ -669,7 +670,7 @@ int CmdLFSniff(const char *Cmd) { return PM3_SUCCESS; } -static void ChkBitstream() { +static void ChkBitstream(void) { // convert to bitstream if necessary for (int i = 0; i < (int)(GraphTraceLen / 2); i++) { if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) { @@ -702,6 +703,8 @@ int CmdLFSim(const char *Cmd) { PrintAndLogEx(DEBUG, "DEBUG: Uploading %zu bytes", GraphTraceLen); + PacketResponseNG resp; + struct pupload { uint8_t flag; uint16_t offset; @@ -726,9 +729,12 @@ int CmdLFSim(const char *Cmd) { for (uint16_t j = 0; j < len; j++) payload_up.data[j] = GraphBuffer[i + j]; - SendCommandNG(CMD_LF_UPLOAD_SIM_SAMPLES, (uint8_t *)&payload_up, sizeof(struct pupload)); - WaitForResponse(CMD_LF_UPLOAD_SIM_SAMPLES, NULL); + WaitForResponse(CMD_LF_UPLOAD_SIM_SAMPLES, &resp); + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(INFO, "Bigbuf is full."); + break; + } printf("."); fflush(stdout); payload_up.flag = 0; @@ -750,7 +756,6 @@ int CmdLFSim(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_LF_SIMULATE, (uint8_t *)&payload, sizeof(payload)); - PacketResponseNG resp; WaitForResponse(CMD_LF_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); @@ -1339,6 +1344,7 @@ out: // identify chipset if (CheckChipType(isOnline) == false) { PrintAndLogEx(DEBUG, "Automatic chip type detection " _RED_("failed")); + retval = false; } return retval; } diff --git a/client/src/cmdlfem4x.c b/client/src/cmdlfem4x.c index 734626700..ebb3fe2e4 100644 --- a/client/src/cmdlfem4x.c +++ b/client/src/cmdlfem4x.c @@ -24,12 +24,13 @@ #include "util_posix.h" #include "protocols.h" #include "ui.h" +#include "proxgui.h" #include "graph.h" #include "cmddata.h" #include "cmdlf.h" #include "lfdemod.h" -uint64_t g_em410xid = 0; +static uint64_t g_em410xid = 0; static int CmdHelp(const char *Cmd); @@ -930,11 +931,11 @@ int EM4x50Read(const char *Cmd, bool verbose) { // report back if (verbose || g_debugMode) { if (start >= 0) { - PrintAndLogEx(NORMAL, "\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)"); + PrintAndLogEx(INFO, "\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)"); } else { - PrintAndLogEx(NORMAL, "No data found!, clock tried: " _YELLOW_("%d"), clk); - PrintAndLogEx(NORMAL, "Try again with more samples."); - PrintAndLogEx(NORMAL, " or after a " _YELLOW_("'data askedge'") " command to clean up the read"); + PrintAndLogEx(INFO, "No data found!, clock tried: " _YELLOW_("%d"), clk); + PrintAndLogEx(HINT, "Try again with more samples"); + PrintAndLogEx(HINT, " or after a " _YELLOW_("'data askedge'") " command to clean up the read"); return PM3_ESOFT; } } else if (start < 0) { @@ -1001,20 +1002,22 @@ int EM4x50Read(const char *Cmd, bool verbose) { //print full code: if (verbose || g_debugMode || AllPTest) { if (!complete) { - PrintAndLogEx(NORMAL, _RED_("* **Warning!")); - PrintAndLogEx(NORMAL, "Partial data - no end found!"); - PrintAndLogEx(NORMAL, "Try again with more samples."); + PrintAndLogEx(WARNING, _RED_("* **Warning!")); + PrintAndLogEx(INFO, "Partial data - no end found!"); + PrintAndLogEx(HINT, "Try again with more samples."); } - PrintAndLogEx(NORMAL, "Found data at sample: %i - using clock: %i", start, clk); + PrintAndLogEx(INFO, "Found data at sample: %i - using clock: %i", start, clk); end = block; + PrintAndLogEx(INFO, "blk | data"); + PrintAndLogEx(INFO, "----+--------------"); for (block = 0; block < end; block++) { - PrintAndLogEx(NORMAL, "Block %d: %08x", block, Code[block]); + PrintAndLogEx(INFO, "%03d | %08x", block, Code[block]); } - - PrintAndLogEx(NORMAL, "Parities checks | %s", (AllPTest) ? _GREEN_("Passed") : _RED_("Fail")); + PrintAndLogEx(INFO, "----+--------------"); + PrintAndLogEx( (AllPTest) ? SUCCESS : WARNING, "Parities checks | %s", (AllPTest) ? _GREEN_("Passed") : _RED_("Fail")); if (AllPTest == false) { - PrintAndLogEx(NORMAL, "Try cleaning the read samples with " _YELLOW_("'data askedge'")); + PrintAndLogEx(HINT, "Try cleaning the read samples with " _YELLOW_("'data askedge'")); } } @@ -1054,7 +1057,7 @@ static int CmdEM4x50Dump(const char *Cmd) { #define EM_PREAMBLE_LEN 6 // download samples from device and copy to Graphbuffer -static bool downloadSamplesEM() { +static bool downloadSamplesEM(void) { // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples) uint8_t got[6000]; @@ -1096,7 +1099,7 @@ static bool doPreambleSearch(size_t *startIdx) { return true; } -static bool detectFSK() { +static bool detectFSK(void) { // detect fsk clock if (GetFskClock("", false) == 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - EM: FSK clock failed"); @@ -1111,7 +1114,7 @@ static bool detectFSK() { return true; } // PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... ) -static bool detectPSK() { +static bool detectPSK(void) { int ans = GetPskClock("", false); if (ans <= 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - EM: PSK clock failed"); @@ -1135,7 +1138,7 @@ static bool detectPSK() { return true; } // try manchester - NOTE: ST only applies to T55x7 tags. -static bool detectASK_MAN() { +static bool detectASK_MAN(void) { bool stcheck = false; if (ASKDemod_ext("0 0 0", false, false, 1, &stcheck) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/Manchester Demod failed"); @@ -1144,7 +1147,7 @@ static bool detectASK_MAN() { return true; } -static bool detectASK_BI() { +static bool detectASK_BI(void) { int ans = ASKbiphaseDemod("0 0 1", false); if (ans != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/biphase normal demod failed"); @@ -1157,7 +1160,7 @@ static bool detectASK_BI() { } return true; } -static bool detectNRZ() { +static bool detectNRZ(void) { int ans = NRZrawDemod("0 0 1", false); if (ans != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - EM: NRZ normal demod failed"); @@ -1606,21 +1609,21 @@ static void printEM4x05config(uint32_t wordData) { uint8_t disable = (wordData & EM4x05_DISABLE_ALLOWED) >> 23; uint8_t rtf = (wordData & EM4x05_READER_TALK_FIRST) >> 24; uint8_t pigeon = (wordData & (1 << 26)) >> 26; - PrintAndLogEx(NORMAL, "ConfigWord: %08X (Word 4)\n", wordData); - PrintAndLogEx(NORMAL, "Config Breakdown:"); - PrintAndLogEx(NORMAL, " Data Rate: %02u | "_YELLOW_("RF/%u"), wordData & 0x3F, datarate); - PrintAndLogEx(NORMAL, " Encoder: %u | " _YELLOW_("%s"), encoder, enc); - PrintAndLogEx(NORMAL, " PSK CF: %u | %s", PSKcf, cf); - PrintAndLogEx(NORMAL, " Delay: %u | %s", delay, cdelay); - PrintAndLogEx(NORMAL, " LastWordR: %02u | Address of last word for default read - meaning %u blocks are output", LWR, numblks); - PrintAndLogEx(NORMAL, " ReadLogin: %u | Read login is %s", readLogin, readLogin ? _YELLOW_("required") : _GREEN_("not required")); - PrintAndLogEx(NORMAL, " ReadHKL: %u | Read housekeeping words login is %s", readHKL, readHKL ? _YELLOW_("required") : _GREEN_("not required")); - PrintAndLogEx(NORMAL, "WriteLogin: %u | Write login is %s", writeLogin, writeLogin ? _YELLOW_("required") : _GREEN_("not required")); - PrintAndLogEx(NORMAL, " WriteHKL: %u | Write housekeeping words login is %s", writeHKL, writeHKL ? _YELLOW_("required") : _GREEN_("not Required")); - PrintAndLogEx(NORMAL, " R.A.W.: %u | Read after write is %s", raw, raw ? "on" : "off"); - PrintAndLogEx(NORMAL, " Disable: %u | Disable command is %s", disable, disable ? "accepted" : "not accepted"); - PrintAndLogEx(NORMAL, " R.T.F.: %u | Reader talk first is %s", rtf, rtf ? _YELLOW_("enabled") : "disabled"); - PrintAndLogEx(NORMAL, " Pigeon: %u | Pigeon mode is %s\n", pigeon, pigeon ? _YELLOW_("enabled") : "disabled"); + PrintAndLogEx(INFO, "ConfigWord: %08X (Word 4)\n", wordData); + PrintAndLogEx(INFO, "Config Breakdown:"); + PrintAndLogEx(INFO, " Data Rate: %02u | "_YELLOW_("RF/%u"), wordData & 0x3F, datarate); + PrintAndLogEx(INFO, " Encoder: %u | " _YELLOW_("%s"), encoder, enc); + PrintAndLogEx(INFO, " PSK CF: %u | %s", PSKcf, cf); + PrintAndLogEx(INFO, " Delay: %u | %s", delay, cdelay); + PrintAndLogEx(INFO, " LastWordR: %02u | Address of last word for default read - meaning %u blocks are output", LWR, numblks); + PrintAndLogEx(INFO, " ReadLogin: %u | Read login is %s", readLogin, readLogin ? _YELLOW_("required") : _GREEN_("not required")); + PrintAndLogEx(INFO, " ReadHKL: %u | Read housekeeping words login is %s", readHKL, readHKL ? _YELLOW_("required") : _GREEN_("not required")); + PrintAndLogEx(INFO, "WriteLogin: %u | Write login is %s", writeLogin, writeLogin ? _YELLOW_("required") : _GREEN_("not required")); + PrintAndLogEx(INFO, " WriteHKL: %u | Write housekeeping words login is %s", writeHKL, writeHKL ? _YELLOW_("required") : _GREEN_("not Required")); + PrintAndLogEx(INFO, " R.A.W.: %u | Read after write is %s", raw, raw ? "on" : "off"); + PrintAndLogEx(INFO, " Disable: %u | Disable command is %s", disable, disable ? "accepted" : "not accepted"); + PrintAndLogEx(INFO, " R.T.F.: %u | Reader talk first is %s", rtf, rtf ? _YELLOW_("enabled") : "disabled"); + PrintAndLogEx(INFO, " Pigeon: %u | Pigeon mode is %s\n", pigeon, pigeon ? _YELLOW_("enabled") : "disabled"); } static void printEM4x05info(uint32_t block0, uint32_t serial) { @@ -1649,36 +1652,36 @@ static void printEM4x05info(uint32_t block0, uint32_t serial) { snprintf(ctstr + strlen(ctstr), sizeof(ctstr) - strlen(ctstr), _YELLOW_("%s"), "Unknown"); break; } - PrintAndLogEx(NORMAL, "%s", ctstr); + PrintAndLogEx(SUCCESS, "%s", ctstr); switch (cap) { case 3: - PrintAndLogEx(NORMAL, " Cap Type: %u | 330pF", cap); + PrintAndLogEx(SUCCESS, " Cap Type: %u | 330pF", cap); break; case 2: - PrintAndLogEx(NORMAL, " Cap Type: %u | %spF", cap, (chipType == 2) ? "75" : "210"); + PrintAndLogEx(SUCCESS, " Cap Type: %u | %spF", cap, (chipType == 2) ? "75" : "210"); break; case 1: - PrintAndLogEx(NORMAL, " Cap Type: %u | 250pF", cap); + PrintAndLogEx(SUCCESS, " Cap Type: %u | 250pF", cap); break; case 0: - PrintAndLogEx(NORMAL, " Cap Type: %u | no resonant capacitor", cap); + PrintAndLogEx(SUCCESS, " Cap Type: %u | no resonant capacitor", cap); break; default: - PrintAndLogEx(NORMAL, " Cap Type: %u | unknown", cap); + PrintAndLogEx(SUCCESS, " Cap Type: %u | unknown", cap); break; } - PrintAndLogEx(NORMAL, " Cust Code: %03u | %s", custCode, (custCode == 0x200) ? "Default" : "Unknown"); + PrintAndLogEx(SUCCESS, " Cust Code: %03u | %s", custCode, (custCode == 0x200) ? "Default" : "Unknown"); if (serial != 0) - PrintAndLogEx(NORMAL, "\n Serial #: " _YELLOW_("%08X") "\n", serial); + PrintAndLogEx(SUCCESS, "\n Serial #: " _YELLOW_("%08X"), serial); } static void printEM4x05ProtectionBits(uint32_t word) { for (uint8_t i = 0; i < 15; i++) { - PrintAndLogEx(NORMAL, " Word: %02u | %s", i, (((1 << i) & word) || i < 2) ? _RED_("write Locked") : "unlocked"); + PrintAndLogEx(INFO, " Word: %02u | %s", i, (((1 << i) & word) || i < 2) ? _RED_("write Locked") : "unlocked"); if (i == 14) - PrintAndLogEx(NORMAL, " Word: %02u | %s", i + 1, (((1 << i) & word) || i < 2) ? _RED_("write locked") : "unlocked"); + PrintAndLogEx(INFO, " Word: %02u | %s", i + 1, (((1 << i) & word) || i < 2) ? _RED_("write locked") : "unlocked"); } } diff --git a/client/src/cmdlffdx.c b/client/src/cmdlffdx.c index 93420ac28..c9af2fffc 100644 --- a/client/src/cmdlffdx.c +++ b/client/src/cmdlffdx.c @@ -62,6 +62,7 @@ static int usage_lf_fdx_clone(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf fdx clone 999 112233"); + PrintAndLogEx(NORMAL, " lf fdx clone 999 112233 16a"); return PM3_SUCCESS; } @@ -78,19 +79,34 @@ static int usage_lf_fdx_sim(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf fdx sim 999 112233"); + PrintAndLogEx(NORMAL, " lf fdx sim 999 112233 16a"); return PM3_SUCCESS; } // clearing the topbit needed for the preambl detection. -static void verify_values(uint64_t *animalid, uint32_t *countryid) { +static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *extended) { if ((*animalid & 0x3FFFFFFFFF) != *animalid) { *animalid &= 0x3FFFFFFFFF; - PrintAndLogEx(INFO, "Animal ID Truncated to 38bits: %"PRIx64, *animalid); + PrintAndLogEx(INFO, "Animal ID truncated to 38bits: " _YELLOW_("%"PRIx64), *animalid); } if ((*countryid & 0x3ff) != *countryid) { *countryid &= 0x3ff; - PrintAndLogEx(INFO, "Country ID Truncated to 10bits: %03d", *countryid); + PrintAndLogEx(INFO, "Country ID truncated to 10bits:" _YELLOW_("%03d"), *countryid); } + if ((*extended & 0xfff) != *extended) { + *extended &= 0xfff; + PrintAndLogEx(INFO, "Extended truncated to 24bits: " _YELLOW_("0x%03X"), *extended); + } +} + +static inline uint32_t bitcount(uint32_t a) { +#if defined __GNUC__ + return __builtin_popcountl(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24; +#endif } // FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) @@ -187,9 +203,7 @@ static int CmdFDXBdemodBI(const char *Cmd) { //see ASKDemod for what args are accepted //almost the same demod as cmddata.c/CmdFDXBdemodBI -static int CmdFdxDemod(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - +int demodFDX(void) { //Differential Biphase / di-phase (inverted biphase) //get binary from ask wave if (ASKbiphaseDemod("0 32 1 100", false) != PM3_SUCCESS) { @@ -234,8 +248,8 @@ static int CmdFdxDemod(const char *Cmd) { num_to_bytes(rawid, 8, raw); PrintAndLogEx(SUCCESS, "\nFDX-B / ISO 11784/5 Animal Tag ID Found: Raw : %s", sprint_hex(raw, 8)); - PrintAndLogEx(SUCCESS, "Animal ID %04u-%012" PRIu64, countryCode, NationalCode); - PrintAndLogEx(SUCCESS, "National Code %012" PRIu64 " (0x%" PRIx64 ")", NationalCode, NationalCode); + PrintAndLogEx(SUCCESS, "Animal ID " _GREEN_("%04u-%012"PRIu64), countryCode, NationalCode); + PrintAndLogEx(SUCCESS, "National Code " _GREEN_("%012" PRIu64) " (0x%" PRIx64 ")", NationalCode, NationalCode); PrintAndLogEx(SUCCESS, "Country Code %04u", countryCode); PrintAndLogEx(SUCCESS, "Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); PrintAndLogEx(SUCCESS, "Animal Tag %s", animalBit ? _YELLOW_("True") : "False"); @@ -243,7 +257,7 @@ static int CmdFdxDemod(const char *Cmd) { uint8_t c[] = {0, 0}; compute_crc(CRC_11784, raw, sizeof(raw), &c[0], &c[1]); - PrintAndLogEx(SUCCESS, "CRC-16 0x%04X [%s] ", crc, (crc == (c[1] << 8 | c[0])) ? _GREEN_("OK") : _RED_("Fail")); + PrintAndLogEx(SUCCESS, "CRC-16 0x%04X (%s) ", crc, (crc == (c[1] << 8 | c[0])) ? _GREEN_("ok") : _RED_("fail")); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %zu", preambleIndex, size); @@ -251,12 +265,30 @@ static int CmdFdxDemod(const char *Cmd) { PrintAndLogEx(DEBUG, "DEBUG bin stream:\n%s", bin); } + uint8_t bt_par = (extended & 0x100) >> 8; + uint8_t bt_temperature = extended & 0xff; + uint8_t bt_calc_parity = (bitcount(bt_temperature) & 0x1) ? 0 : 1; + uint8_t is_bt_temperature = (bt_calc_parity == bt_par) && !(extended & 0xe00) ; + + if (is_bt_temperature) { + float bt_F = 74 + bt_temperature * 0.2; + float bt_C = (bt_F - 32) / 1.8; + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Bio-Thermo detected"); + PrintAndLogEx(INFO, " temperature " _GREEN_("%.1f")" F / " _GREEN_("%.1f") " C", bt_F, bt_C); + } + // set block 0 for later //g_DemodConfig = T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT; return PM3_SUCCESS; } +static int CmdFdxDemod(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + return demodFDX(); +} + static int CmdFdxRead(const char *Cmd) { lf_read(false, 10000); return CmdFdxDemod(Cmd); @@ -272,9 +304,9 @@ static int CmdFdxClone(const char *Cmd) { countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); - extended = param_get32ex(Cmd, 2, 0, 10); + extended = param_get32ex(Cmd, 2, 0, 16); - verify_values(&animalid, &countryid); + verify_values(&animalid, &countryid, &extended); uint8_t *bits = calloc(128, sizeof(uint8_t)); @@ -298,7 +330,7 @@ static int CmdFdxClone(const char *Cmd) { free(bits); - PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); + PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: " _GREEN_("%04u-%"PRIu64)" (extended 0x%X)", countryid, animalid, extended); print_blocks(blocks, ARRAYLEN(blocks)); int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); @@ -316,11 +348,11 @@ static int CmdFdxSim(const char *Cmd) { countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); - extended = param_get32ex(Cmd, 2, 0, 10); + extended = param_get32ex(Cmd, 2, 0, 16); - verify_values(&animalid, &countryid); + verify_values(&animalid, &countryid, &extended); - PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: %04u-%"PRIu64, countryid, animalid); + PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: " _GREEN_("%04u-%"PRIu64)" (extended 0x%X)", countryid, animalid, extended); //getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) uint8_t *bits = calloc(128, sizeof(uint8_t)); @@ -389,10 +421,6 @@ int detectFDXB(uint8_t *dest, size_t *size) { return (int)startIdx; } -int demodFDX(void) { - return CmdFdxDemod(""); -} - int getFDXBits(uint64_t national_id, uint16_t country, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits) { // add preamble ten 0x00 and one 0x01 diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 47971c713..b05405465 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -22,7 +22,7 @@ static int CmdHelp(const char *Cmd); -static char *getHitagTypeStr(uint32_t uid) { +static const char *getHitagTypeStr(uint32_t uid) { //uid s/n ******** uint8_t type = (uid >> 4) & 0xF; switch (type) { @@ -330,7 +330,7 @@ static int CmdLFHitagSim(const char *Cmd) { break; case 'j': param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - res = loadFileJSON(filename, data, maxdatalen, &datalen); + res = loadFileJSON(filename, data, maxdatalen, &datalen, NULL); if (res > 0) { errors = true; break; @@ -363,7 +363,7 @@ static int CmdLFHitagSim(const char *Cmd) { clearCommandBuffer(); if (tag_mem_supplied) { - SendCommandOLD(cmd, 1, 0, 0, data, datalen); + SendCommandMIX(cmd, 1, 0, 0, data, datalen); } else { SendCommandMIX(cmd, 0, 0, 0, NULL, 0); } @@ -572,10 +572,12 @@ static int CmdLFHitagReader(const char *Cmd) { // No additional parameters needed break; } + case RHT1F_PLAIN: + case RHT1F_AUTHENTICATE: case WHTSF_CHALLENGE: case WHTSF_KEY: + case WHT2F_PASSWORD: case WHT2F_CRYPTO: - default: return usage_hitag_reader(); } @@ -678,6 +680,8 @@ static int CmdLFHitagWriter(const char *Cmd) { num_to_bytes(param_get32ex(Cmd, 3, 0, 16), 4, htd.crypto.data); break; } + case RHT1F_PLAIN: + case RHT1F_AUTHENTICATE: case RHTSF_CHALLENGE: case RHTSF_KEY: case RHT2F_PASSWORD: @@ -685,12 +689,11 @@ static int CmdLFHitagWriter(const char *Cmd) { case RHT2F_CRYPTO: case RHT2F_TEST_AUTH_ATTEMPTS: case RHT2F_UID_ONLY: - default: return usage_hitag_writer(); } clearCommandBuffer(); - SendCommandOLD(CMD_LF_HITAGS_WRITE, htf, 0, arg2, &htd, sizeof(htd)); + SendCommandMIX(CMD_LF_HITAGS_WRITE, htf, 0, arg2, &htd, sizeof(htd)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); @@ -722,7 +725,7 @@ static int CmdLFHitag2Dump(const char *Cmd) { saveFile(filename, ".bin", data, 48); saveFileEML(filename, data, 48, 4); - saveFileJSON(filename, jsfHitag, data, 48); + saveFileJSON(filename, jsfHitag, data, 48, NULL); return PM3_SUCCESS; } diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index 69c1e5a55..6457bf671 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -22,6 +22,7 @@ #include "cliparser.h" #include "commonutil.h" #include "ui.h" // PrintAndLog +#include "proxgui.h" #include "lfdemod.h" // parityTest, bitbytes_to_byte #include "cmddata.h" #include "cmdlf.h" // lf_read @@ -559,7 +560,8 @@ static int CmdIndalaClone(const char *Cmd) { uint8_t fc = 0; uint16_t cn = 0; - CLIParserInit("lf indala clone", + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala clone", "clone INDALA tag to T55x7 (or to q5/T5555)", "Examples:\n" "\tlf indala clone --heden 888\n" @@ -577,28 +579,28 @@ static int CmdIndalaClone(const char *Cmd) { arg_int0("", "cn", "", "Cardnumber (26 bit format)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - is_long_uid = arg_get_lit(1); + is_long_uid = arg_get_lit(ctx, 1); // raw param - CLIGetHexWithReturn(3, data, &datalen); + CLIGetHexWithReturn(ctx, 3, data, &datalen); - is_t5555 = arg_get_lit(4); + is_t5555 = arg_get_lit(ctx, 4); if (is_long_uid == false) { // Heden param - cardnumber = arg_get_int_def(2, -1); + cardnumber = arg_get_int_def(ctx, 2, -1); got_cn = (cardnumber != -1); // 26b FC/CN param - fc = arg_get_int_def(5, 0); - cn = arg_get_int_def(6, 0); + fc = arg_get_int_def(ctx, 5, 0); + cn = arg_get_int_def(ctx, 6, 0); got_26 = (fc != 0 && cn != 0); } - CLIParserFree(); + CLIParserFree(ctx); if (is_long_uid) { // 224 BIT UID @@ -838,11 +840,12 @@ int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) { goto inv; } -inv: if (res == 0) { return -4; } +inv: + *invert ^= 1; if (*invert && idx > 0) { @@ -857,7 +860,7 @@ out: *size = found_size; - if (found_size != 224 && found_size != 64) { + if (found_size < 64) { PrintAndLogEx(INFO, "DEBUG: detectindala | %zu", found_size); return -5; } diff --git a/client/src/cmdlfjablotron.c b/client/src/cmdlfjablotron.c index 285ddca7d..3d586215e 100644 --- a/client/src/cmdlfjablotron.c +++ b/client/src/cmdlfjablotron.c @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -70,9 +69,9 @@ static uint64_t getJablontronCardId(uint64_t rawcode) { uint64_t id = 0; uint8_t bytes[] = {0, 0, 0, 0, 0}; num_to_bytes(rawcode, 5, bytes); - for (int i = 4, j = 0; i > -1; --i, j += 2) { - id += NIBBLE_LOW(bytes[i]) * (int)pow(10, j); - id += NIBBLE_HIGH(bytes[i]) * (int)pow(10, j + 1); + for (int i = 0; i < 5; i++) { + id *= 100; + id += NIBBLE_HIGH(bytes[i]) * 10 + NIBBLE_LOW(bytes[i]); } return id; } diff --git a/client/src/cmdlfkeri.c b/client/src/cmdlfkeri.c index 5e126955e..a26278f1c 100644 --- a/client/src/cmdlfkeri.c +++ b/client/src/cmdlfkeri.c @@ -269,19 +269,6 @@ static int CmdKeriClone(const char *Cmd) { } } - // this is managed in above code - // internalid = param_get32ex(Cmd, 0, 0, 10); - /* - // Q5 is caught in the while loop - //Q5 - if (tolower(param_getchar(Cmd, 1)) == 'q') { - blocks[0] = - T5555_MODULATION_PSK1 | - T5555_SET_BITRATE(128) | - T5555_PSK_RF_2 | - 2 << T5555_MAXBLOCK_SHIFT; - } - */ // Setup card data/build internal id switch (keritype) { case 'i' : // Internal ID @@ -390,7 +377,7 @@ int detectKeri(uint8_t *dest, size_t *size, bool *invert) { *invert ^= 1; } - if (*size != 64) return -3; //wrong demoded size + if (*size < 64) return -3; //wrong demoded size return (int)startIdx; } diff --git a/client/src/cmdlfmotorola.c b/client/src/cmdlfmotorola.c index 3db82a0be..fc2156c1a 100644 --- a/client/src/cmdlfmotorola.c +++ b/client/src/cmdlfmotorola.c @@ -150,7 +150,8 @@ static int CmdMotorolaClone(const char *Cmd) { uint8_t data[8]; int datalen = 0; - CLIParserInit("lf indala clone", + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala clone", "Enables cloning of Motorola card with specified uid onto T55x7\n" "defaults to 64.\n", "\n" @@ -163,9 +164,9 @@ static int CmdMotorolaClone(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); - CLIGetHexWithReturn(1, data, &datalen); - CLIParserFree(); + CLIExecWithReturn(ctx, Cmd, argtable, false); + CLIGetHexWithReturn(ctx, 1, data, &datalen); + CLIParserFree(ctx); //TODO add selection of chip for Q5 or T55x7 // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; diff --git a/client/src/cmdlfnedap.c b/client/src/cmdlfnedap.c index cb0b11629..c748a262a 100644 --- a/client/src/cmdlfnedap.c +++ b/client/src/cmdlfnedap.c @@ -95,7 +95,9 @@ static inline uint32_t bitcount(uint32_t a) { } static uint8_t isEven_64_63(const uint8_t *data) { // 8 - return (bitcount(*(uint32_t *) data) + (bitcount((*(uint32_t *)(data + 4)) & 0xfeffffff))) & 1; + uint32_t tmp[2]; + memcpy(tmp, data, 8); + return (bitcount(tmp[0]) + (bitcount(tmp[1] & 0xfeffffff))) & 1; } //NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream) @@ -163,14 +165,14 @@ static int CmdLFNedapDemod(const char *Cmd) { buffer[6] = (data[3] << 7) | ((data[4] & 0xe0) >> 1) | ((data[4] & 0x01) << 3) | ((data[5] & 0xe0) >> 5); buffer[5] = (data[5] << 7) | ((data[6] & 0xe0) >> 1) | ((data[6] & 0x01) << 3) | ((data[7] & 0xe0) >> 5); - - bool isValid = (checksum == *(uint16_t *)(buffer + 5)); + uint16_t checksum2 = (buffer[6] << 8) + buffer[5]; + bool isValid = (checksum == checksum2); subtype = (data[1] & 0x1e) >> 1; customerCode = ((data[1] & 0x01) << 11) | (data[2] << 3) | ((data[3] & 0xe0) >> 5); if (isValid == false) { - PrintAndLogEx(ERR, "Checksum : %s (calc 0x%04X != 0x%04X)", _RED_("failed"), checksum, *(uint16_t *)(buffer + 5)); + PrintAndLogEx(ERR, "Checksum : %s (calc 0x%04X != 0x%04X)", _RED_("failed"), checksum, checksum2); ret = PM3_ESOFT; } diff --git a/client/src/cmdlfnexwatch.c b/client/src/cmdlfnexwatch.c index c5d168a7c..fbf2d55eb 100644 --- a/client/src/cmdlfnexwatch.c +++ b/client/src/cmdlfnexwatch.c @@ -24,38 +24,133 @@ #include "protocols.h" // t55xx defines #include "cmdlft55xx.h" // clone.. +typedef enum { + SCRAMBLE, + DESCRAMBLE +} NexWatchScramble_t; + static int CmdHelp(const char *Cmd); static int usage_lf_nexwatch_clone(void) { PrintAndLogEx(NORMAL, "clone a Nexwatch tag to a T55x7 tag."); + PrintAndLogEx(NORMAL, "You can use raw hex values or create a credential based on id, mode"); + PrintAndLogEx(NORMAL, "and type of credential (Nexkey/Quadrakey)"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf nexwatch clone [h] [b ]"); + PrintAndLogEx(NORMAL, "Usage: lf nexwatch clone [h] [b ] [c ] [m ] [n|q]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, " r : raw hex data. 16 bytes max"); + PrintAndLogEx(NORMAL, " r : raw hex data. 12 bytes max"); + PrintAndLogEx(NORMAL, " c : card id (decimal)"); + PrintAndLogEx(NORMAL, " m : mode (decimal) (0-15, defaults to 1)"); + PrintAndLogEx(NORMAL, " n : Nexkey credential"); + PrintAndLogEx(NORMAL, " q : Quadrakey credential"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf nexwatch clone r 5600000000213C9F8F150C0000000000"); + PrintAndLogEx(NORMAL, " lf nexwatch clone r 5600000000213C9F8F150C"); + PrintAndLogEx(NORMAL, " lf nexwatch clone c 521512301 m 1 n -- Nexkey credential"); + PrintAndLogEx(NORMAL, " lf nexwatch clone c 521512301 m 1 q -- Quadrakey credential"); return PM3_SUCCESS; } static int usage_lf_nexwatch_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of Nexwatch card"); + PrintAndLogEx(NORMAL, "You can use raw hex values or create a credential based on id, mode"); + PrintAndLogEx(NORMAL, "and type of credential (Nexkey/Quadrakey)"); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf nexwatch sim [h] "); + PrintAndLogEx(NORMAL, "Usage: lf nexwatch sim [h] [c ] [m ] [n|q]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " r : raw hex data. 16 bytes max"); + PrintAndLogEx(NORMAL, " c : card id (decimal)"); + PrintAndLogEx(NORMAL, " m : mode (decimal) (0-15, defaults to 1)"); + PrintAndLogEx(NORMAL, " n : Nexkey credential"); + PrintAndLogEx(NORMAL, " q : Quadrakey credential"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf nexwatch sim r 5600000000213C9F8F150C0000000000"); + PrintAndLogEx(NORMAL, " lf nexwatch sim r 5600000000213C9F8F150C"); + PrintAndLogEx(NORMAL, " lf nexwatch sim c 521512301 m 1 n -- Nexkey credential"); + PrintAndLogEx(NORMAL, " lf nexwatch sim c 521512301 m 1 q -- Quadrakey credential"); return PM3_SUCCESS; } -static int CmdNexWatchDemod(const char *Cmd) { - (void)Cmd; +// scramble parity (1234) -> (4231) +static uint8_t nexwatch_parity_swap(uint8_t parity) { + uint8_t a = (((parity >> 3) & 1)); + a |= (((parity >> 1) & 1) << 1); + a |= (((parity >> 2) & 1) << 2); + a |= ((parity & 1) << 3); + return a; +} +// parity check +// from 32b hex id, 4b mode, +static uint8_t nexwatch_parity(uint8_t hexid[5]) { + uint8_t p = 0; + for (uint8_t i = 0; i < 5; i++) { + p ^= NIBBLE_HIGH(hexid[i]); + p ^= NIBBLE_LOW(hexid[i]); + } + return nexwatch_parity_swap(p); +} +/// NETWATCH checksum +/// @param magic = 0xBE Quadrakey, 0x88 Nexkey +/// @param id = descrambled id (printed card number) +/// @param parity = the parity based upon the scrambled raw id. +static uint8_t nexwatch_checksum(uint8_t magic, uint32_t id, uint8_t parity) { + uint8_t a = ((id >> 24) & 0xFF); + a -= ((id >> 16) & 0xFF); + a -= ((id >> 8) & 0xFF); + a -= (id & 0xFF); + a -= magic; + a -= (reflect8(parity) >> 4); + return reflect8(a); +} + +// Scrambled id ( 88 bit cardnumber format) +// ref:: http://www.proxmark.org/forum/viewtopic.php?pid=14662#p14662 +static int nexwatch_scamble(NexWatchScramble_t action, uint32_t *id, uint32_t *scambled) { + + // 255 = Not used/Unknown other values are the bit offset in the ID/FC values + uint8_t hex_2_id [] = { + 31, 27, 23, 19, 15, 11, 7, 3, + 30, 26, 22, 18, 14, 10, 6, 2, + 29, 25, 21, 17, 13, 9, 5, 1, + 28, 24, 20, 16, 12, 8, 4, 0 + }; + + switch (action) { + case DESCRAMBLE: { + *id = 0; + for (uint8_t idx = 0; idx < 32; idx++) { + + if (hex_2_id[idx] == 255) + continue; + + bool bit_state = (*scambled >> hex_2_id[idx]) & 1; + *id |= (bit_state << (31 - idx)); + } + break; + } + case SCRAMBLE: { + *scambled = 0; + for (uint8_t idx = 0; idx < 32; idx++) { + + if (hex_2_id[idx] == 255) + continue; + + bool bit_state = (*id >> idx) & 1; + *scambled |= (bit_state << (31 - hex_2_id[idx])); + } + break; + } + default: + break; + } + return PM3_SUCCESS; +} + +int demodNexWatch(void) { if (PSKDemod("", false) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal"); return PM3_ESOFT; @@ -63,7 +158,7 @@ static int CmdNexWatchDemod(const char *Cmd) { bool invert = false; size_t size = DemodBufferLen; int idx = detectNexWatch(DemodBuffer, &size, &invert); - if (idx <= 0) { + if (idx < 0) { if (idx == -1) PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch not enough samples"); // else if (idx == -2) @@ -80,37 +175,95 @@ static int CmdNexWatchDemod(const char *Cmd) { return PM3_ESOFT; } - setDemodBuff(DemodBuffer, size, idx + 4); - setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 4) * g_DemodClock)); + // skip the 4 first bits from the nexwatch preamble identification (we use 4 extra zeros..) + idx += 4; -// idx = 8 + 32; // 8 = preamble, 32 = reserved bits (always 0) + setDemodBuff(DemodBuffer, size, idx); + setClockGrid(g_DemodClock, g_DemodStartIdx + (idx * g_DemodClock)); - //get ID - uint32_t ID = 0; - for (uint8_t k = 0; k < 4; k++) { - for (uint8_t m = 0; m < 8; m++) { - ID = (ID << 1) | DemodBuffer[m + k + (m * 4)]; - } - } - //parity check (TBD) - - //checksum check (TBD) - - //output - PrintAndLogEx(SUCCESS, "NexWatch ID: " _YELLOW_("%"PRIu32), ID); if (invert) { - PrintAndLogEx(INFO, "Had to Invert - probably NexKey"); + PrintAndLogEx(INFO, "Inverted the demodulated data"); for (size_t i = 0; i < size; i++) DemodBuffer[i] ^= 1; } - // bits to hex - CmdPrintDemodBuff("x"); - //PrintAndLogEx(INFO, "Raw: %s", sprint_hex_inrow(DemodBuffer, DemodBufferLen)); + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); + uint32_t raw3 = bytebits_to_byte(DemodBuffer + 32 + 32, 32); + // get rawid + uint32_t rawid = 0; + for (uint8_t k = 0; k < 4; k++) { + for (uint8_t m = 0; m < 8; m++) { + rawid = (rawid << 1) | DemodBuffer[m + k + (m * 4)]; + } + } + + // descrambled id + uint32_t cn = 0; + uint32_t scambled = bytebits_to_byte(DemodBuffer + 8 + 32, 32); + nexwatch_scamble(DESCRAMBLE, &cn, &scambled); + + uint8_t mode = bytebits_to_byte(DemodBuffer + 72, 4); + uint8_t parity = bytebits_to_byte(DemodBuffer + 76, 4); + uint8_t chk = bytebits_to_byte(DemodBuffer + 80, 8); + + // parity check + // from 32b hex id, 4b mode + uint8_t hex[5] = {0}; + for (uint8_t i = 0; i < 5; i++) { + hex[i] = bytebits_to_byte(DemodBuffer + 8 + 32 + (i * 8), 8); + } + // mode is only 4 bits. + hex[4] &= 0xf0; + uint8_t calc_parity = nexwatch_parity(hex); + + // Checksum + typedef struct { + uint8_t magic; + char desc[10]; + uint8_t chk; + } nexwatch_magic_t; + nexwatch_magic_t items[] = { {0xBE, "Quadrakey", 0}, {0x88, "Nexkey", 0} }; + + uint8_t m_idx; + for (m_idx = 0; m_idx < ARRAYLEN(items); m_idx++) { + + items[m_idx].chk = nexwatch_checksum(items[m_idx].magic, cn, calc_parity); + if (items[m_idx].chk == chk) { + break; + } + } + + // output + PrintAndLogEx(SUCCESS, " NexWatch raw id : " _YELLOW_("0x%"PRIx32), rawid); + + if (m_idx < ARRAYLEN(items)) { + PrintAndLogEx(SUCCESS, " fingerprint : " _GREEN_("%s"), items[m_idx].desc); + } + PrintAndLogEx(SUCCESS, " 88bit id : " _YELLOW_("%"PRIu32) " (" _YELLOW_("0x%"PRIx32)")", cn, cn); + PrintAndLogEx(SUCCESS, " mode : %x", mode); + if (parity == calc_parity) { + PrintAndLogEx(SUCCESS, " parity : %s (0x%X)", _GREEN_("ok"), parity); + } else { + PrintAndLogEx(WARNING, " parity : %s (0x%X != 0x%X)", _RED_("fail"), parity, calc_parity); + } + if (m_idx < ARRAYLEN(items)) { + PrintAndLogEx(SUCCESS, " checksum : %s (0x%02X)", _GREEN_("ok"), chk); + } else { + PrintAndLogEx(WARNING, " checksum : %s (0x%02X)", _RED_("fail"), chk); + } + + PrintAndLogEx(INFO, " raw : " _YELLOW_("%"PRIX32"%"PRIX32"%"PRIX32), raw1, raw2, raw3); return PM3_SUCCESS; } +static int CmdNexWatchDemod(const char *Cmd) { + (void)Cmd; + return demodNexWatch(); +} + //by marshmellow //see ASKDemod for what args are accepted static int CmdNexWatchRead(const char *Cmd) { @@ -120,29 +273,54 @@ static int CmdNexWatchRead(const char *Cmd) { static int CmdNexWatchClone(const char *Cmd) { - // 56000000 00213C9F 8F150C00 00000000 - uint32_t blocks[5]; + // 56000000 00213C9F 8F150C00 + uint32_t blocks[4]; + bool use_raw = false; bool errors = false; uint8_t cmdp = 0; int datalen = 0; + uint8_t magic = 0xBE; + uint32_t cn = 0; + uint8_t rawhex[12] = {0x56, 0}; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_nexwatch_clone(); case 'r': { - // skip first block, 4*4 = 16 bytes left - uint8_t rawhex[16] = {0}; int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen); if (res != 0) errors = true; - for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); - } + use_raw = true; cmdp += 2; break; } + case 'c': { + cn = param_get32ex(Cmd, cmdp + 1, 0, 10); + uint32_t scrambled; + nexwatch_scamble(SCRAMBLE, &cn, &scrambled); + num_to_bytes(scrambled, 4, rawhex + 5); + cmdp += 2; + break; + } + case 'm': { + uint8_t mode = param_get8ex(Cmd, cmdp + 1, 1, 10); + mode &= 0x0F; + rawhex[9] |= (mode << 4); + cmdp += 2; + break; + } + case 'n': { + magic = 0x88; + cmdp++; + break; + } + case 'q': { + magic = 0xBE; + cmdp++; + break; + } default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -153,7 +331,17 @@ static int CmdNexWatchClone(const char *Cmd) { if (errors || cmdp == 0) return usage_lf_nexwatch_clone(); //Nexwatch - compat mode, PSK, data rate 40, 3 data blocks - blocks[0] = T55x7_MODULATION_PSK1 | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT; + blocks[0] = T55x7_MODULATION_PSK1 | T55x7_BITRATE_RF_32 | 3 << T55x7_MAXBLOCK_SHIFT; + + if (use_raw == false) { + uint8_t parity = nexwatch_parity(rawhex + 5) & 0xF; + rawhex[9] |= parity; + rawhex[10] |= nexwatch_checksum(magic, cn, parity); + } + + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t)); + } PrintAndLogEx(INFO, "Preparing to clone NexWatch to T55x7 with raw hex"); print_blocks(blocks, ARRAYLEN(blocks)); @@ -168,9 +356,11 @@ static int CmdNexWatchSim(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; - int rawlen = 0; - uint8_t rawhex[16] = {0}; - uint32_t rawblocks[4]; + bool use_raw = false; + uint8_t rawhex[12] = {0x56, 0}; + int rawlen = sizeof(rawhex); + uint8_t magic = 0xBE; + uint32_t cn = 0; uint8_t bs[128]; memset(bs, 0, sizeof(bs)); @@ -183,9 +373,35 @@ static int CmdNexWatchSim(const char *Cmd) { if (res != 0) errors = true; + use_raw = true; cmdp += 2; break; } + case 'c': { + cn = param_get32ex(Cmd, cmdp + 1, 0, 10); + uint32_t scrambled; + nexwatch_scamble(SCRAMBLE, &cn, &scrambled); + num_to_bytes(scrambled, 4, rawhex + 5); + cmdp += 2; + break; + } + case 'm': { + uint8_t mode = param_get8ex(Cmd, cmdp + 1, 1, 10); + mode &= 0x0F; + rawhex[9] |= (mode << 4); + cmdp += 2; + break; + } + case 'n': { + magic = 0x88; + cmdp++; + break; + } + case 'q': { + magic = 0xBE; + cmdp++; + break; + } default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -195,7 +411,14 @@ static int CmdNexWatchSim(const char *Cmd) { if (errors || cmdp == 0) return usage_lf_nexwatch_sim(); + if (use_raw == false) { + uint8_t parity = nexwatch_parity(rawhex + 5) & 0xF; + rawhex[9] |= parity; + rawhex[10] |= nexwatch_checksum(magic, cn, parity); + } + // hex to bits. + uint32_t rawblocks[3]; for (size_t i = 0; i < ARRAYLEN(rawblocks); i++) { rawblocks[i] = bytes_to_num(rawhex + (i * sizeof(uint32_t)), sizeof(uint32_t)); num_to_bytebits(rawblocks[i], sizeof(uint32_t) * 8, bs + (i * sizeof(uint32_t) * 8)); @@ -247,7 +470,7 @@ int detectNexWatch(uint8_t *dest, size_t *size, bool *invert) { uint8_t preamble[28] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // sanity check. - if (*size < sizeof(preamble) + 100) return -1; + if (*size < 96) return -1; size_t startIdx = 0; @@ -261,8 +484,3 @@ int detectNexWatch(uint8_t *dest, size_t *size, bool *invert) { // size tests? return (int) startIdx; } - -int demodNexWatch(void) { - return CmdNexWatchDemod(""); -} - diff --git a/client/src/cmdlfpac.c b/client/src/cmdlfpac.c index abfb5483a..a8e0401af 100644 --- a/client/src/cmdlfpac.c +++ b/client/src/cmdlfpac.c @@ -130,8 +130,9 @@ static void pacCardIdToRaw(uint8_t *outRawBytes, const char *cardId) { pattern = reflect8(idbytes[i - 2]); pattern |= oddparity8(pattern); if (i > 3) checksum ^= idbytes[i - 2]; - } else - pattern = (reflect8(checksum) & 0xFE) | oddparity8(checksum); + } else { + pattern = (reflect8(checksum) & 0xFE) | (oddparity8(checksum)); + } pattern <<= shift; outRawBytes[index] |= pattern >> 8 & 0xFF; diff --git a/client/src/cmdlfpcf7931.c b/client/src/cmdlfpcf7931.c index 4c2c9848c..2062c8582 100644 --- a/client/src/cmdlfpcf7931.c +++ b/client/src/cmdlfpcf7931.c @@ -32,7 +32,7 @@ struct pcf7931_config configPcf = { }; // Resets the configuration settings to default values. -int pcf7931_resetConfig() { +int pcf7931_resetConfig(void) { memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd)); configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY; configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH; @@ -40,7 +40,7 @@ int pcf7931_resetConfig() { return PM3_SUCCESS; } -int pcf7931_printConfig() { +int pcf7931_printConfig(void) { PrintAndLogEx(NORMAL, "Password (LSB first on bytes) : %s", sprint_hex(configPcf.Pwd, sizeof(configPcf.Pwd))); PrintAndLogEx(NORMAL, "Tag initialization delay : %d us", configPcf.InitDelay); PrintAndLogEx(NORMAL, "Offset low pulses width : %d us", configPcf.OffsetWidth); @@ -48,7 +48,7 @@ int pcf7931_printConfig() { return PM3_SUCCESS; } -static int usage_pcf7931_read() { +static int usage_pcf7931_read(void) { PrintAndLogEx(NORMAL, "Usage: lf pcf7931 read [h] "); PrintAndLogEx(NORMAL, "This command tries to read a PCF7931 tag."); PrintAndLogEx(NORMAL, "Options:"); @@ -58,7 +58,7 @@ static int usage_pcf7931_read() { return PM3_SUCCESS; } -static int usage_pcf7931_write() { +static int usage_pcf7931_write(void) { PrintAndLogEx(NORMAL, "Usage: lf pcf7931 write [h] "); PrintAndLogEx(NORMAL, "This command tries to write a PCF7931 tag."); PrintAndLogEx(NORMAL, "Options:"); @@ -71,7 +71,7 @@ static int usage_pcf7931_write() { return PM3_SUCCESS; } -static int usage_pcf7931_config() { +static int usage_pcf7931_config(void) { PrintAndLogEx(NORMAL, "Usage: lf pcf7931 config [h] [r] "); PrintAndLogEx(NORMAL, "This command tries to set the configuration used with PCF7931 commands"); PrintAndLogEx(NORMAL, "The time offsets could be useful to correct slew rate generated by the antenna"); diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 6d384c33d..b2f048665 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -21,6 +21,7 @@ #include "comms.h" #include "commonutil.h" #include "protocols.h" +#include "proxgui.h" #include "graph.h" #include "cmddata.h" #include "lfdemod.h" @@ -28,7 +29,6 @@ #include "fileutils.h" // loadDictionary #include "util_posix.h" - // Some defines for readability #define T55XX_DLMODE_FIXED 0 // Default Mode #define T55XX_DLMODE_LLR 1 // Long Leading Reference @@ -54,9 +54,9 @@ t55xx_conf_block_t config = { .downlink_mode = refFixedBit }; -t55xx_memory_item_t cardmem[T55x7_BLOCK_COUNT] = {{0}}; +static t55xx_memory_item_t cardmem[T55x7_BLOCK_COUNT] = {{0}}; -t55xx_conf_block_t Get_t55xx_Config() { +t55xx_conf_block_t Get_t55xx_Config(void) { return config; } @@ -77,7 +77,7 @@ static void print_usage_t55xx_downloadlink(uint8_t ShowAll, uint8_t dl_mode_defa PrintAndLogEx(NORMAL, " 4 - Try all downlink modes%s", (dl_mode_default == 4) ? " (default)" : ""); } -static int usage_t55xx_config() { +static int usage_t55xx_config(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx config [c ] [d ] [i [0/1]] [o ] [Q5 [0/1]] [ST [0/1]]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - This help"); @@ -98,7 +98,7 @@ static int usage_t55xx_config() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_read() { +static int usage_t55xx_read(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r ] b [p ] [o] "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b - block number to read. Between 0-7"); @@ -118,7 +118,7 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_resetread() { +static int usage_t55xx_resetread(void) { PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"); PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r ]"); PrintAndLogEx(NORMAL, "Options:"); @@ -129,7 +129,7 @@ static int usage_t55xx_resetread() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_write() { +static int usage_t55xx_write(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t] [v]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " b - block number to write. Between 0-7"); @@ -147,7 +147,7 @@ static int usage_t55xx_write() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_trace() { +static int usage_t55xx_trace(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]"); PrintAndLogEx(NORMAL, "Options:"); print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); @@ -159,7 +159,7 @@ static int usage_t55xx_trace() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_info() { +static int usage_t55xx_info(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [c [q]]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " (default) - read data from tag."); @@ -179,7 +179,7 @@ static int usage_t55xx_info() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_dump() { +static int usage_t55xx_dump(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [p [o]]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); @@ -193,7 +193,7 @@ static int usage_t55xx_dump() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_restore() { +static int usage_t55xx_restore(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx restore f [p password]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " f - filename of the dump file (.bin/.eml)"); @@ -207,7 +207,7 @@ static int usage_t55xx_restore() { return PM3_SUCCESS; } -static int usage_t55xx_detect() { +static int usage_t55xx_detect(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [r ] [p ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); @@ -221,7 +221,7 @@ static int usage_t55xx_detect() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_detectP1() { +static int usage_t55xx_detectP1(void) { PrintAndLogEx(NORMAL, "Command: Detect Page 1 of a t55xx chip"); PrintAndLogEx(NORMAL, "Usage: lf t55xx p1detect [1] [r ] [p ]"); PrintAndLogEx(NORMAL, "Options:"); @@ -236,7 +236,7 @@ static int usage_t55xx_detectP1() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_wakup() { +static int usage_t55xx_wakup(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx wakeup [h] [r ] p "); PrintAndLogEx(NORMAL, "This commands sends the Answer-On-Request command and leaves the readerfield ON afterwards."); PrintAndLogEx(NORMAL, "Options:"); @@ -248,7 +248,7 @@ static int usage_t55xx_wakup() { PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); return PM3_SUCCESS; } -static int usage_t55xx_chk() { +static int usage_t55xx_chk(void) { PrintAndLogEx(NORMAL, "This command uses a dictionary attack"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may brick non-password protected chips!"); @@ -266,7 +266,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_bruteforce() { +static int usage_t55xx_bruteforce(void) { PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may brick non-password protected chips!"); @@ -284,7 +284,7 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_recoverpw() { +static int usage_t55xx_recoverpw(void) { PrintAndLogEx(NORMAL, "This command uses a few tricks to try to recover mangled password"); PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may brick non-password protected chips!"); @@ -305,7 +305,7 @@ static int usage_t55xx_recoverpw() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_wipe() { +static int usage_t55xx_wipe(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p ] [c ]"); PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block"); PrintAndLogEx(NORMAL, "Options:"); @@ -318,7 +318,7 @@ static int usage_t55xx_wipe() { PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a T5555 ( Q5 ) tag, config block 0x6001F004"); return PM3_SUCCESS; } -static int usage_t55xx_deviceconfig() { +static int usage_t55xx_deviceconfig(void) { PrintAndLogEx(NORMAL, "Sets t55x7 timings for direct commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device"); PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig [r ] a b c d e f g [p]"); PrintAndLogEx(NORMAL, "Options:"); @@ -339,7 +339,7 @@ static int usage_t55xx_deviceconfig() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_protect() { +static int usage_t55xx_protect(void) { PrintAndLogEx(NORMAL, "This command sets the pwd bit on T5577."); PrintAndLogEx(NORMAL, _RED_("WARNING:") " this locks the tag!"); PrintAndLogEx(NORMAL, "Usage: lf t55xx protect [r ] [p ] [o] [n ]"); @@ -355,7 +355,7 @@ static int usage_t55xx_protect() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_dangerraw() { +static int usage_t55xx_dangerraw(void) { PrintAndLogEx(NORMAL, "This command allows to emit arbitrary raw commands on T5577 and cut the field after arbitrary duration."); PrintAndLogEx(NORMAL, _RED_("WARNING:") " this may lock definitively the tag in an unusable state!"); PrintAndLogEx(NORMAL, "Uncontrolled usage can easily write an invalid configuration, activate lock bits,"); @@ -371,7 +371,7 @@ static int usage_t55xx_dangerraw() { return PM3_SUCCESS; } -static int usage_t55xx_clonehelp() { +static int usage_t55xx_clonehelp(void) { PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); PrintAndLogEx(NORMAL, _GREEN_("lf awid clone")); // todo: rename to clone @@ -407,13 +407,13 @@ static int CmdT55xxCloneHelp(const char *Cmd) { return usage_t55xx_clonehelp(); } -void T55x7_SaveBlockData(uint8_t idx, uint32_t data) { +static void T55x7_SaveBlockData(uint8_t idx, uint32_t data) { if (idx < T55x7_BLOCK_COUNT) { cardmem[idx].valid = true; cardmem[idx].blockdata = data; } } -void T55x7_ClearAllBlockData(void) { +static void T55x7_ClearAllBlockData(void) { for (uint8_t idx = 0; idx < T55x7_BLOCK_COUNT; idx++) { cardmem[idx].valid = false; cardmem[idx].blockdata = 0x00; @@ -611,7 +611,7 @@ bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, if (GetT55xxBlockData(&read_data) == false) return false; - } else if (res == PM3_EWRONGANSVER) { + } else if (res == PM3_EWRONGANSWER) { // could't decode. Lets see if this was a block 0 write and try read/detect it auto. // this messes up with ppls config.. @@ -852,7 +852,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u if (tryDetectModulation(downlink_mode, false) == false) { PrintAndLogEx(WARNING, "Safety check: Could not detect if PWD bit is set in config block. Exits."); - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; } else { PrintAndLogEx(WARNING, "Safety check: PWD bit is NOT set in config block. Reading without password..."); usepwd = false; @@ -867,7 +867,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u return PM3_ERFTRANS; if (DecodeT55xxBlock() == false) - return PM3_EWRONGANSVER; + return PM3_EWRONGANSWER; if (verbose) printT55xxBlock(block, page1); @@ -960,24 +960,14 @@ bool DecodeT55xxBlock(void) { ans = ASKDemod_ext(cmdStr, false, false, 1, &ST); break; case DEMOD_PSK1: - // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) - save_restoreGB(GRAPH_SAVE); - CmdLtrim("150"); snprintf(cmdStr, sizeof(buf), "%d %d 6", bitRate[config.bitrate], config.inverted); ans = PSKDemod(cmdStr, false); - //undo trim samples - save_restoreGB(GRAPH_RESTORE); break; case DEMOD_PSK2: //inverted won't affect this case DEMOD_PSK3: //not fully implemented - // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) - save_restoreGB(GRAPH_SAVE); - CmdLtrim("150"); snprintf(cmdStr, sizeof(buf), "%d 0 6", bitRate[config.bitrate]); ans = PSKDemod(cmdStr, false); psk1TOpsk2(DemodBuffer, DemodBufferLen); - //undo trim samples - save_restoreGB(GRAPH_RESTORE); break; case DEMOD_NRZ: snprintf(cmdStr, sizeof(buf), "%d %d 1", bitRate[config.bitrate], config.inverted); @@ -1010,7 +1000,7 @@ static int SanityOfflineCheck(bool useGraphBuffer) { return PM3_SUCCESS; } -void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { +static void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { char msg[80]; sprintf(msg, "Downlink Mode used : "); @@ -1598,17 +1588,18 @@ int special(const char *Cmd) { } int printConfiguration(t55xx_conf_block_t b) { - PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555 ( Q5 )" : "T55x7"); - PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation)); - PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); - PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Offset : %d", b.offset); - PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); - PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr(b.downlink_mode)); - PrintAndLogEx(NORMAL, " Password Set : %s", (b.usepwd) ? _RED_("Yes") : _GREEN_("No")); - if (b.usepwd) - PrintAndLogEx(NORMAL, " Password : %08X", b.pwd); + PrintAndLogEx(INFO, " Chip Type : " _GREEN_("%s"), (b.Q5) ? "T5555 ( Q5 )" : "T55x7"); + PrintAndLogEx(INFO, " Modulation : " _GREEN_("%s"), GetSelectedModulationStr(b.modulation)); + PrintAndLogEx(INFO, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); + PrintAndLogEx(INFO, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Offset : %d", b.offset); + PrintAndLogEx(INFO, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Block0 : 0x%08X", b.block0); + PrintAndLogEx(INFO, " Downlink Mode : %s", GetDownlinkModeStr(b.downlink_mode)); + PrintAndLogEx(INFO, " Password Set : %s", (b.usepwd) ? _RED_("Yes") : _GREEN_("No")); + if (b.usepwd) { + PrintAndLogEx(INFO, " Password : %08X", b.pwd); + } PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1618,7 +1609,7 @@ static int CmdT55xxWakeUp(const char *Cmd) { uint32_t password = 0; uint8_t cmdp = 0; bool errors = false; - uint8_t downlink_mode = config.downlink_mode;; + uint8_t downlink_mode = config.downlink_mode; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1674,7 +1665,7 @@ static int CmdT55xxWriteBlock(const char *Cmd) { bool errors = false; bool validate = false; uint8_t cmdp = 0; - uint32_t downlink_mode = config.downlink_mode;; + uint32_t downlink_mode = config.downlink_mode; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1814,7 +1805,7 @@ static int CmdT55xxDangerousRaw(const char *Cmd) { static int CmdT55xxReadTrace(const char *Cmd) { bool frombuff = false; - uint8_t downlink_mode = config.downlink_mode;; + uint8_t downlink_mode = config.downlink_mode; uint8_t cmdp = 0; bool errors = false; @@ -2180,7 +2171,7 @@ static int CmdT55xxInfo(const char *Cmd) { uint32_t datamod = (block0 >> (32 - 28)) & 0x07; uint32_t maxblk = (block0 >> (32 - 31)) & 0x07; uint32_t st = block0 & 0x01; - PrintAndLogEx(NORMAL, "-- Q5 Configuration & Tag Information -----------------------"); + PrintAndLogEx(NORMAL, "--- " _CYAN_("Q5 Configuration & Information") " ------------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, " Header : 0x%03X%s", header, (header != 0x600) ? _RED_(" - Warning") : ""); PrintAndLogEx(NORMAL, " Page select : %d", ps); @@ -2215,7 +2206,7 @@ static int CmdT55xxInfo(const char *Cmd) { uint32_t inv = (block0 >> (32 - 31)) & 0x01; uint32_t por = (block0 >> (32 - 32)) & 0x01; - PrintAndLogEx(NORMAL, "-- T55x7 Configuration & Tag Information --------------------"); + PrintAndLogEx(NORMAL, "--- " _CYAN_("T55x7 Configuration & Information") " ---------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, " Safer key : %s", GetSaferStr(safer)); PrintAndLogEx(NORMAL, " reserved : %d", resv); @@ -2251,7 +2242,7 @@ static int CmdT55xxDump(const char *Cmd) { uint32_t password = 0; uint8_t override = 0; - uint8_t downlink_mode = config.downlink_mode;; + uint8_t downlink_mode = config.downlink_mode; bool usepwd = false; bool errors = false; uint8_t cmdp = 0; @@ -2328,7 +2319,7 @@ static int CmdT55xxDump(const char *Cmd) { for (int i = 0; i < T55x7_BLOCK_COUNT; i++) data[i] = BSWAP_32(cardmem[i].blockdata); - saveFileJSON(preferredName, jsfT55x7, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t)); + saveFileJSON(preferredName, jsfT55x7, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), NULL); saveFileEML(preferredName, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), sizeof(uint32_t)); saveFile(preferredName, ".bin", data, sizeof(data)); } @@ -2454,7 +2445,7 @@ static int CmdT55xxRestore(const char *Cmd) { uint32_t password = 0; uint8_t override = 0; - uint8_t downlink_mode = config.downlink_mode;; + uint8_t downlink_mode = config.downlink_mode; bool usepwd = false; bool errors = false; uint8_t cmdp = 0; @@ -2537,7 +2528,7 @@ bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, u } char *GetPskCfStr(uint32_t id, bool q5) { - static char buf[25]; + static char buf[40]; char *retStr = buf; switch (id) { case 0: @@ -2808,7 +2799,7 @@ static void t55x7_create_config_block(int tagtype) { static int CmdResetRead(const char *Cmd) { - uint8_t downlink_mode = config.downlink_mode;; + uint8_t downlink_mode = config.downlink_mode; uint8_t flags = 0; uint8_t cmdp = 0; bool errors = false; @@ -2846,7 +2837,7 @@ static int CmdResetRead(const char *Cmd) { if (resp.status == PM3_SUCCESS) { - uint16_t gotsize = BIGBUF_SIZE - 1; + uint16_t gotsize = pm3_capabilities.bigbuf_size - 1; uint8_t *got = calloc(gotsize, sizeof(uint8_t)); if (got == NULL) { PrintAndLogEx(WARNING, "failed to allocate memory"); @@ -3054,7 +3045,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { } if (use_pwd_file) { - uint16_t keycount = 0; + uint32_t keycount = 0; int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 4, &keycount); if (res != PM3_SUCCESS || keycount == 0 || keyBlock == NULL) { @@ -3065,7 +3056,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { return PM3_ESOFT; } - for (uint16_t c = 0; c < keycount; ++c) { + for (uint32_t c = 0; c < keycount; ++c) { if (!session.pm3_present) { PrintAndLogEx(WARNING, "Device offline\n"); @@ -3627,7 +3618,7 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { } clearCommandBuffer(); - SendCommandOLD(CMD_LF_T55XX_SET_CONFIG, shall_persist, 0, 0, &configurations, sizeof(t55xx_configurations_t)); + SendCommandMIX(CMD_LF_T55XX_SET_CONFIG, shall_persist, 0, 0, &configurations, sizeof(t55xx_configurations_t)); return PM3_SUCCESS; } diff --git a/client/src/cmdlft55xx.h b/client/src/cmdlft55xx.h index 71fda2a72..7074124e6 100644 --- a/client/src/cmdlft55xx.h +++ b/client/src/cmdlft55xx.h @@ -47,7 +47,7 @@ #define T55X7_bin 0b0010 #define T5555_DEFAULT_CONFIG_BLOCK 0x6001F004 // data rate 64 , ask, manchester, 2 data blocks? -enum { +typedef enum { T55x7_RAW = 0x00, T55x7_DEFAULT = 0x00, T5555_DEFAULT = 0x01, diff --git a/client/src/cmdlfti.c b/client/src/cmdlfti.c index ed3b6f510..a41c70d91 100644 --- a/client/src/cmdlfti.c +++ b/client/src/cmdlfti.c @@ -17,6 +17,7 @@ #include "comms.h" #include "crc16.h" #include "ui.h" +#include "proxgui.h" #include "graph.h" #include "cmdlfti.h" @@ -84,15 +85,14 @@ static int CmdTIDemod(const char *Cmd) { int lowLen = ARRAYLEN(LowTone); int highLen = ARRAYLEN(HighTone); int convLen = (highLen > lowLen) ? highLen : lowLen; - uint16_t crc; int i, j, TagType; - int lowSum = 0, highSum = 0;; + int lowSum = 0, highSum = 0; int lowTot = 0, highTot = 0; int retval = PM3_ESOFT; for (i = 0; i < GraphTraceLen - convLen; i++) { lowSum = 0; - highSum = 0;; + highSum = 0; for (j = 0; j < lowLen; j++) { lowSum += LowTone[j] * GraphBuffer[i + j]; @@ -240,25 +240,23 @@ static int CmdTIDemod(const char *Cmd) { // i'm 99% sure the crc algorithm is correct, but it may need to eat the // bytes in reverse or something // calculate CRC - crc = 0; - crc = update_crc16(crc, (shift0 >> 0) & 0xFF); - crc = update_crc16(crc, (shift0 >> 8) & 0xFF); - crc = update_crc16(crc, (shift0 >> 16) & 0xFF); - crc = update_crc16(crc, (shift0 >> 24) & 0xFF); + uint8_t raw[8] = { + (shift0 >> 0) & 0xFF, + (shift0 >> 8) & 0xFF, + (shift0 >> 16) & 0xFF, + (shift0 >> 24) & 0xFF, + (shift1 >> 0) & 0xFF, + (shift1 >> 8) & 0xFF, + (shift1 >> 16) & 0xFF, + (shift1 >> 24) & 0xFF + }; + init_table(CRC_KERMIT); + uint16_t calccrc = crc16_kermit(raw, sizeof(raw)); + const char *crc_str = (calccrc == (shift2 & 0xFFFF)) ? _GREEN_("ok") : _RED_("fail"); + PrintAndLogEx(INFO, "Tag data = %08X%08X [%04X] (%s)", shift1, shift0, calccrc, crc_str); - crc = update_crc16(crc, (shift1 >> 0) & 0xFF); - crc = update_crc16(crc, (shift1 >> 8) & 0xFF); - crc = update_crc16(crc, (shift1 >> 16) & 0xFF); - crc = update_crc16(crc, (shift1 >> 24) & 0xFF); - - //crc = crc16_ccitt(message, sizeof(message); - - const char *crcStr = (crc == (shift2 & 0xFFFF)) ? _GREEN_("Passed") : _RED_("Fail"); - - PrintAndLogEx(INFO, "Tag data = %08X%08X [Crc %04X %s]", shift1, shift0, crc, crcStr); - - if (crc != (shift2 & 0xFFFF)) - PrintAndLogEx(WARNING, "Warning: CRC mismatch, calculated %04X, got %04X", crc, shift2 & 0xFFFF); + if (calccrc != (shift2 & 0xFFFF)) + PrintAndLogEx(WARNING, "Warning: CRC mismatch, calculated %04X, got %04X", calccrc, shift2 & 0xFFFF); retval = PM3_SUCCESS; goto out; diff --git a/client/src/cmdlfviking.c b/client/src/cmdlfviking.c index 153c1d54d..dccdb16c5 100644 --- a/client/src/cmdlfviking.c +++ b/client/src/cmdlfviking.c @@ -1,4 +1,5 @@ //----------------------------------------------------------------------------- +// Marshmellow, // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -51,19 +52,25 @@ static int usage_lf_viking_sim(void) { return PM3_SUCCESS; } -//by marshmellow -//see ASKDemod for what args are accepted static int CmdVikingDemod(const char *Cmd) { - if (ASKDemod(Cmd, false, false, 1) != PM3_SUCCESS) { + return demodViking(); +} + +//see ASKDemod for what args are accepted +int demodViking(void) { + + if (ASKDemod("", false, false, 1) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - Viking ASKDemod failed"); return PM3_ESOFT; } + size_t size = DemodBufferLen; int ans = detectViking(DemodBuffer, &size); if (ans < 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - Viking Demod %d %s", ans, (ans == -5) ? _RED_("[chksum error]") : ""); return PM3_ESOFT; } + //got a good demod uint32_t raw1 = bytebits_to_byte(DemodBuffer + ans, 32); uint32_t raw2 = bytebits_to_byte(DemodBuffer + ans + 32, 32); @@ -76,7 +83,6 @@ static int CmdVikingDemod(const char *Cmd) { return PM3_SUCCESS; } -//by marshmellow //see ASKDemod for what args are accepted static int CmdVikingRead(const char *Cmd) { lf_read(false, 10000); @@ -211,7 +217,4 @@ int detectViking(uint8_t *src, size_t *size) { return (int)startIdx; } -int demodViking(void) { - return CmdVikingDemod(""); -} diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index f9cfe310a..1e9c8d257 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -79,7 +79,7 @@ static int usage_auto(void) { return PM3_SUCCESS; } -static void AppendDate(char *s, size_t slen, char *fmt) { +static void AppendDate(char *s, size_t slen, const char *fmt) { struct tm *ct, tm_buf; time_t now = time(NULL); #if defined(_WIN32) @@ -287,7 +287,7 @@ int CommandReceived(char *Cmd) { return CmdsParse(CommandTable, Cmd); } -command_t *getTopLevelCommandTable() { +command_t *getTopLevelCommandTable(void) { return CommandTable; } diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index e57d32090..529a3d553 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -234,8 +234,8 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { return PM3_SUCCESS; } -char pparent[512] = {0}; -char *parent = pparent; +static char pparent[512] = {0}; +static char *parent = pparent; void dumpCommandsRecursive(const command_t cmds[], int markdown) { if (cmds[0].Name == NULL) return; diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 4f4a372d8..24fd5ec37 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -7,10 +7,19 @@ //----------------------------------------------------------------------------- // Some lua scripting glue to proxmark core. //----------------------------------------------------------------------------- +// 2020, added Python support (@iceman100) + #include #include +#ifdef HAVE_PYTHON +//#define PY_SSIZE_T_CLEAN +#include +#include +#endif + + #include "cmdparser.h" // command_t #include "scripting.h" #include "comms.h" @@ -24,8 +33,98 @@ #include "ui.h" #include "fileutils.h" +typedef enum { + PM3_UNSPECIFIED, + PM3_LUA, + PM3_CMD, +#ifdef HAVE_PYTHON + PM3_PY +#endif +} pm3_scriptfile_t; + static int CmdHelp(const char *Cmd); +#ifdef HAVE_PYTHON + +#define PYTHON_LIBRARIES_WILDCARD "?.py" + +static int split(char *str, char **arr) { + int begin_index = 0; + int word_cnt = 0; + + while (1) { + while (isspace(str[begin_index])) { + ++begin_index; + } + if (str[begin_index] == '\0') { + break; + } + int end_index = begin_index; + while (str[end_index] && !isspace(str[end_index])) { + ++end_index; + } + int len = end_index - begin_index; + char *tmp = calloc(len + 1, sizeof(char)); + memcpy(tmp, &str[begin_index], len); + arr[word_cnt++] = tmp; + begin_index = end_index; + } + return word_cnt; +} + +static void set_python_path(char *path) { + PyObject *syspath = PySys_GetObject("path"); + if (syspath == 0) { + PrintAndLogEx(WARNING, "Python failed to getobject"); + } + + PyObject *pName = PyUnicode_FromString(path); + if (PyList_Insert(syspath, 0, pName)) { + PrintAndLogEx(WARNING, "Error inserting extra path into sys.path list"); + } + + if (PySys_SetObject("path", syspath)) { + PrintAndLogEx(WARNING, "Error setting sys.path object"); + } +} + +static void set_python_paths(void) { + //--add to the LUA_PATH (package.path in lua) + // so we can load scripts from various places: + const char *exec_path = get_my_executable_directory(); + if (exec_path != NULL) { + // from the ./luascripts/ directory + char scripts_path[strlen(exec_path) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, exec_path); + strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR); +// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); + set_python_path(scripts_path); + } + + const char *user_path = get_my_user_directory(); + if (user_path != NULL) { + // from the $HOME/.proxmark3/luascripts/ directory + char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, user_path); + strcat(scripts_path, PM3_USER_DIRECTORY); + strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR); +// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); + set_python_path(scripts_path); + + } + + if (exec_path != NULL) { + // from the $PREFIX/share/proxmark3/luascripts/ directory + char scripts_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, exec_path); + strcat(scripts_path, PM3_SHARE_RELPATH); + strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR); +// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); + set_python_path(scripts_path); + } +} +#endif + /** * Generate a sorted list of available commands, what it does is * generate a file listing of the script-directory for files @@ -36,7 +135,15 @@ static int CmdScriptList(const char *Cmd) { int ret = searchAndList(LUA_SCRIPTS_SUBDIR, ".lua"); if (ret != PM3_SUCCESS) return ret; - return searchAndList(CMD_SCRIPTS_SUBDIR, ".cmd"); + + ret = searchAndList(CMD_SCRIPTS_SUBDIR, ".cmd"); + if (ret != PM3_SUCCESS) + return ret; +#ifdef HAVE_PYTHON + return searchAndList(PYTHON_SCRIPTS_SUBDIR, ".py"); +#else + return ret; +#endif } /** @@ -54,9 +161,30 @@ static int CmdScriptRun(const char *Cmd) { int arg_len = 0; static uint8_t luascriptfile_idx = 0; sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); + if (strlen(preferredName) == 0) { + PrintAndLogEx(FAILED, "no script name provided"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`script list`") " to see available scripts"); + return PM3_EINVARG; + } + char *extension_chk; + extension_chk = str_dup(preferredName); + str_lower(extension_chk); + + pm3_scriptfile_t ext = PM3_UNSPECIFIED; + if (str_endswith(extension_chk, ".lua")) { + ext = PM3_LUA; + } else if (str_endswith(extension_chk, ".cmd")) { + ext = PM3_CMD; + } +#ifdef HAVE_PYTHON + else if (str_endswith(extension_chk, ".py")) { + ext = PM3_PY; + } +#endif + free(extension_chk); char *script_path = NULL; - if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) { + if (((ext == PM3_LUA) || (ext == PM3_UNSPECIFIED)) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) { int error; if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) { PrintAndLogEx(ERR, "too many nested scripts, skipping %s\n", script_path); @@ -112,7 +240,7 @@ static int CmdScriptRun(const char *Cmd) { return PM3_SUCCESS; } - if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) { + if (((ext == PM3_CMD) || (ext == PM3_UNSPECIFIED)) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) { PrintAndLogEx(SUCCESS, "executing Cmd " _YELLOW_("%s"), script_path); PrintAndLogEx(SUCCESS, "args " _YELLOW_("'%s'"), arguments); @@ -124,18 +252,106 @@ static int CmdScriptRun(const char *Cmd) { return ret; } + /* + For apt (Ubuntu, Debian...): + sudo apt-get install python3-dev # for python3.x installs + + For yum (CentOS, RHEL...): + sudo yum install python3-devel # for python3.x installs + + For dnf (Fedora...): + sudo dnf install python3-devel # for python3.x installs + + For zypper (openSUSE...): + sudo zypper in python3-devel # for python3.x installs + + For apk (Alpine...): + + # This is a departure from the normal Alpine naming + # scheme, which uses py2- and py3- prefixes + + sudo apk add python3-dev # for python3.x installs + + For apt-cyg (Cygwin...): + apt-cyg install python3-devel # for python3.x installs + */ + +#ifdef HAVE_PYTHON + + if (((ext == PM3_PY) || (ext == PM3_UNSPECIFIED)) && (searchFile(&script_path, PYTHON_SCRIPTS_SUBDIR, preferredName, ".py", true) == PM3_SUCCESS)) { + + PrintAndLogEx(SUCCESS, "executing python " _YELLOW_("%s"), script_path); + PrintAndLogEx(SUCCESS, "args " _YELLOW_("'%s'"), arguments); + + wchar_t *program = Py_DecodeLocale(preferredName, NULL); + if (program == NULL) { + PrintAndLogEx(ERR, "could not decode " _YELLOW_("%s"), preferredName); + free(script_path); + return PM3_ESOFT; + } + + // optional but recommended + Py_SetProgramName(program); + Py_Initialize(); + + //int argc, char ** argv + char *argv[128]; + int argc = split(arguments, argv); + wchar_t *py_args[argc]; + py_args[0] = Py_DecodeLocale(preferredName, NULL); + for (int i = 0; i < argc; i++) { + py_args[i + 1] = Py_DecodeLocale(argv[i], NULL); + } + + PySys_SetArgv(argc + 1, py_args); + + // clean up + for (int i = 0; i < argc; ++i) { + free(argv[i]); + } + + // setup search paths. + set_python_paths(); + + FILE *f = fopen(script_path, "r"); + if (f == NULL) { + PrintAndLogEx(ERR, "Could open file " _YELLOW_("%s"), script_path); + free(script_path); + return PM3_ESOFT; + } + + PyRun_SimpleFileExFlags(f, preferredName, 1, NULL); + Py_Finalize(); + PyMem_RawFree(program); + free(script_path); + PrintAndLogEx(SUCCESS, "\nfinished " _YELLOW_("%s"), preferredName); + return PM3_SUCCESS; + } +#endif + // file not found, let's search again to display the error messages int ret = PM3_EUNDEF; - if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); - if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false); + if (ext == PM3_LUA) + ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); + else if (ext == PM3_CMD) + ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false); +#ifdef HAVE_PYTHON + else if (ext == PM3_PY) + ret = searchFile(&script_path, PYTHON_SCRIPTS_SUBDIR, preferredName, ".py", false); + else if (ext == PM3_UNSPECIFIED) + PrintAndLogEx(FAILED, "Error - can't find %s.[lua|cmd|py]", preferredName); +#else + else if (ext == PM3_UNSPECIFIED) + PrintAndLogEx(FAILED, "Error - can't find %s.[lua|cmd]", preferredName); +#endif free(script_path); return ret; } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"help", CmdHelp, AlwaysAvailable, "Usage info"}, {"list", CmdScriptList, AlwaysAvailable, "List available scripts"}, - {"run", CmdScriptRun, AlwaysAvailable, " -- Execute a script"}, + {"run", CmdScriptRun, AlwaysAvailable, " -- execute a script"}, {NULL, NULL, NULL, NULL} }; @@ -147,7 +363,11 @@ static command_t CommandTable[] = { */ static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far - PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place Lua-scripts within the luascripts/-folder. "); +#ifdef HAVE_PYTHON + PrintAndLogEx(NORMAL, "This is a feature to run Lua/Cmd/Python scripts. You can place scripts within the luascripts/cmdscripts/pyscripts folders. "); +#else + PrintAndLogEx(NORMAL, "This is a feature to run Lua/Cmd scripts. You can place scripts within the luascripts/cmdscripts folders. "); +#endif return PM3_SUCCESS; } diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index ba48fae96..009e876c8 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -41,8 +41,7 @@ static int usage_sm_raw(void) { PrintAndLogEx(NORMAL, " sc raw 0 d 00a404000e325041592e5359532e4444463031 - `2PAY.SYS.DDF01` PPSE directory"); PrintAndLogEx(NORMAL, " sc raw 0 t d 00a4040007a0000000041010 - Mastercard"); PrintAndLogEx(NORMAL, " sc raw 0 t d 00a4040007a0000000031010 - Visa"); - - return 0; + return PM3_SUCCESS; } static int usage_sm_reader(void) { PrintAndLogEx(NORMAL, "Usage: sc reader [h|s]"); @@ -51,7 +50,7 @@ static int usage_sm_reader(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc reader"); - return 0; + return PM3_SUCCESS; } static int usage_sm_info(void) { PrintAndLogEx(NORMAL, "Usage: sc info [h|s]"); @@ -60,7 +59,7 @@ static int usage_sm_info(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc info"); - return 0; + return PM3_SUCCESS; } static int usage_sm_upgrade(void) { PrintAndLogEx(NORMAL, "Upgrade RDV4.0 Sim module firmware"); @@ -70,7 +69,7 @@ static int usage_sm_upgrade(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/sim011.bin"); - return 0; + return PM3_SUCCESS; } static int usage_sm_setclock(void) { PrintAndLogEx(NORMAL, "Usage: sc setclock [h] c "); @@ -79,7 +78,7 @@ static int usage_sm_setclock(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc setclock c 2"); - return 0; + return PM3_SUCCESS; } static int usage_sm_brute(void) { PrintAndLogEx(NORMAL, "Tries to bruteforce SFI, using a known list of AID's "); @@ -90,7 +89,7 @@ static int usage_sm_brute(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " sc brute t"); - return 0; + return PM3_SUCCESS; } static int smart_loadjson(const char *preferredName, json_t **root) { @@ -207,7 +206,7 @@ static float GetATRF(uint8_t *atr, size_t atrlen) { return FArray[TA1 >> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi } -static int PrintATR(uint8_t *atr, size_t atrlen) { +static void PrintATR(uint8_t *atr, size_t atrlen) { uint8_t T0 = atr[1]; uint8_t K = T0 & 0x0F; @@ -320,8 +319,6 @@ static int PrintATR(uint8_t *atr, size_t atrlen) { PrintAndLogEx(INFO, "\tHistorical bytes"); dump_buffer(&atr[2 + T1len + TD1len + TDilen], K, NULL, 1); } - - return 0; } static int smart_wait(uint8_t *data, bool silent) { @@ -366,7 +363,7 @@ static int smart_responseEx(uint8_t *data, bool silent) { uint8_t getstatus[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, len}; clearCommandBuffer(); - SendCommandOLD(CMD_SMART_RAW, SC_RAW, sizeof(getstatus), 0, getstatus, sizeof(getstatus)); + SendCommandMIX(CMD_SMART_RAW, SC_RAW, sizeof(getstatus), 0, getstatus, sizeof(getstatus)); datalen = smart_wait(data, silent); @@ -443,13 +440,13 @@ static int CmdSmartRaw(const char *Cmd) { switch (param_gethex_to_eol(Cmd, cmdp + 1, data, sizeof(data), &hexlen)) { case 1: PrintAndLogEx(WARNING, "Invalid HEX value."); - return 1; + return PM3_EINVARG; case 2: PrintAndLogEx(WARNING, "Too many bytes. Max %zu bytes", sizeof(data)); - return 1; + return PM3_EINVARG; case 3: PrintAndLogEx(WARNING, "Hex must have even number of digits."); - return 1; + return PM3_EINVARG; } cmdp++; breakloop = true; @@ -490,19 +487,19 @@ static int CmdSmartRaw(const char *Cmd) { uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); if (!buf) - return 1; + return PM3_EMALLOC; int len = smart_response(buf); if (len < 0) { free(buf); - return 2; + return PM3_ESOFT; } if (buf[0] == 0x6C) { data[4] = buf[1]; clearCommandBuffer(); - SendCommandOLD(CMD_SMART_RAW, 0, hexlen, 0, data, hexlen); + SendCommandMIX(CMD_SMART_RAW, 0, hexlen, 0, data, hexlen); len = smart_response(buf); data[4] = 0; @@ -510,10 +507,19 @@ static int CmdSmartRaw(const char *Cmd) { if (decodeTLV && len > 4) TLVPrintFromBuffer(buf, len - 2); + else { + if (len > 16) { + for (int i = 0; i < len; i += 16) { + PrintAndLogEx(SUCCESS, "%s", sprint_hex_ascii(buf + i, 16)) ; + } + } else { + PrintAndLogEx(SUCCESS, "%s", sprint_hex_ascii(buf, len)) ; + } + } free(buf); } - return 0; + return PM3_SUCCESS; } static int CmdSmartUpgrade(const char *Cmd) { @@ -522,7 +528,6 @@ static int CmdSmartUpgrade(const char *Cmd) { PrintAndLogEx(WARNING, "A dangerous command, do wrong and you could brick the sim module"); PrintAndLogEx(NORMAL, ""); - FILE *f; char filename[FILE_PATH_SIZE] = {0}; uint8_t cmdp = 0; bool errors = false; @@ -530,7 +535,6 @@ static int CmdSmartUpgrade(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'f': - //File handling and reading if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); errors = true; @@ -550,104 +554,74 @@ static int CmdSmartUpgrade(const char *Cmd) { //Validations if (errors || cmdp == 0) return usage_sm_upgrade(); - char sha512filename[FILE_PATH_SIZE] = {'\0'}; + char *bin_extension = filename; char *dot_position = NULL; while ((dot_position = strchr(bin_extension, '.')) != NULL) { bin_extension = dot_position + 1; } + // generate filename for the related SHA512 hash file + char sha512filename[FILE_PATH_SIZE] = {'\0'}; if (!strcmp(bin_extension, "BIN") || !strcmp(bin_extension, "bin")) { memcpy(sha512filename, filename, strlen(filename) - strlen("bin")); strcat(sha512filename, "sha512.txt"); } else { PrintAndLogEx(FAILED, "Filename extension of firmware upgrade file must be .BIN"); - return 1; + return PM3_ESOFT; } - PrintAndLogEx(INFO, "firmware file : " _YELLOW_("%s"), filename); - PrintAndLogEx(INFO, "Checking integrity : " _YELLOW_("%s"), sha512filename); + PrintAndLogEx(INFO, "firmware file " _YELLOW_("%s"), filename); + PrintAndLogEx(INFO, "Checking integrity " _YELLOW_("%s"), sha512filename); // load firmware file - f = fopen(filename, "rb"); - if (!f) { + size_t firmware_size = 0; + uint8_t *firmware = NULL; + if (loadFile_safe(filename, "", (void **)&firmware, &firmware_size) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Firmware file " _YELLOW_("%s") " not found or locked.", filename); return PM3_EFILE; } - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(ERR, "error, when getting filesize"); - fclose(f); - return 1; - } - - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(ERR, "error, cannot allocate memory "); - fclose(f); - return 1; - } - - size_t firmware_size = fread(dump, 1, fsize, f); - fclose(f); - // load sha512 file - f = fopen(sha512filename, "rb"); - if (!f) { + size_t sha512_size = 0; + char *hashstring = NULL; + if (loadFile_safe(sha512filename, "", (void **)&hashstring, &sha512_size) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "SHA-512 file not found or locked."); - free(dump); + free(firmware); return PM3_EFILE; } - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize < 0) { - PrintAndLogEx(FAILED, "Could not determine size of SHA-512 file"); - fclose(f); - free(dump); - return 1; + if (sha512_size < 128) { + PrintAndLogEx(FAILED, "SHA-512 file wrong size"); + free(hashstring); + free(firmware); + return PM3_ESOFT; } - - if (fsize < 128) { - PrintAndLogEx(FAILED, "SHA-512 file too short"); - fclose(f); - free(dump); - return 1; - } - - char hashstring[129]; - size_t bytes_read = fread(hashstring, 1, 128, f); hashstring[128] = '\0'; - fclose(f); - uint8_t hash_1[64]; - if (bytes_read != 128 || param_gethex(hashstring, 0, hash_1, 128)) { + if (param_gethex(hashstring, 0, hash_1, 128)) { PrintAndLogEx(FAILED, "Couldn't read SHA-512 file"); - free(dump); - return 1; + free(hashstring); + free(firmware); + return PM3_ESOFT; } uint8_t hash_2[64]; - if (sha512hash(dump, firmware_size, hash_2)) { + if (sha512hash(firmware, firmware_size, hash_2)) { PrintAndLogEx(FAILED, "Couldn't calculate SHA-512 of firmware"); - free(dump); - return 1; + free(hashstring); + free(firmware); + return PM3_ESOFT; } if (memcmp(hash_1, hash_2, 64)) { PrintAndLogEx(FAILED, "Couldn't verify integrity of firmware file " _RED_("(wrong SHA-512 hash)")); - free(dump); - return 1; + free(hashstring); + free(firmware); + return PM3_ESOFT; } + free(hashstring); PrintAndLogEx(SUCCESS, "Sim module firmware uploading to PM3"); @@ -666,20 +640,19 @@ static int CmdSmartUpgrade(const char *Cmd) { conn.block_after_ACK = false; } clearCommandBuffer(); - SendCommandOLD(CMD_SMART_UPLOAD, index + bytes_sent, bytes_in_packet, 0, dump + bytes_sent, bytes_in_packet); + SendCommandOLD(CMD_SMART_UPLOAD, index + bytes_sent, bytes_in_packet, 0, firmware + bytes_sent, bytes_in_packet); if (!WaitForResponseTimeout(CMD_ACK, NULL, 2000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - free(dump); - return 1; + free(firmware); + return PM3_ETIMEOUT; } bytes_remaining -= bytes_in_packet; bytes_sent += bytes_in_packet; - printf("."); - fflush(stdout); + PrintAndLogEx(INPLACE, "%d bytes sent", bytes_sent); } - free(dump); - printf("\n"); + free(firmware); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "Sim module firmware updating, don\'t turn off your PM3!"); // trigger the firmware upgrade @@ -688,11 +661,11 @@ static int CmdSmartUpgrade(const char *Cmd) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return 1; + return PM3_ETIMEOUT; } if ((resp.oldarg[0] & 0xFF)) { PrintAndLogEx(SUCCESS, "Sim module firmware upgrade " _GREEN_("successful")); - PrintAndLogEx(SUCCESS, "\n run " _YELLOW_("`hw status`") " to validate the fw version "); + PrintAndLogEx(HINT, "run " _YELLOW_("`hw status`") " to validate the fw version "); } else { PrintAndLogEx(FAILED, "Sim module firmware upgrade " _RED_("failed")); } @@ -726,20 +699,20 @@ static int CmdSmartInfo(const char *Cmd) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); - return 1; + return PM3_ETIMEOUT; } uint8_t isok = resp.oldarg[0] & 0xFF; if (!isok) { if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); - return 1; + return PM3_ESOFT; } smart_card_atr_t card; memcpy(&card, (smart_card_atr_t *)resp.data.asBytes, sizeof(smart_card_atr_t)); // print header - PrintAndLogEx(INFO, "--- Smartcard Information ---------"); + PrintAndLogEx(INFO, "--- " _CYAN_("Smartcard Information") " ---------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(INFO, "ISO7618-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); PrintAndLogEx(INFO, "http://smartcard-atr.apdu.fr/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len)); @@ -769,7 +742,7 @@ static int CmdSmartInfo(const char *Cmd) { PrintAndLogEx(WARNING, "\t- Di or Fi is RFU."); }; - return 0; + return PM3_SUCCESS; } static int CmdSmartReader(const char *Cmd) { @@ -799,19 +772,19 @@ static int CmdSmartReader(const char *Cmd) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); - return 1; + return PM3_ETIMEOUT; } uint8_t isok = resp.oldarg[0] & 0xFF; if (!isok) { if (!silent) PrintAndLogEx(WARNING, "smart card select failed"); - return 1; + return PM3_ESOFT; } smart_card_atr_t card; memcpy(&card, (smart_card_atr_t *)resp.data.asBytes, sizeof(smart_card_atr_t)); PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len)); - return 0; + return PM3_SUCCESS; } static int CmdSmartSetClock(const char *Cmd) { @@ -844,13 +817,13 @@ static int CmdSmartSetClock(const char *Cmd) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { PrintAndLogEx(WARNING, "smart card select failed"); - return 1; + return PM3_ETIMEOUT; } uint8_t isok = resp.oldarg[0] & 0xFF; if (!isok) { PrintAndLogEx(WARNING, "smart card set clock failed"); - return 1; + return PM3_ESOFT; } switch (clock1) { @@ -866,16 +839,16 @@ static int CmdSmartSetClock(const char *Cmd) { default: break; } - return 0; + return PM3_SUCCESS; } static int CmdSmartList(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdTraceList("7816"); - return 0; + return PM3_SUCCESS; } -static void smart_brute_prim() { +static void smart_brute_prim(void) { uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); if (!buf) @@ -893,7 +866,7 @@ static void smart_brute_prim() { for (int i = 0; i < ARRAYLEN(get_card_data); i += 5) { clearCommandBuffer(); - SendCommandOLD(CMD_SMART_RAW, SC_RAW_T0, 5, 0, get_card_data + i, 5); + SendCommandMIX(CMD_SMART_RAW, SC_RAW_T0, 5, 0, get_card_data + i, 5); int len = smart_responseEx(buf, true); @@ -936,7 +909,7 @@ static int smart_brute_sfi(bool decodeTLV) { READ_RECORD[3] = (sfi << 3) | 4; clearCommandBuffer(); - SendCommandOLD(CMD_SMART_RAW, SC_RAW_T0, sizeof(READ_RECORD), 0, READ_RECORD, sizeof(READ_RECORD)); + SendCommandMIX(CMD_SMART_RAW, SC_RAW_T0, sizeof(READ_RECORD), 0, READ_RECORD, sizeof(READ_RECORD)); len = smart_responseEx(buf, true); @@ -944,7 +917,7 @@ static int smart_brute_sfi(bool decodeTLV) { READ_RECORD[4] = buf[1]; clearCommandBuffer(); - SendCommandOLD(CMD_SMART_RAW, SC_RAW_T0, sizeof(READ_RECORD), 0, READ_RECORD, sizeof(READ_RECORD)); + SendCommandMIX(CMD_SMART_RAW, SC_RAW_T0, sizeof(READ_RECORD), 0, READ_RECORD, sizeof(READ_RECORD)); len = smart_responseEx(buf, true); READ_RECORD[4] = 0; @@ -979,7 +952,7 @@ static void smart_brute_options(bool decodeTLV) { // Get processing options command clearCommandBuffer(); - SendCommandOLD(CMD_SMART_RAW, SC_RAW_T0, sizeof(GET_PROCESSING_OPTIONS), 0, GET_PROCESSING_OPTIONS, sizeof(GET_PROCESSING_OPTIONS)); + SendCommandMIX(CMD_SMART_RAW, SC_RAW_T0, sizeof(GET_PROCESSING_OPTIONS), 0, GET_PROCESSING_OPTIONS, sizeof(GET_PROCESSING_OPTIONS)); int len = smart_responseEx(buf, true); if (len > 4) { @@ -1038,12 +1011,12 @@ static int CmdSmartBruteforceSFI(const char *Cmd) { uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); if (!buf) - return 1; + return PM3_EMALLOC; PrintAndLogEx(INFO, "Selecting card"); if (!smart_select(false, NULL)) { free(buf); - return 1; + return PM3_ESOFT; } char *caid = NULL; @@ -1062,14 +1035,14 @@ static int CmdSmartBruteforceSFI(const char *Cmd) { if (!json_is_object(data)) { PrintAndLogEx(ERR, "data %d is not an object\n", i + 1); json_decref(root); - return 1; + return PM3_ESOFT; } jaid = json_object_get(data, "AID"); if (!json_is_string(jaid)) { PrintAndLogEx(ERR, "AID data [%d] is not a string", i + 1); json_decref(root); - return 1; + return PM3_ESOFT; } const char *aid = json_string_value(jaid); @@ -1131,7 +1104,7 @@ static int CmdSmartBruteforceSFI(const char *Cmd) { json_decref(root); PrintAndLogEx(SUCCESS, "\nSearch completed."); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -1149,7 +1122,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdSmartcard(const char *Cmd) { @@ -1175,7 +1148,6 @@ int ExchangeAPDUSC(bool silent, uint8_t *datain, int datainlen, bool activateCar SendCommandOLD(CMD_SMART_RAW, flags, datainlen, 0, datain, datainlen); int len = smart_responseEx(dataout, silent); - if (len < 0) { return 1; } @@ -1190,7 +1162,7 @@ int ExchangeAPDUSC(bool silent, uint8_t *datain, int datainlen, bool activateCar clearCommandBuffer(); // something fishy: we have only 5 bytes but we put datainlen in arg1? - SendCommandOLD(CMD_SMART_RAW, SC_RAW_T0, datainlen, 0, data, sizeof(data)); + SendCommandMIX(CMD_SMART_RAW, SC_RAW_T0, datainlen, 0, data, sizeof(data)); len = smart_responseEx(dataout, silent); } diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 41c102aa1..04b71d677 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -18,21 +18,22 @@ #include "comms.h" // for sending cmds to device. GetFromBigBuf #include "fileutils.h" // for saveFile #include "cmdlfhitag.h" // annotate hitag +#include "pm3_cmd.h" // tracelog_hdr_t static int CmdHelp(const char *Cmd); // trace pointer -static uint8_t *trace; -long traceLen = 0; +static uint8_t *g_trace; +static long g_traceLen = 0; -static int usage_trace_list() { +static int usage_trace_list(void) { PrintAndLogEx(NORMAL, "List protocol data in trace buffer."); PrintAndLogEx(NORMAL, "Usage: trace list [f][c| <0|1>"); PrintAndLogEx(NORMAL, " f - show frame delay times as well"); PrintAndLogEx(NORMAL, " c - mark CRC bytes"); PrintAndLogEx(NORMAL, " x - show hexdump to convert to pcap(ng) or to import into Wireshark using encapsulation type \"ISO 14443\""); PrintAndLogEx(NORMAL, " syntax to use: `text2pcap -t \"%%S.\" -l 264 -n `"); - PrintAndLogEx(NORMAL, " <0|1> - use data from Tracebuffer, if not set, try reading data from tag."); + PrintAndLogEx(NORMAL, " <0|1> - use data from Tracebuffer, if not set, try to collect a trace from Proxmark3 device."); PrintAndLogEx(NORMAL, "Supported values:"); PrintAndLogEx(NORMAL, " raw - just show raw data without annotations"); PrintAndLogEx(NORMAL, " 14a - interpret data as iso14443a communications"); @@ -56,14 +57,14 @@ static int usage_trace_list() { PrintAndLogEx(NORMAL, " trace list iclass"); return PM3_SUCCESS; } -static int usage_trace_load() { +static int usage_trace_load(void) { PrintAndLogEx(NORMAL, "Load protocol data from file to trace buffer."); PrintAndLogEx(NORMAL, "Usage: trace load "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " trace load mytracefile.bin"); return PM3_SUCCESS; } -static int usage_trace_save() { +static int usage_trace_save(void) { PrintAndLogEx(NORMAL, "Save protocol data from trace buffer to file."); PrintAndLogEx(NORMAL, "Usage: trace save "); PrintAndLogEx(NORMAL, "Examples:"); @@ -71,13 +72,13 @@ static int usage_trace_save() { return PM3_SUCCESS; } -static bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen) { - return (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) >= traceLen); +static bool is_last_record(uint16_t tracepos, uint16_t traceLen) { + return ((tracepos + TRACELOG_HDR_LEN) >= traceLen); } static bool next_record_is_response(uint16_t tracepos, uint8_t *trace) { - uint16_t next_records_datalen = *((uint16_t *)(trace + tracepos + sizeof(uint32_t) + sizeof(uint16_t))); - return ((next_records_datalen & 0x8000) == 0x8000); + tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos); + return (hdr->isResponse); } static bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, @@ -91,26 +92,22 @@ static bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, ui memcpy(topaz_reader_command, frame, *data_len); - while (!is_last_record(*tracepos, trace, traceLen) && !next_record_is_response(*tracepos, trace)) { - uint32_t next_timestamp = *((uint32_t *)(trace + *tracepos)); - *tracepos += sizeof(uint32_t); - uint16_t next_duration = *((uint16_t *)(trace + *tracepos)); - *tracepos += sizeof(uint16_t); - uint16_t next_data_len = *((uint16_t *)(trace + *tracepos)) & 0x7FFF; - *tracepos += sizeof(uint16_t); - uint8_t *next_frame = (trace + *tracepos); - *tracepos += next_data_len; - if ((next_data_len == 1) && (*data_len + next_data_len <= MAX_TOPAZ_READER_CMD_LEN)) { - memcpy(topaz_reader_command + *data_len, next_frame, next_data_len); - *data_len += next_data_len; - last_timestamp = next_timestamp + next_duration; + while (!is_last_record(*tracepos, traceLen) && !next_record_is_response(*tracepos, trace)) { + + tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + *tracepos); + + *tracepos += TRACELOG_HDR_LEN + hdr->data_len; + + if ((hdr->data_len == 1) && (*data_len + hdr->data_len <= MAX_TOPAZ_READER_CMD_LEN)) { + memcpy(topaz_reader_command + *data_len, hdr->frame, hdr->data_len); + *data_len += hdr->data_len; + last_timestamp = hdr->timestamp + hdr->duration; } else { // rewind and exit - *tracepos = *tracepos - next_data_len - sizeof(uint16_t) - sizeof(uint16_t) - sizeof(uint32_t); + *tracepos = *tracepos - hdr->data_len - TRACELOG_HDR_LEN; break; } - uint16_t next_parity_len = (next_data_len - 1) / 8 + 1; - *tracepos += next_parity_len; + *tracepos += TRACELOG_PARITY_LEN(hdr); } *duration = last_timestamp - timestamp; @@ -120,39 +117,18 @@ static bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, ui static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol) { // sanity check - if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen; + if (is_last_record(tracepos, traceLen)) return traceLen; - bool isResponse; - uint16_t data_len, parity_len; - uint32_t timestamp; + tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos); - timestamp = *((uint32_t *)(trace + tracepos)); - tracepos += 4; - - - // currently we don't use duration, so we skip it - tracepos += 2; - - data_len = *((uint16_t *)(trace + tracepos)); - tracepos += 2; - - if (data_len & 0x8000) { - data_len &= 0x7fff; - isResponse = true; - } else { - isResponse = false; - } - parity_len = (data_len - 1) / 8 + 1; - - if (tracepos + data_len + parity_len > traceLen) { + if (TRACELOG_HDR_LEN + hdr->data_len + TRACELOG_PARITY_LEN(hdr) > traceLen) { return traceLen; } - uint8_t *frame = trace + tracepos; - tracepos += data_len; - //currently we don't use parity bytes, so we skip it - tracepos += parity_len; - if (data_len == 0) { + //set trace position + tracepos += TRACELOG_HDR_LEN + hdr->data_len + TRACELOG_PARITY_LEN(hdr); + + if (hdr->data_len == 0) { PrintAndLogEx(NORMAL, ""); return tracepos; } @@ -167,27 +143,26 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac * we use format timestamp, newline, offset (0x000000), pseudo header, data * `text2pcap -t "%S." -l 264 -n ` */ - char line[(data_len * 3) + 1]; + char line[(hdr->data_len * 3) + 1]; char *ptr = &line[0]; - for (int j = 0; j < data_len ; j++) { - ptr += sprintf(ptr, "%02x", frame[j]); - ptr += sprintf(ptr, " "); + for (int i = 0; i < hdr->data_len ; i++) { + ptr += sprintf(ptr, "%02x ", hdr->frame[i]); } char data_len_str[5]; char temp_str1[3] = {0}; char temp_str2[3] = {0}; - sprintf(data_len_str, "%04x", data_len); + sprintf(data_len_str, "%04x", hdr->data_len); strncat(temp_str1, data_len_str, 2); temp_str1[2] = '\0'; strncat(temp_str2, data_len_str + 2, 2); temp_str2[2] = '\0'; - PrintAndLogEx(NORMAL, "0.%010u", timestamp); + PrintAndLogEx(NORMAL, "0.%010u", hdr->timestamp); PrintAndLogEx(NORMAL, "000000 00 %s %s %s %s", - (isResponse ? "ff" : "fe"), + (hdr->isResponse ? "ff" : "fe"), temp_str1, temp_str2, line); @@ -205,47 +180,34 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes) { // sanity check - if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen; + if (is_last_record(tracepos, traceLen)) return traceLen; - bool isResponse; - uint16_t data_len, parity_len; - uint32_t duration, timestamp, first_timestamp, EndOfTransmissionTimestamp; + uint32_t duration; + uint16_t data_len; + uint32_t EndOfTransmissionTimestamp; uint8_t topaz_reader_command[9]; - char explanation[30] = {0}; + char explanation[40] = {0}; uint8_t mfData[32] = {0}; size_t mfDataLen = 0; + tracelog_hdr_t *first_hdr = (tracelog_hdr_t *)(trace); + tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos); + duration = hdr->duration; + data_len = hdr->data_len; - first_timestamp = *((uint32_t *)(trace)); - timestamp = *((uint32_t *)(trace + tracepos)); - tracepos += 4; - - duration = *((uint16_t *)(trace + tracepos)); - tracepos += 2; - - data_len = *((uint16_t *)(trace + tracepos)); - tracepos += 2; - - if (data_len & 0x8000) { - data_len &= 0x7fff; - isResponse = true; - } else { - isResponse = false; - } - parity_len = (data_len - 1) / 8 + 1; - - if (tracepos + data_len + parity_len > traceLen) { + if (tracepos + TRACELOG_HDR_LEN + data_len + TRACELOG_PARITY_LEN(hdr) > traceLen) { return traceLen; } - uint8_t *frame = trace + tracepos; - tracepos += data_len; - uint8_t *parityBytes = trace + tracepos; - tracepos += parity_len; - if (protocol == TOPAZ && !isResponse) { + uint8_t *frame = hdr->frame; + uint8_t *parityBytes = hdr->frame + data_len; + + tracepos += TRACELOG_HDR_LEN + data_len + TRACELOG_PARITY_LEN(hdr); + + if (protocol == TOPAZ && !hdr->isResponse) { // topaz reader commands come in 1 or 9 separate frames with 7 or 8 Bits each. // merge them: - if (merge_topaz_reader_frames(timestamp, &duration, &tracepos, traceLen, trace, frame, topaz_reader_command, &data_len)) { + if (merge_topaz_reader_frames(hdr->timestamp, &duration, &tracepos, traceLen, trace, frame, topaz_reader_command, &data_len)) { frame = topaz_reader_command; } } @@ -256,7 +218,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (data_len > 2) { switch (protocol) { case ICLASS: - crcStatus = iclass_CRC_check(isResponse, frame, data_len); + crcStatus = iclass_CRC_check(hdr->isResponse, frame, data_len); break; case ISO_14443B: case TOPAZ: @@ -264,12 +226,12 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr crcStatus = !felica_CRC_check(frame + 2, data_len - 4); break; case PROTO_MIFARE: - crcStatus = mifare_CRC_check(isResponse, frame, data_len); + crcStatus = mifare_CRC_check(hdr->isResponse, frame, data_len); break; case ISO_14443A: case MFDES: case LTO: - crcStatus = iso14443A_CRC_check(isResponse, frame, data_len); + crcStatus = iso14443A_CRC_check(hdr->isResponse, frame, data_len); break; case THINFILM: frame[data_len - 1] ^= frame[data_len - 2]; @@ -296,7 +258,12 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr //2 Not crc-command //--- Draw the data column - char line[18][110] = {{0}}; + char line[18][120] = {{0}}; + + if (data_len == 0) { + sprintf(line[0], ""); + return tracepos; + } for (int j = 0; j < data_len && j / 18 < 18; j++) { @@ -312,23 +279,23 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && protocol != THINFILM && protocol != FELICA && protocol != LTO - && (isResponse || protocol == ISO_14443A) + && (hdr->isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { - snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); - } else if (protocol == ICLASS && isResponse == false) { + snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x! ", frame[j]); + } else if (protocol == ICLASS && hdr->isResponse == false) { uint8_t parity = 0; for (int i = 0; i < 6; i++) { parity ^= ((frame[0] >> i) & 1); } if (parity == ((frame[0] >> 7) & 1)) { - snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); + snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x ", frame[j]); } else { - snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); + snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x! ", frame[j]); } } else { - snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); + snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x ", frame[j]); } } @@ -343,27 +310,22 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } } - if (data_len == 0) { - sprintf(line[0], ""); - return tracepos; - } - // Draw the CRC column const char *crc = (crcStatus == 0 ? "!crc" : (crcStatus == 1 ? " ok " : " ")); - EndOfTransmissionTimestamp = timestamp + duration; + EndOfTransmissionTimestamp = hdr->timestamp + duration; // Always annotate LEGIC read/tag if (protocol == LEGIC) annotateLegic(explanation, sizeof(explanation), frame, data_len); if (protocol == PROTO_MIFARE) - annotateMifare(explanation, sizeof(explanation), frame, data_len, parityBytes, parity_len, isResponse); + annotateMifare(explanation, sizeof(explanation), frame, data_len, parityBytes, TRACELOG_PARITY_LEN(hdr), hdr->isResponse); if (protocol == FELICA) annotateFelica(explanation, sizeof(explanation), frame, data_len); - if (!isResponse) { + if (!hdr->isResponse) { switch (protocol) { case ICLASS: annotateIclass(explanation, sizeof(explanation), frame, data_len); @@ -410,9 +372,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr for (int j = 0; j < num_lines ; j++) { if (j == 0) { PrintAndLogEx(NORMAL, " %10u | %10u | %s |%-72s | %s| %s", - (timestamp - first_timestamp), - (EndOfTransmissionTimestamp - first_timestamp), - (isResponse ? "Tag" : "Rdr"), + (hdr->timestamp - first_hdr->timestamp), + (EndOfTransmissionTimestamp - first_hdr->timestamp), + (hdr->isResponse ? "Tag" : "Rdr"), line[j], (j == num_lines - 1) ? crc : " ", (j == num_lines - 1) ? explanation : ""); @@ -424,32 +386,84 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } } - if (DecodeMifareData(frame, data_len, parityBytes, isResponse, mfData, &mfDataLen)) { + if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen)) { memset(explanation, 0x00, sizeof(explanation)); - if (!isResponse) { + if (!hdr->isResponse) { annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen); } - uint8_t crcc = iso14443A_CRC_check(isResponse, mfData, mfDataLen); + uint8_t crcc = iso14443A_CRC_check(hdr->isResponse, mfData, mfDataLen); PrintAndLogEx(NORMAL, " | | * |%-72s | %-4s| %s", sprint_hex_inrow_spaces(mfData, mfDataLen, 2), (crcc == 0 ? "!crc" : (crcc == 1 ? " ok " : " ")), explanation); } - if (is_last_record(tracepos, trace, traceLen)) return traceLen; + if (is_last_record(tracepos, traceLen)) return traceLen; + + if (showWaitCycles && !hdr->isResponse && next_record_is_response(tracepos, trace)) { + + tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); - if (showWaitCycles && !isResponse && next_record_is_response(tracepos, trace)) { - uint32_t next_timestamp = *((uint32_t *)(trace + tracepos)); PrintAndLogEx(NORMAL, " %10u | %10u | %s |fdt (Frame Delay Time): %d", - (EndOfTransmissionTimestamp - first_timestamp), - (next_timestamp - first_timestamp), + (EndOfTransmissionTimestamp - first_hdr->timestamp), + (next_hdr->timestamp - first_hdr->timestamp), " ", - (next_timestamp - EndOfTransmissionTimestamp)); + (next_hdr->timestamp - EndOfTransmissionTimestamp)); } return tracepos; } +static int download_trace(void) { + + if (!IfPm3Present()) { + PrintAndLogEx(FAILED, "You requested a trace upload in offline mode, consider using parameter '1' for working from Tracebuffer"); + return PM3_EINVARG; + } + + // reserve some space. + if (g_trace) + free(g_trace); + + g_traceLen = 0; + + g_trace = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); + if (g_trace == NULL) { + PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); + return PM3_EMALLOC; + } + + PrintAndLogEx(INFO, "downloading tracelog from device"); + + // Query for the size of the trace, downloading PM3_CMD_DATA_SIZE + PacketResponseNG response; + if (!GetFromDevice(BIG_BUF, g_trace, PM3_CMD_DATA_SIZE, 0, NULL, 0, &response, 4000, true)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + free(g_trace); + return PM3_ETIMEOUT; + } + + g_traceLen = response.oldarg[2]; + + // if tracelog buffer was larger and we need to download more. + if (g_traceLen > PM3_CMD_DATA_SIZE) { + + free(g_trace); + g_trace = calloc(g_traceLen, sizeof(uint8_t)); + if (g_trace == NULL) { + PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); + return PM3_EMALLOC; + } + + if (!GetFromDevice(BIG_BUF, g_trace, g_traceLen, 0, NULL, 0, NULL, 2500, false)) { + PrintAndLogEx(WARNING, "command execution time out"); + free(g_trace); + return PM3_ETIMEOUT; + } + } + return PM3_SUCCESS; +} + // sanity check. Don't use proxmark if it is offline and you didn't specify useTraceBuffer /* static int SanityOfflineCheck( bool useTraceBuffer ){ @@ -463,86 +477,47 @@ static int SanityOfflineCheck( bool useTraceBuffer ){ static int CmdTraceLoad(const char *Cmd) { - FILE *f = NULL; char filename[FILE_PATH_SIZE]; char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || cmdp == 'h') return usage_trace_load(); + if (strlen(Cmd) < 1 || (strlen(Cmd) == 1 && cmdp == 'h')) return usage_trace_load(); param_getstr(Cmd, 0, filename, sizeof(filename)); - if ((f = fopen(filename, "rb")) == NULL) { + if (g_trace) + free(g_trace); + + size_t len = 0; + if (loadFile_safe(filename, ".trace", (void **)&g_trace, &len) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Could not open file " _YELLOW_("%s"), filename); return PM3_EIO; } - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); + g_traceLen = (long)len; - if (fsize < 0) { - PrintAndLogEx(FAILED, "error, when getting filesize"); - fclose(f); - return PM3_EIO; - } - if (fsize < 4) { - PrintAndLogEx(FAILED, "error, file is too small"); - fclose(f); - return PM3_ESOFT; - } - - if (trace) - free(trace); - - trace = calloc(fsize, sizeof(uint8_t)); - if (!trace) { - PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); - fclose(f); - return PM3_EMALLOC; - } - - size_t bytes_read = fread(trace, 1, fsize, f); - traceLen = bytes_read; - fclose(f); - PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %lu bytes) loaded from file %s", traceLen, filename); + PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = " _YELLOW_("%lu") " bytes) loaded from " _YELLOW_("%s"), g_traceLen, filename); return PM3_SUCCESS; } static int CmdTraceSave(const char *Cmd) { - if (traceLen == 0) { + if (g_traceLen == 0) { + download_trace(); + } + + if (g_traceLen == 0) { PrintAndLogEx(WARNING, "trace is empty, nothing to save"); return PM3_SUCCESS; } char filename[FILE_PATH_SIZE]; char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || cmdp == 'h') return usage_trace_save(); + if (strlen(Cmd) < 1 || (strlen(Cmd) == 1 && cmdp == 'h')) return usage_trace_save(); param_getstr(Cmd, 0, filename, sizeof(filename)); - saveFile(filename, ".bin", trace, traceLen); + saveFile(filename, ".trace", g_trace, g_traceLen); return PM3_SUCCESS; } -static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, - {"load", CmdTraceLoad, AlwaysAvailable, "Load trace from file"}, - {"save", CmdTraceSave, AlwaysAvailable, "Save trace buffer to file"}, - {NULL, NULL, NULL, NULL} -}; - -static int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return PM3_SUCCESS; -} - -int CmdTrace(const char *Cmd) { - clearCommandBuffer(); - return CmdsParse(CommandTable, Cmd); -} - int CmdTraceList(const char *Cmd) { clearCommandBuffer(); @@ -626,52 +601,25 @@ int CmdTraceList(const char *Cmd) { //Validations if (errors) return usage_trace_list(); - uint16_t tracepos = 0; - - // reserv some space. - if (!trace) { - trace = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); - if (trace == NULL) { - PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); - return PM3_EMALLOC; - } - } - if (isOnline) { - // Query for the size of the trace, downloading PM3_CMD_DATA_SIZE - PacketResponseNG response; - if (!GetFromDevice(BIG_BUF, trace, PM3_CMD_DATA_SIZE, 0, NULL, 0, &response, 4000, true)) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return PM3_ETIMEOUT; - } - - traceLen = response.oldarg[2]; - if (traceLen > PM3_CMD_DATA_SIZE) { - uint8_t *p = realloc(trace, traceLen); - if (p == NULL) { - PrintAndLogEx(FAILED, "Cannot allocate memory for trace"); - free(trace); - return PM3_EMALLOC; - } - trace = p; - if (!GetFromDevice(BIG_BUF, trace, traceLen, 0, NULL, 0, NULL, 2500, false)) { - PrintAndLogEx(WARNING, "command execution time out"); - free(trace); - return PM3_ETIMEOUT; - } - } + download_trace(); } - PrintAndLogEx(SUCCESS, "Recorded activity (trace len = " _YELLOW_("%lu") " bytes)", traceLen); + PrintAndLogEx(SUCCESS, "Recorded activity (trace len = " _YELLOW_("%lu") " bytes)", g_traceLen); + if (g_traceLen == 0) { + return PM3_SUCCESS; + } + + uint16_t tracepos = 0; /* if (protocol == FELICA) { - printFelica(traceLen, trace); + printFelica(g_traceLen, g_trace); } */ if (showHex) { - while (tracepos < traceLen) { - tracepos = printHexLine(tracepos, traceLen, trace, protocol); + while (tracepos < g_traceLen) { + tracepos = printHexLine(tracepos, g_traceLen, g_trace, protocol); } } else { PrintAndLogEx(INFO, _YELLOW_("Start") " = Start of Start Bit, " _YELLOW_("End") " = End of last modulation. " _YELLOW_("Src") " = Source of Transfer"); @@ -700,8 +648,8 @@ int CmdTraceList(const char *Cmd) { PrintAndLogEx(NORMAL, "------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------"); ClearAuthData(); - while (tracepos < traceLen) { - tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes); + while (tracepos < g_traceLen) { + tracepos = printTraceLine(tracepos, g_traceLen, g_trace, protocol, showWaitCycles, markCRCBytes); if (kbd_enter_pressed()) break; @@ -710,3 +658,21 @@ int CmdTraceList(const char *Cmd) { return PM3_SUCCESS; } +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, + {"load", CmdTraceLoad, AlwaysAvailable, "Load trace from file"}, + {"save", CmdTraceSave, AlwaysAvailable, "Save trace buffer to file"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdTrace(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/src/cmdusart.c b/client/src/cmdusart.c index 3168d66b7..56d4b88bb 100644 --- a/client/src/cmdusart.c +++ b/client/src/cmdusart.c @@ -274,7 +274,7 @@ static int usart_bt_testcomm(uint32_t baudrate, uint8_t parity) { if (ret != PM3_SUCCESS) return ret; - char *string = "AT+VERSION"; + const char *string = "AT+VERSION"; uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; size_t len = 0; @@ -359,7 +359,7 @@ static int CmdUsartBtFactory(const char *Cmd) { } PrintAndLogEx(INFO, "Reconfiguring add-on to default settings."); - char *string; + const char *string; uint8_t data[PM3_CMD_DATA_SIZE]; size_t len = 0; memset(data, 0, sizeof(data)); diff --git a/client/src/cmdwiegand.c b/client/src/cmdwiegand.c index 3c939261f..19f166284 100644 --- a/client/src/cmdwiegand.c +++ b/client/src/cmdwiegand.c @@ -24,11 +24,11 @@ static int CmdHelp(const char *Cmd); -static int usage_wiegand_list() { +static int usage_wiegand_list(void) { PrintAndLogEx(NORMAL, "List available wiegand formats"); return PM3_SUCCESS; } -static int usage_wiegand_encode() { +static int usage_wiegand_encode(void) { PrintAndLogEx(NORMAL, "Encode wiegand formatted number to raw hex"); PrintAndLogEx(NORMAL, "Usage: wiegand encode [w ] [ ] {...}"); PrintAndLogEx(NORMAL, "Options:"); @@ -42,7 +42,7 @@ static int usage_wiegand_encode() { PrintAndLogEx(NORMAL, " wiegand encode w H10301 f 101 c 1337"); return PM3_SUCCESS; } -static int usage_wiegand_decode() { +static int usage_wiegand_decode(void) { PrintAndLogEx(NORMAL, "Decode raw hex to wiegand format"); PrintAndLogEx(NORMAL, "Usage: wiegand decode [id]

"); PrintAndLogEx(NORMAL, " p ignore invalid parity"); @@ -52,7 +52,7 @@ static int usage_wiegand_decode() { return PM3_SUCCESS; } -void PrintTagId(wiegand_message_t *packed) { +static void PrintTagId(wiegand_message_t *packed) { if (packed->Top != 0) { PrintAndLogEx(SUCCESS, "Card ID: %X%08X%08X", (uint32_t)packed->Top, diff --git a/client/src/comms.c b/client/src/comms.c index 88ffde16c..df4c404df 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -24,8 +24,6 @@ //#define COMMS_DEBUG //#define COMMS_DEBUG_RAW -uint8_t gui_serial_port_name[FILE_PATH_SIZE]; - // Serial port that we are communicating with the PM3 on. static serial_port sp = NULL; @@ -38,7 +36,7 @@ static bool comm_thread_dead = false; // Transmit buffer. static PacketCommandOLD txBuffer; static PacketCommandNGRaw txBufferNG; -size_t txBufferNGLen; +static size_t txBufferNGLen; static bool txBuffer_pending = false; static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t txBufferSig = PTHREAD_COND_INITIALIZER; @@ -117,11 +115,11 @@ void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, v static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool ng) { #ifdef COMMS_DEBUG - PrintAndLogEx(NORMAL, "Sending %s", ng ? "NG" : "MIX"); + PrintAndLogEx(INFO, "Sending %s", ng ? "NG" : "MIX"); #endif if (!session.pm3_present) { - PrintAndLogEx(NORMAL, "Sending bytes to proxmark failed - offline"); + PrintAndLogEx(INFO, "Sending bytes to proxmark failed - offline"); return; } if (len > PM3_CMD_DATA_SIZE) { @@ -202,7 +200,7 @@ void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, v * A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which * operation. Right now we'll just have to live with this. */ -void clearCommandBuffer() { +void clearCommandBuffer(void) { //This is a very simple operation pthread_mutex_lock(&rxBufferMutex); cmd_tail = cmd_head; @@ -291,7 +289,8 @@ static void PacketResponseReceived(PacketResponseNG *packet) { } if (flag & FLAG_LOG) { - PrintAndLogEx(NORMAL, "#db# %s", s); + //PrintAndLogEx(NORMAL, "[" _MAGENTA_("pm3") "] ["_BLUE_("#")"] " "%s", s); + PrintAndLogEx(NORMAL, "[" _BLUE_("#") "] %s", s); } else { if (flag & FLAG_INPLACE) printf("\r"); @@ -305,7 +304,7 @@ static void PacketResponseReceived(PacketResponseNG *packet) { } case CMD_DEBUG_PRINT_INTEGERS: { if (! packet->ng) - PrintAndLogEx(NORMAL, "#db# %" PRIx64 ", %" PRIx64 ", %" PRIx64 "", packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); + PrintAndLogEx(NORMAL, "[" _MAGENTA_("pm3") "] ["_BLUE_("#")"] " "%" PRIx64 ", %" PRIx64 ", %" PRIx64 "", packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; } // iceman: hw status - down the path on device, runs printusbspeed which starts sending a lot of @@ -537,43 +536,42 @@ bool IsCommunicationThreadDead(void) { return ret; } -bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed) { +bool OpenProxmark(char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed) { - char *portname = (char *)port; if (!wait_for_port) { - PrintAndLogEx(INFO, "Using UART port " _YELLOW_("%s"), portname); - sp = uart_open(portname, speed); + PrintAndLogEx(INFO, "Using UART port " _YELLOW_("%s"), port); + sp = uart_open(port, speed); } else { - PrintAndLogEx(SUCCESS, "Waiting for Proxmark3 to appear on " _YELLOW_("%s"), portname); + PrintAndLogEx(SUCCESS, "Waiting for Proxmark3 to appear on " _YELLOW_("%s"), port); fflush(stdout); int openCount = 0; - PrintAndLogEx(INPLACE, ""); + PrintAndLogEx(INPLACE, "% 3i", timeout); do { - sp = uart_open(portname, speed); + sp = uart_open(port, speed); msleep(500); - printf("."); - fflush(stdout); + PrintAndLogEx(INPLACE, "% 3i", timeout - openCount - 1); + } while (++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT)); } // check result of uart opening if (sp == INVALID_SERIAL_PORT) { - PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " invalid serial port " _YELLOW_("%s"), portname); + PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " invalid serial port " _YELLOW_("%s"), port); + PrintAndLogEx(HINT, "Try the shell script " _YELLOW_("`./pm3 --list`") " to get a list of possible serial ports"); sp = NULL; return false; } else if (sp == CLAIMED_SERIAL_PORT) { - PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " serial port " _YELLOW_("%s") " is claimed by another process", portname); + PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " serial port " _YELLOW_("%s") " is claimed by another process", port); + PrintAndLogEx(HINT, "Try the shell script " _YELLOW_("`./pm3 --list`") " to get a list of possible serial ports"); + sp = NULL; return false; } else { // start the communication thread - if (portname != (char *)conn.serial_port_name) { - uint16_t len = MIN(strlen(portname), FILE_PATH_SIZE - 1); + if (port != conn.serial_port_name) { + uint16_t len = MIN(strlen(port), FILE_PATH_SIZE - 1); memset(conn.serial_port_name, 0, FILE_PATH_SIZE); - memcpy(conn.serial_port_name, portname, len); - - memset(gui_serial_port_name, 0, FILE_PATH_SIZE); - memcpy(gui_serial_port_name, portname, len); + memcpy(conn.serial_port_name, port, len); } conn.run = true; conn.block_after_ACK = flash_mode; @@ -605,24 +603,25 @@ int TestProxmark(void) { clearCommandBuffer(); SendCommandNG(CMD_PING, data, len); - uint32_t timeout = 1000; + uint32_t timeout; #ifdef USART_SLOW_LINK // 10s timeout for slow FPC, e.g. over BT // as this is the very first command sent to the pm3 // that initiates the BT connection timeout = 10000; +#else + timeout = 1000; #endif if (WaitForResponseTimeoutW(CMD_PING, &resp, timeout, false) == 0) { return PM3_ETIMEOUT; } - bool error = false; - error = memcmp(data, resp.data.asBytes, len) != 0; - - if (error) + bool error = memcmp(data, resp.data.asBytes, len) != 0; + if (error) { return PM3_EIO; + } SendCommandNG(CMD_CAPABILITIES, NULL, 0); if (WaitForResponseTimeoutW(CMD_CAPABILITIES, &resp, 1000, false) == 0) { @@ -639,9 +638,10 @@ int TestProxmark(void) { conn.send_via_fpc_usart = pm3_capabilities.via_fpc; conn.uart_speed = pm3_capabilities.baudrate; - PrintAndLogEx(INFO, "Communicating with PM3 over %s%s", + PrintAndLogEx(INFO, "Communicating with PM3 over %s%s%s", conn.send_via_fpc_usart ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"), - memcmp(conn.serial_port_name, "tcp:", 4) == 0 ? " over " _YELLOW_("TCP") : ""); + memcmp(conn.serial_port_name, "tcp:", 4) == 0 ? " over " _YELLOW_("TCP") : "", + memcmp(conn.serial_port_name, "bt:", 3) == 0 ? " over " _YELLOW_("BT") : ""); if (conn.send_via_fpc_usart) { PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", conn.uart_speed); @@ -829,6 +829,9 @@ static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, siz if (getReply(response)) { + if (response->cmd == CMD_ACK) + return true; + // sample_buf is a array pointer, located in data.c // arg0 = offset in transfer. Startindex of this chunk // arg1 = length bytes to transfer @@ -851,8 +854,6 @@ static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, siz memcpy(dest + offset, response->data.asBytes, copy_bytes); bytes_completed += copy_bytes; - } else if (response->cmd == CMD_ACK) { - return true; } else if (response->cmd == CMD_WTX && response->length == sizeof(uint16_t)) { uint16_t wtx = response->data.asDwords[0] & 0xFFFF; PrintAndLogEx(DEBUG, "Got Waiting Time eXtension request %i ms", wtx); @@ -869,8 +870,8 @@ static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, siz if (msclock() - tmp_clk > 3000 && show_warning) { // 3 seconds elapsed (but this doesn't mean the timeout was exceeded) - PrintAndLogEx(NORMAL, "Waiting for a response from the Proxmark3..."); - PrintAndLogEx(NORMAL, "You can cancel this operation by pressing the pm3 button"); + PrintAndLogEx(INFO, "Waiting for a response from the Proxmark3..."); + PrintAndLogEx(INFO, "You can cancel this operation by pressing the pm3 button"); show_warning = false; } } diff --git a/client/src/comms.h b/client/src/comms.h index 288e8a326..9fcf1b7a6 100644 --- a/client/src/comms.h +++ b/client/src/comms.h @@ -16,6 +16,10 @@ #include "pm3_cmd.h" // Packet structs #include "util.h" // FILE_PATH_SIZE +#ifdef __cplusplus +extern "C" { +#endif + #ifndef DropField #define DropField() { \ clearCommandBuffer(); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); \ @@ -56,13 +60,11 @@ typedef struct { // To memorise baudrate uint32_t uart_speed; uint16_t last_command; - uint8_t serial_port_name[FILE_PATH_SIZE]; + char serial_port_name[FILE_PATH_SIZE]; } communication_arg_t; extern communication_arg_t conn; -extern uint8_t gui_serial_port_name[FILE_PATH_SIZE]; - void *uart_receiver(void *targ); void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); @@ -72,7 +74,7 @@ void clearCommandBuffer(void); #define FLASHMODE_SPEED 460800 bool IsCommunicationThreadDead(void); -bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed); +bool OpenProxmark(char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed); int TestProxmark(void); void CloseProxmark(void); @@ -83,6 +85,9 @@ bool WaitForResponse(uint32_t cmd, PacketResponseNG *response); //bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning); bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, uint8_t *data, uint32_t datalen, PacketResponseNG *response, size_t ms_timeout, bool show_warning); +#ifdef __cplusplus +} +#endif #endif diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index 1b2c78212..9e5826712 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -64,14 +64,12 @@ exit: return res; } -static bool print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { +static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { bool candump = true; asn1_tag_dump(tlv, stdout, level, &candump); if (is_leaf && candump) { dump_buffer(tlv->value, tlv->len, stdout, level); } - - return true; } int asn1_print(uint8_t *asn1buf, size_t asn1buflen, const char *indent) { @@ -81,7 +79,7 @@ int asn1_print(uint8_t *asn1buf, size_t asn1buflen, const char *indent) { tlvdb_visit(t, print_cb, NULL, 0); tlvdb_free(t); } else { - PrintAndLogEx(ERR, "Can't parse data as TLV tree."); + PrintAndLogEx(ERR, "Can't parse data as TLV tree"); return 1; } diff --git a/client/src/emv/apduinfo.c b/client/src/emv/apduinfo.c index bc8d3f8ae..2b319cbe8 100644 --- a/client/src/emv/apduinfo.c +++ b/client/src/emv/apduinfo.c @@ -425,7 +425,7 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) { if (len) *len = 0; - if (apdu->le > 0x10000 || apdu->lc > 0xffff) + if (apdu->le > 0x10000) return 1; size_t dptr = 0; @@ -434,7 +434,7 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) { data[dptr++] = apdu->p1; data[dptr++] = apdu->p2; - if (apdu->lc) { + if (apdu->lc) { // apdu->lc is uint16_t so max 0xffff if (apdu->extended_apdu || apdu->lc > 0xff || apdu->le > 0x100) { data[dptr++] = 0x00; data[dptr++] = (apdu->lc >> 8) & 0xff; diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index 2cf76a636..65c9cafb2 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -56,10 +56,10 @@ static void ParamLoadDefaults(struct tlvdb *tlvRoot) { static void PrintChannel(EMVCommandChannel channel) { switch (channel) { case ECC_CONTACTLESS: - PrintAndLogEx(INFO, "Channel: CONTACTLESS (T=CL)"); + PrintAndLogEx(INFO, "Selected channel : " _GREEN_("CONTACTLESS (T=CL)")); break; case ECC_CONTACT: - PrintAndLogEx(INFO, "Channel: CONTACT"); + PrintAndLogEx(INFO, "Selected channel : " _GREEN_("CONTACT")); break; } } @@ -68,7 +68,8 @@ static int CmdEMVSelect(const char *Cmd) { uint8_t data[APDU_AID_LEN] = {0}; int datalen = 0; - CLIParserInit("emv select", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv select", "Executes select applet command", "Usage:\n\temv select -s a00000000101 -> select card, select applet\n\temv select -st a00000000101 -> select card, select applet, show result in TLV\n"); @@ -82,18 +83,18 @@ static int CmdEMVSelect(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool activateField = arg_get_lit(1); - bool leaveSignalON = arg_get_lit(2); - bool APDULogging = arg_get_lit(3); - bool decodeTLV = arg_get_lit(4); + bool activateField = arg_get_lit(ctx, 1); + bool leaveSignalON = arg_get_lit(ctx, 2); + bool APDULogging = arg_get_lit(ctx, 3); + bool decodeTLV = arg_get_lit(ctx, 4); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(5)) + if (arg_get_lit(ctx, 5)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(6, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 6, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -117,7 +118,8 @@ static int CmdEMVSelect(const char *Cmd) { static int CmdEMVSearch(const char *Cmd) { - CLIParserInit("emv search", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv search", "Tries to select all applets from applet list:\n", "Usage:\n\temv search -s -> select card and search\n\temv search -st -> select card, search and show result in TLV\n"); @@ -130,23 +132,22 @@ static int CmdEMVSearch(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool activateField = arg_get_lit(1); - bool leaveSignalON = arg_get_lit(2); - bool APDULogging = arg_get_lit(3); - bool decodeTLV = arg_get_lit(4); + bool activateField = arg_get_lit(ctx, 1); + bool leaveSignalON = arg_get_lit(ctx, 2); + bool APDULogging = arg_get_lit(ctx, 3); + bool decodeTLV = arg_get_lit(ctx, 4); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(5)) + if (arg_get_lit(ctx, 5)) channel = ECC_CONTACT; PrintChannel(channel); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); - struct tlvdb *t = NULL; const char *al = "Applets list"; - t = tlvdb_fixed(1, strlen(al), (const unsigned char *)al); + struct tlvdb *t = tlvdb_fixed(1, strlen(al), (const unsigned char *)al); if (EMVSearch(channel, activateField, leaveSignalON, decodeTLV, t)) { tlvdb_free(t); @@ -167,7 +168,8 @@ static int CmdEMVSearch(const char *Cmd) { static int CmdEMVPPSE(const char *Cmd) { - CLIParserInit("emv pse", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv pse", "Executes PSE/PPSE select command. It returns list of applet on the card:\n", "Usage:\n\temv pse -s1 -> select, get pse\n\temv pse -st2 -> select, get ppse, show result in TLV\n"); @@ -182,22 +184,22 @@ static int CmdEMVPPSE(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool activateField = arg_get_lit(1); - bool leaveSignalON = arg_get_lit(2); + bool activateField = arg_get_lit(ctx, 1); + bool leaveSignalON = arg_get_lit(ctx, 2); uint8_t PSENum = 2; - if (arg_get_lit(3)) + if (arg_get_lit(ctx, 3)) PSENum = 1; - if (arg_get_lit(4)) + if (arg_get_lit(ctx, 4)) PSENum = 2; - bool APDULogging = arg_get_lit(5); - bool decodeTLV = arg_get_lit(6); + bool APDULogging = arg_get_lit(ctx, 5); + bool decodeTLV = arg_get_lit(ctx, 6); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(7)) + if (arg_get_lit(ctx, 7)) channel = ECC_CONTACT; PrintChannel(channel); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -223,7 +225,8 @@ static int CmdEMVGPO(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv gpo", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv gpo", "Executes Get Processing Options command. It returns data in TLV format (0x77 - format2) or plain format (0x80 - format1).\nNeeds a EMV applet to be selected.", "Usage:\n\temv gpo -k -> execute GPO\n" "\temv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n" @@ -240,19 +243,19 @@ static int CmdEMVGPO(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool leaveSignalON = arg_get_lit(1); - bool paramsLoadFromFile = arg_get_lit(2); - bool dataMakeFromPDOL = arg_get_lit(3); - bool APDULogging = arg_get_lit(4); - bool decodeTLV = arg_get_lit(5); + bool leaveSignalON = arg_get_lit(ctx, 1); + bool paramsLoadFromFile = arg_get_lit(ctx, 2); + bool dataMakeFromPDOL = arg_get_lit(ctx, 3); + bool APDULogging = arg_get_lit(ctx, 4); + bool decodeTLV = arg_get_lit(ctx, 5); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(6)) + if (arg_get_lit(ctx, 6)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(7, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 7, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -331,7 +334,8 @@ static int CmdEMVReadRecord(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv readrec", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv readrec", "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.", "Usage:\n\temv readrec -k 0101 -> read file SFI=01, SFIrec=01\n\temv readrec -kt 0201-> read file 0201 and show result in TLV\n"); @@ -344,17 +348,17 @@ static int CmdEMVReadRecord(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool leaveSignalON = arg_get_lit(1); - bool APDULogging = arg_get_lit(2); - bool decodeTLV = arg_get_lit(3); + bool leaveSignalON = arg_get_lit(ctx, 1); + bool APDULogging = arg_get_lit(ctx, 2); + bool decodeTLV = arg_get_lit(ctx, 3); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(4)) + if (arg_get_lit(ctx, 4)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(5, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 5, data, &datalen); + CLIParserFree(ctx); if (datalen != 2) { PrintAndLogEx(ERR, "Command needs to have 2 bytes of data"); @@ -386,7 +390,8 @@ static int CmdEMVAC(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv genac", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv genac", "Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.", "Usage:\n\temv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n" "\temv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n" @@ -406,21 +411,22 @@ static int CmdEMVAC(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - bool leaveSignalON = arg_get_lit(1); - bool trTypeCDA = arg_get_lit(2); + bool leaveSignalON = arg_get_lit(ctx, 1); + bool trTypeCDA = arg_get_lit(ctx, 2); uint8_t termDecision = 0xff; - if (arg_get_str_len(3)) { - if (!strncmp(arg_get_str(3)->sval[0], "aac", 4)) + if (arg_get_str_len(ctx, 3)) { + if (!strncmp(arg_get_str(ctx, 3)->sval[0], "aac", 4)) termDecision = EMVAC_AAC; - if (!strncmp(arg_get_str(3)->sval[0], "tc", 4)) + if (!strncmp(arg_get_str(ctx, 3)->sval[0], "tc", 4)) termDecision = EMVAC_TC; - if (!strncmp(arg_get_str(3)->sval[0], "arqc", 4)) + if (!strncmp(arg_get_str(ctx, 3)->sval[0], "arqc", 4)) termDecision = EMVAC_ARQC; if (termDecision == 0xff) { - PrintAndLogEx(ERR, "ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval[0]); + PrintAndLogEx(ERR, "ERROR: can't find terminal decision '%s'", arg_get_str(ctx, 3)->sval[0]); + CLIParserFree(ctx); return PM3_EINVARG; } } else { @@ -428,16 +434,18 @@ static int CmdEMVAC(const char *Cmd) { } if (trTypeCDA) termDecision = termDecision | EMVAC_CDAREQ; - bool paramsLoadFromFile = arg_get_lit(4); - bool dataMakeFromCDOL = arg_get_lit(5); - bool APDULogging = arg_get_lit(6); - bool decodeTLV = arg_get_lit(7); + bool paramsLoadFromFile = arg_get_lit(ctx, 4); + bool dataMakeFromCDOL = arg_get_lit(ctx, 5); + bool APDULogging = arg_get_lit(ctx, 6); + bool decodeTLV = arg_get_lit(ctx, 7); + EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(8)) + if (arg_get_lit(ctx, 8)) channel = ECC_CONTACT; + PrintChannel(channel); - CLIGetHexWithReturn(9, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 9, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -505,7 +513,8 @@ static int CmdEMVAC(const char *Cmd) { static int CmdEMVGenerateChallenge(const char *Cmd) { - CLIParserInit("emv challenge", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv challenge", "Executes Generate Challenge command. It returns 4 or 8-byte random number from card.\nNeeds a EMV applet to be selected and GPO to be executed.", "Usage:\n\temv challenge -> get challenge\n\temv challenge -k -> get challenge, keep fileld ON\n"); @@ -516,15 +525,15 @@ static int CmdEMVGenerateChallenge(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool leaveSignalON = arg_get_lit(1); - bool APDULogging = arg_get_lit(2); + bool leaveSignalON = arg_get_lit(ctx, 1); + bool APDULogging = arg_get_lit(ctx, 2); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(3)) + if (arg_get_lit(ctx, 3)) channel = ECC_CONTACT; PrintChannel(channel); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -552,7 +561,8 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv intauth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv intauth", "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\n" "Needs a EMV applet to be selected and GPO to be executed.", @@ -572,19 +582,19 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); - bool leaveSignalON = arg_get_lit(1); - bool paramsLoadFromFile = arg_get_lit(2); - bool dataMakeFromDDOL = arg_get_lit(3); - bool APDULogging = arg_get_lit(4); - bool decodeTLV = arg_get_lit(5); + bool leaveSignalON = arg_get_lit(ctx, 1); + bool paramsLoadFromFile = arg_get_lit(ctx, 2); + bool dataMakeFromDDOL = arg_get_lit(ctx, 3); + bool APDULogging = arg_get_lit(ctx, 4); + bool decodeTLV = arg_get_lit(ctx, 5); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(6)) + if (arg_get_lit(ctx, 6)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(7, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 7, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -782,7 +792,8 @@ static int CmdEMVExec(const char *Cmd) { struct tlvdb *tlvRoot = NULL; struct tlv *pdol_data_tlv = NULL; - CLIParserInit("emv exec", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv exec", "Executes EMV contactless transaction", "Usage:\n" "\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n" @@ -803,29 +814,29 @@ static int CmdEMVExec(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool activateField = arg_get_lit(1); - bool showAPDU = arg_get_lit(2); - bool decodeTLV = arg_get_lit(3); - bool paramLoadJSON = arg_get_lit(4); - bool forceSearch = arg_get_lit(5); + bool activateField = arg_get_lit(ctx, 1); + bool showAPDU = arg_get_lit(ctx, 2); + bool decodeTLV = arg_get_lit(ctx, 3); + bool paramLoadJSON = arg_get_lit(ctx, 4); + bool forceSearch = arg_get_lit(ctx, 5); enum TransactionType TrType = TT_MSD; - if (arg_get_lit(7)) + if (arg_get_lit(ctx, 7)) TrType = TT_QVSDCMCHIP; - if (arg_get_lit(8)) + if (arg_get_lit(ctx, 8)) TrType = TT_CDA; - if (arg_get_lit(9)) + if (arg_get_lit(ctx, 9)) TrType = TT_VSDC; - bool GenACGPO = arg_get_lit(10); + bool GenACGPO = arg_get_lit(ctx, 10); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(11)) + if (arg_get_lit(ctx, 11)) channel = ECC_CONTACT; PrintChannel(channel); uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; - CLIParserFree(); + CLIParserFree(ctx); if (!IfPm3Smartcard()) { if (channel == ECC_CONTACT) { @@ -1368,12 +1379,15 @@ static int CmdEMVScan(const char *Cmd) { size_t AIDlen = 0; uint8_t buf[APDU_RES_LEN] = {0}; size_t len = 0; + uint8_t ODAI_list[4096]; + size_t ODAI_listlen = 0; uint16_t sw = 0; int res; json_t *root; json_error_t error; - CLIParserInit("emv scan", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv scan", "Scan EMV card and save it contents to a file.", "It executes EMV contactless transaction and saves result to a file which can be used for emulation\n" "Usage:\n\temv scan -at -> scan MSD transaction mode and show APDU and TLV\n" @@ -1395,37 +1409,37 @@ static int CmdEMVScan(const char *Cmd) { arg_str1(NULL, NULL, "output.json", "JSON output file name"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool showAPDU = arg_get_lit(1); - bool decodeTLV = arg_get_lit(2); - bool extractTLVElements = arg_get_lit(3); - bool paramLoadJSON = arg_get_lit(4); + bool showAPDU = arg_get_lit(ctx, 1); + bool decodeTLV = arg_get_lit(ctx, 2); + bool extractTLVElements = arg_get_lit(ctx, 3); + bool paramLoadJSON = arg_get_lit(ctx, 4); enum TransactionType TrType = TT_MSD; - if (arg_get_lit(6)) + if (arg_get_lit(ctx, 6)) TrType = TT_QVSDCMCHIP; - if (arg_get_lit(7)) + if (arg_get_lit(ctx, 7)) TrType = TT_CDA; - if (arg_get_lit(8)) + if (arg_get_lit(ctx, 8)) TrType = TT_VSDC; - bool GenACGPO = arg_get_lit(9); - bool MergeJSON = arg_get_lit(10); + bool GenACGPO = arg_get_lit(ctx, 9); + bool MergeJSON = arg_get_lit(ctx, 10); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(11)) + if (arg_get_lit(ctx, 11)) channel = ECC_CONTACT; PrintChannel(channel); uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; uint8_t relfname[250] = {0}; char *crelfname = (char *)relfname; int relfnamelen = 0; - CLIGetStrWithReturn(12, relfname, &relfnamelen); - CLIParserFree(); + CLIGetStrWithReturn(ctx, 12, relfname, &relfnamelen); + CLIParserFree(ctx); if (!IfPm3Smartcard()) { if (channel == ECC_CONTACT) { - PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support. Exiting."); + PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support, exiting"); return PM3_EDEVNOTSUPP; } } @@ -1435,6 +1449,7 @@ static int CmdEMVScan(const char *Cmd) { // current path + file name if (!strstr(crelfname, ".json")) strcat(crelfname, ".json"); + char fname[strlen(get_my_executable_directory()) + strlen(crelfname) + 1]; strcpy(fname, get_my_executable_directory()); strcat(fname, crelfname); @@ -1447,7 +1462,7 @@ static int CmdEMVScan(const char *Cmd) { } if (!json_is_object(root)) { - PrintAndLogEx(ERR, "Invalid json format. root must be an object."); + PrintAndLogEx(ERR, "Invalid json format. root must be an object"); return PM3_EFILE; } } else { @@ -1461,7 +1476,7 @@ static int CmdEMVScan(const char *Cmd) { if (channel == ECC_CONTACTLESS) { // iso 14443 select - PrintAndLogEx(NORMAL, "--> GET UID, ATS."); + PrintAndLogEx(INFO, "GET UID, ATS"); iso14a_card_select_t card; if (Hf14443_4aGetCardData(&card)) { @@ -1474,7 +1489,7 @@ static int CmdEMVScan(const char *Cmd) { JsonSaveHex(root, "$.Card.Contactless.SAK", card.sak, 0); JsonSaveBufAsHex(root, "$.Card.Contactless.ATS", (uint8_t *)card.ats, card.ats_len); } else { - PrintAndLogEx(NORMAL, "--> GET ATR."); + PrintAndLogEx(INFO, "GET ATR"); smart_card_atr_t card; smart_select(true, &card); @@ -1492,7 +1507,7 @@ static int CmdEMVScan(const char *Cmd) { struct tlvdb *tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al); // EMV PPSE - PrintAndLogEx(NORMAL, "--> PPSE."); + PrintAndLogEx(INFO, "PPSE"); res = EMVSelectPSE(channel, true, true, 2, buf, sizeof(buf), &len, &sw); if (!res && sw == 0x9000) { @@ -1518,9 +1533,9 @@ static int CmdEMVScan(const char *Cmd) { } else { // EMV SEARCH with AID list SetAPDULogging(false); - PrintAndLogEx(NORMAL, "--> AID search."); + PrintAndLogEx(INFO, "AID search."); if (EMVSearch(channel, false, true, decodeTLV, tlvSelect)) { - PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); + PrintAndLogEx(ERR, "Can't found any of EMV AID, exiting..."); tlvdb_free(tlvSelect); DropFieldEx(channel); return PM3_ERFTRANS; @@ -1537,7 +1552,7 @@ static int CmdEMVScan(const char *Cmd) { tlvdb_free(tlvSelect); if (!AIDlen) { - PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); + PrintAndLogEx(INFO, "Can't select AID. EMV AID not found, exiting..."); DropFieldEx(channel); return PM3_ERFTRANS; } @@ -1550,12 +1565,12 @@ static int CmdEMVScan(const char *Cmd) { // EMV SELECT applet - PrintAndLogEx(NORMAL, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID, AIDlen)); + PrintAndLogEx(INFO, "Selecting AID: " _GREEN_("%s"), sprint_hex_inrow(AID, AIDlen)); SetAPDULogging(showAPDU); res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot); if (res) { - PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); + PrintAndLogEx(ERR, "Can't select AID (%d), exiting...", res); tlvdb_free(tlvRoot); DropFieldEx(channel); return PM3_ERFTRANS; @@ -1577,13 +1592,13 @@ static int CmdEMVScan(const char *Cmd) { tlvdb_free(fci); // create transaction parameters - PrintAndLogEx(NORMAL, "-->Init transaction parameters."); + PrintAndLogEx(INFO, "Init transaction parameters"); InitTransactionParameters(tlvRoot, paramLoadJSON, TrType, GenACGPO); - PrintAndLogEx(NORMAL, "-->Calc PDOL."); + PrintAndLogEx(INFO, "Calc PDOL"); struct tlv *pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83); if (!pdol_data_tlv) { - PrintAndLogEx(ERR, "Can't create PDOL TLV."); + PrintAndLogEx(ERR, "Can't create PDOL TLV"); tlvdb_free(tlvRoot); DropFieldEx(channel); return PM3_ESOFT; @@ -1592,7 +1607,7 @@ static int CmdEMVScan(const char *Cmd) { size_t pdol_data_tlv_data_len; unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len); if (!pdol_data_tlv_data) { - PrintAndLogEx(ERR, "Can't create PDOL data."); + PrintAndLogEx(ERR, "Can't create PDOL data"); tlvdb_free(tlvRoot); free(pdol_data_tlv); DropFieldEx(channel); @@ -1600,14 +1615,14 @@ static int CmdEMVScan(const char *Cmd) { } PrintAndLogEx(INFO, "PDOL data[%zu]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); - PrintAndLogEx(INFO, "-->GPO."); + PrintAndLogEx(INFO, "GPO"); res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot); free(pdol_data_tlv_data); free(pdol_data_tlv); if (res) { - PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); + PrintAndLogEx(ERR, "GPO error(%d): %4x, exiting...", res, sw); tlvdb_free(tlvRoot); DropFieldEx(channel); return PM3_ERFTRANS; @@ -1625,7 +1640,7 @@ static int CmdEMVScan(const char *Cmd) { tlvdb_free(gpofci); - PrintAndLogEx(INFO, "-->Read records from AFL."); + PrintAndLogEx(INFO, "Read records from AFL"); const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL); while (AFL && AFL->len) { @@ -1650,15 +1665,16 @@ static int CmdEMVScan(const char *Cmd) { uint8_t SFIstart = AFL->value[i * 4 + 1]; uint8_t SFIend = AFL->value[i * 4 + 2]; uint8_t SFIoffline = AFL->value[i * 4 + 3]; + bool first_time = SFIoffline; - PrintAndLogEx(INFO, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline); + PrintAndLogEx(INFO, " SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline); if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) { PrintAndLogEx(ERR, "SFI ERROR! Skipped..."); continue; } for (int n = SFIstart; n <= SFIend; n++) { - PrintAndLogEx(INFO, "---->SFI[%02x] %d", SFI, n); + PrintAndLogEx(INFO, " SFI[%02x] %d", SFI, n); res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot); if (res) { @@ -1666,6 +1682,26 @@ static int CmdEMVScan(const char *Cmd) { continue; } + // Build Input list for Offline Data Authentication + // EMV 4.3 book3 10.3, page 96 + if (first_time && SFIoffline) { + if (SFI < 11) { + const unsigned char *abuf = buf; + size_t elmlen = len; + struct tlv e; + if (tlv_parse_tl(&abuf, &elmlen, &e)) { + memcpy(ODAI_list + ODAI_listlen, &buf[len - elmlen], elmlen); + ODAI_listlen += elmlen; + } else { + PrintAndLogEx(WARNING, "Error SFI[%02x]. Creating input list for Offline Data Authentication error", SFI); + } + } else { + memcpy(ODAI_list + ODAI_listlen, buf, len); + ODAI_listlen += len; + } + first_time = false; + } + if (decodeTLV) { TLVPrintFromBuffer(buf, len); PrintAndLogEx(NORMAL, ""); @@ -1683,16 +1719,23 @@ static int CmdEMVScan(const char *Cmd) { JsonSaveTLVTree(root, jsonelm, "$.Data", rsfi); else JsonSaveTLVTreeElm(jsonelm, "$.Data", rsfi, true, true, false); + tlvdb_free(rsfi); } } - break; } + // copy Input list for Offline Data Authentication + if (ODAI_listlen) { + struct tlvdb *oda = tlvdb_fixed(0x21, ODAI_listlen, ODAI_list); // not a standard tag + tlvdb_add(tlvRoot, oda); + PrintAndLogEx(INFO, "Input list for Offline Data Authentication added to TLV [%zu bytes]", ODAI_listlen); + } + // getting certificates if (tlvdb_get(tlvRoot, 0x90, NULL)) { - PrintAndLogEx(INFO, "-->Recovering certificates."); + PrintAndLogEx(INFO, "Recovering certificates"); PKISetStrictExecution(false); RecoveryCertificates(tlvRoot, root); PKISetStrictExecution(true); @@ -1712,7 +1755,6 @@ static int CmdEMVScan(const char *Cmd) { // free json object json_decref(root); - return PM3_SUCCESS; } @@ -1722,7 +1764,8 @@ static int CmdEMVList(const char *Cmd) { } static int CmdEMVTest(const char *Cmd) { - CLIParserInit("emv test", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv test", "Executes tests\n", "Usage:\n\temv test [l]\n"); @@ -1732,11 +1775,11 @@ static int CmdEMVTest(const char *Cmd) { arg_lit0("lL", "long", "run long tests too"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - bool ignoreTimeTest = arg_get_lit(1); - bool runSlowTests = arg_get_lit(2); - CLIParserFree(); + bool ignoreTimeTest = arg_get_lit(ctx, 1); + bool runSlowTests = arg_get_lit(ctx, 2); + CLIParserFree(ctx); return ExecuteCryptoTests(true, ignoreTimeTest, runSlowTests); } @@ -1747,9 +1790,12 @@ static int CmdEMVRoca(const char *Cmd) { uint8_t buf[APDU_RES_LEN] = {0}; size_t len = 0; uint16_t sw = 0; + uint8_t ODAI_list[4096]; + size_t ODAI_listlen = 0; int res; - CLIParserInit("emv roca", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv roca", "Tries to extract public keys and run the ROCA test against them.\n", "Usage:\n" "\temv roca -w -> select --CONTACT-- card and run test\n" @@ -1759,23 +1805,29 @@ static int CmdEMVRoca(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("tT", "selftest", "self test"), - arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), + arg_lit0("aA", "apdu", "show APDU reqests and responses"), + arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); + + if (arg_get_lit(ctx, 1)) { + CLIParserFree(ctx); + return roca_self_test(); + } + + bool show_apdu = arg_get_lit(ctx, 2); EMVCommandChannel channel = ECC_CONTACTLESS; - if (arg_get_lit(1)) - return roca_self_test(); - - if (arg_get_lit(2)) + if (arg_get_lit(ctx, 3)) channel = ECC_CONTACT; + + CLIParserFree(ctx); PrintChannel(channel); - CLIParserFree(); if (!IfPm3Smartcard()) { if (channel == ECC_CONTACT) { - PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support. Exiting."); + PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support, exiting"); return PM3_EDEVNOTSUPP; } } @@ -1783,14 +1835,14 @@ static int CmdEMVRoca(const char *Cmd) { // select card uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; - SetAPDULogging(false); + SetAPDULogging(show_apdu); // init applets list tree const char *al = "Applets list"; struct tlvdb *tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al); // EMV PPSE - PrintAndLogEx(NORMAL, "--> PPSE."); + PrintAndLogEx(INFO, "PPSE"); res = EMVSearchPSE(channel, false, true, psenum, false, tlvSelect); // check PPSE and select application id @@ -1798,9 +1850,9 @@ static int CmdEMVRoca(const char *Cmd) { TLVPrintAIDlistFromSelectTLV(tlvSelect); } else { // EMV SEARCH with AID list - PrintAndLogEx(NORMAL, "--> AID search."); + PrintAndLogEx(INFO, "starting AID search"); if (EMVSearch(channel, false, true, false, tlvSelect)) { - PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit..."); + PrintAndLogEx(ERR, "Can't found any of EMV AID, exiting"); tlvdb_free(tlvSelect); DropFieldEx(channel); return PM3_ERFTRANS; @@ -1817,7 +1869,7 @@ static int CmdEMVRoca(const char *Cmd) { tlvdb_free(tlvSelect); if (!AIDlen) { - PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit..."); + PrintAndLogEx(INFO, "Can't select AID or EMV AID not found, exiting"); DropFieldEx(channel); return PM3_ERFTRANS; } @@ -1827,23 +1879,23 @@ static int CmdEMVRoca(const char *Cmd) { struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr); // EMV SELECT applet - PrintAndLogEx(NORMAL, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID, AIDlen)); + PrintAndLogEx(INFO, "Selecting AID: " _YELLOW_("%s"), sprint_hex_inrow(AID, AIDlen)); res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot); if (res) { - PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res); + PrintAndLogEx(ERR, "Can't select AID (%d), exiting", res); tlvdb_free(tlvRoot); DropFieldEx(channel); return PM3_ERFTRANS; } - PrintAndLogEx(NORMAL, "\n* Init transaction parameters."); + PrintAndLogEx(INFO, "Init transaction parameters"); InitTransactionParameters(tlvRoot, true, TT_QVSDCMCHIP, false); - PrintAndLogEx(NORMAL, "-->Calc PDOL."); + PrintAndLogEx(INFO, "Calc PDOL"); struct tlv *pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83); if (!pdol_data_tlv) { - PrintAndLogEx(ERR, "Can't create PDOL TLV."); + PrintAndLogEx(ERR, "Can't create PDOL TLV"); tlvdb_free(tlvRoot); DropFieldEx(channel); return PM3_ESOFT; @@ -1852,7 +1904,7 @@ static int CmdEMVRoca(const char *Cmd) { size_t pdol_data_tlv_data_len; unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len); if (!pdol_data_tlv_data) { - PrintAndLogEx(ERR, "Can't create PDOL data."); + PrintAndLogEx(ERR, "Can't create PDOL data, exiting"); tlvdb_free(tlvRoot); DropFieldEx(channel); free(pdol_data_tlv); @@ -1860,21 +1912,21 @@ static int CmdEMVRoca(const char *Cmd) { } PrintAndLogEx(INFO, "PDOL data[%zu]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); - PrintAndLogEx(INFO, "-->GPO."); + PrintAndLogEx(INFO, "GPO"); res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot); free(pdol_data_tlv_data); free(pdol_data_tlv); if (res) { - PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw); + PrintAndLogEx(ERR, "GPO error(%d): %4x, exiting", res, sw); tlvdb_free(tlvRoot); DropFieldEx(channel); return PM3_ERFTRANS; } ProcessGPOResponseFormat1(tlvRoot, buf, len, false); - PrintAndLogEx(INFO, "-->Read records from AFL."); + PrintAndLogEx(INFO, "Read records from AFL"); const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL); while (AFL && AFL->len) { @@ -1889,35 +1941,62 @@ static int CmdEMVRoca(const char *Cmd) { uint8_t SFIend = AFL->value[i * 4 + 2]; uint8_t SFIoffline = AFL->value[i * 4 + 3]; - PrintAndLogEx(INFO, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline); + PrintAndLogEx(INFO, " SFI[%02x] start :%02x end :%02x offline :%02x", SFI, SFIstart, SFIend, SFIoffline); if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) { - PrintAndLogEx(ERR, "SFI ERROR! Skipped..."); + PrintAndLogEx(ERR, "SFI ERROR, skipping"); continue; } for (int n = SFIstart; n <= SFIend; n++) { - PrintAndLogEx(INFO, "---->SFI[%02x] %d", SFI, n); + PrintAndLogEx(INFO, " SFI[%02x] %d", SFI, n); res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot); if (res) { PrintAndLogEx(ERR, "SFI[%02x]. APDU error %4x", SFI, sw); continue; } + + // Build Input list for Offline Data Authentication + // EMV 4.3 book3 10.3, page 96 + if (SFIoffline > 0) { + if (SFI < 11) { + const unsigned char *abuf = buf; + size_t elmlen = len; + struct tlv e; + if (tlv_parse_tl(&abuf, &elmlen, &e)) { + memcpy(ODAI_list + ODAI_listlen, &buf[len - elmlen], elmlen); + ODAI_listlen += elmlen; + } else { + PrintAndLogEx(WARNING, "Error SFI[%02x]. Creating input list for Offline Data Authentication error", SFI); + } + } else { + memcpy(ODAI_list + ODAI_listlen, buf, len); + ODAI_listlen += len; + } + SFIoffline--; + } } } - break; } // getting certificates int ret = PM3_SUCCESS; + + // copy Input list for Offline Data Authentication + if (ODAI_listlen) { + struct tlvdb *oda = tlvdb_fixed(0x21, ODAI_listlen, ODAI_list); // not a standard tag + tlvdb_add(tlvRoot, oda); + PrintAndLogEx(INFO, "Input list for Offline Data Authentication added to TLV [%zu bytes]", ODAI_listlen); + } + if (tlvdb_get(tlvRoot, 0x90, NULL)) { - PrintAndLogEx(INFO, "-->Recovering certificates."); + PrintAndLogEx(INFO, "Recovering certificates"); PKISetStrictExecution(false); struct emv_pk *pk = get_ca_pk(tlvRoot); if (!pk) { - PrintAndLogEx(ERR, "ERROR: Key not found. Exit."); + PrintAndLogEx(ERR, "ERROR: Key not found, exiting"); ret = PM3_ESOFT; goto out; } @@ -1925,41 +2004,45 @@ static int CmdEMVRoca(const char *Cmd) { struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlvRoot); if (!issuer_pk) { emv_pk_free(pk); - PrintAndLogEx(WARNING, "WARNING: Issuer certificate not found. Exit."); + PrintAndLogEx(WARNING, "WARNING: Issuer certificate not found, exiting"); ret = PM3_ESOFT; goto out; } - PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %s IDX %02hhx CSN %s", + PrintAndLogEx(SUCCESS, "Issuer Public key recovered RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), sprint_hex(issuer_pk->rid, 5), issuer_pk->index, sprint_hex(issuer_pk->serial, 3) ); - struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlvRoot, NULL); + const struct tlv *sda_tlv = tlvdb_get(tlvRoot, 0x21, NULL); + struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlvRoot, sda_tlv); if (!icc_pk) { emv_pk_free(pk); emv_pk_free(issuer_pk); - PrintAndLogEx(WARNING, "WARNING: ICC certificate not found. Exit."); + PrintAndLogEx(WARNING, "WARNING: ICC certificate not found, exiting"); ret = PM3_ESOFT; goto out; } - PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %s IDX %02hhx CSN %s\n", + + PrintAndLogEx(SUCCESS, "ICC Public key recovered RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), sprint_hex(icc_pk->rid, 5), icc_pk->index, sprint_hex(icc_pk->serial, 3) ); - PrintAndLogEx(INFO, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk->modulus, icc_pk->mlen)); + PrintAndLogEx(INFO, "ICC Public key modulus:"); + print_hex_break(icc_pk->modulus, icc_pk->mlen, 16); // icc_pk->exp, icc_pk->elen // icc_pk->modulus, icc_pk->mlen if (icc_pk->elen > 0 && icc_pk->mlen > 0) { - if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen, true)) { - PrintAndLogEx(INFO, "ICC pk is a subject to ROCA vulnerability, insecure.."); + PrintAndLogEx(NORMAL, ""); + if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen, false)) { + PrintAndLogEx(SUCCESS, "ICC Public key is " _RED_("subject") " to ROCA vulnerability, it is considered insecure"); } else { - PrintAndLogEx(INFO, "ICC pk is OK("); + PrintAndLogEx(INFO, "ICC Public key is " _GREEN_("not subject") " to ROCA vulnerability, it is secure"); } } @@ -1967,10 +2050,7 @@ static int CmdEMVRoca(const char *Cmd) { } out: - - // free tlv object tlvdb_free(tlvRoot); - DropFieldEx(channel); return ret; } diff --git a/client/src/emv/crypto_polarssl.c b/client/src/emv/crypto_polarssl.c index e258f1bbb..f9603ead5 100644 --- a/client/src/emv/crypto_polarssl.c +++ b/client/src/emv/crypto_polarssl.c @@ -20,11 +20,12 @@ #include "crypto_backend.h" -#include -#include +#include // malloc +#include // memset -#include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" +#include "rsa.h" +#include "sha1.h" +#include "ui.h" // printandlog struct crypto_hash_polarssl { struct crypto_hash ch; @@ -33,19 +34,16 @@ struct crypto_hash_polarssl { static void crypto_hash_polarssl_close(struct crypto_hash *_ch) { struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch; - free(ch); } static void crypto_hash_polarssl_write(struct crypto_hash *_ch, const unsigned char *buf, size_t len) { struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch; - mbedtls_sha1_update(&(ch->ctx), buf, len); } static unsigned char *crypto_hash_polarssl_read(struct crypto_hash *_ch) { struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch; - static unsigned char sha1sum[20]; mbedtls_sha1_finish(&(ch->ctx), sha1sum); return sha1sum; @@ -54,8 +52,7 @@ static unsigned char *crypto_hash_polarssl_read(struct crypto_hash *_ch) { static size_t crypto_hash_polarssl_get_size(const struct crypto_hash *ch) { if (ch->algo == HASH_SHA_1) return 20; - else - return 0; + return 0; } static struct crypto_hash *crypto_hash_polarssl_open(enum crypto_algo_hash hash) { @@ -96,7 +93,7 @@ static struct crypto_pk *crypto_pk_polarssl_open_rsa(va_list vl) { int res = mbedtls_rsa_check_pubkey(&cp->ctx); if (res != 0) { - fprintf(stderr, "PolarSSL public key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen); + PrintAndLogEx(WARNING, "PolarSSL public key error res=%x exp=%d mod=%d", res * -1, explen, modlen); free(cp); return NULL; } @@ -139,14 +136,14 @@ static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl) { int res = mbedtls_mpi_inv_mod(&cp->ctx.QP, &cp->ctx.Q, &cp->ctx.P); if (res != 0) { - fprintf(stderr, "PolarSSL private key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen); + PrintAndLogEx(WARNING, "PolarSSL private key error res=%x exp=%d mod=%d", res * -1, explen, modlen); free(cp); return NULL; } res = mbedtls_rsa_check_privkey(&cp->ctx); if (res != 0) { - fprintf(stderr, "PolarSSL private key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen); + PrintAndLogEx(WARNING, "PolarSSL private key error res=%x exp=%d mod=%d", res * -1, explen, modlen); free(cp); return NULL; } @@ -156,7 +153,7 @@ static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl) { static int myrand(void *rng_state, unsigned char *output, size_t len) { size_t i; - rng_state = NULL; + (void)rng_state; for (i = 0; i < len; ++i) output[i] = rand(); @@ -164,7 +161,6 @@ static int myrand(void *rng_state, unsigned char *output, size_t len) { return 0; } - static struct crypto_pk *crypto_pk_polarssl_genkey_rsa(va_list vl) { struct crypto_pk_polarssl *cp = malloc(sizeof(*cp)); memset(cp, 0x00, sizeof(*cp)); @@ -178,7 +174,7 @@ static struct crypto_pk *crypto_pk_polarssl_genkey_rsa(va_list vl) { int res = mbedtls_rsa_gen_key(&cp->ctx, &myrand, NULL, nbits, exp); if (res) { - fprintf(stderr, "PolarSSL private key generation error res=%x exp=%u nbits=%u.\n", res * -1, exp, nbits); + PrintAndLogEx(WARNING, "PolarSSL private key generation error res=%x exp=%u nbits=%u", res * -1, exp, nbits); free(cp); return NULL; } @@ -195,59 +191,50 @@ static void crypto_pk_polarssl_close(struct crypto_pk *_cp) { static unsigned char *crypto_pk_polarssl_encrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen) { struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp; - int res; - unsigned char *result; - *clen = 0; size_t keylen = mbedtls_mpi_size(&cp->ctx.N); - result = malloc(keylen); + unsigned char *result = malloc(keylen); if (!result) { - printf("RSA encrypt failed. Can't allocate result memory.\n"); + PrintAndLogEx(WARNING, "RSA encrypt failed. Can't allocate result memory"); return NULL; } - res = mbedtls_rsa_public(&cp->ctx, buf, result); + int res = mbedtls_rsa_public(&cp->ctx, buf, result); if (res) { - printf("RSA encrypt failed. Error: %x data len: %zu key len: %zu\n", res * -1, len, keylen); + PrintAndLogEx(WARNING, "RSA encrypt failed. Error: %x data len: %zu key len: %zu", res * -1, len, keylen); free(result); return NULL; } *clen = keylen; - return result; } static unsigned char *crypto_pk_polarssl_decrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen) { struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp; - int res; - unsigned char *result; - *clen = 0; size_t keylen = mbedtls_mpi_size(&cp->ctx.N); - result = malloc(keylen); + unsigned char *result = malloc(keylen); if (!result) { - printf("RSA encrypt failed. Can't allocate result memory.\n"); + PrintAndLogEx(WARNING, "RSA encrypt failed. Can't allocate result memory"); return NULL; } - res = mbedtls_rsa_private(&cp->ctx, NULL, NULL, buf, result); // CHECK??? + int res = mbedtls_rsa_private(&cp->ctx, NULL, NULL, buf, result); // CHECK??? if (res) { - printf("RSA decrypt failed. Error: %x data len: %zu key len: %zu\n", res * -1, len, keylen); + PrintAndLogEx(WARNING, "RSA decrypt failed. Error: %x data len: %zu key len: %zu", res * -1, len, keylen); free(result); return NULL; } *clen = keylen; - return result; } static size_t crypto_pk_polarssl_get_nbits(const struct crypto_pk *_cp) { struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp; - return cp->ctx.len * 8; } @@ -263,7 +250,7 @@ static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_ memset(result, 0x00, *plen); res = mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen); if (res < 0) { - printf("Error write_binary."); + PrintAndLogEx(WARNING, "Error write_binary"); free(result); result = 0; } @@ -275,16 +262,15 @@ static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_ memset(result, 0x00, *plen); res = mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen); if (res < 0) { - printf("Error write_binary."); + PrintAndLogEx(WARNING, "Error write_binary"); free(result); result = 0; } break; default: - printf("Error get parameter. Param = %u", param); + PrintAndLogEx(WARNING, "Error get parameter. Param = %u", param); break; } - return result; } diff --git a/client/src/emv/emv_pki.c b/client/src/emv/emv_pki.c index bbdb321b3..0afcfe775 100644 --- a/client/src/emv/emv_pki.c +++ b/client/src/emv/emv_pki.c @@ -26,6 +26,7 @@ #include "crypto.h" #include "dump.h" #include "util.h" +#include "ui.h" static bool strictExecution = true; void PKISetStrictExecution(bool se) { @@ -53,12 +54,12 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, return NULL; if (!cert_tlv) { - printf("ERROR: Can't find certificate\n"); + PrintAndLogEx(WARNING, "ERROR: Can't find certificate"); return NULL; } if (cert_tlv->len != enc_pk->mlen) { - printf("ERROR: Certificate length (%zu) not equal key length (%zu)\n", cert_tlv->len, enc_pk->mlen); + PrintAndLogEx(WARNING, "ERROR: Certificate length (%zu) not equal key length (%zu)", cert_tlv->len, enc_pk->mlen); return NULL; } kcp = crypto_pk_open(enc_pk->pk_algo, @@ -71,19 +72,19 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, crypto_pk_close(kcp); /* if (true){ - printf("Recovered data:\n"); + PrintAndLogEx(SUCCESS, "Recovered data:\n"); dump_buffer(data, data_len, stdout, 0); }*/ if (data[data_len - 1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) { - printf("ERROR: Certificate format\n"); + PrintAndLogEx(WARNING, "ERROR: Certificate format"); free(data); return NULL; } size_t hash_pos = emv_pki_hash_psn[msgtype]; if (hash_pos == 0 || hash_pos > data_len) { - printf("ERROR: Cant get hash position in the certificate\n"); + PrintAndLogEx(WARNING, "ERROR: Cant get hash position in the certificate"); free(data); return NULL; } @@ -91,7 +92,7 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, struct crypto_hash *ch; ch = crypto_hash_open(data[hash_pos]); if (!ch) { - printf("ERROR: Cant do hash\n"); + PrintAndLogEx(WARNING, "ERROR: Cant do hash"); free(data); return NULL; } @@ -113,9 +114,9 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, memset(hash, 0, hash_len); memcpy(hash, crypto_hash_read(ch), hash_len); if (memcmp(data + data_len - 1 - hash_len, hash, hash_len)) { - printf("ERROR: Calculated wrong hash\n"); - printf("decoded: %s\n", sprint_hex(data + data_len - 1 - hash_len, hash_len)); - printf("calculated: %s\n", sprint_hex(hash, hash_len)); + PrintAndLogEx(WARNING, "ERROR: Calculated wrong hash"); + PrintAndLogEx(WARNING, "decoded: " _YELLOW_("%s"), sprint_hex(data + data_len - 1 - hash_len, hash_len)); + PrintAndLogEx(WARNING, "calculated: " _YELLOW_("%s"), sprint_hex(hash, hash_len)); if (strictExecution) { crypto_hash_close(ch); @@ -125,16 +126,12 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, } crypto_hash_close(ch); - *len = data_len - hash_len - 1; - return data; } static unsigned emv_cn_length(const struct tlv *tlv) { - int i; - - for (i = 0; i < tlv->len; i++) { + for (int i = 0; i < tlv->len; i++) { unsigned char c = tlv->value[i]; if (c >> 4 == 0xf) @@ -143,7 +140,6 @@ static unsigned emv_cn_length(const struct tlv *tlv) { if ((c & 0xf) == 0xf) return 2 * i + 1; } - return 2 * tlv->len; } @@ -185,7 +181,7 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, else if (msgtype == 4) pan_length = 10; else { - printf("ERROR: Message type must be 2 or 4\n"); + PrintAndLogEx(WARNING, "ERROR: Message type must be 2 or 4"); return NULL; } @@ -198,12 +194,12 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, sdatl_tlv, NULL); if (!data || data_len < 11 + pan_length) { - printf("ERROR: Can't decode message\n"); + PrintAndLogEx(WARNING, "ERROR: Can't decode message"); return NULL; } if (showData) { - printf("Recovered data:\n"); + PrintAndLogEx(SUCCESS, "Recovered data:"); dump_buffer(data, data_len, stdout, 0); } @@ -219,7 +215,7 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, if (((msgtype == 2) && (pan2_len < 4 || pan2_len > pan_len)) || ((msgtype == 4) && (pan2_len != pan_len))) { - printf("ERROR: Invalid PAN lengths\n"); + PrintAndLogEx(WARNING, "ERROR: Invalid PAN lengths"); free(data); return NULL; @@ -228,9 +224,9 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, unsigned i; for (i = 0; i < pan2_len; i++) if (emv_cn_get(pan_tlv, i) != emv_cn_get(&pan2_tlv, i)) { - printf("ERROR: PAN data mismatch\n"); - printf("tlv pan=%s\n", sprint_hex(pan_tlv->value, pan_tlv->len)); - printf("cert pan=%s\n", sprint_hex(pan2_tlv.value, pan2_tlv.len)); + PrintAndLogEx(WARNING, "ERROR: PAN data mismatch"); + PrintAndLogEx(WARNING, "tlv pan " _YELLOW_("%s"), sprint_hex(pan_tlv->value, pan_tlv->len)); + PrintAndLogEx(WARNING, "cert pan " _YELLOW_("%s"), sprint_hex(pan2_tlv.value, pan2_tlv.len)); free(data); return NULL; @@ -238,7 +234,7 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, pk_len = data[9 + pan_length]; if (pk_len > data_len - 11 - pan_length + rem_tlv->len) { - printf("ERROR: Invalid pk length\n"); + PrintAndLogEx(WARNING, "ERROR: Invalid pk length"); free(data); return NULL; } @@ -268,7 +264,6 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, memcpy(pk->exp, exp_tlv->value, exp_tlv->len); free(data); - return pk; } @@ -354,7 +349,6 @@ unsigned char *emv_pki_sdatl_fill(const struct tlvdb *db, size_t *sdatl_len) { return NULL; } - struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv, bool showData) { size_t data_len; @@ -380,16 +374,15 @@ struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct t return NULL; if (showData) { - printf("Recovered data:\n"); + PrintAndLogEx(SUCCESS, "Recovered data:"); dump_buffer(data, data_len, stdout, 0); } struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data + 3); - free(data); - return dac_db; } + struct tlvdb *emv_pki_recover_dac(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv) { return emv_pki_recover_dac_ex(enc_pk, db, sda_tlv, false); } @@ -415,7 +408,7 @@ struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct t } if (showData) { - printf("Recovered data:\n"); + PrintAndLogEx(SUCCESS, "Recovered data:"); dump_buffer(data, data_len, stdout, 0); } @@ -427,9 +420,7 @@ struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct t // 9f4c ICC Dynamic Number struct tlvdb *idn_db = tlvdb_fixed(0x9f4c, idn_len, data + 5); - free(data); - return idn_db; } @@ -453,7 +444,7 @@ struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct t } if (showData) { - printf("Recovered data:\n"); + PrintAndLogEx(SUCCESS, "Recovered data:"); dump_buffer(data, data_len, stdout, 0); } @@ -471,22 +462,20 @@ struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct t return atc_db; } -static bool tlv_hash(void *data, const struct tlv *tlv, int level, bool is_leaf) { +static void tlv_hash(void *data, const struct tlv *tlv, int level, bool is_leaf) { struct crypto_hash *ch = data; size_t tag_len; unsigned char *tag; if (tlv_is_constructed(tlv)) - return true; + return; if (tlv->tag == 0x9f4b) - return true; + return; tag = tlv_encode(tlv, &tag_len); crypto_hash_write(ch, tag, tag_len); free(tag); - - return true; } struct tlvdb *emv_pki_perform_cda(const struct emv_pk *enc_pk, const struct tlvdb *db, @@ -496,6 +485,7 @@ struct tlvdb *emv_pki_perform_cda(const struct emv_pk *enc_pk, const struct tlvd const struct tlv *crm2_tlv) { return emv_pki_perform_cda_ex(enc_pk, db, this_db, pdol_data_tlv, crm1_tlv, crm2_tlv, false); } + struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlvdb *this_db, // AC TLV result const struct tlv *pdol_data_tlv, // PDOL @@ -515,23 +505,23 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t un_tlv, NULL); if (!data || data_len < 3) { - printf("ERROR: can't decode message. len %zu\n", data_len); + PrintAndLogEx(WARNING, "ERROR: can't decode message. [%zu bytes]", data_len); return NULL; } if (showData) { - printf("Recovered data:\n"); + PrintAndLogEx(SUCCESS, "Recovered data:"); dump_buffer(data, data_len, stdout, 0); } if (data[3] < 30 || data[3] > data_len - 4) { - printf("ERROR: Invalid data length\n"); + PrintAndLogEx(WARNING, "ERROR: Invalid data length"); free(data); return NULL; } if (!cid_tlv || cid_tlv->len != 1 || cid_tlv->value[0] != data[5 + data[4]]) { - printf("ERROR: CID mismatch\n"); + PrintAndLogEx(WARNING, "ERROR: CID mismatch"); free(data); return NULL; } @@ -539,7 +529,7 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t struct crypto_hash *ch; ch = crypto_hash_open(enc_pk->hash_algo); if (!ch) { - printf("ERROR: can't create hash\n"); + PrintAndLogEx(WARNING, "ERROR: can't create hash"); free(data); return NULL; } @@ -554,7 +544,7 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t tlvdb_visit(this_db, tlv_hash, ch, 0); if (memcmp(data + 5 + data[4] + 1 + 8, crypto_hash_read(ch), 20)) { - printf("ERROR: calculated hash error\n"); + PrintAndLogEx(WARNING, "ERROR: calculated hash error"); crypto_hash_close(ch); free(data); return NULL; @@ -563,7 +553,7 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t size_t idn_len = data[4]; if (idn_len > data[3] - 1) { - printf("ERROR: Invalid IDN length\n"); + PrintAndLogEx(WARNING, "ERROR: Invalid IDN length"); free(data); return NULL; } diff --git a/client/src/emv/emv_roca.c b/client/src/emv/emv_roca.c index 521120b05..4c42be7e2 100644 --- a/client/src/emv/emv_roca.c +++ b/client/src/emv/emv_roca.c @@ -24,41 +24,35 @@ #include "emv_roca.h" #include "ui.h" // Print... -#include "mbedtls/bignum.h" +#include "bignum.h" -static uint8_t g_primes[ROCA_PRINTS_LENGTH] = { - 11, 13, 17, 19, 37, 53, 61, 71, 73, 79, 97, 103, 107, 109, 127, 151, 157 -}; - -mbedtls_mpi g_prints[ROCA_PRINTS_LENGTH]; - -static void rocacheck_init(void) { +static void rocacheck_init(mbedtls_mpi *prints) { for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) - mbedtls_mpi_init(&g_prints[i]); + mbedtls_mpi_init(&prints[i]); - mbedtls_mpi_read_string(&g_prints[0], 10, "1026"); - mbedtls_mpi_read_string(&g_prints[1], 10, "5658"); - mbedtls_mpi_read_string(&g_prints[2], 10, "107286"); - mbedtls_mpi_read_string(&g_prints[3], 10, "199410"); - mbedtls_mpi_read_string(&g_prints[4], 10, "67109890"); - mbedtls_mpi_read_string(&g_prints[5], 10, "5310023542746834"); - mbedtls_mpi_read_string(&g_prints[6], 10, "1455791217086302986"); - mbedtls_mpi_read_string(&g_prints[7], 10, "20052041432995567486"); - mbedtls_mpi_read_string(&g_prints[8], 10, "6041388139249378920330"); - mbedtls_mpi_read_string(&g_prints[9], 10, "207530445072488465666"); - mbedtls_mpi_read_string(&g_prints[10], 10, "79228162521181866724264247298"); - mbedtls_mpi_read_string(&g_prints[11], 10, "1760368345969468176824550810518"); - mbedtls_mpi_read_string(&g_prints[12], 10, "50079290986288516948354744811034"); - mbedtls_mpi_read_string(&g_prints[13], 10, "473022961816146413042658758988474"); - mbedtls_mpi_read_string(&g_prints[14], 10, "144390480366845522447407333004847678774"); - mbedtls_mpi_read_string(&g_prints[15], 10, "1800793591454480341970779146165214289059119882"); - mbedtls_mpi_read_string(&g_prints[16], 10, "126304807362733370595828809000324029340048915994"); + mbedtls_mpi_read_string(&prints[0], 10, "1026"); + mbedtls_mpi_read_string(&prints[1], 10, "5658"); + mbedtls_mpi_read_string(&prints[2], 10, "107286"); + mbedtls_mpi_read_string(&prints[3], 10, "199410"); + mbedtls_mpi_read_string(&prints[4], 10, "67109890"); + mbedtls_mpi_read_string(&prints[5], 10, "5310023542746834"); + mbedtls_mpi_read_string(&prints[6], 10, "1455791217086302986"); + mbedtls_mpi_read_string(&prints[7], 10, "20052041432995567486"); + mbedtls_mpi_read_string(&prints[8], 10, "6041388139249378920330"); + mbedtls_mpi_read_string(&prints[9], 10, "207530445072488465666"); + mbedtls_mpi_read_string(&prints[10], 10, "79228162521181866724264247298"); + mbedtls_mpi_read_string(&prints[11], 10, "1760368345969468176824550810518"); + mbedtls_mpi_read_string(&prints[12], 10, "50079290986288516948354744811034"); + mbedtls_mpi_read_string(&prints[13], 10, "473022961816146413042658758988474"); + mbedtls_mpi_read_string(&prints[14], 10, "144390480366845522447407333004847678774"); + mbedtls_mpi_read_string(&prints[15], 10, "1800793591454480341970779146165214289059119882"); + mbedtls_mpi_read_string(&prints[16], 10, "126304807362733370595828809000324029340048915994"); } -static void rocacheck_cleanup(void) { +static void rocacheck_cleanup(mbedtls_mpi *prints) { for (int i = 0; i < ROCA_PRINTS_LENGTH; i++) - mbedtls_mpi_free(&g_prints[i]); + mbedtls_mpi_free(&prints[i]); } static int bitand_is_zero(mbedtls_mpi *a, mbedtls_mpi *b) { @@ -97,8 +91,12 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen, bool verbose) { mbedtls_mpi_init(&t_modulus); bool ret = false; + mbedtls_mpi prints[ROCA_PRINTS_LENGTH]; + uint8_t primes[ROCA_PRINTS_LENGTH] = { + 11, 13, 17, 19, 37, 53, 61, 71, 73, 79, 97, 103, 107, 109, 127, 151, 157 + }; - rocacheck_init(); + rocacheck_init(prints); MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&t_modulus, buf, buflen)); @@ -114,13 +112,13 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen, bool verbose) { MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&g_one, 10, "1")); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&t_prime, &t_prime, g_primes[i])); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&t_prime, &t_prime, primes[i])); MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&t_temp, &t_modulus, &t_prime)); MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&g_one, mpi_get_uint(&t_temp))); - if (bitand_is_zero(&g_one, &g_prints[i])) { + if (bitand_is_zero(&g_one, &prints[i])) { if (verbose) PrintAndLogEx(FAILED, "No fingerprint found.\n"); goto cleanup; @@ -138,13 +136,11 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen, bool verbose) { cleanup: mbedtls_mpi_free(&t_modulus); - rocacheck_cleanup(); + rocacheck_cleanup(prints); return ret; } int roca_self_test(void) { - int ret = 0; - PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "ROCA check vulnerability tests"); @@ -154,12 +150,12 @@ int roca_self_test(void) { "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\ "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; - + int ret = 0; if (emv_rocacheck(keyp, 64, false)) { - PrintAndLogEx(SUCCESS, "Weak modulus [ %s]", _GREEN_("PASS")); + PrintAndLogEx(SUCCESS, "Weak modulus [ %s ]", _GREEN_("PASS")); } else { ret++; - PrintAndLogEx(FAILED, "Weak modulus [ %s]", _RED_("Fail")); + PrintAndLogEx(FAILED, "Weak modulus [ %s ]", _RED_("Fail")); } // negative @@ -170,10 +166,9 @@ int roca_self_test(void) { if (emv_rocacheck(keyn, 64, false)) { ret++; - PrintAndLogEx(FAILED, "Strong modulus [ %s]", _RED_("Fail")); + PrintAndLogEx(FAILED, "Strong modulus [ %s ]", _RED_("Fail")); } else { - PrintAndLogEx(SUCCESS, "Strong modulus [ %s]", _GREEN_("PASS")); + PrintAndLogEx(SUCCESS, "Strong modulus [ %s ]", _GREEN_("PASS")); } - return ret; } diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index 852d801c7..23de78c7d 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -24,7 +24,7 @@ #include "emvjson.h" #include "util_posix.h" -// Got from here. Thanks) +// Got from here. Thanks! // https://eftlab.co.uk/index.php/site-map/knowledge-base/211-emv-aid-rid-pix static const char *PSElist [] = { "325041592E5359532E4444463031", // 2PAY.SYS.DDF01 - Visa Proximity Payment System Environment - PPSE @@ -131,6 +131,7 @@ static const TAIDList AIDlist [] = { { CV_OTHER, "F0000000030001" }, // BRADESCO - Brazilian Bank Banco Bradesco }; +//iceman: this logging setting, should be unified with client debug etc. static bool APDULogging = false; void SetAPDULogging(bool logging) { APDULogging = logging; @@ -156,20 +157,17 @@ enum CardPSVendor GetCardPSVendor(uint8_t *AID, size_t AIDlen) { return CV_NA; } -static bool print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { +static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { emv_tag_dump(tlv, stdout, level); if (is_leaf) { dump_buffer(tlv->value, tlv->len, stdout, level); } - - return true; } bool TLVPrintFromBuffer(uint8_t *data, int datalen) { - struct tlvdb *t = NULL; - t = tlvdb_parse_multi(data, datalen); + struct tlvdb *t = tlvdb_parse_multi(data, datalen); if (t) { - PrintAndLogEx(NORMAL, "-------------------- TLV decoded --------------------"); + PrintAndLogEx(INFO, "-------------------- " _CYAN_("TLV decoded") " --------------------"); tlvdb_visit(t, print_cb, NULL, 0); tlvdb_free(t); @@ -192,13 +190,13 @@ void TLVPrintFromTLV(struct tlvdb *tlv) { } void TLVPrintAIDlistFromSelectTLV(struct tlvdb *tlv) { - PrintAndLogEx(NORMAL, "|------------------|--------|-------------------------|"); - PrintAndLogEx(NORMAL, "| AID |Priority| Name |"); - PrintAndLogEx(NORMAL, "|------------------|--------|-------------------------|"); + PrintAndLogEx(INFO, "|------------------+--------+-------------------------|"); + PrintAndLogEx(INFO, "| AID |Priority| Name |"); + PrintAndLogEx(INFO, "|------------------+--------+-------------------------|"); struct tlvdb *ttmp = tlvdb_find(tlv, 0x6f); if (!ttmp) - PrintAndLogEx(NORMAL, "| none |"); + PrintAndLogEx(INFO, "| none |"); while (ttmp) { const struct tlv *tgAID = tlvdb_get_inchild(ttmp, 0x84, NULL); @@ -206,15 +204,15 @@ void TLVPrintAIDlistFromSelectTLV(struct tlvdb *tlv) { const struct tlv *tgPrio = tlvdb_get_inchild(ttmp, 0x87, NULL); if (!tgAID) break; - PrintAndLogEx(NORMAL, "|%s| %s |%s|", - sprint_hex_inrow_ex(tgAID->value, tgAID->len, 18), + PrintAndLogEx(INFO, "| %s| %s | %s|", + sprint_hex_inrow_ex(tgAID->value, tgAID->len, 17), (tgPrio) ? sprint_hex(tgPrio->value, 1) : " ", - (tgName) ? sprint_ascii_ex(tgName->value, tgName->len, 25) : " "); + (tgName) ? sprint_ascii_ex(tgName->value, tgName->len, 24) : " "); ttmp = tlvdb_find_next(ttmp, 0x6f); } - PrintAndLogEx(NORMAL, "|------------------|--------|-------------------------|"); + PrintAndLogEx(INFO, "|------------------+--------+-------------------------|"); } struct tlvdb *GetPANFromTrack2(const struct tlv *track2) { @@ -308,10 +306,10 @@ static int EMVExchangeEx(EMVCommandChannel channel, bool ActivateField, bool Lea } break; case ECC_CONTACT: + res = 1; if (IfPm3Smartcard()) res = ExchangeAPDUSC(true, data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); - else - res = 1; + if (res) { return res; } @@ -362,7 +360,6 @@ int EMVSelectPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO uint8_t buf[APDU_AID_LEN] = {0}; *ResultLen = 0; int len = 0; - int res = 0; switch (PSENum) { case 1: param_gethex_to_eol(PSElist[1], 0, buf, sizeof(buf), &len); @@ -373,11 +370,7 @@ int EMVSelectPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO default: return -1; } - - // select - res = EMVSelect(channel, ActivateField, LeaveFieldON, buf, len, Result, MaxResultLen, ResultLen, sw, NULL); - - return res; + return EMVSelect(channel, ActivateField, LeaveFieldON, buf, len, Result, MaxResultLen, ResultLen, sw, NULL); } static int EMVSelectWithRetry(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t *AID, size_t AIDLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) { @@ -393,12 +386,12 @@ static int EMVSelectWithRetry(EMVCommandChannel channel, bool ActivateField, boo } else { // card select error, proxmark error if (res == 1) { - PrintAndLogEx(WARNING, "Exit..."); + PrintAndLogEx(WARNING, "exiting..."); return 1; } retrycnt = 0; - PrintAndLogEx(NORMAL, "Retry failed [%s]. Skipped...", sprint_hex_inrow(AID, AIDLen)); + PrintAndLogEx(FAILED, "Retry failed [%s]. Skipped...", sprint_hex_inrow(AID, AIDLen)); return res; } } @@ -430,7 +423,7 @@ static int EMVCheckAID(EMVCommandChannel channel, bool decodeTLV, struct tlvdb * // all is ok if (decodeTLV) { - PrintAndLogEx(NORMAL, "%s:", sprint_hex_inrow(tgAID->value, tgAID->len)); + PrintAndLogEx(SUCCESS, "%s:", sprint_hex_inrow(tgAID->value, tgAID->len)); TLVPrintFromBuffer(data, datalen); } } @@ -446,8 +439,6 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO size_t sfidatalen[0x11] = {0}; uint16_t sw = 0; int res; - bool fileFound = false; - const char *PSE_or_PPSE = PSENum == 1 ? "PSE" : "PPSE"; // select PPSE @@ -459,8 +450,9 @@ int EMVSearchPSE(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldO return 1; } - struct tlvdb *t = NULL; - t = tlvdb_parse_multi(data, datalen); + bool fileFound = false; + + struct tlvdb *t = tlvdb_parse_multi(data, datalen); if (t) { // PSE/PPSE with SFI struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]) {0x6f, 0xa5, 0x88, 0x00}); @@ -557,7 +549,7 @@ int EMVSearch(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, if (!LeaveFieldON) DropFieldEx(channel); - PrintAndLogEx(WARNING, "Exit..."); + PrintAndLogEx(WARNING, "exiting..."); return 1; } @@ -667,7 +659,7 @@ struct emv_pk *get_ca_pk(struct tlvdb *db) { if (!df_tlv || !caidx_tlv || df_tlv->len < 6 || caidx_tlv->len != 1) return NULL; - PrintAndLogEx(NORMAL, "CA public key index 0x%0x", caidx_tlv->value[0]); + PrintAndLogEx(INFO, "CA public key index 0x%0x", caidx_tlv->value[0]); return emv_pk_get_ca_pk(df_tlv->value, caidx_tlv->value[0]); } @@ -675,41 +667,35 @@ int trSDA(struct tlvdb *tlv) { struct emv_pk *pk = get_ca_pk(tlv); if (!pk) { - PrintAndLogEx(ERR, "Error: Key not found. Exit."); + PrintAndLogEx(ERR, "Error: Key not found, exiting"); return 2; } struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv); if (!issuer_pk) { emv_pk_free(pk); - PrintAndLogEx(ERR, "Error: Issuer certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: Issuer certificate not found, exiting"); return 2; } - PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx", - issuer_pk->rid[0], - issuer_pk->rid[1], - issuer_pk->rid[2], - issuer_pk->rid[3], - issuer_pk->rid[4], + PrintAndLogEx(SUCCESS, "Issuer Public key recovered RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(issuer_pk->rid, 5), issuer_pk->index, - issuer_pk->serial[0], - issuer_pk->serial[1], - issuer_pk->serial[2] + sprint_hex(issuer_pk->serial, 3) ); const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL); if (!sda_tlv || sda_tlv->len < 1) { emv_pk_free(issuer_pk); emv_pk_free(pk); - PrintAndLogEx(WARNING, "Can't find input list for Offline Data Authentication. Exit."); + PrintAndLogEx(WARNING, "Can't find input list for Offline Data Authentication, exiting"); return 3; } struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv); if (dac_db) { const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); - PrintAndLogEx(NORMAL, "SDA verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); + PrintAndLogEx(INFO, "SDA verified (%s) (Data Authentication Code: %02hhx:%02hhx)", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { emv_pk_free(issuer_pk); @@ -733,73 +719,57 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct emv_pk *pk = get_ca_pk(tlv); if (!pk) { - PrintAndLogEx(ERR, "Error: Key not found. Exit."); + PrintAndLogEx(ERR, "Error: Key not found, exiting"); return 2; } const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL); /* if (!sda_tlv || sda_tlv->len < 1) { it may be 0!!!! emv_pk_free(pk); - PrintAndLogEx(ERR, "Error: Can't find input list for Offline Data Authentication. Exit."); + PrintAndLogEx(ERR, "Error: Can't find input list for Offline Data Authentication, exiting"); return 3; } */ struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv); if (!issuer_pk) { emv_pk_free(pk); - PrintAndLogEx(ERR, "Error: Issuer certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: Issuer certificate not found, exiting"); return 2; } - PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", - issuer_pk->rid[0], - issuer_pk->rid[1], - issuer_pk->rid[2], - issuer_pk->rid[3], - issuer_pk->rid[4], + + PrintAndLogEx(SUCCESS, "Issuer Public key recovered RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(issuer_pk->rid, 5), issuer_pk->index, - issuer_pk->serial[0], - issuer_pk->serial[1], - issuer_pk->serial[2] + sprint_hex(issuer_pk->serial, 3) ); struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlv, sda_tlv); if (!icc_pk) { emv_pk_free(pk); emv_pk_free(issuer_pk); - PrintAndLogEx(ERR, "Error: ICC certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: ICC certificate not found, exiting"); return 2; } - PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", - icc_pk->rid[0], - icc_pk->rid[1], - icc_pk->rid[2], - icc_pk->rid[3], - icc_pk->rid[4], + + PrintAndLogEx(SUCCESS, "ICC Public key recovered. RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(icc_pk->rid, 5), icc_pk->index, - icc_pk->serial[0], - icc_pk->serial[1], - icc_pk->serial[2] + sprint_hex(icc_pk->serial, 3) ); if (tlvdb_get(tlv, 0x9f2d, NULL)) { struct emv_pk *icc_pe_pk = emv_pki_recover_icc_pe_cert(issuer_pk, tlv); if (!icc_pe_pk) { - PrintAndLogEx(WARNING, "WARNING: ICC PE PK recover error. "); + PrintAndLogEx(WARNING, "WARNING: ICC PE Public key recover error"); } else { - PrintAndLogEx(SUCCESS, "ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", - icc_pe_pk->rid[0], - icc_pe_pk->rid[1], - icc_pe_pk->rid[2], - icc_pe_pk->rid[3], - icc_pe_pk->rid[4], + PrintAndLogEx(SUCCESS, "ICC PE Public key recovered. RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(icc_pe_pk->rid, 5), icc_pe_pk->index, - icc_pe_pk->serial[0], - icc_pe_pk->serial[1], - icc_pe_pk->serial[2] + sprint_hex(icc_pe_pk->serial, 3) ); } } else { - PrintAndLogEx(INFO, "ICC PE PK (PIN Encipherment Public Key Certificate) not found.\n"); + PrintAndLogEx(INFO, "ICC PE Public Key (PIN Encipherment Public Key Certificate) not found.\n"); } // 9F4B: Signed Dynamic Application Data @@ -807,7 +777,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { // DDA with internal authenticate OR fDDA with filled 0x9F4B tag (GPO result) // EMV kernel3 v2.4, contactless book C-3, C.1., page 147 if (sdad_tlv) { - PrintAndLogEx(NORMAL, "\n* * Got Signed Dynamic Application Data (9F4B) form GPO. Maybe fDDA..."); + PrintAndLogEx(INFO, "* * Got Signed Dynamic Application Data (9F4B) form GPO. Maybe fDDA..."); const struct tlvdb *atc_db = emv_pki_recover_atc_ex(icc_pk, tlv, true); if (!atc_db) { @@ -821,7 +791,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { // 9f36 Application Transaction Counter (ATC) const struct tlv *atc_tlv = tlvdb_get(atc_db, 0x9f36, NULL); if (atc_tlv) { - PrintAndLogEx(NORMAL, "\nATC (Application Transaction Counter) [%zu] %s", atc_tlv->len, sprint_hex_inrow(atc_tlv->value, atc_tlv->len)); + PrintAndLogEx(INFO, "ATC (Application Transaction Counter) [%zu] %s", atc_tlv->len, sprint_hex_inrow(atc_tlv->value, atc_tlv->len)); const struct tlv *core_atc_tlv = tlvdb_get(tlv, 0x9f36, NULL); if (tlv_equal(core_atc_tlv, atc_tlv)) { @@ -831,7 +801,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { PrintAndLogEx(WARNING, "Error: fDDA verified, but ATC in the certificate and ATC in the record not the same."); } } else { - PrintAndLogEx(NORMAL, "\nERROR: fDDA (fast DDA) verify error"); + PrintAndLogEx(WARNING, "ERROR: fDDA (fast DDA) verify error"); emv_pk_free(pk); emv_pk_free(issuer_pk); emv_pk_free(icc_pk); @@ -841,7 +811,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv); if (dac_db) { const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); - PrintAndLogEx(NORMAL, "SDAD verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]); + PrintAndLogEx(INFO, "SDAD verified (%s) (Data Authentication Code: %02hhx:%02hhx)\n", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { PrintAndLogEx(ERR, "Error: SSAD verify error"); @@ -851,11 +821,11 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { return 4; } - PrintAndLogEx(NORMAL, "\n* Calc DDOL"); + PrintAndLogEx(INFO, "* Calc DDOL"); const struct tlv *ddol_tlv = tlvdb_get(tlv, 0x9f49, NULL); if (!ddol_tlv) { ddol_tlv = &default_ddol_tlv; - PrintAndLogEx(NORMAL, "DDOL [9f49] not found. Using default DDOL"); + PrintAndLogEx(INFO, "DDOL [9f49] not found. Using default DDOL"); } struct tlv *ddol_data_tlv = dol_process(ddol_tlv, tlv, 0); @@ -867,12 +837,12 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { return 5; } - PrintAndLogEx(NORMAL, "DDOL data[%zu]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len)); + PrintAndLogEx(INFO, "DDOL data[%zu]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len)); - PrintAndLogEx(NORMAL, "\n* Internal Authenticate"); + PrintAndLogEx(INFO, "* Internal Authenticate"); int res = EMVInternalAuthenticate(channel, true, (uint8_t *)ddol_data_tlv->value, ddol_data_tlv->len, buf, sizeof(buf), &len, &sw, NULL); if (res) { - PrintAndLogEx(ERR, "Internal Authenticate error(%d): %4x. Exit...", res, sw); + PrintAndLogEx(ERR, "Internal Authenticate error(%d): %4x, exiting..", res, sw); free(ddol_data_tlv); emv_pk_free(pk); emv_pk_free(issuer_pk); @@ -896,7 +866,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { tlvdb_free(t80); if (decodeTLV) { - PrintAndLogEx(NORMAL, "* * Decode response format 1:"); + PrintAndLogEx(INFO, "* * Decode response format 1:"); TLVPrintFromTLV(dda_db); } } @@ -931,12 +901,12 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { // 9f4c ICC Dynamic Number const struct tlv *idn_tlv = tlvdb_get(idn_db, 0x9f4c, NULL); if (idn_tlv) { - PrintAndLogEx(INFO, "\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv->len, sprint_hex_inrow(idn_tlv->value, idn_tlv->len)); + PrintAndLogEx(INFO, "IDN (ICC Dynamic Number) [%zu] %s", idn_tlv->len, sprint_hex_inrow(idn_tlv->value, idn_tlv->len)); PrintAndLogEx(INFO, "DDA verified OK."); tlvdb_add(tlv, idn_db); tlvdb_free(idn_db); } else { - PrintAndLogEx(ERR, "\nDDA verify error"); + PrintAndLogEx(ERR, "DDA verify error"); tlvdb_free(idn_db); emv_pk_free(pk); @@ -956,58 +926,48 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st struct emv_pk *pk = get_ca_pk(tlv); if (!pk) { - PrintAndLogEx(ERR, "Error: Key not found. Exit."); + PrintAndLogEx(ERR, "Error: Key not found, exiting"); return 2; } const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL); if (!sda_tlv || sda_tlv->len < 1) { - PrintAndLogEx(ERR, "Error: Can't find input list for Offline Data Authentication. Exit."); + PrintAndLogEx(ERR, "Error: Can't find input list for Offline Data Authentication, exiting"); emv_pk_free(pk); return 3; } struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv); if (!issuer_pk) { - PrintAndLogEx(ERR, "Error: Issuer certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: Issuer certificate not found, exiting"); emv_pk_free(pk); return 2; } - PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", - issuer_pk->rid[0], - issuer_pk->rid[1], - issuer_pk->rid[2], - issuer_pk->rid[3], - issuer_pk->rid[4], + + PrintAndLogEx(SUCCESS, "Issuer Public key recovered RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(issuer_pk->rid, 5), issuer_pk->index, - issuer_pk->serial[0], - issuer_pk->serial[1], - issuer_pk->serial[2] + sprint_hex(issuer_pk->serial, 3) ); struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlv, sda_tlv); if (!icc_pk) { - PrintAndLogEx(ERR, "Error: ICC certificate not found. Exit."); + PrintAndLogEx(ERR, "Error: ICC certificate not found, exiting"); emv_pk_free(pk); emv_pk_free(issuer_pk); return 2; } - PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", - icc_pk->rid[0], - icc_pk->rid[1], - icc_pk->rid[2], - icc_pk->rid[3], - icc_pk->rid[4], + + PrintAndLogEx(SUCCESS, "ICC Public key recovered. RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(icc_pk->rid, 5), icc_pk->index, - icc_pk->serial[0], - icc_pk->serial[1], - icc_pk->serial[2] + sprint_hex(icc_pk->serial, 3) ); struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv); if (dac_db) { const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); - PrintAndLogEx(NORMAL, "SSAD verified OK. (%02hhx:%02hhx)", dac_tlv->value[0], dac_tlv->value[1]); + PrintAndLogEx(SUCCESS, "SSAD verified (%s) (%02hhx:%02hhx)", _GREEN_("ok"), dac_tlv->value[0], dac_tlv->value[1]); tlvdb_add(tlv, dac_db); } else { PrintAndLogEx(ERR, "Error: SSAD verify error"); @@ -1017,7 +977,7 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st return 4; } - PrintAndLogEx(NORMAL, "\n* * Check Signed Dynamic Application Data (SDAD)"); + PrintAndLogEx(INFO, "* * Check Signed Dynamic Application Data (SDAD)"); struct tlvdb *idn_db = emv_pki_perform_cda_ex(icc_pk, tlv, ac_tlv, pdol_data_tlv, // pdol ac_data_tlv, // cdol1 @@ -1025,11 +985,11 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st true); if (idn_db) { const struct tlv *idn_tlv = tlvdb_get(idn_db, 0x9f4c, NULL); - PrintAndLogEx(NORMAL, "\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv->len, sprint_hex_inrow(idn_tlv->value, idn_tlv->len)); - PrintAndLogEx(NORMAL, "CDA verified OK."); + PrintAndLogEx(INFO, "IDN (ICC Dynamic Number) [%zu] %s", idn_tlv->len, sprint_hex_inrow(idn_tlv->value, idn_tlv->len)); + PrintAndLogEx(SUCCESS, "CDA verified (%s)", _GREEN_("ok")); tlvdb_add(tlv, idn_db); } else { - PrintAndLogEx(ERR, "\nERROR: CDA verify error"); + PrintAndLogEx(ERR, "ERROR: CDA verify error"); } emv_pk_free(pk); @@ -1039,29 +999,23 @@ int trCDA(struct tlvdb *tlv, struct tlvdb *ac_tlv, struct tlv *pdol_data_tlv, st } int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root) { - struct emv_pk *pk = get_ca_pk(tlvRoot); if (!pk) { - PrintAndLogEx(ERR, "ERROR: Key not found. Exit."); + PrintAndLogEx(ERR, "ERROR: Key not found, exiting"); return 1; } struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlvRoot); if (!issuer_pk) { emv_pk_free(pk); - PrintAndLogEx(WARNING, "WARNING: Issuer certificate not found. Exit."); + PrintAndLogEx(WARNING, "WARNING: Issuer certificate not found, exiting"); return 2; } - PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx", - issuer_pk->rid[0], - issuer_pk->rid[1], - issuer_pk->rid[2], - issuer_pk->rid[3], - issuer_pk->rid[4], + + PrintAndLogEx(SUCCESS, "Issuer Public key recovered RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(issuer_pk->rid, 5), issuer_pk->index, - issuer_pk->serial[0], - issuer_pk->serial[1], - issuer_pk->serial[2] + sprint_hex(issuer_pk->serial, 3) ); JsonSaveBufAsHex(root, "$.ApplicationData.RID", issuer_pk->rid, 5); @@ -1071,29 +1025,24 @@ int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root) { JsonSaveBufAsHex(root, "$.ApplicationData.IssuerPublicKeyModulus", issuer_pk->modulus, issuer_pk->mlen); free(issuer_pk_c); - struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlvRoot, NULL); + const struct tlv *sda_tlv = tlvdb_get(tlvRoot, 0x21, NULL); + struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlvRoot, sda_tlv); if (!icc_pk) { emv_pk_free(pk); emv_pk_free(issuer_pk); - PrintAndLogEx(WARNING, "WARNING: ICC certificate not found. Exit."); + PrintAndLogEx(WARNING, "WARNING: ICC certificate not found, exiting"); return 2; } - PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n", - icc_pk->rid[0], - icc_pk->rid[1], - icc_pk->rid[2], - icc_pk->rid[3], - icc_pk->rid[4], + + PrintAndLogEx(SUCCESS, "ICC Public key recovered RID " _YELLOW_("%s") " IDX " _YELLOW_("%02hhx") " CSN " _YELLOW_("%s"), + sprint_hex(icc_pk->rid, 5), icc_pk->index, - icc_pk->serial[0], - icc_pk->serial[1], - icc_pk->serial[2] + sprint_hex(icc_pk->serial, 3) ); char *icc_pk_c = emv_pk_dump_pk(icc_pk); JsonSaveStr(root, "$.ApplicationData.ICCPublicKeyDec", icc_pk_c); JsonSaveBufAsHex(root, "$.ApplicationData.ICCPublicKeyModulus", icc_pk->modulus, icc_pk->mlen); free(icc_pk_c); - return 0; } diff --git a/client/src/emv/emvjson.c b/client/src/emv/emvjson.c index ebf42704f..43f5095e2 100644 --- a/client/src/emv/emvjson.c +++ b/client/src/emv/emvjson.c @@ -325,7 +325,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { return false; } - PrintAndLogEx(SUCCESS, "Load params: json(%zu) " _GREEN_("OK"), json_array_size(root)); + PrintAndLogEx(SUCCESS, "Load params: json(%zu) (%s)", json_array_size(root), _GREEN_("OK")); for (int i = 0; i < json_array_size(root); i++) { json_t *data, *jtag, *jlength, *jvalue; diff --git a/client/src/emv/emvjson.h b/client/src/emv/emvjson.h index f4f3d4fb4..e90aa42d8 100644 --- a/client/src/emv/emvjson.h +++ b/client/src/emv/emvjson.h @@ -13,6 +13,7 @@ #include "common.h" #include "jansson.h" +#include "jansson_path.h" #include "tlv.h" typedef struct { diff --git a/client/src/emv/test/cda_test.c b/client/src/emv/test/cda_test.c index 38f756073..acdde8bb4 100644 --- a/client/src/emv/test/cda_test.c +++ b/client/src/emv/test/cda_test.c @@ -17,16 +17,16 @@ #include #endif +#include // memcpy +#include // malloc +#include "cda_test.h" + #include "../emv_pk.h" #include "../crypto.h" #include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" - -#include -#include -#include -#include "cda_test.h" +#include "ui.h" // printandlog struct emv_pk c_mchip_05 = { .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, }, @@ -56,6 +56,7 @@ struct emv_pk c_mchip_05 = { 0x10, 0xd2, 0x7b, 0x3e, 0xfc, 0xcd, 0x8f, 0x83, 0xde, 0x30, 0x52, 0xca, 0xd1, 0xe4, 0x89, 0x38, 0xc6, 0x8d, 0x09, 0x5a, 0xac, 0x91, 0xb5, 0xf3, 0x7e, 0x28, 0xbb, 0x49, 0xec, 0x7e, 0xd5, 0x97, }, + .expire = 0, }; const unsigned char c_issuer_cert[] = { @@ -122,6 +123,7 @@ const unsigned char c_ssd1[] = { 0x03, 0x8d, 0x0c, 0x91, 0x0a, 0x8a, 0x02, 0x95, 0x05, 0x9f, 0x37, 0x04, 0x9f, 0x4c, 0x08, 0x39, 0x00, }; + static const struct tlv ssd1_tlv = { .len = sizeof(c_ssd1), .value = c_ssd1, @@ -145,6 +147,7 @@ const unsigned char c_crm1[] = { 0x00, 0x00, 0x00, 0x06, 0x43, 0x14, 0x09, 0x25, 0x50, 0x12, 0x34, 0x57, 0x79, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x00, }; + static const struct tlv crm1_tlv = { .len = sizeof(c_crm1), .value = c_crm1, @@ -168,7 +171,7 @@ static int cda_test_raw(bool verbose) { return 1; if (verbose) { - printf("issuer cert:\n"); + PrintAndLogEx(INFO, "issuer cert:"); dump_buffer(ipk_data, ipk_data_len, stdout, 0); } @@ -198,7 +201,7 @@ static int cda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash:\n"); + PrintAndLogEx(INFO, "crypto hash:"); dump_buffer(h, 20, stdout, 0); } @@ -227,7 +230,7 @@ static int cda_test_raw(bool verbose) { return 1; if (verbose) { - printf("icc cert:\n"); + PrintAndLogEx(INFO, "icc cert:"); dump_buffer(iccpk_data, iccpk_data_len, stdout, 0); } @@ -256,7 +259,7 @@ static int cda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash1.1:\n"); + PrintAndLogEx(INFO, "crypto hash1.1:"); dump_buffer(h, 20, stdout, 0); } @@ -283,7 +286,7 @@ static int cda_test_raw(bool verbose) { return 1; if (verbose) { - printf("SDAD:\n"); + PrintAndLogEx(INFO, "SDAD:"); dump_buffer(sdad, sdad_len, stdout, 0); } @@ -304,7 +307,7 @@ static int cda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash2:\n"); + PrintAndLogEx(INFO, "crypto hash2:"); dump_buffer(h2, 20, stdout, 0); } @@ -327,7 +330,7 @@ static int cda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash2.1:\n"); + PrintAndLogEx(INFO, "crypto hash2.1:"); dump_buffer(h, 20, stdout, 0); } @@ -338,9 +341,7 @@ static int cda_test_raw(bool verbose) { } crypto_hash_close(ch); - free(sdad); - return 0; } @@ -355,7 +356,7 @@ static int cda_test_pk(bool verbose) { struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db); if (!ipk) { - fprintf(stderr, "Could not recover Issuer certificate!\n"); + PrintAndLogEx(WARNING, "Could not recover Issuer certificate!"); tlvdb_free(db); return 2; } @@ -366,7 +367,7 @@ static int cda_test_pk(bool verbose) { struct emv_pk *iccpk = emv_pki_recover_icc_cert(ipk, db, &ssd1_tlv); if (!iccpk) { - fprintf(stderr, "Could not recover ICC certificate!\n"); + PrintAndLogEx(WARNING, "Could not recover ICC certificate!"); emv_pk_free(ipk); tlvdb_free(db); return 2; @@ -386,7 +387,7 @@ static int cda_test_pk(bool verbose) { &crm1_tlv, NULL); if (!idndb) { - fprintf(stderr, "Could not recover IDN!\n"); + PrintAndLogEx(WARNING, "Could not recover IDN!"); tlvdb_free(cda_db); emv_pk_free(iccpk); emv_pk_free(ipk); @@ -396,7 +397,7 @@ static int cda_test_pk(bool verbose) { const struct tlv *idn = tlvdb_get(idndb, 0x9f4c, NULL); if (!idn) { - fprintf(stderr, "IDN not found!\n"); + PrintAndLogEx(WARNING, "IDN not found!"); tlvdb_free(idndb); tlvdb_free(cda_db); emv_pk_free(iccpk); @@ -406,7 +407,7 @@ static int cda_test_pk(bool verbose) { } if (verbose) { - printf("IDN:\n"); + PrintAndLogEx(INFO, "IDN:"); dump_buffer(idn->value, idn->len, stdout, 0); } @@ -415,27 +416,22 @@ static int cda_test_pk(bool verbose) { emv_pk_free(iccpk); emv_pk_free(ipk); tlvdb_free(db); - return 0; } int exec_cda_test(bool verbose) { - int ret; - fprintf(stdout, "\n"); - - ret = cda_test_raw(verbose); + int ret = cda_test_raw(verbose); if (ret) { - fprintf(stderr, "CDA raw test: failed\n"); + PrintAndLogEx(WARNING, "CDA raw test: (%s)", _RED_("failed")); return ret; } - fprintf(stdout, "CDA raw test: passed\n"); + PrintAndLogEx(INFO, "CDA raw test: (%s)", _GREEN_("passed")); ret = cda_test_pk(verbose); if (ret) { - fprintf(stderr, "CDA test pk: failed\n"); + PrintAndLogEx(WARNING, "CDA test pk: (%s)", _RED_("failed")); return ret; } - fprintf(stdout, "CDA test pk: passed\n"); - + PrintAndLogEx(INFO, "CDA test pk: (%s)", _GREEN_("passed")); return 0; } diff --git a/client/src/emv/test/crypto_test.c b/client/src/emv/test/crypto_test.c index 4a40952a8..e3b8124f0 100644 --- a/client/src/emv/test/crypto_test.c +++ b/client/src/emv/test/crypto_test.c @@ -17,16 +17,16 @@ #include #endif -#include "commonutil.h" // ARRAYLEN +#include // memcpy +#include // malloc +#include +#include "crypto_test.h" +#include "commonutil.h" // ARRAYLEN #include "../crypto.h" #include "../dump.h" #include "util_posix.h" - -#include -#include -#include -#include "crypto_test.h" +#include "ui.h" // printandlog static int test_genkey(unsigned int keylength, unsigned char *msg, size_t msg_len, bool verbose) { int ret = 1; @@ -34,46 +34,46 @@ static int test_genkey(unsigned int keylength, unsigned char *msg, size_t msg_le unsigned char *tmp, *tmp2; struct crypto_pk *pk; - printf("Testing key length %u ", keylength); + PrintAndLogEx(INFO, "Testing key length " _GREEN_("%u"), keylength); uint64_t ms = msclock(); pk = crypto_pk_genkey(PK_RSA, 1, keylength, 3); if (!pk) { - fprintf(stderr, "ERROR: key generation error.\n"); + PrintAndLogEx(WARNING, "ERROR: key generation error"); goto out; } tmp_len = crypto_pk_get_nbits(pk); if (tmp_len != keylength) { - fprintf(stderr, "ERROR: crypto_pk_get_nbits.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_get_nbits"); goto close; } tmp = crypto_pk_decrypt(pk, msg, msg_len, &tmp_len); if (!tmp) { - fprintf(stderr, "ERROR: crypto_pk_decrypt.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_decrypt"); goto close; } tmp2 = crypto_pk_encrypt(pk, tmp, tmp_len, &tmp2_len); if (!tmp2) { - fprintf(stderr, "ERROR: crypto_pk_encrypt.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_encrypt"); goto free_tmp; } if (tmp2_len == msg_len && !memcmp(tmp2, msg, tmp2_len)) { ret = 0; } else { - fprintf(stderr, "ERROR: encrypt-decrypt sequence length or data error.\n"); + PrintAndLogEx(WARNING, "ERROR: encrypt-decrypt sequence length or data error"); } free(tmp2); - printf("passed. (%"PRIu64" ms) \n", msclock() - ms); + PrintAndLogEx(SUCCESS, "passed (" _GREEN_("%" PRIu64) " ms)", msclock() - ms); + free_tmp: free(tmp); close: crypto_pk_close(pk); - out: return ret; } @@ -202,25 +202,25 @@ static int test_pk(bool verbose) { unsigned char *msg = message; size_t msg_len = sizeof(pk_N); - printf("Testing public keys interfaces\n"); + PrintAndLogEx(INFO, "Testing public keys interfaces"); pubk = crypto_pk_open(PK_RSA, pk_N, sizeof(pk_N), pk_E, sizeof(pk_E)); if (!pubk) { - fprintf(stderr, "ERROR: open public key.\n"); + PrintAndLogEx(WARNING, "ERROR: open public key"); return 1; } tmp_len = crypto_pk_get_nbits(pubk); if (tmp_len != sizeof(pk_N) * 8) { - fprintf(stderr, "ERROR: crypto_pk_get_nbits mismatch.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_get_nbits mismatch"); goto close_pub; } tmp = crypto_pk_get_parameter(pubk, 0, &tmp_len); if (tmp_len != sizeof(pk_N) || memcmp(tmp, pk_N, tmp_len)) { - fprintf(stderr, "ERROR: crypto_pk_get_parameter(0) Modulus. param len %zu len %zu\n", tmp_len, sizeof(pk_N)); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_get_parameter(0) Modulus. param len %zu len %zu", tmp_len, sizeof(pk_N)); free(tmp); goto close_pub; } @@ -228,7 +228,7 @@ static int test_pk(bool verbose) { tmp = crypto_pk_get_parameter(pubk, 1, &tmp_len); if (tmp_len != sizeof(pk_E) || memcmp(tmp, pk_E, tmp_len)) { - fprintf(stderr, "ERROR: crypto_pk_get_parameter(1) Exponent.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_get_parameter(1) Exponent"); free(tmp); goto close_pub; } @@ -244,20 +244,20 @@ static int test_pk(bool verbose) { pk_dQ, sizeof(pk_dQ), pk_I, sizeof(pk_I)); if (!privk) { - fprintf(stderr, "ERROR: open private key.\n"); + PrintAndLogEx(WARNING, "ERROR: open private key"); goto close_pub; } tmp_len = crypto_pk_get_nbits(privk); if (tmp_len != sizeof(pk_N) * 8) { - fprintf(stderr, "ERROR: crypto_pk_get_nbits mismatch.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_get_nbits mismatch"); goto close_pub; } tmp = crypto_pk_get_parameter(privk, 0, &tmp_len); if (tmp_len != sizeof(pk_N) || memcmp(tmp, pk_N, tmp_len)) { - fprintf(stderr, "ERROR: crypto_pk_get_parameter(0) Modulus. param len %zu len %zu\n", tmp_len, sizeof(pk_N)); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_get_parameter(0) Modulus. param len %zu len %zu", tmp_len, sizeof(pk_N)); free(tmp); goto close; } @@ -265,7 +265,7 @@ static int test_pk(bool verbose) { tmp = crypto_pk_get_parameter(privk, 1, &tmp_len); if (tmp_len != sizeof(pk_E) || memcmp(tmp, pk_E, tmp_len)) { - fprintf(stderr, "ERROR: crypto_pk_get_parameter(1) Exponent.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_get_parameter(1) Exponent"); free(tmp); goto close; } @@ -273,20 +273,20 @@ static int test_pk(bool verbose) { tmp = crypto_pk_decrypt(privk, msg, msg_len, &tmp_len); if (!tmp) { - fprintf(stderr, "ERROR: crypto_pk_decrypt.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_decrypt"); goto close; } tmp2 = crypto_pk_encrypt(pubk, tmp, tmp_len, &tmp2_len); if (!tmp2) { - fprintf(stderr, "ERROR: crypto_pk_encrypt.\n"); + PrintAndLogEx(WARNING, "ERROR: crypto_pk_encrypt"); goto free_tmp; } if (tmp2_len == msg_len && !memcmp(tmp2, msg, tmp2_len)) { ret = 0; } else { - fprintf(stderr, "ERROR: encrypt-decrypt sequence length or data error.\n"); + PrintAndLogEx(WARNING, "ERROR: encrypt-decrypt sequence length or data error"); } free(tmp2); @@ -304,31 +304,27 @@ close_pub: int exec_crypto_test(bool verbose, bool include_slow_tests) { unsigned int keylengths[] = {1024, 2048}; unsigned int extra_keylengths[] = {1152, 1408, 1984, 3072, 4096}; - int i; - int ret; - fprintf(stdout, "\n"); - - ret = test_pk(verbose); + int ret = test_pk(verbose); if (ret) { - fprintf(stderr, "Crypto raw test: failed\n"); + PrintAndLogEx(WARNING, "Crypto raw test: (%s)", _RED_("failed")); return ret; } - fprintf(stdout, "Crypto raw test: passed\n\n"); + PrintAndLogEx(SUCCESS, "Crypto raw test (%s)", _GREEN_("passed")); - for (i = 0; i < ARRAYLEN(keylengths); i++) { + for (int i = 0; i < ARRAYLEN(keylengths); i++) { unsigned int kl = keylengths[i]; ret = test_genkey(kl, message, kl / 8, verbose); if (ret) { - fprintf(stderr, "Crypto generate key[%u] test: failed\n", kl); + PrintAndLogEx(WARNING, "Crypto generate key[%u] test: (%s)", kl, _RED_("failed")); return ret; } } if (include_slow_tests) { - for (i = 0; i < ARRAYLEN(extra_keylengths); i++) { + for (int i = 0; i < ARRAYLEN(extra_keylengths); i++) { unsigned int kl = extra_keylengths[i]; ret = test_genkey(kl, message, kl / 8, verbose); if (ret) { - fprintf(stderr, "Crypto generate key[%u] test: failed\n", kl); + PrintAndLogEx(WARNING, "Crypto generate key[%u] test: (%s)", kl, _RED_("failed")); return ret; } } diff --git a/client/src/emv/test/cryptotest.c b/client/src/emv/test/cryptotest.c index f343ebbea..c15ec54f9 100644 --- a/client/src/emv/test/cryptotest.c +++ b/client/src/emv/test/cryptotest.c @@ -10,22 +10,20 @@ #include "cryptotest.h" #include "util.h" -#include "ui.h" - -#include "mbedtls/bignum.h" -#include "mbedtls/aes.h" -#include "mbedtls/cmac.h" -#include "mbedtls/des.h" -#include "mbedtls/ecp.h" -#include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" -#include "mbedtls/md5.h" -#include "mbedtls/x509.h" -#include "mbedtls/base64.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/entropy.h" -#include "mbedtls/timing.h" - +#include "ui.h" // printandlog +#include "bignum.h" +#include "aes.h" +#include "cmac.h" +#include "des.h" +#include "ecp.h" +#include "rsa.h" +#include "sha1.h" +#include "md5.h" +#include "x509.h" +#include "base64.h" +#include "ctr_drbg.h" +#include "entropy.h" +#include "timing.h" #include "crypto_test.h" #include "sda_test.h" #include "dda_test.h" @@ -63,7 +61,7 @@ int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests) res = mbedtls_timing_self_test(verbose); if (!res) break; - PrintAndLogEx(WARNING, "Repeat timing test %d", i + 1); + PrintAndLogEx(WARNING, "Repeat timing test " _RED_("%d"), i + 1); } if (res && !ignore_time) TestFail = true; @@ -100,12 +98,12 @@ int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests) res = roca_self_test(); if (res) TestFail = true; - PrintAndLogEx(NORMAL, "\n--------------------------"); + PrintAndLogEx(INFO, "--------------------------"); if (TestFail) - PrintAndLogEx(FAILED, "\tTest(s) [ %s ]", _RED_("Fail")); + PrintAndLogEx(FAILED, "\tTest(s) [ %s ]", _RED_("fail")); else - PrintAndLogEx(SUCCESS, "\tTest(s) [ %s ]", _GREEN_("OK")); + PrintAndLogEx(SUCCESS, "\tTest(s) [ %s ]", _GREEN_("ok")); return TestFail; } diff --git a/client/src/emv/test/dda_test.c b/client/src/emv/test/dda_test.c index a23a046dc..7bf6d4975 100644 --- a/client/src/emv/test/dda_test.c +++ b/client/src/emv/test/dda_test.c @@ -17,17 +17,17 @@ #include #endif -#include "dda_test.h" +#include // memcpy +#include // malloc +#include "dda_test.h" #include "../emv_pk.h" #include "../crypto.h" #include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" +#include "ui.h" // printandlog -#include -#include -#include struct emv_pk mchip_05 = { .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, }, @@ -57,6 +57,7 @@ struct emv_pk mchip_05 = { 0x10, 0xd2, 0x7b, 0x3e, 0xfc, 0xcd, 0x8f, 0x83, 0xde, 0x30, 0x52, 0xca, 0xd1, 0xe4, 0x89, 0x38, 0xc6, 0x8d, 0x09, 0x5a, 0xac, 0x91, 0xb5, 0xf3, 0x7e, 0x28, 0xbb, 0x49, 0xec, 0x7e, 0xd5, 0x97, }, + .expire = 0, }; const unsigned char d_issuer_cert[] = { @@ -122,6 +123,7 @@ const unsigned char d_ssd1[] = { 0x03, 0x8d, 0x0c, 0x91, 0x0a, 0x8a, 0x02, 0x95, 0x05, 0x9f, 0x37, 0x04, 0x9f, 0x4c, 0x08, 0x39, 0x00, }; + static const struct tlv ssd1_tlv = { .len = sizeof(d_ssd1), .value = d_ssd1, @@ -134,6 +136,7 @@ const unsigned char d_pan[] = { const unsigned char d_dd1[] = { 0x00, 0x00, 0x00, 0x00, }; + static const struct tlv dd1_tlv = { .len = sizeof(d_dd1), .value = d_dd1, @@ -157,7 +160,7 @@ static int dda_test_raw(bool verbose) { return 1; if (verbose) { - printf("issuer cert:\n"); + PrintAndLogEx(INFO, "issuer cert:"); dump_buffer(ipk_data, ipk_data_len, stdout, 0); } @@ -187,7 +190,7 @@ static int dda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash:\n"); + PrintAndLogEx(INFO, "crypto hash:"); dump_buffer(h, 20, stdout, 0); } @@ -216,7 +219,7 @@ static int dda_test_raw(bool verbose) { return 1; if (verbose) { - printf("icc cert:\n"); + PrintAndLogEx(INFO, "icc cert:"); dump_buffer(iccpk_data, iccpk_data_len, stdout, 0); } @@ -245,7 +248,7 @@ static int dda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash1.1:\n"); + PrintAndLogEx(INFO, "crypto hash1.1:"); dump_buffer(h, 20, stdout, 0); } @@ -272,7 +275,7 @@ static int dda_test_raw(bool verbose) { return 1; if (verbose) { - printf("sdad:\n"); + PrintAndLogEx(INFO, "sdad:"); dump_buffer(sdad, sdad_len, stdout, 0); } @@ -293,14 +296,12 @@ static int dda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash2:\n"); + PrintAndLogEx(INFO, "crypto hash2:"); dump_buffer(h2, 20, stdout, 0); } crypto_hash_close(ch); - free(sdad); - return 0; } @@ -315,7 +316,7 @@ static int dda_test_pk(bool verbose) { struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db); if (!ipk) { - fprintf(stderr, "Could not recover Issuer certificate!\n"); + PrintAndLogEx(WARNING, "Could not recover Issuer certificate!"); tlvdb_free(db); return 2; } @@ -326,7 +327,7 @@ static int dda_test_pk(bool verbose) { struct emv_pk *iccpk = emv_pki_recover_icc_cert(ipk, db, &ssd1_tlv); if (!iccpk) { - fprintf(stderr, "Could not recover ICC certificate!\n"); + PrintAndLogEx(WARNING, "Could not recover ICC certificate!"); emv_pk_free(ipk); tlvdb_free(db); return 2; @@ -336,7 +337,7 @@ static int dda_test_pk(bool verbose) { struct tlvdb *idndb = emv_pki_recover_idn(iccpk, db, &dd1_tlv); if (!idndb) { - fprintf(stderr, "Could not recover IDN!\n"); + PrintAndLogEx(WARNING, "Could not recover IDN!"); emv_pk_free(iccpk); emv_pk_free(ipk); tlvdb_free(db); @@ -345,7 +346,7 @@ static int dda_test_pk(bool verbose) { const struct tlv *idn = tlvdb_get(idndb, 0x9f4c, NULL); if (!idn) { - fprintf(stderr, "IDN not found!\n"); + PrintAndLogEx(WARNING, "IDN not found!"); tlvdb_free(idndb); emv_pk_free(iccpk); emv_pk_free(ipk); @@ -354,7 +355,7 @@ static int dda_test_pk(bool verbose) { } if (verbose) { - printf("IDN:\n"); + PrintAndLogEx(INFO, "IDN:"); dump_buffer(idn->value, idn->len, stdout, 0); } @@ -362,27 +363,22 @@ static int dda_test_pk(bool verbose) { emv_pk_free(iccpk); emv_pk_free(ipk); tlvdb_free(db); - return 0; } int exec_dda_test(bool verbose) { - int ret; - fprintf(stdout, "\n"); - - ret = dda_test_raw(verbose); + int ret = dda_test_raw(verbose); if (ret) { - fprintf(stderr, "DDA raw test: failed\n"); + PrintAndLogEx(WARNING, "DDA raw test: %s", _RED_("failed")); return ret; } - fprintf(stdout, "DDA raw test: passed\n"); + PrintAndLogEx(SUCCESS, "DDA raw test: %s", _GREEN_("passed")); ret = dda_test_pk(verbose); if (ret) { - fprintf(stderr, "DDA test pk: failed\n"); + PrintAndLogEx(WARNING, "DDA test pk: %s", _RED_("failed")); return ret; } - fprintf(stdout, "DDA test pk: passed\n"); - + PrintAndLogEx(SUCCESS, "DDA test pk: %s", _GREEN_("passed")); return 0; } diff --git a/client/src/emv/test/sda_test.c b/client/src/emv/test/sda_test.c index 86f201e58..04f3b70ae 100644 --- a/client/src/emv/test/sda_test.c +++ b/client/src/emv/test/sda_test.c @@ -17,15 +17,16 @@ #include #endif +#include +#include +#include + #include "../emv_pk.h" #include "../crypto.h" #include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" - -#include -#include -#include +#include "ui.h" // printandlog #include "sda_test.h" struct emv_pk vsdc_01 = { @@ -53,6 +54,7 @@ struct emv_pk vsdc_01 = { 0xbc, 0xa2, 0x12, 0x4a, 0x30, 0xa2, 0x8f, 0x54, 0x40, 0x2c, 0x34, 0xae, 0xca, 0x33, 0x1a, 0xb6, 0x7e, 0x1e, 0x79, 0xb2, 0x85, 0xdd, 0x57, 0x71, 0xb5, 0xd9, 0xff, 0x79, 0xea, 0x63, 0x0b, 0x75, }, + .expire = 0, }; const unsigned char issuer_cert[] = { @@ -91,6 +93,7 @@ const unsigned char ssd1[] = { 0x5f, 0x24, 0x03, 0x08, 0x12, 0x31, 0x5a, 0x08, 0x42, 0x76, 0x55, 0x00, 0x13, 0x23, 0x45, 0x99, 0x5f, 0x34, 0x01, 0x01, 0x9f, 0x07, 0x02, 0xff, 0x00, 0x9f, 0x0d, 0x05, 0xd0, 0x40, 0xac, 0xa8, 0x00, 0x9f, 0x0e, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x9f, 0x0f, 0x05, 0xd0, 0x68, 0xbc, 0xf8, 0x00, 0x5c, 0x00, }; + static const struct tlv ssd1_tlv = { .len = sizeof(ssd1), .value = ssd1, @@ -118,7 +121,7 @@ static int sda_test_raw(bool verbose) { return 1; if (verbose) { - printf("issuer cert:\n"); + PrintAndLogEx(INFO, "issuer cert:"); dump_buffer(ipk_data, ipk_data_len, stdout, 0); } @@ -148,7 +151,7 @@ static int sda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash:\n"); + PrintAndLogEx(INFO, "crypto hash:"); dump_buffer(h, 20, stdout, 0); } @@ -175,7 +178,7 @@ static int sda_test_raw(bool verbose) { return 1; if (verbose) { - printf("ssad:\n"); + PrintAndLogEx(INFO, "ssad:"); dump_buffer(ssad, ssad_len, stdout, 0); } @@ -196,14 +199,12 @@ static int sda_test_raw(bool verbose) { } if (verbose) { - printf("crypto hash2:\n"); + PrintAndLogEx(INFO, "crypto hash2:"); dump_buffer(h2, 20, stdout, 0); } crypto_hash_close(ch); - free(ssad); - return 0; } @@ -218,7 +219,7 @@ static int sda_test_pk(bool verbose) { struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db); if (!ipk) { - fprintf(stderr, "Could not recover Issuer certificate!\n"); + PrintAndLogEx(WARNING, "Could not recover Issuer certificate!"); tlvdb_free(db); return 2; } @@ -227,7 +228,7 @@ static int sda_test_pk(bool verbose) { struct tlvdb *dacdb = emv_pki_recover_dac(ipk, db, &ssd1_tlv); if (!dacdb) { - fprintf(stderr, "Could not recover DAC!\n"); + PrintAndLogEx(WARNING, "Could not recover DAC!"); emv_pk_free(ipk); tlvdb_free(db); return 2; @@ -235,7 +236,7 @@ static int sda_test_pk(bool verbose) { const struct tlv *dac = tlvdb_get(dacdb, 0x9f45, NULL); if (!dac) { - fprintf(stderr, "DAC not found!\n"); + PrintAndLogEx(WARNING, "DAC not found!"); tlvdb_free(dacdb); emv_pk_free(ipk); tlvdb_free(db); @@ -243,34 +244,29 @@ static int sda_test_pk(bool verbose) { } if (verbose) { - printf("dac:\n"); + PrintAndLogEx(INFO, "dac:"); dump_buffer(dac->value, dac->len, stdout, 0); } tlvdb_free(dacdb); emv_pk_free(ipk); tlvdb_free(db); - return 0; } int exec_sda_test(bool verbose) { - int ret; - fprintf(stdout, "\n"); - - ret = sda_test_raw(verbose); + int ret = sda_test_raw(verbose); if (ret) { - fprintf(stderr, "SDA raw test: failed\n"); + PrintAndLogEx(WARNING, "SDA raw test: %s", _RED_("failed")); return ret; } - fprintf(stdout, "SDA raw test: passed\n"); + PrintAndLogEx(SUCCESS, "SDA raw test: %s", _GREEN_("passed")); ret = sda_test_pk(verbose); if (ret) { - fprintf(stderr, "SDA test pk: failed\n"); + PrintAndLogEx(WARNING, "SDA test pk: %s", _RED_("failed")); return ret; } - fprintf(stdout, "SDA test pk: passed\n"); - + PrintAndLogEx(SUCCESS, "SDA test pk: %s", _GREEN_("passed")); return 0; } diff --git a/client/src/emv/tlv.h b/client/src/emv/tlv.h index 06a836876..41c28c3ef 100644 --- a/client/src/emv/tlv.h +++ b/client/src/emv/tlv.h @@ -29,7 +29,7 @@ struct tlv { }; struct tlvdb; -typedef bool (*tlv_cb)(void *data, const struct tlv *tlv, int level, bool is_leaf); +typedef void (*tlv_cb)(void *data, const struct tlv *tlv, int level, bool is_leaf); struct tlvdb *tlvdb_fixed(tlv_tag_t tag, size_t len, const unsigned char *value); struct tlvdb *tlvdb_external(tlv_tag_t tag, size_t len, const unsigned char *value); diff --git a/client/src/fido/cbortools.c b/client/src/fido/cbortools.c index d58b11145..a7b08e619 100644 --- a/client/src/fido/cbortools.c +++ b/client/src/fido/cbortools.c @@ -130,7 +130,7 @@ static CborError dumprecursive(uint8_t cmdCode, bool isResponse, CborValue *it, CborError err; CborType type = cbor_value_get_type(it); //printf("^%x^", type); - bool got_next; + bool got_next = false; switch (type) { case CborMapType: @@ -155,8 +155,18 @@ static CborError dumprecursive(uint8_t cmdCode, bool isResponse, CborValue *it, got_next = true; break; } - - default: { + case CborByteStringType: + case CborTextStringType: + case CborTagType: + case CborSimpleType: + case CborBooleanType: + case CborNullType: + case CborUndefinedType: + case CborHalfFloatType: + case CborFloatType: + case CborDoubleType: + case CborInvalidType: + case CborIntegerType: { err = dumpelm(it, &got_next, (isMapType && (elmCount % 2)) ? 0 : nestingLevel); if (err) return err; diff --git a/client/src/fido/fidocore.c b/client/src/fido/fidocore.c index 32d7c9ff0..3cddbc5a9 100644 --- a/client/src/fido/fidocore.c +++ b/client/src/fido/fidocore.c @@ -17,7 +17,7 @@ #include "emv/emvcore.h" #include "emv/emvjson.h" #include "cbortools.h" -#include "mbedtls/x509_crt.h" +#include "x509_crt.h" #include "crypto/asn1utils.h" #include "crypto/libpcrypto.h" #include "additional_ca.h" diff --git a/client/src/fileutils.c b/client/src/fileutils.c index b0b8d9772..8528fa770 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -225,7 +225,7 @@ static char *filenamemcopy(const char *preferredName, const char *suffix) { return fileName; } -static char *newfilenamemcopy(const char *preferredName, const char *suffix) { +char *newfilenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; if (suffix == NULL) return NULL; uint16_t preferredNameLen = strlen(preferredName); @@ -312,7 +312,10 @@ out: return retval; } -int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) { +int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, void (*callback)(json_t *)) { + return saveFileJSONex(preferredName, ftype, data, datalen, true, callback); +} +int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *)) { if (data == NULL) return PM3_EINVARG; @@ -343,37 +346,30 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } if (mfIsSectorTrailer(i)) { - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.KeyA", mfSectorNum(i)); + + snprintf(path, sizeof(path), "$.SectorKeys.%d.KeyA", mfSectorNum(i)); JsonSaveBufAsHexCompact(root, path, &data[i * 16], 6); - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.KeyB", mfSectorNum(i)); + snprintf(path, sizeof(path), "$.SectorKeys.%d.KeyB", mfSectorNum(i)); JsonSaveBufAsHexCompact(root, path, &data[i * 16 + 10], 6); - memset(path, 0x00, sizeof(path)); uint8_t *adata = &data[i * 16 + 6]; - sprintf(path, "$.SectorKeys.%d.AccessConditions", mfSectorNum(i)); + snprintf(path, sizeof(path), "$.SectorKeys.%d.AccessConditions", mfSectorNum(i)); JsonSaveBufAsHexCompact(root, path, &data[i * 16 + 6], 4); - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 3); + snprintf(path, sizeof(path), "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 3); JsonSaveStr(root, path, mfGetAccessConditionsDesc(0, adata)); - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 2); + snprintf(path, sizeof(path), "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 2); JsonSaveStr(root, path, mfGetAccessConditionsDesc(1, adata)); - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 1); + snprintf(path, sizeof(path), "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i - 1); JsonSaveStr(root, path, mfGetAccessConditionsDesc(2, adata)); - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i); + snprintf(path, sizeof(path), "$.SectorKeys.%d.AccessConditionsText.block%zu", mfSectorNum(i), i); JsonSaveStr(root, path, mfGetAccessConditionsDesc(3, adata)); - memset(path, 0x00, sizeof(path)); - sprintf(path, "$.SectorKeys.%d.AccessConditionsText.UserData", mfSectorNum(i)); + snprintf(path, sizeof(path), "$.SectorKeys.%d.AccessConditionsText.UserData", mfSectorNum(i)); JsonSaveBufAsHexCompact(root, path, &adata[3], 1); } } @@ -545,8 +541,8 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } } break; - case jsfSettings: - preferences_save_callback(root); + case jsfCustom: + (*callback)(root); break; default: break; @@ -559,7 +555,9 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s retval = 200; goto out; } - PrintAndLogEx(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName); + if (verbose) + PrintAndLogEx(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName); + json_decref(root); out: @@ -678,7 +676,6 @@ int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_ return PM3_SUCCESS; } - int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { if (data == NULL) return 1; @@ -740,6 +737,9 @@ out: } int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) { + return loadFile_safeEx(preferredName, suffix, pdata, datalen, true); +} +int loadFile_safeEx(const char *preferredName, const char *suffix, void **pdata, size_t *datalen, bool verbose) { char *path; int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false); @@ -785,7 +785,8 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s *datalen = bytes_read; - PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); + if (verbose) + PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); return PM3_SUCCESS; } @@ -820,6 +821,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { if (fgets(line, sizeof(line), f) == NULL) { if (feof(f)) break; + fclose(f); PrintAndLogEx(FAILED, "File reading error."); retval = PM3_EFILE; @@ -829,10 +831,14 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { if (line[0] == '#') continue; + strcleanrn(line, sizeof(line)); + int res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); - if (res == 0 || res == 1) { + if (res == 0) { memcpy(udata + counter, buf, hexlen); counter += hexlen; + } else { + retval = PM3_ESOFT; } } fclose(f); @@ -846,27 +852,123 @@ out: return retval; } -int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) { +int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen) { + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } + + FILE *f = fopen(path, "r"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + free(path); + return PM3_EFILE; + } + free(path); + + // get filesize in order to malloc memory + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + if (fsize <= 0) { + PrintAndLogEx(FAILED, "error, when getting filesize"); + fclose(f); + return PM3_EFILE; + } + + *pdata = calloc(fsize, sizeof(uint8_t)); + if (!*pdata) { + PrintAndLogEx(FAILED, "error, cannot allocate memory"); + fclose(f); + return PM3_EMALLOC; + } + + // 128 + 2 newline chars + 1 null terminator + char line[131]; + memset(line, 0, sizeof(line)); + uint8_t buf[64] = {0x00}; + size_t counter = 0; + int retval = PM3_SUCCESS, hexlen = 0; + + uint8_t *tmp = (uint8_t *)*pdata; + + while (!feof(f)) { + + memset(line, 0, sizeof(line)); + + if (fgets(line, sizeof(line), f) == NULL) { + if (feof(f)) + break; + + fclose(f); + PrintAndLogEx(FAILED, "File reading error."); + return PM3_EFILE; + } + + if (line[0] == '#') + continue; + + strcleanrn(line, sizeof(line)); + + res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); + if (res == 0) { + memcpy(tmp + counter, buf, hexlen); + counter += hexlen; + } else { + retval = PM3_ESOFT; + } + } + fclose(f); + PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from text file " _YELLOW_("%s"), counter, preferredName); + + + uint8_t *newdump = realloc(*pdata, counter); + if (newdump == NULL) { + free(*pdata); + return PM3_EMALLOC; + } else { + *pdata = newdump; + } + + if (datalen) + *datalen = counter; + + return retval; +} + +int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, void (*callback)(json_t *)) { + return loadFileJSONex(preferredName, data, maxdatalen, datalen, true, callback); +} +int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, bool verbose, void (*callback)(json_t *)) { if (data == NULL) return PM3_EINVARG; - char *fileName = filenamemcopy(preferredName, ".json"); - if (fileName == NULL) return PM3_EMALLOC; *datalen = 0; - json_t *root; - json_error_t error; - int retval = PM3_SUCCESS; - root = json_load_file(fileName, 0, &error); + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json", false); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } + + json_error_t error; + json_t *root = json_load_file(path, 0, &error); + if (verbose) + PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), path); + + free(path); + if (!root) { - PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text); + PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", preferredName, error.line, error.text); retval = PM3_ESOFT; goto out; } if (!json_is_object(root)) { - PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName); + PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", preferredName); retval = PM3_ESOFT; goto out; } @@ -887,11 +989,11 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ goto out; } - char path[30] = {0}; - sprintf(path, "$.blocks.%d", i); + char blocks[30] = {0}; + sprintf(blocks, "$.blocks.%d", i); size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 16, &len); + JsonLoadBufAsHex(root, blocks, &udata[sptr], 16, &len); if (!len) break; @@ -909,11 +1011,11 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ goto out; } - char path[30] = {0}; - sprintf(path, "$.blocks.%d", i); + char blocks[30] = {0}; + sprintf(blocks, "$.blocks.%d", i); size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); + JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); if (!len) break; @@ -931,11 +1033,11 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ goto out; } - char path[30] = {0}; - sprintf(path, "$.blocks.%zu", i); + char blocks[30] = {0}; + sprintf(blocks, "$.blocks.%zu", i); size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); + JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); if (!len) break; @@ -953,11 +1055,11 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ goto out; } - char path[30] = {0}; - sprintf(path, "$.blocks.%zu", i); + char blocks[30] = {0}; + sprintf(blocks, "$.blocks.%zu", i); size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 8, &len); + JsonLoadBufAsHex(root, blocks, &udata[sptr], 8, &len); if (!len) break; @@ -974,11 +1076,11 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ goto out; } - char path[30] = {0}; - sprintf(path, "$.blocks.%zu", i); + char blocks[30] = {0}; + sprintf(blocks, "$.blocks.%zu", i); size_t len = 0; - JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); + JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); if (!len) break; @@ -986,17 +1088,18 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ } *datalen = sptr; } - PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); - if (!strcmp(ctype, "settings")) { - preferences_load_callback(root); - } + out: + + if (callback != NULL) { + (*callback)(root); + } + json_decref(root); - free(fileName); return retval; } -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint32_t *keycnt) { // t5577 == 4bytes // mifare == 6 bytes // mf plus == 16 bytes @@ -1009,7 +1112,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u return loadFileDICTIONARYEx(preferredName, data, 0, datalen, keylen, keycnt, 0, NULL, true); } -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint32_t *keycnt, size_t startFilePosition, size_t *endFilePosition, bool verbose) { if (data == NULL) return PM3_EINVARG; @@ -1025,7 +1128,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale keylen <<= 1; char line[255]; - uint16_t vkeycnt = 0; + uint32_t vkeycnt = 0; size_t counter = 0; int retval = PM3_SUCCESS; @@ -1048,7 +1151,8 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale // read file while (!feof(f)) { - size_t filepos = ftell(f); + long filepos = ftell(f); + if (!fgets(line, sizeof(line), f)) { if (endFilePosition) *endFilePosition = 0; @@ -1097,7 +1201,7 @@ out: return retval; } -int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) { +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt) { int retval = PM3_SUCCESS; @@ -1141,7 +1245,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key while (fgets(line, sizeof(line), f)) { // check if we have enough space (if not allocate more) - if ((((size_t)(*keycnt)) * (keylen >> 1)) >= mem_size) { + if ((*keycnt * (keylen >> 1)) >= mem_size) { mem_size += block_size; *pdata = realloc(*pdata, mem_size); @@ -1151,7 +1255,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key fclose(f); goto out; } else { - memset(*pdata + (mem_size - block_size), 0, block_size); + memset((uint8_t *)*pdata + (mem_size - block_size), 0, block_size); } } @@ -1171,7 +1275,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key uint64_t key = strtoull(line, NULL, 16); - num_to_bytes(key, keylen >> 1, *pdata + (*keycnt * (keylen >> 1))); + num_to_bytes(key, keylen >> 1, (uint8_t *)*pdata + (*keycnt * (keylen >> 1))); (*keycnt)++; @@ -1185,38 +1289,137 @@ out: return retval; } -int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { - if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH) - return 1; - // try to check new file format - mfu_dump_t *mfu_dump = (mfu_dump_t *) *dump; - if ((*dumplen - MFU_DUMP_PREFIX_LENGTH) / 4 - 1 == mfu_dump->pages) - return 0; +mfu_df_e detect_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose) { + + mfu_df_e retval = MFU_DF_UNKNOWN; + uint8_t bcc0, bcc1; + uint8_t ct = 0x88; + + // detect new + mfu_dump_t *new = (mfu_dump_t *)*dump; + bcc0 = ct ^ new->data[0] ^ new->data[1] ^ new->data[2]; + bcc1 = new->data[4] ^ new->data[5] ^ new->data[6] ^ new->data[7]; + if (bcc0 == new->data[3] && bcc1 == new->data[8]) { + retval = MFU_DF_NEWBIN; + } + + // detect old + if (retval == MFU_DF_UNKNOWN) { + old_mfu_dump_t *old = (old_mfu_dump_t *)*dump; + bcc0 = ct ^ old->data[0] ^ old->data[1] ^ old->data[2]; + bcc1 = old->data[4] ^ old->data[5] ^ old->data[6] ^ old->data[7]; + if (bcc0 == old->data[3] && bcc1 == old->data[8]) { + retval = MFU_DF_OLDBIN; + } + } + + // detect plain + if (retval == MFU_DF_UNKNOWN) { + uint8_t *plain = *dump; + bcc0 = ct ^ plain[0] ^ plain[1] ^ plain[2]; + bcc1 = plain[4] ^ plain[5] ^ plain[6] ^ plain[7]; + if ((bcc0 == plain[3]) && (bcc1 == plain[8])) { + retval = MFU_DF_PLAINBIN; + } + } + + if (verbose) { + switch (retval) { + case MFU_DF_NEWBIN: + PrintAndLogEx(INFO, "detected " _GREEN_("new") " mfu dump format"); + break; + case MFU_DF_OLDBIN: + PrintAndLogEx(INFO, "detected " _GREEN_("old") " mfu dump format"); + break; + case MFU_DF_PLAINBIN: + PrintAndLogEx(INFO, "detected " _GREEN_("plain") " mfu dump format"); + break; + case MFU_DF_UNKNOWN: + PrintAndLogEx(WARNING, "failed to detected mfu dump format"); + break; + } + } + return retval; +} + +static int convert_plain_mfu_dump(uint8_t **dump, size_t *dumplen, bool verbose) { + + mfu_dump_t *mfu = (mfu_dump_t *) calloc(sizeof(mfu_dump_t), sizeof(uint8_t)); + if (mfu == NULL) { + return PM3_EMALLOC; + } + + memcpy(mfu->data, *dump, *dumplen); + + mfu->pages = *dumplen / 4 - 1; + + if (verbose) { + PrintAndLogEx(SUCCESS, "plain mfu dump format was converted to " _GREEN_("%d") " blocks", mfu->pages + 1); + } + + *dump = (uint8_t *)mfu; + *dumplen += MFU_DUMP_PREFIX_LENGTH ; + return PM3_SUCCESS; +} + +static int convert_old_mfu_dump(uint8_t **dump, size_t *dumplen, bool verbose) { + // convert old format - old_mfu_dump_t *old_mfu_dump = (old_mfu_dump_t *) *dump; + old_mfu_dump_t *old_mfu_dump = (old_mfu_dump_t *)*dump; size_t old_data_len = *dumplen - OLD_MFU_DUMP_PREFIX_LENGTH; size_t new_dump_len = old_data_len + MFU_DUMP_PREFIX_LENGTH; - mfu_dump = (mfu_dump_t *) calloc(new_dump_len, sizeof(uint8_t)); + mfu_dump_t *mfu_dump = (mfu_dump_t *) calloc(sizeof(mfu_dump_t), sizeof(uint8_t)); + if (mfu_dump == NULL) { + return PM3_EMALLOC; + } + + memcpy(mfu_dump->version, old_mfu_dump->version, sizeof(mfu_dump->version)); + memcpy(mfu_dump->tbo, old_mfu_dump->tbo, sizeof(mfu_dump->tbo)); + memcpy(mfu_dump->signature, old_mfu_dump->signature, sizeof(mfu_dump->signature)); - memcpy(mfu_dump->version, old_mfu_dump->version, 8); - memcpy(mfu_dump->tbo, old_mfu_dump->tbo, 2); mfu_dump->tbo1[0] = old_mfu_dump->tbo1[0]; - memcpy(mfu_dump->signature, old_mfu_dump->signature, 32); - for (int i = 0; i < 3; i++) - mfu_dump->counter_tearing[i][3] = old_mfu_dump->tearing[i]; - memcpy(mfu_dump->data, old_mfu_dump->data, old_data_len); + for (int i = 0; i < 3; i++) { + mfu_dump->counter_tearing[i][3] = old_mfu_dump->tearing[i]; + } + + memcpy(mfu_dump->data, old_mfu_dump->data, sizeof(mfu_dump->data)); + mfu_dump->pages = old_data_len / 4 - 1; - // free old buffer, return new buffer - *dumplen = new_dump_len; + + if (verbose) { + PrintAndLogEx(SUCCESS, "old mfu dump format was converted to " _GREEN_("%d") " blocks", mfu_dump->pages + 1); + } + free(*dump); - *dump = (uint8_t *) mfu_dump; - PrintAndLogEx(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1); + *dump = (uint8_t *)mfu_dump; + *dumplen = new_dump_len; return PM3_SUCCESS; } +int convert_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose) { + + if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH) { + return PM3_EINVARG; + } + + mfu_df_e res = detect_mfu_dump_format(dump, dumplen, verbose); + + switch (res) { + case MFU_DF_NEWBIN: + return PM3_SUCCESS; + case MFU_DF_OLDBIN: + return convert_old_mfu_dump(dump, dumplen, verbose); + case MFU_DF_PLAINBIN: + return convert_plain_mfu_dump(dump, dumplen, verbose); + case MFU_DF_UNKNOWN: + default: + return PM3_ESOFT; + } +} + static int filelist(const char *path, const char *ext, bool last, bool tentative) { struct dirent **namelist; int n; @@ -1333,6 +1536,7 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea (strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) || (strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) || (strcmp(CMD_SCRIPTS_SUBDIR, pm3dir) == 0) || + (strcmp(PYTHON_SCRIPTS_SUBDIR, pm3dir) == 0) || (strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) { char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) @@ -1360,7 +1564,7 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea (strcmp(FIRMWARES_SUBDIR, pm3dir) == 0) || (strcmp(BOOTROM_SUBDIR, pm3dir) == 0) || (strcmp(FULLIMAGE_SUBDIR, pm3dir) == 0))) { - char *above = "../"; + const char *above = "../"; char *path = calloc(strlen(exec_path) + strlen(above) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); if (path == NULL) goto out; diff --git a/client/src/fileutils.h b/client/src/fileutils.h index 2f55a3c1a..d9bad1364 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -62,7 +62,7 @@ typedef enum { jsfT55x7, jsfT5555, jsfMfPlusKeys, - jsfSettings, + jsfCustom, jsfMfDesfireKeys, } JSONFileType; @@ -77,6 +77,7 @@ int fileExists(const char *filename); //bool create_path(const char *dirname); //bool setDefaultPath (savePaths_t pathIndex,const char *Path); // set a path in the path list session.defaultPaths +char *newfilenamemcopy(const char *preferredName, const char *suffix); /** * @brief Utility function to save data to a binary file. This method takes a preferred name, but if that @@ -115,7 +116,8 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t * @param datalen the length of the data * @return 0 for ok, 1 for failz */ -int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen); +int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, void (*callback)(json_t *)); +int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *)); /** STUB * @brief Utility function to save WAVE data to a file. This method takes a preferred name, but if that @@ -176,6 +178,7 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m * @return PM3_SUCCESS for ok, PM3_E* for failz */ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen); +int loadFile_safeEx(const char *preferredName, const char *suffix, void **pdata, size_t *datalen, bool verbose); /** * @brief Utility function to load data from a textfile (EML). This method takes a preferred name. * E.g. dumpdata-15.txt @@ -186,6 +189,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s * @return 0 for ok, 1 for failz */ int loadFileEML(const char *preferredName, void *data, size_t *datalen); +int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen); /** * @brief Utility function to load data from a JSON textfile. This method takes a preferred name. @@ -197,7 +201,9 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen); * @param datalen the number of bytes loaded from file * @return 0 for ok, 1 for failz */ -int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen); +int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, void (*callback)(json_t *)); +int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, bool verbose, void (*callback)(json_t *)); + /** * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. @@ -210,7 +216,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ * @param keycnt key count that lays in data. may be NULL * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint32_t *keycnt); /** * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. @@ -228,7 +234,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u * @param verbose print messages if true * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint16_t *keycnt, +int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, uint8_t keylen, uint32_t *keycnt, size_t startFilePosition, size_t *endFilePosition, bool verbose); /** @@ -240,16 +246,25 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale * @param keylen the number of bytes a key per row is * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt); +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt); + +typedef enum { + MFU_DF_UNKNOWN, + MFU_DF_PLAINBIN, + MFU_DF_OLDBIN, + MFU_DF_NEWBIN +} mfu_df_e; /** - * @brief Utility function to check and convert old mfu dump format to new - * + * @brief Utility function to check and convert plain mfu dump format to new mfu binary format. + * plain dumps doesn't have any extra data, like version, signature etc. * @param dump pointer to loaded dump to check and convert format * @param dumplen the number of bytes loaded dump and converted - * @return 0 for ok, 1 for fails + * @param verbose - extra debug output + * @return PM3_SUCCESS for ok, PM3_ESOFT for fails */ -int convertOldMfuDump(uint8_t **dump, size_t *dumplen); +int convert_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose); +mfu_df_e detect_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose); int searchAndList(const char *pm3dir, const char *ext); int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent); diff --git a/client/src/flash.c b/client/src/flash.c index 278aa34d9..249f7d826 100644 --- a/client/src/flash.c +++ b/client/src/flash.c @@ -240,7 +240,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_ goto fail; } - PrintAndLogEx(SUCCESS, _BLUE_("Loading ELF file") _YELLOW_(" %s"), name); + PrintAndLogEx(SUCCESS, _CYAN_("Loading ELF file") _YELLOW_(" %s"), name); if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) { PrintAndLogEx(ERR, "Error while reading ELF file header"); @@ -356,7 +356,7 @@ static int enter_bootloader(char *serial_port_name) { return PM3_SUCCESS; if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) { - PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader...")); + PrintAndLogEx(SUCCESS, _CYAN_("Entering bootloader...")); if ((state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) && (state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT)) { @@ -375,7 +375,7 @@ static int enter_bootloader(char *serial_port_name) { msleep(1000); if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { - PrintAndLogEx(NORMAL, " " _GREEN_("Found")); + PrintAndLogEx(NORMAL, _GREEN_(" found")); return PM3_SUCCESS; } else { PrintAndLogEx(ERR, _RED_("Error:") " Proxmark3 not found."); diff --git a/client/src/graph.c b/client/src/graph.c index f9e610414..3cb253b2c 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -11,6 +11,7 @@ #include #include #include "ui.h" +#include "proxgui.h" #include "util.h" //param_get32ex #include "lfdemod.h" #include "cmddata.h" //for g_debugmode @@ -18,7 +19,6 @@ int GraphBuffer[MAX_GRAPH_TRACE_LEN]; size_t GraphTraceLen; -int s_Buff[MAX_GRAPH_TRACE_LEN]; /* write a manchester bit to the graph TODO, verfy that this doesn't overflow buffer (iceman) @@ -115,7 +115,7 @@ bool isGraphBitstream(void) { return true; } -void convertGraphFromBitstream() { +void convertGraphFromBitstream(void) { convertGraphFromBitstreamEx(1, 0); } @@ -246,7 +246,10 @@ int GetPskClock(const char *str, bool printAns) { size_t firstPhaseShiftLoc = 0; uint8_t curPhase = 0, fc = 0; clock1 = DetectPSKClock(bits, size, 0, &firstPhaseShiftLoc, &curPhase, &fc); - setClockGrid(clock1, firstPhaseShiftLoc); + + if (clock1 >= 0) + setClockGrid(clock1, firstPhaseShiftLoc); + // Only print this message if we're not looping something if (printAns) PrintAndLogEx(SUCCESS, "Auto-detected clock rate: %d", clock1); diff --git a/client/src/graph.h b/client/src/graph.h index 01b20c7e2..deb51a31b 100644 --- a/client/src/graph.h +++ b/client/src/graph.h @@ -13,6 +13,10 @@ #include "common.h" +#ifdef __cplusplus +extern "C" { +#endif + void AppendGraph(bool redraw, uint16_t clock, int bit); size_t ClearGraph(bool redraw); bool HasGraphData(void); @@ -30,15 +34,14 @@ int GetNrzClock(const char *str, bool printAns); int GetFskClock(const char *str, bool printAns); bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge); -// Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample) -#ifndef MAX_GRAPH_TRACE_LEN -#define MAX_GRAPH_TRACE_LEN (40000 * 8 ) -#endif +#define MAX_GRAPH_TRACE_LEN (40000 * 8) #define GRAPH_SAVE 1 #define GRAPH_RESTORE 0 extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; extern size_t GraphTraceLen; -extern int s_Buff[MAX_GRAPH_TRACE_LEN]; +#ifdef __cplusplus +} +#endif #endif diff --git a/client/deps/jansson/path.c b/client/src/jansson_path.c similarity index 70% rename from client/deps/jansson/path.c rename to client/src/jansson_path.c index 11964ec6e..b0db54675 100644 --- a/client/deps/jansson/path.c +++ b/client/src/jansson_path.c @@ -11,7 +11,110 @@ #include #include "jansson.h" -#include "jansson_private.h" +#include "jansson_path.h" + +////// memory.c private functions + +/* C89 allows these to be macros */ +#undef malloc +#undef free + +/* memory function pointers */ +static json_malloc_t do_malloc = malloc; +static json_free_t do_free = free; + +static void *jsonp_malloc(size_t size) { + if (!size) + return NULL; + + return (*do_malloc)(size); +} + +static void jsonp_free(void *ptr) { + if (!ptr) + return; + + (*do_free)(ptr); +} + +static char *jsonp_strndup(const char *str, size_t len) { + char *new_str; + + new_str = jsonp_malloc(len + 1); + if (!new_str) + return NULL; + + memcpy(new_str, str, len); + new_str[len] = '\0'; + return new_str; +} + +static char *jsonp_strdup(const char *str) { + return jsonp_strndup(str, strlen(str)); +} + +////// error.c private functions + +static void jsonp_error_set_source(json_error_t *error, const char *source) { + size_t length; + + if (!error || !source) + return; + + length = strlen(source); + if (length < JSON_ERROR_SOURCE_LENGTH) { + strncpy(error->source, source, JSON_ERROR_SOURCE_LENGTH - 1); + } else { + size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4; + memcpy(error->source, "...", 3); + strncpy(error->source + 3, source + extra, length - extra + 1); + } +} + +static void jsonp_error_init(json_error_t *error, const char *source) { + if (error) { + error->text[0] = '\0'; + error->line = -1; + error->column = -1; + error->position = 0; + if (source) + jsonp_error_set_source(error, source); + else + error->source[0] = '\0'; + } +} + +static void jsonp_error_vset(json_error_t *error, int line, int column, + size_t position, enum json_error_code code, + const char *msg, va_list ap) { + if (!error) + return; + + if (error->text[0] != '\0') { + /* error already set */ + return; + } + + error->line = line; + error->column = column; + error->position = (int)position; + + vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH - 1, msg, ap); + error->text[JSON_ERROR_TEXT_LENGTH - 2] = '\0'; + error->text[JSON_ERROR_TEXT_LENGTH - 1] = code; +} + +static void jsonp_error_set(json_error_t *error, int line, int column, + size_t position, enum json_error_code code, + const char *msg, ...) { + va_list ap; + va_start(ap, msg); + jsonp_error_vset(error, line, column, position, code, msg, ap); + va_end(ap); +} + + +// original path.c from jansson fork json_t *json_path_get(const json_t *json, const char *path) { static const char root_chr = '$', array_open = '['; diff --git a/client/src/jansson_path.h b/client/src/jansson_path.h new file mode 100644 index 000000000..7737c1634 --- /dev/null +++ b/client/src/jansson_path.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2009-2016 Petri Lehtinen + * + * Jansson is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#ifndef JANSSON_PATH_H +#define JANSSON_PATH_H + +//#include +#include /* for size_t */ +//#include + +#ifdef __cplusplus +extern "C" { +#endif + +json_t *json_path_get(const json_t *json, const char *path); +int json_path_set_new(json_t *json, const char *path, json_t *value, size_t flags, json_error_t *error); + +static JSON_INLINE +int json_path_set(json_t *json, const char *path, json_t *value, size_t flags, json_error_t *error) { + return json_path_set_new(json, path, json_incref(value), flags, error); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/client/src/loclass/cipher.c b/client/src/loclass/cipher.c index af5d4f3a3..1753ebc9d 100644 --- a/client/src/loclass/cipher.c +++ b/client/src/loclass/cipher.c @@ -68,17 +68,17 @@ typedef struct { * T (x 0 x 1 . . . . . . x 15 ) = x 0 ⊕ x 1 ⊕ x 5 ⊕ x 7 ⊕ x 10 ⊕ x 11 ⊕ x 14 ⊕ x 15 . **/ static bool T(State state) { -/* - bool x0 = state.t & 0x8000; - bool x1 = state.t & 0x4000; - bool x5 = state.t & 0x0400; - bool x7 = state.t & 0x0100; - bool x10 = state.t & 0x0020; - bool x11 = state.t & 0x0010; - bool x14 = state.t & 0x0002; - bool x15 = state.t & 0x0001; - return x0 ^ x1 ^ x5 ^ x7 ^ x10 ^ x11 ^ x14 ^ x15; -*/ + /* + bool x0 = state.t & 0x8000; + bool x1 = state.t & 0x4000; + bool x5 = state.t & 0x0400; + bool x7 = state.t & 0x0100; + bool x10 = state.t & 0x0020; + bool x11 = state.t & 0x0010; + bool x14 = state.t & 0x0002; + bool x15 = state.t & 0x0001; + return x0 ^ x1 ^ x5 ^ x7 ^ x10 ^ x11 ^ x14 ^ x15; + */ #define _x0 ((state.t & 0x8000) >> 15 ) #define _x1 ((state.t & 0x4000) >> 14 ) #define _x5 ((state.t & 0x0400) >> 10 ) @@ -86,7 +86,7 @@ static bool T(State state) { #define _x10 ((state.t & 0x0020) >> 5 ) #define _x11 ((state.t & 0x0010) >> 4 ) #define _x14 ((state.t & 0x0002) >> 1 ) -#define _x15 (state.t & 0x0001) +#define _x15 (state.t & 0x0001) return (_x0) ^ (_x1) ^ (_x5) ^ (_x7) ^ (_x10) ^ (_x11) ^ (_x14) ^ (_x15); } /** @@ -114,49 +114,49 @@ static bool T(State state) { * z 2 = (r 3 ∧ r 5 ) ⊕ (r 4 ∧ r 6 ) ⊕ r 7 ⊕ x **/ static uint8_t _select(bool x, bool y, uint8_t r) { - #define _r0 ((r >> 7) & 0x01) - #define _r1 ((r >> 6) & 0x01) - #define _r2 ((r >> 5) & 0x01) - #define _r3 ((r >> 4) & 0x01) - #define _r4 ((r >> 3) & 0x01) - #define _r5 ((r >> 2) & 0x01) - #define _r6 ((r >> 1) & 0x01) - #define _r7 (r & 0x01) +#define _r0 ((r >> 7) & 0x01) +#define _r1 ((r >> 6) & 0x01) +#define _r2 ((r >> 5) & 0x01) +#define _r3 ((r >> 4) & 0x01) +#define _r4 ((r >> 3) & 0x01) +#define _r5 ((r >> 2) & 0x01) +#define _r6 ((r >> 1) & 0x01) +#define _r7 (r & 0x01) - #define _z0 ( (_r0 & _r2) ^ ( _r1 & (!_r3)) ^ (_r2 | _r4) ) - #define _z1 ( (_r0 | _r2) ^ ( _r5 | _r7) ^_r1 ^ _r6 ^ x ^ y ) - #define _z2 ( (_r3 & (!_r5)) ^ (_r4 & _r6) ^ _r7 ^ x ) +#define _z0 ( (_r0 & _r2) ^ ( _r1 & (!_r3)) ^ (_r2 | _r4) ) +#define _z1 ( (_r0 | _r2) ^ ( _r5 | _r7) ^_r1 ^ _r6 ^ (x) ^ (y) ) +#define _z2 ( (_r3 & (!_r5)) ^ (_r4 & _r6) ^ _r7 ^ (x) ) -/* - uint8_t r0 = r >> 7 & 0x1; - uint8_t r1 = r >> 6 & 0x1; - uint8_t r2 = r >> 5 & 0x1; - uint8_t r3 = r >> 4 & 0x1; - uint8_t r4 = r >> 3 & 0x1; - uint8_t r5 = r >> 2 & 0x1; - uint8_t r6 = r >> 1 & 0x1; - uint8_t r7 = r & 0x1; + /* + uint8_t r0 = r >> 7 & 0x1; + uint8_t r1 = r >> 6 & 0x1; + uint8_t r2 = r >> 5 & 0x1; + uint8_t r3 = r >> 4 & 0x1; + uint8_t r4 = r >> 3 & 0x1; + uint8_t r5 = r >> 2 & 0x1; + uint8_t r6 = r >> 1 & 0x1; + uint8_t r7 = r & 0x1; - bool z0 = (r0 & r2) ^ (r1 & (!r3)) ^ (r2 | r4); - bool z1 = (r0 | r2) ^ (r5 | r7) ^ r1 ^ r6 ^ x ^ y; - bool z2 = (r3 & (!r5)) ^ (r4 & r6) ^ r7 ^ x; + bool z0 = (r0 & r2) ^ (r1 & (!r3)) ^ (r2 | r4); + bool z1 = (r0 | r2) ^ (r5 | r7) ^ r1 ^ r6 ^ x ^ y; + bool z2 = (r3 & (!r5)) ^ (r4 & r6) ^ r7 ^ x; - // The three bitz z0.. z1 are packed into a uint8_t: - // 00000ZZZ - //Return value is a uint8_t - return ((z0 << 2) & 4) | ((z1 << 1) & 2) | (z2 & 1); -*/ - return ((_z0 << 2) & 4) | ((_z1 << 1) & 2) | (_z2 & 1); + // The three bitz z0.. z1 are packed into a uint8_t: + // 00000ZZZ + //Return value is a uint8_t + return ((z0 << 2) & 4) | ((z1 << 1) & 2) | (z2 & 1); + */ + return ((_z0 << 2) & 4) | ((_z1 << 1) & 2) | (_z2 & 1); -/* - uint8_t retval = 0; - retval |= (z0 << 2) & 4; - retval |= (z1 << 1) & 2; - retval |= (z2) & 1; + /* + uint8_t retval = 0; + retval |= (z0 << 2) & 4; + retval |= (z1 << 1) & 2; + retval |= (z2) & 1; - // Return value 0 <= retval <= 7 - return retval; -*/ + // Return value 0 <= retval <= 7 + return retval; + */ } /** @@ -177,10 +177,10 @@ static State successor(uint8_t *k, State s, bool y) { State successor = {0, 0, 0, 0}; successor.t = s.t >> 1; - successor.t |= (T(s) ^ r0 ^ r4) << 15; + successor.t |= ((T(s)) ^ (r0) ^ (r4)) << 15; successor.b = s.b >> 1; - successor.b |= (B(s) ^ r7) << 7; + successor.b |= ((B(s)) ^ (r7)) << 7; bool Tt = T(s); @@ -247,7 +247,6 @@ static void MAC(uint8_t *k, BitstreamIn input, BitstreamOut out) { void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { uint8_t cc_nr[13] = { 0 }; uint8_t div_key[8]; - //cc_nr=(uint8_t*) calloc(length+1, sizeof(uint8_t)); memcpy(cc_nr, cc_nr_p, 12); memcpy(div_key, div_key_p, 8); @@ -260,7 +259,6 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { //The output MAC must also be reversed reverse_arraybytes(dest, sizeof(dest)); memcpy(mac, dest, 4); - //free(cc_nr); } void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]) { @@ -283,7 +281,7 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke } #ifndef ON_DEVICE -int testMAC() { +int testMAC(void) { PrintAndLogEx(SUCCESS, "Testing MAC calculation..."); //From the "dismantling.IClass" paper: @@ -296,9 +294,9 @@ int testMAC() { doMAC(cc_nr, div_key, calculated_mac); if (memcmp(calculated_mac, correct_MAC, 4) == 0) { - PrintAndLogEx(SUCCESS, "MAC calculation OK!"); + PrintAndLogEx(SUCCESS, " MAC calculation (%s)", _GREEN_("ok")); } else { - PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:"); + PrintAndLogEx(FAILED, " MAC calculation (%s)", _RED_("failed")); printarr(" Calculated_MAC", calculated_mac, 4); printarr(" Correct_MAC ", correct_MAC, 4); return PM3_ESOFT; diff --git a/client/src/loclass/cipherutils.c b/client/src/loclass/cipherutils.c index 09f4bccd7..76415b74f 100644 --- a/client/src/loclass/cipherutils.c +++ b/client/src/loclass/cipherutils.c @@ -164,21 +164,22 @@ void printarr(const char *name, uint8_t *arr, int len) { free(output); } -void printvar(const char *name, uint8_t *arr, int len) { - PrintAndLogEx(INFO, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len)); -} - void printarr_human_readable(const char *title, uint8_t *arr, int len) { if (arr == NULL) return; int cx = 0, i; - size_t outsize = 100 + strlen(title) + len * 4; + size_t outsize = 100 + strlen(title) + (len * 4); char *output = calloc(outsize, sizeof(char)); PrintAndLogEx(INFO, "%s", title); for (i = 0; i < len; i++) { - if (i % 16 == 0) - cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i); + if (i % 16 == 0) { + + if (i == 0) + cx += snprintf(output + cx, outsize - cx, "%02x| ", i); + else + cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i); + } cx += snprintf(output + cx, outsize - cx, "%02x ", *(arr + i)); } PrintAndLogEx(INFO, output); @@ -190,7 +191,7 @@ void printarr_human_readable(const char *title, uint8_t *arr, int len) { //----------------------------- #ifndef ON_DEVICE -static int testBitStream() { +static int testBitStream(void) { uint8_t input [] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF}; uint8_t output [] = {0, 0, 0, 0, 0, 0, 0, 0}; BitstreamIn in = { input, sizeof(input) * 8, 0}; @@ -203,9 +204,9 @@ static int testBitStream() { } if (memcmp(input, output, sizeof(input)) == 0) { - PrintAndLogEx(SUCCESS, " Bitstream test 1 ok"); + PrintAndLogEx(SUCCESS, " Bitstream test 1 (%s)", _GREEN_("ok")); } else { - PrintAndLogEx(FAILED, " Bitstream test 1 failed"); + PrintAndLogEx(FAILED, " Bitstream test 1 (%s)", _RED_("failed")); uint8_t i; for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]); @@ -215,7 +216,7 @@ static int testBitStream() { return PM3_SUCCESS; } -static int testReversedBitstream() { +static int testReversedBitstream(void) { uint8_t input [] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF}; uint8_t reverse [] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t output [] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -233,9 +234,9 @@ static int testReversedBitstream() { } if (memcmp(input, output, sizeof(input)) == 0) { - PrintAndLogEx(SUCCESS, " Bitstream test 2 ok"); + PrintAndLogEx(SUCCESS, " Bitstream test 2 (%s)", _GREEN_("ok")); } else { - PrintAndLogEx(FAILED, " Bitstream test 2 failed"); + PrintAndLogEx(FAILED, " Bitstream test 2 (%s)", _RED_("failed")); uint8_t i; for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]); @@ -245,12 +246,12 @@ static int testReversedBitstream() { return PM3_SUCCESS; } - int testCipherUtils(void) { PrintAndLogEx(INFO, "Testing some internals..."); - int retval = 0; - retval |= testBitStream(); - retval |= testReversedBitstream(); + int retval = testBitStream(); + if (retval == PM3_SUCCESS) + retval = testReversedBitstream(); + return retval; } #endif diff --git a/client/src/loclass/cipherutils.h b/client/src/loclass/cipherutils.h index 6c90326a6..cbe51bb55 100644 --- a/client/src/loclass/cipherutils.h +++ b/client/src/loclass/cipherutils.h @@ -61,7 +61,6 @@ void pushBit(BitstreamOut *stream, bool bit); int bitsLeft(BitstreamIn *stream); #ifndef ON_DEVICE int testCipherUtils(void); -int testMAC(void); #endif void push6bits(BitstreamOut *stream, uint8_t bits); void EncryptDES(bool key[56], bool outBlk[64], bool inBlk[64], int verbose) ; @@ -71,6 +70,5 @@ uint8_t reversebytes(uint8_t b); void reverse_arraybytes(uint8_t *arr, size_t len); void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len); void printarr(const char *name, uint8_t *arr, int len); -void printvar(const char *name, uint8_t *arr, int len); void printarr_human_readable(const char *title, uint8_t *arr, int len); #endif // CIPHERUTILS_H diff --git a/client/src/loclass/elite_crack.c b/client/src/loclass/elite_crack.c index 03a9a3080..a811106d3 100644 --- a/client/src/loclass/elite_crack.c +++ b/client/src/loclass/elite_crack.c @@ -45,7 +45,7 @@ #include "ikeys.h" #include "elite_crack.h" #include "fileutils.h" -#include "mbedtls/des.h" +#include "des.h" #include "util_posix.h" /** @@ -221,15 +221,16 @@ void hash2(uint8_t *key64, uint8_t *outp_keytable) { // Once again, key is on iclass-format desencrypt_iclass(key64, key64_negated, z[0]); -// PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "High security custom key (Kcus):"); -// printvar("z0 ", z[0],8); +// PrintAndLogEx(NORMAL, ""); +// PrintAndLogEx(INFO, "High security custom key (Kcus):"); +// PrintAndLogEx(INFO, "z0 %s", sprint_hex(z[0],8)); uint8_t y[8][8] = {{0}, {0}}; // y[0]=DES_dec(z[0],~key) // Once again, key is on iclass-format desdecrypt_iclass(z[0], key64_negated, y[0]); -// printvar("y0 ", y[0],8); +// PrintAndLogEx(INFO, "y0 %s", sprint_hex(y[0],8)); for (i = 1; i < 8; i++) { // z [i] = DES dec (rk(K cus , i), z [i−1] ) @@ -272,9 +273,9 @@ static int _readFromDump(uint8_t dump[], dumpdata *item, uint8_t i) { memcpy(item, dump + i * itemsize, itemsize); if (true) { - printvar("csn", item->csn, sizeof(item->csn)); - printvar("cc_nr", item->cc_nr, sizeof(item->cc_nr)); - printvar("mac", item->mac, sizeof(item->mac)); + PrintAndLogEx(INFO, "csn %s", sprint_hex(item->csn, sizeof(item->csn))); + PrintAndLogEx(INFO, "cc_nr %s", sprint_hex(item->cc_nr, sizeof(item->cc_nr))); + PrintAndLogEx(INFO, "mac %s", sprint_hex(item->mac, sizeof(item->mac))); } return 0; } @@ -292,7 +293,7 @@ static int _readFromDump(uint8_t dump[], dumpdata *item, uint8_t i) { * @return */ int bruteforceItem(dumpdata item, uint16_t keytable[]) { - int errors = 0; + int found = false; uint8_t key_sel_p[8] = {0}; uint8_t div_key[8] = {0}; @@ -326,14 +327,14 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) { if (numbytes_to_recover > 3) { PrintAndLogEx(FAILED, "The CSN requires > 3 byte bruteforce, not supported"); - printvar("[-] CSN", item.csn, 8); - printvar("[-] HASH1", key_index, 8); + PrintAndLogEx(INFO, "CSN %s", sprint_hex(item.csn, 8)); + PrintAndLogEx(INFO, "HASH1 %s", sprint_hex(key_index, 8)); PrintAndLogEx(NORMAL, ""); //Before we exit, reset the 'BEING_CRACKED' to zero keytable[bytes_to_recover[0]] &= ~BEING_CRACKED; keytable[bytes_to_recover[1]] &= ~BEING_CRACKED; keytable[bytes_to_recover[2]] &= ~BEING_CRACKED; - return 1; + return PM3_ESOFT; } } @@ -399,11 +400,13 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) { } } + int errors = PM3_SUCCESS; + if (!found) { - PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, "Failed to recover %d bytes using the following CSN", numbytes_to_recover); - printvar("[!] CSN", item.csn, 8); - errors++; + PrintAndLogEx(INFO, "CSN %s", sprint_hex(item.csn, 8)); + errors = PM3_ESOFT; //Before we exit, reset the 'BEING_CRACKED' to zero for (i = 0; i < numbytes_to_recover; i++) { @@ -468,20 +471,20 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { mbedtls_des_crypt_ecb(&ctx_e, key64_negated, result); PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(SUCCESS, "-- High security custom key (Kcus) --"); - printvar("[+] Standard format ", key64_stdformat, 8); - printvar("[+] iClass format ", key64, 8); + PrintAndLogEx(SUCCESS, "Standard format %s", sprint_hex(key64_stdformat, 8)); + PrintAndLogEx(SUCCESS, "iClass format %s", sprint_hex(key64, 8)); if (master_key != NULL) memcpy(master_key, key64, 8); + PrintAndLogEx(NORMAL, "\n"); if (memcmp(z_0, result, 4) != 0) { PrintAndLogEx(WARNING, _RED_("Failed to verify") " calculated master key (k_cus)! Something is wrong."); - return 1; - } else { - PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!")); + return PM3_ESOFT; } - return 0; + + PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!")); + return PM3_SUCCESS; } /** * @brief Same as bruteforcefile, but uses a an array of dumpdata instead @@ -492,27 +495,29 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { */ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { uint8_t i; - int errors = 0; size_t itemsize = sizeof(dumpdata); - uint64_t t1 = msclock(); dumpdata *attack = (dumpdata *) calloc(itemsize, sizeof(uint8_t)); + if (attack == NULL) { + PrintAndLogEx(WARNING, "failed to allocate memory"); + return PM3_EMALLOC; + } + int res = 0; for (i = 0 ; i * itemsize < dumpsize ; i++) { memcpy(attack, dump + i * itemsize, itemsize); - errors += bruteforceItem(*attack, keytable); - if (errors) + res += bruteforceItem(*attack, keytable); + if (res != PM3_SUCCESS) break; } free(attack); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000); - - if (errors) { + if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") " again and collect new data"); - return 1; + return PM3_ESOFT; } // Pick out the first 16 bytes of the keytable. @@ -526,11 +531,10 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { if (!(keytable[i] & CRACKED)) { PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); - return 1; + return PM3_ESOFT; } } - errors += calculateMasterKey(first16bytes, NULL); - return errors; + return calculateMasterKey(first16bytes, NULL); } /** * Perform a bruteforce against a file which has been saved by pm3 @@ -568,7 +572,7 @@ int bruteforceFileNoKeys(const char *filename) { // ---------------------------------------------------------------------------- // TEST CODE BELOW // ---------------------------------------------------------------------------- -static int _testBruteforce() { +static int _testBruteforce(void) { PrintAndLogEx(INFO, "Testing crack from dumpfile..."); @@ -588,15 +592,14 @@ static int _testBruteforce() { **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 **** **/ uint16_t keytable[128] = {0}; - int errors = bruteforceFile("iclass_dump.bin", keytable); - if (errors) { + int res = bruteforceFile("iclass_dump.bin", keytable); + if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error: The file " _YELLOW_("iclass_dump.bin") "was not found!"); } - - return errors; + return res; } -static int _test_iclass_key_permutation() { +static int _test_iclass_key_permutation(void) { uint8_t testcase[8] = {0x6c, 0x8d, 0x44, 0xf9, 0x2a, 0x2d, 0x01, 0xbf}; uint8_t testcase_output[8] = {0}; uint8_t testcase_output_correct[8] = {0x8a, 0x0d, 0xb9, 0x88, 0xbb, 0xa7, 0x90, 0xea}; @@ -608,21 +611,21 @@ static int _test_iclass_key_permutation() { PrintAndLogEx(ERR, "Error with iclass key permute!"); printarr("testcase_output", testcase_output, 8); printarr("testcase_output_correct", testcase_output_correct, 8); - return 1; + return PM3_ESOFT; } if (memcmp(testcase, testcase_output_rev, 8) != 0) { PrintAndLogEx(ERR, "Error with reverse iclass key permute"); printarr("testcase", testcase, 8); printarr("testcase_output_rev", testcase_output_rev, 8); - return 1; + return PM3_ESOFT; } - PrintAndLogEx(SUCCESS, "Iclass key permutation OK!"); - return 0; + PrintAndLogEx(SUCCESS, "Iclass key permutation (%s)", _GREEN_("OK")); + return PM3_SUCCESS; } -static int _testHash1() { +static int _testHash1(void) { uint8_t expected[8] = {0x7E, 0x72, 0x2F, 0x40, 0x2D, 0x02, 0x51, 0x42}; uint8_t csn[8] = {0x01, 0x02, 0x03, 0x04, 0xF7, 0xFF, 0x12, 0xE0}; uint8_t k[8] = {0}; @@ -632,9 +635,9 @@ static int _testHash1() { PrintAndLogEx(ERR, "Error with hash1!"); printarr("calculated", k, 8); printarr("expected", expected, 8); - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } int testElite(bool slowtests) { @@ -661,15 +664,21 @@ int testElite(bool slowtests) { hash2(k_cus, keytable); printarr_human_readable("Hash2", keytable, 128); if (keytable[3] == 0xA1 && keytable[0x30] == 0xA3 && keytable[0x6F] == 0x95) { - PrintAndLogEx(SUCCESS, "Hash2 looks fine..."); + PrintAndLogEx(SUCCESS, " Hash2 (%s)", _GREEN_("ok")); } - int errors = 0 ; + int res = PM3_SUCCESS; PrintAndLogEx(INFO, "Testing hash1..."); - errors += _testHash1(); - PrintAndLogEx(INFO, "Testing key diversification ..."); - errors += _test_iclass_key_permutation(); + res += _testHash1(); + PrintAndLogEx(INFO, " hash1 (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")); + + PrintAndLogEx(INFO, "Testing key diversification..."); + res += _test_iclass_key_permutation(); + if (res == PM3_SUCCESS) + PrintAndLogEx(INFO, " key diversification (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")); + if (slowtests) - errors += _testBruteforce(); - return errors; + res += _testBruteforce(); + + return res; } diff --git a/client/src/loclass/elite_crack.h b/client/src/loclass/elite_crack.h index 8b357ac66..a9de5dbd1 100644 --- a/client/src/loclass/elite_crack.h +++ b/client/src/loclass/elite_crack.h @@ -104,7 +104,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]); * @param csn the CSN used * @param k output */ -void hash1(uint8_t csn[], uint8_t k[]); +void hash1(uint8_t *csn, uint8_t *k); void hash2(uint8_t *key64, uint8_t *outp_keytable); /** * From dismantling iclass-paper: diff --git a/client/src/loclass/hash1_brute.c b/client/src/loclass/hash1_brute.c index e381c5a3a..1c944b99e 100644 --- a/client/src/loclass/hash1_brute.c +++ b/client/src/loclass/hash1_brute.c @@ -8,7 +8,6 @@ #include #include "elite_crack.h" - static void calc_score(uint8_t *csn, uint8_t *k) { uint8_t score = 0 ; uint8_t i; diff --git a/client/src/loclass/ikeys.c b/client/src/loclass/ikeys.c index 9d9926547..3adcd97bb 100644 --- a/client/src/loclass/ikeys.c +++ b/client/src/loclass/ikeys.c @@ -70,15 +70,19 @@ From "Dismantling iclass": #include "fileutils.h" #include "cipherutils.h" -#include "mbedtls/des.h" +#include "des.h" -uint8_t pi[35] = {0x0F, 0x17, 0x1B, 0x1D, 0x1E, 0x27, 0x2B, 0x2D, 0x2E, 0x33, 0x35, 0x39, 0x36, 0x3A, 0x3C, 0x47, 0x4B, 0x4D, 0x4E, 0x53, 0x55, 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x69, 0x6A, 0x6C, 0x71, 0x72, 0x74, 0x78}; +uint8_t pi[35] = { + 0x0F, 0x17, 0x1B, 0x1D, 0x1E, 0x27, 0x2B, 0x2D, + 0x2E, 0x33, 0x35, 0x39, 0x36, 0x3A, 0x3C, 0x47, + 0x4B, 0x4D, 0x4E, 0x53, 0x55, 0x56, 0x59, 0x5A, + 0x5C, 0x63, 0x65, 0x66, 0x69, 0x6A, 0x6C, 0x71, + 0x72, 0x74, 0x78 +}; static mbedtls_des_context ctx_enc; static mbedtls_des_context ctx_dec; -static int debug_print = 0; - /** * @brief The key diversification algorithm uses 6-bit bytes. * This implementation uses 64 bit uint to pack seven of them into one @@ -219,25 +223,21 @@ static void permute(BitstreamIn *p_in, uint64_t z, int l, int r, BitstreamOut *o } } -static void printbegin() { - if (debug_print < 2) - return; - - PrintAndLogEx(NORMAL, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|"); -} - static void printState(const char *desc, uint64_t c) { - if (debug_print < 2) + if (g_debugMode == 0) return; + char s[60] = {0}; + snprintf(s, sizeof(s), "%s : ", desc); - printf("%s : ", desc); uint8_t x = (c & 0xFF00000000000000) >> 56; uint8_t y = (c & 0x00FF000000000000) >> 48; - printf(" %02x %02x", x, y); - int i; - for (i = 0; i < 8; i++) - printf(" %02x", getSixBitByte(c, i)); - printf("\n"); + + snprintf(s + strlen(s), sizeof(s) - strlen(s), " %02x %02x", x, y); + + for (uint8_t i = 0; i < 8; i++) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " %02x", getSixBitByte(c, i)); + + PrintAndLogEx(DEBUG, "%s", s); } /** @@ -254,7 +254,7 @@ static void printState(const char *desc, uint64_t c) { void hash0(uint64_t c, uint8_t k[8]) { c = swapZvalues(c); - printbegin(); + PrintAndLogEx(DEBUG, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|"); printState("origin", c); //These 64 bits are divided as c = x, y, z [0] , . . . , z [7] // x = 8 bits @@ -286,7 +286,7 @@ void hash0(uint64_t c, uint8_t k[8]) { if (x & 1) //Check if x7 is 1 p = ~p; - if (debug_print >= 2) PrintAndLogEx(DEBUG, "p:%02x", p); + PrintAndLogEx(DEBUG, "p: %02x", p); BitstreamIn p_in = { &p, 8, 0 }; uint8_t outbuffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -297,7 +297,7 @@ void hash0(uint64_t c, uint8_t k[8]) { // if all went well //Shift z-values down onto the lower segment - uint64_t zTilde = x_bytes_to_num(outbuffer, 8); + uint64_t zTilde = x_bytes_to_num(outbuffer, sizeof(outbuffer)); zTilde >>= 16; @@ -353,7 +353,7 @@ void hash0(uint64_t c, uint8_t k[8]) { * @param key * @param div_key */ -void diversifyKey(uint8_t csn[8], uint8_t key[8], uint8_t div_key[8]) { +void diversifyKey(uint8_t *csn, uint8_t *key, uint8_t *div_key) { // Prepare the DES key mbedtls_des_setkey_enc(&ctx_enc, key); @@ -363,13 +363,13 @@ void diversifyKey(uint8_t csn[8], uint8_t key[8], uint8_t div_key[8]) { mbedtls_des_crypt_ecb(&ctx_enc, csn, crypted_csn); //Calculate HASH0(DES)) - uint64_t crypt_csn = x_bytes_to_num(crypted_csn, 8); + uint64_t c_csn = x_bytes_to_num(crypted_csn, sizeof(crypted_csn)); //uint64_t crypted_csn_swapped = swapZvalues(crypt_csn); - hash0(crypt_csn, div_key); + hash0(c_csn, div_key); } /* -static void testPermute() { +static void testPermute(void) { uint64_t x = 0; pushbackSixBitByte(&x, 0x00, 0); pushbackSixBitByte(&x, 0x01, 1); @@ -555,7 +555,7 @@ Testcase testcases[] = { {{0}, {0}, {0}} }; -static int testKeyDiversificationWithMasterkeyTestcases() { +static int testKeyDiversificationWithMasterkeyTestcases(void) { int i, error = 0; uint8_t empty[8] = {0}; @@ -571,56 +571,42 @@ static int testKeyDiversificationWithMasterkeyTestcases() { return error; } -static void print64bits(const char *name, uint64_t val) { - printf("%s%08x%08x\n", name, (uint32_t)(val >> 32), (uint32_t)(val & 0xFFFFFFFF)); -} +static int testCryptedCSN(uint64_t crypted_csn, uint64_t expected) { -static uint64_t testCryptedCSN(uint64_t crypted_csn, uint64_t expected) { - int retval = 0; uint8_t result[8] = {0}; - if (debug_print) PrintAndLogEx(DEBUG, "debug_print %d", debug_print); - if (debug_print) print64bits(" {csn} ", crypted_csn); - uint64_t crypted_csn_swapped = swapZvalues(crypted_csn); - - if (debug_print) print64bits(" {csn-revz} ", crypted_csn_swapped); - hash0(crypted_csn, result); uint64_t resultbyte = x_bytes_to_num(result, 8); - if (debug_print) print64bits(" hash0 ", resultbyte); + + PrintAndLogEx(DEBUG, ""); + PrintAndLogEx(DEBUG, " {csn} %"PRIx64, crypted_csn); + PrintAndLogEx(DEBUG, " {csn-revz} %"PRIx64, crypted_csn_swapped); + PrintAndLogEx(DEBUG, " hash0 %"PRIx64 " (%s)", resultbyte, (resultbyte == expected) ? _GREEN_("OK") : _RED_("FAIL")); if (resultbyte != expected) { - if (debug_print) { - PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(FAILED, "FAIL!"); - print64bits(" expected ", expected); - } - retval = 1; - } else { - if (debug_print) PrintAndLogEx(SUCCESS, "[OK]"); + PrintAndLogEx(DEBUG, " expected " _YELLOW_("%"PRIx64), expected); + return PM3_ESOFT; } - return retval; + return PM3_SUCCESS; } static int testDES2(uint64_t csn, uint64_t expected) { uint8_t result[8] = {0}; uint8_t input[8] = {0}; - print64bits(" csn ", csn); + PrintAndLogEx(DEBUG, " csn %"PRIx64, csn); x_num_to_bytes(csn, 8, input); mbedtls_des_crypt_ecb(&ctx_enc, input, result); uint64_t crypt_csn = x_bytes_to_num(result, 8); - print64bits(" {csn} ", crypt_csn); - print64bits(" expected ", expected); - if (expected == crypt_csn) { - PrintAndLogEx(SUCCESS, "OK"); - return 0; - } else { - return 1; - } + PrintAndLogEx(DEBUG, " {csn} %"PRIx64, crypt_csn); + PrintAndLogEx(DEBUG, " expected %"PRIx64 " (%s)", expected, (expected == crypt_csn) ? _GREEN_("OK") : _RED_("FAIL")); + + if (expected != crypt_csn) + return PM3_ESOFT; + return PM3_SUCCESS; } /** @@ -628,55 +614,54 @@ static int testDES2(uint64_t csn, uint64_t expected) { * @brief doTestsWithKnownInputs * @return */ -static int doTestsWithKnownInputs() { +static int doTestsWithKnownInputs(void) { // KSel from http://www.proxmark.org/forum/viewtopic.php?pid=10977#p10977 - int errors = 0; - PrintAndLogEx(SUCCESS, "Testing DES encryption"); + PrintAndLogEx(INFO, "Testing DES encryption"); uint8_t key[8] = {0x6c, 0x8d, 0x44, 0xf9, 0x2a, 0x2d, 0x01, 0xbf}; mbedtls_des_setkey_enc(&ctx_enc, key); testDES2(0xbbbbaaaabbbbeeee, 0xd6ad3ca619659e6b); - PrintAndLogEx(SUCCESS, "Testing hashing algorithm"); + PrintAndLogEx(INFO, "Testing hashing algorithm"); - errors += testCryptedCSN(0x0102030405060708, 0x0bdd6512073c460a); - errors += testCryptedCSN(0x1020304050607080, 0x0208211405f3381f); - errors += testCryptedCSN(0x1122334455667788, 0x2bee256d40ac1f3a); - errors += testCryptedCSN(0xabcdabcdabcdabcd, 0xa91c9ec66f7da592); - errors += testCryptedCSN(0xbcdabcdabcdabcda, 0x79ca5796a474e19b); - errors += testCryptedCSN(0xcdabcdabcdabcdab, 0xa8901b9f7ec76da4); - errors += testCryptedCSN(0xdabcdabcdabcdabc, 0x357aa8e0979a5b8d); - errors += testCryptedCSN(0x21ba6565071f9299, 0x34e80f88d5cf39ea); - errors += testCryptedCSN(0x14e2adfc5bb7e134, 0x6ac90c6508bd9ea3); + int res = PM3_SUCCESS; + res += testCryptedCSN(0x0102030405060708, 0x0bdd6512073c460a); + res += testCryptedCSN(0x1020304050607080, 0x0208211405f3381f); + res += testCryptedCSN(0x1122334455667788, 0x2bee256d40ac1f3a); + res += testCryptedCSN(0xabcdabcdabcdabcd, 0xa91c9ec66f7da592); + res += testCryptedCSN(0xbcdabcdabcdabcda, 0x79ca5796a474e19b); + res += testCryptedCSN(0xcdabcdabcdabcdab, 0xa8901b9f7ec76da4); + res += testCryptedCSN(0xdabcdabcdabcdabc, 0x357aa8e0979a5b8d); + res += testCryptedCSN(0x21ba6565071f9299, 0x34e80f88d5cf39ea); + res += testCryptedCSN(0x14e2adfc5bb7e134, 0x6ac90c6508bd9ea3); - if (errors) - PrintAndLogEx(FAILED, "%d errors occurred (9 testcases)", errors); - else + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "%d res occurred (9 testcases)", res); + res = PM3_ESOFT; + } else { PrintAndLogEx(SUCCESS, "Hashing seems to work (9 testcases)"); - return errors; + res = PM3_SUCCESS; + } + return res; } - static bool readKeyFile(uint8_t *key, size_t keylen) { + bool retval = false; size_t len = 0; uint8_t *keyptr = NULL; if (loadFile_safe("iclass_key.bin", "", (void **)&keyptr, &len) != PM3_SUCCESS) { - return false; + return retval; } - - if (keylen != len) { - free(keyptr); - return false; + if (keylen == len) { + memcpy(key, keyptr, keylen); + retval = true; } - - memcpy(key, keyptr, keylen); free(keyptr); - return true; + return retval; } -int doKeyTests(uint8_t debuglevel) { - debug_print = debuglevel; +int doKeyTests(void) { PrintAndLogEx(INFO, "Checking if the master key is present (iclass_key.bin)..."); uint8_t key[8] = {0}; @@ -703,9 +688,8 @@ int doKeyTests(uint8_t debuglevel) { testKeyDiversificationWithMasterkeyTestcases(); } } - PrintAndLogEx(SUCCESS, "Testing key diversification with non-sensitive keys..."); - doTestsWithKnownInputs(); - return 0; + PrintAndLogEx(INFO, "Testing key diversification with non-sensitive keys..."); + return doTestsWithKnownInputs(); } /** diff --git a/client/src/loclass/ikeys.h b/client/src/loclass/ikeys.h index ccbc5539b..4fceda95f 100644 --- a/client/src/loclass/ikeys.h +++ b/client/src/loclass/ikeys.h @@ -52,7 +52,7 @@ * @return */ void hash0(uint64_t c, uint8_t k[8]); -int doKeyTests(uint8_t debuglevel); +int doKeyTests(void); /** * @brief Performs Elite-class key diversification * @param csn diff --git a/client/src/mifare/desfire_crypto.c b/client/src/mifare/desfire_crypto.c index a0e066b44..8dba06ca1 100644 --- a/client/src/mifare/desfire_crypto.c +++ b/client/src/mifare/desfire_crypto.c @@ -29,17 +29,13 @@ #include #include #include "commonutil.h" -#include "mbedtls/aes.h" -#include "mbedtls/des.h" +#include "aes.h" +#include "des.h" #include "ui.h" #include "crc.h" #include "crc16.h" // crc16 ccitt #include "crc32.h" -mbedtls_des_context ctx; -mbedtls_des3_context ctx3; -mbedtls_aes_context actx; - #ifndef AddCrc14A # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) #endif @@ -57,17 +53,20 @@ static inline void update_key_schedules(desfirekey_t key) { /******************************************************************************/ void des_encrypt(void *out, const void *in, const void *key) { + mbedtls_des_context ctx; mbedtls_des_setkey_enc(&ctx, key); mbedtls_des_crypt_ecb(&ctx, in, out); } void des_decrypt(void *out, const void *in, const void *key) { + mbedtls_des_context ctx; mbedtls_des_setkey_dec(&ctx, key); mbedtls_des_crypt_ecb(&ctx, in, out); } void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode) { if (length % 8) return; + mbedtls_des3_context ctx3; if (keymode == 2) mbedtls_des3_set2key_dec(&ctx3, key); else mbedtls_des3_set3key_dec(&ctx3, key); @@ -94,6 +93,7 @@ void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode) { if (length % 8) return; + mbedtls_des3_context ctx3; if (keymode == 2) mbedtls_des3_set2key_enc(&ctx3, key); else mbedtls_des3_set3key_enc(&ctx3, key); @@ -282,7 +282,7 @@ void cmac_generate_subkeys(desfirekey_t key) { void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) { int kbs = key_block_size(key); if (kbs == 0) { - return; + return; } uint8_t *buffer = malloc(padded_data_length(len, kbs)); @@ -754,43 +754,52 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, break; case T_3DES: switch (operation) { - case MCO_ENCYPHER: + case MCO_ENCYPHER: { + mbedtls_des3_context ctx3; mbedtls_des3_set2key_enc(&ctx3, key->data); mbedtls_des3_crypt_ecb(&ctx3, data, edata); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); break; - case MCO_DECYPHER: + } + case MCO_DECYPHER: { + mbedtls_des3_context ctx3; mbedtls_des3_set2key_dec(&ctx3, key->data); mbedtls_des3_crypt_ecb(&ctx3, data, edata); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); break; + } } break; case T_3K3DES: switch (operation) { - case MCO_ENCYPHER: + case MCO_ENCYPHER: { + mbedtls_des3_context ctx3; mbedtls_des3_set3key_enc(&ctx3, key->data); mbedtls_des3_crypt_ecb(&ctx3, data, edata); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT); break; - case MCO_DECYPHER: + } + case MCO_DECYPHER: { + mbedtls_des3_context ctx3; mbedtls_des3_set3key_dec(&ctx3, key->data); mbedtls_des3_crypt_ecb(&ctx3, data, edata); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); break; + } } break; case T_AES: switch (operation) { case MCO_ENCYPHER: { + mbedtls_aes_context actx; mbedtls_aes_init(&actx); mbedtls_aes_setkey_enc(&actx, key->data, 128); mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_ENCRYPT, sizeof(edata), ivect, data, edata); @@ -798,6 +807,7 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, break; } case MCO_DECYPHER: { + mbedtls_aes_context actx; mbedtls_aes_init(&actx); mbedtls_aes_setkey_dec(&actx, key->data, 128); mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_DECRYPT, sizeof(edata), ivect, edata, data); diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index ffacba3a7..9a8e20353 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -11,190 +11,226 @@ #include "mad.h" #include "ui.h" #include "commonutil.h" // ARRAYLEN - +#include "pm3_cmd.h" #include "crc.h" #include "util.h" +#include "fileutils.h" +#include "jansson.h" // https://www.nxp.com/docs/en/application-note/AN10787.pdf -static madAIDDescr madKnownAIDs[] = { - {0x0000, "free"}, - {0x0001, "defect, e.g. access keys are destroyed or unknown"}, - {0x0002, "reserved"}, - {0x0003, "contains additional directory info"}, - {0x0004, "contains card holder information in ASCII format."}, - {0x0005, "not applicable (above memory size)"}, +static json_t *mad_known_aids = NULL; - {0x03e1, "NDEF"}, +static const char *holder_info_type[] = { + "Surname", + "Given name", + "Sex", + "Other" }; -static madAIDDescr madKnownClusterCodes[] = { - {0x00, "cluster: card administration"}, - {0x01, "cluster: miscellaneous applications"}, - {0x02, "cluster: miscellaneous applications"}, - {0x03, "cluster: miscellaneous applications"}, - {0x04, "cluster: miscellaneous applications"}, - {0x05, "cluster: miscellaneous applications"}, - {0x06, "cluster: miscellaneous applications"}, - {0x07, "cluster: miscellaneous applications"}, - {0x08, "cluster: airlines"}, - {0x09, "cluster: ferry traffic"}, - {0x10, "cluster: railway services"}, - {0x11, "cluster: miscellaneous applications"}, - {0x12, "cluster: transport"}, - {0x14, "cluster: security solutions"}, - {0x18, "cluster: city traffic"}, - {0x19, "cluster: Czech Railways"}, - {0x20, "cluster: bus services"}, - {0x21, "cluster: multi modal transit"}, - {0x28, "cluster: taxi"}, - {0x30, "cluster: road toll"}, - {0x31, "cluster: generic transport"}, - {0x38, "cluster: company services"}, - {0x40, "cluster: city card services"}, - {0x47, "cluster: access control & security"}, - {0x48, "cluster: access control & security"}, - {0x49, "cluster: VIGIK"}, - {0x4A, "cluster: Ministry of Defence, Netherlands"}, - {0x4B, "cluster: Bosch Telecom, Germany"}, - {0x4C, "cluster: European Union Institutions"}, - {0x50, "cluster: ski ticketing"}, - {0x51, "cluster: access control & security"}, - {0x52, "cluster: access control & security"}, - {0x53, "cluster: access control & security"}, - {0x54, "cluster: access control & security"}, - {0x55, "cluster: SOAA standard for offline access standard"}, - {0x56, "cluster: access control & security"}, - {0x58, "cluster: academic services"}, - {0x60, "cluster: food"}, - {0x68, "cluster: non-food trade"}, - {0x70, "cluster: hotel"}, - {0x71, "cluster: loyalty"}, - {0x75, "cluster: airport services"}, - {0x78, "cluster: car rental"}, - {0x79, "cluster: Dutch government"}, - {0x80, "cluster: administration services"}, - {0x88, "cluster: electronic purse"}, - {0x90, "cluster: television"}, - {0x91, "cluster: cruise ship"}, - {0x95, "cluster: IOPTA"}, - {0x97, "cluster: metering"}, - {0x98, "cluster: telephone"}, - {0xA0, "cluster: health services"}, - {0xA8, "cluster: warehouse"}, - {0xB0, "cluster: electronic trade"}, - {0xB8, "cluster: banking"}, - {0xC0, "cluster: entertainment & sports"}, - {0xC8, "cluster: car parking"}, - {0xC9, "cluster: fleet management"}, - {0xD0, "cluster: fuel, gasoline"}, - {0xD8, "cluster: info services"}, - {0xE0, "cluster: press"}, - {0xE1, "cluster: NFC Forum"}, - {0xE8, "cluster: computer"}, - {0xF0, "cluster: mail"}, - {0xF8, "cluster: miscellaneous applications"}, +static const char *aid_admin[] = { + "free", + "defect", + "reserved", + "additional directory info", + "card holder info", + "not applicable" }; -static const char unknownAID[] = ""; +static int open_mad_file(json_t **root, bool verbose) { -static const char *GetAIDDescription(uint16_t AID) { - for (int i = 0; i < ARRAYLEN(madKnownAIDs); i++) - if (madKnownAIDs[i].AID == AID) - return madKnownAIDs[i].Description; + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, "mad", ".json", true); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } - for (int i = 0; i < ARRAYLEN(madKnownClusterCodes); i++) - if (madKnownClusterCodes[i].AID == (AID >> 8)) // high byte - cluster code - return madKnownClusterCodes[i].Description; + int retval = PM3_SUCCESS; + json_error_t error; - return unknownAID; + *root = json_load_file(path, 0, &error); + if (!*root) { + PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text); + retval = PM3_ESOFT; + goto out; + } + + if (!json_is_array(*root)) { + PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path); + retval = PM3_ESOFT; + goto out; + } + + if (verbose) + PrintAndLogEx(SUCCESS, "Loaded file " _YELLOW_("`%s`") " (%s) %zu records.", path, _GREEN_("ok"), json_array_size(*root)); +out: + free(path); + return retval; +} + +static int close_mad_file(json_t *root) { + json_decref(root); + return PM3_SUCCESS; +} + +static const char *mad_json_get_str(json_t *data, const char *name) { + + json_t *jstr = json_object_get(data, name); + if (jstr == NULL) + return NULL; + + if (!json_is_string(jstr)) { + PrintAndLogEx(WARNING, _YELLOW_("`%s`") " is not a string", name); + return NULL; + } + + const char *cstr = json_string_value(jstr); + if (strlen(cstr) == 0) + return NULL; + + return cstr; +} + +static int print_aid_description(json_t *root, uint16_t aid, char *fmt, bool verbose) { + char lmad[7] = {0}; + sprintf(lmad, "0x%04x", aid); // must be lowercase + + json_t *elm = NULL; + + for (uint32_t idx = 0; idx < json_array_size(root); idx++) { + json_t *data = json_array_get(root, idx); + if (!json_is_object(data)) { + PrintAndLogEx(ERR, "data [%d] is not an object\n", idx); + continue; + } + const char *fmad = mad_json_get_str(data, "mad"); + char lfmad[strlen(fmad) + 1]; + strcpy(lfmad, fmad); + str_lower(lfmad); + if (strcmp(lmad, lfmad) == 0) { + elm = data; + break; + } + } + + if (elm == NULL) { + PrintAndLogEx(INFO, fmt, " (unknown)"); + return PM3_ENODATA; + } + const char *vmad = mad_json_get_str(elm, "mad"); + const char *application = mad_json_get_str(elm, "application"); + const char *company = mad_json_get_str(elm, "company"); + const char *provider = mad_json_get_str(elm, "service_provider"); + const char *integrator = mad_json_get_str(elm, "system_integrator"); + char result[4 + strlen(application) + strlen(company)]; + sprintf(result, " %s [%s]", application, company); + PrintAndLogEx(INFO, fmt, result); + if (verbose) { + PrintAndLogEx(SUCCESS, " MAD: %s", vmad); + if (application) + PrintAndLogEx(SUCCESS, " Application: %s", application); + if (company) + PrintAndLogEx(SUCCESS, " Company: %s", company); + if (provider) + PrintAndLogEx(SUCCESS, " Service provider: %s", provider); + if (integrator) + PrintAndLogEx(SUCCESS, " System integrator: %s", integrator); + } + return PM3_SUCCESS; } static int madCRCCheck(uint8_t *sector, bool verbose, int MADver) { if (MADver == 1) { uint8_t crc = CRC8Mad(§or[16 + 1], 15 + 16); if (crc != sector[16]) { - PrintAndLogEx(WARNING, "Wrong MAD%d CRC. Calculated: 0x%02x, from card: 0x%02x", MADver, crc, sector[16]); - return 3; + PrintAndLogEx(WARNING, _RED_("Wrong MAD %d CRC") " calculated: 0x%02x != 0x%02x", MADver, crc, sector[16]); + return PM3_ESOFT; }; } else { uint8_t crc = CRC8Mad(§or[1], 15 + 16 + 16); if (crc != sector[0]) { - PrintAndLogEx(WARNING, "Wrong MAD%d CRC. Calculated: 0x%02x, from card: 0x%02x", MADver, crc, sector[16]); - return 3; + PrintAndLogEx(WARNING, _RED_("Wrong MAD %d CRC") " calculated: 0x%02x != 0x%02x", MADver, crc, sector[0]); + return PM3_ESOFT; }; } - - return 0; + return PM3_SUCCESS; } -static uint16_t madGetAID(uint8_t *sector, int MADver, int sectorNo) { +static uint16_t madGetAID(uint8_t *sector, bool swapmad, int MADver, int sectorNo) { + uint16_t mad; if (MADver == 1) - return (sector[16 + 2 + (sectorNo - 1) * 2] << 8) + (sector[16 + 2 + (sectorNo - 1) * 2 + 1]); + mad = (sector[16 + 2 + (sectorNo - 1) * 2 + 1] << 8) + (sector[16 + 2 + (sectorNo - 1) * 2]); else - return (sector[2 + (sectorNo - 1) * 2] << 8) + (sector[2 + (sectorNo - 1) * 2 + 1]); + mad = (sector[2 + (sectorNo - 1) * 2 + 1] << 8) + (sector[2 + (sectorNo - 1) * 2]); + if (swapmad) { + return BSWAP_16(mad); + } else { + return mad; + } } int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) { - int res = 0; - if (!sector0) - return 1; + if (sector0 == NULL) + return PM3_EINVARG; - uint8_t GPB = sector0[3 * 16 + 9]; + uint8_t GPB = sector0[3 * 16 + 9]; if (verbose) - PrintAndLogEx(NORMAL, "GPB: 0x%02x", GPB); + PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x"), "GPB", GPB); // DA (MAD available) if (!(GPB & 0x80)) { - PrintAndLogEx(ERR, "DA=0! MAD not available."); - return 1; + PrintAndLogEx(ERR, "DA = 0! MAD not available"); + return PM3_ESOFT; + } + + uint8_t mad_ver = GPB & 0x03; + if (verbose) + PrintAndLogEx(SUCCESS, "%14s " _GREEN_("%d"), "MAD version", mad_ver); + + // MAD version + if ((mad_ver != 0x01) && (mad_ver != 0x02)) { + PrintAndLogEx(ERR, "Wrong MAD version " _RED_("0x%02x"), mad_ver); + return PM3_ESOFT; + }; + + if (haveMAD2) + *haveMAD2 = (mad_ver == 2); + + int res = madCRCCheck(sector0, true, 1); + + if (verbose && res == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " (%s)", "CRC8", sector0[16], _GREEN_("ok")); + + if (mad_ver == 2 && sector10) { + int res2 = madCRCCheck(sector10, true, 2); + if (res == PM3_SUCCESS) + res = res2; + + if (verbose && !res2) + PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " (%s)", "CRC8", sector10[0], _GREEN_("ok")); } // MA (multi-application card) if (verbose) { if (GPB & 0x40) - PrintAndLogEx(NORMAL, "Multi application card."); + PrintAndLogEx(SUCCESS, "Multi application card"); else - PrintAndLogEx(NORMAL, "Single application card."); + PrintAndLogEx(SUCCESS, "Single application card"); } - - uint8_t MADVer = GPB & 0x03; - if (verbose) - PrintAndLogEx(NORMAL, "MAD version: %d", MADVer); - - // MAD version - if ((MADVer != 0x01) && (MADVer != 0x02)) { - PrintAndLogEx(ERR, "Wrong MAD version: 0x%02x", MADVer); - return 2; - }; - - if (haveMAD2) - *haveMAD2 = (MADVer == 2); - - res = madCRCCheck(sector0, true, 1); - - if (verbose && !res) - PrintAndLogEx(NORMAL, "CRC8-MAD1 OK."); - - if (MADVer == 2 && sector10) { - int res2 = madCRCCheck(sector10, true, 2); - if (!res) - res = res2; - - if (verbose && !res2) - PrintAndLogEx(NORMAL, "CRC8-MAD2 OK."); - } - return res; } -int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen) { +int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen, bool swapmad) { *madlen = 0; bool haveMAD2 = false; - MADCheck(sector0, sector10, false, &haveMAD2); + int res = MADCheck(sector0, sector10, false, &haveMAD2); + if (res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Not a valid MAD"); + return res; + } for (int i = 1; i < 16; i++) { - mad[*madlen] = madGetAID(sector0, 1, i); + mad[*madlen] = madGetAID(sector0, swapmad, 1, i); (*madlen)++; } @@ -204,55 +240,131 @@ int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen (*madlen)++; for (int i = 1; i < 24; i++) { - mad[*madlen] = madGetAID(sector10, 2, i); + mad[*madlen] = madGetAID(sector10, swapmad, 2, i); (*madlen)++; } } - - return 0; + return PM3_SUCCESS; } +int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose) { + size_t idx = 0; + while (idx < datalen) { + uint8_t len = data[idx] & 0x3f; + uint8_t type = data[idx] >> 6; + idx++; + if (len > 0) { + PrintAndLogEx(INFO, "%14s " _GREEN_("%.*s"), holder_info_type[type], len, &data[idx]); + idx += len; + } else { + break; + } + } + return PM3_SUCCESS; +} -int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { +static int MADInfoByteDecode(uint8_t *sector, bool swapmad, int mad_ver, bool verbose) { + uint8_t info; + if (mad_ver == 1) { + info = sector[16 + 1] & 0x3f; + if (info >= 0xF) { + PrintAndLogEx(WARNING, "Invalid Info byte (MAD1) value " _YELLOW_("0x%02x"), info); + if (verbose) + // I understand the spec in a way that MAD1 InfoByte should not point into MAD2 sectors, @lukaskuzmiak + PrintAndLogEx(WARNING, "MAD1 Info byte points outside of MAD1 sector space (0x%02x), report a bug?", info); + return PM3_ESOFT; + } + } else { + info = sector[1] & 0x3f; + if (info == 0x10 || info >= 0x28) { + PrintAndLogEx(WARNING, "Invalid Info byte (MAD2) value " _YELLOW_("0x%02x"), info); + return PM3_ESOFT; + } + } + + return info; +} + +int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMAD2) { + open_mad_file(&mad_known_aids, verbose); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------ " _CYAN_("MAD v1 details") " -------------"); // check MAD1 only MADCheck(sector, NULL, verbose, haveMAD2); - // info byte - uint8_t InfoByte = sector[16 + 1] & 0x3f; - if (InfoByte) { - PrintAndLogEx(NORMAL, "Card publisher sector: 0x%02x", InfoByte); + int ibs = MADInfoByteDecode(sector, swapmad, 1, verbose); + + if (ibs) { + PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02x"), ibs); } else { - if (verbose) - PrintAndLogEx(NORMAL, "Card publisher sector not present."); + PrintAndLogEx(WARNING, "Card publisher " _RED_("not") " present " _YELLOW_("0x%02x"), ibs); } - if (InfoByte == 0x10 || InfoByte >= 0x28) - PrintAndLogEx(WARNING, "Info byte error"); - PrintAndLogEx(NORMAL, "00 MAD1"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "---------------- " _CYAN_("Listing") " ----------------"); + + PrintAndLogEx(INFO, " 00 MAD v1"); + uint32_t prev_aid = 0xFFFFFFFF; for (int i = 1; i < 16; i++) { - uint16_t AID = madGetAID(sector, 1, i); - PrintAndLogEx(NORMAL, "%02d [%04X] %s", i, AID, GetAIDDescription(AID)); - }; - - return 0; + uint16_t aid = madGetAID(sector, swapmad, 1, i); + if (aid < 6) { + PrintAndLogEx(INFO, (ibs == i) ? _MAGENTA_(" %02d [%04X] (%s)") : " %02d [%04X] (%s)", i, aid, aid_admin[aid]); + } else if (prev_aid == aid) { + PrintAndLogEx(INFO, (ibs == i) ? _MAGENTA_(" %02d [%04X] (continuation)") : " %02d [%04X] (continuation)", i, aid); + } else { + char fmt[30]; + sprintf(fmt, (ibs == i) ? _MAGENTA_(" %02d [%04X]%s") : " %02d [%04X]%s", i, aid, "%s"); + print_aid_description(mad_known_aids, aid, fmt, verbose); + prev_aid = aid; + } + } + close_mad_file(mad_known_aids); + return PM3_SUCCESS; } -int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) { - PrintAndLogEx(NORMAL, "16 MAD2"); - +int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { + open_mad_file(&mad_known_aids, verbose); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------ " _CYAN_("MAD v2 details") " -------------"); + int res = madCRCCheck(sector, true, 2); + if (verbose) { + if (res == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, "CRC8 (%s)", _GREEN_("ok")); + else + PrintAndLogEx(WARNING, "CRC8 (%s)", _RED_("fail")); + } - if (verbose && !res) - PrintAndLogEx(NORMAL, "CRC8-MAD2 OK."); + int ibs = MADInfoByteDecode(sector, swapmad, 2, verbose); + if (ibs) { + PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02x"), ibs); + } else { + PrintAndLogEx(WARNING, "Card publisher " _RED_("not") " present " _YELLOW_("0x%02x"), ibs); + } - uint8_t InfoByte = sector[1] & 0x3f; - PrintAndLogEx(NORMAL, "MAD2 Card publisher sector: 0x%02x", InfoByte); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "---------------- " _CYAN_("Listing") " ----------------"); + + PrintAndLogEx(INFO, " 16 MAD v2"); + uint32_t prev_aid = 0xFFFFFFFF; for (int i = 1; i < 8 + 8 + 7 + 1; i++) { - uint16_t AID = madGetAID(sector, 2, i); - PrintAndLogEx(NORMAL, "%02d [%04X] %s", i + 16, AID, GetAIDDescription(AID)); - }; + uint16_t aid = madGetAID(sector, swapmad, 2, i); + if (aid < 6) { + PrintAndLogEx(INFO, (ibs == i) ? _MAGENTA_(" %02d [%04X] (%s)") : " %02d [%04X] (%s)", i + 16, aid, aid_admin[aid]); + } else if (prev_aid == aid) { + PrintAndLogEx(INFO, (ibs == i) ? _MAGENTA_(" %02d [%04X] (continuation)") : " %02d [%04X] (continuation)", i + 16, aid); + } else { + char fmt[30]; + sprintf(fmt, (ibs == i) ? _MAGENTA_(" %02d [%04X]%s") : " %02d [%04X]%s", i + 16, aid, "%s"); + print_aid_description(mad_known_aids, aid, fmt, verbose); + prev_aid = aid; + } + } + close_mad_file(mad_known_aids); - return 0; + return PM3_SUCCESS; } diff --git a/client/src/mifare/mad.h b/client/src/mifare/mad.h index ce5ed4131..bb1b3800c 100644 --- a/client/src/mifare/mad.h +++ b/client/src/mifare/mad.h @@ -13,15 +13,10 @@ #include "common.h" -typedef struct { - uint16_t AID; - const char *Description; -} madAIDDescr; - int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2); -int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen); -int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2); -int MAD2DecodeAndPrint(uint8_t *sector, bool verbose); - +int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen, bool swapmad); +int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMAD2); +int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose); +int MADCardHolderInfoDecode(uint8_t *data, size_t dataLen, bool verbose); #endif // _MAD_H_ diff --git a/client/src/mifare/mfkey.c b/client/src/mifare/mfkey.c index 7d04762b8..710bba449 100644 --- a/client/src/mifare/mfkey.c +++ b/client/src/mifare/mfkey.c @@ -45,11 +45,14 @@ uint32_t intersection(uint64_t *listA, uint64_t *listB) { // Darkside attack (hf mf mifare) // if successful it will return a list of keys, not just one. uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t par_info, uint64_t ks_info, uint64_t **keys) { - struct Crypto1State *states; + union { + struct Crypto1State *states; + uint64_t *keylist; + } unionstate; + uint32_t i, pos; uint8_t ks3x[8], par[8][8]; uint64_t key_recovered; - uint64_t *keylist; // Reset the last three significant bits of the reader nonce nr &= 0xFFFFFF1F; @@ -68,23 +71,21 @@ uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t par[7 - pos][7] = (bt >> 7) & 1; } - states = lfsr_common_prefix(nr, ar, ks3x, par, (par_info == 0)); + unionstate.states = lfsr_common_prefix(nr, ar, ks3x, par, (par_info == 0)); - if (!states) { + if (!unionstate.states) { *keys = NULL; return 0; } - keylist = (uint64_t *)states; - - for (i = 0; keylist[i]; i++) { - lfsr_rollback_word(states + i, uid ^ nt, 0); - crypto1_get_lfsr(states + i, &key_recovered); - keylist[i] = key_recovered; + for (i = 0; unionstate.keylist[i]; i++) { + lfsr_rollback_word(unionstate.states + i, uid ^ nt, 0); + crypto1_get_lfsr(unionstate.states + i, &key_recovered); + unionstate.keylist[i] = key_recovered; } - keylist[i] = -1; + unionstate.keylist[i] = -1; - *keys = keylist; + *keys = unionstate.keylist; return i; } diff --git a/client/src/mifare/mifare4.c b/client/src/mifare/mifare4.c index 09f10d321..55961b15b 100644 --- a/client/src/mifare/mifare4.c +++ b/client/src/mifare/mifare4.c @@ -90,42 +90,42 @@ const char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data) { return StaticNone; } /* -static int CalculateEncIVCommand(mf4Session_t *session, uint8_t *iv, bool verbose) { - memcpy(&iv[0], &session->TI, 4); - memcpy(&iv[4], &session->R_Ctr, 2); - memcpy(&iv[6], &session->W_Ctr, 2); - memcpy(&iv[8], &session->R_Ctr, 2); - memcpy(&iv[10], &session->W_Ctr, 2); - memcpy(&iv[12], &session->R_Ctr, 2); - memcpy(&iv[14], &session->W_Ctr, 2); +static int CalculateEncIVCommand(mf4Session_t *mf4session, uint8_t *iv, bool verbose) { + memcpy(&iv[0], &mf4session->TI, 4); + memcpy(&iv[4], &mf4session->R_Ctr, 2); + memcpy(&iv[6], &mf4session->W_Ctr, 2); + memcpy(&iv[8], &mf4session->R_Ctr, 2); + memcpy(&iv[10], &mf4session->W_Ctr, 2); + memcpy(&iv[12], &mf4session->R_Ctr, 2); + memcpy(&iv[14], &mf4session->W_Ctr, 2); return 0; } -static int CalculateEncIVResponse(mf4Session *session, uint8_t *iv, bool verbose) { - memcpy(&iv[0], &session->R_Ctr, 2); - memcpy(&iv[2], &session->W_Ctr, 2); - memcpy(&iv[4], &session->R_Ctr, 2); - memcpy(&iv[6], &session->W_Ctr, 2); - memcpy(&iv[8], &session->R_Ctr, 2); - memcpy(&iv[10], &session->W_Ctr, 2); - memcpy(&iv[12], &session->TI, 4); +static int CalculateEncIVResponse(mf4Session *mf4session, uint8_t *iv, bool verbose) { + memcpy(&iv[0], &mf4session->R_Ctr, 2); + memcpy(&iv[2], &mf4session->W_Ctr, 2); + memcpy(&iv[4], &mf4session->R_Ctr, 2); + memcpy(&iv[6], &mf4session->W_Ctr, 2); + memcpy(&iv[8], &mf4session->R_Ctr, 2); + memcpy(&iv[10], &mf4session->W_Ctr, 2); + memcpy(&iv[12], &mf4session->TI, 4); return 0; } */ -int CalculateMAC(mf4Session_t *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose) { - if (!session || !session->Authenticated || !mac || !data || !datalen) +int CalculateMAC(mf4Session_t *mf4session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose) { + if (!mf4session || !mf4session->Authenticated || !mac || !data || !datalen) return 1; memset(mac, 0x00, 8); - uint16_t ctr = session->R_Ctr; + uint16_t ctr = mf4session->R_Ctr; switch (mtype) { case mtypWriteCmd: case mtypWriteResp: - ctr = session->W_Ctr; + ctr = mf4session->W_Ctr; break; case mtypReadCmd: case mtypReadResp: @@ -134,7 +134,7 @@ int CalculateMAC(mf4Session_t *session, MACType_t mtype, uint8_t blockNum, uint8 uint8_t macdata[2049] = {data[0], (ctr & 0xFF), (ctr >> 8), 0}; int macdatalen = datalen; - memcpy(&macdata[3], session->TI, 4); + memcpy(&macdata[3], mf4session->TI, 4); switch (mtype) { case mtypReadCmd: @@ -160,10 +160,10 @@ int CalculateMAC(mf4Session_t *session, MACType_t mtype, uint8_t blockNum, uint8 if (verbose) PrintAndLogEx(NORMAL, "MAC data[%d]: %s", macdatalen, sprint_hex(macdata, macdatalen)); - return aes_cmac8(NULL, session->Kmac, macdata, mac, macdatalen); + return aes_cmac8(NULL, mf4session->Kmac, macdata, mac, macdatalen); } -int MifareAuth4(mf4Session_t *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { +int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { uint8_t data[257] = {0}; int datalen = 0; @@ -173,8 +173,8 @@ int MifareAuth4(mf4Session_t *session, uint8_t *keyn, uint8_t *key, bool activat if (silentMode) verbose = false; - if (session) - session->Authenticated = false; + if (mf4session) + mf4session->Authenticated = false; uint8_t cmd1[] = {0x70, keyn[1], keyn[0], 0x00}; int res = ExchangeRAW14a(cmd1, sizeof(cmd1), activateField, true, data, sizeof(data), &datalen, silentMode); @@ -284,19 +284,19 @@ int MifareAuth4(mf4Session_t *session, uint8_t *keyn, uint8_t *key, bool activat if (verbose) PrintAndLogEx(NORMAL, ""); - if (session) { - session->Authenticated = true; - session->R_Ctr = 0; - session->W_Ctr = 0; - session->KeyNum = keyn[1] + (keyn[0] << 8); - memmove(session->RndA, RndA, 16); - memmove(session->RndB, RndB, 16); - memmove(session->Key, key, 16); - memmove(session->TI, raw, 4); - memmove(session->PICCap2, &raw[20], 6); - memmove(session->PCDCap2, &raw[26], 6); - memmove(session->Kenc, kenc, 16); - memmove(session->Kmac, kmac, 16); + if (mf4session) { + mf4session->Authenticated = true; + mf4session->R_Ctr = 0; + mf4session->W_Ctr = 0; + mf4session->KeyNum = keyn[1] + (keyn[0] << 8); + memmove(mf4session->RndA, RndA, 16); + memmove(mf4session->RndB, RndB, 16); + memmove(mf4session->Key, key, 16); + memmove(mf4session->TI, raw, 4); + memmove(mf4session->PICCap2, &raw[20], 6); + memmove(mf4session->PCDCap2, &raw[26], 6); + memmove(mf4session->Kenc, kenc, 16); + memmove(mf4session->Kmac, kmac, 16); } if (verbose) @@ -330,39 +330,39 @@ int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int return intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); } -int MFPReadBlock(mf4Session_t *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { +int MFPReadBlock(mf4Session_t *mf4session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { uint8_t rcmd[4 + 8] = {(plain ? (0x37) : (0x33)), blockNum, 0x00, blockCount}; - if (!plain && session) - CalculateMAC(session, mtypReadCmd, blockNum, blockCount, rcmd, 4, &rcmd[4], VerboseMode); + if (!plain && mf4session) + CalculateMAC(mf4session, mtypReadCmd, blockNum, blockCount, rcmd, 4, &rcmd[4], VerboseMode); int res = intExchangeRAW14aPlus(rcmd, plain ? 4 : sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); if (res) return res; - if (session) - session->R_Ctr++; + if (mf4session) + mf4session->R_Ctr++; - if (session && mac && *dataoutlen > 11) - CalculateMAC(session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, VerboseMode); + if (mf4session && mac && *dataoutlen > 11) + CalculateMAC(mf4session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, VerboseMode); return 0; } -int MFPWriteBlock(mf4Session_t *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { +int MFPWriteBlock(mf4Session_t *mf4session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { uint8_t rcmd[1 + 2 + 16 + 8] = {0xA3, blockNum, 0x00}; memmove(&rcmd[3], data, 16); - if (session) - CalculateMAC(session, mtypWriteCmd, blockNum, 1, rcmd, 19, &rcmd[19], VerboseMode); + if (mf4session) + CalculateMAC(mf4session, mtypWriteCmd, blockNum, 1, rcmd, 19, &rcmd[19], VerboseMode); int res = intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); if (res) return res; - if (session) - session->W_Ctr++; + if (mf4session) + mf4session->W_Ctr++; - if (session && mac && *dataoutlen > 3) - CalculateMAC(session, mtypWriteResp, blockNum, 1, dataout, *dataoutlen, mac, VerboseMode); + if (mf4session && mac && *dataoutlen > 3) + CalculateMAC(mf4session, mtypWriteResp, blockNum, 1, dataout, *dataoutlen, mac, VerboseMode); return 0; } diff --git a/client/src/mifare/mifare4.h b/client/src/mifare/mifare4.h index 0c3e08458..994fb16a5 100644 --- a/client/src/mifare/mifare4.h +++ b/client/src/mifare/mifare4.h @@ -50,13 +50,13 @@ typedef struct { void mfpSetVerboseMode(bool verbose); const char *mfpGetErrorDescription(uint8_t errorCode); -int CalculateMAC(mf4Session_t *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); -int MifareAuth4(mf4Session_t *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); +int CalculateMAC(mf4Session_t *mf4session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); +int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); -int MFPReadBlock(mf4Session_t *session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); -int MFPWriteBlock(mf4Session_t *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +int MFPReadBlock(mf4Session_t *mf4session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); +int MFPWriteBlock(mf4Session_t *mf4session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose); int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 8b57604f9..8e15cb509 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -378,7 +378,7 @@ __attribute__((force_align_arg_pointer)) StateList_t *statelist = arg; statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt_enc ^ statelist->uid); - for (p1 = statelist->head.slhead; * (uint64_t *)p1 != 0; p1++) {}; + for (p1 = statelist->head.slhead; p1->odd | p1->even; p1++) {}; statelist->len = p1 - statelist->head.slhead; statelist->tail.sltail = --p1; @@ -492,8 +492,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, } } - *(uint64_t *)p3 = -1; - *(uint64_t *)p4 = -1; + p3->odd = -1; + p3->even = -1; + p4->odd = -1; + p4->even = -1; statelists[0].len = p3 - statelists[0].head.slhead; statelists[1].len = p4 - statelists[1].head.slhead; statelists[0].tail.sltail = --p3; @@ -536,10 +538,10 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, free(statelists[1].head.slhead); num_to_bytes(key64, 6, resultKey); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") " ]", + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]", package->block, package->keytype ? 'B' : 'A', - sprint_hex_inrow(resultKey, 6) + sprint_hex(resultKey, 6) ); return -5; } @@ -637,7 +639,8 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl } } - *(uint64_t *)p3 = -1; + p3->odd = -1; + p3->even = -1; statelists[0].len = p3 - statelists[0].head.slhead; statelists[0].tail.sltail = --p3; @@ -711,10 +714,10 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl num_to_bytes(key64, 6, resultKey); - PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [ " _YELLOW_("%s") " ]", + PrintAndLogEx(SUCCESS, "target block:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]", package->block, package->keytype ? 'B' : 'A', - sprint_hex_inrow(resultKey, 6) + sprint_hex(resultKey, 6) ); return PM3_SUCCESS; } else if (res == PM3_ETIMEOUT || res == PM3_EOPABORTED) { @@ -745,7 +748,7 @@ out: int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, key, 6); + SendCommandMIX(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, key, 6); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -880,8 +883,11 @@ int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) { int res; for (int blockNo = 0; blockNo < 4 * 16; blockNo++) { for (int retry = 0; retry < 3; retry++) { + + PrintAndLogEx(INPLACE, "wipe block %d", blockNo); + if (blockNo == 0) { - res = mfCSetBlock(blockNo, block0, NULL, params); + res = mfCSetBlock(blockNo, block0, NULL, (params | MAGIC_WIPE)); } else { if (mfIsSectorTrailer(blockNo)) res = mfCSetBlock(blockNo, blockK, NULL, params); @@ -891,23 +897,24 @@ int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) { if (res == PM3_SUCCESS) break; - PrintAndLogEx(WARNING, "Retry block[%d]...", blockNo); + + PrintAndLogEx(WARNING, "retry block %d ...", blockNo); } if (res) { - PrintAndLogEx(ERR, "Error setting block[%d]: %d", blockNo, res); + PrintAndLogEx(ERR, "error setting block %d (%d)", blockNo, res); return res; } } DropField(); - + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { clearCommandBuffer(); - SendCommandOLD(CMD_HF_MIFARE_CSETBL, params, blockNo, 0, data, 16); + SendCommandMIX(CMD_HF_MIFARE_CSETBL, params, blockNo, 0, data, 16); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -941,127 +948,9 @@ int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { // SNIFFER // [iceman] so many global variables.... -// constants -static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00}; - // variables -char logHexFileName[FILE_PATH_SIZE] = {0x00}; -static uint8_t traceCard[4096] = {0x00}; -static char traceFileName[FILE_PATH_SIZE] = {0x00}; -static int traceState = TRACE_IDLE; -static uint8_t traceCurBlock = 0; -static uint8_t traceCurKey = 0; - -struct Crypto1State *traceCrypto1 = NULL; -struct Crypto1State *revstate = NULL; - uint32_t cuid = 0; // uid part used for crypto1. -int isTraceCardEmpty(void) { - return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0)); -} - -int isBlockEmpty(int blockN) { - for (int i = 0; i < 16; i++) - if (traceCard[blockN * 16 + i] != 0) return 0; - - return 1; -} - -int isBlockTrailer(int blockN) { - return ((blockN & 0x03) == 0x03); -} - -int loadTraceCard(uint8_t *tuid, uint8_t uidlen) { - FILE *f; - char buf[64] = {0x00}; - uint8_t buf8[64] = {0x00}; - int i, blockNum; - uint32_t tmp; - - if (!isTraceCardEmpty()) - saveTraceCard(); - - memset(traceCard, 0x00, 4096); - memcpy(traceCard, tuid, uidlen); - - FillFileNameByUID(traceFileName, tuid, ".eml", uidlen); - - f = fopen(traceFileName, "r"); - if (!f) return PM3_EFILE; - - blockNum = 0; - - while (!feof(f)) { - - memset(buf, 0, sizeof(buf)); - if (fgets(buf, sizeof(buf), f) == NULL) { - PrintAndLogEx(FAILED, "No trace file found or reading error."); - fclose(f); - return PM3_EFILE; - } - - if (strlen(buf) < 32) { - if (feof(f)) break; - PrintAndLogEx(FAILED, "File content error. Block data must include 32 HEX symbols"); - fclose(f); - return PM3_EFILE; - } - for (i = 0; i < 32; i += 2) { - sscanf(&buf[i], "%02X", &tmp); - buf8[i / 2] = tmp & 0xFF; - } - - memcpy(traceCard + blockNum * 16, buf8, 16); - - blockNum++; - } - fclose(f); - return PM3_SUCCESS; -} - -int saveTraceCard(void) { - - if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return PM3_ESOFT; - - FILE *f; - f = fopen(traceFileName, "w+"); - if (!f) return PM3_EFILE; - - // given 4096 tracecard size, these loop will only match a 1024, 1kb card memory - // 4086/16 == 256blocks. - for (uint16_t i = 0; i < 256; i++) { // blocks - for (uint8_t j = 0; j < 16; j++) // bytes - fprintf(f, "%02X", *(traceCard + i * 16 + j)); - - // no extra line in the end - if (i < 255) - fprintf(f, "\n"); - } - fflush(f); - fclose(f); - return PM3_SUCCESS; -} -// -int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) { - - if (traceCrypto1) - crypto1_destroy(traceCrypto1); - - traceCrypto1 = NULL; - - if (wantSaveToEmlFile) - loadTraceCard(tuid, uidlen); - - traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3]; - traceCard[5] = sak; - memcpy(&traceCard[6], atqa, 2); - traceCurBlock = 0; - cuid = bytes_to_num(tuid + (uidlen - 4), 4); - traceState = TRACE_IDLE; - return PM3_SUCCESS; -} - void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted) { if (len != 1) { for (int i = 0; i < len; i++) @@ -1076,180 +965,6 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i } } -int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { - if (traceState == TRACE_ERROR) - return PM3_ESOFT; - - if (len > 255) { - traceState = TRACE_ERROR; - return PM3_ESOFT; - } - - uint8_t data[255]; - memset(data, 0x00, sizeof(data)); - - memcpy(data, data_src, len); - - if ((traceCrypto1) && ((traceState == TRACE_IDLE) || (traceState > TRACE_AUTH_OK))) { - mf_crypto1_decrypt(traceCrypto1, data, len, 0); - PrintAndLogEx(NORMAL, "DEC| %s", sprint_hex(data, len)); - AddLogHex(logHexFileName, "DEC| ", data, len); - } - - switch (traceState) { - case TRACE_IDLE: - // check packet crc16! - if ((len >= 4) && (!check_crc(CRC_14443_A, data, len))) { - PrintAndLogEx(NORMAL, "DEC| CRC ERROR!!!"); - AddLogLine(logHexFileName, "DEC| ", "CRC ERROR!!!"); - traceState = TRACE_ERROR; // do not decrypt the next commands - return PM3_ESOFT; - } - - // AUTHENTICATION - if ((len == 4) && ((data[0] == MIFARE_AUTH_KEYA) || (data[0] == MIFARE_AUTH_KEYB))) { - traceState = TRACE_AUTH1; - traceCurBlock = data[1]; - traceCurKey = data[0] == 60 ? 1 : 0; - return PM3_SUCCESS; - } - - // READ - if ((len == 4) && ((data[0] == ISO14443A_CMD_READBLOCK))) { - traceState = TRACE_READ_DATA; - traceCurBlock = data[1]; - return PM3_SUCCESS; - } - - // WRITE - if ((len == 4) && ((data[0] == ISO14443A_CMD_WRITEBLOCK))) { - traceState = TRACE_WRITE_OK; - traceCurBlock = data[1]; - return PM3_SUCCESS; - } - - // HALT - if ((len == 4) && ((data[0] == ISO14443A_CMD_HALT) && (data[1] == 0x00))) { - traceState = TRACE_ERROR; // do not decrypt the next commands - return PM3_SUCCESS; - } - return PM3_SUCCESS; - - case TRACE_READ_DATA: - if (len == 18) { - traceState = TRACE_IDLE; - - if (isBlockTrailer(traceCurBlock)) { - memcpy(traceCard + traceCurBlock * 16 + 6, data + 6, 4); - } else { - memcpy(traceCard + traceCurBlock * 16, data, 16); - } - if (wantSaveToEmlFile) saveTraceCard(); - return PM3_SUCCESS; - } else { - traceState = TRACE_ERROR; - return PM3_ESOFT; - } - break; - case TRACE_WRITE_OK: - if ((len == 1) && (data[0] == 0x0a)) { - traceState = TRACE_WRITE_DATA; - return PM3_SUCCESS; - } else { - traceState = TRACE_ERROR; - return PM3_ESOFT; - } - break; - case TRACE_WRITE_DATA: - if (len == 18) { - traceState = TRACE_IDLE; - memcpy(traceCard + traceCurBlock * 16, data, 16); - if (wantSaveToEmlFile) saveTraceCard(); - return PM3_SUCCESS; - } else { - traceState = TRACE_ERROR; - return PM3_ESOFT; - } - break; - case TRACE_AUTH1: - if (len == 4) { - traceState = TRACE_AUTH2; - //nt = bytes_to_num(data, 4); - return PM3_SUCCESS; - } else { - traceState = TRACE_ERROR; - return PM3_ESOFT; - } - break; - case TRACE_AUTH2: - if (len == 8) { - traceState = TRACE_AUTH_OK; - //nr_enc = bytes_to_num(data, 4); - //ar_enc = bytes_to_num(data + 4, 4); - return PM3_SUCCESS; - } else { - traceState = TRACE_ERROR; - return PM3_ESOFT; - } - break; - case TRACE_AUTH_OK: - if (len == 4) { - uint32_t nt = 0; // tag challenge - uint32_t nr_enc = 0; // encrypted reader challenge - uint32_t ar_enc = 0; // encrypted reader response - uint32_t at_enc = 0; // encrypted tag response - traceState = TRACE_IDLE; - // encrypted tag response - at_enc = bytes_to_num(data, 4); - - // mfkey64 recover key. - uint64_t key = 0; - uint32_t ks2 = ar_enc ^ prng_successor(nt, 64); - uint32_t ks3 = at_enc ^ prng_successor(nt, 96); - revstate = lfsr_recovery64(ks2, ks3); - lfsr_rollback_word(revstate, 0, 0); - lfsr_rollback_word(revstate, 0, 0); - lfsr_rollback_word(revstate, nr_enc, 1); - lfsr_rollback_word(revstate, cuid ^ nt, 0); - crypto1_get_lfsr(revstate, &key); - PrintAndLogEx(SUCCESS, "found Key: [%012" PRIx64 "]", key); - - //if ( tryMfk64(cuid, nt, nr_enc, ar_enc, at_enc, &key) ) - AddLogUint64(logHexFileName, "Found Key: ", key); - - int blockShift = ((traceCurBlock & 0xFC) + 3) * 16; - if (isBlockEmpty((traceCurBlock & 0xFC) + 3)) - memcpy(traceCard + blockShift + 6, trailerAccessBytes, 4); - - // keytype A/B - if (traceCurKey) - num_to_bytes(key, 6, traceCard + blockShift + 10); - else - num_to_bytes(key, 6, traceCard + blockShift); - - if (wantSaveToEmlFile) - saveTraceCard(); - - if (traceCrypto1) - crypto1_destroy(traceCrypto1); - - // set cryptosystem state - traceCrypto1 = lfsr_recovery64(ks2, ks3); - - } else { - PrintAndLogEx(NORMAL, "[!] nested key recovery not implemented!\n"); - //at_enc = bytes_to_num(data, 4); - crypto1_destroy(traceCrypto1); - traceState = TRACE_ERROR; - } - break; - default: - traceState = TRACE_ERROR; - return PM3_ESOFT; - } - return PM3_SUCCESS; -} - int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len) { PrintAndLogEx(SUCCESS, "\nencrypted data: [%s]", sprint_hex(data, len)); struct Crypto1State *s; @@ -1406,7 +1121,7 @@ int detect_classic_static_nonce(void) { } /* try to see if card responses to "chinese magic backdoor" commands. */ -void detect_classic_magic(void) { +int detect_classic_magic(void) { uint8_t isGeneration = 0; PacketResponseNG resp; @@ -1433,4 +1148,5 @@ void detect_classic_magic(void) { default: break; } + return isGeneration; } diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 6f179c573..f8205732f 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -54,7 +54,6 @@ typedef struct { //uint8_t foundKey[2]; } icesector_t; -extern char logHexFileName[FILE_PATH_SIZE]; #define KEYS_IN_BLOCK ((PM3_CMD_DATA_SIZE - 4) / 6) #define KEYBLOCK_SIZE (KEYS_IN_BLOCK * 6) #define CANDIDATE_SIZE (0xFFFF * 6) @@ -81,19 +80,11 @@ int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak); int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params); int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params); -int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile); -int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile); - -int isTraceCardEmpty(void); -int isBlockEmpty(int blockN); -int isBlockTrailer(int blockN); -int loadTraceCard(uint8_t *tuid, uint8_t uidlen); -int saveTraceCard(void); int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len); int detect_classic_prng(void); int detect_classic_nackbug(bool verbose); -void detect_classic_magic(void); +int detect_classic_magic(void); int detect_classic_static_nonce(void); void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted); #endif diff --git a/client/src/mifare/ndef.c b/client/src/mifare/ndef.c index 45ad2e081..2aab01634 100644 --- a/client/src/mifare/ndef.c +++ b/client/src/mifare/ndef.c @@ -127,6 +127,7 @@ static int ndefDecodeHeader(uint8_t *data, size_t datalen, NDEFHeader_t *header) if (header->IDLenPresent) { header->IDLen = (header->ShortRecordBit ? (data[3]) : (data[6])); + header->ID = data + header->len + header->TypeLen; } else { header->IDLen = 0; } @@ -136,7 +137,7 @@ static int ndefDecodeHeader(uint8_t *data, size_t datalen, NDEFHeader_t *header) header->RecLen = header->len + header->TypeLen + header->PayloadLen + header->IDLen; if (header->RecLen > datalen) - return 3; + return PM3_ESOFT; return PM3_SUCCESS; } @@ -436,7 +437,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { size_t indx = 0; PrintAndLogEx(INFO, ""); - PrintAndLogEx(INFO, "NDEF parsing"); + PrintAndLogEx(INFO, "--- " _CYAN_("NDEF parsing") " ----------------"); while (indx < ndefLen) { PrintAndLogEx(INFO, "-----------------------------------------------------"); diff --git a/client/src/pm3_binlib.c b/client/src/pm3_binlib.c index d694ee3b0..56d281636 100644 --- a/client/src/pm3_binlib.c +++ b/client/src/pm3_binlib.c @@ -203,7 +203,8 @@ static int l_unpack(lua_State *L) { /** unpack(f,s, [init]) */ #define PACKNUMBER(OP,T) \ case OP: \ { \ - T a=(T)luaL_checknumber(L,i++); \ + lua_Number n = luaL_checknumber(L,i++); \ + T a=(T)n; \ doswap(swap,&a,sizeof(a)); \ luaL_addlstring(&b,(char*)&a,sizeof(a)); \ break; \ @@ -318,6 +319,7 @@ static const luaL_Reg binlib[] = { {NULL, NULL} }; +LUALIB_API int luaopen_binlib(lua_State *L); LUALIB_API int luaopen_binlib(lua_State *L) { luaL_newlib(L, binlib); return 1; diff --git a/client/src/pm3_bitlib.c b/client/src/pm3_bitlib.c index 15fdbd5d0..064c0f3c9 100644 --- a/client/src/pm3_bitlib.c +++ b/client/src/pm3_bitlib.c @@ -92,16 +92,18 @@ typedef size_t lua_UInteger; #define LOGICAL_SHIFT(name, op) \ static int bit_ ## name(lua_State *L) { \ lua_Number f; \ + lua_Number n = luaL_checknumber(L, 2); \ lua_pushinteger(L, BIT_TRUNCATE(BIT_TRUNCATE((lua_UInteger)TOBIT(L, 1, f)) op \ - (unsigned)luaL_checknumber(L, 2))); \ + (unsigned)n)); \ return 1; \ } #define ARITHMETIC_SHIFT(name, op) \ static int bit_ ## name(lua_State *L) { \ lua_Number f; \ + lua_Number n = luaL_checknumber(L, 2); \ lua_pushinteger(L, BIT_TRUNCATE((lua_Integer)TOBIT(L, 1, f) op \ - (unsigned)luaL_checknumber(L, 2))); \ + (unsigned)n)); \ return 1; \ } @@ -126,6 +128,7 @@ static const struct luaL_Reg bitlib[] = { {NULL, NULL} }; +LUALIB_API int luaopen_bit(lua_State *L); LUALIB_API int luaopen_bit(lua_State *L) { luaL_newlib(L, bitlib); //luaL_register(L, "bit", bitlib); diff --git a/client/src/polarssl_config.h b/client/src/polarssl_config.h deleted file mode 100644 index 5bd88fc07..000000000 --- a/client/src/polarssl_config.h +++ /dev/null @@ -1,2179 +0,0 @@ -/** - * \file config.h - * - * \brief Configuration options (set of defines) - * - * Copyright (C) 2006-2014, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * 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 2 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - */ -#ifndef POLARSSL_CONFIG_H -#define POLARSSL_CONFIG_H - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def POLARSSL_HAVE_INT8 - * - * The system uses 8-bit wide native integers. - * - * Uncomment if native integers are 8-bit wide. - */ -//#define POLARSSL_HAVE_INT8 - -/** - * \def POLARSSL_HAVE_INT16 - * - * The system uses 16-bit wide native integers. - * - * Uncomment if native integers are 16-bit wide. - */ -//#define POLARSSL_HAVE_INT16 - -/** - * \def POLARSSL_HAVE_LONGLONG - * - * The compiler supports the 'long long' type. - * (Only used on 32-bit platforms) - */ -#define POLARSSL_HAVE_LONGLONG - -/** - * \def POLARSSL_HAVE_ASM - * - * The compiler has support for asm(). - * - * Requires support for asm() in compiler. - * - * Used in: - * library/timing.c - * library/padlock.c - * include/polarssl/bn_mul.h - * - * Comment to disable the use of assembly code. - */ -#define POLARSSL_HAVE_ASM - -/** - * \def POLARSSL_HAVE_SSE2 - * - * CPU supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - */ -//#define POLARSSL_HAVE_SSE2 - -/** - * \def POLARSSL_HAVE_TIME - * - * System has time.h and time() / localtime() / gettimeofday(). - * - * Comment if your system does not support time functions - */ -#define POLARSSL_HAVE_TIME - -/** - * \def POLARSSL_HAVE_IPV6 - * - * System supports the basic socket interface for IPv6 (RFC 3493), - * specifically getaddrinfo(), freeaddrinfo() and struct sockaddr_storage. - * - * Note: on Windows/MingW, XP or higher is required. - * - * Comment if your system does not support the IPv6 socket interface - */ -#define POLARSSL_HAVE_IPV6 - -/** - * \def POLARSSL_PLATFORM_MEMORY - * - * Enable the memory allocation layer. - * - * By default PolarSSL uses the system-provided malloc() and free(). - * This allows different allocators (self-implemented or provided) to be - * provided to the platform abstraction layer. - * - * Enabling POLARSSL_PLATFORM_MEMORY will provide "platform_set_malloc_free()" - * to allow you to set an alternative malloc() and free() function pointer. - * - * Requires: POLARSSL_PLATFORM_C - * - * Enable this layer to allow use of alternative memory allocators. - */ -//#define POLARSSL_PLATFORM_MEMORY - -/** - * \def POLARSSL_PLATFORM_NO_STD_FUNCTIONS - * - * Do not assign standard functions in the platform layer (e.g. malloc() to - * POLARSSL_PLATFORM_STD_MALLOC and printf() to POLARSSL_PLATFORM_STD_PRINTF) - * - * This makes sure there are no linking errors on platforms that do not support - * these functions. You will HAVE to provide alternatives, either at runtime - * via the platform_set_xxx() functions or at compile time by setting - * the POLARSSL_PLATFORM_STD_XXX defines. - * - * Requires: POLARSSL_PLATFORM_C - * - * Uncomment to prevent default assignment of standard functions in the - * platform layer. - */ -//#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS - -/** - * \def POLARSSL_PLATFORM_XXX_ALT - * - * Uncomment a macro to let PolarSSL support the function in the platform - * abstraction layer. - * - * Example: In case you uncomment POLARSSL_PLATFORM_PRINTF_ALT, PolarSSL will - * provide a function "platform_set_printf()" that allows you to set an - * alternative printf function pointer. - * - * All these define require POLARSSL_PLATFORM_C to be defined! - * - * Uncomment a macro to enable alternate implementation of specific base - * platform function - */ -//#define POLARSSL_PLATFORM_PRINTF_ALT -//#define POLARSSL_PLATFORM_FPRINTF_ALT -/* \} name SECTION: System support */ - -/** - * \name SECTION: PolarSSL feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def POLARSSL_TIMING_ALT - * - * Uncomment to provide your own alternate implementation for hardclock(), - * get_timer(), set_alarm() and m_sleep(). - * - * Only works if you have POLARSSL_TIMING_C enabled. - * - * You will need to provide a header "timing_alt.h" and an implementation at - * compile time. - */ -//#define POLARSSL_TIMING_ALT - -/** - * \def POLARSSL_XXX_ALT - * - * Uncomment a macro to let PolarSSL use your alternate core implementation of - * a symmetric or hash algorithm (e.g. platform specific assembly optimized - * implementations). Keep in mind that the function prototypes should remain - * the same. - * - * Example: In case you uncomment POLARSSL_AES_ALT, PolarSSL will no longer - * provide the "struct aes_context" definition and omit the base function - * declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation for core algorithm - * functions - */ -//#define POLARSSL_AES_ALT -//#define POLARSSL_ARC4_ALT -//#define POLARSSL_BLOWFISH_ALT -//#define POLARSSL_CAMELLIA_ALT -//#define POLARSSL_DES_ALT -//#define POLARSSL_XTEA_ALT -//#define POLARSSL_MD2_ALT -//#define POLARSSL_MD4_ALT -//#define POLARSSL_MD5_ALT -//#define POLARSSL_RIPEMD160_ALT -//#define POLARSSL_SHA1_ALT -//#define POLARSSL_SHA256_ALT -//#define POLARSSL_SHA512_ALT - -/** - * \def POLARSSL_AES_ROM_TABLES - * - * Store the AES tables in ROM. - * - * Uncomment this macro to store the AES tables in ROM. - * - */ -//#define POLARSSL_AES_ROM_TABLES - -/** - * \def POLARSSL_CIPHER_MODE_CBC - * - * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. - */ -#define POLARSSL_CIPHER_MODE_CBC - -/** - * \def POLARSSL_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -#define POLARSSL_CIPHER_MODE_CFB - -/** - * \def POLARSSL_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define POLARSSL_CIPHER_MODE_CTR - -/** - * \def POLARSSL_CIPHER_NULL_CIPHER - * - * Enable NULL cipher. - * Warning: Only do so when you know what you are doing. This allows for - * encryption or channels without any security! - * - * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable - * the following ciphersuites: - * TLS_ECDH_ECDSA_WITH_NULL_SHA - * TLS_ECDH_RSA_WITH_NULL_SHA - * TLS_ECDHE_ECDSA_WITH_NULL_SHA - * TLS_ECDHE_RSA_WITH_NULL_SHA - * TLS_ECDHE_PSK_WITH_NULL_SHA384 - * TLS_ECDHE_PSK_WITH_NULL_SHA256 - * TLS_ECDHE_PSK_WITH_NULL_SHA - * TLS_DHE_PSK_WITH_NULL_SHA384 - * TLS_DHE_PSK_WITH_NULL_SHA256 - * TLS_DHE_PSK_WITH_NULL_SHA - * TLS_RSA_WITH_NULL_SHA256 - * TLS_RSA_WITH_NULL_SHA - * TLS_RSA_WITH_NULL_MD5 - * TLS_RSA_PSK_WITH_NULL_SHA384 - * TLS_RSA_PSK_WITH_NULL_SHA256 - * TLS_RSA_PSK_WITH_NULL_SHA - * TLS_PSK_WITH_NULL_SHA384 - * TLS_PSK_WITH_NULL_SHA256 - * TLS_PSK_WITH_NULL_SHA - * - * Uncomment this macro to enable the NULL cipher and ciphersuites - */ -//#define POLARSSL_CIPHER_NULL_CIPHER - -/** - * \def POLARSSL_CIPHER_PADDING_XXX - * - * Uncomment or comment macros to add support for specific padding modes - * in the cipher layer with cipher modes that support padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#define POLARSSL_CIPHER_PADDING_PKCS7 -#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS -#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN -#define POLARSSL_CIPHER_PADDING_ZEROS - -/** - * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES - * - * Enable weak ciphersuites in SSL / TLS. - * Warning: Only do so when you know what you are doing. This allows for - * channels with virtually no security at all! - * - * This enables the following ciphersuites: - * TLS_RSA_WITH_DES_CBC_SHA - * TLS_DHE_RSA_WITH_DES_CBC_SHA - * - * Uncomment this macro to enable weak ciphersuites - */ -//#define POLARSSL_ENABLE_WEAK_CIPHERSUITES - -/** - * \def POLARSSL_REMOVE_ARC4_CIPHERSUITES - * - * Remove RC4 ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on RC4 from the default list as - * returned by ssl_list_ciphersuites(). However, it is still possible to - * enable (some of) them with ssl_set_ciphersuites() by including them - * explicitly. - * - * Uncomment this macro to remove RC4 ciphersuites by default. - */ -//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES - -/** - * \def POLARSSL_ECP_XXXX_ENABLED - * - * Enables specific curves within the Elliptic Curve module. - * By default all supported curves are enabled. - * - * Comment macros to disable the curve and functions for it - */ -#define POLARSSL_ECP_DP_SECP192R1_ENABLED -#define POLARSSL_ECP_DP_SECP224R1_ENABLED -#define POLARSSL_ECP_DP_SECP256R1_ENABLED -#define POLARSSL_ECP_DP_SECP384R1_ENABLED -#define POLARSSL_ECP_DP_SECP521R1_ENABLED -#define POLARSSL_ECP_DP_SECP192K1_ENABLED -#define POLARSSL_ECP_DP_SECP224K1_ENABLED -#define POLARSSL_ECP_DP_SECP256K1_ENABLED -#define POLARSSL_ECP_DP_BP256R1_ENABLED -#define POLARSSL_ECP_DP_BP384R1_ENABLED -#define POLARSSL_ECP_DP_BP512R1_ENABLED -//#define POLARSSL_ECP_DP_M221_ENABLED // Not implemented yet! -#define POLARSSL_ECP_DP_M255_ENABLED -//#define POLARSSL_ECP_DP_M383_ENABLED // Not implemented yet! -//#define POLARSSL_ECP_DP_M511_ENABLED // Not implemented yet! - -/** - * \def POLARSSL_ECP_NIST_OPTIM - * - * Enable specific 'modulo p' routines for each NIST prime. - * Depending on the prime and architecture, makes operations 4 to 8 times - * faster on the corresponding curve. - * - * Comment this macro to disable NIST curves optimisation. - */ -#define POLARSSL_ECP_NIST_OPTIM - -/** - * \def POLARSSL_ECDSA_DETERMINISTIC - * - * Enable deterministic ECDSA (RFC 6979). - * Standard ECDSA is "fragile" in the sense that lack of entropy when signing - * may result in a compromise of the long-term signing key. This is avoided by - * the deterministic variant. - * - * Requires: POLARSSL_HMAC_DRBG_C - * - * Comment this macro to disable deterministic ECDSA. - */ -#define POLARSSL_ECDSA_DETERMINISTIC - -/** - * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED - * - * Enable the PSK based ciphersuite modes in SSL / TLS. - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_PSK_WITH_AES_256_GCM_SHA384 - * TLS_PSK_WITH_AES_256_CBC_SHA384 - * TLS_PSK_WITH_AES_256_CBC_SHA - * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_PSK_WITH_AES_128_GCM_SHA256 - * TLS_PSK_WITH_AES_128_CBC_SHA256 - * TLS_PSK_WITH_AES_128_CBC_SHA - * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_PSK_WITH_3DES_EDE_CBC_SHA - * TLS_PSK_WITH_RC4_128_SHA - */ -#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * TLS_DHE_PSK_WITH_RC4_128_SHA - */ -#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED - * - * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_ECDH_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * TLS_ECDHE_PSK_WITH_RC4_128_SHA - */ -#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, - * POLARSSL_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * TLS_RSA_PSK_WITH_RC4_128_SHA - */ -#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, - * POLARSSL_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_RSA_WITH_AES_256_GCM_SHA384 - * TLS_RSA_WITH_AES_256_CBC_SHA256 - * TLS_RSA_WITH_AES_256_CBC_SHA - * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * TLS_RSA_WITH_AES_128_GCM_SHA256 - * TLS_RSA_WITH_AES_128_CBC_SHA256 - * TLS_RSA_WITH_AES_128_CBC_SHA - * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * TLS_RSA_WITH_3DES_EDE_CBC_SHA - * TLS_RSA_WITH_RC4_128_SHA - * TLS_RSA_WITH_RC4_128_MD5 - */ -#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, - * POLARSSL_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - */ -#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED - * - * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, - * POLARSSL_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDHE_RSA_WITH_RC4_128_SHA - */ -#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - * - * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_CRT_PARSE_C, - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - */ -#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - -/** - * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDH_RSA_WITH_RC4_128_SHA - * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED - -/** - * \def POLARSSL_PK_PARSE_EC_EXTENDED - * - * Enhance support for reading EC keys using variants of SEC1 not allowed by - * RFC 5915 and RFC 5480. - * - * Currently this means parsing the SpecifiedECDomain choice of EC - * parameters (only known groups are supported, not arbitrary domains, to - * avoid validation issues). - * - * Disable if you only need to support RFC 5915 + 5480 key formats. - */ -#define POLARSSL_PK_PARSE_EC_EXTENDED - -/** - * \def POLARSSL_ERROR_STRERROR_BC - * - * Make available the backward compatible error_strerror() next to the - * current polarssl_strerror(). - * - * For new code, it is recommended to use polarssl_strerror() instead and - * disable this. - * - * Disable if you run into name conflicts and want to really remove the - * error_strerror() - */ -#define POLARSSL_ERROR_STRERROR_BC - -/** - * \def POLARSSL_ERROR_STRERROR_DUMMY - * - * Enable a dummy error function to make use of polarssl_strerror() in - * third party libraries easier when POLARSSL_ERROR_C is disabled - * (no effect when POLARSSL_ERROR_C is enabled). - * - * You can safely disable this if POLARSSL_ERROR_C is enabled, or if you're - * not using polarssl_strerror() or error_strerror() in your application. - * - * Disable if you run into name conflicts and want to really remove the - * polarssl_strerror() - */ -#define POLARSSL_ERROR_STRERROR_DUMMY - -/** - * \def POLARSSL_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: POLARSSL_BIGNUM_C - */ -#define POLARSSL_GENPRIME - -/** - * \def POLARSSL_FS_IO - * - * Enable functions that use the filesystem. - */ -#define POLARSSL_FS_IO - -/** - * \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES - * - * Do not add default entropy sources. These are the platform specific, - * hardclock and HAVEGE based poll functions. - * - * This is useful to have more control over the added entropy sources in an - * application. - * - * Uncomment this macro to prevent loading of default entropy functions. - */ -//#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES - -/** - * \def POLARSSL_NO_PLATFORM_ENTROPY - * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. - * - * Uncomment this macro to disable the built-in platform entropy functions. - */ -//#define POLARSSL_NO_PLATFORM_ENTROPY - -/** - * \def POLARSSL_ENTROPY_FORCE_SHA256 - * - * Force the entropy accumulator to use a SHA-256 accumulator instead of the - * default SHA-512 based one (if both are available). - * - * Requires: POLARSSL_SHA256_C - * - * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option - * if you have performance concerns. - * - * This option is only useful if both POLARSSL_SHA256_C and - * POLARSSL_SHA512_C are defined. Otherwise the available hash module is used. - */ -//#define POLARSSL_ENTROPY_FORCE_SHA256 - -/** - * \def POLARSSL_MEMORY_DEBUG - * - * Enable debugging of buffer allocator memory issues. Automatically prints - * (to stderr) all (fatal) messages on memory allocation issues. Enables - * function for 'debug output' of allocated memory. - * - * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C - * - * Uncomment this macro to let the buffer allocator print out error messages. - */ -//#define POLARSSL_MEMORY_DEBUG - -/** - * \def POLARSSL_MEMORY_BACKTRACE - * - * Include backtrace information with each allocated block. - * - * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() an backtrace_symbols() support - * - * Uncomment this macro to include backtrace information - */ -//#define POLARSSL_MEMORY_BACKTRACE - -/** - * \def POLARSSL_PKCS1_V15 - * - * Enable support for PKCS#1 v1.5 encoding. - * - * Requires: POLARSSL_RSA_C - * - * This enables support for PKCS#1 v1.5 operations. - */ -#define POLARSSL_PKCS1_V15 - -/** - * \def POLARSSL_PKCS1_V21 - * - * Enable support for PKCS#1 v2.1 encoding. - * - * Requires: POLARSSL_MD_C, POLARSSL_RSA_C - * - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -#define POLARSSL_PKCS1_V21 - -/** - * \def POLARSSL_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * - */ -//#define POLARSSL_RSA_NO_CRT - -/** - * \def POLARSSL_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -#define POLARSSL_SELF_TEST - -/** - * \def POLARSSL_SSL_ALL_ALERT_MESSAGES - * - * Enable sending of alert messages in case of encountered errors as per RFC. - * If you choose not to send the alert messages, PolarSSL can still communicate - * with other servers, only debugging of failures is harder. - * - * The advantage of not sending alert messages, is that no information is given - * about reasons for failures thus preventing adversaries of gaining intel. - * - * Enable sending of all alert messages - */ -#define POLARSSL_SSL_ALERT_MESSAGES - -/** - * \def POLARSSL_SSL_DEBUG_ALL - * - * Enable the debug messages in SSL module for all issues. - * Debug messages have been disabled in some places to prevent timing - * attacks due to (unbalanced) debugging function calls. - * - * If you need all error reporting you should enable this during debugging, - * but remove this for production servers that should log as well. - * - * Uncomment this macro to report all debug messages on errors introducing - * a timing side-channel. - * - */ -//#define POLARSSL_SSL_DEBUG_ALL - -/** - * \def POLARSSL_SSL_HW_RECORD_ACCEL - * - * Enable hooking functions in SSL module for hardware acceleration of - * individual records. - * - * Uncomment this macro to enable hooking functions. - */ -//#define POLARSSL_SSL_HW_RECORD_ACCEL - -/** - * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - * - * Enable support for receiving and parsing SSLv2 Client Hello messages for the - * SSL Server module (POLARSSL_SSL_SRV_C). - * - * Comment this macro to disable support for SSLv2 Client Hello messages. - */ -#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - -/** - * \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE - * - * Pick the ciphersuite according to the client's preferences rather than ours - * in the SSL Server module (POLARSSL_SSL_SRV_C). - * - * Uncomment this macro to respect client's ciphersuite order - */ -//#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE - -/** - * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH - * - * Enable support for RFC 6066 max_fragment_length extension in SSL. - * - * Comment this macro to disable support for the max_fragment_length extension - */ -#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH - -/** - * \def POLARSSL_SSL_PROTO_SSL3 - * - * Enable support for SSL 3.0. - * - * Requires: POLARSSL_MD5_C - * POLARSSL_SHA1_C - * - * Comment this macro to disable support for SSL 3.0 - */ -#define POLARSSL_SSL_PROTO_SSL3 - -/** - * \def POLARSSL_SSL_PROTO_TLS1 - * - * Enable support for TLS 1.0. - * - * Requires: POLARSSL_MD5_C - * POLARSSL_SHA1_C - * - * Comment this macro to disable support for TLS 1.0 - */ -#define POLARSSL_SSL_PROTO_TLS1 - -/** - * \def POLARSSL_SSL_PROTO_TLS1_1 - * - * Enable support for TLS 1.1. - * - * Requires: POLARSSL_MD5_C - * POLARSSL_SHA1_C - * - * Comment this macro to disable support for TLS 1.1 - */ -#define POLARSSL_SSL_PROTO_TLS1_1 - -/** - * \def POLARSSL_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2. - * - * Requires: POLARSSL_SHA1_C or POLARSSL_SHA256_C or POLARSSL_SHA512_C - * (Depends on ciphersuites) - * - * Comment this macro to disable support for TLS 1.2 - */ -#define POLARSSL_SSL_PROTO_TLS1_2 - -/** - * \def POLARSSL_SSL_ALPN - * - * Enable support for Application Layer Protocol Negotiation. - * draft-ietf-tls-applayerprotoneg-05 - * - * Comment this macro to disable support for ALPN. - */ -#define POLARSSL_SSL_ALPN - -/** - * \def POLARSSL_SSL_SESSION_TICKETS - * - * Enable support for RFC 5077 session tickets in SSL. - * - * Requires: POLARSSL_AES_C - * POLARSSL_SHA256_C - * POLARSSL_CIPHER_MODE_CBC - * - * Comment this macro to disable support for SSL session tickets - */ -#define POLARSSL_SSL_SESSION_TICKETS - -/** - * \def POLARSSL_SSL_SERVER_NAME_INDICATION - * - * Enable support for RFC 6066 server name indication (SNI) in SSL. - * - * Comment this macro to disable support for server name indication in SSL - */ -#define POLARSSL_SSL_SERVER_NAME_INDICATION - -/** - * \def POLARSSL_SSL_TRUNCATED_HMAC - * - * Enable support for RFC 6066 truncated HMAC in SSL. - * - * Comment this macro to disable support for truncated HMAC in SSL - */ -#define POLARSSL_SSL_TRUNCATED_HMAC - -/** - * \def POLARSSL_SSL_SET_CURVES - * - * Enable ssl_set_curves(). - * - * This is disabled by default since it breaks binary compatibility with the - * 1.3.x line. If you choose to enable it, you will need to rebuild your - * application against the new header files, relinking will not be enough. - * It will be enabled by default, or no longer an option, in the 1.4 branch. - * - * Uncomment to make ssl_set_curves() available. - */ -//#define POLARSSL_SSL_SET_CURVES - -/** - * \def POLARSSL_THREADING_ALT - * - * Provide your own alternate threading implementation. - * - * Requires: POLARSSL_THREADING_C - * - * Uncomment this to allow your own alternate threading implementation. - */ -//#define POLARSSL_THREADING_ALT - -/** - * \def POLARSSL_THREADING_PTHREAD - * - * Enable the pthread wrapper layer for the threading layer. - * - * Requires: POLARSSL_THREADING_C - * - * Uncomment this to enable pthread mutexes. - */ -//#define POLARSSL_THREADING_PTHREAD - -/** - * \def POLARSSL_VERSION_FEATURES - * - * Allow run-time checking of compile-time enabled features. Thus allowing users - * to check at run-time if the library is for instance compiled with threading - * support via version_check_feature(). - * - * Requires: POLARSSL_VERSION_C - * - * Comment this to disable run-time checking and save ROM space - */ -#define POLARSSL_VERSION_FEATURES - -/** - * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an extension in a v1 or v2 certificate. - * - * Uncomment to prevent an error. - */ -//#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 - -/** - * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * Uncomment to prevent an error. - */ -//#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - -/** - * \def POLARSSL_X509_CHECK_KEY_USAGE - * - * Enable verification of the keyUsage extension (CA and leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused - * (intermediate) CA and leaf certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip keyUsage checking for both CA and leaf certificates. - */ -#define POLARSSL_X509_CHECK_KEY_USAGE - -/** - * \def POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE - * - * Enable verification of the extendedKeyUsage extension (leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip extendedKeyUsage checking for certificates. - */ -#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE - -/** - * \def POLARSSL_X509_RSASSA_PSS_SUPPORT - * - * Enable parsing and verification of X.509 certificates, CRLs and CSRS - * signed with RSASSA-PSS (aka PKCS#1 v2.1). - * - * Comment this macro to disallow using RSASSA-PSS in certificates. - */ -#define POLARSSL_X509_RSASSA_PSS_SUPPORT - -/** - * \def POLARSSL_ZLIB_SUPPORT - * - * If set, the SSL/TLS module uses ZLIB to support compression and - * decompression of packet data. - * - * \warning TLS-level compression MAY REDUCE SECURITY! See for example the - * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be a applicable to your use case. - * - * Used in: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This feature requires zlib library and headers to be present. - * - * Uncomment to enable use of ZLIB - */ -//#define POLARSSL_ZLIB_SUPPORT -/* \} name SECTION: PolarSSL feature support */ - -/** - * \name SECTION: PolarSSL modules - * - * This section enables or disables entire modules in PolarSSL - * \{ - */ - -/** - * \def POLARSSL_AESNI_C - * - * Enable AES-NI support on x86-64. - * - * Module: library/aesni.c - * Caller: library/aes.c - * - * Requires: POLARSSL_HAVE_ASM - * - * This modules adds support for the AES-NI instructions on x86-64 - */ -//#define POLARSSL_AESNI_C - -/** - * \def POLARSSL_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/ssl_tls.c - * library/pem.c - * library/ctr_drbg.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * TLS_RSA_WITH_AES_256_GCM_SHA384 - * TLS_RSA_WITH_AES_256_CBC_SHA256 - * TLS_RSA_WITH_AES_256_CBC_SHA - * TLS_RSA_WITH_AES_128_GCM_SHA256 - * TLS_RSA_WITH_AES_128_CBC_SHA256 - * TLS_RSA_WITH_AES_128_CBC_SHA - * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * TLS_PSK_WITH_AES_256_GCM_SHA384 - * TLS_PSK_WITH_AES_256_CBC_SHA384 - * TLS_PSK_WITH_AES_256_CBC_SHA - * TLS_PSK_WITH_AES_128_GCM_SHA256 - * TLS_PSK_WITH_AES_128_CBC_SHA256 - * TLS_PSK_WITH_AES_128_CBC_SHA - * - * PEM_PARSE uses AES for decrypting encrypted keys. - */ -#define POLARSSL_AES_C - -/** - * \def POLARSSL_ARC4_C - * - * Enable the ARCFOUR stream cipher. - * - * Module: library/arc4.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * TLS_ECDH_RSA_WITH_RC4_128_SHA - * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - * TLS_ECDHE_RSA_WITH_RC4_128_SHA - * TLS_ECDHE_PSK_WITH_RC4_128_SHA - * TLS_DHE_PSK_WITH_RC4_128_SHA - * TLS_RSA_WITH_RC4_128_SHA - * TLS_RSA_WITH_RC4_128_MD5 - * TLS_RSA_PSK_WITH_RC4_128_SHA - * TLS_PSK_WITH_RC4_128_SHA - */ -#define POLARSSL_ARC4_C - -/** - * \def POLARSSL_ASN1_PARSE_C - * - * Enable the generic ASN1 parser. - * - * Module: library/asn1.c - * Caller: library/x509.c - * library/dhm.c - * library/pkcs12.c - * library/pkcs5.c - * library/pkparse.c - */ -#define POLARSSL_ASN1_PARSE_C - -/** - * \def POLARSSL_ASN1_WRITE_C - * - * Enable the generic ASN1 writer. - * - * Module: library/asn1write.c - * Caller: library/ecdsa.c - * library/pkwrite.c - * library/x509_create.c - * library/x509write_crt.c - * library/x509write_csr.c - */ -#define POLARSSL_ASN1_WRITE_C - -/** - * \def POLARSSL_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -#define POLARSSL_BASE64_C - -/** - * \def POLARSSL_BIGNUM_C - * - * Enable the multi-precision integer library. - * - * Module: library/bignum.c - * Caller: library/dhm.c - * library/ecp.c - * library/ecdsa.c - * library/rsa.c - * library/ssl_tls.c - * - * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. - */ -#define POLARSSL_BIGNUM_C - -/** - * \def POLARSSL_BLOWFISH_C - * - * Enable the Blowfish block cipher. - * - * Module: library/blowfish.c - */ -#define POLARSSL_BLOWFISH_C - -/** - * \def POLARSSL_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define POLARSSL_CAMELLIA_C - -/** - * \def POLARSSL_CCM_C - * - * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. - * - * Module: library/ccm.c - * - * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C - * - * This module enables the AES-CCM ciphersuites, if other requisites are - * enabled as well. - */ -#define POLARSSL_CCM_C - -/** - * \def POLARSSL_CERTS_C - * - * Enable the test certificates. - * - * Module: library/certs.c - * Caller: - * - * Requires: POLARSSL_PEM_PARSE_C - * - * This module is used for testing (ssl_client/server). - */ -#define POLARSSL_CERTS_C - -/** - * \def POLARSSL_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ssl_tls.c - * - * Uncomment to enable generic cipher wrappers. - */ -#define POLARSSL_CIPHER_C - -/** - * \def POLARSSL_CTR_DRBG_C - * - * Enable the CTR_DRBG AES-256-based random generator. - * - * Module: library/ctr_drbg.c - * Caller: - * - * Requires: POLARSSL_AES_C - * - * This module provides the CTR_DRBG AES-256 random number generator. - */ -#define POLARSSL_CTR_DRBG_C - -/** - * \def POLARSSL_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module provides debugging functions. - */ -#define POLARSSL_DEBUG_C - -/** - * \def POLARSSL_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/pem.c - * library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * TLS_RSA_WITH_3DES_EDE_CBC_SHA - * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * TLS_PSK_WITH_3DES_EDE_CBC_SHA - * - * PEM_PARSE uses DES/3DES for decrypting encrypted keys. - */ -#define POLARSSL_DES_C - -/** - * \def POLARSSL_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - */ -#define POLARSSL_DHM_C - -/** - * \def POLARSSL_ECDH_C - * - * Enable the elliptic curve Diffie-Hellman library. - * - * Module: library/ecdh.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK - * - * Requires: POLARSSL_ECP_C - */ -#define POLARSSL_ECDH_C - -/** - * \def POLARSSL_ECDSA_C - * - * Enable the elliptic curve DSA library. - * - * Module: library/ecdsa.c - * Caller: - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA - * - * Requires: POLARSSL_ECP_C, POLARSSL_ASN1_WRITE_C, POLARSSL_ASN1_PARSE_C - */ -#define POLARSSL_ECDSA_C - -/** - * \def POLARSSL_ECP_C - * - * Enable the elliptic curve over GF(p) library. - * - * Module: library/ecp.c - * Caller: library/ecdh.c - * library/ecdsa.c - * - * Requires: POLARSSL_BIGNUM_C and at least one POLARSSL_ECP_DP_XXX_ENABLED - */ -#define POLARSSL_ECP_C - -/** - * \def POLARSSL_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: POLARSSL_SHA512_C or POLARSSL_SHA256_C - * - * This module provides a generic entropy pool - */ -#define POLARSSL_ENTROPY_C - -/** - * \def POLARSSL_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables polarssl_strerror(). - */ -#define POLARSSL_ERROR_C - -/** - * \def POLARSSL_GCM_C - * - * Enable the Galois/Counter Mode (GCM) for AES. - * - * Module: library/gcm.c - * - * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C - * - * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other - * requisites are enabled as well. - */ -#define POLARSSL_GCM_C - -/** - * \def POLARSSL_HAVEGE_C - * - * Enable the HAVEGE random generator. - * - * Warning: the HAVEGE random generator is not suitable for virtualized - * environments - * - * Warning: the HAVEGE random generator is dependent on timing and specific - * processor traits. It is therefore not advised to use HAVEGE as - * your applications primary random generator or primary entropy pool - * input. As a secondary input to your entropy pool, it IS able add - * the (limited) extra entropy it provides. - * - * Module: library/havege.c - * Caller: - * - * Requires: POLARSSL_TIMING_C - * - * Uncomment to enable the HAVEGE random generator. - */ -//#define POLARSSL_HAVEGE_C - -/** - * \def POLARSSL_HMAC_DRBG_C - * - * Enable the HMAC_DRBG random generator. - * - * Module: library/hmac_drbg.c - * Caller: - * - * Requires: POLARSSL_MD_C - * - * Uncomment to enable the HMAC_DRBG random number geerator. - */ -#define POLARSSL_HMAC_DRBG_C - -/** - * \def POLARSSL_MD_C - * - * Enable the generic message digest layer. - * - * Module: library/md.c - * Caller: - * - * Uncomment to enable generic message digest wrappers. - */ -#define POLARSSL_MD_C - -/** - * \def POLARSSL_MD2_C - * - * Enable the MD2 hash algorithm. - * - * Module: library/md2.c - * Caller: - * - * Uncomment to enable support for (rare) MD2-signed X.509 certs. - */ -//#define POLARSSL_MD2_C - -/** - * \def POLARSSL_MD4_C - * - * Enable the MD4 hash algorithm. - * - * Module: library/md4.c - * Caller: - * - * Uncomment to enable support for (rare) MD4-signed X.509 certs. - */ -//#define POLARSSL_MD4_C - -/** - * \def POLARSSL_MD5_C - * - * Enable the MD5 hash algorithm. - * - * Module: library/md5.c - * Caller: library/md.c - * library/pem.c - * library/ssl_tls.c - * - * This module is required for SSL/TLS and X.509. - * PEM_PARSE uses MD5 for decrypting encrypted keys. - */ -#define POLARSSL_MD5_C - -/** - * \def POLARSSL_MEMORY_C - * Deprecated since 1.3.5. Please use POLARSSL_PLATFORM_MEMORY instead. - */ -//#define POLARSSL_MEMORY_C - -/** - * \def POLARSSL_MEMORY_BUFFER_ALLOC_C - * - * Enable the buffer allocator implementation that makes use of a (stack) - * based buffer to 'allocate' dynamic memory. (replaces malloc() and free() - * calls) - * - * Module: library/memory_buffer_alloc.c - * - * Requires: POLARSSL_PLATFORM_C - * POLARSSL_PLATFORM_MEMORY (to use it within PolarSSL) - * - * Enable this module to enable the buffer memory allocator. - */ -//#define POLARSSL_MEMORY_BUFFER_ALLOC_C - -/** - * \def POLARSSL_NET_C - * - * Enable the TCP/IP networking routines. - * - * Module: library/net.c - * - * This module provides TCP/IP networking routines. - */ -#define POLARSSL_NET_C - -/** - * \def POLARSSL_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#define POLARSSL_OID_C - -/** - * \def POLARSSL_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * Requires: POLARSSL_HAVE_ASM - * - * This modules adds support for the VIA PadLock on x86. - */ -//#define POLARSSL_PADLOCK_C - -/** - * \def POLARSSL_PBKDF2_C - * - * Enable PKCS#5 PBKDF2 key derivation function. - * DEPRECATED: Use POLARSSL_PKCS5_C instead - * - * Module: library/pbkdf2.c - * - * Requires: POLARSSL_PKCS5_C - * - * This module adds support for the PKCS#5 PBKDF2 key derivation function. - */ -#define POLARSSL_PBKDF2_C - -/** - * \def POLARSSL_PEM_PARSE_C - * - * Enable PEM decoding / parsing. - * - * Module: library/pem.c - * Caller: library/dhm.c - * library/pkparse.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: POLARSSL_BASE64_C - * - * This modules adds support for decoding / parsing PEM files. - */ -#define POLARSSL_PEM_PARSE_C - -/** - * \def POLARSSL_PEM_WRITE_C - * - * Enable PEM encoding / writing. - * - * Module: library/pem.c - * Caller: library/pkwrite.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Requires: POLARSSL_BASE64_C - * - * This modules adds support for encoding / writing PEM files. - */ -#define POLARSSL_PEM_WRITE_C - -/** - * \def POLARSSL_PK_C - * - * Enable the generic public (asymetric) key layer. - * - * Module: library/pk.c - * Caller: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: POLARSSL_RSA_C or POLARSSL_ECP_C - * - * Uncomment to enable generic public key wrappers. - */ -#define POLARSSL_PK_C - -/** - * \def POLARSSL_PK_PARSE_C - * - * Enable the generic public (asymetric) key parser. - * - * Module: library/pkparse.c - * Caller: library/x509_crt.c - * library/x509_csr.c - * - * Requires: POLARSSL_PK_C - * - * Uncomment to enable generic public key parse functions. - */ -#define POLARSSL_PK_PARSE_C - -/** - * \def POLARSSL_PK_WRITE_C - * - * Enable the generic public (asymetric) key writer. - * - * Module: library/pkwrite.c - * Caller: library/x509write.c - * - * Requires: POLARSSL_PK_C - * - * Uncomment to enable generic public key write functions. - */ -#define POLARSSL_PK_WRITE_C - -/** - * \def POLARSSL_PKCS5_C - * - * Enable PKCS#5 functions. - * - * Module: library/pkcs5.c - * - * Requires: POLARSSL_MD_C - * - * This module adds support for the PKCS#5 functions. - */ -#define POLARSSL_PKCS5_C - -/** - * \def POLARSSL_PKCS11_C - * - * Enable wrapper for PKCS#11 smartcard support. - * - * Module: library/pkcs11.c - * Caller: library/pk.c - * - * Requires: POLARSSL_PK_C - * - * This module enables SSL/TLS PKCS #11 smartcard support. - * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) - */ -//#define POLARSSL_PKCS11_C - -/** - * \def POLARSSL_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_CIPHER_C, POLARSSL_MD_C - * Can use: POLARSSL_ARC4_C - * - * This module enables PKCS#12 functions. - */ -#define POLARSSL_PKCS12_C - -/** - * \def POLARSSL_PLATFORM_C - * - * Enable the platform abstraction layer that allows you to re-assign - * functions like malloc(), free(), printf(), fprintf() - * - * Module: library/platform.c - * Caller: Most other .c files - * - * This module enables abstraction of common (libc) functions. - */ -//#define POLARSSL_PLATFORM_C - -/** - * \def POLARSSL_RIPEMD160_C - * - * Enable the RIPEMD-160 hash algorithm. - * - * Module: library/ripemd160.c - * Caller: library/md.c - * - */ -#define POLARSSL_RIPEMD160_C - -/** - * \def POLARSSL_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509.c - * - * This module is used by the following key exchanges: - * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK - * - * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C - */ -#define POLARSSL_RSA_C - -/** - * \def POLARSSL_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/sha1.c - * Caller: library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509write_crt.c - * - * This module is required for SSL/TLS and SHA1-signed certificates. - */ -#define POLARSSL_SHA1_C - -/** - * \def POLARSSL_SHA256_C - * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. - * (Used to be POLARSSL_SHA2_C) - * - * Module: library/sha256.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module adds support for SHA-224 and SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. - */ -#define POLARSSL_SHA256_C - -/** - * \def POLARSSL_SHA512_C - * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. - * (Used to be POLARSSL_SHA4_C) - * - * Module: library/sha512.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This module adds support for SHA-384 and SHA-512. - */ -#define POLARSSL_SHA512_C - -/** - * \def POLARSSL_SSL_CACHE_C - * - * Enable simple SSL cache implementation. - * - * Module: library/ssl_cache.c - * Caller: - * - * Requires: POLARSSL_SSL_CACHE_C - */ -#define POLARSSL_SSL_CACHE_C - -/** - * \def POLARSSL_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl_cli.c - * Caller: - * - * Requires: POLARSSL_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -#define POLARSSL_SSL_CLI_C - -/** - * \def POLARSSL_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl_srv.c - * Caller: - * - * Requires: POLARSSL_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -#define POLARSSL_SSL_SRV_C - -/** - * \def POLARSSL_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: POLARSSL_CIPHER_C, POLARSSL_MD_C - * and at least one of the POLARSSL_SSL_PROTO_* defines - * - * This module is required for SSL/TLS. - */ -#define POLARSSL_SSL_TLS_C - -/** - * \def POLARSSL_THREADING_C - * - * Enable the threading abstraction layer. - * By default PolarSSL assumes it is used in a non-threaded environment or that - * contexts are not shared between threads. If you do intend to use contexts - * between threads, you will need to enable this layer to prevent race - * conditions. - * - * Module: library/threading.c - * - * This allows different threading implementations (self-implemented or - * provided). - * - * You will have to enable either POLARSSL_THREADING_ALT or - * POLARSSL_THREADING_PTHREAD. - * - * Enable this layer to allow use of mutexes within PolarSSL - */ -//#define POLARSSL_THREADING_C - -/** - * \def POLARSSL_TIMING_C - * - * Enable the portable timing interface. - * - * Module: library/timing.c - * Caller: library/havege.c - * - * This module is used by the HAVEGE random number generator. - */ -#define POLARSSL_TIMING_C - -/** - * \def POLARSSL_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -#define POLARSSL_VERSION_C - -/** - * \def POLARSSL_X509_USE_C - * - * Enable X.509 core for using certificates. - * - * Module: library/x509.c - * Caller: library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_OID_C, - * POLARSSL_PK_PARSE_C - * - * This module is required for the X.509 parsing modules. - */ -#define POLARSSL_X509_USE_C - -/** - * \def POLARSSL_X509_CRT_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/x509_crt.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * Requires: POLARSSL_X509_USE_C - * - * This module is required for X.509 certificate parsing. - */ -#define POLARSSL_X509_CRT_PARSE_C - -/** - * \def POLARSSL_X509_CRL_PARSE_C - * - * Enable X.509 CRL parsing. - * - * Module: library/x509_crl.c - * Caller: library/x509_crt.c - * - * Requires: POLARSSL_X509_USE_C - * - * This module is required for X.509 CRL parsing. - */ -#define POLARSSL_X509_CRL_PARSE_C - -/** - * \def POLARSSL_X509_CSR_PARSE_C - * - * Enable X.509 Certificate Signing Request (CSR) parsing. - * - * Module: library/x509_csr.c - * Caller: library/x509_crt_write.c - * - * Requires: POLARSSL_X509_USE_C - * - * This module is used for reading X.509 certificate request. - */ -#define POLARSSL_X509_CSR_PARSE_C - -/** - * \def POLARSSL_X509_CREATE_C - * - * Enable X.509 core for creating certificates. - * - * Module: library/x509_create.c - * - * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C, POLARSSL_PK_WRITE_C - * - * This module is the basis for creating X.509 certificates and CSRs. - */ -#define POLARSSL_X509_CREATE_C - -/** - * \def POLARSSL_X509_CRT_WRITE_C - * - * Enable creating X.509 certificates. - * - * Module: library/x509_crt_write.c - * - * Requires: POLARSSL_CREATE_C - * - * This module is required for X.509 certificate creation. - */ -#define POLARSSL_X509_CRT_WRITE_C - -/** - * \def POLARSSL_X509_CSR_WRITE_C - * - * Enable creating X.509 Certificate Signing Requests (CSR). - * - * Module: library/x509_csr_write.c - * - * Requires: POLARSSL_CREATE_C - * - * This module is required for X.509 certificate request writing. - */ -#define POLARSSL_X509_CSR_WRITE_C - -/** - * \def POLARSSL_XTEA_C - * - * Enable the XTEA block cipher. - * - * Module: library/xtea.c - * Caller: - */ -#define POLARSSL_XTEA_C - -/* \} name SECTION: PolarSSL modules */ - -/** - * \name SECTION: Module configuration options - * - * This section allows for the setting of module specific sizes and - * configuration options. The default values are already present in the - * relevant header files and should suffice for the regular use cases. - * - * Our advice is to enable options and change their values here - * only if you have a good reason and know the consequences. - * - * Please check the respective header file for documentation on these - * parameters (to prevent duplicate documentation). - * \{ - */ - -/* MPI / BIGNUM options */ -//#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ -//#define POLARSSL_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ - -/* CTR_DRBG options */ -//#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* HMAC_DRBG options */ -//#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* ECP options */ -//#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ -//#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ -//#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ - -/* Entropy options */ -//#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ - -/* Memory buffer allocator options */ -//#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -/* Platform options */ -//#define POLARSSL_PLATFORM_STD_MEM_HDR /**< Header to include if POLARSSL_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ -//#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use, can be undefined */ -//#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ -//#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -//#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ - -/* SSL Cache options */ -//#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ - -/* SSL options */ -//#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ -//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ - -/** - * Complete list of ciphersuites to use, in order of preference. - * - * \warning No dependency checking is done on that field! This option can only - * be used to restrict the set of available ciphersuites. It is your - * responsibility to make sure the needed modules are active. - * - * Use this to save a few hundred bytes of ROM (default ordering of all - * available ciphersuites) and a few to a few hundred bytes of RAM. - * - * The value below is only an example, not the default. - */ -//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - -/* Debug options */ -//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ - -/* \} name SECTION: Module configuration options */ - - -#endif /* POLARSSL_CONFIG_H */ diff --git a/client/src/preferences.c b/client/src/preferences.c index b0534a671..4313c9456 100644 --- a/client/src/preferences.c +++ b/client/src/preferences.c @@ -29,22 +29,13 @@ static int CmdHelp(const char *Cmd); static int setCmdHelp(const char *Cmd); -// Load all settings into memory (struct) -#ifdef _WIN32 -#include -#define GetCurrentDir _getcwd -#else -#include -#define GetCurrentDir getcwd -#endif - static char *prefGetFilename(void) { char *path; - if (searchHomeFilePath(&path, preferencesFilename, false) == PM3_SUCCESS) + if (searchHomeFilePath(&path, NULL, preferencesFilename, false) == PM3_SUCCESS) return path; else - return preferencesFilename; + return strdup(preferencesFilename); } int preferences_load(void) { @@ -95,10 +86,10 @@ int preferences_load(void) { size_t dummyDL = 0x00; // to better control json cant find file error msg. - char* fn = prefGetFilename(); + char *fn = prefGetFilename(); if (fileExists(fn)) { - PrintAndLogEx(INFO, "Loading Preferences..."); - if (loadFileJSON(fn, &dummyData, sizeof(dummyData), &dummyDL) == PM3_SUCCESS) { + PrintAndLogEx(INFO, "Loading preferences..."); + if (loadFileJSON(fn, &dummyData, sizeof(dummyData), &dummyDL, &preferences_load_callback) == PM3_SUCCESS) { session.preferences_loaded = true; } } @@ -113,13 +104,13 @@ int preferences_load(void) { int preferences_save(void) { // Note sure if backup has value ? - PrintAndLogEx(INFO, "Saving Preferences..."); + PrintAndLogEx(INFO, "Saving preferences..."); - char* fn = prefGetFilename(); + char *fn = prefGetFilename(); int fnLen = strlen(fn) + 5; // .bak\0 // [FILENAME_MAX+sizeof(preferencesFilename)+10] - char* backupFilename = (char *)calloc(fnLen, sizeof(uint8_t)); + char *backupFilename = (char *)calloc(fnLen, sizeof(uint8_t)); if (backupFilename == NULL) { PrintAndLogEx(ERR, "failed to allocate memory"); free(fn); @@ -148,7 +139,7 @@ int preferences_save(void) { uint8_t dummyData = 0x00; size_t dummyDL = 0x00; - if (saveFileJSON(fn, jsfSettings, &dummyData, dummyDL) != PM3_SUCCESS) + if (saveFileJSON(fn, jsfCustom, &dummyData, dummyDL, &preferences_save_callback) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error saving preferences to \"%s\"", fn); free(fn); @@ -314,7 +305,7 @@ void preferences_load_callback(json_t *root) { // Help Functions -static int usage_set_emoji() { +static int usage_set_emoji(void) { PrintAndLogEx(NORMAL, "Usage: pref set emoji "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); @@ -325,7 +316,7 @@ static int usage_set_emoji() { return PM3_SUCCESS; } -static int usage_set_color() { +static int usage_set_color(void) { PrintAndLogEx(NORMAL, "Usage: pref set color "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); @@ -334,7 +325,7 @@ static int usage_set_color() { return PM3_SUCCESS; } -static int usage_set_debug() { +static int usage_set_debug(void) { PrintAndLogEx(NORMAL, "Usage: pref set clientdebug "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); @@ -344,7 +335,7 @@ static int usage_set_debug() { return PM3_SUCCESS; } /* -static int usage_set_devicedebug() { +static int usage_set_devicedebug(void) { PrintAndLogEx(NORMAL, "Usage: pref set devicedebug "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); @@ -357,7 +348,7 @@ static int usage_set_devicedebug() { return PM3_SUCCESS; } */ -static int usage_set_hints() { +static int usage_set_hints(void) { PrintAndLogEx(NORMAL, "Usage: pref set hints "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); @@ -366,7 +357,7 @@ static int usage_set_hints() { return PM3_SUCCESS; } /* -static int usage_set_savePaths() { +static int usage_set_savePaths(void) { PrintAndLogEx(NORMAL, "Usage: pref set savepaths [help] [create] [default ] [dump ] [trace ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); @@ -382,7 +373,7 @@ static int usage_set_savePaths() { // typedef enum preferenceId {prefNONE,prefHELP,prefEMOJI,prefCOLOR,prefPLOT,prefOVERLAY,prefHINTS,prefCLIENTDEBUG} preferenceId_t; typedef enum prefShowOpt {prefShowNone, prefShowOLD, prefShowNEW} prefShowOpt_t; -const char *prefShowMsg(prefShowOpt_t Opt) { +static const char *prefShowMsg(prefShowOpt_t Opt) { switch (Opt) { case prefShowOLD: return _YELLOW_("[old]"); @@ -395,7 +386,7 @@ const char *prefShowMsg(prefShowOpt_t Opt) { return ""; } -void showEmojiState(prefShowOpt_t Opt) { +static void showEmojiState(prefShowOpt_t Opt) { switch (session.emoji_mode) { case ALIAS: @@ -415,7 +406,7 @@ void showEmojiState(prefShowOpt_t Opt) { } } -void showColorState(prefShowOpt_t Opt) { +static void showColorState(prefShowOpt_t Opt) { if (session.supports_colors) PrintAndLogEx(NORMAL, " %s color.................. "_GREEN_("ansi"), prefShowMsg(Opt)); @@ -423,7 +414,7 @@ void showColorState(prefShowOpt_t Opt) { PrintAndLogEx(NORMAL, " %s color.................. "_WHITE_("off"), prefShowMsg(Opt)); } -void showClientDebugState(prefShowOpt_t Opt) { +static void showClientDebugState(prefShowOpt_t Opt) { switch (session.client_debug_level) { case cdbOFF: @@ -440,7 +431,7 @@ void showClientDebugState(prefShowOpt_t Opt) { } } /* -void showDeviceDebugState(prefShowOpt_t Opt) { +static void showDeviceDebugState(prefShowOpt_t Opt) { switch (session.device_debug_level) { case ddbOFF: PrintAndLogEx(NORMAL, " %s device debug........... "_WHITE_("off"), prefShowMsg(Opt)); @@ -463,7 +454,7 @@ void showDeviceDebugState(prefShowOpt_t Opt) { } */ /* -void showSavePathState(savePaths_t pathIndex, prefShowOpt_t Opt) { +static void showSavePathState(savePaths_t pathIndex, prefShowOpt_t Opt) { char tempStr[50]; @@ -485,18 +476,19 @@ void showSavePathState(savePaths_t pathIndex, prefShowOpt_t Opt) { else PrintAndLogEx(NORMAL, " %s %s "_GREEN_("%s"), prefShowMsg(Opt), tempStr, session.defaultPaths[pathIndex]); } -*/ -void showPlotPosState(void) { + +static void showPlotPosState(void) { PrintAndLogEx(NORMAL, " Plot window............ X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"), session.plot.x, session.plot.y, session.plot.h, session.plot.w); } -void showOverlayPosState(void) { +static void showOverlayPosState(void) { PrintAndLogEx(NORMAL, " Slider/Overlay window.. X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"), session.overlay.x, session.overlay.y, session.overlay.h, session.overlay.w); } +*/ -void showHintsState(prefShowOpt_t Opt) { +static void showHintsState(prefShowOpt_t Opt) { if (session.show_hints) PrintAndLogEx(NORMAL, " %s hints.................. "_GREEN_("on"), prefShowMsg(Opt)); else @@ -850,28 +842,28 @@ static int setCmdSavePaths (const char *Cmd) { return PM3_SUCCESS; } -*/ -int getCmdHelp(const char *Cmd) { +static int getCmdHelp(const char *Cmd) { return PM3_SUCCESS; } +*/ -int getCmdEmoji(const char *Cmd) { +static int getCmdEmoji(const char *Cmd) { showEmojiState(prefShowNone); return PM3_SUCCESS; } -int getCmdHint(const char *Cmd) { +static int getCmdHint(const char *Cmd) { showHintsState(prefShowNone); return PM3_SUCCESS; } -int getCmdColor(const char *Cmd) { +static int getCmdColor(const char *Cmd) { showColorState(prefShowNone); return PM3_SUCCESS; } -int getCmdDebug(const char *Cmd) { +static int getCmdDebug(const char *Cmd) { showClientDebugState(prefShowNone); return PM3_SUCCESS; } @@ -904,30 +896,28 @@ static int setCmdHelp(const char *Cmd) { return PM3_SUCCESS; } -int CmdPrefGet(const char *Cmd) { +static int CmdPrefGet(const char *Cmd) { clearCommandBuffer(); return CmdsParse(getCommandTable, Cmd); } -int CmdPrefSet(const char *Cmd) { +static int CmdPrefSet(const char *Cmd) { clearCommandBuffer(); return CmdsParse(setCommandTable, Cmd); } static int CmdPrefShow(const char *Cmd) { - char* fn = prefGetFilename(); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, _CYAN_("Preferences loaded from %s"), fn); - - free(fn); - - if (!session.preferences_loaded) { + if (session.preferences_loaded) { + char *fn = prefGetFilename(); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, _CYAN_("Preferences loaded from " _YELLOW_("%s")), fn); + free(fn); + } else { PrintAndLogEx(ERR, "Preferences not loaded"); return PM3_ESOFT; } - // PrintAndLogEx(NORMAL, " preference file........ "_GREEN_("%s"), fn); showEmojiState(prefShowNone); showHintsState(prefShowNone); showColorState(prefShowNone); @@ -939,7 +929,6 @@ static int CmdPrefShow(const char *Cmd) { showClientDebugState(prefShowNone); // showDeviceDebugState(prefShowNone); - PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } /* diff --git a/client/src/proxendian.h b/client/src/proxendian.h index fde5126b1..8501858e0 100644 --- a/client/src/proxendian.h +++ b/client/src/proxendian.h @@ -16,17 +16,26 @@ #ifdef _WIN32 # define HOST_LITTLE_ENDIAN #else -# include -# ifndef BYTE_ORDER -# define BYTE_ORDER __BYTE_ORDER -# define LITTLE_ENDIAN __LITTLE_ENDIAN -# define BIG_ENDIAN __BIG_ENDIAN +// Only some OSes include endian.h from sys/types.h, not Termux, so let's include endian.h directly +# if defined(__APPLE__) +# include +# else +# include # endif -# if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) -# error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN -# endif -# if BYTE_ORDER == LITTLE_ENDIAN -# define HOST_LITTLE_ENDIAN +# if !defined(BYTE_ORDER) +# if !defined(__BYTE_ORDER) || (__BYTE_ORDER != __LITTLE_ENDIAN && __BYTE_ORDER != __BIG_ENDIAN) +# error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +# endif +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define HOST_LITTLE_ENDIAN +# endif +# else +# if BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN +# error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +# endif +# if BYTE_ORDER == LITTLE_ENDIAN +# define HOST_LITTLE_ENDIAN +# endif # endif #endif diff --git a/client/src/proxgui.h b/client/src/proxgui.h index c9cd0096d..cc9c9e118 100644 --- a/client/src/proxgui.h +++ b/client/src/proxgui.h @@ -18,7 +18,6 @@ extern "C" { #include #include #include -//#include "comms.h" void ShowGraphWindow(void); void HideGraphWindow(void); @@ -26,12 +25,6 @@ void RepaintGraphWindow(void); void MainGraphics(void); void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); void ExitGraphics(void); -#ifndef MAX_GRAPH_TRACE_LEN -#define MAX_GRAPH_TRACE_LEN (40000 * 8) -#endif -extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; -extern size_t GraphTraceLen; -extern int s_Buff[MAX_GRAPH_TRACE_LEN]; extern double CursorScaleFactor; extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, GridOffset; @@ -40,26 +33,12 @@ extern int CommandFinished; extern int offline; extern bool GridLocked; -//Operations defined in data_operations -//int autoCorr(const int* in, int *out, size_t len, int window); -int AskEdgeDetect(const int *in, int *out, int len, int threshold); -int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveGrph, bool verbose); -int directionalThreshold(const int *in, int *out, size_t len, int8_t up, int8_t down); -void save_restoreGB(uint8_t saveOpt); - #define GRAPH_SAVE 1 #define GRAPH_RESTORE 0 -#define MAX_DEMOD_BUF_LEN (1024*128) -extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; -extern size_t DemodBufferLen; -extern size_t g_DemodStartIdx; -extern bool showDemod; -extern uint8_t g_debugMode; #ifndef FILE_PATH_SIZE #define FILE_PATH_SIZE 1000 #endif -extern uint8_t gui_serial_port_name[FILE_PATH_SIZE]; #ifdef __cplusplus } diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index 855b41c87..149018b9f 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -24,21 +24,22 @@ #include #include #include -#include "proxgui.h" #include +#include "proxgui.h" #include "ui.h" +#include "comms.h" +#include "graph.h" +#include "cmddata.h" +#include "util_darwin.h" extern "C" int preferences_save(void); -extern "C" { -#include "util_darwin.h" -} - -bool g_useOverlays = false; -int g_absVMax = 0; -uint32_t startMax; // Maximum offset in the graph (right side of graph) -uint32_t PageWidth; // How many samples are currently visible on this 'page' / graph -int unlockStart = 0; +static int s_Buff[MAX_GRAPH_TRACE_LEN]; +static bool g_useOverlays = false; +static int g_absVMax = 0; +static uint32_t startMax; // Maximum offset in the graph (right side of graph) +static uint32_t PageWidth; // How many samples are currently visible on this 'page' / graph +static int unlockStart = 0; void ProxGuiQT::ShowGraphWindow(void) { emit ShowGraphWindowSignal(); @@ -233,7 +234,7 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { setLayout(layout); // plot window title - QString pt = QString("[*]Plot [ %1 ]").arg((char *)gui_serial_port_name); + QString pt = QString("[*]Plot [ %1 ]").arg(conn.serial_port_name); setWindowTitle(pt); // shows plot window on the screen. @@ -247,7 +248,7 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { } // Olverlays / slider window title - QString ct = QString("[*]Slider [ %1 ]").arg((char *)gui_serial_port_name); + QString ct = QString("[*]Slider [ %1 ]").arg(conn.serial_port_name); controlWidget->setWindowTitle(ct); controlWidget->show(); diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 6010fb981..eea1718c3 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -15,8 +15,11 @@ #include // for Mingw readline #include #include +#ifdef HAVE_READLINE #include #include +#endif +#include #include "usart_defs.h" #include "util_posix.h" #include "proxgui.h" @@ -29,81 +32,78 @@ #include "flash.h" #include "preferences.h" -#ifdef _WIN32 -#include -#define GetCurrentDir _getcwd -#else -#include -#define GetCurrentDir getcwd -#endif - // Used to enable/disable use of preferences json file #define USE_PREFERENCE_FILE -#ifdef _WIN32 +#define BANNERMSG1 " :snowflake: iceman@icesql.net" +#define BANNERMSG2 " https://github.com/rfidresearchgroup/proxmark3/" +#define BANNERMSG3 " bleeding edge :coffee:" -static void utf8_showBanner(void) { +typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; - char sq[] = { 0xE2, 0x96, 0x88, 0x00 }; // square block - char tr[] = { 0xE2, 0x95, 0x97, 0x00 }; // top rigth corner - char tl[] = { 0xE2, 0x95, 0x94, 0x00 }; // top left corner - char br[] = { 0xE2, 0x95, 0x9D, 0x00 }; // bottom right corner - char bl[] = { 0xE2, 0x95, 0x9A, 0x00 }; // bottom left corner - char hl[] = { 0xE2, 0x95, 0x90, 0x00 }; // horiz line - char vl[] = { 0xE2, 0x95, 0x91, 0x00 }; // vert line - char msg1 [60]; - char msg2 [60]; - char msg3 [60]; +static void showBanner_logo(LogoMode mode) { + switch (mode) { + case UTF8: { + const char *sq = "\xE2\x96\x88"; // square block + const char *tr = "\xE2\x95\x97"; // top right corner + const char *tl = "\xE2\x95\x94"; // top left corner + const char *br = "\xE2\x95\x9D"; // bottom right corner + const char *bl = "\xE2\x95\x9A"; // bottom left corner + const char *hl = "\xE2\x95\x90"; // horiz line + const char *vl = "\xE2\x95\x91"; // vert line + const char *__ = " "; - strcpy(msg1, " :snowflake: iceman@icesql.net :coffee:"); - strcpy(msg2, " https://github.com/rfidresearchgroup/proxmark3/"); - strcpy(msg3, "pre-release v4.0"); - - g_printAndLog = PRINTANDLOG_PRINT; - - PrintAndLogEx(NORMAL, "\n"); - - PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s %s%s%s%s %s%s%s%s %s%s%s%s%s "), sq, sq, sq, sq, sq, sq, tr, sq, sq, sq, tr, sq, sq, sq, tr, sq, sq, sq, sq, tr); - PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s %s%s%s%s%s %s%s%s%s"), sq, sq, tl, hl, hl, sq, sq, tr, sq, sq, sq, sq, tr, sq, sq, sq, sq, vl, hl, hl, sq, vl); - PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s %s%s%s%s%s%s"), sq, sq, sq, sq, sq, sq, tl, br, sq, sq, tl, sq, sq, sq, sq, tl, sq, sq, vl, sq, sq, sq, sq, tl, br); - PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s %s%s%s%s%s%s%s%s%s%s%s %s%s%s%s")" %s", sq, sq, tr, hl, hl, hl, br, sq, sq, vl, bl, sq, sq, tl, br, sq, sq, vl, hl, hl, sq, vl, msg1); - PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s %s%s%s %s%s%s %s%s%s %s%s%s%s%s%s")" %s", sq, sq, vl, sq, sq, vl, bl, hl, br, sq, sq, vl, sq, sq, sq, sq, tl, br, msg2); - PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s %s%s%s %s%s%s %s%s%s%s%s ")" %s", bl, hl, br, bl, hl, br, bl, hl, br, bl, hl, hl, hl, br, msg3); - - PrintAndLogEx(NORMAL, ""); - fflush(stdout); - g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; + PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"), + sq, sq, sq, sq, sq, sq, tr, __, sq, sq, sq, tr, __, __, __, sq, sq, sq, tr, sq, sq, sq, sq, sq, tr, __); + PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"), + sq, sq, tl, hl, hl, sq, sq, tr, sq, sq, sq, sq, tr, __, sq, sq, sq, sq, vl, bl, hl, hl, hl, sq, sq, tr); + PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"), + sq, sq, sq, sq, sq, sq, tl, br, sq, sq, tl, sq, sq, sq, sq, tl, sq, sq, vl, __, sq, sq, sq, sq, tl, br); + PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")" " BANNERMSG1, + sq, sq, tl, hl, hl, hl, br, __, sq, sq, vl, bl, sq, sq, tl, br, sq, sq, vl, __, bl, hl, hl, sq, sq, tr); + PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")" " BANNERMSG2, + sq, sq, vl, __, __, __, __, __, sq, sq, vl, __, bl, hl, br, __, sq, sq, vl, sq, sq, sq, sq, sq, tl, br); + PrintAndLogEx(NORMAL, " " _BLUE_("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")" " BANNERMSG3, + bl, hl, br, __, __, __, __, __, bl, hl, br, __, __, __, __, __, bl, hl, br, bl, hl, hl, hl, hl, br, __); + break; + } + case ANSI: { + PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗█████╗ ")); + PrintAndLogEx(NORMAL, " " _BLUE_("██╔â•â•██╗████╗ ████║╚â•â•â•██╗")); + PrintAndLogEx(NORMAL, " " _BLUE_("██████╔â•██╔████╔██║ ████╔â•")); + PrintAndLogEx(NORMAL, " " _BLUE_("██╔â•â•â•╠██║╚██╔â•██║ ╚â•â•██╗") " " BANNERMSG1); + PrintAndLogEx(NORMAL, " " _BLUE_("██║ ██║ ╚â•╠██║█████╔â•") " " BANNERMSG2); + PrintAndLogEx(NORMAL, " " _BLUE_("╚â•╠╚â•╠╚â•â•╚â•â•â•â•â• ") " " BANNERMSG3); + break; + } + case ASCII: { + PrintAndLogEx(NORMAL, " ######. ###. ###.#####. "); + PrintAndLogEx(NORMAL, " ##...##.####. ####. ...##."); + PrintAndLogEx(NORMAL, " ######..##.####.##. ####.."); + PrintAndLogEx(NORMAL, " ##..... ##..##..##. ..##." " " BANNERMSG1); + PrintAndLogEx(NORMAL, " ##. ##. .. ##.#####.." " " BANNERMSG2); + PrintAndLogEx(NORMAL, " .. .. .. ..... " " " BANNERMSG3); + break; + } + } } -#endif - static void showBanner(void) { -#ifdef _WIN32 - // If on windows and using UTF-8 then we need utf-8 ascii art for banner. - if (GetConsoleCP() == 65001) { - utf8_showBanner(); - return; - } -#endif - g_printAndLog = PRINTANDLOG_PRINT; - PrintAndLogEx(NORMAL, "\n"); -#if defined(__linux__) || (__APPLE__) || (_WIN32) - PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗ ████╗ ")); - PrintAndLogEx(NORMAL, " " _BLUE_("██╔â•â•██╗████╗ ████║ â•â•█║")); - PrintAndLogEx(NORMAL, " " _BLUE_("██████╔â•██╔████╔██║ ████╔â•")); - PrintAndLogEx(NORMAL, " " _BLUE_("██╔â•â•â•╠██║╚██╔â•██║ â•â•█║") " :snowflake: iceman@icesql.net :coffee:"); - PrintAndLogEx(NORMAL, " " _BLUE_("██║ ██║ ╚â•╠██║ ████╔â•") " https://github.com/rfidresearchgroup/proxmark3/"); - PrintAndLogEx(NORMAL, " " _BLUE_("╚â•╠╚â•╠╚â•╠╚â•â•â•â• ") " pre-release v4.0"); + +#if defined(_WIN32) + if (GetConsoleCP() == 65001) { + // If on Windows and using UTF-8 then we need utf-8 ascii art for banner. + showBanner_logo(UTF8); + } else { + showBanner_logo(ANSI); + } +#elif defined(__linux__) || defined(__APPLE__) + showBanner_logo(ANSI); #else - PrintAndLogEx(NORMAL, " ======. ===. ===. ====."); - PrintAndLogEx(NORMAL, " ==...==.====. ====. ..=."); - PrintAndLogEx(NORMAL, " ======..==.====.==. ====.."); - PrintAndLogEx(NORMAL, " ==..... ==..==..==. ..=. iceman@icesql.net :coffee:"); - PrintAndLogEx(NORMAL, " ==. ==. ... ==. ====.. https://github.com/rfidresearchgroup/proxmark3/"); - PrintAndLogEx(NORMAL, " ... ... ... ..... pre-release v4.0"); + showBanner_logo(ASCII); #endif // PrintAndLogEx(NORMAL, "\nSupport iceman on patreon - https://www.patreon.com/iceman1001/"); // PrintAndLogEx(NORMAL, " on paypal - https://www.paypal.me/iceman1001"); @@ -116,10 +116,11 @@ static void showBanner(void) { static const char *prompt_dev = ""; static const char *prompt_ctx = ""; -static void prompt_compose(char *buf, size_t buflen, const char *prompt_ctx, const char *prompt_dev) { - snprintf(buf, buflen - 1, PROXPROMPT_COMPOSE, prompt_dev, prompt_ctx); +static void prompt_compose(char *buf, size_t buflen, const char *promptctx, const char *promptdev) { + snprintf(buf, buflen - 1, PROXPROMPT_COMPOSE, promptdev, promptctx); } +#ifdef HAVE_READLINE static int check_comm(void) { // If communications thread goes down. Device disconnected then this should hook up PM3 again. if (IsCommunicationThreadDead() && session.pm3_present) { @@ -135,31 +136,35 @@ static int check_comm(void) { } return 0; } +#endif // first slot is always NULL, indicating absence of script when idx=0 -FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0}; -uint8_t cmdscriptfile_idx = 0; -bool cmdscriptfile_stayafter = false; +static FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0}; +static uint8_t cmdscriptfile_idx = 0; +static bool cmdscriptfile_stayafter = false; int push_cmdscriptfile(char *path, bool stayafter) { if (cmdscriptfile_idx == MAX_NESTED_CMDSCRIPT) { PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", path); return PM3_EMALLOC; } - FILE *tmp = fopen(path, "r"); - if (tmp == NULL) + + FILE *f = fopen(path, "r"); + if (f == NULL) return PM3_EFILE; + if (cmdscriptfile_idx == 0) cmdscriptfile_stayafter = stayafter; - cmdscriptfile[++cmdscriptfile_idx] = tmp; + + cmdscriptfile[++cmdscriptfile_idx] = f; return PM3_SUCCESS; } -static FILE *current_cmdscriptfile() { +static FILE *current_cmdscriptfile(void) { return cmdscriptfile[cmdscriptfile_idx]; } -static bool pop_cmdscriptfile() { +static bool pop_cmdscriptfile(void) { fclose(cmdscriptfile[cmdscriptfile_idx]); cmdscriptfile[cmdscriptfile_idx--] = NULL; if (cmdscriptfile_idx == 0) @@ -208,13 +213,15 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { } } +#ifdef HAVE_READLINE char *my_history_path = NULL; - if (searchHomeFilePath(&my_history_path, PROXHISTORY, true) != PM3_SUCCESS) { + if (searchHomeFilePath(&my_history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) { PrintAndLogEx(ERR, "No history will be recorded"); my_history_path = NULL; } else { read_history(my_history_path); } +#endif // loops every time enter is pressed... while (1) { bool printprompt = false; @@ -238,6 +245,7 @@ check_script: if (fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile()) == NULL) { if (!pop_cmdscriptfile()) break; + goto check_script; } else { prompt_ctx = PROXPROMPT_CTX_SCRIPTFILE; @@ -289,12 +297,25 @@ check_script: } else { prompt_ctx = PROXPROMPT_CTX_INTERACTIVE; - rl_event_hook = check_comm; char prompt[PROXPROMPT_MAX_SIZE] = {0}; prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev); char prompt_filtered[PROXPROMPT_MAX_SIZE] = {0}; memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !session.supports_colors); +#ifdef HAVE_READLINE + rl_event_hook = check_comm; cmd = readline(prompt_filtered); +#else + printf("%s", prompt_filtered); + cmd = NULL; + size_t len = 0; + int ret; + if ((ret = getline(&cmd, &len, stdin)) < 0) { + // TODO this happens also when kbd_enter_pressed() is used, with a key pressed or not + printf("GETLINE ERR %i", ret); + free(cmd); + cmd = NULL; + } +#endif fflush(NULL); } } @@ -326,9 +347,13 @@ check_script: } char prompt[PROXPROMPT_MAX_SIZE] = {0}; prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev); - PrintAndLogEx(NORMAL, "%s%s", prompt, cmd); + // always filter RL magic separators if not using readline + char prompt_filtered[PROXPROMPT_MAX_SIZE] = {0}; + memcpy_filter_rlmarkers(prompt_filtered, prompt, sizeof(prompt_filtered)); + PrintAndLogEx(NORMAL, "%s%s", prompt_filtered, cmd); g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; +#ifdef HAVE_READLINE // add to history if not from a script if (!current_cmdscriptfile()) { HIST_ENTRY *entry = history_get(history_length); @@ -337,6 +362,7 @@ check_script: add_history(cmd); } } +#endif // process cmd int ret = CommandReceived(cmd); // exit or quit @@ -363,11 +389,12 @@ check_script: while (current_cmdscriptfile()) pop_cmdscriptfile(); +#ifdef HAVE_READLINE if (my_history_path) { write_history(my_history_path); free(my_history_path); } - +#endif if (cmd) { free(cmd); cmd = NULL; @@ -435,30 +462,36 @@ static void set_my_user_directory(void) { // if not found, default to current directory if (my_user_directory == NULL) { - char *cwd_Buffer = NULL; uint16_t pathLen = FILENAME_MAX; // should be a good starting point bool error = false; + char *cwd_buffer = (char *)calloc(pathLen, sizeof(uint8_t)); - cwd_Buffer = (char *)calloc(pathLen, sizeof(uint8_t)); - - while (!error && (GetCurrentDir(cwd_Buffer, pathLen) == NULL)) { + while (!error && (GetCurrentDir(cwd_buffer, pathLen) == NULL)) { if (errno == ERANGE) { // Need bigger buffer pathLen += 10; // if buffer was too small add 10 characters and try again - cwd_Buffer = realloc(cwd_Buffer, pathLen); + char *tmp = realloc(cwd_buffer, pathLen); + if (tmp == NULL) { + PrintAndLogEx(WARNING, "failed to allocate memory"); + free(cwd_buffer); + return; + } + cwd_buffer = tmp; } else { - error = true; - free(cwd_Buffer); - cwd_Buffer = NULL; + free(cwd_buffer); + return; } - printf("Len... %d\n", pathLen); + PrintAndLogEx(NORMAL, "Len... %d", pathLen); } if (!error) { - for (int i = 0; i < strlen(cwd_Buffer); i++) - if (cwd_Buffer[i] == '\\') cwd_Buffer[i] = '/'; + for (int i = 0; i < strlen(cwd_buffer); i++) { + if (cwd_buffer[i] == '\\') { + cwd_buffer[i] = '/'; + } + } - my_user_directory = cwd_Buffer; + my_user_directory = cwd_buffer; } } } @@ -544,11 +577,11 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ PrintAndLogEx(SUCCESS, "About to use the following file%s:", num_files > 1 ? "s" : ""); for (int i = 0 ; i < num_files; ++i) { - PrintAndLogEx(SUCCESS, " %s", filepaths[i]); + PrintAndLogEx(SUCCESS, " "_YELLOW_("%s"), filepaths[i]); } if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { - PrintAndLogEx(NORMAL, _GREEN_("Found")); + PrintAndLogEx(NORMAL, _GREEN_(" found")); } else { PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); ret = PM3_ETIMEOUT; @@ -572,7 +605,7 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ PrintAndLogEx(NORMAL, ""); } - PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); + PrintAndLogEx(SUCCESS, _CYAN_("Flashing...")); for (int i = 0; i < num_files; i++) { ret = flash_write(&files[i]); @@ -580,7 +613,7 @@ static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[ goto finish; } flash_free(&files[i]); - PrintAndLogEx(NORMAL, "\n"); + PrintAndLogEx(NORMAL, ""); } finish: @@ -592,9 +625,9 @@ finish2: free(filepaths[i]); } if (ret == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, _BLUE_("All done.")); + PrintAndLogEx(SUCCESS, _CYAN_("All done")); else - PrintAndLogEx(ERR, "Aborted on error."); + PrintAndLogEx(ERR, "Aborted on error"); PrintAndLogEx(NORMAL, "\nHave a nice day!"); return ret; } @@ -671,12 +704,14 @@ int main(int argc, char *argv[]) { char *port = NULL; uint32_t speed = 0; +#ifdef HAVE_READLINE /* initialize history */ using_history(); #ifdef RL_STATE_READCMD rl_extend_line_buffer(1024); -#endif +#endif // RL_STATE_READCMD +#endif // HAVE_READLINE char *exec_name = argv[0]; #if defined(_WIN32) @@ -690,6 +725,7 @@ int main(int argc, char *argv[]) { bool flash_mode = false; bool flash_can_write_bl = false; + bool debug_mode_forced = false; int flash_num_files = 0; char *flash_filenames[FLASH_MAX_FILES]; @@ -697,16 +733,6 @@ int main(int argc, char *argv[]) { set_my_executable_path(); set_my_user_directory(); -#ifdef USE_PREFERENCE_FILE - // Load Settings and assign - // This will allow the command line to override the settings.json values - preferences_load(); - // quick patch for debug level - g_debugMode = session.client_debug_level; - // settings_save (); - // End Settings -#endif - for (int i = 1; i < argc; i++) { if (argv[i][0] != '-') { @@ -778,6 +804,7 @@ int main(int argc, char *argv[]) { return 1; } g_debugMode = demod; + debug_mode_forced = true; i++; continue; } @@ -885,6 +912,17 @@ int main(int argc, char *argv[]) { return 1; } +#ifdef USE_PREFERENCE_FILE + // Load Settings and assign + // This will allow the command line to override the settings.json values + preferences_load(); + // quick patch for debug level + if (! debug_mode_forced) + g_debugMode = session.client_debug_level; + // settings_save (); + // End Settings +#endif + #ifndef USE_PREFERENCE_FILE // comment next 2 lines to use session values set from settings_load session.supports_colors = DetectWindowsAnsiSupport(); @@ -893,7 +931,7 @@ int main(int argc, char *argv[]) { session.stdinOnTTY = isatty(STDIN_FILENO); session.stdoutOnTTY = isatty(STDOUT_FILENO); -#if defined(__linux__) || (__APPLE__) +#if defined(__linux__) || defined(__APPLE__) // it's okay to use color if: // * Linux or OSX // * Not redirected to a file but printed to term diff --git a/client/src/proxmark3.h b/client/src/proxmark3.h index 9f4c767e2..6d7e9dfb4 100644 --- a/client/src/proxmark3.h +++ b/client/src/proxmark3.h @@ -12,21 +12,21 @@ #ifndef PROXMARK3_H__ #define PROXMARK3_H__ +#include #include "common.h" #define PROXPROMPT_MAX_SIZE 255 #define PROXPROMPT_COMPOSE "[" "%s%s" "] pm3 --> " -#define PROXPROMPT_CTX_SCRIPTFILE "|" _GREEN_("script") -#define PROXPROMPT_CTX_SCRIPTCMD "|" _GREEN_("script") -#define PROXPROMPT_CTX_STDIN "|" _GREEN_("script") +#define PROXPROMPT_CTX_SCRIPTFILE "|" _RL_GREEN_("script") +#define PROXPROMPT_CTX_SCRIPTCMD "|" _RL_GREEN_("script") +#define PROXPROMPT_CTX_STDIN "|" _RL_GREEN_("script") #define PROXPROMPT_CTX_INTERACTIVE "" -#define PROXPROMPT_DEV_USB _BOLD_GREEN_("usb") -#define PROXPROMPT_DEV_FPC _BOLD_GREEN_("fpc") -#define PROXPROMPT_DEV_OFFLINE _BOLD_RED_("offline") - +#define PROXPROMPT_DEV_USB _RL_BOLD_GREEN_("usb") +#define PROXPROMPT_DEV_FPC _RL_BOLD_GREEN_("fpc") +#define PROXPROMPT_DEV_OFFLINE _RL_BOLD_RED_("offline") #define PROXHISTORY "history.txt" #define PROXLOG "log_%Y%m%d.txt" @@ -37,6 +37,14 @@ extern "C" { #endif +// Load all settings into memory (struct) +#ifdef _WIN32 +#include +#define GetCurrentDir _getcwd +#else +#define GetCurrentDir getcwd +#endif + int push_cmdscriptfile(char *path, bool stayafter); const char *get_my_executable_path(void); const char *get_my_executable_directory(void); diff --git a/client/src/scripting.c b/client/src/scripting.c index 756799626..a1fdb8a31 100644 --- a/client/src/scripting.c +++ b/client/src/scripting.c @@ -12,15 +12,17 @@ #include #include +#include #include "lauxlib.h" #include "cmdmain.h" +#include "proxmark3.h" #include "comms.h" #include "mifare/mifarehost.h" #include "crc.h" #include "crc64.h" -#include "mbedtls/sha1.h" -#include "mbedtls/aes.h" +#include "sha1.h" +#include "aes.h" #include "cmdcrc.h" #include "cmdhfmfhard.h" #include "cmdhfmfu.h" @@ -28,11 +30,12 @@ #include "mifare/ndef.h" // ndef parsing #include "commonutil.h" #include "ui.h" -#include "proxmark3.h" + #include "crc16.h" #include "protocols.h" #include "fileutils.h" // searchfile #include "cmdlf.h" // lf_config +#include "generator.h" static int returnToLuaWithError(lua_State *L, const char *fmt, ...) { char buffer[200]; @@ -911,6 +914,12 @@ static int l_detect_prng(lua_State *L) { * @return */ static int l_keygen_algoD(lua_State *L) { + //Check number of arguments + int n = lua_gettop(L); + if (n != 1) { + return returnToLuaWithError(L, "Only UID"); + } + size_t size; uint32_t tmp; const char *p_uid = luaL_checklstring(L, 1, &size); @@ -946,7 +955,7 @@ static int l_T55xx_readblock(lua_State *L) { if (n != 4) return returnToLuaWithError(L, "Wrong number of arguments, got %d bytes, expected 4", n); - uint32_t block, usepage1, override, password; + uint32_t block, usepage1, override, password = 0; bool usepwd; size_t size; @@ -1128,6 +1137,9 @@ static int l_remark(lua_State *L) { return 1; } +// 1. filename +// 2. extension +// output: full search path to file static int l_searchfile(lua_State *L) { //Check number of arguments int n = lua_gettop(L); @@ -1153,6 +1165,40 @@ static int l_searchfile(lua_State *L) { return 1; } +static int l_ud(lua_State *L) { + const char *ud = get_my_user_directory(); + lua_pushstring(L, ud); + return 1; +} +static int l_ewd(lua_State *L) { + const char *ewd = get_my_executable_directory(); + lua_pushstring(L, ewd); + return 1; +} +static int l_cwd(lua_State *L) { + + uint16_t path_len = FILENAME_MAX; // should be a good starting point + bool error = false; + char *cwd = (char *)calloc(path_len, sizeof(uint8_t)); + + while (!error && (GetCurrentDir(cwd, path_len) == NULL)) { + if (errno == ERANGE) { // Need bigger buffer + path_len += 10; // if buffer was too small add 10 characters and try again + cwd = realloc(cwd, path_len); + if (cwd == NULL) { + free(cwd); + return returnToLuaWithError(L, "Failed to allocate memory"); + } + } else { + free(cwd); + return returnToLuaWithError(L, "Failed to get current working directory"); + } + } + lua_pushstring(L, cwd); + free(cwd); + return 1; +} + /** * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be * able to do "require('foobar')" if foobar.lua is within lualibs folder. @@ -1214,6 +1260,9 @@ int set_pm3_libraries(lua_State *L) { {"ndefparse", l_ndefparse}, {"fast_push_mode", l_fast_push_mode}, {"search_file", l_searchfile}, + {"cwd", l_cwd}, + {"ewd", l_ewd}, + {"ud", l_ud}, {"rem", l_remark}, {NULL, NULL} }; diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index a2b324b49..1a6cf32a0 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -48,10 +48,16 @@ #include #include #include -#include "sys/socket.h" -#include "sys/un.h" +#include +#include + +#ifdef HAVE_BLUEZ +#include +#include +#endif #include "comms.h" +#include "ui.h" // Taken from https://github.com/unbit/uwsgi/commit/b608eb1772641d525bfde268fe9d6d8d0d5efde7 #ifndef SOL_TCP @@ -71,8 +77,8 @@ struct timeval timeout = { .tv_usec = UART_FPC_CLIENT_RX_TIMEOUT_MS * 1000 }; -uint32_t newtimeout_value = 0; -bool newtimeout_pending = false; +static uint32_t newtimeout_value = 0; +static bool newtimeout_pending = false; int uart_reconfigure_timeouts(uint32_t value) { newtimeout_value = value; @@ -82,17 +88,36 @@ int uart_reconfigure_timeouts(uint32_t value) { serial_port uart_open(const char *pcPortName, uint32_t speed) { serial_port_unix *sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t)); - if (sp == 0) return INVALID_SERIAL_PORT; + + if (sp == 0) { + PrintAndLogEx(ERR, "UART failed to allocate memory"); + return INVALID_SERIAL_PORT; + } // init timeouts timeout.tv_usec = UART_FPC_CLIENT_RX_TIMEOUT_MS * 1000; - if (memcmp(pcPortName, "tcp:", 4) == 0) { - struct addrinfo *addr = NULL, *rp; - char *addrstr = strdup(pcPortName + 4); + char *prefix = strdup(pcPortName); + if (prefix == NULL) { + PrintAndLogEx(ERR, "error: malloc"); + free(sp); + return INVALID_SERIAL_PORT; + } + str_lower(prefix); + if (memcmp(prefix, "tcp:", 4) == 0) { + free(prefix); + + if (strlen(pcPortName) <= 4) { + free(sp); + return INVALID_SERIAL_PORT; + } + + struct addrinfo *addr = NULL, *rp; + + char *addrstr = strdup(pcPortName + 4); if (addrstr == NULL) { - printf("Error: strdup\n"); + PrintAndLogEx(ERR, "error: malloc"); free(sp); return INVALID_SERIAL_PORT; } @@ -116,7 +141,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { int s = getaddrinfo(addrstr, portstr, &info, &addr); if (s != 0) { - printf("Error: getaddrinfo: %s\n", gai_strerror(s)); + PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); freeaddrinfo(addr); free(addrstr); free(sp); @@ -137,7 +162,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { } if (rp == NULL) { /* No address succeeded */ - printf("Error: Could not connect\n"); + PrintAndLogEx(ERR, "error: Could not connect"); freeaddrinfo(addr); free(addrstr); free(sp); @@ -158,11 +183,61 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { return sp; } + if (memcmp(prefix, "bt:", 3) == 0) { + free(prefix); + +#ifdef HAVE_BLUEZ + if (strlen(pcPortName) != 20) { + free(sp); + return INVALID_SERIAL_PORT; + } + + char *addrstr = strndup(pcPortName + 3, 17); + if (addrstr == NULL) { + PrintAndLogEx(ERR, "error: malloc"); + free(sp); + return INVALID_SERIAL_PORT; + } + + struct sockaddr_rc addr = { 0 }; + addr.rc_family = AF_BLUETOOTH; + addr.rc_channel = (uint8_t) 1; + if (str2ba(addrstr, &addr.rc_bdaddr) != 0) { + PrintAndLogEx(ERR, "Invalid Bluetooth MAC address " _RED_("%s"), addrstr); + free(addrstr); + free(sp); + return INVALID_SERIAL_PORT; + } + int sfd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sfd == -1) { + PrintAndLogEx(ERR, "Error opening Bluetooth socket"); + free(addrstr); + free(sp); + return INVALID_SERIAL_PORT; + } + if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + PrintAndLogEx(ERR, "Error: cannot connect device " _YELLOW_("%s") " over Bluetooth", addrstr); + close(sfd); + free(addrstr); + free(sp); + return INVALID_SERIAL_PORT; + } + + sp->fd = sfd; + return sp; +#else // HAVE_BLUEZ + PrintAndLogEx(ERR, "Sorry, this client doesn't support native Bluetooth addresses"); + free(sp); + return INVALID_SERIAL_PORT; +#endif // HAVE_BLUEZ + } // The socket for abstract namespace implement. // Is local socket buffer, not a TCP or any net connection! // so, you can't connect with address like: 127.0.0.1, or any IP // see http://man7.org/linux/man-pages/man7/unix.7.html - if (memcmp(pcPortName, "socket:", 7) == 0) { + if (memcmp(prefix, "socket:", 7) == 0) { + free(prefix); + if (strlen(pcPortName) <= 7) { free(sp); return INVALID_SERIAL_PORT; @@ -203,6 +278,8 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { return sp; } + free(prefix); + sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (sp->fd == -1) { uart_close(sp); @@ -259,7 +336,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { speed = 115200; if (!uart_set_speed(sp, speed)) { uart_close(sp); - printf("[!] UART error while setting baudrate\n"); + PrintAndLogEx(ERR, "UART error while setting baudrate"); return INVALID_SERIAL_PORT; } } diff --git a/client/src/uart/uart_win32.c b/client/src/uart/uart_win32.c index bbb5bfcfa..93ee2f126 100644 --- a/client/src/uart/uart_win32.c +++ b/client/src/uart/uart_win32.c @@ -43,6 +43,7 @@ #include #include "comms.h" +#include "ui.h" // The windows serial port implementation #ifdef _WIN32 @@ -90,7 +91,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { serial_port_windows *sp = calloc(sizeof(serial_port_windows), sizeof(uint8_t)); if (sp == 0) { - printf("[!] UART failed to allocate memory\n"); + PrintAndLogEx(WARNING, "UART failed to allocate memory\n"); return INVALID_SERIAL_PORT; } // Copy the input "com?" to "\\.\COM?" format @@ -111,14 +112,14 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { sp->dcb.DCBlength = sizeof(DCB); if (!BuildCommDCBA("baud=115200 parity=N data=8 stop=1", &sp->dcb)) { uart_close(sp); - printf("[!] UART error cdc setup\n"); + PrintAndLogEx(WARNING, "UART error cdc setup\n"); return INVALID_SERIAL_PORT; } // Update the active serial port if (!SetCommState(sp->hPort, &sp->dcb)) { uart_close(sp); - printf("[!] UART error while setting com state\n"); + PrintAndLogEx(WARNING, "UART error while setting com state\n"); return INVALID_SERIAL_PORT; } @@ -130,7 +131,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { speed = 115200; if (!uart_set_speed(sp, speed)) { uart_close(sp); - printf("[!] UART error while setting baudrate\n"); + PrintAndLogEx(WARNING, "UART error while setting baudrate\n"); return INVALID_SERIAL_PORT; } } diff --git a/client/src/ui.c b/client/src/ui.c index 5d0e28aec..68f0eab24 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -22,7 +22,7 @@ #include #include -#ifndef ANDROID +#ifdef HAVE_READLINE #include #endif @@ -44,7 +44,7 @@ session_arg_t session; double CursorScaleFactor = 1; int PlotGridX = 0, PlotGridY = 0, PlotGridXdefault = 64, PlotGridYdefault = 64; uint32_t CursorCPos = 0, CursorDPos = 0; -bool flushAfterWrite = 0; +static bool flushAfterWrite = 0; int GridOffset = 0; bool GridLocked = false; bool showDemod = true; @@ -54,17 +54,21 @@ pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; static void fPrintAndLog(FILE *stream, const char *fmt, ...); // needed by flasher, so let's put it here instead of fileutils.c -int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) { +int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home) { if (foundpath == NULL) return PM3_EINVARG; + const char *user_path = get_my_user_directory(); if (user_path == NULL) { fprintf(stderr, "Could not retrieve $HOME from the environment\n"); return PM3_EFILE; } - char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + 1, sizeof(char)); + + size_t pathlen = strlen(user_path) + strlen(PM3_USER_DIRECTORY) + 1; + char *path = calloc(pathlen, sizeof(char)); if (path == NULL) return PM3_EMALLOC; + strcpy(path, user_path); strcat(path, PM3_USER_DIRECTORY); @@ -96,11 +100,54 @@ int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) return PM3_EFILE; } } + if (subdir != NULL) { + pathlen += strlen(subdir); + char *tmp = realloc(path, pathlen * sizeof(char)); + if (tmp == NULL) { + free(path); + return PM3_EMALLOC; + } + path = tmp; + strcat(path, subdir); + +#ifdef _WIN32 + // Mingw _stat fails if path ends with /, so let's use a stripped path + if (path[strlen(path) - 1] == '/') { + path[strlen(path) - 1] = '\0'; + result = _stat(path, &st); + path[strlen(path)] = '/'; + } else { + result = _stat(path, &st); + } +#else + result = stat(path, &st); +#endif + if ((result != 0) && create_home) { + +#ifdef _WIN32 + if (_mkdir(path)) +#else + if (mkdir(path, 0700)) +#endif + { + fprintf(stderr, "Could not create user directory %s\n", path); + free(path); + return PM3_EFILE; + } + } + } + if (filename == NULL) { *foundpath = path; return PM3_SUCCESS; } - path = realloc(path, (strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(filename) + 1) * sizeof(char)); + pathlen += strlen(filename); + char *tmp = realloc(path, pathlen * sizeof(char)); + if (tmp == NULL) { + free(path); + return PM3_EMALLOC; + } + path = tmp; strcat(path, filename); *foundpath = path; return PM3_SUCCESS; @@ -129,7 +176,7 @@ void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) { PrintAndLogEx(NORMAL, "%s", buff); } -uint8_t PrintAndLogEx_spinidx = 0; +static uint8_t PrintAndLogEx_spinidx = 0; void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { @@ -169,6 +216,8 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { strncpy(prefix, _BLUE_("[#] "), sizeof(prefix) - 1); break; case HINT: + strncpy(prefix, _YELLOW_("[?] "), sizeof(prefix) - 1); + break; case SUCCESS: strncpy(prefix, _GREEN_("[+] "), sizeof(prefix) - 1); break; @@ -248,8 +297,6 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { } static void fPrintAndLog(FILE *stream, const char *fmt, ...) { - char *saved_line; - int saved_point; va_list argptr; static FILE *logfile = NULL; static int logging = 1; @@ -266,21 +313,21 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { time_t now = time(NULL); timenow = gmtime(&now); strftime(filename, sizeof(filename), PROXLOG, timenow); - if (searchHomeFilePath(&my_logfile_path, filename, true) != PM3_SUCCESS) { - fprintf(stderr, "[-] Logging disabled!\n\n"); + if (searchHomeFilePath(&my_logfile_path, LOGS_SUBDIR, filename, true) != PM3_SUCCESS) { + printf(_YELLOW_("[-]") " Logging disabled!\n"); my_logfile_path = NULL; logging = 0; } else { logfile = fopen(my_logfile_path, "a"); if (logfile == NULL) { - fprintf(stderr, "[-] Can't open logfile %s, logging disabled!\n", my_logfile_path); + printf(_YELLOW_("[-]") " Can't open logfile %s, logging disabled!\n", my_logfile_path); logging = 0; } else { if (session.supports_colors) { - printf(_YELLOW_("[=] ") "Session log " _YELLOW_("%s") "\n", my_logfile_path); + printf(_YELLOW_("[=]") " Session log " _YELLOW_("%s") "\n", my_logfile_path); } else { - printf("[=] Session log %s\n", my_logfile_path); + printf(_YELLOW_("[=]") " Session log %s\n", my_logfile_path); } } @@ -295,6 +342,8 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { #ifdef RL_STATE_READCMD // We are using GNU readline. libedit (OSX) doesn't support this flag. int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0; + char *saved_line; + int saved_point; if (need_hack) { saved_point = rl_point; @@ -314,7 +363,6 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { if (g_printAndLog & PRINTANDLOG_PRINT) { memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), session.emoji_mode); fprintf(stream, "%s", buffer3); - fprintf(stream, " "); // cleaning prompt fprintf(stream, "\n"); } @@ -351,6 +399,18 @@ void SetFlushAfterWrite(bool value) { flushAfterWrite = value; } +void memcpy_filter_rlmarkers(void *dest, const void *src, size_t n) { + uint8_t *rdest = (uint8_t *)dest; + uint8_t *rsrc = (uint8_t *)src; + uint16_t si = 0; + for (uint16_t i = 0; i < n; i++) { + if ((rsrc[i] == '\001') || (rsrc[i] == '\002')) + // skip readline special markers + continue; + rdest[si++] = rsrc[i]; + } +} + void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter) { if (filter) { // Filter out ANSI sequences on these OS @@ -412,10 +472,13 @@ static bool emojify_token(const char *token, uint8_t token_length, const char ** } break; } - default: {// ERASE + case ERASE: { *emojified_token_length = 0; break; } + case ALIAS: { // should never happen + return false; + } } return true; } @@ -481,10 +544,11 @@ void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode } } memcpy(rdest + si, current_token, current_token_length); - si += current_token_length; } } +/* +// If reactivated, beware it doesn't compile on Android (DXL) void iceIIR_Butterworth(int *data, const size_t len) { int *output = (int *) calloc(sizeof(int) * len, sizeof(uint8_t)); @@ -533,6 +597,7 @@ void iceIIR_Butterworth(int *data, const size_t len) { free(output); } +*/ void iceSimple_Filter(int *data, const size_t len, uint8_t k) { // ref: http://www.edn.com/design/systems-design/4320010/A-simple-software-lowpass-filter-suits-embedded-system-applications diff --git a/client/src/ui.h b/client/src/ui.h index e47031d70..60064c0aa 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -11,10 +11,14 @@ #ifndef UI_H__ #define UI_H__ -#include "common.h" #include +#include "common.h" #include "ansi.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _USE_MATH_DEFINES typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t; @@ -42,32 +46,26 @@ typedef struct { } session_arg_t; extern session_arg_t session; - +extern bool showDemod; #ifndef M_PI #define M_PI 3.14159265358979323846264338327 #endif #define MAX_PRINT_BUFFER 2048 -void ShowGui(void); -void HideGraphWindow(void); -void ShowGraphWindow(void); -void RepaintGraphWindow(void); void PrintAndLogOptions(const char *str[][2], size_t size, size_t space); void PrintAndLogEx(logLevel_t level, const char *fmt, ...); void SetFlushAfterWrite(bool value); void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter); +void memcpy_filter_rlmarkers(void *dest, const void *src, size_t n); void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode); -extern double CursorScaleFactor; -extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, GridOffset; -extern uint32_t CursorCPos, CursorDPos; -extern bool GridLocked; -extern bool showDemod; - -int searchHomeFilePath(char **foundpath, const char *filename, bool create_home); +int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home); extern pthread_mutex_t print_lock; void iceIIR_Butterworth(int *data, const size_t len); void iceSimple_Filter(int *data, const size_t len, uint8_t k); +#ifdef __cplusplus +} +#endif #endif diff --git a/client/src/util.c b/client/src/util.c index 3d0c6bd87..5e1e55d67 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -80,55 +80,6 @@ int kbd_enter_pressed(void) { } #endif -// log files functions - -// open, appped and close logfile -void AddLogLine(const char *fn, const char *data, const char *c) { - FILE *f = NULL; - char filename[FILE_PATH_SIZE] = {0x00}; - int len = 0; - - len = strlen(fn); - if (len > FILE_PATH_SIZE) - len = FILE_PATH_SIZE; - memcpy(filename, fn, len); - - f = fopen(filename, "a"); - if (!f) { - PrintAndLogEx(ERR, "Could not append log file" _YELLOW_("%s"), filename); - return; - } - - fprintf(f, "%s", data); - fprintf(f, "%s\n", c); - fflush(f); - fclose(f); -} - -void AddLogHex(const char *fn, const char *extData, const uint8_t *data, const size_t len) { - AddLogLine(fn, extData, sprint_hex(data, len)); -} - -void AddLogUint64(const char *fn, const char *data, const uint64_t value) { - char buf[20] = {0}; - memset(buf, 0x00, sizeof(buf)); - sprintf(buf, "%016" PRIx64 "", value); - AddLogLine(fn, data, buf); -} - -void AddLogCurrentDT(const char *fn) { - char buf[20] = {0}; - struct tm *ct, tm_buf; - time_t now = time(NULL); -#if defined(_WIN32) - ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL; -#else - ct = gmtime_r(&now, &tm_buf); -#endif - strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ct); - AddLogLine(fn, "\nanticollision: ", buf); -} - // create filename on hex uid. // param *fn - pointer to filename char array // param *uid - pointer to uid byte array @@ -195,9 +146,9 @@ void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex size_t i; memset(tmp, 0x00, hex_max_len); - size_t maxLen = (hex_len > hex_max_len) ? hex_max_len : hex_len; + size_t max_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; - for (i = 0; i < maxLen; ++i, tmp += 2 + spaces_between) { + for (i = 0; i < max_len; ++i, tmp += 2 + spaces_between) { sprintf(tmp, (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]); for (size_t j = 0; j < spaces_between; j++) @@ -205,10 +156,12 @@ void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex } i *= (2 + spaces_between); - size_t minStrLen = min_str_len > i ? min_str_len : 0; - if (minStrLen > hex_max_len) - minStrLen = hex_max_len; - for (; i < minStrLen; i++, tmp += 1) + + size_t mlen = min_str_len > i ? min_str_len : 0; + if (mlen > hex_max_len) + mlen = hex_max_len; + + for (; i < mlen; i++, tmp += 1) sprintf(tmp, " "); // remove last space @@ -823,12 +776,6 @@ void wiegand_add_parity_swapped(uint8_t *target, uint8_t *source, uint8_t length *(target) = GetParity(source + length / 2, EVEN, length / 2); } -// xor two arrays together for len items. The dst array contains the new xored values. -void xor(unsigned char *dst, unsigned char *src, size_t len) { - for (; len > 0; len--, dst++, src++) - *dst ^= *src; -} - // Pack a bitarray into a uint32_t. uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bits) { diff --git a/client/src/util.h b/client/src/util.h index fb31e6013..c15183734 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -21,19 +21,14 @@ # define FILE_PATH_SIZE 1000 #endif -uint8_t g_debugMode; -uint8_t g_printAndLog; +extern uint8_t g_debugMode; +extern uint8_t g_printAndLog; #define PRINTANDLOG_PRINT 1 #define PRINTANDLOG_LOG 2 int kbd_enter_pressed(void); -void AddLogLine(const char *fn, const char *data, const char *c); -void AddLogHex(const char *fn, const char *extData, const uint8_t *data, const size_t len); -void AddLogUint64(const char *fn, const char *data, const uint64_t value); -void AddLogCurrentDT(const char *fn); void FillFileNameByUID(char *filenamePrefix, const uint8_t *uid, const char *ext, const int uidlen); - // fill buffer from structure [{uint8_t data, size_t length},...] int FillBuffer(uint8_t *data, size_t maxDataLength, size_t *dataLength, ...); @@ -87,7 +82,6 @@ void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length); void wiegand_add_parity_swapped(uint8_t *target, uint8_t *source, uint8_t length); //void xor(unsigned char *dst, unsigned char *src, size_t len); -int32_t le24toh(uint8_t data[3]); uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bits); uint64_t HornerScheme(uint64_t num, uint64_t divider, uint64_t factor); diff --git a/client/src/util_darwin.h b/client/src/util_darwin.h index 709680cdc..001282578 100644 --- a/client/src/util_darwin.h +++ b/client/src/util_darwin.h @@ -11,9 +11,16 @@ #ifndef UTIL_DARWIN_H__ #define UTIL_DARWIN_H__ +#ifdef __cplusplus +extern "C" { +#endif + void disableAppNap(const char *reason); void enableAppNap(void); void makeUnfocusable(void); void makeFocusable(void); +#ifdef __cplusplus +} +#endif #endif diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index 0c3c09fb6..7c25cd7ff 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -597,12 +597,12 @@ static const cardformat_t FormatTable[] = { {"H10320", Pack_H10320, Unpack_H10320, "HID H10320 36-bit BCD", {1, 0, 0, 0, 1}}, // from Proxmark forums {"H10302", Pack_H10302, Unpack_H10302, "HID H10302 37-bit huge ID", {1, 0, 0, 0, 1}}, // from Proxmark forums {"H10304", Pack_H10304, Unpack_H10304, "HID H10304 37-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack - {"P10001", Pack_P10001, Unpack_P10001, "HID P10001 Honeywell 40-bit" }, // from cardinfo.barkweb.com.au + {"P10001", Pack_P10001, Unpack_P10001, "HID P10001 Honeywell 40-bit", {1, 1, 0, 1, 0}}, // from cardinfo.barkweb.com.au {"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit standard layout", {1, 1, 0, 0, 1}}, // imported from old pack/unpack {NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array }; -void HIDListFormats() { +void HIDListFormats(void) { if (FormatTable[0].Name == NULL) return; diff --git a/client/src/wiegand_formats.h b/client/src/wiegand_formats.h index 2b9b3df05..4ac36fdcf 100644 --- a/client/src/wiegand_formats.h +++ b/client/src/wiegand_formats.h @@ -39,7 +39,7 @@ typedef struct { cardformatdescriptor_t Fields; } cardformat_t; -void HIDListFormats(); +void HIDListFormats(void); int HIDFindCardFormat(const char *format); cardformat_t HIDGetCardFormat(int idx); bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed); diff --git a/client/src/wiegand_formatutils.c b/client/src/wiegand_formatutils.c index 836da717d..0d58e9d6f 100644 --- a/client/src/wiegand_formatutils.c +++ b/client/src/wiegand_formatutils.c @@ -64,7 +64,7 @@ bool set_bit_by_position(wiegand_message_t *data, bool value, uint8_t pos) { * If the definition of the wiegand_message struct changes, this function must also * be updated to match. */ -void message_datacopy(wiegand_message_t *src, wiegand_message_t *dest) { +static void message_datacopy(wiegand_message_t *src, wiegand_message_t *dest) { dest->Bot = src->Bot; dest->Mid = src->Mid; dest->Top = src->Top; @@ -80,7 +80,7 @@ void message_datacopy(wiegand_message_t *src, wiegand_message_t *dest) { uint64_t get_linear_field(wiegand_message_t *data, uint8_t firstBit, uint8_t length) { uint64_t result = 0; for (uint8_t i = 0; i < length; i++) { - result = (result << 1) | get_bit_by_position(data, firstBit + i); + result = (result << 1) | (get_bit_by_position(data, firstBit + i)); } return result; } @@ -137,9 +137,6 @@ static uint8_t get_length_from_header(wiegand_message_t *data) { printf("a\n"); hfmt = data->Mid & 0x0000001F; len = 32; - } else if (data->Top == 0 && data->Mid == 0) { //< 32 bits - hfmt = data->Bot; - len = 0; } else { hfmt = data->Bot; len = 0; diff --git a/common/commonutil.c b/common/commonutil.c index 3ff2b4eb4..14f2d58e5 100644 --- a/common/commonutil.c +++ b/common/commonutil.c @@ -8,6 +8,40 @@ // Utility functions used in many places, not specific to any piece of code. //----------------------------------------------------------------------------- #include "commonutil.h" +#include + +/* Similar to FpgaGatherVersion this formats stored version information + * into a string representation. It takes a pointer to the struct version_information, + * verifies the magic properties, then stores a formatted string, prefixed by + * prefix in dst. + */ +void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_info) { + struct version_information *v = (struct version_information *)version_info; + dst[0] = 0; + strncat(dst, prefix, len - 1); + if (v->magic != VERSION_INFORMATION_MAGIC) { + strncat(dst, "Missing/Invalid version information", len - strlen(dst) - 1); + return; + } + if (v->versionversion != 1) { + strncat(dst, "Version information not understood", len - strlen(dst) - 1); + return; + } + if (!v->present) { + strncat(dst, "Version information not available", len - strlen(dst) - 1); + return; + } + + strncat(dst, v->gitversion, len - strlen(dst) - 1); + if (v->clean == 0) { + strncat(dst, "-unclean", len - strlen(dst) - 1); + } else if (v->clean == 2) { + strncat(dst, "-suspect", len - strlen(dst) - 1); + } + + strncat(dst, " ", len - strlen(dst) - 1); + strncat(dst, v->buildtime, len - strlen(dst) - 1); +} /* ref http://www.csm.ornl.gov/~dunigan/crc.html @@ -83,7 +117,7 @@ void lsl(uint8_t *data, size_t len) { data[len - 1] <<= 1; } -int32_t le24toh(uint8_t data[3]) { +uint32_t le24toh(uint8_t data[3]) { return (data[2] << 16) | (data[1] << 8) | data[0]; } diff --git a/common/commonutil.h b/common/commonutil.h index a22486fff..fdd2ac065 100644 --- a/common/commonutil.h +++ b/common/commonutil.h @@ -41,6 +41,9 @@ # define NTIME(n) for (int _index = 0; _index < n; _index++) #endif +extern struct version_information version_information; +void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_info); + uint32_t reflect(uint32_t v, int b); // used in crc.c ... uint8_t reflect8(uint8_t b); // dedicated 8bit reversal uint16_t reflect16(uint16_t b); // dedicated 16bit reversal @@ -50,7 +53,7 @@ uint64_t bytes_to_num(uint8_t *src, size_t len); void rol(uint8_t *data, const size_t len); void lsl(uint8_t *data, size_t len); -int32_t le24toh(uint8_t data[3]); +uint32_t le24toh(uint8_t data[3]); void htole24(uint32_t val, uint8_t data[3]); #endif diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index e697b68f0..0d7aaa49e 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -26,7 +26,7 @@ #if !defined LOWMEM && defined __GNUC__ static uint8_t filterlut[1 << 20]; -static void __attribute__((constructor)) fill_lut() { +static void __attribute__((constructor)) fill_lut(void) { uint32_t i; for (i = 0; i < 1 << 20; ++i) filterlut[i] = filter(i); diff --git a/common/crapto1/crapto1.h b/common/crapto1/crapto1.h index b6be544a5..708ddb033 100644 --- a/common/crapto1/crapto1.h +++ b/common/crapto1/crapto1.h @@ -66,6 +66,9 @@ bool validate_prng_nonce(uint32_t nonce); #define LF_POLY_EVEN (0x870804) #define BIT(x, n) ((x) >> (n) & 1) #define BEBIT(x, n) BIT(x, (n) ^ 24) +#ifdef __OPTIMIZE_SIZE__ +int filter(uint32_t const x); +#else static inline int filter(uint32_t const x) { uint32_t f; @@ -77,3 +80,4 @@ static inline int filter(uint32_t const x) { return BIT(0xEC57E80A, f); } #endif +#endif diff --git a/common/crapto1/crypto1.c b/common/crapto1/crypto1.c index dd5541b29..866a0fb98 100644 --- a/common/crapto1/crypto1.c +++ b/common/crapto1/crypto1.c @@ -18,10 +18,22 @@ Copyright (C) 2008-2008 bla */ #include - #include "crapto1.h" #include "parity.h" +#ifdef __OPTIMIZE_SIZE__ +int filter(uint32_t const x) { + uint32_t f; + + f = 0xf22c0 >> (x & 0xf) & 16; + f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8; + f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4; + f |= 0x1e458 >> (x >> 12 & 0xf) & 2; + f |= 0x0d938 >> (x >> 16 & 0xf) & 1; + return BIT(0xEC57E80A, f); +} +#endif + #define SWAPENDIAN(x)\ (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16) @@ -34,7 +46,6 @@ void crypto1_init(struct Crypto1State *state, uint64_t key) { state->odd = state->odd << 1 | BIT(key, (i - 1) ^ 7); state->even = state->even << 1 | BIT(key, i ^ 7); } - return; } void crypto1_deinit(struct Crypto1State *state) { @@ -42,9 +53,9 @@ void crypto1_deinit(struct Crypto1State *state) { state->even = 0; } -#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() +#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks calloc()/free() struct Crypto1State *crypto1_create(uint64_t key) { - struct Crypto1State *state = malloc(sizeof(*state)); + struct Crypto1State *state = calloc(sizeof(*state), sizeof(uint8_t)); if (!state) return NULL; crypto1_init(state, key); return state; diff --git a/common/crc32.c b/common/crc32.c index 440bed910..baf6ddd28 100644 --- a/common/crc32.c +++ b/common/crc32.c @@ -23,8 +23,10 @@ void crc32_ex(const uint8_t *data, const size_t len, uint8_t *crc) { for (size_t i = 0; i < len; i++) { crc32_byte(&desfire_crc, data[i]); } - - *((uint32_t *)(crc)) = htole32(desfire_crc); + uint32_t crctmp = htole32(desfire_crc); + for (size_t i = 0; i < sizeof(uint32_t); i++) { + crc[i] = ((uint8_t *) &crctmp)[i]; + } } void crc32_append(uint8_t *data, const size_t len) { diff --git a/common_arm/default_version.c b/common/default_version.c similarity index 58% rename from common_arm/default_version.c rename to common/default_version.c index b4b8ae17d..0f42590e8 100644 --- a/common_arm/default_version.c +++ b/common/default_version.c @@ -1,6 +1,12 @@ -#include "proxmark3_arm.h" +#include "common.h" /* This is the default version.c file that Makefile.common falls back to if neither sh nor perl are available */ -const struct version_information __attribute__((section(".version_information"))) version_information = { +#ifndef ON_DEVICE +#define SECTVERSINFO +#else +#define SECTVERSINFO __attribute__((section(".version_information"))) +#endif + +const struct version_information SECTVERSINFO version_information = { VERSION_INFORMATION_MAGIC, 1, /* version 1 */ 0, /* version information not present */ diff --git a/common/generator.c b/common/generator.c index a456c6b78..f189d09e3 100644 --- a/common/generator.c +++ b/common/generator.c @@ -34,7 +34,7 @@ // XYZ 3D printing // Vinglock //------------------------------------ -void transform_D(uint8_t *ru) { +static void transform_D(uint8_t *ru) { const uint32_t c_D[] = { 0x6D835AFC, 0x7D15CD97, 0x0942B409, 0x32F9C923, 0xA811FB02, 0x64F121E8, @@ -111,18 +111,17 @@ uint32_t ul_ev1_pwdgenB(uint8_t *uid) { // Lego Dimension pwd generation algo nickname C. uint32_t ul_ev1_pwdgenC(uint8_t *uid) { uint32_t pwd = 0; - uint8_t base[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x28, - 0x63, 0x29, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, - 0x69, 0x67, 0x68, 0x74, 0x20, 0x4c, 0x45, 0x47, - 0x4f, 0x20, 0x32, 0x30, 0x31, 0x34, 0xaa, 0xaa + uint32_t base[] = { + 0xffffffff, 0x28ffffff, + 0x43202963, 0x7279706f, + 0x74686769, 0x47454c20, + 0x3032204f, 0xaaaa3431 }; memcpy(base, uid, 7); - for (int i = 0; i < 32; i += 4) { - uint32_t b = *(uint32_t *)(base + i); - pwd = b + ROTR(pwd, 25) + ROTR(pwd, 10) - pwd; + for (int i = 0; i < 8; i++) { + pwd = base[i] + ROTR(pwd, 25) + ROTR(pwd, 10) - pwd; } return BSWAP_32(pwd); } @@ -215,6 +214,7 @@ int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys) { int mfc_algo_yale_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { if (sector > 15) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + if (keytype > 2) return PM3_EINVARG; *key = 0; return PM3_SUCCESS; } @@ -234,6 +234,7 @@ int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys) { int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { if (sector > 15) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + if (keytype > 2) return PM3_EINVARG; *key = 0; return PM3_SUCCESS; } @@ -254,6 +255,7 @@ int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys) { int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) { if (sector > 4) return PM3_EINVARG; if (key == NULL) return PM3_EINVARG; + if (keytype > 2) return PM3_EINVARG; if (sector == 0) { // A @@ -415,21 +417,21 @@ int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) { //------------------------------------ // Self tests //------------------------------------ -int generator_selftest() { +int generator_selftest(void) { #define NUM_OF_TEST 5 PrintAndLogEx(INFO, "PWD / KEY generator selftest"); PrintAndLogEx(INFO, "----------------------------"); - bool success = false; uint8_t testresult = 0; uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10}; uint32_t pwd1 = ul_ev1_pwdgenA(uid1); - success = (pwd1 == 0x8432EB17); + bool success = (pwd1 == 0x8432EB17); if (success) testresult++; + PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid1, 7), pwd1, success ? "OK" : "->8432EB17<-"); uint8_t uid2[] = {0x04, 0x1f, 0x98, 0xea, 0x1e, 0x3e, 0x81}; diff --git a/common/generator.h b/common/generator.h index d7ca2b8ee..c90fe483a 100644 --- a/common/generator.h +++ b/common/generator.h @@ -32,9 +32,6 @@ int mfc_algo_yale_all(uint8_t *uid, uint8_t *keys); int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); -int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); -int mfc_algo_saflok_all(uint8_t *uid, uint8_t *keys); - int mfc_algo_mizip_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_mizip_all(uint8_t *uid, uint8_t *keys); @@ -44,5 +41,5 @@ int mfc_algo_di_all(uint8_t *uid, uint8_t *keys); int mfc_algo_sky_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys); -int generator_selftest(); +int generator_selftest(void); #endif diff --git a/common/get_lz4.sh b/common/get_lz4.sh new file mode 100755 index 000000000..6c2dcf3cb --- /dev/null +++ b/common/get_lz4.sh @@ -0,0 +1,36 @@ +version=1.9.2 +mkdir -p lz4 +wget https://github.com/lz4/lz4/archive/v$version.zip +unzip -o -j v$version "lz4-$version/LICENSE" "lz4-$version/lib/lz4.h" "lz4-$version/lib/lz4.c" "lz4-$version/lib/lz4hc.h" "lz4-$version/lib/lz4hc.c" -d lz4 +rm v$version.zip +patch -p0 << EOF +diff -Naur lz4/lz4.c lz4/lz4.c +--- lz4/lz4.c ++++ lz4/lz4.c +@@ -1270,6 +1270,7 @@ int LZ4_compress_default(const char* src, char* dst, int srcSize, int maxOutputS + } + + ++int LZ4_compress_fast_force(const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); + /* hidden debug function */ + /* strangely enough, gcc generates faster code when this function is uncommented, even if unused */ + int LZ4_compress_fast_force(const char* src, char* dst, int srcSize, int dstCapacity, int acceleration) +@@ -1644,13 +1645,16 @@ read_variable_length(const BYTE**ip, const BYTE* lencheck, int loop_check, int i + return length; + } + ++int LZ4_decompress_generic(const char* const src, char* const dst, int srcSize, int outputSize, endCondition_directive endOnInput, earlyEnd_directive partialDecoding, ++ dict_directive dict, const BYTE* const lowPrefix, const BYTE* const dictStart, const size_t dictSize ); ++ + /*! LZ4_decompress_generic() : + * This generic decompression function covers all use cases. + * It shall be instantiated several times, using different sets of directives. + * Note that it is important for performance that this function really get inlined, + * in order to remove useless branches during compilation optimization. + */ +-LZ4_FORCE_INLINE int ++int + LZ4_decompress_generic( + const char* const src, + char* const dst, +EOF diff --git a/common/legic_prng.c b/common/legic_prng.c index 8646f55a9..ad16d28b7 100644 --- a/common/legic_prng.c +++ b/common/legic_prng.c @@ -12,7 +12,7 @@ // b is 8bit lsfr // c keeps track on which step the prng is. // legic_prng_get_bit() = gets a bit muxed from a and b. -struct lfsr { +static struct lfsr { uint8_t a; uint8_t b; uint32_t c; @@ -46,7 +46,7 @@ void legic_prng_forward(int count) { } } -uint8_t legic_prng_get_bit() { +uint8_t legic_prng_get_bit(void) { uint8_t idx = 7 - ((lfsr.a & 4) | (lfsr.a >> 2 & 2) | (lfsr.a >> 4 & 1)); return lfsr.b >> idx & 1; } diff --git a/common/lfdemod.c b/common/lfdemod.c index bc753f45d..ee6d6afe0 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -51,6 +51,7 @@ #ifndef ON_DEVICE #include "ui.h" +#include "util.h" # include "cmddata.h" # define prnt(args...) PrintAndLogEx(DEBUG, ## args ); #else @@ -1560,7 +1561,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver } else if (waveHigh) { bits[bitCnt++] = invert; bits[bitCnt++] = invert; - } else if (!waveHigh) { + } else { bits[bitCnt++] = invert ^ 1; bits[bitCnt++] = invert ^ 1; } @@ -1582,9 +1583,10 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver if (waveHigh) { bits[bitCnt++] = invert; - } else if (!waveHigh) { + } else { bits[bitCnt++] = invert ^ 1; } + if (*startIdx == 0) { *startIdx = i - cl_2; if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod minus half clock [%d]", *startIdx); diff --git a/common/lz4/LICENSE b/common/lz4/LICENSE new file mode 100644 index 000000000..c221aebd2 --- /dev/null +++ b/common/lz4/LICENSE @@ -0,0 +1,11 @@ +This repository uses 2 different licenses : +- all files in the `lib` directory use a BSD 2-Clause license +- all other files use a GPLv2 license, unless explicitly stated otherwise + +Relevant license is reminded at the top of each source file, +and with presence of COPYING or LICENSE file in associated directories. + +This model is selected to emphasize that +files in the `lib` directory are designed to be included into 3rd party applications, +while all other files, in `programs`, `tests` or `examples`, +receive more limited attention and support for such scenario. diff --git a/common/lz4/lz4.c b/common/lz4/lz4.c new file mode 100644 index 000000000..5bca93e08 --- /dev/null +++ b/common/lz4/lz4.c @@ -0,0 +1,2370 @@ +/* + LZ4 - Fast LZ compression algorithm + Copyright (C) 2011-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 +*/ + +/*-************************************ +* Tuning parameters +**************************************/ +/* + * LZ4_HEAPMODE : + * Select how default compression functions will allocate memory for their hash table, + * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). + */ +#ifndef LZ4_HEAPMODE +# define LZ4_HEAPMODE 0 +#endif + +/* + * ACCELERATION_DEFAULT : + * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0 + */ +#define ACCELERATION_DEFAULT 1 + + +/*-************************************ +* CPU Feature Detection +**************************************/ +/* LZ4_FORCE_MEMORY_ACCESS + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets which assembly generation depends on alignment. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */ +# if defined(__GNUC__) && \ + ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define LZ4_FORCE_MEMORY_ACCESS 2 +# elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__) +# define LZ4_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +/* + * LZ4_FORCE_SW_BITCOUNT + * Define this parameter if your target system or compiler does not support hardware bit count + */ +#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for WinCE doesn't support Hardware bit count */ +# define LZ4_FORCE_SW_BITCOUNT +#endif + + + +/*-************************************ +* Dependency +**************************************/ +/* + * LZ4_SRC_INCLUDED: + * Amalgamation flag, whether lz4.c is included + */ +#ifndef LZ4_SRC_INCLUDED +# define LZ4_SRC_INCLUDED 1 +#endif + +#ifndef LZ4_STATIC_LINKING_ONLY +#define LZ4_STATIC_LINKING_ONLY +#endif + +#ifndef LZ4_DISABLE_DEPRECATE_WARNINGS +#define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */ +#endif + +#define LZ4_STATIC_LINKING_ONLY /* LZ4_DISTANCE_MAX */ +#include "lz4.h" +/* see also "memory routines" below */ + + +/*-************************************ +* Compiler Options +**************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# include +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ +#endif /* _MSC_VER */ + +#ifndef LZ4_FORCE_INLINE +# ifdef _MSC_VER /* Visual Studio */ +# define LZ4_FORCE_INLINE static __forceinline +# else +# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# ifdef __GNUC__ +# define LZ4_FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define LZ4_FORCE_INLINE static inline +# endif +# else +# define LZ4_FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +# endif /* _MSC_VER */ +#endif /* LZ4_FORCE_INLINE */ + +/* LZ4_FORCE_O2_GCC_PPC64LE and LZ4_FORCE_O2_INLINE_GCC_PPC64LE + * gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy8, + * together with a simple 8-byte copy loop as a fall-back path. + * However, this optimization hurts the decompression speed by >30%, + * because the execution does not go to the optimized loop + * for typical compressible data, and all of the preamble checks + * before going to the fall-back path become useless overhead. + * This optimization happens only with the -O3 flag, and -O2 generates + * a simple 8-byte copy loop. + * With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy8 + * functions are annotated with __attribute__((optimize("O2"))), + * and also LZ4_wildCopy8 is forcibly inlined, so that the O2 attribute + * of LZ4_wildCopy8 does not affect the compression speed. + */ +#if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__) && !defined(__clang__) +# define LZ4_FORCE_O2_GCC_PPC64LE __attribute__((optimize("O2"))) +# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE __attribute__((optimize("O2"))) LZ4_FORCE_INLINE +#else +# define LZ4_FORCE_O2_GCC_PPC64LE +# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) +# define expect(expr,value) (__builtin_expect ((expr),(value)) ) +#else +# define expect(expr,value) (expr) +#endif + +#ifndef likely +#define likely(expr) expect((expr) != 0, 1) +#endif +#ifndef unlikely +#define unlikely(expr) expect((expr) != 0, 0) +#endif + + +/*-************************************ +* Memory routines +**************************************/ +#include /* malloc, calloc, free */ +#define ALLOC(s) malloc(s) +#define ALLOC_AND_ZERO(s) calloc(1,s) +#define FREEMEM(p) free(p) +#include /* memset, memcpy */ +#define MEM_INIT(p,v,s) memset((p),(v),(s)) + + +/*-************************************ +* Common Constants +**************************************/ +#define MINMATCH 4 + +#define WILDCOPYLENGTH 8 +#define LASTLITERALS 5 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ +#define MFLIMIT 12 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ +#define MATCH_SAFEGUARD_DISTANCE ((2*WILDCOPYLENGTH) - MINMATCH) /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */ +#define FASTLOOP_SAFE_DISTANCE 64 +static const int LZ4_minLength = (MFLIMIT + 1); + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define LZ4_DISTANCE_ABSOLUTE_MAX 65535 +#if (LZ4_DISTANCE_MAX > LZ4_DISTANCE_ABSOLUTE_MAX) /* max supported by LZ4 format */ +# error "LZ4_DISTANCE_MAX is too big : must be <= 65535" +#endif + +#define ML_BITS 4 +#define ML_MASK ((1U<=1) +# include +#else +# ifndef assert +# define assert(condition) ((void)0) +# endif +#endif + +#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use after variable declarations */ + +#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) +# include +static int g_debuglog_enable = 1; +# define DEBUGLOG(l, ...) { \ + if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ + fprintf(stderr, __FILE__ ": "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " \n"); \ + } } +#else +# define DEBUGLOG(l, ...) {} /* disabled */ +#endif + + +/*-************************************ +* Types +**************************************/ +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# include +typedef uint8_t BYTE; +typedef uint16_t U16; +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +typedef uintptr_t uptrval; +#else +typedef unsigned char BYTE; +typedef unsigned short U16; +typedef unsigned int U32; +typedef signed int S32; +typedef unsigned long long U64; +typedef size_t uptrval; /* generally true, except OpenVMS-64 */ +#endif + +#if defined(__x86_64__) +typedef U64 reg_t; /* 64-bits in x32 mode */ +#else +typedef size_t reg_t; /* 32-bits in x32 mode */ +#endif + +typedef enum { + notLimited = 0, + limitedOutput = 1, + fillOutput = 2 +} limitedOutput_directive; + + +/*-************************************ +* Reading and writing into memory +**************************************/ +static unsigned LZ4_isLittleEndian(void) { + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + + +#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) +/* lie to the compiler about data alignment; use with caution */ + +static U16 LZ4_read16(const void *memPtr) { return *(const U16 *) memPtr; } +static U32 LZ4_read32(const void *memPtr) { return *(const U32 *) memPtr; } +static reg_t LZ4_read_ARCH(const void *memPtr) { return *(const reg_t *) memPtr; } + +static void LZ4_write16(void *memPtr, U16 value) { *(U16 *)memPtr = value; } +static void LZ4_write32(void *memPtr, U32 value) { *(U32 *)memPtr = value; } + +#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign; + +static U16 LZ4_read16(const void *ptr) { return ((const unalign *)ptr)->u16; } +static U32 LZ4_read32(const void *ptr) { return ((const unalign *)ptr)->u32; } +static reg_t LZ4_read_ARCH(const void *ptr) { return ((const unalign *)ptr)->uArch; } + +static void LZ4_write16(void *memPtr, U16 value) { ((unalign *)memPtr)->u16 = value; } +static void LZ4_write32(void *memPtr, U32 value) { ((unalign *)memPtr)->u32 = value; } + +#else /* safe and portable access using memcpy() */ + +static U16 LZ4_read16(const void *memPtr) { + U16 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +static U32 LZ4_read32(const void *memPtr) { + U32 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +static reg_t LZ4_read_ARCH(const void *memPtr) { + reg_t val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +static void LZ4_write16(void *memPtr, U16 value) { + memcpy(memPtr, &value, sizeof(value)); +} + +static void LZ4_write32(void *memPtr, U32 value) { + memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* LZ4_FORCE_MEMORY_ACCESS */ + + +static U16 LZ4_readLE16(const void *memPtr) { + if (LZ4_isLittleEndian()) { + return LZ4_read16(memPtr); + } else { + const BYTE *p = (const BYTE *)memPtr; + return (U16)((U16)p[0] + (p[1] << 8)); + } +} + +static void LZ4_writeLE16(void *memPtr, U16 value) { + if (LZ4_isLittleEndian()) { + LZ4_write16(memPtr, value); + } else { + BYTE *p = (BYTE *)memPtr; + p[0] = (BYTE) value; + p[1] = (BYTE)(value >> 8); + } +} + +/* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */ +LZ4_FORCE_O2_INLINE_GCC_PPC64LE +void LZ4_wildCopy8(void *dstPtr, const void *srcPtr, void *dstEnd) { + BYTE *d = (BYTE *)dstPtr; + const BYTE *s = (const BYTE *)srcPtr; + BYTE *const e = (BYTE *)dstEnd; + + do { memcpy(d, s, 8); d += 8; s += 8; } + while (d < e); +} + +static const unsigned inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4}; +static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3}; + + +#ifndef LZ4_FAST_DEC_LOOP +# if defined(__i386__) || defined(__x86_64__) +# define LZ4_FAST_DEC_LOOP 1 +# elif defined(__aarch64__) && !defined(__clang__) +/* On aarch64, we disable this optimization for clang because on certain + * mobile chipsets and clang, it reduces performance. For more information + * refer to https://github.com/lz4/lz4/pull/707. */ +# define LZ4_FAST_DEC_LOOP 1 +# else +# define LZ4_FAST_DEC_LOOP 0 +# endif +#endif + +#if LZ4_FAST_DEC_LOOP + +LZ4_FORCE_O2_INLINE_GCC_PPC64LE void +LZ4_memcpy_using_offset_base(BYTE *dstPtr, const BYTE *srcPtr, BYTE *dstEnd, const size_t offset) { + if (offset < 8) { + dstPtr[0] = srcPtr[0]; + dstPtr[1] = srcPtr[1]; + dstPtr[2] = srcPtr[2]; + dstPtr[3] = srcPtr[3]; + srcPtr += inc32table[offset]; + memcpy(dstPtr + 4, srcPtr, 4); + srcPtr -= dec64table[offset]; + dstPtr += 8; + } else { + memcpy(dstPtr, srcPtr, 8); + dstPtr += 8; + srcPtr += 8; + } + + LZ4_wildCopy8(dstPtr, srcPtr, dstEnd); +} + +/* customized variant of memcpy, which can overwrite up to 32 bytes beyond dstEnd + * this version copies two times 16 bytes (instead of one time 32 bytes) + * because it must be compatible with offsets >= 16. */ +LZ4_FORCE_O2_INLINE_GCC_PPC64LE void +LZ4_wildCopy32(void *dstPtr, const void *srcPtr, void *dstEnd) { + BYTE *d = (BYTE *)dstPtr; + const BYTE *s = (const BYTE *)srcPtr; + BYTE *const e = (BYTE *)dstEnd; + + do { memcpy(d, s, 16); memcpy(d + 16, s + 16, 16); d += 32; s += 32; } + while (d < e); +} + +/* LZ4_memcpy_using_offset() presumes : + * - dstEnd >= dstPtr + MINMATCH + * - there is at least 8 bytes available to write after dstEnd */ +LZ4_FORCE_O2_INLINE_GCC_PPC64LE void +LZ4_memcpy_using_offset(BYTE *dstPtr, const BYTE *srcPtr, BYTE *dstEnd, const size_t offset) { + BYTE v[8]; + + assert(dstEnd >= dstPtr + MINMATCH); + LZ4_write32(dstPtr, 0); /* silence an msan warning when offset==0 */ + + switch (offset) { + case 1: + memset(v, *srcPtr, 8); + break; + case 2: + memcpy(v, srcPtr, 2); + memcpy(&v[2], srcPtr, 2); + memcpy(&v[4], &v[0], 4); + break; + case 4: + memcpy(v, srcPtr, 4); + memcpy(&v[4], srcPtr, 4); + break; + default: + LZ4_memcpy_using_offset_base(dstPtr, srcPtr, dstEnd, offset); + return; + } + + memcpy(dstPtr, v, 8); + dstPtr += 8; + while (dstPtr < dstEnd) { + memcpy(dstPtr, v, 8); + dstPtr += 8; + } +} +#endif + + +/*-************************************ +* Common functions +**************************************/ +static unsigned LZ4_NbCommonBytes(reg_t val) { + if (LZ4_isLittleEndian()) { + if (sizeof(val) == 8) { +# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanForward64(&r, (U64)val); + return (int)(r >> 3); +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_ctzll((U64)val) >> 3; +# else + static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, + 0, 3, 1, 3, 1, 4, 2, 7, + 0, 2, 3, 6, 1, 5, 3, 5, + 1, 3, 4, 4, 2, 5, 6, 7, + 7, 0, 1, 2, 3, 3, 4, 6, + 2, 6, 5, 5, 3, 4, 5, 6, + 7, 1, 2, 4, 6, 4, 4, 5, + 7, 2, 6, 5, 7, 6, 7, 7 + }; + return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; +# endif + } else /* 32 bits */ { +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r; + _BitScanForward(&r, (U32)val); + return (int)(r >> 3); +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_ctz((U32)val) >> 3; +# else + static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, + 3, 2, 2, 1, 3, 2, 0, 1, + 3, 3, 1, 2, 2, 2, 2, 0, + 3, 1, 2, 0, 1, 0, 1, 1 + }; + return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; +# endif + } + } else { /* Big Endian CPU */ + if (sizeof(val) == 8) { /* 64-bits */ +# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse64(&r, val); + return (unsigned)(r >> 3); +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_clzll((U64)val) >> 3; +# else + static const U32 by32 = sizeof(val) * 4; /* 32 on 64 bits (goal), 16 on 32 bits. + Just to avoid some static analyzer complaining about shift by 32 on 32-bits target. + Note that this code path is never triggered in 32-bits mode. */ + unsigned r; + if (!(val >> by32)) { r = 4; } + else { r = 0; val >>= by32; } + if (!(val >> 16)) { r += 2; val >>= 8; } + else { val >>= 24; } + r += (!val); + return r; +# endif + } else /* 32 bits */ { +# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) + unsigned long r = 0; + _BitScanReverse(&r, (unsigned long)val); + return (unsigned)(r >> 3); +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) + return (unsigned)__builtin_clz((U32)val) >> 3; +# else + unsigned r; + if (!(val >> 16)) { r = 2; val >>= 8; } + else { r = 0; val >>= 24; } + r += (!val); + return r; +# endif + } + } +} + +#define STEPSIZE sizeof(reg_t) +LZ4_FORCE_INLINE +unsigned LZ4_count(const BYTE *pIn, const BYTE *pMatch, const BYTE *pInLimit) { + const BYTE *const pStart = pIn; + + if (likely(pIn < pInLimit - (STEPSIZE - 1))) { + reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); + if (!diff) { + pIn += STEPSIZE; + pMatch += STEPSIZE; + } else { + return LZ4_NbCommonBytes(diff); + } + } + + while (likely(pIn < pInLimit - (STEPSIZE - 1))) { + reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); + if (!diff) { pIn += STEPSIZE; pMatch += STEPSIZE; continue; } + pIn += LZ4_NbCommonBytes(diff); + return (unsigned)(pIn - pStart); + } + + if ((STEPSIZE == 8) && (pIn < (pInLimit - 3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn += 4; pMatch += 4; } + if ((pIn < (pInLimit - 1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn += 2; pMatch += 2; } + if ((pIn < pInLimit) && (*pMatch == *pIn)) pIn++; + return (unsigned)(pIn - pStart); +} + + +#ifndef LZ4_COMMONDEFS_ONLY +/*-************************************ +* Local Constants +**************************************/ +static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT - 1)); +static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */ + + +/*-************************************ +* Local Structures and types +**************************************/ +typedef enum { clearedTable = 0, byPtr, byU32, byU16 } tableType_t; + +/** + * This enum distinguishes several different modes of accessing previous + * content in the stream. + * + * - noDict : There is no preceding content. + * - withPrefix64k : Table entries up to ctx->dictSize before the current blob + * blob being compressed are valid and refer to the preceding + * content (of length ctx->dictSize), which is available + * contiguously preceding in memory the content currently + * being compressed. + * - usingExtDict : Like withPrefix64k, but the preceding content is somewhere + * else in memory, starting at ctx->dictionary with length + * ctx->dictSize. + * - usingDictCtx : Like usingExtDict, but everything concerning the preceding + * content is in a separate context, pointed to by + * ctx->dictCtx. ctx->dictionary, ctx->dictSize, and table + * entries in the current context that refer to positions + * preceding the beginning of the current compression are + * ignored. Instead, ctx->dictCtx->dictionary and ctx->dictCtx + * ->dictSize describe the location and size of the preceding + * content, and matches are found by looking in the ctx + * ->dictCtx->hashTable. + */ +typedef enum { noDict = 0, withPrefix64k, usingExtDict, usingDictCtx } dict_directive; +typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; + + +/*-************************************ +* Local Utils +**************************************/ +int LZ4_versionNumber(void) { return LZ4_VERSION_NUMBER; } +const char *LZ4_versionString(void) { return LZ4_VERSION_STRING; } +int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } +int LZ4_sizeofState() { return LZ4_STREAMSIZE; } + + +/*-************************************ +* Internal Definitions used in Tests +**************************************/ +#if defined (__cplusplus) +extern "C" { +#endif + +int LZ4_compress_forceExtDict(LZ4_stream_t *LZ4_dict, const char *source, char *dest, int srcSize); + +int LZ4_decompress_safe_forceExtDict(const char *source, char *dest, + int compressedSize, int maxOutputSize, + const void *dictStart, size_t dictSize); + +#if defined (__cplusplus) +} +#endif + +/*-****************************** +* Compression functions +********************************/ +static U32 LZ4_hash4(U32 sequence, tableType_t const tableType) { + if (tableType == byU16) + return ((sequence * 2654435761U) >> ((MINMATCH * 8) - (LZ4_HASHLOG + 1))); + else + return ((sequence * 2654435761U) >> ((MINMATCH * 8) - LZ4_HASHLOG)); +} + +static U32 LZ4_hash5(U64 sequence, tableType_t const tableType) { + const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG + 1 : LZ4_HASHLOG; + if (LZ4_isLittleEndian()) { + const U64 prime5bytes = 889523592379ULL; + return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); + } else { + const U64 prime8bytes = 11400714785074694791ULL; + return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); + } +} + +LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void *const p, tableType_t const tableType) { + if ((sizeof(reg_t) == 8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); + return LZ4_hash4(LZ4_read32(p), tableType); +} + +static void LZ4_clearHash(U32 h, void *tableBase, tableType_t const tableType) { + switch (tableType) { + default: /* fallthrough */ + case clearedTable: { /* illegal! */ assert(0); return; } + case byPtr: + { const BYTE **hashTable = (const BYTE **)tableBase; hashTable[h] = NULL; return; } + case byU32: + { U32 *hashTable = (U32 *) tableBase; hashTable[h] = 0; return; } + case byU16: + { U16 *hashTable = (U16 *) tableBase; hashTable[h] = 0; return; } + } +} + +static void LZ4_putIndexOnHash(U32 idx, U32 h, void *tableBase, tableType_t const tableType) { + switch (tableType) { + default: /* fallthrough */ + case clearedTable: /* fallthrough */ + case byPtr: { /* illegal! */ assert(0); return; } + case byU32: + { U32 *hashTable = (U32 *) tableBase; hashTable[h] = idx; return; } + case byU16: + { U16 *hashTable = (U16 *) tableBase; assert(idx < 65536); hashTable[h] = (U16)idx; return; } + } +} + +static void LZ4_putPositionOnHash(const BYTE *p, U32 h, + void *tableBase, tableType_t const tableType, + const BYTE *srcBase) { + switch (tableType) { + case clearedTable: { /* illegal! */ assert(0); return; } + case byPtr: + { const BYTE **hashTable = (const BYTE **)tableBase; hashTable[h] = p; return; } + case byU32: + { U32 *hashTable = (U32 *) tableBase; hashTable[h] = (U32)(p - srcBase); return; } + case byU16: + { U16 *hashTable = (U16 *) tableBase; hashTable[h] = (U16)(p - srcBase); return; } + } +} + +LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE *p, void *tableBase, tableType_t tableType, const BYTE *srcBase) { + U32 const h = LZ4_hashPosition(p, tableType); + LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); +} + +/* LZ4_getIndexOnHash() : + * Index of match position registered in hash table. + * hash position must be calculated by using base+index, or dictBase+index. + * Assumption 1 : only valid if tableType == byU32 or byU16. + * Assumption 2 : h is presumed valid (within limits of hash table) + */ +static U32 LZ4_getIndexOnHash(U32 h, const void *tableBase, tableType_t tableType) { + LZ4_STATIC_ASSERT(LZ4_MEMORY_USAGE > 2); + if (tableType == byU32) { + const U32 *const hashTable = (const U32 *) tableBase; + assert(h < (1U << (LZ4_MEMORY_USAGE - 2))); + return hashTable[h]; + } + if (tableType == byU16) { + const U16 *const hashTable = (const U16 *) tableBase; + assert(h < (1U << (LZ4_MEMORY_USAGE - 1))); + return hashTable[h]; + } + assert(0); + return 0; /* forbidden case */ +} + +static const BYTE *LZ4_getPositionOnHash(U32 h, const void *tableBase, tableType_t tableType, const BYTE *srcBase) { + if (tableType == byPtr) { const BYTE *const *hashTable = (const BYTE * const *) tableBase; return hashTable[h]; } + if (tableType == byU32) { const U32 *const hashTable = (const U32 *) tableBase; return hashTable[h] + srcBase; } + { const U16 *const hashTable = (const U16 *) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ +} + +LZ4_FORCE_INLINE const BYTE * +LZ4_getPosition(const BYTE *p, + const void *tableBase, tableType_t tableType, + const BYTE *srcBase) { + U32 const h = LZ4_hashPosition(p, tableType); + return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); +} + +LZ4_FORCE_INLINE void +LZ4_prepareTable(LZ4_stream_t_internal *const cctx, + const int inputSize, + const tableType_t tableType) { + /* If compression failed during the previous step, then the context + * is marked as dirty, therefore, it has to be fully reset. + */ + if (cctx->dirty) { + DEBUGLOG(5, "LZ4_prepareTable: Full reset for %p", cctx); + MEM_INIT(cctx, 0, sizeof(LZ4_stream_t_internal)); + return; + } + + /* If the table hasn't been used, it's guaranteed to be zeroed out, and is + * therefore safe to use no matter what mode we're in. Otherwise, we figure + * out if it's safe to leave as is or whether it needs to be reset. + */ + if (cctx->tableType != clearedTable) { + assert(inputSize >= 0); + if (cctx->tableType != tableType + || ((tableType == byU16) && cctx->currentOffset + (unsigned)inputSize >= 0xFFFFU) + || ((tableType == byU32) && cctx->currentOffset > 1 GB) + || tableType == byPtr + || inputSize >= 4 KB) { + DEBUGLOG(4, "LZ4_prepareTable: Resetting table in %p", cctx); + MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE); + cctx->currentOffset = 0; + cctx->tableType = clearedTable; + } else { + DEBUGLOG(4, "LZ4_prepareTable: Re-use hash table (no reset)"); + } + } + + /* Adding a gap, so all previous entries are > LZ4_DISTANCE_MAX back, is faster + * than compressing without a gap. However, compressing with + * currentOffset == 0 is faster still, so we preserve that case. + */ + if (cctx->currentOffset != 0 && tableType == byU32) { + DEBUGLOG(5, "LZ4_prepareTable: adding 64KB to currentOffset"); + cctx->currentOffset += 64 KB; + } + + /* Finally, clear history */ + cctx->dictCtx = NULL; + cctx->dictionary = NULL; + cctx->dictSize = 0; +} + +/** LZ4_compress_generic() : + inlined, to ensure branches are decided at compilation time */ +LZ4_FORCE_INLINE int LZ4_compress_generic( + LZ4_stream_t_internal *const cctx, + const char *const source, + char *const dest, + const int inputSize, + int *inputConsumed, /* only written when outputDirective == fillOutput */ + const int maxOutputSize, + const limitedOutput_directive outputDirective, + const tableType_t tableType, + const dict_directive dictDirective, + const dictIssue_directive dictIssue, + const int acceleration) { + int result; + const BYTE *ip = (const BYTE *) source; + + U32 const startIndex = cctx->currentOffset; + const BYTE *base = (const BYTE *) source - startIndex; + const BYTE *lowLimit; + + const LZ4_stream_t_internal *dictCtx = (const LZ4_stream_t_internal *) cctx->dictCtx; + const BYTE *const dictionary = + dictDirective == usingDictCtx ? dictCtx->dictionary : cctx->dictionary; + const U32 dictSize = + dictDirective == usingDictCtx ? dictCtx->dictSize : cctx->dictSize; + const U32 dictDelta = (dictDirective == usingDictCtx) ? startIndex - dictCtx->currentOffset : 0; /* make indexes in dictCtx comparable with index in current context */ + + int const maybe_extMem = (dictDirective == usingExtDict) || (dictDirective == usingDictCtx); + U32 const prefixIdxLimit = startIndex - dictSize; /* used when dictDirective == dictSmall */ + const BYTE *const dictEnd = dictionary + dictSize; + const BYTE *anchor = (const BYTE *) source; + const BYTE *const iend = ip + inputSize; + const BYTE *const mflimitPlusOne = iend - MFLIMIT + 1; + const BYTE *const matchlimit = iend - LASTLITERALS; + + /* the dictCtx currentOffset is indexed on the start of the dictionary, + * while a dictionary in the current context precedes the currentOffset */ + const BYTE *dictBase = (dictDirective == usingDictCtx) ? + dictionary + dictSize - dictCtx->currentOffset : + dictionary + dictSize - startIndex; + + BYTE *op = (BYTE *) dest; + BYTE *const olimit = op + maxOutputSize; + + U32 offset = 0; + U32 forwardH; + + DEBUGLOG(5, "LZ4_compress_generic: srcSize=%i, tableType=%u", inputSize, tableType); + /* If init conditions are not met, we don't have to mark stream + * as having dirty context, since no action was taken yet */ + if (outputDirective == fillOutput && maxOutputSize < 1) { return 0; } /* Impossible to store anything */ + if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) { return 0; } /* Unsupported inputSize, too large (or negative) */ + if ((tableType == byU16) && (inputSize >= LZ4_64Klimit)) { return 0; } /* Size too large (not within 64K limit) */ + if (tableType == byPtr) assert(dictDirective == noDict); /* only supported use case with byPtr */ + assert(acceleration >= 1); + + lowLimit = (const BYTE *)source - (dictDirective == withPrefix64k ? dictSize : 0); + + /* Update context state */ + if (dictDirective == usingDictCtx) { + /* Subsequent linked blocks can't use the dictionary. */ + /* Instead, they use the block we just compressed. */ + cctx->dictCtx = NULL; + cctx->dictSize = (U32)inputSize; + } else { + cctx->dictSize += (U32)inputSize; + } + cctx->currentOffset += (U32)inputSize; + cctx->tableType = (U16)tableType; + + if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ + + /* First Byte */ + LZ4_putPosition(ip, cctx->hashTable, tableType, base); + ip++; + forwardH = LZ4_hashPosition(ip, tableType); + + /* Main Loop */ + for (; ;) { + const BYTE *match; + BYTE *token; + const BYTE *filledIp; + + /* Find a match */ + if (tableType == byPtr) { + const BYTE *forwardIp = ip; + int step = 1; + int searchMatchNb = acceleration << LZ4_skipTrigger; + do { + U32 const h = forwardH; + ip = forwardIp; + forwardIp += step; + step = (searchMatchNb++ >> LZ4_skipTrigger); + + if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; + assert(ip < mflimitPlusOne); + + match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base); + forwardH = LZ4_hashPosition(forwardIp, tableType); + LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base); + + } while ((match + LZ4_DISTANCE_MAX < ip) + || (LZ4_read32(match) != LZ4_read32(ip))); + + } else { /* byU32, byU16 */ + + const BYTE *forwardIp = ip; + int step = 1; + int searchMatchNb = acceleration << LZ4_skipTrigger; + do { + U32 const h = forwardH; + U32 const current = (U32)(forwardIp - base); + U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); + assert(matchIndex <= current); + assert(forwardIp - base < (ptrdiff_t)(2 GB - 1)); + ip = forwardIp; + forwardIp += step; + step = (searchMatchNb++ >> LZ4_skipTrigger); + + if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; + assert(ip < mflimitPlusOne); + + if (dictDirective == usingDictCtx) { + if (matchIndex < startIndex) { + /* there was no match, try the dictionary */ + assert(tableType == byU32); + matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); + match = dictBase + matchIndex; + matchIndex += dictDelta; /* make dictCtx index comparable with current context */ + lowLimit = dictionary; + } else { + match = base + matchIndex; + lowLimit = (const BYTE *)source; + } + } else if (dictDirective == usingExtDict) { + if (matchIndex < startIndex) { + DEBUGLOG(7, "extDict candidate: matchIndex=%5u < startIndex=%5u", matchIndex, startIndex); + assert(startIndex - matchIndex >= MINMATCH); + match = dictBase + matchIndex; + lowLimit = dictionary; + } else { + match = base + matchIndex; + lowLimit = (const BYTE *)source; + } + } else { /* single continuous memory segment */ + match = base + matchIndex; + } + forwardH = LZ4_hashPosition(forwardIp, tableType); + LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); + + DEBUGLOG(7, "candidate at pos=%u (offset=%u \n", matchIndex, current - matchIndex); + if ((dictIssue == dictSmall) && (matchIndex < prefixIdxLimit)) { continue; } /* match outside of valid area */ + assert(matchIndex < current); + if (((tableType != byU16) || (LZ4_DISTANCE_MAX < LZ4_DISTANCE_ABSOLUTE_MAX)) + && (matchIndex + LZ4_DISTANCE_MAX < current)) { + continue; + } /* too far */ + assert((current - matchIndex) <= LZ4_DISTANCE_MAX); /* match now expected within distance */ + + if (LZ4_read32(match) == LZ4_read32(ip)) { + if (maybe_extMem) offset = current - matchIndex; + break; /* match found */ + } + + } while (1); + } + + /* Catch up */ + filledIp = ip; + while (((ip > anchor) & (match > lowLimit)) && (unlikely(ip[-1] == match[-1]))) { ip--; match--; } + + /* Encode Literals */ + { + unsigned const litLength = (unsigned)(ip - anchor); + token = op++; + if ((outputDirective == limitedOutput) && /* Check output buffer overflow */ + (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength / 255) > olimit))) { + return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ + } + if ((outputDirective == fillOutput) && + (unlikely(op + (litLength + 240) / 255 /* litlen */ + litLength /* literals */ + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit))) { + op--; + goto _last_literals; + } + if (litLength >= RUN_MASK) { + int len = (int)(litLength - RUN_MASK); + *token = (RUN_MASK << ML_BITS); + for (; len >= 255 ; len -= 255) * op++ = 255; + *op++ = (BYTE)len; + } else *token = (BYTE)(litLength << ML_BITS); + + /* Copy Literals */ + LZ4_wildCopy8(op, anchor, op + litLength); + op += litLength; + DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i", + (int)(anchor - (const BYTE *)source), litLength, (int)(ip - (const BYTE *)source)); + } + +_next_match: + /* at this stage, the following variables must be correctly set : + * - ip : at start of LZ operation + * - match : at start of previous pattern occurence; can be within current prefix, or within extDict + * - offset : if maybe_ext_memSegment==1 (constant) + * - lowLimit : must be == dictionary to mean "match is within extDict"; must be == source otherwise + * - token and *token : position to write 4-bits for match length; higher 4-bits for literal length supposed already written + */ + + if ((outputDirective == fillOutput) && + (op + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit)) { + /* the match was too close to the end, rewind and go to last literals */ + op = token; + goto _last_literals; + } + + /* Encode Offset */ + if (maybe_extMem) { /* static test */ + DEBUGLOG(6, " with offset=%u (ext if > %i)", offset, (int)(ip - (const BYTE *)source)); + assert(offset <= LZ4_DISTANCE_MAX && offset > 0); + LZ4_writeLE16(op, (U16)offset); + op += 2; + } else { + DEBUGLOG(6, " with offset=%u (same segment)", (U32)(ip - match)); + assert(ip - match <= LZ4_DISTANCE_MAX); + LZ4_writeLE16(op, (U16)(ip - match)); + op += 2; + } + + /* Encode MatchLength */ + { + unsigned matchCode; + + if ((dictDirective == usingExtDict || dictDirective == usingDictCtx) + && (lowLimit == dictionary) /* match within extDict */) { + const BYTE *limit = ip + (dictEnd - match); + assert(dictEnd > match); + if (limit > matchlimit) limit = matchlimit; + matchCode = LZ4_count(ip + MINMATCH, match + MINMATCH, limit); + ip += (size_t)matchCode + MINMATCH; + if (ip == limit) { + unsigned const more = LZ4_count(limit, (const BYTE *)source, matchlimit); + matchCode += more; + ip += more; + } + DEBUGLOG(6, " with matchLength=%u starting in extDict", matchCode + MINMATCH); + } else { + matchCode = LZ4_count(ip + MINMATCH, match + MINMATCH, matchlimit); + ip += (size_t)matchCode + MINMATCH; + DEBUGLOG(6, " with matchLength=%u", matchCode + MINMATCH); + } + + if ((outputDirective) && /* Check output buffer overflow */ + (unlikely(op + (1 + LASTLITERALS) + (matchCode + 240) / 255 > olimit))) { + if (outputDirective == fillOutput) { + /* Match description too long : reduce it */ + U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 1 - LASTLITERALS) * 255; + ip -= matchCode - newMatchCode; + assert(newMatchCode < matchCode); + matchCode = newMatchCode; + if (unlikely(ip <= filledIp)) { + /* We have already filled up to filledIp so if ip ends up less than filledIp + * we have positions in the hash table beyond the current position. This is + * a problem if we reuse the hash table. So we have to remove these positions + * from the hash table. + */ + const BYTE *ptr; + DEBUGLOG(5, "Clearing %u positions", (U32)(filledIp - ip)); + for (ptr = ip; ptr <= filledIp; ++ptr) { + U32 const h = LZ4_hashPosition(ptr, tableType); + LZ4_clearHash(h, cctx->hashTable, tableType); + } + } + } else { + assert(outputDirective == limitedOutput); + return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ + } + } + if (matchCode >= ML_MASK) { + *token += ML_MASK; + matchCode -= ML_MASK; + LZ4_write32(op, 0xFFFFFFFF); + while (matchCode >= 4 * 255) { + op += 4; + LZ4_write32(op, 0xFFFFFFFF); + matchCode -= 4 * 255; + } + op += matchCode / 255; + *op++ = (BYTE)(matchCode % 255); + } else + *token += (BYTE)(matchCode); + } + /* Ensure we have enough space for the last literals. */ + assert(!(outputDirective == fillOutput && op + 1 + LASTLITERALS > olimit)); + + anchor = ip; + + /* Test end of chunk */ + if (ip >= mflimitPlusOne) break; + + /* Fill table */ + LZ4_putPosition(ip - 2, cctx->hashTable, tableType, base); + + /* Test next position */ + if (tableType == byPtr) { + + match = LZ4_getPosition(ip, cctx->hashTable, tableType, base); + LZ4_putPosition(ip, cctx->hashTable, tableType, base); + if ((match + LZ4_DISTANCE_MAX >= ip) + && (LZ4_read32(match) == LZ4_read32(ip))) + { token = op++; *token = 0; goto _next_match; } + + } else { /* byU32, byU16 */ + + U32 const h = LZ4_hashPosition(ip, tableType); + U32 const current = (U32)(ip - base); + U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); + assert(matchIndex < current); + if (dictDirective == usingDictCtx) { + if (matchIndex < startIndex) { + /* there was no match, try the dictionary */ + matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); + match = dictBase + matchIndex; + lowLimit = dictionary; /* required for match length counter */ + matchIndex += dictDelta; + } else { + match = base + matchIndex; + lowLimit = (const BYTE *)source; /* required for match length counter */ + } + } else if (dictDirective == usingExtDict) { + if (matchIndex < startIndex) { + match = dictBase + matchIndex; + lowLimit = dictionary; /* required for match length counter */ + } else { + match = base + matchIndex; + lowLimit = (const BYTE *)source; /* required for match length counter */ + } + } else { /* single memory segment */ + match = base + matchIndex; + } + LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); + assert(matchIndex < current); + if (((dictIssue == dictSmall) ? (matchIndex >= prefixIdxLimit) : 1) + && (((tableType == byU16) && (LZ4_DISTANCE_MAX == LZ4_DISTANCE_ABSOLUTE_MAX)) ? 1 : (matchIndex + LZ4_DISTANCE_MAX >= current)) + && (LZ4_read32(match) == LZ4_read32(ip))) { + token = op++; + *token = 0; + if (maybe_extMem) offset = current - matchIndex; + DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i", + (int)(anchor - (const BYTE *)source), 0, (int)(ip - (const BYTE *)source)); + goto _next_match; + } + } + + /* Prepare next loop */ + forwardH = LZ4_hashPosition(++ip, tableType); + + } + +_last_literals: + /* Encode Last Literals */ + { + size_t lastRun = (size_t)(iend - anchor); + if ((outputDirective) && /* Check output buffer overflow */ + (op + lastRun + 1 + ((lastRun + 255 - RUN_MASK) / 255) > olimit)) { + if (outputDirective == fillOutput) { + /* adapt lastRun to fill 'dst' */ + assert(olimit >= op); + lastRun = (size_t)(olimit - op) - 1; + lastRun -= (lastRun + 240) / 255; + } else { + assert(outputDirective == limitedOutput); + return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ + } + } + if (lastRun >= RUN_MASK) { + size_t accumulator = lastRun - RUN_MASK; + *op++ = RUN_MASK << ML_BITS; + for (; accumulator >= 255 ; accumulator -= 255) * op++ = 255; + *op++ = (BYTE) accumulator; + } else { + *op++ = (BYTE)(lastRun << ML_BITS); + } + memcpy(op, anchor, lastRun); + ip = anchor + lastRun; + op += lastRun; + } + + if (outputDirective == fillOutput) { + *inputConsumed = (int)(((const char *)ip) - source); + } + DEBUGLOG(5, "LZ4_compress_generic: compressed %i bytes into %i bytes", inputSize, (int)(((char *)op) - dest)); + result = (int)(((char *)op) - dest); + assert(result > 0); + return result; +} + + +int LZ4_compress_fast_extState(void *state, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration) { + LZ4_stream_t_internal *const ctx = & LZ4_initStream(state, sizeof(LZ4_stream_t)) -> internal_donotuse; + assert(ctx != NULL); + if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; + if (maxOutputSize >= LZ4_compressBound(inputSize)) { + if (inputSize < LZ4_64Klimit) { + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, byU16, noDict, noDictIssue, acceleration); + } else { + const tableType_t tableType = ((sizeof(void *) == 4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); + } + } else { + if (inputSize < LZ4_64Klimit) { + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + } else { + const tableType_t tableType = ((sizeof(void *) == 4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration); + } + } +} + +/** + * LZ4_compress_fast_extState_fastReset() : + * A variant of LZ4_compress_fast_extState(). + * + * Using this variant avoids an expensive initialization step. It is only safe + * to call if the state buffer is known to be correctly initialized already + * (see comment in lz4.h on LZ4_resetStream_fast() for a definition of + * "correctly initialized"). + */ +int LZ4_compress_fast_extState_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int acceleration) { + LZ4_stream_t_internal *ctx = &((LZ4_stream_t *)state)->internal_donotuse; + if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; + + if (dstCapacity >= LZ4_compressBound(srcSize)) { + if (srcSize < LZ4_64Klimit) { + const tableType_t tableType = byU16; + LZ4_prepareTable(ctx, srcSize, tableType); + if (ctx->currentOffset) { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, dictSmall, acceleration); + } else { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); + } + } else { + const tableType_t tableType = ((sizeof(void *) == 4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + LZ4_prepareTable(ctx, srcSize, tableType); + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); + } + } else { + if (srcSize < LZ4_64Klimit) { + const tableType_t tableType = byU16; + LZ4_prepareTable(ctx, srcSize, tableType); + if (ctx->currentOffset) { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, dictSmall, acceleration); + } else { + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); + } + } else { + const tableType_t tableType = ((sizeof(void *) == 4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + LZ4_prepareTable(ctx, srcSize, tableType); + return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); + } + } +} + + +int LZ4_compress_fast(const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration) { + int result; +#if (LZ4_HEAPMODE) + LZ4_stream_t *ctxPtr = ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + if (ctxPtr == NULL) return 0; +#else + LZ4_stream_t ctx; + LZ4_stream_t *const ctxPtr = &ctx; +#endif + result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); + +#if (LZ4_HEAPMODE) + FREEMEM(ctxPtr); +#endif + return result; +} + + +int LZ4_compress_default(const char *src, char *dst, int srcSize, int maxOutputSize) { + return LZ4_compress_fast(src, dst, srcSize, maxOutputSize, 1); +} + + +int LZ4_compress_fast_force(const char *src, char *dst, int srcSize, int dstCapacity, int acceleration); +/* hidden debug function */ +/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */ +int LZ4_compress_fast_force(const char *src, char *dst, int srcSize, int dstCapacity, int acceleration) { + LZ4_stream_t ctx; + LZ4_initStream(&ctx, sizeof(ctx)); + + if (srcSize < LZ4_64Klimit) { + return LZ4_compress_generic(&ctx.internal_donotuse, src, dst, srcSize, NULL, dstCapacity, limitedOutput, byU16, noDict, noDictIssue, acceleration); + } else { + tableType_t const addrMode = (sizeof(void *) > 4) ? byU32 : byPtr; + return LZ4_compress_generic(&ctx.internal_donotuse, src, dst, srcSize, NULL, dstCapacity, limitedOutput, addrMode, noDict, noDictIssue, acceleration); + } +} + + +/* Note!: This function leaves the stream in an unclean/broken state! + * It is not safe to subsequently use the same state with a _fastReset() or + * _continue() call without resetting it. */ +static int LZ4_compress_destSize_extState(LZ4_stream_t *state, const char *src, char *dst, int *srcSizePtr, int targetDstSize) { + void *const s = LZ4_initStream(state, sizeof(*state)); + assert(s != NULL); + (void)s; + + if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ + return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); + } else { + if (*srcSizePtr < LZ4_64Klimit) { + return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, byU16, noDict, noDictIssue, 1); + } else { + tableType_t const addrMode = ((sizeof(void *) == 4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; + return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, addrMode, noDict, noDictIssue, 1); + } + } +} + + +int LZ4_compress_destSize(const char *src, char *dst, int *srcSizePtr, int targetDstSize) { +#if (LZ4_HEAPMODE) + LZ4_stream_t *ctx = (LZ4_stream_t *)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ + if (ctx == NULL) return 0; +#else + LZ4_stream_t ctxBody; + LZ4_stream_t *ctx = &ctxBody; +#endif + + int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); + +#if (LZ4_HEAPMODE) + FREEMEM(ctx); +#endif + return result; +} + + + +/*-****************************** +* Streaming functions +********************************/ + +LZ4_stream_t *LZ4_createStream(void) { + LZ4_stream_t *const lz4s = (LZ4_stream_t *)ALLOC(sizeof(LZ4_stream_t)); + LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ + DEBUGLOG(4, "LZ4_createStream %p", lz4s); + if (lz4s == NULL) return NULL; + LZ4_initStream(lz4s, sizeof(*lz4s)); + return lz4s; +} + +#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 : + it reports an aligment of 8-bytes, + while actually aligning LZ4_stream_t on 4 bytes. */ +static size_t LZ4_stream_t_alignment(void) { + struct { char c; LZ4_stream_t t; } t_a; + return sizeof(t_a) - sizeof(t_a.t); +} +#endif + +LZ4_stream_t *LZ4_initStream(void *buffer, size_t size) { + DEBUGLOG(5, "LZ4_initStream"); + if (buffer == NULL) { return NULL; } + if (size < sizeof(LZ4_stream_t)) { return NULL; } +#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 : + it reports an aligment of 8-bytes, + while actually aligning LZ4_stream_t on 4 bytes. */ + if (((size_t)buffer) & (LZ4_stream_t_alignment() - 1)) { return NULL; } /* alignment check */ +#endif + MEM_INIT(buffer, 0, sizeof(LZ4_stream_t)); + return (LZ4_stream_t *)buffer; +} + +/* resetStream is now deprecated, + * prefer initStream() which is more general */ +void LZ4_resetStream(LZ4_stream_t *LZ4_stream) { + DEBUGLOG(5, "LZ4_resetStream (ctx:%p)", LZ4_stream); + MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t)); +} + +void LZ4_resetStream_fast(LZ4_stream_t *ctx) { + LZ4_prepareTable(&(ctx->internal_donotuse), 0, byU32); +} + +int LZ4_freeStream(LZ4_stream_t *LZ4_stream) { + if (!LZ4_stream) return 0; /* support free on NULL */ + DEBUGLOG(5, "LZ4_freeStream %p", LZ4_stream); + FREEMEM(LZ4_stream); + return (0); +} + + +#define HASH_UNIT sizeof(reg_t) +int LZ4_loadDict(LZ4_stream_t *LZ4_dict, const char *dictionary, int dictSize) { + LZ4_stream_t_internal *dict = &LZ4_dict->internal_donotuse; + const tableType_t tableType = byU32; + const BYTE *p = (const BYTE *)dictionary; + const BYTE *const dictEnd = p + dictSize; + const BYTE *base; + + DEBUGLOG(4, "LZ4_loadDict (%i bytes from %p into %p)", dictSize, dictionary, LZ4_dict); + + /* It's necessary to reset the context, + * and not just continue it with prepareTable() + * to avoid any risk of generating overflowing matchIndex + * when compressing using this dictionary */ + LZ4_resetStream(LZ4_dict); + + /* We always increment the offset by 64 KB, since, if the dict is longer, + * we truncate it to the last 64k, and if it's shorter, we still want to + * advance by a whole window length so we can provide the guarantee that + * there are only valid offsets in the window, which allows an optimization + * in LZ4_compress_fast_continue() where it uses noDictIssue even when the + * dictionary isn't a full 64k. */ + dict->currentOffset += 64 KB; + + if (dictSize < (int)HASH_UNIT) { + return 0; + } + + if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; + base = dictEnd - dict->currentOffset; + dict->dictionary = p; + dict->dictSize = (U32)(dictEnd - p); + dict->tableType = tableType; + + while (p <= dictEnd - HASH_UNIT) { + LZ4_putPosition(p, dict->hashTable, tableType, base); + p += 3; + } + + return (int)dict->dictSize; +} + +void LZ4_attach_dictionary(LZ4_stream_t *workingStream, const LZ4_stream_t *dictionaryStream) { + const LZ4_stream_t_internal *dictCtx = dictionaryStream == NULL ? NULL : + &(dictionaryStream->internal_donotuse); + + DEBUGLOG(4, "LZ4_attach_dictionary (%p, %p, size %u)", + workingStream, dictionaryStream, + dictCtx != NULL ? dictCtx->dictSize : 0); + + /* Calling LZ4_resetStream_fast() here makes sure that changes will not be + * erased by subsequent calls to LZ4_resetStream_fast() in case stream was + * marked as having dirty context, e.g. requiring full reset. + */ + LZ4_resetStream_fast(workingStream); + + if (dictCtx != NULL) { + /* If the current offset is zero, we will never look in the + * external dictionary context, since there is no value a table + * entry can take that indicate a miss. In that case, we need + * to bump the offset to something non-zero. + */ + if (workingStream->internal_donotuse.currentOffset == 0) { + workingStream->internal_donotuse.currentOffset = 64 KB; + } + + /* Don't actually attach an empty dictionary. + */ + if (dictCtx->dictSize == 0) { + dictCtx = NULL; + } + } + workingStream->internal_donotuse.dictCtx = dictCtx; +} + + +static void LZ4_renormDictT(LZ4_stream_t_internal *LZ4_dict, int nextSize) { + assert(nextSize >= 0); + if (LZ4_dict->currentOffset + (unsigned)nextSize > 0x80000000) { /* potential ptrdiff_t overflow (32-bits mode) */ + /* rescale hash table */ + U32 const delta = LZ4_dict->currentOffset - 64 KB; + const BYTE *dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; + int i; + DEBUGLOG(4, "LZ4_renormDictT"); + for (i = 0; i < LZ4_HASH_SIZE_U32; i++) { + if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i] = 0; + else LZ4_dict->hashTable[i] -= delta; + } + LZ4_dict->currentOffset = 64 KB; + if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB; + LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; + } +} + + +int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, + const char *source, char *dest, + int inputSize, int maxOutputSize, + int acceleration) { + const tableType_t tableType = byU32; + LZ4_stream_t_internal *streamPtr = &LZ4_stream->internal_donotuse; + const BYTE *dictEnd = streamPtr->dictionary + streamPtr->dictSize; + + DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i)", inputSize); + + if (streamPtr->dirty) { return 0; } /* Uninitialized structure detected */ + LZ4_renormDictT(streamPtr, inputSize); /* avoid index overflow */ + if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; + + /* invalidate tiny dictionaries */ + if ((streamPtr->dictSize - 1 < 4 - 1) /* intentional underflow */ + && (dictEnd != (const BYTE *)source)) { + DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary); + streamPtr->dictSize = 0; + streamPtr->dictionary = (const BYTE *)source; + dictEnd = (const BYTE *)source; + } + + /* Check overlapping input/dictionary space */ + { + const BYTE *sourceEnd = (const BYTE *) source + inputSize; + if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) { + streamPtr->dictSize = (U32)(dictEnd - sourceEnd); + if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; + if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; + streamPtr->dictionary = dictEnd - streamPtr->dictSize; + } + } + + /* prefix mode : source data follows dictionary */ + if (dictEnd == (const BYTE *)source) { + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) + return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, dictSmall, acceleration); + else + return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, noDictIssue, acceleration); + } + + /* external dictionary mode */ + { + int result; + if (streamPtr->dictCtx) { + /* We depend here on the fact that dictCtx'es (produced by + * LZ4_loadDict) guarantee that their tables contain no references + * to offsets between dictCtx->currentOffset - 64 KB and + * dictCtx->currentOffset - dictCtx->dictSize. This makes it safe + * to use noDictIssue even when the dict isn't a full 64 KB. + */ + if (inputSize > 4 KB) { + /* For compressing large blobs, it is faster to pay the setup + * cost to copy the dictionary's tables into the active context, + * so that the compression loop is only looking into one table. + */ + memcpy(streamPtr, streamPtr->dictCtx, sizeof(LZ4_stream_t)); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); + } else { + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration); + } + } else { + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, dictSmall, acceleration); + } else { + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); + } + } + streamPtr->dictionary = (const BYTE *)source; + streamPtr->dictSize = (U32)inputSize; + return result; + } +} + + +/* Hidden debug function, to force-test external dictionary mode */ +int LZ4_compress_forceExtDict(LZ4_stream_t *LZ4_dict, const char *source, char *dest, int srcSize) { + LZ4_stream_t_internal *streamPtr = &LZ4_dict->internal_donotuse; + int result; + + LZ4_renormDictT(streamPtr, srcSize); + + if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { + result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, dictSmall, 1); + } else { + result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); + } + + streamPtr->dictionary = (const BYTE *)source; + streamPtr->dictSize = (U32)srcSize; + + return result; +} + + +/*! LZ4_saveDict() : + * If previously compressed data block is not guaranteed to remain available at its memory location, + * save it into a safer place (char* safeBuffer). + * Note : you don't need to call LZ4_loadDict() afterwards, + * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue(). + * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. + */ +int LZ4_saveDict(LZ4_stream_t *LZ4_dict, char *safeBuffer, int dictSize) { + LZ4_stream_t_internal *const dict = &LZ4_dict->internal_donotuse; + const BYTE *const previousDictEnd = dict->dictionary + dict->dictSize; + + if ((U32)dictSize > 64 KB) { dictSize = 64 KB; } /* useless to define a dictionary > 64 KB */ + if ((U32)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; } + + memmove(safeBuffer, previousDictEnd - dictSize, dictSize); + + dict->dictionary = (const BYTE *)safeBuffer; + dict->dictSize = (U32)dictSize; + + return dictSize; +} + + + +/*-******************************* + * Decompression functions + ********************************/ + +typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; +typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive; + +#undef MIN +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) + +/* Read the variable-length literal or match length. + * + * ip - pointer to use as input. + * lencheck - end ip. Return an error if ip advances >= lencheck. + * loop_check - check ip >= lencheck in body of loop. Returns loop_error if so. + * initial_check - check ip >= lencheck before start of loop. Returns initial_error if so. + * error (output) - error code. Should be set to 0 before call. + */ +typedef enum { loop_error = -2, initial_error = -1, ok = 0 } variable_length_error; +LZ4_FORCE_INLINE unsigned +read_variable_length(const BYTE **ip, const BYTE *lencheck, int loop_check, int initial_check, variable_length_error *error) { + unsigned length = 0; + unsigned s; + if (initial_check && unlikely((*ip) >= lencheck)) { /* overflow detection */ + *error = initial_error; + return length; + } + do { + s = **ip; + (*ip)++; + length += s; + if (loop_check && unlikely((*ip) >= lencheck)) { /* overflow detection */ + *error = loop_error; + return length; + } + } while (s == 255); + + return length; +} + +int LZ4_decompress_generic(const char *const src, char *const dst, int srcSize, int outputSize, endCondition_directive endOnInput, earlyEnd_directive partialDecoding, + dict_directive dict, const BYTE *const lowPrefix, const BYTE *const dictStart, const size_t dictSize); + +/*! LZ4_decompress_generic() : + * This generic decompression function covers all use cases. + * It shall be instantiated several times, using different sets of directives. + * Note that it is important for performance that this function really get inlined, + * in order to remove useless branches during compilation optimization. + */ +int +LZ4_decompress_generic( + const char *const src, + char *const dst, + int srcSize, + int outputSize, /* If endOnInput==endOnInputSize, this value is `dstCapacity` */ + + endCondition_directive endOnInput, /* endOnOutputSize, endOnInputSize */ + earlyEnd_directive partialDecoding, /* full, partial */ + dict_directive dict, /* noDict, withPrefix64k, usingExtDict */ + const BYTE *const lowPrefix, /* always <= dst, == dst when no prefix */ + const BYTE *const dictStart, /* only if dict==usingExtDict */ + const size_t dictSize /* note : = 0 if noDict */ +) { + if (src == NULL) { return -1; } + + { + const BYTE *ip = (const BYTE *) src; + const BYTE *const iend = ip + srcSize; + + BYTE *op = (BYTE *) dst; + BYTE *const oend = op + outputSize; + BYTE *cpy; + + const BYTE *const dictEnd = (dictStart == NULL) ? NULL : dictStart + dictSize; + + const int safeDecode = (endOnInput == endOnInputSize); + const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); + + + /* Set up the "end" pointers for the shortcut. */ + const BYTE *const shortiend = iend - (endOnInput ? 14 : 8) /*maxLL*/ - 2 /*offset*/; + const BYTE *const shortoend = oend - (endOnInput ? 14 : 8) /*maxLL*/ - 18 /*maxML*/; + + const BYTE *match; + size_t offset; + unsigned token; + size_t length; + + + DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i, dstSize:%i)", srcSize, outputSize); + + /* Special cases */ + assert(lowPrefix <= op); + if ((endOnInput) && (unlikely(outputSize == 0))) { + /* Empty output buffer */ + if (partialDecoding) return 0; + return ((srcSize == 1) && (*ip == 0)) ? 0 : -1; + } + if ((!endOnInput) && (unlikely(outputSize == 0))) { return (*ip == 0 ? 1 : -1); } + if ((endOnInput) && unlikely(srcSize == 0)) { return -1; } + + /* Currently the fast loop shows a regression on qualcomm arm chips. */ +#if LZ4_FAST_DEC_LOOP + if ((oend - op) < FASTLOOP_SAFE_DISTANCE) { + DEBUGLOG(6, "skip fast decode loop"); + goto safe_decode; + } + + /* Fast loop : decode sequences as long as output < iend-FASTLOOP_SAFE_DISTANCE */ + while (1) { + /* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */ + assert(oend - op >= FASTLOOP_SAFE_DISTANCE); + if (endOnInput) { assert(ip < iend); } + token = *ip++; + length = token >> ML_BITS; /* literal length */ + + assert(!endOnInput || ip <= iend); /* ip < iend before the increment */ + + /* decode literal length */ + if (length == RUN_MASK) { + variable_length_error error = ok; + length += read_variable_length(&ip, iend - RUN_MASK, endOnInput, endOnInput, &error); + if (error == initial_error) { goto _output_error; } + if ((safeDecode) && unlikely((uptrval)(op) + length < (uptrval)(op))) { goto _output_error; } /* overflow detection */ + if ((safeDecode) && unlikely((uptrval)(ip) + length < (uptrval)(ip))) { goto _output_error; } /* overflow detection */ + + /* copy literals */ + cpy = op + length; + LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); + if (endOnInput) { /* LZ4_decompress_safe() */ + if ((cpy > oend - 32) || (ip + length > iend - 32)) { goto safe_literal_copy; } + LZ4_wildCopy32(op, ip, cpy); + } else { /* LZ4_decompress_fast() */ + if (cpy > oend - 8) { goto safe_literal_copy; } + LZ4_wildCopy8(op, ip, cpy); /* LZ4_decompress_fast() cannot copy more than 8 bytes at a time : + * it doesn't know input length, and only relies on end-of-block properties */ + } + ip += length; + op = cpy; + } else { + cpy = op + length; + if (endOnInput) { /* LZ4_decompress_safe() */ + DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length); + /* We don't need to check oend, since we check it once for each loop below */ + if (ip > iend - (16 + 1/*max lit + offset + nextToken*/)) { goto safe_literal_copy; } + /* Literals can only be 14, but hope compilers optimize if we copy by a register size */ + memcpy(op, ip, 16); + } else { /* LZ4_decompress_fast() */ + /* LZ4_decompress_fast() cannot copy more than 8 bytes at a time : + * it doesn't know input length, and relies on end-of-block properties */ + memcpy(op, ip, 8); + if (length > 8) { memcpy(op + 8, ip + 8, 8); } + } + ip += length; + op = cpy; + } + + /* get offset */ + offset = LZ4_readLE16(ip); + ip += 2; + match = op - offset; + assert(match <= op); + + /* get matchlength */ + length = token & ML_MASK; + + if (length == ML_MASK) { + variable_length_error error = ok; + if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */ + length += read_variable_length(&ip, iend - LASTLITERALS + 1, endOnInput, 0, &error); + if (error != ok) { goto _output_error; } + if ((safeDecode) && unlikely((uptrval)(op) + length < (uptrval)op)) { goto _output_error; } /* overflow detection */ + length += MINMATCH; + if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { + goto safe_match_copy; + } + } else { + length += MINMATCH; + if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { + goto safe_match_copy; + } + + /* Fastpath check: Avoids a branch in LZ4_wildCopy32 if true */ + if ((dict == withPrefix64k) || (match >= lowPrefix)) { + if (offset >= 8) { + assert(match >= lowPrefix); + assert(match <= op); + assert(op + 18 <= oend); + + memcpy(op, match, 8); + memcpy(op + 8, match + 8, 8); + memcpy(op + 16, match + 16, 2); + op += length; + continue; + } + } + } + + if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */ + /* match starting within external dictionary */ + if ((dict == usingExtDict) && (match < lowPrefix)) { + if (unlikely(op + length > oend - LASTLITERALS)) { + if (partialDecoding) { + length = MIN(length, (size_t)(oend - op)); /* reach end of buffer */ + } else { + goto _output_error; /* end-of-block condition violated */ + } + } + + if (length <= (size_t)(lowPrefix - match)) { + /* match fits entirely within external dictionary : just copy */ + memmove(op, dictEnd - (lowPrefix - match), length); + op += length; + } else { + /* match stretches into both external dictionary and current block */ + size_t const copySize = (size_t)(lowPrefix - match); + size_t const restSize = length - copySize; + memcpy(op, dictEnd - copySize, copySize); + op += copySize; + if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ + BYTE *const endOfMatch = op + restSize; + const BYTE *copyFrom = lowPrefix; + while (op < endOfMatch) { *op++ = *copyFrom++; } + } else { + memcpy(op, lowPrefix, restSize); + op += restSize; + } + } + continue; + } + + /* copy match within block */ + cpy = op + length; + + assert((op <= oend) && (oend - op >= 32)); + if (unlikely(offset < 16)) { + LZ4_memcpy_using_offset(op, match, cpy, offset); + } else { + LZ4_wildCopy32(op, match, cpy); + } + + op = cpy; /* wildcopy correction */ + } +safe_decode: +#endif + + /* Main Loop : decode remaining sequences where output < FASTLOOP_SAFE_DISTANCE */ + while (1) { + token = *ip++; + length = token >> ML_BITS; /* literal length */ + + assert(!endOnInput || ip <= iend); /* ip < iend before the increment */ + + /* A two-stage shortcut for the most common case: + * 1) If the literal length is 0..14, and there is enough space, + * enter the shortcut and copy 16 bytes on behalf of the literals + * (in the fast mode, only 8 bytes can be safely copied this way). + * 2) Further if the match length is 4..18, copy 18 bytes in a similar + * manner; but we ensure that there's enough space in the output for + * those 18 bytes earlier, upon entering the shortcut (in other words, + * there is a combined check for both stages). + */ + if ((endOnInput ? length != RUN_MASK : length <= 8) + /* strictly "less than" on input, to re-enter the loop with at least one byte */ + && likely((endOnInput ? ip < shortiend : 1) & (op <= shortoend))) { + /* Copy the literals */ + memcpy(op, ip, endOnInput ? 16 : 8); + op += length; + ip += length; + + /* The second stage: prepare for match copying, decode full info. + * If it doesn't work out, the info won't be wasted. */ + length = token & ML_MASK; /* match length */ + offset = LZ4_readLE16(ip); + ip += 2; + match = op - offset; + assert(match <= op); /* check overflow */ + + /* Do not deal with overlapping matches. */ + if ((length != ML_MASK) + && (offset >= 8) + && (dict == withPrefix64k || match >= lowPrefix)) { + /* Copy the match. */ + memcpy(op + 0, match + 0, 8); + memcpy(op + 8, match + 8, 8); + memcpy(op + 16, match + 16, 2); + op += length + MINMATCH; + /* Both stages worked, load the next token. */ + continue; + } + + /* The second stage didn't work out, but the info is ready. + * Propel it right to the point of match copying. */ + goto _copy_match; + } + + /* decode literal length */ + if (length == RUN_MASK) { + variable_length_error error = ok; + length += read_variable_length(&ip, iend - RUN_MASK, endOnInput, endOnInput, &error); + if (error == initial_error) { goto _output_error; } + if ((safeDecode) && unlikely((uptrval)(op) + length < (uptrval)(op))) { goto _output_error; } /* overflow detection */ + if ((safeDecode) && unlikely((uptrval)(ip) + length < (uptrval)(ip))) { goto _output_error; } /* overflow detection */ + } + + /* copy literals */ + cpy = op + length; +#if LZ4_FAST_DEC_LOOP +safe_literal_copy: +#endif + LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); + if (((endOnInput) && ((cpy > oend - MFLIMIT) || (ip + length > iend - (2 + 1 + LASTLITERALS)))) + || ((!endOnInput) && (cpy > oend - WILDCOPYLENGTH))) { + /* We've either hit the input parsing restriction or the output parsing restriction. + * If we've hit the input parsing condition then this must be the last sequence. + * If we've hit the output parsing condition then we are either using partialDecoding + * or we've hit the output parsing condition. + */ + if (partialDecoding) { + /* Since we are partial decoding we may be in this block because of the output parsing + * restriction, which is not valid since the output buffer is allowed to be undersized. + */ + assert(endOnInput); + /* If we're in this block because of the input parsing condition, then we must be on the + * last sequence (or invalid), so we must check that we exactly consume the input. + */ + if ((ip + length > iend - (2 + 1 + LASTLITERALS)) && (ip + length != iend)) { goto _output_error; } + assert(ip + length <= iend); + /* We are finishing in the middle of a literals segment. + * Break after the copy. + */ + if (cpy > oend) { + cpy = oend; + assert(op <= oend); + length = (size_t)(oend - op); + } + assert(ip + length <= iend); + } else { + /* We must be on the last sequence because of the parsing limitations so check + * that we exactly regenerate the original size (must be exact when !endOnInput). + */ + if ((!endOnInput) && (cpy != oend)) { goto _output_error; } + /* We must be on the last sequence (or invalid) because of the parsing limitations + * so check that we exactly consume the input and don't overrun the output buffer. + */ + if ((endOnInput) && ((ip + length != iend) || (cpy > oend))) { goto _output_error; } + } + memmove(op, ip, length); /* supports overlapping memory regions, which only matters for in-place decompression scenarios */ + ip += length; + op += length; + /* Necessarily EOF when !partialDecoding. When partialDecoding + * it is EOF if we've either filled the output buffer or hit + * the input parsing restriction. + */ + if (!partialDecoding || (cpy == oend) || (ip == iend)) { + break; + } + } else { + LZ4_wildCopy8(op, ip, cpy); /* may overwrite up to WILDCOPYLENGTH beyond cpy */ + ip += length; + op = cpy; + } + + /* get offset */ + offset = LZ4_readLE16(ip); + ip += 2; + match = op - offset; + + /* get matchlength */ + length = token & ML_MASK; + +_copy_match: + if (length == ML_MASK) { + variable_length_error error = ok; + length += read_variable_length(&ip, iend - LASTLITERALS + 1, endOnInput, 0, &error); + if (error != ok) goto _output_error; + if ((safeDecode) && unlikely((uptrval)(op) + length < (uptrval)op)) goto _output_error; /* overflow detection */ + } + length += MINMATCH; + +#if LZ4_FAST_DEC_LOOP +safe_match_copy: +#endif + if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */ + /* match starting within external dictionary */ + if ((dict == usingExtDict) && (match < lowPrefix)) { + if (unlikely(op + length > oend - LASTLITERALS)) { + if (partialDecoding) length = MIN(length, (size_t)(oend - op)); + else goto _output_error; /* doesn't respect parsing restriction */ + } + + if (length <= (size_t)(lowPrefix - match)) { + /* match fits entirely within external dictionary : just copy */ + memmove(op, dictEnd - (lowPrefix - match), length); + op += length; + } else { + /* match stretches into both external dictionary and current block */ + size_t const copySize = (size_t)(lowPrefix - match); + size_t const restSize = length - copySize; + memcpy(op, dictEnd - copySize, copySize); + op += copySize; + if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ + BYTE *const endOfMatch = op + restSize; + const BYTE *copyFrom = lowPrefix; + while (op < endOfMatch) *op++ = *copyFrom++; + } else { + memcpy(op, lowPrefix, restSize); + op += restSize; + } + } + continue; + } + assert(match >= lowPrefix); + + /* copy match within block */ + cpy = op + length; + + /* partialDecoding : may end anywhere within the block */ + assert(op <= oend); + if (partialDecoding && (cpy > oend - MATCH_SAFEGUARD_DISTANCE)) { + size_t const mlen = MIN(length, (size_t)(oend - op)); + const BYTE *const matchEnd = match + mlen; + BYTE *const copyEnd = op + mlen; + if (matchEnd > op) { /* overlap copy */ + while (op < copyEnd) { *op++ = *match++; } + } else { + memcpy(op, match, mlen); + } + op = copyEnd; + if (op == oend) { break; } + continue; + } + + if (unlikely(offset < 8)) { + LZ4_write32(op, 0); /* silence msan warning when offset==0 */ + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += inc32table[offset]; + memcpy(op + 4, match, 4); + match -= dec64table[offset]; + } else { + memcpy(op, match, 8); + match += 8; + } + op += 8; + + if (unlikely(cpy > oend - MATCH_SAFEGUARD_DISTANCE)) { + BYTE *const oCopyLimit = oend - (WILDCOPYLENGTH - 1); + if (cpy > oend - LASTLITERALS) { goto _output_error; } /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ + if (op < oCopyLimit) { + LZ4_wildCopy8(op, match, oCopyLimit); + match += oCopyLimit - op; + op = oCopyLimit; + } + while (op < cpy) { *op++ = *match++; } + } else { + memcpy(op, match, 8); + if (length > 16) { LZ4_wildCopy8(op + 8, match + 8, cpy); } + } + op = cpy; /* wildcopy correction */ + } + + /* end of decoding */ + if (endOnInput) { + return (int)(((char *)op) - dst); /* Nb of output bytes decoded */ + } else { + return (int)(((const char *)ip) - src); /* Nb of input bytes read */ + } + + /* Overflow error detected */ +_output_error: + return (int)(-(((const char *)ip) - src)) - 1; + } +} + + +/*===== Instantiate the API decoding functions. =====*/ + +LZ4_FORCE_O2_GCC_PPC64LE +int LZ4_decompress_safe(const char *source, char *dest, int compressedSize, int maxDecompressedSize) { + return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, + endOnInputSize, decode_full_block, noDict, + (BYTE *)dest, NULL, 0); +} + +LZ4_FORCE_O2_GCC_PPC64LE +int LZ4_decompress_safe_partial(const char *src, char *dst, int compressedSize, int targetOutputSize, int dstCapacity) { + dstCapacity = MIN(targetOutputSize, dstCapacity); + return LZ4_decompress_generic(src, dst, compressedSize, dstCapacity, + endOnInputSize, partial_decode, + noDict, (BYTE *)dst, NULL, 0); +} + +LZ4_FORCE_O2_GCC_PPC64LE +int LZ4_decompress_fast(const char *source, char *dest, int originalSize) { + return LZ4_decompress_generic(source, dest, 0, originalSize, + endOnOutputSize, decode_full_block, withPrefix64k, + (BYTE *)dest - 64 KB, NULL, 0); +} + +/*===== Instantiate a few more decoding cases, used more than once. =====*/ + +LZ4_FORCE_O2_GCC_PPC64LE /* Exported, an obsolete API function. */ +int LZ4_decompress_safe_withPrefix64k(const char *source, char *dest, int compressedSize, int maxOutputSize) { + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, decode_full_block, withPrefix64k, + (BYTE *)dest - 64 KB, NULL, 0); +} + +/* Another obsolete API function, paired with the previous one. */ +int LZ4_decompress_fast_withPrefix64k(const char *source, char *dest, int originalSize) { + /* LZ4_decompress_fast doesn't validate match offsets, + * and thus serves well with any prefixed dictionary. */ + return LZ4_decompress_fast(source, dest, originalSize); +} + +LZ4_FORCE_O2_GCC_PPC64LE +static int LZ4_decompress_safe_withSmallPrefix(const char *source, char *dest, int compressedSize, int maxOutputSize, + size_t prefixSize) { + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, decode_full_block, noDict, + (BYTE *)dest - prefixSize, NULL, 0); +} + +LZ4_FORCE_O2_GCC_PPC64LE +int LZ4_decompress_safe_forceExtDict(const char *source, char *dest, + int compressedSize, int maxOutputSize, + const void *dictStart, size_t dictSize) { + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, decode_full_block, usingExtDict, + (BYTE *)dest, (const BYTE *)dictStart, dictSize); +} + +LZ4_FORCE_O2_GCC_PPC64LE +static int LZ4_decompress_fast_extDict(const char *source, char *dest, int originalSize, + const void *dictStart, size_t dictSize) { + return LZ4_decompress_generic(source, dest, 0, originalSize, + endOnOutputSize, decode_full_block, usingExtDict, + (BYTE *)dest, (const BYTE *)dictStart, dictSize); +} + +/* The "double dictionary" mode, for use with e.g. ring buffers: the first part + * of the dictionary is passed as prefix, and the second via dictStart + dictSize. + * These routines are used only once, in LZ4_decompress_*_continue(). + */ +LZ4_FORCE_INLINE +int LZ4_decompress_safe_doubleDict(const char *source, char *dest, int compressedSize, int maxOutputSize, + size_t prefixSize, const void *dictStart, size_t dictSize) { + return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, + endOnInputSize, decode_full_block, usingExtDict, + (BYTE *)dest - prefixSize, (const BYTE *)dictStart, dictSize); +} + +LZ4_FORCE_INLINE +int LZ4_decompress_fast_doubleDict(const char *source, char *dest, int originalSize, + size_t prefixSize, const void *dictStart, size_t dictSize) { + return LZ4_decompress_generic(source, dest, 0, originalSize, + endOnOutputSize, decode_full_block, usingExtDict, + (BYTE *)dest - prefixSize, (const BYTE *)dictStart, dictSize); +} + +/*===== streaming decompression functions =====*/ + +LZ4_streamDecode_t *LZ4_createStreamDecode(void) { + LZ4_streamDecode_t *lz4s = (LZ4_streamDecode_t *) ALLOC_AND_ZERO(sizeof(LZ4_streamDecode_t)); + LZ4_STATIC_ASSERT(LZ4_STREAMDECODESIZE >= sizeof(LZ4_streamDecode_t_internal)); /* A compilation error here means LZ4_STREAMDECODESIZE is not large enough */ + return lz4s; +} + +int LZ4_freeStreamDecode(LZ4_streamDecode_t *LZ4_stream) { + if (LZ4_stream == NULL) { return 0; } /* support free on NULL */ + FREEMEM(LZ4_stream); + return 0; +} + +/*! LZ4_setStreamDecode() : + * Use this function to instruct where to find the dictionary. + * This function is not necessary if previous data is still available where it was decoded. + * Loading a size of 0 is allowed (same effect as no dictionary). + * @return : 1 if OK, 0 if error + */ +int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode, const char *dictionary, int dictSize) { + LZ4_streamDecode_t_internal *lz4sd = &LZ4_streamDecode->internal_donotuse; + lz4sd->prefixSize = (size_t) dictSize; + lz4sd->prefixEnd = (const BYTE *) dictionary + dictSize; + lz4sd->externalDict = NULL; + lz4sd->extDictSize = 0; + return 1; +} + +/*! LZ4_decoderRingBufferSize() : + * when setting a ring buffer for streaming decompression (optional scenario), + * provides the minimum size of this ring buffer + * to be compatible with any source respecting maxBlockSize condition. + * Note : in a ring buffer scenario, + * blocks are presumed decompressed next to each other. + * When not enough space remains for next block (remainingSize < maxBlockSize), + * decoding resumes from beginning of ring buffer. + * @return : minimum ring buffer size, + * or 0 if there is an error (invalid maxBlockSize). + */ +int LZ4_decoderRingBufferSize(int maxBlockSize) { + if (maxBlockSize < 0) return 0; + if (maxBlockSize > LZ4_MAX_INPUT_SIZE) return 0; + if (maxBlockSize < 16) maxBlockSize = 16; + return LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize); +} + +/* +*_continue() : + These decoding functions allow decompression of multiple blocks in "streaming" mode. + Previously decoded blocks must still be available at the memory position where they were decoded. + If it's not possible, save the relevant part of decoded data into a safe buffer, + and indicate where it stands using LZ4_setStreamDecode() +*/ +LZ4_FORCE_O2_GCC_PPC64LE +int LZ4_decompress_safe_continue(LZ4_streamDecode_t *LZ4_streamDecode, const char *source, char *dest, int compressedSize, int maxOutputSize) { + LZ4_streamDecode_t_internal *lz4sd = &LZ4_streamDecode->internal_donotuse; + int result; + + if (lz4sd->prefixSize == 0) { + /* The first call, no dictionary yet. */ + assert(lz4sd->extDictSize == 0); + result = LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)result; + lz4sd->prefixEnd = (BYTE *)dest + result; + } else if (lz4sd->prefixEnd == (BYTE *)dest) { + /* They're rolling the current segment. */ + if (lz4sd->prefixSize >= 64 KB - 1) + result = LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); + else if (lz4sd->extDictSize == 0) + result = LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, + lz4sd->prefixSize); + else + result = LZ4_decompress_safe_doubleDict(source, dest, compressedSize, maxOutputSize, + lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += (size_t)result; + lz4sd->prefixEnd += result; + } else { + /* The buffer wraps around, or they're switching to another buffer. */ + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; + result = LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, + lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)result; + lz4sd->prefixEnd = (BYTE *)dest + result; + } + + return result; +} + +LZ4_FORCE_O2_GCC_PPC64LE +int LZ4_decompress_fast_continue(LZ4_streamDecode_t *LZ4_streamDecode, const char *source, char *dest, int originalSize) { + LZ4_streamDecode_t_internal *lz4sd = &LZ4_streamDecode->internal_donotuse; + int result; + assert(originalSize >= 0); + + if (lz4sd->prefixSize == 0) { + assert(lz4sd->extDictSize == 0); + result = LZ4_decompress_fast(source, dest, originalSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)originalSize; + lz4sd->prefixEnd = (BYTE *)dest + originalSize; + } else if (lz4sd->prefixEnd == (BYTE *)dest) { + if (lz4sd->prefixSize >= 64 KB - 1 || lz4sd->extDictSize == 0) + result = LZ4_decompress_fast(source, dest, originalSize); + else + result = LZ4_decompress_fast_doubleDict(source, dest, originalSize, + lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize += (size_t)originalSize; + lz4sd->prefixEnd += originalSize; + } else { + lz4sd->extDictSize = lz4sd->prefixSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; + result = LZ4_decompress_fast_extDict(source, dest, originalSize, + lz4sd->externalDict, lz4sd->extDictSize); + if (result <= 0) return result; + lz4sd->prefixSize = (size_t)originalSize; + lz4sd->prefixEnd = (BYTE *)dest + originalSize; + } + + return result; +} + + +/* +Advanced decoding functions : +*_usingDict() : + These decoding functions work the same as "_continue" ones, + the dictionary must be explicitly provided within parameters +*/ + +int LZ4_decompress_safe_usingDict(const char *source, char *dest, int compressedSize, int maxOutputSize, const char *dictStart, int dictSize) { + if (dictSize == 0) + return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); + if (dictStart + dictSize == dest) { + if (dictSize >= 64 KB - 1) { + return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); + } + assert(dictSize >= 0); + return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, (size_t)dictSize); + } + assert(dictSize >= 0); + return LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, dictStart, (size_t)dictSize); +} + +int LZ4_decompress_fast_usingDict(const char *source, char *dest, int originalSize, const char *dictStart, int dictSize) { + if (dictSize == 0 || dictStart + dictSize == dest) + return LZ4_decompress_fast(source, dest, originalSize); + assert(dictSize >= 0); + return LZ4_decompress_fast_extDict(source, dest, originalSize, dictStart, (size_t)dictSize); +} + + +/*=************************************************* +* Obsolete Functions +***************************************************/ +/* obsolete compression functions */ +int LZ4_compress_limitedOutput(const char *source, char *dest, int inputSize, int maxOutputSize) { + return LZ4_compress_default(source, dest, inputSize, maxOutputSize); +} +int LZ4_compress(const char *src, char *dest, int srcSize) { + return LZ4_compress_default(src, dest, srcSize, LZ4_compressBound(srcSize)); +} +int LZ4_compress_limitedOutput_withState(void *state, const char *src, char *dst, int srcSize, int dstSize) { + return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); +} +int LZ4_compress_withState(void *state, const char *src, char *dst, int srcSize) { + return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); +} +int LZ4_compress_limitedOutput_continue(LZ4_stream_t *LZ4_stream, const char *src, char *dst, int srcSize, int dstCapacity) { + return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, dstCapacity, 1); +} +int LZ4_compress_continue(LZ4_stream_t *LZ4_stream, const char *source, char *dest, int inputSize) { + return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); +} + +/* +These decompression functions are deprecated and should no longer be used. +They are only provided here for compatibility with older user programs. +- LZ4_uncompress is totally equivalent to LZ4_decompress_fast +- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe +*/ +int LZ4_uncompress(const char *source, char *dest, int outputSize) { + return LZ4_decompress_fast(source, dest, outputSize); +} +int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize, int maxOutputSize) { + return LZ4_decompress_safe(source, dest, isize, maxOutputSize); +} + +/* Obsolete Streaming functions */ + +int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } + +int LZ4_resetStreamState(void *state, char *inputBuffer) { + (void)inputBuffer; + LZ4_resetStream((LZ4_stream_t *)state); + return 0; +} + +void *LZ4_create(char *inputBuffer) { + (void)inputBuffer; + return LZ4_createStream(); +} + +char *LZ4_slideInputBuffer(void *state) { + /* avoid const char * -> char * conversion warning */ + return (char *)(uptrval)((LZ4_stream_t *)state)->internal_donotuse.dictionary; +} + +#endif /* LZ4_COMMONDEFS_ONLY */ diff --git a/common/lz4/lz4.h b/common/lz4/lz4.h new file mode 100644 index 000000000..82e8008e1 --- /dev/null +++ b/common/lz4/lz4.h @@ -0,0 +1,764 @@ +/* + * LZ4 - Fast LZ compression algorithm + * Header File + * Copyright (C) 2011-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 +*/ +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef LZ4_H_2983827168210 +#define LZ4_H_2983827168210 + +/* --- Dependency --- */ +#include /* size_t */ + + +/** + Introduction + + LZ4 is lossless compression algorithm, providing compression speed >500 MB/s per core, + scalable with multi-cores CPU. It features an extremely fast decoder, with speed in + multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. + + The LZ4 compression library provides in-memory compression and decompression functions. + It gives full buffer control to user. + Compression can be done in: + - a single step (described as Simple Functions) + - a single step, reusing a context (described in Advanced Functions) + - unbounded multiple steps (described as Streaming compression) + + lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md). + Decompressing such a compressed block requires additional metadata. + Exact metadata depends on exact decompression function. + For the typical case of LZ4_decompress_safe(), + metadata includes block's compressed size, and maximum bound of decompressed size. + Each application is free to encode and pass such metadata in whichever way it wants. + + lz4.h only handle blocks, it can not generate Frames. + + Blocks are different from Frames (doc/lz4_Frame_format.md). + Frames bundle both blocks and metadata in a specified manner. + Embedding metadata is required for compressed data to be self-contained and portable. + Frame format is delivered through a companion API, declared in lz4frame.h. + The `lz4` CLI can only manage frames. +*/ + +/*^*************************************************************** +* Export parameters +*****************************************************************/ +/* +* LZ4_DLL_EXPORT : +* Enable exporting of functions when building a Windows DLL +* LZ4LIB_VISIBILITY : +* Control library symbols visibility. +*/ +#ifndef LZ4LIB_VISIBILITY +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default"))) +# else +# define LZ4LIB_VISIBILITY +# endif +#endif +#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) +# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY +#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) +# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define LZ4LIB_API LZ4LIB_VISIBILITY +#endif + +/*------ Version ------*/ +#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ +#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */ + +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) + +#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE +#define LZ4_QUOTE(str) #str +#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) +#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) + +LZ4LIB_API int LZ4_versionNumber(void); /**< library version number; useful to check dll version */ +LZ4LIB_API const char *LZ4_versionString(void); /**< library version string; useful to check dll version */ + + +/*-************************************ +* Tuning parameter +**************************************/ +/*! + * LZ4_MEMORY_USAGE : + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) + * Increasing memory usage improves compression ratio. + * Reduced memory usage may improve speed, thanks to better cache locality. + * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache + */ +#ifndef LZ4_MEMORY_USAGE +# define LZ4_MEMORY_USAGE 14 +#endif + + +/*-************************************ +* Simple Functions +**************************************/ +/*! LZ4_compress_default() : + * Compresses 'srcSize' bytes from buffer 'src' + * into already allocated 'dst' buffer of size 'dstCapacity'. + * Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize). + * It also runs faster, so it's a recommended setting. + * If the function cannot compress 'src' into a more limited 'dst' budget, + * compression stops *immediately*, and the function result is zero. + * In which case, 'dst' content is undefined (invalid). + * srcSize : max supported value is LZ4_MAX_INPUT_SIZE. + * dstCapacity : size of buffer 'dst' (which must be already allocated) + * @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity) + * or 0 if compression fails + * Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer). + */ +LZ4LIB_API int LZ4_compress_default(const char *src, char *dst, int srcSize, int dstCapacity); + +/*! LZ4_decompress_safe() : + * compressedSize : is the exact complete size of the compressed block. + * dstCapacity : is the size of destination buffer (which must be already allocated), presumed an upper bound of decompressed size. + * @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity) + * If destination buffer is not large enough, decoding will stop and output an error code (negative value). + * If the source stream is detected malformed, the function will stop decoding and return a negative result. + * Note 1 : This function is protected against malicious data packets : + * it will never writes outside 'dst' buffer, nor read outside 'source' buffer, + * even if the compressed block is maliciously modified to order the decoder to do these actions. + * In such case, the decoder stops immediately, and considers the compressed block malformed. + * Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them. + * The implementation is free to send / store / derive this information in whichever way is most beneficial. + * If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead. + */ +LZ4LIB_API int LZ4_decompress_safe(const char *src, char *dst, int compressedSize, int dstCapacity); + + +/*-************************************ +* Advanced Functions +**************************************/ +#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) + +/*! LZ4_compressBound() : + Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) + This function is primarily useful for memory allocation purposes (destination buffer size). + Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). + Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize) + inputSize : max supported value is LZ4_MAX_INPUT_SIZE + return : maximum output size in a "worst case" scenario + or 0, if input size is incorrect (too large or negative) +*/ +LZ4LIB_API int LZ4_compressBound(int inputSize); + +/*! LZ4_compress_fast() : + Same as LZ4_compress_default(), but allows selection of "acceleration" factor. + The larger the acceleration value, the faster the algorithm, but also the lesser the compression. + It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. + An acceleration value of "1" is the same as regular LZ4_compress_default() + Values <= 0 will be replaced by ACCELERATION_DEFAULT (currently == 1, see lz4.c). +*/ +LZ4LIB_API int LZ4_compress_fast(const char *src, char *dst, int srcSize, int dstCapacity, int acceleration); + + +/*! LZ4_compress_fast_extState() : + * Same as LZ4_compress_fast(), using an externally allocated memory space for its state. + * Use LZ4_sizeofState() to know how much memory must be allocated, + * and allocate it on 8-bytes boundaries (using `malloc()` typically). + * Then, provide this buffer as `void* state` to compression function. + */ +LZ4LIB_API int LZ4_sizeofState(void); +LZ4LIB_API int LZ4_compress_fast_extState(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int acceleration); + + +/*! LZ4_compress_destSize() : + * Reverse the logic : compresses as much data as possible from 'src' buffer + * into already allocated buffer 'dst', of size >= 'targetDestSize'. + * This function either compresses the entire 'src' content into 'dst' if it's large enough, + * or fill 'dst' buffer completely with as much data as possible from 'src'. + * note: acceleration parameter is fixed to "default". + * + * *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'. + * New value is necessarily <= input value. + * @return : Nb bytes written into 'dst' (necessarily <= targetDestSize) + * or 0 if compression fails. +*/ +LZ4LIB_API int LZ4_compress_destSize(const char *src, char *dst, int *srcSizePtr, int targetDstSize); + + +/*! LZ4_decompress_safe_partial() : + * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src', + * into destination buffer 'dst' of size 'dstCapacity'. + * Up to 'targetOutputSize' bytes will be decoded. + * The function stops decoding on reaching this objective, + * which can boost performance when only the beginning of a block is required. + * + * @return : the number of bytes decoded in `dst` (necessarily <= dstCapacity) + * If source stream is detected malformed, function returns a negative result. + * + * Note : @return can be < targetOutputSize, if compressed block contains less data. + * + * Note 2 : this function features 2 parameters, targetOutputSize and dstCapacity, + * and expects targetOutputSize <= dstCapacity. + * It effectively stops decoding on reaching targetOutputSize, + * so dstCapacity is kind of redundant. + * This is because in a previous version of this function, + * decoding operation would not "break" a sequence in the middle. + * As a consequence, there was no guarantee that decoding would stop at exactly targetOutputSize, + * it could write more bytes, though only up to dstCapacity. + * Some "margin" used to be required for this operation to work properly. + * This is no longer necessary. + * The function nonetheless keeps its signature, in an effort to not break API. + */ +LZ4LIB_API int LZ4_decompress_safe_partial(const char *src, char *dst, int srcSize, int targetOutputSize, int dstCapacity); + + +/*-********************************************* +* Streaming Compression Functions +***********************************************/ +typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ + +LZ4LIB_API LZ4_stream_t *LZ4_createStream(void); +LZ4LIB_API int LZ4_freeStream(LZ4_stream_t *streamPtr); + +/*! LZ4_resetStream_fast() : v1.9.0+ + * Use this to prepare an LZ4_stream_t for a new chain of dependent blocks + * (e.g., LZ4_compress_fast_continue()). + * + * An LZ4_stream_t must be initialized once before usage. + * This is automatically done when created by LZ4_createStream(). + * However, should the LZ4_stream_t be simply declared on stack (for example), + * it's necessary to initialize it first, using LZ4_initStream(). + * + * After init, start any new stream with LZ4_resetStream_fast(). + * A same LZ4_stream_t can be re-used multiple times consecutively + * and compress multiple streams, + * provided that it starts each new stream with LZ4_resetStream_fast(). + * + * LZ4_resetStream_fast() is much faster than LZ4_initStream(), + * but is not compatible with memory regions containing garbage data. + * + * Note: it's only useful to call LZ4_resetStream_fast() + * in the context of streaming compression. + * The *extState* functions perform their own resets. + * Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive. + */ +LZ4LIB_API void LZ4_resetStream_fast(LZ4_stream_t *streamPtr); + +/*! LZ4_loadDict() : + * Use this function to reference a static dictionary into LZ4_stream_t. + * The dictionary must remain available during compression. + * LZ4_loadDict() triggers a reset, so any previous data will be forgotten. + * The same dictionary will have to be loaded on decompression side for successful decoding. + * Dictionary are useful for better compression of small data (KB range). + * While LZ4 accept any input as dictionary, + * results are generally better when using Zstandard's Dictionary Builder. + * Loading a size of 0 is allowed, and is the same as reset. + * @return : loaded dictionary size, in bytes (necessarily <= 64 KB) + */ +LZ4LIB_API int LZ4_loadDict(LZ4_stream_t *streamPtr, const char *dictionary, int dictSize); + +/*! LZ4_compress_fast_continue() : + * Compress 'src' content using data from previously compressed blocks, for better compression ratio. + * 'dst' buffer must be already allocated. + * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. + * + * @return : size of compressed block + * or 0 if there is an error (typically, cannot fit into 'dst'). + * + * Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block. + * Each block has precise boundaries. + * Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata. + * It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together. + * + * Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory ! + * + * Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB. + * Make sure that buffers are separated, by at least one byte. + * This construction ensures that each block only depends on previous block. + * + * Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB. + * + * Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed. + */ +LZ4LIB_API int LZ4_compress_fast_continue(LZ4_stream_t *streamPtr, const char *src, char *dst, int srcSize, int dstCapacity, int acceleration); + +/*! LZ4_saveDict() : + * If last 64KB data cannot be guaranteed to remain available at its current memory location, + * save it into a safer place (char* safeBuffer). + * This is schematically equivalent to a memcpy() followed by LZ4_loadDict(), + * but is much faster, because LZ4_saveDict() doesn't need to rebuild tables. + * @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error. + */ +LZ4LIB_API int LZ4_saveDict(LZ4_stream_t *streamPtr, char *safeBuffer, int maxDictSize); + + +/*-********************************************** +* Streaming Decompression Functions +* Bufferless synchronous API +************************************************/ +typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */ + +/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() : + * creation / destruction of streaming decompression tracking context. + * A tracking context can be re-used multiple times. + */ +LZ4LIB_API LZ4_streamDecode_t *LZ4_createStreamDecode(void); +LZ4LIB_API int LZ4_freeStreamDecode(LZ4_streamDecode_t *LZ4_stream); + +/*! LZ4_setStreamDecode() : + * An LZ4_streamDecode_t context can be allocated once and re-used multiple times. + * Use this function to start decompression of a new stream of blocks. + * A dictionary can optionally be set. Use NULL or size 0 for a reset order. + * Dictionary is presumed stable : it must remain accessible and unmodified during next decompression. + * @return : 1 if OK, 0 if error + */ +LZ4LIB_API int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode, const char *dictionary, int dictSize); + +/*! LZ4_decoderRingBufferSize() : v1.8.2+ + * Note : in a ring buffer scenario (optional), + * blocks are presumed decompressed next to each other + * up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize), + * at which stage it resumes from beginning of ring buffer. + * When setting such a ring buffer for streaming decompression, + * provides the minimum size of this ring buffer + * to be compatible with any source respecting maxBlockSize condition. + * @return : minimum ring buffer size, + * or 0 if there is an error (invalid maxBlockSize). + */ +LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize); +#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */ + +/*! LZ4_decompress_*_continue() : + * These decoding functions allow decompression of consecutive blocks in "streaming" mode. + * A block is an unsplittable entity, it must be presented entirely to a decompression function. + * Decompression functions only accepts one block at a time. + * The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded. + * If less than 64KB of data has been decoded, all the data must be present. + * + * Special : if decompression side sets a ring buffer, it must respect one of the following conditions : + * - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize). + * maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes. + * In which case, encoding and decoding buffers do not need to be synchronized. + * Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize. + * - Synchronized mode : + * Decompression buffer size is _exactly_ the same as compression buffer size, + * and follows exactly same update rule (block boundaries at same positions), + * and decoding function is provided with exact decompressed size of each block (exception for last block of the stream), + * _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB). + * - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes. + * In which case, encoding and decoding buffers do not need to be synchronized, + * and encoding ring buffer can have any size, including small ones ( < 64 KB). + * + * Whenever these conditions are not possible, + * save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression, + * then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block. +*/ +LZ4LIB_API int LZ4_decompress_safe_continue(LZ4_streamDecode_t *LZ4_streamDecode, const char *src, char *dst, int srcSize, int dstCapacity); + + +/*! LZ4_decompress_*_usingDict() : + * These decoding functions work the same as + * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue() + * They are stand-alone, and don't need an LZ4_streamDecode_t structure. + * Dictionary is presumed stable : it must remain accessible and unmodified during decompression. + * Performance tip : Decompression speed can be substantially increased + * when dst == dictStart + dictSize. + */ +LZ4LIB_API int LZ4_decompress_safe_usingDict(const char *src, char *dst, int srcSize, int dstCapcity, const char *dictStart, int dictSize); + +#endif /* LZ4_H_2983827168210 */ + + +/*^************************************* + * !!!!!! STATIC LINKING ONLY !!!!!! + ***************************************/ + +/*-**************************************************************************** + * Experimental section + * + * Symbols declared in this section must be considered unstable. Their + * signatures or semantics may change, or they may be removed altogether in the + * future. They are therefore only safe to depend on when the caller is + * statically linked against the library. + * + * To protect against unsafe usage, not only are the declarations guarded, + * the definitions are hidden by default + * when building LZ4 as a shared/dynamic library. + * + * In order to access these declarations, + * define LZ4_STATIC_LINKING_ONLY in your application + * before including LZ4's headers. + * + * In order to make their implementations accessible dynamically, you must + * define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library. + ******************************************************************************/ + +#ifdef LZ4_STATIC_LINKING_ONLY + +#ifndef LZ4_STATIC_3504398509 +#define LZ4_STATIC_3504398509 + +#ifdef LZ4_PUBLISH_STATIC_FUNCTIONS +#define LZ4LIB_STATIC_API LZ4LIB_API +#else +#define LZ4LIB_STATIC_API +#endif + + +/*! LZ4_compress_fast_extState_fastReset() : + * A variant of LZ4_compress_fast_extState(). + * + * Using this variant avoids an expensive initialization step. + * It is only safe to call if the state buffer is known to be correctly initialized already + * (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized"). + * From a high level, the difference is that + * this function initializes the provided state with a call to something like LZ4_resetStream_fast() + * while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream(). + */ +LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int acceleration); + +/*! LZ4_attach_dictionary() : + * This is an experimental API that allows + * efficient use of a static dictionary many times. + * + * Rather than re-loading the dictionary buffer into a working context before + * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a + * working LZ4_stream_t, this function introduces a no-copy setup mechanism, + * in which the working stream references the dictionary stream in-place. + * + * Several assumptions are made about the state of the dictionary stream. + * Currently, only streams which have been prepared by LZ4_loadDict() should + * be expected to work. + * + * Alternatively, the provided dictionaryStream may be NULL, + * in which case any existing dictionary stream is unset. + * + * If a dictionary is provided, it replaces any pre-existing stream history. + * The dictionary contents are the only history that can be referenced and + * logically immediately precede the data compressed in the first subsequent + * compression call. + * + * The dictionary will only remain attached to the working stream through the + * first compression call, at the end of which it is cleared. The dictionary + * stream (and source buffer) must remain in-place / accessible / unchanged + * through the completion of the first compression call on the stream. + */ +LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t *workingStream, const LZ4_stream_t *dictionaryStream); + + +/*! In-place compression and decompression + * + * It's possible to have input and output sharing the same buffer, + * for highly contrained memory environments. + * In both cases, it requires input to lay at the end of the buffer, + * and decompression to start at beginning of the buffer. + * Buffer size must feature some margin, hence be larger than final size. + * + * |<------------------------buffer--------------------------------->| + * |<-----------compressed data--------->| + * |<-----------decompressed size------------------>| + * |<----margin---->| + * + * This technique is more useful for decompression, + * since decompressed size is typically larger, + * and margin is short. + * + * In-place decompression will work inside any buffer + * which size is >= LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize). + * This presumes that decompressedSize > compressedSize. + * Otherwise, it means compression actually expanded data, + * and it would be more efficient to store such data with a flag indicating it's not compressed. + * This can happen when data is not compressible (already compressed, or encrypted). + * + * For in-place compression, margin is larger, as it must be able to cope with both + * history preservation, requiring input data to remain unmodified up to LZ4_DISTANCE_MAX, + * and data expansion, which can happen when input is not compressible. + * As a consequence, buffer size requirements are much higher, + * and memory savings offered by in-place compression are more limited. + * + * There are ways to limit this cost for compression : + * - Reduce history size, by modifying LZ4_DISTANCE_MAX. + * Note that it is a compile-time constant, so all compressions will apply this limit. + * Lower values will reduce compression ratio, except when input_size < LZ4_DISTANCE_MAX, + * so it's a reasonable trick when inputs are known to be small. + * - Require the compressor to deliver a "maximum compressed size". + * This is the `dstCapacity` parameter in `LZ4_compress*()`. + * When this size is < LZ4_COMPRESSBOUND(inputSize), then compression can fail, + * in which case, the return code will be 0 (zero). + * The caller must be ready for these cases to happen, + * and typically design a backup scheme to send data uncompressed. + * The combination of both techniques can significantly reduce + * the amount of margin required for in-place compression. + * + * In-place compression can work in any buffer + * which size is >= (maxCompressedSize) + * with maxCompressedSize == LZ4_COMPRESSBOUND(srcSize) for guaranteed compression success. + * LZ4_COMPRESS_INPLACE_BUFFER_SIZE() depends on both maxCompressedSize and LZ4_DISTANCE_MAX, + * so it's possible to reduce memory requirements by playing with them. + */ + +#define LZ4_DECOMPRESS_INPLACE_MARGIN(compressedSize) (((compressedSize) >> 8) + 32) +#define LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize) ((decompressedSize) + LZ4_DECOMPRESS_INPLACE_MARGIN(decompressedSize)) /**< note: presumes that compressedSize < decompressedSize. note2: margin is overestimated a bit, since it could use compressedSize instead */ + +#ifndef LZ4_DISTANCE_MAX /* history window size; can be user-defined at compile time */ +# define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */ +#endif + +#define LZ4_COMPRESS_INPLACE_MARGIN (LZ4_DISTANCE_MAX + 32) /* LZ4_DISTANCE_MAX can be safely replaced by srcSize when it's smaller */ +#define LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCompressedSize) ((maxCompressedSize) + LZ4_COMPRESS_INPLACE_MARGIN) /**< maxCompressedSize is generally LZ4_COMPRESSBOUND(inputSize), but can be set to any lower value, with the risk that compression can fail (return code 0(zero)) */ + +#endif /* LZ4_STATIC_3504398509 */ +#endif /* LZ4_STATIC_LINKING_ONLY */ + + + +#ifndef LZ4_H_98237428734687 +#define LZ4_H_98237428734687 + +/*-************************************************************ + * PRIVATE DEFINITIONS + ************************************************************** + * Do not use these definitions directly. + * They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. + * Accessing members will expose code to API and/or ABI break in future versions of the library. + **************************************************************/ +#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) +#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) +#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ + +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +#include + +typedef struct LZ4_stream_t_internal LZ4_stream_t_internal; +struct LZ4_stream_t_internal { + uint32_t hashTable[LZ4_HASH_SIZE_U32]; + uint32_t currentOffset; + uint16_t dirty; + uint16_t tableType; + const uint8_t *dictionary; + const LZ4_stream_t_internal *dictCtx; + uint32_t dictSize; +}; + +typedef struct { + const uint8_t *externalDict; + size_t extDictSize; + const uint8_t *prefixEnd; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#else + +typedef struct LZ4_stream_t_internal LZ4_stream_t_internal; +struct LZ4_stream_t_internal { + unsigned int hashTable[LZ4_HASH_SIZE_U32]; + unsigned int currentOffset; + unsigned short dirty; + unsigned short tableType; + const unsigned char *dictionary; + const LZ4_stream_t_internal *dictCtx; + unsigned int dictSize; +}; + +typedef struct { + const unsigned char *externalDict; + const unsigned char *prefixEnd; + size_t extDictSize; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#endif + +/*! LZ4_stream_t : + * information structure to track an LZ4 stream. + * LZ4_stream_t can also be created using LZ4_createStream(), which is recommended. + * The structure definition can be convenient for static allocation + * (on stack, or as part of larger structure). + * Init this structure with LZ4_initStream() before first use. + * note : only use this definition in association with static linking ! + * this definition is not API/ABI safe, and may change in a future version. + */ +#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4 + ((sizeof(void*)==16) ? 4 : 0) /*AS-400*/ ) +#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long)) +union LZ4_stream_u { + unsigned long long table[LZ4_STREAMSIZE_U64]; + LZ4_stream_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_stream_t */ + +/*! LZ4_initStream() : v1.9.0+ + * An LZ4_stream_t structure must be initialized at least once. + * This is automatically done when invoking LZ4_createStream(), + * but it's not when the structure is simply declared on stack (for example). + * + * Use LZ4_initStream() to properly initialize a newly declared LZ4_stream_t. + * It can also initialize any arbitrary buffer of sufficient size, + * and will @return a pointer of proper type upon initialization. + * + * Note : initialization fails if size and alignment conditions are not respected. + * In which case, the function will @return NULL. + * Note2: An LZ4_stream_t structure guarantees correct alignment and size. + * Note3: Before v1.9.0, use LZ4_resetStream() instead + */ +LZ4LIB_API LZ4_stream_t *LZ4_initStream(void *buffer, size_t size); + + +/*! LZ4_streamDecode_t : + * information structure to track an LZ4 stream during decompression. + * init this structure using LZ4_setStreamDecode() before first use. + * note : only use in association with static linking ! + * this definition is not API/ABI safe, + * and may change in a future version ! + */ +#define LZ4_STREAMDECODESIZE_U64 (4 + ((sizeof(void*)==16) ? 2 : 0) /*AS-400*/ ) +#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) +union LZ4_streamDecode_u { + unsigned long long table[LZ4_STREAMDECODESIZE_U64]; + LZ4_streamDecode_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_streamDecode_t */ + + + +/*-************************************ +* Obsolete Functions +**************************************/ + +/*! Deprecation warnings + * + * Deprecated functions make the compiler generate a warning when invoked. + * This is meant to invite users to update their source code. + * Should deprecation warnings be a problem, it is generally possible to disable them, + * typically with -Wno-deprecated-declarations for gcc + * or _CRT_SECURE_NO_WARNINGS in Visual. + * + * Another method is to define LZ4_DISABLE_DEPRECATE_WARNINGS + * before including the header file. + */ +#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS +# define LZ4_DEPRECATED(message) /* disable deprecation warnings */ +#else +# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define LZ4_DEPRECATED(message) [[deprecated(message)]] +# elif (LZ4_GCC_VERSION >= 405) || defined(__clang__) +# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) +# elif (LZ4_GCC_VERSION >= 301) +# define LZ4_DEPRECATED(message) __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define LZ4_DEPRECATED(message) __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") +# define LZ4_DEPRECATED(message) +# endif +#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ + +/* Obsolete compression functions */ +LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress(const char *src, char *dest, int srcSize); +LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput(const char *src, char *dest, int srcSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState(void *state, const char *source, char *dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState(void *state, const char *source, char *dest, int inputSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue(LZ4_stream_t *LZ4_streamPtr, const char *source, char *dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue(LZ4_stream_t *LZ4_streamPtr, const char *source, char *dest, int inputSize, int maxOutputSize); + +/* Obsolete decompression functions */ +LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress(const char *source, char *dest, int outputSize); +LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize, int maxOutputSize); + +/* Obsolete streaming functions; degraded functionality; do not use! + * + * In order to perform streaming compression, these functions depended on data + * that is no longer tracked in the state. They have been preserved as well as + * possible: using them will still produce a correct output. However, they don't + * actually retain any history between compression calls. The compression ratio + * achieved will therefore be no better than compressing each chunk + * independently. + */ +LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void *LZ4_create(char *inputBuffer); +LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void); +LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void *state, char *inputBuffer); +LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char *LZ4_slideInputBuffer(void *state); + +/* Obsolete streaming decoding functions */ +LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k(const char *src, char *dst, int compressedSize, int maxDstSize); +LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k(const char *src, char *dst, int originalSize); + +/*! LZ4_decompress_fast() : **unsafe!** + * These functions used to be faster than LZ4_decompress_safe(), + * but it has changed, and they are now slower than LZ4_decompress_safe(). + * This is because LZ4_decompress_fast() doesn't know the input size, + * and therefore must progress more cautiously in the input buffer to not read beyond the end of block. + * On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability. + * As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated. + * + * The last remaining LZ4_decompress_fast() specificity is that + * it can decompress a block without knowing its compressed size. + * Such functionality could be achieved in a more secure manner, + * by also providing the maximum size of input buffer, + * but it would require new prototypes, and adaptation of the implementation to this new use case. + * + * Parameters: + * originalSize : is the uncompressed size to regenerate. + * `dst` must be already allocated, its size must be >= 'originalSize' bytes. + * @return : number of bytes read from source buffer (== compressed size). + * The function expects to finish at block's end exactly. + * If the source stream is detected malformed, the function stops decoding and returns a negative result. + * note : LZ4_decompress_fast*() requires originalSize. Thanks to this information, it never writes past the output buffer. + * However, since it doesn't know its 'src' size, it may read an unknown amount of input, past input buffer bounds. + * Also, since match offsets are not validated, match reads from 'src' may underflow too. + * These issues never happen if input (compressed) data is correct. + * But they may happen if input data is invalid (error or intentional tampering). + * As a consequence, use these functions in trusted environments with trusted data **only**. + */ + +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead") +LZ4LIB_API int LZ4_decompress_fast(const char *src, char *dst, int originalSize); +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead") +LZ4LIB_API int LZ4_decompress_fast_continue(LZ4_streamDecode_t *LZ4_streamDecode, const char *src, char *dst, int originalSize); +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead") +LZ4LIB_API int LZ4_decompress_fast_usingDict(const char *src, char *dst, int originalSize, const char *dictStart, int dictSize); + +/*! LZ4_resetStream() : + * An LZ4_stream_t structure must be initialized at least once. + * This is done with LZ4_initStream(), or LZ4_resetStream(). + * Consider switching to LZ4_initStream(), + * invoking LZ4_resetStream() will trigger deprecation warnings in the future. + */ +LZ4LIB_API void LZ4_resetStream(LZ4_stream_t *streamPtr); + + +#endif /* LZ4_H_98237428734687 */ + + +#if defined (__cplusplus) +} +#endif diff --git a/common/lz4/lz4hc.c b/common/lz4/lz4hc.c new file mode 100644 index 000000000..a12cddccc --- /dev/null +++ b/common/lz4/lz4hc.c @@ -0,0 +1,1555 @@ +/* + LZ4 HC - High Compression Mode of LZ4 + Copyright (C) 2011-2017, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 source repository : https://github.com/lz4/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ +/* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */ + + +/* ************************************* +* Tuning Parameter +***************************************/ + +/*! HEAPMODE : + * Select how default compression function will allocate workplace memory, + * in stack (0:fastest), or in heap (1:requires malloc()). + * Since workplace is rather large, heap mode is recommended. + */ +#ifndef LZ4HC_HEAPMODE +# define LZ4HC_HEAPMODE 1 +#endif + + +/*=== Dependency ===*/ +#define LZ4_HC_STATIC_LINKING_ONLY +#include "lz4hc.h" + + +/*=== Common LZ4 definitions ===*/ +#if defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wunused-function" +#endif +#if defined (__clang__) +# pragma clang diagnostic ignored "-Wunused-function" +#endif + +/*=== Enums ===*/ +typedef enum { noDictCtx, usingDictCtxHc } dictCtx_directive; + + +#define LZ4_COMMONDEFS_ONLY +#ifndef LZ4_SRC_INCLUDED +#include "lz4.c" /* LZ4_count, constants, mem */ +#endif + +/*=== Constants ===*/ +#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH) +#define LZ4_OPT_NUM (1<<12) + + +/*=== Macros ===*/ +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) +#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) +#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG)) +#define DELTANEXTMAXD(p) chainTable[(p) & LZ4HC_MAXD_MASK] /* flexible, LZ4HC_MAXD dependent */ +#define DELTANEXTU16(table, pos) table[(U16)(pos)] /* faster */ +/* Make fields passed to, and updated by LZ4HC_encodeSequence explicit */ +#define UPDATABLE(ip, op, anchor) &ip, &op, &anchor + +static U32 LZ4HC_hashPtr(const void *ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); } + + +/************************************** +* HC Compression +**************************************/ +static void LZ4HC_clearTables(LZ4HC_CCtx_internal *hc4) { + MEM_INIT((void *)hc4->hashTable, 0, sizeof(hc4->hashTable)); + MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); +} + +static void LZ4HC_init_internal(LZ4HC_CCtx_internal *hc4, const BYTE *start) { + uptrval startingOffset = (uptrval)(hc4->end - hc4->base); + if (startingOffset > 1 GB) { + LZ4HC_clearTables(hc4); + startingOffset = 0; + } + startingOffset += 64 KB; + hc4->nextToUpdate = (U32) startingOffset; + hc4->base = start - startingOffset; + hc4->end = start; + hc4->dictBase = start - startingOffset; + hc4->dictLimit = (U32) startingOffset; + hc4->lowLimit = (U32) startingOffset; +} + + +/* Update chains up to ip (excluded) */ +LZ4_FORCE_INLINE void LZ4HC_Insert(LZ4HC_CCtx_internal *hc4, const BYTE *ip) { + U16 *const chainTable = hc4->chainTable; + U32 *const hashTable = hc4->hashTable; + const BYTE *const base = hc4->base; + U32 const target = (U32)(ip - base); + U32 idx = hc4->nextToUpdate; + + while (idx < target) { + U32 const h = LZ4HC_hashPtr(base + idx); + size_t delta = idx - hashTable[h]; + if (delta > LZ4_DISTANCE_MAX) delta = LZ4_DISTANCE_MAX; + DELTANEXTU16(chainTable, idx) = (U16)delta; + hashTable[h] = idx; + idx++; + } + + hc4->nextToUpdate = target; +} + +/** LZ4HC_countBack() : + * @return : negative value, nb of common bytes before ip/match */ +LZ4_FORCE_INLINE +int LZ4HC_countBack(const BYTE *const ip, const BYTE *const match, + const BYTE *const iMin, const BYTE *const mMin) { + int back = 0; + int const min = (int)MAX(iMin - ip, mMin - match); + assert(min <= 0); + assert(ip >= iMin); + assert((size_t)(ip - iMin) < (1U << 31)); + assert(match >= mMin); + assert((size_t)(match - mMin) < (1U << 31)); + while ((back > min) + && (ip[back - 1] == match[back - 1])) + back--; + return back; +} + +#if defined(_MSC_VER) +# define LZ4HC_rotl32(x,r) _rotl(x,r) +#else +# define LZ4HC_rotl32(x,r) ((x << r) | (x >> (32 - r))) +#endif + + +static U32 LZ4HC_rotatePattern(size_t const rotate, U32 const pattern) { + size_t const bitsToRotate = (rotate & (sizeof(pattern) - 1)) << 3; + if (bitsToRotate == 0) + return pattern; + return LZ4HC_rotl32(pattern, (int)bitsToRotate); +} + +/* LZ4HC_countPattern() : + * pattern32 must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!) */ +static unsigned +LZ4HC_countPattern(const BYTE *ip, const BYTE *const iEnd, U32 const pattern32) { + const BYTE *const iStart = ip; + reg_t const pattern = (sizeof(pattern) == 8) ? (reg_t)pattern32 + (((reg_t)pattern32) << 32) : pattern32; + + while (likely(ip < iEnd - (sizeof(pattern) - 1))) { + reg_t const diff = LZ4_read_ARCH(ip) ^ pattern; + if (!diff) { ip += sizeof(pattern); continue; } + ip += LZ4_NbCommonBytes(diff); + return (unsigned)(ip - iStart); + } + + if (LZ4_isLittleEndian()) { + reg_t patternByte = pattern; + while ((ip < iEnd) && (*ip == (BYTE)patternByte)) { + ip++; + patternByte >>= 8; + } + } else { /* big endian */ + U32 bitOffset = (sizeof(pattern) * 8) - 8; + while (ip < iEnd) { + BYTE const byte = (BYTE)(pattern >> bitOffset); + if (*ip != byte) break; + ip ++; + bitOffset -= 8; + } + } + + return (unsigned)(ip - iStart); +} + +/* LZ4HC_reverseCountPattern() : + * pattern must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!) + * read using natural platform endianess */ +static unsigned +LZ4HC_reverseCountPattern(const BYTE *ip, const BYTE *const iLow, U32 pattern) { + const BYTE *const iStart = ip; + + while (likely(ip >= iLow + 4)) { + if (LZ4_read32(ip - 4) != pattern) break; + ip -= 4; + } + { + const BYTE *bytePtr = (const BYTE *)(&pattern) + 3; /* works for any endianess */ + while (likely(ip > iLow)) { + if (ip[-1] != *bytePtr) break; + ip--; + bytePtr--; + } + } + return (unsigned)(iStart - ip); +} + +/* LZ4HC_protectDictEnd() : + * Checks if the match is in the last 3 bytes of the dictionary, so reading the + * 4 byte MINMATCH would overflow. + * @returns true if the match index is okay. + */ +static int LZ4HC_protectDictEnd(U32 const dictLimit, U32 const matchIndex) { + return ((U32)((dictLimit - 1) - matchIndex) >= 3); +} + +typedef enum { rep_untested, rep_not, rep_confirmed } repeat_state_e; +typedef enum { favorCompressionRatio = 0, favorDecompressionSpeed } HCfavor_e; + +LZ4_FORCE_INLINE int +LZ4HC_InsertAndGetWiderMatch( + LZ4HC_CCtx_internal *hc4, + const BYTE *const ip, + const BYTE *const iLowLimit, + const BYTE *const iHighLimit, + int longest, + const BYTE **matchpos, + const BYTE **startpos, + const int maxNbAttempts, + const int patternAnalysis, + const int chainSwap, + const dictCtx_directive dict, + const HCfavor_e favorDecSpeed) { + U16 *const chainTable = hc4->chainTable; + U32 *const HashTable = hc4->hashTable; + const LZ4HC_CCtx_internal *const dictCtx = hc4->dictCtx; + const BYTE *const base = hc4->base; + const U32 dictLimit = hc4->dictLimit; + const BYTE *const lowPrefixPtr = base + dictLimit; + const U32 ipIndex = (U32)(ip - base); + const U32 lowestMatchIndex = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX; + const BYTE *const dictBase = hc4->dictBase; + int const lookBackLength = (int)(ip - iLowLimit); + int nbAttempts = maxNbAttempts; + U32 matchChainPos = 0; + U32 const pattern = LZ4_read32(ip); + U32 matchIndex; + repeat_state_e repeat = rep_untested; + size_t srcPatternLength = 0; + + DEBUGLOG(7, "LZ4HC_InsertAndGetWiderMatch"); + /* First Match */ + LZ4HC_Insert(hc4, ip); + matchIndex = HashTable[LZ4HC_hashPtr(ip)]; + DEBUGLOG(7, "First match at index %u / %u (lowestMatchIndex)", + matchIndex, lowestMatchIndex); + + while ((matchIndex >= lowestMatchIndex) && (nbAttempts)) { + int matchLength = 0; + nbAttempts--; + assert(matchIndex < ipIndex); + if (favorDecSpeed && (ipIndex - matchIndex < 8)) { + /* do nothing */ + } else if (matchIndex >= dictLimit) { /* within current Prefix */ + const BYTE *const matchPtr = base + matchIndex; + assert(matchPtr >= lowPrefixPtr); + assert(matchPtr < ip); + assert(longest >= 1); + if (LZ4_read16(iLowLimit + longest - 1) == LZ4_read16(matchPtr - lookBackLength + longest - 1)) { + if (LZ4_read32(matchPtr) == pattern) { + int const back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, lowPrefixPtr) : 0; + matchLength = MINMATCH + (int)LZ4_count(ip + MINMATCH, matchPtr + MINMATCH, iHighLimit); + matchLength -= back; + if (matchLength > longest) { + longest = matchLength; + *matchpos = matchPtr + back; + *startpos = ip + back; + } + } + } + } else { /* lowestMatchIndex <= matchIndex < dictLimit */ + const BYTE *const matchPtr = dictBase + matchIndex; + if (LZ4_read32(matchPtr) == pattern) { + const BYTE *const dictStart = dictBase + hc4->lowLimit; + int back = 0; + const BYTE *vLimit = ip + (dictLimit - matchIndex); + if (vLimit > iHighLimit) vLimit = iHighLimit; + matchLength = (int)LZ4_count(ip + MINMATCH, matchPtr + MINMATCH, vLimit) + MINMATCH; + if ((ip + matchLength == vLimit) && (vLimit < iHighLimit)) + matchLength += LZ4_count(ip + matchLength, lowPrefixPtr, iHighLimit); + back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictStart) : 0; + matchLength -= back; + if (matchLength > longest) { + longest = matchLength; + *matchpos = base + matchIndex + back; /* virtual pos, relative to ip, to retrieve offset */ + *startpos = ip + back; + } + } + } + + if (chainSwap && matchLength == longest) { /* better match => select a better chain */ + assert(lookBackLength == 0); /* search forward only */ + if (matchIndex + (U32)longest <= ipIndex) { + int const kTrigger = 4; + U32 distanceToNextMatch = 1; + int const end = longest - MINMATCH + 1; + int step = 1; + int accel = 1 << kTrigger; + int pos; + for (pos = 0; pos < end; pos += step) { + U32 const candidateDist = DELTANEXTU16(chainTable, matchIndex + (U32)pos); + step = (accel++ >> kTrigger); + if (candidateDist > distanceToNextMatch) { + distanceToNextMatch = candidateDist; + matchChainPos = (U32)pos; + accel = 1 << kTrigger; + } + } + if (distanceToNextMatch > 1) { + if (distanceToNextMatch > matchIndex) break; /* avoid overflow */ + matchIndex -= distanceToNextMatch; + continue; + } + } + } + + { + U32 const distNextMatch = DELTANEXTU16(chainTable, matchIndex); + if (patternAnalysis && distNextMatch == 1 && matchChainPos == 0) { + U32 const matchCandidateIdx = matchIndex - 1; + /* may be a repeated pattern */ + if (repeat == rep_untested) { + if (((pattern & 0xFFFF) == (pattern >> 16)) + & ((pattern & 0xFF) == (pattern >> 24))) { + repeat = rep_confirmed; + srcPatternLength = LZ4HC_countPattern(ip + sizeof(pattern), iHighLimit, pattern) + sizeof(pattern); + } else { + repeat = rep_not; + } + } + if ((repeat == rep_confirmed) && (matchCandidateIdx >= lowestMatchIndex) + && LZ4HC_protectDictEnd(dictLimit, matchCandidateIdx)) { + const int extDict = matchCandidateIdx < dictLimit; + const BYTE *const matchPtr = (extDict ? dictBase : base) + matchCandidateIdx; + if (LZ4_read32(matchPtr) == pattern) { /* good candidate */ + const BYTE *const dictStart = dictBase + hc4->lowLimit; + const BYTE *const iLimit = extDict ? dictBase + dictLimit : iHighLimit; + size_t forwardPatternLength = LZ4HC_countPattern(matchPtr + sizeof(pattern), iLimit, pattern) + sizeof(pattern); + if (extDict && matchPtr + forwardPatternLength == iLimit) { + U32 const rotatedPattern = LZ4HC_rotatePattern(forwardPatternLength, pattern); + forwardPatternLength += LZ4HC_countPattern(lowPrefixPtr, iHighLimit, rotatedPattern); + } + { + const BYTE *const lowestMatchPtr = extDict ? dictStart : lowPrefixPtr; + size_t backLength = LZ4HC_reverseCountPattern(matchPtr, lowestMatchPtr, pattern); + size_t currentSegmentLength; + if (!extDict && matchPtr - backLength == lowPrefixPtr && hc4->lowLimit < dictLimit) { + U32 const rotatedPattern = LZ4HC_rotatePattern((U32)(-(int)backLength), pattern); + backLength += LZ4HC_reverseCountPattern(dictBase + dictLimit, dictStart, rotatedPattern); + } + /* Limit backLength not go further than lowestMatchIndex */ + backLength = matchCandidateIdx - MAX(matchCandidateIdx - (U32)backLength, lowestMatchIndex); + assert(matchCandidateIdx - backLength >= lowestMatchIndex); + currentSegmentLength = backLength + forwardPatternLength; + /* Adjust to end of pattern if the source pattern fits, otherwise the beginning of the pattern */ + if ((currentSegmentLength >= srcPatternLength) /* current pattern segment large enough to contain full srcPatternLength */ + && (forwardPatternLength <= srcPatternLength)) { /* haven't reached this position yet */ + U32 const newMatchIndex = matchCandidateIdx + (U32)forwardPatternLength - (U32)srcPatternLength; /* best position, full pattern, might be followed by more match */ + if (LZ4HC_protectDictEnd(dictLimit, newMatchIndex)) + matchIndex = newMatchIndex; + else { + /* Can only happen if started in the prefix */ + assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict); + matchIndex = dictLimit; + } + } else { + U32 const newMatchIndex = matchCandidateIdx - (U32)backLength; /* farthest position in current segment, will find a match of length currentSegmentLength + maybe some back */ + if (!LZ4HC_protectDictEnd(dictLimit, newMatchIndex)) { + assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict); + matchIndex = dictLimit; + } else { + matchIndex = newMatchIndex; + if (lookBackLength == 0) { /* no back possible */ + size_t const maxML = MIN(currentSegmentLength, srcPatternLength); + if ((size_t)longest < maxML) { + assert(base + matchIndex < ip); + if (ip - (base + matchIndex) > LZ4_DISTANCE_MAX) break; + assert(maxML < 2 GB); + longest = (int)maxML; + *matchpos = base + matchIndex; /* virtual pos, relative to ip, to retrieve offset */ + *startpos = ip; + } + { + U32 const distToNextPattern = DELTANEXTU16(chainTable, matchIndex); + if (distToNextPattern > matchIndex) break; /* avoid overflow */ + matchIndex -= distToNextPattern; + } + } + } + } + } + continue; + } + } + } + } /* PA optimization */ + + /* follow current chain */ + matchIndex -= DELTANEXTU16(chainTable, matchIndex + matchChainPos); + + } /* while ((matchIndex>=lowestMatchIndex) && (nbAttempts)) */ + + if (dict == usingDictCtxHc + && nbAttempts + && ipIndex - lowestMatchIndex < LZ4_DISTANCE_MAX) { + size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->base); + U32 dictMatchIndex = dictCtx->hashTable[LZ4HC_hashPtr(ip)]; + assert(dictEndOffset <= 1 GB); + matchIndex = dictMatchIndex + lowestMatchIndex - (U32)dictEndOffset; + while (ipIndex - matchIndex <= LZ4_DISTANCE_MAX && nbAttempts--) { + const BYTE *const matchPtr = dictCtx->base + dictMatchIndex; + + if (LZ4_read32(matchPtr) == pattern) { + int mlt; + int back = 0; + const BYTE *vLimit = ip + (dictEndOffset - dictMatchIndex); + if (vLimit > iHighLimit) vLimit = iHighLimit; + mlt = (int)LZ4_count(ip + MINMATCH, matchPtr + MINMATCH, vLimit) + MINMATCH; + back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictCtx->base + dictCtx->dictLimit) : 0; + mlt -= back; + if (mlt > longest) { + longest = mlt; + *matchpos = base + matchIndex + back; + *startpos = ip + back; + } + } + + { + U32 const nextOffset = DELTANEXTU16(dictCtx->chainTable, dictMatchIndex); + dictMatchIndex -= nextOffset; + matchIndex -= nextOffset; + } + } + } + + return longest; +} + +LZ4_FORCE_INLINE +int LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal *const hc4, /* Index table will be updated */ + const BYTE *const ip, const BYTE *const iLimit, + const BYTE **matchpos, + const int maxNbAttempts, + const int patternAnalysis, + const dictCtx_directive dict) { + const BYTE *uselessPtr = ip; + /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos), + * but this won't be the case here, as we define iLowLimit==ip, + * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */ + return LZ4HC_InsertAndGetWiderMatch(hc4, ip, ip, iLimit, MINMATCH - 1, matchpos, &uselessPtr, maxNbAttempts, patternAnalysis, 0 /*chainSwap*/, dict, favorCompressionRatio); +} + +/* LZ4HC_encodeSequence() : + * @return : 0 if ok, + * 1 if buffer issue detected */ +LZ4_FORCE_INLINE int LZ4HC_encodeSequence( + const BYTE **ip, + BYTE **op, + const BYTE **anchor, + int matchLength, + const BYTE *const match, + limitedOutput_directive limit, + BYTE *oend) { + size_t length; + BYTE *const token = (*op)++; + +#if defined(LZ4_DEBUG) && (LZ4_DEBUG >= 6) + static const BYTE *start = NULL; + static U32 totalCost = 0; + U32 const pos = (start == NULL) ? 0 : (U32)(*anchor - start); + U32 const ll = (U32)(*ip - *anchor); + U32 const llAdd = (ll >= 15) ? ((ll - 15) / 255) + 1 : 0; + U32 const mlAdd = (matchLength >= 19) ? ((matchLength - 19) / 255) + 1 : 0; + U32 const cost = 1 + llAdd + ll + 2 + mlAdd; + if (start == NULL) start = *anchor; /* only works for single segment */ + /* g_debuglog_enable = (pos >= 2228) & (pos <= 2262); */ + DEBUGLOG(6, "pos:%7u -- literals:%3u, match:%4i, offset:%5u, cost:%3u + %u", + pos, + (U32)(*ip - *anchor), matchLength, (U32)(*ip - match), + cost, totalCost); + totalCost += cost; +#endif + + /* Encode Literal length */ + length = (size_t)(*ip - *anchor); + if ((limit) && ((*op + (length / 255) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */ + if (length >= RUN_MASK) { + size_t len = length - RUN_MASK; + *token = (RUN_MASK << ML_BITS); + for (; len >= 255 ; len -= 255) * (*op)++ = 255; + *(*op)++ = (BYTE)len; + } else { + *token = (BYTE)(length << ML_BITS); + } + + /* Copy Literals */ + LZ4_wildCopy8(*op, *anchor, (*op) + length); + *op += length; + + /* Encode Offset */ + assert((*ip - match) <= LZ4_DISTANCE_MAX); /* note : consider providing offset as a value, rather than as a pointer difference */ + LZ4_writeLE16(*op, (U16)(*ip - match)); + *op += 2; + + /* Encode MatchLength */ + assert(matchLength >= MINMATCH); + length = (size_t)matchLength - MINMATCH; + if ((limit) && (*op + (length / 255) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */ + if (length >= ML_MASK) { + *token += ML_MASK; + length -= ML_MASK; + for (; length >= 510 ; length -= 510) { *(*op)++ = 255; *(*op)++ = 255; } + if (length >= 255) { length -= 255; *(*op)++ = 255; } + *(*op)++ = (BYTE)length; + } else { + *token += (BYTE)(length); + } + + /* Prepare next loop */ + *ip += matchLength; + *anchor = *ip; + + return 0; +} + +LZ4_FORCE_INLINE int LZ4HC_compress_hashChain( + LZ4HC_CCtx_internal *const ctx, + const char *const source, + char *const dest, + int *srcSizePtr, + int const maxOutputSize, + unsigned maxNbAttempts, + const limitedOutput_directive limit, + const dictCtx_directive dict +) { + const int inputSize = *srcSizePtr; + const int patternAnalysis = (maxNbAttempts > 128); /* levels 9+ */ + + const BYTE *ip = (const BYTE *) source; + const BYTE *anchor = ip; + const BYTE *const iend = ip + inputSize; + const BYTE *const mflimit = iend - MFLIMIT; + const BYTE *const matchlimit = (iend - LASTLITERALS); + + BYTE *optr = (BYTE *) dest; + BYTE *op = (BYTE *) dest; + BYTE *oend = op + maxOutputSize; + + int ml0, ml, ml2, ml3; + const BYTE *start0; + const BYTE *ref0; + const BYTE *ref = NULL; + const BYTE *start2 = NULL; + const BYTE *ref2 = NULL; + const BYTE *start3 = NULL; + const BYTE *ref3 = NULL; + + /* init */ + *srcSizePtr = 0; + if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */ + if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ + + /* Main Loop */ + while (ip <= mflimit) { + ml = LZ4HC_InsertAndFindBestMatch(ctx, ip, matchlimit, &ref, maxNbAttempts, patternAnalysis, dict); + if (ml < MINMATCH) { ip++; continue; } + + /* saved, in case we would skip too much */ + start0 = ip; + ref0 = ref; + ml0 = ml; + +_Search2: + if (ip + ml <= mflimit) { + ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, + ip + ml - 2, ip + 0, matchlimit, ml, &ref2, &start2, + maxNbAttempts, patternAnalysis, 0, dict, favorCompressionRatio); + } else { + ml2 = ml; + } + + if (ml2 == ml) { /* No better match => encode ML1 */ + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + continue; + } + + if (start0 < ip) { /* first match was skipped at least once */ + if (start2 < ip + ml0) { /* squeezing ML1 between ML0(original ML1) and ML2 */ + ip = start0; + ref = ref0; + ml = ml0; /* restore initial ML1 */ + } + } + + /* Here, start0==ip */ + if ((start2 - ip) < 3) { /* First Match too small : removed */ + ml = ml2; + ip = start2; + ref = ref2; + goto _Search2; + } + +_Search3: + /* At this stage, we have : + * ml2 > ml1, and + * ip1+3 <= ip2 (usually < ip1+ml1) */ + if ((start2 - ip) < OPTIMAL_ML) { + int correction; + int new_ml = ml; + if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; + if (ip + new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; + correction = new_ml - (int)(start2 - ip); + if (correction > 0) { + start2 += correction; + ref2 += correction; + ml2 -= correction; + } + } + /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */ + + if (start2 + ml2 <= mflimit) { + ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, + start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, + maxNbAttempts, patternAnalysis, 0, dict, favorCompressionRatio); + } else { + ml3 = ml2; + } + + if (ml3 == ml2) { /* No better match => encode ML1 and ML2 */ + /* ip & ref are known; Now for ml */ + if (start2 < ip + ml) ml = (int)(start2 - ip); + /* Now, encode 2 sequences */ + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + ip = start2; + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml2, ref2, limit, oend)) goto _dest_overflow; + continue; + } + + if (start3 < ip + ml + 3) { /* Not enough space for match 2 : remove it */ + if (start3 >= (ip + ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ + if (start2 < ip + ml) { + int correction = (int)(ip + ml - start2); + start2 += correction; + ref2 += correction; + ml2 -= correction; + if (ml2 < MINMATCH) { + start2 = start3; + ref2 = ref3; + ml2 = ml3; + } + } + + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + ip = start3; + ref = ref3; + ml = ml3; + + start0 = start2; + ref0 = ref2; + ml0 = ml2; + goto _Search2; + } + + start2 = start3; + ref2 = ref3; + ml2 = ml3; + goto _Search3; + } + + /* + * OK, now we have 3 ascending matches; + * let's write the first one ML1. + * ip & ref are known; Now decide ml. + */ + if (start2 < ip + ml) { + if ((start2 - ip) < OPTIMAL_ML) { + int correction; + if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; + if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; + correction = ml - (int)(start2 - ip); + if (correction > 0) { + start2 += correction; + ref2 += correction; + ml2 -= correction; + } + } else { + ml = (int)(start2 - ip); + } + } + optr = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow; + + /* ML2 becomes ML1 */ + ip = start2; + ref = ref2; + ml = ml2; + + /* ML3 becomes ML2 */ + start2 = start3; + ref2 = ref3; + ml2 = ml3; + + /* let's find a new ML3 */ + goto _Search3; + } + +_last_literals: + /* Encode Last Literals */ + { + size_t lastRunSize = (size_t)(iend - anchor); /* literals */ + size_t litLength = (lastRunSize + 255 - RUN_MASK) / 255; + size_t const totalSize = 1 + litLength + lastRunSize; + if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */ + if (limit && (op + totalSize > oend)) { + if (limit == limitedOutput) return 0; /* Check output limit */ + /* adapt lastRunSize to fill 'dest' */ + lastRunSize = (size_t)(oend - op) - 1; + litLength = (lastRunSize + 255 - RUN_MASK) / 255; + lastRunSize -= litLength; + } + ip = anchor + lastRunSize; + + if (lastRunSize >= RUN_MASK) { + size_t accumulator = lastRunSize - RUN_MASK; + *op++ = (RUN_MASK << ML_BITS); + for (; accumulator >= 255 ; accumulator -= 255) * op++ = 255; + *op++ = (BYTE) accumulator; + } else { + *op++ = (BYTE)(lastRunSize << ML_BITS); + } + memcpy(op, anchor, lastRunSize); + op += lastRunSize; + } + + /* End */ + *srcSizePtr = (int)(((const char *)ip) - source); + return (int)(((char *)op) - dest); + +_dest_overflow: + if (limit == fillOutput) { + op = optr; /* restore correct out pointer */ + goto _last_literals; + } + return 0; +} + + +static int LZ4HC_compress_optimal(LZ4HC_CCtx_internal *ctx, + const char *const source, char *dst, + int *srcSizePtr, int dstCapacity, + int const nbSearches, size_t sufficient_len, + const limitedOutput_directive limit, int const fullUpdate, + const dictCtx_directive dict, + HCfavor_e favorDecSpeed); + + +LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal( + LZ4HC_CCtx_internal *const ctx, + const char *const src, + char *const dst, + int *const srcSizePtr, + int const dstCapacity, + int cLevel, + const limitedOutput_directive limit, + const dictCtx_directive dict +) { + typedef enum { lz4hc, lz4opt } lz4hc_strat_e; + typedef struct { + lz4hc_strat_e strat; + U32 nbSearches; + U32 targetLength; + } cParams_t; + static const cParams_t clTable[LZ4HC_CLEVEL_MAX + 1] = { + { lz4hc, 2, 16 }, /* 0, unused */ + { lz4hc, 2, 16 }, /* 1, unused */ + { lz4hc, 2, 16 }, /* 2, unused */ + { lz4hc, 4, 16 }, /* 3 */ + { lz4hc, 8, 16 }, /* 4 */ + { lz4hc, 16, 16 }, /* 5 */ + { lz4hc, 32, 16 }, /* 6 */ + { lz4hc, 64, 16 }, /* 7 */ + { lz4hc, 128, 16 }, /* 8 */ + { lz4hc, 256, 16 }, /* 9 */ + { lz4opt, 96, 64 }, /*10==LZ4HC_CLEVEL_OPT_MIN*/ + { lz4opt, 512, 128 }, /*11 */ + { lz4opt, 16384, LZ4_OPT_NUM }, /* 12==LZ4HC_CLEVEL_MAX */ + }; + + DEBUGLOG(4, "LZ4HC_compress_generic(ctx=%p, src=%p, srcSize=%d)", ctx, src, *srcSizePtr); + + if (limit == fillOutput && dstCapacity < 1) return 0; /* Impossible to store anything */ + if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size (too large or negative) */ + + ctx->end += *srcSizePtr; + if (cLevel < 1) cLevel = LZ4HC_CLEVEL_DEFAULT; /* note : convention is different from lz4frame, maybe something to review */ + cLevel = MIN(LZ4HC_CLEVEL_MAX, cLevel); + { + cParams_t const cParam = clTable[cLevel]; + HCfavor_e const favor = ctx->favorDecSpeed ? favorDecompressionSpeed : favorCompressionRatio; + int result; + + if (cParam.strat == lz4hc) { + result = LZ4HC_compress_hashChain(ctx, + src, dst, srcSizePtr, dstCapacity, + cParam.nbSearches, limit, dict); + } else { + assert(cParam.strat == lz4opt); + result = LZ4HC_compress_optimal(ctx, + src, dst, srcSizePtr, dstCapacity, + (int)cParam.nbSearches, cParam.targetLength, limit, + cLevel == LZ4HC_CLEVEL_MAX, /* ultra mode */ + dict, favor); + } + if (result <= 0) ctx->dirty = 1; + return result; + } +} + +static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal *ctxPtr, const BYTE *newBlock); + +static int +LZ4HC_compress_generic_noDictCtx( + LZ4HC_CCtx_internal *const ctx, + const char *const src, + char *const dst, + int *const srcSizePtr, + int const dstCapacity, + int cLevel, + limitedOutput_directive limit +) { + assert(ctx->dictCtx == NULL); + return LZ4HC_compress_generic_internal(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit, noDictCtx); +} + +static int +LZ4HC_compress_generic_dictCtx( + LZ4HC_CCtx_internal *const ctx, + const char *const src, + char *const dst, + int *const srcSizePtr, + int const dstCapacity, + int cLevel, + limitedOutput_directive limit +) { + const size_t position = (size_t)(ctx->end - ctx->base) - ctx->lowLimit; + assert(ctx->dictCtx != NULL); + if (position >= 64 KB) { + ctx->dictCtx = NULL; + return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } else if (position == 0 && *srcSizePtr > 4 KB) { + memcpy(ctx, ctx->dictCtx, sizeof(LZ4HC_CCtx_internal)); + LZ4HC_setExternalDict(ctx, (const BYTE *)src); + ctx->compressionLevel = (short)cLevel; + return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } else { + return LZ4HC_compress_generic_internal(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit, usingDictCtxHc); + } +} + +static int +LZ4HC_compress_generic( + LZ4HC_CCtx_internal *const ctx, + const char *const src, + char *const dst, + int *const srcSizePtr, + int const dstCapacity, + int cLevel, + limitedOutput_directive limit +) { + if (ctx->dictCtx == NULL) { + return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } else { + return LZ4HC_compress_generic_dictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit); + } +} + + +int LZ4_sizeofStateHC(void) { return (int)sizeof(LZ4_streamHC_t); } + +#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 : + * it reports an aligment of 8-bytes, + * while actually aligning LZ4_streamHC_t on 4 bytes. */ +static size_t LZ4_streamHC_t_alignment(void) { + struct { char c; LZ4_streamHC_t t; } t_a; + return sizeof(t_a) - sizeof(t_a.t); +} +#endif + +/* state is presumed correctly initialized, + * in which case its size and alignment have already been validate */ +int LZ4_compress_HC_extStateHC_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel) { + LZ4HC_CCtx_internal *const ctx = &((LZ4_streamHC_t *)state)->internal_donotuse; +#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 : + * it reports an aligment of 8-bytes, + * while actually aligning LZ4_streamHC_t on 4 bytes. */ + assert(((size_t)state & (LZ4_streamHC_t_alignment() - 1)) == 0); /* check alignment */ +#endif + if (((size_t)(state) & (sizeof(void *) -1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */ + LZ4_resetStreamHC_fast((LZ4_streamHC_t *)state, compressionLevel); + LZ4HC_init_internal(ctx, (const BYTE *)src); + if (dstCapacity < LZ4_compressBound(srcSize)) + return LZ4HC_compress_generic(ctx, src, dst, &srcSize, dstCapacity, compressionLevel, limitedOutput); + else + return LZ4HC_compress_generic(ctx, src, dst, &srcSize, dstCapacity, compressionLevel, notLimited); +} + +int LZ4_compress_HC_extStateHC(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel) { + LZ4_streamHC_t *const ctx = LZ4_initStreamHC(state, sizeof(*ctx)); + if (ctx == NULL) return 0; /* init failure */ + return LZ4_compress_HC_extStateHC_fastReset(state, src, dst, srcSize, dstCapacity, compressionLevel); +} + +int LZ4_compress_HC(const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel) { +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + LZ4_streamHC_t *const statePtr = (LZ4_streamHC_t *)ALLOC(sizeof(LZ4_streamHC_t)); +#else + LZ4_streamHC_t state; + LZ4_streamHC_t *const statePtr = &state; +#endif + int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel); +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + FREEMEM(statePtr); +#endif + return cSize; +} + +/* state is presumed sized correctly (>= sizeof(LZ4_streamHC_t)) */ +int LZ4_compress_HC_destSize(void *state, const char *source, char *dest, int *sourceSizePtr, int targetDestSize, int cLevel) { + LZ4_streamHC_t *const ctx = LZ4_initStreamHC(state, sizeof(*ctx)); + if (ctx == NULL) return 0; /* init failure */ + LZ4HC_init_internal(&ctx->internal_donotuse, (const BYTE *) source); + LZ4_setCompressionLevel(ctx, cLevel); + return LZ4HC_compress_generic(&ctx->internal_donotuse, source, dest, sourceSizePtr, targetDestSize, cLevel, fillOutput); +} + + + +/************************************** +* Streaming Functions +**************************************/ +/* allocation */ +LZ4_streamHC_t *LZ4_createStreamHC(void) { + LZ4_streamHC_t *const LZ4_streamHCPtr = (LZ4_streamHC_t *)ALLOC(sizeof(LZ4_streamHC_t)); + if (LZ4_streamHCPtr == NULL) return NULL; + LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); /* full initialization, malloc'ed buffer can be full of garbage */ + return LZ4_streamHCPtr; +} + +int LZ4_freeStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr) { + DEBUGLOG(4, "LZ4_freeStreamHC(%p)", LZ4_streamHCPtr); + if (!LZ4_streamHCPtr) return 0; /* support free on NULL */ + FREEMEM(LZ4_streamHCPtr); + return 0; +} + + +LZ4_streamHC_t *LZ4_initStreamHC(void *buffer, size_t size) { + LZ4_streamHC_t *const LZ4_streamHCPtr = (LZ4_streamHC_t *)buffer; + if (buffer == NULL) return NULL; + if (size < sizeof(LZ4_streamHC_t)) return NULL; +#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 : + * it reports an aligment of 8-bytes, + * while actually aligning LZ4_streamHC_t on 4 bytes. */ + if (((size_t)buffer) & (LZ4_streamHC_t_alignment() - 1)) return NULL; /* alignment check */ +#endif + /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ + LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= LZ4_STREAMHCSIZE); + DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", LZ4_streamHCPtr, (unsigned)size); + /* end-base will trigger a clearTable on starting compression */ + LZ4_streamHCPtr->internal_donotuse.end = (const BYTE *)(ptrdiff_t) -1; + LZ4_streamHCPtr->internal_donotuse.base = NULL; + LZ4_streamHCPtr->internal_donotuse.dictCtx = NULL; + LZ4_streamHCPtr->internal_donotuse.favorDecSpeed = 0; + LZ4_streamHCPtr->internal_donotuse.dirty = 0; + LZ4_setCompressionLevel(LZ4_streamHCPtr, LZ4HC_CLEVEL_DEFAULT); + return LZ4_streamHCPtr; +} + +/* just a stub */ +void LZ4_resetStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel) { + LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); + LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel); +} + +void LZ4_resetStreamHC_fast(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel) { + DEBUGLOG(4, "LZ4_resetStreamHC_fast(%p, %d)", LZ4_streamHCPtr, compressionLevel); + if (LZ4_streamHCPtr->internal_donotuse.dirty) { + LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); + } else { + /* preserve end - base : can trigger clearTable's threshold */ + LZ4_streamHCPtr->internal_donotuse.end -= (uptrval)LZ4_streamHCPtr->internal_donotuse.base; + LZ4_streamHCPtr->internal_donotuse.base = NULL; + LZ4_streamHCPtr->internal_donotuse.dictCtx = NULL; + } + LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel); +} + +void LZ4_setCompressionLevel(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel) { + DEBUGLOG(5, "LZ4_setCompressionLevel(%p, %d)", LZ4_streamHCPtr, compressionLevel); + if (compressionLevel < 1) compressionLevel = LZ4HC_CLEVEL_DEFAULT; + if (compressionLevel > LZ4HC_CLEVEL_MAX) compressionLevel = LZ4HC_CLEVEL_MAX; + LZ4_streamHCPtr->internal_donotuse.compressionLevel = (short)compressionLevel; +} + +void LZ4_favorDecompressionSpeed(LZ4_streamHC_t *LZ4_streamHCPtr, int favor) { + LZ4_streamHCPtr->internal_donotuse.favorDecSpeed = (favor != 0); +} + +/* LZ4_loadDictHC() : + * LZ4_streamHCPtr is presumed properly initialized */ +int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, + const char *dictionary, int dictSize) { + LZ4HC_CCtx_internal *const ctxPtr = &LZ4_streamHCPtr->internal_donotuse; + DEBUGLOG(4, "LZ4_loadDictHC(%p, %p, %d)", LZ4_streamHCPtr, dictionary, dictSize); + assert(LZ4_streamHCPtr != NULL); + if (dictSize > 64 KB) { + dictionary += (size_t)dictSize - 64 KB; + dictSize = 64 KB; + } + /* need a full initialization, there are bad side-effects when using resetFast() */ + { + int const cLevel = ctxPtr->compressionLevel; + LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); + LZ4_setCompressionLevel(LZ4_streamHCPtr, cLevel); + } + LZ4HC_init_internal(ctxPtr, (const BYTE *)dictionary); + ctxPtr->end = (const BYTE *)dictionary + dictSize; + if (dictSize >= 4) LZ4HC_Insert(ctxPtr, ctxPtr->end - 3); + return dictSize; +} + +void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream) { + working_stream->internal_donotuse.dictCtx = dictionary_stream != NULL ? &(dictionary_stream->internal_donotuse) : NULL; +} + +/* compression */ + +static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal *ctxPtr, const BYTE *newBlock) { + DEBUGLOG(4, "LZ4HC_setExternalDict(%p, %p)", ctxPtr, newBlock); + if (ctxPtr->end >= ctxPtr->base + ctxPtr->dictLimit + 4) + LZ4HC_Insert(ctxPtr, ctxPtr->end - 3); /* Referencing remaining dictionary content */ + + /* Only one memory segment for extDict, so any previous extDict is lost at this stage */ + ctxPtr->lowLimit = ctxPtr->dictLimit; + ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base); + ctxPtr->dictBase = ctxPtr->base; + ctxPtr->base = newBlock - ctxPtr->dictLimit; + ctxPtr->end = newBlock; + ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ + + /* cannot reference an extDict and a dictCtx at the same time */ + ctxPtr->dictCtx = NULL; +} + +static int LZ4_compressHC_continue_generic(LZ4_streamHC_t *LZ4_streamHCPtr, + const char *src, char *dst, + int *srcSizePtr, int dstCapacity, + limitedOutput_directive limit) { + LZ4HC_CCtx_internal *const ctxPtr = &LZ4_streamHCPtr->internal_donotuse; + DEBUGLOG(4, "LZ4_compressHC_continue_generic(ctx=%p, src=%p, srcSize=%d)", + LZ4_streamHCPtr, src, *srcSizePtr); + assert(ctxPtr != NULL); + /* auto-init if forgotten */ + if (ctxPtr->base == NULL) LZ4HC_init_internal(ctxPtr, (const BYTE *) src); + + /* Check overflow */ + if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) { + size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit; + if (dictSize > 64 KB) dictSize = 64 KB; + LZ4_loadDictHC(LZ4_streamHCPtr, (const char *)(ctxPtr->end) - dictSize, (int)dictSize); + } + + /* Check if blocks follow each other */ + if ((const BYTE *)src != ctxPtr->end) + LZ4HC_setExternalDict(ctxPtr, (const BYTE *)src); + + /* Check overlapping input/dictionary space */ + { + const BYTE *sourceEnd = (const BYTE *) src + *srcSizePtr; + const BYTE *const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; + const BYTE *const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; + if ((sourceEnd > dictBegin) && ((const BYTE *)src < dictEnd)) { + if (sourceEnd > dictEnd) sourceEnd = dictEnd; + ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase); + if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit; + } + } + + return LZ4HC_compress_generic(ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit); +} + +int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity) { + if (dstCapacity < LZ4_compressBound(srcSize)) + return LZ4_compressHC_continue_generic(LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, limitedOutput); + else + return LZ4_compressHC_continue_generic(LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, notLimited); +} + +int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int *srcSizePtr, int targetDestSize) { + return LZ4_compressHC_continue_generic(LZ4_streamHCPtr, src, dst, srcSizePtr, targetDestSize, fillOutput); +} + + + +/* dictionary saving */ + +int LZ4_saveDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, char *safeBuffer, int dictSize) { + LZ4HC_CCtx_internal *const streamPtr = &LZ4_streamHCPtr->internal_donotuse; + int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); + DEBUGLOG(4, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize); + if (dictSize > 64 KB) dictSize = 64 KB; + if (dictSize < 4) dictSize = 0; + if (dictSize > prefixSize) dictSize = prefixSize; + memmove(safeBuffer, streamPtr->end - dictSize, dictSize); + { + U32 const endIndex = (U32)(streamPtr->end - streamPtr->base); + streamPtr->end = (const BYTE *)safeBuffer + dictSize; + streamPtr->base = streamPtr->end - endIndex; + streamPtr->dictLimit = endIndex - (U32)dictSize; + streamPtr->lowLimit = endIndex - (U32)dictSize; + if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit; + } + return dictSize; +} + + +/*************************************************** +* Deprecated Functions +***************************************************/ + +/* These functions currently generate deprecation warnings */ + +/* Wrappers for deprecated compression functions */ +int LZ4_compressHC(const char *src, char *dst, int srcSize) { return LZ4_compress_HC(src, dst, srcSize, LZ4_compressBound(srcSize), 0); } +int LZ4_compressHC_limitedOutput(const char *src, char *dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); } +int LZ4_compressHC2(const char *src, char *dst, int srcSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } +int LZ4_compressHC2_limitedOutput(const char *src, char *dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); } +int LZ4_compressHC_withStateHC(void *state, const char *src, char *dst, int srcSize) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, LZ4_compressBound(srcSize), 0); } +int LZ4_compressHC_limitedOutput_withStateHC(void *state, const char *src, char *dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, maxDstSize, 0); } +int LZ4_compressHC2_withStateHC(void *state, const char *src, char *dst, int srcSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } +int LZ4_compressHC2_limitedOutput_withStateHC(void *state, const char *src, char *dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, maxDstSize, cLevel); } +int LZ4_compressHC_continue(LZ4_streamHC_t *ctx, const char *src, char *dst, int srcSize) { return LZ4_compress_HC_continue(ctx, src, dst, srcSize, LZ4_compressBound(srcSize)); } +int LZ4_compressHC_limitedOutput_continue(LZ4_streamHC_t *ctx, const char *src, char *dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_continue(ctx, src, dst, srcSize, maxDstSize); } + + +/* Deprecated streaming functions */ +int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; } + +/* state is presumed correctly sized, aka >= sizeof(LZ4_streamHC_t) + * @return : 0 on success, !=0 if error */ +int LZ4_resetStreamStateHC(void *state, char *inputBuffer) { + LZ4_streamHC_t *const hc4 = LZ4_initStreamHC(state, sizeof(*hc4)); + if (hc4 == NULL) return 1; /* init failed */ + LZ4HC_init_internal(&hc4->internal_donotuse, (const BYTE *)inputBuffer); + return 0; +} + +void *LZ4_createHC(const char *inputBuffer) { + LZ4_streamHC_t *const hc4 = LZ4_createStreamHC(); + if (hc4 == NULL) return NULL; /* not enough memory */ + LZ4HC_init_internal(&hc4->internal_donotuse, (const BYTE *)inputBuffer); + return hc4; +} + +int LZ4_freeHC(void *LZ4HC_Data) { + if (!LZ4HC_Data) return 0; /* support free on NULL */ + FREEMEM(LZ4HC_Data); + return 0; +} + +int LZ4_compressHC2_continue(void *LZ4HC_Data, const char *src, char *dst, int srcSize, int cLevel) { + return LZ4HC_compress_generic(&((LZ4_streamHC_t *)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, 0, cLevel, notLimited); +} + +int LZ4_compressHC2_limitedOutput_continue(void *LZ4HC_Data, const char *src, char *dst, int srcSize, int dstCapacity, int cLevel) { + return LZ4HC_compress_generic(&((LZ4_streamHC_t *)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, dstCapacity, cLevel, limitedOutput); +} + +char *LZ4_slideInputBufferHC(void *LZ4HC_Data) { + LZ4_streamHC_t *ctx = (LZ4_streamHC_t *)LZ4HC_Data; + const BYTE *bufferStart = ctx->internal_donotuse.base + ctx->internal_donotuse.lowLimit; + LZ4_resetStreamHC_fast(ctx, ctx->internal_donotuse.compressionLevel); + /* avoid const char * -> char * conversion warning :( */ + return (char *)(uptrval)bufferStart; +} + + +/* ================================================ + * LZ4 Optimal parser (levels [LZ4HC_CLEVEL_OPT_MIN - LZ4HC_CLEVEL_MAX]) + * ===============================================*/ +typedef struct { + int price; + int off; + int mlen; + int litlen; +} LZ4HC_optimal_t; + +/* price in bytes */ +LZ4_FORCE_INLINE int LZ4HC_literalsPrice(int const litlen) { + int price = litlen; + assert(litlen >= 0); + if (litlen >= (int)RUN_MASK) + price += 1 + ((litlen - (int)RUN_MASK) / 255); + return price; +} + + +/* requires mlen >= MINMATCH */ +LZ4_FORCE_INLINE int LZ4HC_sequencePrice(int litlen, int mlen) { + int price = 1 + 2 ; /* token + 16-bit offset */ + assert(litlen >= 0); + assert(mlen >= MINMATCH); + + price += LZ4HC_literalsPrice(litlen); + + if (mlen >= (int)(ML_MASK + MINMATCH)) + price += 1 + ((mlen - (int)(ML_MASK + MINMATCH)) / 255); + + return price; +} + + +typedef struct { + int off; + int len; +} LZ4HC_match_t; + +LZ4_FORCE_INLINE LZ4HC_match_t +LZ4HC_FindLongerMatch(LZ4HC_CCtx_internal *const ctx, + const BYTE *ip, const BYTE *const iHighLimit, + int minLen, int nbSearches, + const dictCtx_directive dict, + const HCfavor_e favorDecSpeed) { + LZ4HC_match_t match = { 0, 0 }; + const BYTE *matchPtr = NULL; + /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos), + * but this won't be the case here, as we define iLowLimit==ip, + * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */ + int matchLength = LZ4HC_InsertAndGetWiderMatch(ctx, ip, ip, iHighLimit, minLen, &matchPtr, &ip, nbSearches, 1 /*patternAnalysis*/, 1 /*chainSwap*/, dict, favorDecSpeed); + if (matchLength <= minLen) return match; + if (favorDecSpeed) { + if ((matchLength > 18) & (matchLength <= 36)) matchLength = 18; /* favor shortcut */ + } + match.len = matchLength; + match.off = (int)(ip - matchPtr); + return match; +} + + +static int LZ4HC_compress_optimal(LZ4HC_CCtx_internal *ctx, + const char *const source, + char *dst, + int *srcSizePtr, + int dstCapacity, + int const nbSearches, + size_t sufficient_len, + const limitedOutput_directive limit, + int const fullUpdate, + const dictCtx_directive dict, + const HCfavor_e favorDecSpeed) { +#define TRAILING_LITERALS 3 + LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* ~64 KB, which is a bit large for stack... */ + + const BYTE *ip = (const BYTE *) source; + const BYTE *anchor = ip; + const BYTE *const iend = ip + *srcSizePtr; + const BYTE *const mflimit = iend - MFLIMIT; + const BYTE *const matchlimit = iend - LASTLITERALS; + BYTE *op = (BYTE *) dst; + BYTE *opSaved = (BYTE *) dst; + BYTE *oend = op + dstCapacity; + + /* init */ + DEBUGLOG(5, "LZ4HC_compress_optimal(dst=%p, dstCapa=%u)", dst, (unsigned)dstCapacity); + *srcSizePtr = 0; + if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */ + if (sufficient_len >= LZ4_OPT_NUM) sufficient_len = LZ4_OPT_NUM - 1; + + /* Main Loop */ + assert(ip - anchor < LZ4_MAX_INPUT_SIZE); + while (ip <= mflimit) { + int const llen = (int)(ip - anchor); + int best_mlen, best_off; + int cur, last_match_pos = 0; + + LZ4HC_match_t const firstMatch = LZ4HC_FindLongerMatch(ctx, ip, matchlimit, MINMATCH - 1, nbSearches, dict, favorDecSpeed); + if (firstMatch.len == 0) { ip++; continue; } + + if ((size_t)firstMatch.len > sufficient_len) { + /* good enough solution : immediate encoding */ + int const firstML = firstMatch.len; + const BYTE *const matchPos = ip - firstMatch.off; + opSaved = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), firstML, matchPos, limit, oend)) /* updates ip, op and anchor */ + goto _dest_overflow; + continue; + } + + /* set prices for first positions (literals) */ + { + int rPos; + for (rPos = 0 ; rPos < MINMATCH ; rPos++) { + int const cost = LZ4HC_literalsPrice(llen + rPos); + opt[rPos].mlen = 1; + opt[rPos].off = 0; + opt[rPos].litlen = llen + rPos; + opt[rPos].price = cost; + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup", + rPos, cost, opt[rPos].litlen); + } + } + /* set prices using initial match */ + { + int mlen = MINMATCH; + int const matchML = firstMatch.len; /* necessarily < sufficient_len < LZ4_OPT_NUM */ + int const offset = firstMatch.off; + assert(matchML < LZ4_OPT_NUM); + for (; mlen <= matchML ; mlen++) { + int const cost = LZ4HC_sequencePrice(llen, mlen); + opt[mlen].mlen = mlen; + opt[mlen].off = offset; + opt[mlen].litlen = llen; + opt[mlen].price = cost; + DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i) -- initial setup", + mlen, cost, mlen); + } + } + last_match_pos = firstMatch.len; + { + int addLit; + for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) { + opt[last_match_pos + addLit].mlen = 1; /* literal */ + opt[last_match_pos + addLit].off = 0; + opt[last_match_pos + addLit].litlen = addLit; + opt[last_match_pos + addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit); + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup", + last_match_pos + addLit, opt[last_match_pos + addLit].price, addLit); + } + } + + /* check further positions */ + for (cur = 1; cur < last_match_pos; cur++) { + const BYTE *const curPtr = ip + cur; + LZ4HC_match_t newMatch; + + if (curPtr > mflimit) break; + DEBUGLOG(7, "rPos:%u[%u] vs [%u]%u", + cur, opt[cur].price, opt[cur + 1].price, cur + 1); + if (fullUpdate) { + /* not useful to search here if next position has same (or lower) cost */ + if ((opt[cur + 1].price <= opt[cur].price) + /* in some cases, next position has same cost, but cost rises sharply after, so a small match would still be beneficial */ + && (opt[cur + MINMATCH].price < opt[cur].price + 3/*min seq price*/)) + continue; + } else { + /* not useful to search here if next position has same (or lower) cost */ + if (opt[cur + 1].price <= opt[cur].price) continue; + } + + DEBUGLOG(7, "search at rPos:%u", cur); + if (fullUpdate) + newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, MINMATCH - 1, nbSearches, dict, favorDecSpeed); + else + /* only test matches of minimum length; slightly faster, but misses a few bytes */ + newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, last_match_pos - cur, nbSearches, dict, favorDecSpeed); + if (!newMatch.len) continue; + + if (((size_t)newMatch.len > sufficient_len) + || (newMatch.len + cur >= LZ4_OPT_NUM)) { + /* immediate encoding */ + best_mlen = newMatch.len; + best_off = newMatch.off; + last_match_pos = cur + 1; + goto encode; + } + + /* before match : set price with literals at beginning */ + { + int const baseLitlen = opt[cur].litlen; + int litlen; + for (litlen = 1; litlen < MINMATCH; litlen++) { + int const price = opt[cur].price - LZ4HC_literalsPrice(baseLitlen) + LZ4HC_literalsPrice(baseLitlen + litlen); + int const pos = cur + litlen; + if (price < opt[pos].price) { + opt[pos].mlen = 1; /* literal */ + opt[pos].off = 0; + opt[pos].litlen = baseLitlen + litlen; + opt[pos].price = price; + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", + pos, price, opt[pos].litlen); + } + } + } + + /* set prices using match at position = cur */ + { + int const matchML = newMatch.len; + int ml = MINMATCH; + + assert(cur + newMatch.len < LZ4_OPT_NUM); + for (; ml <= matchML ; ml++) { + int const pos = cur + ml; + int const offset = newMatch.off; + int price; + int ll; + DEBUGLOG(7, "testing price rPos %i (last_match_pos=%i)", + pos, last_match_pos); + if (opt[cur].mlen == 1) { + ll = opt[cur].litlen; + price = ((cur > ll) ? opt[cur - ll].price : 0) + + LZ4HC_sequencePrice(ll, ml); + } else { + ll = 0; + price = opt[cur].price + LZ4HC_sequencePrice(0, ml); + } + + assert((U32)favorDecSpeed <= 1); + if (pos > last_match_pos + TRAILING_LITERALS + || price <= opt[pos].price - (int)favorDecSpeed) { + DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i)", + pos, price, ml); + assert(pos < LZ4_OPT_NUM); + if ((ml == matchML) /* last pos of last match */ + && (last_match_pos < pos)) + last_match_pos = pos; + opt[pos].mlen = ml; + opt[pos].off = offset; + opt[pos].litlen = ll; + opt[pos].price = price; + } + } + } + /* complete following positions with literals */ + { + int addLit; + for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) { + opt[last_match_pos + addLit].mlen = 1; /* literal */ + opt[last_match_pos + addLit].off = 0; + opt[last_match_pos + addLit].litlen = addLit; + opt[last_match_pos + addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit); + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", last_match_pos + addLit, opt[last_match_pos + addLit].price, addLit); + } + } + } /* for (cur = 1; cur <= last_match_pos; cur++) */ + + assert(last_match_pos < LZ4_OPT_NUM + TRAILING_LITERALS); + best_mlen = opt[last_match_pos].mlen; + best_off = opt[last_match_pos].off; + cur = last_match_pos - best_mlen; + +encode: /* cur, last_match_pos, best_mlen, best_off must be set */ + assert(cur < LZ4_OPT_NUM); + assert(last_match_pos >= 1); /* == 1 when only one candidate */ + DEBUGLOG(6, "reverse traversal, looking for shortest path (last_match_pos=%i)", last_match_pos); + { + int candidate_pos = cur; + int selected_matchLength = best_mlen; + int selected_offset = best_off; + while (1) { /* from end to beginning */ + int const next_matchLength = opt[candidate_pos].mlen; /* can be 1, means literal */ + int const next_offset = opt[candidate_pos].off; + DEBUGLOG(7, "pos %i: sequence length %i", candidate_pos, selected_matchLength); + opt[candidate_pos].mlen = selected_matchLength; + opt[candidate_pos].off = selected_offset; + selected_matchLength = next_matchLength; + selected_offset = next_offset; + if (next_matchLength > candidate_pos) break; /* last match elected, first match to encode */ + assert(next_matchLength > 0); /* can be 1, means literal */ + candidate_pos -= next_matchLength; + } + } + + /* encode all recorded sequences in order */ + { + int rPos = 0; /* relative position (to ip) */ + while (rPos < last_match_pos) { + int const ml = opt[rPos].mlen; + int const offset = opt[rPos].off; + if (ml == 1) { ip++; rPos++; continue; } /* literal; note: can end up with several literals, in which case, skip them */ + rPos += ml; + assert(ml >= MINMATCH); + assert((offset >= 1) && (offset <= LZ4_DISTANCE_MAX)); + opSaved = op; + if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ip - offset, limit, oend)) /* updates ip, op and anchor */ + goto _dest_overflow; + } + } + } /* while (ip <= mflimit) */ + +_last_literals: + /* Encode Last Literals */ + { + size_t lastRunSize = (size_t)(iend - anchor); /* literals */ + size_t litLength = (lastRunSize + 255 - RUN_MASK) / 255; + size_t const totalSize = 1 + litLength + lastRunSize; + if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */ + if (limit && (op + totalSize > oend)) { + if (limit == limitedOutput) return 0; /* Check output limit */ + /* adapt lastRunSize to fill 'dst' */ + lastRunSize = (size_t)(oend - op) - 1; + litLength = (lastRunSize + 255 - RUN_MASK) / 255; + lastRunSize -= litLength; + } + ip = anchor + lastRunSize; + + if (lastRunSize >= RUN_MASK) { + size_t accumulator = lastRunSize - RUN_MASK; + *op++ = (RUN_MASK << ML_BITS); + for (; accumulator >= 255 ; accumulator -= 255) * op++ = 255; + *op++ = (BYTE) accumulator; + } else { + *op++ = (BYTE)(lastRunSize << ML_BITS); + } + memcpy(op, anchor, lastRunSize); + op += lastRunSize; + } + + /* End */ + *srcSizePtr = (int)(((const char *)ip) - source); + return (int)((char *)op - dst); + +_dest_overflow: + if (limit == fillOutput) { + op = opSaved; /* restore correct out pointer */ + goto _last_literals; + } + return 0; +} diff --git a/common/lz4/lz4hc.h b/common/lz4/lz4hc.h new file mode 100644 index 000000000..be39e08a3 --- /dev/null +++ b/common/lz4/lz4hc.h @@ -0,0 +1,436 @@ +/* + LZ4 HC - High Compression Mode of LZ4 + Header File + Copyright (C) 2011-2017, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 source repository : https://github.com/lz4/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ +#ifndef LZ4_HC_H_19834876238432 +#define LZ4_HC_H_19834876238432 + +#if defined (__cplusplus) +extern "C" { +#endif + +/* --- Dependency --- */ +/* note : lz4hc requires lz4.h/lz4.c for compilation */ +#include "lz4.h" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */ + + +/* --- Useful constants --- */ +#define LZ4HC_CLEVEL_MIN 3 +#define LZ4HC_CLEVEL_DEFAULT 9 +#define LZ4HC_CLEVEL_OPT_MIN 10 +#define LZ4HC_CLEVEL_MAX 12 + + +/*-************************************ + * Block Compression + **************************************/ +/*! LZ4_compress_HC() : + * Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm. + * `dst` must be already allocated. + * Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h") + * Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h") + * `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work. + * Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX. + * @return : the number of bytes written into 'dst' + * or 0 if compression fails. + */ +LZ4LIB_API int LZ4_compress_HC(const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel); + + +/* Note : + * Decompression functions are provided within "lz4.h" (BSD license) + */ + + +/*! LZ4_compress_HC_extStateHC() : + * Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`. + * `state` size is provided by LZ4_sizeofStateHC(). + * Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly). + */ +LZ4LIB_API int LZ4_sizeofStateHC(void); +LZ4LIB_API int LZ4_compress_HC_extStateHC(void *stateHC, const char *src, char *dst, int srcSize, int maxDstSize, int compressionLevel); + + +/*! LZ4_compress_HC_destSize() : v1.9.0+ + * Will compress as much data as possible from `src` + * to fit into `targetDstSize` budget. + * Result is provided in 2 parts : + * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize) + * or 0 if compression fails. + * `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src` + */ +LZ4LIB_API int LZ4_compress_HC_destSize(void *stateHC, + const char *src, char *dst, + int *srcSizePtr, int targetDstSize, + int compressionLevel); + + +/*-************************************ + * Streaming Compression + * Bufferless synchronous API + **************************************/ +typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */ + +/*! LZ4_createStreamHC() and LZ4_freeStreamHC() : + * These functions create and release memory for LZ4 HC streaming state. + * Newly created states are automatically initialized. + * A same state can be used multiple times consecutively, + * starting with LZ4_resetStreamHC_fast() to start a new stream of blocks. + */ +LZ4LIB_API LZ4_streamHC_t *LZ4_createStreamHC(void); +LZ4LIB_API int LZ4_freeStreamHC(LZ4_streamHC_t *streamHCPtr); + +/* + These functions compress data in successive blocks of any size, + using previous blocks as dictionary, to improve compression ratio. + One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks. + There is an exception for ring buffers, which can be smaller than 64 KB. + Ring-buffer scenario is automatically detected and handled within LZ4_compress_HC_continue(). + + Before starting compression, state must be allocated and properly initialized. + LZ4_createStreamHC() does both, though compression level is set to LZ4HC_CLEVEL_DEFAULT. + + Selecting the compression level can be done with LZ4_resetStreamHC_fast() (starts a new stream) + or LZ4_setCompressionLevel() (anytime, between blocks in the same stream) (experimental). + LZ4_resetStreamHC_fast() only works on states which have been properly initialized at least once, + which is automatically the case when state is created using LZ4_createStreamHC(). + + After reset, a first "fictional block" can be designated as initial dictionary, + using LZ4_loadDictHC() (Optional). + + Invoke LZ4_compress_HC_continue() to compress each successive block. + The number of blocks is unlimited. + Previous input blocks, including initial dictionary when present, + must remain accessible and unmodified during compression. + + It's allowed to update compression level anytime between blocks, + using LZ4_setCompressionLevel() (experimental). + + 'dst' buffer should be sized to handle worst case scenarios + (see LZ4_compressBound(), it ensures compression success). + In case of failure, the API does not guarantee recovery, + so the state _must_ be reset. + To ensure compression success + whenever `dst` buffer size cannot be made >= LZ4_compressBound(), + consider using LZ4_compress_HC_continue_destSize(). + + Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks, + it's possible to copy the last blocks into a more stable memory space, using LZ4_saveDictHC(). + Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer' (<= 64 KB) + + After completing a streaming compression, + it's possible to start a new stream of blocks, using the same LZ4_streamHC_t state, + just by resetting it, using LZ4_resetStreamHC_fast(). +*/ + +LZ4LIB_API void LZ4_resetStreamHC_fast(LZ4_streamHC_t *streamHCPtr, int compressionLevel); /* v1.9.0+ */ +LZ4LIB_API int LZ4_loadDictHC(LZ4_streamHC_t *streamHCPtr, const char *dictionary, int dictSize); + +LZ4LIB_API int LZ4_compress_HC_continue(LZ4_streamHC_t *streamHCPtr, + const char *src, char *dst, + int srcSize, int maxDstSize); + +/*! LZ4_compress_HC_continue_destSize() : v1.9.0+ + * Similar to LZ4_compress_HC_continue(), + * but will read as much data as possible from `src` + * to fit into `targetDstSize` budget. + * Result is provided into 2 parts : + * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize) + * or 0 if compression fails. + * `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`. + * Note that this function may not consume the entire input. + */ +LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t *LZ4_streamHCPtr, + const char *src, char *dst, + int *srcSizePtr, int targetDstSize); + +LZ4LIB_API int LZ4_saveDictHC(LZ4_streamHC_t *streamHCPtr, char *safeBuffer, int maxDictSize); + + + +/*^********************************************** + * !!!!!! STATIC LINKING ONLY !!!!!! + ***********************************************/ + +/*-****************************************************************** + * PRIVATE DEFINITIONS : + * Do not use these definitions directly. + * They are merely exposed to allow static allocation of `LZ4_streamHC_t`. + * Declare an `LZ4_streamHC_t` directly, rather than any type below. + * Even then, only do so in the context of static linking, as definitions may change between versions. + ********************************************************************/ + +#define LZ4HC_DICTIONARY_LOGSIZE 16 +#define LZ4HC_MAXD (1<= 199901L) /* C99 */) +#include + +typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal; +struct LZ4HC_CCtx_internal { + uint32_t hashTable[LZ4HC_HASHTABLESIZE]; + uint16_t chainTable[LZ4HC_MAXD]; + const uint8_t *end; /* next block here to continue on current prefix */ + const uint8_t *base; /* All index relative to this position */ + const uint8_t *dictBase; /* alternate base for extDict */ + uint32_t dictLimit; /* below that point, need extDict */ + uint32_t lowLimit; /* below that point, no more dict */ + uint32_t nextToUpdate; /* index from which to continue dictionary update */ + short compressionLevel; + int8_t favorDecSpeed; /* favor decompression speed if this flag set, + otherwise, favor compression ratio */ + int8_t dirty; /* stream has to be fully reset if this flag is set */ + const LZ4HC_CCtx_internal *dictCtx; +}; + +#else + +typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal; +struct LZ4HC_CCtx_internal { + unsigned int hashTable[LZ4HC_HASHTABLESIZE]; + unsigned short chainTable[LZ4HC_MAXD]; + const unsigned char *end; /* next block here to continue on current prefix */ + const unsigned char *base; /* All index relative to this position */ + const unsigned char *dictBase; /* alternate base for extDict */ + unsigned int dictLimit; /* below that point, need extDict */ + unsigned int lowLimit; /* below that point, no more dict */ + unsigned int nextToUpdate; /* index from which to continue dictionary update */ + short compressionLevel; + char favorDecSpeed; /* favor decompression speed if this flag set, + otherwise, favor compression ratio */ + char dirty; /* stream has to be fully reset if this flag is set */ + const LZ4HC_CCtx_internal *dictCtx; +}; + +#endif + + +/* Do not use these definitions directly ! + * Declare or allocate an LZ4_streamHC_t instead. + */ +#define LZ4_STREAMHCSIZE (4*LZ4HC_HASHTABLESIZE + 2*LZ4HC_MAXD + 56 + ((sizeof(void*)==16) ? 56 : 0) /* AS400*/ ) /* 262200 or 262256*/ +#define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t)) +union LZ4_streamHC_u { + size_t table[LZ4_STREAMHCSIZE_SIZET]; + LZ4HC_CCtx_internal internal_donotuse; +}; /* previously typedef'd to LZ4_streamHC_t */ + +/* LZ4_streamHC_t : + * This structure allows static allocation of LZ4 HC streaming state. + * This can be used to allocate statically, on state, or as part of a larger structure. + * + * Such state **must** be initialized using LZ4_initStreamHC() before first use. + * + * Note that invoking LZ4_initStreamHC() is not required when + * the state was created using LZ4_createStreamHC() (which is recommended). + * Using the normal builder, a newly created state is automatically initialized. + * + * Static allocation shall only be used in combination with static linking. + */ + +/* LZ4_initStreamHC() : v1.9.0+ + * Required before first use of a statically allocated LZ4_streamHC_t. + * Before v1.9.0 : use LZ4_resetStreamHC() instead + */ +LZ4LIB_API LZ4_streamHC_t *LZ4_initStreamHC(void *buffer, size_t size); + + +/*-************************************ +* Deprecated Functions +**************************************/ +/* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */ + +/* deprecated compression functions */ +LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC(const char *source, char *dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput(const char *source, char *dest, int inputSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2(const char *source, char *dest, int inputSize, int compressionLevel); +LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput(const char *source, char *dest, int inputSize, int maxOutputSize, int compressionLevel); +LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_withStateHC(void *state, const char *source, char *dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_withStateHC(void *state, const char *source, char *dest, int inputSize, int maxOutputSize); +LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_withStateHC(void *state, const char *source, char *dest, int inputSize, int compressionLevel); +LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_withStateHC(void *state, const char *source, char *dest, int inputSize, int maxOutputSize, int compressionLevel); +LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *source, char *dest, int inputSize); +LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *source, char *dest, int inputSize, int maxOutputSize); + +/* Obsolete streaming functions; degraded functionality; do not use! + * + * In order to perform streaming compression, these functions depended on data + * that is no longer tracked in the state. They have been preserved as well as + * possible: using them will still produce a correct output. However, use of + * LZ4_slideInputBufferHC() will truncate the history of the stream, rather + * than preserve a window-sized chunk of history. + */ +LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void *LZ4_createHC(const char *inputBuffer); +LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char *LZ4_slideInputBufferHC(void *LZ4HC_Data); +LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC(void *LZ4HC_Data); +LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue(void *LZ4HC_Data, const char *source, char *dest, int inputSize, int compressionLevel); +LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_continue(void *LZ4HC_Data, const char *source, char *dest, int inputSize, int maxOutputSize, int compressionLevel); +LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void); +LZ4_DEPRECATED("use LZ4_initStreamHC() instead") LZ4LIB_API int LZ4_resetStreamStateHC(void *state, char *inputBuffer); + + +/* LZ4_resetStreamHC() is now replaced by LZ4_initStreamHC(). + * The intention is to emphasize the difference with LZ4_resetStreamHC_fast(), + * which is now the recommended function to start a new stream of blocks, + * but cannot be used to initialize a memory segment containing arbitrary garbage data. + * + * It is recommended to switch to LZ4_initStreamHC(). + * LZ4_resetStreamHC() will generate deprecation warnings in a future version. + */ +LZ4LIB_API void LZ4_resetStreamHC(LZ4_streamHC_t *streamHCPtr, int compressionLevel); + + +#if defined (__cplusplus) +} +#endif + +#endif /* LZ4_HC_H_19834876238432 */ + + +/*-************************************************** + * !!!!! STATIC LINKING ONLY !!!!! + * Following definitions are considered experimental. + * They should not be linked from DLL, + * as there is no guarantee of API stability yet. + * Prototypes will be promoted to "stable" status + * after successfull usage in real-life scenarios. + ***************************************************/ +#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */ +#ifndef LZ4_HC_SLO_098092834 +#define LZ4_HC_SLO_098092834 + +#define LZ4_STATIC_LINKING_ONLY /* LZ4LIB_STATIC_API */ +#include "lz4.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/*! LZ4_setCompressionLevel() : v1.8.0+ (experimental) + * It's possible to change compression level + * between successive invocations of LZ4_compress_HC_continue*() + * for dynamic adaptation. + */ +LZ4LIB_STATIC_API void LZ4_setCompressionLevel( + LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel); + +/*! LZ4_favorDecompressionSpeed() : v1.8.2+ (experimental) + * Opt. Parser will favor decompression speed over compression ratio. + * Only applicable to levels >= LZ4HC_CLEVEL_OPT_MIN. + */ +LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed( + LZ4_streamHC_t *LZ4_streamHCPtr, int favor); + +/*! LZ4_resetStreamHC_fast() : v1.9.0+ + * When an LZ4_streamHC_t is known to be in a internally coherent state, + * it can often be prepared for a new compression with almost no work, only + * sometimes falling back to the full, expensive reset that is always required + * when the stream is in an indeterminate state (i.e., the reset performed by + * LZ4_resetStreamHC()). + * + * LZ4_streamHCs are guaranteed to be in a valid state when: + * - returned from LZ4_createStreamHC() + * - reset by LZ4_resetStreamHC() + * - memset(stream, 0, sizeof(LZ4_streamHC_t)) + * - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast() + * - the stream was in a valid state and was then used in any compression call + * that returned success + * - the stream was in an indeterminate state and was used in a compression + * call that fully reset the state (LZ4_compress_HC_extStateHC()) and that + * returned success + * + * Note: + * A stream that was last used in a compression call that returned an error + * may be passed to this function. However, it will be fully reset, which will + * clear any existing history and settings from the context. + */ +LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast( + LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel); + +/*! LZ4_compress_HC_extStateHC_fastReset() : + * A variant of LZ4_compress_HC_extStateHC(). + * + * Using this variant avoids an expensive initialization step. It is only safe + * to call if the state buffer is known to be correctly initialized already + * (see above comment on LZ4_resetStreamHC_fast() for a definition of + * "correctly initialized"). From a high level, the difference is that this + * function initializes the provided state with a call to + * LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a + * call to LZ4_resetStreamHC(). + */ +LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset( + void *state, + const char *src, char *dst, + int srcSize, int dstCapacity, + int compressionLevel); + +/*! LZ4_attach_HC_dictionary() : + * This is an experimental API that allows for the efficient use of a + * static dictionary many times. + * + * Rather than re-loading the dictionary buffer into a working context before + * each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a + * working LZ4_streamHC_t, this function introduces a no-copy setup mechanism, + * in which the working stream references the dictionary stream in-place. + * + * Several assumptions are made about the state of the dictionary stream. + * Currently, only streams which have been prepared by LZ4_loadDictHC() should + * be expected to work. + * + * Alternatively, the provided dictionary stream pointer may be NULL, in which + * case any existing dictionary stream is unset. + * + * A dictionary should only be attached to a stream without any history (i.e., + * a stream that has just been reset). + * + * The dictionary will remain attached to the working stream only for the + * current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the + * dictionary context association from the working stream. The dictionary + * stream (and source buffer) must remain in-place / accessible / unchanged + * through the lifetime of the stream session. + */ +LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary( + LZ4_streamHC_t *working_stream, + const LZ4_streamHC_t *dictionary_stream); + +#if defined (__cplusplus) +} +#endif + +#endif /* LZ4_HC_SLO_098092834 */ +#endif /* LZ4_HC_STATIC_LINKING_ONLY */ diff --git a/common/mbedtls/Makefile b/common/mbedtls/Makefile index be5f08a0a..4ae8357b3 100644 --- a/common/mbedtls/Makefile +++ b/common/mbedtls/Makefile @@ -1,6 +1,6 @@ MYSRCPATHS = MYINCLUDES = -I. -I.. -MYCFLAGS = +MYCFLAGS = -Wno-cast-align -Wno-switch-enum MYDEFS = MYSRCS = \ aes.c \ diff --git a/common/parity.c b/common/parity.c index ce61ad40a..64e034a6d 100644 --- a/common/parity.c +++ b/common/parity.c @@ -25,7 +25,7 @@ const uint8_t OddByteParity[256] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 }; - +/* const uint8_t EvenByteParity[256] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, @@ -44,4 +44,4 @@ const uint8_t EvenByteParity[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; - +*/ diff --git a/common/zlib/ChangeLog b/common/zlib/ChangeLog deleted file mode 100644 index 30199a65a..000000000 --- a/common/zlib/ChangeLog +++ /dev/null @@ -1,1515 +0,0 @@ - - ChangeLog file for zlib - -Changes in 1.2.11 (15 Jan 2017) -- Fix deflate stored bug when pulling last block from window -- Permit immediate deflateParams changes before any deflate input - -Changes in 1.2.10 (2 Jan 2017) -- Avoid warnings on snprintf() return value -- Fix bug in deflate_stored() for zero-length input -- Fix bug in gzwrite.c that produced corrupt gzip files -- Remove files to be installed before copying them in Makefile.in -- Add warnings when compiling with assembler code - -Changes in 1.2.9 (31 Dec 2016) -- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] -- Improve contrib/blast to return unused bytes -- Assure that gzoffset() is correct when appending -- Improve compress() and uncompress() to support large lengths -- Fix bug in test/example.c where error code not saved -- Remedy Coverity warning [Randers-Pehrson] -- Improve speed of gzprintf() in transparent mode -- Fix inflateInit2() bug when windowBits is 16 or 32 -- Change DEBUG macro to ZLIB_DEBUG -- Avoid uninitialized access by gzclose_w() -- Allow building zlib outside of the source directory -- Fix bug that accepted invalid zlib header when windowBits is zero -- Fix gzseek() problem on MinGW due to buggy _lseeki64 there -- Loop on write() calls in gzwrite.c in case of non-blocking I/O -- Add --warn (-w) option to ./configure for more compiler warnings -- Reject a window size of 256 bytes if not using the zlib wrapper -- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE -- Add --debug (-d) option to ./configure to define ZLIB_DEBUG -- Fix bugs in creating a very large gzip header -- Add uncompress2() function, which returns the input size used -- Assure that deflateParams() will not switch functions mid-block -- Dramatically speed up deflation for level 0 (storing) -- Add gzfread(), duplicating the interface of fread() -- Add gzfwrite(), duplicating the interface of fwrite() -- Add deflateGetDictionary() function -- Use snprintf() for later versions of Microsoft C -- Fix *Init macros to use z_ prefix when requested -- Replace as400 with os400 for OS/400 support [Monnerat] -- Add crc32_z() and adler32_z() functions with size_t lengths -- Update Visual Studio project files [AraHaan] - -Changes in 1.2.8 (28 Apr 2013) -- Update contrib/minizip/iowin32.c for Windows RT [Vollant] -- Do not force Z_CONST for C++ -- Clean up contrib/vstudio [Roß] -- Correct spelling error in zlib.h -- Fix mixed line endings in contrib/vstudio - -Changes in 1.2.7.3 (13 Apr 2013) -- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc - -Changes in 1.2.7.2 (13 Apr 2013) -- Change check for a four-byte type back to hexadecimal -- Fix typo in win32/Makefile.msc -- Add casts in gzwrite.c for pointer differences - -Changes in 1.2.7.1 (24 Mar 2013) -- Replace use of unsafe string functions with snprintf if available -- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] -- Fix gzgetc undefine when Z_PREFIX set [Turk] -- Eliminate use of mktemp in Makefile (not always available) -- Fix bug in 'F' mode for gzopen() -- Add inflateGetDictionary() function -- Correct comment in deflate.h -- Use _snprintf for snprintf in Microsoft C -- On Darwin, only use /usr/bin/libtool if libtool is not Apple -- Delete "--version" file if created by "ar --version" [Richard G.] -- Fix configure check for veracity of compiler error return codes -- Fix CMake compilation of static lib for MSVC2010 x64 -- Remove unused variable in infback9.c -- Fix argument checks in gzlog_compress() and gzlog_write() -- Clean up the usage of z_const and respect const usage within zlib -- Clean up examples/gzlog.[ch] comparisons of different types -- Avoid shift equal to bits in type (caused endless loop) -- Fix uninitialized value bug in gzputc() introduced by const patches -- Fix memory allocation error in examples/zran.c [Nor] -- Fix bug where gzopen(), gzclose() would write an empty file -- Fix bug in gzclose() when gzwrite() runs out of memory -- Check for input buffer malloc failure in examples/gzappend.c -- Add note to contrib/blast to use binary mode in stdio -- Fix comparisons of differently signed integers in contrib/blast -- Check for invalid code length codes in contrib/puff -- Fix serious but very rare decompression bug in inftrees.c -- Update inflateBack() comments, since inflate() can be faster -- Use underscored I/O function names for WINAPI_FAMILY -- Add _tr_flush_bits to the external symbols prefixed by --zprefix -- Add contrib/vstudio/vc10 pre-build step for static only -- Quote --version-script argument in CMakeLists.txt -- Don't specify --version-script on Apple platforms in CMakeLists.txt -- Fix casting error in contrib/testzlib/testzlib.c -- Fix types in contrib/minizip to match result of get_crc_table() -- Simplify contrib/vstudio/vc10 with 'd' suffix -- Add TOP support to win32/Makefile.msc -- Suport i686 and amd64 assembler builds in CMakeLists.txt -- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h -- Add vc11 and vc12 build files to contrib/vstudio -- Add gzvprintf() as an undocumented function in zlib -- Fix configure for Sun shell -- Remove runtime check in configure for four-byte integer type -- Add casts and consts to ease user conversion to C++ -- Add man pages for minizip and miniunzip -- In Makefile uninstall, don't rm if preceding cd fails -- Do not return Z_BUF_ERROR if deflateParam() has nothing to write - -Changes in 1.2.7 (2 May 2012) -- Replace use of memmove() with a simple copy for portability -- Test for existence of strerror -- Restore gzgetc_ for backward compatibility with 1.2.6 -- Fix build with non-GNU make on Solaris -- Require gcc 4.0 or later on Mac OS X to use the hidden attribute -- Include unistd.h for Watcom C -- Use __WATCOMC__ instead of __WATCOM__ -- Do not use the visibility attribute if NO_VIZ defined -- Improve the detection of no hidden visibility attribute -- Avoid using __int64 for gcc or solo compilation -- Cast to char * in gzprintf to avoid warnings [Zinser] -- Fix make_vms.com for VAX [Zinser] -- Don't use library or built-in byte swaps -- Simplify test and use of gcc hidden attribute -- Fix bug in gzclose_w() when gzwrite() fails to allocate memory -- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() -- Fix bug in test/minigzip.c for configure --solo -- Fix contrib/vstudio project link errors [Mohanathas] -- Add ability to choose the builder in make_vms.com [Schweda] -- Add DESTDIR support to mingw32 win32/Makefile.gcc -- Fix comments in win32/Makefile.gcc for proper usage -- Allow overriding the default install locations for cmake -- Generate and install the pkg-config file with cmake -- Build both a static and a shared version of zlib with cmake -- Include version symbols for cmake builds -- If using cmake with MSVC, add the source directory to the includes -- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] -- Move obsolete emx makefile to old [Truta] -- Allow the use of -Wundef when compiling or using zlib -- Avoid the use of the -u option with mktemp -- Improve inflate() documentation on the use of Z_FINISH -- Recognize clang as gcc -- Add gzopen_w() in Windows for wide character path names -- Rename zconf.h in CMakeLists.txt to move it out of the way -- Add source directory in CMakeLists.txt for building examples -- Look in build directory for zlib.pc in CMakeLists.txt -- Remove gzflags from zlibvc.def in vc9 and vc10 -- Fix contrib/minizip compilation in the MinGW environment -- Update ./configure for Solaris, support --64 [Mooney] -- Remove -R. from Solaris shared build (possible security issue) -- Avoid race condition for parallel make (-j) running example -- Fix type mismatch between get_crc_table() and crc_table -- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] -- Fix the path to zlib.map in CMakeLists.txt -- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] -- Add instructions to win32/Makefile.gcc for shared install [Torri] - -Changes in 1.2.6.1 (12 Feb 2012) -- Avoid the use of the Objective-C reserved name "id" -- Include io.h in gzguts.h for Microsoft compilers -- Fix problem with ./configure --prefix and gzgetc macro -- Include gz_header definition when compiling zlib solo -- Put gzflags() functionality back in zutil.c -- Avoid library header include in crc32.c for Z_SOLO -- Use name in GCC_CLASSIC as C compiler for coverage testing, if set -- Minor cleanup in contrib/minizip/zip.c [Vollant] -- Update make_vms.com [Zinser] -- Remove unnecessary gzgetc_ function -- Use optimized byte swap operations for Microsoft and GNU [Snyder] -- Fix minor typo in zlib.h comments [Rzesniowiecki] - -Changes in 1.2.6 (29 Jan 2012) -- Update the Pascal interface in contrib/pascal -- Fix function numbers for gzgetc_ in zlibvc.def files -- Fix configure.ac for contrib/minizip [Schiffer] -- Fix large-entry detection in minizip on 64-bit systems [Schiffer] -- Have ./configure use the compiler return code for error indication -- Fix CMakeLists.txt for cross compilation [McClure] -- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] -- Fix compilation of contrib/minizip on FreeBSD [Marquez] -- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] -- Include io.h for Turbo C / Borland C on all platforms [Truta] -- Make version explicit in contrib/minizip/configure.ac [Bosmans] -- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] -- Minor cleanup up contrib/minizip/unzip.c [Vollant] -- Fix bug when compiling minizip with C++ [Vollant] -- Protect for long name and extra fields in contrib/minizip [Vollant] -- Avoid some warnings in contrib/minizip [Vollant] -- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip -- Add missing libs to minizip linker command -- Add support for VPATH builds in contrib/minizip -- Add an --enable-demos option to contrib/minizip/configure -- Add the generation of configure.log by ./configure -- Exit when required parameters not provided to win32/Makefile.gcc -- Have gzputc return the character written instead of the argument -- Use the -m option on ldconfig for BSD systems [Tobias] -- Correct in zlib.map when deflateResetKeep was added - -Changes in 1.2.5.3 (15 Jan 2012) -- Restore gzgetc function for binary compatibility -- Do not use _lseeki64 under Borland C++ [Truta] -- Update win32/Makefile.msc to build test/*.c [Truta] -- Remove old/visualc6 given CMakefile and other alternatives -- Update AS400 build files and documentation [Monnerat] -- Update win32/Makefile.gcc to build test/*.c [Truta] -- Permit stronger flushes after Z_BLOCK flushes -- Avoid extraneous empty blocks when doing empty flushes -- Permit Z_NULL arguments to deflatePending -- Allow deflatePrime() to insert bits in the middle of a stream -- Remove second empty static block for Z_PARTIAL_FLUSH -- Write out all of the available bits when using Z_BLOCK -- Insert the first two strings in the hash table after a flush - -Changes in 1.2.5.2 (17 Dec 2011) -- fix ld error: unable to find version dependency 'ZLIB_1.2.5' -- use relative symlinks for shared libs -- Avoid searching past window for Z_RLE strategy -- Assure that high-water mark initialization is always applied in deflate -- Add assertions to fill_window() in deflate.c to match comments -- Update python link in README -- Correct spelling error in gzread.c -- Fix bug in gzgets() for a concatenated empty gzip stream -- Correct error in comment for gz_make() -- Change gzread() and related to ignore junk after gzip streams -- Allow gzread() and related to continue after gzclearerr() -- Allow gzrewind() and gzseek() after a premature end-of-file -- Simplify gzseek() now that raw after gzip is ignored -- Change gzgetc() to a macro for speed (~40% speedup in testing) -- Fix gzclose() to return the actual error last encountered -- Always add large file support for windows -- Include zconf.h for windows large file support -- Include zconf.h.cmakein for windows large file support -- Update zconf.h.cmakein on make distclean -- Merge vestigial vsnprintf determination from zutil.h to gzguts.h -- Clarify how gzopen() appends in zlib.h comments -- Correct documentation of gzdirect() since junk at end now ignored -- Add a transparent write mode to gzopen() when 'T' is in the mode -- Update python link in zlib man page -- Get inffixed.h and MAKEFIXED result to match -- Add a ./config --solo option to make zlib subset with no library use -- Add undocumented inflateResetKeep() function for CAB file decoding -- Add --cover option to ./configure for gcc coverage testing -- Add #define ZLIB_CONST option to use const in the z_stream interface -- Add comment to gzdopen() in zlib.h to use dup() when using fileno() -- Note behavior of uncompress() to provide as much data as it can -- Add files in contrib/minizip to aid in building libminizip -- Split off AR options in Makefile.in and configure -- Change ON macro to Z_ARG to avoid application conflicts -- Facilitate compilation with Borland C++ for pragmas and vsnprintf -- Include io.h for Turbo C / Borland C++ -- Move example.c and minigzip.c to test/ -- Simplify incomplete code table filling in inflate_table() -- Remove code from inflate.c and infback.c that is impossible to execute -- Test the inflate code with full coverage -- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) -- Add deflateResetKeep and fix inflateResetKeep to retain dictionary -- Fix gzwrite.c to accommodate reduced memory zlib compilation -- Have inflate() with Z_FINISH avoid the allocation of a window -- Do not set strm->adler when doing raw inflate -- Fix gzeof() to behave just like feof() when read is not past end of file -- Fix bug in gzread.c when end-of-file is reached -- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF -- Document gzread() capability to read concurrently written files -- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] - -Changes in 1.2.5.1 (10 Sep 2011) -- Update FAQ entry on shared builds (#13) -- Avoid symbolic argument to chmod in Makefile.in -- Fix bug and add consts in contrib/puff [Oberhumer] -- Update contrib/puff/zeros.raw test file to have all block types -- Add full coverage test for puff in contrib/puff/Makefile -- Fix static-only-build install in Makefile.in -- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] -- Add libz.a dependency to shared in Makefile.in for parallel builds -- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out -- Replace $(...) with `...` in configure for non-bash sh [Bowler] -- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] -- Add solaris* to Linux* in configure to allow gcc use [Groffen] -- Add *bsd* to Linux* case in configure [Bar-Lev] -- Add inffast.obj to dependencies in win32/Makefile.msc -- Correct spelling error in deflate.h [Kohler] -- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc -- Add test to configure for GNU C looking for gcc in output of $cc -v -- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] -- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not -- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense -- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) -- Make stronger test in zconf.h to include unistd.h for LFS -- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] -- Fix zlib.h LFS support when Z_PREFIX used -- Add updated as400 support (removed from old) [Monnerat] -- Avoid deflate sensitivity to volatile input data -- Avoid division in adler32_combine for NO_DIVIDE -- Clarify the use of Z_FINISH with deflateBound() amount of space -- Set binary for output file in puff.c -- Use u4 type for crc_table to avoid conversion warnings -- Apply casts in zlib.h to avoid conversion warnings -- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] -- Improve inflateSync() documentation to note indeterminancy -- Add deflatePending() function to return the amount of pending output -- Correct the spelling of "specification" in FAQ [Randers-Pehrson] -- Add a check in configure for stdarg.h, use for gzprintf() -- Check that pointers fit in ints when gzprint() compiled old style -- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] -- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] -- Add debug records in assmebler code [Londer] -- Update RFC references to use http://tools.ietf.org/html/... [Li] -- Add --archs option, use of libtool to configure for Mac OS X [Borstel] - -Changes in 1.2.5 (19 Apr 2010) -- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] -- Default to libdir as sharedlibdir in configure [Nieder] -- Update copyright dates on modified source files -- Update trees.c to be able to generate modified trees.h -- Exit configure for MinGW, suggesting win32/Makefile.gcc -- Check for NULL path in gz_open [Homurlu] - -Changes in 1.2.4.5 (18 Apr 2010) -- Set sharedlibdir in configure [Torok] -- Set LDFLAGS in Makefile.in [Bar-Lev] -- Avoid mkdir objs race condition in Makefile.in [Bowler] -- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays -- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C -- Don't use hidden attribute when it is a warning generator (e.g. Solaris) - -Changes in 1.2.4.4 (18 Apr 2010) -- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] -- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty -- Try to use bash or ksh regardless of functionality of /bin/sh -- Fix configure incompatibility with NetBSD sh -- Remove attempt to run under bash or ksh since have better NetBSD fix -- Fix win32/Makefile.gcc for MinGW [Bar-Lev] -- Add diagnostic messages when using CROSS_PREFIX in configure -- Added --sharedlibdir option to configure [Weigelt] -- Use hidden visibility attribute when available [Frysinger] - -Changes in 1.2.4.3 (10 Apr 2010) -- Only use CROSS_PREFIX in configure for ar and ranlib if they exist -- Use CROSS_PREFIX for nm [Bar-Lev] -- Assume _LARGEFILE64_SOURCE defined is equivalent to true -- Avoid use of undefined symbols in #if with && and || -- Make *64 prototypes in gzguts.h consistent with functions -- Add -shared load option for MinGW in configure [Bowler] -- Move z_off64_t to public interface, use instead of off64_t -- Remove ! from shell test in configure (not portable to Solaris) -- Change +0 macro tests to -0 for possibly increased portability - -Changes in 1.2.4.2 (9 Apr 2010) -- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 -- Really provide prototypes for *64 functions when building without LFS -- Only define unlink() in minigzip.c if unistd.h not included -- Update README to point to contrib/vstudio project files -- Move projects/vc6 to old/ and remove projects/ -- Include stdlib.h in minigzip.c for setmode() definition under WinCE -- Clean up assembler builds in win32/Makefile.msc [Rowe] -- Include sys/types.h for Microsoft for off_t definition -- Fix memory leak on error in gz_open() -- Symbolize nm as $NM in configure [Weigelt] -- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] -- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined -- Fix bug in gzeof() to take into account unused input data -- Avoid initialization of structures with variables in puff.c -- Updated win32/README-WIN32.txt [Rowe] - -Changes in 1.2.4.1 (28 Mar 2010) -- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] -- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] -- Restore "for debugging" comment on sprintf() in gzlib.c -- Remove fdopen for MVS from gzguts.h -- Put new README-WIN32.txt in win32 [Rowe] -- Add check for shell to configure and invoke another shell if needed -- Fix big fat stinking bug in gzseek() on uncompressed files -- Remove vestigial F_OPEN64 define in zutil.h -- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE -- Avoid errors on non-LFS systems when applications define LFS macros -- Set EXE to ".exe" in configure for MINGW [Kahle] -- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] -- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] -- Add DLL install in win32/makefile.gcc [Bar-Lev] -- Allow Linux* or linux* from uname in configure [Bar-Lev] -- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] -- Add cross-compilation prefixes to configure [Bar-Lev] -- Match type exactly in gz_load() invocation in gzread.c -- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func -- Provide prototypes for *64 functions when building zlib without LFS -- Don't use -lc when linking shared library on MinGW -- Remove errno.h check in configure and vestigial errno code in zutil.h - -Changes in 1.2.4 (14 Mar 2010) -- Fix VER3 extraction in configure for no fourth subversion -- Update zlib.3, add docs to Makefile.in to make .pdf out of it -- Add zlib.3.pdf to distribution -- Don't set error code in gzerror() if passed pointer is NULL -- Apply destination directory fixes to CMakeLists.txt [Lowman] -- Move #cmakedefine's to a new zconf.in.cmakein -- Restore zconf.h for builds that don't use configure or cmake -- Add distclean to dummy Makefile for convenience -- Update and improve INDEX, README, and FAQ -- Update CMakeLists.txt for the return of zconf.h [Lowman] -- Update contrib/vstudio/vc9 and vc10 [Vollant] -- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc -- Apply license and readme changes to contrib/asm686 [Raiter] -- Check file name lengths and add -c option in minigzip.c [Li] -- Update contrib/amd64 and contrib/masmx86/ [Vollant] -- Avoid use of "eof" parameter in trees.c to not shadow library variable -- Update make_vms.com for removal of zlibdefs.h [Zinser] -- Update assembler code and vstudio projects in contrib [Vollant] -- Remove outdated assembler code contrib/masm686 and contrib/asm586 -- Remove old vc7 and vc8 from contrib/vstudio -- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] -- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() -- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] -- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) -- Fix bug in void-returning vsprintf() case in gzwrite.c -- Fix name change from inflate.h in contrib/inflate86/inffas86.c -- Check if temporary file exists before removing in make_vms.com [Zinser] -- Fix make install and uninstall for --static option -- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] -- Update readme.txt in contrib/masmx64 and masmx86 to assemble - -Changes in 1.2.3.9 (21 Feb 2010) -- Expunge gzio.c -- Move as400 build information to old -- Fix updates in contrib/minizip and contrib/vstudio -- Add const to vsnprintf test in configure to avoid warnings [Weigelt] -- Delete zconf.h (made by configure) [Weigelt] -- Change zconf.in.h to zconf.h.in per convention [Weigelt] -- Check for NULL buf in gzgets() -- Return empty string for gzgets() with len == 1 (like fgets()) -- Fix description of gzgets() in zlib.h for end-of-file, NULL return -- Update minizip to 1.1 [Vollant] -- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c -- Note in zlib.h that gzerror() should be used to distinguish from EOF -- Remove use of snprintf() from gzlib.c -- Fix bug in gzseek() -- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] -- Fix zconf.h generation in CMakeLists.txt [Lowman] -- Improve comments in zconf.h where modified by configure - -Changes in 1.2.3.8 (13 Feb 2010) -- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] -- Use z_off64_t in gz_zero() and gz_skip() to match state->skip -- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) -- Revert to Makefile.in from 1.2.3.6 (live with the clutter) -- Fix missing error return in gzflush(), add zlib.h note -- Add *64 functions to zlib.map [Levin] -- Fix signed/unsigned comparison in gz_comp() -- Use SFLAGS when testing shared linking in configure -- Add --64 option to ./configure to use -m64 with gcc -- Fix ./configure --help to correctly name options -- Have make fail if a test fails [Levin] -- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] -- Remove assembler object files from contrib - -Changes in 1.2.3.7 (24 Jan 2010) -- Always gzopen() with O_LARGEFILE if available -- Fix gzdirect() to work immediately after gzopen() or gzdopen() -- Make gzdirect() more precise when the state changes while reading -- Improve zlib.h documentation in many places -- Catch memory allocation failure in gz_open() -- Complete close operation if seek forward in gzclose_w() fails -- Return Z_ERRNO from gzclose_r() if close() fails -- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL -- Return zero for gzwrite() errors to match zlib.h description -- Return -1 on gzputs() error to match zlib.h description -- Add zconf.in.h to allow recovery from configure modification [Weigelt] -- Fix static library permissions in Makefile.in [Weigelt] -- Avoid warnings in configure tests that hide functionality [Weigelt] -- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] -- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] -- Avoid access of uninitialized data for first inflateReset2 call [Gomes] -- Keep object files in subdirectories to reduce the clutter somewhat -- Remove default Makefile and zlibdefs.h, add dummy Makefile -- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ -- Remove zlibdefs.h completely -- modify zconf.h instead - -Changes in 1.2.3.6 (17 Jan 2010) -- Avoid void * arithmetic in gzread.c and gzwrite.c -- Make compilers happier with const char * for gz_error message -- Avoid unused parameter warning in inflate.c -- Avoid signed-unsigned comparison warning in inflate.c -- Indent #pragma's for traditional C -- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() -- Correct email address in configure for system options -- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] -- Update zlib.map [Brown] -- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] -- Apply various fixes to CMakeLists.txt [Lowman] -- Add checks on len in gzread() and gzwrite() -- Add error message for no more room for gzungetc() -- Remove zlib version check in gzwrite() -- Defer compression of gzprintf() result until need to -- Use snprintf() in gzdopen() if available -- Remove USE_MMAP configuration determination (only used by minigzip) -- Remove examples/pigz.c (available separately) -- Update examples/gun.c to 1.6 - -Changes in 1.2.3.5 (8 Jan 2010) -- Add space after #if in zutil.h for some compilers -- Fix relatively harmless bug in deflate_fast() [Exarevsky] -- Fix same problem in deflate_slow() -- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] -- Add deflate_rle() for faster Z_RLE strategy run-length encoding -- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding -- Change name of "write" variable in inffast.c to avoid library collisions -- Fix premature EOF from gzread() in gzio.c [Brown] -- Use zlib header window size if windowBits is 0 in inflateInit2() -- Remove compressBound() call in deflate.c to avoid linking compress.o -- Replace use of errno in gz* with functions, support WinCE [Alves] -- Provide alternative to perror() in minigzip.c for WinCE [Alves] -- Don't use _vsnprintf on later versions of MSVC [Lowman] -- Add CMake build script and input file [Lowman] -- Update contrib/minizip to 1.1 [Svensson, Vollant] -- Moved nintendods directory from contrib to . -- Replace gzio.c with a new set of routines with the same functionality -- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above -- Update contrib/minizip to 1.1b -- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h - -Changes in 1.2.3.4 (21 Dec 2009) -- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility -- Update comments in configure and Makefile.in for default --shared -- Fix test -z's in configure [Marquess] -- Build examplesh and minigzipsh when not testing -- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h -- Import LDFLAGS from the environment in configure -- Fix configure to populate SFLAGS with discovered CFLAGS options -- Adapt make_vms.com to the new Makefile.in [Zinser] -- Add zlib2ansi script for C++ compilation [Marquess] -- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) -- Add AMD64 assembler code for longest match to contrib [Teterin] -- Include options from $SFLAGS when doing $LDSHARED -- Simplify 64-bit file support by introducing z_off64_t type -- Make shared object files in objs directory to work around old Sun cc -- Use only three-part version number for Darwin shared compiles -- Add rc option to ar in Makefile.in for when ./configure not run -- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* -- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile -- Protect against _FILE_OFFSET_BITS being defined when compiling zlib -- Rename Makefile.in targets allstatic to static and allshared to shared -- Fix static and shared Makefile.in targets to be independent -- Correct error return bug in gz_open() by setting state [Brown] -- Put spaces before ;;'s in configure for better sh compatibility -- Add pigz.c (parallel implementation of gzip) to examples/ -- Correct constant in crc32.c to UL [Leventhal] -- Reject negative lengths in crc32_combine() -- Add inflateReset2() function to work like inflateEnd()/inflateInit2() -- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] -- Correct typo in doc/algorithm.txt [Janik] -- Fix bug in adler32_combine() [Zhu] -- Catch missing-end-of-block-code error in all inflates and in puff - Assures that random input to inflate eventually results in an error -- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ -- Update ENOUGH and its usage to reflect discovered bounds -- Fix gzerror() error report on empty input file [Brown] -- Add ush casts in trees.c to avoid pedantic runtime errors -- Fix typo in zlib.h uncompress() description [Reiss] -- Correct inflate() comments with regard to automatic header detection -- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) -- Put new version of gzlog (2.0) in examples with interruption recovery -- Add puff compile option to permit invalid distance-too-far streams -- Add puff TEST command options, ability to read piped input -- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but - _LARGEFILE64_SOURCE not defined -- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart -- Fix deflateSetDictionary() to use all 32K for output consistency -- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) -- Clear bytes after deflate lookahead to avoid use of uninitialized data -- Change a limit in inftrees.c to be more transparent to Coverity Prevent -- Update win32/zlib.def with exported symbols from zlib.h -- Correct spelling errors in zlib.h [Willem, Sobrado] -- Allow Z_BLOCK for deflate() to force a new block -- Allow negative bits in inflatePrime() to delete existing bit buffer -- Add Z_TREES flush option to inflate() to return at end of trees -- Add inflateMark() to return current state information for random access -- Add Makefile for NintendoDS to contrib [Costa] -- Add -w in configure compile tests to avoid spurious warnings [Beucler] -- Fix typos in zlib.h comments for deflateSetDictionary() -- Fix EOF detection in transparent gzread() [Maier] - -Changes in 1.2.3.3 (2 October 2006) -- Make --shared the default for configure, add a --static option -- Add compile option to permit invalid distance-too-far streams -- Add inflateUndermine() function which is required to enable above -- Remove use of "this" variable name for C++ compatibility [Marquess] -- Add testing of shared library in make test, if shared library built -- Use ftello() and fseeko() if available instead of ftell() and fseek() -- Provide two versions of all functions that use the z_off_t type for - binary compatibility -- a normal version and a 64-bit offset version, - per the Large File Support Extension when _LARGEFILE64_SOURCE is - defined; use the 64-bit versions by default when _FILE_OFFSET_BITS - is defined to be 64 -- Add a --uname= option to configure to perhaps help with cross-compiling - -Changes in 1.2.3.2 (3 September 2006) -- Turn off silly Borland warnings [Hay] -- Use off64_t and define _LARGEFILE64_SOURCE when present -- Fix missing dependency on inffixed.h in Makefile.in -- Rig configure --shared to build both shared and static [Teredesai, Truta] -- Remove zconf.in.h and instead create a new zlibdefs.h file -- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] -- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] - -Changes in 1.2.3.1 (16 August 2006) -- Add watcom directory with OpenWatcom make files [Daniel] -- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] -- Update make_vms.com [Zinser] -- Use -fPIC for shared build in configure [Teredesai, Nicholson] -- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] -- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] -- Add some FAQ entries about the contrib directory -- Update the MVS question in the FAQ -- Avoid extraneous reads after EOF in gzio.c [Brown] -- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] -- Add comments to zlib.h about gzerror() usage [Brown] -- Set extra flags in gzip header in gzopen() like deflate() does -- Make configure options more compatible with double-dash conventions - [Weigelt] -- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] -- Fix uninstall target in Makefile.in [Truta] -- Add pkgconfig support [Weigelt] -- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] -- Replace set_data_type() with a more accurate detect_data_type() in - trees.c, according to the txtvsbin.txt document [Truta] -- Swap the order of #include and #include "zlib.h" in - gzio.c, example.c and minigzip.c [Truta] -- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, - Truta] (where?) -- Fix target "clean" from win32/Makefile.bor [Truta] -- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] -- Update zlib www home address in win32/DLL_FAQ.txt [Truta] -- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] -- Enable browse info in the "Debug" and "ASM Debug" configurations in - the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] -- Add pkgconfig support [Weigelt] -- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, - for use in win32/zlib1.rc [Polushin, Rowe, Truta] -- Add a document that explains the new text detection scheme to - doc/txtvsbin.txt [Truta] -- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] -- Move algorithm.txt into doc/ [Truta] -- Synchronize FAQ with website -- Fix compressBound(), was low for some pathological cases [Fearnley] -- Take into account wrapper variations in deflateBound() -- Set examples/zpipe.c input and output to binary mode for Windows -- Update examples/zlib_how.html with new zpipe.c (also web site) -- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems - that gcc became pickier in 4.0) -- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain - un-versioned, the patch adds versioning only for symbols introduced in - zlib-1.2.0 or later. It also declares as local those symbols which are - not designed to be exported." [Levin] -- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure -- Do not initialize global static by default in trees.c, add a response - NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] -- Don't use strerror() in gzio.c under WinCE [Yakimov] -- Don't use errno.h in zutil.h under WinCE [Yakimov] -- Move arguments for AR to its usage to allow replacing ar [Marot] -- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] -- Improve inflateInit() and inflateInit2() documentation -- Fix structure size comment in inflate.h -- Change configure help option from --h* to --help [Santos] - -Changes in 1.2.3 (18 July 2005) -- Apply security vulnerability fixes to contrib/infback9 as well -- Clean up some text files (carriage returns, trailing space) -- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] - -Changes in 1.2.2.4 (11 July 2005) -- Add inflatePrime() function for starting inflation at bit boundary -- Avoid some Visual C warnings in deflate.c -- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit - compile -- Fix some spelling errors in comments [Betts] -- Correct inflateInit2() error return documentation in zlib.h -- Add zran.c example of compressed data random access to examples - directory, shows use of inflatePrime() -- Fix cast for assignments to strm->state in inflate.c and infback.c -- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] -- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] -- Add cast in trees.c t avoid a warning [Oberhumer] -- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] -- Update make_vms.com [Zinser] -- Initialize state->write in inflateReset() since copied in inflate_fast() -- Be more strict on incomplete code sets in inflate_table() and increase - ENOUGH and MAXD -- this repairs a possible security vulnerability for - invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases. -- Add ia64 support to configure for HP-UX [Smith] -- Add error return to gzread() for format or i/o error [Levin] -- Use malloc.h for OS/2 [Necasek] - -Changes in 1.2.2.3 (27 May 2005) -- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile -- Typecast fread() return values in gzio.c [Vollant] -- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) -- Fix crc check bug in gzread() after gzungetc() [Heiner] -- Add the deflateTune() function to adjust internal compression parameters -- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) -- Remove an incorrect assertion in examples/zpipe.c -- Add C++ wrapper in infback9.h [Donais] -- Fix bug in inflateCopy() when decoding fixed codes -- Note in zlib.h how much deflateSetDictionary() actually uses -- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) -- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] -- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] -- Add gzdirect() function to indicate transparent reads -- Update contrib/minizip [Vollant] -- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] -- Add casts in crc32.c to avoid warnings [Oberhumer] -- Add contrib/masmx64 [Vollant] -- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] - -Changes in 1.2.2.2 (30 December 2004) -- Replace structure assignments in deflate.c and inflate.c with zmemcpy to - avoid implicit memcpy calls (portability for no-library compilation) -- Increase sprintf() buffer size in gzdopen() to allow for large numbers -- Add INFLATE_STRICT to check distances against zlib header -- Improve WinCE errno handling and comments [Chang] -- Remove comment about no gzip header processing in FAQ -- Add Z_FIXED strategy option to deflateInit2() to force fixed trees -- Add updated make_vms.com [Coghlan], update README -- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. -- Add FAQ entry and comments in deflate.c on uninitialized memory access -- Add Solaris 9 make options in configure [Gilbert] -- Allow strerror() usage in gzio.c for STDC -- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] -- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] -- Use z_off_t for adler32_combine() and crc32_combine() lengths -- Make adler32() much faster for small len -- Use OS_CODE in deflate() default gzip header - -Changes in 1.2.2.1 (31 October 2004) -- Allow inflateSetDictionary() call for raw inflate -- Fix inflate header crc check bug for file names and comments -- Add deflateSetHeader() and gz_header structure for custom gzip headers -- Add inflateGetheader() to retrieve gzip headers -- Add crc32_combine() and adler32_combine() functions -- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list -- Use zstreamp consistently in zlib.h (inflate_back functions) -- Remove GUNZIP condition from definition of inflate_mode in inflate.h - and in contrib/inflate86/inffast.S [Truta, Anderson] -- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] -- Update projects/README.projects and projects/visualc6 [Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] -- Deprecate Z_ASCII; use Z_TEXT instead [Truta] -- Use a new algorithm for setting strm->data_type in trees.c [Truta] -- Do not define an exit() prototype in zutil.c unless DEBUG defined -- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] -- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() -- Fix Darwin build version identification [Peterson] - -Changes in 1.2.2 (3 October 2004) -- Update zlib.h comments on gzip in-memory processing -- Set adler to 1 in inflateReset() to support Java test suite [Walles] -- Add contrib/dotzlib [Ravn] -- Update win32/DLL_FAQ.txt [Truta] -- Update contrib/minizip [Vollant] -- Move contrib/visual-basic.txt to old/ [Truta] -- Fix assembler builds in projects/visualc6/ [Truta] - -Changes in 1.2.1.2 (9 September 2004) -- Update INDEX file -- Fix trees.c to update strm->data_type (no one ever noticed!) -- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] -- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) -- Add limited multitasking protection to DYNAMIC_CRC_TABLE -- Add NO_vsnprintf for VMS in zutil.h [Mozilla] -- Don't declare strerror() under VMS [Mozilla] -- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize -- Update contrib/ada [Anisimkov] -- Update contrib/minizip [Vollant] -- Fix configure to not hardcode directories for Darwin [Peterson] -- Fix gzio.c to not return error on empty files [Brown] -- Fix indentation; update version in contrib/delphi/ZLib.pas and - contrib/pascal/zlibpas.pas [Truta] -- Update mkasm.bat in contrib/masmx86 [Truta] -- Update contrib/untgz [Truta] -- Add projects/README.projects [Truta] -- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] -- Remove an unnecessary assignment to curr in inftrees.c [Truta] -- Add OS/2 to exe builds in configure [Poltorak] -- Remove err dummy parameter in zlib.h [Kientzle] - -Changes in 1.2.1.1 (9 January 2004) -- Update email address in README -- Several FAQ updates -- Fix a big fat bug in inftrees.c that prevented decoding valid - dynamic blocks with only literals and no distance codes -- - Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case. - -Changes in 1.2.1 (17 November 2003) -- Remove a tab in contrib/gzappend/gzappend.c -- Update some interfaces in contrib for new zlib functions -- Update zlib version number in some contrib entries -- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] -- Support shared libraries on Hurd and KFreeBSD [Brown] -- Fix error in NO_DIVIDE option of adler32.c - -Changes in 1.2.0.8 (4 November 2003) -- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas -- Add experimental NO_DIVIDE #define in adler32.c - - Possibly faster on some processors (let me know if it is) -- Correct Z_BLOCK to not return on first inflate call if no wrap -- Fix strm->data_type on inflate() return to correctly indicate EOB -- Add deflatePrime() function for appending in the middle of a byte -- Add contrib/gzappend for an example of appending to a stream -- Update win32/DLL_FAQ.txt [Truta] -- Delete Turbo C comment in README [Truta] -- Improve some indentation in zconf.h [Truta] -- Fix infinite loop on bad input in configure script [Church] -- Fix gzeof() for concatenated gzip files [Johnson] -- Add example to contrib/visual-basic.txt [Michael B.] -- Add -p to mkdir's in Makefile.in [vda] -- Fix configure to properly detect presence or lack of printf functions -- Add AS400 support [Monnerat] -- Add a little Cygwin support [Wilson] - -Changes in 1.2.0.7 (21 September 2003) -- Correct some debug formats in contrib/infback9 -- Cast a type in a debug statement in trees.c -- Change search and replace delimiter in configure from % to # [Beebe] -- Update contrib/untgz to 0.2 with various fixes [Truta] -- Add build support for Amiga [Nikl] -- Remove some directories in old that have been updated to 1.2 -- Add dylib building for Mac OS X in configure and Makefile.in -- Remove old distribution stuff from Makefile -- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X -- Update links in README - -Changes in 1.2.0.6 (13 September 2003) -- Minor FAQ updates -- Update contrib/minizip to 1.00 [Vollant] -- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] -- Update POSTINC comment for 68060 [Nikl] -- Add contrib/infback9 with deflate64 decoding (unsupported) -- For MVS define NO_vsnprintf and undefine FAR [van Burik] -- Add pragma for fdopen on MVS [van Burik] - -Changes in 1.2.0.5 (8 September 2003) -- Add OF to inflateBackEnd() declaration in zlib.h -- Remember start when using gzdopen in the middle of a file -- Use internal off_t counters in gz* functions to properly handle seeks -- Perform more rigorous check for distance-too-far in inffast.c -- Add Z_BLOCK flush option to return from inflate at block boundary -- Set strm->data_type on return from inflate - - Indicate bits unused, if at block boundary, and if in last block -- Replace size_t with ptrdiff_t in crc32.c, and check for correct size -- Add condition so old NO_DEFLATE define still works for compatibility -- FAQ update regarding the Windows DLL [Truta] -- INDEX update: add qnx entry, remove aix entry [Truta] -- Install zlib.3 into mandir [Wilson] -- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] -- Adapt the zlib interface to the new DLL convention guidelines [Truta] -- Introduce ZLIB_WINAPI macro to allow the export of functions using - the WINAPI calling convention, for Visual Basic [Vollant, Truta] -- Update msdos and win32 scripts and makefiles [Truta] -- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] -- Add contrib/ada [Anisimkov] -- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] -- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] -- Add contrib/masm686 [Truta] -- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm - [Truta, Vollant] -- Update contrib/delphi; rename to contrib/pascal; add example [Truta] -- Remove contrib/delphi2; add a new contrib/delphi [Truta] -- Avoid inclusion of the nonstandard in contrib/iostream, - and fix some method prototypes [Truta] -- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip - [Truta] -- Avoid the use of backslash (\) in contrib/minizip [Vollant] -- Fix file time handling in contrib/untgz; update makefiles [Truta] -- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines - [Vollant] -- Remove contrib/vstudio/vc15_16 [Vollant] -- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] -- Update README.contrib [Truta] -- Invert the assignment order of match_head and s->prev[...] in - INSERT_STRING [Truta] -- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings - [Truta] -- Compare function pointers with 0, not with NULL or Z_NULL [Truta] -- Fix prototype of syncsearch in inflate.c [Truta] -- Introduce ASMINF macro to be enabled when using an ASM implementation - of inflate_fast [Truta] -- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] -- Modify test_gzio in example.c to take a single file name as a - parameter [Truta] -- Exit the example.c program if gzopen fails [Truta] -- Add type casts around strlen in example.c [Truta] -- Remove casting to sizeof in minigzip.c; give a proper type - to the variable compared with SUFFIX_LEN [Truta] -- Update definitions of STDC and STDC99 in zconf.h [Truta] -- Synchronize zconf.h with the new Windows DLL interface [Truta] -- Use SYS16BIT instead of __32BIT__ to distinguish between - 16- and 32-bit platforms [Truta] -- Use far memory allocators in small 16-bit memory models for - Turbo C [Truta] -- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in - zlibCompileFlags [Truta] -- Cygwin has vsnprintf [Wilson] -- In Windows16, OS_CODE is 0, as in MSDOS [Truta] -- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] - -Changes in 1.2.0.4 (10 August 2003) -- Minor FAQ updates -- Be more strict when checking inflateInit2's windowBits parameter -- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well -- Add gzip wrapper option to deflateInit2 using windowBits -- Add updated QNX rule in configure and qnx directory [Bonnefoy] -- Make inflate distance-too-far checks more rigorous -- Clean up FAR usage in inflate -- Add casting to sizeof() in gzio.c and minigzip.c - -Changes in 1.2.0.3 (19 July 2003) -- Fix silly error in gzungetc() implementation [Vollant] -- Update contrib/minizip and contrib/vstudio [Vollant] -- Fix printf format in example.c -- Correct cdecl support in zconf.in.h [Anisimkov] -- Minor FAQ updates - -Changes in 1.2.0.2 (13 July 2003) -- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons -- Attempt to avoid warnings in crc32.c for pointer-int conversion -- Add AIX to configure, remove aix directory [Bakker] -- Add some casts to minigzip.c -- Improve checking after insecure sprintf() or vsprintf() calls -- Remove #elif's from crc32.c -- Change leave label to inf_leave in inflate.c and infback.c to avoid - library conflicts -- Remove inflate gzip decoding by default--only enable gzip decoding by - special request for stricter backward compatibility -- Add zlibCompileFlags() function to return compilation information -- More typecasting in deflate.c to avoid warnings -- Remove leading underscore from _Capital #defines [Truta] -- Fix configure to link shared library when testing -- Add some Windows CE target adjustments [Mai] -- Remove #define ZLIB_DLL in zconf.h [Vollant] -- Add zlib.3 [Rodgers] -- Update RFC URL in deflate.c and algorithm.txt [Mai] -- Add zlib_dll_FAQ.txt to contrib [Truta] -- Add UL to some constants [Truta] -- Update minizip and vstudio [Vollant] -- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h -- Expand use of NO_DUMMY_DECL to avoid all dummy structures -- Added iostream3 to contrib [Schwardt] -- Replace rewind() with fseek() for WinCE [Truta] -- Improve setting of zlib format compression level flags - - Report 0 for huffman and rle strategies and for level == 0 or 1 - - Report 2 only for level == 6 -- Only deal with 64K limit when necessary at compile time [Truta] -- Allow TOO_FAR check to be turned off at compile time [Truta] -- Add gzclearerr() function [Souza] -- Add gzungetc() function - -Changes in 1.2.0.1 (17 March 2003) -- Add Z_RLE strategy for run-length encoding [Truta] - - When Z_RLE requested, restrict matches to distance one - - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE -- Correct FASTEST compilation to allow level == 0 -- Clean up what gets compiled for FASTEST -- Incorporate changes to zconf.in.h [Vollant] - - Refine detection of Turbo C need for dummy returns - - Refine ZLIB_DLL compilation - - Include additional header file on VMS for off_t typedef -- Try to use _vsnprintf where it supplants vsprintf [Vollant] -- Add some casts in inffast.c -- Enchance comments in zlib.h on what happens if gzprintf() tries to - write more than 4095 bytes before compression -- Remove unused state from inflateBackEnd() -- Remove exit(0) from minigzip.c, example.c -- Get rid of all those darn tabs -- Add "check" target to Makefile.in that does the same thing as "test" -- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in -- Update contrib/inflate86 [Anderson] -- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] -- Add msdos and win32 directories with makefiles [Truta] -- More additions and improvements to the FAQ - -Changes in 1.2.0 (9 March 2003) -- New and improved inflate code - - About 20% faster - - Does not allocate 32K window unless and until needed - - Automatically detects and decompresses gzip streams - - Raw inflate no longer needs an extra dummy byte at end - - Added inflateBack functions using a callback interface--even faster - than inflate, useful for file utilities (gzip, zip) - - Added inflateCopy() function to record state for random access on - externally generated deflate streams (e.g. in gzip files) - - More readable code (I hope) -- New and improved crc32() - - About 50% faster, thanks to suggestions from Rodney Brown -- Add deflateBound() and compressBound() functions -- Fix memory leak in deflateInit2() -- Permit setting dictionary for raw deflate (for parallel deflate) -- Fix const declaration for gzwrite() -- Check for some malloc() failures in gzio.c -- Fix bug in gzopen() on single-byte file 0x1f -- Fix bug in gzread() on concatenated file with 0x1f at end of buffer - and next buffer doesn't start with 0x8b -- Fix uncompress() to return Z_DATA_ERROR on truncated input -- Free memory at end of example.c -- Remove MAX #define in trees.c (conflicted with some libraries) -- Fix static const's in deflate.c, gzio.c, and zutil.[ch] -- Declare malloc() and free() in gzio.c if STDC not defined -- Use malloc() instead of calloc() in zutil.c if int big enough -- Define STDC for AIX -- Add aix/ with approach for compiling shared library on AIX -- Add HP-UX support for shared libraries in configure -- Add OpenUNIX support for shared libraries in configure -- Use $cc instead of gcc to build shared library -- Make prefix directory if needed when installing -- Correct Macintosh avoidance of typedef Byte in zconf.h -- Correct Turbo C memory allocation when under Linux -- Use libz.a instead of -lz in Makefile (assure use of compiled library) -- Update configure to check for snprintf or vsnprintf functions and their - return value, warn during make if using an insecure function -- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that - is lost when library is used--resolution is to build new zconf.h -- Documentation improvements (in zlib.h): - - Document raw deflate and inflate - - Update RFCs URL - - Point out that zlib and gzip formats are different - - Note that Z_BUF_ERROR is not fatal - - Document string limit for gzprintf() and possible buffer overflow - - Note requirement on avail_out when flushing - - Note permitted values of flush parameter of inflate() -- Add some FAQs (and even answers) to the FAQ -- Add contrib/inflate86/ for x86 faster inflate -- Add contrib/blast/ for PKWare Data Compression Library decompression -- Add contrib/puff/ simple inflate for deflate format description - -Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions. - This creates a security problem described in - http://www.zlib.org/advisory-2002-03-11.txt -- Returned incorrect error (Z_MEM_ERROR) on some invalid data -- Avoid accesses before window for invalid distances with inflate window - less than 32K. -- force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5). - -Changes in 1.1.3 (9 July 1998) -- fix "an inflate input buffer bug that shows up on rare but persistent - occasions" (Mark) -- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) -- fix gzseek(..., SEEK_SET) in write mode -- fix crc check after a gzeek (Frank Faubert) -- fix miniunzip when the last entry in a zip file is itself a zip file - (J Lillge) -- add contrib/asm586 and contrib/asm686 (Brian Raiter) - See http://www.muppetlabs.com/~breadbox/software/assembly.html -- add support for Delphi 3 in contrib/delphi (Bob Dellaca) -- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) -- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) -- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) -- added a FAQ file - -- Support gzdopen on Mac with Metrowerks (Jason Linhart) -- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) -- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) -- avoid some warnings with Borland C (Tom Tanner) -- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) -- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) -- allow several arguments to configure (Tim Mooney, Frodo Looijaard) -- use libdir and includedir in Makefile.in (Tim Mooney) -- support shared libraries on OSF1 V4 (Tim Mooney) -- remove so_locations in "make clean" (Tim Mooney) -- fix maketree.c compilation error (Glenn, Mark) -- Python interface to zlib now in Python 1.5 (Jeremy Hylton) -- new Makefile.riscos (Rich Walker) -- initialize static descriptors in trees.c for embedded targets (Nick Smith) -- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) -- add the OS/2 files in Makefile.in too (Andrew Zabolotny) -- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) -- fix maketree.c to allow clean compilation of inffixed.h (Mark) -- fix parameter check in deflateCopy (Gunther Nikl) -- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) -- Many portability patches by Christian Spieler: - . zutil.c, zutil.h: added "const" for zmem* - . Make_vms.com: fixed some typos - . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists - . msdos/Makefile.msc: remove "default rtl link library" info from obj files - . msdos/Makefile.*: use model-dependent name for the built zlib library - . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: - new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) -- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) -- replace __far with _far for better portability (Christian Spieler, Tom Lane) -- fix test for errno.h in configure (Tim Newsham) - -Changes in 1.1.2 (19 March 98) -- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) - See http://www.winimage.com/zLibDll/unzip.html -- preinitialize the inflate tables for fixed codes, to make the code - completely thread safe (Mark) -- some simplifications and slight speed-up to the inflate code (Mark) -- fix gzeof on non-compressed files (Allan Schrum) -- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) -- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) -- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) -- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) -- do not wrap extern "C" around system includes (Tom Lane) -- mention zlib binding for TCL in README (Andreas Kupries) -- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) -- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) -- allow "configure --prefix $HOME" (Tim Mooney) -- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) -- move Makefile.sas to amiga/Makefile.sas - -Changes in 1.1.1 (27 Feb 98) -- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) -- remove block truncation heuristic which had very marginal effect for zlib - (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the - compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow. -- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - -Changes in 1.1.0 (24 Feb 98) -- do not return STREAM_END prematurely in inflate (John Bowler) -- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) -- compile with -DFASTEST to get compression code optimized for speed only -- in minigzip, try mmap'ing the input file first (Miguel Albrecht) -- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain - on Sun but significant on HP) - -- add a pointer to experimental unzip library in README (Gilles Vollant) -- initialize variable gcc in configure (Chris Herborth) - -Changes in 1.0.9 (17 Feb 1998) -- added gzputs and gzgets functions -- do not clear eof flag in gzseek (Mark Diekhans) -- fix gzseek for files in transparent mode (Mark Diekhans) -- do not assume that vsprintf returns the number of bytes written (Jens Krinke) -- replace EXPORT with ZEXPORT to avoid conflict with other programs -- added compress2 in zconf.h, zlib.def, zlib.dnt -- new asm code from Gilles Vollant in contrib/asm386 -- simplify the inflate code (Mark): - . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() - . ZALLOC the length list in inflate_trees_fixed() instead of using stack - . ZALLOC the value area for huft_build() instead of using stack - . Simplify Z_FINISH check in inflate() - -- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 -- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) -- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles VOllant) -- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) -- read_buf buf parameter of type Bytef* instead of charf* -- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) -- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) -- fix check for presence of directories in "make install" (Ian Willis) - -Changes in 1.0.8 (27 Jan 1998) -- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) -- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) -- added compress2() to allow setting the compression level -- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) -- use constant arrays for the static trees in trees.c instead of computing - them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test". -- check return code of example in "make test" and display result -- pass minigzip command line options to file_compress -- simplifying code of inflateSync to avoid gcc 2.8 bug - -- support CC="gcc -Wall" in configure -s (QingLong) -- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) -- fix test for shared library support to avoid compiler warnings -- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) -- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) -- do not use fdopen for Metrowerks on Mac (Brad Pettit)) -- add checks for gzputc and gzputc in example.c -- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) -- use const for the CRC table (Ken Raeburn) -- fixed "make uninstall" for shared libraries -- use Tracev instead of Trace in infblock.c -- in example.c use correct compressed length for test_sync -- suppress +vnocompatwarnings in configure for HPUX (not always supported) - -Changes in 1.0.7 (20 Jan 1998) -- fix gzseek which was broken in write mode -- return error for gzseek to negative absolute position -- fix configure for Linux (Chun-Chung Chen) -- increase stack space for MSC (Tim Wegner) -- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) -- define EXPORTVA for gzprintf (Gilles Vollant) -- added man page zlib.3 (Rick Rodgers) -- for contrib/untgz, fix makedir() and improve Makefile - -- check gzseek in write mode in example.c -- allocate extra buffer for seeks only if gzseek is actually called -- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) -- add inflateSyncPoint in zconf.h -- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def - -Changes in 1.0.6 (19 Jan 1998) -- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) -- Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one). -- In minigzip, pass transparently also the first byte for .Z files. -- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() -- check Z_FINISH in inflate (thanks to Marc Schluper) -- Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option. -- move MSDOS or Windows specific files to directory msdos -- suppress the notion of partial flush to simplify the interface - (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) -- suppress history buffer provided by application to simplify the interface - (this feature was not implemented anyway in 1.0.4) -- next_in and avail_in must be initialized before calling inflateInit or - inflateInit2 -- add EXPORT in all exported functions (for Windows DLL) -- added Makefile.nt (thanks to Stephen Williams) -- added the unsupported "contrib" directory: - contrib/asm386/ by Gilles Vollant - 386 asm code replacing longest_match(). - contrib/iostream/ by Kevin Ruland - A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Løvset - Another C++ I/O streams interface - contrib/untgz/ by "Pedro A. Aranda Guti\irrez" - A very simple tar.gz file extractor using zlib - contrib/visual-basic.txt by Carlos Rios - How to use compress(), uncompress() and the gz* functions from VB. -- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - level) in minigzip (thanks to Tom Lane) - -- use const for rommable constants in deflate -- added test for gzseek and gztell in example.c -- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) -- add undocumented function zError to convert error code to string - (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. -- Use default memcpy for Symantec MSDOS compiler. -- Add EXPORT keyword for check_func (needed for Windows DLL) -- add current directory to LD_LIBRARY_PATH for "make test" -- create also a link for libz.so.1 -- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) -- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) -- added -soname for Linux in configure (Chun-Chung Chen, -- assign numbers to the exported functions in zlib.def (for Windows DLL) -- add advice in zlib.h for best usage of deflateSetDictionary -- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) -- allow compilation with ANSI keywords only enabled for TurboC in large model -- avoid "versionString"[0] (Borland bug) -- add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). -- allow compilation with CC -- defined STDC for OS/2 (David Charlap) -- limit external names to 8 chars for MVS (Thomas Lund) -- in minigzip.c, use static buffers only for 16-bit systems -- fix suffix check for "minigzip -d foo.gz" -- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) -- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) -- added makelcc.bat for lcc-win32 (Tom St Denis) -- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. -- check for unistd.h in configure (for off_t) -- remove useless check parameter in inflate_blocks_free -- avoid useless assignment of s->check to itself in inflate_blocks_new -- do not flush twice in gzclose (thanks to Ken Raeburn) -- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h -- use NO_ERRNO_H instead of enumeration of operating systems with errno.h -- work around buggy fclose on pipes for HP/UX -- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) -- fix configure if CC is already equal to gcc - -Changes in 1.0.5 (3 Jan 98) -- Fix inflate to terminate gracefully when fed corrupted or invalid data -- Use const for rommable constants in inflate -- Eliminate memory leaks on error conditions in inflate -- Removed some vestigial code in inflate -- Update web address in README - -Changes in 1.0.4 (24 Jul 96) -- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too. -- zlibVersion and gzerror return const char* (needed for DLL) -- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) -- use z_error only for DEBUG (avoid problem with DLLs) - -Changes in 1.0.3 (2 Jul 96) -- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS - small and medium models; this makes the library incompatible with previous - versions for these models. (No effect in large model or on other systems.) -- return OK instead of BUF_ERROR if previous deflate call returned with - avail_out as zero but there is nothing to do -- added memcmp for non STDC compilers -- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) -- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) -- better check for 16-bit mode MSC (avoids problem with Symantec) - -Changes in 1.0.2 (23 May 96) -- added Windows DLL support -- added a function zlibVersion (for the DLL support) -- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) -- Bytef is define's instead of typedef'd only for Borland C -- avoid reading uninitialized memory in example.c -- mention in README that the zlib format is now RFC1950 -- updated Makefile.dj2 -- added algorithm.doc - -Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] -- fix array overlay in deflate.c which sometimes caused bad compressed data -- fix inflate bug with empty stored block -- fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generate bad compressed data. -- Bytef is define'd instead of typedef'ed (work around Borland bug) -- added an INDEX file -- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) -- speed up adler32 for modern machines without auto-increment -- added -ansi for IRIX in configure -- static_init_done in trees.c is an int -- define unlink as delete for VMS -- fix configure for QNX -- add configure branch for SCO and HPUX -- avoid many warnings (unused variables, dead assignments, etc...) -- no fdopen for BeOS -- fix the Watcom fix for 32 bit mode (define FAR as empty) -- removed redefinition of Byte for MKWERKS -- work around an MWKERKS bug (incorrect merge of all .h files) - -Changes in 0.99 (27 Jan 96) -- allow preset dictionary shared between compressor and decompressor -- allow compression level 0 (no compression) -- add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy. -- test large buffers and deflateParams in example.c -- add optional "configure" to build zlib as a shared library -- suppress Makefile.qnx, use configure instead -- fixed deflate for 64-bit systems (detected on Cray) -- fixed inflate_blocks for 64-bit systems (detected on Alpha) -- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) -- always return Z_BUF_ERROR when deflate() has nothing to do -- deflateInit and inflateInit are now macros to allow version checking -- prefix all global functions and types with z_ with -DZ_PREFIX -- make falloc completely reentrant (inftrees.c) -- fixed very unlikely race condition in ct_static_init -- free in reverse order of allocation to help memory manager -- use zlib-1.0/* instead of zlib/* inside the tar.gz -- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith - -Wconversion -Wstrict-prototypes -Wmissing-prototypes" -- allow gzread on concatenated .gz files -- deflateEnd now returns Z_DATA_ERROR if it was premature -- deflate is finally (?) fully deterministic (no matches beyond end of input) -- Document Z_SYNC_FLUSH -- add uninstall in Makefile -- Check for __cpluplus in zlib.h -- Better test in ct_align for partial flush -- avoid harmless warnings for Borland C++ -- initialize hash_head in deflate.c -- avoid warning on fdopen (gzio.c) for HP cc -Aa -- include stdlib.h for STDC compilers -- include errno.h for Cray -- ignore error if ranlib doesn't exist -- call ranlib twice for NeXTSTEP -- use exec_prefix instead of prefix for libz.a -- renamed ct_* as _tr_* to avoid conflict with applications -- clear z->msg in inflateInit2 before any error return -- initialize opaque in example.c, gzio.c, deflate.c and inflate.c -- fixed typo in zconf.h (_GNUC__ => __GNUC__) -- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) -- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) -- in fcalloc, normalize pointer if size > 65520 bytes -- don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... -- use Z_BINARY instead of BINARY -- document that gzclose after gzdopen will close the file -- allow "a" as mode in gzopen. -- fix error checking in gzread -- allow skipping .gz extra-field on pipes -- added reference to Perl interface in README -- put the crc table in FAR data (I dislike more and more the medium model :) -- added get_crc_table -- added a dimension to all arrays (Borland C can't count). -- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast -- guard against multiple inclusion of *.h (for precompiled header on Mac) -- Watcom C pretends to be Microsoft C small model even in 32 bit mode. -- don't use unsized arrays to avoid silly warnings by Visual C++: - warning C4746: 'inflate_mask' : unsized array treated as '__far' - (what's wrong with far data in far model?). -- define enum out of inflate_blocks_state to allow compilation with C++ - -Changes in 0.95 (16 Aug 95) -- fix MSDOS small and medium model (now easier to adapt to any compiler) -- inlined send_bits -- fix the final (:-) bug for deflate with flush (output was correct but - not completely flushed in rare occasions). -- default window size is same for compression and decompression - (it's now sufficient to set MAX_WBITS in zconf.h). -- voidp -> voidpf and voidnp -> voidp (for consistency with other - typedefs and because voidnp was not near in large model). - -Changes in 0.94 (13 Aug 95) -- support MSDOS medium model -- fix deflate with flush (could sometimes generate bad output) -- fix deflateReset (zlib header was incorrectly suppressed) -- added support for VMS -- allow a compression level in gzopen() -- gzflush now calls fflush -- For deflate with flush, flush even if no more input is provided. -- rename libgz.a as libz.a -- avoid complex expression in infcodes.c triggering Turbo C bug -- work around a problem with gcc on Alpha (in INSERT_STRING) -- don't use inline functions (problem with some gcc versions) -- allow renaming of Byte, uInt, etc... with #define. -- avoid warning about (unused) pointer before start of array in deflate.c -- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c -- avoid reserved word 'new' in trees.c - -Changes in 0.93 (25 June 95) -- temporarily disable inline functions -- make deflate deterministic -- give enough lookahead for PARTIAL_FLUSH -- Set binary mode for stdin/stdout in minigzip.c for OS/2 -- don't even use signed char in inflate (not portable enough) -- fix inflate memory leak for segmented architectures - -Changes in 0.92 (3 May 95) -- don't assume that char is signed (problem on SGI) -- Clear bit buffer when starting a stored block -- no memcpy on Pyramid -- suppressed inftest.c -- optimized fill_window, put longest_match inline for gcc -- optimized inflate on stored blocks. -- untabify all sources to simplify patches - -Changes in 0.91 (2 May 95) -- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h -- Document the memory requirements in zconf.h -- added "make install" -- fix sync search logic in inflateSync -- deflate(Z_FULL_FLUSH) now works even if output buffer too short -- after inflateSync, don't scare people with just "lo world" -- added support for DJGPP - -Changes in 0.9 (1 May 95) -- don't assume that zalloc clears the allocated memory (the TurboC bug - was Mark's bug after all :) -- let again gzread copy uncompressed data unchanged (was working in 0.71) -- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented -- added a test of inflateSync in example.c -- moved MAX_WBITS to zconf.h because users might want to change that. -- document explicitly that zalloc(64K) on MSDOS must return a normalized - pointer (zero offset) -- added Makefiles for Microsoft C, Turbo C, Borland C++ -- faster crc32() - -Changes in 0.8 (29 April 95) -- added fast inflate (inffast.c) -- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - is incompatible with previous versions of zlib which returned Z_OK. -- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - (actually that was not a compiler bug, see 0.81 above) -- gzread no longer reads one extra byte in certain cases -- In gzio destroy(), don't reference a freed structure -- avoid many warnings for MSDOS -- avoid the ERROR symbol which is used by MS Windows - -Changes in 0.71 (14 April 95) -- Fixed more MSDOS compilation problems :( There is still a bug with - TurboC large model. - -Changes in 0.7 (14 April 95) -- Added full inflate support. -- Simplified the crc32() interface. The pre- and post-conditioning - (one's complement) is now done inside crc32(). WARNING: this is - incompatible with previous versions; see zlib.h for the new usage. - -Changes in 0.61 (12 April 95) -- workaround for a bug in TurboC. example and minigzip now work on MSDOS. - -Changes in 0.6 (11 April 95) -- added minigzip.c -- added gzdopen to reopen a file descriptor as gzFile -- added transparent reading of non-gziped files in gzread. -- fixed bug in gzread (don't read crc as data) -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). -- don't allocate big arrays in the stack (for MSDOS) -- fix some MSDOS compilation problems - -Changes in 0.5: -- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - not yet Z_FULL_FLUSH. -- support decompression but only in a single step (forced Z_FINISH) -- added opaque object for zalloc and zfree. -- added deflateReset and inflateReset -- added a variable zlib_version for consistency checking. -- renamed the 'filter' parameter of deflateInit2 as 'strategy'. - Added Z_FILTERED and Z_HUFFMAN_ONLY constants. - -Changes in 0.4: -- avoid "zip" everywhere, use zlib instead of ziplib. -- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - if compression method == 8. -- added adler32 and crc32 -- renamed deflateOptions as deflateInit2, call one or the other but not both -- added the method parameter for deflateInit2. -- added inflateInit2 -- simplied considerably deflateInit and inflateInit by not supporting - user-provided history buffer. This is supported only in deflateInit2 - and inflateInit2. - -Changes in 0.3: -- prefix all macro names with Z_ -- use Z_FINISH instead of deflateEnd to finish compression. -- added Z_HUFFMAN_ONLY -- added gzerror() diff --git a/common/zlib/FAQ b/common/zlib/FAQ deleted file mode 100644 index 99b7cf92e..000000000 --- a/common/zlib/FAQ +++ /dev/null @@ -1,368 +0,0 @@ - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://zlib.net/ which may have more recent information. -The lastest zlib FAQ is at http://zlib.net/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. See the - file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the - precompiled DLL are found in the zlib web site at http://zlib.net/ . - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://marknelson.us/1997/01/01/zlib-engine/ - * win32/DLL_FAQ.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR. - - Make sure that before the call of compress(), the length of the compressed - buffer is equal to the available size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR. - - Before making the call, make sure that avail_in and avail_out are not zero. - When setting the parameter flush equal to Z_FINISH, also make sure that - avail_out is big enough to allow processing all pending input. Note that a - Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be - made with more input or output space. A Z_BUF_ERROR may in fact be - unavoidable depending on how the functions are used, since it is not - possible to tell whether or not there is more output pending when - strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a - heavily annotated example. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h . Examples of zlib usage are in the files test/example.c - and test/minigzip.c, with more in examples/ . - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple package. - zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of zlib. - Please try to reproduce the problem with a small program and send the - corresponding source to us at zlib@gzip.org . Do not send multi-megabyte - data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - Not by itself, no. See the directory contrib/minizip in the zlib - distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - By default a shared (and a static) library is built for Unix. So: - - make distclean - ./configure - make - -14. How do I install a shared zlib library on Unix? - - After the above, then: - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to - it. You can check the version at the top of zlib.h or with the - ZLIB_VERSION symbol defined in zlib.h . - -15. I have a question about OttoPDF. - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site: Joel Hainley, jhainley@myndkryme.com. - -16. Can zlib decode Flate data in an Adobe PDF file? - - Yes. See http://www.pdflib.com/ . To modify PDF forms, see - http://sourceforge.net/projects/acroformtool/ . - -17. Why am I getting this "register_frame_info not found" error on Solaris? - - After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib - generates an error such as: - - ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: - symbol __register_frame_info: referenced symbol not found - - The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See - http://www.sunfreeware.com for Solaris versions of zlib and applications - using zlib. - -18. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip formats - use the same compressed data format internally, but have different headers - and trailers around the compressed data. - -19. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about a - single file, such as the name and last modification date. The zlib format - on the other hand was designed for in-memory and communication channel - applications, and has a much more compact header and trailer and uses a - faster integrity check than gzip. - -20. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode the - gzip format using inflateInit2(). Read zlib.h for more details. - -21. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's *Init* functions - allow for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -22. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -23. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -24. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -25. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -26. Will zlib work on a 64-bit machine? - - Yes. It has been tested on 64-bit machines, and has no dependence on any - data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to zlib@gzip.org - -27. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format than - does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -28. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically use - Z_FULL_FLUSH, carefully write all the pending data at those points, and - keep an index of those locations, then you can start decompression at those - points. You have to be careful to not use Z_FULL_FLUSH too often, since it - can significantly degrade compression. Alternatively, you can scan a - deflate stream once to generate an index, and then use that index for - random access. See examples/zran.c . - -29. Does zlib work on MVS, OS/390, CICS, etc.? - - It has in the past, but we have not heard of any recent evidence. There - were working ports of zlib 1.1.4 to MVS, but those links no longer work. - If you know of recent, successful applications of zlib on these operating - systems, please let us know. Thanks. - -30. Is there some simpler, easier to read version of inflate I can look at to - understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -31. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -32. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit only - if the compiler's "long" type is 32 bits. If the compiler's "long" type is - 64 bits, then the limit is 16 exabytes. - -33. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib is - compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of an 8K string space (or other value as set by - gzbuffer()), other than the caller of gzprintf() assuring that the output - will not exceed 8K. On the other hand, if zlib is compiled to use - snprintf() or vsnprintf(), which should normally be the case, then there is - no vulnerability. The ./configure script will display warnings if an - insecure variation of sprintf() will be used by gzprintf(). Also the - zlibCompileFlags() function will return information on what variant of - sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability, and versions - 1.2.1 and 1.2.2 were subject to an access exception when decompressing - invalid compressed data. - -34. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://zlib.net/ . - -35. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pedantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly as well as contradicted each other. So now, we simply - make sure that the code always works. - -36. Valgrind (or some similar memory access checker) says that deflate is - performing a conditional jump that depends on an uninitialized value. - Isn't that a bug? - - No. That is intentional for performance reasons, and the output of deflate - is not affected. This only started showing up recently since zlib 1.2.x - uses malloc() by default for allocations, whereas earlier versions used - calloc(), which zeros out the allocated memory. Even though the code was - correct, versions 1.2.4 and later was changed to not stimulate these - checkers. - -37. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -38. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very - weak and can be broken with freely available programs. To get strong - encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib - compression. For PKZIP compatible "encryption", look at - http://www.info-zip.org/ - -39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion with - the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specification in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -40. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. In - any case, the compression improvements are so modest compared to other more - modern approaches, that it's not worth the effort to implement. - -41. I'm having a problem with the zip functions in zlib, can you help? - - There are no zip functions in zlib. You are probably using minizip by - Giles Vollant, which is found in the contrib directory of zlib. It is not - part of zlib. In fact none of the stuff in contrib is part of zlib. The - files in there are not supported by the zlib authors. You need to contact - the authors of the respective contribution for help. - -42. The match.asm code in contrib is under the GNU General Public License. - Since it's part of zlib, doesn't that mean that all of zlib falls under the - GNU GPL? - - No. The files in contrib are not part of zlib. They were contributed by - other authors and are provided as a convenience to the user within the zlib - distribution. Each item in contrib has its own license. - -43. Is zlib subject to export controls? What is its ECCN? - - zlib is not subject to export controls, and so is classified as EAR99. - -44. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/common/zlib/Makefile b/common/zlib/Makefile deleted file mode 100644 index acc35bf42..000000000 --- a/common/zlib/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -MYSRCPATHS = ../../common/zlib -MYSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c -MYINCLUDES = -I../../common/zlib -MYCFLAGS = -MYDEFS = -DZ_SOLO -DNO_GZIP -DZLIB_PM3_TUNED -#-DDEBUG -Dverbose=1 - -LIB_A = libz.a - -include ../../Makefile.host diff --git a/common/zlib/README b/common/zlib/README deleted file mode 100644 index 51106de47..000000000 --- a/common/zlib/README +++ /dev/null @@ -1,115 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.11 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and -rfc1952 (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file test/example.c which also tests that -the library is working correctly. Another example is given in the file -test/minigzip.c. The compression library itself is composed of all source -files in the root directory. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile.in. In short "./configure; make test", and if that goes -well, "make install" should work for most flavors of Unix. For Windows, use -one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use -make_vms.com. - -Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. - -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available at -http://marknelson.us/1997/01/01/zlib-engine/ . - -The changes made in version 1.2.11 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory contrib/ . - -zlib is available in Java using the java.util.zip package, documented at -http://java.sun.com/developer/technicalArticles/Programming/compression/ . - -A Perl interface to zlib written by Paul Marquess is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . - -A Python interface to zlib written by A.M. Kuchling is -available in Python 1.5 and later versions, see -http://docs.python.org/library/zlib.html . - -zlib is built into tcl: http://wiki.tcl.tk/4610 . - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant , is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS or BEOS. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate and - zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; they - are too numerous to cite here. - -Copyright notice: - - (C) 1995-2017 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/common/zlib/README_proxmark3 b/common/zlib/README_proxmark3 deleted file mode 100644 index 0c7babf57..000000000 --- a/common/zlib/README_proxmark3 +++ /dev/null @@ -1,63 +0,0 @@ -This version of zlib is modified for use within the Proxmark3 project. -Files from the original distribution which are not required for this -purpose are not included. All modifications can easily be found -by searching for #ifdef ZLIB_PM3_TUNED and #ifndef ZLIB_PM3_TUNED. - -Current zlib base version is 1.2.11 - -ChangeLog for Proxmark3 project only ------------------------------------- - -Changes in 1.2.11.f-Proxmark3 (26 May 2015) -- port 1.2.11 upstream changes to 1.2.8.f-Proxmark3 - -Changes in 1.2.8.f-Proxmark3 (26 May 2015) -- disable decoding of fixed code blocks in deflate (eliminates the need - to store the fixed tree in RAM or ROM) -- disable generating fixed code blocks in inflate -- look harder for local optimum of consecutive matches and single literals - in inflate. -- stripped down version - unnecessary files from original distribution - are not included - -Notes on porting 1.2.11 upstream changes to 1.2.8.f-Proxmark3 -------------------------------------------------------------- - -mkdir zlib-1.2.8-stripped -for f in adler32.c ChangeLog deflate.c deflate.h FAQ inffast.c inffast.h inffixed.h inflate.c inflate.h inftrees.c inftrees.h README trees.c trees.h zconf.h zlib.h zutil.c zutil.h; do - cp zlib-1.2.8/$f zlib-1.2.8-stripped -done -# make style -find zlib-1.2.8-stripped -name "*.[ch]" \ - -exec perl -pi -e 's/[ \t]+$$//' {} \; \ - -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ - -exec sh -c "echo >> {}" \; \ - -exec astyle --formatted --mode=c --suffix=none \ - --indent=spaces=4 --indent-switches \ - --keep-one-line-blocks --max-instatement-indent=60 \ - --style=google --pad-oper --unpad-paren --pad-header \ - --align-pointer=name {} \; -diff -Naur zlib-1.2.8-stripped zlib > zlib-1.2.8-pm3.diff - -mkdir zlib-1.2.11-stripped -for f in adler32.c ChangeLog deflate.c deflate.h FAQ inffast.c inffast.h inffixed.h inflate.c inflate.h inftrees.c inftrees.h README trees.c trees.h zconf.h zlib.h zutil.c zutil.h; do - cp zlib-1.2.11/$f zlib-1.2.11-stripped -done -# make style -find zlib-1.2.11-stripped -name "*.[ch]" \ - -exec perl -pi -e 's/[ \t]+$$//' {} \; \ - -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ - -exec sh -c "echo >> {}" \; \ - -exec astyle --formatted --mode=c --suffix=none \ - --indent=spaces=4 --indent-switches \ - --keep-one-line-blocks --max-instatement-indent=60 \ - --style=google --pad-oper --unpad-paren --pad-header \ - --align-pointer=name {} \; - -diff -Naur zlib-1.2.8-stripped zlib-1.2.11-stripped > zlib-1.2.8-to-1.2.11.diff - -cd zlib -patch -p1 < ../zlib-1.2.8-to-1.2.11.diff -# fix .rej files manually... - -diff -Naur zlib-1.2.11-stripped zlib > zlib-1.2.11-pm3.diff diff --git a/common/zlib/adler32.c b/common/zlib/adler32.c deleted file mode 100644 index 962e1ee91..000000000 --- a/common/zlib/adler32.c +++ /dev/null @@ -1,187 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z(adler, buf, len) -uLong adler; -const Bytef *buf; -z_size_t len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) -uLong adler; -const Bytef *buf; -uInt len; -{ - return adler32_z(adler, buf, len); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) -uLong adler1; -uLong adler2; -z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) -uLong adler1; -uLong adler2; -z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) -uLong adler1; -uLong adler2; -z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - diff --git a/common/zlib/deflate.c b/common/zlib/deflate.c deleted file mode 100644 index a44bdb3ab..000000000 --- a/common/zlib/deflate.c +++ /dev/null @@ -1,2254 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = -#ifdef ZLIB_PM3_TUNED - " deflate 1.2.11.f-Proxmark3 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; -#else - " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; -#endif -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state(*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local int deflateStateCheck OF((z_streamp strm)); -local void slide_hash OF((deflate_state *s)); -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV -# pragma message("Assembler code may have bugs -- use at your own risk") -void match_init OF((void)); /* asm code initialization */ -uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef ZLIB_DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { - /* good lazy nice chain */ - /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ - /* 1 */ {4, 4, 8, 4, deflate_fast} -}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { - /* good lazy nice chain */ - /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ - /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ - /* 2 */ {4, 5, 16, 8, deflate_fast}, - /* 3 */ {4, 6, 32, 32, deflate_fast}, - - /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ - /* 5 */ {8, 16, 32, 32, deflate_slow}, - /* 6 */ {8, 16, 128, 128, deflate_slow}, - /* 7 */ {8, 32, 128, 256, deflate_slow}, - /* 8 */ {32, 128, 258, 1024, deflate_slow}, - /* 9 */ {32, 258, 258, 4096, deflate_slow} -}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive input - * characters, so that a running hash key can be computed from the previous - * key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to INSERT_STRING are made with consecutive input - * characters and the first MIN_MATCH bytes of str are valid (except for - * the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) {\ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); \ -} - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -local void slide_hash(s) -deflate_state *s; -{ - unsigned n, m; - Posf *p; - uInt wsize = s->w_size; - - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif -} - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) -z_streamp strm; -int level; -const char *version; -int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) -z_streamp strm; -int level; -int method; -int windowBits; -int memLevel; -int strategy; -const char *version; -int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - s->status = INIT_STATE; /* to pass state test in deflateReset() */ - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = (uInt)windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = (uInt)memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2 * sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush) + 2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush) + 2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd(strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize / sizeof(ush); - s->l_buf = s->pending_buf + (1 + sizeof(ush)) * s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -local int deflateStateCheck(strm) -z_streamp strm; -{ - deflate_state *s; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - s = strm->state; - if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && -#ifdef GZIP - s->status != GZIP_STATE && -#endif - s->status != EXTRA_STATE && - s->status != NAME_STATE && - s->status != COMMENT_STATE && - s->status != HCRC_STATE && - s->status != BUSY_STATE && - s->status != FINISH_STATE)) - return 1; - return 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; - - if (deflateStateCheck(strm) || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH - 1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH - 1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH - 1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH - 1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ - deflate_state *s; - uInt len; - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) - len = s->w_size; - if (dictionary != Z_NULL && len) - zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); - if (dictLength != Z_NULL) - *dictLength = len; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep(strm) -z_streamp strm; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = -#ifdef GZIP - s->wrap == 2 ? GZIP_STATE : -#endif - s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset(strm) -z_streamp strm; -{ - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - if (deflateStateCheck(strm) || strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending(strm, pending, bits) -unsigned *pending; -int *bits; -z_streamp strm; -{ - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - deflate_state *s; - int put; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) -z_streamp strm; -int level; -int strategy; -{ - deflate_state *s; - compress_func func; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - s->high_water) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_out == 0) - return Z_BUF_ERROR; - } - if (s->level != level) { - if (s->level == 0 && s->matches != 0) { - if (s->matches == 1) - slide_hash(s); - else - CLEAR_HASH(s); - s->matches = 0; - } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) -z_streamp strm; -int good_length; -int max_lazy; -int nice_length; -int max_chain; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = (uInt)good_length; - s->max_lazy_match = (uInt)max_lazy; - s->nice_match = nice_length; - s->max_chain_length = (uInt)max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) -z_streamp strm; -uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (deflateStateCheck(strm)) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; -#ifdef GZIP - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - Bytef *str; - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; -#endif - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB(s, b) -deflate_state *s; -uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -local void flush_pending(strm) -z_streamp strm; -{ - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* =========================================================================== - * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. - */ -#define HCRC_UPDATE(beg) \ - do { \ - if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ - } while (0) - -/* ========================================================================= */ -int ZEXPORT deflate(strm, flush) -z_streamp strm; -int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - old_flush = s->last_flush; - s->last_flush = flush; - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Write the header */ - if (s->status == INIT_STATE) { - /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#ifdef GZIP - if (s->status == GZIP_STATE) { - /* gzip header */ - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; - while (s->pending + left > s->pending_buf_size) { - uInt copy = s->pending_buf_size - s->pending; - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, copy); - s->pending = s->pending_buf_size; - HCRC_UPDATE(beg); - s->gzindex += copy; - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - left -= copy; - } - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, left); - s->pending += left; - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - } - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) { - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - } - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#endif - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char *)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd(strm) -z_streamp strm; -{ - int status; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - - status = strm->state->status; - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (deflateStateCheck(source) || dest == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2 * sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush) + 2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd(dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize / sizeof(ush); - ds->l_buf = ds->pending_buf + (1 + sizeof(ush)) * ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(strm, buf, size) -z_streamp strm; -Bytef *buf; -unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(s) -deflate_state *s; -{ - s->window_size = (ulg)2L * s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH - 1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) -deflate_state *s; -IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ -#ifdef ZLIB_PM3_TUNED - int best_len = MIN_MATCH - 1; /* lift the restriction on prev-length */ -#else - int best_len = (int)s->prev_length; /* best match length so far */ -#endif - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf *)scan; - register ush scan_end = *(ushf *)(scan + best_len - 1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len - 1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf *)(match + best_len - 1) != scan_end || - *(ushf *)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf *)(scan += 2) == *(ushf *)(match += 2) && - *(ushf *)(scan += 2) == *(ushf *)(match += 2) && - *(ushf *)(scan += 2) == *(ushf *)(match += 2) && - *(ushf *)(scan += 2) == *(ushf *)(match += 2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend - scan); - scan = strend - (MAX_MATCH - 1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len - 1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf *)(scan + best_len - 1); -#else - scan_end1 = scan[best_len - 1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) -deflate_state *s; -IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH - 1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef ZLIB_DEBUG - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) -deflate_state *s; -IPos start, match; -int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr, "\\[%d,%d]", start - match, length); - do { putc(s->window[start++], stderr); } - while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* ZLIB_DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) -deflate_state *s; -{ - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size - (ulg)s->lookahead - (ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize + MAX_DIST(s)) { - - zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH - 3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH - 1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* Maximum stored block length in deflate format (not including header). */ -#define MAX_STORED 65535 - -/* Minimum of a and b. */ -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ -local block_state deflate_stored(s, flush) -deflate_state *s; -int flush; -{ - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - unsigned len, left, have, last = 0; - unsigned used = s->strm->avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = MAX_STORED; /* maximum deflate stored block length */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - if (s->strm->avail_out < have) /* need room for header */ - break; - /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out - have; - left = s->strstart - s->block_start; /* bytes left in window */ - if (len > (ulg)left + s->strm->avail_in) - len = left + s->strm->avail_in; /* limit len to the input */ - if (len > have) - len = have; /* limit len to the output */ - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len == 0 && flush != Z_FINISH) || - flush == Z_NO_FLUSH || - len != left + s->strm->avail_in)) - break; - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; - _tr_stored_block(s, (char *)0, 0L, last); - - /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s->strm); - -#ifdef ZLIB_DEBUG - /* Update debugging counts for the data about to be copied. */ - s->compressed_len += len << 3; - s->bits_sent += len << 3; -#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) - left = len; - zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s->strm->next_out += left; - s->strm->avail_out -= left; - s->strm->total_out += left; - s->block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s->strm, s->strm->next_out, len); - s->strm->next_out += len; - s->strm->avail_out -= len; - s->strm->total_out += len; - } - } while (last == 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s->strm->avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s->w_size) { /* supplant the previous history */ - s->matches = 2; /* clear hash */ - zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s->strstart = s->w_size; - } else { - if (s->window_size - s->strstart <= used) { - /* Slide the window down. */ - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - } - zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s->strstart += used; - } - s->block_start = s->strstart; - s->insert += MIN(used, s->w_size - s->insert); - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* If the last block was written to next_out, then done. */ - if (last) - return finish_done; - - /* If flushing and all input has been consumed, then done. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH && - s->strm->avail_in == 0 && (long)s->strstart == s->block_start) - return block_done; - - /* Fill the window with any remaining input. */ - have = s->window_size - s->strstart - 1; - if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { - /* Slide the window down. */ - s->block_start -= s->w_size; - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - have += s->w_size; /* more space now */ - } - if (have > s->strm->avail_in) - have = s->strm->avail_in; - if (have) { - read_buf(s->strm, s->window + s->strstart, have); - s->strstart += have; - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = MIN(s->pending_buf_size - have, MAX_STORED); - min_block = MIN(have, s->w_size); - left = s->strstart - s->block_start; - if (left >= min_block || - ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && - s->strm->avail_in == 0 && left <= have)) { - len = MIN(left, have); - last = flush == Z_FINISH && s->strm->avail_in == 0 && - len == left ? 1 : 0; - _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); - s->block_start += len; - flush_pending(s->strm); - } - - /* We've done all we can with the available input and output. */ - return last ? finish_started : need_more; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) -deflate_state *s; -int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH - 3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr, "%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH - 1 ? s->strstart : MIN_MATCH - 1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - - -#ifdef ZLIB_PM3_TUNED -local uInt try_harder(s, strstart, lookahead, hash_head) -deflate_state *s; -uInt strstart; -uInt lookahead; -IPos hash_head; -{ - uInt strstart_save = s->strstart; - s->strstart = strstart; - uInt lookahead_save = s->lookahead; - s->lookahead = lookahead; - uInt ins_h_save = s->ins_h; - uInt combined_gain; - uInt best_combined_gain = 0; - uInt match_length; - uInt prev_length = s->prev_length < MIN_MATCH ? 1 : s->prev_length; - uInt best_prev_length = prev_length; - uInt current_match_start = s->match_start; - uInt current_match_length = s->match_length; - - do { - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } else { - match_length = MIN_MATCH - 1; - } -#if TOO_FAR <= 32767 - if (match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) { - match_length = MIN_MATCH - 1; - } -#endif - if (s->strstart == strstart) { // store match at current position - current_match_length = match_length; - current_match_start = s->match_start; - } - if (s->strstart - strstart + 1 < MIN_MATCH) { // previous match reduced to one or two literals - combined_gain = 0; // need one literal per byte: no gain (assuming 8 bits per literal) - } else { - combined_gain = s->strstart - strstart + 1 - MIN_MATCH; // (possibly truncated) previous_length - 3 literals - } - if (match_length < MIN_MATCH) { - combined_gain += 0; // no gain - } else { - combined_gain += match_length - MIN_MATCH; // match_length bytes are coded as three literals - } - if (combined_gain >= best_combined_gain) { // in case of a tie we prefer the longer prev_length - best_combined_gain = combined_gain; - best_prev_length = s->strstart - strstart + 1; - } - s->strstart++; - s->lookahead--; - UPDATE_HASH(s, s->ins_h, s->window[(s->strstart) + (MIN_MATCH - 1)]); - hash_head = s->head[s->ins_h]; - } while (s->strstart <= strstart - 1 + prev_length // try to truncate the previous match to 1, 3, ... prev_length - && s->strstart <= s->window_size - MIN_LOOKAHEAD); // watch out for the end of the input - - s->strstart = strstart_save; - s->lookahead = lookahead_save; - s->ins_h = ins_h_save; - s->match_length = current_match_length; - s->match_start = current_match_start; - if (best_prev_length >= MIN_MATCH) { - s->prev_length = best_prev_length; - s->match_length = MIN_MATCH - 1; - } else { - s->prev_length = MIN_MATCH - 1; - } - return best_combined_gain; -} -#endif - - - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) -deflate_state *s; -int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH - 1; - -#ifdef ZLIB_PM3_TUNED - if (s->prev_length < s->max_lazy_match) { - try_harder(s, s->strstart, s->lookahead, hash_head); - } - -#else - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH - 1; - } - } -#endif /* ZLIB_PM3_TUNED */ - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart - 1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart - 1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length - 1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH - 1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr, "%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert(flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr, "%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH - 1 ? s->strstart : MIN_MATCH - 1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) -deflate_state *s; -int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (uInt)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window + (uInt)(s->window_size - 1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr, "%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) -deflate_state *s; -int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr, "%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - diff --git a/common/zlib/deflate.h b/common/zlib/deflate.h deleted file mode 100644 index 10956218e..000000000 --- a/common/zlib/deflate.h +++ /dev/null @@ -1,350 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2016 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ -#ifdef GZIP -# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ -#endif -#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ -#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ -#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ -#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ -#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ -#define FINISH_STATE 666 /* stream complete */ -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - const static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - ulg pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - ulg gzindex; /* where in extra, name, or comment */ - Byte method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2 * D_CODES + 1]; /* distance tree */ - struct ct_data_s bl_tree[2 * BL_CODES + 1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS + 1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2 * L_CODES + 1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2 * L_CODES + 1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef ZLIB_DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - -/* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef ZLIB_DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) -extern uch ZLIB_INTERNAL _length_code[]; -extern uch ZLIB_INTERNAL _dist_code[]; -#else -extern const uch ZLIB_INTERNAL _length_code[]; -extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ - diff --git a/common/zlib/inffast.c b/common/zlib/inffast.c deleted file mode 100644 index 874ecc02c..000000000 --- a/common/zlib/inffast.c +++ /dev/null @@ -1,315 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") -#else - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode[hold & lmask]; -dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - *out++ = (unsigned char)(here.val); - } else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode[hold & dmask]; -dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ - diff --git a/common/zlib/inffast.h b/common/zlib/inffast.h deleted file mode 100644 index 131f157a1..000000000 --- a/common/zlib/inffast.h +++ /dev/null @@ -1,12 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); - diff --git a/common/zlib/inffixed.h b/common/zlib/inffixed.h deleted file mode 100644 index fec0606fd..000000000 --- a/common/zlib/inffixed.h +++ /dev/null @@ -1,95 +0,0 @@ -/* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - -/* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - -static const code lenfix[512] = { - {96, 7, 0}, {0, 8, 80}, {0, 8, 16}, {20, 8, 115}, {18, 7, 31}, {0, 8, 112}, {0, 8, 48}, - {0, 9, 192}, {16, 7, 10}, {0, 8, 96}, {0, 8, 32}, {0, 9, 160}, {0, 8, 0}, {0, 8, 128}, - {0, 8, 64}, {0, 9, 224}, {16, 7, 6}, {0, 8, 88}, {0, 8, 24}, {0, 9, 144}, {19, 7, 59}, - {0, 8, 120}, {0, 8, 56}, {0, 9, 208}, {17, 7, 17}, {0, 8, 104}, {0, 8, 40}, {0, 9, 176}, - {0, 8, 8}, {0, 8, 136}, {0, 8, 72}, {0, 9, 240}, {16, 7, 4}, {0, 8, 84}, {0, 8, 20}, - {21, 8, 227}, {19, 7, 43}, {0, 8, 116}, {0, 8, 52}, {0, 9, 200}, {17, 7, 13}, {0, 8, 100}, - {0, 8, 36}, {0, 9, 168}, {0, 8, 4}, {0, 8, 132}, {0, 8, 68}, {0, 9, 232}, {16, 7, 8}, - {0, 8, 92}, {0, 8, 28}, {0, 9, 152}, {20, 7, 83}, {0, 8, 124}, {0, 8, 60}, {0, 9, 216}, - {18, 7, 23}, {0, 8, 108}, {0, 8, 44}, {0, 9, 184}, {0, 8, 12}, {0, 8, 140}, {0, 8, 76}, - {0, 9, 248}, {16, 7, 3}, {0, 8, 82}, {0, 8, 18}, {21, 8, 163}, {19, 7, 35}, {0, 8, 114}, - {0, 8, 50}, {0, 9, 196}, {17, 7, 11}, {0, 8, 98}, {0, 8, 34}, {0, 9, 164}, {0, 8, 2}, - {0, 8, 130}, {0, 8, 66}, {0, 9, 228}, {16, 7, 7}, {0, 8, 90}, {0, 8, 26}, {0, 9, 148}, - {20, 7, 67}, {0, 8, 122}, {0, 8, 58}, {0, 9, 212}, {18, 7, 19}, {0, 8, 106}, {0, 8, 42}, - {0, 9, 180}, {0, 8, 10}, {0, 8, 138}, {0, 8, 74}, {0, 9, 244}, {16, 7, 5}, {0, 8, 86}, - {0, 8, 22}, {64, 8, 0}, {19, 7, 51}, {0, 8, 118}, {0, 8, 54}, {0, 9, 204}, {17, 7, 15}, - {0, 8, 102}, {0, 8, 38}, {0, 9, 172}, {0, 8, 6}, {0, 8, 134}, {0, 8, 70}, {0, 9, 236}, - {16, 7, 9}, {0, 8, 94}, {0, 8, 30}, {0, 9, 156}, {20, 7, 99}, {0, 8, 126}, {0, 8, 62}, - {0, 9, 220}, {18, 7, 27}, {0, 8, 110}, {0, 8, 46}, {0, 9, 188}, {0, 8, 14}, {0, 8, 142}, - {0, 8, 78}, {0, 9, 252}, {96, 7, 0}, {0, 8, 81}, {0, 8, 17}, {21, 8, 131}, {18, 7, 31}, - {0, 8, 113}, {0, 8, 49}, {0, 9, 194}, {16, 7, 10}, {0, 8, 97}, {0, 8, 33}, {0, 9, 162}, - {0, 8, 1}, {0, 8, 129}, {0, 8, 65}, {0, 9, 226}, {16, 7, 6}, {0, 8, 89}, {0, 8, 25}, - {0, 9, 146}, {19, 7, 59}, {0, 8, 121}, {0, 8, 57}, {0, 9, 210}, {17, 7, 17}, {0, 8, 105}, - {0, 8, 41}, {0, 9, 178}, {0, 8, 9}, {0, 8, 137}, {0, 8, 73}, {0, 9, 242}, {16, 7, 4}, - {0, 8, 85}, {0, 8, 21}, {16, 8, 258}, {19, 7, 43}, {0, 8, 117}, {0, 8, 53}, {0, 9, 202}, - {17, 7, 13}, {0, 8, 101}, {0, 8, 37}, {0, 9, 170}, {0, 8, 5}, {0, 8, 133}, {0, 8, 69}, - {0, 9, 234}, {16, 7, 8}, {0, 8, 93}, {0, 8, 29}, {0, 9, 154}, {20, 7, 83}, {0, 8, 125}, - {0, 8, 61}, {0, 9, 218}, {18, 7, 23}, {0, 8, 109}, {0, 8, 45}, {0, 9, 186}, {0, 8, 13}, - {0, 8, 141}, {0, 8, 77}, {0, 9, 250}, {16, 7, 3}, {0, 8, 83}, {0, 8, 19}, {21, 8, 195}, - {19, 7, 35}, {0, 8, 115}, {0, 8, 51}, {0, 9, 198}, {17, 7, 11}, {0, 8, 99}, {0, 8, 35}, - {0, 9, 166}, {0, 8, 3}, {0, 8, 131}, {0, 8, 67}, {0, 9, 230}, {16, 7, 7}, {0, 8, 91}, - {0, 8, 27}, {0, 9, 150}, {20, 7, 67}, {0, 8, 123}, {0, 8, 59}, {0, 9, 214}, {18, 7, 19}, - {0, 8, 107}, {0, 8, 43}, {0, 9, 182}, {0, 8, 11}, {0, 8, 139}, {0, 8, 75}, {0, 9, 246}, - {16, 7, 5}, {0, 8, 87}, {0, 8, 23}, {64, 8, 0}, {19, 7, 51}, {0, 8, 119}, {0, 8, 55}, - {0, 9, 206}, {17, 7, 15}, {0, 8, 103}, {0, 8, 39}, {0, 9, 174}, {0, 8, 7}, {0, 8, 135}, - {0, 8, 71}, {0, 9, 238}, {16, 7, 9}, {0, 8, 95}, {0, 8, 31}, {0, 9, 158}, {20, 7, 99}, - {0, 8, 127}, {0, 8, 63}, {0, 9, 222}, {18, 7, 27}, {0, 8, 111}, {0, 8, 47}, {0, 9, 190}, - {0, 8, 15}, {0, 8, 143}, {0, 8, 79}, {0, 9, 254}, {96, 7, 0}, {0, 8, 80}, {0, 8, 16}, - {20, 8, 115}, {18, 7, 31}, {0, 8, 112}, {0, 8, 48}, {0, 9, 193}, {16, 7, 10}, {0, 8, 96}, - {0, 8, 32}, {0, 9, 161}, {0, 8, 0}, {0, 8, 128}, {0, 8, 64}, {0, 9, 225}, {16, 7, 6}, - {0, 8, 88}, {0, 8, 24}, {0, 9, 145}, {19, 7, 59}, {0, 8, 120}, {0, 8, 56}, {0, 9, 209}, - {17, 7, 17}, {0, 8, 104}, {0, 8, 40}, {0, 9, 177}, {0, 8, 8}, {0, 8, 136}, {0, 8, 72}, - {0, 9, 241}, {16, 7, 4}, {0, 8, 84}, {0, 8, 20}, {21, 8, 227}, {19, 7, 43}, {0, 8, 116}, - {0, 8, 52}, {0, 9, 201}, {17, 7, 13}, {0, 8, 100}, {0, 8, 36}, {0, 9, 169}, {0, 8, 4}, - {0, 8, 132}, {0, 8, 68}, {0, 9, 233}, {16, 7, 8}, {0, 8, 92}, {0, 8, 28}, {0, 9, 153}, - {20, 7, 83}, {0, 8, 124}, {0, 8, 60}, {0, 9, 217}, {18, 7, 23}, {0, 8, 108}, {0, 8, 44}, - {0, 9, 185}, {0, 8, 12}, {0, 8, 140}, {0, 8, 76}, {0, 9, 249}, {16, 7, 3}, {0, 8, 82}, - {0, 8, 18}, {21, 8, 163}, {19, 7, 35}, {0, 8, 114}, {0, 8, 50}, {0, 9, 197}, {17, 7, 11}, - {0, 8, 98}, {0, 8, 34}, {0, 9, 165}, {0, 8, 2}, {0, 8, 130}, {0, 8, 66}, {0, 9, 229}, - {16, 7, 7}, {0, 8, 90}, {0, 8, 26}, {0, 9, 149}, {20, 7, 67}, {0, 8, 122}, {0, 8, 58}, - {0, 9, 213}, {18, 7, 19}, {0, 8, 106}, {0, 8, 42}, {0, 9, 181}, {0, 8, 10}, {0, 8, 138}, - {0, 8, 74}, {0, 9, 245}, {16, 7, 5}, {0, 8, 86}, {0, 8, 22}, {64, 8, 0}, {19, 7, 51}, - {0, 8, 118}, {0, 8, 54}, {0, 9, 205}, {17, 7, 15}, {0, 8, 102}, {0, 8, 38}, {0, 9, 173}, - {0, 8, 6}, {0, 8, 134}, {0, 8, 70}, {0, 9, 237}, {16, 7, 9}, {0, 8, 94}, {0, 8, 30}, - {0, 9, 157}, {20, 7, 99}, {0, 8, 126}, {0, 8, 62}, {0, 9, 221}, {18, 7, 27}, {0, 8, 110}, - {0, 8, 46}, {0, 9, 189}, {0, 8, 14}, {0, 8, 142}, {0, 8, 78}, {0, 9, 253}, {96, 7, 0}, - {0, 8, 81}, {0, 8, 17}, {21, 8, 131}, {18, 7, 31}, {0, 8, 113}, {0, 8, 49}, {0, 9, 195}, - {16, 7, 10}, {0, 8, 97}, {0, 8, 33}, {0, 9, 163}, {0, 8, 1}, {0, 8, 129}, {0, 8, 65}, - {0, 9, 227}, {16, 7, 6}, {0, 8, 89}, {0, 8, 25}, {0, 9, 147}, {19, 7, 59}, {0, 8, 121}, - {0, 8, 57}, {0, 9, 211}, {17, 7, 17}, {0, 8, 105}, {0, 8, 41}, {0, 9, 179}, {0, 8, 9}, - {0, 8, 137}, {0, 8, 73}, {0, 9, 243}, {16, 7, 4}, {0, 8, 85}, {0, 8, 21}, {16, 8, 258}, - {19, 7, 43}, {0, 8, 117}, {0, 8, 53}, {0, 9, 203}, {17, 7, 13}, {0, 8, 101}, {0, 8, 37}, - {0, 9, 171}, {0, 8, 5}, {0, 8, 133}, {0, 8, 69}, {0, 9, 235}, {16, 7, 8}, {0, 8, 93}, - {0, 8, 29}, {0, 9, 155}, {20, 7, 83}, {0, 8, 125}, {0, 8, 61}, {0, 9, 219}, {18, 7, 23}, - {0, 8, 109}, {0, 8, 45}, {0, 9, 187}, {0, 8, 13}, {0, 8, 141}, {0, 8, 77}, {0, 9, 251}, - {16, 7, 3}, {0, 8, 83}, {0, 8, 19}, {21, 8, 195}, {19, 7, 35}, {0, 8, 115}, {0, 8, 51}, - {0, 9, 199}, {17, 7, 11}, {0, 8, 99}, {0, 8, 35}, {0, 9, 167}, {0, 8, 3}, {0, 8, 131}, - {0, 8, 67}, {0, 9, 231}, {16, 7, 7}, {0, 8, 91}, {0, 8, 27}, {0, 9, 151}, {20, 7, 67}, - {0, 8, 123}, {0, 8, 59}, {0, 9, 215}, {18, 7, 19}, {0, 8, 107}, {0, 8, 43}, {0, 9, 183}, - {0, 8, 11}, {0, 8, 139}, {0, 8, 75}, {0, 9, 247}, {16, 7, 5}, {0, 8, 87}, {0, 8, 23}, - {64, 8, 0}, {19, 7, 51}, {0, 8, 119}, {0, 8, 55}, {0, 9, 207}, {17, 7, 15}, {0, 8, 103}, - {0, 8, 39}, {0, 9, 175}, {0, 8, 7}, {0, 8, 135}, {0, 8, 71}, {0, 9, 239}, {16, 7, 9}, - {0, 8, 95}, {0, 8, 31}, {0, 9, 159}, {20, 7, 99}, {0, 8, 127}, {0, 8, 63}, {0, 9, 223}, - {18, 7, 27}, {0, 8, 111}, {0, 8, 47}, {0, 9, 191}, {0, 8, 15}, {0, 8, 143}, {0, 8, 79}, - {0, 9, 255} -}; - -static const code distfix[32] = { - {16, 5, 1}, {23, 5, 257}, {19, 5, 17}, {27, 5, 4097}, {17, 5, 5}, {25, 5, 1025}, - {21, 5, 65}, {29, 5, 16385}, {16, 5, 3}, {24, 5, 513}, {20, 5, 33}, {28, 5, 8193}, - {18, 5, 9}, {26, 5, 2049}, {22, 5, 129}, {64, 5, 0}, {16, 5, 2}, {23, 5, 385}, - {19, 5, 25}, {27, 5, 6145}, {17, 5, 7}, {25, 5, 1537}, {21, 5, 97}, {29, 5, 24577}, - {16, 5, 4}, {24, 5, 769}, {20, 5, 49}, {28, 5, 12289}, {18, 5, 13}, {26, 5, 3073}, - {22, 5, 193}, {64, 5, 0} -}; - diff --git a/common/zlib/inflate.c b/common/zlib/inflate.c deleted file mode 100644 index 753671080..000000000 --- a/common/zlib/inflate.c +++ /dev/null @@ -1,1561 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -#ifdef ZLIB_PM3_TUNED -extern void Dbprintf(const char *fmt, ...); -#else -local void fixedtables OF((struct inflate_state FAR *state)); -#endif -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED -void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -#ifndef ZLIB_PM3_TUNED -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() { - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ -#endif /* ZLIB_PM3_TUNED */ -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - } else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ -#ifdef ZLIB_PM3_TUNED - strm->msg = (char *)"fixed block coding not supported"; - state->mode = BAD; -#else - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } -#endif - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ -inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long dictid; - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; - out = strm->total_out; - inflateReset(strm); - strm->total_in = in; - strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long) - 1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} diff --git a/common/zlib/inflate.h b/common/zlib/inflate.h deleted file mode 100644 index f91e0aa78..000000000 --- a/common/zlib/inflate.h +++ /dev/null @@ -1,130 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ -#ifdef GUNZIP - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ -#endif - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ -#ifdef GUNZIP - LENGTH, /* i: waiting for 32-bit length (gzip) */ -#endif - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; - diff --git a/common/zlib/inftrees.c b/common/zlib/inftrees.c deleted file mode 100644 index 3dae7e534..000000000 --- a/common/zlib/inftrees.c +++ /dev/null @@ -1,306 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = -#ifdef ZLIB_PM3_TUNED - " inflate 1.2.11.f-Proxmark3 Copyright 1995-2017 Mark Adler "; -#else - " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; -#endif -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, - unsigned codes, code FAR *FAR *table, - unsigned FAR *bits, unsigned short FAR *work) { - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS + 1]; /* number of codes of each length */ - unsigned short offs[MAXBITS + 1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - }; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202 - }; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 - }; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 - }; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - case DISTS: - default: - base = dbase; - extra = dext; - match = 0; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} - diff --git a/common/zlib/inftrees.h b/common/zlib/inftrees.h deleted file mode 100644 index 33584c58d..000000000 --- a/common/zlib/inftrees.h +++ /dev/null @@ -1,63 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR *FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); - diff --git a/common/zlib/trees.c b/common/zlib/trees.c deleted file mode 100644 index 1ef49d00d..000000000 --- a/common/zlib/trees.c +++ /dev/null @@ -1,1222 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2017 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef ZLIB_DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; - -local const uch bl_order[BL_CODES] - = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES + 2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH - MIN_MATCH + 1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local const static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS}; - -local const static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local const static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef ZLIB_DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) -/* Send a code of the given tree. c and tree must not have side effects */ - -#else /* !ZLIB_DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef ZLIB_DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) -deflate_state *s; -int value; /* value to send */ -int length; /* number of bits */ -{ - Tracevv((stderr, " l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !ZLIB_DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = (int)value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* ZLIB_DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() { -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS + 1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES - 1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = (uch)code; - } - } - Assert(length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = (uch)code; - } - } - Assert(dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert(dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() { - FILE *header = fopen("trees.h", "w"); - int i; - - Assert(header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES + 2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES + 1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES - 1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN - 1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH - MIN_MATCH + 1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH - MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES - 1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES - 1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) -deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) -deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) -deflate_state *s; -ct_data *tree; /* the tree to restore */ -int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) -deflate_state *s; -tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n - base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (unsigned)(bits + xbits); - if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); - } - if (overflow == 0) return; - - Tracev((stderr, "\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Tracev((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(tree, max_code, bl_count) -ct_data *tree; /* the tree to decorate */ -int max_code; /* largest code with non zero frequency */ -ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS + 1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert(code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); - Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = (ush)bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(s, desc) -deflate_state *s; -tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; - if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len / 2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree(s, tree, max_code) -deflate_state *s; -ct_data *tree; /* the tree to be scanned */ -int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code + 1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; - prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree(s, tree, max_code) -deflate_state *s; -ct_data *tree; /* the tree to be scanned */ -int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } - while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); - count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); - send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); - send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); - send_bits(s, count - 11, 7); - } - count = 0; - prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) -deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3 * ((ulg)max_blindex + 1) + 5 + 5 + 4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) -deflate_state *s; -int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) -deflate_state *s; -charf *buf; /* input block */ -ulg stored_len; /* length of input block */ -int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK << 1) + last, 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, (ush)stored_len); - put_short(s, (ush)~stored_len); - zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); - s->pending += stored_len; -#ifdef ZLIB_DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - s->bits_sent += 2 * 16; - s->bits_sent += stored_len << 3; -#endif -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(s) -deflate_state *s; -{ - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(s) -deflate_state *s; -{ - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef ZLIB_DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) -deflate_state *s; -charf *buf; /* input block, or NULL if too old */ -ulg stored_len; /* length of input block */ -int last; /* one if this is the last block for a file */ -{ -#ifdef ZLIB_PM3_TUNED - (void) buf; - (void) stored_len; -#endif - int max_blindex = 0; /* index of last bit length code of non zero freq */ -#ifndef ZLIB_PM3_TUNED - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { -#endif - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - -#ifndef ZLIB_PM3_TUNED - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len + 3 + 7) >> 3; - static_lenb = (s->static_len + 3 + 7) >> 3; - - Tracev((stderr, "\nopt %" PRIu32 "(%" PRIu32 ") stat %" PRIu32 "(%" PRIu32 ") stored %" PRIu32 " lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char *)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char *)0) { /* force stored block */ -#else - if (stored_len + 4 <= opt_lenb && buf != (char *)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES << 1) + last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { -#endif /* !ZLIB_PM3_TUNED */ - send_bits(s, (DYN_TREES << 1) + last, 3); - send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, - max_blindex + 1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->opt_len; -#endif -#ifndef ZLIB_PM3_TUNED - } -#endif - Assert(s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef ZLIB_DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len >> 3, - s->compressed_len - 7 * last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally(s, dist, lc) -deflate_state *s; -unsigned dist; /* distance of matched string */ -unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH - MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit * 8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L + extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr, "\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length * 100L / in_length)); - if (s->matches < s->last_lit / 2 && out_length < in_length / 2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize - 1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) -deflate_state *s; -const ct_data *ltree; /* literal tree */ -const ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert(code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2 * lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) -deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) -unsigned code; /* the value to invert */ -int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) -deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) -deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~7; -#endif -} - diff --git a/common/zlib/trees.h b/common/zlib/trees.h deleted file mode 100644 index 74383d7c2..000000000 --- a/common/zlib/trees.h +++ /dev/null @@ -1,129 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES + 2] = { - {{ 12}, { 8}}, {{140}, { 8}}, {{ 76}, { 8}}, {{204}, { 8}}, {{ 44}, { 8}}, - {{172}, { 8}}, {{108}, { 8}}, {{236}, { 8}}, {{ 28}, { 8}}, {{156}, { 8}}, - {{ 92}, { 8}}, {{220}, { 8}}, {{ 60}, { 8}}, {{188}, { 8}}, {{124}, { 8}}, - {{252}, { 8}}, {{ 2}, { 8}}, {{130}, { 8}}, {{ 66}, { 8}}, {{194}, { 8}}, - {{ 34}, { 8}}, {{162}, { 8}}, {{ 98}, { 8}}, {{226}, { 8}}, {{ 18}, { 8}}, - {{146}, { 8}}, {{ 82}, { 8}}, {{210}, { 8}}, {{ 50}, { 8}}, {{178}, { 8}}, - {{114}, { 8}}, {{242}, { 8}}, {{ 10}, { 8}}, {{138}, { 8}}, {{ 74}, { 8}}, - {{202}, { 8}}, {{ 42}, { 8}}, {{170}, { 8}}, {{106}, { 8}}, {{234}, { 8}}, - {{ 26}, { 8}}, {{154}, { 8}}, {{ 90}, { 8}}, {{218}, { 8}}, {{ 58}, { 8}}, - {{186}, { 8}}, {{122}, { 8}}, {{250}, { 8}}, {{ 6}, { 8}}, {{134}, { 8}}, - {{ 70}, { 8}}, {{198}, { 8}}, {{ 38}, { 8}}, {{166}, { 8}}, {{102}, { 8}}, - {{230}, { 8}}, {{ 22}, { 8}}, {{150}, { 8}}, {{ 86}, { 8}}, {{214}, { 8}}, - {{ 54}, { 8}}, {{182}, { 8}}, {{118}, { 8}}, {{246}, { 8}}, {{ 14}, { 8}}, - {{142}, { 8}}, {{ 78}, { 8}}, {{206}, { 8}}, {{ 46}, { 8}}, {{174}, { 8}}, - {{110}, { 8}}, {{238}, { 8}}, {{ 30}, { 8}}, {{158}, { 8}}, {{ 94}, { 8}}, - {{222}, { 8}}, {{ 62}, { 8}}, {{190}, { 8}}, {{126}, { 8}}, {{254}, { 8}}, - {{ 1}, { 8}}, {{129}, { 8}}, {{ 65}, { 8}}, {{193}, { 8}}, {{ 33}, { 8}}, - {{161}, { 8}}, {{ 97}, { 8}}, {{225}, { 8}}, {{ 17}, { 8}}, {{145}, { 8}}, - {{ 81}, { 8}}, {{209}, { 8}}, {{ 49}, { 8}}, {{177}, { 8}}, {{113}, { 8}}, - {{241}, { 8}}, {{ 9}, { 8}}, {{137}, { 8}}, {{ 73}, { 8}}, {{201}, { 8}}, - {{ 41}, { 8}}, {{169}, { 8}}, {{105}, { 8}}, {{233}, { 8}}, {{ 25}, { 8}}, - {{153}, { 8}}, {{ 89}, { 8}}, {{217}, { 8}}, {{ 57}, { 8}}, {{185}, { 8}}, - {{121}, { 8}}, {{249}, { 8}}, {{ 5}, { 8}}, {{133}, { 8}}, {{ 69}, { 8}}, - {{197}, { 8}}, {{ 37}, { 8}}, {{165}, { 8}}, {{101}, { 8}}, {{229}, { 8}}, - {{ 21}, { 8}}, {{149}, { 8}}, {{ 85}, { 8}}, {{213}, { 8}}, {{ 53}, { 8}}, - {{181}, { 8}}, {{117}, { 8}}, {{245}, { 8}}, {{ 13}, { 8}}, {{141}, { 8}}, - {{ 77}, { 8}}, {{205}, { 8}}, {{ 45}, { 8}}, {{173}, { 8}}, {{109}, { 8}}, - {{237}, { 8}}, {{ 29}, { 8}}, {{157}, { 8}}, {{ 93}, { 8}}, {{221}, { 8}}, - {{ 61}, { 8}}, {{189}, { 8}}, {{125}, { 8}}, {{253}, { 8}}, {{ 19}, { 9}}, - {{275}, { 9}}, {{147}, { 9}}, {{403}, { 9}}, {{ 83}, { 9}}, {{339}, { 9}}, - {{211}, { 9}}, {{467}, { 9}}, {{ 51}, { 9}}, {{307}, { 9}}, {{179}, { 9}}, - {{435}, { 9}}, {{115}, { 9}}, {{371}, { 9}}, {{243}, { 9}}, {{499}, { 9}}, - {{ 11}, { 9}}, {{267}, { 9}}, {{139}, { 9}}, {{395}, { 9}}, {{ 75}, { 9}}, - {{331}, { 9}}, {{203}, { 9}}, {{459}, { 9}}, {{ 43}, { 9}}, {{299}, { 9}}, - {{171}, { 9}}, {{427}, { 9}}, {{107}, { 9}}, {{363}, { 9}}, {{235}, { 9}}, - {{491}, { 9}}, {{ 27}, { 9}}, {{283}, { 9}}, {{155}, { 9}}, {{411}, { 9}}, - {{ 91}, { 9}}, {{347}, { 9}}, {{219}, { 9}}, {{475}, { 9}}, {{ 59}, { 9}}, - {{315}, { 9}}, {{187}, { 9}}, {{443}, { 9}}, {{123}, { 9}}, {{379}, { 9}}, - {{251}, { 9}}, {{507}, { 9}}, {{ 7}, { 9}}, {{263}, { 9}}, {{135}, { 9}}, - {{391}, { 9}}, {{ 71}, { 9}}, {{327}, { 9}}, {{199}, { 9}}, {{455}, { 9}}, - {{ 39}, { 9}}, {{295}, { 9}}, {{167}, { 9}}, {{423}, { 9}}, {{103}, { 9}}, - {{359}, { 9}}, {{231}, { 9}}, {{487}, { 9}}, {{ 23}, { 9}}, {{279}, { 9}}, - {{151}, { 9}}, {{407}, { 9}}, {{ 87}, { 9}}, {{343}, { 9}}, {{215}, { 9}}, - {{471}, { 9}}, {{ 55}, { 9}}, {{311}, { 9}}, {{183}, { 9}}, {{439}, { 9}}, - {{119}, { 9}}, {{375}, { 9}}, {{247}, { 9}}, {{503}, { 9}}, {{ 15}, { 9}}, - {{271}, { 9}}, {{143}, { 9}}, {{399}, { 9}}, {{ 79}, { 9}}, {{335}, { 9}}, - {{207}, { 9}}, {{463}, { 9}}, {{ 47}, { 9}}, {{303}, { 9}}, {{175}, { 9}}, - {{431}, { 9}}, {{111}, { 9}}, {{367}, { 9}}, {{239}, { 9}}, {{495}, { 9}}, - {{ 31}, { 9}}, {{287}, { 9}}, {{159}, { 9}}, {{415}, { 9}}, {{ 95}, { 9}}, - {{351}, { 9}}, {{223}, { 9}}, {{479}, { 9}}, {{ 63}, { 9}}, {{319}, { 9}}, - {{191}, { 9}}, {{447}, { 9}}, {{127}, { 9}}, {{383}, { 9}}, {{255}, { 9}}, - {{511}, { 9}}, {{ 0}, { 7}}, {{ 64}, { 7}}, {{ 32}, { 7}}, {{ 96}, { 7}}, - {{ 16}, { 7}}, {{ 80}, { 7}}, {{ 48}, { 7}}, {{112}, { 7}}, {{ 8}, { 7}}, - {{ 72}, { 7}}, {{ 40}, { 7}}, {{104}, { 7}}, {{ 24}, { 7}}, {{ 88}, { 7}}, - {{ 56}, { 7}}, {{120}, { 7}}, {{ 4}, { 7}}, {{ 68}, { 7}}, {{ 36}, { 7}}, - {{100}, { 7}}, {{ 20}, { 7}}, {{ 84}, { 7}}, {{ 52}, { 7}}, {{116}, { 7}}, - {{ 3}, { 8}}, {{131}, { 8}}, {{ 67}, { 8}}, {{195}, { 8}}, {{ 35}, { 8}}, - {{163}, { 8}}, {{ 99}, { 8}}, {{227}, { 8}} -}; - -local const ct_data static_dtree[D_CODES] = { - {{ 0}, { 5}}, {{16}, { 5}}, {{ 8}, { 5}}, {{24}, { 5}}, {{ 4}, { 5}}, - {{20}, { 5}}, {{12}, { 5}}, {{28}, { 5}}, {{ 2}, { 5}}, {{18}, { 5}}, - {{10}, { 5}}, {{26}, { 5}}, {{ 6}, { 5}}, {{22}, { 5}}, {{14}, { 5}}, - {{30}, { 5}}, {{ 1}, { 5}}, {{17}, { 5}}, {{ 9}, { 5}}, {{25}, { 5}}, - {{ 5}, { 5}}, {{21}, { 5}}, {{13}, { 5}}, {{29}, { 5}}, {{ 3}, { 5}}, - {{19}, { 5}}, {{11}, { 5}}, {{27}, { 5}}, {{ 7}, { 5}}, {{23}, { 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, - 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH - MIN_MATCH + 1] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, - 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, - 64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - - diff --git a/common/zlib/zconf.h b/common/zlib/zconf.h deleted file mode 100644 index 2cf63398b..000000000 --- a/common/zlib/zconf.h +++ /dev/null @@ -1,535 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO -typedef unsigned long z_size_t; -#else -# define z_longlong long long -# if defined(NO_SIZE_T) -typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include -typedef size_t z_size_t; -# else -typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - -/* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) -/* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) -/* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) -/* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ -/* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include -/* No need for _export, use ZLIB.DEF instead. */ -/* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM -/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else -typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC -typedef void const *voidpc; -typedef void FAR *voidpf; -typedef void *voidp; -#else -typedef Byte const *voidpc; -typedef Byte FAR *voidpf; -typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 -typedef Z_U4 z_crc_t; -#else -typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -#pragma map(deflateInit_,"DEIN") -#pragma map(deflateInit2_,"DEIN2") -#pragma map(deflateEnd,"DEEND") -#pragma map(deflateBound,"DEBND") -#pragma map(inflateInit_,"ININ") -#pragma map(inflateInit2_,"ININ2") -#pragma map(inflateEnd,"INEND") -#pragma map(inflateSync,"INSY") -#pragma map(inflateSetDictionary,"INSEDI") -#pragma map(compressBound,"CMBND") -#pragma map(inflate_table,"INTABL") -#pragma map(inflate_fast,"INFA") -#pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ - diff --git a/common/zlib/zlib.h b/common/zlib/zlib.h deleted file mode 100644 index ca35828f0..000000000 --- a/common/zlib/zlib.h +++ /dev/null @@ -1,1924 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.11, January 15th, 2017 - - Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ZLIB_PM3_TUNED -#define ZLIB_VERSION "1.2.11" -#define ZLIB_VERNUM 0x12b0 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 11 -#define ZLIB_VER_SUBREVISION 0 -#else -#define ZLIB_VERSION "1.2.11.f-Proxmark3" -#define ZLIB_VERNUM 0x12bf -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 11 -#define ZLIB_VER_SUBREVISION f -#endif - - - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf(*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - -/* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - -/* basic functions */ - -ZEXTERN const char *ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more ouput - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provided input is not - read or consumed. The allocation of a sliding window will be deferred to - the first call of inflate (if the decompression does not complete on the - first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_in are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - -/* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, and if any input has been consumed in a previous - deflate() call, then the input available so far is compressed with the old - level and strategy using deflate(strm, Z_BLOCK). There are three approaches - for the compression levels 0, 1..3, and 4..9 respectively. The new level - and strategy will take effect at the next call of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will not automatically decode concatenated gzip streams. - inflate() will return Z_STREAM_END at the end of the gzip stream. The state - would need to be reset to continue decoding a subsequent gzip stream. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned(*in_func) OF((void FAR *, - z_const unsigned char FAR *FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - -/* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - -/* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. Previously provided - data is flushed before the parameter change. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); -/* - Read up to nitems items of size size from file to buf, otherwise operating - as gzread() does. This duplicates the interface of stdio's fread(), with - size_t request and return types. If the library defines size_t, then - z_size_t is identical to size_t. If not, then z_size_t is an unsigned - integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); -/* - gzfwrite() writes nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char *ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char *ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - -/* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - -/* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 -ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); -ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); -ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); -ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); -ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); -ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef Z_LARGE64 -ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); -ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); -ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); -ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); -ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); -ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else -ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -#else /* Z_SOLO */ - -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char *ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR *ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ - diff --git a/common/zlib/zutil.c b/common/zlib/zutil.c deleted file mode 100644 index 2d70d74c9..000000000 --- a/common/zlib/zutil.c +++ /dev/null @@ -1,344 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2017 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -z_const char *const z_errmsg[10] = { - (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ - (z_const char *)"stream end", /* Z_STREAM_END 1 */ - (z_const char *)"", /* Z_OK 0 */ - (z_const char *)"file error", /* Z_ERRNO (-1) */ - (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ - (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ - (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ - (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ - (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ - (z_const char *)"" -}; - - -const char *ZEXPORT zlibVersion() { - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() { - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: - break; - case 4: - flags += 1; - break; - case 8: - flags += 2; - break; - default: - flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: - break; - case 4: - flags += 1 << 2; - break; - case 8: - flags += 2 << 2; - break; - default: - flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: - break; - case 4: - flags += 1 << 4; - break; - case 8: - flags += 2 << 4; - break; - default: - flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: - break; - case 4: - flags += 1 << 6; - break; - case 8: - flags += 2 << 6; - break; - default: - flags += 3 << 6; - } -#ifdef ZLIB_DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef ZLIB_DEBUG -#include -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error(m) -char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char *ZEXPORT zError(err) -int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) -/* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ -int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) -Bytef *dest; -const Bytef *source; -uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) -const Bytef *s1; -const Bytef *s2; -uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2 * (s1[j] > s2[j]) - 1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) -Bytef *dest; -uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - voidpf buf; - ulg bsize = (ulg)items * size; - - (void)opaque; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush *)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush *)&buf + 1) += ((ush)((uch *)buf - 0) + 15) >> 4; - *(ush *)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - int n; - - (void)opaque; - - if (*(ush *)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n - 1] = table[n]; - } - next_ptr--; - return; - } - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { - (void)opaque; - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - (void)opaque; - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc(opaque, items, size) -voidpf opaque; -unsigned items; -unsigned size; -{ - (void)opaque; - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree(opaque, ptr) -voidpf opaque; -voidpf ptr; -{ - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ - diff --git a/common/zlib/zutil.h b/common/zlib/zutil.h deleted file mode 100644 index a5bf91366..000000000 --- a/common/zlib/zutil.h +++ /dev/null @@ -1,272 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifdef Z_SOLO -typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern z_const char *const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - -/* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - -/* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) -/* Allow compilation with ANSI keywords only enabled */ -void _Cdecl farfree(void *block); -void *_Cdecl farmalloc(unsigned long nbytes); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 1 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 2 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef __370__ -# if __TARGET_LIB__ < 0x20000000 -# define OS_CODE 4 -# elif __TARGET_LIB__ < 0x40000000 -# define OS_CODE 11 -# else -# define OS_CODE 8 -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 5 -#endif - -#ifdef OS2 -# define OS_CODE 6 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif -#endif - -#ifdef __acorn -# define OS_CODE 13 -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -# define OS_CODE 10 -#endif - -#ifdef _BEOS_ -# define OS_CODE 16 -#endif - -#ifdef __TOS_OS400__ -# define OS_CODE 18 -#endif - -#ifdef __APPLE__ -# define OS_CODE 19 -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED -typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) -#pragma warn -8004 -#pragma warn -8008 -#pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && \ - (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) -ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); -ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - -/* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 3 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - -/* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) -/* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else -void ZLIB_INTERNAL zmemcpy OF((Bytef *dest, const Bytef *source, uInt len)); -int ZLIB_INTERNAL zmemcmp OF((const Bytef *s1, const Bytef *s2, uInt len)); -void ZLIB_INTERNAL zmemzero OF((Bytef *dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef ZLIB_DEBUG -# include -extern int ZLIB_INTERNAL z_verbose; -extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO -voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); -void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#endif /* ZUTIL_H */ - diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index be5d2a847..e6d1636e9 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -34,15 +34,65 @@ OBJDIR = obj INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. -# Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory -VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/zlib ../fpga ../armsrc/Standalone +# Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the lz4 directory +VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/lz4 ../fpga ../armsrc/Standalone INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h -CFLAGS ?= -Wall -Werror -pedantic -Wunused -Os -mthumb-interwork -CFLAGS += -c $(INCLUDE) -std=c99 $(APP_CFLAGS) +ARMCFLAGS = -mthumb-interwork -fno-builtin +DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe -LDFLAGS += -nostartfiles -nodefaultlibs -Wl,-gc-sections -Wl,--build-id=none -n +# Some more warnings we want as errors: +DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits + +# Some more warnings we need first to eliminate, so temporarely tolerated: +DEFCFLAGS += -Wshadow -Wno-error=shadow +DEFCFLAGS += -Winline -Wno-error=inline +DEFCFLAGS += -Wmissing-prototypes -Wno-error=missing-prototypes +DEFCFLAGS += -Wmissing-declarations -Wno-error=missing-declarations +DEFCFLAGS += -Wstrict-prototypes -Wno-error=strict-prototypes +# still vsnprintf etc to sort out... +#DEFCFLAGS += -Wredundant-decls -Wno-error=redundant-decls +#DEFCFLAGS += -Wcast-align -Wno-error=cast-align + +# Next ones are activated only if GCCEXTRA=1 +EXTRACFLAGS = +EXTRACFLAGS += -Wunused-parameter -Wno-error=unused-parameter +EXTRACFLAGS += -Wswitch-enum -Wno-error=switch-enum +EXTRACFLAGS += -Wsign-compare -Wno-error=sign-compare +EXTRACFLAGS += -Wold-style-definition -Wno-error=old-style-definition +EXTRACFLAGS += -Wconversion -Wno-error=conversion -Wno-error=sign-conversion -Wno-error=float-conversion + +# unknown to clang or old gcc: +# First we activate Wextra then we explicitly list those we know about +# Those without -Wno-error are supposed to be completely solved +GCCEXTRACFLAGS = -Wextra +# unknown to arm-none-eabi/4.9.3 +GCCEXTRACFLAGS += -Wwrite-strings -Wno-error=discarded-qualifiers + +GCCEXTRACFLAGS += -Wold-style-declaration -Wno-error=old-style-declaration +GCCEXTRACFLAGS += -Wimplicit-fallthrough=3 -Wno-error=implicit-fallthrough +GCCEXTRACFLAGS += -Wclobbered +GCCEXTRACFLAGS += -Wcast-function-type +GCCEXTRACFLAGS += -Wmissing-parameter-type +GCCEXTRACFLAGS += -Woverride-init +GCCEXTRACFLAGS += -Wshift-negative-value +GCCEXTRACFLAGS += -Wunused-but-set-parameter +# Not yet enabled in DEFCFLAGS: +GCCEXTRACFLAGS += -Wredundant-decls -Wno-error=redundant-decls +GCCEXTRACFLAGS += -Wcast-align -Wno-error=cast-align + +ifeq ($(GCCEXTRA),1) + DEFCFLAGS += $(GCCEXTRACFLAGS) $(EXTRACFLAGS) +endif +ifeq ($(NOERROR),1) + DEFCFLAGS += -Wno-error +endif + +CROSS_CFLAGS ?= $(DEFCFLAGS) +CROSS_CFLAGS += $(ARMCFLAGS) -c $(INCLUDE) -std=c99 -DON_DEVICE $(APP_CFLAGS) + +CROSS_LDFLAGS += -nostartfiles -nodefaultlibs -Wl,-gc-sections -Wl,--build-id=none -n LIBS = -lgcc # Flags to generate temporary dependency files @@ -57,21 +107,21 @@ VERSIONOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(VERSIONSRC))) $(THUMBOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -mthumb -o $@ $< + $(Q)$(CC) $(CROSS_CFLAGS) $(DEPFLAGS) -mthumb -o $@ $< $(Q)$(POSTCOMPILE) $(ARMOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) $(DEPFLAGS) -o $@ $< + $(Q)$(CC) $(CROSS_CFLAGS) $(DEPFLAGS) -o $@ $< $(Q)$(POSTCOMPILE) $(ASMOBJ): $(OBJDIR)/%.o: %.s $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -o $@ $< + $(Q)$(CC) $(CROSS_CFLAGS) -o $@ $< $(VERSIONOBJ): $(OBJDIR)/%.o: %.c $(INCLUDES) $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -mthumb -o $@ $< + $(Q)$(CC) $(CROSS_CFLAGS) -mthumb -o $@ $< # This objcopy call translates physical flash addresses to logical addresses # without touching start address or RAM addresses (.bss and .data sections) @@ -85,7 +135,7 @@ $(OBJDIR)/%.s19: $(OBJDIR)/%.elf $(Q)$(OBJCOPY) -Osrec --srec-forceS3 --strip-debug $(OBJCOPY_TRANSLATIONS) $^ $@ # easy printing of MAKE VARIABLES -print-%: ; @echo $* = $($*) +print-%: ; @echo $* = $($*) # Automatic dependency generation DEPENDENCY_FILES = $(patsubst %.c,$(OBJDIR)/%.d,$(notdir $(THUMBSRC))) \ diff --git a/common_arm/ldscript.common b/common_arm/ldscript.common index 1be33df95..9e53d8436 100644 --- a/common_arm/ldscript.common +++ b/common_arm/ldscript.common @@ -9,17 +9,21 @@ ms of the GNU GPL, version 2 or, ----------------------------------------------------------------------------- */ +stacksize = DEFINED(stacksize) ? stacksize : 5K; +commonareasize = 0x20; + /* AT91SAM7S256 has 256k Flash and 64k RAM */ /* AT91SAM7S512 has 512k Flash and 64k RAM */ /* boot space = 8192bytes (0x2000) */ /* osimage space = (512k - 0x2000 == 524288 - 8192 == 516096bytes == 0x7E000 ) */ MEMORY { - bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */ - bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */ - osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */ - ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */ - commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */ + bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */ + bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */ + osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */ + ram : ORIGIN = 0x00200000, LENGTH = 64K - commonareasize /* RAM, minus small common area */ + stack : ORIGIN = 0x00200000 + 64K - stacksize - commonareasize, LENGTH = stacksize /* Stack */ + commonarea : ORIGIN = 0x00200000 + 64K - commonareasize, LENGTH = commonareasize /* Communication between bootloader and main OS */ } /* Export some information that can be used from within the firmware */ @@ -29,4 +33,5 @@ _bootrom_start = ORIGIN(bootphase1); _bootrom_end = ORIGIN(bootphase2) + LENGTH(bootphase2); _flash_start = ORIGIN(bootphase1); _flash_end = ORIGIN(osimage) + LENGTH(osimage); +_stack_start = ORIGIN(stack); _stack_end = ORIGIN(ram) + LENGTH(ram) - 8; diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index ca2c1986a..34400f4d5 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -130,9 +130,9 @@ AT91SAM7S256 USB Device Port #define SET_CONTROL_LINE_STATE 0x2221 AT91PS_UDP pUdp = AT91C_BASE_UDP; -uint8_t btConfiguration = 0; -uint8_t btConnection = 0; -uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; +static uint8_t btConfiguration = 0; +static uint8_t btConnection = 0; +static uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; static const char devDescriptor[] = { /* Device descriptor */ @@ -394,7 +394,7 @@ static const char StrMS_OSDescriptor[] = { 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0, MS_VENDOR_CODE, 0 }; -const char *getStringDescriptor(uint8_t idx) { +static const char *getStringDescriptor(uint8_t idx) { switch (idx) { case 0: return StrLanguageCodes; @@ -479,7 +479,7 @@ static void SpinDelayUs(int us) { * \brief This function deactivates the USB device *---------------------------------------------------------------------------- */ -void usb_disable() { +void usb_disable(void) { // Disconnect the USB device AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU; @@ -495,7 +495,7 @@ void usb_disable() { * \brief This function Activates the USB device *---------------------------------------------------------------------------- */ -void usb_enable() { +void usb_enable(void) { // Set the PLL USB Divider AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ; @@ -548,7 +548,7 @@ int GetUSBconfigured(void) { return usb_configured; } -bool usb_check() { +bool usb_check(void) { /* // reconnected ONCE and @@ -599,7 +599,7 @@ bool usb_check() { return (btConfiguration) ? true : false; } -bool usb_poll() { +bool usb_poll(void) { if (!usb_check()) return false; return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank); } @@ -612,7 +612,7 @@ bool usb_poll() { that the length available to read is non-zero, thus hopefully fixes the bug. **/ -bool usb_poll_validate_length() { +bool usb_poll_validate_length(void) { if (!usb_check()) return false; if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false; return ((pUdp->UDP_CSR[AT91C_EP_OUT] & AT91C_UDP_RXBYTECNT) >> 16) > 0; @@ -793,7 +793,7 @@ int usb_write(const uint8_t *data, const size_t len) { * \brief Send Data through the control endpoint *---------------------------------------------------------------------------- */ -void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { +void AT91F_USB_SendData(AT91PS_UDP pudp, const char *pData, uint32_t length) { AT91_REG csr; do { @@ -801,17 +801,17 @@ void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { length -= cpt; while (cpt--) - pUdp->UDP_FDR[AT91C_EP_CONTROL] = *pData++; + pudp->UDP_FDR[AT91C_EP_CONTROL] = *pData++; - if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) { + if (pudp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) { UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP); + while (pudp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP); } UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY); do { - csr = pUdp->UDP_CSR[AT91C_EP_CONTROL]; + csr = pudp->UDP_CSR[AT91C_EP_CONTROL]; // Data IN stage has been stopped by a status OUT if (csr & AT91C_UDP_RX_DATA_BK0) { @@ -822,9 +822,9 @@ void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { } while (length); - if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) { + if (pudp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) { UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP); + while (pudp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP); } } @@ -833,22 +833,22 @@ void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { //* \fn AT91F_USB_SendZlp //* \brief Send zero length packet through the control endpoint //*---------------------------------------------------------------------------- -void AT91F_USB_SendZlp(AT91PS_UDP pUdp) { +void AT91F_USB_SendZlp(AT91PS_UDP pudp) { UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY); - while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)) {}; + while (!(pudp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)) {}; UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {}; + while (pudp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {}; } //*---------------------------------------------------------------------------- //* \fn AT91F_USB_SendStall //* \brief Stall the control endpoint //*---------------------------------------------------------------------------- -void AT91F_USB_SendStall(AT91PS_UDP pUdp) { +void AT91F_USB_SendStall(AT91PS_UDP pudp) { UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL); - while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR)) {}; + while (!(pudp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR)) {}; UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)); - while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)) {}; + while (pudp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)) {}; } //*---------------------------------------------------------------------------- @@ -858,7 +858,7 @@ void AT91F_USB_SendStall(AT91PS_UDP pUdp) { //* 1. this is for USB endpoint0. the control endpoint. //* 2. mixed with CDC ACM endpoint3 , interrupt, control endpoint //*---------------------------------------------------------------------------- -void AT91F_CDC_Enumerate() { +void AT91F_CDC_Enumerate(void) { uint8_t bmRequestType, bRequest; uint16_t wValue, wIndex, wLength, wStatus; diff --git a/common_arm/usb_cdc.h b/common_arm/usb_cdc.h index b5ec2e8d7..2f6c5b15d 100644 --- a/common_arm/usb_cdc.h +++ b/common_arm/usb_cdc.h @@ -52,9 +52,9 @@ int GetUSBreconnect(void); void SetUSBconfigured(int value); int GetUSBconfigured(void); -void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length); -void AT91F_USB_SendZlp(AT91PS_UDP pUdp); -void AT91F_USB_SendStall(AT91PS_UDP pUdp); +void AT91F_USB_SendData(AT91PS_UDP pudp, const char *pData, uint32_t length); +void AT91F_USB_SendZlp(AT91PS_UDP pudp); +void AT91F_USB_SendStall(AT91PS_UDP pudp); void AT91F_CDC_Enumerate(void); #endif // _USB_CDC_H_ diff --git a/common_fpga/fpga.h b/common_fpga/fpga.h index 31580d8c9..c8390ff7e 100644 --- a/common_fpga/fpga.h +++ b/common_fpga/fpga.h @@ -13,11 +13,11 @@ #define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(bitparse_fixed_header) #define FPGA_INTERLEAVE_SIZE 288 #define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE - +#define FPGA_RING_BUFFER_BYTES (1024 * 39) #define FPGA_TRACE_SIZE 3072 static const uint8_t bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01}; -extern const int fpga_bitstream_num; -extern const char *const fpga_version_information[]; +extern const int g_fpga_bitstream_num; +extern const char *const g_fpga_version_information[]; #endif diff --git a/covbuild.sh b/covbuild.sh index 2e18e677f..73c9a4441 100755 --- a/covbuild.sh +++ b/covbuild.sh @@ -32,7 +32,7 @@ cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate- ######################################### # Run tests # ######################################### -cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --test-capture ./pm3test.sh long +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --test-capture tools/pm3_tests.sh --long #cov-manage-emit --dir "$COVDIR" list-coverage-known ######################################### diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 38f5f0d3b..e474c0ec7 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -1,8 +1,36 @@ -# MANUAL -### Bluetooth / Battery add-on 'Blue Shark' -_rev. v1.0 (draft)_ +# MANUAL Bluetooth / Battery add-on 'Blue Shark' + +_rev. v1.1_ -### 1. FEATURES +## Table of Contents + + * [1. FEATURES](#1-features) + * [2. PARAMETERS](#2-parameters) + * [3. ASSEMBLY STEPS](#3-assembly-steps) + * [4. COMPILATION / FLASHING](#4-compilation--flashing) + * [4.1 From Source](#41-from-source) + * [4.2 Homebrew (macOS)](#42-homebrew-macos) + * [5. CONNECT WITH BLUETOOTH](#5-connect-with-bluetooth) + * [5.1 Windows](#51-windows) + * [5.1.1 Connecting your RDV4.0 with Bluetooth on mobile phone or computer](#511-connecting-your-rdv40-with-bluetooth-on-mobile-phone-or-computer) + * [5.1.2 Fast connection using dedicated USB Bluetooth adapter under Windows](#512-fast-connection-using-dedicated-usb-bluetooth-adapter-under-windows) + * [5.2 Linux](#52-linux) + * [5.2.1 Connecting rdv4.0 with Bluetooth on Linux computer via native Bluetooth support in the client](#521-connecting-rdv40-with-bluetooth-on-linux-computer-via-native-bluetooth-support-in-the-client) + * [5.2.2 Fast connection using dedicated USB Bluetooth adapter under Linux](#522-fast-connection-using-dedicated-usb-bluetooth-adapter-under-linux) + * [5.2.3 (deprecated) Connecting rdv4.0 with Bluetooth on Linux computer via rfcomm](#523-deprecated-connecting-rdv40-with-bluetooth-on-linux-computer-via-rfcomm) + * [5.3 MacOS](#53-macos) + * [5.3.1 Connecting rdv4.0 with Bluetooth on MacOS](#531-connecting-rdv40-with-bluetooth-on-macos) + * [5.4 Android](#54-android) + * [5.4.1 Fast connection using dedicated Bluetooth (HC-06 Master CP2102) adapter under Android with Termux](#541-fast-connection-using-dedicated-bluetooth-hc-06-master--cp2102-adapter-under-android-with-termux) + * [6. OTHER NOTES](#6-other-notes) + * [6.1 Default settings](#61-default-settings) + * [6.2 UART and LED behavior](#62-uart-and-led-behavior) + * [6.3 Disassembly](#63-disassembly) + * [6.4 Battery charging](#64-battery-charging) + * [6.5 Get better signals](#65-get-better-signals) + +## 1. FEATURES +^[Top](#top) * Built-in Bluetooth 2.0 with EDR Bluetooth module, default baud rate 115200. * Built-in 400 mAh polymer lithium-ion battery, typical standby time up to 3.5 hours. @@ -17,7 +45,8 @@ It can easily connect to Bluetooth mobile phone, portable computer, etc. Without Built-in battery can support standalone mode, off-line sniffing, off-line reading & simulation, etc. The temperature of the device is stable. -### 2. PARAMETERS +## 2. PARAMETERS +^[Top](#top) * Battery capacity: 400 mAh * Standby time: 3.5h @ StandBy; 2.9h @ LF-On; 50min @ HF-On; @@ -29,7 +58,8 @@ Built-in battery can support standalone mode, off-line sniffing, off-line readin * Size and weight: 54.4mm * 29.4mm * 13.5mm 24g -### 3. ASSEMBLY STEPS +## 3. ASSEMBLY STEPS +^[Top](#top) * Unplug your Proxmark3 RDV4.0 device from any usb cable. * Remove the plastic upper case of Proxmark3 RDV4.0 with opener. @@ -45,9 +75,11 @@ Built-in battery can support standalone mode, off-line sniffing, off-line readin Image of blue shark add-on open fitImage of blue shark add-on fitted

-### 4. COMPILATION / FLASHING +## 4. COMPILATION / FLASHING +^[Top](#top) -#### From Source +#### 4.1 From Source +^[Top](#top) Please download the latest source code from Rfid Research Group's Github repo: https://github.com/RfidResearchGroup/proxmark3 @@ -55,39 +87,63 @@ https://github.com/RfidResearchGroup/proxmark3 To compile the client and firmware with FPC support, the easiest way is to 1. Copy the sample file: `Makefile.platform.sample` ⇒ `Makefile.platform` + * `cp Makefile.platform.sample Makefile.platform` 2. Edit `Makefile.platform`, uncomment the line `#PLATFORM_EXTRAS=BTADDON` by removing the `#` 3. Recompile the project: - * `make clean; make -j8` + * `make clean; make -j` 4. Flash the firmware + * `./pm3-flash-fullimage` You are now ready to run the client with the serial port you got from your BT device on your laptop etc. See instructions below. -#### Homebrew (macOS) +#### 4.2 Homebrew (macOS) +^[Top](#top) + From the [homebrew-proxmark3 readme](https://github.com/RfidResearchGroup/homebrew-proxmark3) 1. `brew tap rfidresearchgroup/proxmark3` 2. `brew install --with-blueshark proxmark3` -### 5. CONNECT WITH BLUETOOTH + +## 5. CONNECT WITH BLUETOOTH +^[Top](#top) You can have both USB cable connect and BT active at the same time and connect to either serial port. You can also switch serial port from inside the proxmark3 client using the new command `hw connect`. -### Default settings +### 5.1 Windows +^[Top](#top) -1. Serial: `115200 8N1` -2. Name: `PM3_RDV4.0` -3. Pin: `1234` +#### 5.1.1 Connecting your RDV4.0 with Bluetooth on mobile phone or computer +^[Top](#top) -#### Windows - -#### (1) Connecting your RDV4.0 with Bluetooth on mobile phone or computer * Open Bluetooth and search for a device named PM3_RDV4.0. * Enter the paired password 1234 and establish the connection. * The blue state LED on the add-on will keep blinking after the connection is established. Only when the mobile phone or computer opens the correct COM port, the blue LED turns on solid, indicating that the connection is successful. -#### (2) Fast connection using dedicated USB Bluetooth adapter under Windows +* First time you do this you might need to go into Bluetooth more settings and add a outgoing com port. If so, follow these steps below. + +* First open your bluetooth settings, click on "more options". +

+Image of bluetooth more options popup +

+* Go to second tab and view the list of current bluetooth comports. If you don't have an outgoing com port setup, click 'add' +

+Image of current bluetooth comports +

+* Select `outgoing comport` and select the Proxmark3 RDV4.0 device. Click `OK` when done. +

+Image of adding outgoing comport +

+* Verify that you now have a outgoing comport. Remember this com port when you want to use your Proxmark3. +

+Image of ok bluetooth outgoing comport +

+* done! + +#### 5.1.2 Fast connection using dedicated USB Bluetooth adapter under Windows +^[Top](#top)

Image of blue shark add-on HC-06 white dongle

@@ -100,35 +156,34 @@ http://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp * After the connection is established, the blue state LED on add-on will turn on solid. * look for _CP2104 USB tp UART bridge controller_ under devices in order to get the assigned serial port -#### Linux +### 5.2 Linux +^[Top](#top) -#### (1) Connecting rdv4.0 with Bluetooth on Linux computer +#### 5.2.1 Connecting rdv4.0 with Bluetooth on Linux computer via native Bluetooth support in the client +^[Top](#top) + +This requires to have compiled the client with Bluetooth support. + +Be sure your user has permissions to use Bluetooth + + * On most distributions, you've to be part of group `bluetooth`: `sudo adduser $USER bluetooth` then log out and log in + * else, run the following commands as root : `sudo ...` 1. Find the MAC address of the Bluetooth add-on, named PM3_RDV4.0. ```sh -sudo hcitool scan +hcitool scan Scanning ... aa:bb:cc:dd:ee:ff PM3_RDV4.0 ``` Instead of `aa:bb:cc:dd:ee:ff`, you'll see your MAC address. -2. Bind your BT add-on MAC address to a serial port +If you don't have `hcitool`, you can use `bluetoothctl` and `scan on` as shown in next section. + +2. Use Proxmark client with Bluetooth MAC address as bt: ```sh -sudo rfcomm bind rfcomm0 aa:bb:cc:dd:ee:ff -``` - -Replace `aa:bb:cc:dd:ee:ff` by your MAC address. - -3. The blue state LED on the add-on will keep blinking after the -connection is established. Only when the Proxmark3 client opens the -`/dev/rfcomm0` port, the blue LED turns on solid, indicating that the -connection is successful. - -4. Use Proxmark client on BT-serial port -```sh -./proxmark3 /dev/rfcomm0 +./proxmark3 bt:aa:bb:cc:dd:ee:ff ``` The first time, your OS will ask you for pairing. The default PIN is 1234. If PIN is not typed in quickly, the client might timeout. Simply @@ -149,7 +204,8 @@ Discovery started [bluetooth]# quit ``` -#### (2) Fast connection using dedicated USB Bluetooth adapter under Linux +#### 5.2.2 Fast connection using dedicated USB Bluetooth adapter under Linux +^[Top](#top)

Image of blue shark add-on HC-06 white dongle

@@ -172,9 +228,45 @@ turn on solid. ./proxmark3 /dev/ttyUSB0 ``` -#### MacOS +#### 5.2.3 (deprecated) Connecting rdv4.0 with Bluetooth on Linux computer via rfcomm +^[Top](#top) -#### (1) Connecting rdv4.0 with Bluetooth on MacOS +rfcomm is a deprecated tool which might be unavailable in your Linux distribution. + +1. Find the MAC address of the Bluetooth add-on, named PM3_RDV4.0. + +```sh +hcitool scan +Scanning ... + aa:bb:cc:dd:ee:ff PM3_RDV4.0 +``` + +Instead of `aa:bb:cc:dd:ee:ff`, you'll see your MAC address. + +2. Bind your BT add-on MAC address to a serial port +```sh +sudo rfcomm bind rfcomm0 aa:bb:cc:dd:ee:ff +``` + +Replace `aa:bb:cc:dd:ee:ff` by your MAC address. + +3. The blue state LED on the add-on will keep blinking after the +connection is established. Only when the Proxmark3 client opens the +`/dev/rfcomm0` port, the blue LED turns on solid, indicating that the +connection is successful. + +4. Use Proxmark client on BT-serial port +```sh +./proxmark3 /dev/rfcomm0 +``` + +See instructions above (method 1) for initial pairing. + +### 5.3 MacOS +^[Top](#top) + +#### 5.3.1 Connecting rdv4.0 with Bluetooth on MacOS +^[Top](#top) With MacOS Mojave 10.14.5 you could experience some continuosly disconnecting and difficult to recconnect the device at the system wakeup, to avoid this problem do a PRAM reset before to add your Proxmark3 RDV4 Blue Shark: @@ -193,34 +285,53 @@ After reboot you can go ahead to pairing your Proxmark3 RDV4 Blue Shark: ```sh ./proxmark3 /dev/tty.PM3_RDV40-DevB ``` -#### Android +### 5.4 Android +^[Top](#top) + +#### 5.4.1 Fast connection using dedicated Bluetooth (HC-06 Master + CP2102) adapter under Android with Termux +^[Top](#top) -#### (2) Fast connection using dedicated Bluetooth (HC-06 Master + CP2102) adapter under Android with Termux - 1. Make sure you already followed this tutorial https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/termux_notes.md#setup and have Termux with an running Proxmark3 client ready. You need additional the `cp210x` serial usb driver enabled and working, like the `USB_ACM` driver to communicate wireless. 2. Insert the Bluetooth adapter with an fitting USB-C/Micro-USB converter into your Android USB port and a serial port `/dev/ttyUSB0` will be created. To see if it's working, run `tsudo ls /dev/ttyU*` and it should list `/dev/ttyUSB0`. 3. The adapter will search automatically and establish the connection to BlueShark. The adapter will remember the device that was first connected and after that the same device will be connected. After the connection is established, the blue state LED on add-on will turn on solid. 4. If you see this, congratulations, you can run your Proxmark3 client in Termux with `tsudo proxmark3/client/proxmark3 /dev/ttyUSB0` -##### Notes -If you bought your Bluetooth adapter somewhere else, make sure to set the baud rate to 115200 `AT+BAUD8` and PIN `AT+PIN1234` correctly +## 6. OTHER NOTES +^[Top](#top) -### 6. OTHER NOTES +### 6.1 Default settings +^[Top](#top) + +Settings of the Blue Shark add-on and of the white dongle: + +1. Serial: `115200 8N1` +2. Name: `PM3_RDV4.0` +3. Pin: `1234` + +If you bought your Bluetooth adapter dongle somewhere else, make sure to set the baud rate to 115200 `AT+BAUD8`, the name `AT+NAMEPM3_RDV4.0` and PIN `AT+PIN1234` correctly. + +### 6.2 UART and LED behavior +^[Top](#top) -#### (1) UART and LED behavior Bluetooth is connected to Proxmark3 RDV4.0 via UART. The USB and UART interfaces of RDV4.0 can coexist without conflict, and no special switching is required. The following link has helpful notes on UART usage and baud rates: https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/uart_notes.md -#### (2) Disassembly +### 6.3 Disassembly +^[Top](#top) + There is a heat conductive double-sided tape inside the add-on, which has strong adhesive force. Therefore, if add-on needs to be removed, it needs to be pulled out from the heat sink end with greater efforts. Each disassembly will reduce the viscidity of double-sided tape. When double-sided tape is well protected, it will not affect the second use. Thermal conductivity will be slightly worse and will therefore have a direct impact on the thermal performance of the heat sink. -#### (3) Battery charging +### 6.4 Battery charging +^[Top](#top) + The battery charging circuit is turned on by default. Any time a USB cable is inserted, the battery will be automatically charged. The red LED will remain bright when charging. The red LED will be extinguished when charging is completed. -#### (4) Get better signals +### 6.5 Get better signals +^[Top](#top) + For the better heat dissipation, we have used a cast metal enclosure for the add-on. As a result Bluetooth wireless signals are sacrificed. For example, if the back of add-on is facing the Bluetooth host, the signal is very bad and the distance will be reduced. The best signal strength can be obtained when the front glass faces the Bluetooth host. If the Proxmark3 is not responding, it may be due to a poor Bluetooth connection. To improve performance, try repositioning the Proxmark3 so the glass face is directed toward the host. diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 74a061b10..0ae47b68c 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,5 +1,5 @@ -# Command Cheat Sheet +# Command Cheat Sheet |Generic|Low Frequence 125 kHz|High Frequence 13.56 MHz| |---|---|---| diff --git a/doc/fpga_arm_notes.md b/doc/fpga_arm_notes.md new file mode 100644 index 000000000..c066b316b --- /dev/null +++ b/doc/fpga_arm_notes.md @@ -0,0 +1,249 @@ +# Notes on ARM & FPGA comms + + +https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/original_proxmark3/proxmark3.pdf + +INTERFACE FROM THE ARM TO THE FPGA +================================== + +The FPGA and the ARM can communicate in two main ways: using the ARM's +general-purpose synchronous serial port (the SSP), or using the ARM's +SPI port. The SPI port is used to configure the FPGA. The ARM writes a +configuration word to the FPGA, which determines what operation will +be performed (e.g. read 13.56 MHz vs. read 125 kHz vs. read 134 kHz +vs...). The SPI is used exclusively for configuration. + +The SSP is used for actual data sent over the air. The ARM's SSP can +work in slave mode, which means that we can send the data using clocks +generated by the FPGA (either from the PCK0 clock, which the ARM itself +supplies, or from the 13.56 MHz clock, which is certainly not going to +be synchronous to anything in the ARM), which saves synchronizing logic +in the FPGA. The SSP is bi-directional and full-duplex. + + +The FPGA communicates with the ARM through either +1) SPI port (the ARM is the master) +2) SSC synchronous serial port (the ARM is the master). + + +opamps, (*note, this affects source code in ARM, calculating actual voltage from antenna. Manufacturers never report what they use to much frustration) +comparators +coil drivers + +LF analog path (MCP6294 opamp. This has a GBW of 10 MHz), all 'slow' signals. Used for low frequency signals. Follows the peak detector. Signal centered around generated voltage Vmid. + + +## FPGA +Since the SPARTAN II is a old outdated FPGA, thus is very limited resource there was a need to split LF and HF functionality into two seperate FPGA images. Which are stored in ARM flash memory as bitstreams. + +We swap between these images by flashing fpga from ARM on the go. It takes about 1sec. Hence its usually a bad idea to program your device to continuously execute LF alt HF commands. + +The FPGA images is precompiled and located inside the /fpga folder. + - fpga_hf.bit + - fpga_lf.bit + +There is very rarely changes to the images so there is no need to setup a fpga tool chain to compile it yourself. +Since the FPGA is very old, the Xilinix WebPack ISE 10.1 is the last working tool chain. You can download this legacy development on xilinix and register for a free product installation id. +Or use mine `11LTAJ5ZJK3PXTUBMF0C0J6C4` The package to download is about 7Gb and linux based. Though I recently managed to install it on WSL for Windows 10. + +In order to save space, these fpga images are LZ4 compressed and included in the fullimage.elf file when compiling the ARM SRC. `make armsrc` +This means we save some precious space on the ARM but its a bit more complex when flashing to fpga since it has to decompress on the fly. + + +### FPGA modes. + - Major modes + - Minor modes + +## ARM FPGA communications. + +The ARM talks with FPGA over the Synchronous Serial Port (SSC) rx an tx. + +ARM, send a 16bit configuration with fits the select major mode. + + + +## ARM GPIO setup + +``` + // First configure the GPIOs, and get ourselves a clock. + AT91C_BASE_PIOA->PIO_ASR = + GPIO_SSC_FRAME | + GPIO_SSC_DIN | + GPIO_SSC_DOUT | + GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC); + + // Now set up the SSC proper, starting from a known state. + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + + // RX clock comes from TX clock, RX starts on Transmit Start, + // data and frame signal is sampled on falling edge of RK + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); + + // 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync + // pulse, no output sync + if ((FPGA_mode & FPGA_MAJOR_MODE_MASK) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) { + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + } else { + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + } + + // TX clock comes from TK pin, no clock output, outputs change on rising edge of TK, + // TF (frame sync) is sampled on falling edge of TK, start TX on rising edge of TF + AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); + + // tx framing is the same as the rx framing + AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR; + +``` + +## FPGA Setup + +// Set up DMA to receive samples from the FPGA. We will use the PDC, with +// a single buffer as a circular buffer (so that we just chain back to + + + +# HARDWARE OVERVIEW + +## ADC (ANALOG TO DIGITAL CONVERTER) +The analogue signal that comes from the antenna circuit is fed into an 8-bit Analogue to Digital Converter +(ADC). This delivers 8 output bits in parallel which represent the current voltage retrieved from the field. + + +## FIELD PROGRAMMABLE GATE ARRAY, FPGA +The 8 output pins from the ADC are connected to 8 pins of the Field Programmable Gate Array (FPGA). An +FPGA has a great advantage over a normal microcontroller in the sense that it emulates hardware. A +hardware description can be compiled and flashed into an FPGA. + +Because basic arithmetic functions can be performed fast and in parallel by an FPGA it is faster than an +implementation on a normal microcontroller. Only a real hardware implementation would be faster but +this lacks the flexibility of an FPGA. + +The FPGA can therefore be seen as dynamic hardware. It is possible to make a hardware design and flash +it into the memory of the FPGA. This gives some major advantages: + + + - "Hardware" errors can be corrected; the FPGA can be flashed with a new hardware design. + - Although not as fast as a real hardware implementation, an FPGA is faster than its equivalent on microprocessor. That is, it is specialized for one job. + +The FPGA has two main tasks. The first task is to demodulate the signal received from the ADC and relay +this as a digital encoded signal to the ARM. Depending on the task this might be the demodulation of a +100% Amplitude Shift Keying (ASK) signal from the reader or the load modulation of a card. The encodin +schemes used to communicate the signal to the ARM are Modified Miller for the reader and Manchester +encoding for the card signal. + +The second task is to modulate an encoded signal that is received from the ARM into the field of the +antenna. This can be both the encoding of reader messages or card messages. For reader messages the +FPGA generates an electromagnetic field on power hi and drops the amplitude for short periods. + + +## MICROCONTROLLER +The microcontroller is responsible for the protocol management. It receives the digital encoded signals +from the FPGA and decodes them. The decoded signals can just be copied to a buffer in the EEPROM +memory. Additionally, an answer to the received message can be send by encoding a reply and +communicating this to the FPGA. + +The microcontroller (ARM) implements the transport layer. First it decodes the samples received from +the FPGA. These samples are stored in a Direct Memory Access (DMA) buffer. The samples are binary +sequences that represent whether the signal was high or low. The software on the ARM tries to decode +these samples. When the Proxmark is in sniffing mode this is done for both the Manchester and Modified +Miller at the same time. Whenever one of the decoding procedures returns a valid message, this message +is stored in another buffer (BigBuf) and both decoding procedures are set to an un-synced state. The +BigBuf is limited to the available memory on the ARM. The current firmware has 2 KB of memory +reserved for traces (Besides the tracethe buffer also stores some temporary data that is needed in the +processing). When the BigBuf buffer is full the function normally returns. A new function call from the +client is needed to download the BigBuf contents to the computer. The BigBuf is especially useful for +ptocol investigation. Every single message is stored in this buffer. When a card is emulated or when the +Proxmark is used as a reader the BigBuf can be used to store status messages or protocol exceptions. + +``` +HF PATH + -- ANTENNA -> rectifying -> lowpass filter -> ADC -> FPGA -> ARM -> USB/CDC | FPC -> CLIENT + | | | | + induct peak detect (8bit) -- modes: + via circuit HF - peak-detected + HF - RAW + HF - +``` + + +``` +LF PATH + + -- ANTENNA -> rectifying -> lowpass filter -> ADC -> FPGA -> ARM -> USB/CDC | FPC -> CLIENT + | | | | + induct peak detect (8bit) -- modes: + via circuit LF - peak-detected + LF - RAW +``` +Problems: + 1. dynamic range of signal. Ie: High Carrier signal (reader) and low + + +## + +## To behave like a READER. +By driving all of the buffers LOW, it is possible to make the antenna +look to the receive path like a parallel LC circuit; this provides a +high-voltage output signal. This is typically what will be done when we +are not actively transmitting a carrier (i.e., behaving as a reader). + +## To behave like a TAG +On the receive side, there are two possibilities, which are selected by +RLY1. A mechanical relay is used, because the signal from the antenna is +likely to be more positive or negative than the highest or lowest supply +voltages on-board. In the usual case (PEAK-DETECTED mode), the received +signal is peak-detected by an analog circuit, then filtered slightly, +and then digitized by the ADC. This is the case for both the low- and +high-frequency paths, although the details of the circuits for the +two cases are somewhat different. This receive path would typically +be selected when the device is behaving as a reader, or when it is +eavesdropping at close range. + +It is also possible to digitize the signal from the antenna directly (RAW +mode), after passing it through a gain stage. This is more likely to be +useful in reading signals at long range, but the available dynamic range +will be poor, since it is limited by the 8-bit A/D. + +In either case, an analog signal is digitized by the ADC, and +from there goes in to the FPGA. The FPGA is big enough that it +can perform DSP operations itself. For some high-frequency standards, +the subcarriers are fast enough that it would be inconvenient to do all +the math on a general-purpose CPU. The FPGA can therefore correlate for +the desired signal itself, and simply report the total to the ARM. For +low-frequency tags, it probably makes sense just to pass data straight +through to the ARM. + +The FPGA communicates with the ARM through either its SPI port (the ARM +is the master) or its generic synchronous serial port (again, the ARM +is the master). The ARM connects to the outside world over USB. + +## To sniff traffic + + + +## FPGA purpose +Digtal signal processing. +In short, apply low pass / hi pass filtering, peak detect, correlate signal meaning IQ pair collecting. + +IQ means measure at In-phase and 90 phase shift later Quadrature-phase, with IQ samples you can plot the signal on a vector plan. + + +``` +IQ1 = 1,1 : 1, -1 (rising) +IQ2 = -1,1 : 1, 1 (falling) + + + + -1,1 | 1,1 + | (q2) + (i2) | (i1) + | + ----------0------------> + | + | (q1) + -1,-1 | 1, -1 +``` diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md index ff3525784..66c736235 100644 --- a/doc/md/Development/Maintainers.md +++ b/doc/md/Development/Maintainers.md @@ -49,10 +49,38 @@ and it will be added along the other firmware as: For verbose usage and see the actual commands being executed, add `V=1`. -`CFLAGS` and `LDFLAGS` can be overriden by environment variables. +`CFLAGS` and `LDFLAGS` can be overriden by environment variables for client-side components. + +`CROSS_CFLAGS` and `CROSS_LDFLAGS` can be overriden by environment variables for ARM-side components. Default compiler is gcc but you can use clang for the non-ARM parts with e.g. `make client CC=clang CXX=clang++ LD=clang++`. +If your platform needs specific lib/include paths for the client, you can use `LDLIBS` and `INCLUDES_CLIENT` *as envvars*, e.g. `LDLIBS="-L/some/more/lib" INCLUDES_CLIENT="-I/some/more/include" make client ...` + +It's also possible to skip parts even if libraries are present in the compilation environment: + +* `make client SKIPQT=1` to skip GUI even if Qt is present +* `make client SKIPBT=1` to skip native Bluetooth support even if libbluetooth is present +* `make client SKIPPYTHON=1` to skip embedded Python 3 interpreter even if libpython3 is present +* `make client SKIPLUASYSTEM=1` to skip system Lua lib even if liblua5.2 is present, use embedded Lua lib instead +* `make client SKIPJANSSONSYSTEM=1` to skip system Jansson lib even if libjansson is present, use embedded Jansson lib instead +* `make client SKIPWHEREAMISYSTEM=1` to skip system Whereami lib even if libwhereami is present, use embedded whereami lib instead + +If you're cross-compiling, these ones might be useful: + +* `make client SKIPREVENGTEST=1` to skip compilation and execution of a consistency test for reveng, which can be problematic in case of cross-compilation +* `make client cpu_arch=generic` to skip Intel specialized hardnested components, which is required e.g. if cross-compilation host is Intel but not the target + +On some architectures, pthread library is not present: + +* `make client SKIPPTHREAD=1` to skip `-lpthread` at linker stage. + +One tool requires a CUDA compilation environment, it can be skipped as well: + +* `make hitag2crack SKIPGPU=1` to skip ht2crack5gpu tool when compiling the hitag2crack toolsuite. + +Some unittests are available via `make check`, which is actually triggering individual targets as for `make install`. + `make install` is actually triggering the following individual targets which can be accessed individually: * `make client/install` @@ -70,4 +98,4 @@ Default compiler is gcc but you can use clang for the non-ARM parts with e.g. `m * SIM firmware * udev rule on Linux -Same logic for `make all`, `make clean`, `make uninstall` +Same logic for `make all`, `make clean`, `make uninstall` and `make check`. diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index b381eb7d9..688091ee8 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -25,9 +25,11 @@ Install the requirements ```sh sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ -libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev ``` +If you don't need the native Bluetooth support in the client, you can skip the installation of `libbluetooth-dev`. + If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `qtbase5-dev`. If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to load module "canberra-gtk-module"_ you may have to install `libcanberra-gtk-module`. @@ -35,27 +37,33 @@ If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to ## On ArchLinux ```sh -sudo pacman -Sy git base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib qt5-base --needed +sudo pacman -Sy git base-devel readline bzip2 arm-none-eabi-gcc arm-none-eabi-newlib qt5-base bluez --needed ``` +If you don't need the native Bluetooth support in the client, you can skip the installation of `bluez`. + If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `qt5-base`. ## On Fedora ```sh -sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic +sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel bzip2-devel qt5-qtbase-devel bluez-libs-devel libatomic ``` +If you don't need the native Bluetooth support in the client, you can skip the installation of `bluez-libs-devel`. + If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `qt5-qtbase-devel`. ## On openSUSE ```sh -sudo zypper install git patterns-devel-base-devel_basis gcc-c++ readline-devel cross-arm-none-gcc9 cross-arm-none-newlib-devel libqt5-qtbase-devel +sudo zypper install git patterns-devel-base-devel_basis gcc-c++ readline-devel libbz2-devel cross-arm-none-gcc9 cross-arm-none-newlib-devel libqt5-qtbase-devel ``` If you don't need the graphical components of the Proxmark3 client (such as in `hw tune`), you can skip the installation of `libqt5-qtbase-devel`. +Note that Bluez is not available on openSUSE so the native Bluetooth support won't be available in the client. + # Clone the RRG/Iceman repository ```sh diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index d2c062dcb..dac35cd74 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -18,8 +18,10 @@ Always use the latest repository commits from *master* branch. There are always * [File not found](#file-not-found) * [Pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) * [Usb cable](#usb-cable) - * [WSL 2 explorer.exe . doesnt work](#WSL-2) + * [WSL explorer.exe . doesnt work](#WSL) * [Troubles with running the Proxmark3 client](#troubles-with-running-the-proxmark3-client) + * [libQt5Core.so.5 not found](#libQt5Coreso5-not-found) + * [Target attribute is not supported on this machine](#target-attribute-is-not-supported-on-this-machine) ## `pm3` or `pm3-flash*` doesn't see my Proxmark @@ -167,7 +169,7 @@ It's needed to have a good USB cable to connect Proxmark3 to USB. If you have st - check your cable with a USB tester (or try to change it). It needs to have a resistance smaller or equal to 0.3 Ohm. -## WSL 2 +## WSL When ```explorer.exe .``` doesn't work. Trying to access the dump files created in WSL, you will need to run ```explorer.exe .``` but sometimes this doesn't work. [As seen here](https://github.com/microsoft/WSL/issues/4027) they suggest checking the following registry value for *P9NP* @@ -178,3 +180,46 @@ Trying to access the dump files created in WSL, you will need to run ```explore Some reports has stated that they needed to execute the Proxmark3 as root on their *nix system. Try running it with `sudo ./pm3` + +## libQt5Core.so.5 not found +On WSL1 / updated to Ubuntu 20.04, there is a slight chance you experience problems when compiling the repo with QT5. +The following steps is needed to make the development environment happy again. +``` +sudo apt reinstall qtbase5-dev +sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 +``` + +## target attribute is not supported on this machine +If you get the message ```error: target attribute is not supported on this machine [-Werror=attributes]``` +when trying to compile, its because you have an older arm-none-eabi tool chain. + +On OSX/Homebrew, the solution is to reinstall the brew. It will trigger a new download of a later tool chain. +``` +brew remove proxmark3 +brew reinstall proxmark3 +``` + +On Ubuntu 16.04 (xenial) you should either conside a later release or you can install a later toolchain. + + +sample error output: +``` +[*] MAKE armsrc/all +compiler version: arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496] + +[-] CC start.c +In file included from start.c:18:0: +BigBuf.h:41:1: error: target attribute is not supported on this machine [-Werror=attributes] + bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); + ^ +cc1: all warnings being treated as errors +In file included from iso15693.c:72:0: +ticks.h:25:1: error: target attribute is not supported on this machine [-Werror=attributes] + uint32_t RAMFUNC GetTickCount(void); + ^ +ticks.h:26:1: error: target attribute is not supported on this machine [-Werror=attributes] + uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks); + ^ +``` + + diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index 9d94490f5..2741850d5 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -77,7 +77,7 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ -libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev +libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev qtbase5-dev ``` If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. diff --git a/doc/md/Use_of_Proxmark/1_Validation.md b/doc/md/Use_of_Proxmark/1_Validation.md index 507648e64..9bb93c453 100644 --- a/doc/md/Use_of_Proxmark/1_Validation.md +++ b/doc/md/Use_of_Proxmark/1_Validation.md @@ -3,26 +3,27 @@ If all went well you should get some information about the firmware and memory usage as well as the prompt, something like this. ``` +[=] Session log /home/iceman/.proxmark3/log_20200521.txt +[=] Loading Preferences... +[+] loaded from JSON file /home/iceman/.proxmark3/preferences.json +[=] Using UART port /dev/ttyS7 +[=] Communicating with PM3 over USB-CDC -██████╗ ███╗ ███╗ ████╗ ...iceman fork -██╔â•â•██╗████╗ ████║ â•â•█║ ...dedicated to RDV40 + +██████╗ ███╗ ███╗ ████╗ +██╔â•â•██╗████╗ ████║ â•â•█║ ██████╔â•██╔████╔██║ ████╔╠-██╔â•â•â•╠██║╚██╔â•██║ â•â•█║ iceman@icesql.net +██╔â•â•â•╠██║╚██╔â•██║ â•â•█║ iceman@icesql.net ██║ ██║ ╚â•╠██║ ████╔╠https://github.com/rfidresearchgroup/proxmark3/ -╚â•╠╚â•╠╚â•╠╚â•â•â•â• pre-release v4.0 +╚â•╠╚â•╠╚â•╠╚â•â•â•â• Release v4.9237 - Ice Coffee -Support iceman on patreon, https://www.patreon.com/iceman1001/ - - -[=] Using UART port /dev/pm3-0 -[=] Communicating with PM3 over USB-CDC [ Proxmark3 RFID instrument ] - [ CLIENT ] - client: RRG/Iceman - + client: RRG/Iceman/master/v4.9237-2-g2cb19874 2020-05-21 22:00:00 + compiled with GCC 9.3.0 OS:Linux ARCH:x86_64 + [ PROXMARK RDV4 ] external flash: present smartcard reader: present @@ -31,27 +32,28 @@ Support iceman on patreon, https://www.patreon.com/iceman1001/ FPC USART for BT add-on support: absent [ ARM ] - bootrom: RRG/Iceman/master/5ab9716e 2019-05-01 11:02:08 - os: RRG/Iceman/master/6b5a0f83 2019-05-04 23:57:47 + bootrom: RRG/Iceman/master/v4.9237-2-g2cb19874 2020-05-21 22:00:10 + os: RRG/Iceman/master/v4.9237-2-g2cb19874 2019-05-21 22:00:26 + compiled with GCC 8.3.1 20190703 (release) [gcc-8-branch revision 273027] [ FPGA ] - LF image built for 2s30vq100 on 2019/ 4/18 at 9:35:32 - HF image built for 2s30vq100 on 2018/ 9/ 3 at 21:40:23 + LF image built for 2s30vq100 on 2020/02/22 at 12:51:14 + HF image built for 2s30vq100 on 2020/01/12 at 15:31:16 [ Hardware ] --= uC: AT91SAM7S512 Rev B --= Embedded Processor: ARM7TDMI - --= Nonvolatile Program Memory Size: 512K bytes, Used: 250913 bytes (48%) Free: 273375 bytes (52%) + --= Nonvolatile Program Memory Size: 512K bytes, Used: 291382 bytes (56%) Free: 232906 bytes (44%) --= Second Nonvolatile Program Memory Size: None --= Internal SRAM Size: 64K bytes --= Architecture Identifier: AT91SAM7Sxx Series --= Nonvolatile Program Memory Type: Embedded Flash Memory -pm3 --> +[usb] pm3 --> ``` -This `pm3 --> ` is the Proxmark3 interactive prompt. +This `[usb] pm3 --> ` is the Proxmark3 interactive prompt. ### To get interactive help @@ -62,16 +64,16 @@ For basic help type `help`. Or for help on a set of sub commands type the comman These commands will return some info about your Proxmark software and hardware status. ``` -pm3 --> hw status -pm3 --> hw version -pm3 --> hw tune +[usb] pm3 --> hw status +[usb] pm3 --> hw version +[usb] pm3 --> hw tune ``` You are now ready to use your newly flashed proxmark3 device. Many commands uses the `h` parameter to show a help text. ### To quit the client ``` -pm3 --> quit +[usb] pm3 --> quit ``` or simple press `CTRL-D`. diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 8b88115c6..fe87ec633 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -1,16 +1,16 @@ ### First things on your RDV40 You will need to run these commands to make sure your rdv4 is prepared ``` -pm3 --> mem load f mfc_default_keys m -pm3 --> mem load f t55xx_default_pwds t -pm3 --> mem load f iclass_default_keys i -pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p -pm3 --> lf t55xx deviceconfig r 1 a 31 b 20 c 18 d 50 e 15 p -pm3 --> lf t55xx deviceconfig r 2 a 31 b 20 c 18 d 40 e 15 p -pm3 --> lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p +[usb] pm3 --> mem load f mfc_default_keys m +[usb] pm3 --> mem load f t55xx_default_pwds t +[usb] pm3 --> mem load f iclass_default_keys i +[usb] pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p +[usb] pm3 --> lf t55xx deviceconfig r 1 a 31 b 20 c 18 d 50 e 15 p +[usb] pm3 --> lf t55xx deviceconfig r 2 a 31 b 20 c 18 d 40 e 15 p +[usb] pm3 --> lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p Set all t55xx settings to defaults (will set all 4 at once) -pm3 --> lf t55xx deviceconfig z p +[usb] pm3 --> lf t55xx deviceconfig z p ``` ### Verify sim module firmware version @@ -20,7 +20,7 @@ To make sure you got the latest sim module firmware. _Lastest version is v3.11_ ``` -pm3 --> hw status +[usb] pm3 --> hw status ``` Find version in the long output, look for these two lines @@ -46,9 +46,9 @@ Don't not turn off your device during the execution of this command!! Even its a quite fast command you should be warned. You may brick it if you interrupt it. ``` -pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin +[usb] pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin # or if from local repo -pm3 --> sc upgrade f tools/simmodule/sim011.bin +[usb] pm3 --> sc upgrade f tools/simmodule/sim011.bin ``` You get the following output if the execution was successful: @@ -71,7 +71,7 @@ You get the following output if the execution was successful: Run hw status command to verify that the upgrade went well. ``` -pm3 --> hw status +[usb] pm3 --> hw status ``` ## Next steps diff --git a/doc/md/Use_of_Proxmark/3_Commands-and-Features.md b/doc/md/Use_of_Proxmark/3_Commands-and-Features.md index deb7036d7..195468002 100644 --- a/doc/md/Use_of_Proxmark/3_Commands-and-Features.md +++ b/doc/md/Use_of_Proxmark/3_Commands-and-Features.md @@ -21,17 +21,17 @@ Here are some commands to start off with. To get an overview of the available commands for LF RFID and HF RFID: ``` -pm3 --> lf -pm3 --> hf +[usb] pm3 --> lf +[usb] pm3 --> hf ``` To search quickly for known LF or HF tags: ``` -pm3 --> lf search -pm3 --> hf search +[usb] pm3 --> lf search +[usb] pm3 --> hf search ``` To get info on a ISO14443-A tag: ``` -pm3 --> hf 14a info +[usb] pm3 --> hf 14a info ``` diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 5e953883a..0780ec87b 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -19,6 +19,14 @@ make clean make SKIPQT=1 ``` +On Linux hosts, if the Bluez headers and library are present, the client will be compiled with native Bluetooth support. It's possible to explicitly skip Bluetooth support with: + +``` +make clean +make SKIPBT=1 +``` + + ## Firmware By default, the firmware is of course tuned for the Proxmark3 Rdv4.0 device, which has built-in support for 256kb onboard flash SPI memory, Sim module (smart card support), FPC connector. @@ -74,6 +82,7 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | | No standalone mode | LF_SKELETON | standalone mode skeleton - Iceman | LF_EM4100EMUL | LF EM4100 simulator standalone mode - temskiy +| LF_EM4100RSWB | LF EM4100 read/write/clone/brute mode - Monster1024 | LF_EM4100RWC | LF EM4100 read/write/clone mode - temskiy | LF_HIDBRUTE | HID corporate 1000 bruteforce - Federico dotta & Maurizio Agazzini | LF_ICEHID | LF HID collector to flashmem - Iceman diff --git a/doc/mfu_binary_format_notes.md b/doc/mfu_binary_format_notes.md new file mode 100644 index 000000000..dfde0da7a --- /dev/null +++ b/doc/mfu_binary_format_notes.md @@ -0,0 +1,101 @@ +# Notes on MFU binary formats + + - new mfu format + - old mfu format + - plain mfu format + - future mfu format + +## New mfu format +The new mfu binary format was created to compensate for different manufactures tag functions. +Like UL-Ev1 has three counter and tearing bytes, while NTAG only has one counter and tearing byte. +PACK was removed from header, since its just normally part of the tag memory, unreadable, but when +a proxmark3 dumps a tag and we have pwd/pack, we add those to their normal location in memory. +This makes memory not a exact memory dump from a tag, but a "what it should have looked like" if we could read all memory + +``` +// New Ultralight/NTAG dump file format +// Length must be aligned to 4 bytes (UL/NTAG page) +#define MFU_DUMP_PREFIX_LENGTH 56 + +typedef struct { + uint8_t version[8]; + uint8_t tbo[2]; + uint8_t tbo1[1]; + uint8_t pages; // max page number in dump + uint8_t signature[32]; + uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag + uint8_t data[1024]; +} PACKED mfu_dump_t; +``` + +## Old mfu format +The old binary format saved the extra data on tag in order for the Proxmark3 to able to simulate a real tag. + +``` +// Old Ultralight/NTAG dump file format +#define OLD_MFU_DUMP_PREFIX_LENGTH 48 + +typedef struct { + uint8_t version[8]; + uint8_t tbo[2]; + uint8_t tearing[3]; + uint8_t pack[2]; + uint8_t tbo1[1]; + uint8_t signature[32]; + uint8_t data[1024]; +} old_mfu_dump_t; +``` + +## Plain mfu format +The first binary format for MFU was just a memory dump from the tag block 0 to end. +No extra data was saved. +``` + uint8_t data[1024]; +``` + +## future mfu format +For developers of apps and other tools, like libnfc, we don't recommend using binary formats. +We decided to adopt a JSON based format, which is much more flexible to changes of new tag functionality. + +Example +``` +{ + "Created": "proxmark3", + "FileType": "mfu", + "Card": { + "UID": "04F654CAFC388", + "Version": "0004030101000B0", + "TBO_0": "000", + "TBO_1": "0", + "Signature": "BC9BFD4B550C16B2B5A5ABA10B644A027B4CB03DDB46F94D992DC0FB02E0C3F", + "Counter0": "00000", + "Tearing0": "BD", + "Counter1": "00000", + "Tearing1": "BD", + "Counter2": "00000", + "Tearing2": "BD" + }, + "blocks": { + "0": "04F6542", + "1": "CAFC388", + "2": "8E48000", + "3": "E110120", + "4": "0103A00", + "5": "340300F", + "6": "0000000", + "7": "0000000", + "8": "0000000", + "9": "0000000", + "10": "0000000", + "11": "0000000", + "12": "1122334", + "13": "0000000", + "14": "0000000", + "15": "0000000", + "16": "000000F", + "17": "0005000", + "18": "0000000", + "19": "0000000" + } +} +``` diff --git a/doc/termux_notes.md b/doc/termux_notes.md index 6b3eb132c..1b1ccc75c 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -1,6 +1,27 @@ + # Proxmark 3 on Android +## Table of Contents + * [ Requirements ](#requirements) + * [ Notes ](#notes) + * [ Tested setups ](#tested-setups) + * OnePlus 5 (arm64, USB-C) + * Nexus 5X (arm64, USB-C) + * Xiaomi Mi Mix 2S (arm64, USB-C) + * OnePlus 5T (arm64, USB-C) + * Samsung Galaxy Tab S2 (arm64, MicroUSB) + * [ Setup ](#setup) + * [ Setting up Termux ](#setting-up-termux) + * [ Install Proxmark3 package ](#install-proxmark3-package) + * [ USB_ACM ](#usb_acm) + * [ Enable the driver ](#enable-the-driver) + * [ Building the kernel ](#building-the-kernel) + * [ Flashing the kernel ](#flashing-the-kernel) + * [ Testing ](#testing) + * [ Troubleshooting ](#troubleshooting) ## Requirements +^[Top](#top) + - Android phone - Kernel with one of: - USB_ACM driver @@ -10,11 +31,13 @@ - [Termux](https://play.google.com/store/apps/details?id=com.termux) ## Notes +^[Top](#top) From official Proxmark3 wiki: > In any case, you would need a USB-C to A or USB-OTG cable to connect Proxmark3 to your Android device. Some Android devices may not supply enough power (USB-OTG = 100mA), and need a USB Y-cable and external battery, otherwise they will get strange failures. ref : https://github.com/Proxmark/proxmark3/wiki/android ## Tested setups +^[Top](#top) - OnePlus 5 (arm64, USB-C) @@ -45,9 +68,17 @@ ref : https://github.com/Proxmark/proxmark3/wiki/android ## Setup +^[Top](#top) + ### Setting up Termux +^[Top](#top) + Install [Termux](https://play.google.com/store/apps/details?id=com.termux) and start it + + ### Install Proxmark3 package +^[Top](#top) + Run the following commands: ``` pkg install proxmark3 tsu @@ -61,18 +92,28 @@ make clean && make client ``` ### USB_ACM +^[Top](#top) + You need the `USB_ACM` driver enabled and working to communicate with the Proxmark3. To see if it's working, run `tsudo ls /dev/tty*` and it should list `/dev/ttyACM0` (or similar). If you see this, congratulations, skip this step! #### Enable the driver +^[Top](#top) + If your kernel has module loading enabled, you should be able to build the module separately and load it on your system without any changes. Otherwise, grab your kernel sources and edit your build config to include `CONFIG_USB_ACM=y`. On the tested kernel, this was under: `android_kernel_oneplus_msm8998/arch/arm64/configs/omni_oneplus5_defconfig` #### Building the kernel +^[Top](#top) + If using a custom kernel, refer to the build instructions provided by its maintainer. Otherwise, follow the standard Linux kernel build procedure #### Flashing the kernel +^[Top](#top) + You can flash the kernel however it suits you. On the tested device, this was achieved using [TWRP](https://twrp.me/), the most popular custom recovery ### Testing +^[Top](#top) + Open Termux and start the Proxmark3 client: ``` tsudo proxmark3/client/proxmark3 /dev/ttyACM0 @@ -80,5 +121,7 @@ tsudo proxmark3/client/proxmark3 /dev/ttyACM0 Everything should work just like if it was your PC! ### Troubleshooting +^[Top](#top) + - `dmesg | grep usb` - useful debug info - `/proc/config.gz` - contains your kernel's build configuration. Look for `CONFIG_USB_ACM`, which should be enabled diff --git a/doc/trace_notes.md b/doc/trace_notes.md index a126a238f..a95285518 100644 --- a/doc/trace_notes.md +++ b/doc/trace_notes.md @@ -1,10 +1,21 @@ -# Trace command notes + +# Notes about the tracelog + +## Table of Contents + * [Command](#trace-command) + * [File format](#tracelog-format) + * [Wireshark dissector interoperability](#trace-and-wireshark) + + +## Trace command +^[Top](#top) The `trace` command lists the data exchange by the proxmark3 and a tag or a reader in human readable form. With `trace list` a table is shown which gives timing information, the src of the data bytes, the transmitted/received bytes itself, a check if the CRC was correct and some decoding of the command. -## Timing +### Timing +^[Top](#top) The Start and the End coloumn lists timestamps when the transmission of the shown data started (time of first bit) and when it ended (end of last modulation). @@ -20,26 +31,58 @@ The unit for this time information depends on the protocol in use: By specifing the option ```f``` (e.g. ```trace list 14a f```) the frame delay times are shown. (So you don't have to do the math by your own). -## Sources +### Sources +^[Top](#top) If the data is marked as a response the source is shown as Tag. Otherwise it is marked as Reader (Rdr). -## Data +### Data +^[Top](#top) This coloumn show the raw bytes trasmitted over the air. With option ```c``` CRC bytes are marked in square brackets. -## CRC +### CRC +^[Top](#top) Marks if the transmitted CRC matches with the calculated CRC. -## Annotation +### Annotation +^[Top](#top) Annotations provide a rough decoding of the transmitted data. For ISO14443A a more detailed decoding is available with Wireshark (s. next chapter) +## Tracelog format +^[Top](#top) --- +The binary format for the dynamic tracelog is as following. -# Trace and Wireshark +``` + /* + Traceformat: + 32 bits timestamp (little endian) + 16 bits duration (little endian) + 15 bits data length (little endian) (0x7FFF) + 1 bit isResponse (0=reader to tag, 1=tag to reader) + data length Bytes data + x Bytes parity, where x == ceil(data length/8) +*/ + +typedef struct { + uint32_t timestamp; + uint16_t duration; + uint16_t data_len : 15; + bool isResponse : 1; + uint8_t frame[]; + // data_len bytes of data + // ceil(data_len/8) bytes of parity +} PACKED tracelog_hdr_t; + +#define TRACELOG_HDR_LEN sizeof(tracelog_hdr_t) +#define TRACELOG_PARITY_LEN(x) (((x)->data_len - 1) / 8 + 1) +``` + +## Trace and Wireshark +^[Top](#top) To get a more detailed explanation of the transmitted data for ISO14443A traces the output can be converted to a pcapng file to read it with [Wireshark](https://www.wireshark.org/). diff --git a/docker/archlinux/Dockerfile b/docker/archlinux/Dockerfile new file mode 100644 index 000000000..c5517c0fb --- /dev/null +++ b/docker/archlinux/Dockerfile @@ -0,0 +1,19 @@ +FROM archlinux/base + +ENV LANG C +RUN pacman -Syy +RUN pacman-db-upgrade +# qt5-base skipped +RUN pacman -S --noconfirm sudo git base-devel cmake libusb readline bzip2 arm-none-eabi-gcc arm-none-eabi-newlib --needed + +# Create rrg user +RUN useradd -ms /bin/bash rrg +RUN passwd -d rrg +RUN printf 'rrg ALL=(ALL) ALL\n' | tee -a /etc/sudoers + +USER rrg +WORKDIR "/home/rrg" + +RUN git clone https://aur.archlinux.org/package-query.git && cd package-query && makepkg -si --noconfirm --needed && cd .. && rm -rf package-query + +CMD ["/bin/bash"] diff --git a/docker/archlinux/docker_build.sh b/docker/archlinux/docker_build.sh new file mode 100755 index 000000000..be92402d6 --- /dev/null +++ b/docker/archlinux/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-arch:1.0" . diff --git a/docker/archlinux/docker_run.sh b/docker/archlinux/docker_run.sh new file mode 100755 index 000000000..eac7e1378 --- /dev/null +++ b/docker/archlinux/docker_run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-arch:1.0 diff --git a/docker/debian/Dockerfile b/docker/debian/Dockerfile new file mode 100644 index 000000000..030611739 --- /dev/null +++ b/docker/debian/Dockerfile @@ -0,0 +1,19 @@ +FROM debian:buster-slim + +ENV LANG C +ENV DEBIAN_FRONTEND noninteractive +# qtbase5-dev skipped +RUN apt-get update && \ + apt-get dist-upgrade -y && \ + apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev sudo && \ + apt-get clean + +# Create rrg user +RUN useradd -ms /bin/bash rrg +RUN passwd -d rrg +RUN printf 'rrg ALL=(ALL) ALL\n' | tee -a /etc/sudoers + +USER rrg +WORKDIR "/home/rrg" + +CMD ["/bin/bash"] diff --git a/docker/debian/docker_build.sh b/docker/debian/docker_build.sh new file mode 100755 index 000000000..b051aaf7c --- /dev/null +++ b/docker/debian/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-debian:1.0" . diff --git a/docker/debian/docker_run.sh b/docker/debian/docker_run.sh new file mode 100755 index 000000000..faf35d849 --- /dev/null +++ b/docker/debian/docker_run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-debian:1.0 diff --git a/docker/fedora/Dockerfile b/docker/fedora/Dockerfile new file mode 100644 index 000000000..db634fc0d --- /dev/null +++ b/docker/fedora/Dockerfile @@ -0,0 +1,15 @@ +FROM fedora:31 + +ENV LANG C +# qt5-qtbase-devel skipped +RUN dnf install -y passwd sudo git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel bzip2-devel bluez-libs-devel libatomic + +# Create rrg user +RUN useradd -ms /bin/bash rrg +RUN passwd -d rrg +RUN printf 'rrg ALL=(ALL) ALL\n' | tee -a /etc/sudoers + +USER rrg +WORKDIR "/home/rrg" + +CMD ["/bin/bash"] diff --git a/docker/fedora/docker_build.sh b/docker/fedora/docker_build.sh new file mode 100755 index 000000000..e4ef2258a --- /dev/null +++ b/docker/fedora/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-fedora:1.0" . diff --git a/docker/fedora/docker_run.sh b/docker/fedora/docker_run.sh new file mode 100755 index 000000000..79718b831 --- /dev/null +++ b/docker/fedora/docker_run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-fedora:1.0 diff --git a/docker/opensuse/Dockerfile b/docker/opensuse/Dockerfile new file mode 100644 index 000000000..4fa4e93a8 --- /dev/null +++ b/docker/opensuse/Dockerfile @@ -0,0 +1,16 @@ +#FROM opensuse/leap +FROM opensuse/tumbleweed + +ENV LANG C +# libqt5-qtbase-devel skipped +RUN zypper --non-interactive install --no-recommends shadow sudo git patterns-devel-base-devel_basis gcc-c++ readline-devel libbz2-devel cross-arm-none-gcc9 cross-arm-none-newlib-devel + +# Create rrg user +RUN useradd -ms /bin/bash rrg +RUN passwd -d rrg +RUN printf 'rrg ALL=(ALL) NOPASSWD: ALL\n' | tee -a /etc/sudoers + +USER rrg +WORKDIR "/home/rrg" + +CMD ["/bin/bash"] diff --git a/docker/opensuse/docker_build.sh b/docker/opensuse/docker_build.sh new file mode 100755 index 000000000..e25149697 --- /dev/null +++ b/docker/opensuse/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-suse:1.0" . diff --git a/docker/opensuse/docker_run.sh b/docker/opensuse/docker_run.sh new file mode 100755 index 000000000..9b346bf69 --- /dev/null +++ b/docker/opensuse/docker_run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-suse:1.0 diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile new file mode 100644 index 000000000..673120e0e --- /dev/null +++ b/docker/ubuntu/Dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:20.04 + +ENV LANG C +ENV DEBIAN_FRONTEND noninteractive +# qtbase5-dev skipped +RUN apt-get update && \ + apt-get dist-upgrade -y && \ + apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev sudo && \ + apt-get clean + +# Create rrg user +RUN useradd -ms /bin/bash rrg +RUN passwd -d rrg +RUN printf 'rrg ALL=(ALL) ALL\n' | tee -a /etc/sudoers + +USER rrg +WORKDIR "/home/rrg" + +CMD ["/bin/bash"] diff --git a/docker/ubuntu/docker_build.sh b/docker/ubuntu/docker_build.sh new file mode 100755 index 000000000..9c09b3aad --- /dev/null +++ b/docker/ubuntu/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-ubuntu:1.0" . diff --git a/docker/ubuntu/docker_run.sh b/docker/ubuntu/docker_run.sh new file mode 100755 index 000000000..6d43e4d15 --- /dev/null +++ b/docker/ubuntu/docker_run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-ubuntu:1.0 diff --git a/include/ansi.h b/include/ansi.h index e86a36ee4..28784ba8c 100644 --- a/include/ansi.h +++ b/include/ansi.h @@ -5,12 +5,22 @@ #define _BLUE_(s) "\x1b[34m" s AEND #define _RED_(s) "\x1b[31m" s AEND -#define _BOLD_RED_(s) "\x1b[1;31m" s AEND #define _GREEN_(s) "\x1b[32m" s AEND -#define _BOLD_GREEN_(s) "\x1b[1;32m" s AEND #define _YELLOW_(s) "\x1b[33m" s AEND #define _MAGENTA_(s) "\x1b[35m" s AEND #define _CYAN_(s) "\x1b[36m" s AEND #define _WHITE_(s) "\x1b[37m" s AEND +// https://wiki.hackzine.org/development/misc/readline-color-prompt.html +// Applications may indicate that the prompt contains +// characters that take up no physical screen space when displayed by +// bracketing a sequence of such characters with the special markers +// RL_PROMPT_START_IGNORE = '\001' and RL_PROMPT_END_IGNORE = '\002' +#define RL_ESC(a) "\001" a "\002" + +#define _RL_RED_(s) RL_ESC("\x1b[31m") s RL_ESC(AEND) +#define _RL_GREEN_(s) RL_ESC("\x1b[32m") s RL_ESC(AEND) +#define _RL_BOLD_RED_(s) RL_ESC("\x1b[1;31m") s RL_ESC(AEND) +#define _RL_BOLD_GREEN_(s) RL_ESC("\x1b[1;32m") s RL_ESC(AEND) + #endif diff --git a/include/common.h b/include/common.h index e7d6bba90..3c6245e52 100644 --- a/include/common.h +++ b/include/common.h @@ -24,18 +24,30 @@ #define PM3_USER_DIRECTORY PATHSEP ".proxmark3" PATHSEP // PM3 subdirectories: +#define PYTHON_SCRIPTS_SUBDIR "pyscripts" PATHSEP #define CMD_SCRIPTS_SUBDIR "cmdscripts" PATHSEP #define DICTIONARIES_SUBDIR "dictionaries" PATHSEP #define LUA_LIBRARIES_SUBDIR "lualibs" PATHSEP #define LUA_SCRIPTS_SUBDIR "luascripts" PATHSEP #define RESOURCES_SUBDIR "resources" PATHSEP #define TRACES_SUBDIR "traces" PATHSEP +#define LOGS_SUBDIR "logs" PATHSEP #define FIRMWARES_SUBDIR "firmware" PATHSEP -#define BOOTROM_SUBDIR "bootrom/obj" PATHSEP -#define FULLIMAGE_SUBDIR "armsrc/obj" PATHSEP +#define BOOTROM_SUBDIR "bootrom" PATHSEP "obj" PATHSEP +#define FULLIMAGE_SUBDIR "armsrc" PATHSEP "obj" PATHSEP #define PACKED __attribute__((packed)) +#define VERSION_INFORMATION_MAGIC 0x56334d50 // "PM3V" +struct version_information { + int magic; /* Magic sequence to identify this as a correct version information structure. Must be VERSION_INFORMATION_MAGIC */ + char versionversion; /* Must be 1 */ + char present; /* 1 if the version information could be created at compile time, otherwise 0 and the remaining fields (except for magic) are empty */ + char clean; /* 1: Tree was clean, no local changes. 0: Tree was unclean. 2: Couldn't be determined */ + char gitversion[50]; /* String with the git revision */ + char buildtime[30]; /* string with the build time */ +} PACKED; + // debug #define DBG_NONE 0 // no messages #define DBG_ERROR 1 // errors only @@ -58,7 +70,10 @@ extern int DBGLEVEL; #ifndef ABS # define ABS(a) ( ((a)<0) ? -(a) : (a) ) #endif -#define RAMFUNC __attribute((long_call, section(".ramfunc"))) + + +//#define RAMFUNC __attribute((long_call, section(".ramfunc"))) +#define RAMFUNC __attribute((long_call, section(".ramfunc"))) __attribute__((target("arm"))) #ifndef ROTR # define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) diff --git a/include/hitag.h b/include/hitag.h index af90c9f88..14231bdeb 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -21,8 +21,10 @@ typedef enum { RHTSF_KEY = 02, WHTSF_CHALLENGE = 03, WHTSF_KEY = 04, + HTS_LAST_CMD = WHTSF_KEY, RHT1F_PLAIN = 11, RHT1F_AUTHENTICATE = 12, + HT1_LAST_CMD = RHT1F_AUTHENTICATE, RHT2F_PASSWORD = 21, RHT2F_AUTHENTICATE = 22, RHT2F_CRYPTO = 23, @@ -30,6 +32,7 @@ typedef enum { RHT2F_TEST_AUTH_ATTEMPTS = 25, RHT2F_UID_ONLY = 26, WHT2F_PASSWORD = 27, + HT2_LAST_CMD = WHT2F_PASSWORD, } hitag_function; typedef struct { diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 6ce271aab..3cafb9df1 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -121,6 +121,20 @@ typedef struct { int32_t samples_to_skip; bool verbose; } PACKED sample_config; + +typedef struct { + uint32_t timestamp; + uint16_t duration; + uint16_t data_len : 15; + bool isResponse : 1; + uint8_t frame[]; + // data_len bytes of data + // ceil(data_len/8) bytes of parity +} PACKED tracelog_hdr_t; + +#define TRACELOG_HDR_LEN sizeof(tracelog_hdr_t) +#define TRACELOG_PARITY_LEN(x) (((x)->data_len - 1) / 8 + 1) + /* typedef struct { uint16_t start_gap; @@ -161,6 +175,7 @@ typedef struct { typedef struct { uint8_t version; uint32_t baudrate; + uint32_t bigbuf_size; bool via_fpc : 1; bool via_usb : 1; // rdv4 @@ -189,7 +204,7 @@ typedef struct { bool hw_available_flash : 1; bool hw_available_smartcard : 1; } PACKED capabilities_t; -#define CAPABILITIES_VERSION 4 +#define CAPABILITIES_VERSION 5 extern capabilities_t pm3_capabilities; // For CMD_LF_T55XX_WRITEBL @@ -613,7 +628,7 @@ typedef struct { // Initialization error pm3: error related to trying to initalize the pm3 / fpga for different operations #define PM3_EINIT -15 // Expected a different answer error client/pm3: error when expecting one answer and got another one -#define PM3_EWRONGANSVER -16 +#define PM3_EWRONGANSWER -16 // Memory out-of-bounds error client/pm3: error when a read/write is outside the expected array #define PM3_EOUTOFBOUND -17 // exchange with card error client/pm3: error when cant get answer from card or got an incorrect answer diff --git a/include/pmflash.h b/include/pmflash.h index d61b5647d..4c970a628 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -14,9 +14,6 @@ #include "common.h" -// Flashmem spi baudrate -extern uint32_t FLASHMEM_SPIBAUDRATE; - // RDV40 Section // 256kb divided into 4k sectors. // diff --git a/include/proxmark3_arm.h b/include/proxmark3_arm.h index 3ea80da9d..de3ae9caa 100644 --- a/include/proxmark3_arm.h +++ b/include/proxmark3_arm.h @@ -115,15 +115,7 @@ //NVDD goes LOW when USB is attached. #define USB_ATTACHED() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_NVDD_ON) == GPIO_NVDD_ON) -#define VERSION_INFORMATION_MAGIC 0x56334d50 // "PM3V" -struct version_information { - int magic; /* Magic sequence to identify this as a correct version information structure. Must be VERSION_INFORMATION_MAGIC */ - char versionversion; /* Must be 1 */ - char present; /* 1 if the version information could be created at compile time, otherwise 0 and the remaining fields (except for magic) are empty */ - char clean; /* 1: Tree was clean, no local changes. 0: Tree was unclean. 2: Couldn't be determined */ - char gitversion[50]; /* String with the git revision */ - char buildtime[30]; /* string with the build time */ -} PACKED; +// VERSION_INFORMATION is now in common.h #define COMMON_AREA_MAGIC 0x43334d50 // "PM3C" #define COMMON_AREA_COMMAND_NONE 0 diff --git a/pm3 b/pm3 index 52b434e13..771dce77d 100755 --- a/pm3 +++ b/pm3 @@ -2,10 +2,12 @@ # Usage: run option -h to get help -# BT auto detection: only working under Linux at the moment +# BT auto detection # Shall we look for white HC-06-USB dongle ? FINDBTDONGLE=true # Shall we look for rfcomm interface ? +FINDBTRFCOMM=true +# Shall we look for registered BT device ? (Linux only) FINDBTDIRECT=true PM3PATH=$(dirname "$0") @@ -28,49 +30,80 @@ SHOWLIST=false function get_pm3_list_Linux { N=$1 PM3LIST=() + if [ ! -c "/dev/tty0" ]; then + echo >&2 "[!!] Script cannot access /dev/ttyXXX files, insufficient privileges" + exit 1 + fi for DEV in $(find /dev/ttyACM* 2>/dev/null); do - if udevadm info -q property -n "$DEV" |grep -q "ID_VENDOR=proxmark.org"; then - PM3LIST+=("$DEV") - if [ ${#PM3LIST[*]} -ge $N ]; then - return + if which udevadm >/dev/null; then + if udevadm info -q property -n "$DEV" | grep -q "ID_VENDOR=proxmark.org"; then + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi + fi + else + if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi fi fi done if $FINDBTDONGLE; then # check if the HC-06-USB white dongle is present (still, that doesn't tell us if it's paired with a Proxmark3...) for DEV in $(find /dev/ttyUSB* 2>/dev/null); do - if udevadm info -q property -n "$DEV" |grep -q "ID_MODEL=CP2104_USB_to_UART_Bridge_Controller"; then - PM3LIST+=("$DEV") - if [ ${#PM3LIST[*]} -ge $N ]; then + if which udevadm >/dev/null; then + if udevadm info -q property -n "$DEV" | grep -q "ID_MODEL=CP2104_USB_to_UART_Bridge_Controller"; then + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi + fi + else + if grep -q "DRIVER=cp210x" "/sys/class/tty/${DEV#/dev/}/../../uevent" 2>/dev/null; then + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi + fi + fi + done + fi + if $FINDBTRFCOMM; then + # check if the MAC of a Proxmark3 was bound to a local rfcomm interface + # (on OSes without deprecated rfcomm and hcitool, the loop will be simply skipped) + for DEVMAC in $(rfcomm -a 2>/dev/null | grep " 20:19:0[45]" | sed 's/^\(.*\): \([0-9:]*\) .*/\1@\2/'); do + DEV=${DEVMAC/@*/} + MAC=${DEVMAC/*@/} + # check which are Proxmark3 and, side-effect, if they're actually present + if hcitool name "$MAC" | grep -q "PM3"; then + PM3LIST+=("/dev/$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then return fi fi done fi if $FINDBTDIRECT; then - # check if the MAC of a Proxmark3 was bound to a local rfcomm interface - for DEVMAC in $(rfcomm -a|grep " 20:19:0[45]"|sed 's/^\(.*\): \([0-9:]*\) .*/\1@\2/'); do - DEV=${DEVMAC/@*/} - MAC=${DEVMAC/*@/} - # check if Proxmark3 is actually present - if hcitool name "$MAC" | grep -q "PM3"; then - PM3LIST+=("/dev/$DEV") - if [ ${#PM3LIST[*]} -ge $N ]; then - return - fi - fi + # check if the MAC of a Proxmark3 was registered in the known devices + for MAC in $(dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/' org.freedesktop.DBus.ObjectManager.GetManagedObjects 2>/dev/null|\ + awk '/"Address"/{getline;gsub(/"/,"",$3);a=$3}/Name/{getline;if (/PM3_RDV4/) print a}'); do + PM3LIST+=("bt:$MAC") done + # we don't probe the device so there is no guarantee the device is actually present fi } function get_pm3_list_macOS { N=$1 PM3LIST=() - for DEV in $(ioreg -r -c "IOUSBHostDevice" -l|awk -F '"' ' + for DEV in $(ioreg -r -c "IOUSBHostDevice" -l | awk -F '"' ' $2=="USB Vendor Name"{b=($4=="proxmark.org")} b==1 && $2=="IODialinDevice"{print $4}'); do PM3LIST+=("$DEV") - if [ ${#PM3LIST[*]} -ge $N ]; then + if [ ${#PM3LIST[*]} -ge "$N" ]; then return fi done @@ -79,32 +112,101 @@ function get_pm3_list_macOS { function get_pm3_list_Windows { N=$1 PM3LIST=() - for DEV in $(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null|awk '/^COM/{print $1}'); do + # Need to look for this first, the call to Win32_serialport "crashes" then native bt serial port. Don't ask why. + #BT direct SERIAL PORTS (COM) + if $FINDBTRFCOMM; then + for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_PnPEntity | Where-Object Caption -like 'Standard Serial over Bluetooth link (COM*' | Select Name" 2> /dev/null | awk 'match($0,/COM([0-9]+)/,m){print m[1]}'); do + DEV=${DEV/ */} + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi + done + fi + + # Normal SERIAL PORTS (COM) + for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_9AC4&PID_4B8F*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do DEV=${DEV/ */} PM3LIST+=("$DEV") - if [ ${#PM3LIST[*]} -ge $N ]; then + if [ ${#PM3LIST[*]} -ge "$N" ]; then return fi done + + #white BT dongle SERIAL PORTS (COM) + if $FINDBTDONGLE; then + for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_10C4&PID_EA60*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do + DEV=${DEV/ */} + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi + done + fi } function get_pm3_list_WSL { + N=$1 PM3LIST=() - for DEV in $(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null|awk '/^COM/{print $1}'); do + + # Need to look for this first, the call to Win32_serialport "crashes" then native bt serial port. Don't ask why. + #BT direct SERIAL PORTS (COM) + if $FINDBTRFCOMM; then + for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_PnPEntity | Where-Object Caption -like 'Standard Serial over Bluetooth link (COM*' | Select Name" 2> /dev/null | awk 'match($0,/COM([0-9]+)/,m){print m[1]}'); do + + DEV=${DEV/ */} + DEV="/dev/ttyS${DEV#COM}" + # ttyS counterpart takes some more time to appear + if [ -e "$DEV" ]; then + PM3LIST+=("$DEV") + if [ ! -w "$DEV" ]; then + echo "[!] Let's give users read/write access to $DEV" + sudo chmod 666 "$DEV" + fi + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi + fi + + done + fi + + # Normal SERIAL PORTS (COM) + for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_9AC4&PID_4B8F*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do DEV=${DEV/ */} DEV="/dev/ttyS${DEV#COM}" # ttyS counterpart takes some more time to appear if [ -e "$DEV" ]; then PM3LIST+=("$DEV") if [ ! -w "$DEV" ]; then - echo "[!!] Let's give users read/write access to $DEV" + echo "[!] Let's give users read/write access to $DEV" sudo chmod 666 "$DEV" fi - if [ ${#PM3LIST[*]} -ge $N ]; then + if [ ${#PM3LIST[*]} -ge "$N" ]; then return fi fi done + + #white BT dongle SERIAL PORTS (COM) + if $FINDBTDONGLE; then + for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_10C4&PID_EA60*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do + DEV=${DEV/ */} + DEV="/dev/ttyS${DEV#COM}" + # ttyS counterpart takes some more time to appear + if [ -e "$DEV" ]; then + PM3LIST+=("$DEV") + if [ ! -w "$DEV" ]; then + echo "[!] Let's give users read/write access to $DEV" + sudo chmod 666 "$DEV" + fi + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi + fi + + done + fi } SCRIPT=$(basename -- "$0") @@ -113,25 +215,46 @@ if [ "$SCRIPT" = "pm3" ]; then CMD() { $CLIENT "$@"; } HELP() { cat << EOF -Quick helper script for proxmark3 client when working with a Proxmark3 device connected via USB + +Quick helper script for proxmark3 client when working with a Proxmark3 device Description: The usage is the same as for the proxmark3 client, with the following differences: * the correct port name will be automatically guessed; * the script will wait for a Proxmark to be connected (same as option -w of the client). - You can also specify a first option -n N to access the Nth Proxmark3 connected on USB. - Don't use this script if you want to work offline or with the BT addon. + You can also specify a first option -n N to access the Nth Proxmark3 connected. + Don't use this script if you want to work offline. To see a list of available ports, use --list. Usage: $SCRIPT [-n ] [-f] [-c ]|[-l ]|[-s ] [-i] - $SCRIPT --list + $SCRIPT [--list] [--help] + + +Arguments: + --help this help + --list list all detected com ports + -n connect device refered to the N:th number on the --list output + -c 'cmd' execute the pm3 cmd in client and exit afterwards + -i interactive, stay in client after executing a cmd or script + -s 'script' execute a cmd script file and exit afterwards + -l 'luascript' execute a lua script file and exit afterwards + -w wait + -p specifiy which port to connect to + + +Samples: + ./$SCRIPT -- Auto detect/ select com port in the following order BT, USB/CDC, BT DONGLE + ./$SCRIPT -p /dev/ttyACM0 -- connect to port /dev/ttyACM0 + ./$SCRIPT -n 2 -- use second item from the --list output + ./$SCRIPT -c 'lf search' -i -- run command and stay in client once completed + -See "$CLIENT -h" for more details on options. EOF } elif [ "$SCRIPT" = "pm3-flash" ]; then FINDBTDONGLE=false + FINDBTRFCOMM=false FINDBTDIRECT=false CMD() { ARGS=("--port" "$1" "--flash") @@ -144,7 +267,7 @@ elif [ "$SCRIPT" = "pm3-flash" ]; then fi shift; done - $CLIENT ${ARGS[@]}; + $CLIENT "${ARGS[@]}"; } HELP() { cat << EOF @@ -169,6 +292,7 @@ EOF } elif [ "$SCRIPT" = "pm3-flash-all" ]; then FINDBTDONGLE=false + FINDBTRFCOMM=false FINDBTDIRECT=false CMD() { $CLIENT "--port" "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; } HELP() { @@ -188,6 +312,7 @@ EOF } elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then FINDBTDONGLE=false + FINDBTRFCOMM=false FINDBTDIRECT=false CMD() { $CLIENT "--port" "$1" "--flash" "--image" "$FULLIMAGE"; } HELP() { @@ -207,6 +332,7 @@ EOF } elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then FINDBTDONGLE=false + FINDBTRFCOMM=false FINDBTDIRECT=false CMD() { $CLIENT "--port" "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; } HELP() { @@ -225,7 +351,7 @@ Usage: EOF } else - echo "[!!] Script ran under unknown name, abort: $SCRIPT" + echo >&2 "[!!] Script ran under unknown name, abort: $SCRIPT" exit 1 fi if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then @@ -244,7 +370,7 @@ done if [ "$1" == "--list" ]; then shift if [ "$1" != "" ]; then - echo "Option --list must be used alone" + echo >&2 "[!!] Option --list must be used alone" exit 1 fi SHOWLIST=true @@ -258,7 +384,7 @@ if [ "$1" == "-n" ]; then N=$1 shift else - echo "Option -n requires a number between 1 and 9, got \"$1\"" + echo >&2 "[!!] Option -n requires a number between 1 and 9, got \"$1\"" exit 1 fi fi @@ -267,9 +393,8 @@ HOSTOS=$(uname | awk '{print toupper($0)}') if [ "$HOSTOS" = "LINUX" ]; then if uname -a|grep -q Microsoft; then # Test presence of wmic - wmic.exe computersystem get name >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "[!] Cannot run wmic.exe, are you sure your WSL is authorized to run Windows processes? (cf WSL interop flag)" + if ! wmic.exe computersystem get name >/dev/null 2>&1; then + echo >&2 "[!!] Cannot run wmic.exe, are you sure your WSL is authorized to run Windows processes? (cf WSL interop flag)" exit 1 fi GETPM3LIST=get_pm3_list_WSL @@ -281,7 +406,7 @@ elif [ "$HOSTOS" = "DARWIN" ]; then elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then GETPM3LIST=get_pm3_list_Windows else - echo "[!!] Host OS not recognized, abort: $HOSTOS" + echo >&2 "[!!] Host OS not recognized, abort: $HOSTOS" exit 1 fi @@ -289,11 +414,11 @@ if $SHOWLIST; then # Probe for up to 9 devs $GETPM3LIST 9 if [ ${#PM3LIST} -lt 1 ]; then - echo "[!!] No port found" - exit 0 + echo >&2 "[!!] No port found" + exit 1 fi n=1 - for DEV in ${PM3LIST[@]} + for DEV in "${PM3LIST[@]}" do echo "$n: $DEV" n=$((n+1)) @@ -302,20 +427,29 @@ if $SHOWLIST; then fi # Wait till we get at least N proxmark3 devices -$GETPM3LIST $N -if [ ${#PM3LIST} -lt $N ]; then +$GETPM3LIST "$N" +if [ ${#PM3LIST} -lt "$N" ]; then echo >&2 "[=] Waiting for Proxmark3 to appear..." fi while true; do - if [ ${#PM3LIST[*]} -ge $N ]; then + if [ ${#PM3LIST[*]} -ge "$N" ]; then break fi sleep .1 - $GETPM3LIST $N + $GETPM3LIST "$N" done -if [ ${#PM3LIST} -lt $N ]; then - echo "[!!] No port found, abort" +if [ ${#PM3LIST} -lt "$N" ]; then + HELP() { + cat << EOF +[!!] No port found, abort + +[?] Hint: try '$SCRIPT --list' to see list of available ports, and use the -n command like below +[?] $SCRIPT [-n ] + +EOF + } + HELP exit 1 fi diff --git a/pm3test.sh b/pm3test.sh deleted file mode 100755 index be9331358..000000000 --- a/pm3test.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 - -if [ "$1" == "client" ]; then - shift - TESTDEVICE=false - TESTTOOLS=false -else - TESTDEVICE=true - TESTTOOLS=true -fi -if [ "$1" == "long" ]; then - shift - SLOWTESTS=true -else - SLOWTESTS=false -fi - -C_RED='\033[0;31m' -C_GREEN='\033[0;32m' -C_YELLOW='\033[0;33m' -C_BLUE='\033[0;34m' -C_NC='\033[0m' # No Color - -# title, file name or file wildcard to check -function CheckFileExist() { - - if [ -f "$2" ]; then - echo -e "$1 ${C_GREEN}[OK]${C_NC}" - return 0 - fi - - if ls $2 1> /dev/null 2>&1; then - echo -e "$1 ${C_GREEN}[OK]${C_NC}" - return 0 - fi - - echo -e "$1 ${C_RED}[Fail]${C_NC}" - return 1 -} - -# title, command line, check result, repeat several times if failed, ignore if fail -function CheckExecute() { - - if [ $4 ]; then - local RETRY="1 2 3 e" - else - local RETRY="e" - fi - - for I in $RETRY - do - RES=$(eval "$2") - if echo "$RES" | grep -q "$3"; then - echo -e "$1 ${C_GREEN}[OK]${C_NC}" - return 0 - fi - if [ ! $I == "e" ]; then echo "retry $I"; fi - done - - - if [ $5 ]; then - echo -e "$1 ${C_YELLOW}[Ignored]${C_NC}" - return 0 - fi - - echo -e "$1 ${C_RED}[Fail]${C_NC}" - echo -e "Execution trace:\n$RES" - return 1 -} - -printf "\n${C_BLUE}RRG/Iceman Proxmark3 test tool ${C_NC}\n\n" - -printf "work directory: " -pwd -printf "client ${PM3BIN:="./client/proxmark3"}\n" - -if [ "$TRAVIS_COMMIT" ]; then - if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then - echo "Travis branch: $TRAVIS_BRANCH slug: $TRAVIS_REPO_SLUG commit: $TRAVIS_COMMIT" - else - echo "Travis pull request: $TRAVIS_PULL_REQUEST branch: $TRAVIS_BRANCH slug: $TRAVIS_PULL_REQUEST_SLUG commit: $TRAVIS_COMMIT" - fi -fi - -printf "git branch: " -git describe --all -printf "git sha: " -git rev-parse HEAD -echo "" - -while true; do - printf "\n${C_BLUE}Testing files:${C_NC}\n" - if ! CheckFileExist "proxmark3 exists" "$PM3BIN"; then break; fi - if ! CheckFileExist "hardnested tables exists" "./client/resources/hardnested_tables/*.z"; then break; fi - if $TESTDEVICE; then - if ! CheckFileExist "arm image exists" "./armsrc/obj/fullimage.elf"; then break; fi - if ! CheckFileExist "bootrom exists" "./bootrom/obj/bootrom.elf"; then break; fi - fi - - printf "\n${C_BLUE}Testing basic help:${C_NC}\n" - if ! CheckExecute "proxmark help" "$PM3BIN -h" "wait"; then break; fi - if ! CheckExecute "proxmark help text ISO7816" "$PM3BIN -t 2>&1" "ISO7816"; then break; fi - if ! CheckExecute "proxmark help text hardnested" "$PM3BIN -t 2>&1" "hardnested"; then break; fi - - printf "\n${C_BLUE}Testing data manipulation:${C_NC}\n" - if ! CheckExecute "reveng test" "$PM3BIN -c 'reveng -w 8 -s 01020304e3 010204039d'" "CRC-8/SMBUS"; then break; fi - if ! CheckExecute "mfu pwdgen test" "$PM3BIN -c 'hf mfu pwdgen t'" "Selftest OK"; then break; fi - - printf "\n${C_BLUE}Testing LF:${C_NC}\n" - if ! CheckExecute "lf em4x05 test" "$PM3BIN -c 'data load traces/em4x05.pm3;lf search 1'" "FDX-B ID found"; then break; fi - if ! CheckExecute "lf em410x test" "$PM3BIN -c 'data load traces/EM4102-1.pm3;lf search 1'" "EM410x ID found"; then break; fi - if ! CheckExecute "lf visa2000 test" "$PM3BIN -c 'data load traces/visa2000.pm3;lf search 1'" "Visa2000 ID found"; then break; fi - if ! CheckExecute "lf awid test" "$PM3BIN -c 'data load traces/AWID-15-259.pm3;lf search 1'" "AWID ID found"; then break; fi - if ! CheckExecute "lf securakey test" "$PM3BIN -c 'data load traces/securakey-64169.pm3;lf search 1 '" "Securakey ID found"; then break; fi - if ! CheckExecute "lf keri test" "$PM3BIN -c 'data load traces/keri.pm3;lf search 1'" "Pyramid ID found"; then break; fi - if ! CheckExecute "lf HID Prox test" "$PM3BIN -c 'data load traces/hid-proxCardII-05512-11432784-1.pm3;lf search 1'" "HID Prox ID found"; then break; fi - if ! CheckExecute "lf Paradox test" "$PM3BIN -c 'data load traces/Paradox-96_40426-APJN08.pm3;lf search 1'" "Paradox ID found"; then break; fi - if ! CheckExecute "lf IO Prox test" "$PM3BIN -c 'data load traces/ioprox-XSF-01-3B-44725.pm3;lf search 1'" "IO Prox ID found"; then break; fi - - printf "\n${C_BLUE}Testing HF:${C_NC}\n" - if ! CheckExecute "hf mf offline text" "$PM3BIN -c 'hf mf'" "at_enc"; then break; fi - if $SLOWTESTS; then - if ! CheckExecute "hf mf hardnested test" "$PM3BIN -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi - if ! CheckExecute "hf iclass test" "$PM3BIN -c 'hf iclass loclass t l'" "verified ok"; then break; fi - if ! CheckExecute "emv test" "$PM3BIN -c 'emv test -l'" "Test(s) \[ OK"; then break; fi - else - if ! CheckExecute "hf iclass test" "$PM3BIN -c 'hf iclass loclass t'" "OK!"; then break; fi - if ! CheckExecute "emv test" "$PM3BIN -c 'emv test'" "Test(s) \[ OK"; then break; fi - fi - - if $TESTTOOLS; then - printf "\n${C_BLUE}Testing tools:${C_NC}\n" - # Need a decent example for mfkey32... - if ! CheckExecute "mfkey32v2 test" "tools/mfkey/mfkey32v2 12345678 1AD8DF2B 1D316024 620EF048 30D6CB07 C52077E2 837AC61A" "Found Key: \[a0a1a2a3a4a5\]"; then break; fi - if ! CheckExecute "mfkey64 test" "tools/mfkey/mfkey64 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439" "Found Key: \[ffffffffffff\]"; then break; fi - if ! CheckExecute "mfkey64 long trace test" "tools/mfkey/./mfkey64 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea" "Found Key: \[091e639cb715\]"; then break; fi - if ! CheckExecute "nonce2key test" "tools/nonce2key/nonce2key e9cadd9c a8bf4a12 a020a8285858b090 050f010607060e07 5693be6c00000000" "key recovered: fc00018778f7"; then break; fi - if ! CheckExecute "xorcheck test" "tools/xorcheck.py 04 00 80 64 ba" "final LRC XOR byte value: 5A"; then break; fi - if ! CheckExecute "findbits test" "tools/findbits.py 73 0110010101110011" "Match at bit 9: 011001010"; then break; fi - if ! CheckExecute "findbits_test test" "tools/findbits_test.py 2>&1" "OK"; then break; fi - if ! CheckExecute "pm3_eml_mfd test" "tools/pm3_eml_mfd_test.py 2>&1" "OK"; then break; fi - fi - - printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" - exit 0 -done - -printf "\n${C_RED}Tests [FAIL]${C_NC}\n\n" -exit 1 diff --git a/tools/Makefile b/tools/Makefile index 5f2355f20..df6a0682f 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -11,10 +11,6 @@ get_crapto1: $(WGET) http://crapto1.netgarage.org/crapto1-v3.3.tar.xz $(TAR) Jxvf crapto1-v3.3.tar.xz -C crapto1-v3.3 -get_nonce_bf: -# $(GIT) https://github.com/J-Run/mf_key_brute.git mf_key_brute - $(GIT) https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute - get_xorsearch: $(MKDIR) xorsearch $(WGET) https://didierstevens.com/files/software/XORSearch_V1_11_2.zip diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile index 5452f9083..4a97776b2 100644 --- a/tools/fpga_compress/Makefile +++ b/tools/fpga_compress/Makefile @@ -5,9 +5,10 @@ MYDEFS = MYSRCS = MYLIBS = -ZLIBPATH = ../../common/zlib -MYINCLUDES += -I$(ZLIBPATH) -MYLIBS += $(OBJDIR)/libz.a +MYSRCPATHS += ../../common/lz4 +MYINCLUDES += -I../../common/lz4 +MYSRCS += lz4hc.c lz4.c +MYCFLAGS += -DLZ4_MEMORY_USAGE=20 -Wno-redundant-decls -Wno-old-style-definition -Wno-missing-prototypes -Wno-missing-declarations BINS = fpga_compress @@ -16,9 +17,6 @@ ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) include ../../Makefile.host fpga_compress: $(OBJDIR)/fpga_compress.o $(MYOBJS) -$(OBJDIR)/libz.a: - $(info [*] MAKE zlib) - $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index 0992c53ca..b03caabf4 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -7,7 +7,7 @@ //----------------------------------------------------------------------------- // Compression tool for FPGA config files. Compress several *.bit files at // compile time. Decompression is done at run time (see fpgaloader.c). -// This uses the zlib library tuned to this specific case. The small file sizes +// This uses the lz4 library tuned to this specific case. The small file sizes // allow to use "insane" parameters for optimum compression ratio. //----------------------------------------------------------------------------- @@ -15,30 +15,11 @@ #include #include #include +#include +#include +#include #include "fpga.h" -#include "zlib.h" - -// zlib configuration -#define COMPRESS_LEVEL 9 // use best possible compression -#define COMPRESS_WINDOW_BITS 15 // default = max = 15 for a window of 2^15 = 32KBytes -#define COMPRESS_MEM_LEVEL 9 // determines the amount of memory allocated during compression. Default = 8. - -/* COMPRESS_STRATEGY can be - Z_DEFAULT_STRATEGY (the default), - Z_FILTERED (more huffmann, less string matching), - Z_HUFFMAN_ONLY (huffman only, no string matching) - Z_RLE (distances limited to one) - Z_FIXED (prevents the use of dynamic Huffman codes) -*/ - -#define COMPRESS_STRATEGY Z_DEFAULT_STRATEGY -// zlib tuning parameters: -#define COMPRESS_GOOD_LENGTH 258 -#define COMPRESS_MAX_LAZY 258 -#define COMPRESS_MAX_NICE_LENGTH 258 -#define COMPRESS_MAX_CHAIN 8192 - -#define HARDNESTED_TABLE_SIZE (uint32_t)(sizeof(uint32_t) * ((1L<<19)+1)) +#include "lz4hc.h" static void usage(void) { fprintf(stdout, "Usage: fpga_compress ... \n"); @@ -47,23 +28,8 @@ static void usage(void) { fprintf(stdout, " Extract Version Information from FPGA bitstream files and write it to \n\n"); fprintf(stdout, " fpga_compress -d \n"); fprintf(stdout, " Decompress . Write result to \n\n"); - fprintf(stdout, " fpga_compress -t \n"); - fprintf(stdout, " Compress hardnested table . Write result to \n\n"); } - -static voidpf fpga_deflate_malloc(voidpf opaque, uInt items, uInt size) { - (void) opaque; - return calloc(items * size, sizeof(uint8_t)); -} - - -static void fpga_deflate_free(voidpf opaque, voidpf address) { - (void) opaque; - free(address); -} - - static bool all_feof(FILE *infile[], uint8_t num_infiles) { for (uint16_t i = 0; i < num_infiles; i++) { if (!feof(infile[i])) { @@ -73,34 +39,18 @@ static bool all_feof(FILE *infile[], uint8_t num_infiles) { return true; } - -static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardnested_mode) { +static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) { uint8_t *fpga_config; - uint32_t i; - int32_t ret; - uint8_t c; - z_stream compressed_fpga_stream; - if (hardnested_mode) { - fpga_config = calloc(num_infiles * HARDNESTED_TABLE_SIZE, sizeof(uint8_t)); - } else { - fpga_config = calloc(num_infiles * FPGA_CONFIG_SIZE, sizeof(uint8_t)); - } + fpga_config = calloc(num_infiles * FPGA_CONFIG_SIZE, sizeof(uint8_t)); // read the input files. Interleave them into fpga_config[] - i = 0; + uint32_t total_size = 0; do { - if (i >= num_infiles * (hardnested_mode ? HARDNESTED_TABLE_SIZE : FPGA_CONFIG_SIZE)) { - if (hardnested_mode) { - fprintf(stderr, - "Input file too big (> %" PRIu32 " bytes). This is probably not a hardnested bitflip state table.\n" - , HARDNESTED_TABLE_SIZE); - - } else { - fprintf(stderr, - "Input files too big (total > %li bytes). These are probably not PM3 FPGA config files.\n" - , num_infiles * FPGA_CONFIG_SIZE); - } + if (total_size >= num_infiles * FPGA_CONFIG_SIZE) { + fprintf(stderr, + "Input files too big (total > %li bytes). These are probably not PM3 FPGA config files.\n" + , num_infiles * FPGA_CONFIG_SIZE); for (uint16_t j = 0; j < num_infiles; j++) { fclose(infile[j]); } @@ -110,147 +60,124 @@ static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, boo for (uint16_t j = 0; j < num_infiles; j++) { for (uint16_t k = 0; k < FPGA_INTERLEAVE_SIZE; k++) { - c = (uint8_t)fgetc(infile[j]); + uint8_t c = (uint8_t)fgetc(infile[j]); + if (!feof(infile[j])) { - fpga_config[i++] = c; + fpga_config[total_size++] = c; } else if (num_infiles > 1) { - fpga_config[i++] = '\0'; + fpga_config[total_size++] = '\0'; } } } } while (!all_feof(infile, num_infiles)); - // initialize zlib structures - compressed_fpga_stream.next_in = fpga_config; - compressed_fpga_stream.avail_in = i; - compressed_fpga_stream.zalloc = fpga_deflate_malloc; - compressed_fpga_stream.zfree = fpga_deflate_free; - compressed_fpga_stream.opaque = Z_NULL; + uint32_t buffer_size = FPGA_RING_BUFFER_BYTES; - ret = deflateInit2(&compressed_fpga_stream, - COMPRESS_LEVEL, - Z_DEFLATED, - COMPRESS_WINDOW_BITS, - COMPRESS_MEM_LEVEL, - COMPRESS_STRATEGY); + if (num_infiles == 1) + buffer_size = 1024 * 1024; //1M for now - // estimate the size of the compressed output - uint32_t outsize_max = deflateBound(&compressed_fpga_stream, compressed_fpga_stream.avail_in); - uint8_t *outbuf = calloc(outsize_max, sizeof(uint8_t)); - compressed_fpga_stream.next_out = outbuf; - compressed_fpga_stream.avail_out = outsize_max; + uint32_t outsize_max = LZ4_compressBound(buffer_size); - if (ret == Z_OK) { - ret = deflateTune(&compressed_fpga_stream, - COMPRESS_GOOD_LENGTH, - COMPRESS_MAX_LAZY, - COMPRESS_MAX_NICE_LENGTH, - COMPRESS_MAX_CHAIN); - } - - if (ret == Z_OK) { - ret = deflate(&compressed_fpga_stream, Z_FINISH); - } - - fprintf(stdout, "compressed %u input bytes to %lu output bytes\n", i, compressed_fpga_stream.total_out); - - if (ret != Z_STREAM_END) { - fprintf(stderr, "Error in deflate(): %d %s\n", ret, compressed_fpga_stream.msg); - free(outbuf); - deflateEnd(&compressed_fpga_stream); - for (uint16_t j = 0; j < num_infiles; j++) { - fclose(infile[j]); - } - fclose(outfile); - free(fpga_config); - return (EXIT_FAILURE); - } - - for (i = 0; i < compressed_fpga_stream.total_out; i++) { - fputc(outbuf[i], outfile); + char *outbuf = calloc(outsize_max, sizeof(char)); + + LZ4_streamHC_t *lz4_streamhc = LZ4_createStreamHC(); + LZ4_resetStreamHC_fast(lz4_streamhc, LZ4HC_CLEVEL_MAX); + + int current_in = 0; + int current_out = 0; + char *ring_buffer = calloc(buffer_size, sizeof(char)); + while (current_in < total_size) { + int bytes_to_copy = FPGA_RING_BUFFER_BYTES; + if (total_size - current_in < FPGA_RING_BUFFER_BYTES) + bytes_to_copy = total_size - current_in; + + memcpy(ring_buffer, fpga_config + current_in, bytes_to_copy); + int cmp_bytes = LZ4_compress_HC_continue(lz4_streamhc, ring_buffer, outbuf, bytes_to_copy, outsize_max); + + fwrite(&cmp_bytes, sizeof(int), 1, outfile); + fwrite(outbuf, sizeof(char), cmp_bytes, outfile); + + current_in += bytes_to_copy; + current_out += cmp_bytes; } + free(ring_buffer); free(outbuf); - deflateEnd(&compressed_fpga_stream); + free(fpga_config); + + fclose(outfile); for (uint16_t j = 0; j < num_infiles; j++) { fclose(infile[j]); } - fclose(outfile); - free(fpga_config); + LZ4_freeStreamHC(lz4_streamhc); + fprintf(stdout, "compressed %u input bytes to %u output bytes\n", total_size, current_out); + + if (current_out == 0) { + fprintf(stderr, "Error in lz4"); + return (EXIT_FAILURE); + } return (EXIT_SUCCESS); - } +typedef struct lz4_stream_s { + LZ4_streamDecode_t *lz4StreamDecode; + char *next_in; + int avail_in; +} lz4_stream; static int zlib_decompress(FILE *infile, FILE *outfile) { -#define DECOMPRESS_BUF_SIZE 1024 - uint8_t outbuf[DECOMPRESS_BUF_SIZE]; - uint8_t inbuf[DECOMPRESS_BUF_SIZE]; - int32_t ret; - z_stream compressed_fpga_stream; + LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }}; + char outbuf[FPGA_RING_BUFFER_BYTES]; - // initialize zlib structures - compressed_fpga_stream.next_in = inbuf; - compressed_fpga_stream.avail_in = 0; - compressed_fpga_stream.next_out = outbuf; - compressed_fpga_stream.avail_out = DECOMPRESS_BUF_SIZE; - compressed_fpga_stream.zalloc = fpga_deflate_malloc; - compressed_fpga_stream.zfree = fpga_deflate_free; - compressed_fpga_stream.opaque = Z_NULL; + fseek(infile, 0L, SEEK_END); + long infile_size = ftell(infile); + fseek(infile, 0L, SEEK_SET); - ret = inflateInit2(&compressed_fpga_stream, 0); - if (ret < 0) - return (EXIT_FAILURE); - - do { - if (compressed_fpga_stream.avail_in == 0) { - compressed_fpga_stream.next_in = inbuf; - uint16_t i = 0; - do { - int32_t c = fgetc(infile); - if (!feof(infile)) { - inbuf[i++] = c & 0xFF; - compressed_fpga_stream.avail_in++; - } else { - break; - } - } while (i < DECOMPRESS_BUF_SIZE); - } - - ret = inflate(&compressed_fpga_stream, Z_SYNC_FLUSH); - - if (ret != Z_OK && ret != Z_STREAM_END) { - break; - } - - if (compressed_fpga_stream.avail_out == 0) { - for (uint16_t i = 0; i < DECOMPRESS_BUF_SIZE; i++) { - fputc(outbuf[i], outfile); - } - compressed_fpga_stream.avail_out = DECOMPRESS_BUF_SIZE; - compressed_fpga_stream.next_out = outbuf; - } - } while (ret == Z_OK); - - if (ret == Z_STREAM_END) { // reached end of input - uint16_t i = 0; - while (compressed_fpga_stream.avail_out < DECOMPRESS_BUF_SIZE) { - fputc(outbuf[i++], outfile); - compressed_fpga_stream.avail_out++; - } - fclose(outfile); - fclose(infile); - return (EXIT_SUCCESS); - } else { - fprintf(stderr, "Error. Inflate() returned error %d, %s", ret, compressed_fpga_stream.msg); + if (infile_size <= 0) { + printf("error, when getting filesize"); fclose(outfile); fclose(infile); return (EXIT_FAILURE); } + char *inbuf = calloc(infile_size, sizeof(char)); + size_t num_read = fread(inbuf, sizeof(char), infile_size, infile); + + if (num_read != infile_size) { + fclose(outfile); + fclose(infile); + free(inbuf); + return (EXIT_FAILURE); + } + + lz4_stream compressed_fpga_stream; + // initialize lz4 structures + compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body; + compressed_fpga_stream.next_in = inbuf; + compressed_fpga_stream.avail_in = infile_size; + + int total_size = 0; + while (compressed_fpga_stream.avail_in > 0) { + int cmp_bytes; + memcpy(&cmp_bytes, compressed_fpga_stream.next_in, sizeof(int)); + compressed_fpga_stream.next_in += 4; + compressed_fpga_stream.avail_in -= cmp_bytes + 4; + const int decBytes = LZ4_decompress_safe_continue(compressed_fpga_stream.lz4StreamDecode, compressed_fpga_stream.next_in, outbuf, cmp_bytes, FPGA_RING_BUFFER_BYTES); + if (decBytes <= 0) { + break; + } + fwrite(outbuf, decBytes, sizeof(char), outfile); + total_size += decBytes; + compressed_fpga_stream.next_in += cmp_bytes; + } + printf("uncompressed %li input bytes to %i output bytes\n", infile_size, total_size); + fclose(outfile); + fclose(infile); + free(inbuf); + return (EXIT_SUCCESS); } @@ -376,10 +303,10 @@ static void print_version_info_preamble(FILE *outfile, int num_infiles) { fprintf(outfile, "//\n"); fprintf(outfile, "// This file is generated by fpga_compress. Don't edit!\n"); fprintf(outfile, "//-----------------------------------------------------------------------------\n"); - fprintf(outfile, "\n"); - fprintf(outfile, "\n"); - fprintf(outfile, "const int fpga_bitstream_num = %d;\n", num_infiles); - fprintf(outfile, "const char *const fpga_version_information[%d] = {\n", num_infiles); + fprintf(outfile, "// slurdge, 2020\n"); + fprintf(outfile, "\n\n"); + fprintf(outfile, "const int g_fpga_bitstream_num = %d;\n", num_infiles); + fprintf(outfile, "const char *const g_fpga_version_information[%d] = {\n", num_infiles); } static int generate_fpga_version_info(FILE *infile[], char *infile_names[], int num_infiles, FILE *outfile) { @@ -433,17 +360,9 @@ int main(int argc, char **argv) { } else { // Compress or generate version info - bool hardnested_mode = false; bool generate_version_file = false; int num_input_files = 0; - if (!strcmp(argv[1], "-t")) { // compress one hardnested table - if (argc != 4) { - usage(); - return (EXIT_FAILURE); - } - hardnested_mode = true; - num_input_files = 1; - } else if (!strcmp(argv[1], "-v")) { // generate version info + if (!strcmp(argv[1], "-v")) { // generate version info generate_version_file = true; num_input_files = argc - 3; } else { // compress 1..n fpga files @@ -453,7 +372,7 @@ int main(int argc, char **argv) { FILE **infiles = calloc(num_input_files, sizeof(FILE *)); char **infile_names = calloc(num_input_files, sizeof(char *)); for (uint16_t i = 0; i < num_input_files; i++) { - infile_names[i] = argv[i + ((hardnested_mode || generate_version_file) ? 2 : 1)]; + infile_names[i] = argv[i + (generate_version_file ? 2 : 1)]; infiles[i] = fopen(infile_names[i], "rb"); if (infiles[i] == NULL) { fprintf(stderr, "Error. Cannot open input file %s\n\n", infile_names[i]); @@ -476,7 +395,7 @@ int main(int argc, char **argv) { return (EXIT_FAILURE); } } else { - int ret = zlib_compress(infiles, num_input_files, outfile, hardnested_mode); + int ret = zlib_compress(infiles, num_input_files, outfile); free(infile_names); free(infiles); return (ret); diff --git a/tools/hitag2crack/Makefile b/tools/hitag2crack/Makefile new file mode 100644 index 000000000..c36d18b30 --- /dev/null +++ b/tools/hitag2crack/Makefile @@ -0,0 +1,33 @@ +# Must be called before any Makefile include +ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) + +include ../../Makefile.defs + +all clean install uninstall check: %: crack2/% crack3/% crack4/% crack5/% +ifneq ($(SKIPGPU),1) +all clean install uninstall check: %: crack5gpu/% +endif + +crack2/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C crack2 $(patsubst crack2/%,%,$@) DESTDIR=$(MYDESTDIR) + +crack3/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C crack3 $(patsubst crack3/%,%,$@) DESTDIR=$(MYDESTDIR) + +crack4/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C crack4 $(patsubst crack4/%,%,$@) DESTDIR=$(MYDESTDIR) + +crack5/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C crack5 $(patsubst crack5/%,%,$@) DESTDIR=$(MYDESTDIR) + +crack5gpu/%: FORCE + $(info [*] MAKE $@) + $(Q)$(MAKE) --no-print-directory -C crack5gpu $(patsubst crack5gpu/%,%,$@) DESTDIR=$(MYDESTDIR) + +FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) + +.phony: crack2 crack3 crack4 crack5 crack5gpu FORCE diff --git a/tools/hitag2crack/common/ht2crackutils.c b/tools/hitag2crack/common/ht2crackutils.c index 8b67cf789..ac492ffa0 100644 --- a/tools/hitag2crack/common/ht2crackutils.c +++ b/tools/hitag2crack/common/ht2crackutils.c @@ -190,7 +190,6 @@ unsigned long hexreversetoulong(char *hex) { // convert byte-reversed 12 digit hex to unsigned long unsigned long long hexreversetoulonglong(char *hex) { - unsigned long long ret = 0LL; char tmp[9]; // this may seem an odd way to do it, but weird compiler issues were @@ -199,7 +198,7 @@ unsigned long long hexreversetoulonglong(char *hex) { tmp[8] = '\0'; memset(tmp + 4, '0', 4); memcpy(tmp, hex + 8, 4); - ret = hexreversetoulong(tmp); + unsigned long long ret = hexreversetoulong(tmp); ret <<= 32; memcpy(tmp, hex, 8); ret += hexreversetoulong(tmp); diff --git a/tools/hitag2crack/common/ht2crackutils.h b/tools/hitag2crack/common/ht2crackutils.h index 41c3a07c2..16f4fab5b 100644 --- a/tools/hitag2crack/common/ht2crackutils.h +++ b/tools/hitag2crack/common/ht2crackutils.h @@ -1,3 +1,6 @@ +#ifndef HT2CRACKUTILS_H +#define HT2CRACKUTILS_H + #include #include #include @@ -41,3 +44,5 @@ void buildlfsr(Hitag_State *hstate); #define rev64(X) (rev32(X) + (rev32(X >> 32) << 32)) unsigned long hexreversetoulong(char *hex); unsigned long long hexreversetoulonglong(char *hex); + +#endif /* HT2CRACKUTILS_H */ diff --git a/tools/hitag2crack/crack2/Makefile b/tools/hitag2crack/crack2/Makefile index 4794d6ec4..e8dbc4bac 100644 --- a/tools/hitag2crack/crack2/Makefile +++ b/tools/hitag2crack/crack2/Makefile @@ -1,23 +1,22 @@ -CFLAGS?=-Wall -Werror -O3 -# Linux libs -LIBS=-pthread -D_GNU_SOURCE -# Mac libs -# LIBS= -VPATH=../common -INC=-I ../common +MYSRCPATHS = ../common +MYSRCS = ht2crackutils.c hitagcrypto.c +MYINCLUDES =-I ../common +MYCFLAGS = -D_GNU_SOURCE +MYDEFS = +MYLDLIBS = -lpthread -all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o ht2crackutils.o - $(CC) $(CFLAGS) $(INC) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crackutils.o $(LIBS) - $(CC) $(CFLAGS) $(INC) -o ht2crack2search ht2crack2search.c hitagcrypto.o ht2crackutils.o $(LIBS) - $(CC) $(CFLAGS) $(INC) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o ht2crackutils.o $(LIBS) +BINS = ht2crack2buildtable ht2crack2search ht2crack2gentest +INSTALLTOOLS = $(BINS) -ht2crackutils.o: ht2crackutils.c ht2crackutils.h - $(CC) $(CFLAGS) -c $< +include ../../../Makefile.host -hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) -c $< +# checking platform can be done only after Makefile.host +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + CFLAGS += -D_ISOC99_SOURCE +endif -clean: - rm -rf *.o ht2crack2buildtable ht2crack2search ht2crack2gentest - -fresh: clean all +ht2crack2buildtable : $(OBJDIR)/ht2crack2buildtable.o $(MYOBJS) +ht2crack2search : $(OBJDIR)/ht2crack2search.o $(MYOBJS) +ht2crack2gentest : $(OBJDIR)/ht2crack2gentest.o $(MYOBJS) diff --git a/tools/hitag2crack/crack2/ht2crack2buildtable.c b/tools/hitag2crack/crack2/ht2crack2buildtable.c index 8bf67a8ac..6f8319a02 100644 --- a/tools/hitag2crack/crack2/ht2crack2buildtable.c +++ b/tools/hitag2crack/crack2/ht2crack2buildtable.c @@ -4,7 +4,7 @@ */ #include "ht2crackutils.h" - +#include // DATAMAX is the size of each bucket (bytes). There are 65536 buckets so choose a value such that // DATAMAX * 65536 < RAM available. For ex, if you want to use 12GB of RAM (for a 16GB machine @@ -53,63 +53,63 @@ uint64_t d2[48]; int nsteps2; // create table entry -void create_table(struct table *t, int d1, int d2) { - if (!t) { +static void create_table(struct table *tt, int d_1, int d_2) { + if (!tt) { printf("create_table: t is NULL\n"); exit(1); } // create some space - t->data = (unsigned char *)malloc(DATAMAX); - if (!(t->data)) { + tt->data = (unsigned char *)malloc(DATAMAX); + if (!(tt->data)) { printf("create_table: cannot malloc data\n"); exit(1); } // set data ptr to start of data table - t->ptr = t->data; + tt->ptr = tt->data; // init the mutex - if (pthread_mutex_init(&(t->mutex), NULL)) { + if (pthread_mutex_init(&(tt->mutex), NULL)) { printf("create_table: cannot init mutex\n"); exit(1); } // create the path -// sprintf(t->path, "/Volumes/2tb/%02X/%02X.bin", d1 & 0xff, d2 & 0xff); - sprintf(t->path, "table/%02x/%02x.bin", d1 & 0xff, d2 & 0xff); +// sprintf(tt->path, "/Volumes/2tb/%02X/%02X.bin", d_1 & 0xff, d_2 & 0xff); + sprintf(tt->path, "table/%02x/%02x.bin", d_1 & 0xff, d_2 & 0xff); } // create all table entries -void create_tables(struct table *t) { +static void create_tables(struct table *tt) { int i, j; - if (!t) { + if (!tt) { printf("create_tables: t is NULL\n"); exit(1); } for (i = 0; i < 0x100; i++) { for (j = 0; j < 0x100; j++) { - create_table(t + ((i * 0x100) + j), i, j); + create_table(tt + ((i * 0x100) + j), i, j); } } } // free the table memory -void free_tables(struct table *t) { +static void free_tables(struct table *tt) { int i; struct table *ttmp; - if (!t) { + if (!tt) { printf("free_tables: t is NULL\n"); exit(1); } for (i = 0; i < 0x10000; i++) { - ttmp = t + i; + ttmp = tt + i; free(ttmp->data); } } @@ -117,7 +117,7 @@ void free_tables(struct table *t) { // write (partial) table to file -void writetable(struct table *t1) { +static void writetable(struct table *t1) { int fd; if (debug) printf("writetable %s\n", t1->path); @@ -142,7 +142,7 @@ void writetable(struct table *t1) { // store value in table -void store(unsigned char *data) { +static void store(unsigned char *data) { unsigned char d_1, d_2; int offset; struct table *t1; @@ -194,7 +194,7 @@ void store(unsigned char *data) { } // writes the ks (keystream) and s (state) -void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) { +static void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) { unsigned char buf[16]; // create buffer @@ -204,12 +204,11 @@ void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) { // store buffer store(buf); - } // builds the di table for jumping -void builddi(int steps, int table) { +static void builddi(int steps, int table) { uint64_t statemask; int i; Hitag_State mystate; @@ -241,7 +240,7 @@ void builddi(int steps, int table) { } // jump function - quickly jumps a load of steps -void jumpnsteps(Hitag_State *hstate, int table) { +static void jumpnsteps(Hitag_State *hstate, int table) { uint64_t output = 0; uint64_t bitmask; int i; @@ -277,14 +276,14 @@ void jumpnsteps(Hitag_State *hstate, int table) { // thread to build a part of the table -void *buildtable(void *d) { +static void *buildtable(void *dd) { Hitag_State hstate; Hitag_State hstate2; unsigned long i; unsigned long maxentries = 1; uint32_t ks1; uint32_t ks2; - int index = (int)(long)d; + int index = (int)(long)dd; int tnum = NUM_BUILD_THREADS; /* set random state */ @@ -334,7 +333,7 @@ void *buildtable(void *d) { // make 'table/' (unsorted) and 'sorted/' dir structures -void makedirs() { +static void makedirs(void) { char path[32]; int i; @@ -368,7 +367,7 @@ static int datacmp(const void *p1, const void *p2, void *dummy) { return memcmp(d_1, d_2, DATASIZE); } -void *sorttable(void *d) { +static void *sorttable(void *dd) { int i, j; int fdin; int fdout; @@ -376,13 +375,12 @@ void *sorttable(void *d) { char outfile[64]; unsigned char *data = NULL; struct stat filestat; - unsigned char *table = NULL; uint64_t numentries = 0; - int index = (int)(long)d; + int index = (int)(long)dd; int space = 0x100 / NUM_SORT_THREADS; // create table - 50MB should be enough - table = (unsigned char *)malloc(50UL * 1024UL * 1024UL); + unsigned char *table = (unsigned char *)malloc(50UL * 1024UL * 1024UL); if (!table) { printf("sorttable: cannot malloc table\n"); exit(1); @@ -438,7 +436,10 @@ void *sorttable(void *d) { printf("cannot create outfile %s\n", outfile); exit(1); } - write(fdout, table, numentries * DATASIZE); + if (write(fdout, table, numentries * DATASIZE)) { + printf("writetable cannot write all of the data\n"); + exit(1); + } close(fdout); // remove input file diff --git a/tools/hitag2crack/crack2/ht2crack2gentest.c b/tools/hitag2crack/crack2/ht2crack2gentest.c index fb9ff484b..cc8d1e94e 100644 --- a/tools/hitag2crack/crack2/ht2crack2gentest.c +++ b/tools/hitag2crack/crack2/ht2crack2gentest.c @@ -5,7 +5,7 @@ #include "ht2crackutils.h" -int makerandom(char *hex, unsigned int len, int fd) { +static int makerandom(char *hex, unsigned int len, int fd) { unsigned char raw[32]; int i; @@ -41,10 +41,9 @@ int main(int argc, char *argv[]) { int i, j; int numtests; int urandomfd; - FILE *fp; if (argc < 2) { - printf("ht2crack2gentest number\n"); + printf("%s number\n", argv[0]); exit(1); } @@ -68,7 +67,7 @@ int main(int argc, char *argv[]) { makerandom(nR, 4, urandomfd); sprintf(filename, "keystream.key-%s.uid-%s.nR-%s", key, uid, nR); - fp = fopen(filename, "w"); + FILE *fp = fopen(filename, "w"); if (!fp) { printf("cannot open file '%s' for writing\n", filename); exit(1); @@ -87,9 +86,7 @@ int main(int argc, char *argv[]) { fclose(fp); } - return 0; - } diff --git a/tools/hitag2crack/crack2/ht2crack2search.c b/tools/hitag2crack/crack2/ht2crack2search.c index 16a2e00b8..d339f878f 100644 --- a/tools/hitag2crack/crack2/ht2crack2search.c +++ b/tools/hitag2crack/crack2/ht2crack2search.c @@ -23,7 +23,7 @@ static int datacmp(const void *p1, const void *p2) { return memcmp(d1, d2, DATASIZE - 6); } -int loadrngdata(struct rngdata *r, char *file) { +static int loadrngdata(struct rngdata *r, char *file) { int fd; int i, j; int nibble; @@ -90,7 +90,7 @@ int loadrngdata(struct rngdata *r, char *file) { return 1; } -int makecand(unsigned char *c, struct rngdata *r, int bitoffset) { +static int makecand(unsigned char *c, struct rngdata *r, int bitoffset) { int bytenum; int bitnum; int i; @@ -116,7 +116,7 @@ int makecand(unsigned char *c, struct rngdata *r, int bitoffset) { // test the candidate against the next or previous rng data -int testcand(unsigned char *f, unsigned char *rt, int fwd) { +static int testcand(unsigned char *f, unsigned char *rt, int fwd) { Hitag_State hstate; int i; uint32_t ks1; @@ -154,7 +154,7 @@ int testcand(unsigned char *f, unsigned char *rt, int fwd) { } } -int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s) { +static int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s) { int fd; struct stat filestat; char file[64]; @@ -222,7 +222,7 @@ int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, u } -int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset) { +static int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset) { int i; int bitlen; unsigned char cand[6]; @@ -276,7 +276,7 @@ int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstat -void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) { +static void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) { int i; if (!s) { @@ -305,7 +305,7 @@ void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) { } -uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) { +static uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) { uint64_t key; uint64_t keyupper; uint32_t uid; @@ -368,7 +368,7 @@ int main(int argc, char *argv[]) { int i; if (argc < 4) { - printf("ht2crack2search rngdatafile UID nR\n"); + printf("%s rngdatafile UID nR\n", argv[0]); exit(1); } diff --git a/tools/hitag2crack/crack3/.gitignore b/tools/hitag2crack/crack3/.gitignore index c993f2fe3..adf433d08 100644 --- a/tools/hitag2crack/crack3/.gitignore +++ b/tools/hitag2crack/crack3/.gitignore @@ -1,6 +1,5 @@ ht2crack3 -ht2test +ht2crack3test ht2crack3.exe -ht2test.exe - +ht2crack3test.exe diff --git a/tools/hitag2crack/crack3/Makefile b/tools/hitag2crack/crack3/Makefile index 318b5db78..010b6151c 100644 --- a/tools/hitag2crack/crack3/Makefile +++ b/tools/hitag2crack/crack3/Makefile @@ -1,19 +1,21 @@ -CFLAGS?=-Wall -Werror -O3 -LIBS= -VPATH=../common -INC=-I ../common +MYSRCPATHS = ../common +MYSRCS = ht2crackutils.c hitagcrypto.c +MYINCLUDES =-I ../common +MYCFLAGS = -D_GNU_SOURCE +MYDEFS = +MYLDLIBS = -lpthread -all: ht2crack3.c ht2test.c hitagcrypto.o ht2crackutils.o - $(CC) $(CFLAGS) $(INC) -o ht2crack3 $< hitagcrypto.o ht2crackutils.o -lpthread $(LIBS) - $(CC) $(CFLAGS) $(INC) -o ht2test ht2test.c hitagcrypto.o ht2crackutils.o $(LIBS) +BINS = ht2crack3 ht2crack3test +INSTALLTOOLS = $(BINS) -ht2crackutils.o: ht2crackutils.c ht2crackutils.h - $(CC) $(CFLAGS) -c $< +include ../../../Makefile.host -hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) -c $< +# checking platform can be done only after Makefile.host +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + CFLAGS += -D_ISOC99_SOURCE +endif -clean: - rm -rf *.o ht2crack3 ht2test - -fresh: clean all +ht2crack3 : $(OBJDIR)/ht2crack3.o $(MYOBJS) +ht2crack3test : $(OBJDIR)/ht2crack3test.o $(MYOBJS) diff --git a/tools/hitag2crack/crack3/README.md b/tools/hitag2crack/crack3/README.md index 57d5d2aa8..955775a62 100644 --- a/tools/hitag2crack/crack3/README.md +++ b/tools/hitag2crack/crack3/README.md @@ -31,9 +31,9 @@ Tests If you happen to know the key and want to check that all your nR aR values are valid (for high-powered demonstrations only, really) then you can use -the ht2test program to check them. It's otherwise massively pointless and a +the ht2crack3test program to check them. It's otherwise massively pointless and a complete waste of space. ``` -./ht2test NRARFILE KEY UID +./ht2crack3test NRARFILE KEY UID ``` diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c index 4f481fbf7..fba050d67 100644 --- a/tools/hitag2crack/crack3/ht2crack3.c +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -65,7 +65,7 @@ static uint32_t hitag2_crypt(uint64_t s) { // this function is a modification of the filter function f, based heavily // on the hitag2_crypt function in Rfidler -int fnP(uint64_t klowery) { +static int fnP(uint64_t klowery) { const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001 const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001 const uint32_t ht2_function4p = 0xAE83; // 1010 1110 1000 0011 @@ -84,7 +84,7 @@ int fnP(uint64_t klowery) { } // comparison function for sorting/searching Tklower entries -int Tk_cmp(const void *v1, const void *v2) { +static int Tk_cmp(const void *v1, const void *v2) { const struct Tklower *Tk1 = (struct Tklower *)v1; const struct Tklower *Tk2 = (struct Tklower *)v2; @@ -98,7 +98,7 @@ int Tk_cmp(const void *v1, const void *v2) { } // test for bad guesses of kmiddle -int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) { +static int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) { struct Tklower *result, target; @@ -122,7 +122,7 @@ int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) { } // function to test if a partial key is valid -int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR) { +static int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR) { uint64_t kupper; uint64_t key; Hitag_State hstate; @@ -147,12 +147,6 @@ int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR return 0; } - - - - - - // some notes on how I think this attack should work. // due to the way fc works, in a number of cases, it doesn't matter what // the most significant bits are doing for it to produce the same result. @@ -177,8 +171,7 @@ int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR // limit our guesses to a smaller set than a full brute force and // effectively work out candidates for the lower 34 bits of the key. - -void *crack(void *d) { +static void *crack(void *d) { struct threaddata *data = (struct threaddata *)d; uint64_t uid; struct nRaR *TnRaR; @@ -187,21 +180,14 @@ void *crack(void *d) { Hitag_State hstate; int i, j; - uint64_t klower; - uint64_t kmiddle; - uint64_t y; + uint64_t klower, kmiddle, klowery; + uint64_t y, b, z, bit; uint64_t ytmp; - uint64_t klowery; unsigned int count; - uint64_t bit; - uint64_t b; - uint64_t z; - uint64_t foundkey; - uint64_t revkey; + uint64_t foundkey, revkey; int ret; unsigned int found; unsigned int badguess; - struct Tklower *Tk = NULL; if (!data) { @@ -216,7 +202,7 @@ void *crack(void *d) { // create space for tables Tk = (struct Tklower *)malloc(sizeof(struct Tklower) * 0x40000); if (!Tk) { - printf("cannot malloc Tk\n"); + printf("Failed to allocate memory (Tk)\n"); exit(1); } @@ -301,6 +287,7 @@ void *crack(void *d) { } } + free(Tk); return NULL; } int main(int argc, char *argv[]) { @@ -321,7 +308,7 @@ int main(int argc, char *argv[]) { struct threaddata *tdata = NULL; if (argc < 3) { - printf("ht2crack3 uid nRaRfile\n"); + printf("%s uid nRaRfile\n", argv[0]); exit(1); } @@ -383,7 +370,6 @@ int main(int argc, char *argv[]) { // close file fclose(fp); - fp = NULL; printf("Loaded %u NrAr pairs\n", numnrar); diff --git a/tools/hitag2crack/crack3/ht2test.c b/tools/hitag2crack/crack3/ht2crack3test.c similarity index 96% rename from tools/hitag2crack/crack3/ht2test.c rename to tools/hitag2crack/crack3/ht2crack3test.c index 53d47cfca..8d48cc914 100644 --- a/tools/hitag2crack/crack3/ht2test.c +++ b/tools/hitag2crack/crack3/ht2crack3test.c @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) { char *uid; if (argc < 4) { - printf("ht2test nRaRfile KEY UID\n"); + printf("%s nRaRfile KEY UID\n", argv[0]); exit(1); } diff --git a/tools/hitag2crack/crack4/Makefile b/tools/hitag2crack/crack4/Makefile index b560577bd..1c7298840 100644 --- a/tools/hitag2crack/crack4/Makefile +++ b/tools/hitag2crack/crack4/Makefile @@ -1,18 +1,20 @@ -CFLAGS?=-Wall -Werror -O3 -LIBS=-lpthread -VPATH=../common -INC=-I ../common +MYSRCPATHS = ../common +MYSRCS = ht2crackutils.c hitagcrypto.c +MYINCLUDES =-I ../common +MYCFLAGS = -D_GNU_SOURCE +MYDEFS = +MYLDLIBS = -lpthread -all: ht2crack4.c hitagcrypto.o ht2crackutils.o - $(CC) $(CFLAGS) $(INC) -o ht2crack4 $< hitagcrypto.o ht2crackutils.o $(LIBS) +BINS = ht2crack4 +INSTALLTOOLS = $(BINS) -hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) -c $< +include ../../../Makefile.host -ht2crackutils.o: ht2crackutils.c ht2crackutils.h - $(CC) $(CFLAGS) -c $< +# checking platform can be done only after Makefile.host +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + CFLAGS += -D_ISOC99_SOURCE +endif -clean: - rm -rf *.o ht2crack4 - -fresh: clean all +ht2crack4 : $(OBJDIR)/ht2crack4.o $(MYOBJS) diff --git a/tools/hitag2crack/crack4/ht2crack4.c b/tools/hitag2crack/crack4/ht2crack4.c index 4c923737f..26460a112 100644 --- a/tools/hitag2crack/crack4/ht2crack4.c +++ b/tools/hitag2crack/crack4/ht2crack4.c @@ -93,7 +93,7 @@ uint64_t uid; int maxtablesize = 800000; uint64_t supplied_testkey = 0; -void usage() { +static void usage(void) { printf("ht2crack4 - K Sheldrake, based on the work of Garcia et al\n\n"); printf("Cracks a HiTag2 key using a small number (4 to 16) of encrypted\n"); printf("nonce and challenge response pairs, using a fast correlation\n"); @@ -147,6 +147,7 @@ double pfnc[][16] = { /* hitag2_crypt works on the post-shifted form of the lfsr; this is the ref in rfidler code */ +/* static uint32_t hitag2_crypt(uint64_t s) { uint32_t bitindex; @@ -158,9 +159,10 @@ static uint32_t hitag2_crypt(uint64_t s) { return (ht2_function5c >> bitindex) & 1; } +*/ /* ht2crypt works on the pre-shifted form of the lfsr; this is the ref in the paper */ -uint64_t ht2crypt(uint64_t s) { +static uint64_t ht2crypt(uint64_t s) { uint64_t bitindex; bitindex = (ht2_function4a >> pickbits2_2(s, 2, 5)) & 1; @@ -174,12 +176,13 @@ uint64_t ht2crypt(uint64_t s) { /* fnL is the feedback function for the reference code */ -uint64_t fnL(uint64_t x) { +/* +static uint64_t fnL(uint64_t x) { return (bitn(x, 0) ^ bitn(x, 2) ^ bitn(x, 3) ^ bitn(x, 6) ^ bitn(x, 7) ^ bitn(x, 8) ^ bitn(x, 16) ^ bitn(x, 22) ^ bitn(x, 23) ^ bitn(x, 26) ^ bitn(x, 30) ^ bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 43) ^ bitn(x, 46) ^ bitn(x, 47)); } - +*/ /* packed_size is an array that maps the number of confirmed bits in a state to * the number of relevant bits. @@ -193,7 +196,7 @@ unsigned int packed_size[] = { 0, 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5 /* f20 is the same as hitag2_crypt except it works on the packed version * of the state where all 20 relevant bits are squashed together */ -uint64_t f20(uint64_t y) { +static uint64_t f20(uint64_t y) { uint64_t bitindex; bitindex = (ht2_function4a >> (y & 0xf)) & 1; @@ -207,7 +210,7 @@ uint64_t f20(uint64_t y) { /* packstate packs the relevant bits from LFSR state into 20 bits for pre-shifted lfsr */ -uint64_t packstate(uint64_t s) { +static uint64_t packstate(uint64_t s) { uint64_t packed; packed = pickbits2_2(s, 2, 5); @@ -221,7 +224,7 @@ uint64_t packstate(uint64_t s) { /* create_guess_table mallocs the tables */ -void create_guess_table() { +static void create_guess_table(void) { guesses = (struct guess *)malloc(sizeof(struct guess) * maxtablesize); if (!guesses) { printf("cannot malloc guess table\n"); @@ -232,7 +235,7 @@ void create_guess_table() { /* init the guess table by reading in the encrypted nR,aR values and * setting the first 2^16 key guesses */ -void init_guess_table(char *filename, char *uidstr) { +static void init_guess_table(char *filename, char *uidstr) { unsigned int i, j; FILE *fp; char *buf = NULL; @@ -292,8 +295,6 @@ void init_guess_table(char *filename, char *uidstr) { } fclose(fp); - fp = NULL; - fprintf(stderr, "Loaded %u nRaR pairs\n", num_nRaR); // set key and copy in enc_nR and ks values @@ -313,7 +314,7 @@ void init_guess_table(char *filename, char *uidstr) { /* bit_score calculates the ratio of partial states that could generate * the resulting bit b to all possible states * size is the number of confirmed bits in the state */ -double bit_score(uint64_t s, uint64_t size, uint64_t b) { +static double bit_score(uint64_t s, uint64_t size, uint64_t b) { uint64_t packed; uint64_t chopped; unsigned int n; @@ -396,8 +397,8 @@ double bit_score(uint64_t s, uint64_t size, uint64_t b) { * bit_scores together until no bits remain. bit_scores are * multiplied by the number of relevant bits in the scored state * to give weight to more complete states. */ -double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) { - double sc, sc2; +static double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) { + double sc; if ((size == 1) || (kssize == 1)) { sc = bit_score(s, size, ks & 0x1); @@ -413,7 +414,7 @@ double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) { return 0.0; } else { - sc2 = score(s >> 1, size - 1, ks >> 1, kssize - 1); + double sc2 = score(s >> 1, size - 1, ks >> 1, kssize - 1); // if score returns a probability of 0 then this can't be a winner if (sc2 == 0.0) { @@ -427,7 +428,7 @@ double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) { /* score_traces runs score for each encrypted nonce */ -void score_traces(struct guess *g, unsigned int size) { +static void score_traces(struct guess *g, unsigned int size) { uint64_t lfsr; unsigned int i; double sc; @@ -481,7 +482,7 @@ void score_all_traces(unsigned int size) */ /* score_some_traces runs score_traces for every key guess in a section of the table */ -void *score_some_traces(void *data) { +static void *score_some_traces(void *data) { unsigned int i; struct thread_data *tdata = (struct thread_data *)data; @@ -494,7 +495,7 @@ void *score_some_traces(void *data) { /* score_all_traces runs score_traces for every key guess in the table */ -void score_all_traces(unsigned int size) { +static void score_all_traces(unsigned int size) { pthread_t threads[NUM_THREADS]; void *status; struct thread_data tdata[NUM_THREADS]; @@ -535,7 +536,7 @@ void score_all_traces(unsigned int size) { /* cmp_guess is the comparison function for qsorting the guess table */ -int cmp_guess(const void *a, const void *b) { +static int cmp_guess(const void *a, const void *b) { struct guess *a1 = (struct guess *)a; struct guess *b1 = (struct guess *)b; @@ -552,7 +553,7 @@ int cmp_guess(const void *a, const void *b) { /* expand all guesses in first half of (sorted) table by * copying them into the second half and extending the copied * ones with an extra 1, leaving the first half with an extra 0 */ -void expand_guesses(unsigned int halfsize, unsigned int size) { +static void expand_guesses(unsigned int halfsize, unsigned int size) { unsigned int i, j; for (i = 0; i < halfsize; i++) { @@ -567,7 +568,7 @@ void expand_guesses(unsigned int halfsize, unsigned int size) { /* checks if the supplied test key is still in the table, which * is useful when testing different scoring methods */ -void check_supplied_testkey(unsigned int size) { +static void check_supplied_testkey(unsigned int size) { uint64_t partkey; unsigned int i; @@ -586,7 +587,7 @@ void check_supplied_testkey(unsigned int size) { /* execute_round scores the guesses, sorts them and expands the good half */ -void execute_round(unsigned int size) { +static void execute_round(unsigned int size) { unsigned int halfsize; // score all the current guesses @@ -614,7 +615,7 @@ void execute_round(unsigned int size) { /* crack is the main cracking algo; it executes the rounds */ -void crack() { +static void crack(void) { unsigned int i; uint64_t revkey; uint64_t foundkey; @@ -630,9 +631,9 @@ void crack() { } } - /* test function to make sure I know how the LFSR works */ -void testkey(uint64_t key) { +/* +static void testkey(uint64_t key) { uint64_t i; uint64_t b0to31 = 0; uint64_t ks = 0; @@ -689,10 +690,11 @@ void testkey(uint64_t key) { printbin2(lfsr, 48); printf("\n\n"); } - +*/ /* test function to generate test data */ -void gen_bitstreams_testks(struct guess *g, uint64_t key) { +/* +static void gen_bitstreams_testks(struct guess *g, uint64_t key) { unsigned int i, j; uint64_t nRxorkey, lfsr, ks; @@ -730,10 +732,11 @@ void gen_bitstreams_testks(struct guess *g, uint64_t key) { } } } - +*/ /* test function */ -void test() { +/* +static void test(void) { uint64_t lfsr; uint64_t packed; @@ -751,10 +754,10 @@ void test() { printf("test done\n"); } - +*/ /* check_key tests the potential key against an encrypted nonce, ks pair */ -int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) { +static int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) { Hitag_State hstate; uint64_t bits; int i; diff --git a/tools/hitag2crack/crack5/Makefile b/tools/hitag2crack/crack5/Makefile index 9d19b63ee..8fc46e838 100644 --- a/tools/hitag2crack/crack5/Makefile +++ b/tools/hitag2crack/crack5/Makefile @@ -1,17 +1,20 @@ -CFLAGS?=-Wall -Werror -O3 -LIBS=-lpthread -VPATH=../common -INC=-I ../common +MYSRCPATHS = ../common +MYSRCS = ht2crackutils.c hitagcrypto.c +MYINCLUDES =-I ../common +MYCFLAGS = +MYDEFS = +MYLDLIBS = -lpthread -all: ht2crack5.c ht2crackutils.o hitagcrypto.o - $(CC) $(CFLAGS) $(INC) -O3 $< -o ht2crack5 ht2crackutils.o hitagcrypto.o $(LIBS) +BINS = ht2crack5 +INSTALLTOOLS = $(BINS) -hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) -c $< +include ../../../Makefile.host -ht2crackutils.o: ht2crackutils.c ht2crackutils.h - $(CC) $(CFLAGS) -c $< +# checking platform can be done only after Makefile.host +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + CFLAGS += -D_ISOC99_SOURCE +endif -clean: - rm -f *.o ht2crack5 -fresh: clean all +ht2crack5 : $(OBJDIR)/ht2crack5.o $(MYOBJS) diff --git a/tools/hitag2crack/crack5/ht2crack5.c b/tools/hitag2crack/crack5/ht2crack5.c index 79557bbfd..a92afc854 100644 --- a/tools/hitag2crack/crack5/ht2crack5.c +++ b/tools/hitag2crack/crack5/ht2crack5.c @@ -55,7 +55,7 @@ bitslice_t bs_zeroes, bs_ones; #define get_bit(n, word) ((word >> (n)) & 1) #define get_vector_bit(slice, value) get_bit(slice&0x3f, value.bytes64[slice>>6]) -const uint64_t expand(uint64_t mask, uint64_t value) { +static uint64_t expand(uint64_t mask, uint64_t value) { uint64_t fill = 0; for (uint64_t bit_index = 0; bit_index < 48; bit_index++) { if (mask & 1) { @@ -67,7 +67,7 @@ const uint64_t expand(uint64_t mask, uint64_t value) { return fill; } -void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) { +static void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) { size_t bit_idx; for (bit_idx = 0; bit_idx < bit_len; bit_idx++) { bool bit; @@ -84,7 +84,7 @@ void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const } } -const uint64_t unbitslice(const bitslice_t *restrict b, const uint8_t s, const uint8_t n) { +static uint64_t unbitslice(const bitslice_t *restrict b, const uint8_t s, const uint8_t n) { uint64_t result = 0; for (uint8_t i = 0; i < n; ++i) { result <<= 1; @@ -93,6 +93,24 @@ const uint64_t unbitslice(const bitslice_t *restrict b, const uint8_t s, const u return result; } + +// determine number of logical CPU cores (use for multithreaded functions) +static int num_CPUs(void) { +#if defined(_WIN32) +#include + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else +#include + int count = sysconf(_SC_NPROCESSORS_ONLN); + if (count < 2) + count = 2; + return count; +#endif +} + + uint32_t uid, nR1, aR1, nR2, aR2; uint64_t candidates[(1 << 20)]; @@ -100,7 +118,7 @@ bitslice_t initial_bitslices[48]; size_t filter_pos[20] = {4, 7, 9, 13, 16, 18, 22, 24, 27, 30, 32, 35, 45, 47 }; size_t thread_count = 8; uint64_t layer_0_found; -void *find_state(void *thread_d); +static void *find_state(void *thread_d); static void try_state(uint64_t s); int main(int argc, char *argv[]) { @@ -116,12 +134,7 @@ int main(int argc, char *argv[]) { uint32_t target = 0; -#ifndef __WIN32 - thread_count = sysconf(_SC_NPROCESSORS_CONF); - if ( thread_count < 2) - thread_count = 2; -#endif /* _WIN32 */ - + thread_count = num_CPUs(); if (!strncmp(argv[1], "0x", 2) || !strncmp(argv[1], "0X", 2)) { uid = rev32(hexreversetoulong(argv[1] + 2)); @@ -188,7 +201,7 @@ int main(int argc, char *argv[]) { exit(1); } -void *find_state(void *thread_d) { +static void *find_state(void *thread_d) { uint64_t thread = (uint64_t)thread_d; for (uint64_t index = thread; index < layer_0_found; index += thread_count) { diff --git a/tools/hitag2crack/crack5gpu/Makefile b/tools/hitag2crack/crack5gpu/Makefile index b88fa00e8..57e44641f 100644 --- a/tools/hitag2crack/crack5gpu/Makefile +++ b/tools/hitag2crack/crack5gpu/Makefile @@ -1,23 +1,27 @@ -CFLAGS?=-Wall -#INCLUDE=-I/usr/local/cuda-7.5/include -INCLUDE=-I/opt/nvidia/cuda/include -#Linux -#LIBS=-L/usr/local/cuda-7.5/lib64 -lOpenCL -LIBS=-L/opt/nvidia/cuda/lib64 -lOpenCL -#Mac -#LIBS=-framework OpenCL -VPATH=../common -INC=-I ../common +MYSRCPATHS = ../common +MYSRCS = ht2crackutils.c hitagcrypto.c +MYCFLAGS = +MYDEFS = +ifeq ($(platform),Darwin) + MYLDLIBS ?= -framework OpenCL +else + #MYINCLUDES ?=-I/usr/local/cuda-7.5/include + #MYINCLUDES ?=-I/opt/nvidia/cuda/include + #MYLDLIBS ?= -L/usr/local/cuda-7.5/lib64 -lOpenCL + MYLDLIBS ?= -L/opt/nvidia/cuda/lib64 -lOpenCL +endif +MYINCLUDES +=-I ../common -all: ht2crack5.c ht2crackutils.o hitagcrypto.o - $(CC) $(CFLAGS) $(INC) -o ht2crack5gpu $< ht2crackutils.o hitagcrypto.o $(LIBS) -lpthread +BINS = ht2crack5gpu +INSTALLTOOLS = $(BINS) -hitagcrypto.o: hitagcrypto.c hitagcrypto.h - $(CC) $(CFLAGS) $(INCLUDE) -c $< +include ../../../Makefile.host -ht2crackutils.o: ht2crackutils.c ht2crackutils.h - $(CC) $(CFLAGS) $(INCLUDE) -c $< +# checking platform can be done only after Makefile.host +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + CFLAGS += -D_ISOC99_SOURCE +endif -clean: - rm -f *.o ht2crack5gpu -fresh: clean all +ht2crack5gpu : $(OBJDIR)/ht2crack5gpu.o $(MYOBJS) diff --git a/tools/hitag2crack/crack5gpu/ht2crack5.c b/tools/hitag2crack/crack5gpu/ht2crack5gpu.c similarity index 97% rename from tools/hitag2crack/crack5gpu/ht2crack5.c rename to tools/hitag2crack/crack5gpu/ht2crack5gpu.c index adaf1ae82..8cb720540 100644 --- a/tools/hitag2crack/crack5gpu/ht2crack5.c +++ b/tools/hitag2crack/crack5gpu/ht2crack5gpu.c @@ -65,7 +65,7 @@ bitslice_t bs_zeroes, bs_ones; state[-2+i+42].value ^ state[-2+i+43].value ^ state[-2+i+46].value ^ state[-2+i+47].value); #define get_bit(n, word) ((word >> (n)) & 1) -const uint64_t expand(uint64_t mask, uint64_t value) { +static uint64_t expand(uint64_t mask, uint64_t value) { uint64_t fill = 0; for (uint64_t bit_index = 0; bit_index < 48; bit_index++) { if (mask & 1) { @@ -77,7 +77,7 @@ const uint64_t expand(uint64_t mask, uint64_t value) { return fill; } -void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) { +static void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) { size_t bit_idx; for (bit_idx = 0; bit_idx < bit_len; bit_idx++) { bool bit; @@ -123,7 +123,7 @@ struct context { }; -void runKernel(struct context *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found) { +static void runKernel(struct context *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found) { int err; size_t global[2]; @@ -236,7 +236,7 @@ int main(int argc, char *argv[]) { for (size_t i0 = 0; i0 < 1 << 20; i0++) { uint64_t state0 = expand(0x5806b4a2d16c, i0); - if (f(state0) == target >> 31 ) { + if (f(state0) == target >> 31) { // cf kernel, state is now split in 3 shorts >> 2 candidates[(layer_0_found * 3) + 0] = (uint16_t)((state0 >> (32 + 2)) & 0xffff); candidates[(layer_0_found * 3) + 1] = (uint16_t)((state0 >> (16 + 2)) & 0xffff); diff --git a/tools/hitag2crack/hitag2_gen_nRaR.py b/tools/hitag2crack/hitag2_gen_nRaR.py new file mode 100755 index 000000000..232add1f3 --- /dev/null +++ b/tools/hitag2crack/hitag2_gen_nRaR.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 + +""" +HITAG2 cipher +Implemented by Aram Verstegen +""" +import random + +def i4(x, a, b, c, d): + return (((x >> a) & 1)*8)+((x >> b) & 1)*4+((x >> c) & 1)*2+((x >> d) & 1) + + +def f20_4(state): + return ((0x3c65 >> i4(state,34,43,44,46)) & 1) + +def f20_3(state): + return (( 0xee5 >> i4(state,28,29,31,33)) & 1) + +def f20_2(state): + return (( 0xee5 >> i4(state,17,21,23,26)) & 1) + +def f20_1(state): + return (( 0xee5 >> i4(state, 8,12,14,15)) & 1) + +def f20_0(state): + return ((0x3c65 >> i4(state, 2, 3, 5, 6)) & 1) + +def f20_last(s0,s1,s2,s3,s4): + return (0xdd3929b >> ((s0 * 16) + + (s1 * 8) + + (s2 * 4) + + (s3 * 2) + + (s4 * 1))) & 1 + +def f20(state): + return f20_last(f20_0(state), f20_1(state), f20_2(state), f20_3(state), f20_4(state)) + +def lfsr_bs(state, i): + return (state[i+ 0] ^ state[i+ 2] ^ state[i+ 3] ^ state[i+ 6] ^ + state[i+ 7] ^ state[i+ 8] ^ state[i+16] ^ state[i+22] ^ + state[i+23] ^ state[i+26] ^ state[i+30] ^ state[i+41] ^ + state[i+42] ^ state[i+43] ^ state[i+46] ^ state[i+47]) + +def f20a_bs(a,b,c,d): + return (~(((a|b)&c)^(a|d)^b)) # 6 ops +def f20b_bs(a,b,c,d): + return (~(((d|c)&(a^b))^(d|a|b))) # 7 ops +def f20c_bs(a,b,c,d,e): + return (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) # 13 ops + +def filter_bs(state, i): + return (f20c_bs( f20a_bs(state[i+ 2],state[i+ 3],state[i+ 5],state[i+ 6]), + f20b_bs(state[i+ 8],state[i+12],state[i+14],state[i+15]), + f20b_bs(state[i+17],state[i+21],state[i+23],state[i+26]), + f20b_bs(state[i+28],state[i+29],state[i+31],state[i+33]), + f20a_bs(state[i+34],state[i+43],state[i+44],state[i+46]))) + +def unbitslice(s, n): + return int(''.join(map(str,map(int,map(bool,s[n:n+48])))[::-1]),2) + +def hitag2_init(key, uid, nonce): + state = 0 + for i in range(32, 48): + state = (state << 1) | ((key >> i) & 1) + for i in range(0, 32): + state = (state << 1) | ((uid >> i) & 1) + #print '%012x' % state + #print '%012x' % (int("{0:048b}".format(state)[::-1],2)) + for i in range(0, 32): + nonce_bit = (f20(state) ^ ((nonce >> (31-i)) & 1)) + #print nonce_bit + state = (state >> 1) | (((nonce_bit ^ (key >> (31-i))) & 1) << 47) + #print '%012x' % state + #print '%012x' % (int("{0:048b}".format(state)[::-1],2)) + return state + +def lfsr_feedback(state): + return (((state >> 0) ^ (state >> 2) ^ (state >> 3) + ^ (state >> 6) ^ (state >> 7) ^ (state >> 8) + ^ (state >> 16) ^ (state >> 22) ^ (state >> 23) + ^ (state >> 26) ^ (state >> 30) ^ (state >> 41) + ^ (state >> 42) ^ (state >> 43) ^ (state >> 46) + ^ (state >> 47)) & 1) +def lfsr(state): + return (state >> 1) + (lfsr_feedback(state) << 47) + +def lfsr_feedback_inv(state): + return (((state >> 47) ^ (state >> 1) ^ (state >> 2) + ^ (state >> 5) ^ (state >> 6) ^ (state >> 7) + ^ (state >> 15) ^ (state >> 21) ^ (state >> 22) + ^ (state >> 25) ^ (state >> 29) ^ (state >> 40) + ^ (state >> 41) ^ (state >> 42) ^ (state >> 45) + ^ (state >> 46)) & 1) + +def lfsr_inv(state): + return ((state << 1) + (lfsr_feedback_inv(state))) & ((1<<48)-1) + +def hitag2(state, length=48): + c = 0 + for i in range(0, length): + c = (c << 1) | f20(state) + #print '%012x' % state + #print '%012x' % (int("{0:048b}".format(state)[::-1],2)) + state = lfsr(state) + return c + +if __name__ == "__main__": + import sys + if len(sys.argv) == 4: + key = int(sys.argv[1], 16) + uid = int(sys.argv[2], 16) + n = int(sys.argv[3]) + for i in range(n): + nonce = random.randrange(2**32) + state = hitag2_init(key, uid, nonce) + print('%08X %08X' % (nonce, hitag2(state, 32)^0xffffffff)) + else: + print("Usage: python %s " % sys.argv[0]) diff --git a/tools/mf_nonce_brute/Makefile b/tools/mf_nonce_brute/Makefile new file mode 100644 index 000000000..cf565e72c --- /dev/null +++ b/tools/mf_nonce_brute/Makefile @@ -0,0 +1,23 @@ +MYSRCPATHS = ../../common ../../common/crapto1 +MYSRCS = crypto1.c crapto1.c bucketsort.c iso14443crc.c sleep.c +MYINCLUDES = -I../../include -I../../common +MYCFLAGS = +MYDEFS = +MYLDLIBS = +ifneq ($(SKIPPTHREAD),1) +MYLDLIBS += -lpthread +endif + +BINS = mf_nonce_brute +INSTALLTOOLS = $(BINS) + +include ../../Makefile.host + +# checking platform can be done only after Makefile.host +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + CFLAGS += -D_ISOC99_SOURCE +endif + +mf_nonce_brute : $(OBJDIR)/mf_nonce_brute.o $(MYOBJS) diff --git a/tools/mf_nonce_brute/README.md b/tools/mf_nonce_brute/README.md new file mode 100644 index 000000000..c2e5f3e6f --- /dev/null +++ b/tools/mf_nonce_brute/README.md @@ -0,0 +1,132 @@ +mf_nonce_brute +============== + +Nested authentificated sector key recovery tool +----------------------------------------------- + +Compatible tags: +* Mifare Classic 1k (4k) +* Mifare Plus in SL1 mode + +To recover keys to nested authentificated sectors you need a reader-card communication log. To get it use +hardware tools that able to sniff communication (for example Proxmark3 or HydraNFC). + +This enhanced version: +First 2 bytes should be bruteforced in phase 2 with mf_key_brute tool that interacts with a card. + +Sample trace: +``` + 93 70 fd ac f6 d8 7f 21 4f // select card with UID fdacf6d8 +TAG 08 b6 dd // sak + 60 04 d1 3d // wanna auth block 0x04 with A key +TAG ed 12 9c 74 // 1st auth clear text nt + 55 53 9f cc 41 8d e8 f3 // nr', ar' (nr^ks1, ar^ks2 ) +TAG 05 49 e1 65 // at' ( at^ks3 ) + 03 24 26 56 // wanna read block 0x04 +TAG ac 69 ef 58 45 e1 c2 1d a9 47 a5 94 54 ef 5d c7 1e a9 // block 0x04 content + d4 3e a8 aa +TAG 8e 8e e3 e6 e9 e2 5f dd f6 08 ce fb 02 6a db 75 94 2f + 79 77 68 3c +TAG e0 00 00 80 80 08 cc 80 08 9c 82 e0 68 64 60 30 91 60 // 18 bytes = 16 byte content + 2 bytes crc + ea 88 c3 c2 // 4 byte read cmd +TAG a3 76 dc df c1 42 e0 ee c6 75 a4 ca eb 0c da eb 46 a0 // 18 bytes = 16 byte content + 2 bytes crc ks8 + crc + 2d 27 ab 6f // wanna auth to 0x04 block with key B + +-------Until this line we can recover key or decrypt communication with no troubles (see mfkey64 tool)-------------------------------- + +TAG 52 6e af 8b // nested auth encrypted tag nonce that we dont know + 8e 21 3a 29 a4 80 7e 02 // nr_enc = nr^ks1, ar_enc = ar^ks2 +TAG b9 43 74 8d // at_enc = at^ks3 + e2 25 f8 32 // probably next command (actually is read block cmd, but we dont know it yet) +TAG 1f 26 82 8d 12 21 dd 42 c2 84 3e d0 26 7f 6b 2a 81 a9 // probably data + ba 85 1d 36 // probably read cmd +TAG 62 a8 78 69 ee 36 22 16 1c ff 4b 4e 69 cb 27 c2 e8 7e // probably data + a7 b1 c8 da // probably read cmd +TAG b2 fc 6c 65 60 ec 35 83 87 56 e3 7e 3c bf 38 b8 73 21 // probably data + 99 92 13 55 // probably read cmd +TAG 93 5b 65 a3 1d 8c 75 b8 3a 63 e2 31 f0 d0 a9 24 9a f6 // probably data +``` + + +Phase 1 +------- + +Syntax: +`mf_nonce_brute <{nt}> <{nr}> <{ar}> <{at}> [<{next_command}>]` + +Example: if `nt` in trace is `8c! 42 e6! 4e!`, then `nt` is `8c42e64e` and `nt_par_err` is `1011` + +Example with parity (from this trace http://www.proxmark.org/forum/viewtopic.php?pid=550#p550) : + +``` + + 561882: 1 : 26 + + 64: 2 : TAG 04 00 + + 10217: 2 : 93 20 + + 64: 5 : TAG 9c 59 9b 32 6c UID + + 12313: 9 : 93 70 9c 59 9b 32 6c 6b 30 + + 64: 3 : TAG 08 b6 dd + + 923318: 4 : 60 00 f5 7b AUTH Block 0 + + 112: 4 : TAG 82 a4 16 6c Nonce Tag (NT) + + 6985: 8 : a1 e4! 58 ce! 6e ea! 41 e0! NR , AR + + 64: 4 : TAG 5c! ad f4 39! AT + + 811513: 4 : 8e 0e! 5d! b9 AUTH Block 0 (nested) + + 112: 4 : TAG 5a! 92 0d! 85! Nonce Tag (NT) + + 6946: 8 : 98! d7 6b! 77 d6 c6 e8 70 NR , AR + + 64: 4 : TAG ca 7e! 0b! 63! AT + + 670868: 4 : 3e! 70 9c! 8a + + 112: 4 : TAG 36! 41 24! 79 + + 9505: 8 : 1b! 8c 3a! 48! 83 5a 4a! 27 + + 64: 4 : TAG 40! 6a! 99! 4b + + 905612: 4 : c9 7c 64! 13! !crc + + 112: 4 : TAG b5! ab! 1d! 2b + + 6936: 8 : 7e! d2 5c! ca! 4b! 50! 88! c4 !crc + + 64: 4 : TAG bf dd 01 be! + + 987853: 4 : 56 98 49 d6! !crc +``` +=> +``` +./mf_nonce_brute 9c599b32 82a4166c 0000 a1e458ce 6eea41e0 0101 5cadf439 1001 3e709c8a + | | | | | | | | | + +UID +nt_enc | +nr_enc +ar_enc | +at_enc | +encrypted next cmd + +nt_par_err +at_par_err +at_par_err +``` + +These two taken from above use the plaintext tagnonce `nt`=`82a4166c`, they still find a possible key candidate. +``` +./mf_nonce_brute 9c599b32 82a4166c 0000 a1e458ce 6eea41e0 0101 5cadf439 1001 +./mf_nonce_brute 9c599b32 82a4166c 0000 98d76b77 d6c6e870 0000 ca7e0b63 0111 +``` + +This one uses the encrypted tagnonce `nt`=`5a920d85`, it finds a valid key. +``` +./mf_nonce_brute 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 +``` + +This one uses the encrypted tagnonce `nt`=`5a920d85` and the encrypted cmd `3e709c8a` to validate , it finds a valid key. +``` +./mf_nonce_brute 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 3e709c8a +``` +Full output: +``` +$ ./mf_nonce_brute 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 3e709c8a +Mifare classic nested auth key recovery. Phase 1. +------------------------------------------------- +uid: 9c599b32 +nt encrypted: 5a920d85 +nt parity err: 1011 +nr encrypted: 98d76b77 +ar encrypted: d6c6e870 +ar parity err: 0000 +at encrypted: ca7e0b63 +at parity err: 0111 +next cmd enc: 3e709c8a + + +Starting 4 threads to bruteforce encrypted tag nonce last bytes +CMD enc(3e709c8a) + dec(6000f57b) <-- Valid cmd + +Valid Key found: [ffffffffffff] + +Time in mf_nonce_brute (Phase 1): 1763 ticks 2.0 seconds +``` diff --git a/tools/mf_nonce_brute/iso14443crc.c b/tools/mf_nonce_brute/iso14443crc.c new file mode 100644 index 000000000..60631f4fb --- /dev/null +++ b/tools/mf_nonce_brute/iso14443crc.c @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// ISO14443 CRC calculation code. +//----------------------------------------------------------------------------- + +#include "iso14443crc.h" + +static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc) { + ch = (ch ^ (unsigned char)((*lpwCrc) & 0x00FF)); + ch = (ch ^ (ch << 4)); + *lpwCrc = (*lpwCrc >> 8) ^ ((unsigned short) ch << 8) ^ + ((unsigned short) ch << 3) ^ ((unsigned short) ch >> 4); + return (*lpwCrc); +} + +void ComputeCrc14443(int CrcType, + const unsigned char *Data, int Length, + unsigned char *TransmitFirst, + unsigned char *TransmitSecond) { + unsigned char chBlock; + unsigned short wCrc = CrcType; + + do { + chBlock = *Data++; + UpdateCrc14443(chBlock, &wCrc); + } while (--Length); + + if (CrcType == CRC_14443_B) + wCrc = ~wCrc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ + + *TransmitFirst = (unsigned char)(wCrc & 0xFF); + *TransmitSecond = (unsigned char)((wCrc >> 8) & 0xFF); + return; +} + +int CheckCrc14443(int CrcType, const unsigned char *Data, int Length) { + unsigned char b1; + unsigned char b2; + if (Length < 3) return 0; + ComputeCrc14443(CrcType, Data, Length - 2, &b1, &b2); + if ((b1 == Data[Length - 2]) && (b2 == Data[Length - 1])) return 1; + return 0; +} diff --git a/tools/mf_nonce_brute/iso14443crc.h b/tools/mf_nonce_brute/iso14443crc.h new file mode 100644 index 000000000..e9a82d521 --- /dev/null +++ b/tools/mf_nonce_brute/iso14443crc.h @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// ISO14443 CRC calculation code. +//----------------------------------------------------------------------------- + +#ifndef __ISO14443CRC_H +#define __ISO14443CRC_H + +//----------------------------------------------------------------------------- +// Routines to compute the CRCs (two different flavours, just for confusion) +// required for ISO 14443, swiped directly from the spec. +//----------------------------------------------------------------------------- +#define CRC_14443_A 0x6363 /* ITU-V.41 */ +#define CRC_14443_B 0xFFFF /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ +#define CRC_ICLASS 0xE012 /* ICLASS PREFIX */ + +void ComputeCrc14443(int CrcType, + const unsigned char *Data, int Length, + unsigned char *TransmitFirst, + unsigned char *TransmitSecond); +int CheckCrc14443(int CrcType, const unsigned char *Data, int Length); + +#endif diff --git a/tools/mf_nonce_brute/mf_nonce_brute.c b/tools/mf_nonce_brute/mf_nonce_brute.c new file mode 100644 index 000000000..93a3025ea --- /dev/null +++ b/tools/mf_nonce_brute/mf_nonce_brute.c @@ -0,0 +1,402 @@ +#define __STDC_FORMAT_MACROS + +#if !defined(_WIN64) +#if defined(_WIN32) || defined(__WIN32__) +# define _USE_32BIT_TIME_T 1 +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include "crapto1/crapto1.h" +#include "protocol.h" +#include "iso14443crc.h" + +#define odd_parity(i) (( (i) ^ (i)>>1 ^ (i)>>2 ^ (i)>>3 ^ (i)>>4 ^ (i)>>5 ^ (i)>>6 ^ (i)>>7 ^ 1) & 0x01) + +// a global mutex to prevent interlaced printing from different threads +pthread_mutex_t print_lock; + +//--------------------- define options here +uint32_t uid = 0; // serial number +uint32_t nt_enc = 0; // Encrypted tag nonce +uint32_t nr_enc = 0; // encrypted reader challenge +uint32_t ar_enc = 0; // encrypted reader response +uint32_t at_enc = 0; // encrypted tag response +uint32_t cmd_enc = 0; // next encrypted command to sector + +uint32_t nt_par_err = 0; +uint32_t ar_par_err = 0; +uint32_t at_par_err = 0; + +typedef struct thread_args { + uint16_t xored; + int thread; + int idx; + bool ev1; +} targs; + +//------------------------------------------------------------------ +uint8_t cmds[] = { + ISO14443A_CMD_READBLOCK, + ISO14443A_CMD_WRITEBLOCK, + MIFARE_AUTH_KEYA, + MIFARE_AUTH_KEYB, + MIFARE_CMD_INC, + MIFARE_CMD_DEC, + MIFARE_CMD_RESTORE, + MIFARE_CMD_TRANSFER +}; + +int global_counter = 0; +int global_fin_flag = 0; +int global_found = 0; +int global_found_candidate = 0; +size_t thread_count = 2; + +static uint16_t parity_from_err(uint32_t data, uint16_t par_err) { + + uint16_t par = 0; + par |= odd_parity((data >> 24) & 0xFF) ^ ((par_err >> 12) & 1); + par <<= 4; + + par |= odd_parity((data >> 16) & 0xFF) ^ ((par_err >> 8) & 1); + par <<= 4; + + par |= odd_parity((data >> 8) & 0xFF) ^ ((par_err >> 4) & 1); + par <<= 4; + + par |= odd_parity(data & 0xFF) ^ (par_err & 1); + return par; +} + +static uint16_t xored_bits(uint16_t nt_par, uint32_t ntenc, uint16_t ar_par, uint32_t arenc, uint16_t at_par, uint32_t atenc) { + uint16_t xored = 0; + + uint8_t par; + //1st (1st nt) + par = (nt_par >> 12) & 1; + xored |= par ^ ((ntenc >> 16) & 1); + xored <<= 1; + + //2nd (2nd nt) + par = (nt_par >> 8) & 1; + xored |= par ^ ((ntenc >> 8) & 1); + xored <<= 1; + + //3rd (3rd nt) + par = (nt_par >> 4) & 1; + xored |= par ^ (ntenc & 1); + xored <<= 1; + + //4th (1st ar) + par = (ar_par >> 12) & 1; + xored |= par ^ ((arenc >> 16) & 1); + xored <<= 1; + + //5th (2nd ar) + par = (ar_par >> 8) & 1; + xored |= par ^ ((arenc >> 8) & 1); + xored <<= 1; + + //6th (3rd ar) + par = (ar_par >> 4) & 1; + xored |= par ^ (arenc & 1); + xored <<= 1; + + //7th (4th ar) + par = ar_par & 1; + xored |= par ^ ((atenc >> 24) & 1); + xored <<= 1; + + //8th (1st at) + par = (at_par >> 12) & 1; + xored |= par ^ ((atenc >> 16) & 1); + xored <<= 1; + + //9th (2nd at) + par = (at_par >> 8) & 1; + xored |= par ^ ((atenc >> 8) & 1); + xored <<= 1; + + //10th (3rd at) + par = (at_par >> 4) & 1; + xored |= par ^ (atenc & 1); + + return xored; +} + +static bool candidate_nonce(uint32_t xored, uint32_t nt, bool ev1) { + uint8_t byte, check; + + if (!ev1) { + //1st (1st nt) + byte = (nt >> 24) & 0xFF; + check = odd_parity(byte) ^ ((nt >> 16) & 1) ^ ((xored >> 9) & 1); + if (check) return false; + + //2nd (2nd nt) + byte = (nt >> 16) & 0xFF; + check = odd_parity(byte) ^ ((nt >> 8) & 1) ^ ((xored >> 8) & 1); + if (check) return false; + } + + //3rd (3rd nt) + byte = (nt >> 8) & 0xFF; + check = odd_parity(byte) ^ (nt & 1) ^ ((xored >> 7) & 1); + if (check) return false; + + uint32_t ar = prng_successor(nt, 64); + + //4th (1st ar) + byte = (ar >> 24) & 0xFF; + check = odd_parity(byte) ^ ((ar >> 16) & 1) ^ ((xored >> 6) & 1); + if (check) return false; + + //5th (2nd ar) + byte = (ar >> 16) & 0x0FF; + check = odd_parity(byte) ^ ((ar >> 8) & 1) ^ ((xored >> 5) & 1); + if (check) return false; + + //6th (3rd ar) + byte = (ar >> 8) & 0xFF; + check = odd_parity(byte) ^ (ar & 1) ^ ((xored >> 4) & 1); + if (check) return false; + + uint32_t at = prng_successor(nt, 96); + + //7th (4th ar) + byte = ar & 0xFF; + check = odd_parity(byte) ^ ((at >> 24) & 1) ^ ((xored >> 3) & 1); + if (check) return false; + + //8th (1st at) + byte = (at >> 24) & 0xFF; + check = odd_parity(byte) ^ ((at >> 16) & 1) ^ ((xored >> 2) & 1); + if (check) return false; + + //9th (2nd at) + byte = (at >> 16) & 0xFF; + check = odd_parity(byte) ^ ((at >> 8) & 1) ^ ((xored >> 1) & 1) ; + if (check) return false; + + //10th (3rd at) + byte = (at >> 8) & 0xFF; + check = odd_parity(byte) ^ (at & 1) ^ (xored & 1); + if (check) return false; + + return true; +} + +static bool checkValidCmd(uint32_t decrypted) { + uint8_t cmd = (decrypted >> 24) & 0xFF; + for (int i = 0; i < sizeof(cmds); ++i) { + if (cmd == cmds[i]) + return true; + } + return false; +} + +static bool checkCRC(uint32_t decrypted) { + uint8_t data[] = { + (decrypted >> 24) & 0xFF, + (decrypted >> 16) & 0xFF, + (decrypted >> 8) & 0xFF, + decrypted & 0xFF + }; + return CheckCrc14443(CRC_14443_A, data, sizeof(data)); +} + +static void *brute_thread(void *arguments) { + + //int shift = (int)arg; + struct thread_args *args = (struct thread_args *) arguments; + + struct Crypto1State *revstate; + uint64_t key; // recovered key candidate + uint32_t ks2; // keystream used to encrypt reader response + uint32_t ks3; // keystream used to encrypt tag response + uint32_t ks4; // keystream used to encrypt next command + uint32_t nt; // current tag nonce + + uint32_t p64 = 0; + uint32_t count; + int found = 0; + // TC == 4 ( + // threads calls 0 ev1 == false + // threads calls 0,1,2 ev1 == true + for (count = args->idx; count < 0xFFFF; count += thread_count - 1) { + + found = global_found; + if (found) break; + + nt = count << 16 | prng_successor(count, 16); + + if (!candidate_nonce(args->xored, nt, args->ev1)) + continue; + + p64 = prng_successor(nt, 64); + ks2 = ar_enc ^ p64; + ks3 = at_enc ^ prng_successor(p64, 32); + revstate = lfsr_recovery64(ks2, ks3); + ks4 = crypto1_word(revstate, 0, 0); + + if (ks4 != 0) { + + // lock this section to avoid interlacing prints from different threats + pthread_mutex_lock(&print_lock); + if (args->ev1) + printf("\n**** Possible key candidate ****\n"); + +#if 0 + printf("thread #%d idx %d %s\n", args->thread, args->idx, (args->ev1) ? "(Ev1)" : ""); + printf("current nt(%08x) ar_enc(%08x) at_enc(%08x)\n", nt, ar_enc, at_enc); + printf("ks2:%08x\n", ks2); + printf("ks3:%08x\n", ks3); + printf("ks4:%08x\n", ks4); +#endif + if (cmd_enc) { + uint32_t decrypted = ks4 ^ cmd_enc; + printf("CMD enc(%08x)\n", cmd_enc); + printf(" dec(%08x)\t", decrypted); + + uint8_t isOK = 0; + // check if cmd exists + isOK = checkValidCmd(decrypted); + (void)isOK; + + // Add a crc-check. + isOK = checkCRC(decrypted); + + if (!isOK) { + printf("<-- not a valid cmd\n"); + pthread_mutex_unlock(&print_lock); + continue; + } else { + printf("<-- Valid cmd\n"); + } + } + + lfsr_rollback_word(revstate, 0, 0); + lfsr_rollback_word(revstate, 0, 0); + lfsr_rollback_word(revstate, 0, 0); + lfsr_rollback_word(revstate, nr_enc, 1); + lfsr_rollback_word(revstate, uid ^ nt, 0); + crypto1_get_lfsr(revstate, &key); + free(revstate); + + if (args->ev1) { + printf("\nKey candidate: [%012" PRIx64 "]\n\n", key); + __sync_fetch_and_add(&global_found_candidate, 1); + } else { + printf("\nValid Key found: [%012" PRIx64 "]\n\n", key); + __sync_fetch_and_add(&global_found, 1); + } + //release lock + pthread_mutex_unlock(&print_lock); + } + } + return NULL; +} + +static int usage(void) { + printf(" syntax: mf_nonce_brute []\n\n"); + printf(" example: nt in trace = 8c! 42 e6! 4e!\n"); + printf(" nt = 8c42e64e\n"); + printf(" nt_par_err = 1011\n\n"); + printf("\n expected outcome:\n"); + printf(" KEY 0xFFFFFFFFFFFF == fa247164 fb47c594 0000 71909d28 0c254817 1000 0dc7cfbd 1110\n"); + return 1; +} + +int main(int argc, char *argv[]) { + printf("Mifare classic nested auth key recovery. Phase 1.\n"); + + if (argc < 9) return usage(); + + sscanf(argv[1], "%x", &uid); + sscanf(argv[2], "%x", &nt_enc); + sscanf(argv[3], "%x", &nt_par_err); + sscanf(argv[4], "%x", &nr_enc); + sscanf(argv[5], "%x", &ar_enc); + sscanf(argv[6], "%x", &ar_par_err); + sscanf(argv[7], "%x", &at_enc); + sscanf(argv[8], "%x", &at_par_err); + + if (argc > 9) + sscanf(argv[9], "%x", &cmd_enc); + + printf("-------------------------------------------------\n"); + printf("uid:\t\t%08x\n", uid); + printf("nt encrypted:\t%08x\n", nt_enc); + printf("nt parity err:\t%04x\n", nt_par_err); + printf("nr encrypted:\t%08x\n", nr_enc); + printf("ar encrypted:\t%08x\n", ar_enc); + printf("ar parity err:\t%04x\n", ar_par_err); + printf("at encrypted:\t%08x\n", at_enc); + printf("at parity err:\t%04x\n", at_par_err); + + if (argc > 9) + printf("next cmd enc:\t%08x\n\n", cmd_enc); + + clock_t t1 = clock(); + uint16_t nt_par = parity_from_err(nt_enc, nt_par_err); + uint16_t ar_par = parity_from_err(ar_enc, ar_par_err); + uint16_t at_par = parity_from_err(at_enc, at_par_err); + + //calc (parity XOR corresponding nonce bit encoded with the same keystream bit) + uint16_t xored = xored_bits(nt_par, nt_enc, ar_par, ar_enc, at_par, at_enc); + +#if !defined(_WIN32) || !defined(__WIN32__) + thread_count = sysconf(_SC_NPROCESSORS_CONF); + if (thread_count < 2) + thread_count = 2; +#endif /* _WIN32 */ + + printf("\nBruteforce using %zu threads to find encrypted tagnonce last bytes\n", thread_count); + + pthread_t threads[thread_count]; + + // create a mutex to avoid interlacing print commands from our different threads + pthread_mutex_init(&print_lock, NULL); + + // one thread T0 for none EV1. + struct thread_args *a = malloc(sizeof(struct thread_args)); + a->xored = xored; + a->thread = 0; + a->idx = 0; + a->ev1 = false; + pthread_create(&threads[0], NULL, brute_thread, (void *)a); + + // the rest of available threads to EV1 scenario + for (int i = 0; i < thread_count - 1; ++i) { + struct thread_args *b = malloc(sizeof(struct thread_args)); + b->xored = xored; + b->thread = i + 1; + b->idx = i; + b->ev1 = true; + pthread_create(&threads[i + 1], NULL, brute_thread, (void *)b); + } + + // wait for threads to terminate: + for (int i = 0; i < thread_count; ++i) + pthread_join(threads[i], NULL); + + if (!global_found && !global_found_candidate) { + printf("\nFailed to find a key\n\n"); + } + + t1 = clock() - t1; + if (t1 > 0) + printf("Execution time: %.0f ticks\n", (float)t1); + + // clean up mutex + pthread_mutex_destroy(&print_lock); + return 0; +} diff --git a/tools/mf_nonce_brute/protocol.h b/tools/mf_nonce_brute/protocol.h new file mode 100644 index 000000000..4f7f8b7e0 --- /dev/null +++ b/tools/mf_nonce_brute/protocol.h @@ -0,0 +1,20 @@ +#ifndef PROTOCOL_H +#define PROTOCOL_H + +#define ISO14443A_CMD_READBLOCK 0x30 +#define ISO14443A_CMD_WRITEBLOCK 0xA0 + +#define MIFARE_AUTH_KEYA 0x60 +#define MIFARE_AUTH_KEYB 0x61 +#define MIFARE_CMD_INC 0xC0 +#define MIFARE_CMD_DEC 0xC1 +#define MIFARE_CMD_RESTORE 0xC2 +#define MIFARE_CMD_TRANSFER 0xB0 + +// mifare 4bit card answers +#define CARD_ACK 0x0A // 1010 - ACK +#define CARD_NACK_NA 0x04 // 0100 - NACK, not allowed (command not allowed) +#define CARD_NACK_TR 0x05 // 0101 - NACK, transmission error + +#endif +// PROTOCOL_H diff --git a/tools/mf_nonce_brute/sleep.c b/tools/mf_nonce_brute/sleep.c new file mode 100644 index 000000000..0dd4c089d --- /dev/null +++ b/tools/mf_nonce_brute/sleep.c @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 iZsh +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// platform-independant sleep macros +//----------------------------------------------------------------------------- + +#ifndef _WIN32 + +#define _POSIX_C_SOURCE 199309L +#include "sleep.h" +#include +#include +#include +#include + +void nsleep(uint64_t n) { + struct timespec timeout; + timeout.tv_sec = n / 1000000000; + timeout.tv_nsec = n % 1000000000; + while (nanosleep(&timeout, &timeout) && errno == EINTR); +} + +#endif // _WIN32 + diff --git a/tools/mf_nonce_brute/sleep.h b/tools/mf_nonce_brute/sleep.h new file mode 100644 index 000000000..8465b6041 --- /dev/null +++ b/tools/mf_nonce_brute/sleep.h @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 iZsh +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// platform-independant sleep macros +//----------------------------------------------------------------------------- + +#ifndef SLEEP_H__ +#define SLEEP_H__ + +#ifdef _WIN32 +# include +# define sleep(n) Sleep(1000 * n) +# define msleep(n) Sleep(n) +#else +# include +# include +void nsleep(uint64_t n); +# define msleep(n) nsleep(1000000 * n) +# define usleep(n) nsleep(1000 * n) +#endif // _WIN32 + +#endif // SLEEP_H__ + diff --git a/tools/mkversion.pl b/tools/mkversion.pl old mode 100644 new mode 100755 index 95a794697..ea3b9940a --- a/tools/mkversion.pl +++ b/tools/mkversion.pl @@ -18,7 +18,7 @@ my $fullgitinfo = 'RRG/Iceman'; my $ctime; # GIT status 0 = dirty, 1 = clean , 2 = undecided my $clean = 2; - +my $undecided = (defined $ARGV[0]) && ($ARGV[0] =~ '--undecided'); # Do we have acces to git command? ####### # solves some bug on macos i.e: @@ -37,8 +37,9 @@ if ( defined($commandGIT) ) { # now avoiding the "fatal: No names found, cannot describe anything." error by fallbacking to abbrev hash in such case my $gitversion = `git describe --dirty --always`; my $gitbranch = `git rev-parse --abbrev-ref HEAD`; - $clean = $gitversion =~ '-dirty' ? 0 : 1; - + if (not $undecided) { + $clean = $gitversion =~ '-dirty' ? 0 : 1; + } if ( defined($gitbranch) and defined($gitversion) ) { $fullgitinfo = $fullgitinfo.'/'. $gitbranch . '/' . $gitversion; @@ -64,9 +65,15 @@ $fullgitinfo =~ s/(\s)//g; $fullgitinfo = substr $fullgitinfo, 0, 49; print <&2 + exit 1 + fi + ;; + mfkey) + TESTALL=false + TESTMFKEY=true + shift + ;; + nonce2key) + TESTALL=false + TESTNONCE2KEY=true + shift + ;; + mf_nonce_brute) + TESTALL=false + TESTMFNONCEBRUTE=true + shift + ;; + fpga_compress) + TESTALL=false + TESTFPGACOMPRESS=true + shift + ;; + hitag2crack) + TESTALL=false + TESTHITAG2CRACK=true + shift + ;; + bootrom) + TESTALL=false + TESTBOOTROM=true + shift + ;; + armsrc) + TESTALL=false + TESTARMSRC=true + shift + ;; + client) + TESTALL=false + TESTCLIENT=true + shift + ;; + recovery) + TESTALL=false + TESTRECOVERY=true + shift + ;; + common) + TESTALL=false + TESTCOMMON=true + shift + ;; + -*|--*=) # unsupported flags + echo "Error: Unsupported flag $1" >&2 + exit 1 + ;; + *) # preserve positional arguments + PARAMS="$PARAMS $1" + shift + ;; + esac +done +# set positional arguments in their proper place +eval set -- "$PARAMS" + +C_RED='\033[0;31m' +C_GREEN='\033[0;32m' +C_YELLOW='\033[0;33m' +C_BLUE='\033[0;34m' +C_NC='\033[0m' # No Color + +# title, file name or file wildcard to check +function CheckFileExist() { + + printf "%-40s" "$1 " + + if [ -f "$2" ]; then + echo -e "${C_GREEN}[OK]${C_NC}" + return 0 + fi + + if ls "$2" 1> /dev/null 2>&1; then + echo -e "${C_GREEN}[OK]${C_NC}" + return 0 + fi + + echo -e "${C_RED}[FAIL]${C_NC}" + return 1 +} + +# [slow] [gpu] [retry] [ignore] <command_line> <check_result_regex> +# slow: test takes more than ~5s +# gpu: test requires GPU presence +# retry: test repeated up to 3 times in case of failure +# ignore: test failure is not fatal +function CheckExecute() { + if [ "$1" == "slow" ]; then + local SLOWTEST=true + shift + else + local SLOWTEST=false + fi + if [ "$1" == "gpu" ]; then + local GPUTEST=true + shift + else + local GPUTEST=false + fi + if [ "$1" == "retry" ]; then + local RETRY="1 2 3 e" + shift + else + local RETRY="e" + fi + if [ "$1" == "ignore" ]; then + local IGNOREFAILURE=true + shift + else + local IGNOREFAILURE=false + fi + + printf "%-40s" "$1 " + + if $SLOWTEST && ! $SLOWTESTS; then + echo -e "${C_YELLOW}[SKIPPED]${C_NC} (slow)\n" + return 0 + fi + if $GPUTEST && ! $GPUTESTS; then + echo -e "${C_YELLOW}[SKIPPED]${C_NC} (gpu)\n" + return 0 + fi + + for I in $RETRY + do + RES=$(eval "$2") + if echo "$RES" | grep -q "$3"; then + echo -e "${C_GREEN}[OK]${C_NC}" + return 0 + fi + if [ ! $I == "e" ]; then echo "retry $I"; fi + done + + if $IGNOREFAILURE; then + echo -e "${C_YELLOW}[IGNORED]${C_NC}" + return 0 + fi + + echo -e "${C_RED}[FAIL]${C_NC}" + echo -e "Execution trace:\n$RES" + return 1 +} + +echo -e "\n${C_BLUE}RRG/Iceman Proxmark3 test tool ${C_NC}\n" + +echo -n "work directory: " +pwd + +if [ "$TRAVIS_COMMIT" ]; then + if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + echo "Travis branch: $TRAVIS_BRANCH slug: $TRAVIS_REPO_SLUG commit: $TRAVIS_COMMIT" + else + echo "Travis pull request: $TRAVIS_PULL_REQUEST branch: $TRAVIS_BRANCH slug: $TRAVIS_PULL_REQUEST_SLUG commit: $TRAVIS_COMMIT" + fi +fi + +echo -n "git branch: " +git describe --all +echo -n "git sha: " +git rev-parse HEAD +echo "" + +while true; do + if $TESTALL || $TESTCOMMON; then + echo -e "\n${C_BLUE}Testing common:${C_NC}" + if ! CheckFileExist "hardnested tables exists" "./client/resources/hardnested_tables/bitflip_0_001_states.bin.bz2"; then break; fi + if ! CheckFileExist "simmodule fw file exists" "./tools/simmodule/sim011.bin"; then break; fi + echo -e "\n${C_BLUE}Testing tools:${C_NC}" + if ! CheckExecute "xorcheck test" "tools/xorcheck.py 04 00 80 64 ba" "final LRC XOR byte value: 5A"; then break; fi + if ! CheckExecute "findbits test" "tools/findbits.py 73 0110010101110011" "Match at bit 9: 011001010"; then break; fi + if ! CheckExecute "findbits_test test" "tools/findbits_test.py 2>&1" "OK"; then break; fi + if ! CheckExecute "pm3_eml_mfd test" "tools/pm3_eml_mfd_test.py 2>&1" "OK"; then break; fi + fi + if $TESTALL || $TESTBOOTROM; then + echo -e "\n${C_BLUE}Testing bootrom:${C_NC}" + if ! CheckFileExist "bootrom exists" "./bootrom/obj/bootrom.elf"; then break; fi + fi + if $TESTALL || $TESTARMSRC; then + echo -e "\n${C_BLUE}Testing armsrc:${C_NC}" + if ! CheckFileExist "arm image exists" "./armsrc/obj/fullimage.elf"; then break; fi + fi + if $TESTALL || $TESTRECOVERY; then + echo -e "\n${C_BLUE}Testing recovery:${C_NC}" + if ! CheckFileExist "recovery image exists" "./recovery/proxmark3_recovery.bin"; then break; fi + + fi + if $TESTALL || $TESTFPGACOMPRESS; then + echo -e "\n${C_BLUE}Testing fpgacompress:${C_NC} ${FPGACPMPRESSBIN:=./tools/fpga_compress/fpga_compress}" + if ! CheckFileExist "fpgacompress exists" "$FPGACPMPRESSBIN"; then break; fi + fi + if $TESTALL || $TESTMFKEY; then + echo -e "\n${C_BLUE}Testing mfkey:${C_NC} ${MFKEY32V2BIN:=./tools/mfkey/mfkey32v2} ${MFKEY64BIN:=./tools/mfkey/mfkey64}" + if ! CheckFileExist "mfkey32v2 exists" "$MFKEY32V2BIN"; then break; fi + if ! CheckFileExist "mfkey64 exists" "$MFKEY64BIN"; then break; fi + # Need a decent example for mfkey32... + if ! CheckExecute "mfkey32v2 test" "$MFKEY32V2BIN 12345678 1AD8DF2B 1D316024 620EF048 30D6CB07 C52077E2 837AC61A" "Found Key: \[a0a1a2a3a4a5\]"; then break; fi + if ! CheckExecute "mfkey64 test" "$MFKEY64BIN 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439" "Found Key: \[ffffffffffff\]"; then break; fi + if ! CheckExecute "mfkey64 long trace test" "$MFKEY64BIN 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea" "Found Key: \[091e639cb715\]"; then break; fi + fi + if $TESTALL || $TESTNONCE2KEY; then + echo -e "\n${C_BLUE}Testing nonce2key:${C_NC} ${NONCE2KEYBIN:=./tools/nonce2key/nonce2key}" + if ! CheckFileExist "nonce2key exists" "$NONCE2KEYBIN"; then break; fi + if ! CheckExecute "nonce2key test" "$NONCE2KEYBIN e9cadd9c a8bf4a12 a020a8285858b090 050f010607060e07 5693be6c00000000" "key recovered: fc00018778f7"; then break; fi + fi + if $TESTALL || $TESTMFNONCEBRUTE; then + echo -e "\n${C_BLUE}Testing mf_nonce_brute:${C_NC} ${MFNONCEBRUTEBIN:=./tools/mf_nonce_brute/mf_nonce_brute}" + if ! CheckFileExist "mf_nonce_brute exists" "$MFNONCEBRUTEBIN"; then break; fi + if ! CheckExecute slow "mf_nonce_brute test" "$MFNONCEBRUTEBIN 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 3e709c8a" "Key.*: \[ffffffffffff\]"; then break; fi + fi + # hitag2crack not yet part of "all" + # if $TESTALL || $TESTHITAG2CRACK; then + if $TESTHITAG2CRACK; then + echo -e "\n${C_BLUE}Testing ht2crack2:${C_NC} ${HT2CRACK2PATH:=./tools/hitag2crack/crack2/}" + if ! CheckFileExist "ht2crack2buildtable exists" "$HT2CRACK2PATH/ht2crack2buildtable"; then break; fi + if ! CheckFileExist "ht2crack2gentest exists" "$HT2CRACK2PATH/ht2crack2gentest"; then break; fi + if ! CheckFileExist "ht2crack2search exists" "$HT2CRACK2PATH/ht2crack2search"; then break; fi + # 1.5Tb tables are supposed to be absent, so it's just a fast check without real cracking + if ! CheckExecute "ht2crack2 quick test" "cd $HT2CRACK2PATH; ./ht2crack2gentest 1 && ./runalltests.sh; rm keystream*" "searching on bit"; then break; fi + + echo -e "\n${C_BLUE}Testing ht2crack3:${C_NC} ${HT2CRACK3PATH:=./tools/hitag2crack/crack3/}" + if ! CheckFileExist "ht2crack3 exists" "$HT2CRACK3PATH/ht2crack3"; then break; fi + if ! CheckFileExist "ht2crack3test exists" "$HT2CRACK3PATH/ht2crack3test"; then break; fi + HT2CRACK3UID=AABBCCDD + # Test fast only for HT2CRACK3KEY in begin of keyspace! + HT2CRACK3KEY=000102030405 + HT2CRACK3N=32 + HT2CRACK3NRAR=hitag2_${HT2CRACK3UID}_nrar_${HT2CRACK3N}emul.txt + if ! CheckExecute "ht2crack3 gen testfile" "cd $HT2CRACK3PATH; python3 ../hitag2_gen_nRaR.py $HT2CRACK3KEY $HT2CRACK3UID $HT2CRACK3N > $HT2CRACK3NRAR && echo SUCCESS" "SUCCESS"; then break; fi + if ! CheckExecute "ht2crack3test test" "cd $HT2CRACK3PATH; ./ht2crack3test $HT2CRACK3NRAR $HT2CRACK3KEY $HT2CRACK3UID|grep -v SUCCESS||echo SUCCESS" "SUCCESS"; then break; fi + if ! CheckExecute "ht2crack3 test" "cd $HT2CRACK3PATH; ./ht2crack3 $HT2CRACK3UID $HT2CRACK3NRAR |egrep -v '(trying|partial)'" "key = $HT2CRACK3KEY"; then break; fi + if ! CheckExecute "ht2crack3 rm testfile" "cd $HT2CRACK3PATH; rm $HT2CRACK3NRAR && echo SUCCESS" "SUCCESS"; then break; fi + + echo -e "\n${C_BLUE}Testing ht2crack4:${C_NC} ${HT2CRACK4PATH:=./tools/hitag2crack/crack4/}" + if ! CheckFileExist "ht2crack4 exists" "$HT2CRACK4PATH/ht2crack4"; then break; fi + HT2CRACK4UID=12345678 + HT2CRACK4KEY=AABBCCDDEEFF + HT2CRACK4N=32 + HT2CRACK4NRAR=hitag2_${HT2CRACK4UID}_nrar_${HT2CRACK4N}emul.txt + # The success is probabilistic: a fresh random nRaR file is required for each run + # Order of magnitude to crack it: ~15s -> tagged as "slow" + if ! CheckExecute slow retry ignore "ht2crack4 test" "cd $HT2CRACK4PATH; \ + python3 ../hitag2_gen_nRaR.py $HT2CRACK4KEY $HT2CRACK4UID $HT2CRACK4N > $HT2CRACK4NRAR; \ + ./ht2crack4 -u $HT2CRACK4UID -n $HT2CRACK4NRAR -N 16 -t 500000 2>&1; \ + rm $HT2CRACK4NRAR" "key = $HT2CRACK4KEY"; then break; fi + + echo -e "\n${C_BLUE}Testing ht2crack5:${C_NC} ${HT2CRACK5PATH:=./tools/hitag2crack/crack5/}" + if ! CheckFileExist "ht2crack5 exists" "$HT2CRACK5PATH/ht2crack5"; then break; fi + HT2CRACK5UID=12345678 + HT2CRACK5KEY=AABBCCDDEEFF + # The speed depends on the nRaR so we'll use two pairs known to work fast + HT2CRACK5NRAR="71DA20AA 7EFDF3FA 2A4265F9 59653B07" + # Order of magnitude to crack it: ~12s on 1 core, ~3s on 4 cores -> tagged as "slow" + if ! CheckExecute slow "ht2crack5 test" "cd $HT2CRACK5PATH; ./ht2crack5 $HT2CRACK5UID $HT2CRACK5NRAR" "Key: $HT2CRACK5KEY"; then break; fi + + echo -e "\n${C_BLUE}Testing ht2crack5gpu:${C_NC} ${HT2CRACK5GPUPATH:=./tools/hitag2crack/crack5gpu/}" + if ! CheckFileExist "ht2crack5gpu exists" "$HT2CRACK5GPUPATH/ht2crack5gpu"; then break; fi + HT2CRACK5GPUUID=12345678 + HT2CRACK5GPUKEY=AABBCCDDEEFF + # The speed depends on the nRaR so we'll use two pairs known to work fast + HT2CRACK5GPUNRAR="B438220C 944FFD74 942C59E3 3D450B34" + # Order of magnitude to crack it: ~15s -> tagged as "slow" + if ! CheckExecute slow gpu "ht2crack5gpu test" "cd $HT2CRACK5GPUPATH; ./ht2crack5gpu $HT2CRACK5GPUUID $HT2CRACK5GPUNRAR" "Key: $HT2CRACK5GPUKEY"; then break; fi + fi + if $TESTALL || $TESTCLIENT; then + echo -e "\n${C_BLUE}Testing client:${C_NC} ${CLIENTBIN:=./client/proxmark3}" + if ! CheckFileExist "proxmark3 exists" "$CLIENTBIN"; then break; fi + echo -e "\n${C_BLUE}Testing basic help:${C_NC}" + if ! CheckExecute "proxmark help" "$CLIENTBIN -h" "wait"; then break; fi + if ! CheckExecute "proxmark help text ISO7816" "$CLIENTBIN -t 2>&1" "ISO7816"; then break; fi + if ! CheckExecute "proxmark help text hardnested" "$CLIENTBIN -t 2>&1" "hardnested"; then break; fi + + echo -e "\n${C_BLUE}Testing data manipulation:${C_NC}" + if ! CheckExecute "reveng readline test" "$CLIENTBIN -c 'reveng -h;reveng -D'" "CRC-64/GO-ISO"; then break; fi + if ! CheckExecute "reveng -g test" "$CLIENTBIN -c 'reveng -g abda202c'" "CRC-16/ISO-IEC-14443-3-A"; then break; fi + if ! CheckExecute "reveng -w test" "$CLIENTBIN -c 'reveng -w 8 -s 01020304e3 010204039d'" "CRC-8/SMBUS"; then break; fi + if ! CheckExecute "mfu pwdgen test" "$CLIENTBIN -c 'hf mfu pwdgen t'" "Selftest OK"; then break; fi + if ! CheckExecute "trace load/list 14a" "$CLIENTBIN -c 'trace load traces/hf_mfu.trace; trace list 1;'" "READBLOCK(8)"; then break; fi + if ! CheckExecute "trace load/list x" "$CLIENTBIN -c 'trace load traces/hf_mfu.trace; trace list x 1;'" "0.0101840425"; then break; fi + + echo -e "\n${C_BLUE}Testing LF:${C_NC}" + if ! CheckExecute "lf EM4x05 test" "$CLIENTBIN -c 'data load traces/em4x05.pm3;lf search 1'" "FDX-B ID found"; then break; fi + if ! CheckExecute "lf EM410x test" "$CLIENTBIN -c 'data load traces/EM4102-1.pm3;lf search 1'" "EM410x ID found"; then break; fi + if ! CheckExecute "lf VISA2000 test" "$CLIENTBIN -c 'data load traces/visa2000.pm3;lf search 1'" "Visa2000 ID found"; then break; fi + if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load traces/AWID-15-259.pm3;lf search 1'" "AWID ID found"; then break; fi + if ! CheckExecute "lf SECURAKEY test" "$CLIENTBIN -c 'data load traces/securakey-64169.pm3;lf search 1 '" "Securakey ID found"; then break; fi + if ! CheckExecute "lf NEXWATCH test" "$CLIENTBIN -c 'data load traces/quadrakey-521512301.pm3;lf search 1 '" "NexWatch ID found"; then break; fi + if ! CheckExecute "lf KERI test" "$CLIENTBIN -c 'data load traces/keri.pm3;lf search 1'" "Pyramid ID found"; then break; fi + if ! CheckExecute "lf HID Prox test" "$CLIENTBIN -c 'data load traces/hid-proxCardII-05512-11432784-1.pm3;lf search 1'" "HID Prox ID found"; then break; fi + if ! CheckExecute "lf PARADOX test" "$CLIENTBIN -c 'data load traces/Paradox-96_40426-APJN08.pm3;lf search 1'" "Paradox ID found"; then break; fi + if ! CheckExecute "lf PAC test" "$CLIENTBIN -c 'data load traces/pac-8E4C058E.pm3;lf search 1'" "PAC/Stanley ID found"; then break; fi + if ! CheckExecute "lf VIKING test" "$CLIENTBIN -c 'data load traces/Transit999-best.pm3;lf search 1'" "Viking ID found"; then break; fi + if ! CheckExecute "lf FDX-B test" "$CLIENTBIN -c 'data load traces/homeagain1600.pm3;lf search 1'" "FDX-B ID found"; then break; fi + if ! CheckExecute "lf INDALA test" "$CLIENTBIN -c 'data load traces/indala-504278295.pm3;lf search 1'" "Indala ID found"; then break; fi + if ! CheckExecute "lf FDX/BioThermo test" "$CLIENTBIN -c 'data load traces/lf_fdx_biothermo.pm3; lf fdx demo'" "95.2 F / 35.1 C"; then break; fi + + echo -e "\n${C_BLUE}Testing HF:${C_NC}" + if ! CheckExecute "hf mf offline text" "$CLIENTBIN -c 'hf mf'" "at_enc"; then break; fi + if ! CheckExecute slow retry ignore "hf mf hardnested long test" "$CLIENTBIN -c 'hf mf hardnested t 1 000000000000'" "found:"; then break; fi + if ! CheckExecute slow "hf iclass long test" "$CLIENTBIN -c 'hf iclass loclass t l'" "verified ok"; then break; fi + if ! CheckExecute slow "emv long test" "$CLIENTBIN -c 'emv test -l'" "Test(s) \[ ok"; then break; fi + if ! $SLOWTESTS; then + if ! CheckExecute "hf iclass test" "$CLIENTBIN -c 'hf iclass loclass t'" "key diversification (ok)"; then break; fi + if ! CheckExecute "emv test" "$CLIENTBIN -c 'emv test'" "Test(s) \[ ok"; then break; fi + fi + fi + echo -e "\n${C_GREEN}Tests [OK]${C_NC}\n" + exit 0 +done +echo -e "\n${C_RED}Tests [FAIL]${C_NC}\n" +exit 1 diff --git a/tools/rfidtest.pl b/tools/rfidtest.pl old mode 100644 new mode 100755 diff --git a/traces/README.txt b/traces/README.txt index 5eada015d..a55786807 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -1,36 +1,42 @@ -pac-8E4C058E.pm3: PAC/Stanley 20204/21020 PAC8 tag (ID: 8E4C058E) em4102-clamshell.pm3: Samy's clamshell EM4102 tag (ID: 1f00d9b3a5) em4102-thin.pm3: Samy's thin credit-card style EM4102 tag (ID: 1a0041375d) EM4102-1.pm3: credit card style card EM4102 tag (ID: 010872e77c) EM4102-2.pm3: credit card style card EM4102 tag (ID: 010872beec) EM4102-3.pm3: credit card style card EM4102 tag (ID: 010872e14f) +EM4102-Fob.pm3: (ID: 0400193cbe) em4x05.pm3: ear tag FDX-B ISO-11784/5 (ID: 6DB0840800F80001 - Application Identifier: 8000, Country Code: 124 (Canada), National ID: 270601654) em4x50.pm3: credit card style card EM4x50 tag (ID: DE2A3F00) hid-proxCardII-05512-11432784-1.pm3: clamshell-style HID ProxCard II card +HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but just readable. indala-00002-12345678-1A.pm3: Indala credit-card style card +indala-504278295.pm3: PSK 26 bit indala homeagain.pm3: HomeAgain animal (cat) tag - ID 985121004515220 homeagain1600.pm3: HomeAgain animal (cat) tag - ID 985121004515220 keri.pm3: Keri PSK-3 Key Ring tag (back of tag: 1460 3411) Transit999-best.pm3: Transit 999 format (UID 99531670) - -The files 'modulation-'... are all encoded with identical data (hex 00 01 02 03 04 05 06 07 08 09 0A 0B) -for the purpose of recognition and testing of demodulation schemes. They were created by writing Q5 tags -appropriately configured. The raw data is in 'modulation-data.dat'. - -ata5577-HIDemu-FC1-C9.pm3: ata5577 in hid prox 26 bit emulation facility code:1 card#:9 -casi-12ed825c29.pm3: casi rusco 40 bit (EM410x ID: 12ed825c29) -EM4102-Fob.pm3: (ID: 0400193cbe) +ATA5577-HIDemu-FC1-C9.pm3: ata5577 in hid prox 26 bit emulation facility code:1 card#:9 +AWID-15-259.pm3: AWID FSK RF/50 FC: 15 Card: 259 +Casi-12ed825c29.pm3: casi rusco 40 bit (EM410x ID: 12ed825c29) ioprox-XSF-01-3B-44725.pm3: IO Prox FSK RF/64 ID in name ioprox-XSF-01-BE-03011.pm3: IO Prox FSK RF/64 ID in name -indala-504278295.pm3: PSK 26 bit indala -AWID-15-259.pm3: AWID FSK RF/50 FC: 15 Card: 259 -HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but just readable. -visa2000.pm3: VISA2000 ASK/MAN RF/64, Card: 480518 -securakey-64169.pm3 Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35 - motorola_0437_00072.pm3: Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1) +nexkey_74755342.pm3: NEXWATCH, Nexkey ID: 74755342 +pac-8E4C058E.pm3: PAC/Stanley 20204/21020 PAC8 tag (ID: 8E4C058E) +quadrakey-521512301.pm3: NEXWATCH, Quadrakey ID: 521512301 +securakey-64169.pm3: Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35 verichip_1022000000084146.pm3: VeriChip, epoxy encased glasschip (ID: 1022-00000000084146) - +visa2000.pm3: VISA2000 ASK/MAN RF/64, Card: 480518 +Paradox-96_40426-APJN08.pm3: PARADOX FC 96 CN 40426 +TITEST.txt: Texas Instrument - can't decode it any longer +gallagher.pm3: GALLAGHER tag. +--- sniff-ht2-BC3B8810-acg-reader.pm3: sniffing of Hitag2 being read by an HID ACG LF Multitag reader sniff-ht2-BC3B8810-frosch-reader.pm3: sniffing of Hitag2 being read by a Frosch Hitag reader sniff-ht2-BC3B8810-rfidler-reader.pm3: sniffing of Hitag2 being read by a RFIDler +--- +The files 'modulation-'... +are all encoded with identical data (hex 00 01 02 03 04 05 06 07 08 09 0A 0B) +for the purpose of recognition and testing of demodulation schemes. They were created by writing Q5 tags +appropriately configured. The raw data is in 'modulation-data.dat'. +--- +hf_mfu.trace: Tracelog file for a MFU simulation \ No newline at end of file diff --git a/traces/hf-mfu-0466D65F00509C-sim.trace b/traces/hf-mfu-0466D65F00509C-sim.trace new file mode 100644 index 000000000..ff5a36594 Binary files /dev/null and b/traces/hf-mfu-0466D65F00509C-sim.trace differ diff --git a/traces/hf_14a_reader.trace b/traces/hf_14a_reader.trace new file mode 100644 index 000000000..6bf0ab7b6 Binary files /dev/null and b/traces/hf_14a_reader.trace differ diff --git a/traces/hf_14b_reader.trace b/traces/hf_14b_reader.trace new file mode 100644 index 000000000..ed707d458 Binary files /dev/null and b/traces/hf_14b_reader.trace differ diff --git a/traces/hf_15_reader.trace b/traces/hf_15_reader.trace new file mode 100644 index 000000000..e3ea16c2b Binary files /dev/null and b/traces/hf_15_reader.trace differ diff --git a/traces/hf_mdes_oyster_reader.trace b/traces/hf_mdes_oyster_reader.trace new file mode 100644 index 000000000..ef42bf4d6 Binary files /dev/null and b/traces/hf_mdes_oyster_reader.trace differ diff --git a/traces/hf_mdes_reader.trace b/traces/hf_mdes_reader.trace new file mode 100644 index 000000000..2410bedef Binary files /dev/null and b/traces/hf_mdes_reader.trace differ diff --git a/traces/hf_mfu.trace b/traces/hf_mfu.trace new file mode 100644 index 000000000..7b325653c Binary files /dev/null and b/traces/hf_mfu.trace differ diff --git a/traces/lf_fdx_biothermo.pm3 b/traces/lf_fdx_biothermo.pm3 new file mode 100644 index 000000000..77f390f2f --- /dev/null +++ b/traces/lf_fdx_biothermo.pm3 @@ -0,0 +1,10000 @@ +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-111 +-104 +-98 +-91 +-84 +-77 +-71 +-67 +-63 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +110 +102 +94 +89 +84 +77 +70 +-14 +-113 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-115 +-108 +-100 +-92 +-84 +-79 +-75 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +125 +116 +108 +102 +95 +87 +80 +75 +71 +-13 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-121 +-114 +-107 +-99 +-91 +-86 +-81 +-75 +96 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +125 +118 +109 +101 +93 +87 +82 +75 +69 +-15 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-115 +-108 +-100 +-91 +-84 +-79 +-75 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +115 +-1 +-108 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-9 +112 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +81 +-30 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-18 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +112 +104 +96 +88 +82 +77 +73 +66 +61 +56 +-26 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-59 +67 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +64 +-47 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-26 +97 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-112 +-104 +-98 +-92 +-85 +-78 +-74 +-69 +-64 +107 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +117 +109 +102 +96 +89 +81 +75 +70 +-13 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-55 +69 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-24 +98 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-110 +-103 +-97 +-91 +-84 +-77 +-71 +-68 +-64 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +4 +-103 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-9 +114 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +83 +-29 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +110 +103 +97 +90 +83 +76 +72 +68 +63 +57 +-27 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-117 +-109 +-102 +-93 +-86 +-81 +-76 +94 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +110 +101 +94 +88 +80 +74 +69 +-14 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-58 +67 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +68 +-43 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-114 +-105 +-99 +-93 +-86 +-79 +-74 +-70 +-65 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +5 +-103 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +83 +-30 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +112 +104 +96 +88 +82 +78 +72 +66 +61 +58 +-25 +-125 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-117 +-109 +-101 +-93 +-86 +-81 +-76 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +117 +108 +101 +94 +86 +80 +75 +69 +-16 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-59 +68 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +70 +-41 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-114 +-107 +-99 +-91 +-84 +-79 +-75 +-70 +-64 +107 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +4 +-104 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +123 +113 +105 +98 +93 +86 +79 +73 +67 +64 +59 +-26 +-125 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-61 +66 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +66 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-116 +-108 +-99 +-91 +-86 +-80 +-75 +-69 +-63 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +113 +105 +95 +88 +83 +77 +70 +-15 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-56 +70 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +69 +-40 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-113 +-105 +-99 +-93 +-86 +-79 +-73 +-69 +-65 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +110 +102 +94 +88 +83 +77 +70 +-15 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-58 +68 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +69 +-42 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-25 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-36 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-113 +-103 +-97 +-91 +-85 +-78 +-71 +-66 +-62 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +3 +-105 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-8 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +81 +-30 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-18 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +110 +103 +96 +88 +82 +77 +72 +66 +61 +57 +-25 +-125 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-60 +68 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +70 +-40 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-24 +98 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-112 +-105 +-98 +-90 +-83 +-78 +-73 +-68 +-62 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +110 +103 +95 +87 +81 +77 +72 +-13 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-56 +69 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +68 +-41 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-25 +98 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-113 +-103 +-97 +-91 +-85 +-78 +-72 +-67 +-64 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +3 +-104 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-8 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +122 +112 +104 +98 +90 +83 +77 +73 +67 +62 +58 +-24 +-124 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-117 +-107 +-100 +-94 +-88 +-81 +-74 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +115 +1 +-106 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-12 +112 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +121 +113 +106 +99 +91 +84 +78 +74 +68 +62 +58 +-25 +-124 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-59 +67 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-42 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-114 +-105 +-98 +-92 +-86 +-78 +-74 +-70 +-64 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +111 +103 +94 +88 +83 +78 +71 +-15 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-58 +68 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-115 +-106 +-98 +-92 +-86 +-80 +-72 +-68 +-64 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +110 +101 +94 +89 +84 +77 +70 +-15 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-57 +70 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +65 +-46 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-121 +-114 +-106 +-99 +-90 +-84 +-79 +-74 +-69 +-63 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +109 +102 +96 +90 +83 +76 +71 +-13 +-112 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-115 +-108 +-100 +-91 +-85 +-80 +-75 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +113 +-1 +-108 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-9 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +83 +-30 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +121 +111 +102 +95 +90 +84 +77 +71 +67 +63 +58 +-27 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-61 +66 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-43 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-25 +98 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-119 +-110 +-104 +-97 +-90 +-82 +-76 +-72 +-68 +-63 +107 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +4 +-103 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +81 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-18 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +110 +103 +97 +91 +84 +77 +71 +67 +63 +57 +-27 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-117 +-109 +-102 +-93 +-86 +-81 +-76 +94 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +124 +116 +109 +102 +93 +86 +80 +76 +70 +-15 +-116 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-114 +-106 +-100 +-94 +-86 +-79 +-73 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +115 +0 +-107 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-11 +112 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +110 +103 +97 +90 +83 +76 +71 +67 +62 +57 +-27 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-117 +-109 +-101 +-93 +-86 +-81 +-76 +94 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +125 +118 +109 +100 +92 +86 +81 +76 +69 +-16 +-116 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-115 +-106 +-99 +-93 +-87 +-79 +-74 +94 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +124 +118 +110 +101 +93 +86 +81 +76 +70 +-14 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-116 +-108 +-98 +-92 +-87 +-80 +-73 +96 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +124 +116 +108 +102 +94 +86 +79 +75 +71 +-14 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-56 +69 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +65 +-45 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +99 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-112 +-103 +-97 +-91 +-85 +-78 +-71 +-67 +-64 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +117 +2 +-104 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-9 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +83 +-29 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +121 +111 +102 +95 +89 +84 +77 +71 +66 +62 +59 +-25 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-117 +-107 +-100 +-94 +-88 +-81 +-74 +96 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +115 +1 +-106 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +81 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +113 +104 +96 +89 +84 +78 +72 +66 +62 +58 +-26 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-62 +65 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +66 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-24 +99 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-113 +-105 +-97 +-88 +-83 +-78 +-73 +-66 +-61 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +111 +104 +96 +88 +81 +76 +72 +-12 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-116 +-107 +-98 +-91 +-86 +-80 +-74 +97 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +116 +2 +-106 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-11 +112 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +113 +106 +98 +90 +84 +79 +73 +67 +62 +59 +-24 +-123 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-59 +65 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-43 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-26 +98 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-113 +-105 +-97 +-89 +-83 +-78 +-73 +-67 +-61 +108 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +110 +104 +96 +89 +81 +76 +72 +-12 +-113 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-115 +-106 +-98 +-92 +-86 +-80 +-74 +97 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +116 +2 +-106 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-11 +111 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +123 +114 +105 +97 +91 +86 +80 +73 +67 +63 +60 +-24 +-125 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-60 +65 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +66 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-115 +-106 +-98 +-90 +-83 +-76 +-72 +-68 +-63 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +2 +-105 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-8 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +122 +115 +107 +99 +91 +84 +79 +75 +69 +63 +58 +-24 +-124 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-126 +-118 +-108 +-99 +-93 +-87 +-81 +-76 +96 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +113 +-1 +-108 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-11 +112 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +122 +112 +104 +98 +92 +86 +78 +72 +67 +63 +58 +-27 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-115 +-108 +-100 +-93 +-88 +-82 +-75 +94 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +113 +-1 +-108 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +111 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +82 +-30 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-36 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +110 +102 +97 +89 +82 +76 +72 +66 +61 +57 +-26 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-60 +65 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-26 +98 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-119 +-111 +-104 +-97 +-89 +-82 +-76 +-72 +-67 +-62 +108 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +4 +-104 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +114 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +111 +102 +95 +89 +84 +77 +71 +66 +63 +58 +-27 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-116 +-109 +-102 +-95 +-87 +-80 +-75 +93 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +113 +-2 +-109 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-9 +114 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +110 +104 +95 +87 +82 +77 +71 +65 +61 +58 +-26 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-62 +64 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-114 +-105 +-98 +-92 +-86 +-79 +-72 +-67 +-64 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +110 +104 +96 +88 +81 +76 +72 +-13 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-56 +69 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +66 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-115 +-106 +-98 +-91 +-86 +-80 +-74 +-67 +-63 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +5 +-102 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +113 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +122 +113 +105 +98 +92 +84 +78 +73 +69 +64 +58 +-26 +-124 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-116 +-109 +-101 +-92 +-86 +-81 +-76 +94 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +114 +1 +-106 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-11 +112 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +121 +114 +106 +97 +90 +86 +80 +73 +68 +65 +60 +-25 +-124 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-117 +-109 +-101 +-93 +-86 +-80 +-76 +93 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +115 +1 +-106 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-10 +111 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +113 +106 +98 +90 +84 +78 +74 +69 +63 +58 +-25 +-124 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-126 +-117 +-108 +-99 +-92 +-87 +-81 +-76 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +117 +107 +101 +93 +86 +80 +75 +69 +-16 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-57 +70 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +66 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-26 +97 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-18 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +75 +-37 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-112 +-106 +-98 +-90 +-83 +-77 +-73 +-68 +-62 +107 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +5 +-103 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-8 +114 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-31 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-33 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +111 +104 +96 +88 +82 +77 +72 +66 +61 +57 +-26 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-61 +64 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-25 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-111 +-104 +-99 +-92 +-85 +-79 +-75 +-69 +-63 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +120 +110 +101 +94 +88 +83 +77 +70 +-15 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-114 +-107 +-100 +-91 +-84 +-78 +-74 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +108 +100 +94 +87 +80 +74 +70 +-14 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-56 +68 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +68 +-43 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-26 +99 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-111 +-104 +-98 +-91 +-83 +-76 +-71 +-67 +-63 +107 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +109 +101 +94 +89 +82 +75 +70 +-13 +-113 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-116 +-107 +-99 +-91 +-85 +-80 +-75 +96 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +125 +117 +110 +101 +93 +86 +81 +76 +70 +-15 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-122 +-114 +-107 +-100 +-92 +-84 +-78 +-74 +95 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +125 +115 +106 +100 +94 +87 +80 +74 +69 +-14 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-116 +-107 +-98 +-91 +-86 +-80 +-75 +96 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +114 +0 +-107 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-11 +111 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +82 +-30 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +79 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +102 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +111 +103 +97 +90 +83 +77 +72 +68 +64 +58 +-26 +-125 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-61 +66 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +65 +-46 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-25 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-23 +100 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-36 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-19 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +80 +-32 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-120 +-111 +-104 +-98 +-91 +-84 +-76 +-71 +-67 +-63 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +111 +102 +94 +88 +82 +78 +71 +-15 +-115 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-57 +68 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +67 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-24 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-121 +-112 +-103 +-96 +-90 +-85 +-79 +-72 +-66 +-62 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +3 +-105 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-7 +114 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +81 +-31 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-18 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +119 +111 +103 +98 +90 +83 +76 +71 +67 +63 +57 +-27 +-126 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-117 +-109 +-102 +-93 +-86 +-81 +-76 +93 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +125 +118 +109 +100 +92 +86 +81 +76 +69 +-15 +-116 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-59 +67 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +70 +-41 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-113 +-104 +-98 +-92 +-85 +-78 +-72 +-68 +-64 +105 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +4 +-103 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-6 +117 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +81 +-30 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +77 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-20 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +118 +109 +102 +96 +89 +82 +75 +72 +67 +61 +56 +-27 +-125 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-125 +-117 +-109 +-101 +-92 +-85 +-80 +-76 +94 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +124 +115 +107 +101 +94 +87 +80 +75 +70 +-13 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-56 +68 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +66 +-43 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-123 +-115 +-108 +-100 +-91 +-86 +-81 +-75 +-68 +-64 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +117 +2 +-106 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-8 +115 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +121 +113 +106 +99 +91 +84 +78 +74 +69 +64 +58 +-26 +-124 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-61 +66 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +66 +-44 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-114 +-106 +-100 +-93 +-85 +-79 +-74 +-69 +-64 +106 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +117 +109 +103 +96 +89 +81 +76 +71 +-12 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-56 +69 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +69 +-41 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-124 +-115 +-105 +-97 +-91 +-86 +-80 +-73 +-67 +-63 +104 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +117 +109 +103 +95 +88 +81 +76 +72 +-13 +-114 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-55 +69 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +68 +-42 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-25 +99 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +78 +-34 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +103 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-35 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-21 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +76 +-36 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-127 +-22 +101 +126 +126 +126 +126 +126 +126 +126 +126 +126 diff --git a/traces/nexkey_74755342.pm3 b/traces/nexkey_74755342.pm3 new file mode 100644 index 000000000..d956250e6 --- /dev/null +++ b/traces/nexkey_74755342.pm3 @@ -0,0 +1,10000 @@ +-18 +0 +-15 +-1 +-16 +-1 +-17 +-1 +-16 +1 +-15 +1 +-15 +-1 +-17 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-16 +2 +-15 +-1 +-17 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +-1 +-16 +1 +-15 +1 +-14 +0 +-16 +-1 +-16 +1 +-13 +2 +-14 +0 +-17 +-1 +-17 +2 +-13 +2 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +-1 +-16 +-1 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +1 +-15 +1 +-14 +2 +-15 +0 +-16 +-1 +-15 +1 +-15 +2 +-15 +0 +-17 +-1 +-16 +1 +-14 +1 +-14 +1 +-16 +-1 +-15 +1 +-15 +2 +-15 +1 +-16 +0 +-16 +1 +-14 +2 +-15 +1 +-16 +0 +-15 +2 +-13 +2 +-14 +0 +-15 +1 +-15 +2 +-14 +1 +-14 +0 +-16 +1 +-15 +2 +-13 +3 +-13 +2 +-14 +2 +-14 +3 +-12 +3 +-13 +1 +-15 +1 +-15 +1 +-13 +2 +-14 +1 +-16 +0 +-15 +2 +-13 +1 +-14 +2 +-16 +2 +-15 +2 +-13 +1 +-15 +1 +-15 +1 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +0 +-14 +2 +-14 +1 +-16 +0 +-16 +1 +-14 +2 +-15 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +-2 +-18 +-1 +-18 +0 +-15 +1 +-15 +0 +-16 +0 +-15 +2 +-14 +2 +-13 +1 +-16 +1 +-16 +1 +-14 +3 +-14 +1 +-16 +0 +-16 +2 +-14 +1 +-14 +0 +-16 +1 +-15 +1 +-14 +1 +-15 +-1 +-17 +-2 +-17 +-1 +-15 +0 +-16 +-2 +-17 +-2 +-16 +0 +-16 +0 +-15 +-1 +-18 +-2 +-17 +-1 +-15 +0 +-16 +-1 +-17 +-1 +-16 +1 +-15 +0 +-15 +-1 +-17 +0 +-15 +0 +-15 +0 +-15 +1 +-16 +-1 +-17 +2 +-15 +1 +-13 +0 +-17 +-1 +-16 +1 +-14 +1 +-15 +0 +-15 +0 +-16 +1 +-15 +0 +-14 +0 +-16 +-1 +-16 +1 +-13 +1 +-15 +0 +-16 +0 +-15 +1 +-14 +1 +-15 +1 +-16 +-1 +-16 +1 +-14 +1 +-14 +-1 +-17 +1 +-15 +1 +-15 +2 +-14 +0 +-15 +0 +-15 +1 +-14 +2 +-15 +1 +-16 +1 +-16 +0 +-15 +2 +-14 +0 +-16 +-1 +-16 +1 +-15 +1 +-13 +1 +-15 +0 +-15 +0 +-14 +2 +-15 +0 +-15 +0 +-16 +1 +-15 +2 +-15 +0 +-15 +1 +-16 +1 +-14 +1 +-15 +1 +-16 +2 +-15 +1 +-14 +1 +-15 +1 +-15 +0 +-16 +1 +-14 +2 +-15 +2 +-15 +0 +-16 +1 +-14 +1 +-14 +0 +-15 +0 +-15 +2 +-14 +1 +-14 +1 +-17 +-1 +-16 +0 +-15 +1 +-15 +1 +-16 +1 +-15 +1 +-14 +2 +-14 +1 +-16 +1 +-15 +1 +-15 +1 +-15 +1 +-17 +1 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-15 +1 +-15 +1 +-15 +1 +-15 +0 +-15 +1 +-15 +1 +-16 +0 +-15 +1 +-15 +1 +-14 +0 +-17 +0 +-16 +0 +-14 +3 +-14 +0 +-16 +0 +-16 +2 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +3 +-14 +0 +-17 +0 +-16 +1 +-13 +2 +-13 +1 +-16 +2 +-16 +2 +-14 +1 +-14 +0 +-17 +1 +-16 +1 +-14 +2 +-15 +0 +-16 +0 +-16 +2 +-14 +1 +-14 +1 +-17 +-1 +-16 +1 +-13 +2 +-13 +0 +-16 +1 +-16 +1 +-14 +1 +-14 +0 +-15 +0 +-15 +1 +-15 +2 +-14 +-1 +-16 +0 +-16 +2 +-13 +2 +-14 +0 +-16 +-1 +-17 +1 +-13 +2 +-15 +-1 +-16 +0 +-14 +1 +-32 +-60 +-11 +-13 +10 +-9 +3 +-15 +1 +-13 +5 +-11 +5 +-11 +5 +-10 +57 +31 +-3 +-5 +-22 +-5 +-19 +-1 +-17 +-1 +-16 +-1 +-19 +-3 +-18 +0 +-33 +-61 +-12 +-14 +9 +-11 +2 +-16 +0 +-15 +3 +-12 +4 +-11 +4 +-10 +58 +30 +-3 +-5 +-21 +-5 +-18 +-1 +-18 +-1 +-16 +-3 +-19 +-3 +-18 +-1 +-34 +-61 +-13 +-14 +8 +-11 +1 +-17 +0 +-14 +4 +-12 +3 +-13 +3 +-10 +5 +-10 +5 +-13 +2 +-13 +2 +-13 +2 +-13 +3 +-15 +2 +-15 +0 +-15 +54 +27 +-7 +-6 +-24 +-8 +-21 +-3 +-20 +-3 +-17 +-3 +-19 +-3 +-18 +-1 +-16 +0 +-17 +-2 +-17 +-1 +-18 +-1 +-16 +-1 +-16 +-1 +-18 +-2 +-17 +-1 +-16 +0 +-16 +0 +-16 +0 +-16 +2 +-14 +0 +-16 +-1 +-17 +0 +-14 +1 +-15 +1 +-15 +0 +-16 +1 +-14 +1 +-14 +2 +-15 +1 +-17 +-1 +-15 +0 +-15 +1 +-13 +1 +-16 +1 +-16 +1 +-13 +1 +-15 +0 +-15 +0 +-16 +2 +-14 +1 +-14 +0 +-16 +1 +-16 +0 +-14 +1 +-14 +0 +-16 +1 +-15 +1 +-13 +0 +-15 +1 +-16 +1 +-16 +1 +-15 +1 +-13 +0 +-15 +0 +-16 +1 +-13 +1 +-15 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-15 +0 +-16 +1 +-15 +1 +-15 +0 +-15 +0 +-16 +1 +-15 +1 +-15 +1 +-16 +1 +-16 +0 +-13 +2 +-14 +1 +-16 +1 +-16 +1 +-14 +1 +-14 +2 +-17 +-1 +-17 +0 +-15 +1 +-14 +0 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-14 +1 +-13 +1 +-14 +-1 +-16 +1 +-16 +2 +-14 +1 +-15 +0 +-16 +0 +-14 +2 +-13 +1 +-14 +-1 +-15 +0 +-16 +2 +-14 +1 +-15 +0 +-15 +1 +-16 +1 +-13 +1 +-14 +1 +-16 +1 +-15 +1 +-15 +1 +-14 +0 +-15 +0 +-16 +1 +-15 +2 +-15 +0 +-16 +0 +-15 +1 +-15 +1 +-15 +-1 +-16 +1 +-15 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-15 +2 +-14 +1 +-15 +0 +-17 +0 +-15 +1 +-15 +0 +-16 +0 +-15 +1 +-15 +1 +-15 +0 +-16 +1 +-16 +1 +-14 +2 +-14 +0 +-17 +-1 +-16 +1 +-14 +1 +-14 +2 +-16 +-1 +-16 +1 +-15 +1 +-14 +0 +-16 +-1 +-17 +1 +-14 +1 +-13 +1 +-15 +0 +-16 +1 +-14 +2 +-13 +1 +-14 +2 +-14 +2 +-13 +2 +-13 +3 +-13 +3 +-13 +3 +-13 +2 +-15 +1 +-16 +1 +-16 +0 +-14 +1 +-15 +0 +-16 +0 +-16 +2 +-13 +2 +-13 +3 +-14 +2 +-14 +3 +-12 +4 +-12 +2 +-14 +2 +-15 +3 +-13 +2 +-13 +1 +-15 +1 +-14 +1 +-13 +3 +-13 +1 +-16 +1 +-16 +1 +-14 +2 +-15 +1 +-15 +0 +-15 +1 +-14 +2 +-14 +0 +-17 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-12 +2 +-14 +-1 +-16 +-1 +-17 +1 +-14 +0 +-16 +-1 +-17 +-1 +-17 +0 +-15 +0 +-16 +-2 +-17 +-1 +-17 +0 +-15 +1 +-15 +0 +-18 +-1 +-16 +0 +-15 +1 +-15 +0 +-17 +0 +-16 +0 +-14 +1 +-15 +0 +-17 +-1 +-16 +0 +-14 +1 +-16 +0 +-16 +-1 +-16 +1 +-14 +1 +-14 +-1 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-15 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-14 +2 +-16 +0 +-16 +-1 +-16 +1 +-15 +1 +-15 +1 +-16 +1 +-16 +0 +-14 +1 +-16 +0 +-17 +1 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-17 +0 +-14 +2 +-15 +-1 +-16 +1 +-17 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +1 +-17 +-1 +-17 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +0 +-14 +2 +-15 +0 +-15 +0 +-16 +2 +-32 +-59 +-10 +-12 +9 +-9 +3 +-15 +2 +-12 +4 +-10 +5 +-10 +5 +-11 +56 +30 +-4 +-4 +-21 +-6 +-20 +-1 +-17 +-2 +-18 +-2 +-18 +-3 +-18 +-1 +-15 +-1 +-17 +-2 +-17 +-3 +-17 +0 +-15 +1 +-15 +-1 +-17 +-1 +-16 +0 +-33 +-60 +-11 +-13 +9 +-9 +3 +-15 +2 +-13 +5 +-11 +5 +-11 +5 +-11 +57 +30 +-3 +-4 +-22 +-4 +-18 +-1 +-16 +-1 +-17 +-2 +-18 +-1 +-16 +0 +-14 +1 +-14 +0 +-16 +1 +-15 +2 +-13 +2 +-14 +1 +-16 +0 +-16 +0 +-16 +1 +-15 +-1 +-17 +-1 +-17 +0 +-15 +1 +-15 +1 +-16 +0 +-15 +2 +-31 +-59 +-10 +-11 +11 +-9 +4 +-15 +3 +-12 +4 +-10 +5 +-11 +5 +-9 +7 +-9 +5 +-12 +3 +-12 +3 +-14 +3 +-12 +3 +-14 +1 +-15 +1 +-15 +54 +28 +-6 +-6 +-23 +-6 +-20 +-3 +-18 +-2 +-17 +-3 +-19 +-2 +-18 +-1 +-15 +0 +-17 +-2 +-18 +-2 +-18 +-1 +-16 +0 +-15 +0 +-17 +-1 +-16 +1 +-33 +-60 +-11 +-12 +9 +-10 +2 +-15 +1 +-14 +4 +-11 +4 +-11 +4 +-11 +57 +30 +-4 +-5 +-22 +-4 +-18 +-2 +-17 +-2 +-17 +-3 +-19 +-2 +-18 +-1 +-16 +-1 +-16 +-1 +-17 +-1 +-16 +0 +-15 +0 +-17 +-2 +-18 +-2 +-18 +0 +-15 +0 +-16 +-2 +-18 +-1 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +2 +-14 +1 +-14 +1 +-16 +1 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-32 +-60 +-10 +-12 +10 +-9 +3 +-15 +1 +-14 +4 +-11 +4 +-11 +5 +-10 +6 +-9 +4 +-13 +2 +-14 +2 +-13 +3 +-13 +2 +-15 +1 +-15 +1 +-15 +3 +-13 +1 +-15 +0 +-16 +0 +-15 +2 +-14 +2 +-15 +0 +-15 +1 +-15 +2 +-14 +1 +-15 +1 +-16 +0 +-16 +2 +-14 +0 +-16 +-1 +-17 +-1 +-16 +-1 +-15 +0 +-18 +-1 +-17 +-2 +-16 +0 +-15 +0 +-16 +0 +-17 +0 +-16 +2 +-13 +1 +-17 +-1 +-17 +-1 +-16 +1 +-14 +0 +-15 +1 +-16 +-1 +-16 +52 +27 +-7 +-9 +-27 +-9 +-23 +-5 +-20 +-3 +-18 +-4 +-19 +-3 +-18 +-1 +-17 +0 +-16 +-2 +-18 +-1 +-17 +0 +-16 +0 +-15 +-1 +-16 +-1 +-17 +0 +-15 +0 +-14 +1 +-16 +0 +-16 +1 +-15 +0 +-14 +0 +-16 +-1 +-16 +0 +-33 +-61 +-11 +-12 +10 +-9 +3 +-15 +2 +-14 +5 +-11 +4 +-11 +4 +-10 +57 +31 +-3 +-5 +-21 +-5 +-18 +-3 +-16 +-1 +-17 +-3 +-18 +-2 +-18 +0 +-16 +0 +-17 +-1 +-17 +-1 +-18 +-1 +-15 +0 +-15 +0 +-17 +-1 +-16 +1 +-33 +-59 +-11 +-14 +10 +-11 +2 +-15 +1 +-13 +3 +-11 +5 +-11 +4 +-10 +57 +29 +-5 +-4 +-21 +-5 +-19 +-3 +-18 +-1 +-18 +-3 +-19 +-3 +-18 +-1 +-15 +0 +-15 +-1 +-18 +-2 +-16 +0 +-15 +0 +-16 +0 +-17 +0 +-16 +1 +-15 +1 +-14 +0 +-17 +0 +-16 +0 +-15 +1 +-14 +0 +-17 +1 +-16 +1 +-14 +1 +-14 +-1 +-17 +-1 +-15 +0 +-14 +0 +-15 +1 +-16 +-1 +-16 +1 +-33 +-60 +-9 +-12 +9 +-9 +3 +-14 +3 +-13 +4 +-10 +4 +-11 +5 +-10 +57 +31 +-3 +-5 +-22 +-5 +-19 +-1 +-17 +-2 +-18 +-2 +-18 +-3 +-18 +-1 +-16 +-1 +-17 +-2 +-18 +-1 +-17 +0 +-15 +0 +-14 +-1 +-17 +-1 +-16 +1 +-32 +-60 +-10 +-12 +9 +-10 +3 +-15 +2 +-14 +4 +-12 +5 +-11 +5 +-10 +5 +-10 +4 +-13 +1 +-15 +0 +-15 +1 +-14 +0 +-16 +1 +-16 +1 +-15 +3 +-13 +1 +-15 +0 +-16 +0 +-15 +2 +-13 +1 +-16 +1 +-16 +0 +-15 +54 +29 +-5 +-7 +-25 +-6 +-21 +-3 +-18 +-1 +-17 +-3 +-19 +-3 +-18 +-1 +-16 +-1 +-16 +-2 +-18 +-2 +-17 +0 +-15 +0 +-15 +-1 +-16 +0 +-17 +0 +-15 +1 +-16 +-1 +-17 +0 +-17 +1 +-15 +2 +-15 +1 +-16 +0 +-15 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +0 +-15 +1 +-14 +0 +-16 +-1 +-16 +1 +-14 +1 +-14 +0 +-16 +1 +-14 +2 +-14 +2 +-14 +2 +-14 +1 +-14 +3 +-30 +-57 +-10 +-13 +9 +-10 +4 +-15 +1 +-13 +5 +-10 +7 +-9 +7 +-7 +59 +31 +-3 +-5 +-22 +-5 +-19 +-3 +-18 +-1 +-17 +-1 +-17 +-1 +-17 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-14 +2 +-14 +0 +-16 +1 +-15 +2 +-14 +2 +-14 +1 +-15 +-1 +-15 +2 +-15 +1 +-15 +1 +-16 +0 +-15 +1 +-15 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +-1 +-15 +2 +-14 +1 +-15 +0 +-17 +1 +-15 +1 +-14 +1 +-14 +1 +-15 +0 +-15 +1 +-14 +2 +-13 +1 +-16 +1 +-16 +1 +-14 +2 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-17 +0 +-16 +0 +-14 +2 +-14 +0 +-16 +-1 +-16 +1 +-14 +0 +-15 +-1 +-16 +-1 +-16 +0 +-16 +1 +-15 +-1 +-18 +-2 +-17 +0 +-15 +1 +-16 +-2 +-17 +-1 +-17 +0 +-15 +1 +-15 +0 +-16 +1 +-14 +2 +-12 +2 +-13 +1 +-15 +0 +-15 +2 +-14 +2 +-13 +1 +-16 +1 +-14 +2 +-13 +2 +-13 +1 +-15 +1 +-16 +2 +-14 +2 +-14 +1 +-15 +1 +-16 +2 +-14 +1 +-14 +0 +-16 +1 +-15 +2 +-14 +2 +-15 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-15 +1 +-16 +-1 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-15 +0 +-17 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +2 +-14 +-1 +-17 +0 +-16 +-1 +-16 +0 +-16 +-1 +-17 +0 +-15 +2 +-14 +2 +-13 +0 +-15 +1 +-15 +1 +-14 +2 +-14 +0 +-15 +0 +-16 +1 +-14 +2 +-14 +1 +-16 +1 +-16 +1 +-13 +1 +-15 +0 +-16 +1 +-16 +1 +-14 +2 +-15 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +1 +-15 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-15 +2 +-14 +0 +-16 +0 +-16 +0 +-14 +1 +-14 +0 +-15 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +1 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +1 +-14 +-1 +-17 +1 +-16 +1 +-14 +1 +-14 +1 +-16 +-1 +-16 +1 +-15 +1 +-15 +-1 +-18 +-2 +-17 +0 +-15 +0 +-16 +-1 +-17 +-1 +-16 +1 +-15 +2 +-14 +1 +-16 +1 +-15 +2 +-12 +2 +-14 +1 +-16 +1 +-15 +2 +-13 +2 +-13 +1 +-16 +1 +-16 +1 +-13 +2 +-14 +1 +-16 +0 +-15 +1 +-13 +2 +-14 +0 +-15 +0 +-16 +1 +-15 +2 +-15 +1 +-16 +0 +-16 +0 +-14 +2 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +0 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-17 +1 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +-1 +-16 +1 +-15 +0 +-16 +-1 +-17 +-1 +-16 +-1 +-15 +1 +-14 +1 +-15 +1 +-15 +2 +-13 +2 +-14 +1 +-15 +1 +-14 +1 +-13 +3 +-14 +1 +-15 +1 +-15 +1 +-14 +1 +-15 +1 +-16 +0 +-15 +1 +-14 +2 +-15 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-15 +2 +-14 +1 +-15 +0 +-17 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-17 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +0 +-14 +1 +-15 +0 +-16 +-1 +-17 +0 +-16 +-1 +-16 +-1 +-17 +-1 +-17 +-1 +-15 +0 +-17 +-1 +-16 +0 +-15 +2 +-12 +2 +-13 +2 +-15 +1 +-15 +2 +-12 +3 +-13 +0 +-15 +1 +-15 +2 +-14 +1 +-14 +1 +-16 +1 +-15 +1 +-32 +-59 +-10 +-12 +9 +-9 +4 +-15 +2 +-13 +5 +-10 +4 +-11 +5 +-10 +58 +31 +-3 +-4 +-22 +-4 +-19 +-2 +-17 +-1 +-17 +-2 +-18 +-2 +-18 +-1 +-34 +-62 +-12 +-13 +8 +-11 +2 +-16 +0 +-14 +3 +-12 +3 +-12 +4 +-11 +57 +29 +-4 +-5 +-23 +-5 +-20 +-2 +-17 +-1 +-17 +-3 +-19 +-2 +-19 +-1 +-34 +-61 +-13 +-15 +8 +-12 +2 +-16 +0 +-15 +3 +-11 +3 +-12 +4 +-11 +6 +-10 +2 +-14 +1 +-15 +0 +-15 +1 +-14 +1 +-15 +0 +-15 +1 +-14 +54 +29 +-5 +-7 +-24 +-6 +-21 +-3 +-18 +-2 +-17 +-2 +-19 +-2 +-17 +-1 +-15 +0 +-16 +-1 +-17 +-2 +-17 +-1 +-15 +1 +-16 +-1 +-17 +0 +-16 +1 +-15 +0 +-15 +0 +-16 +0 +-16 +0 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +-1 +-16 +0 +-15 +1 +-14 +-1 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-13 +2 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +1 +-15 +0 +-15 +1 +-15 +0 +-16 +1 +-16 +1 +-14 +1 +-14 +0 +-17 +0 +-16 +-1 +-16 +1 +-16 +-1 +-17 +-1 +-16 +1 +-15 +1 +-15 +1 +-16 +1 +-15 +1 +-13 +2 +-13 +0 +-16 +1 +-16 +2 +-13 +1 +-15 +1 +-16 +0 +-15 +2 +-13 +2 +-14 +-1 +-16 +1 +-16 +1 +-15 +2 +-14 +0 +-15 +1 +-16 +2 +-14 +2 +-14 +0 +-16 +-1 +-15 +1 +-14 +2 +-14 +0 +-16 +1 +-16 +2 +-13 +2 +-14 +0 +-16 +-1 +-16 +1 +-14 +2 +-15 +0 +-17 +0 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-15 +0 +-17 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +2 +-14 +0 +-16 +0 +-16 +1 +-15 +0 +-15 +0 +-18 +-1 +-17 +0 +-16 +0 +-16 +-1 +-18 +-1 +-17 +1 +-15 +2 +-14 +2 +-15 +1 +-15 +2 +-14 +2 +-14 +1 +-16 +1 +-16 +2 +-13 +2 +-14 +1 +-15 +0 +-15 +2 +-13 +2 +-14 +0 +-16 +0 +-16 +2 +-14 +2 +-14 +0 +-16 +1 +-16 +2 +-13 +1 +-14 +0 +-16 +-1 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-15 +2 +-14 +2 +-14 +1 +-15 +-1 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-15 +1 +-16 +-1 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-15 +-1 +-17 +-1 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +2 +-13 +1 +-14 +0 +-16 +-1 +-16 +0 +-15 +1 +-15 +-1 +-18 +-1 +-16 +0 +-15 +1 +-15 +-1 +-17 +-1 +-16 +2 +-13 +2 +-14 +1 +-15 +1 +-15 +2 +-13 +2 +-14 +0 +-15 +1 +-15 +2 +-13 +3 +-13 +1 +-15 +0 +-16 +2 +-12 +2 +-14 +0 +-16 +0 +-16 +1 +-15 +2 +-15 +0 +-16 +1 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-15 +1 +-14 +2 +-14 +1 +-16 +-1 +-15 +1 +-15 +1 +-15 +0 +-17 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-17 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-17 +0 +-14 +1 +-15 +1 +-16 +0 +-15 +1 +-15 +1 +-15 +-1 +-16 +0 +-17 +-1 +-16 +0 +-17 +-1 +-18 +-1 +-17 +1 +-13 +3 +-13 +1 +-16 +0 +-15 +1 +-14 +2 +-14 +1 +-15 +-1 +-15 +2 +-14 +2 +-14 +1 +-15 +0 +-15 +1 +-13 +3 +-14 +0 +-15 +0 +-15 +2 +-13 +2 +-15 +0 +-17 +0 +-16 +1 +-15 +1 +-14 +-1 +-16 +0 +-15 +1 +-13 +2 +-14 +1 +-16 +0 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-15 +1 +-32 +-60 +-11 +-13 +10 +-9 +3 +-15 +2 +-13 +4 +-10 +4 +-11 +5 +-10 +57 +30 +-4 +-5 +-22 +-5 +-19 +-2 +-17 +-1 +-17 +-2 +-19 +-2 +-18 +-1 +-16 +0 +-17 +-2 +-19 +-1 +-17 +0 +-16 +0 +-15 +-1 +-17 +-1 +-16 +1 +-33 +-60 +-11 +-14 +7 +-11 +1 +-17 +1 +-15 +2 +-13 +4 +-12 +3 +-12 +56 +29 +-5 +-6 +-23 +-6 +-19 +-3 +-17 +-2 +-18 +-3 +-19 +-4 +-19 +-1 +-17 +-1 +-16 +-1 +-18 +-1 +-16 +0 +-15 +1 +-14 +0 +-15 +0 +-15 +2 +-13 +2 +-14 +1 +-16 +0 +-16 +2 +-13 +1 +-14 +0 +-16 +1 +-15 +1 +-32 +-60 +-10 +-12 +11 +-8 +3 +-14 +2 +-14 +5 +-10 +4 +-10 +5 +-10 +7 +-9 +5 +-12 +3 +-13 +1 +-13 +3 +-13 +2 +-15 +0 +-15 +1 +-15 +54 +28 +-6 +-8 +-24 +-7 +-21 +-3 +-17 +-2 +-17 +-2 +-19 +-3 +-18 +-1 +-16 +-1 +-16 +-2 +-18 +-2 +-17 +-1 +-16 +0 +-16 +-1 +-16 +-2 +-16 +0 +-33 +-61 +-12 +-14 +8 +-11 +2 +-16 +1 +-14 +3 +-10 +5 +-11 +4 +-10 +57 +31 +-3 +-5 +-22 +-5 +-18 +-1 +-16 +-1 +-17 +-3 +-18 +-2 +-18 +0 +-16 +0 +-16 +-1 +-17 +-1 +-16 +1 +-15 +0 +-15 +-1 +-17 +-1 +-16 +0 +-14 +1 +-15 +-1 +-16 +-1 +-16 +0 +-14 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +1 +-15 +-1 +-16 +-1 +-16 +1 +-14 +1 +-14 +1 +-17 +0 +-16 +1 +-32 +-60 +-10 +-13 +10 +-10 +3 +-15 +2 +-14 +4 +-11 +5 +-11 +5 +-10 +5 +-9 +5 +-13 +3 +-14 +2 +-15 +3 +-12 +1 +-15 +1 +-16 +1 +-15 +2 +-13 +0 +-16 +0 +-16 +0 +-15 +2 +-14 +1 +-15 +0 +-17 +0 +-17 +1 +-15 +0 +-17 +-1 +-17 +0 +-16 +1 +-14 +1 +-15 +1 +-14 +1 +-14 +3 +-13 +1 +-15 +0 +-15 +1 +-15 +2 +-12 +2 +-15 +1 +-15 +0 +-15 +3 +-14 +2 +-15 +0 +-15 +0 +-15 +3 +-13 +2 +-14 +0 +-15 +1 +-15 +54 +29 +-6 +-7 +-25 +-7 +-22 +-3 +-18 +-2 +-17 +-3 +-19 +-3 +-18 +-2 +-16 +0 +-16 +-1 +-18 +-1 +-18 +0 +-16 +0 +-16 +0 +-17 +-1 +-17 +1 +-14 +1 +-14 +-1 +-16 +0 +-17 +1 +-14 +1 +-15 +0 +-17 +0 +-15 +1 +-33 +-60 +-11 +-13 +10 +-10 +3 +-15 +1 +-13 +4 +-11 +5 +-11 +5 +-10 +57 +29 +-4 +-4 +-23 +-4 +-19 +-3 +-17 +-2 +-18 +-3 +-19 +-4 +-20 +-3 +-17 +-2 +-17 +-2 +-18 +-1 +-16 +0 +-15 +1 +-15 +-1 +-16 +0 +-16 +2 +-31 +-60 +-10 +-12 +10 +-9 +4 +-14 +2 +-13 +5 +-11 +5 +-11 +4 +-10 +57 +30 +-4 +-5 +-22 +-5 +-18 +-2 +-17 +-1 +-17 +-2 +-19 +-2 +-18 +0 +-15 +0 +-16 +-2 +-18 +-1 +-17 +0 +-15 +0 +-16 +0 +-17 +-1 +-16 +1 +-15 +1 +-15 +-1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-17 +0 +-17 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-32 +-60 +-10 +-12 +9 +-10 +3 +-16 +1 +-13 +4 +-11 +5 +-11 +5 +-10 +57 +30 +-4 +-5 +-22 +-5 +-20 +-4 +-19 +-3 +-19 +-4 +-20 +-3 +-19 +-1 +-16 +-1 +-17 +-1 +-17 +-1 +-16 +1 +-14 +1 +-15 +-1 +-16 +0 +-16 +1 +-32 +-60 +-10 +-13 +9 +-10 +3 +-15 +1 +-13 +5 +-11 +5 +-10 +5 +-10 +7 +-9 +5 +-12 +3 +-14 +2 +-14 +3 +-12 +2 +-15 +1 +-15 +1 +-15 +3 +-13 +1 +-16 +0 +-16 +1 +-15 +2 +-13 +1 +-15 +0 +-16 +0 +-14 +53 +27 +-6 +-8 +-25 +-7 +-21 +-3 +-18 +-2 +-18 +-3 +-19 +-3 +-18 +-1 +-17 +0 +-16 +-1 +-17 +-2 +-17 +-1 +-15 +1 +-16 +-1 +-16 +0 +-17 +1 +-16 +1 +-16 +0 +-17 +0 +-16 +1 +-15 +1 +-15 +0 +-17 +-1 +-16 +1 +-15 +1 +-15 +-1 +-18 +-3 +-17 +-1 +-17 +-1 +-15 +0 +-16 +1 +-16 +2 +-13 +1 +-14 +1 +-15 +0 +-15 +2 +-14 +3 +-13 +1 +-15 +1 +-15 +2 +-31 +-59 +-11 +-12 +10 +-10 +4 +-14 +1 +-13 +4 +-10 +5 +-11 +5 +-11 +57 +29 +-4 +-5 +-22 +-4 +-19 +-1 +-17 +-1 +-17 +-2 +-18 +-2 +-17 +-1 +-16 +0 +-16 +-2 +-17 +-1 +-17 +0 +-16 +1 +-16 +-1 +-17 +-1 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +0 +-14 +1 +-15 +0 +-15 +0 +-16 +1 +-15 +1 +-15 +0 +-17 +1 +-15 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-14 +0 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +-1 +-16 +-1 +-17 +-2 +-17 +0 +-16 +0 +-15 +-1 +-16 +0 +-16 +2 +-13 +3 +-14 +2 +-15 +0 +-15 +1 +-15 +1 +-15 +-1 +-17 +-1 +-17 +0 +-15 +1 +-16 +-1 +-17 +-1 +-17 +0 +-15 +1 +-15 +0 +-17 +-1 +-16 +0 +-15 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +-1 +-17 +-1 +-16 +2 +-13 +3 +-15 +-1 +-18 +-1 +-16 +1 +-15 +0 +-15 +-1 +-18 +-1 +-16 +0 +-14 +0 +-15 +0 +-17 +1 +-16 +1 +-15 +1 +-15 +0 +-16 +-1 +-15 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +0 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +1 +-15 +1 +-16 +1 +-16 +0 +-14 +2 +-15 +-1 +-18 +-1 +-18 +0 +-15 +1 +-15 +0 +-15 +0 +-15 +2 +-14 +2 +-14 +1 +-16 +1 +-15 +0 +-14 +2 +-14 +0 +-16 +0 +-15 +1 +-15 +2 +-15 +-1 +-16 +0 +-15 +2 +-13 +3 +-13 +2 +-15 +1 +-15 +2 +-13 +5 +-12 +3 +-13 +2 +-14 +3 +-13 +3 +-13 +1 +-15 +1 +-14 +2 +-13 +3 +-13 +2 +-15 +1 +-14 +3 +-13 +3 +-14 +1 +-15 +1 +-14 +1 +-13 +3 +-14 +1 +-15 +0 +-15 +2 +-13 +2 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-14 +1 +-16 +1 +-16 +2 +-14 +2 +-14 +0 +-17 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +-1 +-16 +1 +-15 +1 +-16 +-2 +-18 +-1 +-17 +-1 +-16 +1 +-15 +-1 +-17 +-1 +-17 +0 +-16 +1 +-14 +1 +-16 +1 +-14 +2 +-13 +2 +-14 +2 +-15 +1 +-15 +2 +-14 +2 +-14 +1 +-16 +1 +-15 +1 +-13 +3 +-13 +1 +-16 +1 +-15 +1 +-14 +2 +-14 +1 +-15 +-1 +-15 +1 +-14 +2 +-13 +1 +-16 +1 +-16 +1 +-14 +1 +-14 +1 +-16 +-1 +-15 +1 +-13 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +2 +-13 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +2 +-13 +2 +-15 +1 +-17 +0 +-15 +1 +-15 +1 +-14 +0 +-16 +1 +-16 +0 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-15 +0 +-17 +-2 +-18 +-1 +-17 +0 +-15 +1 +-14 +1 +-16 +1 +-16 +1 +-13 +2 +-14 +1 +-15 +1 +-15 +1 +-14 +2 +-14 +1 +-16 +1 +-14 +2 +-14 +2 +-14 +1 +-16 +1 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-15 +0 +-15 +0 +-16 +2 +-14 +1 +-14 +0 +-16 +0 +-15 +0 +-14 +1 +-14 +1 +-16 +0 +-15 +2 +-14 +2 +-14 +0 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +1 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +-1 +-16 +0 +-15 +1 +-14 +1 +-15 +1 +-16 +-1 +-15 +1 +-13 +1 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-17 +-1 +-16 +1 +-15 +1 +-15 +0 +-18 +0 +-16 +0 +-15 +1 +-15 +0 +-17 +-1 +-17 +0 +-15 +0 +-15 +0 +-16 +1 +-14 +2 +-13 +2 +-14 +1 +-16 +1 +-15 +1 +-13 +2 +-13 +1 +-15 +1 +-15 +2 +-13 +1 +-14 +1 +-16 +1 +-15 +1 +-14 +1 +-14 +1 +-16 +1 +-16 +2 +-13 +2 +-14 +0 +-17 +0 +-16 +1 +-14 +2 +-14 +1 +-15 +1 +-15 +2 +-13 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +1 +-14 +0 +-15 +0 +-16 +1 +-33 +-60 +-11 +-12 +9 +-9 +4 +-14 +2 +-13 +4 +-11 +5 +-11 +4 +-11 +57 +31 +-3 +-4 +-22 +-4 +-19 +-2 +-17 +-2 +-17 +-3 +-19 +-3 +-19 +-1 +-34 +-62 +-13 +-15 +7 +-12 +-1 +-18 +-1 +-16 +2 +-12 +2 +-13 +3 +-12 +56 +29 +-4 +-5 +-22 +-4 +-19 +-1 +-15 +-1 +-16 +-2 +-18 +-1 +-17 +0 +-33 +-61 +-11 +-14 +9 +-10 +2 +-16 +1 +-15 +4 +-11 +4 +-11 +5 +-10 +6 +-10 +4 +-12 +2 +-14 +2 +-15 +3 +-13 +2 +-15 +1 +-15 +1 +-15 +53 +28 +-6 +-7 +-24 +-6 +-20 +-3 +-18 +-1 +-18 +-3 +-19 +-3 +-18 +-1 +-16 +0 +-16 +-1 +-18 +-2 +-18 +-1 +-16 +1 +-16 +-1 +-17 +0 +-17 +0 +-15 +1 +-16 +0 +-17 +-1 +-17 +1 +-16 +1 +-15 +0 +-16 +-1 +-15 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-14 +1 +-15 +0 +-17 +0 +-17 +-1 +-16 +-1 +-16 +-1 +-17 +-1 +-17 +0 +-16 +0 +-16 +-1 +-17 +1 +-15 +1 +-13 +2 +-13 +1 +-16 +1 +-16 +2 +-14 +2 +-13 +2 +-15 +0 +-14 +1 +-14 +2 +-13 +0 +-15 +1 +-15 +2 +-14 +2 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-14 +2 +-15 +-1 +-16 +0 +-15 +1 +-13 +1 +-14 +1 +-16 +-1 +-16 +1 +-14 +1 +-15 +-1 +-16 +0 +-15 +2 +-13 +2 +-14 +1 +-16 +-1 +-16 +1 +-14 +1 +-15 +0 +-15 +0 +-15 +1 +-15 +1 +-15 +1 +-16 +-1 +-15 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +-1 +-18 +-1 +-17 +-1 +-16 +0 +-17 +-1 +-17 +-1 +-17 +0 +-15 +-1 +-16 +0 +-16 +1 +-14 +3 +-13 +3 +-13 +1 +-15 +1 +-15 +2 +-13 +2 +-14 +1 +-16 +0 +-14 +2 +-14 +3 +-13 +1 +-15 +1 +-15 +1 +-13 +1 +-14 +0 +-16 +1 +-16 +2 +-14 +2 +-14 +1 +-16 +0 +-15 +1 +-15 +2 +-15 +0 +-16 +0 +-15 +2 +-13 +1 +-15 +1 +-16 +0 +-16 +1 +-15 +2 +-14 +0 +-16 +0 +-15 +1 +-13 +1 +-15 +0 +-16 +-1 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +2 +-14 +1 +-14 +0 +-17 +0 +-15 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +0 +-14 +1 +-16 +-1 +-17 +-1 +-17 +-1 +-17 +0 +-17 +-1 +-17 +-1 +-17 +0 +-15 +1 +-15 +1 +-16 +1 +-14 +2 +-13 +3 +-13 +1 +-15 +1 +-15 +2 +-14 +2 +-13 +1 +-15 +0 +-15 +2 +-14 +2 +-14 +1 +-15 +1 +-15 +2 +-14 +1 +-14 +1 +-16 +1 +-16 +2 +-13 +2 +-14 +0 +-15 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +1 +-16 +1 +-13 +1 +-15 +0 +-16 +-1 +-15 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-13 +2 +-15 +-1 +-16 +-1 +-16 +1 +-13 +1 +-14 +0 +-16 +0 +-16 +0 +-14 +2 +-14 +1 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +2 +-14 +1 +-14 +0 +-16 +-1 +-17 +-1 +-17 +0 +-16 +-1 +-17 +-1 +-16 +1 +-14 +2 +-13 +0 +-16 +1 +-16 +1 +-13 +1 +-13 +1 +-15 +1 +-15 +1 +-13 +2 +-14 +0 +-16 +1 +-16 +1 +-14 +2 +-15 +1 +-16 +1 +-15 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-13 +0 +-16 +1 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-17 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +-1 +-15 +1 +-14 +1 +-15 +1 +-16 +1 +-15 +1 +-14 +2 +-14 +0 +-16 +-1 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-14 +2 +-15 +0 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +1 +-16 +1 +-33 +-60 +-10 +-13 +8 +-11 +1 +-16 +1 +-14 +4 +-11 +4 +-12 +5 +-10 +57 +30 +-3 +-4 +-22 +-4 +-19 +-2 +-17 +-1 +-17 +-2 +-18 +-3 +-18 +-1 +-15 +0 +-15 +-1 +-17 +-1 +-16 +0 +-15 +1 +-15 +0 +-17 +0 +-16 +1 +-33 +-60 +-10 +-12 +10 +-10 +3 +-15 +2 +-13 +5 +-11 +5 +-10 +5 +-11 +57 +31 +-4 +-5 +-22 +-4 +-19 +-1 +-16 +-1 +-17 +-2 +-19 +-3 +-18 +-1 +-16 +-1 +-16 +-2 +-17 +-1 +-17 +0 +-15 +0 +-15 +-1 +-18 +0 +-16 +1 +-14 +2 +-16 +0 +-16 +0 +-17 +1 +-15 +1 +-14 +0 +-16 +-1 +-16 +1 +-32 +-60 +-10 +-13 +10 +-10 +3 +-15 +2 +-13 +3 +-11 +4 +-11 +5 +-10 +5 +-10 +4 +-13 +2 +-14 +1 +-14 +3 +-13 +1 +-15 +1 +-16 +1 +-15 +53 +27 +-6 +-7 +-25 +-6 +-21 +-4 +-17 +-1 +-18 +-2 +-18 +-2 +-17 +0 +-16 +0 +-16 +-2 +-19 +-1 +-17 +0 +-16 +0 +-16 +-1 +-17 +-1 +-16 +0 +-33 +-60 +-11 +-13 +9 +-10 +3 +-15 +1 +-13 +4 +-11 +4 +-11 +5 +-11 +57 +30 +-5 +-5 +-22 +-5 +-19 +-1 +-17 +-2 +-17 +-3 +-18 +-2 +-18 +-1 +-16 +0 +-16 +-1 +-17 +-1 +-17 +0 +-16 +0 +-16 +-1 +-17 +-1 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-17 +0 +-15 +-1 +-15 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-17 +0 +-15 +1 +-14 +1 +-15 +1 +-16 +-1 +-16 +1 +-32 +-60 +-11 +-13 +9 +-10 +3 +-16 +2 +-14 +4 +-10 +4 +-11 +5 +-10 +6 +-10 +4 +-13 +2 +-13 +3 +-14 +3 +-13 +2 +-15 +1 +-15 +1 +-15 +3 +-13 +1 +-15 +0 +-16 +1 +-15 +3 +-13 +1 +-15 +1 +-15 +1 +-15 +2 +-13 +1 +-16 +0 +-15 +0 +-15 +2 +-14 +1 +-15 +1 +-15 +1 +-15 +2 +-13 +1 +-16 +1 +-16 +1 +-15 +1 +-14 +1 +-16 +0 +-16 +0 +-15 +1 +-14 +1 +-16 +0 +-16 +0 +-15 +3 +-13 +1 +-16 +0 +-16 +1 +-15 +54 +29 +-6 +-7 +-25 +-7 +-21 +-3 +-18 +-2 +-18 +-3 +-19 +-3 +-19 +-2 +-16 +-1 +-17 +-3 +-19 +-2 +-17 +-1 +-16 +0 +-16 +-1 +-17 +-1 +-17 +1 +-15 +1 +-15 +0 +-17 +-1 +-16 +0 +-15 +1 +-14 +0 +-16 +0 +-16 +1 +-32 +-60 +-10 +-13 +9 +-10 +4 +-15 +1 +-14 +4 +-11 +5 +-11 +4 +-10 +57 +30 +-3 +-5 +-21 +-4 +-19 +-2 +-17 +-1 +-17 +-3 +-18 +-3 +-18 +-1 +-16 +0 +-16 +-2 +-17 +-1 +-17 +-1 +-15 +1 +-15 +-1 +-17 +-1 +-16 +1 +-32 +-60 +-10 +-12 +9 +-9 +4 +-15 +1 +-13 +5 +-11 +4 +-12 +5 +-10 +56 +30 +-4 +-4 +-22 +-4 +-18 +-3 +-18 +-2 +-17 +-2 +-18 +-3 +-18 +0 +-16 +0 +-17 +-2 +-19 +-1 +-17 +0 +-16 +0 +-15 +-1 +-16 +0 +-17 +0 +-15 +0 +-16 +-1 +-17 +-1 +-16 +1 +-15 +1 +-15 +-1 +-16 +0 +-16 +1 +-15 +2 +-15 +1 +-16 +0 +-16 +1 +-15 +1 +-15 +0 +-15 +1 +-16 +1 +-32 +-60 +-11 +-12 +9 +-10 +3 +-14 +2 +-13 +5 +-11 +5 +-10 +5 +-10 +57 +30 +-3 +-4 +-22 +-5 +-19 +-2 +-16 +-1 +-17 +-3 +-19 +-2 +-18 +-1 +-16 +0 +-16 +-2 +-17 +-1 +-17 +0 +-15 +0 +-16 +0 +-16 +-1 +-16 +1 +-32 +-60 +-11 +-13 +9 +-9 +3 +-15 +2 +-14 +3 +-11 +4 +-11 +5 +-10 +6 +-9 +4 +-12 +2 +-14 +2 +-14 +3 +-12 +1 +-15 +0 +-16 +1 +-15 +2 +-13 +1 +-16 +0 +-16 +1 +-15 +2 +-13 +1 +-15 +1 +-16 +0 +-15 +54 +27 +-6 +-7 +-25 +-7 +-21 +-4 +-19 +-3 +-18 +-3 +-19 +-2 +-18 +-1 +-16 +-1 +-16 +-1 +-18 +-2 +-18 +-1 +-16 +0 +-16 +-1 +-17 +-1 +-17 +0 +-15 +0 +-15 +0 +-16 +-1 +-16 +1 +-15 +1 +-15 +0 +-17 +0 +-15 +1 +-14 +1 +-15 +0 +-16 +1 +-15 +2 +-13 +1 +-13 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-15 +0 +-15 +1 +-32 +-59 +-10 +-12 +10 +-9 +4 +-15 +1 +-13 +5 +-10 +5 +-11 +5 +-10 +56 +30 +-4 +-5 +-23 +-5 +-18 +-2 +-17 +-1 +-18 +-2 +-19 +-2 +-18 +-1 +-16 +0 +-16 +-1 +-18 +-1 +-17 +-1 +-16 +1 +-15 +-1 +-17 +0 +-17 +0 +-15 +0 +-15 +0 +-17 +-1 +-17 +1 +-15 +1 +-15 +-1 +-17 +0 +-17 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +2 +-14 +2 +-13 +0 +-16 +0 +-15 +1 +-13 +1 +-14 +0 +-16 +0 +-15 +2 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +1 +-14 +1 +-15 +0 +-16 +1 +-15 +2 +-14 +0 +-16 +0 +-16 +1 +-13 +1 +-14 +1 +-16 +-1 +-16 +1 +-15 +1 +-15 +1 +-16 +1 +-14 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +1 +-16 +1 +-14 +1 +-14 +1 +-16 +1 +-16 +2 +-13 +2 +-14 +-1 +-16 +0 +-16 +1 +-14 +2 +-15 +-1 +-17 +-1 +-17 +1 +-14 +1 +-15 +0 +-16 +0 +-15 +1 +-14 +1 +-14 +-1 +-15 +1 +-15 +1 +-13 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-13 +2 +-15 +1 +-16 +0 +-15 +2 +-14 +1 +-15 +0 +-16 +-1 +-16 +2 +-15 +2 +-15 +1 +-16 +1 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-13 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +1 +-15 +0 +-15 +1 +-13 +1 +-15 +0 +-17 +0 +-16 +1 +-15 +2 +-15 +1 +-15 +0 +-16 +1 +-13 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +-1 +-16 +0 +-16 +2 +-13 +2 +-14 +1 +-16 +-1 +-16 +1 +-15 +1 +-15 +-1 +-16 +0 +-16 +0 +-15 +1 +-16 +0 +-17 +-1 +-16 +1 +-15 +1 +-14 +0 +-16 +1 +-15 +1 +-14 +3 +-14 +1 +-15 +0 +-15 +1 +-14 +1 +-14 +1 +-16 +1 +-15 +1 +-14 +3 +-14 +1 +-16 +1 +-15 +1 +-14 +2 +-14 +1 +-15 +1 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-15 +-1 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-15 +1 +-13 +1 +-15 +1 +-16 +-1 +-16 +1 +-14 +1 +-14 +1 +-16 +1 +-15 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-17 +0 +-15 +1 +-15 +2 +-15 +0 +-17 +0 +-15 +1 +-13 +2 +-15 +1 +-16 +-1 +-16 +1 +-15 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +3 +-14 +1 +-16 +-1 +-15 +0 +-14 +1 +-13 +0 +-16 +1 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +1 +-16 +1 +-15 +1 +-14 +2 +-14 +0 +-16 +-1 +-16 +1 +-14 +1 +-14 +0 +-15 +1 +-16 +1 +-14 +2 +-14 +0 +-16 +1 +-15 +1 +-14 +1 +-15 +0 +-16 +1 +-16 +1 +-14 +1 +-15 +1 +-16 +1 +-16 +0 +-14 +2 +-14 +1 +-16 +1 +-16 +1 +-13 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-15 +-1 +-16 +1 +-15 +1 +-14 +0 +-15 +0 +-16 +1 +-14 +1 +-15 +0 +-17 +-1 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-15 +1 +-15 +1 +-14 +1 +-14 +1 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +1 +-15 +2 +-14 +2 +-14 +0 +-16 +1 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-13 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +1 +-16 +1 +-16 +2 +-13 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +2 +-13 +2 +-14 +1 +-15 +0 +-15 +1 +-15 +1 +-14 +0 +-16 +0 +-16 +0 +-15 +1 +-16 +1 +-16 +0 +-16 +1 +-15 +2 +-15 +0 +-17 +-1 +-16 +1 +-13 +1 +-15 +-1 +-16 +-1 +-16 +1 +-15 +1 +-15 +0 +-16 +1 +-15 +1 +-33 +-60 +-10 +-12 +9 +-9 +3 +-15 +3 +-14 +5 +-10 +4 +-10 +6 +-10 +58 +31 +-3 +-4 +-22 +-4 +-19 +-2 +-17 +-1 +-17 +-2 +-19 +-2 +-18 +-1 +-34 +-61 +-12 +-14 +8 +-11 +2 +-17 +1 +-15 +3 +-12 +4 +-12 +4 +-11 +56 +29 +-4 +-5 +-23 +-5 +-19 +-2 +-18 +-1 +-17 +-3 +-19 +-2 +-19 +-1 +-34 +-61 +-12 +-15 +8 +-11 +2 +-16 +0 +-15 +3 +-13 +3 +-12 +3 +-11 +5 +-9 +4 +-13 +2 +-14 +2 +-14 +2 +-13 +2 +-15 +1 +-16 +1 +-15 +54 +29 +-6 +-7 +-24 +-7 +-20 +-4 +-19 +-3 +-18 +-3 +-19 +-3 +-18 +-2 +-16 +-1 +-17 +-2 +-18 +-2 +-18 +-1 +-16 +0 +-16 +-1 +-18 +-1 +-16 +1 +-14 +1 +-15 +-1 +-16 +-1 +-16 +1 +-14 +0 +-15 +1 +-16 +-1 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-15 +0 +-16 +1 +-14 +1 +-14 +1 +-17 +0 +-15 +1 +-15 +2 +-15 +1 +-15 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-15 +2 +-14 +2 +-14 +1 +-16 +0 +-16 +1 +-13 +1 +-14 +0 +-16 +0 +-15 +1 +-15 +1 +-15 +0 +-16 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +2 +-15 +0 +-16 +0 +-16 +2 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-15 +1 +-15 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +2 +-14 +2 +-14 +0 +-16 +-1 +-15 +1 +-13 +1 +-14 +0 +-16 +1 +-15 +1 +-14 +2 +-14 +1 +-16 +1 +-16 +1 +-15 +1 +-14 +0 +-17 +0 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-16 +1 +-15 +1 +-14 +1 +-16 +1 +-15 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-14 +2 +-15 +1 +-16 +0 +-15 +1 +-13 +1 +-15 +-1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +0 +-15 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-13 +2 +-14 +0 +-16 +-1 +-16 +1 +-15 +1 +-15 +-1 +-16 +1 +-16 +0 +-15 +1 +-14 +1 +-15 +0 +-15 +2 +-13 +2 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +1 +-16 +1 +-16 +1 +-13 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +-1 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +1 +-14 +0 +-15 +1 +-16 +1 +-14 +2 +-15 +0 +-15 +-1 +-15 +2 +-14 +1 +-15 +1 +-16 +0 +-16 +0 +-14 +2 +-14 +1 +-16 +1 +-15 +2 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +-1 +-17 +1 +-15 +1 +-15 +0 +-16 +0 +-15 +3 +-12 +3 +-14 +-1 +-17 +0 +-17 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +-1 +-15 +1 +-14 +1 +-15 +1 +-16 +1 +-16 +2 +-13 +2 +-15 +0 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +1 +-16 +1 +-15 +2 +-15 +0 +-16 +0 +-15 +2 +-14 +2 +-14 +1 +-16 +1 +-16 +1 +-13 +1 +-14 +0 +-15 +0 +-16 +1 +-14 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +1 +-16 +1 +-15 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-15 +0 +-16 +0 +-16 +2 +-13 +1 +-15 +0 +-16 +-1 +-15 +1 +-14 +1 +-15 +-1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +-1 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-14 +1 +-15 +0 +-15 +1 +-32 +-59 +-11 +-12 +10 +-9 +3 +-15 +1 +-13 +5 +-11 +4 +-11 +5 +-10 +57 +30 +-4 +-4 +-21 +-6 +-19 +-2 +-16 +-1 +-17 +-2 +-19 +-2 +-17 +-1 +-16 +0 +-17 +-1 +-17 +-1 +-17 +0 +-15 +0 +-15 +0 +-17 +-1 +-17 +0 +-33 +-61 +-11 +-13 +9 +-10 +2 +-14 +2 +-13 +4 +-10 +4 +-11 +5 +-10 +56 +30 +-4 +-5 +-23 +-5 +-19 +-2 +-17 +-1 +-17 +-2 +-19 +-3 +-17 +-1 +-17 +-1 +-17 +-2 +-18 +-2 +-17 +-1 +-15 +0 +-16 +-1 +-17 +-1 +-16 +1 +-14 +1 +-15 +0 +-17 +-1 +-16 +0 +-14 +1 +-16 +0 +-16 +0 +-16 +1 +-32 +-60 +-10 +-12 +10 +-10 +3 +-15 +1 +-13 +5 +-11 +5 +-10 +5 +-10 +7 +-9 +4 +-12 +3 +-13 +2 +-13 +3 +-12 +1 +-15 +0 +-16 +1 +-16 +53 +27 +-6 +-7 +-24 +-7 +-21 +-3 +-18 +-2 +-18 +-2 +-19 +-2 +-18 +-1 +-16 +-1 +-17 +-1 +-18 +-1 +-17 +0 +-15 +-1 +-16 +-1 +-18 +-1 +-16 +1 +-33 +-60 +-11 +-13 +9 +-10 +2 +-15 +1 +-14 +4 +-11 +4 +-11 +5 +-10 +57 +31 +-3 +-5 +-22 +-4 +-18 +-2 +-16 +-1 +-18 +-3 +-19 +-2 +-18 +-1 +-16 +0 +-16 +-2 +-18 +-1 +-17 +0 +-14 +1 +-16 +-1 +-17 +0 +-16 +1 +-15 +1 +-15 +-1 +-17 +-1 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-15 +1 +-15 +1 +-15 +1 +-14 +1 +-16 +1 +-15 +1 +-32 +-60 +-11 +-13 +9 +-9 +2 +-14 +1 +-14 +4 +-11 +4 +-12 +6 +-11 +6 +-10 +5 +-13 +3 +-14 +2 +-13 +3 +-13 +1 +-15 +0 +-15 +1 +-15 +2 +-14 +1 +-15 +0 +-16 +1 +-15 +3 +-13 +2 +-15 +0 +-16 +0 +-15 +1 +-14 +1 +-15 +1 +-16 +1 +-15 +2 +-14 +1 +-16 +0 +-16 +1 +-14 +2 +-13 +1 +-16 +0 +-16 +0 +-15 +1 +-14 +0 +-16 +0 +-15 +1 +-15 +2 +-13 +2 +-15 +0 +-15 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-15 +53 +28 +-5 +-7 +-25 +-6 +-21 +-4 +-19 +-3 +-18 +-3 +-19 +-3 +-18 +-1 +-16 +-1 +-17 +-2 +-17 +-1 +-18 +-1 +-16 +0 +-16 +-1 +-17 +-1 +-16 +0 +-14 +1 +-16 +-1 +-17 +0 +-16 +1 +-15 +1 +-15 +1 +-16 +0 +-15 +1 +-32 +-60 +-10 +-13 +9 +-10 +3 +-15 +2 +-13 +4 +-11 +4 +-12 +5 +-11 +58 +31 +-3 +-4 +-22 +-4 +-19 +-2 +-17 +-1 +-18 +-2 +-19 +-3 +-18 +-1 +-16 +0 +-16 +-1 +-18 +-1 +-17 +0 +-15 +1 +-16 +0 +-16 +-1 +-17 +1 +-32 +-60 +-11 +-13 +9 +-11 +3 +-16 +1 +-14 +3 +-11 +4 +-11 +4 +-11 +57 +29 +-4 +-5 +-23 +-5 +-19 +-3 +-18 +-1 +-17 +-3 +-18 +-2 +-17 +0 +-15 +-1 +-16 +-1 +-17 +-2 +-17 +0 +-16 +0 +-16 +-1 +-16 +0 +-15 +1 +-14 +1 +-15 +0 +-17 +-1 +-16 +2 +-14 +1 +-14 +1 +-17 +0 +-16 +1 +-14 +2 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-15 +1 +-32 +-59 +-10 +-12 +9 +-9 +3 +-15 +1 +-13 +4 +-10 +4 +-11 +6 +-10 +57 +30 +-4 +-5 +-22 +-5 +-19 +-2 +-17 +-1 +-17 +-2 +-17 +-3 +-17 +-1 +-16 +0 +-16 +-1 +-18 +-1 +-17 +-1 +-15 +1 +-16 +-1 +-16 +-1 +-17 +1 +-33 +-60 +-12 +-13 +8 +-10 +3 +-16 +1 +-14 +4 +-11 +5 +-11 +5 +-11 +6 +-11 +4 +-12 +2 +-13 +2 +-14 +3 +-12 +1 +-15 +1 +-15 +1 +-14 +3 +-13 +1 +-15 +1 +-16 +1 +-15 +2 +-12 +2 +-15 +1 +-16 +1 +-15 +54 +27 +-6 +-8 +-24 +-7 +-21 +-4 +-18 +-2 +-18 +-2 +-19 +-3 +-18 +-1 +-17 +0 +-16 +-1 +-18 +-1 +-17 +-1 +-15 +0 +-15 +-1 +-17 +-1 +-16 +1 +-14 +1 +-15 +-1 +-17 +0 +-15 +1 +-15 +1 +-15 +0 +-16 +-1 +-16 +0 +-14 +2 +-14 +0 +-17 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +-1 +-17 +0 +-16 +1 +-32 +-60 +-11 +-13 +9 +-10 +3 +-15 +1 +-13 +4 +-11 +5 +-11 +5 +-10 +58 +31 +-3 +-3 +-22 +-5 +-19 +-1 +-17 +-1 +-17 +-2 +-18 +-3 +-17 +-1 +-16 +0 +-16 +-1 +-18 +-1 +-17 +0 +-16 +0 +-15 +-1 +-17 +0 +-17 +1 +-15 +2 +-15 +0 +-16 +0 +-17 +1 +-14 +1 +-15 +0 +-16 +-1 +-15 +2 +-13 +1 +-15 +0 +-17 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +1 +-15 +0 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-16 +0 +-17 +-1 +-16 +1 +-14 +1 +-14 +1 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +-1 +-17 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-15 +2 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-14 +3 +-14 +0 +-15 +0 +-15 +2 +-13 +3 +-15 +-1 +-16 +0 +-16 +2 +-13 +2 +-14 +0 +-15 +-1 +-16 +1 +-14 +1 +-14 +0 +-16 +1 +-15 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-14 +1 +-14 +0 +-15 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +-1 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-15 +2 +-13 +2 +-15 +0 +-17 +0 +-16 +0 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +-1 +-15 +1 +-14 +1 +-15 +-1 +-17 +-1 +-16 +1 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-14 +1 +-15 +1 +-16 +1 +-15 +1 +-14 +1 +-15 +0 +-15 +-1 +-15 +1 +-14 +1 +-14 +1 +-16 +1 +-15 +2 +-13 +2 +-14 +1 +-16 +0 +-15 +1 +-14 +2 +-15 +1 +-16 +0 +-15 +2 +-14 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-14 +1 +-16 +0 +-16 +2 +-13 +2 +-14 +0 +-17 +0 +-15 +0 +-14 +1 +-15 +0 +-16 +-1 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-17 +1 +-15 +1 +-14 +2 +-15 +0 +-16 +0 +-15 +2 +-14 +1 +-15 +0 +-16 +-1 +-16 +1 +-15 +1 +-15 +0 +-17 +0 +-16 +1 +-13 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +2 +-15 +0 +-16 +1 +-16 +2 +-14 +2 +-15 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +2 +-13 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +-1 +-15 +2 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-15 +0 +-15 +2 +-14 +2 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-17 +1 +-15 +2 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +-1 +-16 +1 +-15 +0 +-15 +0 +-16 +0 +-15 +1 +-13 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +0 +-14 +1 +-14 +0 +-15 +0 +-15 +2 +-14 +1 +-14 +1 +-15 +0 +-15 +2 +-13 +1 +-15 +0 +-16 +0 +-15 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-17 +1 +-15 +1 +-14 +2 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-17 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +1 +-16 +2 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +0 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +1 +-15 +1 +-14 +2 +-15 +0 +-16 +1 +-15 +2 +-13 +1 +-14 +0 +-16 +1 +-14 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +-1 +-16 +1 +-12 +2 +-14 +0 +-17 +0 +-16 +0 +-14 +1 +-14 +0 +-16 +0 +-16 +2 +-31 +-59 +-11 +-13 +10 +-10 +4 +-15 +1 +-13 +3 +-11 +5 +-11 +4 +-10 +58 +29 +-3 +-5 +-22 +-5 +-18 +-2 +-17 +-1 +-17 +-2 +-19 +-2 +-19 +-1 +-34 +-61 +-13 +-15 +7 +-12 +2 +-16 +0 +-15 +3 +-12 +3 +-12 +5 +-11 +57 +30 +-4 +-5 +-21 +-5 +-19 +-3 +-17 +-1 +-18 +-3 +-19 +-3 +-19 +-3 +-35 +-62 +-13 +-15 +7 +-12 +1 +-16 +0 +-15 +3 +-12 +3 +-12 +4 +-11 +5 +-9 +4 +-13 +3 +-13 +2 +-14 +3 +-13 +1 +-15 +1 +-16 +0 +-15 +53 +28 +-6 +-7 +-24 +-6 +-20 +-3 +-18 +-2 +-18 +-2 +-18 +-2 +-18 +-1 +-15 +-1 +-16 +-1 +-18 +-2 +-17 +0 +-15 +0 +-15 +-1 +-16 +-1 +-16 +1 +-15 +0 +-14 +0 +-17 +0 +-16 +1 +-15 +2 +-15 +-1 +-17 +-1 +-16 +0 +-15 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +2 +-15 +0 +-17 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-15 +1 +-16 +-1 +-16 +1 +-15 +1 +-15 +0 +-17 +0 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +2 +-14 +1 +-15 +0 +-16 +0 +-15 +2 +-14 +2 +-13 +1 +-16 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-15 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +1 +-16 +2 +-13 +1 +-14 +0 +-16 +0 +-16 +0 +-14 +2 +-14 +0 +-15 +1 +-16 +1 +-14 +1 +-14 +0 +-17 +0 +-16 +1 +-14 +2 +-14 +0 +-15 +0 +-16 +1 +-14 +2 +-14 +0 +-16 +-1 +-15 +1 +-14 +2 +-15 +1 +-16 +0 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-15 +1 +-15 +1 +-14 +0 +-17 +0 +-16 +1 +-14 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +0 +-15 +-1 +-17 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +0 +-15 +2 +-14 +2 +-14 +1 +-16 +0 +-16 +2 +-14 +2 +-14 +1 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-15 +1 +-14 +1 +-14 +1 +-16 +1 +-16 +1 +-13 +1 +-14 +0 +-16 +0 +-16 +1 +-15 +2 +-14 +0 +-15 +0 +-15 +1 +-14 +2 +-14 +1 +-15 +1 +-15 +1 +-14 +2 +-14 +1 +-16 +1 +-15 +1 +-14 +1 +-14 +-1 +-16 +0 +-16 +1 +-14 +2 +-15 +1 +-16 +0 +-15 +0 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-16 +0 +-16 +1 +-15 +1 +-15 +-1 +-17 +-1 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +1 +-15 +1 +-14 +0 +-16 +1 +-16 +1 +-14 +1 +-15 +0 +-16 +1 +-16 +2 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-13 +2 +-14 +0 +-16 +1 +-16 +2 +-14 +2 +-14 +0 +-16 +0 +-16 +2 +-14 +2 +-14 +0 +-16 +0 +-15 +2 +-13 +3 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +-1 +-16 +-1 +-16 +1 +-14 +1 +-14 +1 +-16 +-1 +-16 +1 +-13 +2 +-14 +1 +-17 +1 +-16 +2 +-14 +2 +-14 +0 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-16 +0 +-13 +1 +-15 +-1 +-17 +0 +-16 +1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +-1 +-16 +0 +-16 +0 +-15 +1 +-15 +0 +-16 +-1 +-15 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-13 +2 +-14 +1 +-15 +0 +-15 +1 +-14 +1 +-15 +0 +-16 +1 +-15 +2 +-14 +1 +-14 +1 +-15 +0 +-15 +1 +-14 +1 +-14 +1 +-15 +0 +-15 +1 +-15 +2 +-14 +0 +-16 +0 +-15 +1 +-14 +2 +-15 +1 +-16 +-1 +-15 +1 +-14 +2 +-14 +1 +-16 +0 +-16 +0 +-14 +2 +-15 +0 +-16 +0 +-16 +1 +-14 +2 +-14 +1 +-16 +0 +-16 +0 +-33 +-61 +-11 +-12 +10 +-9 +4 +-15 +2 +-13 +5 +-11 +3 +-11 +5 +-10 +57 +29 +-4 +-5 +-22 +-5 +-19 +-2 +-17 +-2 +-18 +-3 +-19 +-3 +-18 +-1 +-16 +-1 +-16 +-2 +-18 +-3 +-18 +-1 +-15 +1 +-15 +1 +-16 +-1 +-16 +1 +-33 +-60 +-11 +-12 +9 +-10 +3 +-15 +2 +-13 +4 +-11 +5 +-11 +5 +-10 +57 +31 +-3 +-4 +-21 +-5 +-18 +-1 +-17 +-1 +-17 +-3 +-18 +-2 +-17 +-1 +-16 +0 +-16 +-1 +-17 +-2 +-17 +0 +-15 +1 +-15 +0 +-16 +-1 +-16 +0 +-14 +0 +-15 +0 +-16 +0 +-16 +1 +-14 +1 +-15 +1 +-17 +0 +-16 +0 +-33 +-61 +-11 +-13 +10 +-10 +3 +-15 +1 +-13 +4 +-11 +3 +-11 +5 +-10 +6 +-10 +4 +-13 +2 +-13 +2 +-14 +3 +-13 +1 +-15 +1 +-15 +1 +-16 +53 +28 +-6 +-7 +-25 +-7 +-21 +-4 +-18 +-1 +-18 +-2 +-19 +-3 +-18 +-1 +-16 +-1 +-16 +-2 +-18 +-1 +-17 +-1 +-16 +0 +-16 +-1 +-17 +-1 +-17 +1 +-32 +-60 +-11 +-12 +10 +-9 +4 +-16 +1 +-14 +4 +-11 +5 +-11 +5 +-9 +58 +31 +-3 +-4 +-22 +-4 +-19 +-1 +-16 +-2 +-17 +-3 +-19 +-2 +-18 +-1 +-16 +-1 +-17 +-1 +-18 +-1 +-17 +0 +-15 +1 +-15 +-1 +-17 +-1 +-16 +-1 +-14 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +1 +-15 +0 +-17 +1 +-16 +1 +-14 +1 +-14 +-1 +-16 +0 +-16 +1 +-14 +1 +-14 +1 +-16 +0 +-15 +1 +-32 +-59 +-10 +-12 +10 +-10 +2 +-15 +1 +-14 +4 +-11 +5 +-12 +5 +-10 +6 +-10 +5 +-13 +3 +-14 +3 +-14 +3 +-13 +0 +-16 +0 +-16 +1 +-15 +2 +-13 +1 +-15 +1 +-15 +1 +-15 +2 +-13 +1 +-16 +1 +-15 +1 +-15 +3 +-14 +1 +-15 +1 +-15 +1 +-14 +1 +-13 +1 +-16 +1 +-15 +1 +-15 +3 +-13 +2 +-16 +1 +-15 +1 +-15 +2 +-14 +1 +-15 +0 +-16 +0 +-15 +1 +-13 +1 +-16 +0 +-15 +0 +-15 +2 +-13 +1 +-15 +0 +-16 +0 +-15 +53 +28 +-6 +-7 +-25 +-7 +-21 +-3 +-18 +-2 +-18 +-3 +-19 +-4 +-18 +-2 +-16 +-1 +-16 +-1 +-18 +-1 +-17 +-1 +-16 +0 +-16 +-1 +-17 +-1 +-17 +1 +-14 +0 +-15 +0 +-18 +-1 +-16 +0 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-32 +-60 +-11 +-13 +9 +-10 +3 +-15 +1 +-14 +4 +-11 +4 +-11 +4 +-10 +57 +30 +-4 +-5 +-22 +-5 +-19 +-2 +-17 +-1 +-17 +-3 +-18 +-2 +-17 +-1 +-16 +0 +-16 +-1 +-17 +-1 +-17 +1 +-15 +0 +-15 +-1 +-16 +0 +-16 +1 +-32 +-60 +-11 +-13 +10 +-10 +2 +-15 +1 +-14 +4 +-10 +4 +-12 +5 +-11 +57 +29 +-4 +-5 +-22 +-5 +-20 +-2 +-17 +-2 +-17 +-2 +-18 +-3 +-18 +-1 +-16 +0 +-16 +-2 +-18 +-1 +-18 +0 +-15 +1 +-16 +0 +-16 +-1 +-16 +1 +-14 +1 +-15 +-1 +-16 +-1 +-16 +1 +-15 +1 +-15 +0 +-16 +0 +-16 +1 +-15 +1 +-14 +0 +-17 +0 +-15 +0 +-14 +1 +-14 +0 +-16 +0