diff --git a/.gitmodules b/.gitmodules
index 452224ad72ce457e8e43e55f32b54ed216837e9b..6dd7bd5323d60f7d8437d2d75bc16fef600a57e9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -14,3 +14,6 @@
 [submodule "libs/eigen"]
 	path = libs/eigen
 	url = https://gitlab.com/libeigen/eigen.git
+[submodule "libs/mxgui"]
+	path = libs/mxgui
+	url = git@git.skywarder.eu:scs/mxgui.git
diff --git a/Makefile.template b/Makefile.template
index ca62562a9f898923e20fb8ecbe7c4305679bb803..3b3ea18e0452bc4bc7eda4146e7deabbad50703b 100644
--- a/Makefile.template
+++ b/Makefile.template
@@ -15,7 +15,7 @@ include $(CONFPATH)/config/Makefile.inc
 ##
 ## List here subdirectories which contains makefiles
 ##
-SUBDIRS := $(KPATH) {SBS_PROJECT_SUBDIRS}
+SUBDIRS := $(KPATH) {SBS_PROJECT_SUBDIRS} {SBS_LIB_SUBDIR}
 
 ##
 ## List here your source files (both .s, .c and .cpp)
@@ -25,13 +25,13 @@ SRC := {SBS_SOURCE_FILES}
 ##
 ## List here additional static libraries with relative path
 ##
-LIBS := {SBS_PROJECT_LIBS}
+LIBS := {SBS_PROJECT_LIBS} {SBS_LIB_LIBS}
 
 ##
 ## List here additional include directories (in the form -Iinclude_dir)
 ##
 INCLUDE_DIRS := -I$(SBS_BASE)/libs -I$(SBS_BASE)/libs/miosix-kernel/miosix \
-                {SBS_PROJECT_INCLUDES}
+                {SBS_PROJECT_INCLUDES} {SBS_LIB_INCLUDES}
 
 ##############################################################################
 ## You should not need to modify anything below                             ##
@@ -54,10 +54,12 @@ OBJ := $(addprefix $(OBJDIR)/, $(addsuffix .o, $(basename $(SRC))))
 ## Always include CONFPATH first, as it overrides the config file location
 CXXFLAGS := $(CXXFLAGS_BASE) -I$(CONFPATH) -I$(CONFPATH)/config/$(BOARD_INC)  \
             -I. -I$(KPATH) -I$(KPATH)/arch/common -I$(KPATH)/$(ARCH_INC)      \
-            -I$(KPATH)/$(BOARD_INC) $(INCLUDE_DIRS) -Wall -Wextra -pedantic
+            -I$(KPATH)/$(BOARD_INC) $(INCLUDE_DIRS) -Wall -Wextra -Wcast-align \
+			-pedantic
 CFLAGS   := $(CFLAGS_BASE)   -I$(CONFPATH) -I$(CONFPATH)/config/$(BOARD_INC)  \
             -I. -I$(KPATH) -I$(KPATH)/arch/common -I$(KPATH)/$(ARCH_INC)      \
-            -I$(KPATH)/$(BOARD_INC) $(INCLUDE_DIRS) -Wall -Wextra -pedantic
+            -I$(KPATH)/$(BOARD_INC) $(INCLUDE_DIRS) -Wall -Wextra -Wcast-align \
+			-pedantic
 AFLAGS   := $(AFLAGS_BASE)
 LFLAGS   := $(LFLAGS_BASE) -Wl,--gc-sections,-Map,$(BINDIR)/${SBS_BIN_NAME}.map
 DFLAGS   := -MMD -MP
diff --git a/libs/miosix-kernel b/libs/miosix-kernel
index 7cda1e7c1d55766f2f75806b56e4bad60db1fcf7..7ff90e110b1e0cb0c7acc7c652cf593087ccd18a 160000
--- a/libs/miosix-kernel
+++ b/libs/miosix-kernel
@@ -1 +1 @@
-Subproject commit 7cda1e7c1d55766f2f75806b56e4bad60db1fcf7
+Subproject commit 7ff90e110b1e0cb0c7acc7c652cf593087ccd18a
diff --git a/libs/mxgui b/libs/mxgui
new file mode 160000
index 0000000000000000000000000000000000000000..cab17f6185da95502d20dd31b17fef67e06ca6ef
--- /dev/null
+++ b/libs/mxgui
@@ -0,0 +1 @@
+Subproject commit cab17f6185da95502d20dd31b17fef67e06ca6ef
diff --git a/sbs b/sbs
index d159ba3a51bb38c2280f2f0853a1aa75da16d187..6c5201fe2bd2d0f3c0f3ea6699ff72b552a857c0 100755
--- a/sbs
+++ b/sbs
@@ -48,9 +48,8 @@ except ImportError:
 # Global variables
 #
 srcfiles={}
+extlibs={}
 mainfiles={}
-tests={}
-entrypoints={}
 colors=False
 
 # Map for the project configuration, filled in when parsing sbs.conf
@@ -154,27 +153,30 @@ def parseConf(path):
                 projconf[i] = conf.get('SBS_PROJECT', i)
         elif stype == 'srcfiles':
             srcfiles[i] = [x.strip() for x in conf.get(i, 'Files').split("\n")]
-        elif stype == 'board':
-            entrypoints[i] = {   'id': conf.get(i, 'BoardId'),
-                            'bin': conf.get(i, 'BinName'),
-                            'defines': conf.get(i, 'Defines'),
-                            'files': [entrypoint_mask % conf.get(i, 'Main').strip()] +
-                             [x.strip() for x in conf.get(i, 'Include').split(' ')]
-                        }
-        elif stype == 'test':
-            tests[i] = {   'id': conf.get(i, 'BoardId'),
+        elif stype == 'library':
+            extlibs[i] = {'subdir': conf.get(i, 'Subdir'),
+                          'libs': [x.strip() for x in conf.get(i, 'Libs').split()],
+                          'includes': [x.strip() for x in conf.get(i, 'Includes').split()]}
+        elif stype == 'board' or stype == 'test':
+            if stype == 'test':
+                mask = test_mask
+                add_def = " -I" + projconf['TESTS_PATH']
+            else:
+                mask = entrypoint_mask
+                add_def = ""
+            
+            mainfiles[i] = {'type': stype,
+                            'id': conf.get(i, 'BoardId').strip(),
                             'bin': conf.get(i, 'BinName'),
-                            'defines': conf.get(i, 'Defines') + " -I" + projconf['TESTS_PATH'],
-                            'files': [test_mask % conf.get(i, 'Main').strip()] +
+                            'defines': conf.get(i, 'Defines') + add_def,
+                            'libs': [x.strip() for x in conf.get(i, 'Libs', fallback="").split()],
+                            'files': [mask % conf.get(i, 'Main').strip()] +
                              [x.strip() for x in conf.get(i, 'Include').split(' ')]
                         }
         else:
             print('[SBS] Syntax error in %s: type %s not implemented' % (path, stype))
             exit(1)
 
-    # Join tests and entrypoints in mainfiles
-    mainfiles.update(entrypoints)
-    mainfiles.update(tests)
 
     # Exit if nothing was found
     if (len(mainfiles) == 0 ):
@@ -184,6 +186,7 @@ def parseConf(path):
     # Import also srcfiles from boardcore if executing from another folders
     if projconf['SBS_BASE'] != '.':
         importSrcFiles(projconf['SBS_BASE'] + "/sbs.conf")
+        importLibs(projconf['SBS_BASE'] + "/sbs.conf")
 
     # Substitute includes
     for i in mainfiles:
@@ -194,6 +197,13 @@ def parseConf(path):
             else:
                 files += [j]
         mainfiles[i]['files'] = files
+    
+    # Substitute libs
+    for i in mainfiles:
+        lib_dicts = {}
+        for j in mainfiles[i]['libs']:
+            lib_dicts[j] = extlibs[j]
+        mainfiles[i]['libs'] = lib_dicts
 
 #
 # Create a Makefile for a specific board starting from Makefile.template
@@ -208,7 +218,10 @@ def build_makefile(template, board, bname):
              "MAP_FILE": "export MAIN_MAP_FILE := bin/%s.map\n" % board['bin'],
              "SOURCE_FILES": "%s\n" % (" ".join(board['files'])),
              "CUSTOM_DEFINES": board['defines'],
-             "BIN_NAME": board['bin']
+             "BIN_NAME": board['bin'],
+             "LIB_SUBDIR": " ".join([x['subdir'] for _,x in board['libs'].items()]),
+             "LIB_LIBS": " ".join([" ".join(x['libs']) for _,x in board['libs'].items()]),
+             "LIB_INCLUDES": " ".join([" ".join([ "-I" + s for s in x['includes']]) for _,x in board['libs'].items()])
     }
 
     rmap["PROJECT_INCLUDES"] = "-I" + projconf["SRC_PATH"].strip() + " "
@@ -255,7 +268,24 @@ def importSrcFiles(path):
             else:
                 print('[SBS] Syntax error in %s: a srcfiles group named %s is already defined. Terminating' % (path, i))
                 exit(1)
+#
+# Import libraries groups from another .conf file.
+# Libraries are added only if there's not a group already with the same name.
+#
+def importLibs(path):
+    conf = cp.RawConfigParser()
+    conf.read(path)
 
+    for i in conf.sections():
+        stype = conf.get(i, 'Type')
+        if stype == 'library':
+            if i not in extlibs:
+                extlibs[i] =  {'subdir': conf.get(i, 'Subdir'),
+                            'libs': [x.strip() for x in conf.get(i, 'Libs').split()],
+                            'includes': [x.strip() for x in conf.get(i, 'Includes').split()]}
+            else:
+                print('[SBS] Syntax error in %s: a library group named %s is already defined. Terminating' % (path, i))
+                exit(1)
 
 ##-------------------------------------------------------------
 ##                       MAIN
@@ -297,14 +327,17 @@ if options.lint == True:
 # List
 if options.list == True:
     print('[SBS] List of available entrypoints:')
-    for entrypoint in entrypoints:
-        print(entrypoint)
+    for main in mainfiles:
+        if(mainfiles[main]['type'] == 'board'):
+            print(main)
     print('\n[SBS] List of available tests:')
-    for test in tests:
-        print(test)
+    for main in mainfiles:
+        if(mainfiles[main]['type'] == 'test'):
+            print(main)
     exit(0)
 
 # Set how many main files to build:
+files = list(mainfiles.keys()).copy()
 if options.board != None:       # just one
     try:
         good = mainfiles[options.board]
@@ -313,9 +346,13 @@ if options.board != None:       # just one
         print('[SBS] No entrypoint or test named %s. Terminating.' % (options.board))
         sys.exit(2)
 elif options.all_entry == True:  # all entrypoints
-    mainfiles = entrypoints
+     for main in files:
+        if(mainfiles[main]['type'] == 'test'):
+            del mainfiles[main]
 elif options.all_tests == True:  # all tests
-    mainfiles = tests
+    for main in files:
+        if(mainfiles[main]['type'] == 'board'):
+            del mainfiles[main]
 
 
 # Set action
diff --git a/sbs.conf b/sbs.conf
index e05829a53834135e832ef40df48ca669bdf09d39..a02fab8cf725ef8abc40b080ebb333e3ff4e2e89 100644
--- a/sbs.conf
+++ b/sbs.conf
@@ -77,16 +77,36 @@ ENTRY_PATH:       src/entrypoints
 TESTS_PATH:       src/tests
 SRC_PATH:         src/shared
 SBS_BASE:         .
-PROJECT_INCLUDES: -Ilibs/eigen/
-PROJECT_SUBDIRS:
-PROJECT_LIBS:
+PROJECT_INCLUDES: 
+PROJECT_SUBDIRS:  
+PROJECT_LIBS:     
+
+#----------------------------------------------#
+#          List of External Libraries          #
+#----------------------------------------------#
+# [name]    -> can be included using 'name'
+#     Type: library
+#     Subdir: Subdirectory containing the library makefile
+#     Libs: Static libraries to link against (whitespace-separated)
+#     Includes: List of additional include directories (whitespace-separated)
+[libmxgui]
+Type:       library
+Subdir:     libs/mxgui
+Libs:       libs/mxgui/libmxgui.a
+Includes:   libs/mxgui
+
+[eigen]
+Type:       library
+Subdir:     
+Libs:       
+Includes:   libs/eigen
 
 #-----------------------------------#
 #          List of Sources          #
 #-----------------------------------#
 # [name]    -> can be included using '%name'
 #     Type: srcfiles
-#     Files: a '/n'-separated list of f
+#     Files: a '/n'-separated list of source files
 
 [shared]
 Type:       srcfiles
@@ -121,8 +141,7 @@ Files:      src/shared/drivers/pwm/pwm.cpp
 
 [spi]
 Type:       srcfiles
-Files:      src/shared/drivers/spi/SPIBus.cpp
-            src/shared/drivers/spi/SPITransaction.cpp
+Files:      src/shared/drivers/spi/SPITransaction.cpp
 
 [i2c]
 Type:       srcfiles
@@ -163,7 +182,9 @@ Files:      src/shared/drivers/gamma868/Gamma868.cpp
 
 [xbee]
 Type:       srcfiles
-Files:      src/shared/drivers/Xbee/Xbee.cpp
+Files:      src/shared/drivers/Xbee/APIFrameParser.cpp
+            src/shared/drivers/Xbee/Xbee.cpp
+            
 
 [events]
 Type:       srcfiles
@@ -192,6 +213,8 @@ Files:      src/tests/catch/test-aero.cpp
             src/tests/catch/test-matrix.cpp
             src/tests/catch/test-packetqueue.cpp
             src/tests/catch/spidriver/test-spidriver
+            src/tests/catch/xbee/test-xbee-parser.cpp
+            src/tests/catch/xbee/test-xbee-driver.cpp
 
 [internal-adc]
 Type:       srcfiles
@@ -231,6 +254,15 @@ Include:
 Defines:
 Main:       kernel-testsuite
 
+[mxgui-helloworld]
+Type:       board
+BoardId:    stm32f429zi_stm32f4discovery
+BinName:    mxgui-helloworld
+Include:    
+Defines:    -DDEBUG
+Libs:       libmxgui
+Main:       examples/mxgui-helloworld
+
 [sdcard-benchmark]
 Type:       board
 BoardId:    stm32f429zi_stm32f4discovery
@@ -256,8 +288,8 @@ Main:       sdcard-benchmark
 Type:       test
 BoardId:    stm32f429zi_stm32f4discovery
 BinName:    tests-catch
-Include:    %tests-boardcore %shared %test-utils %spi %sensormanager
-Defines:
+Include:    %tests-boardcore %shared %test-utils %spi %sensormanager %xbee
+Defines:    -DUSE_MOCK_PERIPHERALS
 Main:       catch/catch-tests-entry
 
 [test-kalman]
@@ -274,6 +306,7 @@ BoardId:    stm32f429zi_stm32f4discovery
 BinName:    test-kalman-eigen
 Include:    %shared 
 Defines:    -DDEBUG -DSTANDALONE_CATCH1_TEST
+Libs:       eigen
 Main:       catch/test-kalman-eigen
 
 [test-taskscheduler]
@@ -338,6 +371,7 @@ BoardId:    stm32f429zi_stm32f4discovery
 BinName:    test-kalman-eigen-benchmark
 Include:    %shared 
 Defines:    
+Libs:       eigen
 Main:       kalman/test-kalman-eigen-benchmark
 
 [test-pinobserver]
@@ -414,29 +448,29 @@ Include:    %shared %gamma868
 Defines:   -DDEBUG
 Main:       drivers/test-mavlink
 
-[xbee-bitrate]
-Type:       test
-BoardId:    stm32f429zi_skyward_death_stack
-BinName:    xbee-bitrate
-Include:    %shared %xbee %spi
-Defines:   -DDEBUG -DSDRAM_ISSI
-Main:       misc/xbee-bitrate
+# [xbee-bitrate]
+# Type:       test
+# BoardId:    stm32f429zi_skyward_death_stack
+# BinName:    xbee-bitrate
+# Include:    %shared %xbee %spi
+# Defines:   -DDEBUG -DSDRAM_ISSI
+# Main:       misc/xbee-bitrate
 
-[xbee-send-rcv]
-Type:       test
-BoardId:    stm32f429zi_skyward_death_stack
-BinName:    xbee-send-rcv
-Include:    %shared %xbee %spi
-Defines:    -DDEBUG
-Main:       misc/xbee-send-rcv
+# [xbee-send-rcv]
+# Type:       test
+# BoardId:    stm32f429zi_skyward_death_stack
+# BinName:    xbee-send-rcv
+# Include:    %shared %xbee %spi
+# Defines:    -DDEBUG
+# Main:       misc/xbee-send-rcv
 
-[xbee-time-to-send]
-Type:       test
-BoardId:    stm32f429zi_skyward_death_stack
-BinName:    xbee-time-to-send
-Include:    %shared %xbee %spi
-Defines:    -DDEBUG
-Main:       misc/xbee-time-to-send
+# [xbee-time-to-send]
+# Type:       test
+# BoardId:    stm32f429zi_skyward_death_stack
+# BinName:    xbee-time-to-send
+# Include:    %shared %xbee %spi
+# Defines:    -DDEBUG
+# Main:       misc/xbee-time-to-send
 
 [test-circularbuffer]
 Type:       test
@@ -534,6 +568,39 @@ Include:    %shared %spi %ads1118
 Defines:    -DDEBUG
 Main:       drivers/test-ads1118
 
+[test-xbee-snd]
+Type:       test
+BoardId:    stm32f429zi_stm32f4discovery
+BinName:    test-xbee-snd
+Include:    %shared %spi %xbee %logger
+Defines:    -DDEBUG
+Main:       drivers/xbee/test-xbee-snd
+
+[test-xbee-rcv]
+Type:       test
+BoardId:    stm32f429zi_stm32f4discovery
+BinName:    test-xbee-rcv
+Include:    %shared %spi %xbee %logger
+Defines:    -DDEBUG
+Main:       drivers/xbee/test-xbee-rcv
+
+[test-xbee-bidir]
+Type:       test
+BoardId:    stm32f429zi_stm32f4discovery
+BinName:    test-xbee-bidir
+Include:    %shared %spi %xbee %logger
+Defines:    -DDEBUG
+Main:       drivers/xbee/test-xbee-bidir
+
+[test-xbee-gui]
+Type:       test
+BoardId:    stm32f429zi_stm32f4discovery
+BinName:    test-xbee-gui
+Include:    %shared %spi %xbee %logger src/tests/drivers/xbee/gui/res/respect.cpp
+Defines:    -DDEBUG 
+Libs:       libmxgui
+Main:       drivers/xbee/test-xbee-gui
+
 [test-bme280]
 Type:       test
 BoardId:    stm32f407vg_stm32f4discovery
@@ -686,4 +753,4 @@ Main:       drivers/test-hwtimer-chain
 # BinName:    calibrate-mpu9250
 # Include:    %shared %sensormanager
 # Defines:
-# Main:       drivers/calibrate-mpu9250
\ No newline at end of file
+# Main:       drivers/calibrate-mpu9250
diff --git a/src/entrypoints/examples/mxgui-helloworld.cpp b/src/entrypoints/examples/mxgui-helloworld.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f2ef202d889c65456bb06645f4d5248af69a138d
--- /dev/null
+++ b/src/entrypoints/examples/mxgui-helloworld.cpp
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <cstdio>
+#include <miosix.h>
+
+#include <mxgui/entry.h>
+#include <mxgui/display.h>
+
+using namespace mxgui;
+using namespace miosix;
+
+int main()
+{
+    {
+		DrawingContext dc(DisplayManager::instance().getDisplay());
+		dc.write(Point(0,0),"Hello world");
+	}
+    for(;;)
+    {
+        printf("Hello world! Look at the screen!\n");
+        Thread::sleep(1000);
+    }
+}
\ No newline at end of file
diff --git a/src/entrypoints/kernel-testsuite.cpp b/src/entrypoints/kernel-testsuite.cpp
index ce71b9421b1a6a3e247a195cfecdd4f3926f9846..dd00dac1a818396f7e32d90d45bef513f4831d53 100644
--- a/src/entrypoints/kernel-testsuite.cpp
+++ b/src/entrypoints/kernel-testsuite.cpp
@@ -190,6 +190,7 @@ int main()
         }
         //For testing mpu
         unsigned int *m;
+        (void)m; // Disable unused warning
         switch(c)
         {
             case 't':
@@ -347,6 +348,7 @@ int main()
             case 's':
                 iprintf("Shutting down\n");
                 shutdown();
+                break;
             default:
                 iprintf("Unrecognized option\n");
         }
@@ -609,6 +611,7 @@ static volatile bool t1_v1;
 
 static void t1_p1(void *argv)
 {
+    (void)argv;
     for(;;)
     {
         if(Thread::testTerminate()) break;
@@ -701,6 +704,8 @@ static Thread *t2_p_v1;
 
 static void t2_p1(void *argv)
 {
+    (void)argv;
+
     //This is to fix a race condition: the immediately after the thread
     //creation a yield occurs, t2_p_v1 is not yet assigned so the check fails
     Thread::sleep(5);
@@ -718,6 +723,7 @@ static void t2_p1(void *argv)
 
 static void t2_p2(void *argv)
 {
+    (void)argv;
     while(Thread::testTerminate()==false) t2_v1=true;
 }
 
@@ -782,6 +788,7 @@ also tests creation of multiple instances of the same thread
 
 static void t3_p1(void *argv)
 {
+    (void)argv;
     const int SLEEP_TIME=100;
     for(;;)
     {
@@ -799,6 +806,7 @@ static volatile bool t3_deleted;//Set when an instance of t3_p2 is deleted
 
 static void t3_p2(void *argv)
 {
+    (void)argv;
     const int SLEEP_TIME=15;
     for(;;)
     {
@@ -893,6 +901,7 @@ static volatile bool t4_v1;
 
 static void t4_p1(void *argv)
 {
+    (void)argv;
     for(;;)
     {
         if(Thread::testTerminate()) break;
@@ -1035,6 +1044,7 @@ static volatile bool t5_v2;//False=testing Thread::wait() else Thread::IRQwait()
 
 static void t5_p1(void *argv)
 {
+    (void)argv;
     for(;;)
     {
         if(Thread::testTerminate()) break;
@@ -1153,6 +1163,7 @@ static FastMutex t6_m1a;
 
 static void t6_p1(void *argv)
 {
+    (void)argv;
     t6_m1.lock();
     seq.add('1');
     Thread::sleep(100);
@@ -1165,6 +1176,7 @@ static void t6_p1(void *argv)
 
 static void t6_p2(void *argv)
 {
+    (void)argv;
     t6_m1.lock();
     seq.add('2');
     Thread::sleep(100);
@@ -1176,6 +1188,7 @@ static void t6_p2(void *argv)
 
 static void t6_p3(void *argv)
 {
+    (void)argv;
     t6_m1.lock();
     seq.add('3');
     Thread::sleep(100);
@@ -1187,6 +1200,7 @@ static void t6_p3(void *argv)
 
 static void t6_p4(void *argv)
 {
+    (void)argv;
     t6_m1.lock();
     for(;;)
     {
@@ -1205,6 +1219,7 @@ static void t6_p4(void *argv)
 
 static void t6_p1a(void *argv)
 {
+    (void)argv;
     t6_m1a.lock();
     seq.add('1');
     Thread::sleep(100);
@@ -1213,6 +1228,7 @@ static void t6_p1a(void *argv)
 
 static void t6_p2a(void *argv)
 {
+    (void)argv;
     t6_m1a.lock();
     seq.add('2');
     Thread::sleep(100);
@@ -1221,6 +1237,7 @@ static void t6_p2a(void *argv)
 
 static void t6_p3a(void *argv)
 {
+    (void)argv;
     t6_m1a.lock();
     seq.add('3');
     Thread::sleep(100);
@@ -1229,6 +1246,7 @@ static void t6_p3a(void *argv)
 
 static void t6_p4a(void *argv)
 {
+    (void)argv;
     t6_m1a.lock();
     for(;;)
     {
@@ -1251,6 +1269,7 @@ static FastMutex t6_m2a;
 
 static void t6_p5(void *argv)
 {
+    (void)argv;
     for(;;)
     {
         if(Thread::testTerminate()) break;
@@ -1266,6 +1285,7 @@ static void t6_p5(void *argv)
 
 static void t6_p5a(void *argv)
 {
+    (void)argv;
     for(;;)
     {
         if(Thread::testTerminate()) break;
@@ -1305,6 +1325,7 @@ static FastMutex t6_m5a(FastMutex::RECURSIVE);
 
 static void *t6_p7(void *argv)
 {
+    (void)argv;
     if(t6_m5.tryLock()==false) return reinterpret_cast<void*>(1); // 1 = locked
     t6_m5.unlock();
     return reinterpret_cast<void*>(0); // 0 = unlocked
@@ -1320,6 +1341,7 @@ bool checkIft6_m5IsLocked()
 
 static void *t6_p7a(void *argv)
 {
+    (void)argv;
     if(t6_m5a.tryLock()==false) return reinterpret_cast<void*>(1); // 1 = locked
     t6_m5a.unlock();
     return reinterpret_cast<void*>(0); // 0 = unlocked
@@ -1741,6 +1763,7 @@ static Queue<char,4> t8_q2;
 
 static void t8_p1(void *argv)
 {
+    (void)argv;
     for(;;)
     {
         if(Thread::testTerminate()) break;
@@ -1985,6 +2008,7 @@ void t10_f2()
 
 void t10_p1(void *argv)
 {
+    (void)argv;
     t10_f2();
     fail("Exception not thrown");
 }
@@ -2011,6 +2035,7 @@ static volatile unsigned int t11_v1;//Free heap after spawning thread
 
 void t11_p1(void *argv)
 {
+    (void)argv;
     if(MemoryProfiling::getStackSize()!=STACK_SMALL) fail("getStackSize (2)");
     //Check that getCurrentFreeHeap returns the same value from different
     //threads if no heap allocation happened in between
@@ -2032,7 +2057,8 @@ void test_11()
         fail("getAbsoluteFreeStack (1)");
     if(MemoryProfiling::getAbsoluteFreeStack()>curFreeStack-4)
         fail("getAbsoluteFreeStack (2)");
-        unsigned int heapSize=MemoryProfiling::getHeapSize();
+    
+    unsigned int heapSize=MemoryProfiling::getHeapSize();
     if(MemoryProfiling::getCurrentFreeHeap()>heapSize)
         fail("getCurrentFreeHeap");
     if(MemoryProfiling::getAbsoluteFreeHeap()>heapSize)
@@ -2057,12 +2083,14 @@ Mutex t12_m2;
 
 void t12_p1(void *argv)
 {
+    (void)argv;
     Lock<Mutex> l1(t12_m1);
     Lock<Mutex> l2(t12_m2);
 }
 
 void t12_p2(void *argv)
 {
+    (void)argv;
     Lock<Mutex> l(t12_m1);
 }
 
@@ -2265,6 +2293,7 @@ static Mutex t15_m1;
 
 void t15_p1(void *argv)
 {
+    (void)argv;
     for(int i=0;i<10;i++)
     {
         Lock<Mutex> l(t15_m1);
@@ -2276,6 +2305,7 @@ void t15_p1(void *argv)
 
 void t15_p2(void *argv)
 {
+    (void)argv;
     for(int i=0;i<10;i++)
     {
         Lock<Mutex> l(t15_m1);
@@ -2395,6 +2425,7 @@ pthread_cond_t t16_c1=PTHREAD_COND_INITIALIZER;
 
 void *t16_p3(void *argv)
 {
+    (void)argv;
     Thread::sleep(30);
     if(pthread_mutex_trylock(&t16_m1)!=0)
         fail("cond_wait did not release mutex"); //<---
@@ -2408,6 +2439,7 @@ pthread_cond_t t16_c2;
 
 void *t16_p4(void *argv)
 {
+    (void)argv;
     Thread::sleep(30);
     if(pthread_mutex_trylock(&t16_m1)!=0)
         fail("cond_wait did not release mutex (2)"); //<---
@@ -2791,6 +2823,7 @@ static void be()
 
 static void t19_p1(void *argv)
 {
+    (void)argv;
     Thread::sleep(50);
     {
         FastInterruptDisableLock dLock;
@@ -3232,6 +3265,7 @@ struct t22_s1
 
 static void t22_t2(void *argv)
 {
+    (void)argv;
     while(Thread::testTerminate()==false)
     {
         t22_v5=true;
@@ -3958,6 +3992,7 @@ static volatile bool fs_1_error;
 
 static void fs_t1_p1(void *argv)
 {
+    (void)argv;
     FILE *f;
     if((f=fopen("/sd/testdir/file_1.txt","w"))==NULL)
     {
@@ -3990,6 +4025,7 @@ static void fs_t1_p1(void *argv)
 
 static void fs_t1_p2(void *argv)
 {
+    (void)argv;
     FILE *f;
     if((f=fopen("/sd/testdir/file_2.txt","w"))==NULL)
     {
@@ -4022,6 +4058,7 @@ static void fs_t1_p2(void *argv)
 
 static void fs_t1_p3(void *argv)
 {
+    (void)argv;
     FILE *f;
     if((f=fopen("/sd/testdir/file_3.txt","w"))==NULL)
     {
@@ -4558,6 +4595,7 @@ context switch speed
 
 static void b2_p1(void *argv)
 {
+    (void)argv;
     for(;;)
     {
         if(Thread::testTerminate()) break;
diff --git a/src/shared/ActiveObject.h b/src/shared/ActiveObject.h
index f3cd2a415a3e608fa5c29c21b9b14b288a934470..9204180b121e916b0b65a11c39190c19d32c3992 100644
--- a/src/shared/ActiveObject.h
+++ b/src/shared/ActiveObject.h
@@ -26,6 +26,7 @@
 #define SRC_SHARED_ACTIVEOBJECT_H
 
 #include <Common.h>
+
 #include "diagnostic/SkywardStack.h"
 
 /**
@@ -84,9 +85,12 @@ public:
      */
     virtual void stop()
     {
-        should_stop = true;
-        thread->join();
-        stopped = true;
+        if (isRunning())
+        {
+            should_stop = true;
+            thread->join();
+            stopped = true;
+        }
     }
 
     bool isStarted() { return started; }
diff --git a/src/shared/drivers/BusTemplate.h b/src/shared/drivers/BusTemplate.h
index 0a9ebfbc6b2fab8322900d69f2bd86067938703e..da58a217e901fcbb647fd470997cfa875d7a0bbb 100644
--- a/src/shared/drivers/BusTemplate.h
+++ b/src/shared/drivers/BusTemplate.h
@@ -219,7 +219,7 @@ private:
         return n_spi == 1 || n_spi == 2 ? 5 : 6;
     }
 
-    constexpr SPI_TypeDef* getSPIAddr(unsigned n)
+    constexpr SPI_TypeDef* getSPIAddr(unsigned n) const
     {
         return n == 1 ? SPI1 : n == 2 ? SPI2 : SPI3;
     }
diff --git a/src/shared/drivers/Transceiver.h b/src/shared/drivers/Transceiver.h
index 3bfd631a8ee7e878f3ef8293af771ffc3005caaf..fca35311650292d022ce6dff487a496aeb067a46 100644
--- a/src/shared/drivers/Transceiver.h
+++ b/src/shared/drivers/Transceiver.h
@@ -23,8 +23,6 @@
 #ifndef TRANSCEIVER_H
 #define TRANSCEIVER_H
 
-#include <Common.h>
-
 class Transceiver
 {
 public:
diff --git a/src/shared/drivers/Xbee/APIFrameParser.cpp b/src/shared/drivers/Xbee/APIFrameParser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed91fa946236c68d2e6c1f7330fdbe0f63554d68
--- /dev/null
+++ b/src/shared/drivers/Xbee/APIFrameParser.cpp
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "APIFrameParser.h"
+#include "Debug.h"
+
+namespace Xbee
+{
+
+APIFrameParser::APIFrameParser() {}
+
+APIFrameParser::ParseResult APIFrameParser::parse(uint8_t byte, APIFrame* frame)
+{
+    switch (parser_state)
+    {
+        // Look for the start of frame delimiter
+        case ParserState::FIND_START:
+
+            if (byte == START_DELIMITER)
+            {
+                parser_state = ParserState::READ_LENGTH_1;
+            }
+            break;
+        // Read most significant byte of the length
+        case ParserState::READ_LENGTH_1:
+            frame->length = byte;
+            parser_state         = ParserState::READ_LENGTH_2;
+
+            break;
+        // Read least significant byte of the length
+        case ParserState::READ_LENGTH_2:
+            frame->length |= ((uint16_t)byte << 8) & 0xFF00;
+            // At least two frame data bytes (frame_type and a payload)
+            if(swapBytes16(frame->length) < 2)
+            {
+                parser_state = ParserState::FIND_START;
+                return ParseResult::FAIL;
+            }
+
+            if (frame->getFrameDataLength() > FRAME_DATA_SIZE)
+            {
+                parser_state = ParserState::FIND_START;
+                return ParseResult::FAIL;
+            }
+
+            parser_state = ParserState::READ_FRAME_TYPE;
+            break;
+        // Read frame type
+        case ParserState::READ_FRAME_TYPE:
+            frame->frame_type = byte;
+            parser_state             = ParserState::READ_FRAME_DATA;
+            break;
+        // Read the data frame
+        case ParserState::READ_FRAME_DATA:
+            frame->frame_data[current_frame_data_index++] = byte;
+
+            if (current_frame_data_index == frame->getFrameDataLength())
+            {
+                current_frame_data_index = 0;
+                parser_state             = ParserState::READ_CHECKSUM;
+            }
+            break;
+        // Read & verify checksum
+        case ParserState::READ_CHECKSUM:
+            frame->checksum = byte;
+            parser_state           = ParserState::FIND_START;
+
+            if (frame->verifyChecksum())
+            {
+                return ParseResult::SUCCESS;
+            }
+            else
+            {
+                TRACE("[XbeeParser] Wrong packet checksum!\n");
+                return ParseResult::FAIL;
+            }
+            break;
+    }
+
+    if (parser_state != ParserState::FIND_START)
+    {
+        return ParseResult::PARSING;
+    }
+    else
+    {
+        return ParseResult::IDLE;
+    }
+}
+
+}  // namespace Xbee
\ No newline at end of file
diff --git a/src/shared/drivers/Xbee/APIFrameParser.h b/src/shared/drivers/Xbee/APIFrameParser.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4dcaaa039d3a5a6f946713de4b36a5e9cfb41c3
--- /dev/null
+++ b/src/shared/drivers/Xbee/APIFrameParser.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+#include "APIFrames.h"
+
+namespace Xbee
+{
+
+/**
+ * @brief Parses a byte sequence into an Xbee APIFrame
+ */
+class APIFrameParser
+{
+public:
+    /**
+     * @brief Current state of the parser internal state machine
+     */
+    enum class ParserState
+    {
+        FIND_START,
+        READ_LENGTH_1,
+        READ_LENGTH_2,
+        READ_FRAME_TYPE,
+        READ_FRAME_DATA,
+        READ_CHECKSUM
+    };
+
+    /**
+     * @brief Result of the last parse operation
+     *
+     */
+    enum class ParseResult : uint8_t
+    {
+        IDLE = 0,  // No frame has been found yet
+        PARSING,   // Currently paring a frame
+        SUCCESS,   // A frame has been parsed successfully
+        FAIL  // The parsed frame was invalid (eg wrong length, wrong checksum)
+    };
+
+    APIFrameParser();
+
+    /**
+     * @brief Parses a single byte. When this function returns
+     * ParseResult:SUCESS, @p frame contains a valid APIFrame
+     *
+     * @param byte Byte to parse
+     * @param frame Frame to be constructed from the parsed data.
+     * @return ParseResult If SUCCESS is returned, then the provided frame is
+     * valid and can be used
+     */
+    ParseResult parse(uint8_t byte, APIFrame* frame);
+
+    /**
+     * @brief Returns the current state of the parser
+     */
+    ParserState getParserState() { return parser_state; }
+private:
+    ParserState parser_state          = ParserState::FIND_START;
+    uint16_t current_frame_data_index = 0;
+};
+
+}  // namespace Xbee
\ No newline at end of file
diff --git a/src/shared/drivers/Xbee/APIFrames.h b/src/shared/drivers/Xbee/APIFrames.h
new file mode 100644
index 0000000000000000000000000000000000000000..401b76b9ac6538bb9f04fc0fb7201d73947ae554
--- /dev/null
+++ b/src/shared/drivers/Xbee/APIFrames.h
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <ostream>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#ifndef COMPILE_FOR_X86
+#include <interfaces/endianness.h>
+#elif defined(__GNUC__)
+
+#define swapBytes64 __builtin_bswap64
+
+static uint16_t swapBytes16(uint16_t x)
+{
+    return (x & 0xFF00) >> 8 | (x & 0x00FF) << 8;
+}
+#endif
+
+using std::min;
+using std::string;
+
+namespace Xbee
+{
+/// Maximum length for a TX/RX frame payload. User-configurable using the "NP"
+/// AT command or the Xbee configuration software (see Xbee datasheet)
+static constexpr size_t MIN_RX_PACKET_FRAME_SIZE   = 11;
+static constexpr size_t MIN_TX_REQUEST_FRAME_SIZE  = 13;
+static constexpr size_t MIN_AT_COMMAND_FRAME_SIZE  = 3;
+static constexpr size_t MIN_AT_RESPONSE_FRAME_SIZE = 4;
+
+static constexpr size_t TX_STATUS_FRAME_SIZE    = 6;
+static constexpr size_t MODEM_STATUS_FRAME_SIZE = 1;
+
+static constexpr uint16_t MAX_PACKET_PAYLOAD_LENGTH      = 256;
+static constexpr uint16_t MAX_AT_COMMAND_PARAMS_LENGTH   = 20;
+static constexpr uint16_t MAX_AT_COMMAND_RESPONSE_LENGTH = 30;
+
+static constexpr size_t FRAME_DATA_SIZE =
+    MAX_PACKET_PAYLOAD_LENGTH + MIN_TX_REQUEST_FRAME_SIZE;
+
+static constexpr size_t MAX_API_FRAME_SIZE = FRAME_DATA_SIZE + 5;
+static constexpr size_t MIN_API_FRAME_SIZE = 5;
+
+static constexpr uint64_t ADDRESS_BROADCAST = 0xFFFF;
+static constexpr uint8_t START_DELIMITER    = 0x7E;
+
+enum FrameType : uint8_t
+{
+    FTYPE_AT_COMMAND          = 0x08,
+    FTYPE_AT_COMMAND_QUEUE    = 0x09,
+    FTYPE_TX_REQUEST          = 0x10,
+    FTYPE_AT_COMMAND_RESPONSE = 0x88,
+    FTYPE_MODEM_STATUS        = 0x8A,
+    FTYPE_TX_STATUS           = 0x8B,
+    FTYPE_RX_PACKET_FRAME     = 0x90,
+};
+
+enum TransmitOptionsBitfield : uint8_t
+{
+    TO_DISABLE_ACK = 0x01,
+    TO_DISABLE_RD  = 0x02,
+    TO_NACK        = 0x04,
+    TO_TRACE_ROUTE = 0x08,
+
+    TO_DM_POINT_MULTIPOINT = 0x40,
+    TO_DM_REPEATER_MODE    = 0x80,
+    TO_DM_DIGIMESH         = 0xC0
+};
+
+enum CommandStatusBitfield : uint8_t
+{
+    CS_OK                = 0x00,
+    CS_ERROR             = 0x01,
+    CS_INVALID_COMMAND   = 0x02,
+    CS_INVALID_PARAMETER = 0x03,
+    CS_RSSI_INVALID      = 0x40,
+    CS_IS_REMOTE_COMMAND = 0x80
+};
+
+enum ModemStatus : uint8_t
+{
+    MS_HARDWARE_RESET       = 0x00,
+    MS_WATCHDOG_TIMER_RESET = 0x01,
+    MS_NETWORK_WOKE_UP      = 0x0B,
+    MS_NETWORK_WENT_SLEEP   = 0x0C,
+};
+
+enum DeliveryStatus : uint8_t
+{
+    DELS_SUCCESS               = 0x00,
+    DELS_MAC_ACK_FAILURE       = 0x01,
+    DELS_COLL_AVOID_FAILURE    = 0x02,
+    DELS_NO_SPECTRUM_AVAILABLE = 0x03,
+    DELS_NET_ACK_FAILURE       = 0x21,
+    DELS_ROUTE_NOT_FOUND       = 0x25,
+    DELS_INT_RESOURCE_ERR      = 0x31,
+    DELS_INTERNAL_ERROR        = 0x32,
+    DELS_PAYLOAD_TOO_LARGE     = 0x74,
+    DELS_INDIRECT_MSG_REQ      = 0x75,
+};
+
+enum DiscoveryStatus : uint8_t
+{
+    DISCS_NO_DISC_OVERHEAD = 0x00,
+    DISCS_ROUTE_DISCOVERY  = 0x02
+};
+
+enum ReceiveOptions : uint8_t
+{
+    RO_PACKET_ACK          = 0x00,
+    RO_PACKET_IS_BROADCAST = 0x01,
+    RO_POINT_MULTIPOINT    = 0x40,
+    RO_REPEATER_MODE       = 0x80,
+    RO_DIGIMESH            = 0xC0,
+};
+
+#pragma pack(1)
+struct APIFrame
+{
+    uint8_t start_del  = 0x7E;
+    uint16_t length    = 0;
+    uint8_t frame_type = 0;
+    uint8_t frame_data[FRAME_DATA_SIZE];
+
+    uint8_t checksum = 0;
+    // Used for logging, not part of the standard Xbee API Frame
+    long long timestamp = 0;
+
+    APIFrame() { memset(frame_data, 0, FRAME_DATA_SIZE); }
+
+    uint16_t getFrameDataLength() const
+    {
+        size_t len = swapBytes16(length) - 1;
+        assert(len <= FRAME_DATA_SIZE);
+
+        return min(len, FRAME_DATA_SIZE);
+    }
+
+    void setFrameDataLength(uint16_t len)
+    {
+        assert(len <= FRAME_DATA_SIZE);
+        length = swapBytes16(min((size_t)(len + 1), FRAME_DATA_SIZE + 1));
+    }
+
+    bool verifyChecksum() const
+    {
+        assert(getFrameDataLength() <= FRAME_DATA_SIZE);
+        // Sum all the bytes including checksum and frame type.
+        // The sum can be stored in a uint8_t since we only care about the least
+        // significant byte.
+        uint8_t sum = checksum + frame_type;
+        for (uint16_t i = 0; i < getFrameDataLength(); ++i)
+        {
+            sum += frame_data[i];
+        }
+        return sum == 0xFF;
+    }
+
+    void calcChecksum()
+    {
+        assert(getFrameDataLength() <= FRAME_DATA_SIZE);
+        checksum = frame_type;
+        for (uint16_t i = 0; i < getFrameDataLength(); ++i)
+        {
+            checksum += frame_data[i];
+        }
+
+        checksum = 0xFF - checksum;
+    }
+
+    template <typename FrameType>
+    FrameType* toFrameType()
+    {
+        static_assert(
+            std::is_base_of<APIFrame, FrameType>::value ||
+                std::is_same<APIFrame, FrameType>::value,
+            "FrameType must be derived from APIFrame or be an APIFrame");
+
+        return reinterpret_cast<FrameType*>(this);
+    }
+
+    size_t toBytes(uint8_t* bytes)
+    {
+        memcpy(bytes, this, 4 + getFrameDataLength());
+
+        bytes[4 + getFrameDataLength()] = checksum;
+        return 5 + getFrameDataLength();
+    }
+
+    static bool fromBytes(uint8_t* bytes, size_t size, APIFrame* f)
+    {
+        if (size >= MIN_API_FRAME_SIZE && size <= MAX_API_FRAME_SIZE)
+        {
+            memcpy(f, bytes, size - 1);
+            f->checksum = bytes[size - 1];
+
+            return true;
+        }
+        return false;
+    }
+};
+#pragma pack()
+struct ATCommandFrame : public APIFrame
+{
+    ATCommandFrame() : APIFrame()
+    {
+        frame_type = FTYPE_AT_COMMAND;
+        setFrameDataLength(MIN_AT_COMMAND_FRAME_SIZE);
+    }
+
+    uint8_t getFrameID() const { return frame_data[0]; }
+
+    void setFrameID(uint8_t frame_id) { frame_data[0] = frame_id; }
+
+    const char* getATCommand() const
+    {
+        return reinterpret_cast<const char*>(&frame_data[1]);
+    }
+
+    void setATCommand(const char* at)
+    {
+        frame_data[1] = at[0];
+        frame_data[2] = at[1];
+    }
+
+    uint8_t* getCommandDataPointer() { return &frame_data[3]; }
+
+    uint16_t getCommandDataLength() const
+    {
+        return getFrameDataLength() - MIN_AT_COMMAND_FRAME_SIZE;
+    }
+
+    void setParameterSize(uint16_t size)
+    {
+        assert(size <= FRAME_DATA_SIZE - MIN_AT_COMMAND_FRAME_SIZE);
+        size = min((size_t)size, FRAME_DATA_SIZE - MIN_AT_COMMAND_FRAME_SIZE);
+
+        setFrameDataLength(MIN_AT_COMMAND_FRAME_SIZE + size);
+    }
+};
+static_assert(sizeof(ATCommandFrame) == sizeof(APIFrame),
+              "Size of derived classes must be the same as APIFrame class (no "
+              "additional members & no virtual functions)");
+
+struct ATCommandResponseFrame : public APIFrame
+{
+    ATCommandResponseFrame() : APIFrame()
+    {
+        frame_type = FTYPE_AT_COMMAND_RESPONSE;
+        setFrameDataLength(MIN_AT_RESPONSE_FRAME_SIZE);
+    }
+
+    uint8_t getFrameID() const { return frame_data[0]; }
+
+    void setFrameID(uint8_t frame_id) { frame_data[0] = frame_id; }
+
+    const char* getATCommand() const
+    {
+        return reinterpret_cast<const char*>(&frame_data[1]);
+    }
+
+    void setATCommand(const char* at)
+    {
+        frame_data[1] = at[0];
+        frame_data[2] = at[1];
+    }
+
+    uint8_t getCommandStatus() const { return frame_data[3]; }
+
+    void setCommandStatus(uint8_t cs) { frame_data[3] = cs; }
+
+    uint8_t* getCommandDataPointer() { return &frame_data[4]; }
+
+    uint16_t getCommandDataLength() const
+    {
+        return getFrameDataLength() - MIN_AT_RESPONSE_FRAME_SIZE;
+    }
+
+    void setCommandDataSize(uint16_t size)
+    {
+        assert(size <= FRAME_DATA_SIZE - MIN_AT_RESPONSE_FRAME_SIZE);
+        size = min((size_t)size, FRAME_DATA_SIZE - MIN_AT_RESPONSE_FRAME_SIZE);
+
+        setFrameDataLength(MIN_AT_RESPONSE_FRAME_SIZE + size);
+    }
+};
+static_assert(sizeof(ATCommandFrame) == sizeof(APIFrame),
+              "Size of derived classes must be the same as APIFrame class (no "
+              "additional members & no virtual functions)");
+
+struct TXRequestFrame : public APIFrame
+{
+    TXRequestFrame() : APIFrame()
+    {
+        frame_type = FTYPE_TX_REQUEST;
+        setFrameDataLength(MIN_TX_REQUEST_FRAME_SIZE);
+
+        // Reserved bytes
+        frame_data[9]  = 0xFF;
+        frame_data[10] = 0xFE;
+    }
+
+    uint8_t getFrameID() const { return frame_data[0]; }
+
+    void setFrameID(uint8_t frame_id) { frame_data[0] = frame_id; }
+
+    uint64_t getDestAddress() const
+    {
+        uint64_t addr;
+        memcpy(&addr, &frame_data[1], sizeof(uint64_t));
+        return swapBytes64(addr);
+    }
+
+    void setDestAddress(uint64_t address)
+    {
+        address = swapBytes64(address);
+        memcpy(&frame_data[1], &address, 8);
+    }
+
+    uint8_t getBroadcastRadius() const { return frame_data[11]; }
+
+    void setBroadcastRadius(uint8_t br) { frame_data[11] = br; }
+
+    uint8_t getTrasmitOptions() const { return frame_data[12]; }
+
+    void setTransmitOptions(uint8_t br) { frame_data[12] = br; }
+
+    uint8_t* getRFDataPointer() { return &frame_data[13]; }
+
+    uint16_t getRFDataLength() const
+    {
+        return min((size_t)(getFrameDataLength() - MIN_TX_REQUEST_FRAME_SIZE),
+                   (size_t)MAX_PACKET_PAYLOAD_LENGTH);
+    }
+
+    void setRFDataLength(uint16_t size)
+    {
+        assert(size <= MAX_PACKET_PAYLOAD_LENGTH);
+        size = min(size, MAX_PACKET_PAYLOAD_LENGTH);
+
+        setFrameDataLength(MIN_TX_REQUEST_FRAME_SIZE + size);
+    }
+};
+static_assert(sizeof(TXRequestFrame) == sizeof(APIFrame),
+              "Size of derived classes must be the same as APIFrame class (no "
+              "additional members & no virtual functions)");
+
+struct ModemStatusFrame : public APIFrame
+{
+    ModemStatusFrame() : APIFrame()
+    {
+        frame_type = FTYPE_MODEM_STATUS;
+        setFrameDataLength(MODEM_STATUS_FRAME_SIZE);
+    }
+
+    uint8_t getStatus() const { return frame_data[0]; }
+
+    void setStatus(uint8_t status) { frame_data[0] = status; }
+};
+static_assert(sizeof(ModemStatusFrame) == sizeof(APIFrame),
+              "Size of derived classes must be the same as APIFrame class (no "
+              "additional members & no virtual functions)");
+
+struct TXStatusFrame : public APIFrame
+{
+    TXStatusFrame() : APIFrame()
+    {
+        frame_type = FTYPE_TX_STATUS;
+        setFrameDataLength(TX_STATUS_FRAME_SIZE);
+
+        // Reserved bytes
+        frame_data[1] = 0xFF;
+        frame_data[2] = 0xFE;
+    }
+
+    uint8_t getFrameID() const { return frame_data[0]; }
+
+    void setFrameID(uint8_t frame_id) { frame_data[0] = frame_id; }
+
+    uint8_t getTransmitRetryCount() const { return frame_data[3]; }
+
+    void setTransmitRetryCount(uint8_t trc) { frame_data[3] = trc; }
+
+    uint8_t getDeliveryStatus() const { return frame_data[4]; }
+
+    void setDeliveryStatus(uint8_t ds) { frame_data[4] = ds; }
+
+    uint8_t getDiscoveryStatus() const { return frame_data[5]; }
+
+    void setDiscoveryStatus(uint8_t ds) { frame_data[5] = ds; }
+};
+
+static_assert(sizeof(TXStatusFrame) == sizeof(APIFrame),
+              "Size of derived classes must be the same as APIFrame class (no "
+              "additional members & no virtual functions)");
+
+struct RXPacketFrame : public APIFrame
+{
+    RXPacketFrame() : APIFrame()
+    {
+        frame_type = FTYPE_RX_PACKET_FRAME;
+        setFrameDataLength(MIN_RX_PACKET_FRAME_SIZE);
+
+        frame_data[8] = 0xFF;
+        frame_data[9] = 0xFE;
+    }
+
+    uint64_t getSourceAddress() const
+    {
+        uint64_t addr;
+        memcpy(&addr, &frame_data[0], sizeof(uint64_t));
+        return swapBytes64(addr);
+    }
+
+    void setSourceAddress(uint64_t address)
+    {
+        address       = swapBytes64(address);
+        uint8_t* addr = reinterpret_cast<uint8_t*>(&address);
+
+        memcpy(&frame_data[0], addr, 8);
+    }
+
+    uint8_t getReceiveOptions() const { return frame_data[10]; }
+
+    void setReceiveOptions(uint8_t ro) { frame_data[10] = ro; }
+
+    uint8_t* getRXDataPointer() { return &frame_data[11]; }
+
+    uint16_t getRXDataLength() const
+    {
+        return min((size_t)(getFrameDataLength() - MIN_RX_PACKET_FRAME_SIZE),
+                   (size_t)MAX_PACKET_PAYLOAD_LENGTH);
+    }
+
+    void setRXDataLength(uint16_t size)
+    {
+        assert(size <= MAX_PACKET_PAYLOAD_LENGTH);
+        size = min(size, MAX_PACKET_PAYLOAD_LENGTH);
+
+        setFrameDataLength(MIN_RX_PACKET_FRAME_SIZE + size);
+    }
+};
+
+static_assert(sizeof(RXPacketFrame) == sizeof(APIFrame),
+              "Size of derived classes must be the same as APIFrame class (no "
+              "additional members & no virtual functions)");
+}  // namespace Xbee
\ No newline at end of file
diff --git a/src/shared/drivers/Xbee/APIFramesLog.h b/src/shared/drivers/Xbee/APIFramesLog.h
new file mode 100644
index 0000000000000000000000000000000000000000..d97736f8a38fa9b5a9a34c78820b96008763247b
--- /dev/null
+++ b/src/shared/drivers/Xbee/APIFramesLog.h
@@ -0,0 +1,394 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <cstdint>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "APIFrames.h"
+
+using std::min;
+
+/**
+ * Classes used if you want to log an APIFrame, but do not want to log the base
+ * APIFrame class, which is quite heavy on memory
+ */
+
+namespace Xbee
+{
+
+struct APIFrameLog
+{
+    long long timestamp;
+    uint8_t frame_type;
+    uint16_t frame_data_length;
+    uint8_t frame_data[FRAME_DATA_SIZE];
+
+    static bool fromAPIFrame(APIFrame& api, APIFrameLog* dest)
+    {
+        dest->timestamp         = api.timestamp;
+        dest->frame_type        = api.frame_type;
+        dest->frame_data_length = api.getFrameDataLength();
+
+        memcpy(dest->frame_data, api.frame_data, dest->frame_data_length);
+
+        return true;
+    }
+
+    static string header() { return "timestamp,length,frame_type\n"; }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << frame_data_length << "," << frame_type
+           << "\n";
+    }
+};
+
+struct ATCommandFrameLog
+{
+    long long timestamp;
+    uint8_t frame_id = 0;
+    char at_command[2];
+
+    uint8_t command_data[MAX_AT_COMMAND_PARAMS_LENGTH];
+    uint16_t command_data_length = 0;
+
+    static bool toFrameType(APIFrame& api, ATCommandFrameLog* dest)
+    {
+        if (api.frame_type != FTYPE_AT_COMMAND)
+        {
+            return false;
+        }
+
+        if (api.getFrameDataLength() < MIN_AT_COMMAND_FRAME_SIZE ||
+            api.getFrameDataLength() >
+                MIN_AT_COMMAND_FRAME_SIZE + MAX_AT_COMMAND_PARAMS_LENGTH)
+        {
+            return false;
+        }
+        ATCommandFrame* at = api.toFrameType<ATCommandFrame>();
+
+        dest->timestamp = at->timestamp;
+        dest->frame_id  = at->getFrameID();
+
+        memcpy(dest->at_command, at->getATCommand(), 2);
+
+        dest->command_data_length = at->getCommandDataLength();
+        memcpy(dest->command_data, at->getCommandDataPointer(),
+               dest->command_data_length);
+
+        return true;
+    }
+
+    static string header() { return "timestamp,id,cmd,param_size,params\n"; }
+
+    void print(std::ostream& os) const
+    {
+        char cmd[3];
+
+        strncpy(cmd, at_command, 2);
+        cmd[2] = '\0';
+
+        os << timestamp << "," << (int)frame_id << "," << cmd << ","
+           << command_data_length << ",";
+
+        if (command_data_length > 0)
+        {
+            for (uint16_t i = 0; i < command_data_length; i++)
+            {
+                os << (int)command_data[i] << " ";
+            }
+        }
+        else
+        {
+            os << "-";
+        }
+
+        os << "\n";
+    }
+};
+
+struct TXRequestFrameLog
+{
+    long long timestamp = 0;
+    uint8_t frame_id    = 0;
+
+    uint64_t dest_address = 0;
+
+    uint8_t broadcast_radius = 0;
+    uint8_t transmit_options = 0;
+
+    uint8_t rf_data[MAX_PACKET_PAYLOAD_LENGTH];
+    uint16_t rf_data_length = 0;
+
+    static bool toFrameType(APIFrame& api, TXRequestFrameLog* dest)
+    {
+        if (api.frame_type != FTYPE_TX_REQUEST)
+        {
+            return false;
+        }
+
+        if (api.getFrameDataLength() < MIN_TX_REQUEST_FRAME_SIZE ||
+            api.getFrameDataLength() >
+                MIN_TX_REQUEST_FRAME_SIZE + MAX_PACKET_PAYLOAD_LENGTH)
+        {
+            return false;
+        }
+
+        TXRequestFrame* tx = api.toFrameType<TXRequestFrame>();
+
+        dest->timestamp = api.timestamp;
+        dest->frame_id  = tx->getFrameID();
+
+        dest->dest_address = tx->getDestAddress();
+
+        dest->broadcast_radius = tx->getBroadcastRadius();
+        dest->transmit_options = tx->getTrasmitOptions();
+
+        dest->rf_data_length = tx->getRFDataLength();
+        memcpy(dest->rf_data, tx->getRFDataPointer(), dest->rf_data_length);
+
+        return true;
+    }
+
+    static string header()
+    {
+        return "timestamp,id,dest_addr,broadcast_radius,tx_options,rf_data_"
+               "len,first_uint32\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        uint32_t d;
+        memcpy(&d, rf_data, sizeof(d));
+        os << timestamp << "," << (int)frame_id << "," << dest_address << ","
+           << (int)broadcast_radius << "," << (int)transmit_options << ","
+           << rf_data_length << "," << d << "\n";
+    }
+};
+
+struct ATCommandResponseFrameLog
+{
+    long long timestamp = 0;
+    uint8_t frame_id    = 0;
+    char at_command[2];
+    uint8_t command_status = 0;
+
+    uint8_t command_data[MAX_AT_COMMAND_RESPONSE_LENGTH];
+    uint16_t command_data_length = 0;
+
+    static bool toFrameType(APIFrame& api, ATCommandResponseFrameLog* dest)
+    {
+        if (api.frame_type != FTYPE_AT_COMMAND_RESPONSE)
+        {
+            return false;
+        }
+
+        if (api.getFrameDataLength() < MIN_AT_COMMAND_FRAME_SIZE ||
+            api.getFrameDataLength() >
+                MIN_AT_COMMAND_FRAME_SIZE + MAX_AT_COMMAND_RESPONSE_LENGTH)
+        {
+            return false;
+        }
+
+        ATCommandResponseFrame* at = api.toFrameType<ATCommandResponseFrame>();
+
+        dest->timestamp = api.timestamp;
+        dest->frame_id  = at->getFrameID();
+        memcpy(dest->at_command, at->getATCommand(), 2);
+
+        dest->command_status = at->getCommandStatus();
+
+        dest->command_data_length = at->getCommandDataLength();
+        memcpy(dest->command_data, at->getCommandDataPointer(),
+               dest->command_data_length);
+
+        return true;
+    }
+
+    static string header()
+    {
+        return "timestamp,id,cmd,status,param_size,params\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        char cmd[3];
+
+        strncpy(cmd, at_command, 2);
+        cmd[2] = '\0';
+
+        os << timestamp << "," << (int)frame_id << "," << cmd << ","
+           << (int)command_status << "," << command_data_length << ",";
+
+        if (command_data_length > 0)
+        {
+            for (uint16_t i = 0; i < command_data_length; i++)
+            {
+                os << (int)command_data[i] << " ";
+            }
+        }
+        else
+        {
+            os << "-";
+        }
+
+        os << "\n";
+    }
+};
+
+struct ModemStatusFrameLog
+{
+    long long timestamp  = 0;
+    uint8_t modem_status = 0;
+
+    static bool toFrameType(APIFrame& api, ModemStatusFrameLog* dest)
+    {
+        if (api.frame_type != FTYPE_MODEM_STATUS)
+        {
+            return false;
+        }
+
+        if (api.getFrameDataLength() != MODEM_STATUS_FRAME_SIZE)
+        {
+            return false;
+        }
+
+        ModemStatusFrame* modem = api.toFrameType<ModemStatusFrame>();
+
+        dest->timestamp    = api.timestamp;
+        dest->modem_status = modem->getStatus();
+
+        return true;
+    }
+
+    static string header() { return "timestamp,status\n"; }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << (int)modem_status << "\n";
+    }
+};
+
+struct TXStatusFrameLog
+{
+    long long timestamp      = 0;
+    uint8_t frame_id         = 0;
+    uint8_t tx_retry_count   = 0;
+    uint8_t delivery_status  = 0;
+    uint8_t discovery_status = 0;
+
+    static bool toFrameType(APIFrame& api, TXStatusFrameLog* dest)
+    {
+        if (api.frame_type != FTYPE_TX_STATUS)
+        {
+            return false;
+        }
+
+        if (api.getFrameDataLength() != TX_STATUS_FRAME_SIZE)
+        {
+            return false;
+        }
+
+        TXStatusFrame* tx = api.toFrameType<TXStatusFrame>();
+
+        dest->timestamp = api.timestamp;
+        dest->frame_id  = tx->getFrameID();
+
+        dest->tx_retry_count   = tx->getTransmitRetryCount();
+        dest->delivery_status  = tx->getDeliveryStatus();
+        dest->discovery_status = tx->getDiscoveryStatus();
+
+        return true;
+    }
+
+    static string header()
+    {
+        return "timestamp,id,tx_retries,delivery_status,discovery_status\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << (int)frame_id << "," << (int)tx_retry_count
+           << "," << (int)delivery_status << "," << (int)discovery_status
+           << "\n";
+    }
+};
+
+struct RXPacketFrameLog
+{
+    long long timestamp = 0;
+
+    uint64_t source_address = 0;
+
+    uint8_t receive_options = 0;
+
+    uint8_t rx_data[MAX_PACKET_PAYLOAD_LENGTH];
+    uint16_t rx_data_length = 0;
+
+    static bool toFrameType(APIFrame& api, RXPacketFrameLog* dest)
+    {
+        if (api.frame_type != FTYPE_RX_PACKET_FRAME)
+        {
+            return false;
+        }
+
+        if (api.getFrameDataLength() < MIN_RX_PACKET_FRAME_SIZE ||
+            api.getFrameDataLength() >
+                MIN_RX_PACKET_FRAME_SIZE + MAX_PACKET_PAYLOAD_LENGTH)
+        {
+            return false;
+        }
+
+        RXPacketFrame* rx = api.toFrameType<RXPacketFrame>();
+
+        dest->timestamp      = api.timestamp;
+        dest->source_address = rx->getSourceAddress();
+
+        dest->receive_options = rx->getReceiveOptions();
+
+        dest->rx_data_length = rx->getRXDataLength();
+        memcpy(dest->rx_data, rx->getRXDataPointer(), dest->rx_data_length);
+
+        return true;
+    }
+
+    static string header()
+    {
+        return "timestamp,src_addr,rx_options,rx_data_size,payload32_0,payload32_1\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        uint32_t data[2];
+        memcpy(&data, rx_data, min(sizeof(uint32_t)*2, (size_t)rx_data_length));
+        os << timestamp << "," << source_address << "," << (int)receive_options
+           << "," << rx_data_length << "," << data[0] << "," << data[1] << "\n";
+    }
+};
+
+}  // namespace Xbee
\ No newline at end of file
diff --git a/src/shared/drivers/Xbee/ATCommands.h b/src/shared/drivers/Xbee/ATCommands.h
new file mode 100644
index 0000000000000000000000000000000000000000..09280f9b74ff1b46c370019d921ecaf7ba8e1eed
--- /dev/null
+++ b/src/shared/drivers/Xbee/ATCommands.h
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "APIFrames.h"
+#include "Xbee.h"
+
+namespace Xbee
+{
+
+/**
+ * @brief Enables or disable the specified channels. Channel 9 and 24 are always
+ * disabled due to regulatory limitations.
+ * See datasheet for the list of channel frequencies.
+ *
+ * @param xbee Reference to an xbee object
+ * @param channels channel mask
+ * @return True if the command was executed successfully
+ */
+bool setChannelMask(Xbee& xbee, uint32_t mask, unsigned int timeout = 1000)
+{
+    ATCommandResponseFrame response;
+
+    mask = swapBytes32(mask);
+
+    return xbee.sendATCommand("CM", &response,
+                              reinterpret_cast<uint8_t*>(&mask), 4, timeout);
+}
+
+/**
+ * @brief Enables or disable the specified channels. Channel 9 and 24 are always
+ * disabled due to regulatory limitations.
+ * See datasheet for the list of channel frequencies.
+ *
+ * @param xbee Reference to an xbee object
+ * @param channels channel mask array
+ *
+ * @return True if the command was executed successfully
+ */
+bool setChannelMask(Xbee& xbee, bool channels[30], unsigned int timeout = 1000)
+{
+    uint32_t val = 0;
+
+    for (int i = 0; i < 30; i++)
+    {
+        val &= ((uint32_t)channels[i]) << i;
+    }
+
+    return setChannelMask(xbee, val, timeout);
+}
+
+/**
+ * @brief Enable communication on all available channels. Equivalent to calling
+ * setChannelMask(xbee, 0x3EFFFDFF).
+ *
+ * @param xbee Reference to an xbee object
+ * @return True if the command was executed successfully
+ */
+bool enableAllChannels(Xbee& xbee, unsigned int timeout = 1000)
+{
+    return setChannelMask(xbee, 0x3EFFFDFF, timeout);
+}
+
+/**
+ * @brief Disables frequency hopping by allowing communication only on channel
+ * #29. Equivalent to calling setChannelMask(xbee, 0x20000000).
+ *
+ * @param xbee Reference to an xbee object
+ */
+bool disableFrequencyHopping(Xbee& xbee, unsigned int timeout = 1000)
+{
+    return setChannelMask(xbee, 0x20000000, timeout);
+}
+
+/**
+ * @brief Configures the desired xbee data rate.
+ *
+ * @param xbee Reference to an xbee object
+ * @param data_rate_80kbps true for 80kbps, false for 10kbps
+ * @return True if the command was executed successfully
+ */
+bool setDataRate(Xbee& xbee, bool data_rate_80kbps, unsigned int timeout = 1000)
+{
+    uint8_t param = (uint8_t)data_rate_80kbps;
+    ATCommandResponseFrame response;
+
+    return xbee.sendATCommand("BR", &response, &param, 1, timeout);
+}
+
+/**
+ * @brief Writes parameter values to non-volatile memory so that parameter
+ * modifications persist through subsequent resets.
+ *
+ * @param xbee Reference to an xbee object
+ * @return True if the command was executed successfully
+ */
+bool writeToMemory(Xbee& xbee, unsigned int timeout = 1000)
+{
+    ATCommandResponseFrame response;
+    return xbee.sendATCommand("WR", &response, nullptr, 0, timeout);
+}
+
+/**
+ * @brief Performs an energy detect scan on all channels
+ *
+ * @param xbee Reference to an xbee object
+ * @param energy_detect_data Pointer to a 30-bytes buffer where energy levels
+ * will be stored. Energy levels are in -dBm units.
+ * @param duration Scan duration in ms
+ * @return True if the command was executed successfully and data stored in
+ * energy_detect_data is valid
+ */
+bool energyDetect(Xbee& xbee, int* energy_detect_data, uint8_t duration,
+                  unsigned int timeout = 1000)
+{
+    ATCommandResponseFrame response;
+    if (xbee.sendATCommand("ED", &response, &duration, 1, timeout))
+    {
+        uint16_t resp_len = response.getCommandDataLength();
+        if (resp_len == 30)
+        {
+            for (int i = 0; i < 30; i++)
+            {
+                energy_detect_data[i] =
+                    (int)(*(response.getCommandDataPointer() + i));
+            }
+
+            return true;
+        }
+    }
+    return false;
+}
+
+}  // namespace Xbee
diff --git a/src/shared/drivers/Xbee/Xbee.cpp b/src/shared/drivers/Xbee/Xbee.cpp
index 4cc53fb6b2ba165fd28aa69da0a2877b28f2f986..965f158edab37589f0082608a1bb5a592e3f0683 100644
--- a/src/shared/drivers/Xbee/Xbee.cpp
+++ b/src/shared/drivers/Xbee/Xbee.cpp
@@ -1,17 +1,17 @@
 /**
- * Copyright (c) 2019 Skyward Experimental Rocketry
- * Authors: Luca Erbetta
- * 
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
@@ -23,7 +23,512 @@
 
 #include "Xbee.h"
 
+#include <Debug.h>
+#include <kernel/scheduler/scheduler.h>
+#include <miosix.h>
+
+#include <algorithm>
+
+using miosix::FastMutex;
+using miosix::Lock;
+using miosix::Unlock;
+using std::min;
+
 namespace Xbee
 {
-miosix::Thread* waiting = nullptr;
-}
\ No newline at end of file
+
+Xbee::Xbee(SPIBusInterface& bus, GpioType cs, GpioType attn, GpioType rst,
+           long long tx_timeout)
+    : Xbee(bus, {}, cs, attn, rst, tx_timeout)
+{
+    spi_xbee.config.clock_div = SPIClockDivider::DIV128;
+}
+
+Xbee::Xbee(SPIBusInterface& bus, SPIBusConfig config, GpioType cs,
+           GpioType attn, GpioType rst, long long tx_timeout)
+    : spi_xbee(bus, cs, config), attn(attn), rst(rst), tx_timeout(tx_timeout)
+{
+    reset();
+}
+
+Xbee::~Xbee() { wakeReceiver(true); }
+
+bool Xbee::send(uint8_t* pkt, size_t pkt_len)
+{
+    if (pkt_len > MAX_PACKET_PAYLOAD_LENGTH || pkt_len == 0)
+    {
+        TRACE("[Xbee] Invalid packet length (0< %u <= %u)\n", pkt_len,
+              MAX_PACKET_PAYLOAD_LENGTH);
+        return false;
+    }
+    long long start_tick = miosix::getTick();
+
+    TXRequestFrame tx_req;
+    uint8_t tx_frame_id = buildTXRequestFrame(tx_req, pkt, pkt_len);
+    bool success        = false;
+    bool status_timeout = true;
+    {
+        Lock<FastMutex> l(mutex_xbee_comm);
+        writeFrame(tx_req);
+
+        // Wait for a TX Status frame
+        long long timeout_tick = miosix::getTick() + tx_timeout;
+
+        while (waitForFrame(FTYPE_TX_STATUS, FRAME_POLL_INTERVAL, timeout_tick))
+        {
+            TXStatusFrame* f = parsing_api_frame.toFrameType<TXStatusFrame>();
+
+            if (f->getFrameID() == tx_frame_id)
+            {
+                success        = f->getDeliveryStatus() == DELS_SUCCESS;
+                status_timeout = false;
+                break;
+            }
+            else
+            {
+                TRACE("[Xbee] Wrong tx_status ID\n");
+            }
+        }
+
+        // Ak for total transmitted byte count for logging  purposes
+        sendATCommandInternal("BC");
+    }
+
+    // If there is more data to receive, wake the receive() thread
+    if (attn.value() == 0)
+    {
+        wakeReceiver();
+    }
+    if (status_timeout)
+    {
+        ++status.tx_timeout_count;
+        TRACE("[Xbee] TX_STATUS timeout\n");
+    }
+    time_to_send_stats.add(miosix::getTick() - start_tick);
+    return success;
+}
+
+ssize_t Xbee::receive(uint8_t* buf, size_t buf_max_size)
+{
+    while (true)
+    {
+        // We have data in the buffer pending to be returned
+        if (!rx_frames_buf.isEmpty() || curr_rx_payload_ptr >= 0)
+        {
+            return fillReceiveBuf(buf, buf_max_size);
+        }
+        // No data in the buffer, but the xbee has data to return via SPI
+        else if (attn.value() == 0)
+        {
+            Lock<FastMutex> l(mutex_xbee_comm);
+            if (readRXFrame())
+            {
+                sendATCommandInternal("DB");  // Query last packet RSSI
+                sendATCommandInternal("ER");  // Query receive error count
+            }
+        }
+        // No data available at all: sleep until we have something to do
+        else
+        {
+            {
+                miosix::FastInterruptDisableLock dLock;
+                receive_thread = miosix::Thread::getCurrentThread();
+
+                while (receive_thread != 0)  // Avoid spurious wakeups
+                {
+                    receive_thread->IRQwait();
+                    {
+                        miosix::FastInterruptEnableLock eLock(dLock);
+                        miosix::Thread::yield();
+                    }
+                }
+            }
+
+            // Forcefully return without receiving anything
+            if (force_rcv_return)
+            {
+                force_rcv_return = false;
+                return -1;
+            }
+        }
+    }
+}
+
+XbeeStatus Xbee::getStatus()
+{
+    status.timestamp          = miosix::getTick();
+    status.time_to_send_stats = time_to_send_stats.getStats();
+    return status;
+}
+
+void Xbee::reset()
+{
+    Lock<FastMutex> l(mutex_xbee_comm);
+    {
+        miosix::FastInterruptDisableLock dLock();
+        rst.mode(miosix::Mode::OPEN_DRAIN);
+    }
+    rst.low();
+    miosix::delayUs(50);
+    rst.high();
+
+    // When the xbee is ready, we should assert SSEL to tell it to use
+    // SPI, and it should provide us with a modem status frame
+    long long timeout = miosix::getTick() + 1000;
+    do
+    {
+        // Assert SSEL on every iteration as we don't exactly know when the
+        // xbee will be ready.
+        {
+            SPIAcquireLock acq(spi_xbee);
+            spi_xbee.cs.low();
+            miosix::delayUs(10);
+            spi_xbee.cs.high();
+        }
+
+        miosix::delayUs(50);
+
+        if (attn.value() == 0 && readOneFrame() == ParseResult::SUCCESS)
+        {
+            handleFrame(parsing_api_frame);
+
+            if (parsing_api_frame.frame_type == FTYPE_MODEM_STATUS)
+            {
+                break;
+            }
+        }
+        miosix::Thread::sleep(5);
+    } while (miosix::getTick() < timeout);
+}
+
+void Xbee::wakeReceiver(bool force_return)
+{
+    force_rcv_return = force_return;
+    miosix::FastInterruptDisableLock dLock;
+
+    if (receive_thread)
+    {
+        receive_thread->IRQwakeup();
+        receive_thread = 0;
+    }
+}
+
+void Xbee::handleATTNInterrupt()
+{
+    if (receive_thread)
+    {
+        receive_thread->IRQwakeup();
+        if (receive_thread->IRQgetPriority() >
+            miosix::Thread::IRQgetCurrentThread()->IRQgetPriority())
+        {
+            miosix::Scheduler::IRQfindNextThread();
+        }
+        receive_thread = 0;
+    }
+}
+
+size_t Xbee::fillReceiveBuf(uint8_t* buf, size_t buf_max_size)
+{
+    if (!rx_frames_buf.isEmpty() && curr_rx_payload_ptr == -1)
+    {
+        Lock<FastMutex> l(mutex_rx_frames);
+        curr_rx_frame       = rx_frames_buf.pop();
+        curr_rx_payload_ptr = 0;
+    }
+
+    if (curr_rx_payload_ptr >= 0)
+    {
+        size_t len_remaining_data =
+            curr_rx_frame.getRXDataLength() - curr_rx_payload_ptr;
+
+        // The buffer may be smaller than the data we need to return
+        size_t len_to_copy = min(buf_max_size, len_remaining_data);
+
+        memcpy(buf, curr_rx_frame.getRXDataPointer() + curr_rx_payload_ptr,
+               len_to_copy);
+
+        curr_rx_payload_ptr += len_to_copy;
+
+        if (curr_rx_payload_ptr == curr_rx_frame.getRXDataLength())
+        {
+            // We've emptied the current frame
+            curr_rx_payload_ptr = -1;
+        }
+
+        return len_to_copy;
+    }
+    
+
+    return 0;
+}
+
+ParseResult Xbee::readOneFrame()
+{
+    SPIAcquireLock acq(spi_xbee);
+    SPISelectLock sel(spi_xbee);
+
+    ParseResult result = ParseResult::IDLE;
+    do
+    {
+        result = parser.parse(spi_xbee.bus.read(), &parsing_api_frame);
+    } while (attn.value() == 0 && result == ParseResult::PARSING);
+
+    return result;
+}
+
+bool Xbee::readRXFrame()
+{
+    while (attn.value() == 0)
+    {
+        if (readOneFrame() == ParseResult::SUCCESS)
+        {
+            handleFrame(parsing_api_frame);
+
+            if (parsing_api_frame.frame_type == FTYPE_RX_PACKET_FRAME)
+            {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+void Xbee::writeFrame(APIFrame& frame)
+{
+    frame.timestamp = miosix::getTick();  // Only for logging purposes
+
+    // Serialize the frame
+    uint8_t tx_buf[MAX_API_FRAME_SIZE];
+    size_t tx_buf_size = frame.toBytes(tx_buf);
+
+    {
+        SPITransaction spi(spi_xbee);
+        spi.transfer(tx_buf, tx_buf_size);
+    }
+
+    // Pass the frame we just sent to the listener
+    if (frame_listener)
+    {
+        frame_listener(frame);
+    }
+
+    // Full duplex spi transfer: we may have received valid data while we
+    // were sending the frame.
+    for (unsigned int i = 0; i < tx_buf_size; i++)
+    {
+        ParseResult res = parser.parse(tx_buf[i], &parsing_api_frame);
+        if (res == ParseResult::SUCCESS)
+        {
+            handleFrame(parsing_api_frame);
+        }
+    }
+}
+
+bool Xbee::waitForFrame(uint8_t frame_type, unsigned int poll_interval,
+                        long long timeout_tick)
+{
+    do
+    {
+        if (attn.value() == 0)
+        {
+            if (readOneFrame() == ParseResult::SUCCESS)
+            {
+                handleFrame(parsing_api_frame);
+
+                if (parsing_api_frame.frame_type == frame_type)
+                {
+                    return true;
+                }
+            }
+        }
+        else
+        {
+            miosix::Thread::sleep(poll_interval);
+        }
+    } while (miosix::getTick() < timeout_tick);
+
+    return false;
+}
+
+uint8_t Xbee::buildTXRequestFrame(TXRequestFrame& tx_req, uint8_t* pkt,
+                                  size_t pkt_len)
+{
+    memcpy(tx_req.getRFDataPointer(), pkt, pkt_len);
+    tx_req.setRFDataLength(pkt_len);
+
+    uint8_t tx_frame_id = getNewFrameID();
+
+    tx_req.setFrameID(tx_frame_id);
+
+    tx_req.setDestAddress(ADDRESS_BROADCAST);
+    tx_req.setBroadcastRadius(0);  // 0 = max hops, but we don't really care as
+                                   // it does not apply to point-multipoint mode
+    // Point-multipoint mode, disable ack, disable route discovery
+    tx_req.setTransmitOptions(TO_DM_POINT_MULTIPOINT | TO_DISABLE_ACK |
+                              TO_DISABLE_RD);
+    tx_req.calcChecksum();
+
+    return tx_frame_id;
+}
+
+void Xbee::sendATCommand(const char* cmd, uint8_t* params, size_t params_len)
+{
+    Lock<FastMutex> l(mutex_xbee_comm);
+
+    sendATCommandInternal(0, cmd, params, params_len);
+}
+
+bool Xbee::sendATCommand(const char* cmd, ATCommandResponseFrame* response,
+                         uint8_t* params, size_t params_len,
+                         unsigned int timeout)
+{
+    Lock<FastMutex> l(mutex_xbee_comm);
+
+    uint8_t tx_frame_id = sendATCommandInternal(cmd, params, params_len);
+
+    bool success = false;
+
+    long long timeout_tick = miosix::getTick() + timeout;
+
+    while (waitForFrame(FTYPE_AT_COMMAND_RESPONSE, FRAME_POLL_INTERVAL,
+                        timeout_tick))
+    {
+        ATCommandResponseFrame* f =
+            parsing_api_frame.toFrameType<ATCommandResponseFrame>();
+
+        if (f->getFrameID() == tx_frame_id &&
+            strncmp(cmd, f->getATCommand(), 2) == 0)
+        {
+            memcpy(response, f, sizeof(ATCommandResponseFrame));
+            success = true;
+            break;
+        }
+    }
+
+    return success;
+}
+
+uint8_t Xbee::sendATCommandInternal(const char* cmd, uint8_t* params,
+                                    size_t params_len)
+{
+    return sendATCommandInternal(getNewFrameID(), cmd, params, params_len);
+}
+
+uint8_t Xbee::sendATCommandInternal(uint8_t tx_frame_id, const char* cmd,
+                                    uint8_t* params, size_t params_len)
+{
+    // Build the AT command
+    ATCommandFrame at;
+    at.setATCommand(cmd);
+    at.setFrameID(tx_frame_id);
+    if (params_len > 0)
+    {
+        if (params_len > MAX_AT_COMMAND_PARAMS_LENGTH)
+        {
+            TRACE(
+                "[Xbee] ERROR! AT Command payload too large. It was "
+                "truncated.\n");
+            params_len = MAX_AT_COMMAND_PARAMS_LENGTH;
+        }
+        at.setParameterSize(params_len);
+        memcpy(at.getCommandDataPointer(), params, params_len);
+    }
+
+    at.calcChecksum();
+
+    // Send it
+    writeFrame(at);
+
+    return tx_frame_id;
+}
+
+void Xbee::handleFrame(APIFrame& frame)
+{
+    // Set the timestamp to the frame
+    frame.timestamp = miosix::getTick();
+
+    switch (frame.frame_type)
+    {
+        case FTYPE_RX_PACKET_FRAME:
+        {
+            RXPacketFrame* pf = frame.toFrameType<RXPacketFrame>();
+            {
+                Lock<FastMutex> l(mutex_rx_frames);
+
+                if (rx_frames_buf.isFull())
+                {
+                    ++status.rx_dropped_buffers;
+                }
+                rx_frames_buf.put(*pf);
+                if (rx_frames_buf.count() > status.frame_buf_max_length)
+                {
+                    status.frame_buf_max_length = rx_frames_buf.count();
+                }
+            }
+            wakeReceiver();
+            break;
+        }
+        case FTYPE_MODEM_STATUS:
+        {
+            ModemStatusFrame* ms = frame.toFrameType<ModemStatusFrame>();
+
+            switch (ms->getStatus())
+            {
+                case MS_HARDWARE_RESET:
+                    TRACE("[Xbee] Modem status: Hardware reset\n");
+                    break;
+                case MS_WATCHDOG_TIMER_RESET:
+                    TRACE("[Xbee] Modem status: Watchdog timer reset\n");
+                    break;
+            }
+            break;
+        }
+        case FTYPE_TX_STATUS:
+        {
+            TXStatusFrame* ts     = frame.toFrameType<TXStatusFrame>();
+            status.last_tx_status = ts->getDeliveryStatus();
+            if (status.last_tx_status != DELS_SUCCESS)
+            {
+                status.last_tx_status_error = status.last_tx_status;
+            }
+            switch (status.last_tx_status)
+            {
+                case DELS_SUCCESS:
+                    break;
+                default:
+                    TRACE(
+                        "TX Status Error: %d (retries: %d, RD: %s)\n",
+                        status.last_tx_status, ts->getTransmitRetryCount(),
+                        ts->getDiscoveryStatus() == 2 ? "Enabled" : "Disabled");
+                    break;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    // Pass the frame to the listener
+    if (frame_listener)
+    {
+        frame_listener(frame);
+    }
+}
+
+void Xbee::setOnFrameReceivedListener(OnFrameReceivedListener listener)
+{
+    frame_listener = listener;
+}
+
+uint8_t Xbee::getNewFrameID()
+{
+    uint8_t tx_frame_id = frame_id_counter++;
+
+    // Any value != 0 implies that we DO want a tx status response
+    if (frame_id_counter == 0)
+        frame_id_counter = 1;
+
+    return tx_frame_id;
+}
+
+}  // namespace Xbee
\ No newline at end of file
diff --git a/src/shared/drivers/Xbee/Xbee.h b/src/shared/drivers/Xbee/Xbee.h
index cea5d667c63934b656b2da8f9647a8c34bb1c593..8b5cfb0e2d9b7ae36cf2a09b4f97a141ad288dc5 100644
--- a/src/shared/drivers/Xbee/Xbee.h
+++ b/src/shared/drivers/Xbee/Xbee.h
@@ -1,5 +1,6 @@
-/* Copyright (c) 2015-2019 Skyward Experimental Rocketry
- * Authors: Andrea Milluzzo, Artem Glukhov, Alvise de Faveri Tron, Luca Erbetta
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,628 +23,259 @@
 
 #pragma once
 
-#include <Common.h>
-#include <drivers/Transceiver.h>
-#include <drivers/spi/SPIDriver.h>
 #include <miosix.h>
 
-#include <algorithm>
-#include <vector>
+#include <functional>
 
-#include "ActiveObject.h"
 #include "XbeeStatus.h"
-#include "diagnostic/StackLogger.h"
-
-using miosix::FastInterruptDisableLock;
-using miosix::FastInterruptEnableLock;
-using miosix::Thread;
+#include "drivers/Transceiver.h"
+#include "drivers/Xbee/APIFrameParser.h"
+#include "drivers/spi/SPIDriver.h"
+#include "utils/collections/CircularBuffer.h"
 
-using miosix::ConditionVariable;
 using miosix::FastMutex;
-using miosix::Lock;
-using miosix::Unlock;
 
-using std::vector;
+#ifndef USE_MOCK_PERIPHERALS
+using GpioType = GpioPin;
+#else
+#include "utils/testutils/MockGpioPin.h"
+using GpioType = MockGpioPin;
+#endif
 
 namespace Xbee
 {
-// Constants
+using ParseResult = APIFrameParser::ParseResult;
 
-// How often should we check if we received a transmit status response.
-static constexpr unsigned int SEND_STATUS_POLL_INTERVAL = 10;  // ms
+static constexpr unsigned int FRAME_POLL_INTERVAL = 10;    // ms
+static constexpr unsigned int DEFAULT_TX_TIMEOUT  = 5000;  // ms
 
-static constexpr uint16_t MAX_PAYLOAD_LEN = 0xFFFF;
+// Size (in frames) of the receive circular buffer
+static constexpr unsigned int RX_FRAMES_BUF_SIZE = 3;
 
-static constexpr uint8_t START_DELIMITER            = 0x7E;
-static constexpr uint64_t BROADCAST_ADDR            = 0xFFFF;
-static constexpr uint8_t ID_ACK_DISABLE             = 0x00;
-static constexpr uint8_t MAX_BROADCAST_HOPS         = 0x00;
-static constexpr uint8_t TX_STATUS_DELIVERY_SUCCESS = 0x00;
+class Xbee : public Transceiver
+{
+public:
+    using OnFrameReceivedListener = std::function<void(APIFrame& frame)>;
 
-// NOTE: 0x43 = Point-Multipoint, No Ack, No route discovery. See transmit
-// request frame bit options
-static constexpr uint8_t TRANSMIT_OPTIONS = 0x43;
+    /**
+     * @brief Constructs a new instance of the Xbee driver.
+     *
+     * @param bus The SPI bus where the xbee is connected
+     * @param cs Xbee SPI Chip Select Pin
+     * @param attn Xbee ATTN Pin
+     * @param rst Xbee RST PIN
+     * @param tx_timeout How long to wait to for a TX Status
+     */
+    Xbee(SPIBusInterface& bus, GpioType cs, GpioType attn, GpioType rst,
+         long long tx_timeout = DEFAULT_TX_TIMEOUT);
 
-// Frame Sizes
-static constexpr uint8_t API_HEADER_SIZE = 3;
+    /**
+     * @brief Constructs a new instance of the Xbee driver.
+     *
+     * @param bus The SPI bus where the xbee is connected
+     * @param config Custom SPI bus configuration
+     * @param cs Xbee SPI Chip Select Pin
+     * @param attn Xbee ATTN Pin
+     * @param rst Xbee RST PIN
+     * @param tx_timeout How long to wait to for a TX Status
+     *
+     */
+    Xbee(SPIBusInterface& bus, SPIBusConfig config, GpioType cs, GpioType attn,
+         GpioType rst, long long tx_timeout = DEFAULT_TX_TIMEOUT);
 
-static constexpr uint8_t TX_FRAME_HEADER_SIZE    = 14;
-static constexpr uint8_t RX_FRAME_HEADER_SIZE    = 12;
-static constexpr uint8_t CHECKSUM_SIZE           = 1;
-static constexpr uint8_t TX_STATUS_FRAME_SIZE    = 7;
-static constexpr uint8_t MODEM_STATUS_FRAME_SIZE = 2;
+    ~Xbee();
 
-// Bit definitions for status frame
-static constexpr uint8_t BIT_STATUS_RETRY_COUNT = 4;
-static constexpr uint8_t BIT_STATUS_DELIVERY    = 5;
-static constexpr uint8_t BIT_STATUS_DISCOVERY   = 6;
+    /**
+     * @brief Sends a packet.
+     * The function blocks until the packet is sent to the peripheral, but does
+     * not wait for an ACK or send confirmation from the Xbee. Thus, it always
+     * returns true.
+     *
+     * @param pkt       Pointer to the packet (needs to be at least pkt_len
+     * bytes).
+     * @param pkt_len   Lenght of the packet to be sent.
+     * @return          Always true
+     */
+    bool send(uint8_t* pkt, size_t pkt_len) override;
 
-// Waiting thread to be woken when something has been received or must be sent.
-// Defined extern so it can be accessed from multiple translation units
-extern miosix::Thread* waiting;
+    /**
+     * @brief Waits until a new packet is received.
+     *
+     * @param buf            Buffer to store the received packet into.
+     * @param buf_max_size   Maximum length of the received data.
+     * @return               Size of the data received or -1 if failure
+     */
+    ssize_t receive(uint8_t* buf, size_t buf_max_size) override;
 
-/**
- * @brief Handler for the ATTN interrupt: wakes up the thread.
- * The ATTN (ATTention Needed) pin is raised when the transceiver has
- * received something.
- * Call this function from inside an IRQHandler, after you have
- * enabled the corresponding interrupt in the NVIC vector.
- */
-static void __attribute__((used)) handleATTNInterrupt()
-{
-    if (waiting)
-    {
-        // Wake
-        waiting->IRQwakeup();
+    /**
+     * @brief Hardware resets the Xbee.
+     */
+    void reset();
 
-        if (waiting->IRQgetPriority() >
-            miosix::Thread::IRQgetCurrentThread()->IRQgetPriority())
-        {
-            miosix::Scheduler::IRQfindNextThread();
-        }
+    /**
+     * @brief Signals the receive() function that there is new data available.
+     * Call this from the ATTN pin interrupt servirce routine, and nowhere else
+     * plese.
+     *
+     */
+    void handleATTNInterrupt();
 
-        waiting = nullptr;
-    }
-}
+    /**
+     * @brief Wakes the receive function without needing an interrupt
+     *
+     * @param force_return Wether receive(..) should return even if it has not
+     * received any data
+     */
+    void wakeReceiver(bool force_return = false);
 
-/**
- * @warning: An IRQ linked with the ATTN pin of the Xbee module must be enabled
- * before using this class. See test/misc/xbee-bitrate for an example.
- * @warning: Due to the way this driver is written, the SPI bus must be reserved
- * only for the XBee device. No other devices can communicate on the same bus.
- */
-class Xbee : public Transceiver, public ActiveObject
-{
-public:
-    Xbee(SPIBusInterface& bus, GpioPin cs, GpioPin attn, GpioPin rst,
-         unsigned int send_timeout = 1000)
-        : send_timeout(send_timeout), spi_xbee(bus, cs, {}), attn(attn), rst(rst)
-    {
-        spi_xbee.config.clock_div = SPIClockDivider::DIV128;
-
-        // No need to configure before each transaction, we are the only device
-        // on the bus.
-        spi_xbee.bus.configure(spi_xbee.config);
-
-        reset();
-        miosix::Thread::sleep(10);
-
-        spi_xbee.cs.low();
-        miosix::Thread::sleep(1);
-        spi_xbee.cs.high();
-        miosix::Thread::sleep(1);
-    }
-
-    Xbee(SPIBusInterface& bus, GpioPin cs, GpioPin attn, GpioPin rst,
-         SPIBusConfig spi_config, unsigned int send_timeout = 1000)
-        : send_timeout(send_timeout), spi_xbee(bus, cs, spi_config), attn(attn),
-          rst(rst)
-    {
-        // No need to configure before each transaction, we are the only device
-        // on the bus.
-        spi_xbee.bus.configure(spi_xbee.config);
-
-        reset();
-        miosix::Thread::sleep(10);
-
-        spi_xbee.cs.low();
-        miosix::Thread::sleep(1);
-        spi_xbee.cs.high();
-        miosix::Thread::sleep(1);
-    }
-
-    /*
-     * Send a message through the XBee
-     * Blocks until the message is sent (successfully or not)
+    /**
+     * @brief Sends an AT Command to the Xbee (see datasheet) without waiting
+     * for a response
      *
-     * @param msg               Message to be sent
-     * @param pkt_len           Lenght of the message
-     * @return true             The message was sent correctly.
-     * @return false            There was an error sending the message.
+     * @param cmd Two character string with the name of the command (eg "DB")
+     * @param params Optional command parameters
+     * @param params_len Length in bytes of the params array
      */
-    bool send(uint8_t* msg, size_t msg_len) override
-    {
-        if (msg == nullptr || msg_len == 0)
-        {
-            return false;
-        }
-
-        // Create a TX API packet
-        vector<uint8_t> tx_pkt;
-        buildTxPacket(tx_pkt, msg, msg_len);
-
-        // Send the packet
-        setTxBuf(tx_pkt.data(), tx_pkt.size());
-
-        // Wake the runner thread in order to send the data
-        wakeThread();
-
-        // Wait until the XBee sends the message or a timeout expires
-        // It would be cool to have condition variables with timeout to avoid
-        // polling...
-        unsigned int timeout = 0;
-        while (!received_tx_status)
-        {
-            if (timeout > send_timeout)
-            {
-                // Timeout. Return error
-                TRACE("[Xbee] Send Timeout!\n");
-                ++status.tx_timeout_count;
-                return false;
-            }
-            Thread::sleep(SEND_STATUS_POLL_INTERVAL);
-            timeout += SEND_STATUS_POLL_INTERVAL;
-        }
-
-        received_tx_status = false;
-        if (status.tx_delivery_status != TX_STATUS_DELIVERY_SUCCESS)
-        {
-            TRACE("[Xbee] Error: %02X\n", status.tx_delivery_status);
-        }
-        return status.tx_delivery_status == TX_STATUS_DELIVERY_SUCCESS;
-    }
-
-    /*
-     * Wait for a new message to be received by the XBee
-     * @param rcv_buf Buffer to store the received message
-     * @param rcv_buf_len Maximum length of the message to be received
-     * @return true A message was successfully received
-     * @return false Received invalid message
+    void sendATCommand(const char* cmd, uint8_t* params = nullptr,
+                       size_t params_len = 0);
+
+    /**
+     * @brief Sends an AT Command to the Xbee and wait for a response (see
+     * datasheet)
+     *
+     * @param cmd Two character string with the name of the command (eg "DB")
+     * @param params Optional command parameters
+     * @param params_len Length in bytes of the params array
+     * @param response Where to store the response
+     * @param timeout Maximum time to wait for the response
+     * @return true if response received before the timeout, false otherwise
      */
-    ssize_t receive(uint8_t* rcv_buf, size_t rcv_buf_len) override
-    {
-        Lock<FastMutex> l(rx_mutex);
-
-        while (rx_frame.size() == 0)
-        {
-            rx_cond.wait(l);
-        }
-
-        if (rx_frame.size() > rcv_buf_len)
-        {
-            return -1;
-        }
-        else
-        {
-            memcpy(rcv_buf, rx_frame.data(), rx_frame.size());
-            rcv_buf_len = rx_frame.size();
-
-            rx_frame.clear();
-
-            return rcv_buf_len;
-        }
-    }
-
-    void stop() override
-    {
-        should_stop = true;
-        wakeThread();
-        ActiveObject::stop();
-    }
-
-    XbeeStatus getStatus() { return status; }
-
-protected:
+    bool sendATCommand(const char* cmd, ATCommandResponseFrame* response,
+                       uint8_t* params = nullptr, size_t params_len = 0,
+                       unsigned int timeout = 1000);
+
     /**
-     * Sends and receives data, puts the thread to sleep if nothing to
-     * send/receive.
+     * @brief Set the frame received listener, called each time a new APIFrame
+     * is received from the device
+     *
+     * @param listener The listener
      */
-    void run() override
-    {
-        while (!shouldStop())
-        {
-            // Wait for RX or TX request
-            {
-                miosix::FastInterruptDisableLock dLock;
-
-                // Check if we have data to send (tx_buf.size > 0) or receive
-                // (attn == 0) with disabled interrupts to avoid race conditions
-                if (attn.value() != 0 && tx_buf.size() == 0)
-                {
-                    // If we have nothing to receive or send, wait.
-                    waiting = miosix::Thread::getCurrentThread();
-
-                    while (waiting != 0)
-                    {
-                        waiting->IRQwait();
-                        {
-                            miosix::FastInterruptEnableLock eLock(dLock);
-                            miosix::Thread::yield();
-                        }
-                    }
-                }
-
-                StackLogger::getInstance()->updateStack(THID_XBEE);
-            }
-            // Transfer any data on the tx buffer and receive any incoming data
-            transferData();
-        }
-    }
+    void setOnFrameReceivedListener(OnFrameReceivedListener listener);
+
+    XbeeStatus getStatus();
 
 private:
-    enum class ParseResult : uint8_t
-    {
-        IDLE,
-        PARSING,
-        SUCCESS,
-        FAIL
-    };
-
-    enum class ParserState
-    {
-        FIND_START,
-        READ_LENGTH_1,
-        READ_LENGTH_2,
-        READ_FRAME,
-        READ_CHECKSUM
-    };
-
-    enum FrameType : uint8_t
-    {
-        FRAMETYPE_AT_COMMAND                    = 0x08,
-        FRAMETYPE_AT_QUEUE_PARAM_VALUE          = 0x09,
-        FRAMETYPE_TX_REQUEST                    = 0x10,
-        FRAMETYPE_EXPICIT_TX_REQUEST            = 0x11,
-        FRAMETYPE_REMOTE_AT_REQUEST             = 0x17,
-        FRAMETYPE_AT_COMMAND_RESPONSE           = 0x88,
-        FRAMETYPE_MODEM_STATUS                  = 0x8A,
-        FRAMETYPE_TRANSMIT_STATUS               = 0x8B,
-        FRAMETYPE_ROUTE_INFO_PACKET             = 0x8D,
-        FRAMETYPE_AGGREGATE_ADRESSING_UPDATE    = 0x8E,
-        FRAMETYPE_RX_PACKET                     = 0x90,
-        FRAMETYPE_EXPLICIT_RX_PACKET            = 0x91,
-        FRAMETYPE_DATA_SAMPLE_RX_INDICATOR      = 0x92,
-        FRAMETYPE_NODE_IDENTIFICATION_INDICATOR = 0x95,
-        FRAMETYPE_REMOTE_COMMAND_RESPONSE       = 0x97
-    };
-
-    void reset()
-    {
-        rst.mode(miosix::Mode::OPEN_DRAIN);
-        rst.low();
-        miosix::delayUs(500);
-        rst.high();
-    }
+    /**
+     * @brief Handles an API Frame
+     * @attention  mutex_xbee_comm must be locked before calling this function.
+     */
+    void handleFrame(APIFrame& frame);
 
     /**
-     * Wake the AO thread from another thread.
-     * Cannot be called with disabled interrupts.
+     * @brief Sends an AT command to the devices
+     * @attention  mutex_xbee_comm must be locked before calling this function.
      */
-    void wakeThread()
-    {
-        FastInterruptDisableLock dLock;
+    uint8_t sendATCommandInternal(const char* cmd, uint8_t* params = nullptr,
+                                  size_t params_len = 0);
 
-        if (waiting)
-        {
-            waiting->IRQwakeup();
-            waiting = nullptr;
-        }
-    }
+    /**
+     * @brief Sends an AT command to the devices
+     * @attention  mutex_xbee_comm must be locked before calling this function.
+     */
+    uint8_t sendATCommandInternal(uint8_t frame_id, const char* cmd,
+                                  uint8_t* params   = nullptr,
+                                  size_t params_len = 0);
+
+    uint8_t buildTXRequestFrame(TXRequestFrame& tx_req, uint8_t* pkt,
+                                size_t pkt_len);
 
     /**
-     * Transfer data to/from the Xbee.
-     * Performs a full duplex transaction.
+     * @brief Fills the provided buffer with data contained in rx_frames_buf
      */
-    void transferData()
-    {
-        SPIBusInterface& bus = spi_xbee.bus;
-
-        ParseResult result = ParseResult::IDLE;
-
-        bus.select(spi_xbee.cs);
-
-        vector<uint8_t> data;
-
-        {
-            // Make a local copy of the TX buffer
-            FastInterruptDisableLock dLock;
-            data = tx_buf;
-
-            // Clear the tx buffer
-            tx_buf.clear();
-        }
-
-        // If there is data to send
-        if (data.size() > 0)
-        {
-            // Full duplex transfer, the data vector is replaced with received
-            // data, if any.
-            bus.transfer(data.data(), data.size());
-
-            // Parse the received data
-            for (uint8_t rx : data)
-            {
-                result = parse(rx);
-
-                // We received something
-                if (result == ParseResult::SUCCESS)
-                {
-                    handleFrame(parser_buf);
-                }
-            }
-
-            // If there's nothing more to parse, return
-            if (result != ParseResult::PARSING)
-            {
-                bus.deselect(spi_xbee.cs);
-                return;
-            }
-
-            // If there is more data to be received, continue below.
-        }
-
-        // Read until we have received a packet (or no packet is found)
-        do
-        {
-            result = parse(bus.read());
-        } while (result == ParseResult::PARSING);
-
-        if (result == ParseResult::SUCCESS)
-        {
-            handleFrame(parser_buf);
-        }
-        else if (result == ParseResult::FAIL)
-        {
-            TRACE("[Xbee] Read failed. Parser result: %d\n", (int)result);
-        }
-
-        bus.deselect(spi_xbee.cs);
-    }
+    size_t fillReceiveBuf(uint8_t* buf, size_t buf_max_size);
 
     /**
-     * Parse received data one byte at a time, storing it in the parser_buf.
-     * When a full packet is received, returns ParseResult::SUCCESS.
-     * Returns ParseResult::FAIL if a full packet is received but checksum
-     * verification fails.
-     * In both cases, the frame is stored in parser_buf.
-     *
-     * Returns ParseResult::IDLE if no frame start delimiter has been found yet.
-     * Returns ParseResult::PARSING if a start delimiter was found and a packet
-     * is being parsed.
+     * @brief Reads a single frame from the SPI bus.
+     * @attention mutex_xbee_comm must be locked before calling this function.
+     */
+    ParseResult readOneFrame();
+
+    /**
+     * @brief Reads the SPI bus until an RXPacketFrame is encountered or no more
+     * data is available
+     * @attention  mutex_xbee_comm must be locked before calling this function.
      *
-     * @param byte byte to be parsed
-     * @return
+     * @return true RXPacketFrame received
+     * @return false No more data available on SPI and RXPacketFrame not
+     * received
      */
-    ParseResult parse(uint8_t byte)
-    {
-        switch (parser_state)
-        {
-            // Look for the start of frame delimiter
-            case ParserState::FIND_START:
-                if (byte == START_DELIMITER)
-                {
-                    parser_state = ParserState::READ_LENGTH_1;
-
-                    // Frame start found, clear old rx buf
-                    parser_buf.clear();
-                    parser_packet_length = 0;
-                }
-                else
-                {
-                    return ParseResult::IDLE;
-                }
-                break;
-            // Read most significant byte of the length
-            case ParserState::READ_LENGTH_1:
-                parser_packet_length = byte << 8;
-                parser_state         = ParserState::READ_LENGTH_2;
-                break;
-            // Read least significant byte of the length
-            case ParserState::READ_LENGTH_2:
-                parser_packet_length += byte;
-
-                parser_state = ParserState::READ_FRAME;
-
-                // Now that we know how long the packet is, reserve memory to
-                // store it
-                parser_buf.reserve(parser_packet_length);
-                break;
-            // Read the data frame
-            case ParserState::READ_FRAME:
-                parser_buf.push_back(byte);
-
-                if (parser_buf.size() == parser_packet_length)
-                {
-                    parser_state = ParserState::READ_CHECKSUM;
-                }
-                break;
-            // Read & verify checksum
-            case ParserState::READ_CHECKSUM:
-                parser_state = ParserState::FIND_START;
-
-                if (verifyChecksum(parser_buf, byte))
-                {
-                    return ParseResult::SUCCESS;
-                }
-                else
-                {
-                    ++status.rx_wrong_checksum;
-                    TRACE("[Xbee] Rx checksum verification failed\n");
-                    return ParseResult::FAIL;
-                }
-                break;
-        }
-
-        return ParseResult::PARSING;
-    }
-
-    void handleFrame(const vector<uint8_t>& frame)
-    {
-        if (frame.size() == 0)
-        {
-            return;
-        }
-        // The first byte indicates the frame type
-        switch (frame[0])
-        {
-            case FRAMETYPE_RX_PACKET:
-            {
-                size_t payload_size = frame.size() - RX_FRAME_HEADER_SIZE;
-
-                if (payload_size > 0)
-                {
-                    {
-                        Lock<FastMutex> l(rx_mutex);
-                        rx_frame.clear();
-                        rx_frame.insert(rx_frame.end(),
-                                        frame.begin() + RX_FRAME_HEADER_SIZE,
-                                        frame.end());
-                    }
-                    rx_cond.signal();
-                }
-                break;
-            }
-            case FRAMETYPE_TRANSMIT_STATUS:
-            {
-                if (frame.size() == TX_STATUS_FRAME_SIZE)
-                {
-                    status.tx_retry_count      = frame[BIT_STATUS_RETRY_COUNT];
-                    status.tx_delivery_status  = frame[BIT_STATUS_DELIVERY];
-                    status.tx_discovery_status = frame[BIT_STATUS_DISCOVERY];
-
-                    received_tx_status = true;
-                }
-                else
-                {
-                    TRACE("[Xbee] Wrong TX status frame size.\n");
-                }
-                break;
-            }
-            case FRAMETYPE_MODEM_STATUS:
-            {
-                if (frame.size() == MODEM_STATUS_FRAME_SIZE)
-                {
-                    TRACE("[Xbee] Modem status: %d\n", frame[1]);
-                }
-                else
-                {
-                    TRACE("[Xbee] Wrong MODEM status frame size.\n");
-                }
-                break;
-            }
-            default:
-                break;
-        }
-    }
-
-    void buildTxPacket(vector<uint8_t>& tx_pkt, uint8_t* msg, size_t msg_len)
-    {
-        tx_pkt.reserve(API_HEADER_SIZE + TX_FRAME_HEADER_SIZE + msg_len +
-                       CHECKSUM_SIZE);
-
-        tx_pkt.push_back(START_DELIMITER);
-
-        uint16_t frame_len = msg_len + TX_FRAME_HEADER_SIZE;
-        // invert pkt_len bytes order
-        tx_pkt.push_back((frame_len & 0xff00) >> 8);
-        tx_pkt.push_back(frame_len & 0xff);
-
-        tx_pkt.push_back(FRAMETYPE_TX_REQUEST);
-
-        // Any value != 0 indicates that we want a tx status response
-        tx_pkt.push_back(0x01);
-
-        // Split the address in bytes & add to the buffer
-        uint8_t addr_buffer[8];
-        memcpy(addr_buffer, &BROADCAST_ADDR, 8);
-
-        for (int i = 7; i >= 0; i--)
-        {
-            tx_pkt.push_back(addr_buffer[i]);
-        }
-
-        // Reserved bytes
-        tx_pkt.push_back(0xff);
-        tx_pkt.push_back(0xfe);
-
-        tx_pkt.push_back(MAX_BROADCAST_HOPS);
-
-        tx_pkt.push_back(TRANSMIT_OPTIONS);
-
-        // payload
-        for (uint32_t i = 0; i < msg_len; i++)
-        {
-            tx_pkt.push_back(*(msg + i));
-        }
-
-        // Calculate & add checksum
-        uint32_t checksum = 0;
-        for (uint32_t i = 3; i < tx_pkt.size(); i++)
-        {
-            checksum += tx_pkt.at(i);
-        }
-
-        tx_pkt.push_back(0xff - (checksum & 0xff));
-    }
+    bool readRXFrame();
 
     /**
-     * Set the tx buffer with the provided data.
+     * @brief Writes a frame from the SPI bus.
+     * @attention  mutex_xbee_comm must be locked before calling this function.
      */
-    void setTxBuf(uint8_t* buf, size_t size)
-    {
-        // We need to disable interrupts (instead of using a mutex) becouse we
-        // need to synchronize the access to the tx buf in the waiting thread
-        // before putting it to sleep (which requires disabling interrupts)
-        FastInterruptDisableLock dLock;
-
-        // Copy buf into tx_buf, removing old content
-        tx_buf.clear();
-        tx_buf.insert(tx_buf.end(), buf, buf + size);
-    }
-
-    bool verifyChecksum(vector<uint8_t> frame, uint8_t checksum)
-    {
-        // Sum all the bytes including checksum.
-        // The sum can be stored in a uint8_t since we only care about the least
-        // significant bits.
-        uint8_t sum = checksum;
-        for (size_t i = 0; i < frame.size(); ++i)
-        {
-            sum += frame[i];
-        }
-        return sum == 0xFF;
-    }
-
-    // How long to wait for a transmit status response.
-    unsigned int send_timeout;
-
-    vector<uint8_t> tx_buf;
-
-    bool received_tx_status = false;
-
-    FastMutex rx_mutex;
-    vector<uint8_t> rx_frame;
-    ConditionVariable rx_cond;
-
-    ParserState parser_state    = ParserState::FIND_START;
-    size_t parser_packet_length = 0;
-    vector<uint8_t> parser_buf;
+    void writeFrame(APIFrame& frame);
 
-    XbeeStatus status;
+    uint8_t getNewFrameID();
 
+    /**
+     * @brief Waits until an APIFrame with frame type \p frame_type is received
+     * on the SPI or until the timeouts expires. The frame is then stored in the
+     * parsing_api_frame local class varibale. Any frame received by this
+     * function is automatically passed to the handleFrame() function
+     * @attention mutex_xbee_comm must be locked before calling this function.
+     *
+     * @param poll_interval Polling interval for the attn pin in milliseconds
+     * @param timeout_tick Tick after which the function should stop waiting for
+     * frames
+     * @return true If a frame with type equal to \p frame_type is received
+     * @return false If the timeout_tick reached
+     */
+    bool waitForFrame(uint8_t frame_type, unsigned int poll_interval,
+                      long long timeout_tick);
+
+    // Synchronizes all communications to the xbee, as they may happen on
+    // multiple threads
+    FastMutex mutex_xbee_comm;
+
+    APIFrameParser parser;
+    // Frame being parsed. Only valid if last call to
+    // parser.parse() returned ParseResult::SUCCESS
+    APIFrame parsing_api_frame;
+
+    // Temporary storage for RX packet frames, waiting to be returned by
+    // receive()
+    CircularBuffer<RXPacketFrame, RX_FRAMES_BUF_SIZE> rx_frames_buf;
+    FastMutex mutex_rx_frames;
+    // RX Packet currently being returned by receive()
+    RXPacketFrame curr_rx_frame;
+    // Index of the first byte of the payload of curr_rx_frame that will be
+    // returned on the next call to receive()
+    int curr_rx_payload_ptr = -1;
+
+    // SPI defs
     SPISlave spi_xbee;
-    GpioPin attn;
-    GpioPin rst;
-};  // namespace Xbee
+    GpioType attn;
+    GpioType rst;
+
+    // How long to wait for a TX Status
+    long long tx_timeout;
+
+    OnFrameReceivedListener frame_listener;
+
+    // Used to generate a unique frame id
+    uint8_t frame_id_counter = 1;
+
+    // Forces receive() to return even if there is no new data
+    bool force_rcv_return = false;
+
+    // Status structs
+    XbeeStatus status;
+    Stats time_to_send_stats;
+
+    // Waiting thread to be woken when something has been received.
+    miosix::Thread* receive_thread = 0;
+};
 
 }  // namespace Xbee
\ No newline at end of file
diff --git a/src/shared/drivers/Xbee/XbeeStatus.h b/src/shared/drivers/Xbee/XbeeStatus.h
index a3bfcaa44f8e38d951da2aa1bd1b48b2cb296d71..08cb93c7de37d7eb367de279613e7371a4a7ff47 100644
--- a/src/shared/drivers/Xbee/XbeeStatus.h
+++ b/src/shared/drivers/Xbee/XbeeStatus.h
@@ -1,17 +1,17 @@
-/* 
+/*
  * Copyright (c) 2019 Skyward Experimental Rocketry
  * Authors: Luca Erbetta
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
@@ -25,27 +25,43 @@
 
 #include <cstdint>
 #include <cstdio>
+#include <ostream>
+#include <string>
 
+#include "math/Stats.h"
 namespace Xbee
 {
-    struct XbeeStatus
+struct XbeeStatus
+{
+    long long timestamp = 0LL;
+
+    uint8_t last_tx_status_error = 0;
+    uint8_t last_tx_status       = 0;
+
+    StatsResult time_to_send_stats;
+
+    unsigned int tx_timeout_count = 0;
+
+    unsigned int rx_dropped_buffers = 0;
+
+    unsigned int frame_buf_max_length = 0;
+
+    static std::string header()
+    {
+        return "timestamp,last_tx_status_error,last_tx_status,tts_stats.min,"
+               "tts_stats.max,tts_stats.mean,tts_stats.stddev,tts_stats.n_"
+               "samples,tx_timeout_count,rx_dropped_buffers,frame_buf_max_"
+               "length\n";
+    }
+
+    void print(std::ostream& os) const
     {
-        uint8_t tx_retry_count = 0;
-        uint8_t tx_delivery_status = 0;
-        uint8_t tx_discovery_status = 0;
-        unsigned int tx_timeout_count = 0;
-
-        unsigned int rx_dropped_buffers = 0;
-        unsigned int rx_wrong_checksum = 0;
-
-        void print()
-        {
-            TRACE("+++XBEE STATUS+++");
-            TRACE("TX: Timeouts: %d\n", tx_timeout_count);
-            TRACE("TXSTATUS: Retries: %d, Delivery: %02X, Discovery: %02X\n",
-                   tx_retry_count, tx_delivery_status, tx_discovery_status);
-            TRACE("RX: Dropped: %d, Checksum: %d\n", rx_dropped_buffers, rx_wrong_checksum);
-                
-        }
-    };
-}
\ No newline at end of file
+        os << timestamp << "," << (int)last_tx_status_error << ","
+           << (int)last_tx_status << "," << time_to_send_stats.minValue << ","
+           << time_to_send_stats.maxValue << "," << time_to_send_stats.mean
+           << "," << time_to_send_stats.stdev << ","
+           << time_to_send_stats.nSamples << "," << tx_timeout_count << ","
+           << rx_dropped_buffers << "," << frame_buf_max_length << "\n";
+    }
+};
+}  // namespace Xbee
\ No newline at end of file
diff --git a/src/shared/drivers/gps/piksi/piksi.cpp b/src/shared/drivers/gps/piksi/piksi.cpp
index 8e05730f2c26f78c800ee1e4288d09addae4f198..be56df4ed70c725387a6b279daaae2fb8b4bacad 100644
--- a/src/shared/drivers/gps/piksi/piksi.cpp
+++ b/src/shared/drivers/gps/piksi/piksi.cpp
@@ -188,8 +188,9 @@ unsigned int Piksi::lookForMessages(uint8_t *buffer, unsigned int size)
         if (messageSize > size)
             return consumed;  // We don't have the entire message
 
-        uint16_t crc =
-            *reinterpret_cast<uint16_t *>(buffer + messageSize - crcSize);
+        uint16_t crc;
+        memcpy(&crc, buffer + messageSize - crcSize, sizeof(crc));
+
         if (crc16piksi(buffer + 1, messageSize - crcSize - 1) == crc)
         {
             processValidMessage(buffer, messageSize);
diff --git a/src/shared/drivers/servo/servo.cpp b/src/shared/drivers/servo/servo.cpp
index d4222928546a22cfccb6468e248724bea10c1504..d45ba9f2e61e7dc14eb909b3ef7d5ed4e268862d 100644
--- a/src/shared/drivers/servo/servo.cpp
+++ b/src/shared/drivers/servo/servo.cpp
@@ -26,7 +26,7 @@
 #include <cstring>
 
 // Initialize the pwm with 50 Hz frequency and 65535 levels of duty cycle
-Servo::Servo(PWM::Timer t) : pwm(t, 50, 65535) { memset(&positions, 0, 4); }
+Servo::Servo(PWM::Timer t) : pwm(t, 50, 65535) { memset(&positions, 0, 4*sizeof(float)); }
 
 Servo::~Servo() {}
 
diff --git a/src/shared/drivers/spi/SPIBus.h b/src/shared/drivers/spi/SPIBus.h
index e31c4232974fd91442c5181a45023e5bcfea18d0..c8830353ec802d5d2aa8eb90a50e72ebaedb151c 100644
--- a/src/shared/drivers/spi/SPIBus.h
+++ b/src/shared/drivers/spi/SPIBus.h
@@ -21,9 +21,19 @@
  * THE SOFTWARE.
  */
 
+#pragma once
+
+#include <cassert>
+
 #include "SPIBusInterface.h"
 
-#pragma once
+
+#ifndef USE_MOCK_PERIPHERALS
+using SPIType = SPI_TypeDef;
+#else
+#include "test/FakeSpiTypedef.h"
+using SPIType = FakeSpiTypedef;
+#endif
 
 /**
  * @brief Low level driver for communicating on a SPI Bus, provides
@@ -37,7 +47,7 @@ public:
      *
      * @param spi Pointer to the SPI peripheral to be used
      */
-    SPIBus(SPI_TypeDef* spi);
+    SPIBus(SPIType* spi) : spi(spi) {}
     ~SPIBus() {}
 
     // Delete copy/move contructors/operators
@@ -87,17 +97,23 @@ public:
     /**
      * @brief See SPIBusInterface::select()
      */
-    void select(GpioPin& cs) override;
+    void select(GpioType& cs) override;
 
     /**
      * @brief See SPIBusInterface::deselect()
      */
-    void deselect(GpioPin& cs) override;
+    void deselect(GpioType& cs) override;
 
     /**
-     * @brief See SPIBusInterface::configure()
+     * @brief Obtains ownership of the bus, configuring it with the provided
+     * config. Since this implementation is not syncronized, if acquire() is
+     * called on an already locked bus, it will:
+     * - FAIL in DEBUG mode
+     * - Do nothing when NOT in DEBUG mode
+     *
+     * Use SyncedSPIBus if you need to synchronize access to the bus.
      */
-    void configure(SPIBusConfig config) override;
+    void acquire(SPIBusConfig config) override;
 
 protected:
     /**
@@ -122,7 +138,9 @@ protected:
      */
     void transfer(uint8_t* byte);
 
-    SPI_TypeDef* spi;
+    void configure(SPIBusConfig new_config);
+
+    SPIType* spi;
 
     SPIBusConfig config{};
     bool config_enabled       = true;
@@ -171,7 +189,7 @@ inline void SPIBus::transfer(uint8_t* data, size_t size)
     }
 }
 
-inline void SPIBus::select(GpioPin& cs)
+inline void SPIBus::select(GpioType& cs)
 {
     cs.low();
     if (config.cs_setup_time_us > 0)
@@ -180,7 +198,7 @@ inline void SPIBus::select(GpioPin& cs)
     }
 }
 
-inline void SPIBus::deselect(GpioPin& cs)
+inline void SPIBus::deselect(GpioType& cs)
 {
     if (config.cs_hold_time_us > 0)
     {
@@ -202,7 +220,7 @@ inline void SPIBus::write(uint8_t* byte)
         ;
 
     // Clear the RX buffer by accessing the DR register
-    spi->DR;
+    (void)spi->DR;
 }
 
 inline void SPIBus::transfer(uint8_t* byte)
@@ -235,4 +253,51 @@ inline void SPIBus::read(uint8_t* byte)
 
     // Store the received data in the byte
     *byte = (uint8_t)spi->DR;
+}
+
+inline void SPIBus::acquire(SPIBusConfig new_config)
+{
+    // Assert that the bus is not already acquired.
+    // This bus is not syncronized: fail if someone tries to take ownership when
+    // the bus is already being used. Use SyncedSPIBus if you need to
+    // synchronize access to the bus
+#ifdef DEBUG
+    assert(isBusy() == false);
+#endif
+
+    SPIBusInterface::acquire(new_config);
+
+    configure(new_config);
+}
+
+inline void SPIBus::configure(SPIBusConfig new_config)
+{
+    // Reconfigure the bus only if config enabled. Do not reconfigure if already
+    // in the correct configuration.
+    if (config_enabled && (!first_config_applied || new_config != config))
+    {
+        first_config_applied = true;
+        config               = new_config;
+
+        // Wait until the peripheral is done before changing configuration
+        while ((spi->SR & SPI_SR_TXE) == 0)
+            ;
+        while ((spi->SR & SPI_SR_BSY) > 0)
+            ;
+
+        spi->CR1 = 0;
+
+        // Configure CPOL & CPHA bits
+        spi->CR1 |= static_cast<uint32_t>(config.mode);
+
+        // Configure clock division (BR bits)
+        spi->CR1 |= static_cast<uint32_t>(config.clock_div);
+
+        // Configure LSBFIRST bit
+        spi->CR1 |= static_cast<uint32_t>(config.bit_order);
+
+        spi->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM  // Use software chip-select
+                    | SPI_CR1_MSTR             // Master mode
+                    | SPI_CR1_SPE;             // Enable SPI
+    }
 }
\ No newline at end of file
diff --git a/src/shared/drivers/spi/SPIBusInterface.h b/src/shared/drivers/spi/SPIBusInterface.h
index 9af7e336a23e77f59faf3d23144f216a65e3d3ea..bb313d16714196c504820285ea6ff1cee2922dc2 100644
--- a/src/shared/drivers/spi/SPIBusInterface.h
+++ b/src/shared/drivers/spi/SPIBusInterface.h
@@ -31,7 +31,12 @@
 using miosix::delayUs;
 using miosix::GpioPin;
 
-class SPITransaction;
+#ifndef USE_MOCK_PERIPHERALS
+using GpioType = GpioPin;
+#else
+#include "utils/testutils/MockGpioPin.h"
+using GpioType = MockGpioPin;
+#endif
 
 /**
  * @brief SPI Clock divider.
@@ -118,11 +123,10 @@ struct SPIBusConfig
  */
 class SPIBusInterface
 {
-    friend class SPITransaction;
 public:
     SPIBusInterface() {}
 
-    ~SPIBusInterface() {}
+    virtual ~SPIBusInterface() {}
 
     // Delete copy/move contructors/operators
     SPIBusInterface(const SPIBusInterface&) = delete;
@@ -184,7 +188,7 @@ public:
      *
      * @param    cs Chip select pin for the slave
      */
-    virtual void select(GpioPin& cs) = 0;
+    virtual void select(GpioType& cs) = 0;
 
     /**
      * @brief Deselects the slave
@@ -192,18 +196,34 @@ public:
      * @param    cs Chip select pin for the slave
      * @return
      */
-    virtual void deselect(GpioPin& cs) = 0;
+    virtual void deselect(GpioType& cs) = 0;
 
     /**
      * @brief Configures the bus with the provided configuration parameters.
+     * Call this before every transaction, after the call to lock() and before
+     * select(..)
      *
      * @param    config    Configuration parameters
      * @return
      */
-    virtual void configure(SPIBusConfig config) = 0;
+    virtual void acquire(SPIBusConfig config)
+    {
+        (void)config;
+        busy = true;
+    }
+
+    /**
+     * @brief Releases ownership of the bus
+     */
+    virtual void release() { busy = false; }
+
+    /**
+     * @brief Checks wether the bus is currently being used
+     */
+    virtual bool isBusy() { return busy; }
 
 private:
-    bool locked = false; // For use by SPITransaction
+    bool busy = false;  // For use by SPITransaction
 };
 
 /**
@@ -215,10 +235,51 @@ struct SPISlave
 
     SPIBusConfig config;  ///> How the bus should be configured to communicate
                           ///> with the slave.
-    GpioPin cs;           ///> Chip select pin
+    GpioType cs;          ///> Chip select pin
 
-    SPISlave(SPIBusInterface& bus, GpioPin cs, SPIBusConfig config)
+    SPISlave(SPIBusInterface& bus, GpioType cs, SPIBusConfig config)
         : bus(bus), config(config), cs(cs)
     {
     }
 };
+
+/**
+ * @brief RAII Interface for SPI bus acquisition
+ *
+ */
+class SPIAcquireLock
+{
+public:
+    SPIAcquireLock(SPISlave slave) : SPIAcquireLock(slave.bus, slave.config) {}
+
+    SPIAcquireLock(SPIBusInterface& bus, SPIBusConfig cfg) : bus(bus)
+    {
+        bus.acquire(cfg);
+    }
+
+    ~SPIAcquireLock() { bus.release(); }
+
+private:
+    SPIBusInterface& bus;
+};
+
+/**
+ * @brief RAII Interface for SPI chip selection
+ *
+ */
+class SPISelectLock
+{
+public:
+    SPISelectLock(SPISlave slave) : SPISelectLock(slave.bus, slave.cs) {}
+
+    SPISelectLock(SPIBusInterface& bus, GpioType cs) : bus(bus), cs(cs)
+    {
+        bus.select(cs);
+    }
+
+    ~SPISelectLock() { bus.deselect(cs); }
+
+private:
+    SPIBusInterface& bus;
+    GpioType& cs;
+};
\ No newline at end of file
diff --git a/src/shared/drivers/spi/SPITransaction.cpp b/src/shared/drivers/spi/SPITransaction.cpp
index de43334f0cb5770f0fdc6537748929f491e8f27f..b0bc6dfc8d44a4ca0bf93f854b6175d5b1d23c91 100644
--- a/src/shared/drivers/spi/SPITransaction.cpp
+++ b/src/shared/drivers/spi/SPITransaction.cpp
@@ -23,29 +23,19 @@
 
 #include "SPITransaction.h"
 
-#include <cassert>
-
 SPITransaction::SPITransaction(SPISlave slave)
     : SPITransaction(slave.bus, slave.cs, slave.config)
 {
 }
 
-SPITransaction::SPITransaction(SPIBusInterface& bus, GpioPin cs,
+SPITransaction::SPITransaction(SPIBusInterface& bus, GpioType cs,
                                SPIBusConfig config)
     : bus(bus), cs(cs)
 {
-    // Only one SPITransaction may be active at any given time.
-    // Do not store an instance of SPITransaction for a long time! Create one,
-    // use it, and destroy it as soon as you are done operating on the bus!
-    // (just like mutexes)
-#ifdef DEBUG
-    assert(bus.locked == false);
-#endif
-    bus.locked = true;
-    bus.configure(config);
+    bus.acquire(config);
 }
 
-SPITransaction::~SPITransaction() { bus.locked = false; }
+SPITransaction::~SPITransaction() { bus.release(); }
 
 void SPITransaction::write(uint8_t cmd)
 {
diff --git a/src/shared/drivers/spi/SPITransaction.h b/src/shared/drivers/spi/SPITransaction.h
index b75c20d4ab86f2fdc8e57f8f08e6ba6a7e6ee038..3ede19959f6f81d01c2fc5b170512df93cbef8b0 100644
--- a/src/shared/drivers/spi/SPITransaction.h
+++ b/src/shared/drivers/spi/SPITransaction.h
@@ -71,7 +71,7 @@ public:
      * @param    cs        Chip select of the slave to communicate to
      * @param    config    Configuration of the bus for the selected slave
      */
-    SPITransaction(SPIBusInterface& bus, GpioPin cs, SPIBusConfig config);
+    SPITransaction(SPIBusInterface& bus, GpioType cs, SPIBusConfig config);
 
     ~SPITransaction();
 
@@ -161,5 +161,5 @@ public:
 
 private:
     SPIBusInterface& bus;
-    GpioPin cs;
+    GpioType cs;
 };
\ No newline at end of file
diff --git a/src/shared/drivers/spi/SPIBus.cpp b/src/shared/drivers/spi/SyncedSPIBus.h
similarity index 53%
rename from src/shared/drivers/spi/SPIBus.cpp
rename to src/shared/drivers/spi/SyncedSPIBus.h
index a28324ce1933f44fa699e82658252cae5030ac6d..e71f77b140dcdb67efb2024d46e99c9e117699f8 100644
--- a/src/shared/drivers/spi/SPIBus.cpp
+++ b/src/shared/drivers/spi/SyncedSPIBus.h
@@ -21,38 +21,31 @@
  * THE SOFTWARE.
  */
 
+#pragma once
+
 #include "SPIBus.h"
+#include <miosix.h>
 
-SPIBus::SPIBus(SPI_TypeDef* spi) : spi(spi) {}
+using miosix::FastMutex;
 
-void SPIBus::configure(SPIBusConfig new_config)
+/**
+ * @brief Extension of SPIBus to sync access to the bus between multiple threads
+ */
+class SyncedSPIBus : public SPIBus
 {
-    // Reconfigure the bus only if config enabled. Do not reconfigure if already
-    // in the correct configuration.
-    if (config_enabled && (!first_config_applied || new_config != config))
+    virtual void acquire(SPIBusConfig config) override
     {
-        first_config_applied = true;
-        config               = new_config;
-
-        // Wait until the peripheral is done before changing configuration
-        while (!(spi->SR & SPI_SR_TXE))
-            ;
-        while ((spi->SR & SPI_SR_BSY))
-            ;
-
-        spi->CR1 = 0;
+        mutex.lock();
+        SPIBusInterface::acquire(config);
 
-        // Configure CPOL & CPHA bits
-        spi->CR1 |= static_cast<uint32_t>(config.mode);
-
-        // Configure clock division (BR bits)
-        spi->CR1 |= static_cast<uint32_t>(config.clock_div);
-
-        // Configure LSBFIRST bit
-        spi->CR1 |= static_cast<uint32_t>(config.bit_order);
+        configure(config);
+    }
 
-        spi->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM  // Use software chip-select
-                    | SPI_CR1_MSTR             // Master mode
-                    | SPI_CR1_SPE;             // Enable SPI
+    virtual void release() override
+    {
+        SPIBusInterface::release();
+        mutex.unlock();
     }
-}
\ No newline at end of file
+private:
+    FastMutex mutex;
+};
\ No newline at end of file
diff --git a/src/tests/catch/spidriver/FakeSpiTypedef.h b/src/shared/drivers/spi/test/FakeSpiTypedef.h
similarity index 89%
rename from src/tests/catch/spidriver/FakeSpiTypedef.h
rename to src/shared/drivers/spi/test/FakeSpiTypedef.h
index dab7a26fa77879e52f1316d44550f0acac447f2c..433a69f8a46105df511e42cd499dff0364734338 100644
--- a/src/tests/catch/spidriver/FakeSpiTypedef.h
+++ b/src/shared/drivers/spi/test/FakeSpiTypedef.h
@@ -26,24 +26,10 @@
 
 #include <cstdint>
 #include <vector>
+#include "utils/testutils/MockGpioPin.h"
 
 using std::vector;
 
-class FakeGpioPin : public miosix::GpioPin
-{
-public:
-    FakeGpioPin() : GpioPin(GPIOA_BASE,1) {}
-
-    void high() { val = 1; }
-
-    void low() { val = 0; }
-
-    int value() { return val; }
-
-private:
-    int val = 1;
-};
-
 /**
  * @brief Mock STM32F4 SPI peripheral: intercepts register value changes to
  * emulate a real SPI peripheral / slave.
@@ -93,7 +79,7 @@ struct FakeSpiTypedef
     uint32_t CR2_expected = 0;
 
     RegDR DR;
-    FakeGpioPin cs;
+    MockGpioPin cs;
 
-    FakeSpiTypedef() : DR(*this) {}
+    FakeSpiTypedef() : DR(*this) {cs.high();}
 };
\ No newline at end of file
diff --git a/src/shared/drivers/spi/MockSPIBus.h b/src/shared/drivers/spi/test/MockSPIBus.h
similarity index 52%
rename from src/shared/drivers/spi/MockSPIBus.h
rename to src/shared/drivers/spi/test/MockSPIBus.h
index d3436ffe53216251065910730c580914af6e49f8..8bb7aee7ce76d310667ab36098d8f57dc789c3df 100644
--- a/src/shared/drivers/spi/MockSPIBus.h
+++ b/src/shared/drivers/spi/test/MockSPIBus.h
@@ -24,9 +24,10 @@
 #pragma once
 
 #include <cstdint>
+#include <cstdio>
 #include <vector>
 
-#include "SPIBusInterface.h"
+#include "../SPIBusInterface.h"
 
 using std::vector;
 
@@ -47,10 +48,23 @@ using std::vector;
  * 5. ???
  * 6. Profit.
  */
+
+#ifndef USE_MOCK_PERIPHERALS
+#error \
+    "SpiBusInterface must be built using MockGpioPin (-DUSE_MOCK_PERIPHERALS)"
+#endif
+
+#include "utils/testutils/MockGpioPin.h"
+
+using miosix::FastMutex;
+using miosix::Lock;
 class MockSPIBus : public SPIBusInterface
 {
 public:
-    MockSPIBus() {}
+    MockSPIBus(SPIBusConfig expected_config) : expected_config(expected_config)
+    {
+    }
+
     ~MockSPIBus() {}
 
     // Delete copy/move contructors/operators
@@ -63,17 +77,17 @@ public:
     /**
      * @brief See SPIBusInterface::write()
      */
-    void write(uint8_t byte) override;
+    virtual void write(uint8_t byte) override;
 
     /**
      * @brief See SPIBusInterface::write()
      */
-    void write(uint8_t* data, size_t size) override;
+    virtual void write(uint8_t* data, size_t size) override;
 
     /**
      * @brief See SPIBusInterface::read()
      */
-    uint8_t read() override;
+    virtual uint8_t read() override;
 
     /**
      * @brief See SPIBusInterface::read()
@@ -83,57 +97,100 @@ public:
     /**
      * @brief See SPIBusInterface::transfer()
      */
-    uint8_t transfer(uint8_t data) override;
+    virtual uint8_t transfer(uint8_t data) override;
 
     /**
      * @brief See SPIBusInterface::transfer()
      */
-    void transfer(uint8_t* data, size_t size) override;
+    virtual void transfer(uint8_t* data, size_t size) override;
 
     /**
      * @brief See SPIBusInterface::select()
      *
-     * @param cs Not used, pass any GpioPin
      */
-    void select(GpioPin& cs) override;
+    virtual void select(GpioType& cs) override;
 
     /**
      * @brief See SPIBusInterface::deselect()
      *
-     * @param cs Not used, pass any GpioPin
      */
-    void deselect(GpioPin& cs) override;
+    virtual void deselect(GpioType& cs) override;
 
     /**
-     * @brief See SPIBusInterface::configure()
+     * @brief See SPIBusInterface::acquire()
      */
-    void configure(SPIBusConfig config) override;
+    virtual void acquire(SPIBusConfig config) override;
 
     /**
      * @brief Wether the chip select is asserted or not
      */
-    bool isSelected() { return selected; }
+    virtual bool isSelected()
+    {
+
+        Lock<FastMutex> l(mutex);
+        return selected;
+    }
+
+    virtual vector<uint8_t> getOutBuf()
+    {
+        Lock<FastMutex> l(mutex);
+        return out_buf;
+    }
+
+    virtual vector<uint8_t> getInBuf()
+    {
+        Lock<FastMutex> l(mutex);
+        return in_buf;
+    }
+
+    virtual void push(uint8_t* data, size_t len);
+
+    virtual void clearBuffers()
+    {
+        out_buf.clear();
+        in_buf.clear();
+        in_buf_pos_cntr = 0;
+    }
+
+protected:
+    FastMutex mutex;
 
     vector<uint8_t> out_buf;  // Data written on the bus are stored here
     vector<uint8_t> in_buf;   // Store here data to be read from the bus
-
-    unsigned int in_buf_pos = 0;  // Read data iterator
+    size_t in_buf_pos_cntr = 0;
 
     SPIBusConfig expected_config;  // Expected configuration of the bus
 
-private:
+    virtual uint8_t _read();
+    virtual void _write(uint8_t);
+
+    virtual void _push(uint8_t* data, size_t len);
+
     bool canCommunicate();
 
     SPIBusConfig current_config;
     bool selected = false;
 };
 
-bool MockSPIBus::canCommunicate()
+inline bool MockSPIBus::canCommunicate()
 {
-    return selected && current_config == expected_config;
+    bool result = selected && current_config == expected_config;
+    if (!result)
+    {
+        printf("Error, cannot communicato on MockSPIBus: ");
+        if (!selected)
+        {
+            printf("Chip select not asserted\n");
+        }
+        else
+        {
+            printf("Incorrect configuration\n");
+        }
+    }
+    return result;
 }
 
-void MockSPIBus::write(uint8_t byte)
+inline void MockSPIBus::_write(uint8_t byte)
 {
     if (canCommunicate())
     {
@@ -145,95 +202,97 @@ void MockSPIBus::write(uint8_t byte)
     }
 }
 
-void MockSPIBus::write(uint8_t* data, size_t size)
+inline void MockSPIBus::write(uint8_t byte)
 {
-    if (canCommunicate())
-    {
-        out_buf.insert(out_buf.end(), data, data + size);
-    }
-    else
-    {
-        out_buf.insert(out_buf.end(), size, 0);
-    }
+    Lock<FastMutex> l(mutex);
+    _write(byte);
 }
 
-uint8_t MockSPIBus::read()
+inline void MockSPIBus::write(uint8_t* data, size_t size)
 {
-    if (canCommunicate())
+    Lock<FastMutex> l(mutex);
+
+    for (size_t i = 0; i < size; i++)
     {
-        return in_buf[in_buf_pos++];
+        _write(data[i]);
     }
-    return 0;
 }
 
-void MockSPIBus::read(uint8_t* data, size_t size)
+inline uint8_t MockSPIBus::read()
 {
-    if (canCommunicate())
-    {
-        for (size_t i = 0; i < size; i++)
-        {
-            *data = in_buf[in_buf_pos++];
-            data++;
-        }
-    }
-    else
-    {
-        for (size_t i = 0; i < size; i++)
-        {
-            *data = 0;
-            data++;
-        }
-    }
+    Lock<FastMutex> l(mutex);
+    return _read();
 }
 
-uint8_t MockSPIBus::transfer(uint8_t data)
+inline void MockSPIBus::read(uint8_t* data, size_t size)
 {
-    if (canCommunicate())
+    Lock<FastMutex> l(mutex);
+    for (size_t i = 0; i < size; i++)
     {
-
-        out_buf.push_back(data);
-        return in_buf[in_buf_pos++];
-    }
-    else
-    {
-
-        out_buf.push_back(0);
-        return 0;
+        *data = _read();
+        data++;
     }
 }
 
-void MockSPIBus::transfer(uint8_t* data, size_t size)
+inline uint8_t MockSPIBus::_read()
 {
     if (canCommunicate())
     {
-        for (size_t i = 0; i < size; i++)
+        if (in_buf_pos_cntr < in_buf.size())
         {
-            out_buf.push_back(*data);
-            *data = in_buf[in_buf_pos++];
-            data++;
+            return in_buf[in_buf_pos_cntr++];
         }
     }
-    else
+    return 0;
+}
+
+inline uint8_t MockSPIBus::transfer(uint8_t data)
+{
+    Lock<FastMutex> l(mutex);
+    _write(data);
+    return _read();
+}
+
+inline void MockSPIBus::transfer(uint8_t* data, size_t size)
+{
+    Lock<FastMutex> l(mutex);
+    for (size_t i = 0; i < size; i++)
     {
-        for (size_t i = 0; i < size; i++)
-        {
-            out_buf.push_back(0);
-            *data = 0;
-            data++;
-        }
+        _write(data[i]);
+        data[i] = _read();
     }
 }
 
-void MockSPIBus::select(GpioPin& cs)
+inline void MockSPIBus::select(GpioType& cs)
 {
-    (void)cs;
+    Lock<FastMutex> l(mutex);
+    cs.low();
     selected = true;
 }
 
-void MockSPIBus::deselect(GpioPin& cs)
+inline void MockSPIBus::deselect(GpioType& cs)
 {
-    (void)cs;
+    Lock<FastMutex> l(mutex);
+    cs.high();
     selected = false;
 }
 
-void MockSPIBus::configure(SPIBusConfig config) { current_config = config; }
\ No newline at end of file
+inline void MockSPIBus::acquire(SPIBusConfig config)
+{
+    Lock<FastMutex> l(mutex);
+
+    SPIBusInterface::acquire(config);
+
+    current_config = config;
+}
+
+inline void MockSPIBus::push(uint8_t* data, size_t len)
+{
+    Lock<FastMutex> l(mutex);
+    _push(data, len);
+}
+
+inline void MockSPIBus::_push(uint8_t* data, size_t len)
+{
+    in_buf.insert(in_buf.end(), data, data + len);
+}
\ No newline at end of file
diff --git a/src/shared/logger/Deserializer.h b/src/shared/logger/Deserializer.h
index aa673fdaa38496cd21644179171d1aae112a75e2..7c1193f8620d5b4e2c56d9d5ad00ce39c1aee02c 100644
--- a/src/shared/logger/Deserializer.h
+++ b/src/shared/logger/Deserializer.h
@@ -83,7 +83,7 @@ public:
             return false;
         }
 
-        char c_filename[64];
+        char c_filename[128];
         sprintf(c_filename, "%s%s_%s.csv", prefix.c_str(), logFile.c_str(),
                 typeid(T).name());
 
diff --git a/src/shared/logger/Logger.cpp b/src/shared/logger/Logger.cpp
index afa1d7656c1076a320c80987a856a17df3062dbb..2a4e6e789f387ca4c5b5e5d0f9d8f5e8c8473ed6 100644
--- a/src/shared/logger/Logger.cpp
+++ b/src/shared/logger/Logger.cpp
@@ -26,16 +26,19 @@
  ***************************************************************************/
 
 #include "Logger.h"
+
+#include <errno.h>
 #include <fcntl.h>
 #include <interfaces/atomic_ops.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <tscpp/buffer.h>
+
 #include <stdexcept>
+
 #include "Debug.h"
 #include "diagnostic/SkywardStack.h"
 #include "diagnostic/StackLogger.h"
-#include <errno.h>
 
 using namespace std;
 using namespace miosix;
@@ -74,7 +77,10 @@ int Logger::start()
 
     file = fopen(filename.c_str(), "ab");
     if (file == NULL)
+    {
+        fileNumber = -1;
         throw runtime_error("Error opening log file");
+    }
     setbuf(file, NULL);
 
     // The boring part, start threads one by one and if they fail, undo
diff --git a/src/shared/logger/Logger.h b/src/shared/logger/Logger.h
index 0794e0fa6f67f2780226b17ec41612edecce2610..1c313805a21ea9d9794bb99f79a17120bb1528bd 100644
--- a/src/shared/logger/Logger.h
+++ b/src/shared/logger/Logger.h
@@ -28,11 +28,13 @@
 #pragma once
 
 #include <miosix.h>
+
 #include <cstdio>
 #include <list>
 #include <queue>
 #include <string>
 #include <type_traits>
+
 #include "LogStats.h"
 
 using std::string;
@@ -101,9 +103,9 @@ public:
     }
 
     /**
-    * Returns current log filename
-    * @return
-    */
+     * Returns current log filename
+     * @return
+     */
     string getFileName() { return getFileName(fileNumber); }
 
     LogStats getLogStats() { return s; }
@@ -129,7 +131,10 @@ public:
     template <typename T>
     LogResult log(const T &t)
     {
-        // static_assert(std::is_trivially_copyable<T>::value,"");
+        static_assert(
+            std::is_trivially_copyable<T>::value,
+            "A type T must be trivially copyable in order to be logged!");
+
         return logImpl(typeid(t).name(), &t, sizeof(t));
     }
 
@@ -176,8 +181,8 @@ private:
 
     static const unsigned int filenameMaxRetry =
         100;                                         ///< Limit on new filename
-    static const unsigned int maxRecordSize = 256;   ///< Limit on logged data
-    static const unsigned int numRecords    = 1024;  ///< Size of record queues
+    static const unsigned int maxRecordSize = 512;   ///< Limit on logged data
+    static const unsigned int numRecords    = 512;  ///< Size of record queues
     static const unsigned int bufferSize = 64 * 1024;  ///< Size of each buffer
     static const unsigned int numBuffers = 8;          ///< Number of buffers
 
diff --git a/src/shared/math/Stats.cpp b/src/shared/math/Stats.cpp
index 3b3567a716bd53d048fa16aa723c5de331a22729..43231d8f20f998784a19af71c6062ef0b9053be2 100644
--- a/src/shared/math/Stats.cpp
+++ b/src/shared/math/Stats.cpp
@@ -42,7 +42,7 @@ ostream& operator<<(ostream& os, const StatsResult& sr)
 
 Stats::Stats()
     : minValue(numeric_limits<float>::max()),
-      maxValue(numeric_limits<float>::min()), mean(0.f), m2(0.f), n(0)
+      maxValue(numeric_limits<float>::lowest()), mean(0.f), m2(0.f), n(0)
 {
 }
 
@@ -64,7 +64,7 @@ void Stats::add(float data)
 void Stats::reset()
 {
     minValue = numeric_limits<float>::max();
-    maxValue = numeric_limits<float>::min();
+    maxValue = numeric_limits<float>::lowest();
     mean     = 0.f;
     m2       = 0.f;
     n        = 0;
diff --git a/src/shared/sensors/MS580301BA07/MS580301BA07.h b/src/shared/sensors/MS580301BA07/MS580301BA07.h
index efc5e36187084a22c26c4e42e0f70044e9162758..4aefbee2a3241cbce27eb82adc44eaa07f2454bf 100644
--- a/src/shared/sensors/MS580301BA07/MS580301BA07.h
+++ b/src/shared/sensors/MS580301BA07/MS580301BA07.h
@@ -123,7 +123,7 @@ public:
             case STATE_INIT:
                 spi.write(CONVERT_D1_4096);
                 mStatus = STATE_SAMPLED_PRESSURE;
-
+                break;
             case STATE_SAMPLED_PRESSURE:
                 spi.read(ADC_READ, rcvbuf, 3, false);
                 mInternalPressure = rcvbuf[2] | ((uint32_t)rcvbuf[1] << 8) |
diff --git a/src/shared/utils/gui/GridLayout.h b/src/shared/utils/gui/GridLayout.h
new file mode 100644
index 0000000000000000000000000000000000000000..d5bd5441802295263d742a3044a29fd860f5fc12
--- /dev/null
+++ b/src/shared/utils/gui/GridLayout.h
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <mxgui/misc_inst.h>
+
+#include <map>
+
+#include "View.h"
+
+/**
+ * @brief Displays childs in a num_rows*num_cols grid
+ */
+class GridLayout : public View
+{
+public:
+    using GridPosition = std::pair<uint8_t, uint8_t>;
+
+    /**
+     * @brief Creates a new GridLayout
+     * 
+     * @param num_rows Number of rows
+     * @param num_cols Number of columns
+     * @param spacing Distance in pixels between each cell
+     */
+    GridLayout(uint8_t num_rows, uint8_t num_cols, short int spacing = 0)
+        : View(), num_rows(num_rows), num_cols(num_cols), spacing(spacing)
+    {
+    }
+
+    virtual ~GridLayout() {}
+
+    void setCell(View* child, unsigned int position)
+    {
+        uint8_t col = position % num_cols;
+        uint8_t row = (position - col) / num_cols;
+
+        setCell(child, row, col);
+    }
+
+    void setCell(View* child, uint8_t row, uint8_t col)
+    {
+        if (row >= num_rows || col >= num_cols)
+        {
+            return;
+        }
+
+        map_childs[GridPosition(row, col)] = child;
+        
+        updateChildBounds();
+        invalidate();
+    }
+
+    View* getCell(uint8_t row, uint8_t col)
+    {
+        GridPosition pos(row, col);
+
+        if (map_childs.count(pos) > 0)
+            return map_childs[pos];
+        else
+            return nullptr;
+    }
+
+    View* getCell(unsigned int position)
+    {
+        uint8_t col = position % num_cols;
+        uint8_t row = position - col / num_rows;
+
+        return getCell(row, col);
+    }
+
+    void clearCell(View* child)
+    {
+        for (auto it = map_childs.begin(); it != map_childs.end(); it++)
+        {
+            if (it->second == child)
+            {
+                map_childs.erase(it);
+                break;
+            }
+        }
+
+        invalidate();
+    }
+
+    /**
+     * @brief Wether to draw the borders of each cell or not
+     * 
+     * @param draw_border True: draw the border
+     * @param color Border color
+     */
+    void setDrawBorder(bool draw_border, mxgui::Color color = mxgui::white)
+    {
+        this->draw_border = draw_border;
+        border_color      = color;
+
+        invalidate();
+    }
+
+    void setBounds(Bounds bounds) override
+    {
+        View::setBounds(bounds);
+
+        updateChildBounds();
+    }
+
+    virtual void draw(mxgui::DrawingContext& context) override
+    {
+        View::draw(context);
+
+        for (uint8_t row = 0; row < num_rows; ++row)
+        {
+            for (uint8_t col = 0; col < num_cols; ++col)
+            {
+                GridPosition pos(row, col);
+
+                bool child_selected = false;
+                if (map_childs.count(pos) > 0)
+                {
+                    map_childs[pos]->draw(context);
+                    child_selected = map_childs[pos]->isSelected();
+                }
+
+                if (draw_border && !child_selected)
+                {
+                    context.drawRectangle(
+                        map_child_bounds[pos].topLeft(),
+                        map_child_bounds[pos].bottomRight(), border_color);
+                }
+            }
+        }   
+    }
+
+    uint8_t getRows() { return num_rows; }
+
+    uint8_t getCols() { return num_cols; }
+
+    std::vector<View*> getChilds() override
+    {
+        std::vector<View*> out;
+        for (auto it = map_childs.begin(); it != map_childs.end(); it++)
+        {
+            out.push_back(it->second);
+        }
+        return out;
+    }
+
+private:
+    void updateChildBounds()
+    {
+        Bounds bounds = getBounds();
+        Bounds child_bounds;
+
+        child_bounds.size.width = std::max(
+            0, (bounds.size.width - (num_cols + 1) * spacing) / num_cols);
+        child_bounds.size.height = std::max(
+            0, (bounds.size.height - (num_rows + 1) * spacing) / num_rows);
+
+        for (uint8_t row = 0; row < num_rows; ++row)
+        {
+            for (uint8_t col = 0; col < num_cols; ++col)
+            {
+                GridPosition pos(row, col);
+
+                child_bounds.pos.x = bounds.pos.x + (col + 1) * spacing +
+                                     col * child_bounds.size.width;
+                child_bounds.pos.y = bounds.pos.y + (row + 1) * spacing +
+                                     row * child_bounds.size.height;
+
+                map_child_bounds[pos] = child_bounds;
+                if (map_childs.count(pos) > 0)
+                {
+                    map_childs[pos]->setBounds(child_bounds);
+                }
+            }
+        }
+    }
+
+    uint8_t num_rows;
+    uint8_t num_cols;
+    short int spacing;
+
+    bool draw_border          = false;
+    mxgui::Color border_color = mxgui::white;
+
+    std::map<GridPosition, View*> map_childs;
+    std::map<GridPosition, Bounds> map_child_bounds;
+};
\ No newline at end of file
diff --git a/src/shared/utils/gui/ImageView.h b/src/shared/utils/gui/ImageView.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ecdc37bba903f81cec7c0fb2823253f9ea6ae76
--- /dev/null
+++ b/src/shared/utils/gui/ImageView.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <mxgui/image.h>
+
+#include "View.h"
+
+/**
+ * @brief Simple view that displays an image
+ */
+class ImageView : public View
+{
+public:
+    ImageView(const mxgui::Image* image) : image(image) {}
+
+    void setImage(mxgui::Image* image)
+    {
+        this->image = image;
+        invalidate();
+    }
+
+    const mxgui::Image* getImage() { return image; }
+
+    void draw(mxgui::DrawingContext& dc) override
+    {
+        if (isInvalidated())
+        {
+            View::draw(dc);
+
+            dc.clippedDrawImage(getBounds().topLeft(), getBounds().topLeft(),
+                                getBounds().bottomRight(), *image);
+        }
+    }
+private:
+    const mxgui::Image* image;
+};
\ No newline at end of file
diff --git a/src/shared/utils/gui/Misc.h b/src/shared/utils/gui/Misc.h
new file mode 100644
index 0000000000000000000000000000000000000000..0576c5afa101d13646e28cf60a0a4f48538f7f74
--- /dev/null
+++ b/src/shared/utils/gui/Misc.h
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+#include <mxgui/display.h>
+
+/**
+ * @brief Converts a 24bit color to a 16bit color
+ * 
+ * @param rgb 24 bit color
+ * @return Color Closest 16 bit color
+ */
+mxgui::Color color24to16(uint32_t rgb)
+{
+    uint8_t r, g, b;
+    r = ((rgb >> 2) & 0xFF) >> 3;
+    g = ((rgb >> 1) & 0xFF) >> 3;
+    b = (rgb & 0xFF) >> 3;
+    return ((b << 10) | (g << 5) | (r));
+}
\ No newline at end of file
diff --git a/src/shared/utils/gui/NavController.h b/src/shared/utils/gui/NavController.h
new file mode 100644
index 0000000000000000000000000000000000000000..7cd611aceb485ecebd16b241abc13f8162aa0407
--- /dev/null
+++ b/src/shared/utils/gui/NavController.h
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "Debug.h"
+#include "TextView.h"
+#include "View.h"
+#include "utils/ButtonHandler.h"
+
+/**
+ * @brief UI navigation controller: listens for button clicks and dispatches the
+ * interactions to the view tree.
+ */
+class NavController
+{
+public:
+    NavController() {}
+
+    /**
+     * @brief
+     *
+     * @param root
+     */
+    void updateViewTree(View* root)
+    {
+        if (selected_index < vec_selectable.size())
+        {
+            vec_selectable.at(selected_index)->setSelected(false);
+        }
+
+        vec_selectable.clear();
+        selected_index = 0;
+
+        updateSelectableViews(root);
+
+        if (vec_selectable.size() > 0)
+        {
+            vec_selectable.at(0)->setSelected(true);
+        }
+    }
+
+    void onButtonPress(ButtonPress press)
+    {
+        switch (press)
+        {
+            case ButtonPress::SHORT:
+                if (vec_selectable.size() > 0)
+                {
+                    selectNext();
+                }
+                break;
+            case ButtonPress::DOWN:
+                if (selected_index < vec_selectable.size())
+                {
+                    vec_selectable.at(selected_index)
+                        ->performInteraction(Interaction::BTN_DOWN);
+                }
+                break;
+            case ButtonPress::UP:
+                if (selected_index < vec_selectable.size())
+                {
+                    vec_selectable.at(selected_index)
+                        ->performInteraction(Interaction::BTN_UP);
+                }
+                break;
+            case ButtonPress::LONG:
+                if (selected_index < vec_selectable.size())
+                {
+                    vec_selectable.at(selected_index)
+                        ->performInteraction(Interaction::CLICK);
+                }
+                break;
+            case ButtonPress::VERY_LONG:
+                if (selected_index < vec_selectable.size())
+                {
+                    vec_selectable.at(selected_index)
+                        ->performInteraction(Interaction::LONG_CLICK);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+private:
+    void selectNext()
+    {
+        // Deselect old drawble
+        if (selected_index < vec_selectable.size())
+        {
+            vec_selectable.at(selected_index)->setSelected(false);
+        }
+
+        if (vec_selectable.size() > 0)
+        {
+            selected_index = (selected_index + 1) % vec_selectable.size();
+
+            vec_selectable.at(selected_index)->setSelected(true);
+
+            TextView* text =
+                dynamic_cast<TextView*>(vec_selectable.at(selected_index));
+
+            if (text)
+            {
+                TRACE("[NavController] %s\n", text->getText().c_str());
+            }
+        }
+    }
+
+    void updateSelectableViews(View* root)
+    {
+        std::vector<View*> childs = root->getChilds();
+        for (auto child : childs)
+        {
+            if (child->isSelectable())
+            {
+                vec_selectable.push_back(child);
+            }
+            updateSelectableViews(child);
+        }
+    }
+
+    unsigned int selected_index = 0;
+    std::vector<View*> vec_selectable;
+};
\ No newline at end of file
diff --git a/src/shared/utils/gui/OptionView.h b/src/shared/utils/gui/OptionView.h
new file mode 100644
index 0000000000000000000000000000000000000000..9dbef9b77442c23fcfec96bb8d1581aabac8c1df
--- /dev/null
+++ b/src/shared/utils/gui/OptionView.h
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+
+#include "GridLayout.h"
+#include "TextView.h"
+
+/**
+ * @brief View used to display an option list, so the user can select one by
+ * clicking on it.
+ */
+class OptionView : public View
+{
+public:
+    using OnOptionChosenListener = std::function<void(unsigned int id)>;
+
+    OptionView(std::string name, std::map<uint8_t, std::string> options,
+               uint8_t default_option = 0, uint8_t num_cols = 4)
+        : tv_title(new TextView(name))
+    {
+        uint8_t num_rows = options.size() / num_cols;
+        if (options.size() % num_cols != 0)
+        {
+            ++num_rows;
+        }
+
+        grid_options = new GridLayout(num_rows, num_cols);
+
+        unsigned int grid_pos = 0;
+        unsigned int i        = 0;
+        for (auto it = options.begin(); it != options.end(); it++)
+        {
+            using namespace std::placeholders;
+
+            TextView* tv_opt = new TextView(it->second);
+            tv_opt->setSelectable(true);
+            tv_opt->addOnInteractionListener(
+                std::bind(&OptionView::onOptionClick, this, _1, _2));
+            tv_opt->setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+
+            map_options[tv_opt] = it->first;
+
+            grid_options->setCell(tv_opt, grid_pos++);
+
+            if (i == default_option)
+            {
+                selectOption(tv_opt);
+            }
+
+            ++i;
+        }
+    }
+
+    virtual ~OptionView()
+    {
+        delete grid_options;
+        delete tv_title;
+        for (auto it = map_options.begin(); it != map_options.end(); it++)
+        {
+            delete it->first;
+        }
+    }
+
+    void setBounds(Bounds bounds) override
+    {
+        View::setBounds(bounds);
+
+        Bounds title_bounds      = getBounds();
+        title_bounds.size.height = tv_title->getFont().getHeight();
+        tv_title->setBounds(title_bounds);
+
+        Bounds grid_bounds = getBounds();
+        grid_bounds.pos.y  = getBounds().pos.y + title_bounds.size.height + 1;
+        grid_bounds.size.height =
+            getBounds().size.height - title_bounds.size.height;
+
+        grid_options->setBounds(grid_bounds);
+    }
+
+    /**
+     * @brief Adds a callback to be called each time an option is selected by
+     * the user
+     */
+    void addOnOptionChosenListener(OnOptionChosenListener listener)
+    {
+        opt_listeners.push_back(listener);
+    }
+
+    std::vector<View*> getChilds() override
+    {
+        std::vector<View*> out;
+        out.push_back(tv_title);
+        out.push_back(grid_options);
+
+        return out;
+    }
+
+    void draw(mxgui::DrawingContext& dc) override
+    {
+        View::draw(dc);
+        tv_title->draw(dc);
+        grid_options->draw(dc);
+    }
+
+private:
+    void selectOption(TextView* opt)
+    {
+        if (selected_option != nullptr)
+        {
+            selected_option->setBackgroundColor(col_bg_normal);
+        }
+
+        selected_option = opt;
+
+        selected_option->setBackgroundColor(col_bg_highlight);
+    }
+
+    void onOptionClick(View* option, Interaction action)
+    {
+        if (action == Interaction::CLICK)
+        {
+            TextView* textview = static_cast<TextView*>(option);
+
+            selectOption(textview);
+
+            for (auto l : opt_listeners)
+            {
+                if (l != nullptr)
+                {
+                    l(map_options[textview]);
+                }
+            }
+        }
+    }
+
+    TextView* tv_title;
+    mxgui::Color col_bg_normal    = mxgui::black;
+    mxgui::Color col_bg_highlight = mxgui::blue;
+
+    GridLayout* grid_options;
+    std::map<TextView*, uint8_t> map_options;
+
+    std::vector<OnOptionChosenListener> opt_listeners;
+
+    TextView* selected_option = nullptr;
+};
\ No newline at end of file
diff --git a/src/shared/utils/gui/ScreenManager.h b/src/shared/utils/gui/ScreenManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8b34e352caadf4908c45dcb782a6b5e1bc7394b
--- /dev/null
+++ b/src/shared/utils/gui/ScreenManager.h
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <miosix.h>
+
+#include <map>
+#include <deque>
+
+#include "NavController.h"
+#include "View.h"
+
+/**
+ * @brief UI Thread: Manages multiple view trees ("Screen") and draws the active
+ * one at the provided refresh rate
+ */
+class ScreenManager : public ActiveObject
+{
+public:
+    ScreenManager(mxgui::DisplayManager& display, unsigned int refresh_rate)
+        : dc(display.getDisplay()), refresh_interval(1000 / refresh_rate)
+    {
+    }
+
+    void showScreen(uint8_t id)
+    {
+        active_screen = id;
+        controller.updateViewTree(screens[id]);
+    }
+
+    uint8_t getScreen() { return active_screen; }
+
+    void addScreen(uint8_t id, View* root)
+    {
+        screens[id] = root;
+
+        root->setBounds({{0, 0}, {dc.getWidth(), dc.getHeight()}});
+
+        if (screens.size() == 1)
+        {
+            showScreen(id);
+        }
+    }
+
+    void onButtonPress(ButtonPress press) { controller.onButtonPress(press); }
+
+    mxgui::DrawingContext& getDrawingContext() { return dc; }
+
+protected:
+    void run() override
+    {
+        uint8_t last_screen = 0;
+        while (!shouldStop())
+        {
+            if (active_screen != last_screen)
+            {
+                last_screen = active_screen;
+                dc.clear(mxgui::black);
+                screens[active_screen]->invalidateTree();
+            }
+
+            long long start = miosix::getTick();
+
+            drawViewTree(screens[active_screen], dc);
+
+            Thread::sleepUntil(start + refresh_interval);
+        }
+    }
+private:
+    /**
+     * @brief Draws the provided view tree on screen
+     * 
+     * @param root Root of the view tree
+     * @param dc Drawing context
+     */
+    void drawViewTree(View* root, mxgui::DrawingContext& dc)
+    {
+        // Avoid recursion
+        std::deque<View*> views_dc;
+        views_dc.push_back(root);
+
+        while(views_dc.size() != 0)
+        {
+            View* view = views_dc.front();
+            views_dc.pop_front();
+
+            view->draw(dc);
+
+            for(View* c : view->getChilds())
+            {
+                views_dc.push_back(c);
+            }
+        }
+    }
+
+    mxgui::DrawingContext dc;
+
+    unsigned int refresh_interval;
+
+    NavController controller;
+    std::map<uint8_t, View*> screens;
+
+    uint8_t active_screen = 0;
+};
\ No newline at end of file
diff --git a/src/shared/utils/gui/TextView.h b/src/shared/utils/gui/TextView.h
new file mode 100644
index 0000000000000000000000000000000000000000..a695e0ccd9996cea6a17c2533e5810890928c9a9
--- /dev/null
+++ b/src/shared/utils/gui/TextView.h
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <mxgui/misc_inst.h>
+
+#include "View.h"
+
+/**
+ * @brief Simple view to display text on screen.
+ *
+ */
+class TextView : public View
+{
+public:
+    /**
+     * @brief Creates a new TextView
+     *
+     * @param text Text
+     * @param text_color Text color
+     * @param padding Spacing from view bounds in pixels
+     */
+    TextView(std::string text = "", mxgui::Color text_color = mxgui::white,
+             uint8_t padding = 1)
+        : View(), text(text), col_text(text_color), padding(padding)
+    {
+    }
+
+    void setVerticalAlignment(VertAlignment alignment)
+    {
+        vert_align = alignment;
+        invalidate();
+    }
+
+    void setHorizontalAlignment(HorizAlignment alignment)
+    {
+        horiz_align = alignment;
+        invalidate();
+    }
+
+    void setAlignment(HorizAlignment horiz_align, VertAlignment vert_align)
+    {
+        setVerticalAlignment(vert_align);
+        setHorizontalAlignment(horiz_align);
+    }
+
+    void setText(std::string text)
+    {
+        if (text != this->text)
+        {
+            invalidate();
+            this->text = text;
+        }
+    }
+
+    std::string getText() { return text; }
+
+    virtual void setTextColor(mxgui::Color color)
+    {
+        if (color != col_text)
+        {
+            this->col_text = color;
+            invalidate();
+        }
+    }
+
+    mxgui::Color getTextColor() { return col_text; }
+
+    virtual void draw(mxgui::DrawingContext& dc) override
+    {
+        if (isInvalidated())
+        {
+            View::draw(dc);
+
+            Bounds padded_bounds = getBounds();
+            padded_bounds.pos += Position{padding, padding};
+            padded_bounds.size.height -= padding;
+            padded_bounds.size.width -= padding;
+
+            Position top_left = padded_bounds.topLeft();
+            switch (vert_align)
+            {
+                case VertAlignment::BOTTOM:
+                    top_left.y =
+                        padded_bounds.bottomLeft().y - dc.getFont().getHeight();
+                    break;
+                case VertAlignment::CENTER:
+                    top_left.y =
+                        padded_bounds.pos.y +
+                        (padded_bounds.size.height - dc.getFont().getHeight()) /
+                            2;
+                    break;
+                case VertAlignment::TOP:
+                    break;
+            }
+
+            switch (horiz_align)
+            {
+                case HorizAlignment::RIGHT:
+                    top_left.x =
+                        padded_bounds.topRight().x - getTextWidth(text);
+                    break;
+                case HorizAlignment::CENTER:
+                    top_left.x =
+                        padded_bounds.pos.x +
+                        (padded_bounds.size.width - getTextWidth(text)) / 2;
+                    break;
+                case HorizAlignment::LEFT:
+                    break;
+            }
+
+            mxgui::Font old_font = dc.getFont();
+            dc.setFont(font);
+
+            dc.setTextColor(getTextColor(), getBackgroundColor());
+            dc.clippedWrite(top_left, padded_bounds.topLeft(),
+                            padded_bounds.bottomRight(), text);
+
+            dc.setFont(old_font);
+        }
+    }
+
+    void setFont(mxgui::Font font)
+    {
+        this->font = font;
+        invalidate();
+    }
+
+    mxgui::Font getFont() { return font; }
+
+protected:
+    short int getTextWidth(std::string text)
+    {
+        short int w = 0;
+        for (char c : text)
+        {
+            if (c >= font.getStartChar() && c <= font.getEndChar())
+            {
+                if (font.isFixedWidth())
+                {
+                    w += font.getWidth();
+                }
+                else
+                {
+                    w += font.getWidths()[c - font.getStartChar()];
+                }
+            }
+        }
+        return w;
+    }
+
+private:
+    mxgui::Font font           = mxgui::tahoma;
+    VertAlignment vert_align   = VertAlignment::TOP;
+    HorizAlignment horiz_align = HorizAlignment::LEFT;
+    std::string text;
+
+    mxgui::Color col_text = mxgui::white;
+    uint8_t padding;
+};
\ No newline at end of file
diff --git a/src/shared/utils/gui/VerticalLayout.h b/src/shared/utils/gui/VerticalLayout.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d19c2eb02f6c44bbdcfed1f594c425feb00f4fa
--- /dev/null
+++ b/src/shared/utils/gui/VerticalLayout.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "View.h"
+
+/**
+ * @brief Positions the childs in a vertical grid. The height of each child is
+ * dictated by its weight parameter
+ */
+class VerticalLayout : public View
+{
+public:
+    /**
+     * @brief Creates a new VerticalLayout
+     *
+     * @param spacing Vertical space between each child in pixels
+     */
+    VerticalLayout(short int spacing = 0) : View(), spacing(spacing) {}
+
+    /**
+     * @brief Adds a view to the layout.
+     *
+     * @param view Pointer to the view to be added
+     * @param weight Relative weight of the view to determine its display height
+     */
+    void addView(View* view, float weight)
+    {
+        if (weight < 0)
+            weight = 0;
+        childs.push_back({weight, view});
+        weigth_sum += weight;
+
+        // Recalculated child bounds
+        updateChildBounds();
+
+        // Redraw
+        invalidate();
+    }
+
+    void setBounds(Bounds bounds) override
+    {
+        View::setBounds(bounds);
+
+        updateChildBounds();
+    }
+
+    void draw(mxgui::DrawingContext& dc) override
+    {
+        View::draw(dc);
+
+        for (auto view : childs)
+        {
+            view.drawable->draw(dc);
+        }
+    }
+
+    virtual std::vector<View*> getChilds() override
+    {
+        std::vector<View*> out;
+        out.reserve(childs.size());
+        for (auto v : childs)
+        {
+            out.push_back(v.drawable);
+        }
+        return out;
+    }
+
+private:
+    void updateChildBounds()
+    {
+        if (weigth_sum > 0)
+        {
+            short int aval_height =
+                getBounds().size.height - (childs.size() - 1) * spacing;
+
+            short int y = 0;
+
+            for (auto view : childs)
+            {
+                Bounds view_bounds{{0, y}, {getBounds().size.width, 0}};
+
+                view_bounds.size.height =
+                    aval_height / weigth_sum * view.vert_weight;
+                view_bounds.pos += getBounds().pos;
+
+                view.drawable->setBounds(view_bounds);
+
+                y += view_bounds.size.height + spacing;
+            }
+        }
+    }
+
+    struct Child
+    {
+        float vert_weight;
+        View* drawable;
+    };
+
+    float weigth_sum = 0;
+    short int spacing;
+    std::vector<Child> childs;
+};
\ No newline at end of file
diff --git a/src/shared/utils/gui/View.h b/src/shared/utils/gui/View.h
new file mode 100644
index 0000000000000000000000000000000000000000..ffa4a844984c942f2e507d77598d75a09d476fb3
--- /dev/null
+++ b/src/shared/utils/gui/View.h
@@ -0,0 +1,261 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <mxgui/display.h>
+#include <mxgui/misc_inst.h>
+
+#include <functional>
+
+#include "Misc.h"
+
+struct Size
+{
+    short int width;
+    short int height;
+};
+
+struct Position
+{
+    short int x;
+    short int y;
+
+    operator mxgui::Point() { return mxgui::Point(x, y); }
+
+    Position operator+(const Position& other)
+    {
+        return {short(x + other.x), short(y + other.y)};
+    }
+
+    Position operator-(const Position& other)
+    {
+        return {short(x - other.x), short(y - other.y)};
+    }
+
+    void operator+=(const Position& other)
+    {
+        x += other.x;
+        y += other.y;
+    }
+
+    void operator-=(const Position& other)
+    {
+        x -= other.x;
+        y -= other.y;
+    }
+
+    void print() { printf("pos: %d %d\n", x, y); }
+};
+
+struct Bounds
+{
+    Position pos;
+    Size size;
+
+    Position topLeft() { return {pos.x, pos.y}; }
+    Position topRight() { return {short(pos.x + size.width - 1), pos.y}; }
+
+    Position bottomRight()
+    {
+        return {short(pos.x + size.width - 1), short(pos.y + size.height - 1)};
+    }
+
+    Position bottomLeft()
+    {
+        return {pos.x, short(pos.y + short(size.height - 1))};
+    }
+
+    void print()
+    {
+        printf("Bounds: p:{%d %d} s:{%d %d}\n", pos.x, pos.y, size.width,
+               size.height);
+    }
+};
+
+enum class VertAlignment
+{
+    TOP,
+    CENTER,
+    BOTTOM
+};
+
+enum class HorizAlignment
+{
+    LEFT,
+    CENTER,
+    RIGHT
+};
+
+enum class Interaction
+{
+    BTN_DOWN,
+    BTN_UP,
+    CLICK,
+    LONG_CLICK
+};
+
+/**
+ * @brief Base class for anything that can be drawn on the screen and interacted
+ * with
+ */
+class View
+{
+public:
+    using OnInteractionListener = std::function<void(View*, Interaction)>;
+
+    View() {}
+    virtual ~View() {}
+
+    /**
+     * @brief Sets the bounds in which the view will be drawn
+     */
+    virtual void setBounds(Bounds bounds)
+    {
+        this->bounds = bounds;
+        invalidate();
+    }
+
+    Bounds getBounds() { return bounds; }
+
+    /**
+     * @brief Signal that what has been previously drawn is now invalid and has
+     * to be redrawn.
+     */
+    void invalidate()
+    {
+        if (!invalidated)
+        {
+            invalidated = true;
+        }
+    }
+
+    /**
+     * @brief Invalidate the view tree which has this view as a root
+     */
+    void invalidateTree()
+    {
+        invalidate();
+
+        std::vector<View*> childs = getChilds();
+        for (auto child : childs)
+        {
+            child->invalidateTree();
+        }
+    }
+
+    /**
+     * @brief Draw the view in its bounds
+     *
+     * @param dc Reference to a drawingcontext
+     */
+    virtual void draw(mxgui::DrawingContext& dc)
+    {
+        if (invalidated)
+        {
+            invalidated = false;
+
+            dc.clear(bounds.topLeft(), bounds.bottomRight(),
+                     getBackgroundColor());
+
+            dc.drawRectangle(bounds.topLeft(), bounds.bottomRight(),
+                             selected ? col_selected : getBackgroundColor());
+        }
+    }
+
+    /**
+     * @brief Returns the list of childs
+     *
+     * @return std::vector<View*>
+     */
+    virtual std::vector<View*> getChilds()
+    {
+        // Default behavious is no childs
+        return {};
+    }
+
+    virtual void setBackgroundColor(mxgui::Color color)
+    {
+        if (color != col_bg)
+        {
+            col_bg = color;
+            invalidate();
+        }
+    }
+
+    virtual mxgui::Color getBackgroundColor() { return col_bg; }
+
+    void setSelectedColor(mxgui::Color color)
+    {
+        col_selected = color;
+        invalidate();
+    }
+
+    void setSelectable(bool selectable) { this->selectable = selectable; }
+
+    bool isSelectable() { return selectable; }
+
+    void setSelected(bool selected)
+    {
+        this->selected = selected;
+        invalidate();
+    }
+
+    bool isSelected() { return selected && selectable; }
+
+    void addOnInteractionListener(OnInteractionListener listener)
+    {
+        listeners.push_back(listener);
+    }
+
+    virtual void performInteraction(Interaction action)
+    {
+        for (auto lst : listeners)
+        {
+            if (lst)
+            {
+                lst(this, action);
+            }
+        }
+    }
+
+protected:
+    bool isInvalidated() { return invalidated; }
+
+private:
+    mxgui::Color col_selected = mxgui::red;
+    mxgui::Color col_bg       = mxgui::black;
+
+    std::vector<OnInteractionListener> listeners;
+
+    bool selected    = false;
+    bool selectable  = false;
+    bool invalidated = true;
+
+    Bounds bounds{{0, 0}, {0, 0}};
+
+    // Drawing big solid chunks (such as backgrounds) takes a lot of time: do
+    // not redraw if not necessary
+    bool was_selected          = false;
+    mxgui::Color last_bg_color = col_bg;
+};
diff --git a/src/shared/utils/testutils/MockGpioPin.h b/src/shared/utils/testutils/MockGpioPin.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3246d4d84183c77f1db9bd7a58db698a4733a4e
--- /dev/null
+++ b/src/shared/utils/testutils/MockGpioPin.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2021 Luca Erbetta
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <miosix.h>
+
+#include <memory>
+
+class MockGpioPin
+{
+public:
+    MockGpioPin()
+        : val(new int(0)),
+          gpio_mode(new miosix::Mode::Mode_(miosix::Mode::OUTPUT))
+    {
+    }
+
+    void mode(miosix::Mode::Mode_ m) { *gpio_mode = m; }
+
+    void high() { *val = 1; }
+
+    void low() { *val = 0; }
+
+    int value() { return *val; }
+
+    // shared_ptr: make all copies of this instance share the same val /
+    // gpio_mode
+    std::shared_ptr<int> val;
+    std::shared_ptr<miosix::Mode::Mode_> gpio_mode;
+};
\ No newline at end of file
diff --git a/src/shared/utils/testutils/ThroughputCalculator.h b/src/shared/utils/testutils/ThroughputCalculator.h
new file mode 100644
index 0000000000000000000000000000000000000000..49b59cfe59d5dc07bdd15535a0a275893b3817a1
--- /dev/null
+++ b/src/shared/utils/testutils/ThroughputCalculator.h
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <miosix.h>
+
+#include <deque>
+#include <limits>
+
+using miosix::FastMutex;
+using miosix::Lock;
+using std::deque;
+
+struct DataRateResult
+{
+    float data_rate;
+    float packet_loss;
+    float packets_per_second;
+};
+
+/**
+ * Helper class for calculating the throughput of communications. Just
+ * pass the size of a packet to addPacket(...) as soon as the packet is
+ * received.
+ */
+class ThroughputCalculator
+{
+public:
+    /**
+     * @brief Creates a new ThroughputCalculator
+     *
+     * @param expected_pkt_interval Expected packet delivery interval for packet
+     * loss estimation
+     * @param window_duration Duration of the observation window. Longer windows
+     * means more stable values but slow response to abrupt changes
+     */
+    ThroughputCalculator(unsigned int expected_pkt_interval,
+                         unsigned int window_duration = 2000)
+        : expected_pkt_interval(expected_pkt_interval),
+          window_duration(window_duration)
+    {
+    }
+
+    /**
+     * @brief Signal that a new packet has arrived. Call this as soon as the
+     * packet is available
+     *
+     * @param packet_size The size of the packet
+     */
+    void addPacket(size_t packet_size)
+    {
+        Lock<FastMutex> lock(mutex_pkt);
+
+        long long ts = miosix::getTick();
+
+        unsigned int interval = 0;
+        if (packets.size() > 0)
+        {
+            interval = static_cast<unsigned int>(ts - packets.back().timestamp);
+        }
+
+        packets.push_back({ts, packet_size, interval});
+
+        removeOldPackets(ts);
+    }
+
+    /**
+     * @brief Returns the datarate in Bytes/second averaged over the duration of
+     * the window
+     */
+    float getDataRate()
+    {
+        Lock<FastMutex> lock(mutex_pkt);
+
+        long long ts = miosix::getTick();
+        removeOldPackets(ts);
+
+        float sum = 0;
+        for (size_t i = 0; i < packets.size(); i++)
+        {
+            sum += packets[i].size;
+        }
+        return sum / (window_duration / 1000.0f);
+    }
+
+    /**
+     * @brief Returns the packet loss percentage ([0-1]) based on the expected packet
+     * delivery interval 
+     */
+    float getPacketLoss()
+    {
+        Lock<FastMutex> lock(mutex_pkt);
+        long long ts = miosix::getTick();
+        removeOldPackets(ts);
+
+        float avg_interval = std::numeric_limits<float>::infinity();
+        if (packets.size() > 0)
+        {
+            avg_interval = packets[0].interval;
+            for (size_t i = 1; i < packets.size(); i++)
+            {
+                avg_interval += packets[i].interval;
+            }
+
+            avg_interval /= packets.size();
+        }
+
+        return 1 - expected_pkt_interval / avg_interval;
+    }
+
+    /**
+     * @brief Returns the pps value averaged over the duration of the window
+     */
+    float getPacketsPerSecond()
+    {
+        Lock<FastMutex> lock(mutex_pkt);
+        long long ts = miosix::getTick();
+        removeOldPackets(ts);
+
+        return (float)packets.size() / (window_duration / 1000.0f);
+    }
+
+    DataRateResult getResult()
+    {
+        DataRateResult r;
+        r.data_rate          = getDataRate();
+        r.packet_loss        = getPacketLoss();
+        r.packets_per_second = getPacketsPerSecond();
+
+        return r;
+    }
+
+private:
+    struct Packet
+    {
+        long long timestamp;
+        size_t size;
+        unsigned int interval;
+    };
+
+    void removeOldPackets(long long ts)
+    {
+        while (packets.size() > 0 &&
+               packets.front().timestamp < ts - window_duration)
+        {
+            packets.pop_front();
+        }
+    }
+
+    unsigned int expected_pkt_interval;
+    unsigned int window_duration;
+    deque<Packet> packets;
+
+    FastMutex mutex_pkt;
+};
\ No newline at end of file
diff --git a/src/tests/catch/spidriver/FakeSPIBus.h b/src/tests/catch/spidriver/FakeSPIBus.h
deleted file mode 100644
index d1213bfd6e6f9441e453cb84eb68e631572ca863..0000000000000000000000000000000000000000
--- a/src/tests/catch/spidriver/FakeSPIBus.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * Copyright (c) 2020 Skyward Experimental Rocketry
- * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "FakeSpiTypedef.h"
-#include "drivers/spi/SPIBusInterface.h"
-
-#pragma once
-
-/**
- * @brief SPIBus modified to accept a fake Chip select & spi peripheral struct.
- * Not ideal as modifications to SPIBus have to be manually applied here too,
- * but that's the only way I found to test it effectively
- */
-class FakeSPIBus : public SPIBusInterface
-{
-public:
-    /**
-     * @brief Instantiates a new FakeSPIBus
-     *
-     * @param spi Pointer to the SPI peripheral to be used
-     */
-    FakeSPIBus(FakeSpiTypedef* spi);
-    ~FakeSPIBus() {}
-
-    // Delete copy/move contructors/operators
-    FakeSPIBus(const FakeSPIBus&) = delete;
-    FakeSPIBus& operator=(const FakeSPIBus&) = delete;
-
-    FakeSPIBus(FakeSPIBus&&) = delete;
-    FakeSPIBus& operator=(FakeSPIBus&&) = delete;
-
-    void disableBusConfiguration() { config_enabled = false; }
-
-    /**
-     * @brief See SPIBusInterface::write()
-     */
-    void write(uint8_t byte) override;
-
-    /**
-     * @brief See SPIBusInterface::write()
-     */
-    void write(uint8_t* data, size_t size) override;
-
-    /**
-     * @brief See SPIBusInterface::read()
-     */
-    uint8_t read() override;
-
-    /**
-     * @brief See SPIBusInterface::read()
-     */
-    void read(uint8_t* data, size_t size) override;
-
-    /**
-     * @brief See SPIBusInterface::transfer()
-     */
-    uint8_t transfer(uint8_t data) override;
-
-    /**
-     * @brief See SPIBusInterface::transfer()
-     */
-    void transfer(uint8_t* data, size_t size) override;
-
-    /**
-     * @brief See SPIBusInterface::select()
-     */
-    void select(GpioPin& cs) override;
-
-    /**
-     * @brief See SPIBusInterface::deselect()
-     */
-    void deselect(GpioPin& cs) override;
-
-    /**
-     * @brief See SPIBusInterface::configure()
-     */
-    void configure(SPIBusConfig config) override;
-
-private:
-    /**
-     * Writes a single byte on the SPI bus.
-     *
-     * @param    byte Pointer to the byte to be written
-     */
-    void write(uint8_t* byte);
-
-    /**
-     * Reads a single byte from the SPI bus.
-     *
-     * @param    byte Pointer to the byte where the read data will be stored
-     */
-    void read(uint8_t* byte);
-
-    /**
-     * Full duplex transfer. Writes a single byte on the SPI bus and replaces
-     * its content with the received data
-     *
-     * @param    byte Pointer to the byte to be transfered
-     */
-    void transfer(uint8_t* byte);
-
-    FakeSpiTypedef* spi;
-
-    SPIBusConfig config;
-    bool config_enabled       = true;
-    bool first_config_applied = false;
-};
-
-FakeSPIBus::FakeSPIBus(FakeSpiTypedef* spi) : spi(spi) {}
-
-void FakeSPIBus::configure(SPIBusConfig new_config)
-{
-    // Reconfigure the bus only if config enabled. Do not reconfigure if already
-    // in the correct configuration.
-    if (config_enabled && (!first_config_applied || new_config != config))
-    {
-        first_config_applied = true;
-        config               = new_config;
-
-        // Clean CR1
-        spi->CR1 = 0;
-
-        // Configure CPOL & CPHA bits
-        spi->CR1 |= static_cast<uint32_t>(config.mode);
-
-        // Configure clock division (BR bits)
-        spi->CR1 |= static_cast<uint32_t>(config.clock_div);
-        
-        // Configure LSBFIRST bit
-        spi->CR1 |= static_cast<uint32_t>(config.bit_order);
-
-        spi->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM  // Use software chip-select
-                    | SPI_CR1_MSTR             // Master mode
-                    | SPI_CR1_SPE;             // Enable SPI
-    }
-}
-
-inline void FakeSPIBus::write(uint8_t data) { write(&data); }
-
-inline void FakeSPIBus::write(uint8_t* data, size_t size)
-{
-    for (size_t i = 0; i < size; i++)
-    {
-        write(data + i);
-    }
-}
-
-inline uint8_t FakeSPIBus::read()
-{
-    uint8_t data;
-    read(&data);
-
-    return data;
-}
-
-inline void FakeSPIBus::read(uint8_t* data, size_t size)
-{
-    for (size_t i = 0; i < size; i++)
-    {
-        read(data + i);
-    }
-}
-
-inline uint8_t FakeSPIBus::transfer(uint8_t data)
-{
-    transfer(&data);
-    return data;
-}
-
-inline void FakeSPIBus::transfer(uint8_t* data, size_t size)
-{
-    for (size_t i = 0; i < size; i++)
-    {
-        transfer(data + i);
-    }
-}
-
-inline void FakeSPIBus::select(GpioPin& rcs)
-{
-    FakeGpioPin& cs = static_cast<FakeGpioPin&>(rcs);
-
-    cs.low();
-    if (config.cs_setup_time_us > 0)
-    {
-        delayUs(config.cs_setup_time_us);
-    }
-}
-
-inline void FakeSPIBus::deselect(GpioPin& rcs)
-{
-    FakeGpioPin& cs = static_cast<FakeGpioPin&>(rcs);
-
-    if (config.cs_hold_time_us > 0)
-    {
-        delayUs(config.cs_hold_time_us);
-    }
-    cs.high();
-}
-
-inline void FakeSPIBus::write(uint8_t* byte)
-{
-    // Wait until the peripheral is ready to transmit
-    while ((spi->SR & SPI_SR_TXE) == 0)
-        ;
-    // Write the byte in the transmit buffer
-    spi->DR = *byte;
-
-    // Wait until byte is transmitted
-    while ((spi->SR & SPI_SR_RXNE) == 0)
-        ;
-
-    // Clear the RX buffer by accessing the DR register
-    (void)spi->DR;
-}
-
-inline void FakeSPIBus::transfer(uint8_t* byte)
-{
-    // Wait until the peripheral is ready to transmit
-    while ((spi->SR & SPI_SR_TXE) == 0)
-        ;
-    // Write the byte in the transmit buffer
-    spi->DR = *byte;
-
-    // Wait until byte is transmitted
-    while ((spi->SR & SPI_SR_RXNE) == 0)
-        ;
-
-    // Store the received data in the byte
-    *byte = (uint8_t)spi->DR;
-}
-
-inline void FakeSPIBus::read(uint8_t* byte)
-{
-    // Wait until the peripheral is ready to transmit
-    while ((spi->SR & SPI_SR_TXE) == 0)
-        ;
-    // Write the byte in the transmit buffer
-    spi->DR = 0;
-
-    // Wait until byte is transmitted
-    while ((spi->SR & SPI_SR_RXNE) == 0)
-        ;
-
-    // Store the received data in the byte
-    *byte = (uint8_t)spi->DR;
-}
\ No newline at end of file
diff --git a/src/tests/catch/spidriver/test-spidriver.cpp b/src/tests/catch/spidriver/test-spidriver.cpp
index e0facfd1b7da9cce148af88ea0ebe7075d605c3f..26773eed2eb3b7050dd0e711d406656ec04fd177 100644
--- a/src/tests/catch/spidriver/test-spidriver.cpp
+++ b/src/tests/catch/spidriver/test-spidriver.cpp
@@ -25,11 +25,16 @@
 #include "../catch-tests-entry.cpp"
 #endif
 
+#ifndef USE_MOCK_PERIPHERALS
+#error "This test requires SpiBusInterface built with MockGpioPin (-DUSE_MOCK_PERIPHERALS)"
+#endif
+
 #include <utils/testutils/catch.hpp>
 
-#include "FakeSPIBus.h"
-#include "drivers/spi/MockSPIBus.h"
+#include "drivers/spi/SPIBus.h"
 #include "drivers/spi/SPIDriver.h"
+#include "drivers/spi/test/FakeSpiTypedef.h"
+#include "drivers/spi/test/MockSPIBus.h"
 
 template <typename T1, typename T2>
 bool bufcmp(T1* buf1, T2* buf2, size_t size)
@@ -49,7 +54,7 @@ TEST_CASE("SPIBus - Bus Configuration")
 {
     FakeSpiTypedef spi;
 
-    FakeSPIBus bus{&spi};
+    SPIBus bus{&spi};
 
     REQUIRE(spi.CR1 == 0);
 
@@ -62,79 +67,93 @@ TEST_CASE("SPIBus - Bus Configuration")
         {
             config.mode           = SPIMode::MODE0;
             uint32_t expected_CR1 = 0x0344;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.mode  = SPIMode::MODE1;
             expected_CR1 = 0x0345;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.mode  = SPIMode::MODE2;
             expected_CR1 = 0x0346;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.mode  = SPIMode::MODE3;
             expected_CR1 = 0x0347;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
         }
 
         SECTION("Clock Divider")
         {
             config.clock_div      = SPIClockDivider::DIV2;
             uint32_t expected_CR1 = 0x0344;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.clock_div = SPIClockDivider::DIV4;
             expected_CR1     = 0x034C;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.clock_div = SPIClockDivider::DIV8;
             expected_CR1     = 0x0354;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.clock_div = SPIClockDivider::DIV16;
             expected_CR1     = 0x035C;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.clock_div = SPIClockDivider::DIV32;
             expected_CR1     = 0x0364;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.clock_div = SPIClockDivider::DIV64;
             expected_CR1     = 0x036C;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.clock_div = SPIClockDivider::DIV128;
             expected_CR1     = 0x0374;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.clock_div = SPIClockDivider::DIV256;
             expected_CR1     = 0x037C;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
         }
 
         SECTION("Bit order")
         {
             config.bit_order      = SPIBitOrder::MSB_FIRST;
             uint32_t expected_CR1 = 0x0344;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
 
             config.bit_order = SPIBitOrder::LSB_FIRST;
             expected_CR1     = 0x03C4;
-            bus.configure(config);
+            bus.acquire(config);
             REQUIRE(spi.CR1 == expected_CR1);
+            bus.release();
         }
     }
 
@@ -147,8 +166,9 @@ TEST_CASE("SPIBus - Bus Configuration")
         config.bit_order = SPIBitOrder::LSB_FIRST;
 
         bus.disableBusConfiguration();
-        bus.configure(config);
+        bus.acquire(config);
         REQUIRE(spi.CR1 == 0);
+        bus.release();
     }
 }
 
@@ -156,7 +176,7 @@ TEST_CASE("SPIBus - Chip select")
 {
     FakeSpiTypedef spi;
 
-    FakeSPIBus bus{&spi};
+    SPIBus bus{&spi};
 
     REQUIRE(spi.cs.value() == 1);
 
@@ -174,7 +194,7 @@ TEST_CASE("SPIBus - One byte operations")
     spi.DR.in_buf    = {1, 2, 3, 4, 5, 6, 7, 8, 9};
     spi.CR1_expected = 0x03DF;
 
-    FakeSPIBus bus{&spi};
+    SPIBus bus{&spi};
 
     SPIBusConfig config;
     config.clock_div = SPIClockDivider::DIV16;
@@ -182,7 +202,7 @@ TEST_CASE("SPIBus - One byte operations")
     config.mode      = SPIMode::MODE3;
     config.bit_order = SPIBitOrder::LSB_FIRST;
 
-    bus.configure(config);
+    bus.acquire(config);
     bus.select(spi.cs);
 
     SECTION("Write")
@@ -216,6 +236,9 @@ TEST_CASE("SPIBus - One byte operations")
         REQUIRE(spi.DR.out_buf.back() == 255);
         REQUIRE(spi.DR.out_buf.size() == 2);
     }
+
+    bus.deselect(spi.cs);
+    bus.release();
 }
 
 TEST_CASE("SPIBus - Multi byte operations")
@@ -225,7 +248,7 @@ TEST_CASE("SPIBus - Multi byte operations")
     spi.DR.in_buf    = {100, 101, 102, 103, 104, 105, 106, 107, 108};
     spi.CR1_expected = 0x03DF;
 
-    FakeSPIBus bus{&spi};
+    SPIBus bus{&spi};
 
     SPIBusConfig config;
     config.clock_div = SPIClockDivider::DIV16;
@@ -233,7 +256,7 @@ TEST_CASE("SPIBus - Multi byte operations")
     config.mode      = SPIMode::MODE3;
     config.bit_order = SPIBitOrder::LSB_FIRST;
 
-    bus.configure(config);
+    bus.acquire(config);
     bus.select(spi.cs);
 
     // 2 identical buffers
@@ -293,30 +316,33 @@ TEST_CASE("SPIBus - Multi byte operations")
         // No overflows
         REQUIRE(bufcmp(bufc + 4, buf + 4, 1));
     }
+
+    bus.deselect(spi.cs);
+    bus.release();
 }
 
 TEST_CASE("SPITransaction - writes")
 {
-    MockSPIBus bus{};
     SPIBusConfig config1{};
 
     config1.mode      = SPIMode::MODE1;
     config1.clock_div = SPIClockDivider::DIV32;
 
-    bus.expected_config = config1;
+    MockSPIBus bus(config1);
+    MockGpioPin cs;
 
     SECTION("Transaction")
     {
-        SPITransaction spi(bus, GpioPin(GPIOA_BASE, 1), config1);
+        SPITransaction spi(bus, cs, config1);
 
-        REQUIRE(bus.out_buf.size() == 0);
+        REQUIRE(bus.getOutBuf().size() == 0);
 
         SECTION("cmd write")
         {
             spi.write(9);
             REQUIRE_FALSE(bus.isSelected());
-            REQUIRE(bus.out_buf.size() == 1);
-            REQUIRE(bus.out_buf.back() == 9);
+            REQUIRE(bus.getOutBuf().size() == 1);
+            REQUIRE(bus.getOutBuf().back() == 9);
         }
 
         SECTION("1 byte reg write")
@@ -324,9 +350,9 @@ TEST_CASE("SPITransaction - writes")
             spi.write(10, 77);
             REQUIRE_FALSE(bus.isSelected());
 
-            REQUIRE(bus.out_buf.size() == 2);
-            REQUIRE(bus.out_buf[0] == 10);
-            REQUIRE(bus.out_buf[1] == 77);
+            REQUIRE(bus.getOutBuf().size() == 2);
+            REQUIRE(bus.getOutBuf()[0] == 10);
+            REQUIRE(bus.getOutBuf()[1] == 77);
         }
 
         SECTION("multi byte reg write")
@@ -338,8 +364,8 @@ TEST_CASE("SPITransaction - writes")
                 spi.write(10, buf, 0);
                 REQUIRE_FALSE(bus.isSelected());
 
-                REQUIRE(bus.out_buf.size() == 1);
-                REQUIRE(bus.out_buf[0] == 10);
+                REQUIRE(bus.getOutBuf().size() == 1);
+                REQUIRE(bus.getOutBuf()[0] == 10);
             }
 
             SECTION("2 writes")
@@ -347,18 +373,18 @@ TEST_CASE("SPITransaction - writes")
                 spi.write(10, buf, 4);
                 REQUIRE_FALSE(bus.isSelected());
 
-                REQUIRE(bus.out_buf.size() == 5);
+                REQUIRE(bus.getOutBuf().size() == 5);
 
-                REQUIRE(bus.out_buf[0] == 10);
-                REQUIRE(bufcmp(buf, bus.out_buf.data() + 1, 4));
+                REQUIRE(bus.getOutBuf()[0] == 10);
+                REQUIRE(bufcmp(buf, bus.getOutBuf().data() + 1, 4));
 
                 spi.write(99, buf, 6);
                 REQUIRE_FALSE(bus.isSelected());
 
-                REQUIRE(bus.out_buf.size() == 12);
+                REQUIRE(bus.getOutBuf().size() == 12);
 
-                REQUIRE(bus.out_buf[5] == 99);
-                REQUIRE(bufcmp(buf, bus.out_buf.data() + 6, 6));
+                REQUIRE(bus.getOutBuf()[5] == 99);
+                REQUIRE(bufcmp(buf, bus.getOutBuf().data() + 6, 6));
             }
         }
 
@@ -369,65 +395,65 @@ TEST_CASE("SPITransaction - writes")
             spi.write(buf, 0);
             REQUIRE_FALSE(bus.isSelected());
 
-            REQUIRE(bus.out_buf.size() == 0);
+            REQUIRE(bus.getOutBuf().size() == 0);
 
             spi.write(buf, 4);
             REQUIRE_FALSE(bus.isSelected());
 
-            REQUIRE(bus.out_buf.size() == 4);
+            REQUIRE(bus.getOutBuf().size() == 4);
 
-            REQUIRE(bufcmp(buf, bus.out_buf.data(), 4));
+            REQUIRE(bufcmp(buf, bus.getOutBuf().data(), 4));
 
             spi.write(buf, 6);
             REQUIRE_FALSE(bus.isSelected());
 
-            REQUIRE(bus.out_buf.size() == 10);
+            REQUIRE(bus.getOutBuf().size() == 10);
 
-            REQUIRE(bufcmp(buf, bus.out_buf.data() + 4, 6));
+            REQUIRE(bufcmp(buf, bus.getOutBuf().data() + 4, 6));
         }
     }
 }
 
 TEST_CASE("SPITransaction - reads")
 {
-    MockSPIBus bus;
-
-    bus.in_buf = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109};
-
     SPIBusConfig config1;
 
     config1.mode      = SPIMode::MODE1;
     config1.clock_div = SPIClockDivider::DIV32;
 
-    bus.expected_config = config1;
+    MockSPIBus bus(config1);
+    MockGpioPin cs;
+
+    uint8_t in_data[10] = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109};
+    bus.push(in_data, 10);
 
     SECTION("Transaction")
     {
-        SPISlave slave(bus, GpioPin(GPIOA_BASE, 1), config1);
+        SPISlave slave(bus, cs, config1);
         SPITransaction spi(slave);
 
-        REQUIRE(bus.out_buf.size() == 0);
+        REQUIRE(bus.getOutBuf().size() == 0);
 
         SECTION("1 byte reg read")
         {
 
-            REQUIRE(spi.read(0x05) == bus.in_buf[0]);
+            REQUIRE(spi.read(0x05) == in_data[0]);
             REQUIRE_FALSE(bus.isSelected());
 
-            REQUIRE(bus.out_buf.size() == 1);
-            REQUIRE(bus.out_buf.back() == 0x85);
+            REQUIRE(bus.getOutBuf().size() == 1);
+            REQUIRE(bus.getOutBuf().back() == 0x85);
 
-            REQUIRE(spi.read(0x05, true) == bus.in_buf[1]);
+            REQUIRE(spi.read(0x05, true) == in_data[1]);
             REQUIRE_FALSE(bus.isSelected());
 
-            REQUIRE(bus.out_buf.size() == 2);
-            REQUIRE(bus.out_buf.back() == 0x85);
+            REQUIRE(bus.getOutBuf().size() == 2);
+            REQUIRE(bus.getOutBuf().back() == 0x85);
 
-            REQUIRE(spi.read(0x05, false) == bus.in_buf[2]);
+            REQUIRE(spi.read(0x05, false) == in_data[2]);
             REQUIRE_FALSE(bus.isSelected());
 
-            REQUIRE(bus.out_buf.size() == 3);
-            REQUIRE(bus.out_buf.back() == 0x05);
+            REQUIRE(bus.getOutBuf().size() == 3);
+            REQUIRE(bus.getOutBuf().back() == 0x05);
         }
 
         SECTION("multi byte reg read")
@@ -438,29 +464,29 @@ TEST_CASE("SPITransaction - reads")
 
             spi.read(0x05, buf, 0);
             REQUIRE_FALSE(bus.isSelected());
-            REQUIRE(bus.out_buf.size() == 1);
-            REQUIRE(bus.out_buf.back() == 0x85);
+            REQUIRE(bus.getOutBuf().size() == 1);
+            REQUIRE(bus.getOutBuf().back() == 0x85);
             REQUIRE(bufcmp(buf, cmp, buf_size));
 
             spi.read(0x05, buf, 3);
             REQUIRE_FALSE(bus.isSelected());
-            REQUIRE(bus.out_buf.size() == 2);
-            REQUIRE(bus.out_buf.back() == 0x85);
-            REQUIRE(bufcmp(buf, bus.in_buf.data(), 3));
+            REQUIRE(bus.getOutBuf().size() == 2);
+            REQUIRE(bus.getOutBuf().back() == 0x85);
+            REQUIRE(bufcmp(buf, &in_data[0], 3));
             REQUIRE(bufcmp(buf + 3, cmp + 3, buf_size - 3));
 
             spi.read(0x05, buf, 3, true);
             REQUIRE_FALSE(bus.isSelected());
-            REQUIRE(bus.out_buf.size() == 3);
-            REQUIRE(bus.out_buf.back() == 0x85);
-            REQUIRE(bufcmp(buf, bus.in_buf.data() + 3, 3));
+            REQUIRE(bus.getOutBuf().size() == 3);
+            REQUIRE(bus.getOutBuf().back() == 0x85);
+            REQUIRE(bufcmp(buf, &in_data[3], 3));
             REQUIRE(bufcmp(buf + 3, cmp + 3, buf_size - 3));
 
             spi.read(0x05, buf, 4, false);
             REQUIRE_FALSE(bus.isSelected());
-            REQUIRE(bus.out_buf.size() == 4);
-            REQUIRE(bus.out_buf.back() == 0x05);
-            REQUIRE(bufcmp(buf, bus.in_buf.data() + 6, 4));
+            REQUIRE(bus.getOutBuf().size() == 4);
+            REQUIRE(bus.getOutBuf().back() == 0x05);
+            REQUIRE(bufcmp(buf,&in_data[6], 4));
             REQUIRE(bufcmp(buf + 4, cmp + 4, buf_size - 4));
         }
 
@@ -472,13 +498,13 @@ TEST_CASE("SPITransaction - reads")
 
             spi.read(buf, 0);
             REQUIRE_FALSE(bus.isSelected());
-            REQUIRE(bus.out_buf.size() == 0);
+            REQUIRE(bus.getOutBuf().size() == 0);
             REQUIRE(bufcmp(buf, cmp, buf_size));
 
             spi.read(buf, 3);
             REQUIRE_FALSE(bus.isSelected());
-            REQUIRE(bus.out_buf.size() == 0);
-            REQUIRE(bufcmp(buf, bus.in_buf.data(), 3));
+            REQUIRE(bus.getOutBuf().size() == 0);
+            REQUIRE(bufcmp(buf, &in_data[0], 3));
             REQUIRE(bufcmp(buf + 3, cmp + 3, buf_size - 3));
         }
     }
@@ -486,20 +512,21 @@ TEST_CASE("SPITransaction - reads")
 
 TEST_CASE("SPITransaction - transfer")
 {
-    MockSPIBus bus;
-
-    bus.in_buf = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-
     SPIBusConfig config1;
 
     config1.mode      = SPIMode::MODE1;
     config1.clock_div = SPIClockDivider::DIV32;
 
-    bus.expected_config = config1;
+    MockSPIBus bus(config1);
+    MockGpioPin cs;
+
+    uint8_t data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    
+    bus.push(data, 10);
 
     SECTION("Transaction")
     {
-        SPISlave slave(bus, GpioPin(GPIOA_BASE, 1), config1);
+        SPISlave slave(bus, cs, config1);
         SPITransaction spi(slave);
 
         const int buf_size = 7;
@@ -508,14 +535,14 @@ TEST_CASE("SPITransaction - transfer")
 
         spi.transfer(buf, 0);
         REQUIRE_FALSE(bus.isSelected());
-        REQUIRE(bus.out_buf.size() == 0);
+        REQUIRE(bus.getOutBuf().size() == 0);
         REQUIRE(bufcmp(buf, cmp, buf_size));
 
         spi.transfer(buf, 4);
         REQUIRE_FALSE(bus.isSelected());
-        REQUIRE(bus.out_buf.size() == 4);
-        REQUIRE(bufcmp(buf, bus.in_buf.data(), 4));
-        REQUIRE(bufcmp(cmp, bus.out_buf.data(), 4));
+        REQUIRE(bus.getOutBuf().size() == 4);
+        REQUIRE(bufcmp(buf, &data[0], 4));
+        REQUIRE(bufcmp(cmp, bus.getOutBuf().data(), 4));
         REQUIRE(bufcmp(buf + 4, cmp + 4, buf_size - 4));
     }
 }
\ No newline at end of file
diff --git a/src/tests/catch/xbee/MockXbeeSPIBus.h b/src/tests/catch/xbee/MockXbeeSPIBus.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c23b4fd810ff53d48dc74944a05cf89073005ab
--- /dev/null
+++ b/src/tests/catch/xbee/MockXbeeSPIBus.h
@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <deque>
+#include <functional>
+#include <memory>
+
+#include "drivers/Xbee/APIFrameParser.h"
+#include "drivers/Xbee/APIFrames.h"
+#include "drivers/spi/test/MockSPIBus.h"
+#include "utils/testutils/MockGpioPin.h"
+
+using std::deque;
+using std::function;
+using std::unique_ptr;
+
+class MockXbeeSPIBus : public MockSPIBus
+{
+public:
+    MockXbeeSPIBus(SPIBusConfig expected_config, MockGpioPin& attn)
+        : MockSPIBus(expected_config), attn(attn)
+    {
+    }
+
+    void registerCallback(function<void(MockGpioPin&)> callback)
+    {
+        this->callback = callback;
+    }
+
+    void removeCallback() { this->callback = nullptr; }
+
+    void pushApiFrame(Xbee::APIFrame& api)
+    {
+        unique_ptr<uint8_t> bytes(new uint8_t[Xbee::MAX_API_FRAME_SIZE]);
+
+        size_t len = api.toBytes(bytes.get());
+        push(bytes.get(), len);
+    }
+
+    deque<Xbee::APIFrame> getParsedFrames()
+    {
+        Lock<FastMutex> l(mutex);
+        return parsed_frames;
+    }
+
+    /**
+     * @brief Wether to generate a tx_status responde upon receiving a tx
+     * request
+     *
+     */
+    void setRespondWithTxStatus(bool respond, uint8_t delivery_status = 0)
+    {
+        tx_status_delivery_status = delivery_status;
+        respond_with_tx_status    = respond;
+    }
+
+protected:
+    void _push(uint8_t* data, size_t len) override
+    {
+        MockSPIBus::_push(data, len);
+
+        assertATTN();
+    }
+
+    uint8_t _read() override
+    {
+        uint8_t r = MockSPIBus::_read();
+
+        if (in_buf_pos_cntr == in_buf.size())
+        {
+            resetATTN();
+        }
+
+        return r;
+    }
+
+    void _write(uint8_t byte) override
+    {
+        MockSPIBus::_write(byte);
+
+        Xbee::APIFrameParser::ParseResult res =
+            parser.parse(byte, &parsing_frame);
+
+        if (res == Xbee::APIFrameParser::ParseResult::SUCCESS)
+        {
+            parsed_frames.push_back(parsing_frame);
+
+            if (parsing_frame.frame_type == Xbee::FTYPE_TX_REQUEST &&
+                respond_with_tx_status)
+            {
+                Xbee::TXRequestFrame* tx_req =
+                    parsing_frame.toFrameType<Xbee::TXRequestFrame>();
+                Xbee::TXStatusFrame tx_stat;
+
+                tx_stat.setFrameID(tx_req->getFrameID());
+                tx_stat.setDeliveryStatus(tx_status_delivery_status);
+                tx_stat.setDiscoveryStatus(0);
+                tx_stat.setTransmitRetryCount(0);
+                tx_stat.calcChecksum();
+                
+                _pushApiFrame(tx_stat);
+            }
+        }
+        else if (res == Xbee::APIFrameParser::ParseResult::FAIL)
+        {
+            printf("[MockXbeeSPI] Failed parsing frame written to SPI bus\n");
+        }
+    }
+
+private:
+    void _pushApiFrame(Xbee::APIFrame& api)
+    {
+        uint8_t* bytes = new uint8_t[Xbee::MAX_API_FRAME_SIZE];
+        size_t len     = api.toBytes(bytes);
+        _push(bytes, len);
+
+        delete[] bytes;
+    }
+
+    void assertATTN()
+    {
+        if (attn.value() != 0)
+        {
+            attn.low();
+            if (callback)
+                callback(attn);
+        }
+    }
+
+    void resetATTN()
+    {
+        if (attn.value() == 0)
+        {
+            attn.high();
+            if (callback)
+                callback(attn);
+        }
+    }
+
+    deque<Xbee::APIFrame> parsed_frames;
+
+    Xbee::APIFrameParser parser;
+    Xbee::APIFrame parsing_frame;
+
+    function<void(MockGpioPin&)> callback;
+    MockGpioPin attn;
+
+    bool respond_with_tx_status       = true;
+    uint8_t tx_status_delivery_status = 0;
+};
\ No newline at end of file
diff --git a/src/tests/catch/xbee/test-xbee-driver.cpp b/src/tests/catch/xbee/test-xbee-driver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..71aa6b54e833e0cd460616320dd7aefe5b3860d5
--- /dev/null
+++ b/src/tests/catch/xbee/test-xbee-driver.cpp
@@ -0,0 +1,415 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef STANDALONE_CATCH1_TEST
+#include "../catch-tests-entry.cpp"
+#endif
+#include <ctime>
+#include <future>
+#include <memory>
+
+#include "MockXbeeSPIBus.h"
+#include "drivers/Xbee/Xbee.h"
+#include "drivers/spi/SPIDriver.h"
+#include "utils/testutils/catch.hpp"
+
+using namespace Xbee;
+using std::async;
+using std::unique_ptr;
+
+using uint8_ptr = unique_ptr<uint8_t>;
+
+/**
+ * @brief Generates a sequence of incremental bytes
+ */
+uint8_ptr incrementalBytes(size_t length, uint8_t start_from = 0)
+{
+    uint8_ptr bytes(new uint8_t[length]);
+
+    for (size_t i = 0; i < length; i++)
+    {
+        bytes.get()[i] = (start_from + i) % 256;
+    }
+
+    return bytes;
+}
+
+class XbeeWrapper
+{
+public:
+    XbeeWrapper(unsigned int tx_timeout)
+        : bus(new MockXbeeSPIBus(xbee_cfg, attn)),
+          xbee(new Xbee::Xbee(*bus.get(), xbee_cfg, cs, attn, rst, tx_timeout))
+    {
+        attn.high();
+    }
+
+    MockGpioPin cs;
+    MockGpioPin attn;
+
+    MockGpioPin rst;
+
+    SPIBusConfig xbee_cfg{};
+
+    unique_ptr<MockXbeeSPIBus> bus;
+    unique_ptr<Xbee::Xbee> xbee;
+};
+
+TEST_CASE("[Xbee] Test xbee.send(...) by itself")
+{
+    uint8_ptr pkt      = incrementalBytes(Xbee::MAX_PACKET_PAYLOAD_LENGTH + 1);
+    uint8_ptr pkt_orig = incrementalBytes(Xbee::MAX_PACKET_PAYLOAD_LENGTH + 1);
+
+    XbeeWrapper wrap(DEFAULT_TX_TIMEOUT);
+
+    SECTION("Middle payload length")
+    {
+        REQUIRE(wrap.xbee->send(pkt.get(), 128));
+        REQUIRE(wrap.bus->getParsedFrames().size() > 0);
+
+        REQUIRE(wrap.bus->getParsedFrames().front().frame_type ==
+                Xbee::FTYPE_TX_REQUEST);
+
+        TXRequestFrame tx_req = *wrap.bus->getParsedFrames()
+                                     .front()
+                                     .toFrameType<Xbee::TXRequestFrame>();
+
+        REQUIRE(tx_req.getRFDataLength() == 128);
+        REQUIRE(memcmp(tx_req.getRFDataPointer(), pkt_orig.get(), 128) == 0);
+    }
+
+    SECTION("Max payload length")
+    {
+        REQUIRE(wrap.xbee->send(pkt.get(), Xbee::MAX_PACKET_PAYLOAD_LENGTH));
+        REQUIRE(wrap.bus->getParsedFrames().size() > 0);
+
+        REQUIRE(wrap.bus->getParsedFrames().front().frame_type ==
+                Xbee::FTYPE_TX_REQUEST);
+
+        TXRequestFrame tx_req = *wrap.bus->getParsedFrames()
+                                     .front()
+                                     .toFrameType<Xbee::TXRequestFrame>();
+
+        REQUIRE(tx_req.getRFDataLength() == Xbee::MAX_PACKET_PAYLOAD_LENGTH);
+        REQUIRE(memcmp(tx_req.getRFDataPointer(), pkt_orig.get(),
+                       Xbee::MAX_PACKET_PAYLOAD_LENGTH) == 0);
+    }
+
+    SECTION("Oversize payload")
+    {
+        REQUIRE_FALSE(
+            wrap.xbee->send(pkt.get(), Xbee::MAX_PACKET_PAYLOAD_LENGTH + 1));
+        REQUIRE(wrap.bus->getParsedFrames().size() == 0);
+    }
+
+    SECTION("No payload")
+    {
+        REQUIRE_FALSE(wrap.xbee->send(pkt.get(), 0));
+        REQUIRE(wrap.bus->getParsedFrames().size() == 0);
+    }
+
+    SECTION("Send error")
+    {
+        wrap.bus->setRespondWithTxStatus(true, DELS_NO_SPECTRUM_AVAILABLE);
+
+        REQUIRE_FALSE(
+            wrap.xbee->send(pkt.get(), Xbee::MAX_PACKET_PAYLOAD_LENGTH));
+    }
+
+    SECTION("TX status timeout")
+    {
+        wrap.bus->setRespondWithTxStatus(false);
+
+        long long start = miosix::getTick();
+
+        REQUIRE_FALSE(
+            wrap.xbee->send(pkt.get(), Xbee::MAX_PACKET_PAYLOAD_LENGTH));
+
+        // Should not have returned until the timeout has expired
+        REQUIRE(miosix::getTick() >= start + DEFAULT_TX_TIMEOUT);
+    }
+}
+
+TEST_CASE("[Xbee] Test xbee.receive(...) by itself")
+{
+    uint8_ptr rx_buf(new uint8_t[MAX_PACKET_PAYLOAD_LENGTH]);
+
+    uint8_ptr pkt = incrementalBytes(Xbee::MAX_PACKET_PAYLOAD_LENGTH);
+
+    XbeeWrapper wrap(DEFAULT_TX_TIMEOUT);
+
+    RXPacketFrame rx;
+    rx.setRXDataLength(MAX_PACKET_PAYLOAD_LENGTH);
+    memcpy(rx.getRXDataPointer(), pkt.get(), MAX_PACKET_PAYLOAD_LENGTH);
+    rx.setReceiveOptions(RO_POINT_MULTIPOINT);
+    rx.setSourceAddress(0x1122334455667788);
+
+    SECTION("RX buffer bigger than RX packet payload")
+    {
+        rx.setRXDataLength(50);
+        rx.calcChecksum();
+
+        wrap.bus->pushApiFrame(rx);
+
+        REQUIRE(wrap.xbee->receive(rx_buf.get(), MAX_PACKET_PAYLOAD_LENGTH) ==
+                50);
+
+        REQUIRE(memcmp(rx_buf.get(), pkt.get(), 50) == 0);
+    }
+
+    SECTION("RX buffer smaller than RX packet payload")
+    {
+        rx.setRXDataLength(130);
+        rx.calcChecksum();
+
+        wrap.bus->pushApiFrame(rx);
+
+        REQUIRE(wrap.xbee->receive(rx_buf.get(), 50) == 50);
+        REQUIRE(wrap.xbee->receive(rx_buf.get() + 50, 50) == 50);
+        REQUIRE(wrap.xbee->receive(rx_buf.get() + 100, 50) == 30);
+
+        REQUIRE(memcmp(rx_buf.get(), pkt.get(), 130) == 0);
+    }
+
+    SECTION("RX buffer == 1")
+    {
+        rx.setRXDataLength(30);
+        rx.calcChecksum();
+
+        wrap.bus->pushApiFrame(rx);
+
+        for (int i = 0; i < 30; i++)
+        {
+            REQUIRE(wrap.xbee->receive(rx_buf.get() + i, 1) == 1);
+        }
+
+        REQUIRE(memcmp(rx_buf.get(), pkt.get(), 30) == 0);
+    }
+
+    SECTION("RX packet with wrong checksum")
+    {
+        rx.setRXDataLength(20);
+        rx.calcChecksum();
+        wrap.bus->pushApiFrame(rx);
+
+        rx.setRXDataLength(21);
+        rx.calcChecksum();
+        rx.setRXDataLength(20);  // Now the checksum is wrong
+        wrap.bus->pushApiFrame(rx);
+
+        // Only receive one of the two frames
+        REQUIRE(wrap.xbee->receive(rx_buf.get(), 50) == 20);
+
+        auto dont_care = async(std::launch::async, [&]() {
+            miosix::Thread::sleep(1000);
+            wrap.xbee->wakeReceiver(true);
+        });
+
+        // This should block until we force it to return
+        REQUIRE(wrap.xbee->receive(rx_buf.get(), 50) == -1);
+    }
+
+    SECTION("receive() blocks until an interrupt is received")
+    {
+        rx.setRXDataLength(20);
+        rx.calcChecksum();
+
+        // Send an rx frame in one second
+        auto dont_care = async(std::launch::async, [&]() {
+            miosix::Thread::sleep(1000);
+            wrap.bus->pushApiFrame(rx);
+            wrap.xbee->wakeReceiver();
+        });
+
+        long long start = miosix::getTick();
+        REQUIRE(wrap.xbee->receive(rx_buf.get(), 50) == 20);
+
+        // Should not have returned before we sent the rx frame
+        REQUIRE(miosix::getTick() >= start + 1000);
+    }
+}
+
+TEST_CASE("[Xbee] Receive while sending")
+{
+    uint8_ptr rx_buf(new uint8_t[MAX_PACKET_PAYLOAD_LENGTH]);
+
+    uint8_ptr pkt_rx = incrementalBytes(Xbee::MAX_PACKET_PAYLOAD_LENGTH);
+    uint8_ptr pkt_tx = incrementalBytes(Xbee::MAX_PACKET_PAYLOAD_LENGTH);
+
+    XbeeWrapper wrap(1000);
+    wrap.bus->setRespondWithTxStatus(true, 0);
+
+    RXPacketFrame rx;
+    rx.setRXDataLength(MAX_PACKET_PAYLOAD_LENGTH);
+    memcpy(rx.getRXDataPointer(), pkt_rx.get(), MAX_PACKET_PAYLOAD_LENGTH);
+    rx.setReceiveOptions(RO_POINT_MULTIPOINT);
+    rx.setSourceAddress(0x1122334455667788);
+
+    int num_rx_while_tx = 0;
+
+    wrap.xbee->setOnFrameReceivedListener([&](APIFrame& api) {
+        if (api.frame_type == FTYPE_RX_PACKET_FRAME)
+        {
+            ++num_rx_while_tx;
+        }
+    });
+
+    SECTION("2 RX packet smaller than one TX packet")
+    {
+        rx.setRXDataLength(50);
+        rx.calcChecksum();
+
+        wrap.bus->pushApiFrame(rx);
+        wrap.bus->pushApiFrame(rx);
+
+        REQUIRE(wrap.xbee->send(pkt_tx.get(), 150));
+
+        REQUIRE(num_rx_while_tx == 2);
+
+        size_t rx_len = 0;
+        while (rx_len < 100)
+        {
+            rx_len += wrap.xbee->receive(rx_buf.get() + rx_len, 200);
+        }
+
+        REQUIRE(rx_len == 100);
+        REQUIRE(memcmp(rx_buf.get(), pkt_rx.get(), 50) == 0);
+        REQUIRE(memcmp(rx_buf.get() + 50, pkt_rx.get(), 50) == 0);
+    }
+
+    SECTION("More RX packets than buffer size: drop the oldest")
+    {
+        rx.setRXDataLength(10);
+
+        // 1 packet too many
+        unsigned int numpkts = RX_FRAMES_BUF_SIZE + 1;
+        for (unsigned int i = 0; i < numpkts; i++)
+        {
+            memcpy(rx.getRXDataPointer(), pkt_rx.get() + i, 10);
+            rx.calcChecksum();
+            wrap.bus->pushApiFrame(rx);
+        }
+
+        // Should receive all the packets while sending
+        REQUIRE(wrap.xbee->send(pkt_tx.get(), MAX_PACKET_PAYLOAD_LENGTH));
+
+        REQUIRE(num_rx_while_tx == numpkts);
+
+        // Only receive the last three packets
+        size_t rx_len = 0;
+        while (rx_len < (numpkts - 1) * 10)
+        {
+            rx_len += wrap.xbee->receive(rx_buf.get() + rx_len, 200);
+        }
+
+        REQUIRE(rx_len == (numpkts - 1) * 10);
+
+        for (unsigned int i = 0; i < numpkts - 1; i++)
+        {
+            REQUIRE(memcmp(rx_buf.get() + i * 10, pkt_rx.get() + i + 1, 10) ==
+                    0);
+        }
+    }
+
+    SECTION("2 RX packet smaller than one TX packet, 1 byte receive")
+    {
+        rx.setRXDataLength(50);
+        rx.calcChecksum();
+
+        wrap.bus->pushApiFrame(rx);
+        wrap.bus->pushApiFrame(rx);
+
+        REQUIRE(wrap.xbee->send(pkt_tx.get(), 150));
+
+        REQUIRE(num_rx_while_tx == 2);
+
+        for (int i = 0; i < 50; i++)
+        {
+            REQUIRE(wrap.xbee->receive(rx_buf.get() + i, 1) == 1);
+        }
+        REQUIRE(memcmp(rx_buf.get(), pkt_rx.get(), 50) == 0);
+
+        for (int i = 0; i < 50; i++)
+        {
+            REQUIRE(wrap.xbee->receive(rx_buf.get() + i, 1) == 1);
+        }
+        REQUIRE(memcmp(rx_buf.get(), pkt_rx.get(), 50) == 0);
+    }
+}
+
+TEST_CASE("[Xbee] Test Xbee::sendAtCommand(...)")
+{
+    XbeeWrapper wrap(DEFAULT_TX_TIMEOUT);
+
+    SECTION("AT Command, no response required")
+    {
+        wrap.xbee->sendATCommand("AB");
+
+        REQUIRE(wrap.bus->getParsedFrames().size() > 0);
+        REQUIRE(wrap.bus->getParsedFrames()[0].frame_type == FTYPE_AT_COMMAND);
+    }
+
+    SECTION("AT Command, response required but not received")
+    {
+        ATCommandResponseFrame response;
+        long long start = miosix::getTick();
+        REQUIRE_FALSE(
+            wrap.xbee->sendATCommand("AB", &response, nullptr, 0, 1000));
+        REQUIRE(miosix::getTick() >= start + 1000);
+
+        REQUIRE(wrap.bus->getParsedFrames().size() > 0);
+        REQUIRE(wrap.bus->getParsedFrames()[0].frame_type == FTYPE_AT_COMMAND);
+    }
+
+    SECTION("AT Command, response required and received")
+    {
+        // Padding required in order to not receive the ATCommandResponse
+        // frame too early in testing
+        RXPacketFrame padding;
+        padding.setRXDataLength(50);
+        padding.calcChecksum();
+
+        ATCommandResponseFrame resp;
+        resp.setATCommand("AB");
+        resp.setFrameID(1);
+        resp.setCommandDataSize(1);
+        resp.getCommandDataPointer()[0] = 0xAB;
+        resp.calcChecksum();
+
+        wrap.bus->pushApiFrame(padding);
+        wrap.bus->pushApiFrame(resp);
+
+        ATCommandResponseFrame received_response;
+        long long start = miosix::getTick();
+
+        REQUIRE(wrap.xbee->sendATCommand("AB", &received_response, nullptr, 0,
+                                         1000));
+        REQUIRE(miosix::getTick() < start + 1000);
+
+        REQUIRE(wrap.bus->getParsedFrames().size() > 0);
+        REQUIRE(wrap.bus->getParsedFrames()[0].frame_type == FTYPE_AT_COMMAND);
+
+        REQUIRE(received_response.getCommandDataLength() == 1);
+        REQUIRE(received_response.getCommandDataPointer()[0] == 0xAB);
+    }
+}
\ No newline at end of file
diff --git a/src/tests/catch/xbee/test-xbee-parser.cpp b/src/tests/catch/xbee/test-xbee-parser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..10c54ae87414c37f61c528f8902164fdbe817c23
--- /dev/null
+++ b/src/tests/catch/xbee/test-xbee-parser.cpp
@@ -0,0 +1,575 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// Disable asserts
+#define NDEBUG
+
+#include <cstdio>
+
+#ifdef STANDALONE_CATCH1_TEST
+#include "../catch-tests-entry.cpp"
+#endif
+
+#include <cstdio>
+#include <cstring>
+
+#include "drivers/Xbee/APIFrameParser.h"
+#include "utils/testutils/catch.hpp"
+
+using namespace Xbee;
+
+/**
+ * @brief Calculates the checksum for a sequence of bytes representing an API
+ * frame.
+ *
+ * @param frame bytes (including start delimiter, and checksum set to 0)
+ * @param frame_size size of the frame, including start delimiter and checksum
+ */
+void calcChecksum(uint8_t* frame, size_t frame_size)
+{
+    frame[frame_size - 1] = 0;
+    for (size_t i = 3; i < frame_size - 1; i++)
+    {
+        frame[frame_size - 1] += frame[i];
+    }
+    frame[frame_size - 1] = 0xFF - frame[frame_size - 1];
+}
+
+void printHex(uint8_t* frame, size_t frame_size)
+{
+    for (size_t i = 0; i < frame_size; i++)
+    {
+        printf("%02X ", frame[i]);
+    }
+    printf("\n");
+}
+
+void printu64(uint64_t v)
+{
+    uint8_t* p = reinterpret_cast<uint8_t*>(&v);
+
+    for (int i = 0; i < 8; i++)
+    {
+        printf("%02X ", p[i]);
+    }
+
+    printf("\n");
+}
+
+void printBuf(uint8_t* buf, size_t size)
+{
+    for (size_t i = 0; i < size; i++)
+    {
+        printf("%02X ", buf[i]);
+    }
+
+    printf("\n");
+}
+
+bool compareAPIFrames(const APIFrame& a, const APIFrame& b)
+{
+    bool result = a.start_del == b.start_del && a.frame_type == b.frame_type &&
+                  a.length == b.length && a.checksum == b.checksum;
+
+    return result &&
+           memcmp(a.frame_data, b.frame_data, a.getFrameDataLength()) == 0;
+}
+
+APIFrame parse(APIFrameParser& parser, uint8_t* data, size_t len)
+{
+    APIFrame out;
+    for (size_t i = 0; i < len; i++)
+    {
+        APIFrameParser::ParseResult pres = parser.parse(data[i], &out);
+
+        if (i < len - 1)
+        {
+            CAPTURE(i);
+            REQUIRE(pres == APIFrameParser::ParseResult::PARSING);
+        }
+        else
+        {
+            REQUIRE(pres == APIFrameParser::ParseResult::SUCCESS);
+        }
+    }
+
+    REQUIRE(out.verifyChecksum());
+
+    return out;
+}
+
+template <typename FrameType>
+void testParse(APIFrameParser& parser, FrameType orig)
+{
+    uint8_t bytes[MAX_API_FRAME_SIZE];
+
+    size_t len = orig.toBytes(bytes);
+
+    APIFrame parsed_api = parse(parser, bytes, len);
+
+    REQUIRE(compareAPIFrames(orig, parsed_api));
+}
+
+// Taken from examples in the datasheet
+TEST_CASE("Frame serialization")
+{
+    uint8_t bytes[MAX_API_FRAME_SIZE];
+    APIFrame deserialized;
+
+    SECTION("AT Command")
+    {
+        ATCommandFrame at_orig;
+        at_orig.setATCommand("NH");
+        REQUIRE(memcmp(at_orig.getATCommand(), "NH", 2) == 0);
+
+        at_orig.setFrameID(0x01);
+        REQUIRE(at_orig.getFrameID() == 0x01);
+
+        at_orig.setParameterSize(2);
+        at_orig.getCommandDataPointer()[0] = 0x07;
+        at_orig.getCommandDataPointer()[1] = 0x17;
+
+        REQUIRE(at_orig.getCommandDataLength() == 2);
+        REQUIRE(at_orig.getFrameDataLength() == 5);
+
+        at_orig.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0,    6,    0x08, 1,
+                                    0x4E, 0x48, 0x07, 0x17, 0x00};
+
+        calcChecksum(expected_bytes, 10);
+
+        size_t len = at_orig.toBytes(bytes);
+
+        REQUIRE(len == 10);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, at_orig));
+    }
+
+    SECTION("AT Command, No parameters")
+    {
+        ATCommandFrame at_orig;
+
+        at_orig.setATCommand("NH");
+
+        at_orig.setFrameID(0x01);
+        REQUIRE(at_orig.getFrameID() == 0x01);
+
+        REQUIRE(at_orig.getCommandDataLength() == 0);
+        REQUIRE(at_orig.getFrameDataLength() == 3);
+
+        at_orig.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0, 4, 0x08, 1, 0x4E, 0x48, 0x60};
+
+        size_t len = at_orig.toBytes(bytes);
+
+        REQUIRE(len == 8);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, at_orig));
+    }
+
+    SECTION("AT Command Response")
+    {
+        ATCommandResponseFrame at_orig;
+        at_orig.setATCommand("BD");
+        REQUIRE(memcmp(at_orig.getATCommand(), "BD", 2) == 0);
+
+        at_orig.setFrameID(0x01);
+        REQUIRE(at_orig.getFrameID() == 0x01);
+
+        at_orig.setCommandDataSize(3);
+        at_orig.getCommandDataPointer()[0] = 0x07;
+        at_orig.getCommandDataPointer()[1] = 0x17;
+        at_orig.getCommandDataPointer()[2] = 0x27;
+
+        REQUIRE(at_orig.getCommandDataLength() == 3);
+        REQUIRE(at_orig.getFrameDataLength() == 7);
+
+        at_orig.setCommandStatus(0x55);
+        REQUIRE(at_orig.getCommandStatus() == 0x55);
+
+        at_orig.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0,    8,    0x88, 0x01, 0x42,
+                                    0x44, 0x55, 0x07, 0x17, 0x27, 0};
+
+        calcChecksum(expected_bytes, 12);
+
+        size_t len = at_orig.toBytes(bytes);
+        REQUIRE(len == 12);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, at_orig));
+    }
+
+    SECTION("AT Command Response, No cmd data")
+    {
+        ATCommandResponseFrame at_orig;
+        at_orig.setATCommand("BD");
+
+        at_orig.setFrameID(0x01);
+        REQUIRE(at_orig.getFrameID() == 0x01);
+
+        REQUIRE(at_orig.getCommandDataLength() == 0);
+        REQUIRE(at_orig.getFrameDataLength() == 4);
+
+        at_orig.setCommandStatus(0x0);
+        REQUIRE(at_orig.getCommandStatus() == 0x00);
+
+        at_orig.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0,    5,    0x88, 0x01,
+                                    0x42, 0x44, 0x00, 0xF0};
+
+        calcChecksum(expected_bytes, 9);
+
+        size_t len = at_orig.toBytes(bytes);
+        REQUIRE(len == 9);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, at_orig));
+    }
+
+    SECTION("TX Request Frame")
+    {
+        TXRequestFrame tx_orig;
+
+        tx_orig.setFrameID(0x01);
+        REQUIRE(tx_orig.getFrameID() == 0x01);
+
+        tx_orig.setDestAddress(0x0013A200400A0127);
+
+        bool addr_cmp = tx_orig.getDestAddress() == 0x0013A200400A0127;
+        REQUIRE(addr_cmp);
+
+        tx_orig.setBroadcastRadius(0x55);
+        REQUIRE(tx_orig.getBroadcastRadius() == 0x55);
+
+        tx_orig.setTransmitOptions(0x40);
+        REQUIRE(tx_orig.getTrasmitOptions() == 0x40);
+
+        uint8_t* rf_data = tx_orig.getRFDataPointer();
+
+        rf_data[0] = 0x54;
+        rf_data[1] = 0x78;
+        rf_data[2] = 0x44;
+        rf_data[3] = 0x61;
+        rf_data[4] = 0x74;
+        rf_data[5] = 0x61;
+        rf_data[6] = 0x30;
+        rf_data[7] = 0x41;
+
+        tx_orig.setRFDataLength(8);
+
+        REQUIRE(tx_orig.getRFDataLength() == 8);
+        REQUIRE(tx_orig.getFrameDataLength() == 21);
+
+        uint8_t expected_bytes[] = {0x7E, 0,    0x16, 0x10, 0x01, 0x00, 0x13,
+                                    0xA2, 0x00, 0x40, 0x0A, 0x01, 0x27, 0xFF,
+                                    0xFE, 0x55, 0x40, 0x54, 0x78, 0x44, 0x61,
+                                    0x74, 0x61, 0x30, 0x41, 0x00};
+
+        // Datasheet example checksum is wrong
+        calcChecksum(expected_bytes, 26);
+        tx_orig.calcChecksum();
+        size_t len = tx_orig.toBytes(bytes);
+
+        REQUIRE(len == 26);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, tx_orig));
+    }
+
+    SECTION("TX Request Frame - No payload")
+    {
+        TXRequestFrame tx_orig;
+
+        tx_orig.setFrameID(0x01);
+        REQUIRE(tx_orig.getFrameID() == 0x01);
+
+        tx_orig.setDestAddress(0x0013A200400A0127);
+        bool addr_cmp = tx_orig.getDestAddress() == 0x0013A200400A0127;
+        REQUIRE(addr_cmp);
+
+        tx_orig.setBroadcastRadius(0x55);
+        REQUIRE(tx_orig.getBroadcastRadius() == 0x55);
+
+        tx_orig.setTransmitOptions(0x40);
+        REQUIRE(tx_orig.getTrasmitOptions() == 0x40);
+
+        uint8_t* rf_data = tx_orig.getRFDataPointer();
+
+        REQUIRE(tx_orig.getRFDataLength() == 0);
+        REQUIRE(tx_orig.getFrameDataLength() == 13);
+
+        tx_orig.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0,    14,   0x10, 0x01, 0x00,
+                                    0x13, 0xA2, 0x00, 0x40, 0x0A, 0x01,
+                                    0x27, 0xFF, 0xFE, 0x55, 0x40, 0x00};
+
+        calcChecksum(expected_bytes, 18);
+
+        size_t len = tx_orig.toBytes(bytes);
+
+        REQUIRE(len == 18);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, tx_orig));
+    }
+
+    SECTION("Modem status frame")
+    {
+        ModemStatusFrame mod_orig;
+
+        mod_orig.setStatus(0x55);
+
+        mod_orig.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0, 2, 0x8A, 0x55, 0x00};
+
+        calcChecksum(expected_bytes, 6);
+
+        size_t len = mod_orig.toBytes(bytes);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, mod_orig));
+    }
+
+    SECTION("TX Status frame")
+    {
+        constexpr size_t frame_size = 11;
+        TXStatusFrame tx_orig{};
+
+        tx_orig.setFrameID(0x47);
+        REQUIRE(tx_orig.getFrameID() == 0x47);
+        tx_orig.setTransmitRetryCount(0x55);
+        REQUIRE(tx_orig.getTransmitRetryCount() == 0x55);
+
+        tx_orig.setDeliveryStatus(0x44);
+        REQUIRE(tx_orig.getDeliveryStatus() == 0x44);
+
+        tx_orig.setDiscoveryStatus(2);
+        REQUIRE(tx_orig.getDiscoveryStatus() == 2);
+
+        tx_orig.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0,    0x07, 0x8B, 0x47, 0xFF,
+                                    0xFE, 0x55, 0x44, 0x02, 0x00};
+
+        calcChecksum(expected_bytes, 11);
+
+        size_t len = tx_orig.toBytes(bytes);
+        REQUIRE(len == 11);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, tx_orig));
+    }
+
+    SECTION("RX Packet frame")
+    {
+        RXPacketFrame rx;
+
+        rx.setSourceAddress(0x0013A20040522BAA);
+        bool addr_cmp = rx.getSourceAddress() == 0x0013A20040522BAA;
+        REQUIRE(addr_cmp);
+
+        rx.setReceiveOptions(0x01);
+        REQUIRE(rx.getReceiveOptions() == 0x01);
+
+        uint8_t* rf_data = rx.getRXDataPointer();
+
+        rf_data[0] = 0x52;
+        rf_data[1] = 0x78;
+        rf_data[2] = 0x44;
+        rf_data[3] = 0x61;
+        rf_data[4] = 0x74;
+        rf_data[5] = 0x61;
+
+        rx.setRXDataLength(6);
+        REQUIRE(rx.getRXDataLength() == 6);
+        REQUIRE(rx.getFrameDataLength() == 0x11);
+
+        rx.calcChecksum();
+
+        uint8_t expected_bytes[] = {
+            0x7E, 0,    0x12, 0x90, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B,
+            0xAA, 0xFF, 0xFE, 0x01, 0x52, 0x78, 0x44, 0x61, 0x74, 0x61, 0x11};
+
+        // calcChecksum(expected_bytes, frame_size);
+
+        size_t len = rx.toBytes(bytes);
+
+        REQUIRE(len == 22);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, rx));
+    }
+
+    SECTION("RX Packet frame - no payload")
+    {
+        RXPacketFrame rx;
+
+        rx.setSourceAddress(0x0013A20040522BAA);
+        bool addr_cmp = rx.getSourceAddress() == 0x0013A20040522BAA;
+        REQUIRE(addr_cmp);
+
+        rx.setReceiveOptions(0x01);
+        REQUIRE(rx.getReceiveOptions() == 0x01);
+
+        REQUIRE(rx.getRXDataLength() == 0);
+        REQUIRE(rx.getFrameDataLength() == 11);
+
+        rx.calcChecksum();
+
+        uint8_t expected_bytes[] = {0x7E, 0,    12,   0x90, 0x00, 0x13,
+                                    0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA,
+                                    0xFF, 0xFE, 0x01, 0x00};
+
+        calcChecksum(expected_bytes, 16);
+
+        size_t len = rx.toBytes(bytes);
+
+        REQUIRE(len == 16);
+
+        REQUIRE(memcmp(bytes, expected_bytes, len) == 0);
+
+        memset(deserialized.frame_data, 0, FRAME_DATA_SIZE);
+        REQUIRE(APIFrame::fromBytes(bytes, len, &deserialized));
+        REQUIRE(compareAPIFrames(deserialized, rx));
+    }
+}
+
+TEST_CASE("Frame parsing")
+{
+    APIFrameParser parser;
+
+    SECTION("RXPacketFrame Parsing")
+    {
+        RXPacketFrame rx;
+        rx.setSourceAddress(0x0013A20040522BAA);
+        rx.setReceiveOptions(0x01);
+        uint8_t* rf_data = rx.getRXDataPointer();
+
+        rf_data[0] = 0x52;
+        rf_data[1] = 0x78;
+        rf_data[2] = 0x44;
+        rf_data[3] = 0x61;
+        rf_data[4] = 0x74;
+        rf_data[5] = 0x61;
+
+        rx.setRXDataLength(6);
+        rx.calcChecksum();
+
+        // Parse 3 times the same frame
+        testParse(parser, rx);
+        testParse(parser, rx);
+        testParse(parser, rx);
+    }
+}
+
+TEST_CASE("Parser edge cases")
+{
+    APIFrameParser parser;
+
+    SECTION("Wrong checksum")
+    {
+        RXPacketFrame rx;
+        rx.setSourceAddress(0x0013A20040522BAA);
+        rx.setReceiveOptions(0x01);
+        uint8_t* rf_data = rx.getRXDataPointer();
+
+        rf_data[0] = 0x52;
+        rf_data[1] = 0x78;
+        rf_data[2] = 0x44;
+        rf_data[3] = 0x61;
+        rf_data[4] = 0x74;
+        rf_data[5] = 0x61;
+
+        rx.setRXDataLength(6);
+        rx.calcChecksum();
+
+        uint8_t bytes[MAX_API_FRAME_SIZE];
+
+        size_t len = rx.toBytes(bytes);
+
+        bytes[len - 1] += 1;
+
+        APIFrame out;
+        for (size_t i = 0; i < len; i++)
+        {
+            APIFrameParser::ParseResult res = parser.parse(bytes[i], &out);
+            REQUIRE_FALSE(res == APIFrameParser::ParseResult::SUCCESS);
+
+            if (i == len - 1)
+            {
+                REQUIRE(res == APIFrameParser::ParseResult::FAIL);
+            }
+        }
+    }
+
+    SECTION("Wrong start delimiter")
+    {
+        RXPacketFrame rx;
+        rx.start_del = 0x55;
+        rx.setSourceAddress(0x0013A20040522BAA);
+        rx.setReceiveOptions(0x01);
+        uint8_t* rf_data = rx.getRXDataPointer();
+
+        rf_data[0] = 0x52;
+        rf_data[1] = 0x78;
+        rf_data[2] = 0x44;
+        rf_data[3] = 0x61;
+        rf_data[4] = 0x74;
+        rf_data[5] = 0x61;
+
+        rx.setRXDataLength(6);
+        rx.calcChecksum();
+
+        uint8_t bytes[MAX_API_FRAME_SIZE];
+
+        size_t len = rx.toBytes(bytes);
+
+        APIFrame out;
+        for (size_t i = 0; i < len; i++)
+        {
+            APIFrameParser::ParseResult res = parser.parse(bytes[i], &out);
+            REQUIRE(res == APIFrameParser::ParseResult::IDLE);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/tests/drivers/test-mavlink.cpp b/src/tests/drivers/test-mavlink.cpp
index e15a022eeb87ea186aebf8f7b93396af27976155..1cfd991812d3abdf2d09bad197a1ad0caa38b9f2 100644
--- a/src/tests/drivers/test-mavlink.cpp
+++ b/src/tests/drivers/test-mavlink.cpp
@@ -20,7 +20,13 @@
  * THE SOFTWARE.
  */
 
+// Ignore warnings, as we don't want to change third party generated files to 
+// fix them
+#pragma GCC diagnostic push 
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
 #include <libs/mavlink_skyward_lib/mavlink_lib/r2a/mavlink.h>
+#pragma GCC diagnostic pop 
 
 #include <Common.h>
 #include <drivers/gamma868/Gamma868.h>
diff --git a/src/tests/drivers/xbee/EnergyScanData.h b/src/tests/drivers/xbee/EnergyScanData.h
new file mode 100644
index 0000000000000000000000000000000000000000..68e672e27e27e0b952747a23656e35072bd197b3
--- /dev/null
+++ b/src/tests/drivers/xbee/EnergyScanData.h
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <array>
+#include <string>
+#include <ostream>
+
+using std::array;
+using std::string;
+using std::to_string;
+
+struct EnergyScanData
+{
+    long long timestamp;
+    int channel_data[30];
+
+    EnergyScanData() = default;
+
+    EnergyScanData(long long ts, array<int, 30> scan)
+    {
+        for(int i = 0; i < 30; i++)
+        {
+            channel_data[i] = scan[i];
+        }
+    }
+
+    static string header()
+    {
+        string out = "timestamp";
+        for(int i = 0; i < 30; i++)
+        {
+            out += ",channel_" + to_string(i);
+        }
+        return out + "\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp;
+
+        for(int i = 0; i < 30; i++)
+        {
+            os << "," << channel_data[i];
+        }
+
+        os << "\n";
+    }
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/Mark.h b/src/tests/drivers/xbee/Mark.h
new file mode 100644
index 0000000000000000000000000000000000000000..52b3c9be11029702d43fc312f3c85ca7a311cd64
--- /dev/null
+++ b/src/tests/drivers/xbee/Mark.h
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <string>
+#include <ostream>
+
+using std::string;
+/**
+ * @brief Used to mark a specific instant in the log
+ */
+struct Mark
+{
+    long long timestamp;
+    unsigned int seq;
+
+    static string header()
+    {
+        return "timestamp,seq\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << seq << "\n";
+    }
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/XbeeTestData.h b/src/tests/drivers/xbee/XbeeTestData.h
new file mode 100644
index 0000000000000000000000000000000000000000..3416b48e48f08ec51b1b18b050b62b3a142aa705
--- /dev/null
+++ b/src/tests/drivers/xbee/XbeeTestData.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <ostream>
+#include <array>
+#include <string>
+
+#include "math/Stats.h"
+
+using std::array;
+using std::string;
+using std::to_string;
+
+struct XbeeConfig
+{
+    long long timestamp;
+    bool tx_enabled            = false;
+    uint16_t packet_size       = 256;
+    unsigned int send_interval = 0;
+    bool freq_hop              = true;
+    bool data_rate_80k         = false;
+
+    void print()
+    {
+        printf("+++XBee configuration+++\n\n");
+        printf("Tx: %s, pkt: %u B, int: %d ms\n",
+               tx_enabled ? "enabled" : "disabled", packet_size, send_interval);
+        printf("Freq hop: %s, data rate: %s \n", freq_hop ? "on" : "off",
+               data_rate_80k ? "80 kbps" : "10 kbps");
+    }
+
+    static string header()
+    {
+        return "timestamp,tx_enabled,packet_size,send_interval,freq_hop,data_"
+               "rate_80k\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << tx_enabled << "," << packet_size << ","
+           << send_interval << "," << freq_hop << "," << data_rate_80k << "\n";
+    }
+};
+
+struct TxData
+{
+    long long timestamp               = 0LL;
+    unsigned int packet_size          = 0;
+    unsigned int time_since_last_send = 0;
+    unsigned int time_to_send         = 0;
+    unsigned int tx_success_counter   = 0;
+    unsigned int tx_fail_counter      = 0;
+
+    static string header()
+    {
+        return "timestamp,packet_size,time_since_last_send,time_to_send,tx_"
+               "success_cnt,tx_fail_cnt\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << packet_size << "," << time_since_last_send
+           << "," << time_to_send << "," << tx_success_counter << ","
+           << tx_fail_counter << "\n";
+    }
+};
+
+struct RxData
+{
+    long long timestamp;
+    size_t pkt_size                 = 0;
+    long long last_packet_timestamp = 0;
+    int RSSI                        = 0;
+    unsigned int rcv_count          = 0;
+    unsigned int packets_lost       = 0;
+    unsigned int rcv_errors         = 0;
+    unsigned int rcv_wrong_payload  = 0;
+
+    static string header()
+    {
+        return "timestamp,packet_size,last_packet_timestamp,RSSI,rcv_cnt,rcv_errors,"
+               "rcv_wrong\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << pkt_size << "," << last_packet_timestamp << ","
+           << RSSI << "," << rcv_count << "," << rcv_errors << ","
+           << rcv_wrong_payload << "\n";
+    }
+};
+
+struct EnergyScanData
+{
+    long long timestamp;
+    int channel_data[30];
+
+    EnergyScanData() = default;
+
+    EnergyScanData(long long ts, array<int, 30> scan)
+    {
+        for(int i = 0; i < 30; i++)
+        {
+            channel_data[i] = scan[i];
+        }
+
+        timestamp = ts;
+    }
+
+    static string header()
+    {
+        string out = "timestamp";
+        for(int i = 0; i < 30; i++)
+        {
+            out += ",channel_" + to_string(i);
+        }
+        return out + "\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp;
+
+        for(int i = 0; i < 30; i++)
+        {
+            os << "," << channel_data[i];
+        }
+
+        os << "\n";
+    }
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/XbeeTransceiver.h b/src/tests/drivers/xbee/XbeeTransceiver.h
new file mode 100644
index 0000000000000000000000000000000000000000..82000b9c9f595d813f7335e37cab611c5577e41b
--- /dev/null
+++ b/src/tests/drivers/xbee/XbeeTransceiver.h
@@ -0,0 +1,424 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <arch/common/drivers/stm32_hardware_rng.h>
+#include <miosix.h>
+
+#include <functional>
+
+#include "ActiveObject.h"
+#include "XbeeTestData.h"
+#include "drivers/Xbee/APIFramesLog.h"
+#include "drivers/Xbee/Xbee.h"
+#include "logger/Logger.h"
+#include "utils/testutils/ThroughputCalculator.h"
+
+using miosix::getTick;
+using std::bind;
+using std::function;
+
+static constexpr size_t RCV_BUF_SIZE       = 256;
+static constexpr uint32_t PACKET_FIRST_INT = 0xF0E1C2B3;
+
+/**
+ * @brief Repeats the provided 32 bit value in the buffer, filling it.
+ *
+ * @param buf Buffer to fill
+ * @param val Value to fill the buffer with
+ * @param buf_size size of the buffer
+ */
+void memset32(uint8_t* buf, uint32_t val, int buf_size)
+{
+    int i = 0;
+    while (i <= buf_size - (int)sizeof(val))
+    {
+        memcpy(buf + i, &val, sizeof(val));
+        i += sizeof(val);
+    }
+
+    memcpy(buf + i, &val, buf_size % sizeof(val));
+}
+
+struct SendIntervalBase
+{
+    virtual unsigned int getInterval() const = 0;
+};
+
+struct ConstSendInterval : public SendIntervalBase
+{
+    ConstSendInterval(unsigned int interval) : interval(interval) {}
+    unsigned int interval;
+    unsigned int getInterval() const override { return interval; }
+};
+
+struct RandSendInterval : public SendIntervalBase
+{
+    RandSendInterval(unsigned int min, unsigned int max)
+        : min(min), diff(max - min)
+    {
+    }
+    unsigned int min;
+    unsigned int diff;
+    unsigned int getInterval() const override
+    {
+        return (miosix::HardwareRng::instance().get() % diff) + min;
+    }
+};
+
+class Sender : public ActiveObject
+{
+    friend class XbeeTransceiver;
+
+public:
+    Sender(Xbee::Xbee& xbee, Logger& logger, const SendIntervalBase& interval,
+           size_t packet_size, long long expected_packet_interval)
+        : xbee(xbee), logger(logger), dr_calc(expected_packet_interval),
+          interval(interval)
+    {
+        data.packet_size = packet_size;
+        packet_counter   = 0;
+    }
+
+    TxData getTxData() const { return data; }
+
+    DataRateResult getDataRate() { return dr_calc.getResult(); }
+
+protected:
+    void run() override
+    {
+        long long loop_start_ts = getTick();
+        while (!shouldStop())
+        {
+            data.time_since_last_send = getTick() - loop_start_ts;
+            loop_start_ts             = getTick();
+
+            // Create packet
+            memcpy(buf, &PACKET_FIRST_INT, sizeof(uint32_t));
+            memset32(buf + sizeof(uint32_t), packet_counter++,
+                     data.packet_size - sizeof(uint32_t));
+
+            long long send_start_ts = getTick();
+
+            bool result = xbee.send(buf, data.packet_size);
+
+            data.time_to_send = getTick() - send_start_ts;
+            data.timestamp    = send_start_ts;
+
+            if (result)
+            {
+                ++data.tx_success_counter;
+                dr_calc.addPacket(data.packet_size);
+            }
+            else
+            {
+                ++data.tx_fail_counter;
+            }
+
+            logger.log(data);
+
+            miosix::Thread::sleepUntil(loop_start_ts + interval.getInterval());
+        }
+    }
+
+private:
+    Xbee::Xbee& xbee;
+    Logger& logger;
+    ThroughputCalculator dr_calc;
+    TxData data;
+    const SendIntervalBase& interval;
+
+    uint32_t packet_counter = 0;
+
+    uint8_t buf[Xbee::MAX_PACKET_PAYLOAD_LENGTH];
+};
+
+class Receiver : public ActiveObject
+{
+    friend class XbeeTransceiver;
+
+public:
+    Receiver(Xbee::Xbee& xbee, Logger& logger,
+             long long expected_packet_interval)
+        : xbee(xbee), logger(logger), dr_calc(expected_packet_interval)
+    {
+    }
+
+    void stop() override
+    {
+        should_stop = true;
+        xbee.wakeReceiver(true);
+        ActiveObject::stop();
+    }
+
+    RxData getRxData() const { return data; }
+
+    DataRateResult getDataRate() { return dr_calc.getResult(); }
+
+protected:
+    void run() override
+    {
+        while (!shouldStop())
+        {
+            long long start = getTick();
+
+            size_t len = xbee.receive(buf, RCV_BUF_SIZE);
+
+            data.last_packet_timestamp = getTick();
+            data.timestamp             = start;
+
+            ++data.rcv_count;
+
+            if (len > sizeof(uint32_t))
+            {
+                data.pkt_size = len;
+
+                // Packet payload is a repeated sequential 32 bit number
+                uint32_t num, strt;
+                memcpy(&strt, buf, sizeof(uint32_t));
+                memcpy(&num, buf + sizeof(uint32_t), sizeof(uint32_t));
+
+                if (checkPacket(num, buf, len))
+                {
+                    dr_calc.addPacket(len);
+                    if (last_packet_num > 0)
+                    {
+                        if (num > last_packet_num)
+                            data.packets_lost += num - last_packet_num - 1;
+                    }
+                    last_packet_num = num;
+                }
+                else
+                {
+                    TRACE("[XBeeTransceiver] Wrong packet payload! num: %u, start: 0x%08X\n", num, strt);
+                    ++data.rcv_wrong_payload;
+                }
+            }
+
+            logger.log(data);
+        }
+    }
+
+private:
+    bool checkPacket(uint32_t expected_num, uint8_t* packet, size_t packet_size)
+    {
+        if (memcmp(packet, &PACKET_FIRST_INT, sizeof(uint32_t)) == 0)
+        {
+            int i = sizeof(uint32_t);
+            while (i <= (int)packet_size - (int)sizeof(expected_num))
+            {
+                if (memcmp(packet + i, &expected_num, sizeof(expected_num)) !=
+                    0)
+                {
+                    return false;
+                }
+                i += sizeof(expected_num);
+            }
+            memcpy(packet + i, &expected_num,
+                   packet_size % sizeof(expected_num));
+            return true;
+        }
+        return false;
+    }
+
+    Xbee::Xbee& xbee;
+    Logger& logger;
+    ThroughputCalculator dr_calc;
+    RxData data{};
+
+    uint8_t buf[RCV_BUF_SIZE];
+    uint32_t last_packet_num = 0;
+};
+
+class XbeeTransceiver
+{
+public:
+    XbeeTransceiver(Xbee::Xbee& xbee, Logger& logger,
+                    const SendIntervalBase& snd_interval, size_t tx_pkt_size,
+                    long long expected_packet_interval)
+        : sender(new Sender(xbee, logger, snd_interval, tx_pkt_size,
+                            expected_packet_interval)),
+          receiver(new Receiver(xbee, logger, expected_packet_interval)),
+          logger(logger)
+    {
+        using namespace std::placeholders;
+        xbee.setOnFrameReceivedListener(
+            bind(&XbeeTransceiver::handleApiFrame, this, _1));
+    }
+
+    ~XbeeTransceiver()
+    {
+        sender->stop();
+        receiver->stop();
+
+        delete sender;
+        delete receiver;
+    }
+
+    void disableSender() { sender_enabled = false; }
+
+    void disableReceiver() { receiver_enabled = false; }
+
+    void start()
+    {
+        if (sender_enabled)
+        {
+            sender->start();
+        }
+        if (receiver_enabled)
+        {
+            receiver->start();
+        }
+    }
+
+    void stop()
+    {
+        sender->stop();
+        receiver->stop();
+    }
+
+    void setOnFrameReceivedListener(
+        Xbee::Xbee::OnFrameReceivedListener frame_listener)
+    {
+        this->frame_listener = frame_listener;
+    }
+
+    Sender& getSender() { return *sender; }
+
+    Receiver& getReceiver() { return *receiver; }
+
+private:
+    void handleApiFrame(Xbee::APIFrame& frame)
+    {
+        logAPIFrame(frame);
+
+        if (frame_listener)
+        {
+            frame_listener(frame);
+        }
+
+        if (frame.frame_type == Xbee::FTYPE_AT_COMMAND_RESPONSE)
+        {
+            Xbee::ATCommandResponseFrame* at =
+                frame.toFrameType<Xbee::ATCommandResponseFrame>();
+
+            if (strncmp(at->getATCommand(), "DB", 2) == 0)
+            {
+                receiver->data.RSSI = -*at->getCommandDataPointer();
+            }
+
+            if (strncmp(at->getATCommand(), "ER", 2) == 0)
+            {
+                uint16_t errs;
+                memcpy(&errs, at->getCommandDataPointer(), 2);
+                receiver->data.rcv_errors = swapBytes16(errs);
+            }
+        }
+    }
+
+    void logAPIFrame(Xbee::APIFrame& frame)
+    {
+        using namespace Xbee;
+        bool logged = false;
+        switch (frame.frame_type)
+        {
+            case FTYPE_AT_COMMAND:
+            {
+                ATCommandFrameLog dest;
+                logged = ATCommandFrameLog::toFrameType(frame, &dest);
+                if (logged)
+                {
+                    logger.log(dest);
+                }
+                break;
+            }
+            case FTYPE_AT_COMMAND_RESPONSE:
+            {
+                ATCommandResponseFrameLog dest;
+                logged = ATCommandResponseFrameLog::toFrameType(frame, &dest);
+                if (logged)
+                {
+                    logger.log(dest);
+                }
+                break;
+            }
+            case FTYPE_MODEM_STATUS:
+            {
+                ModemStatusFrameLog dest;
+                logged = ModemStatusFrameLog::toFrameType(frame, &dest);
+                if (logged)
+                {
+                    logger.log(dest);
+                }
+                break;
+            }
+            case FTYPE_TX_REQUEST:
+            {
+                TXRequestFrameLog dest;
+                logged = TXRequestFrameLog::toFrameType(frame, &dest);
+                if (logged)
+                {
+                    logger.log(dest);
+                }
+                break;
+            }
+            case FTYPE_TX_STATUS:
+            {
+                TXStatusFrameLog dest;
+                logged = TXStatusFrameLog::toFrameType(frame, &dest);
+                if (logged)
+                {
+                    logger.log(dest);
+                }
+                break;
+            }
+            case FTYPE_RX_PACKET_FRAME:
+            {
+                RXPacketFrameLog dest;
+                logged = RXPacketFrameLog::toFrameType(frame, &dest);
+                if (logged)
+                {
+                    logger.log(dest);
+                }
+                break;
+            }
+        }
+
+        if (!logged)
+        {
+            APIFrameLog api;
+            APIFrameLog::fromAPIFrame(frame, &api);
+            logger.log(api);
+        }
+    }
+
+    bool sender_enabled   = true;
+    bool receiver_enabled = true;
+
+    Sender* sender;
+    Receiver* receiver;
+    Logger& logger;
+
+    Xbee::Xbee::OnFrameReceivedListener frame_listener;
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/ConfigScreen.h b/src/tests/drivers/xbee/gui/ConfigScreen.h
new file mode 100644
index 0000000000000000000000000000000000000000..32140ef6501e79ca7ebcc9104e0fe47a51dc9c32
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/ConfigScreen.h
@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <mxgui/display.h>
+
+#include "utils/gui/GridLayout.h"
+#include "utils/gui/TextView.h"
+#include "utils/gui/VerticalLayout.h"
+#include "utils/gui/OptionView.h"
+
+#include "../XbeeTestData.h"
+
+struct ConfigScreen
+{
+    XbeeConfig config;
+
+    enum OptSendEnableIDs : uint8_t
+    {
+        TX_ENABLED,
+        TX_DISABLED
+    };
+
+    enum OptFreqHopIDs : uint8_t
+    {
+        FH_ENABLED,
+        FH_DISABLED
+    };
+
+    enum OptDataRateIDs : uint8_t
+    {
+        DR_10K,
+        DR_80K
+    };
+
+    enum OptPacketSizeIDs : uint8_t
+    {
+        PKTSIZE_64,
+        PKTSIZE_128,
+        PKTSIZE_256
+    };
+
+    enum OptSendIntervalIDs : uint8_t
+    {
+        TXINT_CONTINUOUS,
+        TXINT_200MS,
+        TXINT_250MS,
+        TXINT_333MS,
+        TXINT_500MS,
+        TXINT_1000MS
+    };
+
+    ConfigScreen()
+    {
+        title.setFont(mxgui::miscFixedBold);
+        title.setTextColor(mxgui::black);
+        title.setBackgroundColor(mxgui::green);
+        title.setAlignment(HorizAlignment::LEFT, VertAlignment::CENTER);
+
+        tv_log_status.setFont(mxgui::miscFixedBold);
+        tv_log_status.setTextColor(mxgui::white);
+        tv_log_status.setBackgroundColor(mxgui::red);
+        tv_log_status.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+
+        grid_title.setCell(&title, 0, 0);
+        grid_title.setCell(&tv_log_status, 0, 1);
+
+        grid.setCell(&btn_energy, 0);
+        grid.setCell(&btn_start, 1);
+        grid.setDrawBorder(true);
+
+        btn_start.setSelectable(true);
+        btn_start.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        btn_start.setBackgroundColor(mxgui::darkGrey);
+        
+        btn_energy.setSelectable(true);
+        btn_energy.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        btn_energy.setBackgroundColor(mxgui::darkGrey);
+
+        root.addView(&grid_title, 0.6);
+        root.addView(&opt_send_enable, 1);
+        root.addView(&opt_packet_size, 1);
+
+        root.addView(&opt_send_interval, 2);
+
+        root.addView(&opt_freq_hop, 1);
+        root.addView(&opt_data_rate, 1);
+        root.addView(&grid, 1);
+
+        addOptionCallbacks();
+    }
+
+    void updateLogStatus(Logger& logger)
+    {
+        if (logger.getLogNumber() >= 0)
+        {
+            string log_name = logger.getFileName(logger.getLogNumber());
+
+            tv_log_status.setText(log_name);
+            tv_log_status.setTextColor(mxgui::black);
+            tv_log_status.setBackgroundColor(mxgui::green);
+        }
+        else
+        {
+            tv_log_status.setText("SD ERR");
+            tv_log_status.setTextColor(mxgui::white);
+            tv_log_status.setBackgroundColor(mxgui::red);
+        }
+    }
+
+    VerticalLayout root{10};
+
+    TextView btn_start{"Start"};
+    TextView btn_energy{"Energy scan"};
+
+private:
+    void addOptionCallbacks()
+    {
+        opt_send_enable.addOnOptionChosenListener(
+            [&](unsigned int id) { config.tx_enabled = id == TX_ENABLED; });
+
+        opt_send_interval.addOnOptionChosenListener([&](unsigned int id) {
+            switch (id)
+            {
+                case TXINT_CONTINUOUS:
+                    config.send_interval = 0;
+                    break;
+                case TXINT_200MS:
+                    config.send_interval = 200;
+                    break;
+                case TXINT_250MS:
+                    config.send_interval = 250;
+                    break;
+                case TXINT_333MS:
+                    config.send_interval = 333;
+                    break;
+                case TXINT_500MS:
+                    config.send_interval = 500;
+                    break;
+                case TXINT_1000MS:
+                    config.send_interval = 1000;
+                    break;
+            }
+        });
+
+        opt_packet_size.addOnOptionChosenListener([&](unsigned int id) {
+            switch (id)
+            {
+                case PKTSIZE_64:
+                    config.packet_size = 64;
+                    break;
+                case PKTSIZE_128:
+                    config.packet_size = 128;
+                    break;
+                case PKTSIZE_256:
+                    config.packet_size = 256;
+                    break;
+            }
+        });
+
+        opt_freq_hop.addOnOptionChosenListener(
+            [&](unsigned int id) { config.freq_hop = id == FH_ENABLED; });
+
+        opt_data_rate.addOnOptionChosenListener(
+            [&](unsigned int id) { config.data_rate_80k = id == DR_80K; });
+    }
+
+    OptionView opt_send_enable{
+        "Transmission",
+        {{TX_ENABLED, "Enabled"}, {TX_DISABLED, "Disabled"}},
+        TX_DISABLED,
+        2};
+
+    OptionView opt_packet_size{
+        "TX Packet Size",
+        {{PKTSIZE_64, "64 B"}, {PKTSIZE_128, "128 B"}, {PKTSIZE_256, "256 B"}},
+        PKTSIZE_256,
+        3};
+
+    OptionView opt_send_interval{"Send Interval",
+                                 {{TXINT_CONTINUOUS, "Cont"},
+                                  {TXINT_200MS, "200 ms"},
+                                  {TXINT_250MS, "250 ms"},
+                                  {TXINT_333MS, "333 ms"},
+                                  {TXINT_500MS, "500 ms"},
+                                  {TXINT_1000MS, "1 sec"}},
+                                 TXINT_CONTINUOUS,
+                                 4};
+
+    OptionView opt_freq_hop{
+        "Frequency hopping",
+        {{FH_ENABLED, "Enabled"}, {FH_DISABLED, "Disabled"}},
+        FH_ENABLED,
+        2};
+    OptionView opt_data_rate{
+        "Xbee datarate", {{DR_10K, "10 kbps"}, {DR_80K, "80 kbps"}}, DR_10K, 2};
+
+    GridLayout grid{1, 2};
+    GridLayout grid_title{1,2};
+    TextView title{"Xbee Setup"};
+    TextView tv_log_status{"SD ERR!"};
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/EndScreen.h b/src/tests/drivers/xbee/gui/EndScreen.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c19f211a6f1d55a84a72c0a52a426922545b7ff
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/EndScreen.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <mxgui/display.h>
+
+#include "utils/gui/GridLayout.h"
+#include "utils/gui/TextView.h"
+#include "utils/gui/VerticalLayout.h"
+#include "utils/gui/OptionView.h"
+
+
+
+struct EndScreen
+{
+    EndScreen()
+    {
+        tv_title.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        tv_f.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        tv_reset.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+
+        tv_f.setSelectable(true);
+        tv_reset.setSelectable(true);
+
+        root.addView(&tv_title, 1);
+        root.addView(&tv_f, 1);
+        root.addView(&tv_reset, 1);
+    }
+
+    VerticalLayout root;
+
+    TextView tv_f{"Press F to pay respects"};
+    TextView tv_reset{"Or RESET to start again"};
+private:
+    TextView tv_title{"You killed the program, you maniac!"}; 
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/EnergyScanScreen.h b/src/tests/drivers/xbee/gui/EnergyScanScreen.h
new file mode 100644
index 0000000000000000000000000000000000000000..a463f90672637330dbded3afb6d0c5fd946ed8e2
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/EnergyScanScreen.h
@@ -0,0 +1,232 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <mxgui/display.h>
+
+#include <array>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "math/Stats.h"
+#include "utils/gui/GridLayout.h"
+#include "utils/gui/TextView.h"
+#include "utils/gui/VerticalLayout.h"
+
+using std::array;
+using std::to_string;
+
+struct EnergyScanScreen
+{
+    static constexpr unsigned int NUM_CHANNELS     = 30;
+    static constexpr unsigned int NUM_CHANNEL_ROWS = (NUM_CHANNELS + 1) / 2;
+    static constexpr unsigned int NUM_COLS         = 8;
+
+    static constexpr float COLOR_PERCENTILE = 0.15f;
+    EnergyScanScreen()
+    {
+        tv_title.setFont(mxgui::miscFixedBold);
+        tv_title.setTextColor(mxgui::black);
+        tv_title.setBackgroundColor(mxgui::green);
+        tv_title.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+
+        tv_log_status.setFont(mxgui::miscFixedBold);
+        tv_log_status.setTextColor(mxgui::white);
+        tv_log_status.setBackgroundColor(mxgui::red);
+        tv_log_status.setAlignment(HorizAlignment::CENTER,
+                                   VertAlignment::CENTER);
+
+        grid_title.setCell(&tv_title, 0, 0);
+        grid_title.setCell(&tv_log_status, 0, 1);
+
+        for (unsigned int i = 0; i < NUM_COLS; i++)
+        {
+            col_titles[i] = new TextView(titles[i % (NUM_COLS / 2)]);
+            col_titles[i]->setTextColor(mxgui::blue);
+
+            grid_channels.setCell(col_titles[i], 0, i);
+        }
+
+        mxgui::Color pink(0xFC59);
+        for (unsigned int i = 0; i < NUM_CHANNELS; ++i)
+        {
+            char buf[3];
+            snprintf(buf, 3, "%02d", i);
+
+            col_names[i] = new TextView(buf);
+            col_names[i]->setTextColor(pink);
+
+            col_current[i] = new TextView("-40");
+            col_min[i]    = new TextView("-40");
+            col_max[i]     = new TextView("-40");
+
+            grid_channels.setCell(col_names[i], (i % NUM_CHANNEL_ROWS) + 1,
+                                  (i / NUM_CHANNEL_ROWS) * 4 + 0);
+            grid_channels.setCell(col_current[i], (i % NUM_CHANNEL_ROWS) + 1,
+                                  (i / NUM_CHANNEL_ROWS) * 4 + 1);
+            grid_channels.setCell(col_min[i], (i % NUM_CHANNEL_ROWS) + 1,
+                                  (i / NUM_CHANNEL_ROWS) * 4 + 2);
+            grid_channels.setCell(col_max[i], (i % NUM_CHANNEL_ROWS) + 1,
+                                  (i / NUM_CHANNEL_ROWS) * 4 + 3);
+        }
+
+        btn_mark.setSelectable(true);
+        btn_mark.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        btn_mark.setBackgroundColor(mxgui::darkGrey);
+
+        btn_stop.setSelectable(true);
+        btn_stop.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        btn_stop.setBackgroundColor(mxgui::darkGrey);
+
+        btn_reset.setSelectable(true);
+        btn_reset.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        btn_reset.setBackgroundColor(mxgui::darkGrey);
+
+        grid_buttons.setCell(&btn_mark, 0);
+        grid_buttons.setCell(&btn_reset, 1);
+        grid_buttons.setCell(&btn_stop, 2);
+        grid_buttons.setDrawBorder(true);
+
+        root.addView(&grid_title, 0.8);
+        root.addView(&grid_channels, 10);
+        root.addView(&grid_buttons, 1);
+    }
+
+    ~EnergyScanScreen()
+    {
+        for (unsigned int i = 0; i < NUM_COLS; i++)
+        {
+            delete col_titles[i];
+        }
+
+        for (unsigned int i = 0; i < NUM_CHANNELS; ++i)
+        {
+            delete col_names[i];
+            delete col_current[i];
+            delete col_min[i];
+            delete col_max[i];
+        }
+    }
+
+    void updateScan(array<int, NUM_CHANNELS> scan)
+    {
+        for (unsigned int i = 0; i < NUM_CHANNELS; i++)
+        {
+            ch_stats[i].add(scan[i]);
+
+            StatsResult r = ch_stats[i].getStats();
+
+            abs_max = std::max(r.maxValue, abs_max);
+            abs_min = std::min(r.minValue, abs_min);
+        }
+
+        for (unsigned int i = 0; i < NUM_CHANNELS; i++)
+        {
+            StatsResult r = ch_stats[i].getStats();
+
+            col_min[i]->setText(to_string((int)r.minValue));
+            setColor(col_min[i], r.minValue);
+
+            col_current[i]->setText(to_string(scan[i]));
+            setColor(col_current[i], scan[i]);
+
+            col_max[i]->setText(to_string((int)r.maxValue));
+            setColor(col_max[i], r.maxValue);
+        }
+    }
+
+    void resetStats()
+    {
+        for (unsigned int i = 0; i < NUM_CHANNELS; i++)
+        {
+            ch_stats[i].reset();
+        }
+
+        abs_max = std::numeric_limits<float>::lowest();
+        abs_min = std::numeric_limits<float>::max();
+    }
+
+    void updateLogStatus(Logger& logger)
+    {
+        if (logger.getLogNumber() >= 0)
+        {
+            string log_name = logger.getFileName(logger.getLogNumber());
+
+            tv_log_status.setText(log_name);
+            tv_log_status.setTextColor(mxgui::black);
+            tv_log_status.setBackgroundColor(mxgui::green);
+        }
+        else
+        {
+            tv_log_status.setText("SD ERR");
+            tv_log_status.setTextColor(mxgui::white);
+            tv_log_status.setBackgroundColor(mxgui::red);
+        }
+    }
+
+    VerticalLayout root{5};
+
+    TextView btn_mark{"Mark Log (1)"};
+    TextView btn_stop{"Stop"};
+    TextView btn_reset{"Reset"};
+
+private:
+    void setColor(TextView* tv, float val)
+    {
+        float delta = abs_max - abs_min;
+        if (val >= abs_max - delta * COLOR_PERCENTILE)
+        {
+            tv->setTextColor(mxgui::green);
+        }
+        else if (val <= abs_min + delta * COLOR_PERCENTILE)
+        {
+            tv->setTextColor(0xFDC0);  // Light orange
+        }
+        else
+        {
+            tv->setTextColor(mxgui::white);
+        }
+    }
+    float abs_max = std::numeric_limits<float>::lowest();
+    float abs_min = std::numeric_limits<float>::max();
+
+    GridLayout grid_channels{NUM_CHANNEL_ROWS + 1, NUM_COLS};
+    GridLayout grid_title{1, 2};
+    GridLayout grid_buttons{1, 3};
+
+    TextView tv_log_status{"SD ERR"};
+    TextView tv_title{"Energy Scan"};
+
+    array<std::string, NUM_COLS / 2> titles = {"CH", "Curr", "Min", "Max"};
+    array<TextView*, NUM_COLS> col_titles;
+
+    array<TextView*, NUM_CHANNELS> col_names;
+    array<TextView*, NUM_CHANNELS> col_current;
+    array<TextView*, NUM_CHANNELS> col_min;
+    array<TextView*, NUM_CHANNELS> col_max;
+
+    array<Stats, NUM_CHANNELS> ch_stats;
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/RespectScreen.h b/src/tests/drivers/xbee/gui/RespectScreen.h
new file mode 100644
index 0000000000000000000000000000000000000000..2dbc1d6ef37302bdfa440e4b9fd40698643334d1
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/RespectScreen.h
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <mxgui/display.h>
+
+#include "res/respect.h"
+#include "utils/gui/ImageView.h"
+
+struct RespectScreen
+{
+    RespectScreen()
+    {
+        
+    }
+
+    ImageView root{&respect};
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/StatusScreen.h b/src/tests/drivers/xbee/gui/StatusScreen.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9661a4047a5f53901a27e2f19780e962f48766c
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/StatusScreen.h
@@ -0,0 +1,334 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <mxgui/display.h>
+
+#include <cstdint>
+#include <string>
+#include <cstring>
+
+#include "utils/testutils/ThroughputCalculator.h"
+#include "../XbeeTestData.h"
+#include "logger/Logger.h"
+
+#include "utils/gui/GridLayout.h"
+#include "utils/gui/OptionView.h"
+#include "utils/gui/TextView.h"
+#include "utils/gui/VerticalLayout.h"
+
+using std::to_string;
+
+/**
+ * @brief Converts tick in milliseconds to the HH:MM:SS format
+ */
+std::string tickToHMS(long long tick)
+{
+    char buf[15];
+
+    int h = tick / (1000 * 3600);
+    tick -= h * (1000 * 3600);
+    int m = tick / (1000 * 60);
+    tick -= m * (1000 * 60);
+    int s = tick/1000;
+
+    snprintf(buf, 15, "%02d:%02d:%02d", h, m, s);
+
+    return string(buf);
+}
+
+struct StatusScreen
+{
+    XbeeConfig config;
+
+    StatusScreen()
+    {
+        title.setFont(mxgui::miscFixedBold);
+        title.setTextColor(mxgui::black);
+        title.setBackgroundColor(mxgui::green);
+        title.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+
+        tv_log_status.setFont(mxgui::miscFixedBold);
+        tv_log_status.setTextColor(mxgui::white);
+        tv_log_status.setBackgroundColor(mxgui::red);
+        tv_log_status.setAlignment(HorizAlignment::CENTER,
+                                   VertAlignment::CENTER);
+
+        grid_title.setCell(&title, 0, 0);
+        grid_title.setCell(&tv_log_status, 0, 1);
+
+        grid_config.setCell(&tv_cfg_txt_tx_enabled, 0, 0);
+        grid_config.setCell(&tv_cfg_tx_enabled, 0, 1);
+
+        grid_config.setCell(&tv_cfg_txt_pkt_size, 0, 2);
+        grid_config.setCell(&tv_cfg_pkt_size, 0, 3);
+
+        grid_config.setCell(&tv_cfg_txt_snd_interval, 1, 0);
+        grid_config.setCell(&tv_cfg_snd_interval, 1, 1);
+
+        grid_config.setCell(&tv_cfg_txt_freq_hop, 1, 2);
+        grid_config.setCell(&tv_cfg_freq_hop, 1, 3);
+
+        grid_config.setCell(&tv_cfg_txt_data_rate, 2, 0);
+        grid_config.setCell(&tv_cfg_data_rate, 2, 1);
+
+        tv_log_title.setTextColor(mxgui::blue);
+
+        grid_log_status.setCell(&tv_log_title, 0, 0);
+
+        grid_log_status.setCell(&tv_log_txt_buf_written, 1, 0);
+        grid_log_status.setCell(&tv_log_buf_written, 1, 1);
+
+        grid_log_status.setCell(&tv_log_txt_buf_ttw, 1, 2);
+        grid_log_status.setCell(&tv_log_buf_ttw, 1, 3);
+
+        grid_log_status.setCell(&tv_log_txt_buf_dropped, 2, 0);
+        grid_log_status.setCell(&tv_log_buf_dropped, 2, 1);
+
+        grid_log_status.setCell(&tv_log_txt_buf_failed, 2, 2);
+        grid_log_status.setCell(&tv_log_buf_failed, 2, 3);
+
+        tv_tx_title.setTextColor(mxgui::blue);
+
+        grid_data.setCell(&tv_tx_title, 0, 0);
+
+        grid_data.setCell(&tv_tx_txt_num_pkt, 1, 0);
+        grid_data.setCell(&tv_tx_num_pkt, 1, 1);
+
+        grid_data.setCell(&tv_tx_txt_num_fail, 2, 0);
+        grid_data.setCell(&tv_tx_num_fail, 2, 1);
+
+        grid_data.setCell(&tv_tx_txt_pps, 3, 0);
+        grid_data.setCell(&tv_tx_pps, 3, 1);
+
+        grid_data.setCell(&tv_tx_txt_TTS, 4, 0);
+        grid_data.setCell(&tv_tx_tts, 4, 1);
+
+        grid_data.setCell(&tv_tx_txt_last_status, 5, 0);
+        grid_data.setCell(&tv_tx_last_status, 5, 1);
+
+        grid_data.setCell(&tv_tx_txt_last_err, 6, 0);
+        grid_data.setCell(&tv_tx_last_err, 6, 1);
+
+        tv_rx_title.setTextColor(mxgui::blue);
+        grid_data.setCell(&tv_rx_title, 0, 2);
+
+        grid_data.setCell(&tv_rx_txt_num_pkt, 1, 2);
+        grid_data.setCell(&tv_rx_num_pkt, 1, 3);
+
+        grid_data.setCell(&tv_rx_txt_num_fail, 2, 2);
+        grid_data.setCell(&tv_rx_num_fail, 2, 3);
+
+        grid_data.setCell(&tv_rx_txt_lost, 3, 2);
+        grid_data.setCell(&tv_rx_lost, 3, 3);
+
+        grid_data.setCell(&tv_rx_txt_RSSI, 4, 2);
+        grid_data.setCell(&tv_rx_RSSI, 4, 3);
+
+        grid_data.setCell(&tv_rx_txt_data_rate, 5, 2);
+        grid_data.setCell(&tv_rx_data_rate, 5, 3);
+
+        grid_data.setCell(&tv_rx_txt_pps, 6, 2);
+        grid_data.setCell(&tv_rx_pps, 6, 3);
+
+        grid_data.setCell(&tv_rx_txt_time_since_last_rx, 7, 2);
+        grid_data.setCell(&tv_rx_time_since_last_rx, 7, 3);
+
+        btn_mark.setSelectable(true);
+        btn_mark.setAlignment(HorizAlignment::CENTER,
+                                     VertAlignment::CENTER);
+        btn_mark.setBackgroundColor(mxgui::darkGrey);
+
+        btn_stop.setSelectable(true);
+        btn_stop.setAlignment(HorizAlignment::CENTER, VertAlignment::CENTER);
+        btn_stop.setBackgroundColor(mxgui::darkGrey);
+
+        grid_buttons.setCell(&btn_mark, 0);
+        grid_buttons.setCell(&btn_stop, 1);
+        grid_buttons.setDrawBorder(true);
+
+        root.addView(&grid_title, 0.8);
+        root.addView(&grid_config, 1.5);
+        root.addView(&grid_log_status, 1.5);
+        root.addView(&grid_data, 5);
+        root.addView(&grid_buttons, 1);
+    }
+
+    void updateConfig(XbeeConfig cfg)
+    {
+        // Update GUI with selected config values
+        tv_cfg_tx_enabled.setText(cfg.tx_enabled ? "Enabled" : "Disabled");
+        tv_cfg_pkt_size.setText(std::to_string(cfg.packet_size));
+        tv_cfg_snd_interval.setText(cfg.send_interval == 0
+                                        ? "Cont"
+                                        : std::to_string(cfg.send_interval));
+
+        tv_cfg_freq_hop.setText(cfg.freq_hop ? "Enabled" : "Disabled");
+        tv_cfg_data_rate.setText(cfg.data_rate_80k ? "80 kbps" : "10 kbps");
+    }
+
+    void updateLogStatus(Logger& logger)
+    {
+        LogStats stats = logger.getLogStats();
+
+        if (logger.getLogNumber() >= 0)
+        {
+            string log_name = logger.getFileName(logger.getLogNumber());
+
+            tv_log_status.setText(log_name);
+            tv_log_status.setTextColor(mxgui::black);
+            tv_log_status.setBackgroundColor(mxgui::green);
+        }
+        else
+        {
+            tv_log_status.setText("SD ERR");
+            tv_log_status.setTextColor(mxgui::white);
+            tv_log_status.setBackgroundColor(mxgui::red);
+        }
+
+        tv_log_buf_dropped.setText(to_string(stats.statDroppedSamples));
+
+        if (stats.statDroppedSamples > 0)
+        {
+            tv_log_buf_dropped.setBackgroundColor(mxgui::red);
+        }
+
+        tv_log_buf_failed.setText(to_string(stats.statWriteFailed) + "   (" +
+                                  to_string(stats.statWriteError) + ")");
+
+        if (stats.statWriteError != 0)
+        {
+            tv_log_buf_failed.setBackgroundColor(mxgui::red);
+        }
+
+        tv_log_buf_written.setText(to_string(stats.statBufferWritten));
+        tv_log_buf_ttw.setText(to_string(stats.statWriteTime) + " ms");
+    }
+
+    void updateXbeeStatus(DataRateResult res_rcv, DataRateResult res_snd,
+                          TxData txd, RxData rxd, Xbee::XbeeStatus xbee_status)
+    {
+        char str_buf[30];
+
+        tv_tx_num_pkt.setText(
+            to_string(txd.tx_success_counter + txd.tx_fail_counter));
+        tv_tx_num_fail.setText(to_string(txd.tx_fail_counter));
+
+        snprintf(str_buf, 30, "%.1f pkt/s", res_snd.packets_per_second);
+
+        tv_tx_pps.setText(str_buf);
+        tv_tx_tts.setText(to_string(txd.time_to_send) + " ms");
+
+        tv_tx_last_status.setText(to_string(xbee_status.last_tx_status));
+        tv_tx_last_err.setText(to_string(xbee_status.last_tx_status_error));
+
+        tv_rx_num_pkt.setText(to_string(rxd.rcv_count));
+        tv_rx_num_fail.setText(to_string(rxd.rcv_errors));
+        // tv_rx_num_fail.setText(to_string(int_counter) + " " +
+        //                               to_string(GpioATTN::value()));
+        tv_rx_lost.setText(to_string(rxd.packets_lost));
+
+        tv_rx_RSSI.setText(to_string(rxd.RSSI) + " dB");
+
+        snprintf(str_buf, 30, "%.0f B/s", res_rcv.data_rate);
+        tv_rx_data_rate.setText(str_buf);
+
+        snprintf(str_buf, 30, "%.1f pkt/s", res_rcv.packets_per_second);
+        tv_rx_pps.setText(str_buf);
+
+        tv_rx_time_since_last_rx.setText(tickToHMS(miosix::getTick() - rxd.last_packet_timestamp));
+    }
+
+    VerticalLayout root{10};
+
+    TextView tv_cfg_tx_enabled{"Disabled"};
+    TextView tv_cfg_pkt_size{"256 B"};
+    TextView tv_cfg_snd_interval{"Cont"};
+    TextView tv_cfg_freq_hop{"Enabled"};
+    TextView tv_cfg_data_rate{"10 kbps"};
+
+    TextView tv_log_status{"SD ERR"};
+
+    TextView tv_log_buf_dropped{"0"};
+    TextView tv_log_buf_failed{"0 (0)"};
+    TextView tv_log_buf_written{"0"};
+    TextView tv_log_buf_ttw{"0 ms"};
+
+    TextView tv_tx_num_pkt{"0"};
+    TextView tv_tx_num_fail{"0"};
+    TextView tv_tx_pps{"0 pkt/s"};
+    TextView tv_tx_tts{"- ms"};
+    TextView tv_tx_last_status{"0"};
+    TextView tv_tx_last_err{"0"};
+
+    TextView tv_rx_num_pkt{"0"};
+    TextView tv_rx_num_fail{"0"};
+    TextView tv_rx_lost{"0"};
+    TextView tv_rx_RSSI{"-40 dB"};
+    TextView tv_rx_data_rate{"0 B/s"};
+    TextView tv_rx_pps{"0 pkt/s"};
+    TextView tv_rx_time_since_last_rx{"00:00:00"};
+
+    TextView btn_mark{"Mark Log (1)"};
+    TextView btn_stop{"Stop"};
+
+private:
+    TextView title{"Xbee Status"};
+    GridLayout grid_title{1, 2};
+    GridLayout grid_config{3, 4};
+    GridLayout grid_buttons{1, 2};
+    GridLayout grid_log_status{3, 4};
+    GridLayout grid_data{8, 4};
+
+    TextView tv_cfg_txt_tx_enabled{"TX"};
+    TextView tv_cfg_txt_pkt_size{"Pkt size"};
+    TextView tv_cfg_txt_snd_interval{"Interv"};
+    TextView tv_cfg_txt_freq_hop{"Freq hop"};
+    TextView tv_cfg_txt_data_rate{"Data rate"};
+
+    TextView tv_log_title{"LOG"};
+    TextView tv_log_txt_buf_dropped{"Buf drops"};
+    TextView tv_log_txt_buf_failed{"Wrt fails"};
+    TextView tv_log_txt_buf_written{"Wrt succ"};
+    TextView tv_log_txt_buf_ttw{"TTW"};
+
+    TextView tv_tx_title{"TX"};
+
+    TextView tv_tx_txt_num_pkt{"Sent"};
+    TextView tv_tx_txt_num_fail{"Fails"};
+    TextView tv_tx_txt_pps{"PPS"};
+    TextView tv_tx_txt_TTS{"TTS"};
+    TextView tv_tx_txt_last_status{"Status"};
+    TextView tv_tx_txt_last_err{"Last err"};
+
+    TextView tv_rx_title{"RX"};
+
+    TextView tv_rx_txt_num_pkt{"Recv"};
+    TextView tv_rx_txt_num_fail{"Fails"};
+    TextView tv_rx_txt_lost{"Lost"};
+    TextView tv_rx_txt_RSSI{"RSSI"};
+    TextView tv_rx_txt_data_rate{"DR"};
+    TextView tv_rx_txt_pps{"PPS"};
+    TextView tv_rx_txt_time_since_last_rx{"No RX dt"};
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/XbeeGui.h b/src/tests/drivers/xbee/gui/XbeeGui.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e5062f2aadf584a7ca8a86ef2fd0f941489f419
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/XbeeGui.h
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <mxgui/display.h>
+
+#include <cstdint>
+#include <functional>
+
+#include "ConfigScreen.h"
+#include "StatusScreen.h"
+#include "EnergyScanScreen.h"
+#include "EndScreen.h"
+#include "RespectScreen.h"
+#include "utils/gui/ScreenManager.h"
+
+class XbeeGUI
+{
+public:
+    enum Screens : uint8_t
+    {
+        SCREEN_CONFIG,
+        SCREEN_STATUS,
+        SCREEN_ENERGYSCAN,
+        SCREEN_END,
+        SCREEN_RESPECT
+    };
+
+    XbeeGUI()
+        : screen_manager(mxgui::DisplayManager::instance(), 4)
+    {
+        screen_manager.addScreen(SCREEN_CONFIG, &screen_config.root);
+        screen_manager.addScreen(SCREEN_STATUS, &screen_status.root);
+        screen_manager.addScreen(SCREEN_ENERGYSCAN, &screen_energy.root);
+        screen_manager.addScreen(SCREEN_END, &screen_end.root);
+        screen_manager.addScreen(SCREEN_RESPECT, &screen_respect.root);
+
+        screen_manager.start();
+    }
+
+    ~XbeeGUI()
+    {
+        screen_manager.stop();
+    }
+
+    ScreenManager screen_manager;
+
+    ConfigScreen screen_config{};
+    StatusScreen screen_status{};
+    EnergyScanScreen screen_energy{};
+    EndScreen screen_end{};
+    RespectScreen screen_respect{};
+};
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/res/respect.cpp b/src/tests/drivers/xbee/gui/res/respect.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..90e91dd6a0ff8818fe56eac3b26a2b3fc83857dc
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/res/respect.cpp
@@ -0,0 +1,9614 @@
+
+//This file has been automatcally generated by pngconverter utility
+//Please do not edit
+#include "respect.h"
+
+using namespace mxgui;
+
+static const short int height=320;
+static const short int width =240;
+
+static const unsigned short pixelData[]={
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,2145,6371,19049,
+ 29614,35921,38066,38034,35953,29614,21130,10597,
+ 2145,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,
+ 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,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,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,32,10597,33808,50712,61277,65503,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 54970,40147,21130,4258,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,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,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,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,10597,42260,63422,65535,65535,65535,65535,
+ 65503,65503,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,57051,31727,6371,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,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,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,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,
+ 29582,61277,65503,65535,65503,59164,42260,31727,
+ 23243,19017,16936,21162,27501,35953,48631,61277,
+ 63422,65535,65535,65535,65535,61277,35921,4258,
+ 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,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,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,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,4226,40179,
+ 65535,65535,61277,38034,14823,32,0,0,
+ 0,0,0,32,0,0,32,2145,
+ 19017,33840,57083,65535,65535,65535,65535,52857,
+ 14823,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,
+ 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,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,4226,44405,65503,
+ 63390,38034,6371,0,32,4226,14823,23275,
+ 27469,25388,21162,16904,10565,4258,32,32,
+ 0,0,2145,25388,57051,65535,65535,65535,
+ 61309,19049,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,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,
+ 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,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,2113,42260,65503,57083,
+ 19017,2113,32,4258,33840,57083,65503,65503,
+ 65535,65535,65503,65503,63422,61277,50744,38066,
+ 23243,6339,32,32,4258,38066,65535,65535,
+ 65535,59196,10565,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,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,31727,65503,52857,12678,
+ 0,0,14791,52857,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65503,63390,44373,19049,2113,32,27501,63390,
+ 65535,65535,50744,2113,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,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,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,14823,63390,57051,8452,0,
+ 0,12710,59164,65535,65535,63390,63390,63422,
+ 65535,65535,65535,65535,65535,65503,65535,65535,
+ 65535,65503,65503,65503,48599,10565,0,27501,
+ 65503,65535,65503,25388,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,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,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,2145,54938,63422,16936,0,0,
+ 4258,54938,65535,63390,31695,12678,6371,12678,
+ 14823,19017,23243,27469,29582,31727,35953,40179,
+ 52825,63390,65535,65535,65503,57083,12678,32,
+ 40147,65535,65535,52857,2113,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,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,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,31727,65535,31695,32,0,0,
+ 35953,65535,63390,21162,0,0,0,0,
+ 0,0,0,32,0,0,0,32,
+ 0,12678,38066,63422,65535,65535,52825,4258,
+ 6371,59164,65535,65503,19049,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,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,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,10565,61309,54938,4226,0,0,14791,
+ 63422,65503,31695,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,19017,59196,65535,65535,27469,
+ 0,29582,65535,65535,42260,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,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,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,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,0,
+ 32,42292,65535,23243,0,0,2145,48599,
+ 65535,44405,2113,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,16904,61309,65535,52857,
+ 2113,6371,61277,65535,57051,2145,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,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,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 12710,63390,52857,2113,32,0,19049,63422,
+ 57083,8484,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,27501,65535,63422,
+ 12710,32,46486,65535,63422,12710,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,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,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,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,32,0,32,
+ 42260,65535,29582,0,0,2113,50712,65535,
+ 27501,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,50744,65503,
+ 33808,0,21130,65535,65535,25356,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,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,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,6371,
+ 65503,61277,8452,0,0,16936,65535,54970,
+ 4226,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,21130,65503,
+ 50712,0,6371,61309,65535,40179,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,32,0,0,33808,
+ 65535,44373,32,0,0,44405,65503,29582,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4226,57083,
+ 61309,4258,32,52857,65535,54970,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,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,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,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,2145,54970,
+ 65535,23275,0,0,12678,63422,61277,8452,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,42292,
+ 65535,16904,0,42292,65535,59196,4258,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,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,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,0,0,0,0,
+ 0,0,0,0,0,0,16936,65535,
+ 61277,6339,0,0,35953,65535,52825,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,27469,
+ 65535,27469,32,29582,65535,63422,12678,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,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,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,0,0,0,0,
+ 0,0,0,0,0,0,42260,65535,
+ 50712,0,0,6339,57083,65535,38034,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,14823,
+ 65535,31727,0,23243,65535,65535,19017,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,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,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,0,0,0,0,
+ 0,0,0,0,32,4258,59164,65535,
+ 33808,0,32,19049,65503,65535,29582,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,32,0,8484,
+ 63422,35953,0,16936,65535,65535,25388,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,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,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,0,0,0,0,
+ 0,0,0,0,0,16936,65503,65503,
+ 14823,0,0,40179,65535,65535,25388,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,4258,
+ 57083,35921,0,12710,65535,65535,31695,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,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,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,0,0,0,0,
+ 0,0,0,0,32,35921,65535,59196,
+ 4226,0,4226,57083,65535,65535,27469,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,2113,
+ 52857,31695,0,12678,65535,65535,38066,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,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,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,0,0,0,0,
+ 0,0,0,0,0,52857,65535,48599,
+ 0,0,12710,65535,65535,65535,33808,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,8452,
+ 61309,27501,0,10565,65535,65535,44373,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,8484,63390,65535,31727,
+ 0,32,31727,65535,65535,65535,44373,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,10565,
+ 63390,21162,0,12678,65535,65503,44405,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,23275,65503,65503,19017,
+ 0,32,48631,65535,65535,65535,50712,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,10565,
+ 63390,16936,0,14791,65535,65535,44373,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,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,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,0,0,0,0,
+ 0,0,0,32,40147,65535,63390,8452,
+ 0,4226,59196,65535,65535,65535,57083,2113,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,10565,
+ 61309,10565,0,16904,65535,65535,42292,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,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,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,0,0,0,0,
+ 0,0,0,2113,52857,65535,57083,2113,
+ 32,16904,65535,65535,65535,65535,59196,2145,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,10565,
+ 61309,6339,0,19017,65503,65535,42260,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,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,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,0,0,0,0,
+ 0,0,0,6339,63390,65535,46486,32,
+ 0,29582,65535,65535,65535,65535,61309,2145,
+ 0,0,0,0,0,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,19049,
+ 59196,2145,0,25356,65535,65535,38066,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,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,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,0,0,0,0,
+ 0,0,0,14823,65503,65535,35953,0,
+ 0,42260,65535,65535,65535,65535,61309,6371,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,29614,
+ 57051,2113,0,31695,65535,65535,33840,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,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,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,0,0,0,0,
+ 0,0,0,29582,65535,65535,25356,0,
+ 2113,54938,65535,65535,65503,65535,63390,8484,
+ 32,0,2113,4226,10597,19017,27469,31695,
+ 31695,25356,14823,8484,2113,32,0,32,
+ 0,0,0,0,0,0,2113,46486,
+ 50744,32,0,40147,65535,65535,27469,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,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,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,0,0,0,0,
+ 0,0,0,40147,65535,65503,16936,0,
+ 4258,61309,65535,65535,65535,65535,65503,23243,
+ 2145,16904,40147,59164,65503,65535,65535,65535,
+ 65535,65535,65503,63422,52857,31727,8484,2145,
+ 0,0,0,0,32,0,4258,57083,
+ 48599,0,32,46486,65535,65503,21162,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,32,48599,65535,63390,10565,0,
+ 10597,65503,65535,65535,65535,65535,65503,63422,
+ 57051,65503,65535,65535,65535,65535,65503,65535,
+ 65535,65535,65535,65535,65535,65535,63390,44373,
+ 16904,32,0,0,0,32,23275,65535,
+ 42292,32,2113,52825,65535,65503,16936,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,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,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,0,0,0,0,
+ 0,0,2145,54938,65535,61309,8452,0,
+ 21162,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,59164,48631,35921,
+ 29582,29582,38066,50712,59164,65535,65535,65535,
+ 63422,44405,12678,32,0,4258,54938,65535,
+ 35953,0,4226,54970,65535,63390,12678,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,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,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,0,0,0,0,
+ 0,0,4258,61277,65535,59196,4258,0,
+ 31727,63390,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,54970,23275,4258,0,32,
+ 0,0,32,32,6371,27469,54938,65535,
+ 65535,65503,61277,31727,10565,42260,65535,65535,
+ 29582,0,6371,61277,65535,59196,4258,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,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,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,0,0,0,0,
+ 0,32,8452,63390,65535,59164,2145,0,
+ 21130,48599,59164,63422,65535,65535,65535,65535,
+ 65535,65503,65535,52825,40179,33808,23275,14791,
+ 10565,6339,2113,0,0,0,4226,35953,
+ 65535,65535,65535,65535,63390,65535,65535,65535,
+ 23275,0,8484,63422,65535,57083,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,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,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,0,0,0,0,0,
+ 0,0,10565,65503,65535,52825,32,0,
+ 32,32,6339,12710,31695,46486,59196,63422,
+ 65503,65535,65535,65535,65535,65535,65535,65535,
+ 63422,59196,54970,48599,40147,29582,19017,14823,
+ 59196,65535,65535,65503,65535,65535,65535,65503,
+ 16936,0,14791,65535,65535,46486,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,12678,65535,65535,50744,32,0,
+ 32,0,0,32,0,0,4226,12678,
+ 25356,38066,50744,59196,65503,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65503,
+ 65503,65535,65535,65535,65535,65535,65535,63390,
+ 10565,32,23275,65535,65535,38066,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,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,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,0,0,0,0,0,
+ 0,0,14823,65535,65535,48631,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,4258,12710,23275,38066,48631,
+ 57083,63390,65503,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,63390,42292,
+ 32,0,31727,65535,65535,25388,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,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,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,0,0,0,0,0,
+ 0,0,16936,65535,65535,46518,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 4226,8484,16936,29582,42292,52857,61309,63422,
+ 65503,65503,65535,65535,65503,59164,31727,2145,
+ 0,32,38066,65535,65535,16936,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,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,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,0,0,0,0,0,
+ 0,0,16936,65535,65535,46486,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4258,12678,
+ 21130,27501,29614,25388,16904,2145,0,2113,
+ 0,0,48599,65535,63390,8484,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,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,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,0,0,0,0,0,
+ 0,0,16936,65535,65535,44373,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,32,0,
+ 0,32,50712,65535,61277,6371,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,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,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,0,0,0,0,0,
+ 0,0,16936,65535,65535,42260,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,32,0,
+ 0,2145,52857,65535,57083,2145,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,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,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,0,0,0,0,0,
+ 0,0,16936,65535,65535,40179,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,32,
+ 0,0,0,32,0,0,0,0,
+ 0,4226,57051,65535,54970,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,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,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,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,12710,65535,65535,42260,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,4258,59196,65503,48599,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,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,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,0,0,0,0,0,0,
+ 0,0,10597,65503,65535,42260,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,6371,61277,65535,48599,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,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,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,0,0,0,0,0,0,
+ 0,0,8484,63422,65535,42260,32,0,
+ 0,0,0,0,0,0,0,0,
+ 29582,27501,14791,6339,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,8452,63390,65535,48599,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,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,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,0,0,0,0,0,0,
+ 0,0,6371,63390,65535,42260,32,0,
+ 0,0,0,0,0,0,0,0,
+ 21162,59196,65535,61277,52825,42260,31695,29582,
+ 21162,19017,14791,12678,8484,6339,2145,2145,
+ 2145,2113,32,32,0,0,0,0,
+ 32,10565,63422,65535,48599,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,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,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,0,0,0,0,0,0,
+ 0,0,4226,59196,65535,44373,32,0,
+ 0,0,0,0,0,0,0,0,
+ 32,12710,52857,65503,65535,65535,65535,65535,
+ 65535,65535,65503,65503,65535,65503,65503,61277,
+ 59164,54970,54938,46518,16936,0,0,32,
+ 0,12678,65535,65535,46518,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,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,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,0,0,0,0,0,0,
+ 0,0,2145,54970,65535,44373,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,4258,50744,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 63422,63390,54970,42292,14823,0,0,0,
+ 0,14791,65535,65535,46518,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,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,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,0,0,0,0,0,0,
+ 0,0,32,48631,65535,42292,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,21130,54970,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65503,59164,
+ 29582,10597,2113,32,0,0,0,32,
+ 0,19017,65535,65535,46518,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,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,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,0,0,0,0,0,0,
+ 0,32,0,44405,65535,42292,0,0,
+ 0,0,0,0,0,0,0,0,
+ 16904,46518,65503,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65503,
+ 38066,8452,0,0,0,0,0,0,
+ 0,21162,65535,65503,46518,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,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,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,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,42292,65535,42292,0,0,
+ 0,0,0,0,0,0,32,2145,
+ 52857,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,57051,21130,0,0,0,0,0,
+ 0,23275,65535,65535,44405,32,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,42292,65535,42292,0,0,
+ 0,0,0,0,0,0,0,32,
+ 6339,31695,38066,40179,40147,40179,42292,44373,
+ 46486,46518,48631,50744,54938,57051,59164,59196,
+ 65503,65535,61309,35953,0,0,0,0,
+ 0,25388,65535,65535,44405,32,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,42292,65535,42292,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,32,
+ 0,0,32,32,32,2113,2113,2113,
+ 2113,4258,8452,6339,0,0,0,0,
+ 0,27501,65535,65535,44373,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,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,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,0,0,0,0,0,0,
+ 0,0,0,42292,65535,42292,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,0,0,0,2113,4226,6339,
+ 6339,6371,6371,6371,6371,6371,8452,6371,
+ 4258,0,0,0,0,0,0,0,
+ 0,29614,65535,65535,44373,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,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,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,0,0,0,0,0,0,
+ 0,0,32,46518,65535,40179,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2113,44373,61277,
+ 63390,61309,61277,61309,61309,61277,63390,54970,
+ 16904,0,0,0,0,0,0,0,
+ 0,33808,65535,65535,42292,2113,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,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,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,0,0,0,0,0,
+ 0,0,32,52825,65535,38034,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4258,23243,
+ 38066,48599,54938,54970,57051,48631,31727,6371,
+ 0,0,0,0,0,0,0,0,
+ 0,33840,65535,65535,42260,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,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,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,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,6339,61277,65535,33840,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,2113,2113,32,0,0,0,
+ 0,0,0,32,0,0,0,0,
+ 0,38034,65535,65535,40147,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,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,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,0,0,0,0,0,0,
+ 32,32,12710,65503,65535,31695,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,0,0,0,0,0,
+ 0,38066,65535,65503,38066,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,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,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,0,0,0,0,0,0,
+ 32,0,31695,65535,65535,27469,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,42260,65535,65535,38066,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,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,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,0,0,0,0,0,0,
+ 0,2113,52825,65535,65535,19049,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,44373,65535,65535,38034,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,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,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,0,0,0,0,0,0,
+ 0,10597,65535,65535,63390,10565,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,46486,65535,65535,33840,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,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,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,0,0,0,0,0,0,
+ 0,33840,65535,65535,61277,4226,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,48599,65535,65535,31727,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,
+ 2145,52857,65535,65535,50744,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,
+ 32,50744,65535,65535,27501,32,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,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,
+ 10565,63422,65535,65535,35921,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,
+ 32,52825,65535,65535,25356,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,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,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,0,0,0,0,0,0,
+ 29582,65535,65535,65535,19049,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,
+ 2113,54938,65535,65503,19017,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,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,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,0,0,0,0,0,0,
+ 44373,65535,65535,63390,10565,0,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 2113,57051,65535,65503,14823,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,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,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,0,0,32,0,0,4258,
+ 57083,65535,65535,59164,2113,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,
+ 2145,59196,65535,63390,6371,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,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,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,0,0,0,0,0,12678,
+ 63422,65535,65535,46486,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,
+ 4226,59196,65535,61277,4226,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,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,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,0,0,0,0,0,23275,
+ 65535,65535,65535,31695,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,
+ 6339,61309,65535,54938,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,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,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,0,0,0,0,0,32,38066,
+ 65535,65535,65503,19049,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,
+ 8484,63390,65535,48631,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,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,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,0,0,0,32,0,2113,52857,
+ 65503,65535,63390,8452,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,
+ 10565,65503,65535,40179,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,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,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,0,0,0,0,0,4258,61309,
+ 65535,65535,57083,4226,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,
+ 14791,65535,65535,27501,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,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,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,0,0,0,0,0,16936,65535,
+ 65535,65535,46518,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,
+ 21162,65535,65535,16936,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,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,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,0,0,0,0,0,29582,65535,
+ 65535,65535,35953,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,
+ 33808,65535,63422,12678,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,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,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,
+ 2113,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2113,46486,65535,
+ 65535,65535,25356,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,32,0,0,0,
+ 42292,65535,61277,6371,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,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,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,0,0,0,0,2145,52857,65535,
+ 65535,65535,16936,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,32,0,0,2113,
+ 50744,65535,59164,2113,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,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,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,4226,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,6339,61277,65535,
+ 65535,63390,8484,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,4258,
+ 57083,65535,54970,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,8452,57051,42292,14823,6371,
+ 4258,2145,0,0,0,0,0,0,
+ 0,0,0,0,0,8484,63422,65535,
+ 65535,61277,6339,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,6371,
+ 61309,65535,52825,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,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,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,33808,65535,65535,65535,61309,
+ 61277,59164,14823,0,0,0,0,0,
+ 0,0,0,0,0,19049,65535,65535,
+ 65535,57083,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,12678,
+ 65535,65535,44373,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,6371,59164,65535,65535,65535,65535,
+ 65535,65535,59196,10565,0,0,0,32,
+ 0,0,0,0,0,27469,65535,65535,
+ 65535,52825,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,21130,
+ 65535,65535,42292,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,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,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,32,38066,65535,65535,65535,65535,59196,
+ 54938,65503,65535,52857,6371,0,0,0,
+ 0,0,0,0,0,38034,65535,65535,
+ 65535,44373,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,33808,
+ 65535,65535,40179,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,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,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,27501,65503,65535,65503,65535,54938,10565,
+ 6339,54938,65535,65535,46518,4226,0,0,
+ 0,0,0,0,0,44405,65535,65535,
+ 65535,38066,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,42260,
+ 65535,65535,38066,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,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,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,32,0,0,0,2145,
+ 29614,63390,65535,65535,65535,65503,25356,32,
+ 0,21130,65535,65535,65503,35921,0,0,
+ 0,0,0,0,32,50712,65535,65535,
+ 65535,25388,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,32,50712,
+ 65535,65535,38034,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,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,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,8484,44405,
+ 65535,61277,57083,65503,65535,61309,6371,0,
+ 0,8452,63390,65535,65535,63390,16904,0,
+ 0,0,0,0,2113,54970,65535,65535,
+ 65535,21162,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,2113,52857,
+ 65535,65535,35953,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,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,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,32,32,31695,61277,65503,
+ 44373,6371,10597,65503,65535,46486,32,0,
+ 0,32,59164,65535,65535,65535,48599,2145,
+ 0,0,0,0,4258,61277,65535,65535,
+ 63422,14791,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,4226,59164,
+ 65535,65535,33840,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,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,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,
+ 32,0,32,4258,44405,65535,65503,40147,
+ 2145,32,27469,65535,65503,19049,0,0,
+ 0,0,50712,65535,65535,65503,63422,12710,
+ 0,0,0,0,8452,63390,65535,65535,
+ 63390,10565,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,4258,61309,
+ 65535,65535,31727,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,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,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,4258,48631,65535,65535,38066,32,
+ 32,10597,61309,65535,46518,32,0,32,
+ 0,32,38066,65535,65535,65535,65535,33808,
+ 32,0,0,0,12710,65535,65535,65535,
+ 61277,8484,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,6371,63390,
+ 65535,65535,31695,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,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,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,2113,44405,65535,65503,44405,32,0,
+ 32,46486,65535,61277,10565,0,32,0,
+ 0,0,31695,65535,65535,65535,65535,50744,
+ 32,0,0,0,19017,65535,65535,65535,
+ 59196,4226,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,6371,61309,
+ 65535,65535,31695,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,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,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,
+ 32,29582,65535,65535,54970,6371,0,0,
+ 16904,63422,65503,27469,0,0,0,0,
+ 0,0,27469,65535,65535,65535,65535,61277,
+ 6339,0,0,0,23275,65535,65535,65535,
+ 54970,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,6339,61277,
+ 65535,65535,31695,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,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,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,
+ 10597,63390,65535,63390,14823,0,32,6339,
+ 54970,65535,44373,32,0,32,0,0,
+ 0,0,27469,65535,65535,65535,65535,65535,
+ 14791,32,0,0,27501,65535,65535,65535,
+ 50712,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,2145,4226,8452,10565,8484,4258,
+ 2145,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4258,59196,
+ 65535,65535,29614,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,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,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,2113,
+ 46518,65535,65535,42260,32,0,8452,48599,
+ 65535,52857,4258,0,0,0,0,32,
+ 32,0,42260,65535,65535,65535,65535,65535,
+ 31727,0,0,0,35953,65535,65535,65535,
+ 42292,32,0,0,0,0,0,0,
+ 0,0,0,0,0,32,32,6371,
+ 27469,44373,54970,63390,63422,65503,65503,63422,
+ 59164,50744,40179,29582,8452,32,0,0,
+ 0,0,0,0,0,0,4226,57083,
+ 65535,65535,29582,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,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,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,32,32,21162,
+ 63422,65535,61277,10565,0,12678,52857,65535,
+ 61277,14791,0,0,0,0,0,0,
+ 2113,21162,63422,65535,65535,65535,65535,65535,
+ 46518,32,0,0,42292,65535,65535,65535,
+ 38034,0,0,0,0,0,0,0,
+ 0,0,0,32,0,6339,38034,61309,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,63390,40147,8484,0,
+ 0,0,0,0,0,0,2113,54970,
+ 65535,65535,29582,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,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,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,32,0,2145,54970,
+ 65535,65535,31695,0,19049,59196,65535,63390,
+ 21162,32,0,0,0,0,4258,21162,
+ 44405,63390,65535,65535,65535,65535,65535,65535,
+ 54938,2145,0,32,50744,65535,65535,65535,
+ 29582,0,0,0,0,0,0,0,
+ 0,0,32,32,21162,59164,65503,65535,
+ 65535,63390,61309,59164,52857,54970,57083,57083,
+ 63390,65503,65503,65503,65535,65535,59164,14823,
+ 0,0,0,0,0,0,32,52857,
+ 65535,65535,29582,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,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,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,31695,65535,
+ 65535,61309,23275,33840,63422,65535,61309,23275,
+ 32,0,0,0,8484,38066,61277,65503,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 61309,10565,32,2145,57051,65535,65535,65535,
+ 23275,0,32,0,0,0,0,0,
+ 0,32,32,27501,61277,52825,35953,25356,
+ 16904,6371,2113,2113,2113,2113,32,0,
+ 6339,12710,23275,35921,52825,63422,65503,61277,
+ 12710,0,0,0,32,0,0,50744,
+ 65535,65535,29582,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,0,0,0,32,10565,63390,65503,
+ 65535,65535,65535,65535,65535,59164,16936,0,
+ 0,0,4258,29582,61309,65503,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,23275,0,4258,61277,65535,65535,65503,
+ 19017,0,32,0,0,0,0,0,
+ 0,0,6371,21162,4258,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,8484,33808,52857,
+ 44405,2113,0,0,0,0,32,48631,
+ 65535,65535,35921,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,0,0,0,2113,46486,65535,65535,
+ 65535,65535,65535,65535,50744,10565,0,0,
+ 0,21162,54970,65503,65503,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,48599,2145,21162,63422,65535,65535,65535,
+ 14791,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,32,32,
+ 16936,4258,32,32,0,0,0,48631,
+ 65535,65535,42260,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,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,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,
+ 32,0,0,2113,19049,63422,65535,65535,
+ 65535,65535,65535,46486,4226,0,32,12710,
+ 46518,65503,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65503,42260,61277,65535,65535,65535,63422,
+ 8452,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,32,0,0,0,0,48631,
+ 65535,65535,50744,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,0,32,4258,57051,65535,65535,65503,
+ 65535,65535,65535,16904,32,10565,40147,65535,
+ 65535,65503,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65503,65535,65535,65503,65535,65535,61277,
+ 6371,0,0,32,0,0,0,0,
+ 0,0,0,0,32,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,0,0,0,0,48631,
+ 65503,65535,59196,2145,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,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,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,33808,65535,65535,65535,65535,
+ 65535,65535,65535,44405,40179,61277,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,57051,
+ 2145,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,50744,
+ 65535,65535,65503,16936,32,0,0,0,
+ 0,0,0,32,0,0,0,0,
+ 0,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,10565,61277,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65503,65503,52857,38066,27469,21130,14791,
+ 12678,16904,23243,29582,42260,54970,65503,65535,
+ 65535,65535,65535,65535,65535,65535,65535,52825,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,52825,
+ 65535,65535,65535,40147,32,0,0,0,
+ 0,32,16936,35921,38034,31695,21130,10565,
+ 2145,32,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,2113,44405,65535,65535,65535,65535,65535,
+ 65535,65535,65503,65535,65535,65535,65535,65535,
+ 61309,42292,14791,4258,8452,6339,2113,0,
+ 32,0,0,0,0,32,16904,42292,
+ 63422,65535,65535,65535,65535,65535,65535,46486,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2113,2113,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,2113,52857,
+ 65535,65535,65535,59164,10565,8484,12710,19049,
+ 27469,40179,65535,65535,65535,65535,65535,63422,
+ 59196,46486,29614,16936,8484,4226,32,2113,
+ 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,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,21130,65503,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65503,48631,
+ 12710,2145,25388,57051,63422,61309,52857,38034,
+ 19017,4258,0,32,0,0,0,2113,
+ 10597,46518,65535,65535,65535,65535,65535,42292,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,29614,54970,50744,46486,
+ 38034,35921,31727,29614,27501,27469,23275,23243,
+ 19049,16904,10565,6371,0,0,0,0,
+ 0,0,0,0,0,0,2145,54938,
+ 65535,65535,65535,65535,63390,63422,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65503,65535,65535,63390,61277,54938,48599,
+ 33808,19017,2145,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,
+ 4258,54970,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,63422,65535,63390,33808,32,
+ 32,8452,46518,57051,63390,65535,65535,65503,
+ 65535,61277,42292,23243,4258,32,0,32,
+ 0,4258,46486,65535,65535,65535,65535,35953,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,2113,8452,16936,23275,
+ 29614,33840,42260,46486,50744,54938,59164,61309,
+ 63422,63422,63390,63390,54970,42260,23275,10597,
+ 32,0,0,0,0,0,4226,59164,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65503,65535,65535,
+ 65535,65503,57083,31727,8452,32,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,
+ 35921,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,61309,19049,32,0,
+ 0,0,2145,12678,59196,65535,65535,65535,
+ 65535,65535,65535,65503,54970,16904,0,0,
+ 0,0,8452,57083,65535,65535,65535,29614,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,32,32,2113,2145,4258,
+ 10597,16904,25356,29614,40147,44373,50712,54938,
+ 38034,2113,0,0,0,0,6339,59196,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,63422,61277,59164,61277,
+ 61277,63422,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,61277,25388,32,0,
+ 32,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,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,
+ 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,12678,
+ 61309,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,59196,14823,0,32,0,
+ 0,14791,40147,61277,65535,65535,65535,65535,
+ 65535,65535,65535,52857,16936,2113,32,0,
+ 32,0,0,27501,65535,65535,65535,23275,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,32,
+ 0,0,0,0,0,0,32,2145,
+ 4226,0,0,0,0,0,8452,61309,
+ 65535,65535,65535,65535,65535,65535,65535,63390,
+ 50712,38034,21130,16904,16904,16904,12678,6371,
+ 4258,10565,19017,31695,44405,59164,65503,65535,
+ 65535,65535,65535,65535,65535,63422,44373,4258,
+ 0,32,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,2113,48631,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,63390,16936,0,0,0,4258,
+ 42292,63422,65535,65503,65535,65535,65503,65535,
+ 65535,65535,65535,65503,63390,50712,25388,4258,
+ 0,0,32,8484,63390,65535,65535,21162,
+ 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,32,32,32,0,0,8484,63390,
+ 65535,65535,65535,65535,65535,59196,33840,8452,
+ 2113,2145,42292,61277,63422,65503,63390,61309,
+ 54938,38034,23275,10565,2113,2145,12678,33808,
+ 48599,61277,65535,65535,65535,65535,65535,50744,
+ 8484,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,32,27501,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,63390,21130,0,0,0,0,35953,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,54938,
+ 6371,0,0,2113,48631,65535,65535,16936,
+ 0,0,0,0,0,0,0,0,
+ 0,32,0,0,0,0,32,0,
+ 0,32,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,10597,65503,
+ 65535,65535,65535,65535,61309,16904,32,0,
+ 0,0,14823,54938,65535,65535,65535,65535,
+ 65503,65503,65503,65503,52857,27501,6371,32,
+ 0,6371,35953,61309,65535,65535,65535,65535,
+ 52857,6371,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,8484,61277,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,31695,0,0,32,0,0,19049,
+ 25356,25356,25356,25356,25356,25356,25356,23275,
+ 23275,23275,23275,25356,23275,23243,23275,23275,
+ 10597,0,0,0,38066,65535,65535,16904,
+ 0,0,0,0,0,0,0,0,
+ 6339,42292,35921,14791,2145,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,14791,65503,
+ 65535,65535,65535,65535,31695,0,0,0,
+ 0,0,0,4226,19017,42292,61309,65535,
+ 65535,65535,65535,65535,65535,65535,61309,46486,
+ 23243,4226,0,8452,44373,65503,65535,65535,
+ 65535,52857,8452,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,2113,42292,65535,65535,
+ 65535,65535,65535,65503,65535,65535,65535,65535,
+ 46518,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,0,
+ 0,0,0,32,0,0,0,0,
+ 0,0,0,0,25356,65535,65535,14791,
+ 0,0,0,0,0,0,0,0,
+ 0,31695,65503,63422,59164,38034,16936,6339,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,16936,65535,
+ 65535,65535,65535,59164,4226,0,0,32,
+ 0,32,2145,6371,8452,14791,33808,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65503,61277,35921,12710,2145,23243,61277,65535,
+ 65535,65535,50744,4258,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,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,21130,65535,65535,65535,
+ 65535,65535,61277,31727,65535,65535,65535,65535,
+ 12678,0,0,0,0,0,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,0,
+ 32,0,0,0,14791,65535,65535,12710,
+ 0,0,0,0,0,0,0,0,
+ 0,32,33808,65503,65535,65535,65503,61277,
+ 42292,19049,4226,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,19049,65535,
+ 65535,65535,65535,38066,0,0,0,0,
+ 10597,33808,50744,59196,63422,63422,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,63422,
+ 61277,63390,63390,61309,21130,0,16904,59164,
+ 65535,65535,63422,44373,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,6371,57083,65503,65535,65535,
+ 65535,63422,27469,19017,65535,65503,65535,42260,
+ 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,6339,63390,65503,12678,
+ 0,0,0,0,0,0,0,0,
+ 0,0,2113,35921,65503,65535,65535,65535,
+ 65535,65503,59164,48599,27501,12710,4258,0,
+ 0,0,0,0,0,32,0,0,
+ 0,4226,10565,32,0,0,23243,65535,
+ 65535,65535,63422,16936,0,0,0,0,
+ 0,0,2145,10565,19049,33808,48599,54970,
+ 63422,65535,65535,65535,65535,65535,65535,65503,
+ 40179,12678,6371,8452,2145,0,32,14823,
+ 57083,65535,65535,63422,21130,0,0,0,
+ 0,0,0,0,0,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,40179,65535,65535,65535,65535,
+ 65535,44405,2113,21162,65535,65535,63422,12710,
+ 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,2113,57051,65503,10597,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,2113,27501,61277,65535,65535,
+ 65535,65535,65535,65503,65535,65503,59196,48631,
+ 38034,31695,27469,27501,29582,29582,31695,31727,
+ 44373,44373,8452,0,0,0,23275,65535,
+ 65535,65535,59196,4226,0,0,0,0,
+ 0,0,0,0,32,0,32,2145,
+ 8452,23243,40147,48599,57083,63422,65535,65535,
+ 65535,61277,33808,10597,0,0,0,0,
+ 14791,57083,65535,65535,50744,32,0,0,
+ 0,32,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,23243,65535,65535,65535,65535,65535,
+ 54970,8452,0,27501,65503,65535,50744,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,50744,63422,10565,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,12678,50744,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65503,65535,63422,
+ 33840,4226,0,0,0,0,25356,65535,
+ 65535,65535,44373,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,32,4226,12678,25356,38066,
+ 52825,63390,65503,63390,33840,32,0,0,
+ 0,10565,54938,65535,65503,16904,0,0,
+ 2113,19017,35921,38066,29582,10597,32,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,10565,59196,65535,65535,65503,65535,63422,
+ 16936,0,0,35921,65535,65535,29614,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,32,48599,65503,8484,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,2145,27469,
+ 54938,65503,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,61277,42260,10597,
+ 32,0,0,0,0,0,25388,65535,
+ 65535,65535,27469,0,0,0,0,0,
+ 0,0,0,32,0,0,0,0,
+ 0,0,0,0,32,0,32,0,
+ 2113,6339,14823,27501,42260,19049,32,0,
+ 0,0,8452,52857,65535,44405,32,8452,
+ 46486,63422,65535,65535,65535,61277,44405,14823,
+ 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,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,
+ 4258,50712,65535,65535,65503,65535,65503,27501,
+ 0,0,0,44373,65535,63390,12678,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,32,46486,63422,10565,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 2145,19017,44373,57083,63390,65503,65535,65503,
+ 65535,65503,59164,50744,27501,6371,32,0,
+ 0,0,0,0,0,0,23243,65535,
+ 65535,65535,19049,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,8484,57083,63390,14823,52825,
+ 65535,65535,65535,65535,65535,65535,65503,63422,
+ 44405,10565,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,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,32,0,0,32,
+ 33840,65535,65535,65535,65535,65535,42260,32,
+ 0,32,32,50744,65503,61309,2145,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,48599,63390,8452,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,2145,8452,14823,21162,21162,
+ 16936,10597,4226,32,0,0,0,0,
+ 0,0,0,0,0,0,19049,65535,
+ 65535,65535,16936,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,19049,63422,61277,65535,
+ 65535,65535,65535,63422,61277,63422,65535,65535,
+ 65535,61277,33840,2113,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,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,32,19049,
+ 63390,65535,65535,65535,65535,52825,4258,0,
+ 0,32,4226,59196,65535,48599,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,32,52857,63390,6371,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 32,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,32,0,
+ 0,0,0,0,0,0,14823,65535,
+ 65535,65503,14791,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,32,32,32,50744,65535,65535,
+ 65535,65535,57083,19049,4226,8452,23275,50744,
+ 65535,65535,65503,52857,16936,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,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,10565,59164,
+ 65535,65535,65535,65535,59196,10597,0,0,
+ 0,0,8452,65503,65535,35953,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,2145,57051,63422,6371,
+ 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,12678,65535,
+ 65535,65503,12678,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,33840,65535,65535,
+ 65535,57083,10597,0,0,32,0,2113,
+ 25356,59196,65535,65535,63390,33840,4226,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,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,
+ 32,0,0,0,0,2113,48599,65535,
+ 65535,65535,65535,63390,21130,0,32,0,
+ 0,0,21130,65535,65535,27501,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,4258,61277,63390,6371,
+ 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,8484,63390,
+ 65535,63422,10597,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,19049,65535,65535,
+ 65503,16936,2145,16936,29614,29614,21162,10565,
+ 2145,10597,52825,65535,65535,65535,54938,14823,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 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,33840,65503,65535,
+ 65535,65535,65535,33808,2113,0,0,0,
+ 0,0,31695,65503,65535,23243,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,10565,63422,61309,6339,
+ 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,8452,61309,
+ 65535,63390,10565,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,14823,63422,65535,
+ 48631,32,29614,59164,65535,65535,65535,65503,
+ 52857,33840,23243,61309,65535,63422,65535,63390,
+ 31695,2145,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,0,0,19049,65503,65535,65535,
+ 65535,65503,46486,2113,0,0,0,0,
+ 0,0,42292,65503,63422,16904,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,16936,65535,61309,6339,
+ 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,6371,61277,
+ 65535,61309,8484,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,8484,61309,65535,
+ 33808,0,0,6371,31695,54938,65535,65535,
+ 65535,65535,65503,63422,65535,65535,65535,65535,
+ 65535,48599,8484,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,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,6371,59164,65535,65535,65535,
+ 65535,57083,6371,0,0,0,0,0,
+ 0,2145,48631,65535,63390,12678,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,25356,63422,61309,6371,
+ 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,6339,59196,
+ 65535,61277,8452,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,32,4226,59196,65535,
+ 21130,0,32,32,0,2113,21130,44405,
+ 61309,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,59164,21162,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,2113,44373,65535,65535,65535,65535,
+ 61277,16936,0,0,0,0,0,0,
+ 0,2113,54970,65535,63390,6339,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,33840,65535,61277,6339,
+ 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,32,6339,61277,
+ 65535,61309,8452,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,2145,59164,65503,
+ 10565,0,0,0,0,0,0,32,
+ 8484,31727,57051,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65503,33808,2113,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,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,27469,63390,65503,65535,65535,65535,
+ 31695,0,0,0,0,0,0,0,
+ 0,4258,59196,65535,61277,2145,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,40179,65535,61277,4258,
+ 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,6371,61309,
+ 65535,61277,6371,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,2145,59164,61309,
+ 6339,0,0,0,0,0,0,32,
+ 4258,4226,8484,42292,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65503,42260,2145,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,
+ 32,10597,61277,65535,65535,65535,65503,46486,
+ 2113,0,0,0,0,0,0,0,
+ 0,8452,63390,65535,52857,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,46518,65535,61277,4226,
+ 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,8484,63390,
+ 65535,59196,6339,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,2145,59164,57051,
+ 2145,0,32,0,32,0,32,4258,
+ 50744,61309,61309,63422,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,40147,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 2113,46486,65535,65535,65535,65535,59164,8484,
+ 0,0,32,0,0,0,0,0,
+ 0,23243,65503,65535,48599,2113,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,50744,65535,61309,6339,
+ 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,10565,63422,
+ 65535,59164,4258,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,2145,59164,52857,
+ 32,0,0,0,0,0,0,0,
+ 12678,52825,63422,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,63390,23243,
+ 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,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 23275,65535,65535,65535,65535,65503,21162,0,
+ 0,0,0,0,0,0,0,2113,
+ 12678,54970,65535,65535,42260,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,2113,52857,65535,61277,4258,
+ 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,12678,63422,
+ 65535,59164,4258,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,4258,59196,48599,
+ 0,0,0,0,0,0,0,0,
+ 0,2113,16904,29582,44373,54970,63390,65535,
+ 65535,65535,65535,65535,65535,65535,65535,57083,
+ 2113,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,4258,
+ 57083,65535,65535,65535,65535,44373,32,0,
+ 0,0,0,0,0,0,0,31727,
+ 65503,65535,65535,65535,33840,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,2113,52857,65535,61277,4258,
+ 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,12710,65503,
+ 65535,57083,4226,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,6339,61277,46486,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,0,0,32,10565,31727,
+ 54938,65503,65503,65535,65535,65535,65535,65503,
+ 21162,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,29582,
+ 65535,65535,65535,65535,63390,12678,0,0,
+ 0,0,0,0,0,0,0,12678,
+ 63422,65535,65535,65535,25388,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,2113,52857,65535,61277,4258,
+ 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,16904,65535,
+ 65535,57051,2145,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,8452,61309,44405,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,0,
+ 2145,25388,57083,65535,65535,65535,65535,65535,
+ 38066,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,2145,54970,
+ 65535,65535,65535,65535,42292,0,32,0,
+ 0,0,0,0,0,0,0,32,
+ 50712,65535,65535,65503,19049,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,2113,52857,65535,61277,4258,
+ 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,19017,65535,
+ 65535,54970,2113,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,8484,63390,44405,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 32,0,6371,48599,65503,65535,65535,65535,
+ 50744,32,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,19017,65535,
+ 65535,65535,65535,63422,14791,32,0,0,
+ 0,0,0,0,2113,19049,10565,2113,
+ 31695,65535,65535,65535,12678,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,2113,52857,65535,61277,2145,
+ 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,23243,65535,
+ 65535,54970,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,12678,63390,50712,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,2113,48599,65535,65535,65535,
+ 57083,2113,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,32,32,42292,65535,
+ 65535,65535,65535,57051,2145,0,0,0,
+ 0,0,0,0,4258,59196,63390,54970,
+ 50744,65535,65535,63390,6371,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,32,50744,65535,59196,2145,
+ 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,25356,65535,
+ 65535,52857,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,14791,65535,52857,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,8452,54938,65535,65535,
+ 61277,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,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,2113,59196,65535,
+ 65503,65535,65535,44373,32,0,0,0,
+ 0,0,0,0,32,44405,65535,65535,
+ 65503,65535,65535,59196,2145,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,32,48599,65535,59164,2145,
+ 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,29582,65535,
+ 65535,50744,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,19049,65535,54970,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,19049,65503,65535,
+ 65503,6339,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,12710,63390,65535,
+ 65535,65535,65535,33840,0,0,0,0,
+ 0,0,0,0,0,16936,65503,65535,
+ 65535,65535,65535,59164,2145,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,32,46518,65535,59164,2145,
+ 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,31727,65535,
+ 65535,50744,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,32,25356,65503,57051,
+ 2113,32,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,48599,65535,
+ 65535,10597,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,19049,65535,65535,
+ 65535,65535,65535,27469,0,0,0,0,
+ 0,0,0,0,0,2145,54938,65535,
+ 65535,65535,65535,54938,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,46486,65535,59164,2145,
+ 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,33840,65535,
+ 65535,48599,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,29614,65535,57051,
+ 2113,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,23275,65503,
+ 65503,16904,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,25356,65535,65535,
+ 65535,65535,65535,23275,0,0,0,0,
+ 0,0,0,0,0,0,27501,65503,
+ 65535,65535,65535,48631,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,44373,65535,59164,2113,
+ 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,38034,65535,
+ 65535,46486,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,35921,65535,57051,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,8452,63390,
+ 65535,21162,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,27469,65535,65535,
+ 65535,65535,65535,25388,0,0,0,0,
+ 0,0,0,0,0,0,6339,59164,
+ 65535,65535,65535,42260,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,42260,65535,59164,2113,
+ 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,42260,65535,
+ 65535,44405,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,42260,65535,54970,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,2113,54970,
+ 65535,29582,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,25356,65535,65535,
+ 65535,65535,65535,31695,0,0,0,0,
+ 0,0,0,0,0,0,0,44373,
+ 65535,65535,65535,38034,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,40179,65535,59164,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,44405,65535,
+ 65535,44373,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,44373,65535,52857,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,44373,
+ 65535,33840,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,16936,65535,65535,
+ 65535,65535,65535,44405,32,0,0,0,
+ 0,0,0,0,0,0,0,21162,
+ 65503,65535,65535,29582,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,38066,65535,57083,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,46518,65535,
+ 65535,40147,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,50712,65535,50744,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,35953,
+ 65535,40147,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,10597,63422,65535,
+ 65535,65535,65535,54938,2145,0,0,32,
+ 0,0,0,0,0,32,0,8484,
+ 65535,65535,65503,21162,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,38066,65535,57083,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,50712,65535,
+ 65535,38066,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,52857,65535,46518,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,29614,
+ 65535,44373,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,0,0,0,0,0,0,0,
+ 0,0,0,0,32,4258,57051,65535,
+ 65535,65535,65535,65503,10565,0,32,0,
+ 0,0,0,0,0,0,0,4258,
+ 61277,65535,63422,16904,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,38066,65535,57083,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2113,54938,65535,
+ 65535,35953,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,2113,57083,65535,40179,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,27469,
+ 65535,50712,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,32,0,33840,65535,
+ 65535,65535,65535,65535,33808,0,0,0,
+ 0,0,0,0,0,0,0,2145,
+ 59164,65535,63390,10597,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,38066,65535,57083,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2113,57083,65535,
+ 65535,35921,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,4258,61277,65535,33840,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,27501,
+ 65535,54938,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,10597,61309,
+ 65535,65535,65535,65535,57083,2145,0,0,
+ 0,0,0,0,0,0,0,32,
+ 57051,65535,63390,4226,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,38034,65535,57051,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,4258,61309,65535,
+ 65503,33808,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,6339,61309,65535,27501,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,29582,
+ 65535,57083,2145,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,42260,
+ 65535,65535,65535,65503,65535,25356,0,0,
+ 0,0,0,0,0,0,0,2145,
+ 59164,65535,59164,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,38034,65535,57051,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,6339,61309,65535,
+ 65535,31695,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,10565,65503,65535,19049,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,35953,
+ 65535,61277,4226,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,10565,
+ 61277,65535,65535,65535,65535,54938,2145,0,
+ 0,0,0,0,0,0,0,4226,
+ 61309,65535,48599,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,38034,65535,57051,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,8452,63390,65535,
+ 65535,29614,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,14791,65503,65503,12678,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,46518,
+ 65535,63390,6339,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,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,32,
+ 27501,65535,65535,65535,65535,65535,27501,0,
+ 0,0,0,0,0,0,0,6339,
+ 65503,65535,40147,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,38034,65535,57051,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,8484,63390,65535,
+ 65535,29582,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,21162,65535,63390,6339,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,54938,
+ 65535,63390,8484,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 2113,46486,65535,65535,65535,65535,59196,8484,
+ 0,0,0,0,0,0,0,14823,
+ 65535,65535,29582,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,38034,65535,54970,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,8484,63422,65535,
+ 65535,27469,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,25388,65535,57083,2113,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4226,61309,
+ 65535,63422,10597,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,6371,57083,65535,65535,65535,65535,46486,
+ 2145,0,0,0,0,0,32,29582,
+ 65535,65535,21130,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,38034,65535,54970,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,8484,63422,65535,
+ 65535,25388,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,29614,65535,54938,2113,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,6371,63390,
+ 65535,65503,14791,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,19049,63422,65535,65535,65535,65535,
+ 27501,0,0,0,32,0,0,40179,
+ 65535,63390,10597,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,35953,65535,54970,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,8484,63422,65535,
+ 65535,23275,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,35921,65535,48631,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,12678,65503,
+ 65535,65503,19049,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,35953,63422,65535,65535,65535,
+ 61309,12678,0,0,0,0,32,50744,
+ 65535,61277,6339,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,35953,65535,54970,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,8484,63422,65535,
+ 65535,23243,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,40147,65535,46486,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,16904,65535,
+ 65535,65503,23243,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,4226,52825,65535,65535,65535,
+ 65535,50712,4258,0,0,0,4258,59164,
+ 65535,52857,32,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,35921,65535,54970,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,6339,63390,65535,
+ 65535,21162,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,44405,65535,42292,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,19049,65535,
+ 65535,65535,29582,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,32,12678,61277,65535,65535,
+ 65535,65535,40147,2113,32,0,21130,65535,
+ 65535,44405,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,35953,65535,54938,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,4258,61309,65535,
+ 65535,19049,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,48599,65535,42292,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,19049,65535,
+ 65535,65535,31727,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,31695,63422,65535,
+ 65535,65535,65503,42292,16936,16904,54970,65535,
+ 65535,33840,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,38066,65535,52857,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,4226,61277,65535,
+ 65535,16936,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,50744,65535,42292,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,19049,65535,
+ 65535,65535,35953,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,4226,52825,65535,
+ 65535,65535,65535,65535,65535,65503,65535,65535,
+ 65535,27469,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,38066,65535,52857,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,2145,59196,65535,
+ 65503,16904,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,54938,65535,44373,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,19049,65535,
+ 65535,65535,40179,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,16936,63422,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,16936,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,38066,65535,52857,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,32,57083,65535,
+ 65503,14791,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,2113,57083,65535,44373,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,16904,65535,
+ 65535,65535,42260,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,32,44405,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65503,10565,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,42260,65535,52825,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,32,54938,65535,
+ 65503,14791,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,2145,59164,65535,44405,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,14791,65535,
+ 65535,65535,44373,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,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,10597,
+ 63390,65535,65503,65535,65535,65535,65535,65535,
+ 63390,6339,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,44405,65535,52825,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,50712,65535,
+ 65503,14791,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,4258,59164,65535,46486,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,12678,65535,
+ 65535,65535,46486,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,32,0,0,
+ 40179,65535,65535,65535,65535,65535,65535,65535,
+ 61277,6371,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,48599,65503,52825,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,46518,65535,
+ 63422,12710,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,6339,59196,65535,48599,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,10597,65503,
+ 65535,65535,48599,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,
+ 10597,63390,65535,65535,65535,65535,65535,65535,
+ 61277,6339,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,4226,54938,65535,52825,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,44373,65535,
+ 63422,12678,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,
+ 32,0,0,6339,59196,65535,50712,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,8484,63422,
+ 65535,65535,50712,2113,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,44373,65535,65535,65535,65535,65535,65535,
+ 61309,4258,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,6339,61277,65535,50712,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,40179,65535,
+ 63422,12678,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,6371,61277,65535,50744,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,8484,63422,
+ 65535,65535,50712,2113,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,12678,63422,65535,65535,65535,65535,65535,
+ 63422,8452,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,12710,65535,65535,50712,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,35953,65535,
+ 63422,12678,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,8452,61309,65535,52857,2113,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,8484,63422,
+ 65535,65535,50712,2113,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,48599,65503,65535,65535,65535,65535,
+ 65503,12710,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,21162,65535,65535,50744,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,33840,65535,
+ 65503,12710,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,8452,63390,65535,54938,2113,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,8484,63422,
+ 65535,65535,50712,2113,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,19017,63422,65535,65535,65535,65503,
+ 65503,19049,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,38034,65535,65535,48631,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,31695,65535,
+ 63422,16936,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,8484,63390,65535,57083,2145,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,10565,65535,
+ 65535,65535,44405,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,2145,52857,65535,65535,65535,65535,
+ 65535,23243,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,
+ 32,0,32,52825,65535,65535,48631,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,29582,65535,
+ 65535,19049,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,10565,63422,65535,59196,4258,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,10597,65503,
+ 65535,65535,40179,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,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,27469,65503,65535,65535,65535,
+ 65535,27469,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,4258,57051,65535,65535,48631,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,27469,65535,
+ 65535,25356,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,12678,65503,65535,63390,8484,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,19017,65503,
+ 65535,65535,31695,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,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,6339,59164,65535,65535,65535,
+ 65535,27501,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,10565,61309,65535,65535,48631,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,25388,65535,
+ 65535,31695,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,12710,65535,65535,63422,10597,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,27469,65535,
+ 65535,65535,21162,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,35953,65535,65535,65535,
+ 65535,29582,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,12678,65503,65535,65535,57051,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,23243,65535,
+ 65535,42260,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,32,14823,65503,65535,65535,16904,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,32,48599,65535,
+ 65535,63422,14791,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,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,8484,61309,65535,65535,
+ 65535,27501,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,16904,65535,65535,65535,61277,2145,
+ 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,23243,65535,
+ 65535,50744,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,16936,65503,65535,63422,21130,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,16904,65503,65535,
+ 65535,61309,4226,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,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,2113,52857,65535,65535,
+ 65535,25388,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,16904,65535,65535,65535,65503,12678,
+ 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,23243,65535,
+ 65535,59196,4258,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,25356,65535,65535,65535,27469,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,4258,50744,65535,65535,
+ 65535,63390,6339,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,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,32,48599,65535,65535,
+ 65535,25356,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,12678,65503,65535,65535,65535,23243,
+ 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,23243,65535,
+ 65535,63390,10597,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,35921,65535,65535,65535,33840,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,25356,65503,65503,65535,
+ 65535,65503,19017,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,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,32,48599,65535,65535,
+ 65535,19049,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,6339,59196,65535,65535,65535,35953,
+ 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,23243,65535,
+ 65535,65535,19049,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,52825,65535,65535,65535,44373,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,42292,65535,65535,65535,
+ 65535,65535,38066,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,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,2113,50744,65535,65535,
+ 65503,16936,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,42260,65535,65535,65535,38066,
+ 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,25388,65535,
+ 65535,65535,31727,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,
+ 32,0,4258,59196,65535,65535,65535,54970,
+ 2113,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,35953,65535,65535,65535,
+ 65535,65535,54970,2113,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,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,2145,54970,65535,65535,
+ 65503,14791,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,32,12678,63390,65535,63390,19049,
+ 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,29614,65535,
+ 65535,65535,44373,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,
+ 32,0,10597,63422,65535,65535,65535,65503,
+ 12678,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,12678,63390,65535,65535,
+ 65535,65535,63422,8484,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,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,4226,59164,65535,65535,
+ 63422,12678,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,33808,63422,29614,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,32,33808,65535,
+ 65535,65503,48631,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,14823,63390,65535,65535,65535,65535,
+ 25388,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,42260,65535,65535,
+ 65535,65535,65535,25356,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,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,4258,61309,65535,65535,
+ 63422,10597,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,2145,21162,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,23243,63390,
+ 65535,65535,42292,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,14791,63422,65535,65535,65535,65535,
+ 46518,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,10565,63390,65535,
+ 65535,65535,65535,40179,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,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,4258,61309,65535,65535,
+ 63422,10597,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,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,21162,
+ 59164,63390,19017,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,2145,52825,65535,65535,65535,65535,
+ 57083,4258,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,31695,65503,
+ 65535,65535,65535,54938,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,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,6371,63390,65535,65535,
+ 65503,12678,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,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,32,
+ 6339,12710,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,8452,40147,57083,61309,59164,
+ 31727,2145,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4226,50744,
+ 65503,65535,65535,59196,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,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,8452,63422,65535,65535,
+ 65503,12678,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2145,6371,4226,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,10565,
+ 61277,65535,65535,63422,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,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,6339,63422,65535,65535,
+ 65503,16936,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 38034,65535,65535,57083,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,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,4258,61309,65535,65535,
+ 65535,19049,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 19017,65535,65535,48631,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,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,4258,59196,65535,65535,
+ 65535,21162,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 21130,65535,65535,42260,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,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,4258,59164,65535,65535,
+ 65535,23243,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 33808,65535,65535,31695,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,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,2113,52857,65535,65535,
+ 65535,21162,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,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,0,0,0,0,0,
+ 0,0,0,0,0,0,32,32,
+ 48631,65535,65503,19017,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,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,32,48631,65535,65535,
+ 65535,21162,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,4258,
+ 61309,65535,63422,8484,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,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,40147,65535,65535,
+ 65535,23275,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,21162,
+ 65503,65535,57083,2145,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,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,29582,65503,65535,
+ 65535,25388,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,12710,
+ 2145,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,
+ 0,0,0,0,0,0,0,0,
+ 0,14823,25356,6371,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,40179,
+ 65535,65535,44373,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,16936,65503,65535,
+ 65503,27501,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,32,0,0,10597,54938,
+ 6339,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,
+ 0,0,0,0,0,0,0,0,
+ 0,12710,63390,59164,19049,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4258,59196,
+ 65535,65503,21130,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,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,8484,65503,65535,
+ 65535,31727,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,32,0,10565,54938,63390,
+ 8452,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,2113,50744,65535,61309,14791,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,21130,65535,
+ 65535,59196,4258,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,2113,52857,65503,
+ 65535,40179,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 32,32,0,0,12710,57051,65535,61277,
+ 6339,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,27469,65535,65535,50744,2113,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,46486,65535,
+ 65535,42260,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,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,38034,65535,
+ 65535,48631,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,14791,59164,65535,65535,52857,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 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,4258,52825,65503,65503,19017,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,14823,65503,65535,
+ 63390,10565,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,19017,65535,
+ 65535,59164,4258,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,14823,59196,65535,65535,65535,35921,
+ 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,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,14823,65503,65535,44373,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,2145,50744,65535,65535,
+ 35921,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,
+ 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,4226,57083,
+ 65535,65503,16904,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 2113,8452,59164,65503,65535,65535,61277,6371,
+ 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,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,32,48599,65535,54970,2113,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,32,33840,65535,65535,52857,
+ 4226,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,40147,
+ 65535,65535,35921,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,
+ 32,40179,65535,65535,65535,65535,31695,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,31727,65535,59196,2145,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,25388,65503,65535,57051,8484,
+ 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,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,12710,
+ 65503,65535,59164,6339,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,
+ 8452,63390,65535,65535,65535,54938,6339,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,27469,65535,59164,4226,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,2145,27469,63390,65503,57051,14791,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,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,
+ 40147,65535,65503,31727,32,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 19049,65503,65535,65535,65503,25388,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,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,32,40147,65535,52825,32,
+ 0,0,0,0,0,32,32,0,
+ 0,0,0,0,0,32,0,32,
+ 8452,44373,65535,65535,52857,8484,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,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,
+ 6339,57083,65503,59164,6371,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 35921,65535,65535,65535,59164,4226,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,2113,10597,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,4258,57083,65535,33808,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,4258,29614,
+ 59164,65535,65535,52825,6371,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,0,0,
+ 0,16936,63390,65535,44373,2113,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,32,
+ 50744,65535,65535,65535,40147,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,2113,42260,19017,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,23275,65535,61277,8452,0,
+ 0,0,0,0,0,0,0,32,
+ 0,0,32,4226,14823,35953,61277,65535,
+ 65535,65535,48599,6339,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,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,35921,65535,65503,23275,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,2145,
+ 59164,65535,65535,65535,25356,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,19049,61277,21162,
+ 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,44405,65503,29614,32,0,
+ 0,0,0,0,0,0,32,4226,
+ 14823,27469,46486,61277,65503,65535,65535,65535,
+ 65503,38066,2145,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,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,2113,48631,65535,59196,12710,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,6339,
+ 61277,65535,65535,63422,19017,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,32,52857,63390,
+ 23275,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,32,0,21162,33808,2113,0,32,
+ 0,0,0,0,2145,27469,50744,61277,
+ 65535,65535,65535,65535,65535,65535,65535,59164,
+ 25388,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,
+ 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,12678,61309,65535,54938,8452,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,6371,
+ 61277,65535,65535,65535,19049,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,25388,65503,
+ 61309,25356,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,0,2113,32,0,0,0,
+ 0,32,0,19017,54938,65503,65535,65535,
+ 65535,65535,65503,65535,65535,61309,42292,8484,
+ 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,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,27469,65503,65535,48631,
+ 4258,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,4258,
+ 59196,65535,65535,65535,23275,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,4258,59196,
+ 65535,63390,14823,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,32,32,0,
+ 0,32,29614,63422,65535,65503,65535,65535,
+ 65503,65503,61277,54938,35953,10565,0,0,
+ 0,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,0,0,0,0,0,0,0,
+ 32,0,0,0,2113,46486,65535,65535,
+ 48631,6339,32,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,0,0,4226,
+ 57083,65535,65535,65535,31695,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,32,38066,
+ 65535,65535,52857,2113,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,
+ 2145,40147,65535,65535,61277,42292,23275,14791,
+ 12710,10597,6339,32,0,0,0,0,
+ 0,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,6371,57051,65503,
+ 65535,52857,8484,32,0,0,32,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 46486,65535,65535,65535,42292,0,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,14791,
+ 65503,65535,65503,14823,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,32,0,0,4226,
+ 44373,65503,65503,42260,6371,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,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,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,32,14823,63390,
+ 65535,65535,59196,19017,0,0,32,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 23243,65535,65535,65535,48631,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,4226,
+ 59196,65535,65535,25356,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,4226,46486,
+ 65535,63422,33840,2113,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,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,27469,
+ 63422,65535,65535,63390,35921,6371,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 2145,54938,65535,65535,57051,2113,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,2145,
+ 57051,65535,65535,25388,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,2145,42292,65535,
+ 65535,44373,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,32,0,0,
+ 31727,65503,65535,65535,65535,57051,21162,2145,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,23243,63422,65535,61277,4258,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,2145,
+ 57083,65535,63422,16904,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,32,40179,65535,65535,
+ 57083,8452,0,32,0,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,
+ 32,29614,65503,65535,65535,65535,65535,50744,
+ 21162,2113,0,0,0,32,0,0,
+ 0,32,0,32,0,0,0,0,
+ 0,32,40147,65535,63422,6371,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,4226,
+ 59164,65503,57051,2145,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,31695,65535,65535,65535,
+ 25356,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,
+ 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,0,
+ 0,32,19049,59164,65535,65535,65535,65535,
+ 65503,52825,27469,8452,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,4258,48631,63390,6371,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,6339,
+ 61309,65503,25356,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,32,23275,63422,65535,65535,46486,
+ 2113,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,6339,38066,61277,65535,65535,
+ 65535,65535,65535,61277,46486,21130,4258,32,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,10597,52825,4226,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,4226,
+ 54938,33840,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,16936,61309,65535,65535,61277,8484,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 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,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,10597,38034,59196,
+ 65535,65535,65535,65535,65535,65535,61277,46518,
+ 27469,12710,2145,32,0,0,0,0,
+ 0,0,0,0,10565,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,
+ 4226,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,10565,57051,65535,65535,65503,23243,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,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,0,0,0,
+ 0,0,0,0,0,0,0,8484,
+ 31727,57083,65503,65535,65535,65535,65535,65535,
+ 65503,65503,57051,44373,19049,4258,0,0,
+ 32,32,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,
+ 6339,50744,65535,65535,65535,31727,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,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,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 32,4226,23243,50712,63390,65535,65535,65535,
+ 65535,65535,65535,65535,63422,52857,19049,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,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,4258,
+ 48599,65535,65535,65503,40147,2113,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,32,0,0,0,
+ 0,0,0,2113,14791,40179,61277,65535,
+ 65535,65535,65535,65535,65535,65503,65503,38034,
+ 4226,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,2145,42260,
+ 65503,65535,65503,46518,2145,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,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,6371,29614,
+ 52857,65503,65535,65535,65535,65535,65535,65503,
+ 48631,8452,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,0,0,0,0,0,0,0,
+ 0,0,0,0,32,4258,46486,65503,
+ 65535,65535,50744,6371,0,0,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,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,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,
+ 4226,19049,46486,63390,65535,65535,65535,65535,
+ 65535,52857,10565,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,0,0,0,0,0,0,
+ 0,0,0,32,8452,46518,65535,65535,
+ 65535,54970,8484,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,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,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,32,10565,33840,52857,65535,65535,
+ 65503,65535,54970,10597,0,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,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,32,14823,54938,65535,65535,65535,
+ 57083,10597,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 32,32,0,32,0,4226,21130,50712,
+ 65535,65535,65535,57051,12710,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,0,0,0,0,
+ 32,4258,35921,63390,65535,65535,65503,59164,
+ 14823,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,
+ 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,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,32,0,2113,
+ 29614,63422,65535,65535,54970,10597,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,0,32,4226,
+ 27469,54970,65535,65535,65535,65535,61309,19017,
+ 0,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,27469,65535,65535,65535,54970,12678,0,
+ 0,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,2113,10565,31695,59164,
+ 65535,65535,65535,65535,65535,61309,23275,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,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,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,38034,65535,65535,65535,57083,12678,
+ 32,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,2113,4226,
+ 4226,4258,8452,10597,12678,14791,12678,6371,
+ 6339,4258,2145,2113,2113,0,0,2113,
+ 2145,4258,16936,33808,52825,63390,65535,65535,
+ 65535,65535,65535,65535,63422,27469,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,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,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,8452,59164,65535,65535,65535,54938,
+ 8484,0,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,2145,10597,29582,40147,44405,52825,57083,
+ 61309,63422,65535,65535,65535,65535,65503,63422,
+ 63422,61277,54970,50744,48631,46518,46518,48631,
+ 57083,63390,65535,65535,65535,65503,65535,65535,
+ 65535,65535,65535,65503,29614,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,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,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,32,0,31727,65503,65535,65535,65535,
+ 54970,10565,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,32,6339,
+ 31695,54938,65503,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,63422,33840,32,32,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,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,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,0,0,0,0,0,
+ 0,0,0,6371,57083,65503,65535,65503,
+ 65503,54970,10565,0,0,32,0,32,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,32,8452,35953,59196,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,63390,25388,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,0,0,0,0,0,0,0,
+ 0,0,0,0,27469,65535,65535,65535,
+ 65535,65535,57051,10597,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,6339,31727,59196,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65503,
+ 63390,59196,54970,52825,50744,48631,48599,48599,
+ 50712,54970,61309,65503,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65503,
+ 48631,12710,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,2145,48631,65535,65503,
+ 65535,65535,65535,57083,14791,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,2113,21162,54970,65503,65535,65535,65535,
+ 65535,65535,65535,65535,65503,54970,40179,21162,
+ 6371,2113,0,32,0,0,0,32,
+ 0,0,6371,19017,38034,50712,61309,65503,
+ 65535,65535,65535,65535,65503,61277,48599,19049,
+ 32,32,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,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,
+ 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,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,10565,59164,65535,
+ 65535,65503,65535,65535,61277,21130,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 16904,48599,65503,65535,65535,65535,65535,65535,
+ 65535,65535,63422,46486,16936,2145,0,32,
+ 0,32,0,0,32,0,0,0,
+ 0,0,0,0,0,32,6371,14823,
+ 25388,31695,31695,25388,16904,6371,32,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,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,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,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,16936,61309,
+ 65535,65535,65503,65535,65535,63390,35953,6371,
+ 0,0,32,0,32,0,0,0,
+ 0,0,0,0,2113,6371,25356,46518,
+ 65503,65535,65535,65535,65535,65535,65535,61309,
+ 50712,33808,10597,2113,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,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,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,32,21162,
+ 61309,65535,65535,65535,65535,65535,65535,61277,
+ 35921,14823,4258,32,32,0,0,32,
+ 2145,4258,10597,27469,46486,61309,65503,65503,
+ 65535,65535,65503,65535,65535,54970,25356,4258,
+ 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,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,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,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,32,0,0,
+ 21162,63390,65535,65535,65535,65535,63422,65535,
+ 65535,63390,59196,52857,48599,44405,44405,48599,
+ 52857,61277,63390,65503,65535,65535,65535,65535,
+ 65535,65535,65535,65503,50744,8452,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,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,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,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 32,21130,59164,65503,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,63422,61277,50744,10597,0,32,0,
+ 0,32,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,
+ 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,
+ 32,0,10597,50744,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,65535,65535,61277,46486,
+ 31695,19017,4258,2113,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,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,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,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,32,0,2145,29582,57083,63422,65535,
+ 65535,65535,65535,65535,65535,65535,65535,65535,
+ 65535,65535,65535,65535,52857,25356,4258,2113,
+ 0,0,0,32,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,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,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,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,4258,27501,48631,
+ 61309,65503,65503,65535,65535,65535,65503,63422,
+ 63390,59196,44405,23243,2113,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,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,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,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,32,
+ 4258,16904,25388,33840,35953,35921,29614,23243,
+ 10597,4226,32,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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,
+ 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,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,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,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,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,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,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,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
+};
+
+const basic_image<unsigned short> respect(height,width,pixelData);
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/gui/res/respect.h b/src/tests/drivers/xbee/gui/res/respect.h
new file mode 100644
index 0000000000000000000000000000000000000000..543531b60ad8c0c932e4756a1a0e0fa897e355ad
--- /dev/null
+++ b/src/tests/drivers/xbee/gui/res/respect.h
@@ -0,0 +1,11 @@
+
+//This file has been automatcally generated by pngconverter utility
+//Please do not edit
+#ifndef RESPECT_H
+#define RESPECT_H
+
+#include "mxgui/image.h"
+
+extern const mxgui::Image respect;
+
+#endif //RESPECT_H
diff --git a/src/tests/drivers/xbee/logdecoder/.gitignore b/src/tests/drivers/xbee/logdecoder/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..8b193293c00f3d4483c23b0d5c2e705d0617e209
--- /dev/null
+++ b/src/tests/drivers/xbee/logdecoder/.gitignore
@@ -0,0 +1 @@
+logdecoder
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/logdecoder/LogTypes.h b/src/tests/drivers/xbee/logdecoder/LogTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b7b17baec1dfa8d29e47f5eaf3fe5fa23279f1b
--- /dev/null
+++ b/src/tests/drivers/xbee/logdecoder/LogTypes.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2015-2018 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <fstream>
+#include <iostream>
+
+#include "drivers/Xbee/APIFramesLog.h"
+#include "drivers/Xbee/XbeeStatus.h"
+#include "drivers/xbee/Mark.h"
+#include "drivers/xbee/XbeeTestData.h"
+#include "logger/Deserializer.h"
+#include "logger/LogStats.h"
+
+// Serialized classes
+using std::ofstream;
+
+template <typename T>
+void print(T& t, ostream& os)
+{
+    t.print(os);
+}
+
+template <typename T>
+void registerType(Deserializer& ds)
+{
+    ds.registerType<T>(print<T>, T::header());
+}
+
+void registerTypes(Deserializer& ds)
+{
+    registerType<LogStats>(ds);
+
+    registerType<Xbee::APIFrameLog>(ds);
+    registerType<Xbee::ATCommandFrameLog>(ds);
+    registerType<Xbee::ATCommandResponseFrameLog>(ds);
+    registerType<Xbee::ModemStatusFrameLog>(ds);
+    registerType<Xbee::TXRequestFrameLog>(ds);
+    registerType<Xbee::TXStatusFrameLog>(ds);
+    registerType<Xbee::RXPacketFrameLog>(ds);
+    registerType<Xbee::XbeeStatus>(ds);
+
+    registerType<TxData>(ds);
+    registerType<RxData>(ds);
+    registerType<Mark>(ds);
+    registerType<XbeeConfig>(ds);
+    registerType<EnergyScanData>(ds);
+}
diff --git a/src/tests/drivers/xbee/logdecoder/Makefile b/src/tests/drivers/xbee/logdecoder/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..47258b629723d159885432ac1e485023f5d40002
--- /dev/null
+++ b/src/tests/drivers/xbee/logdecoder/Makefile
@@ -0,0 +1,13 @@
+BASE := ../../../../../
+
+all:
+	g++ -std=c++17 -O2 -o logdecoder logdecoder.cpp \
+					-DCOMPILE_FOR_X86 \
+					$(BASE)libs/tscpp/stream.cpp \
+	 				-I$(BASE)src/shared \
+	 				-I$(BASE)src/tests \
+					-I$(BASE)libs \
+					-I$(BASE)libs/miosix-kernel/miosix
+
+clean:
+	rm logdecoder
diff --git a/src/tests/drivers/xbee/logdecoder/logdecoder.cpp b/src/tests/drivers/xbee/logdecoder/logdecoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3f1f725ddf79da1d1610633fce3594fa66824360
--- /dev/null
+++ b/src/tests/drivers/xbee/logdecoder/logdecoder.cpp
@@ -0,0 +1,168 @@
+/***************************************************************************
+ *   Copyright (C) 2018 by Terraneo Federico                               *
+ *                                                                         *
+ *   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.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+/*
+ * This is a stub program for the program that will decode the logged data.
+ * Fill in the TODO to make it work.
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <tscpp/stream.h>
+
+#include <filesystem>
+#include <fstream>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include "LogTypes.h"
+
+using namespace std;
+using namespace tscpp;
+
+namespace fs = filesystem;
+
+void showHelp(string cmdName)
+{
+    std::cerr << "Usage: " << cmdName
+              << " {-a [logs_diretory] | <log_file_path> | -h}"
+              << "Options:\n"
+              << "\t-h,--help\t\tShow help message\n"
+              << "\t-a,--all [dir=\".\"] Deserialize all logs in the provided directory\n"
+              << std::endl;
+}
+
+vector<fs::path> listLogFiles(fs::path dir)
+{
+    vector<fs::path> out;
+    for (const auto& entry : fs::directory_iterator(dir))
+    {
+        if (entry.exists() && entry.is_regular_file())
+        {
+            if (entry.path().extension() == ".dat")
+            {
+                out.push_back(entry.path());
+            }
+        }
+    }
+    return out;
+}
+
+bool deserialize(fs::path log_path)
+{
+    cout << "Deserializing " << log_path << ".dat...\n";
+
+    // remove extension
+    log_path.replace_extension("");
+    Deserializer d(log_path);
+    registerTypes(d);
+
+    return d.deserialize();
+}
+
+bool deserializeAll(fs::path dir = ".")
+{
+    vector<fs::path> logs = listLogFiles(dir);
+    for (auto log : logs)
+    {
+        if (!deserialize(log.string()))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+int main(int argc, char* argv[])
+{
+    if (argc < 2)
+    {
+        showHelp(string(argv[0]));
+        return 1;
+    }
+
+    bool success = false;
+    string arg1  = string(argv[1]);
+    if (arg1 == "-h" || arg1 == "--help")
+    {
+        showHelp(string(argv[0]));
+        return 0;
+    }
+
+    if (arg1 == "-a" || arg1 == "--all")
+    {
+        fs::path dir = ".";
+        if (argc == 3)
+        {
+            string arg2 = string(argv[2]);
+            fs::directory_entry entry(arg2);
+            if (entry.exists() && entry.is_directory())
+            {
+                dir = arg2;
+            }
+            else
+            {
+                cout << "Second argument after '-a' or '--all' must be a "
+                        "directory\n";
+                showHelp(string(argv[0]));
+                return 1;
+            }
+        }
+        cout << "Deserializing all logs...\n";
+        success = deserializeAll(dir);
+    }
+    else if (arg1[0] == '-')
+    {
+        cerr << "Unknown option\n";
+        return 1;
+    }
+    else
+    {
+        fs::directory_entry entry(arg1);
+        if (entry.exists() && entry.is_regular_file())
+        {
+            success = deserialize(arg1);
+        }
+        else
+        {
+            showHelp(string(argv[0]));
+            return 1;
+        }
+    }
+
+    if (success)
+    {
+        cout << "Deserialization completed successfully.\n";
+    }
+    else
+    {
+        cout << "Deserialization ended with errors.\n";
+    }
+}
diff --git a/src/tests/drivers/xbee/test-xbee-bidir.cpp b/src/tests/drivers/xbee/test-xbee-bidir.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c8abcb445427b4e1e8813d488f12eb5cce0bbd89
--- /dev/null
+++ b/src/tests/drivers/xbee/test-xbee-bidir.cpp
@@ -0,0 +1,267 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef RUN_SENDER
+#define RUN_SENDER true
+#endif
+#ifndef RUN_RECEIVER
+#define RUN_RECEIVER true
+#endif
+
+#include <miosix.h>
+
+#include <cstdio>
+#include <stdexcept>
+
+#include "ActiveObject.h"
+#include "XbeeTransceiver.h"
+#include "drivers/Xbee/APIFramesLog.h"
+#include "drivers/Xbee/ATCommands.h"
+#include "drivers/Xbee/Xbee.h"
+#include "drivers/interrupt/external_interrupts.h"
+#include "logger/Logger.h"
+
+using namespace miosix;
+
+#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X
+#include "interfaces-impl/hwmapping.h"
+using GpioMiso = miosix::interfaces::spi2::miso;
+using GpioMosi = miosix::interfaces::spi2::mosi;
+using GpioSck  = miosix::interfaces::spi2::sck;
+
+using GpioCS   = xbee::cs;
+using GpioATTN = xbee::attn;
+using GpioRST  = xbee::reset;
+
+using GpioLedLog = Gpio<GPIOG_BASE, 2>;
+
+#define XBEE_SPI SPI2
+#else
+using GpioMiso = Gpio<GPIOB_BASE, 4>;
+using GpioMosi = Gpio<GPIOA_BASE, 7>;
+using GpioSck  = Gpio<GPIOA_BASE, 5>;
+
+using GpioCS   = Gpio<GPIOC_BASE, 1>;
+using GpioATTN = Gpio<GPIOE_BASE, 5>;
+using GpioRST  = Gpio<GPIOE_BASE, 6>;
+
+using GpioLedLog = Gpio<GPIOC_BASE, 13>;
+#define XBEE_SPI SPI1
+#endif
+
+using GpioUserBtn = Gpio<GPIOA_BASE, 0>;
+
+Xbee::Xbee* xbee_driver = nullptr;
+Logger& logger          = Logger::instance();
+
+#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X
+void __attribute__((used)) EXTI10_IRQHandlerImpl()
+#else
+void __attribute__((used)) EXTI5_IRQHandlerImpl()
+#endif
+{
+    if (xbee_driver != nullptr)
+    {
+        xbee_driver->handleATTNInterrupt();
+    }
+}
+
+int getUserBtnValue()
+{
+#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X
+    return 0;
+#else
+    return GpioUserBtn::value();
+#endif
+}
+
+void configure()
+{
+#ifndef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X
+    {
+        FastInterruptDisableLock dLock;
+
+        RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
+
+        // Set SPI pins to correct alternate mode
+        GpioSck::mode(Mode::ALTERNATE);
+        GpioMiso::mode(Mode::ALTERNATE);
+        GpioMosi::mode(Mode::ALTERNATE);
+
+        GpioSck::alternateFunction(5);
+        GpioMiso::alternateFunction(5);
+        GpioMosi::alternateFunction(5);
+
+        GpioATTN::mode(Mode::INPUT);
+
+        GpioLedLog::mode(Mode::OUTPUT);
+
+        GpioUserBtn::mode(Mode::INPUT_PULL_DOWN);
+
+        GpioCS::mode(Mode::OUTPUT);
+    }
+
+    GpioCS::high();
+    GpioLedLog::low();
+#endif
+
+#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X
+    enableExternalInterrupt(GPIOF_BASE, 10, InterruptTrigger::FALLING_EDGE);
+#else
+    enableExternalInterrupt(GPIOE_BASE, 5, InterruptTrigger::FALLING_EDGE);
+#endif
+}
+
+void setupXbee(XbeeConfig config)
+{
+    if (xbee_driver)
+    {
+        if (config.data_rate_80k)
+        {
+            if (!Xbee::setDataRate(*xbee_driver, true))
+            {
+                TRACE("[main] Error setting xbee_driver data rate!\n");
+            }
+        }
+
+        if (!config.freq_hop)
+        {
+            if (!Xbee::disableFrequencyHopping(*xbee_driver))
+            {
+                TRACE("[main] Error disabling frequency hop!\n");
+            }
+        }
+    }
+}
+
+int main()
+{
+    XbeeConfig config;
+    config.data_rate_80k = true;
+    config.freq_hop      = true;
+
+    config.packet_size   = 256;
+    config.send_interval = 333;
+    config.tx_enabled    = RUN_SENDER;
+    config.timestamp     = getTick();
+
+    configure();
+
+    int filenum;
+    try
+    {
+        filenum = logger.start();
+
+        printf("\nLog file opened! (%s)\n\n",
+               logger.getFileName(filenum).c_str());
+    }
+    catch (const std::runtime_error& err)
+    {
+        GpioLedLog::high();
+        printf("\n!!!!!!Error opening log file!!!!!!!\n\n");
+    }
+
+    logger.log(config);
+
+    SPIBus spi_bus(XBEE_SPI);
+    SPIBusConfig cfg{};
+    cfg.clock_div = SPIClockDivider::DIV16;
+
+    GpioPin cs   = GpioCS::getPin();
+    GpioPin attn = GpioATTN::getPin();
+    GpioPin rst  = GpioRST::getPin();
+
+    xbee_driver = new Xbee::Xbee(spi_bus, cfg, cs, attn, rst);
+
+    setupXbee(config);
+
+    // RandSendInterval intv(333, 1500);
+    ConstSendInterval intv(config.send_interval);
+    XbeeTransceiver* trans =
+        new XbeeTransceiver(*xbee_driver, logger, intv, 256, 333);
+    if (!config.tx_enabled)
+    {
+        trans->disableSender();
+    }
+    if (!RUN_RECEIVER)
+    {
+        trans->disableReceiver();
+    }
+    trans->start();
+
+    while (getUserBtnValue() == 0)
+    {
+        long long loop_start = getTick();
+
+        DataRateResult res_rcv = trans->getReceiver().getDataRate();
+        DataRateResult res_snd = trans->getSender().getDataRate();
+
+        TxData txd = trans->getSender().getTxData();
+        RxData rxd = trans->getReceiver().getRxData();
+
+        logger.log(xbee_driver->getStatus());
+        logger.log(logger.getLogStats());
+
+        long long tick = getTick();
+        unsigned int h = tick / (1000 * 3600);
+        unsigned int m = (tick - h * 1000 * 3600) / (1000 * 60);
+        float s        = (tick - h * 1000 * 3600 - m * 1000 * 60) / 1000.0f;
+
+        printf("%02u:%02u:%06.3f\n", h, m, s);
+        if (RUN_SENDER)
+        {
+            printf("SND: int: %d, cnt: %d, tts: %u ms, pps: %.1f, fail: % d\n ",
+                   txd.time_since_last_send,
+                   txd.tx_success_counter + txd.tx_fail_counter,
+                   txd.time_to_send, res_snd.packets_per_second,
+                   txd.tx_fail_counter);
+        }
+        if (RUN_RECEIVER)
+        {
+            printf(
+                "RCV: cnt: %d, last_rx: %lld ms,  RSSI: %d, dr: %.0f, pps: "
+                "%.1f,"
+                " pl: %.0f%%, lcnt: %u, fail: %u\n",
+                rxd.rcv_count, rxd.last_packet_timestamp, rxd.RSSI,
+                res_rcv.data_rate, res_rcv.packets_per_second,
+                res_rcv.packet_loss * 100, rxd.packets_lost, rxd.rcv_errors);
+        }
+        printf("\n");
+
+        Thread::sleepUntil(loop_start + 1000);
+    }
+
+    trans->stop();
+    delete trans;
+    delete xbee_driver;
+    logger.stop();
+    printf("Log closed.\n");
+
+    for (;;)
+    {
+        GpioLedLog::high();
+        Thread::sleep(50);
+        GpioLedLog::low();
+        Thread::sleep(5000);
+    }
+}
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/test-xbee-gui.cpp b/src/tests/drivers/xbee/test-xbee-gui.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..60019fa0c190d5c809b6719e0f09f0d45e3e8070
--- /dev/null
+++ b/src/tests/drivers/xbee/test-xbee-gui.cpp
@@ -0,0 +1,368 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <miosix.h>
+#include <mxgui/display.h>
+
+#include <array>
+#include <cstdio>
+#include <functional>
+#include <stdexcept>
+
+#include "ActiveObject.h"
+#include "Mark.h"
+#include "XbeeTransceiver.h"
+#include "drivers/Xbee/APIFramesLog.h"
+#include "drivers/Xbee/ATCommands.h"
+#include "drivers/Xbee/Xbee.h"
+#include "drivers/interrupt/external_interrupts.h"
+#include "gui/XbeeGui.h"
+#include "logger/Logger.h"
+#include "utils/ButtonHandler.h"
+
+using namespace miosix;
+using namespace mxgui;
+using namespace std::placeholders;
+
+using std::array;
+using std::bind;
+using std::to_string;
+
+/// Pin definitions
+using GpioMiso = Gpio<GPIOB_BASE, 4>;
+using GpioMosi = Gpio<GPIOA_BASE, 7>;
+using GpioSck  = Gpio<GPIOA_BASE, 5>;
+
+using GpioCS   = Gpio<GPIOC_BASE, 1>;
+using GpioATTN = Gpio<GPIOE_BASE, 5>;
+using GpioRST  = Gpio<GPIOE_BASE, 6>;
+
+using GpioUserBtn = Gpio<GPIOA_BASE, 0>;
+using GpioLedLog  = Gpio<GPIOC_BASE, 13>;
+
+// Forward dec
+void onStartButtonClick(View* btn, Interaction action);
+void onEnergyButtonClick(View* btn, Interaction action);
+void onMarkButtonClick(View* btn, Interaction action);
+void onStopButtonClick(View* btn, Interaction action);
+void startTransceiver(XbeeConfig config);
+void setupXbee(XbeeConfig config);
+void configure();
+
+// Global variables
+Logger& logger   = Logger::instance();
+Xbee::Xbee* xbee = nullptr;
+ConstSendInterval snd_int{0};
+XbeeTransceiver* trans = nullptr;
+XbeeGUI* gui;
+ButtonHandler<GpioUserBtn>* btn_handler;
+
+unsigned int mark_counter = 1;
+
+/**
+ * @brief Activeobject to perform an energy detect scan as frequently as
+ * possible
+ */
+class EnergyScanner : public ActiveObject
+{
+protected:
+    void run() override
+    {
+        while (!shouldStop())
+        {
+            Xbee::ATCommandResponseFrame response;
+
+            uint8_t duration = 0xFF;
+
+            if (xbee->sendATCommand("ED", &response, &duration, 1, 1000) &&
+                response.getCommandDataLength() == 30)
+            {
+                array<int, 30> scan;
+
+                for (uint16_t i = 0; i < response.getCommandDataLength(); i++)
+                {
+                    scan[i] = -(int)(*(response.getCommandDataPointer() + i));
+                }
+
+                gui->screen_energy.updateScan(scan);
+
+                EnergyScanData data{getTick(), scan};
+                logger.log(data);
+            }
+        }
+    }
+} energy_scanner;
+
+int main()
+{
+    // Hardware
+    configure();
+
+    // SD
+    try
+    {
+        logger.start();
+        printf("\nLog file opened! (%s)\n\n",
+               logger.getFileName(logger.getLogNumber()).c_str());
+    }
+    catch (const std::runtime_error& err)
+    {
+        GpioLedLog::high();
+        printf("\n!!!!!!Error opening log file!!!!!!!\n\n");
+    }
+
+    // XBee
+    SPIBus spi_bus(SPI1);
+    SPIBusConfig cfg{};
+    cfg.clock_div = SPIClockDivider::DIV16;
+
+    GpioPin cs   = GpioCS::getPin();
+    GpioPin attn = GpioATTN::getPin();
+    GpioPin rst  = GpioRST::getPin();
+
+    xbee = new Xbee::Xbee(spi_bus, cfg, cs, attn, rst);
+
+    // GUI
+    gui = new XbeeGUI();
+
+    btn_handler = new ButtonHandler<GpioUserBtn>(
+        0, bind(&ScreenManager::onButtonPress, &gui->screen_manager, _2));
+
+    btn_handler->start();
+
+    gui->screen_config.btn_start.addOnInteractionListener(onStartButtonClick);
+    gui->screen_config.btn_energy.addOnInteractionListener(onEnergyButtonClick);
+
+    gui->screen_status.btn_stop.addOnInteractionListener(onStopButtonClick);
+    gui->screen_status.btn_mark.addOnInteractionListener(onMarkButtonClick);
+
+    gui->screen_energy.btn_stop.addOnInteractionListener(onStopButtonClick);
+    gui->screen_energy.btn_mark.addOnInteractionListener(onMarkButtonClick);
+    gui->screen_energy.btn_reset.addOnInteractionListener(
+        [&](View* d, Interaction action) {
+            UNUSED(d);
+            if (action == Interaction::CLICK)
+                gui->screen_energy.resetStats();
+        });
+
+    gui->screen_end.tv_f.addOnInteractionListener(
+        [&](View* d, Interaction action) {
+            UNUSED(d);
+            if (action == Interaction::CLICK)
+                gui->screen_manager.showScreen(XbeeGUI::SCREEN_RESPECT);
+        });
+
+    gui->screen_end.tv_reset.addOnInteractionListener(
+        [&](View* d, Interaction action) {
+            UNUSED(d);
+            if (action == Interaction::CLICK)
+                miosix::reboot();
+        });
+
+    // Main loop: updates the information in the GUI
+    for (;;)
+    {
+        long long start = getTick();
+        // Update display values
+        switch (gui->screen_manager.getScreen())
+        {
+            case XbeeGUI::SCREEN_CONFIG:
+                gui->screen_config.updateLogStatus(logger);
+                break;
+            case XbeeGUI::SCREEN_STATUS:
+                if (trans && xbee)
+                {
+                    gui->screen_status.updateXbeeStatus(
+                        trans->getReceiver().getDataRate(),
+                        trans->getSender().getDataRate(),
+                        trans->getSender().getTxData(),
+                        trans->getReceiver().getRxData(), xbee->getStatus());
+
+                    logger.log(xbee->getStatus());
+                }
+
+                gui->screen_status.updateLogStatus(logger);
+                break;
+            case XbeeGUI::SCREEN_ENERGYSCAN:
+                gui->screen_energy.updateLogStatus(logger);
+                break;
+            default:
+                break;
+        }
+
+        logger.log(logger.getLogStats());
+        Thread::sleepUntil(start + 500);
+    }
+}
+
+void onStartButtonClick(View* btn, Interaction action)
+{
+    UNUSED(btn);
+    if (action == Interaction::CLICK)
+    {
+
+        XbeeConfig cfg = gui->screen_config.config;
+        cfg.timestamp  = getTick();
+        logger.log(cfg);
+
+        gui->screen_config.btn_start.setText("Starting...");
+
+        gui->screen_status.updateConfig(cfg);
+
+        setupXbee(cfg);
+        startTransceiver(cfg);
+
+        // Show status screen
+        gui->screen_manager.showScreen(XbeeGUI::SCREEN_STATUS);
+    }
+}
+
+void onStopButtonClick(View* btn, Interaction action)
+{
+    if (action == Interaction::LONG_CLICK)
+    {
+        TextView* tv_btn = dynamic_cast<TextView*>(btn);
+
+        if (tv_btn)
+        {
+            tv_btn->setText("Stopping...");
+        }
+
+        if (trans)
+        {
+            trans->stop();
+        }
+
+        if (energy_scanner.isRunning())
+        {
+            energy_scanner.stop();
+        }
+
+        logger.stop();
+
+        gui->screen_manager.showScreen(XbeeGUI::SCREEN_END);
+    }
+}
+
+void onMarkButtonClick(View* btn, Interaction action)
+{
+    UNUSED(btn);
+    if (action == Interaction::CLICK)
+    {
+        Mark m{getTick(), mark_counter++};
+        logger.log(m);
+
+        TextView* tv_btn = dynamic_cast<TextView*>(btn);
+        if (tv_btn)
+        {
+            tv_btn->setText("Mark Log (" + to_string(mark_counter) + ")");
+        }
+    }
+}
+
+void onEnergyButtonClick(View* btn, Interaction action)
+{
+    UNUSED(btn);
+    if (action == Interaction::CLICK)
+    {
+        energy_scanner.start();
+        gui->screen_manager.showScreen(XbeeGUI::SCREEN_ENERGYSCAN);
+    }
+}
+
+void startTransceiver(XbeeConfig config)
+{
+    snd_int.interval = config.send_interval;
+    trans = new XbeeTransceiver(*xbee, logger, snd_int, config.packet_size,
+                                config.send_interval);
+
+    if (!config.tx_enabled)
+    {
+        trans->disableSender();
+    }
+
+    trans->start();
+}
+
+void setupXbee(XbeeConfig config)
+{
+    if (config.data_rate_80k)
+    {
+        if (!Xbee::setDataRate(*xbee, true))
+        {
+            gui->screen_status.tv_cfg_data_rate.setBackgroundColor(mxgui::red);
+            TRACE("[main] Error setting xbee data rate!\n");
+        }
+    }
+
+    if (!config.freq_hop)
+    {
+        if (!Xbee::disableFrequencyHopping(*xbee))
+        {
+            gui->screen_status.tv_cfg_freq_hop.setBackgroundColor(mxgui::red);
+            TRACE("[main] Error disabling frequency hop!\n");
+        }
+    }
+}
+
+void configure()
+{
+    {
+        FastInterruptDisableLock dLock;
+
+        // Enable SPI5 and TIM5 peripheral clocks
+        RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
+
+        // Set SPI pins to correct alternate mode
+        GpioSck::mode(Mode::ALTERNATE);
+        GpioMiso::mode(Mode::ALTERNATE);
+        GpioMosi::mode(Mode::ALTERNATE);
+
+        GpioSck::alternateFunction(5);
+        GpioMiso::alternateFunction(5);
+        GpioMosi::alternateFunction(5);
+
+        GpioATTN::mode(Mode::INPUT_PULL_UP);
+
+        GpioLedLog::mode(Mode::OUTPUT);
+        GpioUserBtn::mode(Mode::INPUT_PULL_DOWN);
+
+        // Set chip select pin to OUTPUT
+        GpioCS::mode(Mode::OUTPUT);
+    }
+
+    // Chip select starts high (not asserted)
+    GpioCS::high();
+    GpioLedLog::low();
+
+    // Enable rising-edge interrupt detection on PA2
+    enableExternalInterrupt(GPIOE_BASE, 5, InterruptTrigger::FALLING_EDGE);
+}
+
+void __attribute__((used)) EXTI5_IRQHandlerImpl()
+{
+    if (xbee)
+    {
+        xbee->handleATTNInterrupt();
+    }
+}
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/test-xbee-rcv.cpp b/src/tests/drivers/xbee/test-xbee-rcv.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d542ddf699222d2dc37a3c335551d6d4f55db181
--- /dev/null
+++ b/src/tests/drivers/xbee/test-xbee-rcv.cpp
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#define RUN_SENDER false
+
+#include "test-xbee-bidir.cpp"
\ No newline at end of file
diff --git a/src/tests/drivers/xbee/test-xbee-snd.cpp b/src/tests/drivers/xbee/test-xbee-snd.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c0f3508c7b2009887718720d51d151c895344b7
--- /dev/null
+++ b/src/tests/drivers/xbee/test-xbee-snd.cpp
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2021 Skyward Experimental Rocketry
+ * Authors: Luca Erbetta (luca.erbetta@skywarder.eu)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#define RUN_RECEIVER false
+
+#include "test-xbee-bidir.cpp"
diff --git a/src/tests/test-hsm.cpp b/src/tests/test-hsm.cpp
index 8495f86f8f0bf4404f82d76a3c1aa37545e1d2fb..2fa2687165f79f3cc3c27748d6626394d0923ea5 100644
--- a/src/tests/test-hsm.cpp
+++ b/src/tests/test-hsm.cpp
@@ -32,7 +32,7 @@ using namespace miosix;
 
 #define TOPIC_TEST  1
 
-#define CHECK_INIT() bool test_value = false
+#define CHECK_INIT() bool test_value = false; (void)test_value
 
 #define CHECK_STATE(HSM, SIGNAL, STATE) do{ \
 cout << "------------------------------" << endl; \