From e863d595b50867c550d53cd9d92032fcbb82ef3c Mon Sep 17 00:00:00 2001 From: Dominik Wenger Date: Wed, 21 Feb 2007 20:27:14 +0000 Subject: Implementation of Bootloader installation/uninstallation for all Targets in rbUtil. Needs testing. FS#6643 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12439 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/Makefile | 5 +- rbutil/Makefile.macosx | 216 ++++ rbutil/bootloaders.cpp | 452 ++++++++ rbutil/bootloaders.h | 41 + rbutil/credits.h | 1 + rbutil/h100sums.h | 23 + rbutil/h120sums.h | 23 + rbutil/h300sums.h | 17 + rbutil/irivertools.cpp | 613 +++++++++++ rbutil/irivertools.h | 65 ++ rbutil/md5sum.cpp | 300 ++++++ rbutil/md5sum.h | 51 + rbutil/mksums.pl | 69 ++ rbutil/rbutil.cbp | 212 ++-- rbutil/rbutil.cpp | 38 +- rbutil/rbutil.h | 13 + rbutil/rbutil.ini | 190 +++- rbutil/rbutil.r | 2675 +++++++++++++++++++++++++++++++++++++++++++++++ rbutil/rbutilApp.cpp | 58 +- rbutil/rbutilFrm.cpp | 250 ++++- rbutil/rbutilFrm.h | 7 +- rbutil/wizard_pages.cpp | 362 ++++++- rbutil/wizard_pages.h | 97 +- 23 files changed, 5566 insertions(+), 212 deletions(-) create mode 100755 rbutil/Makefile.macosx create mode 100755 rbutil/bootloaders.cpp create mode 100755 rbutil/bootloaders.h create mode 100755 rbutil/h100sums.h create mode 100755 rbutil/h120sums.h create mode 100755 rbutil/h300sums.h create mode 100755 rbutil/irivertools.cpp create mode 100755 rbutil/irivertools.h create mode 100755 rbutil/md5sum.cpp create mode 100755 rbutil/md5sum.h create mode 100755 rbutil/mksums.pl create mode 100755 rbutil/rbutil.r (limited to 'rbutil') diff --git a/rbutil/Makefile b/rbutil/Makefile index a7f9102fed..40091fd4a3 100644 --- a/rbutil/Makefile +++ b/rbutil/Makefile @@ -9,10 +9,9 @@ # Unix-style Makefile for rbutil - CXX=$(shell $(PREFIX)wx-config --cxx) -INC = -OBJS=rbutil.o rbutilApp.o rbutilFrm.o wizard_pages.o bootloaders.o installlog.o ipodpatcher/ipodpatcher.o ipodpatcher/ipodio-posix.o fwpatcher/md5.o fwpatcher/iriver.o +INC = +OBJS=rbutil.o rbutilApp.o rbutilFrm.o wizard_pages.o bootloaders.o installlog.o ipodpatcher/ipodpatcher.o ipodpatcher/ipodio-posix.o irivertools.o md5sum.o # Install into /usr/local by default ifndef DESTDIR diff --git a/rbutil/Makefile.macosx b/rbutil/Makefile.macosx new file mode 100755 index 0000000000..daeb7215bc --- /dev/null +++ b/rbutil/Makefile.macosx @@ -0,0 +1,216 @@ +# ========================================================================= +# This makefile was generated by +# Bakefile 0.2.1 (http://bakefile.sourceforge.net) +# Do not modify, all changes will be overwritten! +# ========================================================================= + + + + +srcdir = /Users/dave/rockbox/rockbox-devel/rbutil +top_srcdir = /Users/dave/src/wxMac-2.8.0/ +BK_DEPS = /Users/dave/src/wxMac-2.8.0/osx_build/bk-deps +wx_top_builddir = /Users/dave/src/wxMac-2.8.0/osx_build + +prefix = /usr/local +exec_prefix = ${prefix} +INSTALL = /usr/bin/install -c +EXEEXT = +WINDRES = +REZ = /Developer/Tools/Rez +SETFILE = /Developer/Tools/SetFile +NM = nm +LIBS = -lz -lpthread -liconv +LDFLAGS_GUI = +CXX = g++ +CXXFLAGS = -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386 -Wall -Wundef -Wno-ctor-dtor-privacy -O2 -fno-strict-aliasing -fno-common +CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I${wx_top_builddir}/lib/wx/include/mac-ansi-release-static-2.8 -I${top_srcdir}/include -fpascal-strings -I${top_srcdir}/src/mac/carbon/morefilex -I/Developer/Headers/FlatCarbon +RBUTIL_CFLAGS = $(CXXFLAGS) -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I${wx_top_builddir}/lib/wx/include/mac-ansi-release-static-2.8 -I${top_srcdir}/include -fpascal-strings -I${top_srcdir}/src/mac/carbon/morefilex -I/Developer/Headers/FlatCarbon +LDFLAGS = -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386 -framework QuickTime -framework IOKit -framework Carbon -framework Cocoa -framework System +WX_LIB_FLAVOUR = +TOOLKIT = MAC +TOOLKIT_LOWERCASE = mac +TOOLKIT_VERSION = +TOOLCHAIN_FULLNAME = mac-ansi-release-static-2.8 +EXTRALIBS = -framework QuickTime -framework IOKit -framework Carbon -framework Cocoa -framework System -lz -lpthread -liconv +EXTRALIBS_GUI = -framework WebKit +HOST_SUFFIX = +SAMPLES_RPATH_FLAG = +SAMPLES_RPATH_POSTLINK = + +### Variables: ### + +DESTDIR = +WX_RELEASE = 2.8 +WX_VERSION = $(WX_RELEASE).0 +LIBDIRNAME = $(wx_top_builddir)/lib +RBUTIL_CXXFLAGS = -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \ + $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) \ + -I$(srcdir) $(__DLLFLAG_p) $(CPPFLAGS) $(CXXFLAGS) +RBUTIL_OBJECTS = \ + $(__rbutil_os2_lib_res) \ + rbutil.o rbutilApp.o rbutilFrm.o wizard_pages.o bootloaders.o installlog.o \ + ipodpatcher/ipodpatcher.o ipodpatcher/ipodio-posix.o \ + md5sum.o irivertools.o \ + $(__rbutil___win32rc) + +### Conditionally set variables: ### + +#CXXC = $(CXX) +CXXC = $(BK_DEPS) $(CXX) +#PORTNAME = base +PORTNAME = $(TOOLKIT_LOWERCASE)$(TOOLKIT_VERSION) +WXBASEPORT = _carbon +#WXDEBUGFLAG = d +#WXDEBUGFLAG = d +#WXUNICODEFLAG = u +#WXUNIVNAME = univ +EXTRALIBS_FOR_BASE = $(EXTRALIBS) +#EXTRALIBS_FOR_BASE = $(EXTRALIBS) $(EXTRALIBS_GUI) +EXTRALIBS_FOR_GUI = $(EXTRALIBS_GUI) +#EXTRALIBS_FOR_GUI = +__rbutil___mac_setfilecmd = \ + $(SETFILE) -a C rbutil$(EXEEXT) +__rbutil___mac_rezcmd = $(__MACOSX_RESOURCES_p_1) +#__WXUNIV_DEFINE_p = -D__WXUNIVERSAL__ +#__WXUNIV_DEFINE_p_1 = -d __WXUNIVERSAL__ +#__WXUNIV_DEFINE_p_2 = --define __WXUNIVERSAL__ +#__EXCEPTIONS_DEFINE_p = -DwxNO_EXCEPTIONS +#__EXCEPTIONS_DEFINE_p_1 = -d wxNO_EXCEPTIONS +#__EXCEPTIONS_DEFINE_p_2 = --define wxNO_EXCEPTIONS +#__RTTI_DEFINE_p = -DwxNO_RTTI +#__RTTI_DEFINE_p_1 = -d wxNO_RTTI +#__RTTI_DEFINE_p_2 = --define wxNO_RTTI +#__THREAD_DEFINE_p = -DwxNO_THREADS +#__THREAD_DEFINE_p_1 = -d wxNO_THREADS +#__THREAD_DEFINE_p_2 = --define wxNO_THREADS +#__DLLFLAG_p = -DWXUSINGDLL +#__DLLFLAG_p_1 = -d WXUSINGDLL +#__DLLFLAG_p_2 = --define WXUSINGDLL +COND_PLATFORM_OS2_1___rbutil___os2_emxbindcmd = $(NM) rbutil$(EXEEXT) | if \ + grep -q pmwin.763 ; then emxbind -ep rbutil$(EXEEXT) ; fi +#__rbutil___os2_emxbindcmd = $(COND_PLATFORM_OS2_1___rbutil___os2_emxbindcmd) +#__RCDEFDIR_p = -i \ +# $(LIBDIRNAME)/wx/include/$(TOOLCHAIN_FULLNAME) +#__RCDEFDIR_p_1 = --include-dir \ +# $(LIBDIRNAME)/wx/include/$(TOOLCHAIN_FULLNAME) +#__rbutil_os2_lib_res = \ +# $(top_srcdir)/include/wx/os2/wx.res +__rbutil_bundle___depname = rbutil_bundle +#____rbutil_BUNDLE_TGT_REF_DEP = \ +# rbutil.app/Contents/PkgInfo +____rbutil_BUNDLE_TGT_REF_DEP = \ + rbutil.app/Contents/PkgInfo +COND_MONOLITHIC_0___WXLIB_CORE_p = \ + -lwx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_core-$(WX_RELEASE)$(HOST_SUFFIX) +__WXLIB_CORE_p = $(COND_MONOLITHIC_0___WXLIB_CORE_p) +COND_MONOLITHIC_0___WXLIB_BASE_p = \ + -lwx_base$(WXBASEPORT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +__WXLIB_BASE_p = $(COND_MONOLITHIC_0___WXLIB_BASE_p) + +__WXLIB_ADV_p = -lwx_mac_adv$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +__WXLIB_NET_p = -lwx_base_carbon_net-$(WX_RELEASE)$(HOST_SUFFIX) + +#__rbutil___win32rc = rbutil_rc.o +COND_MONOLITHIC_1___WXLIB_MONO_p = \ + -lwx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +#__WXLIB_MONO_p = $(COND_MONOLITHIC_1___WXLIB_MONO_p) +__LIB_TIFF_p \ + = \ + -lwxtiff$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +__LIB_JPEG_p \ + = \ + -lwxjpeg$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +__LIB_PNG_p \ + = \ + -lwxpng$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +#__LIB_ZLIB_p = \ +# -lwxzlib$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +#__LIB_ODBC_p = \ +# -lwxodbc$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +COND_WXUSE_REGEX_BUILTIN___LIB_REGEX_p = \ + -lwxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +#__LIB_REGEX_p = $(COND_WXUSE_REGEX_BUILTIN___LIB_REGEX_p) +__LIB_EXPAT_p = \ + -lwxexpat$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX) +COND_TOOLKIT_MAC___MACOSX_RESOURCES_p_1 = $(REZ) -d __DARWIN__ -t APPL -d \ + __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) \ + $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) -i $(srcdir) $(__DLLFLAG_p_1) -i \ + $(srcdir)/../../samples $(__RCDEFDIR_p) -i $(top_srcdir)/include -o \ + rbutil$(EXEEXT) Carbon.r rbutil.r +__MACOSX_RESOURCES_p_1 = $(COND_TOOLKIT_MAC___MACOSX_RESOURCES_p_1) + +### Targets: ### + +all: rbutil$(EXEEXT) $(__rbutil_bundle___depname) data + +install: all + +uninstall: + +install-strip: install + +clean: + rm -rf ./.deps ./.pch + rm -f $(RBUTIL_OBJECTS) + rm -f rbutil$(EXEEXT) + rm -rf rbutil.app + +distclean: clean + rm -f config.cache config.log config.status bk-deps bk-make-pch shared-ld-sh Makefile + +rbutil$(EXEEXT): $(RBUTIL_OBJECTS) $(__rbutil___win32rc) + $(CXX) -o $@ $(RBUTIL_OBJECTS) $(LDFLAGS) -L$(LIBDIRNAME) $(LDFLAGS_GUI) $(SAMPLES_RPATH_FLAG) $(LIBS) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__WXLIB_ADV_p) $(__WXLIB_NET_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) $(EXTRALIBS_FOR_GUI) $(__LIB_ZLIB_p) $(__LIB_ODBC_p) $(__LIB_REGEX_p) $(__LIB_EXPAT_p) $(EXTRALIBS_FOR_BASE) + $(__rbutil___mac_rezcmd) + $(__rbutil___mac_setfilecmd) + $(__rbutil___os2_emxbindcmd) + $(SAMPLES_RPATH_POSTLINK) + +rbutil.app/Contents/PkgInfo: rbutil$(EXEEXT) $(top_srcdir)/src/mac/carbon/Info.plist.in $(top_srcdir)/src/mac/carbon/wxmac.icns + mkdir -p rbutil.app/Contents + mkdir -p rbutil.app/Contents/MacOS + mkdir -p rbutil.app/Contents/Resources + + + sed -e "s/IDENTIFIER/`echo $(srcdir) | sed -e 's,\.\./,,g' | sed -e 's,/,.,g'`/" \ + -e "s/EXECUTABLE/rbutil/" \ + -e "s/VERSION/$(WX_VERSION)/" \ + $(top_srcdir)/src/mac/carbon/Info.plist.in >rbutil.app/Contents/Info.plist + + + echo -n "APPL????" >rbutil.app/Contents/PkgInfo + + + ln -f rbutil$(EXEEXT) rbutil.app/Contents/MacOS/rbutil + + + cp -f $(top_srcdir)/src/mac/carbon/wxmac.icns rbutil.app/Contents/Resources/wxmac.icns + +rbutil_bundle: $(____rbutil_BUNDLE_TGT_REF_DEP) + +data: + @mkdir -p . + @for f in rbutil.ini; do \ + if test ! -f ./$$f -a ! -d ./$$f ; \ + then x=yep ; \ + else x=`find $(srcdir)/$$f -newer ./$$f -print` ; \ + fi; \ + case "$$x" in ?*) \ + cp -pRf $(srcdir)/$$f . ;; \ + esac; \ + done + +.cpp.o : + $(CXXC) $(RBUTIL_CXXFLAGS) -c -o $@ $< + +.c.o : + $(CC) $(RBUTIL_CFLAGS) -c -o $@ $< + +rbutil_rc.o: $(srcdir)/rbutil.rc + $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_2) $(__EXCEPTIONS_DEFINE_p_2) $(__RTTI_DEFINE_p_2) $(__THREAD_DEFINE_p_2) --include-dir $(srcdir) $(__DLLFLAG_p_2) --include-dir $(srcdir)/../../samples $(__RCDEFDIR_p_1) --include-dir $(top_srcdir)/include + + +# Include dependency info, if present: +-include .deps/*.d + +.PHONY: all install uninstall clean distclean rbutil_bundle data diff --git a/rbutil/bootloaders.cpp b/rbutil/bootloaders.cpp new file mode 100755 index 0000000000..a2a52be209 --- /dev/null +++ b/rbutil/bootloaders.cpp @@ -0,0 +1,452 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: bootloaders.cpp + * + * Copyright (C) 2007 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "bootloaders.h" +#include "irivertools.h" +#include "md5sum.h" + +#include "rbutil.h" +#include "installlog.h" + + +// for ipodpatcher +int verbose = 0; +// reserves memory for ipodpatcher +bool initIpodpatcher() +{ + if (ipod_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) return true; + else return false; +} +// uses ipodpatcher for add and rem of bootloader +bool ipodpatcher(int mode) +{ + wxString src,dest,buf; + + // downloading files + if(mode == BOOTLOADER_ADD) + { + src.Printf("%s/ipod/%s.ipod", gv->bootloader_url.c_str(),gv->curbootloader.c_str()); + dest.Printf("%s" PATH_SEP "download" PATH_SEP "%s", + gv->stdpaths->GetUserDataDir().c_str(),gv->curbootloader.c_str()); + if ( DownloadURL(src, dest) ) + { + wxRemoveFile(dest); + buf.Printf(_("Unable to download %s"), src.c_str() ); + ERR_DIALOG(buf, _("Install")); + return false; + } + } + + struct ipod_t ipod; + + int n = ipod_scan(&ipod); + if (n == 0) + { + ERR_DIALOG("[ERR] No ipods found.", _("Scanning for Ipods")); + return false; + } + if (n > 1) + { + ERR_DIALOG("[ERR] to many ipods found.", _("Scanning for Ipods")); + return false; + } + + if (ipod_open(&ipod, 0) < 0) + { + ERR_DIALOG("[ERR] could not open ipod", _("open Ipod")); + return false; + } + + if (read_partinfo(&ipod,0) < 0) + { + ERR_DIALOG("[ERR] could not read partitiontable", _("reading partitiontable")); + return false; + } + + if (ipod.pinfo[0].start==0) + { + ERR_DIALOG("[ERR] No partition 0 on disk", _("reading partitiontable")); + int i; + double sectors_per_MB = (1024.0*1024.0)/ipod.sector_size; + + buf.Printf("[INFO] Part Start Sector End Sector Size (MB) Type\n"); + ERR_DIALOG(buf, _("reading partitiontable")); + for ( i = 0; i < 4; i++ ) { + if (ipod.pinfo[i].start != 0) { + buf.Printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n", + i, + ipod.pinfo[i].start, + ipod.pinfo[i].start+ipod.pinfo[i].size-1, + ipod.pinfo[i].size/sectors_per_MB, + get_parttype(ipod.pinfo[i].type), + ipod.pinfo[i].type); + ERR_DIALOG(buf, _("reading partitiontable")); + } + } + return false; + } + + read_directory(&ipod); + + if (ipod.nimages <= 0) + { + ERR_DIALOG("[ERR] Failed to read firmware directory", _("reading directory")); + return false; + } + if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) + { + buf.Printf(_("[ERR] Unknown version number in firmware (%08x)\n"), + ipod.ipod_directory[0].vers ); + ERR_DIALOG(buf, _("reading directory")); + return false; + } + + if (ipod.macpod) + { + WARN_DIALOG("Warning this is a MacPod, Rockbox doesnt work on this. Convert it to WinPod",_("MacPod")); + } + + + if(mode == BOOTLOADER_ADD) + { + if (ipod_reopen_rw(&ipod) < 0) { + ERR_DIALOG("[ERR] Could not open Ipod in RW mode", _("Bootloader add")); + return false; + } + + if (add_bootloader(&ipod, (char*)dest.c_str(), FILETYPE_DOT_IPOD)==0) { + + } else { + ERR_DIALOG("[ERR] failed to add Bootloader", _("Bootloader add")); + return false; + } + } + else if(mode == BOOTLOADER_REM) + { + if (ipod_reopen_rw(&ipod) < 0) { + ERR_DIALOG("[ERR] Could not open Ipod in RW mode", _("Bootloader add")); + return false; + } + + if (ipod.ipod_directory[0].entryOffset==0) { + ERR_DIALOG("[ERR] No bootloader detected.\n", _("Bootloader del")); + return false; + } else { + if (delete_bootloader(&ipod)==0) { + + } else { + ERR_DIALOG("[ERR] --delete-bootloader failed.\n", _("Bootloader del")); + return false; + } + } + } + + ipod_close(&ipod); + return true; +} + +// gigabeatinstallation +bool gigabeatf(int mode) +{ + wxString path1,path2; + wxString err; + wxString src,dest; + + path1.Printf("%s" PATH_SEP "GBSYSTEM" PATH_SEP "FWIMG" PATH_SEP "FWIMG01.DAT",gv->curdestdir.c_str()); + + if(mode == BOOTLOADER_ADD) + { + //Files downloaden + src.Printf("%s/gigabeat/%s", gv->bootloader_url.c_str(),gv->curbootloader.c_str()); + dest.Printf("%s" PATH_SEP "download" PATH_SEP "%s", + gv->stdpaths->GetUserDataDir().c_str(),gv->curbootloader.c_str()); + if( DownloadURL(src, dest) ) + { + wxRemoveFile(dest); + err.Printf(_("Unable to download %s"), src.c_str() ); + ERR_DIALOG(err, _("Install")); + return false; + } + + + if(!wxFileExists(path1)) + { + err.Printf("[ERR] Coud not find %s",path1.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + path2 = path1; + path2.Append(".ORIG"); + if(wxFileExists(path2)) + { + err = "Its seems there is already a Bootloader install, if not, delete the *.IMG.ORIG file"; + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + + if(!wxRenameFile(path1,path2,false)) + { + err.Printf("[ERR] Coud not rename %s to %s",path1.c_str(),path2.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + if(!wxCopyFile(dest,path1)) + { + err.Printf("[ERR] Coud not copy %s to %s",dest.c_str(),path2.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + } + else if(mode == BOOTLOADER_REM) + { + path2 = path1; + path2.Append(".ORIG"); + if(!wxFileExists(path2)) + { + err.Printf("[ERR] Coud not find %s",path1.c_str()); + ERR_DIALOG(err, _("Bootloader del")); + return false; + } + if(!wxRenameFile(path2,path1,true)) + { + err.Printf("[ERR] Coud not rename %s to %s",path1.c_str(),path2.c_str()); + ERR_DIALOG(err, _("Bootloader del")); + return false; + } + } + return true; +} + +// iaudio bootloader install +bool iaudiox5(int mode) +{ + wxString path1,path2; + wxString err; + wxString src,dest; + + path1.Printf("%s" PATH_SEP "FIRMWARE" PATH_SEP "%s",gv->curdestdir.c_str(),gv->curbootloader.c_str()); + + if(mode == BOOTLOADER_ADD) + { + //Files downloaden + src.Printf("%s/iaudio/%s", gv->bootloader_url.c_str(),gv->curbootloader.c_str()); + dest.Printf("%s" PATH_SEP "download" PATH_SEP "%s", + gv->stdpaths->GetUserDataDir().c_str(),gv->curbootloader.c_str()); + if( DownloadURL(src, dest) ) + { + wxRemoveFile(dest); + err.Printf(_("Unable to download %s"), src.c_str() ); + ERR_DIALOG(err, _("Install")); + return false; + } + + // copy file + if(!wxCopyFile(dest,path1)) + { + err.Printf("[ERR] Coud not copy %s to %s",dest.c_str(),path2.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + + return true; // install ready + } + else + return false; //no uninstallation possible +} + +// H10 install +bool h10(int mode) +{ + wxString err,src,dest,path1,path2; + + int pos = gv->curbootloader.Find('/'); + wxString firmwarename = gv->curbootloader.SubString(pos,gv->curbootloader.Length()); + wxString firmDir = gv->curbootloader.SubString(0,pos); + + if(mode == BOOTLOADER_ADD) + { + //Files downloaden + src.Printf("%s/iriver/%s", gv->bootloader_url.c_str(),gv->curbootloader.c_str()); + dest.Printf("%s" PATH_SEP "download" PATH_SEP "%s", + gv->stdpaths->GetUserDataDir().c_str(),firmwarename.c_str()); + if( DownloadURL(src, dest) ) + { + wxRemoveFile(dest); + err.Printf(_("Unable to download %s"), src.c_str() ); + ERR_DIALOG(err, _("Install")); + return false; + } + + path1.Printf("%s" PATH_SEP "SYSTEM" PATH_SEP "%s",gv->curdestdir.c_str(),firmwarename.c_str()); + path2.Printf("%s" PATH_SEP "SYSTEM" PATH_SEP "Original.mi4",gv->curdestdir.c_str()); + + if(!wxFileExists(path1)) //Firmware dosent exists on player + { + path1.Printf("%s" PATH_SEP "SYSTEM" PATH_SEP "H10EMP.mi4"); //attempt other firmwarename + if(!wxFileExists(path1)) //Firmware dosent exists on player + { + err.Printf("[ERR] File %s does not Exist",path1.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + } + if(!wxFileExists(path2)) //there is already a original firmware + { + err.Printf("[ERR] File %s does not Exist",path1.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + if(!wxRenameFile(path1,path2,false)) //rename Firmware to Original + { + err.Printf("[ERR] Coud not rename %s to %s",path1.c_str(),path2.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + if(!wxCopyFile(dest,path1)) // copy file + { + err.Printf("[ERR] Coud not copy %s to %s",dest.c_str(),path1.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + + return true; //install ready + + } + else if(mode == BOOTLOADER_REM) + { + path1.Printf("%s" PATH_SEP "SYSTEM" PATH_SEP "%s",gv->curdestdir.c_str(),firmwarename.c_str()); + path2.Printf("%s" PATH_SEP "SYSTEM" PATH_SEP "Original.mi4",gv->curdestdir.c_str()); + if(!wxFileExists(path1)) //Firmware dosent exists on player + { + path1.Printf("%s" PATH_SEP "SYSTEM" PATH_SEP "H10EMP.mi4"); //attempt other firmwarename + if(!wxFileExists(path1)) //Firmware dosent exists on player + { + err.Printf("[ERR] File %s does not Exist",path1.c_str()); + ERR_DIALOG(err, _("Bootloader rem")); + return false; + } + } + + if(!wxFileExists(path2)) //Original Firmware dosent exists on player + { + err.Printf("[ERR] File %s does not Exist",path2.c_str()); + ERR_DIALOG(err, _("Bootloader rem")); + return false; + } + + if(!wxRenameFile(path2,path1,true)) //rename Firmware to Original + { + err.Printf("[ERR] Coud not rename %s to %s",path2.c_str(),path1.c_str()); + ERR_DIALOG(err, _("Bootloader add")); + return false; + } + + } + +} + +// FWPatcher +bool fwpatcher(int mode) +{ + if(mode == BOOTLOADER_ADD) + { + wxString md5sum_str,src,dest,err; + int series,table_entry; + + if (!FileMD5(gv->curfirmware, &md5sum_str)) { + ERR_DIALOG("Could not open firmware", _("Open Firmware")); + return false; + } + else { + /* Check firmware against md5sums in h120sums and h100sums */ + series = 0; + table_entry = intable(md5sum_str, &h120pairs[0], + sizeof(h120pairs)/sizeof(struct sumpairs)); + if (table_entry >= 0) { + series = 120; + } + else { + table_entry = intable(md5sum_str, &h100pairs[0], + sizeof(h100pairs)/sizeof(struct sumpairs)); + if (table_entry >= 0) { + series = 100; + } + else { + table_entry = + intable(md5sum_str, &h300pairs[0], + sizeof(h300pairs)/sizeof(struct sumpairs)); + if (table_entry >= 0) + series = 300; + } + } + if (series == 0) { + ERR_DIALOG("Could not detect firmware type", _("Detect Player out of Firmware")); + return false; + } + else + { + //Download bootloader + src.Printf("%s/iriver/%s", gv->bootloader_url.c_str(),gv->curbootloader.c_str()); + dest.Printf("%s" PATH_SEP "download" PATH_SEP "%s", + gv->stdpaths->GetUserDataDir().c_str(),gv->curbootloader.c_str()); + if( DownloadURL(src, dest) ) + { + wxRemoveFile(dest); + err.Printf(_("Unable to download %s"), src.c_str() ); + ERR_DIALOG(err, _("Install")); + return false; + } + + if(!PatchFirmware(gv->curfirmware,dest,series, table_entry)) // Patch firmware + { + ERR_DIALOG("Patching Firmware failed", _("Patching Firmware")); + return false; + } + } + + // Load patched Firmware to player + src.Printf("%s" PATH_SEP "download" PATH_SEP "new.hex", + gv->stdpaths->GetUserDataDir().c_str()); + + if(gv->curplat == "h100") + dest.Printf("%s" PATH_SEP "ihp_100.hex",gv->curdestdir.c_str()); + else if(gv->curplat == "h120") + dest.Printf("%s" PATH_SEP "ihp_120.hex",gv->curdestdir.c_str()); + else if(gv->curplat == "h300") + dest.Printf("%s" PATH_SEP "H300.hex",gv->curdestdir.c_str()); + + if(!wxRenameFile(src,dest)) + { + ERR_DIALOG("Copying Firmware to Device failed", _("Copying Firmware")); + return false; + } + else + { + return true; + } + + } + + } + else + { + return false; //no uninstall possible + } +} diff --git a/rbutil/bootloaders.h b/rbutil/bootloaders.h new file mode 100755 index 0000000000..53569e34da --- /dev/null +++ b/rbutil/bootloaders.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: bootloaders.h + * + * Copyright (C) 2007 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + + +#ifndef BOOTLOADERS_H_INCLUDED +#define BOOTLOADERS_H_INCLUDED + + +extern "C" { + // Ipodpatcher + #include "ipodpatcher/ipodpatcher.h" +}; + + +bool initIpodpatcher(); +bool ipodpatcher(int mode); +bool gigabeatf(int mode); +bool iaudiox5(int mode); +bool fwpatcher(int mode); +bool h10(int mode); + + +#endif // BOOTLOADERS_H_INCLUDED diff --git a/rbutil/credits.h b/rbutil/credits.h index 867661b067..39f8389621 100644 --- a/rbutil/credits.h +++ b/rbutil/credits.h @@ -27,6 +27,7 @@ static const char* rbutil_developers[] = { "Christi Alice Scarborough", "Dave Chapman", + "Dominik Wenger", "" }; diff --git a/rbutil/h100sums.h b/rbutil/h100sums.h new file mode 100755 index 0000000000..ebbdcc28db --- /dev/null +++ b/rbutil/h100sums.h @@ -0,0 +1,23 @@ +/* Checksums of firmwares for ihp_100 */ +/* order: unpatched, patched */ + +/* 1.63eu */ +{"86103cb05658970b43ce1f40f93d53a8", "4938420d83aa6da3764d33e5a008c8d4"}, +/* 1.63k */ +{"70127fa9ee69afab7645297fbb61636d", "044b737ddb74436353e290d3fbcc3333"}, +/* 1.63us */ +{"7a504a450c76a0dda757fdb6b5531b22", "e51883ed89d49f5677b0a976aef7b154"}, +/* 1.65eu */ +{"478dc657b97e77d1b4944ef26c3dcb8e", "528917d9e5b34a3e5bcac8fe1f4bd7a9"}, +/* 1.65k */ +{"97ba82fb8099bb23ca0c78fc119f8cce", "ef24f69a679e5eba2216045cb24d8b15"}, +/* 1.65us */ +{"d3725865e0948cd5f604b00db2ec89aa", "76d83812b9e1856f768ba913eeba44e1"}, +/* 1.66eu */ +{"fc59f742fe383da3e4d17a660c46afb9", "2aa9d16d3e166a7575fc652db8588daa"}, +/* 1.66k */ +{"22d214401994c276ec6878288caa0dba", "a87dbe604ea98d035450a34b6e184a08"}, +/* 1.66us */ +{"0ae247f567aeafcafecf823a50cbf33e", "f7668e8949f1a78e8ecd685db78b6824"}, +/* 1.66jp */ +{"8bfc8ae5805c270597232efeafade5fd", "72613b75c5196f63e99e41b7a88d7241"}, diff --git a/rbutil/h120sums.h b/rbutil/h120sums.h new file mode 100755 index 0000000000..09da891ae1 --- /dev/null +++ b/rbutil/h120sums.h @@ -0,0 +1,23 @@ +/* Checksums of firmwares for ihp_120 */ +/* order: unpatched, patched */ + +/* 1.63eu */ +{"14488347a171480c63c94bc7b885225d", "15f09130a1aa02c25f820e8cc68259a4"}, +/* 1.63k */ +{"3401fe8845e569156abfaddf05ca7771", "55e4cb20e36f4da06ad80b31aaaa3054"}, +/* 1.63us */ +{"d9078209105c186cee5246055fdb99c9", "dbdd012a3d821d26f907879cca71e9f4"}, +/* 1.65eu */ +{"c9e71aac4a498f1e2f0e684c2d554ea1", "43454df30c176e55d0df7e3c48e67785"}, +/* 1.65k */ +{"360c0c565266f84e9bca610c596f3207", "d8cb7d9f586186bf9780ee761fc8a677"}, +/* 1.65us */ +{"b9e516d4b8a0265605f46f254897bfb0", "99c5666e990dc782b9daefcb1a087ec0"}, +/* 1.66eu */ +{"a094999b41781f4322a57b9be7fa4534", "e26d2574f39cee0adcdd54fb9f316293"}, +/* 1.66k */ +{"79daba973bb31b60b4b87c2ef497587d", "e76121ba9efe72ecfbb6392eaefe6d96"}, +/* 1.66us */ +{"7fa020a3104c76fbbfcb8313e287dbe2", "12194678a2fdd0814d2e0bb57c8e8e6e"}, +/* 1.66jp */ +{"271d151eb6586929da24b3458ea965fe", "51716393ea0605d225e70a6be29dfdbd"}, diff --git a/rbutil/h300sums.h b/rbutil/h300sums.h new file mode 100755 index 0000000000..1c6581a6d1 --- /dev/null +++ b/rbutil/h300sums.h @@ -0,0 +1,17 @@ +/* Checksums of firmwares for ihp_300 */ +/* order: unpatched, patched */ + +/* 1.28eu */ +{"0b2083d37f24899b82d21a14d2b38060", "9cd7e291a66f55335c619d63f3a7634b"}, +/* 1.28k */ +{"c6f854ae3d8f48e8982819a4b5302fb0", "90967247ba3f1bcb257432a4d78553bf"}, +/* 1.28jp */ +{"7fcd7bca6b98a34134e2518a616f4e85", "cfd22c20e473727148f11f83d0028fb3"}, +/* 1.29eu */ +{"27d90fc316709c096979ab24c914ee31", "5982302507d57c2a96e9480c242b5de0"}, +/* 1.29k */ +{"44416d97737fc47cd417a64d44064768", "1303e22ef5b1af866aa4def03d6c5f5a"}, +/* 1.29jp */ +{"1ac242c645572a0a5de99ae2b23453b8", "ce433c404ff7531f5852ce3cb61143ee"}, +/* 1.30eu */ +{"8d2d775b018f0532235d38f5317ae10c", "7fb49041294b3e6aea3894218d6d64cf"}, diff --git a/rbutil/irivertools.cpp b/rbutil/irivertools.cpp new file mode 100755 index 0000000000..f04db6417a --- /dev/null +++ b/rbutil/irivertools.cpp @@ -0,0 +1,613 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: irivertools.cpp + * + * Copyright (C) 2007 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "irivertools.h" +#include "md5sum.h" + + +const unsigned char munge[] = { + 0x7a, 0x36, 0xc4, 0x43, 0x49, 0x6b, 0x35, 0x4e, 0xa3, 0x46, 0x25, 0x84, + 0x4d, 0x73, 0x74, 0x61 +}; + +const unsigned char header_modify[] = "* IHPFIRM-DECODED "; + +const char * const models[] = { "iHP-100", "iHP-120/iHP-140", "H300 series", + NULL }; + +/* aligns with models array; expected min firmware size */ +const unsigned int firmware_minsize[] = { 0x100000, 0x100000, 0x200000 }; +/* aligns with models array; expected max firmware size */ +const unsigned int firmware_maxsize[] = { 0x200000, 0x200000, 0x400000 }; + +const unsigned char header[][16] = { + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, + { 0x20, 0x03, 0x08, 0x27, 0x24, 0x00, 0x02, 0x30, 0x19, 0x17, 0x65, 0x73, + 0x85, 0x32, 0x83, 0x22 }, + { 0x20, 0x04, 0x03, 0x27, 0x20, 0x50, 0x01, 0x70, 0x80, 0x30, 0x80, 0x06, + 0x30, 0x19, 0x17, 0x65 } +}; + +/* begin mkboot.c excerpt */ +unsigned char image[0x400000 + 0x220 + 0x400000/0x200]; + +bool mkboot(wxString infile, wxString outfile,wxString bootloader,int origin) +{ + wxString err; + int i; + int len,bllen; + int actual_length, total_length, binary_length, num_chksums; + + memset(image, 0xff, sizeof(image)); + + /* First, read the iriver original firmware into the image */ + wxFile f; + if(!f.Open(infile)) + { + err.Printf("Could not open: %s",infile.c_str()); + ERR_DIALOG(err, _("mkboot")); + return false; + } + i = f.Read(image,16); + if(i < 16) { + ERR_DIALOG("reading header failed", _("mkboot")); + return false; + } + + /* This is the length of the binary image without the scrambling + overhead (but including the ESTFBINR header) */ + binary_length = image[4] + (image[5] << 8) + + (image[6] << 16) + (image[7] << 24); + + /* Read the rest of the binary data, but not the checksum block */ + len = binary_length+0x200-16; + i = f.Read(image+16, len); + if(i < len) { + ERR_DIALOG("reading firmware failed", _("mkboot")); + return false; + } + + f.Close(); + /* Now, read the boot loader into the image */ + if(!f.Open(bootloader)) + { + err.Printf("Could not open: %s",bootloader.c_str()); + ERR_DIALOG(err, _("mkboot")); + return false; + } + + bllen = f.Length(); + + i = f.Read(image+0x220 + origin, bllen); + if(i < bllen) { + ERR_DIALOG("reading bootloader failed", _("mkboot")); + return false; + } + + f.Close(); + + if(!f.Open(outfile,wxFile::write)) + { + err.Printf("Could not open: %s",outfile.c_str()); + ERR_DIALOG(err, _("mkboot")); + return false; + } + + /* Patch the reset vector to start the boot loader */ + image[0x220 + 4] = image[origin + 0x220 + 4]; + image[0x220 + 5] = image[origin + 0x220 + 5]; + image[0x220 + 6] = image[origin + 0x220 + 6]; + image[0x220 + 7] = image[origin + 0x220 + 7]; + + /* This is the actual length of the binary, excluding all headers */ + actual_length = origin + bllen; + + /* Patch the ESTFBINR header */ + image[0x20c] = (actual_length >> 24) & 0xff; + image[0x20d] = (actual_length >> 16) & 0xff; + image[0x20e] = (actual_length >> 8) & 0xff; + image[0x20f] = actual_length & 0xff; + + image[0x21c] = (actual_length >> 24) & 0xff; + image[0x21d] = (actual_length >> 16) & 0xff; + image[0x21e] = (actual_length >> 8) & 0xff; + image[0x21f] = actual_length & 0xff; + + /* This is the length of the binary, including the ESTFBINR header and + rounded up to the nearest 0x200 boundary */ + binary_length = (actual_length + 0x20 + 0x1ff) & 0xfffffe00; + + /* The number of checksums, i.e number of 0x200 byte blocks */ + num_chksums = binary_length / 0x200; + + /* The total file length, including all headers and checksums */ + total_length = binary_length + num_chksums + 0x200; + + /* Patch the scrambler header with the new length info */ + image[0] = total_length & 0xff; + image[1] = (total_length >> 8) & 0xff; + image[2] = (total_length >> 16) & 0xff; + image[3] = (total_length >> 24) & 0xff; + + image[4] = binary_length & 0xff; + image[5] = (binary_length >> 8) & 0xff; + image[6] = (binary_length >> 16) & 0xff; + image[7] = (binary_length >> 24) & 0xff; + + image[8] = num_chksums & 0xff; + image[9] = (num_chksums >> 8) & 0xff; + image[10] = (num_chksums >> 16) & 0xff; + image[11] = (num_chksums >> 24) & 0xff; + + i = f.Write(image,total_length); + if(i < total_length) { + ERR_DIALOG("writing bootloader failed", _("mkboot")); + return false; + } + + f.Close(); + + return true; +} + +/* end mkboot.c excerpt */ + + +int intable(wxString md5, struct sumpairs *table, int len) +{ + int i; + for (i = 0; i < len; i++) { + if (md5.Cmp(table[i].unpatched) == 0) { + return i; + } + } + return -1; +} + + + + +static int testheader( const unsigned char * const data ) +{ + const unsigned char * const d = data+16; + const char * const * m = models; + int index = 0; + while( *m ) + { + if( memcmp( header[ index ], d, 16 ) == 0 ) + return index; + index++; + m++; + }; + return -1; +}; + +static void modifyheader( unsigned char * data ) +{ + const unsigned char * h = header_modify; + int i; + for( i=0; i<512; i++ ) + { + if( *h == '\0' ) + h = header_modify; + *data++ ^= *h++; + }; +}; + +int iriver_decode(wxString infile_name, wxString outfile_name, unsigned int modify, + enum striptype stripmode ) +{ + wxString err; + wxFile infile; + wxFile outfile; + int i = -1; + unsigned char headerdata[512]; + unsigned long dwLength1, dwLength2, dwLength3, fp = 0; + unsigned char blockdata[16+16]; + unsigned char out[16]; + unsigned char newmunge; + signed long lenread; + int s = 0; + unsigned char * pChecksums, * ppChecksums = 0; + unsigned char ck; + + if(!infile.Open(infile_name)) + { + err.Printf("Could not open: %s",infile_name.c_str()); + ERR_DIALOG(err, _("iriver_decode")); + return -1; + } + if(!outfile.Open(outfile_name,wxFile::write)) + { + err.Printf("Could not open: %s",outfile_name.c_str()); + ERR_DIALOG(err, _("iriver_decode")); + return -1; + } + lenread = infile.Read( headerdata, 512); + if( lenread != 512 ) + { + ERR_DIALOG(_("This doesn't look like a valid encrypted iHP " + "firmware - reason: header length\n"),_("iriver_decode")); + + infile.Close(); + outfile.Close(); + return -1; + }; + + i = testheader( headerdata ); + if( i == -1 ) + { + ERR_DIALOG( _( "This firmware is for an unknown model, or is not" + " a valid encrypted iHP firmware\n" ),_("iriver_decode")); + infile.Close(); + outfile.Close(); + return -1; + }; + fprintf( stderr, "Model %s\n", models[ i ] ); + + dwLength1 = headerdata[0] | (headerdata[1]<<8) | + (headerdata[2]<<16) | (headerdata[3]<<24); + dwLength2 = headerdata[4] | (headerdata[5]<<8) | + (headerdata[6]<<16) | (headerdata[7]<<24); + dwLength3 = headerdata[8] | (headerdata[9]<<8) | + (headerdata[10]<<16) | (headerdata[11]<<24); + + if( dwLength1 < firmware_minsize[ i ] || + dwLength1 > firmware_maxsize[ i ] || + dwLength2 < firmware_minsize[ i ] || + dwLength2 > dwLength1 || + dwLength3 > dwLength1 || + dwLength2>>9 != dwLength3 || + dwLength2+dwLength3+512 != dwLength1 ) + { + ERR_DIALOG( _( "This doesn't look like a valid encrypted " + "iHP firmware - reason: file 'length' data\n" ),_("iriver_decode")); + infile.Close(); + outfile.Close(); + return -1; + }; + + pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); + + if( modify ) + { + modifyheader( headerdata ); + }; + + if( stripmode == STRIP_NONE ) + outfile.Write( headerdata, 512); + + memset( blockdata, 0, 16 ); + + ck = 0; + while( ( fp < dwLength2 ) && + ( lenread = infile.Read( blockdata+16, 16) == 16) ) + { + fp += 16; + + for( i=0; i<16; ++i ) + { + newmunge = blockdata[16+i] ^ munge[i]; + out[i] = newmunge ^ blockdata[i]; + blockdata[i] = newmunge; + ck += out[i]; + } + + if( fp > ESTF_SIZE || stripmode != STRIP_HEADER_CHECKSUM_ESTF ) + { + outfile.Write( out+4, 12); + outfile.Write( out, 4); + } + else + { + if( ESTF_SIZE - fp < 16 ) + { + memcpy( out+4, blockdata+16, 12 ); + memcpy( out, blockdata+28, 4 ); + outfile.Write( blockdata+16+ESTF_SIZE-fp, ESTF_SIZE-fp); + } + } + + + if( s == 496 ) + { + s = 0; + memset( blockdata, 0, 16 ); + *ppChecksums++ = ck; + ck = 0; + } + else + s+=16; + }; + + if( fp != dwLength2 ) + { + ERR_DIALOG( _( "This doesn't look like a valid encrypted " + "iHP firmware - reason: 'length2' mismatch\n" ),_("iriver_decode")); + infile.Close(); + outfile.Close(); + return -1; + }; + + fp = 0; + ppChecksums = pChecksums; + while( ( fp < dwLength3 ) && + ( lenread = infile.Read( blockdata, 32 ) ) > 0 ) + { + fp += lenread; + if( stripmode == STRIP_NONE ) + outfile.Write( blockdata, lenread ); + if( memcmp( ppChecksums, blockdata, lenread ) != 0 ) + { + ERR_DIALOG( _( "This doesn't look like a valid encrypted " + "iHP firmware - reason: Checksum mismatch!" ),_("iriver_decode")); + infile.Close(); + outfile.Close(); + return -1; + }; + ppChecksums += lenread; + }; + + if( fp != dwLength3 ) + { + ERR_DIALOG(_( "This doesn't look like a valid encrypted " + "iHP firmware - reason: 'length3' mismatch\n" ),_("iriver_decode")); + infile.Close(); + outfile.Close(); + return -1; + }; + + + fprintf( stderr, "File decoded correctly and all checksums matched!\n" ); + switch( stripmode ) + { + default: + case STRIP_NONE: + fprintf(stderr, "Output file contains all headers and " + "checksums\n"); + break; + case STRIP_HEADER_CHECKSUM: + fprintf( stderr, "NB: output file contains only ESTFBINR header" + " and decoded firmware code\n" ); + break; + case STRIP_HEADER_CHECKSUM_ESTF: + fprintf( stderr, "NB: output file contains only raw decoded " + "firmware code\n" ); + break; + }; + + infile.Close(); + outfile.Close(); + return 0; + +}; + +int iriver_encode(wxString infile_name, wxString outfile_name, unsigned int modify ) +{ + wxString err; + wxFile infile; + wxFile outfile; + int i = -1; + unsigned char headerdata[512]; + unsigned long dwLength1, dwLength2, dwLength3, fp = 0; + unsigned char blockdata[16+16]; + unsigned char out[16]; + unsigned char newmunge; + signed long lenread; + int s = 0; + unsigned char * pChecksums, * ppChecksums; + unsigned char ck; + + enum striptype stripmode = STRIP_NONE; + + if(!infile.Open(infile_name,wxFile::read)) + { + err.Printf("Could not open: %s",infile_name.c_str()); + ERR_DIALOG(err, _("iriver_decode")); + return -1; + } + if(!outfile.Open(outfile_name,wxFile::write)) + { + err.Printf("Could not open: %s",outfile_name.c_str()); + ERR_DIALOG(err, _("iriver_decode")); + return -1; + } + + lenread = infile.Read( headerdata, 512 ); + if( lenread != 512 ) + { + ERR_DIALOG("This doesn't look like a valid decoded " + "iHP firmware - reason: header length\n", _("iriver_decode")); + infile.Close(); + outfile.Close(); + }; + + if( modify ) + { + modifyheader( headerdata ); /* reversible */ + }; + + i = testheader( headerdata ); + if( i == -1 ) + { + ERR_DIALOG("This firmware is for an unknown model, or is not" + " a valid decoded iHP firmware\n", _("iriver_decode")); + infile.Close(); + outfile.Close(); + }; + fprintf( stderr, "Model %s\n", models[ i ] ); + + dwLength1 = headerdata[0] | (headerdata[1]<<8) | + (headerdata[2]<<16) | (headerdata[3]<<24); + dwLength2 = headerdata[4] | (headerdata[5]<<8) | + (headerdata[6]<<16) | (headerdata[7]<<24); + dwLength3 = headerdata[8] | (headerdata[9]<<8) | + (headerdata[10]<<16) | (headerdata[11]<<24); + + if( dwLength1 < firmware_minsize[i] || + dwLength1 > firmware_maxsize[i] || + dwLength2 < firmware_minsize[i] || + dwLength2 > dwLength1 || + dwLength3 > dwLength1 || + dwLength2+dwLength3+512 != dwLength1 ) + { + ERR_DIALOG("This doesn't look like a valid decoded iHP" + " firmware - reason: file 'length' data\n", _("iriver_decode")); + infile.Close(); + outfile.Close(); + }; + + pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) ); + + outfile.Write( headerdata, 512); + + memset( blockdata, 0, 16 ); + ck = 0; + while( ( fp < dwLength2 ) && + ( lenread = infile.Read( blockdata+16, 16) ) == 16 ) + { + fp += 16; + for( i=0; i<16; ++i ) + { + newmunge = blockdata[16+((12+i)&0xf)] ^ blockdata[i]; + out[i] = newmunge ^ munge[i]; + ck += blockdata[16+i]; + blockdata[i] = newmunge; + }; + outfile.Write( out, 16); + + if( s == 496 ) + { + s = 0; + memset( blockdata, 0, 16 ); + *ppChecksums++ = ck; + ck = 0; + } + else + s+=16; + }; + + if( fp != dwLength2 ) + { + ERR_DIALOG("This doesn't look like a valid decoded " + "iHP firmware - reason: 'length1' mismatch\n", _("iriver_decode")); + infile.Close(); + outfile.Close(); + }; + + /* write out remainder w/out applying descrambler */ + fp = 0; + lenread = dwLength3; + ppChecksums = pChecksums; + while( ( fp < dwLength3) && + ( lenread = outfile.Write( ppChecksums, lenread) ) > 0 ) + { + fp += lenread; + ppChecksums += lenread; + lenread = dwLength3 - fp; + }; + + if( fp != dwLength3 ) + { + ERR_DIALOG("This doesn't look like a valid decoded " + "iHP firmware - reason: 'length2' mismatch\n", _("iriver_decode")); + infile.Close(); + outfile.Close(); + }; + + fprintf( stderr, "File encoded successfully and checksum table built!\n" ); + + infile.Close(); + outfile.Close(); + return 0; + +}; + +bool PatchFirmware(wxString firmware,wxString bootloader,int series, int table_entry) +{ + wxString name1, name2, name3; + + wxString md5sum_str; + int i; + struct sumpairs *sums; + int origin; + + /* get pointer to the correct bootloader.bin */ + switch(series) { + case 100: + sums = &h100pairs[0]; + origin = 0x1f0000; + break; + case 120: + sums = &h120pairs[0]; + origin = 0x1f0000; + break; + case 300: + sums = &h300pairs[0]; + origin = 0x3f0000; + break; + } + + name1.Printf("%s" PATH_SEP "download" PATH_SEP "firmware.bin", + gv->stdpaths->GetUserDataDir().c_str()); + /* descrambled file */ + name2.Printf("%s" PATH_SEP "download" PATH_SEP "new.bin", + gv->stdpaths->GetUserDataDir().c_str()); + /* patched file */ + name3.Printf("%s" PATH_SEP "download" PATH_SEP "new.hex", + gv->stdpaths->GetUserDataDir().c_str()); + if (iriver_decode(firmware, name1, FALSE, STRIP_NONE) == -1) { + ERR_DIALOG("Error in descramble", _("Descramble Firmware")); + wxRemoveFile(name1); + wxRemoveFile(name2); + wxRemoveFile(name3); + return false; + } + if (!mkboot(name1, name2, bootloader, origin)) { + ERR_DIALOG("Error in patching",_("Patching Firmware")); + wxRemoveFile(name1); + wxRemoveFile(name2); + wxRemoveFile(name3); + return false; + } + if (iriver_encode(name2, name3, FALSE) == -1) { + ERR_DIALOG("Error in scramble",_("Scramble Firmware")); + wxRemoveFile(name1); + wxRemoveFile(name2); + wxRemoveFile(name3); + return false; + } + /* now md5sum it */ + if (!FileMD5(name3, &md5sum_str)) { + ERR_DIALOG("Error in checksumming",_("Checksumming Firmware")); + wxRemoveFile(name1); + wxRemoveFile(name2); + wxRemoveFile(name3); + return false; + } + if (strncmp(sums[table_entry].patched, md5sum_str.c_str(), 32) == 0) { + /* delete temp files */ + wxRemoveFile(name1); + wxRemoveFile(name2); + } + + return true; +} + diff --git a/rbutil/irivertools.h b/rbutil/irivertools.h new file mode 100755 index 0000000000..deae3f4006 --- /dev/null +++ b/rbutil/irivertools.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: irivertools.h + * + * Copyright (C) 2007 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#ifndef IRIVERTOOLS_H_INCLUDED +#define IRIVERTOOLS_H_INCLUDED + +#include "rbutil.h" +#include "installlog.h" + +#define ESTF_SIZE 32 + +struct sumpairs { + char *unpatched; + char *patched; +}; + +/* precalculated checksums for H110/H115 */ +static struct sumpairs h100pairs[] = { +#include "h100sums.h" +}; + +/* precalculated checksums for H120/H140 */ +static struct sumpairs h120pairs[] = { +#include "h120sums.h" +}; + +/* precalculated checksums for H320/H340 */ +static struct sumpairs h300pairs[] = { +#include "h300sums.h" +}; + + +enum striptype +{ + STRIP_NONE, + STRIP_HEADER_CHECKSUM, + STRIP_HEADER_CHECKSUM_ESTF +}; + +/* protos for iriver.c */ + +int intable(wxString md5, struct sumpairs *table, int len); + +bool PatchFirmware(wxString firmware,wxString bootloader,int series, int table_entry); + + +#endif // IRIVERTOOLS_H_INCLUDED diff --git a/rbutil/md5sum.cpp b/rbutil/md5sum.cpp new file mode 100755 index 0000000000..9c253beed2 --- /dev/null +++ b/rbutil/md5sum.cpp @@ -0,0 +1,300 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: md5sum.cpp + * + * Copyright (C) 2007 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +/* + * RFC 1321 compliant MD5 implementation + * + * Copyright (C) 2001-2003 Christophe Devine + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "md5sum.h" + + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ( (uint32) (b)[(i) ] ) \ + | ( (uint32) (b)[(i) + 1] << 8 ) \ + | ( (uint32) (b)[(i) + 2] << 16 ) \ + | ( (uint32) (b)[(i) + 3] << 24 ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8) ( (n) ); \ + (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \ + (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \ + (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \ +} + +void md5_starts( md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +void md5_process( md5_context *ctx, uint8 data[64] ) +{ + uint32 X[16], A, B, C, D; + + GET_UINT32( X[0], data, 0 ); + GET_UINT32( X[1], data, 4 ); + GET_UINT32( X[2], data, 8 ); + GET_UINT32( X[3], data, 12 ); + GET_UINT32( X[4], data, 16 ); + GET_UINT32( X[5], data, 20 ); + GET_UINT32( X[6], data, 24 ); + GET_UINT32( X[7], data, 28 ); + GET_UINT32( X[8], data, 32 ); + GET_UINT32( X[9], data, 36 ); + GET_UINT32( X[10], data, 40 ); + GET_UINT32( X[11], data, 44 ); + GET_UINT32( X[12], data, 48 ); + GET_UINT32( X[13], data, 52 ); + GET_UINT32( X[14], data, 56 ); + GET_UINT32( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F +#undef S +#undef P + + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +void md5_update( md5_context *ctx, uint8 *input, uint32 length ) +{ + uint32 left, fill; + + if( ! length ) return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += length; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < length ) + ctx->total[1]++; + + if( left && length >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + md5_process( ctx, ctx->buffer ); + length -= fill; + input += fill; + left = 0; + } + + while( length >= 64 ) + { + md5_process( ctx, input ); + length -= 64; + input += 64; + } + + if( length ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, length ); + } +} + +static uint8 md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void md5_finish( md5_context *ctx, uint8 digest[16] ) +{ + uint32 last, padn; + uint32 high, low; + uint8 msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32( low, msglen, 0 ); + PUT_UINT32( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_UINT32( ctx->state[0], digest, 0 ); + PUT_UINT32( ctx->state[1], digest, 4 ); + PUT_UINT32( ctx->state[2], digest, 8 ); + PUT_UINT32( ctx->state[3], digest, 12 ); +} + +int FileMD5(wxString name,wxString *md5) +{ + int i, read; + md5_context ctx; + unsigned char md5sum[16]; + unsigned char block[32768]; + + char temp[255]; + wxFile file; + + file.Open(name); + + if (!file.IsOpened()) { + ERR_DIALOG("Could not open patched firmware for checksum check", _("Open Firmware")); + return 0; + } + md5_starts(&ctx); + while ( !file.Eof() ) { + read = file.Read(block, sizeof(block)); + md5_update(&ctx, block, read); + } + file.Close(); + md5_finish(&ctx, md5sum); + for (i = 0; i < 16; ++i) + { + sprintf(temp + 2*i, "%02x", md5sum[i]); + } + md5->Append(temp); + return 1; +} diff --git a/rbutil/md5sum.h b/rbutil/md5sum.h new file mode 100755 index 0000000000..5cc894c0ea --- /dev/null +++ b/rbutil/md5sum.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: md5sum.h + * + * Copyright (C) 2007 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#ifndef MD5SUM_H_INCLUDED +#define MD5SUM_H_INCLUDED + +#ifndef uint8 +#define uint8 unsigned char +#endif + + +#ifndef uint32 +#define uint32 unsigned long int +#endif + +#include "rbutil.h" + + +typedef struct +{ + uint32 total[2]; + uint32 state[4]; + uint8 buffer[64]; +} +md5_context; + +void md5_starts( md5_context *ctx ); +void md5_update( md5_context *ctx, uint8 *input, uint32 length ); +void md5_finish( md5_context *ctx, uint8 digest[16] ); + +int FileMD5(wxString name,wxString *md5); + +#endif // MD5SUM_H_INCLUDED diff --git a/rbutil/mksums.pl b/rbutil/mksums.pl new file mode 100755 index 0000000000..99786fe161 --- /dev/null +++ b/rbutil/mksums.pl @@ -0,0 +1,69 @@ +#!/usr/bin/perl + +# This script creates the h100sums.h and h300sums.h files for fwpatcher. +# +# It expects a file tree with scrambled and descrambled +# firmwares like this: +# orig-firmware/ +# h1xx/ +# 1.66jp/ +# ihp_100.bin +# ihp_100.hex +# ihp_120.bin +# ihp_120.hex +# h3xx/ +# 1.29jp/ +# H300.bin +# H300.hex +# etc. +# +# It also expects the bootloader binaries in the current directory: +# bootloader-h100.bin +# bootloader-h120.bin +# bootloader-h300.bin + +$orig_path = "~/orig-firmware"; + +mksumfile("100"); +mksumfile("120"); +mksumfile("300"); + +sub mksumfile { + ($model) = @_; + + open FILE, ">h${model}sums.h" or die "Can't open h${model}sums.h"; + + print FILE "/* Checksums of firmwares for ihp_$model */\n"; + print FILE "/* order: unpatched, patched */\n\n"; + + if($model < 300) { + foreach("1.63eu","1.63k", "1.63us", "1.65eu","1.65k", "1.65us", + "1.66eu", "1.66k", "1.66us", "1.66jp") { + `../mkboot $orig_path/h1xx/$_/ihp_$model.bin bootloader-h$model.bin ihp_$model.bin`; + `../scramble -iriver ihp_$model.bin ihp_$model.hex`; + $origsum = `md5sum $orig_path/h1xx/$_/ihp_$model.hex`; + chomp $origsum; + ($os, $or) = split / /, $origsum; + $sum = `md5sum ihp_$model.hex`; + chomp $sum; + ($s, $r) = split / /, $sum; + print FILE "/* $_ */\n"; + print FILE "{\"$os\", \"$s\"},\n"; + } + } else { + foreach("1.28eu", "1.28k", "1.28jp", "1.29eu", "1.29k", "1.29jp", + "1.30eu") { + `../mkboot -h300 $orig_path/h3xx/$_/H$model.bin bootloader-h$model.bin H$model.bin`; + `../scramble -iriver H$model.bin H$model.hex`; + $origsum = `md5sum $orig_path/h3xx/$_/H$model.hex`; + chomp $origsum; + ($os, $or) = split / /, $origsum; + $sum = `md5sum H$model.hex`; + chomp $sum; + ($s, $r) = split / /, $sum; + print FILE "/* $_ */\n"; + print FILE "{\"$os\", \"$s\"},\n"; + } + } + close FILE; +} diff --git a/rbutil/rbutil.cbp b/rbutil/rbutil.cbp index ae6fc4a15a..2ee3f2316d 100644 --- a/rbutil/rbutil.cbp +++ b/rbutil/rbutil.cbp @@ -1,18 +1,45 @@ - + - \ No newline at end of file + diff --git a/rbutil/rbutil.cpp b/rbutil/rbutil.cpp index b7a1fa6a73..9ffe9a6c58 100644 --- a/rbutil/rbutil.cpp +++ b/rbutil/rbutil.cpp @@ -21,28 +21,29 @@ #include "rbutil.h" #include "installlog.h" + // This class allows us to return directories as well as files to // wxDir::Traverse class wxDirTraverserIncludeDirs : public wxDirTraverser - { - public: - wxDirTraverserIncludeDirs(wxArrayString& files) : m_files(files) { } +{ +public: + wxDirTraverserIncludeDirs(wxArrayString& files) : m_files(files) { } - virtual wxDirTraverseResult OnFile(const wxString& filename) - { - m_files.Add(filename); - return wxDIR_CONTINUE; - } + virtual wxDirTraverseResult OnFile(const wxString& filename) + { + m_files.Add(filename); + return wxDIR_CONTINUE; + } - virtual wxDirTraverseResult OnDir(const wxString& dirname) - { - m_files.Add(dirname); - return wxDIR_CONTINUE; - } + virtual wxDirTraverseResult OnDir(const wxString& dirname) + { + m_files.Add(dirname); + return wxDIR_CONTINUE; + } - private: - wxArrayString& m_files; - }; +private: + wxArrayString& m_files; +}; wxDEFINE_SCOPED_PTR_TYPE(wxZipEntry); @@ -272,18 +273,15 @@ int UnzipFile(wxString src, wxString destdir, bool isInstall) in_str.Printf(wxT("%s" PATH_SEP "%s"), destdir.c_str(), name.c_str()); if (entry->IsDir() ) { - wxDir* dirname = new wxDir(in_str); - if (! dirname->Exists(in_str) ) { + if (!wxDirExists(in_str) ) { if (! wxMkdir(in_str, 0777) ) { buf.Printf(_("Unable to create directory %s"), in_str.c_str() ); errnum = 100; - delete dirname; break; } } log->WriteFile(name, true); // Directory - delete dirname; continue; } diff --git a/rbutil/rbutil.h b/rbutil/rbutil.h index c1816d5d0b..b499f44e18 100644 --- a/rbutil/rbutil.h +++ b/rbutil/rbutil.h @@ -85,6 +85,11 @@ public: wxArrayString plat_id; wxArrayString plat_name; wxArrayInt plat_released; + wxArrayInt plat_needsbootloader; + wxArrayString plat_bootloadermethod; + wxArrayString plat_bootloadername; + wxArrayInt plat_autodetect; + wxArrayString plat_combinedname; wxString download_url; wxString daily_url; wxString bleeding_url; @@ -92,6 +97,7 @@ public: wxString font_url; wxString last_release; wxString prog_name; + wxString bootloader_url; // User configuration data. wxString curplat; @@ -101,6 +107,9 @@ public: bool curisfull; bool nocache; bool portable; + wxString curbootloadermethod; + wxString curbootloader; + wxString curfirmware; // Global system variables wxFFile* logfile; @@ -120,6 +129,7 @@ bool InstallRbutil(wxString dest); wxString stream_err_str(int errnum); bool rm_rf(wxString file); + #define ERR_DIALOG(msg, title) \ wxLogError("%s: %s", ((wxString) title).c_str(), ((wxString) msg).c_str()) @@ -136,4 +146,7 @@ bool rm_rf(wxString file); #define BUILD_DAILY 1 #define BUILD_BLEEDING 2 +#define BOOTLOADER_ADD 0 +#define BOOTLOADER_REM 1 + #endif diff --git a/rbutil/rbutil.ini b/rbutil/rbutil.ini index f8d42d6c8b..56f5baf3ac 100644 --- a/rbutil/rbutil.ini +++ b/rbutil/rbutil.ini @@ -1,11 +1,12 @@ [general] download_url=http://www.rockbox.org/download/ -daily_url=http://www.rockbox.org/daily/ -bleeding_url=http://www.rockbox.org/dist/build- +daily_url=http://download.rockbox.org/daily/ +bleeding_url=http://build.rockbox.org/dist/build- server_conf_url=http://www.rockbox.org/daily/build-info font_url=http://www.rockbox.org/daily/fonts/rockbox-fonts- last_release=2.5 prog_name=rockbox +bootloader_url=http://download.rockbox.org/bootloader [platforms] platform1=player @@ -19,96 +20,255 @@ platform8=ondiofm platform9=h100 platform10=h120 platform11=h300 -platform12=h10_5gb -platform13=h10 -platform14=ipod3g -platform15=ipod4gray -platform16=ipodcolor -platform17=ipodvideo -platform18=ipodmini1g -platform19=ipodmini2g -platform20=ipodnano -platform21=iaudiox5 +platform12=h10_5gbums +platform13=h10_5gbmtp +platform14=h10 +platform15=ipod3g +platform16=ipod4gray +platform17=ipodcolor +platform18=ipodvideo +platform19=ipodmini1g +platform20=ipodmini2g +platform21=ipodnano +platform22=iaudiox5 +platform23=iaudiox5v +platform24=gigabeatf [player] name=Archos Jukebox Player 6000, Jukebox Studio 5/10/20 +platform=player released=yes +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [recorder] name=Archos Jukebox Recorder 10, 20 +platform=recorder released=yes +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [recorder8mb] name=Archos Jukebox Recorder 10, 20 (with 8mb memory) +platform=recorder8mb released=no +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [recorderv2] name=Archos Jukebox Recorder v2 (20GB) +platform=recorderv2 released=yes +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [fmrecorder] name=Archos Jukebox Recorder FM +platform=fmrecorder released=yes +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [fmrecorder8mb] name=Archos Jukebox Recorder FM (with 8mb memory) +platform=fmrecorder8mb released=no +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [ondiosp] name=Archos Ondio SP +platform=ondiosp released=yes +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [ondiofm] name=Archos Ondio FM +platform=ondiofm released=yes +needsbootloader=no +bootloadermethod= +bootloadername= +autodetect=no +combinedname= [h100] name=Iriver iHP100, iHP110 +platform=h100 released=no +needsbootloader=yes +bootloadermethod=fwpatcher +bootloadername=bootloader-h100.bin +autodetect=no +combinedname= [h120] name=Iriver iHP120, iHP140, H120, H140 +platform=h120 released=no +needsbootloader=yes +bootloadermethod=fwpatcher +bootloadername=bootloader-h120.bin +autodetect=no +combinedname= [h300] name=Iriver H320, H340 +platform=h300 released=no +needsbootloader=yes +bootloadermethod=fwpatcher +bootloadername=bootloader-h300.bin +autodetect=no +combinedname= -[h10_5gb] -name=Iriver H10 (5GB) +[h10_5gbums] +name=Iriver H10 (5GB) UMS +platform=h10_5gb released=no +needsbootloader=yes +bootloadermethod=h10 +bootloadername=H10.mi4 +autodetect=no +combinedname= + +[h10_5gbmtp] +name=Iriver H10 (5GB) MTP +platform=h10_5gb +released=no +needsbootloader=yes +bootloadermethod=h10 +bootloadername=H10_5GB-MTP/H10.mi4 +autodetect=no +combinedname= [h10] name=Iriver H10 (20GB) +platform=h10 +released=no +needsbootloader=yes +bootloadermethod=h10 +bootloadername=H10_20GC.mi4 +autodetect=no +combinedname= [ipodcolor] name=Apple Ipod Colour/Photo/U2 (4th gen) +platform=ipodcolor released=no +needsbootloader=yes +bootloadermethod=ipodpatcher +bootloadername=none +autodetect=yes +combinedname=Ipod mini 1g, mini 2g, 3g, 4g, color, video, nano 1g [ipodnano] name=Apple Ipod Nano (1st gen) +platform=ipodnano released=no +needsbootloader=yes +bootloadermethod=ipodpatcher +bootloadername=none +autodetect=yes +combinedname=Ipod mini 1g, mini 2g, 3g, 4g, color, video, nano 1g [ipod4gray] name=Apple Ipod (4th gen, greyscale) +platform=ipod4gray released=no +needsbootloader=yes +bootloadermethod=ipodpatcher +bootloadername=none +autodetect=yes +combinedname=Ipod mini 1g, mini 2g, 3g, 4g, color, video, nano 1g [ipodvideo] name=Apple Ipod Video (5th gen) +platform=ipodvideo released=no +needsbootloader=yes +bootloadermethod=ipodpatcher +bootloadername=none +autodetect=yes +combinedname=Ipod mini 1g, mini 2g, 3g, 4g, color, video, nano 1g [ipod3g] name=Apple Ipod (3rd gen) +platform=ipod3g released=no +needsbootloader=yes +bootloadermethod=ipodpatcher +bootloadername=none +autodetect=yes +combinedname=Ipod mini 1g, mini 2g, 3g, 4g, color, video, nano 1g [ipodmini1g] name=Apple Ipod Mini (1st gen) +platform=ipodmini1g released=no +needsbootloader=yes +bootloadermethod=ipodpatcher +bootloadername=none +autodetect=yes +combinedname=Ipod mini 1g, mini 2g, 3g, 4g, color, video, nano 1g [ipodmini2g] name=Apple Ipod Mini (2nd gen) +platform=ipodmini2g released=no +needsbootloader=yes +bootloadermethod=ipodpatcher +bootloadername=none +autodetect=yes +combinedname=Ipod mini 1g, mini 2g, 3g, 4g, color, video, nano 1g [iaudiox5] -name=Cowan iAudio X5 +name=Cowan iAudio X5 , X5L +platform=iaudiox5 released=no +needsbootloader=yes +bootloadermethod=iaudio +bootloadername=x5_fw.bin +autodetect=no +combinedname= + +[iaudiox5v] +name=Cowan iAudio X5V +platform=iaudiox5 +released=no +needsbootloader=yes +bootloadermethod=iaudio +bootloadername=x5v_fw.bin +autodetect=no +combinedname= + +[gigabeatf] +name=Toshiba Gigabeat F , X +platform=gigabeatf +needsbootloader=yes +bootloadermethod=gigabeatf +bootloadername=FWIMG01.DAT +autodetect=no +combinedname= diff --git a/rbutil/rbutil.r b/rbutil/rbutil.r new file mode 100755 index 0000000000..e7c39a882c --- /dev/null +++ b/rbutil/rbutil.r @@ -0,0 +1,2675 @@ +data 'vers' (2) { +$"0100 2000 0000 0531 2E30 6430 0531 2E30" +$"6430"} ; + +data 'vers' (1) { +$"0100 2000 0000 0531 2E30 6430 0531 2E30" +$"6430"} ; + +data 'ICN#' (-16455, "Item Icon") { + $"FFFF FFFF F700 001D BB00 002B D700 0057" + $"ED00 009D BB00 0539 DD00 1261 F700 A4E1" + $"FFFE 539F 8100 A52F 8102 AED7 8105 4BAB" + $"8103 BD12 810E 4A65 8105 2492 8102 F926" + $"810B 5FA9 8114 0B7E 8108 05AC 8100 0021" + $"8100 0027 8100 0021 8100 0021 8100 0021" + $"81FF FFE1 8100 0FE1 8122 0AE1 8108 2FA1" + $"8141 0DE1 8104 0B61 8100 9DA1 FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" +}; + +data 'icl4' (-16455, "Item Icon") { + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"F333 333F 0000 0000 0000 0000 0003 3E0F" + $"F333 333F 0000 0000 0000 0000 00A4 3AEF" + $"F333 333F 0000 0000 0000 0000 0DCA 3EEF" + $"F333 333F 0000 0000 0000 0000 E1C5 FE0F" + $"F333 333F 0000 0000 000C CDCB 1DEA E00F" + $"F333 333F 0000 0000 0CCC 1CB1 C3FD 000F" + $"F333 333F 0000 0000 D02C CB1D A9E0 000F" + $"FFFF FFFF FFFF FFFC C2C3 BCD3 EDDF FFFF" + $"F000 000F 0000 00CC 2DAB 02BF 2DDD 666F" + $"F000 000F 0000 0C1D BBB1 BEAB BDCB D66F" + $"F000 000F 0000 CCD4 E2CB BAEE B42C CD6F" + $"F000 000F 0000 C2BA BD2E FF3B DCC2 DCDD" + $"F000 000F 0000 D3BD D2CC 2DCD 02D0 DCEB" + $"F000 000F 0000 0EAC CDB2 CCCC 20D2 CDDB" + $"F000 000F 0000 CBBB 3AAE E2D2 CC2C C2DC" + $"F000 000F 0000 BC2E DD4A EEAE EBBB BBCD" + $"F000 000F 000C DEDD 00CD DAEA AAEF 35DC" + $"F000 000F 000B D000 0000 CCD4 DEBE EADC" + $"F000 000F 0000 0000 0000 0000 00F0 0BCD" + $"F000 000F 0000 0000 0000 0000 00F0 0FEE" + $"F000 000F 0000 0000 0000 0000 00F0 000F" + $"F000 000F 0000 0000 0000 0000 00F0 000F" + $"F000 000F 0000 0000 0000 0000 00F0 000F" + $"F000 000F FFFF FFFF FFFF FFFF FFF0 000F" + $"F000 000F 1111 1111 1111 F999 99F0 000F" + $"F000 000F 1111 1111 1111 F898 99F0 000F" + $"F000 000F 1111 1111 1111 F999 98F0 000F" + $"F000 000F 1111 1111 1111 F989 99F0 000F" + $"F000 000F 1111 1111 1111 F899 89F0 000F" + $"F000 000F 1111 1111 1111 F989 98F0 000F" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" +}; + +data 'icl8' (-16455, "Item Icon") { + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 00DB 22FC 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 DB21 6BDB FCFF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0081 2BDA 6BB2 FCFF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 FB03 5581 FDFB 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0007 2C32 325E 0358 88DE FC00 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"002B 0832 0832 5803 3988 ADFB 0000 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"3208 3208 5658 0934 88AD FC00 0000 00FF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FF32" + $"0833 3964 5809 3388 AD32 FBFF FFFF FFFF" + $"FF00 0000 0000 00FF 0000 0000 0000 3208" + $"3339 8858 0934 82DF 3933 3281 D2D2 D2FF" + $"FF00 0000 0000 00FF 0000 0000 002C 0833" + $"6488 5E09 3388 B35E 6433 3233 81D2 D2FF" + $"FF00 0000 0000 00FF 0000 0000 F608 395D" + $"8858 0934 82E0 8888 5E39 332C 3281 D2FF" + $"FF00 0000 0000 00FF 0000 0000 F739 5E8E" + $"820F 5788 FFFD 645E 3357 0E32 3332 81F9" + $"FF00 0000 0000 00FF 0000 0000 3965 8833" + $"3933 3332 3357 320E 2C0E 322C 0E2D 815D" + $"FF00 0000 0000 00FF 0000 0000 F5FC 8808" + $"325D 5D34 320E 082C 0E2C 3233 3232 FA58" + $"FF00 0000 0000 00FF 0000 0000 2B58 3464" + $"88DE 8988 885E 5D33 3232 3332 335E F954" + $"FF00 0000 0000 00FF 0000 0000 5D33 5D82" + $"FA5D 8789 8EAC 89AC 885E 645E 5D64 5654" + $"FF00 0000 0000 00FF 0000 002C 8187 5756" + $"0000 F632 8189 B2DE 89B2 88AC 8888 F9F8" + $"FF00 0000 0000 00FF 0000 0081 562B 0000" + $"0000 0000 F6F7 325D 815E FB88 88FC 5656" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 005D 57F8" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 00FD AB88" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 0000 00FF" + $"FF00 0000 0000 00FF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E6E6 E6E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE5 E6E5 E6E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E6E6 E6E5 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E5E6 E6E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E6E6 E5E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE5 E6E6 E6E6 FF00 0000 00FF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" +}; + +data 'icm#' (-16455, "Item Icon") { + $"F24B D007 B028 5557 81B1 124A 8236 1005" + $"8000 1ABD 8030 557D FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" +}; + +data 'icm4' (-16455, "Item Icon") { + $"A33F CDCC DCCD CAAE A333 0000 0000 CDEE" + $"333A 0000 CCCB 2E0D EDCE CDCD DB2B DB6F" + $"D00D 00C2 BBEA BCD5 D00D 00BD 2D2D CC2D" + $"D00D 0CDC CCDB BADC D00D 0000 0000 0DCE" + $"D00D 0000 0000 0D0D D00D B1BB 1BF9 FD0D" + $"D00D 1111 1199 8D0D ECDB BB1B B1F9 FECE" +}; + +data 'icm8' (-16455, "Item Icon") { + $"DDDA DADD F8F8 F8F8 F8F8 F8F8 F864 8EAC" + $"DB23 23DC 0000 0000 0000 0000 F85C 89FB" + $"DC23 23DB 0000 0000 F608 3234 5E82 2AFA" + $"FBF8 F8FB F8F8 5633 335D 3488 575D EFF1" + $"F900 00FA 0000 2C63 5E34 FD64 5D2C 33AA" + $"FA00 00F9 0000 395E 5D5D 5733 0832 33F9" + $"F900 00FA 00F6 F92C 2B32 5D88 8888 88F8" + $"FA00 00F9 0000 0000 0000 0000 00FA F781" + $"F900 00FA 0000 0000 0000 0000 00F9 00F9" + $"FA00 00F9 3559 5335 5959 E9E7 E7FA 00FA" + $"F900 00FA 0505 0505 0505 E8E6 E6F9 00F9" + $"FBF8 F8FB 592F 5959 2F59 E9E7 E7FB F8FB" +}; + +data 'icns' (-16455, "Item Icon") { + $"6963 6E73 0000 9AB8 4943 4E23 0000 0108" + $"FFFF FFFF F700 001D BB00 002B D700 0057" + $"ED00 009D BB00 0539 DD00 1261 F700 A4E1" + $"FFFE 539F 8100 A52F 8102 AED7 8105 4BAB" + $"8103 BD12 810E 4A65 8105 2492 8102 F926" + $"810B 5FA9 8114 0B7E 8108 05AC 8100 0021" + $"8100 0027 8100 0021 8100 0021 8100 0021" + $"81FF FFE1 8100 0FE1 8122 0AE1 8108 2FA1" + $"8141 0DE1 8104 0B61 8100 9DA1 FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"6963 6C34 0000 0208 FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF F333 333F 0000 0000" + $"0000 0000 0003 3E0F F333 333F 0000 0000" + $"0000 0000 00A4 3AEF F333 333F 0000 0000" + $"0000 0000 0DCA 3EEF F333 333F 0000 0000" + $"0000 0000 E1C5 FE0F F333 333F 0000 0000" + $"000C CDCB 1DEA E00F F333 333F 0000 0000" + $"0CCC 1CB1 C3FD 000F F333 333F 0000 0000" + $"D02C CB1D A9E0 000F FFFF FFFF FFFF FFFC" + $"C2C3 BCD3 EDDF FFFF F000 000F 0000 00CC" + $"2DAB 02BF 2DDD 666F F000 000F 0000 0C1D" + $"BBB1 BEAB BDCB D66F F000 000F 0000 CCD4" + $"E2CB BAEE B42C CD6F F000 000F 0000 C2BA" + $"BD2E FF3B DCC2 DCDD F000 000F 0000 D3BD" + $"D2CC 2DCD 02D0 DCEB F000 000F 0000 0EAC" + $"CDB2 CCCC 20D2 CDDB F000 000F 0000 CBBB" + $"3AAE E2D2 CC2C C2DC F000 000F 0000 BC2E" + $"DD4A EEAE EBBB BBCD F000 000F 000C DEDD" + $"00CD DAEA AAEF 35DC F000 000F 000B D000" + $"0000 CCD4 DEBE EADC F000 000F 0000 0000" + $"0000 0000 00F0 0BCD F000 000F 0000 0000" + $"0000 0000 00F0 0FEE F000 000F 0000 0000" + $"0000 0000 00F0 000F F000 000F 0000 0000" + $"0000 0000 00F0 000F F000 000F 0000 0000" + $"0000 0000 00F0 000F F000 000F FFFF FFFF" + $"FFFF FFFF FFF0 000F F000 000F 1111 1111" + $"1111 F999 99F0 000F F000 000F 1111 1111" + $"1111 F898 99F0 000F F000 000F 1111 1111" + $"1111 F999 98F0 000F F000 000F 1111 1111" + $"1111 F989 99F0 000F F000 000F 1111 1111" + $"1111 F899 89F0 000F F000 000F 1111 1111" + $"1111 F989 98F0 000F FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF 6963 6C38 0000 0408" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 00DB 22FC 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 DB21 6BDB FCFF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0081 2BDA 6BB2 FCFF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 FB03 5581 FDFB 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"0000 0007 2C32 325E 0358 88DE FC00 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"002B 0832 0832 5803 3988 ADFB 0000 00FF" + $"FF23 2323 2323 23FF 0000 0000 0000 0000" + $"3208 3208 5658 0934 88AD FC00 0000 00FF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FF32" + $"0833 3964 5809 3388 AD32 FBFF FFFF FFFF" + $"FF00 0000 0000 00FF 0000 0000 0000 3208" + $"3339 8858 0934 82DF 3933 3281 D2D2 D2FF" + $"FF00 0000 0000 00FF 0000 0000 002C 0833" + $"6488 5E09 3388 B35E 6433 3233 81D2 D2FF" + $"FF00 0000 0000 00FF 0000 0000 F608 395D" + $"8858 0934 82E0 8888 5E39 332C 3281 D2FF" + $"FF00 0000 0000 00FF 0000 0000 F739 5E8E" + $"820F 5788 FFFD 645E 3357 0E32 3332 81F9" + $"FF00 0000 0000 00FF 0000 0000 3965 8833" + $"3933 3332 3357 320E 2C0E 322C 0E2D 815D" + $"FF00 0000 0000 00FF 0000 0000 F5FC 8808" + $"325D 5D34 320E 082C 0E2C 3233 3232 FA58" + $"FF00 0000 0000 00FF 0000 0000 2B58 3464" + $"88DE 8988 885E 5D33 3232 3332 335E F954" + $"FF00 0000 0000 00FF 0000 0000 5D33 5D82" + $"FA5D 8789 8EAC 89AC 885E 645E 5D64 5654" + $"FF00 0000 0000 00FF 0000 002C 8187 5756" + $"0000 F632 8189 B2DE 89B2 88AC 8888 F9F8" + $"FF00 0000 0000 00FF 0000 0081 562B 0000" + $"0000 0000 F6F7 325D 815E FB88 88FC 5656" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 005D 57F8" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 00FD AB88" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 FF00 0000 00FF" + $"FF00 0000 0000 00FF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E6E6 E6E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE5 E6E5 E6E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E6E6 E6E5 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E5E6 E6E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE6 E6E6 E5E6 FF00 0000 00FF" + $"FF00 0000 0000 00FF 0505 0505 0505 0505" + $"0505 0505 FFE5 E6E6 E6E6 FF00 0000 00FF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"696C 3332 0000 0670 9E00 83FF 0000 90FF" + $"058E EA44 FF00 0083 FF00 008F FF06 8FEA" + $"AB8E 4400 0083 FF00 008E FF07 5ABE AB8E" + $"4544 0000 83FF 0000 8DFF 0864 FE91 6945" + $"44FF 0000 83FF 0000 88FF 0DE2 E1CB B8A1" + $"FEB1 6245 44FF FF00 0083 FF00 0086 FF0A" + $"E2E6 E9EF B89F FEC1 6245 4480 FF01 0000" + $"83FF 0000 85FF 0AD9 E4E9 EBB8 9FFE C362" + $"4544 81FF 8D00 0BD7 E3DE BA8F A2FE C662" + $"45D0 6183 0083 FF00 0083 FF0D DAE5 D4B3" + $"679A FEC8 6245 A5C9 D361 8200 83FF 0000" + $"82FF 0FDC E2D4 A469 9EF2 C962 4579 9BC2" + $"D2D0 6181 0083 FF00 0081 FF11 E8DD D2B3" + $"6AA0 F3C7 5C1B 5D89 9CB5 CDD5 D361 8000" + $"83FF 0000 81FF 14DF C29C 657A DEB3 6A0D" + $"2082 ADBD C3D1 D5D7 D069 8800 83FF 0000" + $"81FF 14AE 8170 B9C5 C1CE C7B2 AFDA E7EA" + $"E1D9 D8D9 D469 8600 83FF 0000 81FF 14EE" + $"5C75 EBD4 9FB3 C4DE E7EC EBE3 E4DD D6CE" + $"C672 9C00 83FF 0000 81FF 14C6 A2C7 886F" + $"4D61 6F7F 9094 C1DB CCC1 C0B7 AB82 A200" + $"83FF 0000 81FF 1499 BFAE 5C8A 856D 504E" + $"5A5B 556C 8F8B 8C95 888F A400 83FF 0000" + $"80FF 15CA 667C 8C9F FFFF DCB5 8251 4A43" + $"3F4B 535E 6860 8FA6 0083 FF00 0080 FF02" + $"669F C283 FF0C DCC3 A88D 847B 686D 5A5E" + $"8FAF 0083 FF00 008F FF06 00FF FF81 8FB5" + $"0083 FF00 008F FF06 00FF FF22 4444 0083" + $"FF00 008F FF00 0081 FF01 0000 83FF 0000" + $"8FFF 0000 81FF 0100 0083 FF00 008F FF00" + $"0081 FF01 0000 83FF 9100 81FF 0100 0083" + $"FF00 0089 FF84 0081 FF01 0000 83FF 0000" + $"89FF 8400 81FF 0100 0083 FF00 0089 FF84" + $"0081 FF01 0000 83FF 0000 89FF 8400 81FF" + $"0100 0083 FF00 0089 FF84 0081 FF01 0000" + $"83FF 0000 89FF 8400 81FF 9E00 A500 90FF" + $"0301 0044 FF86 008F FF04 0900 0001 4486" + $"008E FF05 67BC 0001 1944 8600 8DFF 0666" + $"E49D 7119 44FF 8600 88FF 0BC9 BEA7 9B82" + $"E489 4419 44FF FF86 0086 FF0A CFB6 B9BB" + $"9B79 E493 4419 4480 FF86 0085 FF0A B2AC" + $"B6B5 9B7D E497 4419 4481 FF8D 000B AFAF" + $"A06E 5180 E49A 4419 9B62 8300 83FF 0000" + $"83FF 0DB2 B397 682E 76E4 9D44 1963 96A1" + $"6282 0083 FF00 0082 FF0F BEB0 9953 307E" + $"CF9C 4619 3459 8BA6 9C62 8100 83FF 0000" + $"81FF 11E0 B191 672E 7ED0 9A44 0E2A 3C55" + $"7BA0 A8A2 6280 0083 FF00 0081 FF14 C576" + $"4B2D 51B5 864F 040E 3461 818A 9FA8 A7A1" + $"687C 0083 FF00 0081 FF14 722D 3A7D 8683" + $"9998 8C85 A0B3 B9AE A9AA AAA5 687E 0083" + $"FF00 0081 FF14 E844 38B3 A962 6F7D 9DB2" + $"BEBC B5B7 AFA5 9B95 7392 0083 FF00 0081" + $"FF14 C283 9A44 3D1E 2934 4455 5C8E AC9A" + $"8B89 7D75 829A 0083 FF00 0081 FF14 6E8B" + $"8044 746B 4522 222F 302E 425C 5558 6055" + $"8E9E 0083 FF00 0080 FF15 B466 5A81 9FFF" + $"FFD6 9F5B 231B 1310 202B 333C 378E A000" + $"83FF 0000 80FF 0266 9FC2 83FF 0CD6 B692" + $"6F66 5B47 4931 3B8E A600 83FF 0000 8FFF" + $"0600 FFFF 728E AB00 83FF 0000 8FFF 0600" + $"FFFF 2244 4400 83FF 0000 8FFF 0000 81FF" + $"0100 0083 FF00 008F FF00 0081 FF01 0000" + $"83FF 0000 8FFF 0000 81FF 0100 0083 FF91" + $"0081 FF01 0000 83FF 0000 89FF 0000 827B" + $"0000 81FF 0100 0083 FF00 0089 FF00 0082" + $"7B00 0081 FF01 0000 83FF 0000 89FF 0000" + $"827B 0000 81FF 0100 0083 FF00 0089 FF00" + $"0082 7B00 0081 FF01 0000 83FF 0000 89FF" + $"0000 827B 0000 81FF 0100 0083 FF00 0089" + $"FF00 0082 7B00 0081 FF9E 00A5 0090 FF03" + $"0F43 44FF 8600 8FFF 0417 4316 0F44 8600" + $"8EFF 0565 C416 0F1A 4486 008D FF06 5567" + $"A76C 1A44 FF86 0088 FF0B BCA9 9293 3E67" + $"4D23 1A44 FFFF 8600 86FF 0AC6 9A98 9893" + $"3167 4A23 1A44 80FF 8600 85FF 0A9C 8E99" + $"9593 3767 4F23 1A44 81FF 8D00 0B92 8F86" + $"5747 3967 5223 1A7A 6183 0083 FF00 0083" + $"FF0D 9591 7C51 2A32 6753 231A 4B78 8361" + $"80FF 0100 0083 FF00 0082 FF13 A98B 7D41" + $"2C37 6353 241A 2C44 6D8A 8061 FFFF 0000" + $"83FF 0000 81FF 14DA 9278 5427 3761 5122" + $"1124 323F 6084 8D86 61FF 0000 83FF 0000" + $"81FF 14B7 5B3C 2730 5956 2A0A 0C2C 4F65" + $"6C85 8D89 8869 8800 83FF 0000 81FF 1461" + $"202F 6A76 7683 8378 748C 9A9D 918E 8E8C" + $"8869 5500 83FF 0000 81FF 14E7 2230 9694" + $"5354 5F80 95A2 9E9A 9D94 8881 7A73 4400" + $"83FF 0000 81FF 14C6 4651 3538 191F 2A36" + $"444A 7591 8173 7268 6081 FF00 83FF 0000" + $"81FF 0859 6A49 2277 683C 1A1D 8028 0838" + $"4D47 484F 478E FF00 83FF 0000 80FF 15A8" + $"654A 7F9F FFFF D39A 551C 140E 0B1B 262B" + $"3330 8E9A 0083 FF00 0080 FF02 659F C283" + $"FF0C D3B2 8E69 5F56 4243 2B35 8E9F 0083" + $"FF00 008F FF06 00FF FF6B 8EA7 0083 FF00" + $"008F FF06 00FF FF22 4444 0083 FF00 008F" + $"FF00 0081 FF01 0000 83FF 0000 8FFF 0000" + $"81FF 0100 0083 FF00 008F FF00 0081 FF01" + $"0000 83FF 9100 81FF 0100 0083 FF91 0081" + $"FF01 0000 83FF 9100 81FF 0100 0083 FF91" + $"0081 FF01 0000 83FF 9100 81FF 0100 0083" + $"FF91 0081 FF01 0000 83FF 9100 81FF 9E00" + $"6C38 6D6B 0000 0408 FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF 6963 6823 0000 0248" + $"FFFF FFFF FFFF FFFF FFFF FFFF F770 0000" + $"0001 EEB0 0000 0001 F5D0 0000 0001 EF70" + $"0000 0001 DBB0 0000 0001 F570 0000 0001" + $"FED0 0000 0001 D5B0 0000 0001 EF70 0000" + $"0001 FAD0 0000 0001 FFFF FFFF FFFF FFFF" + $"FFFF FFFF C010 0000 01FF C010 0000 01FF" + $"C010 0000 01EF C010 0000 01FF C010 0000" + $"01FB C010 0000 01DF C010 0000 01FF C010" + $"0000 01FF C010 0000 01FF C010 0000 0181" + $"C010 0000 0181 C010 0000 0181 C010 0000" + $"0181 C010 0000 0181 C010 0000 0181 C010" + $"0000 0181 C010 0000 0181 C010 0000 0181" + $"C010 0000 0181 C010 0000 0181 C010 0000" + $"0181 C010 0000 0181 C01F FFFF FF81 C01F" + $"FFFF FF81 C010 0003 FF81 C011 1113 D581" + $"C010 4443 6F81 C012 000B BB81 C010 8883" + $"DD81 C014 2203 6B81 C011 004B BD81 C010" + $"1103 F781 C014 0423 5B81 FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"6963 6834 0000 0488 FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FF33 3333 333F 0000" + $"0000 0000 0000 0000 0000 0000 0000 000F" + $"FF33 3333 333F 0000 0000 0000 0000 0000" + $"0000 0000 0000 000F FF33 3333 333F 0000" + $"0000 0000 0000 0000 0000 0000 0000 000F" + $"FF33 3333 333F 0000 0000 0000 0000 0000" + $"0000 0000 0000 000F FF33 3333 333F 0000" + $"0000 0000 0000 0000 0000 0000 0000 000F" + $"FF33 3333 333F 0000 0000 0000 0000 0000" + $"0000 0000 0000 000F FF33 3333 333F 0000" + $"0000 0000 0000 0000 0000 0000 0000 000F" + $"FF33 3333 333F 0000 0000 0000 0000 0000" + $"0000 0000 0000 000F FF33 3333 333F 0000" + $"0000 0000 0000 0000 0000 0000 0000 000F" + $"FF33 3333 333F 0000 0000 0000 0000 0000" + $"0000 0000 0000 000F FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F666 666F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F666 666F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F666 666F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F666 666F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F666 666F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F666 666F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F666 666F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F FFFF FFFF FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F FFFF FFFF" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F000 000F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F000 000F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F000 000F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F000 000F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F000 000F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F000 000F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F000 000F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F000 000F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F000 000F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F000 000F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F000 000F FF00 0000 000F 0000" + $"0000 0000 0000 0000 0000 000F F000 000F" + $"FF00 0000 000F 0000 0000 0000 0000 0000" + $"0000 000F F000 000F FF00 0000 000F FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF F000 000F" + $"FF00 0000 000F FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF F000 000F FF00 0000 000F 1111" + $"1111 1111 1111 11FF 9999 999F F000 000F" + $"FF00 0000 000F 1111 1111 1111 1111 11FF" + $"9989 898F F000 000F FF00 0000 000F 1111" + $"1111 1111 1111 11FF 8998 999F F000 000F" + $"FF00 0000 000F 1111 1111 1111 1111 11FF" + $"9899 989F F000 000F FF00 0000 000F 1111" + $"1111 1111 1111 11FF 9989 998F F000 000F" + $"FF00 0000 000F 1111 1111 1111 1111 11FF" + $"8999 899F F000 000F FF00 0000 000F 1111" + $"1111 1111 1111 11FF 9899 989F F000 000F" + $"FF00 0000 000F 1111 1111 1111 1111 11FF" + $"9999 899F F000 000F FF00 0000 000F 1111" + $"1111 1111 1111 11FF 8989 989F F000 000F" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF 6963 6838 0000 0908" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF 2323 2323 2323 2323 23FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 00FF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFD2 D2D2 D2D2 D2FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFD2 D2D2 D2D2 D2FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFD2 D2D2 D2D2 D2FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFD2 D2D2 D2D2 D2FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFD2 D2D2 D2D2 D2FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFD2 D2D2 D2D2 D2FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFD2 D2D2 D2D2 D2FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFFF FFFF FFFF FFFF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FFFF FFFF FFFF FFFF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0000 0000" + $"0000 0000 0000 0000 0000 0000 0000 0000" + $"0000 0000 0000 00FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E6E6 E6E6 E6E6 E6FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E6E6 E5E6 E5E6 E5FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E5E6 E6E6 E6E6 E6FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E6E6 E6E5 E6E5 E6FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E6E5 E6E6 E6E6 E5FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E6E6 E6E6 E5E6 E6FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E5E6 E6E6 E6E5 E6FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E6E6 E6E5 E6E6 E6FF FF00 0000 0000 00FF" + $"FFFF 0000 0000 0000 0000 00FF 0505 0505" + $"0505 0505 0505 0505 0505 0505 0505 FFFF" + $"E6E5 E6E6 E5E6 E6FF FF00 0000 0000 00FF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"6968 3332 0000 052A DF00 86FF 0000 A0FF" + $"8000 86FF 0000 A0FF 8000 86FF 0000 A0FF" + $"8000 86FF 0000 A0FF 8000 86FF 0000 A0FF" + $"8000 86FF 0000 A0FF 8000 86FF 0000 A0FF" + $"8000 86FF 0000 A0FF 8000 86FF 0000 A0FF" + $"8000 86FF 0000 A0FF E000 86FF 0000 98FF" + $"8800 86FF 0000 98FF 8800 86FF 0000 98FF" + $"8800 86FF 0000 98FF 8800 86FF 0000 98FF" + $"8800 86FF 0000 98FF 8800 86FF 0000 98FF" + $"8800 86FF 0000 98FF 8800 86FF 0000 98FF" + $"8800 86FF 0000 98FF 0100 0083 FF80 0086" + $"FF00 0098 FF01 0000 83FF 8000 86FF 0000" + $"98FF 0100 0083 FF80 0086 FF00 0098 FF01" + $"0000 83FF 8000 86FF 0000 98FF 0100 0083" + $"FF80 0086 FF00 0098 FF01 0000 83FF 8000" + $"86FF 0000 98FF 0100 0083 FF80 0086 FF00" + $"0098 FF01 0000 83FF 8000 86FF 0000 98FF" + $"0100 0083 FF80 0086 FF00 0098 FF01 0000" + $"83FF 8000 86FF 0000 98FF 0100 0083 FF80" + $"0086 FF00 0098 FF01 0000 83FF 8000 86FF" + $"0000 98FF 0100 0083 FF80 0086 FF9B 0083" + $"FF80 0086 FF9B 0083 FF80 0086 FF00 008F" + $"FF88 0083 FF80 0086 FF00 008F FF88 0083" + $"FF80 0086 FF00 008F FF88 0083 FF80 0086" + $"FF00 008F FF88 0083 FF80 0086 FF00 008F" + $"FF88 0083 FF80 0086 FF00 008F FF88 0083" + $"FF80 0086 FF00 008F FF88 0083 FF80 0086" + $"FF00 008F FF88 0083 FF80 0086 FF00 008F" + $"FF88 0083 FFAE 00E9 00A0 FF8A 00A0 FF8A" + $"00A0 FF8A 00A0 FF8A 00A0 FF8A 00A0 FF8A" + $"00A0 FF8A 00A0 FF8A 00A0 FF8A 00A0 FFE0" + $"0086 FF00 0098 FF88 0086 FF00 0098 FF88" + $"0086 FF00 0098 FF88 0086 FF00 0098 FF88" + $"0086 FF00 0098 FF88 0086 FF00 0098 FF88" + $"0086 FF00 0098 FF88 0086 FF00 0098 FF88" + $"0086 FF00 0098 FF88 0086 FF00 0098 FF01" + $"0000 83FF 8000 86FF 0000 98FF 0100 0083" + $"FF80 0086 FF00 0098 FF01 0000 83FF 8000" + $"86FF 0000 98FF 0100 0083 FF80 0086 FF00" + $"0098 FF01 0000 83FF 8000 86FF 0000 98FF" + $"0100 0083 FF80 0086 FF00 0098 FF01 0000" + $"83FF 8000 86FF 0000 98FF 0100 0083 FF80" + $"0086 FF00 0098 FF01 0000 83FF 8000 86FF" + $"0000 98FF 0100 0083 FF80 0086 FF00 0098" + $"FF01 0000 83FF 8000 86FF 0000 98FF 0100" + $"0083 FF80 0086 FF00 0098 FF01 0000 83FF" + $"8000 86FF 9B00 83FF 8000 86FF 9B00 83FF" + $"8000 86FF 0000 8FFF 0100 0084 7B01 0000" + $"83FF 8000 86FF 0000 8FFF 0100 0084 7B01" + $"0000 83FF 8000 86FF 0000 8FFF 0100 0084" + $"7B01 0000 83FF 8000 86FF 0000 8FFF 0100" + $"0084 7B01 0000 83FF 8000 86FF 0000 8FFF" + $"0100 0084 7B01 0000 83FF 8000 86FF 0000" + $"8FFF 0100 0084 7B01 0000 83FF 8000 86FF" + $"0000 8FFF 0100 0084 7B01 0000 83FF 8000" + $"86FF 0000 8FFF 0100 0084 7B01 0000 83FF" + $"8000 86FF 0000 8FFF 0100 0084 7B01 0000" + $"83FF AE00 E900 A0FF 8A00 A0FF 8A00 A0FF" + $"8A00 A0FF 8A00 A0FF 8A00 A0FF 8A00 A0FF" + $"8A00 A0FF 8A00 A0FF 8A00 A0FF E000 86FF" + $"0000 98FF 0100 0083 FF80 0086 FF00 0098" + $"FF01 0000 83FF 8000 86FF 0000 98FF 0100" + $"0083 FF80 0086 FF00 0098 FF01 0000 83FF" + $"8000 86FF 0000 98FF 0100 0083 FF80 0086" + $"FF00 0098 FF01 0000 83FF 8000 86FF 0000" + $"98FF 0100 0083 FF80 0086 FF00 0098 FF88" + $"0086 FF00 0098 FF88 0086 FF00 0098 FF01" + $"0000 83FF 8000 86FF 0000 98FF 0100 0083" + $"FF80 0086 FF00 0098 FF01 0000 83FF 8000" + $"86FF 0000 98FF 0100 0083 FF80 0086 FF00" + $"0098 FF01 0000 83FF 8000 86FF 0000 98FF" + $"0100 0083 FF80 0086 FF00 0098 FF01 0000" + $"83FF 8000 86FF 0000 98FF 0100 0083 FF80" + $"0086 FF00 0098 FF01 0000 83FF 8000 86FF" + $"0000 98FF 0100 0083 FF80 0086 FF00 0098" + $"FF01 0000 83FF 8000 86FF 0000 98FF 0100" + $"0083 FF80 0086 FF00 0098 FF01 0000 83FF" + $"8000 86FF 9B00 83FF 8000 86FF 9B00 83FF" + $"8000 86FF 9B00 83FF 8000 86FF 9B00 83FF" + $"8000 86FF 9B00 83FF 8000 86FF 9B00 83FF" + $"8000 86FF 9B00 83FF 8000 86FF 9B00 83FF" + $"8000 86FF 9B00 83FF 8000 86FF 9B00 83FF" + $"8000 86FF 9B00 83FF AE00 6838 6D6B 0000" + $"0908 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF 6963 7323 0000 0048 F557 D001 700E" + $"E024 9A9B 0175 9299 0162 923E 0001 9004" + $"0000 9BBC 102C 8434 5AFD FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF 6963 7334 0000" + $"0088 AA3F DDDD DDDD DDAE A333 0000 0000" + $"0C3E 333A 0000 000C DBEC A333 0000 0CBC" + $"2A00 EDDF DDDB D2CB ECFF D00D 00CD BBBA" + $"B2D6 D00D 00B2 DDBB DCCB D00D 00D4 D2D2" + $"CC2D D00D 00BD CCE5 3EEC D00D 0C00 0000" + $"CBCB D00D 0000 0000 0D0D D00D 0000 0000" + $"0D00 D00D ABAB ABAF 9F00 D00D 1111 11B8" + $"9900 D00D 1111 1189 9F00 EDDA 8291 ABAF" + $"9FDD 6963 7338 0000 0108 DEDC DBB3 F9FA" + $"F9FA F9FA F9FA F9FA 8FFB DC23 23DB 0000" + $"0000 0000 0000 0032 6A88 DB23 23DC 0000" + $"0000 0000 F52B 3357 882B DC23 23DB 0000" + $"0000 F608 3234 33AD F600 FCFA F9AC F9FA" + $"F95D 0E5D 3457 8833 F1F2 FA00 00F9 0000" + $"0733 825E 33AD 6432 33EF F900 00FA 0000" + $"5D5E 5D33 825D 3332 2C57 FA00 00F9 0000" + $"5739 5D64 5D33 3232 335C F900 00FA 00F5" + $"5D57 F732 828E 8988 88F9 FA00 00F9 00F6" + $"F600 0000 F5F6 4F5D F85D F900 00FA 0000" + $"0000 0000 0000 00FA 0056 FA00 00FA 0000" + $"0000 0000 0000 00F9 0000 F900 00F9 8359" + $"8359 8359 ADD1 E8EA 0000 FA00 00FA 0505" + $"0505 0505 5FE5 E6E8 0000 F900 00F9 0505" + $"0505 0505 7DE6 E6D1 0000 ACF9 FAFC 8359" + $"8359 8359 ADD1 E8E9 FAF9 6973 3332 0000" + $"026C 0340 8080 4087 8005 5E51 80FF FF80" + $"86FF 06AA B457 80FF FF80 83FF 09F1 E1C1" + $"A94E D180 FFFF 8081 FF0B ECE6 DFBE BA4D" + $"D1FF 4080 8040 8080 4FA6 DCAD B3BC 65B4" + $"1900 80FF FF80 FFFF E9CF 87A7 B848 8FC6" + $"B719 80FF FF80 FFFF B58B A0C9 7D8B CFD4" + $"D89E 80FF FF80 FFFF ADAC A280 A5BE DBD4" + $"C79A 80FF FF80 FFF2 8F8E C5B4 7655 516E" + $"7A82 80FF FF80 FFD9 D880 FF09 F7DB C479" + $"B280 80FF FF80 86FF 0680 FF9A 80FF FF80" + $"86FF 0580 FFFF 80FF FF84 8000 4080 0005" + $"FFFF 80FF FF80 83FF 0080 8000 05FF FF80" + $"FFFF 8083 FF00 8080 0005 FFFF 4080 8040" + $"8380 0040 8000 0180 8081 0087 8001 0151" + $"8100 86FF 028B 0129 8100 83FF 05E2 D0B3" + $"943A D181 0081 FF0B D9BA B19E 952F D1FF" + $"4080 8040 8080 4F85 A369 8B98 378E 1900" + $"80FF FF80 FFFF D491 417F 9326 4893 9219" + $"80FF FF80 FFFF 774C 6C96 5E5A 94A0 A986" + $"80FF FF80 FFFF 9D73 7346 6589 ABA3 9280" + $"80FF FF80 FFED 6F7A BAA2 5028 253F 4A6A" + $"80FF FF80 FFD9 D880 FF09 F5D2 B569 9E73" + $"80FF FF80 86FF 0680 FF9A 80FF FF80 86FF" + $"0580 FFFF 80FF FF84 8009 403E 3E1F FFFF" + $"80FF FF80 83FF 0980 7B7B 3EFF FF80 FFFF" + $"8083 FF09 807B 7B3E FFFF 4080 8040 8380" + $"0540 3E3E 1F80 8081 0087 8001 1551 8100" + $"86FF 0290 202D 8100 83FF 05D9 C97F 6039" + $"D181 0081 FF0B CEA2 9759 4927 D1FF 4080" + $"8040 8080 4F6F 8657 474C 2976 5980 80FF" + $"FF80 FFFF C676 343F 4B1D 3977 7ED8 80FF" + $"FF80 FFFF 6540 536B 4C4E 7B85 8D79 80FF" + $"FF80 FFFF 8654 6638 5072 908A 7974 80FF" + $"FF80 FFEA 5D63 BB9E 4A20 1F36 3E65 80FF" + $"FF80 FFD9 D880 FF09 F4D0 B266 9B6F 80FF" + $"FF80 86FF 0680 FF9A 80FF FF80 86FF 0680" + $"FFFF 80FF FF80 8700 05FF FF80 FFFF 8087" + $"0005 FFFF 80FF FF80 8700 05FF FF40 8080" + $"4087 0001 8080 7338 6D6B 0000 0108 FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF 6963" + $"6D23 0000 0038 F24B D007 B028 5557 81B1" + $"124A 8236 1005 8000 1ABD 8030 557D FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF 6963 6D34 0000 0068 A33F" + $"CDCC DCCD CAAE A333 0000 0000 CDEE 333A" + $"0000 CCCB 2E0D EDCE CDCD DB2B DB6F D00D" + $"00C2 BBEA BCD5 D00D 00BD 2D2D CC2D D00D" + $"0CDC CCDB BADC D00D 0000 0000 0DCE D00D" + $"0000 0000 0D0D D00D B1BB 1BF9 FD0D D00D" + $"1111 1199 8D0D ECDB BB1B B1F9 FECE 6963" + $"6D38 0000 00C8 DDDA DADD F8F8 F8F8 F8F8" + $"F8F8 F864 8EAC DB23 23DC 0000 0000 0000" + $"0000 F85C 89FB DC23 23DB 0000 0000 F608" + $"3234 5E82 2AFA FBF8 F8FB F8F8 5633 335D" + $"3488 575D EFF1 F900 00FA 0000 2C63 5E34" + $"FD64 5D2C 33AA FA00 00F9 0000 395E 5D5D" + $"5733 0832 33F9 F900 00FA 00F6 F92C 2B32" + $"5D88 8888 88F8 FA00 00F9 0000 0000 0000" + $"0000 00FA F781 F900 00FA 0000 0000 0000" + $"0000 00F9 00F9 FA00 00F9 3559 5335 5959" + $"E9E7 E7FA 00FA F900 00FA 0505 0505 0505" + $"E8E6 E6F9 00F9 FBF8 F8FB 592F 5959 2F59" + $"E9E7 E7FB F8FB 6974 3332 0000 245A 0000" + $"0000 FF00 FF00 FF00 FB00 95FF 8100 C9FF" + $"818E 81EA 8144 81FF 8500 95FF 8100 C9FF" + $"818E 81EA 8144 81FF 8500 95FF 8100 C9FF" + $"818E 81EA 8144 81FF 8500 95FF 8100 C9FF" + $"818E 81EA 8144 81FF 8500 95FF 8100 C5FF" + $"818F 81EA 81AB 818E 8144 8500 95FF 8100" + $"C5FF 818F 81EA 81AB 818E 8144 8500 95FF" + $"8100 C5FF 818F 81EA 81AB 818E 8144 8500" + $"95FF 8100 C5FF 818F 81EA 81AB 818E 8144" + $"8500 95FF 8100 C1FF 815A 81BE 81AB 818E" + $"8145 8144 8500 95FF 8100 C1FF 815A 81BE" + $"81AB 818E 8145 8144 8500 95FF 8100 C1FF" + $"815A 81BE 81AB 818E 8145 8144 8500 95FF" + $"8100 C1FF 815A 81BE 81AB 818E 8145 8144" + $"8500 95FF 8100 BDFF 8164 81FE 8191 8169" + $"8145 8144 81FF 8500 95FF 8100 BDFF 8164" + $"81FE 8191 8169 8145 8144 81FF 8500 95FF" + $"8100 BDFF 8164 81FE 8191 8169 8145 8144" + $"81FF 8500 95FF 8100 BDFF 8164 81FE 8191" + $"8169 8145 8144 81FF 8500 95FF 8100 A9FF" + $"81E2 81E1 81CB 81B8 81A1 81FE 81B1 8162" + $"8145 8144 85FF 8500 95FF 8100 A9FF 81E2" + $"81E1 81CB 81B8 81A1 81FE 81B1 8162 8145" + $"8144 85FF 8500 95FF 8100 A9FF 81E2 81E1" + $"81CB 81B8 81A1 81FE 81B1 8162 8145 8144" + $"85FF 8500 95FF 8100 A9FF 81E2 81E1 81CB" + $"81B8 81A1 81FE 81B1 8162 8145 8144 85FF" + $"8500 95FF 8100 A1FF 81E2 81E6 81E9 81EF" + $"81B8 819F 81FE 81C1 8162 8145 8144 89FF" + $"8500 95FF 8100 A1FF 81E2 81E6 81E9 81EF" + $"81B8 819F 81FE 81C1 8162 8145 8144 89FF" + $"8500 95FF 8100 A1FF 81E2 81E6 81E9 81EF" + $"81B8 819F 81FE 81C1 8162 8145 8144 89FF" + $"8500 95FF 8100 A1FF 81E2 81E6 81E9 81EF" + $"81B8 819F 81FE 81C1 8162 8145 8144 89FF" + $"8500 95FF 8100 9DFF 81D9 81E4 81E9 81EB" + $"81B8 819F 81FE 81C3 8162 8145 8144 8DFF" + $"8500 95FF 8100 9DFF 81D9 81E4 81E9 81EB" + $"81B8 819F 81FE 81C3 8162 8145 8144 8DFF" + $"8500 95FF 8100 9DFF 81D9 81E4 81E9 81EB" + $"81B8 819F 81FE 81C3 8162 8145 8144 8DFF" + $"8500 95FF 8100 9DFF 81D9 81E4 81E9 81EB" + $"81B8 819F 81FE 81C3 8162 8145 8144 8DFF" + $"BD00 81D7 81E3 81DE 81BA 818F 81A2 81FE" + $"81C6 8162 8145 81D0 8161 CD00 81D7 81E3" + $"81DE 81BA 818F 81A2 81FE 81C6 8162 8145" + $"81D0 8161 CD00 81D7 81E3 81DE 81BA 818F" + $"81A2 81FE 81C6 8162 8145 81D0 8161 CD00" + $"81D7 81E3 81DE 81BA 818F 81A2 81FE 81C6" + $"8162 8145 81D0 8161 9500 95FF 8100 95FF" + $"81DA 81E5 81D4 81B3 8167 819A 81FE 81C8" + $"8162 8145 81A5 81C9 81D3 8161 9100 95FF" + $"8100 95FF 81DA 81E5 81D4 81B3 8167 819A" + $"81FE 81C8 8162 8145 81A5 81C9 81D3 8161" + $"9100 95FF 8100 95FF 81DA 81E5 81D4 81B3" + $"8167 819A 81FE 81C8 8162 8145 81A5 81C9" + $"81D3 8161 9100 95FF 8100 95FF 81DA 81E5" + $"81D4 81B3 8167 819A 81FE 81C8 8162 8145" + $"81A5 81C9 81D3 8161 9100 95FF 8100 91FF" + $"81DC 81E2 81D4 81A4 8169 819E 81F2 81C9" + $"8162 8145 8179 819B 81C2 81D2 81D0 8161" + $"8D00 95FF 8100 91FF 81DC 81E2 81D4 81A4" + $"8169 819E 81F2 81C9 8162 8145 8179 819B" + $"81C2 81D2 81D0 8161 8D00 95FF 8100 91FF" + $"81DC 81E2 81D4 81A4 8169 819E 81F2 81C9" + $"8162 8145 8179 819B 81C2 81D2 81D0 8161" + $"8D00 95FF 8100 91FF 81DC 81E2 81D4 81A4" + $"8169 819E 81F2 81C9 8162 8145 8179 819B" + $"81C2 81D2 81D0 8161 8D00 95FF 8100 8DFF" + $"81E8 81DD 81D2 81B3 816A 81A0 81F3 81C7" + $"815C 811B 815D 8189 819C 81B5 81CD 81D5" + $"81D3 8161 8900 95FF 8100 8DFF 81E8 81DD" + $"81D2 81B3 816A 81A0 81F3 81C7 815C 811B" + $"815D 8189 819C 81B5 81CD 81D5 81D3 8161" + $"8900 95FF 8100 8DFF 81E8 81DD 81D2 81B3" + $"816A 81A0 81F3 81C7 815C 811B 815D 8189" + $"819C 81B5 81CD 81D5 81D3 8161 8900 95FF" + $"8100 8DFF 81E8 81DD 81D2 81B3 816A 81A0" + $"81F3 81C7 815C 811B 815D 8189 819C 81B5" + $"81CD 81D5 81D3 8161 8900 95FF 8100 8DFF" + $"81DF 81C2 819C 8165 817A 81DE 81B3 816A" + $"810D 8120 8182 81AD 81BD 81C3 81D1 81D5" + $"81D7 81D0 8169 8188 8100 95FF 8100 8DFF" + $"81DF 81C2 819C 8165 817A 81DE 81B3 816A" + $"810D 8120 8182 81AD 81BD 81C3 81D1 81D5" + $"81D7 81D0 8169 8188 8100 95FF 8100 8DFF" + $"81DF 81C2 819C 8165 817A 81DE 81B3 816A" + $"810D 8120 8182 81AD 81BD 81C3 81D1 81D5" + $"81D7 81D0 8169 8188 8100 95FF 8100 8DFF" + $"81DF 81C2 819C 8165 817A 81DE 81B3 816A" + $"810D 8120 8182 81AD 81BD 81C3 81D1 81D5" + $"81D7 81D0 8169 8188 8100 95FF 8100 8DFF" + $"81AE 8181 8170 81B9 81C5 81C1 81CE 81C7" + $"81B2 81AF 81DA 81E7 81EA 81E1 81D9 81D8" + $"81D9 81D4 8169 8186 8100 95FF 8100 8DFF" + $"81AE 8181 8170 81B9 81C5 81C1 81CE 81C7" + $"81B2 81AF 81DA 81E7 81EA 81E1 81D9 81D8" + $"81D9 81D4 8169 8186 8100 95FF 8100 8DFF" + $"81AE 8181 8170 81B9 81C5 81C1 81CE 81C7" + $"81B2 81AF 81DA 81E7 81EA 81E1 81D9 81D8" + $"81D9 81D4 8169 8186 8100 95FF 8100 8DFF" + $"81AE 8181 8170 81B9 81C5 81C1 81CE 81C7" + $"81B2 81AF 81DA 81E7 81EA 81E1 81D9 81D8" + $"81D9 81D4 8169 8186 8100 95FF 8100 8DFF" + $"81EE 815C 8175 81EB 81D4 819F 81B3 81C4" + $"81DE 81E7 81EC 81EB 81E3 81E4 81DD 81D6" + $"81CE 81C6 8172 819C 8100 95FF 8100 8DFF" + $"81EE 815C 8175 81EB 81D4 819F 81B3 81C4" + $"81DE 81E7 81EC 81EB 81E3 81E4 81DD 81D6" + $"81CE 81C6 8172 819C 8100 95FF 8100 8DFF" + $"81EE 815C 8175 81EB 81D4 819F 81B3 81C4" + $"81DE 81E7 81EC 81EB 81E3 81E4 81DD 81D6" + $"81CE 81C6 8172 819C 8100 95FF 8100 8DFF" + $"81EE 815C 8175 81EB 81D4 819F 81B3 81C4" + $"81DE 81E7 81EC 81EB 81E3 81E4 81DD 81D6" + $"81CE 81C6 8172 819C 8100 95FF 8100 8DFF" + $"81C6 81A2 81C7 8188 816F 814D 8161 816F" + $"817F 8190 8194 81C1 81DB 81CC 81C1 81C0" + $"81B7 81AB 8182 81A2 8100 95FF 8100 8DFF" + $"81C6 81A2 81C7 8188 816F 814D 8161 816F" + $"817F 8190 8194 81C1 81DB 81CC 81C1 81C0" + $"81B7 81AB 8182 81A2 8100 95FF 8100 8DFF" + $"81C6 81A2 81C7 8188 816F 814D 8161 816F" + $"817F 8190 8194 81C1 81DB 81CC 81C1 81C0" + $"81B7 81AB 8182 81A2 8100 95FF 8100 8DFF" + $"81C6 81A2 81C7 8188 816F 814D 8161 816F" + $"817F 8190 8194 81C1 81DB 81CC 81C1 81C0" + $"81B7 81AB 8182 81A2 8100 95FF 8100 8DFF" + $"8199 81BF 81AE 815C 818A 8185 816D 8150" + $"814E 815A 815B 8155 816C 818F 818B 818C" + $"8195 8188 818F 81A4 8100 95FF 8100 8DFF" + $"8199 81BF 81AE 815C 818A 8185 816D 8150" + $"814E 815A 815B 8155 816C 818F 818B 818C" + $"8195 8188 818F 81A4 8100 95FF 8100 8DFF" + $"8199 81BF 81AE 815C 818A 8185 816D 8150" + $"814E 815A 815B 8155 816C 818F 818B 818C" + $"8195 8188 818F 81A4 8100 95FF 8100 8DFF" + $"8199 81BF 81AE 815C 818A 8185 816D 8150" + $"814E 815A 815B 8155 816C 818F 818B 818C" + $"8195 8188 818F 81A4 8100 95FF 8100 89FF" + $"81CA 8166 817C 818C 819F 85FF 81DC 81B5" + $"8182 8151 814A 8143 813F 814B 8153 815E" + $"8168 8160 818F 81A6 8100 95FF 8100 89FF" + $"81CA 8166 817C 818C 819F 85FF 81DC 81B5" + $"8182 8151 814A 8143 813F 814B 8153 815E" + $"8168 8160 818F 81A6 8100 95FF 8100 89FF" + $"81CA 8166 817C 818C 819F 85FF 81DC 81B5" + $"8182 8151 814A 8143 813F 814B 8153 815E" + $"8168 8160 818F 81A6 8100 95FF 8100 89FF" + $"81CA 8166 817C 818C 819F 85FF 81DC 81B5" + $"8182 8151 814A 8143 813F 814B 8153 815E" + $"8168 8160 818F 81A6 8100 95FF 8100 89FF" + $"8166 819F 81C2 95FF 81DC 81C3 81A8 818D" + $"8184 817B 8168 816D 815A 815E 818F 81AF" + $"8100 95FF 8100 89FF 8166 819F 81C2 95FF" + $"81DC 81C3 81A8 818D 8184 817B 8168 816D" + $"815A 815E 818F 81AF 8100 95FF 8100 89FF" + $"8166 819F 81C2 95FF 81DC 81C3 81A8 818D" + $"8184 817B 8168 816D 815A 815E 818F 81AF" + $"8100 95FF 8100 89FF 8166 819F 81C2 95FF" + $"81DC 81C3 81A8 818D 8184 817B 8168 816D" + $"815A 815E 818F 81AF 8100 95FF 8100 C5FF" + $"8100 85FF 8181 818F 81B5 8100 95FF 8100" + $"C5FF 8100 85FF 8181 818F 81B5 8100 95FF" + $"8100 C5FF 8100 85FF 8181 818F 81B5 8100" + $"95FF 8100 C5FF 8100 85FF 8181 818F 81B5" + $"8100 95FF 8100 C5FF 8100 85FF 8122 8544" + $"8100 95FF 8100 C5FF 8100 85FF 8122 8544" + $"8100 95FF 8100 C5FF 8100 85FF 8122 8544" + $"8100 95FF 8100 C5FF 8100 85FF 8122 8544" + $"8100 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF 8100 ADFF 9900 8DFF 8500 95FF" + $"8100 ADFF 9900 8DFF 8500 95FF 8100 ADFF" + $"9900 8DFF 8500 95FF 8100 ADFF 9900 8DFF" + $"8500 95FF 8100 ADFF 9900 8DFF 8500 95FF" + $"8100 ADFF 9900 8DFF 8500 95FF 8100 ADFF" + $"9900 8DFF 8500 95FF 8100 ADFF 9900 8DFF" + $"8500 95FF 8100 ADFF 9900 8DFF 8500 95FF" + $"8100 ADFF 9900 8DFF 8500 95FF 8100 ADFF" + $"9900 8DFF 8500 95FF 8100 ADFF 9900 8DFF" + $"8500 95FF 8100 ADFF 9900 8DFF 8500 95FF" + $"8100 ADFF 9900 8DFF 8500 95FF 8100 ADFF" + $"9900 8DFF 8500 95FF 8100 ADFF 9900 8DFF" + $"8500 95FF 8100 ADFF 9900 8DFF 8500 95FF" + $"8100 ADFF 9900 8DFF 8500 95FF 8100 ADFF" + $"9900 8DFF 8500 95FF 8100 ADFF 9900 8DFF" + $"8500 95FF 8100 ADFF 9900 8DFF 8500 95FF" + $"8100 ADFF 9900 8DFF 8500 95FF 8100 ADFF" + $"9900 8DFF 8500 95FF 8100 ADFF 9900 8DFF" + $"FF00 FF00 FF00 FB00 FF00 FF00 FF00 FF00" + $"9500 C9FF 8101 8100 8144 81FF A100 C9FF" + $"8101 8100 8144 81FF A100 C9FF 8101 8100" + $"8144 81FF A100 C9FF 8101 8100 8144 81FF" + $"A100 C5FF 8109 8500 8101 8144 A100 C5FF" + $"8109 8500 8101 8144 A100 C5FF 8109 8500" + $"8101 8144 A100 C5FF 8109 8500 8101 8144" + $"A100 C1FF 8167 81BC 8100 8101 8119 8144" + $"A100 C1FF 8167 81BC 8100 8101 8119 8144" + $"A100 C1FF 8167 81BC 8100 8101 8119 8144" + $"A100 C1FF 8167 81BC 8100 8101 8119 8144" + $"A100 BDFF 8166 81E4 819D 8171 8119 8144" + $"81FF A100 BDFF 8166 81E4 819D 8171 8119" + $"8144 81FF A100 BDFF 8166 81E4 819D 8171" + $"8119 8144 81FF A100 BDFF 8166 81E4 819D" + $"8171 8119 8144 81FF A100 A9FF 81C9 81BE" + $"81A7 819B 8182 81E4 8189 8144 8119 8144" + $"85FF A100 A9FF 81C9 81BE 81A7 819B 8182" + $"81E4 8189 8144 8119 8144 85FF A100 A9FF" + $"81C9 81BE 81A7 819B 8182 81E4 8189 8144" + $"8119 8144 85FF A100 A9FF 81C9 81BE 81A7" + $"819B 8182 81E4 8189 8144 8119 8144 85FF" + $"A100 A1FF 81CF 81B6 81B9 81BB 819B 8179" + $"81E4 8193 8144 8119 8144 89FF A100 A1FF" + $"81CF 81B6 81B9 81BB 819B 8179 81E4 8193" + $"8144 8119 8144 89FF A100 A1FF 81CF 81B6" + $"81B9 81BB 819B 8179 81E4 8193 8144 8119" + $"8144 89FF A100 A1FF 81CF 81B6 81B9 81BB" + $"819B 8179 81E4 8193 8144 8119 8144 89FF" + $"A100 9DFF 81B2 81AC 81B6 81B5 819B 817D" + $"81E4 8197 8144 8119 8144 8DFF A100 9DFF" + $"81B2 81AC 81B6 81B5 819B 817D 81E4 8197" + $"8144 8119 8144 8DFF A100 9DFF 81B2 81AC" + $"81B6 81B5 819B 817D 81E4 8197 8144 8119" + $"8144 8DFF A100 9DFF 81B2 81AC 81B6 81B5" + $"819B 817D 81E4 8197 8144 8119 8144 8DFF" + $"BD00 85AF 81A0 816E 8151 8180 81E4 819A" + $"8144 8119 819B 8162 CD00 85AF 81A0 816E" + $"8151 8180 81E4 819A 8144 8119 819B 8162" + $"CD00 85AF 81A0 816E 8151 8180 81E4 819A" + $"8144 8119 819B 8162 CD00 85AF 81A0 816E" + $"8151 8180 81E4 819A 8144 8119 819B 8162" + $"9500 95FF 8100 95FF 81B2 81B3 8197 8168" + $"812E 8176 81E4 819D 8144 8119 8163 8196" + $"81A1 8162 9100 95FF 8100 95FF 81B2 81B3" + $"8197 8168 812E 8176 81E4 819D 8144 8119" + $"8163 8196 81A1 8162 9100 95FF 8100 95FF" + $"81B2 81B3 8197 8168 812E 8176 81E4 819D" + $"8144 8119 8163 8196 81A1 8162 9100 95FF" + $"8100 95FF 81B2 81B3 8197 8168 812E 8176" + $"81E4 819D 8144 8119 8163 8196 81A1 8162" + $"9100 95FF 8100 91FF 81BE 81B0 8199 8153" + $"8130 817E 81CF 819C 8146 8119 8134 8159" + $"818B 81A6 819C 8162 8D00 95FF 8100 91FF" + $"81BE 81B0 8199 8153 8130 817E 81CF 819C" + $"8146 8119 8134 8159 818B 81A6 819C 8162" + $"8D00 95FF 8100 91FF 81BE 81B0 8199 8153" + $"8130 817E 81CF 819C 8146 8119 8134 8159" + $"818B 81A6 819C 8162 8D00 95FF 8100 91FF" + $"81BE 81B0 8199 8153 8130 817E 81CF 819C" + $"8146 8119 8134 8159 818B 81A6 819C 8162" + $"8D00 95FF 8100 8DFF 81E0 81B1 8191 8167" + $"812E 817E 81D0 819A 8144 810E 812A 813C" + $"8155 817B 81A0 81A8 81A2 8162 8900 95FF" + $"8100 8DFF 81E0 81B1 8191 8167 812E 817E" + $"81D0 819A 8144 810E 812A 813C 8155 817B" + $"81A0 81A8 81A2 8162 8900 95FF 8100 8DFF" + $"81E0 81B1 8191 8167 812E 817E 81D0 819A" + $"8144 810E 812A 813C 8155 817B 81A0 81A8" + $"81A2 8162 8900 95FF 8100 8DFF 81E0 81B1" + $"8191 8167 812E 817E 81D0 819A 8144 810E" + $"812A 813C 8155 817B 81A0 81A8 81A2 8162" + $"8900 95FF 8100 8DFF 81C5 8176 814B 812D" + $"8151 81B5 8186 814F 8104 810E 8134 8161" + $"8181 818A 819F 81A8 81A7 81A1 8168 817C" + $"8100 95FF 8100 8DFF 81C5 8176 814B 812D" + $"8151 81B5 8186 814F 8104 810E 8134 8161" + $"8181 818A 819F 81A8 81A7 81A1 8168 817C" + $"8100 95FF 8100 8DFF 81C5 8176 814B 812D" + $"8151 81B5 8186 814F 8104 810E 8134 8161" + $"8181 818A 819F 81A8 81A7 81A1 8168 817C" + $"8100 95FF 8100 8DFF 81C5 8176 814B 812D" + $"8151 81B5 8186 814F 8104 810E 8134 8161" + $"8181 818A 819F 81A8 81A7 81A1 8168 817C" + $"8100 95FF 8100 8DFF 8172 812D 813A 817D" + $"8186 8183 8199 8198 818C 8185 81A0 81B3" + $"81B9 81AE 81A9 85AA 81A5 8168 817E 8100" + $"95FF 8100 8DFF 8172 812D 813A 817D 8186" + $"8183 8199 8198 818C 8185 81A0 81B3 81B9" + $"81AE 81A9 85AA 81A5 8168 817E 8100 95FF" + $"8100 8DFF 8172 812D 813A 817D 8186 8183" + $"8199 8198 818C 8185 81A0 81B3 81B9 81AE" + $"81A9 85AA 81A5 8168 817E 8100 95FF 8100" + $"8DFF 8172 812D 813A 817D 8186 8183 8199" + $"8198 818C 8185 81A0 81B3 81B9 81AE 81A9" + $"85AA 81A5 8168 817E 8100 95FF 8100 8DFF" + $"81E8 8144 8138 81B3 81A9 8162 816F 817D" + $"819D 81B2 81BE 81BC 81B5 81B7 81AF 81A5" + $"819B 8195 8173 8192 8100 95FF 8100 8DFF" + $"81E8 8144 8138 81B3 81A9 8162 816F 817D" + $"819D 81B2 81BE 81BC 81B5 81B7 81AF 81A5" + $"819B 8195 8173 8192 8100 95FF 8100 8DFF" + $"81E8 8144 8138 81B3 81A9 8162 816F 817D" + $"819D 81B2 81BE 81BC 81B5 81B7 81AF 81A5" + $"819B 8195 8173 8192 8100 95FF 8100 8DFF" + $"81E8 8144 8138 81B3 81A9 8162 816F 817D" + $"819D 81B2 81BE 81BC 81B5 81B7 81AF 81A5" + $"819B 8195 8173 8192 8100 95FF 8100 8DFF" + $"81C2 8183 819A 8144 813D 811E 8129 8134" + $"8144 8155 815C 818E 81AC 819A 818B 8189" + $"817D 8175 8182 819A 8100 95FF 8100 8DFF" + $"81C2 8183 819A 8144 813D 811E 8129 8134" + $"8144 8155 815C 818E 81AC 819A 818B 8189" + $"817D 8175 8182 819A 8100 95FF 8100 8DFF" + $"81C2 8183 819A 8144 813D 811E 8129 8134" + $"8144 8155 815C 818E 81AC 819A 818B 8189" + $"817D 8175 8182 819A 8100 95FF 8100 8DFF" + $"81C2 8183 819A 8144 813D 811E 8129 8134" + $"8144 8155 815C 818E 81AC 819A 818B 8189" + $"817D 8175 8182 819A 8100 95FF 8100 8DFF" + $"816E 818B 8180 8144 8174 816B 8145 8522" + $"812F 8130 812E 8142 815C 8155 8158 8160" + $"8155 818E 819E 8100 95FF 8100 8DFF 816E" + $"818B 8180 8144 8174 816B 8145 8522 812F" + $"8130 812E 8142 815C 8155 8158 8160 8155" + $"818E 819E 8100 95FF 8100 8DFF 816E 818B" + $"8180 8144 8174 816B 8145 8522 812F 8130" + $"812E 8142 815C 8155 8158 8160 8155 818E" + $"819E 8100 95FF 8100 8DFF 816E 818B 8180" + $"8144 8174 816B 8145 8522 812F 8130 812E" + $"8142 815C 8155 8158 8160 8155 818E 819E" + $"8100 95FF 8100 89FF 81B4 8166 815A 8181" + $"819F 85FF 81D6 819F 815B 8123 811B 8113" + $"8110 8120 812B 8133 813C 8137 818E 81A0" + $"8100 95FF 8100 89FF 81B4 8166 815A 8181" + $"819F 85FF 81D6 819F 815B 8123 811B 8113" + $"8110 8120 812B 8133 813C 8137 818E 81A0" + $"8100 95FF 8100 89FF 81B4 8166 815A 8181" + $"819F 85FF 81D6 819F 815B 8123 811B 8113" + $"8110 8120 812B 8133 813C 8137 818E 81A0" + $"8100 95FF 8100 89FF 81B4 8166 815A 8181" + $"819F 85FF 81D6 819F 815B 8123 811B 8113" + $"8110 8120 812B 8133 813C 8137 818E 81A0" + $"8100 95FF 8100 89FF 8166 819F 81C2 95FF" + $"81D6 81B6 8192 816F 8166 815B 8147 8149" + $"8131 813B 818E 81A6 8100 95FF 8100 89FF" + $"8166 819F 81C2 95FF 81D6 81B6 8192 816F" + $"8166 815B 8147 8149 8131 813B 818E 81A6" + $"8100 95FF 8100 89FF 8166 819F 81C2 95FF" + $"81D6 81B6 8192 816F 8166 815B 8147 8149" + $"8131 813B 818E 81A6 8100 95FF 8100 89FF" + $"8166 819F 81C2 95FF 81D6 81B6 8192 816F" + $"8166 815B 8147 8149 8131 813B 818E 81A6" + $"8100 95FF 8100 C5FF 8100 85FF 8172 818E" + $"81AB 8100 95FF 8100 C5FF 8100 85FF 8172" + $"818E 81AB 8100 95FF 8100 C5FF 8100 85FF" + $"8172 818E 81AB 8100 95FF 8100 C5FF 8100" + $"85FF 8172 818E 81AB 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF 8500 95FF 8100 ADFF" + $"8100 917B 8100 8DFF FF00 FF00 FF00 FB00" + $"FF00 FF00 FF00 FF00 9500 C9FF 810F 8143" + $"8144 81FF A100 C9FF 810F 8143 8144 81FF" + $"A100 C9FF 810F 8143 8144 81FF A100 C9FF" + $"810F 8143 8144 81FF A100 C5FF 8117 8143" + $"8116 810F 8144 A100 C5FF 8117 8143 8116" + $"810F 8144 A100 C5FF 8117 8143 8116 810F" + $"8144 A100 C5FF 8117 8143 8116 810F 8144" + $"A100 C1FF 8165 81C4 8116 810F 811A 8144" + $"A100 C1FF 8165 81C4 8116 810F 811A 8144" + $"A100 C1FF 8165 81C4 8116 810F 811A 8144" + $"A100 C1FF 8165 81C4 8116 810F 811A 8144" + $"A100 BDFF 8155 8167 81A7 816C 811A 8144" + $"81FF A100 BDFF 8155 8167 81A7 816C 811A" + $"8144 81FF A100 BDFF 8155 8167 81A7 816C" + $"811A 8144 81FF A100 BDFF 8155 8167 81A7" + $"816C 811A 8144 81FF A100 A9FF 81BC 81A9" + $"8192 8193 813E 8167 814D 8123 811A 8144" + $"85FF A100 A9FF 81BC 81A9 8192 8193 813E" + $"8167 814D 8123 811A 8144 85FF A100 A9FF" + $"81BC 81A9 8192 8193 813E 8167 814D 8123" + $"811A 8144 85FF A100 A9FF 81BC 81A9 8192" + $"8193 813E 8167 814D 8123 811A 8144 85FF" + $"A100 A1FF 81C6 819A 8598 8193 8131 8167" + $"814A 8123 811A 8144 89FF A100 A1FF 81C6" + $"819A 8598 8193 8131 8167 814A 8123 811A" + $"8144 89FF A100 A1FF 81C6 819A 8598 8193" + $"8131 8167 814A 8123 811A 8144 89FF A100" + $"A1FF 81C6 819A 8598 8193 8131 8167 814A" + $"8123 811A 8144 89FF A100 9DFF 819C 818E" + $"8199 8195 8193 8137 8167 814F 8123 811A" + $"8144 8DFF A100 9DFF 819C 818E 8199 8195" + $"8193 8137 8167 814F 8123 811A 8144 8DFF" + $"A100 9DFF 819C 818E 8199 8195 8193 8137" + $"8167 814F 8123 811A 8144 8DFF A100 9DFF" + $"819C 818E 8199 8195 8193 8137 8167 814F" + $"8123 811A 8144 8DFF BD00 8192 818F 8186" + $"8157 8147 8139 8167 8152 8123 811A 817A" + $"8161 CD00 8192 818F 8186 8157 8147 8139" + $"8167 8152 8123 811A 817A 8161 CD00 8192" + $"818F 8186 8157 8147 8139 8167 8152 8123" + $"811A 817A 8161 CD00 8192 818F 8186 8157" + $"8147 8139 8167 8152 8123 811A 817A 8161" + $"9500 95FF 8100 95FF 8195 8191 817C 8151" + $"812A 8132 8167 8153 8123 811A 814B 8178" + $"8183 8161 89FF 8500 95FF 8100 95FF 8195" + $"8191 817C 8151 812A 8132 8167 8153 8123" + $"811A 814B 8178 8183 8161 89FF 8500 95FF" + $"8100 95FF 8195 8191 817C 8151 812A 8132" + $"8167 8153 8123 811A 814B 8178 8183 8161" + $"89FF 8500 95FF 8100 95FF 8195 8191 817C" + $"8151 812A 8132 8167 8153 8123 811A 814B" + $"8178 8183 8161 89FF 8500 95FF 8100 91FF" + $"81A9 818B 817D 8141 812C 8137 8163 8153" + $"8124 811A 812C 8144 816D 818A 8180 8161" + $"85FF 8500 95FF 8100 91FF 81A9 818B 817D" + $"8141 812C 8137 8163 8153 8124 811A 812C" + $"8144 816D 818A 8180 8161 85FF 8500 95FF" + $"8100 91FF 81A9 818B 817D 8141 812C 8137" + $"8163 8153 8124 811A 812C 8144 816D 818A" + $"8180 8161 85FF 8500 95FF 8100 91FF 81A9" + $"818B 817D 8141 812C 8137 8163 8153 8124" + $"811A 812C 8144 816D 818A 8180 8161 85FF" + $"8500 95FF 8100 8DFF 81DA 8192 8178 8154" + $"8127 8137 8161 8151 8122 8111 8124 8132" + $"813F 8160 8184 818D 8186 8161 81FF 8500" + $"95FF 8100 8DFF 81DA 8192 8178 8154 8127" + $"8137 8161 8151 8122 8111 8124 8132 813F" + $"8160 8184 818D 8186 8161 81FF 8500 95FF" + $"8100 8DFF 81DA 8192 8178 8154 8127 8137" + $"8161 8151 8122 8111 8124 8132 813F 8160" + $"8184 818D 8186 8161 81FF 8500 95FF 8100" + $"8DFF 81DA 8192 8178 8154 8127 8137 8161" + $"8151 8122 8111 8124 8132 813F 8160 8184" + $"818D 8186 8161 81FF 8500 95FF 8100 8DFF" + $"81B7 815B 813C 8127 8130 8159 8156 812A" + $"810A 810C 812C 814F 8165 816C 8185 818D" + $"8189 8188 8169 8188 8100 95FF 8100 8DFF" + $"81B7 815B 813C 8127 8130 8159 8156 812A" + $"810A 810C 812C 814F 8165 816C 8185 818D" + $"8189 8188 8169 8188 8100 95FF 8100 8DFF" + $"81B7 815B 813C 8127 8130 8159 8156 812A" + $"810A 810C 812C 814F 8165 816C 8185 818D" + $"8189 8188 8169 8188 8100 95FF 8100 8DFF" + $"81B7 815B 813C 8127 8130 8159 8156 812A" + $"810A 810C 812C 814F 8165 816C 8185 818D" + $"8189 8188 8169 8188 8100 95FF 8100 8DFF" + $"8161 8120 812F 816A 8576 8583 8178 8174" + $"818C 819A 819D 8191 858E 818C 8188 8169" + $"8155 8100 95FF 8100 8DFF 8161 8120 812F" + $"816A 8576 8583 8178 8174 818C 819A 819D" + $"8191 858E 818C 8188 8169 8155 8100 95FF" + $"8100 8DFF 8161 8120 812F 816A 8576 8583" + $"8178 8174 818C 819A 819D 8191 858E 818C" + $"8188 8169 8155 8100 95FF 8100 8DFF 8161" + $"8120 812F 816A 8576 8583 8178 8174 818C" + $"819A 819D 8191 858E 818C 8188 8169 8155" + $"8100 95FF 8100 8DFF 81E7 8122 8130 8196" + $"8194 8153 8154 815F 8180 8195 81A2 819E" + $"819A 819D 8194 8188 8181 817A 8173 8144" + $"8100 95FF 8100 8DFF 81E7 8122 8130 8196" + $"8194 8153 8154 815F 8180 8195 81A2 819E" + $"819A 819D 8194 8188 8181 817A 8173 8144" + $"8100 95FF 8100 8DFF 81E7 8122 8130 8196" + $"8194 8153 8154 815F 8180 8195 81A2 819E" + $"819A 819D 8194 8188 8181 817A 8173 8144" + $"8100 95FF 8100 8DFF 81E7 8122 8130 8196" + $"8194 8153 8154 815F 8180 8195 81A2 819E" + $"819A 819D 8194 8188 8181 817A 8173 8144" + $"8100 95FF 8100 8DFF 81C6 8146 8151 8135" + $"8138 8119 811F 812A 8136 8144 814A 8175" + $"8191 8181 8173 8172 8168 8160 8181 81FF" + $"8100 95FF 8100 8DFF 81C6 8146 8151 8135" + $"8138 8119 811F 812A 8136 8144 814A 8175" + $"8191 8181 8173 8172 8168 8160 8181 81FF" + $"8100 95FF 8100 8DFF 81C6 8146 8151 8135" + $"8138 8119 811F 812A 8136 8144 814A 8175" + $"8191 8181 8173 8172 8168 8160 8181 81FF" + $"8100 95FF 8100 8DFF 81C6 8146 8151 8135" + $"8138 8119 811F 812A 8136 8144 814A 8175" + $"8191 8181 8173 8172 8168 8160 8181 81FF" + $"8100 95FF 8100 8DFF 8159 816A 8149 8122" + $"8177 8168 813C 811A 811D 8928 8138 814D" + $"8147 8148 814F 8147 818E 81FF 8100 95FF" + $"8100 8DFF 8159 816A 8149 8122 8177 8168" + $"813C 811A 811D 8928 8138 814D 8147 8148" + $"814F 8147 818E 81FF 8100 95FF 8100 8DFF" + $"8159 816A 8149 8122 8177 8168 813C 811A" + $"811D 8928 8138 814D 8147 8148 814F 8147" + $"818E 81FF 8100 95FF 8100 8DFF 8159 816A" + $"8149 8122 8177 8168 813C 811A 811D 8928" + $"8138 814D 8147 8148 814F 8147 818E 81FF" + $"8100 95FF 8100 89FF 81A8 8165 814A 817F" + $"819F 85FF 81D3 819A 8155 811C 8114 810E" + $"810B 811B 8126 812B 8133 8130 818E 819A" + $"8100 95FF 8100 89FF 81A8 8165 814A 817F" + $"819F 85FF 81D3 819A 8155 811C 8114 810E" + $"810B 811B 8126 812B 8133 8130 818E 819A" + $"8100 95FF 8100 89FF 81A8 8165 814A 817F" + $"819F 85FF 81D3 819A 8155 811C 8114 810E" + $"810B 811B 8126 812B 8133 8130 818E 819A" + $"8100 95FF 8100 89FF 81A8 8165 814A 817F" + $"819F 85FF 81D3 819A 8155 811C 8114 810E" + $"810B 811B 8126 812B 8133 8130 818E 819A" + $"8100 95FF 8100 89FF 8165 819F 81C2 95FF" + $"81D3 81B2 818E 8169 815F 8156 8142 8143" + $"812B 8135 818E 819F 8100 95FF 8100 89FF" + $"8165 819F 81C2 95FF 81D3 81B2 818E 8169" + $"815F 8156 8142 8143 812B 8135 818E 819F" + $"8100 95FF 8100 89FF 8165 819F 81C2 95FF" + $"81D3 81B2 818E 8169 815F 8156 8142 8143" + $"812B 8135 818E 819F 8100 95FF 8100 89FF" + $"8165 819F 81C2 95FF 81D3 81B2 818E 8169" + $"815F 8156 8142 8143 812B 8135 818E 819F" + $"8100 95FF 8100 C5FF 8100 85FF 816B 818E" + $"81A7 8100 95FF 8100 C5FF 8100 85FF 816B" + $"818E 81A7 8100 95FF 8100 C5FF 8100 85FF" + $"816B 818E 81A7 8100 95FF 8100 C5FF 8100" + $"85FF 816B 818E 81A7 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 85FF 8122 8544 8100 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF 8100 C5FF" + $"8100 8DFF 8500 95FF 8100 C5FF 8100 8DFF" + $"8500 95FF 8100 C5FF 8100 8DFF 8500 95FF" + $"8100 C5FF 8100 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF 8500 95FF CD00 8DFF" + $"8500 95FF CD00 8DFF FF00 FF00 FF00 FB00" + $"7438 6D6B 0000 4008 FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF" +}; + +data 'ics#' (-16455, "Item Icon") { + $"F557 D001 700E E024 9A9B 0175 9299 0162" + $"923E 0001 9004 0000 9BBC 102C 8434 5AFD" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" +}; + +data 'ics4' (-16455, "Item Icon") { + $"AA3F DDDD DDDD DDAE A333 0000 0000 0C3E" + $"333A 0000 000C DBEC A333 0000 0CBC 2A00" + $"EDDF DDDB D2CB ECFF D00D 00CD BBBA B2D6" + $"D00D 00B2 DDBB DCCB D00D 00D4 D2D2 CC2D" + $"D00D 00BD CCE5 3EEC D00D 0C00 0000 CBCB" + $"D00D 0000 0000 0D0D D00D 0000 0000 0D00" + $"D00D ABAB ABAF 9F00 D00D 1111 11B8 9900" + $"D00D 1111 1189 9F00 EDDA 8291 ABAF 9FDD" +}; + +data 'ics8' (-16455, "Item Icon") { + $"DEDC DBB3 F9FA F9FA F9FA F9FA F9FA 8FFB" + $"DC23 23DB 0000 0000 0000 0000 0032 6A88" + $"DB23 23DC 0000 0000 0000 F52B 3357 882B" + $"DC23 23DB 0000 0000 F608 3234 33AD F600" + $"FCFA F9AC F9FA F95D 0E5D 3457 8833 F1F2" + $"FA00 00F9 0000 0733 825E 33AD 6432 33EF" + $"F900 00FA 0000 5D5E 5D33 825D 3332 2C57" + $"FA00 00F9 0000 5739 5D64 5D33 3232 335C" + $"F900 00FA 00F5 5D57 F732 828E 8988 88F9" + $"FA00 00F9 00F6 F600 0000 F5F6 4F5D F85D" + $"F900 00FA 0000 0000 0000 0000 00FA 0056" + $"FA00 00FA 0000 0000 0000 0000 00F9 0000" + $"F900 00F9 8359 8359 8359 ADD1 E8EA 0000" + $"FA00 00FA 0505 0505 0505 5FE5 E6E8 0000" + $"F900 00F9 0505 0505 0505 7DE6 E6D1 0000" + $"ACF9 FAFC 8359 8359 8359 ADD1 E8E9 FAF9" +}; + diff --git a/rbutil/rbutilApp.cpp b/rbutil/rbutilApp.cpp index 215e9ebc8e..c30e5b4aaa 100644 --- a/rbutil/rbutilApp.cpp +++ b/rbutil/rbutilApp.cpp @@ -19,6 +19,7 @@ ****************************************************************************/ #include "rbutilApp.h" +#include "bootloaders.h" GlobalVars* gv = new GlobalVars(); @@ -30,15 +31,16 @@ bool rbutilFrmApp::OnInit() wxLogVerbose(wxT("=== begin rbutilFrmApp::Oninit()")); + gv->stdpaths = new wxStandardPaths(); // Get application directory // DANGER! GetDataDir() doesn't portably return the application directory // We want to use the form below instead, but not until wxWidgets 2.8 is - // released. + // released. *Datadir gives the wrong dir for this on Linux/Mac even on Wx2.8 * gv->AppDir = gv->stdpaths->GetExecutablePath().BeforeLast(PATH_SEP_CHR); -// buf = gv->stdpaths->GetDataDir(); buf.Append(PATH_SEP); -// gv->AppDir = buf.BeforeLast(PATH_SEP_CHR).c_str(); + // buf = gv->stdpaths->GetDataDir(); buf.Append(PATH_SEP); + // gv->AppDir = buf.BeforeLast(PATH_SEP_CHR).c_str(); buf = gv->stdpaths->GetUserDataDir(); if (! wxDirExists(buf) ) @@ -80,6 +82,7 @@ bool rbutilFrmApp::OnInit() SetTopWindow(myFrame); myFrame->Show(TRUE); + initIpodpatcher(); // reserve mem for ipodpatcher wxLogVerbose(wxT("=== end rbUtilFrmApp::OnInit()")); return TRUE; } @@ -92,7 +95,7 @@ int rbutilFrmApp::OnExit() gv->logfile->Close(); /* Enabling this code causes the program to crash. I - * have no idea why. + * have no idea why. (possibly because deleting non existing objects ? :-) ) wxLog::DontCreateOnDemand(); // Free a bunch of structures. delete gv->GlobalConfig; @@ -120,15 +123,15 @@ bool rbutilFrmApp::ReadGlobalConfig(rbutilFrm* myFrame) // are of course the same directory. buf.Printf(wxT("%s" PATH_SEP "rbutil.ini"), gv->AppDir.c_str() ); - if (! wxFileExists(buf) ) - { - gv->ResourceDir = gv->stdpaths->GetResourcesDir(); - buf.Printf(wxT("%s" PATH_SEP "rbutil.ini"), - gv->ResourceDir.c_str() ); - } else - { - gv->ResourceDir = gv->AppDir; - } +// if (! wxFileExists(buf) ) +// { +// gv->ResourceDir = gv->stdpaths->GetResourcesDir(); +// buf.Printf(wxT("%s" PATH_SEP "rbutil.ini"), +// gv->ResourceDir.c_str() ); +// } else +// { +// gv->ResourceDir = gv->AppDir; +// } wxFileInputStream* cfgis = new wxFileInputStream(buf); @@ -146,13 +149,33 @@ bool rbutilFrmApp::ReadGlobalConfig(rbutilFrm* myFrame) gv->GlobalConfig->SetPath(wxT("/platforms")); while(gv->GlobalConfig->Read(buf.Format(wxT("platform%d"), i + 1), &tmpstr)) { - gv->plat_id.Add(tmpstr); + wxString cur = tmpstr; + //gv->plat_id.Add(tmpstr); gv->GlobalConfig->Read(buf.Format(wxT("/%s/name"), - gv->plat_id[i].c_str()), &tmpstr); + cur.c_str()), &tmpstr); gv->plat_name.Add(tmpstr); + gv->GlobalConfig->Read(buf.Format(wxT("/%s/platform"), + cur.c_str()), &tmpstr); + gv->plat_id.Add(tmpstr); gv->GlobalConfig->Read(buf.Format(wxT("/%s/released"), - gv->plat_id[i].c_str()), &tmpstr); + cur.c_str()), &tmpstr); gv->plat_released.Add( (tmpstr == wxT("yes")) ? true : false ) ; + gv->GlobalConfig->Read(buf.Format(wxT("/%s/needsbootloader"), + cur.c_str()), &tmpstr); + gv->plat_needsbootloader.Add( (tmpstr == wxT("yes")) ? true : false ) ; + gv->GlobalConfig->Read(buf.Format(wxT("/%s/bootloadermethod"), + cur.c_str()), &tmpstr); + gv->plat_bootloadermethod.Add(tmpstr); + gv->GlobalConfig->Read(buf.Format(wxT("/%s/bootloadername"), + cur.c_str()), &tmpstr); + gv->plat_bootloadername.Add(tmpstr); + gv->GlobalConfig->Read(buf.Format(wxT("/%s/autodetect"), + cur.c_str()), &tmpstr); + gv->plat_autodetect.Add( (tmpstr == wxT("yes")) ? true : false ) ; + gv->GlobalConfig->Read(buf.Format(wxT("/%s/combinedname"), + cur.c_str()), &tmpstr); + gv->plat_combinedname.Add(tmpstr); + i++; } @@ -184,6 +207,9 @@ bool rbutilFrmApp::ReadGlobalConfig(rbutilFrm* myFrame) gv->GlobalConfig->Read(wxT("prog_name"), &tmpstr); gv->prog_name = tmpstr; + gv->GlobalConfig->Read(wxT("bootloader_url"), &tmpstr); + gv->bootloader_url = tmpstr; + #ifdef __WXMSW__ gv->curdestdir = wxT("D:\\"); #else diff --git a/rbutil/rbutilFrm.cpp b/rbutil/rbutilFrm.cpp index 0d56e9c5b1..738da27f2a 100644 --- a/rbutil/rbutilFrm.cpp +++ b/rbutil/rbutilFrm.cpp @@ -28,6 +28,8 @@ #include "tools2_3d.xpm" #include "rblogo.xpm" +#include "bootloaders.h" + #include "wizard.xpm" //---------------------------------------------------------------------------- @@ -39,6 +41,7 @@ BEGIN_EVENT_TABLE(rbutilFrm,wxFrame) EVT_BUTTON (ID_REMOVE_BTN, rbutilFrm::OnRemoveBtn) EVT_BUTTON (ID_FONT_BTN, rbutilFrm::OnFontBtn) EVT_BUTTON (ID_BOOTLOADER_BTN, rbutilFrm::OnBootloaderBtn) + EVT_BUTTON (ID_BOOTLOADERREMOVE_BTN, rbutilFrm::OnBootloaderRemoveBtn) EVT_CLOSE(rbutilFrm::rbutilFrmClose) EVT_MENU(ID_FILE_EXIT, rbutilFrm::OnFileExit) @@ -116,8 +119,7 @@ void rbutilFrm::CreateGUIControls(void) wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); WxStaticText2 = new wxStaticText(WxPanel1, ID_WXSTATICTEXT2, - _("Install Rockbox on your audio player"), wxPoint(70,16), - wxSize(175,17), 0, wxT("WxStaticText2")); + _("Install Rockbox on your audio player")); WxFlexGridSizer1->Add(WxStaticText2,0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL,5); @@ -149,11 +151,24 @@ void rbutilFrm::CreateGUIControls(void) wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); WxStaticText3 = new wxStaticText(WxPanel1, ID_WXSTATICTEXT3, - _("Remove Rockbox from your audio player"), wxPoint(60,66), - wxSize(196,17), 0, wxT("WxStaticText3")); + _("Remove Rockbox from your audio player")); WxFlexGridSizer1->Add(WxStaticText3,0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL,5); + wxBitmap WxBitmapButton4_BITMAP (uninstall_3d_xpm); + WxBitmapButton4 = new wxBitmapButton(WxPanel1, ID_BOOTLOADERREMOVE_BTN, + WxBitmapButton4_BITMAP, wxPoint(0,0), wxSize(64,54), + wxRAISED_BORDER | wxBU_AUTODRAW, wxDefaultValidator, + wxT("WxBitmapButton4")); + WxBitmapButton4->SetToolTip(_("Uninstall Bootloader")); + WxFlexGridSizer1->Add(WxBitmapButton4,0, + wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); + + WxStaticText4 = new wxStaticText(WxPanel1, ID_WXSTATICTEXT4, + _("Remove Rockbox Bootloader from your audio player")); + WxFlexGridSizer1->Add(WxStaticText4,0, + wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL,5); + WxMenuBar1 = new wxMenuBar(); wxMenu *ID_FILE_MENU_Mnu_Obj = new wxMenu(0); WxMenuBar1->Append(ID_FILE_MENU_Mnu_Obj, _("&File")); @@ -251,7 +266,10 @@ void rbutilFrm::OnFileWipeCache(wxCommandEvent& event) if (! rm_rf(cacheloc) ) { - MESG_DIALOG(_("Local download cache has been deleted.")); + wxMessageDialog* msg = new wxMessageDialog(this, _("Local download cache has been deleted.") + ,"Cache deletion", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; } else { MESG_DIALOG(_("Errors occured deleting the local download cache.")); @@ -260,16 +278,207 @@ void rbutilFrm::OnFileWipeCache(wxCommandEvent& event) wxMkdir(cacheloc, 0777); } +void rbutilFrm::OnBootloaderRemoveBtn(wxCommandEvent& event) +{ + wxLogVerbose("=== begin rbutilFrm::OnBootloaderRemoveBtn(event)"); + + wxWizard *wizard = new wxWizard(this, wxID_ANY, + _("Rockbox Bootloader Uninstallation Wizard"), + wxBitmap(wizard_xpm), + wxDefaultPosition, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wxBootPlatformPage* page1 = new wxBootPlatformPage(wizard); + wxBootLocationPage* page2 = new wxBootLocationPage(wizard); // Only one of these pages are shown + wxIpodLocationPage* page3 = new wxIpodLocationPage(wizard); // depending on Device selected + + page1->SetNext(page2); + page2->SetPrev(page1); + page2->SetNext(page3); + page3->SetPrev(page2); + + wizard->GetPageAreaSizer()->Add(page1); + + + if (wizard->RunWizard(page1) ) + { + // uninstall the bootloader + if(gv->curbootloadermethod == "ipodpatcher") + { + + if(ipodpatcher(BOOTLOADER_REM)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been uninstalled.") + ,"Uninstallation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + { + MESG_DIALOG(_("The Uninstallation has failed.") ); + } + } + else if(gv->curbootloadermethod == "gigabeatf") + { + + if(gigabeatf(BOOTLOADER_REM)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been uninstalled.") + ,"Uninstallation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + MESG_DIALOG(_("The Uninstallation has failed.") ); + } + else if(gv->curbootloadermethod == "h10") + { + if(h10(BOOTLOADER_REM)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been uninstalled.") + ,"Uninstallation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + MESG_DIALOG(_("The Uninstallation has failed.") ); + + } + else if(gv->curbootloadermethod == "iaudio" ) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("To uninstall the Bootloader on this Device,\n" + "you need to download and install an Original Firmware from the Manufacturer.") + ,"Uninstallation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else if(gv->curbootloadermethod == "fwpatcher" ) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("To uninstall the Bootloader on this Device,\n" + "you need to download and install an original Firmware from the Manufacturer.\n" + "To do this, you need to boot into the original Firmware.") + ,"Uninstallation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + { + MESG_DIALOG(_("Unsupported Bootloader Method") ); + } + } + else + { + MESG_DIALOG(_("The bootloader Uninstallation wizard was cancelled") ); + } + + wxLogVerbose("=== end rbutilFrm::OnBootloaderRemoveBtn"); +} void rbutilFrm::OnBootloaderBtn(wxCommandEvent& event) { - if (!wxLaunchDefaultBrowser(wxT( - "http://www.rockbox.org/twiki/bin/view/Main/" - "DocsIndex#Rockbox_Installation_Instruction") ) ) + wxLogVerbose("=== begin rbutilFrm::OnBootloaderBtn(event)"); + + wxWizard *wizard = new wxWizard(this, wxID_ANY, + _("Rockbox Installation Wizard"), + wxBitmap(wizard_xpm), + wxDefaultPosition, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wxBootPlatformPage* page1 = new wxBootPlatformPage(wizard); + wxFirmwareLocationPage* page2 = new wxFirmwareLocationPage(wizard); //this page is optional + wxBootLocationPage* page3 = new wxBootLocationPage(wizard); // Only one of these pages are shown + wxIpodLocationPage* page4 = new wxIpodLocationPage(wizard); // depending on Device selected + + page1->SetNext(page2); + page2->SetPrev(page1); + page2->SetNext(page3); + page3->SetPrev(page2); + page3->SetNext(page4); + page4->SetPrev(page3); + + wizard->GetPageAreaSizer()->Add(page1); + + if (wizard->RunWizard(page1) ) + { + // start installation depending on player + if(gv->curbootloadermethod == "ipodpatcher") + { + + if(ipodpatcher(BOOTLOADER_ADD)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been installed on your device.") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + { + MESG_DIALOG(_("The installation has failed.") ); + } + } + else if(gv->curbootloadermethod == "gigabeatf") + { + + if(gigabeatf(BOOTLOADER_ADD)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been installed on your device.") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + MESG_DIALOG(_("The installation has failed.") ); + } + else if(gv->curbootloadermethod == "iaudio" ) + { + if(iaudiox5(BOOTLOADER_ADD)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been installed on your device.\n" + "Now turn OFF your Device, unplug USB,and insert Charger\n" + "Your Device will automatically upgrade the flash with the Rockbox bootloader") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + MESG_DIALOG(_("The installation has failed.") ); + } + else if(gv->curbootloadermethod == "fwpatcher") + { + if(fwpatcher(BOOTLOADER_ADD)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been patched and copied on your device.\n" + "Now use the Firmware upgrade option of your Device\n") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + MESG_DIALOG(_("The installation has failed.") ); + } + else if(gv->curbootloadermethod == "h10") + { + if(h10(BOOTLOADER_ADD)) + { + wxMessageDialog* msg = new wxMessageDialog(this, _("The Bootloader has been patched and copied on your device.\n" + "Now use the Firmware upgrade option of your Device\n") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; + } + else + MESG_DIALOG(_("The installation has failed.") ); + } + else + { + MESG_DIALOG(_("Unsupported Bootloader Method") ); + } + } + else { - ERR_DIALOG(_("Unable to launch external browser"), - _("Boot loader install instructions.")); + MESG_DIALOG(_("The bootloader installation wizard was cancelled") ); } + + wxLogVerbose("=== end rbutilFrm::OnBootloaderBtn"); + } void rbutilFrm::OnInstallBtn(wxCommandEvent& event) @@ -378,7 +587,10 @@ void rbutilFrm::OnInstallBtn(wxCommandEvent& event) if ( !UnzipFile(dest, gv->curdestdir, true) ) { - MESG_DIALOG(_("Rockbox has been installed on your device.") ); + wxMessageDialog* msg = new wxMessageDialog(this, _("Rockbox has been installed on your device.") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; } else { wxRemoveFile(dest); @@ -472,7 +684,10 @@ void rbutilFrm::OnFontBtn(wxCommandEvent& event) if ( !UnzipFile(dest, gv->curdestdir, true) ) { - MESG_DIALOG(_("The Rockbox fonts have been installed on your device.") ); + wxMessageDialog* msg = new wxMessageDialog(this, _("The Rockbox fonts have been installed on your device.") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; } else { wxRemoveFile(dest); @@ -511,7 +726,11 @@ void rbutilFrm::OnRemoveBtn(wxCommandEvent& event) _("The uninstallation wizard was cancelled or completed with " "some errors.") ); } else { - MESG_DIALOG(_("The uninstall wizard completed successfully") ); + wxMessageDialog* msg = new wxMessageDialog(this, _("The uninstall wizard completed successfully\n" + "Depending on which Device you own, you also have to uninstall the Bootloader") + ,"Uninstallation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; } } else { @@ -542,7 +761,10 @@ void rbutilFrm::OnPortableInstall(wxCommandEvent& event) { if ( InstallRbutil(gv->curdestdir) ) { - MESG_DIALOG(_("The Rockbox Utility has been installed on your device.") ); + wxMessageDialog* msg = new wxMessageDialog(this, _("The Rockbox Utility has been installed on your device.") + ,"Installation", wxOK |wxICON_INFORMATION); + msg->ShowModal(); + delete msg; } else { ERR_DIALOG(_("Installation failed"), _("Portable Install")); diff --git a/rbutil/rbutilFrm.h b/rbutil/rbutilFrm.h index b0332d0c74..9e75be3851 100644 --- a/rbutil/rbutilFrm.h +++ b/rbutil/rbutilFrm.h @@ -58,11 +58,13 @@ public: public: wxMenuBar *WxMenuBar1; wxStaticText *WxStaticText3; + wxStaticText *WxStaticText4; wxBitmapButton *WxBitmapButton2; wxStaticText *WxStaticText2; wxBitmapButton *WxBitmapButton1; wxBitmapButton *WxBitmapButton3; wxBitmapButton *WxBitmapButton4; + wxBitmapButton *WxBitmapButton5; wxFlexGridSizer *WxFlexGridSizer1; wxStaticBoxSizer *WxStaticBoxSizer3; wxStaticBitmap *WxStaticBitmap1; @@ -78,7 +80,9 @@ public: ID_PORTABLE_INSTALL = 1037, ID_WXSTATICTEXT3 = 1032, - ID_REMOVE_BTN = 1031, + ID_WXSTATICTEXT4 = 1032, + ID_REMOVE_BTN = 1039, + ID_BOOTLOADERREMOVE_BTN = 1038, ID_WXSTATICTEXT2 = 1029, ID_INSTALL_BTN = 1028, ID_WXSTATICBITMAP1 = 1053, @@ -100,6 +104,7 @@ public: void OnFontBtn(wxCommandEvent& event); void OnBootloaderBtn(wxCommandEvent& event); void OnPortableInstall(wxCommandEvent& event); + void OnBootloaderRemoveBtn(wxCommandEvent& event); }; diff --git a/rbutil/wizard_pages.cpp b/rbutil/wizard_pages.cpp index 7cd38cf004..2c4c609271 100644 --- a/rbutil/wizard_pages.cpp +++ b/rbutil/wizard_pages.cpp @@ -19,6 +19,85 @@ ****************************************************************************/ #include "wizard_pages.h" +#include "bootloaders.h" + +wxBootPlatformPage::wxBootPlatformPage(wxWizard *parent) : wxWizardPageSimple(parent) +{ + wxBoxSizer* WxBoxSizer1 = new wxBoxSizer(wxVERTICAL); + + wxStaticText* WxStaticText1 = new wxStaticText(this, wxID_ANY, + _("Please select the model of audio device that you would like to" + "\ninstall the Rockbox Bootloader on from the list below:")); + WxBoxSizer1->Add(WxStaticText1,0,wxGROW | wxALL,5); + + wxArrayString arrayStringFor_WxListBox1; + for (unsigned int i=0; i< gv->plat_name.GetCount(); i++) { + if (gv->plat_needsbootloader[i]) + { + if(gv->plat_autodetect[i]) + { + if(arrayStringFor_WxListBox1.Index(gv->plat_combinedname[i]) == wxNOT_FOUND) + arrayStringFor_WxListBox1.Add(gv->plat_combinedname[i]); + } + else + { + arrayStringFor_WxListBox1.Add(gv->plat_name[i]); + } + } + } + + BootPlatformListBox = new wxListBox(this, wxID_ANY, wxDefaultPosition, + wxDefaultSize, arrayStringFor_WxListBox1, wxLB_SINGLE); + WxBoxSizer1->Add(BootPlatformListBox,0,wxGROW | wxALL,5); + + SetSizer(WxBoxSizer1); + WxBoxSizer1->Fit(this); + + for (unsigned int i=0; i< gv->plat_id.GetCount(); i++) { + if (gv->plat_id[i] == gv->curplat) BootPlatformListBox->SetSelection(i); + } + +} + +wxWizardPage * wxBootPlatformPage::GetNext() const +{ + if(gv->curbootloadermethod != "fwpatcher"&& gv->curbootloadermethod != "ipodpatcher") + { + if(wxWizardPageSimple::GetNext()->GetNext() != NULL) // not iriver hx0 and ipod, skip one page + return wxWizardPageSimple::GetNext()->GetNext(); + } + else if(gv->curbootloadermethod == "ipodpatcher") + { + if(wxWizardPageSimple::GetNext()->GetNext() != NULL) + if(wxWizardPageSimple::GetNext()->GetNext()->GetNext() != NULL) + return wxWizardPageSimple::GetNext()->GetNext()->GetNext(); //ipod, skip 2 pages + else + return wxWizardPageSimple::GetNext()->GetNext(); //ipod, skip 1 page (for uninstallation) + } + + // all others , no skip + return wxWizardPageSimple::GetNext(); +} + +bool wxBootPlatformPage::TransferDataFromWindow() +{ + if (BootPlatformListBox->GetSelection() == wxNOT_FOUND ) + { + WARN_DIALOG(_("You must select an audio device type before proceeding"), + _("Select Platform")); + return false; + } else + { + int idx = gv->plat_name.Index(BootPlatformListBox->GetStringSelection()); + if(idx == wxNOT_FOUND) idx =gv->plat_combinedname.Index(BootPlatformListBox->GetStringSelection()); + gv->curplatnum = idx; + gv->curplat = gv->plat_id[gv->curplatnum]; + gv->curbootloadermethod = gv->plat_bootloadermethod[gv->curplatnum]; + gv->curbootloader = gv->plat_bootloadername[gv->curplatnum]; + + return true; + } +} wxPlatformPage::wxPlatformPage(wxWizard *parent) : wxWizardPageSimple(parent) { @@ -56,8 +135,265 @@ bool wxPlatformPage::TransferDataFromWindow() } } +BEGIN_EVENT_TABLE(wxIpodLocationPage,wxWizardPageSimple) + EVT_BUTTON (ID_IPODLOCATION_BTN, wxIpodLocationPage::OnIpodLocationBtn) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, wxIpodLocationPage::OnWizardPageChanging) +END_EVENT_TABLE(); + +wxIpodLocationPage::wxIpodLocationPage(wxWizard* parent) : wxWizardPageSimple(parent) +{ + + wxBoxSizer* WxBoxSizer1 = new wxBoxSizer(wxVERTICAL); + + // Header text + IpodLocationLabel = new wxStaticText(this, wxID_ANY, + wxT("Rockbox utility needs to know the device where your ipod\n" + "device is located on your computer. Rockbox utility\n" + "has detected the following location:")); + WxBoxSizer1->Add(IpodLocationLabel,0,wxGROW | wxALL, 5); + + // device location + wxBoxSizer* WxBoxSizer3 = new wxBoxSizer(wxHORIZONTAL); + WxBoxSizer1->Add(WxBoxSizer3,0, + wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5); + + IpodLocationText = new wxStaticText(this, wxID_ANY, "", + wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + WxBoxSizer3->Add(IpodLocationText,1, + wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5); + + IpodLocationBtn = new wxButton(this, ID_IPODLOCATION_BTN, wxT("Scan"), + wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, + wxT("IpodLocationBtn")); + IpodLocationBtn->SetToolTip(wxT("Scan for your Ipod")); + WxBoxSizer3->Add(IpodLocationBtn,0,wxALIGN_CENTER_VERTICAL | wxALL, 5); + + // Extra text + IpodLocationExtraText = new wxStaticText(this,wxID_ANY, wxT("")); + WxBoxSizer1->Add(IpodLocationExtraText,0,wxGROW | wxALL, 5); + + SetSizer(WxBoxSizer1); + WxBoxSizer1->Fit(this); +} + +wxWizardPage* wxIpodLocationPage::GetPrev() const +{ + if(gv->curbootloadermethod == "ipodpatcher") //if ipod, skip previous + { + if(wxWizardPageSimple::GetPrev()->GetPrev() != NULL) + return wxWizardPageSimple::GetPrev()->GetPrev(); + + } +} + +void wxIpodLocationPage::OnWizardPageChanging(wxWizardEvent& event) +{ + if(event.GetDirection()) // going forwards in the Wizard + { + if(gv->curbootloadermethod=="ipodpatcher") + { + if(IpodLocationText->GetLabel() == "no Ipod found" || + IpodLocationText->GetLabel() =="More than 1 Ipod found" || + IpodLocationText->GetLabel() =="") + { + WARN_DIALOG(_("No valid ipod found!"), _("Select Location")); + event.Veto(); //stop pagechanging + } + } + } +} + +void wxIpodLocationPage::OnIpodLocationBtn(wxCommandEvent& event) +{ + wxLogVerbose("=== begin wxIpodLocationPage::OnIpodLocationBtn"); + struct ipod_t ipod; + int n = ipod_scan(&ipod); + + gv->curbootloader="bootloader-"; + gv->curbootloader.Append(ipod.targetname); + if(n == 0) + IpodLocationText->SetLabel("no Ipod found"); + else if( n==1) + IpodLocationText->SetLabel(ipod.modelstr); + else + IpodLocationText->SetLabel("More than 1 Ipod found"); + + if(ipod.macpod) + IpodLocationExtraText->SetLabel("This Ipod is a Mac formated Ipod\n" + "Rockbox will not work on this.\n" + "You have to convert it first to Fat32"); + wxLogVerbose("=== end wxIpodLocationPage::OnIpodLocationBtn"); + +} + +BEGIN_EVENT_TABLE(wxBootLocationPage,wxWizardPageSimple) + EVT_BUTTON (ID_BOOTLOCATION_BTN, wxBootLocationPage::OnBootLocationBtn) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, wxBootLocationPage::OnWizardPageChanging) +END_EVENT_TABLE(); + +wxBootLocationPage::wxBootLocationPage(wxWizard* parent) : wxWizardPageSimple(parent) + { + + wxBoxSizer* WxBoxSizer1 = new wxBoxSizer(wxVERTICAL); + + // Header text + BootLocationLabel = new wxStaticText(this, wxID_ANY, + wxT("Rockbox utility needs to know the folder where your audio\n" + "device is located on your computer. Currently Rockbox utility\n" + "is configured to use the following location:")); + WxBoxSizer1->Add(BootLocationLabel,0,wxGROW | wxALL, 5); + + // device location + wxBoxSizer* WxBoxSizer3 = new wxBoxSizer(wxHORIZONTAL); + WxBoxSizer1->Add(WxBoxSizer3,0, + wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5); + + if (gv->curdestdir == wxT("")) gv->curdestdir = _(""); + BootLocationText = new wxStaticText(this, wxID_ANY, gv->curdestdir, + wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + WxBoxSizer3->Add(BootLocationText,1, + wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5); + + BootLocationBtn = new wxButton(this, ID_BOOTLOCATION_BTN, wxT("Change"), + wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, + wxT("BootLocationBtn")); + BootLocationBtn->SetToolTip(wxT("Select the location of your audio device")); + WxBoxSizer3->Add(BootLocationBtn,0,wxALIGN_CENTER_VERTICAL | wxALL, 5); + + SetSizer(WxBoxSizer1); + WxBoxSizer1->Fit(this); +} + +wxWizardPage* wxBootLocationPage::GetPrev() const +{ + if(gv->curbootloadermethod != "fwpatcher") + { + if(wxWizardPageSimple::GetPrev()->GetPrev() != NULL) + return wxWizardPageSimple::GetPrev()->GetPrev(); + + } + + return wxWizardPageSimple::GetPrev(); +} + +wxWizardPage* wxBootLocationPage::GetNext() const +{ + if(gv->curbootloadermethod == "ipodpatcher") + { + return wxWizardPageSimple::GetNext(); // if ipod then this is not the last page + } + else return NULL; // else this is the last page +} + +void wxBootLocationPage::OnWizardPageChanging(wxWizardEvent& event) +{ + if(event.GetDirection()) // going forwards in the Wizard + { + if(!wxDirExists(BootLocationText->GetLabel())) + { + WARN_DIALOG(_("You have not selected a valid location for your audio " + "device"), _("Select Location")); + event.Veto(); + } + + } +} + +bool wxBootLocationPage::TransferDataFromWindow() +{ + gv->curdestdir = BootLocationText->GetLabel(); + return true; + +} + + +void wxBootLocationPage::OnBootLocationBtn(wxCommandEvent& event) +{ + const wxString& temp = wxDirSelector( + _("Please select the location of your audio device"), gv->curdestdir); + wxLogVerbose("=== begin wxBootLocationPage::OnBootLocationBtn(event)"); + if (!temp.empty()) + { + BootLocationText->SetLabel(temp); + } + wxLogVerbose("=== end wxBootLocationPage::OnBootLocationBtn"); + +} + + +BEGIN_EVENT_TABLE(wxFirmwareLocationPage,wxWizardPageSimple) + EVT_BUTTON (ID_FIRMWARELOCATION_BTN, wxFirmwareLocationPage::OnFirmwareFilenameBtn) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, wxFirmwareLocationPage::OnWizardPageChanging) +END_EVENT_TABLE(); + +wxFirmwareLocationPage::wxFirmwareLocationPage(wxWizard* parent) : wxWizardPageSimple(parent) +{ + + wxBoxSizer* WxBoxSizer1 = new wxBoxSizer(wxVERTICAL); + + // Header text + FirmwareLocationText = new wxStaticText(this, wxID_ANY, + wxT("For this step Rockbox Utility needs an original Firmware.\n" + "You can download this from the Manufacturers Website.")); + WxBoxSizer1->Add(FirmwareLocationText,0,wxGROW | wxALL, 5); + + // Filename text + wxBoxSizer* WxBoxSizer4 = new wxBoxSizer(wxHORIZONTAL); + WxBoxSizer1->Add(WxBoxSizer4,0, + wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5); + + FirmwareLocationFilename = new wxStaticText(this, wxID_ANY, gv->curfirmware, + wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + WxBoxSizer4->Add(FirmwareLocationFilename,1, + wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5); + + // Button + FirmwareLocationBtn = new wxButton(this, ID_FIRMWARELOCATION_BTN, wxT("Explore"), + wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, + wxT("FirmwareLocationBtn")); + FirmwareLocationBtn->SetToolTip(wxT("Select the location of the downloaded Firmware")); + WxBoxSizer4->Add(FirmwareLocationBtn,0,wxALIGN_CENTER_VERTICAL | wxALL, 5); + + + SetSizer(WxBoxSizer1); + WxBoxSizer1->Fit(this); +} + +void wxFirmwareLocationPage::OnWizardPageChanging(wxWizardEvent& event) +{ + if(event.GetDirection()) // going forwards in the Wizard + { + if( !wxFileExists(gv->curfirmware)) + { + WARN_DIALOG(_("You have not selected a valid location for the firmware " + "file"), _("Select File")); + event.Veto(); + } + } + +} + +void wxFirmwareLocationPage::OnFirmwareFilenameBtn(wxCommandEvent& event) +{ + wxString temp = wxFileSelector( + _("Please select the location of the original Firmware"), gv->curdestdir,"","","*.hex"); + wxLogVerbose("=== begin wxFirmwareLocationPage::OnFirmwareFilenameBtn(event)"); + if (!temp.empty()) + { + gv->curfirmware=temp; + if(temp.Length() > 30) + { + temp.Remove(0, temp.Length()-30); + temp.Prepend("..."); + } + FirmwareLocationFilename->SetLabel(temp); + } + wxLogVerbose("=== end wxFirmwareLocationPage::OnFirmwareFilenameBtn"); +} + BEGIN_EVENT_TABLE(wxLocationPage,wxWizardPageSimple) EVT_BUTTON (ID_LOCATION_BTN, wxLocationPage::OnLocationBtn) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, wxLocationPage::OnWizardPageChanging) END_EVENT_TABLE(); wxLocationPage::wxLocationPage(wxWizard* parent) : wxWizardPageSimple(parent) @@ -90,18 +426,24 @@ wxLocationPage::wxLocationPage(wxWizard* parent) : wxWizardPageSimple(parent) WxBoxSizer1->Fit(this); } -bool wxLocationPage::TransferDataFromWindow() + +void wxLocationPage::OnWizardPageChanging(wxWizardEvent& event) { - if ( wxDirExists(LocationText->GetLabel() ) ) - { - gv->curdestdir = LocationText->GetLabel(); - return true; - } else - { - WARN_DIALOG(_("You have not selected a valid location for your audio " + if(event.GetDirection()) // going forwards in the Wizard + { + if(!wxDirExists(LocationText->GetLabel())) + { + WARN_DIALOG(_("You have not selected a valid location for your audio " "device"), _("Select Location")); - return false; - } + event.Veto(); + } + } +} + +bool wxLocationPage::TransferDataFromWindow() +{ + gv->curdestdir = LocationText->GetLabel(); + return true; } void wxLocationPage::OnLocationBtn(wxCommandEvent& event) diff --git a/rbutil/wizard_pages.h b/rbutil/wizard_pages.h index d0fd4459e0..1b6dc5be78 100644 --- a/rbutil/wizard_pages.h +++ b/rbutil/wizard_pages.h @@ -24,6 +24,96 @@ #include "rbutil.h" +class wxBootPlatformPage : public wxWizardPageSimple +{ +public: + wxBootPlatformPage(wxWizard *parent); + virtual bool TransferDataFromWindow(void); + virtual wxWizardPage *GetNext() const; + void SetNext(wxWizardPage * next) {wxWizardPageSimple::SetNext(next); my_next = next;} + +public: + wxListBox* BootPlatformListBox; + wxWizardPage *my_next; +}; + +class wxIpodLocationPage : public wxWizardPageSimple +{ +private: + DECLARE_EVENT_TABLE() + +public: + enum { + ID_IPODLOCATION_BTN = 1000, + }; +public: + wxIpodLocationPage(wxWizard* parent); + void OnIpodLocationBtn(wxCommandEvent& event); + void OnWizardPageChanging(wxWizardEvent& event); + virtual wxWizardPage *GetPrev() const; + void SetPrev(wxWizardPage * prev) {wxWizardPageSimple::SetPrev(prev); my_prev = prev;} + +private: + wxStaticText* IpodLocationText; + wxStaticText* IpodLocationLabel; + wxStaticText* IpodLocationExtraText; + wxButton* IpodLocationBtn; + wxWizardPage *my_prev; +}; + + + +class wxBootLocationPage : public wxWizardPageSimple +{ +private: + DECLARE_EVENT_TABLE() + +public: + enum { + ID_BOOTLOCATION_BTN = 1000, + }; + +public: + wxBootLocationPage(wxWizard* parent); + virtual bool TransferDataFromWindow(void); + void OnBootLocationBtn(wxCommandEvent& event); + void OnPageShown(wxWizardEvent& event); + void OnWizardPageChanging(wxWizardEvent& event); + virtual wxWizardPage *GetPrev() const; + virtual wxWizardPage *GetNext() const; + void SetPrev(wxWizardPage * prev) {wxWizardPageSimple::SetPrev(prev); my_prev = prev;} + +private: + wxStaticText* BootLocationText; + wxStaticText* BootLocationLabel; + wxButton* BootLocationBtn; + wxWizardPage *my_prev; + +}; + +class wxFirmwareLocationPage : public wxWizardPageSimple +{ + private: + DECLARE_EVENT_TABLE() + +public: + enum { + ID_FIRMWARELOCATION_BTN = 1000, + }; + +public: + wxFirmwareLocationPage(wxWizard* parent); + void OnFirmwareFilenameBtn(wxCommandEvent& event); + void OnWizardPageChanging(wxWizardEvent& event); + +private: + wxStaticText* FirmwareLocationText; + wxStaticText* FirmwareLocationFilename; + wxButton* FirmwareLocationBtn; + +}; + + class wxPlatformPage : public wxWizardPageSimple { public: @@ -47,9 +137,10 @@ public: public: wxLocationPage(wxWizard* parent); virtual bool TransferDataFromWindow(void); + void OnWizardPageChanging(wxWizardEvent& event); void OnLocationBtn(wxCommandEvent& event); -public: +private: wxStaticText* LocationText; }; @@ -69,7 +160,7 @@ public: void OnBuildBox(wxCommandEvent& event); void OnPageShown(wxWizardEvent& event); -public: +private: wxRadioBox* BuildRadioBox; wxStaticText* DetailText; wxCheckBox* NoCacheCheckBox; @@ -81,7 +172,7 @@ public: wxFullUninstallPage(wxWizard *parent); virtual bool TransferDataFromWindow(void); -public: +private: wxCheckBox* FullCheckBox; }; -- cgit