Merge Network code with webserver etc
authorJim Morris <morris@wolfman.com>
Sun, 22 Dec 2013 09:56:41 +0000 (01:56 -0800)
committerJim Morris <morris@wolfman.com>
Sun, 22 Dec 2013 09:56:41 +0000 (01:56 -0800)
Add some re entrancy fixes to circbuffer and ringbuffer
Allow network to be eliminated from build with make NONETWORK=1

104 files changed:
ConfigSamples/Smoothieboard/config
build/common.mk
mbed/src/mbed-lpc1768.mk
smoothie-stream.py [new file with mode: 0644]
smoothie-upload.py [new file with mode: 0644]
src/libs/Kernel.cpp
src/libs/Network/Drivers/LPC17XX_Ethernet.cpp
src/libs/Network/Drivers/LPC17XX_Ethernet.h
src/libs/Network/net_util.h
src/libs/Network/uip/CallbackStream.cpp [new file with mode: 0644]
src/libs/Network/uip/CallbackStream.h [new file with mode: 0644]
src/libs/Network/uip/CommandQueue.cpp [new file with mode: 0644]
src/libs/Network/uip/CommandQueue.h [new file with mode: 0644]
src/libs/Network/uip/Network.cpp [new file with mode: 0644]
src/libs/Network/uip/Network.h [new file with mode: 0644]
src/libs/Network/uip/NetworkPublicAccess.h [new file with mode: 0644]
src/libs/Network/uip/c-fifo.h [new file with mode: 0644]
src/libs/Network/uip/clock-arch.c [new file with mode: 0644]
src/libs/Network/uip/clock-arch.h [new file with mode: 0644]
src/libs/Network/uip/dhcpc/dhcpc.c [new file with mode: 0644]
src/libs/Network/uip/dhcpc/dhcpc.h [new file with mode: 0644]
src/libs/Network/uip/fifo.cpp [new file with mode: 0644]
src/libs/Network/uip/fifo.h [new file with mode: 0644]
src/libs/Network/uip/lib/memb.c [new file with mode: 0644]
src/libs/Network/uip/lib/memb.h [new file with mode: 0644]
src/libs/Network/uip/sftp/sftpd.cpp [new file with mode: 0644]
src/libs/Network/uip/sftp/sftpd.h [new file with mode: 0644]
src/libs/Network/uip/telnetd/shell.cpp [new file with mode: 0644]
src/libs/Network/uip/telnetd/shell.h [new file with mode: 0644]
src/libs/Network/uip/telnetd/telnetd.cpp [new file with mode: 0644]
src/libs/Network/uip/telnetd/telnetd.h [new file with mode: 0644]
src/libs/Network/uip/uip-conf.h [new file with mode: 0644]
src/libs/Network/uip/uip/clock.h [new file with mode: 0644]
src/libs/Network/uip/uip/lc-addrlabels.h [new file with mode: 0644]
src/libs/Network/uip/uip/lc-switch.h [new file with mode: 0644]
src/libs/Network/uip/uip/lc.h [new file with mode: 0644]
src/libs/Network/uip/uip/psock.c [new file with mode: 0644]
src/libs/Network/uip/uip/psock.h [new file with mode: 0644]
src/libs/Network/uip/uip/pt.h [new file with mode: 0644]
src/libs/Network/uip/uip/timer.c [new file with mode: 0644]
src/libs/Network/uip/uip/timer.h [new file with mode: 0644]
src/libs/Network/uip/uip/uip-fw.c [new file with mode: 0644]
src/libs/Network/uip/uip/uip-fw.h [new file with mode: 0644]
src/libs/Network/uip/uip/uip-neighbor.c [new file with mode: 0644]
src/libs/Network/uip/uip/uip-neighbor.h [new file with mode: 0644]
src/libs/Network/uip/uip/uip-split.c [new file with mode: 0644]
src/libs/Network/uip/uip/uip-split.h [new file with mode: 0644]
src/libs/Network/uip/uip/uip.c [new file with mode: 0644]
src/libs/Network/uip/uip/uip.h [new file with mode: 0644]
src/libs/Network/uip/uip/uip_arch.h [new file with mode: 0644]
src/libs/Network/uip/uip/uip_arp.c [new file with mode: 0644]
src/libs/Network/uip/uip/uip_arp.h [new file with mode: 0644]
src/libs/Network/uip/uip/uiplib.c [new file with mode: 0644]
src/libs/Network/uip/uip/uiplib.h [new file with mode: 0644]
src/libs/Network/uip/uip/uipopt.h [new file with mode: 0644]
src/libs/Network/uip/webserver/http-strings [new file with mode: 0644]
src/libs/Network/uip/webserver/http-strings.c [new file with mode: 0644]
src/libs/Network/uip/webserver/http-strings.h [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fs.c [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fs.h [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fs/404.html [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fs/img/control_xy.png [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fs/img/control_z.png [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fs/index.html [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fsdata.h [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd-fsdata2.h [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd.c [new file with mode: 0644]
src/libs/Network/uip/webserver/httpd.h [new file with mode: 0644]
src/libs/Network/uip/webserver/makefsdata.pl [new file with mode: 0644]
src/libs/Network/uip/webserver/makestrings [new file with mode: 0755]
src/libs/Network/uip/webserver/webserver.h [new file with mode: 0644]
src/libs/Pin.cpp
src/libs/Pin.h
src/libs/RingBuffer.h
src/libs/StreamOutputPool.h
src/libs/USBDevice/USBSerial/CircBuffer.h
src/main.cpp
src/modules/robot/Conveyor.h
src/modules/robot/Robot.cpp
src/modules/tools/endstops/Endstops.cpp
src/modules/utils/panel/panels/VikiLCD.cpp
src/modules/utils/panel/screens/WatchScreen.cpp
src/modules/utils/panel/screens/WatchScreen.h
src/modules/utils/player/Player.cpp
src/modules/utils/simpleshell/SimpleShell.cpp
src/modules/utils/simpleshell/SimpleShell.h
webif/404.html [new file with mode: 0644]
webif/css/font-awesome-ie7.css [new symlink]
webif/css/font-awesome.css [new symlink]
webif/css/style.css [new file with mode: 0644]
webif/images/control_e.png [new file with mode: 0755]
webif/images/control_xy.png [new file with mode: 0755]
webif/images/control_z.png [new file with mode: 0755]
webif/images/prusa_icon.png [new file with mode: 0644]
webif/images/upload_stripe.png [new file with mode: 0644]
webif/img/control_xy.png [new file with mode: 0644]
webif/img/control_z.png [new file with mode: 0644]
webif/index.html [new file with mode: 0644]
webif/js/boundvalue.js [new file with mode: 0644]
webif/js/jog.js [new file with mode: 0644]
webif/js/netrap.js [new file with mode: 0644]
webif/js/prototype.js [new file with mode: 0644]
webif/netrap.html [new file with mode: 0644]
webif/netrap_old.html [new file with mode: 0644]

index 7966ac3..55230ef 100644 (file)
@@ -181,3 +181,13 @@ currentcontrol_module_enable                 true             #
 
 return_error_on_unhandled_gcode              false            #
 
+# network settings
+network.enable                               false            # enable the ethernet network services
+network.webserver.enable                     true             # enable the webserver
+network.telnet.enable                        true             # enable the telnet server
+network.ip_address                           auto             # use dhcp to get ip address
+# uncomment the 3 below to manually setup ip address 
+#network.ip_address                           192.168.3.222    # the IP address
+#network.ip_mask                              255.255.255.0    # the ip mask
+#network.ip_gateway                           192.168.3.1      # the gateway address
+#network.mac_override                         xx.xx.xx.xx.xx.xx  # override the mac address, only do this if you have a conflict
index 6886a1f..80fc708 100755 (executable)
@@ -76,12 +76,24 @@ MRI_INIT_PARAMETERS=$(MRI_UART)
 OUTDIR=../$(DEVICE)
 
 # List of sources to be compiled/assembled
-CSRCS = $(wildcard $(SRC)/*.c $(SRC)/*/*.c $(SRC)/*/*/*.c $(SRC)/*/*/*/*.c $(SRC)/*/*/*/*/*.c $(SRC)/*/*/*/*/*/*.c)
+CSRCS1 = $(wildcard $(SRC)/*.c $(SRC)/*/*.c $(SRC)/*/*/*.c $(SRC)/*/*/*/*.c $(SRC)/*/*/*/*/*.c $(SRC)/*/*/*/*/*/*.c)
+ifeq "$(NONETWORK)" "1"
+CSRCS = $(filter-out $(SRC)/libs/Network/%,$(CSRCS1))
+DEFINES += -DNONETWORK
+else
+CSRCS = $(CSRCS1)
+endif
+
 ASRCS =  $(wildcard $(SRC)/*.S $(SRC)/*/*.S $(SRC)/*/*/*.S $(SRC)/*/*/*/*.S $(SRC)/*/*/*/*/*.S)
 ifneq "$(OS)" "Windows_NT"
 ASRCS +=  $(wildcard $(SRC)/*.s $(SRC)/*/*.s $(SRC)/*/*/*.s $(SRC)/*/*/*/*.s $(SRC)/*/*/*/*/*.s)
 endif
-CPPSRCS = $(wildcard $(SRC)/*.cpp $(SRC)/*/*.cpp $(SRC)/*/*/*.cpp $(SRC)/*/*/*/*.cpp $(SRC)/*/*/*/*/*.cpp $(SRC)/*/*/*/*/*/*.cpp)
+CPPSRCS1 = $(wildcard $(SRC)/*.cpp $(SRC)/*/*.cpp $(SRC)/*/*/*.cpp $(SRC)/*/*/*/*.cpp $(SRC)/*/*/*/*/*.cpp $(SRC)/*/*/*/*/*/*.cpp)
+ifeq "$(NONETWORK)" "1"
+CPPSRCS = $(filter-out $(SRC)/libs/Network/%,$(CPPSRCS1))
+else
+CPPSRCS = $(CPPSRCS1)
+endif
 
 # List of the objects files to be compiled/assembled
 OBJECTS = $(patsubst %.c,$(OUTDIR)/%.o,$(CSRCS)) $(patsubst %.s,$(OUTDIR)/%.o,$(patsubst %.S,$(OUTDIR)/%.o,$(ASRCS))) $(patsubst %.cpp,$(OUTDIR)/%.o,$(CPPSRCS))
index e1d467a..48b2b5d 100755 (executable)
@@ -27,5 +27,10 @@ DEVICE=LPC1768
 DEVICE_C_FLAGS =-mcpu=cortex-m3 -mthumb -mthumb-interwork
 DEVICE_AS_FLAGS=-mcpu=cortex-m3 -mthumb
 
+# If compiling for newer smoothie boards set clock to 120MHz
+SMOOTHIEBETA?=1
+ifeq "$(SMOOTHIEBETA)" "0"
+DEVICE_C_FLAGS += -DUSE120MHZ
+endif
 
 include arm-common.mk
diff --git a/smoothie-stream.py b/smoothie-stream.py
new file mode 100644 (file)
index 0000000..54564a6
--- /dev/null
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+"""\
+Stream g-code to Smoothie telnet connection
+
+Based on GRBL stream.py
+"""
+
+from __future__ import print_function
+import sys
+import telnetlib
+import argparse
+
+# Define command line argument interface
+parser = argparse.ArgumentParser(description='Stream g-code file to Smoothie over telnet.')
+parser.add_argument('gcode_file', type=argparse.FileType('r'),
+        help='g-code filename to be streamed')
+parser.add_argument('ipaddr',
+        help='Smoothie IP address')
+parser.add_argument('-q','--quiet',action='store_true', default=False,
+        help='suppress output text')
+args = parser.parse_args()
+
+f = args.gcode_file
+verbose = not args.quiet
+
+# Stream g-code to Smoothie
+print("Streaming " + args.gcode_file.name + " to " + args.ipaddr)
+
+tn = telnetlib.Telnet(args.ipaddr)
+# read startup prompt
+tn.read_until("> ")
+
+okcnt= 0
+linecnt= 0
+for line in f:
+    tn.write(line)
+    linecnt+=1
+    rep= tn.read_eager()
+    okcnt += rep.count("ok")
+    if verbose: print("SND " + str(linecnt) + ": " + line.strip() + " - " + str(okcnt))
+
+print("Waiting for complete...")
+
+while okcnt < linecnt:
+    rep= tn.read_some()
+    okcnt += rep.count("ok")
+    if verbose: print(str(linecnt) + " - " + str(okcnt) )
+
+tn.write("exit\n")
+tn.read_all()
+
+print("Done")
+
+
+
diff --git a/smoothie-upload.py b/smoothie-upload.py
new file mode 100644 (file)
index 0000000..ff5e17f
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+"""\
+Upload a file to Smoothie over the network
+"""
+
+from __future__ import print_function
+import sys
+import argparse
+import socket
+import os
+# Define command line argument interface
+parser = argparse.ArgumentParser(description='Upload a file to Smoothie over network.')
+parser.add_argument('file', type=argparse.FileType('r'),
+        help='filename to be uploaded')
+parser.add_argument('ipaddr',
+        help='Smoothie IP address')
+parser.add_argument('-v','--verbose',action='store_true',
+        help='Show data being uploaded')
+parser.add_argument('-o','--output',
+        help='Set output filename')
+parser.add_argument('-q','--quiet',action='store_true',
+        help='suppress all output to terminal')
+
+args = parser.parse_args()
+
+f = args.file
+verbose = args.verbose
+output = args.output
+if output == None :
+    output= args.file.name
+
+filesize= os.path.getsize(args.file.name)
+
+if not args.quiet : print("Uploading " + args.file.name + " to " + args.ipaddr + " as " + output + " size: " + str(filesize) )
+
+# make connection to sftp server
+s =  socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+s.settimeout(4.0)
+s.connect((args.ipaddr, 115))
+tn= s.makefile()
+
+# read startup prompt
+ln= tn.readline()
+if not ln.startswith("+") :
+    print("Failed to connect with sftp: " + ln)
+    sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+# Issue initial store command
+tn.write("STOR OLD /sd/" + output + "\n")
+tn.flush()
+
+ln= tn.readline()
+if not ln.startswith("+") :
+    print("Failed to create file: " + ln)
+    sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+# send size of file
+tn.write("SIZE " + str(filesize) + "\n")
+tn.flush()
+
+ln= tn.readline()
+if not ln.startswith("+") :
+    print("Failed: " + ln)
+    sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+cnt= 0
+# now send file
+for line in f:
+    tn.write(line)
+    if verbose :
+        print("SND: " + line.strip())
+    elif not args.quiet :
+        cnt += len(line)
+        print(str(cnt) + "/" + str(filesize) + "\r", end='')
+
+
+tn.flush()
+
+ln= tn.readline()
+if not ln.startswith("+") :
+    print("Failed to save file: " + ln)
+    sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+# exit
+tn.write("DONE\n")
+tn.flush()
+ln= tn.readline()
+tn.close()
+f.close()
+
+if not args.quiet : print("Upload complete")
+
index 79c554b..0ab71f7 100644 (file)
@@ -39,13 +39,13 @@ static int isDebugMonitorUsingUart0(){
 // The kernel is the central point in Smoothie : it stores modules, and handles event calls
 Kernel::Kernel(){
     instance= this; // setup the Singleton instance of the kernel
-    
+
     // Config first, because we need the baud_rate setting before we start serial
     this->config         = new Config();
 
     // Serial second, because the other modules might want to say something
     this->streams        = new StreamOutputPool();
-    
+
     // Configure UART depending on MRI config
     // If MRI is using UART0, we want to use UART1, otherwise, we want to use UART0. This makes it easy to use only one UART for both debug and actual commands.
     NVIC_SetPriorityGrouping(0);
index 4306019..9984f6f 100644 (file)
@@ -1,6 +1,8 @@
-#if 0
+#if 1
 #include "LPC17XX_Ethernet.h"
 
+#include "Kernel.h"
+
 #include <cstring>
 #include <cstdio>
 
@@ -153,33 +155,35 @@ int32_t emac_SetPHYMode(uint32_t ulPHYMode)
     return (0);
 }
 
-_rxbuf_t LPC17XX_Ethernet::rxbuf __attribute__ ((section ("AHBSRAM1")));
-_txbuf_t LPC17XX_Ethernet::txbuf __attribute__ ((section ("AHBSRAM1")));
+_rxbuf_t LPC17XX_Ethernet::rxbuf __attribute__ ((section ("AHBSRAM1"))) __attribute__((aligned(8)));
+_txbuf_t LPC17XX_Ethernet::txbuf __attribute__ ((section ("AHBSRAM1"))) __attribute__((aligned(8)));
 
 LPC17XX_Ethernet* LPC17XX_Ethernet::instance;
 
 LPC17XX_Ethernet::LPC17XX_Ethernet()
 {
-    mac_address[0] = 0xAE;
-    mac_address[1] = 0xF0;
-    mac_address[2] = 0x28;
-    mac_address[3] = 0x5D;
-    mac_address[4] = 0x66;
-    mac_address[5] = 0x41;
-
-    ip_address = IPA(192,168,1,27);
-    ip_mask = 0xFFFFFF00;
-
-    for (int i = 0; i < 5; i++)
-    {
+    // TODO these need to be configurable
+    // mac_address[0] = 0xAE;
+    // mac_address[1] = 0xF0;
+    // mac_address[2] = 0x28;
+    // mac_address[3] = 0x5D;
+    // mac_address[4] = 0x66;
+    // mac_address[5] = 0x41;
+
+    // ip_address = IPA(192,168,3,222);
+    // ip_mask = 0xFFFFFF00;
+
+    for (int i = 0; i < LPC17XX_RXBUFS; i++) {
         rxbuf.rxdesc[i].packet = rxbuf.buf[i];
-        rxbuf.rxdesc[i].control = (1536 - 1) | EMAC_RCTRL_INT;
+        rxbuf.rxdesc[i].control = (LPC17XX_MAX_PACKET - 1) | EMAC_RCTRL_INT;
 
         rxbuf.rxstat[i].Info = 0;
         rxbuf.rxstat[i].HashCRC = 0;
+    }
 
+    for (int i = 0; i < LPC17XX_TXBUFS; i++) {
         txbuf.txdesc[i].packet = txbuf.buf[i];
-        txbuf.txdesc[i].control = (1536 - 1) | EMAC_TCTRL_PAD | EMAC_TCTRL_CRC | EMAC_TCTRL_LAST | EMAC_TCTRL_INT;
+        txbuf.txdesc[i].control = (LPC17XX_MAX_PACKET - 1) | EMAC_TCTRL_PAD | EMAC_TCTRL_CRC | EMAC_TCTRL_LAST | EMAC_TCTRL_INT;
 
         txbuf.txstat[i].Info = 0;
     }
@@ -202,19 +206,24 @@ void LPC17XX_Ethernet::on_module_loaded()
     emac_init();
     printf("INIT OK\n");
 
-    register_for_event(ON_IDLE);
+    //register_for_event(ON_IDLE);
     register_for_event(ON_SECOND_TICK);
 }
 
 void LPC17XX_Ethernet::on_idle(void*)
 {
-    _receive_frame();
+    //_receive_frame();
+}
+
+void LPC17XX_Ethernet::on_second_tick(void *) {
+    check_interface();
 }
 
-void LPC17XX_Ethernet::on_second_tick(void*)
+void LPC17XX_Ethernet::check_interface()
 {
 //     LPC_EMAC->Command = 0x303;
 //     setEmacAddr(mac_address);
+
     uint32_t st;
     st  = read_PHY (EMAC_PHY_REG_BMSR);
 
@@ -243,6 +252,7 @@ void LPC17XX_Ethernet::on_second_tick(void*)
                 printf("Unknown speed: SCSR = 0x%04lX\n", scsr);
                 break;
         }
+        printf("MAC Address: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n", (LPC_EMAC->SA2) & 0xFF, (LPC_EMAC->SA2 >> 8) & 0xFF, (LPC_EMAC->SA1) & 0xFF, (LPC_EMAC->SA1 >> 8) & 0xFF, (LPC_EMAC->SA0) & 0xFF, (LPC_EMAC->SA0 >> 8) & 0xFF);
     }
     else if (((st & EMAC_PHY_BMSR_LINK_ESTABLISHED) == 0) && up)
     {
@@ -252,13 +262,13 @@ void LPC17XX_Ethernet::on_second_tick(void*)
         printf("%s: link down\n", interface_name);
     }
 
-//     printf("PHY: id:%04lX %04lX st:%04lX\n", id1, id2, st);
-//     printf("ETH: Rx:%lu/%lu Tx:%lu/%lu\n", LPC_EMAC->RxConsumeIndex, LPC_EMAC->RxProduceIndex, LPC_EMAC->TxProduceIndex, LPC_EMAC->TxConsumeIndex);
-//     printf("MII: 0x%1lX\n", LPC_EMAC->MIND);
-//     printf("Command: 0x%03lX Status: 0x%1lX\n", LPC_EMAC->Command, LPC_EMAC->Status);
-//     printf("RxN: %lu TxN: %lu\n", LPC_EMAC->RxDescriptorNumber, LPC_EMAC->TxDescriptorNumber);
-//     printf("MAC1: 0x%04lX MAC2: 0x%04lX\n", LPC_EMAC->MAC1, LPC_EMAC->MAC2);
-//     printf("MAC Address: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n", (LPC_EMAC->SA2) & 0xFF, (LPC_EMAC->SA2 >> 8) & 0xFF, (LPC_EMAC->SA1) & 0xFF, (LPC_EMAC->SA1 >> 8) & 0xFF, (LPC_EMAC->SA0) & 0xFF, (LPC_EMAC->SA0 >> 8) & 0xFF);
+    //printf("PHY: id:%04lX %04lX st:%04lX\n", id1, id2, st);
+    // printf("ETH: Rx:%lu/%lu Tx:%lu/%lu\n", LPC_EMAC->RxConsumeIndex, LPC_EMAC->RxProduceIndex, LPC_EMAC->TxProduceIndex, LPC_EMAC->TxConsumeIndex);
+    // printf("MII: 0x%1lX\n", LPC_EMAC->MIND);
+    // printf("Command: 0x%03lX Status: 0x%1lX\n", LPC_EMAC->Command, LPC_EMAC->Status);
+    // printf("RxN: %lu TxN: %lu\n", LPC_EMAC->RxDescriptorNumber, LPC_EMAC->TxDescriptorNumber);
+    // printf("MAC1: 0x%04lX MAC2: 0x%04lX\n", LPC_EMAC->MAC1, LPC_EMAC->MAC2);
+    // printf("MAC Address: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n", (LPC_EMAC->SA2) & 0xFF, (LPC_EMAC->SA2 >> 8) & 0xFF, (LPC_EMAC->SA1) & 0xFF, (LPC_EMAC->SA1 >> 8) & 0xFF, (LPC_EMAC->SA0) & 0xFF, (LPC_EMAC->SA0 >> 8) & 0xFF);
 }
 
 void LPC17XX_Ethernet::emac_init()
@@ -337,11 +347,11 @@ void LPC17XX_Ethernet::emac_init()
     /* Initialize Tx and Rx DMA Descriptors */
     LPC_EMAC->RxDescriptor       = (uint32_t) rxbuf.rxdesc;
     LPC_EMAC->RxStatus           = (uint32_t) rxbuf.rxstat;
-    LPC_EMAC->RxDescriptorNumber = 4;
+    LPC_EMAC->RxDescriptorNumber = LPC17XX_RXBUFS-1;
 
     LPC_EMAC->TxDescriptor       = (uint32_t) txbuf.txdesc;
     LPC_EMAC->TxStatus           = (uint32_t) txbuf.txstat;
-    LPC_EMAC->TxDescriptorNumber = 4;
+    LPC_EMAC->TxDescriptorNumber = LPC17XX_TXBUFS-1;
 
     // Set Receive Filter register: enable broadcast and multicast
     LPC_EMAC->RxFilterCtrl = EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;
@@ -364,42 +374,38 @@ void LPC17XX_Ethernet::set_mac(uint8_t* newmac)
     memcpy(mac_address, newmac, 6);
 }
 
-void LPC17XX_Ethernet::_receive_frame()
+bool LPC17XX_Ethernet::_receive_frame(void *packet, int *size)
 {
     if (can_read_packet() && can_write_packet())
     {
         int i = LPC_EMAC->RxConsumeIndex;
         RX_Stat* stat = &(rxbuf.rxstat[i]);
-        NET_PACKET packet = (NET_PACKET) rxbuf.buf[i];
+        *size = stat->Info & EMAC_RINFO_SIZE;
+        memcpy(packet, rxbuf.buf[i], *size);
 
-        int size = stat->Info & EMAC_RINFO_SIZE;
-        printf("Received %d byte Ethernet frame %lu/%lu\n", size, LPC_EMAC->RxProduceIndex, LPC_EMAC->RxConsumeIndex);
-
-//      TODO: feed received packet to network stack here
-//         int s = net->receive_packet(this, packet, size);
-//         if (s)
-//         {
-//             memcpy(request_packet_buffer(), packet, s);
-//             write_packet((uint8_t*) request_packet_buffer(), s);
-//         }
+        //printf("Received %d byte Ethernet frame %lu/%lu\n", *size, LPC_EMAC->RxProduceIndex, LPC_EMAC->RxConsumeIndex);
 
         uint32_t r = LPC_EMAC->RxConsumeIndex + 1;
         if (r > LPC_EMAC->RxDescriptorNumber)
             r = 0;
         LPC_EMAC->RxConsumeIndex = r;
+
+        return true;
     }
+
+    return false;
 }
 
 void LPC17XX_Ethernet::irq()
 {
-    if (EMAC_IntGetStatus(EMAC_INT_RX_DONE))
-    {
-        _receive_frame();
-    }
-
-    if (EMAC_IntGetStatus(EMAC_INT_TX_DONE))
-    {
-    }
+    // if (EMAC_IntGetStatus(EMAC_INT_RX_DONE))
+    // {
+    //     //_receive_frame();
+    // }
+
+    // if (EMAC_IntGetStatus(EMAC_INT_TX_DONE))
+    // {
+    // }
 }
 
 bool LPC17XX_Ethernet::can_read_packet()
@@ -431,7 +437,7 @@ bool LPC17XX_Ethernet::can_write_packet()
 
 int LPC17XX_Ethernet::write_packet(uint8_t* buf, int size)
 {
-    txbuf.txdesc[LPC_EMAC->TxProduceIndex].control = size | EMAC_TCTRL_LAST | EMAC_TCTRL_CRC | EMAC_TCTRL_PAD | EMAC_TCTRL_INT;
+    txbuf.txdesc[LPC_EMAC->TxProduceIndex].control = ((size - 1) & 0x7ff) | EMAC_TCTRL_LAST | EMAC_TCTRL_CRC | EMAC_TCTRL_PAD | EMAC_TCTRL_INT;
 
     uint32_t r = LPC_EMAC->TxProduceIndex + 1;
     if (r > LPC_EMAC->TxDescriptorNumber)
index f252289..be730a6 100644 (file)
@@ -11,9 +11,9 @@
 // SMSC 8720A special control/status register
 #define EMAC_PHY_REG_SCSR 0x1F
 
-#define LPC17XX_MAX_PACKET 1536
-#define LPC17XX_TXBUFS     5
-#define LPC17XX_RXBUFS     5
+#define LPC17XX_MAX_PACKET 600
+#define LPC17XX_TXBUFS     4
+#define LPC17XX_RXBUFS     4
 
 typedef struct {
     void* packet;
@@ -49,7 +49,7 @@ public:
 
     void irq(void);
 
-    void _receive_frame(void);
+    bool _receive_frame(void *packet, int* size);
 
     // NetworkInterface methods
 //     void provide_net(netcore* n);
@@ -72,8 +72,11 @@ public:
 
     static LPC17XX_Ethernet* instance;
 
+private:
     static _rxbuf_t rxbuf;
     static _txbuf_t txbuf;
+
+    void check_interface();
 };
 
 #endif /* _LPC17XX_ETHERNET_H */
index 3452471..2c39735 100644 (file)
@@ -75,6 +75,8 @@ public:
     virtual void set_ip(uint32_t new_ip)     { ip_address = new_ip; };
     virtual void set_mac(uint8_t new_mac[6]) { memcpy(mac_address, new_mac, 6); };
 
+    bool isUp() { return up; }
+
 //     netcore* net;
     uint8_t* interface_name;
 
@@ -92,5 +94,6 @@ bool compare_mac(const uint8_t*, const uint8_t*, const uint8_t*);
 int format_mac(uint8_t*, uint8_t*);
 int format_ip(uint32_t, uint8_t*);
 int checksum16(uint8_t*, int, int);
+uint32_t crc32(uint8_t* buf, int length);
 
 #endif /* _NET_UTIL_H */
diff --git a/src/libs/Network/uip/CallbackStream.cpp b/src/libs/Network/uip/CallbackStream.cpp
new file mode 100644 (file)
index 0000000..29dd39d
--- /dev/null
@@ -0,0 +1,67 @@
+#include "CallbackStream.h"
+#include "Kernel.h"
+
+#define DEBUG_PRINTF std::printf
+
+CallbackStream::CallbackStream(cb_t cb, void *u)
+{
+    DEBUG_PRINTF("Callbackstream ctor: %p\n", this);
+    callback= cb;
+    user= u;
+    closed= false;
+    use_count= 0;
+}
+
+CallbackStream::~CallbackStream()
+{
+    DEBUG_PRINTF("Callbackstream dtor: %p\n", this);
+}
+
+int CallbackStream::puts(const char *s)
+{
+    if(closed) return 0;
+
+    if(s == NULL) return (*callback)(NULL, user);
+
+    int len = strlen(s);
+    int n;
+    do {
+        // call this streams result callback
+        n= (*callback)(s, user);
+
+        // if closed just pretend we sent it
+        if(n == -1) {
+            closed= true;
+            return len;
+
+        }else if(n == 0) {
+            // if output queue is full
+            // call idle until we can output more
+            THEKERNEL->call_event(ON_IDLE);
+        }
+    } while(n == 0);
+
+    return len;
+}
+
+void CallbackStream::mark_closed()
+{
+    closed= true;
+    if(use_count <= 0) delete this;
+}
+void CallbackStream::dec()
+{
+    use_count--;
+    if(closed && use_count <= 0) delete this;
+}
+
+extern "C" void *new_callback_stream(cb_t cb, void *u)
+{
+    return new CallbackStream(cb, u);
+}
+
+extern "C" void delete_callback_stream(void *p)
+{
+    // we don't delete it in case it is still on the command queue
+    ((CallbackStream*)p)->mark_closed();
+}
diff --git a/src/libs/Network/uip/CallbackStream.h b/src/libs/Network/uip/CallbackStream.h
new file mode 100644 (file)
index 0000000..e77acd1
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef CALLBACKSTREAM_H
+#define CALLBACKSTREAM_H
+
+typedef int (*cb_t)(const char *, void *);
+
+#ifdef __cplusplus
+#include "libs/StreamOutput.h"
+
+
+class CallbackStream : public StreamOutput {
+    public:
+        CallbackStream(cb_t cb, void *u);
+        virtual ~CallbackStream();
+        int puts(const char*);
+        void inc() { use_count++; }
+        void dec();
+        int get_count() { return use_count; }
+        void mark_closed();
+
+    private:
+        cb_t callback;
+        void *user;
+        bool closed;
+        int use_count;
+};
+
+#else
+
+extern void *new_callback_stream(cb_t cb, void *);
+extern void delete_callback_stream(void *);
+
+#endif // __cplusplus
+
+#endif
diff --git a/src/libs/Network/uip/CommandQueue.cpp b/src/libs/Network/uip/CommandQueue.cpp
new file mode 100644 (file)
index 0000000..4216028
--- /dev/null
@@ -0,0 +1,68 @@
+#include "CommandQueue.h"
+
+#include "stdio.h"
+#include "string.h"
+#include "stdlib.h"
+
+#include "Kernel.h"
+#include "libs/SerialMessage.h"
+#include "CallbackStream.h"
+
+static CommandQueue *command_queue_instance;
+CommandQueue *CommandQueue::instance = NULL;
+
+
+CommandQueue::CommandQueue()
+{
+    command_queue_instance = this;
+    null_stream= &(StreamOutput::NullStream);
+}
+
+CommandQueue* CommandQueue::getInstance()
+{
+    if(instance == 0) instance= new CommandQueue();
+    return instance;
+}
+
+extern "C" {
+    int network_add_command(const char *cmd, void *pstream)
+    {
+        return command_queue_instance->add(cmd, (StreamOutput*)pstream);
+    }
+}
+
+int CommandQueue::add(const char *cmd, StreamOutput *pstream)
+{
+    cmd_t c= {strdup(cmd), pstream==NULL?null_stream:pstream};
+    q.push(c);
+    if(pstream != NULL) {
+        // count how many times this is on the queue
+        CallbackStream *s= static_cast<CallbackStream *>(pstream);
+        s->inc();
+    }
+    return q.size();
+}
+
+// pops the next command off the queue and submits it.
+bool CommandQueue::pop()
+{
+    if (q.size() == 0) return false;
+
+    cmd_t c= q.pop();
+    char *cmd= c.str;
+
+    struct SerialMessage message;
+    message.message = cmd;
+    message.stream = c.pstream;
+
+    free(cmd);
+    THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message );
+
+    if(message.stream != null_stream) {
+        message.stream->puts(NULL); // indicates command is done
+        // decrement usage count
+        CallbackStream *s= static_cast<CallbackStream *>(message.stream);
+        s->dec();
+    }
+    return true;
+}
diff --git a/src/libs/Network/uip/CommandQueue.h b/src/libs/Network/uip/CommandQueue.h
new file mode 100644 (file)
index 0000000..f56ff32
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _COMMANDQUEUE_H_
+#define _COMMANDQUEUE_H_
+
+#ifdef __cplusplus
+
+#include "fifo.h"
+#include <string>
+
+#include "StreamOutput.h"
+
+class CommandQueue
+{
+public:
+    CommandQueue();
+    ~CommandQueue();
+    bool pop();
+    int add(const char* cmd, StreamOutput *pstream);
+    int size() {return q.size();}
+    static CommandQueue* getInstance();
+
+private:
+    typedef struct {char* str; StreamOutput *pstream; } cmd_t;
+    Fifo<cmd_t> q;
+    static CommandQueue *instance;
+    StreamOutput *null_stream;
+};
+
+#else
+
+extern int network_add_command(const char * cmd, void *pstream);
+#endif
+
+#endif
diff --git a/src/libs/Network/uip/Network.cpp b/src/libs/Network/uip/Network.cpp
new file mode 100644 (file)
index 0000000..9d7f50b
--- /dev/null
@@ -0,0 +1,428 @@
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+#include "CommandQueue.h"
+
+#include "Kernel.h"
+
+#include "Network.h"
+#include "PublicDataRequest.h"
+#include "PlayerPublicAccess.h"
+#include "net_util.h"
+#include "uip_arp.h"
+#include "clock-arch.h"
+
+#include "uip.h"
+#include "telnetd.h"
+#include "webserver.h"
+#include "dhcpc.h"
+#include "sftpd.h"
+
+
+#include <mri.h>
+
+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+
+extern "C" void uip_log(char *m)
+{
+    printf("uIP log message: %s\n", m);
+}
+
+static bool webserver_enabled, telnet_enabled, use_dhcp;
+static Network *theNetwork;
+static Sftpd *sftpd;
+static CommandQueue *command_q= CommandQueue::getInstance();
+
+Network* Network::instance;
+Network::Network()
+{
+    ethernet = new LPC17XX_Ethernet();
+    tickcnt= 0;
+    theNetwork= this;
+    sftpd= NULL;
+    instance= this;
+}
+
+Network::~Network()
+{
+    delete ethernet;
+}
+
+static uint32_t getSerialNumberHash()
+{
+#define IAP_LOCATION 0x1FFF1FF1
+    uint32_t command[1];
+    uint32_t result[5];
+    typedef void (*IAP)(uint32_t *, uint32_t *);
+    IAP iap = (IAP) IAP_LOCATION;
+
+    __disable_irq();
+
+    command[0] = 58;
+    iap(command, result);
+    __enable_irq();
+    return crc32((uint8_t *)&result[1], 4 * 4);
+}
+
+static bool parse_ip_str(const string &s, uint8_t *a, int len, char sep = '.')
+{
+    int p = 0;
+    const char *n;
+    for (int i = 0; i < len; i++) {
+        if (i < len - 1) {
+            size_t o = s.find(sep, p);
+            if (o == string::npos) return false;
+            n = s.substr(p, o - p).c_str();
+            p = o + 1;
+        } else {
+            n = s.substr(p).c_str();
+        }
+        a[i] = atoi(n);
+    }
+    return true;
+}
+
+void Network::on_module_loaded()
+{
+    if ( !THEKERNEL->config->value( network_checksum, network_enable_checksum )->by_default(false)->as_bool() ) {
+        // as not needed free up resource
+        delete this;
+        return;
+    }
+
+    webserver_enabled = THEKERNEL->config->value( network_checksum, network_webserver_checksum, network_enable_checksum )->by_default(false)->as_bool();
+    telnet_enabled = THEKERNEL->config->value( network_checksum, network_telnet_checksum, network_enable_checksum )->by_default(false)->as_bool();
+
+    string mac = THEKERNEL->config->value( network_checksum, network_mac_override_checksum )->by_default("")->as_string();
+    if (mac.size() == 17 ) { // parse mac address
+        if (!parse_ip_str(mac, mac_address, 6, ':')) {
+            printf("Invalid MAC address: %s\n", mac.c_str());
+            printf("Network not started due to errors in config");
+            return;
+        }
+
+    } else {   // autogenerate
+        uint32_t h = getSerialNumberHash();
+        mac_address[0] = 0x00;   // OUI
+        mac_address[1] = 0x1F;   // OUI
+        mac_address[2] = 0x11;   // OUI
+        mac_address[3] = 0x02;   // Openmoko allocation for smoothie board
+        mac_address[4] = 0x04;   // 04-14  03 bits -> chip id, 1 bits -> hashed serial
+        mac_address[5] = h & 0xFF; // 00-FF  8bits -> hashed serial
+    }
+
+    ethernet->set_mac(mac_address);
+
+    // get IP address, mask and gateway address here....
+    bool bad = false;
+    string s = THEKERNEL->config->value( network_checksum, network_ip_address_checksum )->by_default("192.168.3.222")->as_string();
+    if (s == "auto") {
+        use_dhcp = true;
+
+    } else {
+        use_dhcp = false;
+        if (!parse_ip_str(s, ipaddr, 4)) {
+            printf("Invalid IP address: %s\n", s.c_str());
+            bad = true;
+        }
+        s = THEKERNEL->config->value( network_checksum, network_ip_mask_checksum )->by_default("255.255.255.0")->as_string();
+        if (!parse_ip_str(s, ipmask, 4)) {
+            printf("Invalid IP Mask: %s\n", s.c_str());
+            bad = true;
+        }
+        s = THEKERNEL->config->value( network_checksum, network_ip_gateway_checksum )->by_default("192.168.3.1")->as_string();
+        if (!parse_ip_str(s, ipgw, 4)) {
+            printf("Invalid IP gateway: %s\n", s.c_str());
+            bad = true;
+        }
+
+        if (bad) {
+            printf("Network not started due to errors in config");
+            return;
+        }
+    }
+
+    THEKERNEL->add_module( ethernet );
+    THEKERNEL->slow_ticker->attach( 100, this, &Network::tick );
+
+    // Register for events
+    this->register_for_event(ON_IDLE);
+    this->register_for_event(ON_MAIN_LOOP);
+    this->register_for_event(ON_GET_PUBLIC_DATA);
+
+    this->init();
+}
+
+void Network::on_get_public_data(void* argument) {
+    PublicDataRequest* pdr = static_cast<PublicDataRequest*>(argument);
+
+    if(!pdr->starts_with(network_checksum)) return;
+
+    if(pdr->second_element_is(get_ip_checksum)) {
+        pdr->set_data_ptr(this->ipaddr);
+        pdr->set_taken();
+
+    }else if(pdr->second_element_is(get_ipconfig_checksum)) {
+        // NOTE caller must free the returned string when done
+        char buf[200];
+        int n1= snprintf(buf,             sizeof(buf),         "IP Addr: %d.%d.%d.%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+        int n2= snprintf(&buf[n1],       sizeof(buf)-n1,       "IP GW: %d.%d.%d.%d\n", ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
+        int n3= snprintf(&buf[n1+n2],    sizeof(buf)-n1-n2,    "IP mask: %d.%d.%d.%d\n", ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
+        int n4= snprintf(&buf[n1+n2+n3], sizeof(buf)-n1-n2-n3, "MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+            mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);
+        char *str = (char *)malloc(n1+n2+n3+n4+1);
+        memcpy(str, buf, n1+n2+n3+n4);
+        str[n1+n2+n3+n4]= '\0';
+        pdr->set_data_ptr(str);
+        pdr->set_taken();
+    }
+}
+
+uint32_t Network::tick(uint32_t dummy)
+{
+    do_tick();
+    tickcnt++;
+    return 0;
+}
+
+void Network::on_idle(void *argument)
+{
+    if (!ethernet->isUp()) return;
+
+    int len;
+    if (ethernet->_receive_frame(uip_buf, &len)) {
+        uip_len = len;
+        this->handlePacket();
+
+    } else {
+
+        if (timer_expired(&periodic_timer)) { /* no packet but periodic_timer time out (0.1s)*/
+            timer_reset(&periodic_timer);
+
+            for (int i = 0; i < UIP_CONNS; i++) {
+                uip_periodic(i);
+                /* If the above function invocation resulted in data that
+                   should be sent out on the network, the global variable
+                   uip_len is set to a value > 0. */
+                if (uip_len > 0) {
+                    uip_arp_out();
+                    tapdev_send(uip_buf, uip_len);
+                }
+            }
+
+#if UIP_CONF_UDP
+            for (int i = 0; i < UIP_UDP_CONNS; i++) {
+                uip_udp_periodic(i);
+                /* If the above function invocation resulted in data that
+                   should be sent out on the network, the global variable
+                   uip_len is set to a value > 0. */
+                if (uip_len > 0) {
+                    uip_arp_out();
+                    tapdev_send(uip_buf, uip_len);
+                }
+            }
+#endif
+        }
+/*
+        This didn't work actually made it worse,it should have worked though
+        else{
+            // TODO if the command queue is below a certain amount we should poll any stopped connections
+            if(command_q->size() < 4) {
+                for (struct uip_conn *connr = &uip_conns[0]; connr <= &uip_conns[UIP_CONNS - 1]; ++connr) {
+                    if(uip_stopped(connr)){
+                        // Force a poll of this
+                        printf("Force poll of connection\n");
+                        uip_poll_conn(connr);
+                    }
+                }
+            }
+        }
+*/
+        /* Call the ARP timer function every 10 seconds. */
+        if (timer_expired(&arp_timer)) {
+            timer_reset(&arp_timer);
+            uip_arp_timer();
+        }
+    }
+}
+
+static void setup_servers()
+{
+    if (webserver_enabled) {
+        // Initialize the HTTP server, listen to port 80.
+        httpd_init();
+        printf("Webserver initialized\n");
+    }
+
+    if (telnet_enabled) {
+        // Initialize the telnet server
+        Telnetd::init();
+        printf("Telnetd initialized\n");
+    }
+
+    // sftpd service, which is lazily created on reciept of first packet
+    uip_listen(HTONS(115));
+}
+
+extern "C" void dhcpc_configured(const struct dhcpc_state *s)
+{
+    printf("Got IP address %d.%d.%d.%d\n",
+           uip_ipaddr1(&s->ipaddr), uip_ipaddr2(&s->ipaddr),
+           uip_ipaddr3(&s->ipaddr), uip_ipaddr4(&s->ipaddr));
+    printf("Got netmask %d.%d.%d.%d\n",
+           uip_ipaddr1(&s->netmask), uip_ipaddr2(&s->netmask),
+           uip_ipaddr3(&s->netmask), uip_ipaddr4(&s->netmask));
+    printf("Got DNS server %d.%d.%d.%d\n",
+           uip_ipaddr1(&s->dnsaddr), uip_ipaddr2(&s->dnsaddr),
+           uip_ipaddr3(&s->dnsaddr), uip_ipaddr4(&s->dnsaddr));
+    printf("Got default router %d.%d.%d.%d\n",
+           uip_ipaddr1(&s->default_router), uip_ipaddr2(&s->default_router),
+           uip_ipaddr3(&s->default_router), uip_ipaddr4(&s->default_router));
+    printf("Lease expires in %ld seconds\n", ntohl(s->lease_time));
+
+    theNetwork->dhcpc_configured(s->ipaddr, s->netmask, s->default_router);
+}
+
+void Network::dhcpc_configured(uint32_t ipaddr, uint32_t ipmask, uint32_t ipgw)
+{
+    memcpy(this->ipaddr, &ipaddr, 4);
+    memcpy(this->ipmask, &ipmask, 4);
+    memcpy(this->ipgw, &ipgw, 4);
+
+    uip_sethostaddr((u16_t*)this->ipaddr);
+    uip_setnetmask((u16_t*)this->ipmask);
+    uip_setdraddr((u16_t*)this->ipgw);
+
+    setup_servers();
+}
+
+void Network::init(void)
+{
+    // two timers for tcp/ip
+    timer_set(&periodic_timer, CLOCK_SECOND / 2); /* 0.5s */
+    timer_set(&arp_timer, CLOCK_SECOND * 10);   /* 10s */
+
+    // Initialize the uIP TCP/IP stack.
+    uip_init();
+
+    uip_setethaddr(mac_address);
+
+    if (!use_dhcp) { // manual setup of ip
+        uip_ipaddr_t tip;  /* local IP address */
+        uip_ipaddr(tip, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+        uip_sethostaddr(tip);    /* host IP address */
+        printf("IP Addr: %d.%d.%d.%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+
+        uip_ipaddr(tip, ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
+        uip_setdraddr(tip);  /* router IP address */
+        printf("IP GW: %d.%d.%d.%d\n", ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
+
+        uip_ipaddr(tip, ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
+        uip_setnetmask(tip); /* mask */
+        printf("IP mask: %d.%d.%d.%d\n", ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
+        setup_servers();
+
+    }else{
+    #if UIP_CONF_UDP
+        dhcpc_init(mac_address, sizeof(mac_address));
+        dhcpc_request();
+        printf("Getting IP address....\n");
+    #endif
+    }
+}
+
+void Network::on_main_loop(void *argument)
+{
+    // issue commands here if any available
+    while(command_q->pop()) {
+        // keep feeding them until empty
+    }
+}
+
+// select between webserver and telnetd server
+extern "C" void app_select_appcall(void)
+{
+    switch (uip_conn->lport) {
+        case HTONS(80):
+            if (webserver_enabled) httpd_appcall();
+            break;
+
+        case HTONS(23):
+            if (telnet_enabled) Telnetd::appcall();
+            break;
+
+        case HTONS(115):
+            if(sftpd == NULL) {
+                sftpd= new Sftpd();
+                sftpd->init();
+                printf("Created sftpd service\n");
+            }
+            sftpd->appcall();
+            break;
+
+        default:
+            printf("unknown app for port: %d\n", uip_conn->lport);
+
+    }
+}
+
+void Network::tapdev_send(void *pPacket, unsigned int size)
+{
+    memcpy(ethernet->request_packet_buffer(), pPacket, size);
+    ethernet->write_packet((uint8_t *) pPacket, size);
+}
+
+// define this to split full frames into two to illicit an ack from the endpoint
+#define SPLIT_OUTPUT
+
+#ifdef SPLIT_OUTPUT
+extern "C" void uip_split_output(void);
+extern "C" void tcpip_output()
+{
+    theNetwork->tapdev_send(uip_buf, uip_len);
+}
+void network_device_send()
+{
+    uip_split_output();
+    //tcpip_output();
+}
+#else
+void network_device_send()
+{
+    tapdev_send(uip_buf, uip_len);
+}
+#endif
+
+void Network::handlePacket(void)
+{
+    if (uip_len > 0) {  /* received packet */
+        //printf("handlePacket: %d\n", uip_len);
+
+        if (BUF->type == htons(UIP_ETHTYPE_IP)) { /* IP packet */
+            uip_arp_ipin();
+            uip_input();
+            /* If the above function invocation resulted in data that
+                should be sent out on the network, the global variable
+                uip_len is set to a value > 0. */
+
+            if (uip_len > 0) {
+                uip_arp_out();
+                network_device_send();
+            }
+
+        } else if (BUF->type == htons(UIP_ETHTYPE_ARP)) { /*ARP packet */
+            uip_arp_arpin();
+            /* If the above function invocation resulted in data that
+                should be sent out on the network, the global variable
+                uip_len is set to a value > 0. */
+            if (uip_len > 0) {
+                tapdev_send(uip_buf, uip_len);  /* ARP ack*/
+            }
+
+        } else {
+            printf("Unknown ethernet packet type %04X\n", htons(BUF->type));
+            uip_len = 0;
+        }
+    }
+}
diff --git a/src/libs/Network/uip/Network.h b/src/libs/Network/uip/Network.h
new file mode 100644 (file)
index 0000000..2fd1bf1
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _NETWORK_H
+#define _NETWORK_H
+
+#include "timer.h"
+#include "LPC17XX_Ethernet.h"
+#include "Module.h"
+#include "NetworkPublicAccess.h"
+
+#define network_enable_checksum CHECKSUM("enable")
+#define network_webserver_checksum CHECKSUM("webserver")
+#define network_telnet_checksum CHECKSUM("telnet")
+#define network_mac_override_checksum CHECKSUM("mac_override")
+#define network_ip_address_checksum CHECKSUM("ip_address")
+#define network_ip_gateway_checksum CHECKSUM("ip_gateway")
+#define network_ip_mask_checksum CHECKSUM("ip_mask")
+
+class Network : public Module
+{
+public:
+    Network();
+    virtual ~Network();
+
+    void on_module_loaded();
+    void on_idle(void* argument);
+    void on_main_loop(void* argument);
+    void on_get_public_data(void* argument);
+    void dhcpc_configured(uint32_t ipaddr, uint32_t ipmask, uint32_t ipgw);
+    static Network *getInstance() { return instance;}
+    void tapdev_send(void *pPacket, unsigned int size);
+
+private:
+    void init();
+    uint32_t tick(uint32_t dummy);
+    void handlePacket();
+
+    static Network *instance;
+
+    LPC17XX_Ethernet *ethernet;
+
+    struct timer periodic_timer, arp_timer;
+    uint8_t mac_address[6];
+    uint8_t ipaddr[4];
+    uint8_t ipmask[4];
+    uint8_t ipgw[4];
+    volatile uint32_t tickcnt;
+
+};
+
+#endif
diff --git a/src/libs/Network/uip/NetworkPublicAccess.h b/src/libs/Network/uip/NetworkPublicAccess.h
new file mode 100644 (file)
index 0000000..358da95
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef NETWORKPUBLICACCESS_H
+#define NETWORKPUBLICACCESS_H
+
+#define network_checksum        CHECKSUM("network")
+#define get_ip_checksum         CHECKSUM("getip")
+#define get_ipconfig_checksum   CHECKSUM("getipconfig")
+
+#endif
diff --git a/src/libs/Network/uip/c-fifo.h b/src/libs/Network/uip/c-fifo.h
new file mode 100644 (file)
index 0000000..8632cae
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _CFIFO_H_
+#define _CFIFO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *new_fifo();
+void delete_fifo(void *);
+char *fifo_pop(void *);
+void fifo_push(void *, char *);
+int fifo_size(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/libs/Network/uip/clock-arch.c b/src/libs/Network/uip/clock-arch.c
new file mode 100644 (file)
index 0000000..e7a0e26
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $
+ */
+
+/**
+ * \file
+ *         Implementation of architecture-specific clock functionality
+ * \author
+ *         Adam Dunkels <adam@sics.se>
+ */
+
+#include "clock-arch.h"
+static clock_time_t Ticks;
+
+void do_tick() {
+    Ticks++;
+}
+
+/*---------------------------------------------------------------------------*/
+clock_time_t clock_time(void)
+{
+    return Ticks;
+}
+/*---------------------------------------------------------------------------*/
diff --git a/src/libs/Network/uip/clock-arch.h b/src/libs/Network/uip/clock-arch.h
new file mode 100644 (file)
index 0000000..41ee122
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $
+ */
+
+#ifndef __CLOCK_ARCH_H__
+#define __CLOCK_ARCH_H__
+
+typedef unsigned clock_time_t;
+#define CLOCK_CONF_SECOND 100
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void do_tick();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLOCK_ARCH_H__ */
diff --git a/src/libs/Network/uip/dhcpc/dhcpc.c b/src/libs/Network/uip/dhcpc/dhcpc.c
new file mode 100644 (file)
index 0000000..fc7cfe6
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "uip.h"
+#include "dhcpc.h"
+#include "timer.h"
+#include "pt.h"
+
+#if UIP_CONF_UDP
+
+#define STATE_INITIAL         0
+#define STATE_SENDING         1
+#define STATE_OFFER_RECEIVED  2
+#define STATE_CONFIG_RECEIVED 3
+
+#define ntohl(a) ((((a) >> 24) & 0x000000FF) | (((a) >> 8) & 0x0000FF00) | (((a) << 8) & 0x00FF0000) | (((a) << 24) & 0xFF000000))
+static struct dhcpc_state s __attribute__ ((section ("AHBSRAM1")));
+//#define UIP_CONF_DHCP_LIGHT
+
+struct dhcp_msg {
+    u8_t op, htype, hlen, hops;
+    u8_t xid[4];
+    u16_t secs, flags;
+    u8_t ciaddr[4];
+    u8_t yiaddr[4];
+    u8_t siaddr[4];
+    u8_t giaddr[4];
+    u8_t chaddr[16];
+#ifndef UIP_CONF_DHCP_LIGHT
+    u8_t sname[64];
+    u8_t file[128];
+#endif
+    u8_t options[312];
+};
+
+#define BOOTP_BROADCAST 0x8000
+
+#define DHCP_REQUEST        1
+#define DHCP_REPLY          2
+#define DHCP_HTYPE_ETHERNET 1
+#define DHCP_HLEN_ETHERNET  6
+#define DHCP_MSG_LEN      236
+
+#define DHCPC_SERVER_PORT  67
+#define DHCPC_CLIENT_PORT  68
+
+#define DHCPDISCOVER  1
+#define DHCPOFFER     2
+#define DHCPREQUEST   3
+#define DHCPDECLINE   4
+#define DHCPACK       5
+#define DHCPNAK       6
+#define DHCPRELEASE   7
+
+#define DHCP_OPTION_SUBNET_MASK   1
+#define DHCP_OPTION_ROUTER        3
+#define DHCP_OPTION_DNS_SERVER    6
+#define DHCP_OPTION_REQ_IPADDR   50
+#define DHCP_OPTION_LEASE_TIME   51
+#define DHCP_OPTION_MSG_TYPE     53
+#define DHCP_OPTION_SERVER_ID    54
+#define DHCP_OPTION_REQ_LIST     55
+#define DHCP_OPTION_END         255
+
+static uint32_t xid= 0x00112233;
+
+static const u8_t magic_cookie[4] = {99, 130, 83, 99};
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_msg_type(u8_t *optptr, u8_t type)
+{
+    *optptr++ = DHCP_OPTION_MSG_TYPE;
+    *optptr++ = 1;
+    *optptr++ = type;
+    return optptr;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_server_id(u8_t *optptr)
+{
+    *optptr++ = DHCP_OPTION_SERVER_ID;
+    *optptr++ = 4;
+    memcpy(optptr, &s.serverid, 4);
+    return optptr + 4;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_req_ipaddr(u8_t *optptr)
+{
+    *optptr++ = DHCP_OPTION_REQ_IPADDR;
+    *optptr++ = 4;
+    memcpy(optptr, &s.ipaddr, 4);
+    return optptr + 4;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_req_options(u8_t *optptr)
+{
+    *optptr++ = DHCP_OPTION_REQ_LIST;
+    *optptr++ = 3;
+    *optptr++ = DHCP_OPTION_SUBNET_MASK;
+    *optptr++ = DHCP_OPTION_ROUTER;
+    *optptr++ = DHCP_OPTION_DNS_SERVER;
+    return optptr;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_end(u8_t *optptr)
+{
+    *optptr++ = DHCP_OPTION_END;
+    return optptr;
+}
+/*---------------------------------------------------------------------------*/
+static void
+create_msg(register struct dhcp_msg *m, int rea)
+{
+    m->op = DHCP_REQUEST;
+    m->htype = DHCP_HTYPE_ETHERNET;
+    m->hlen = s.mac_len;
+    m->hops = 0;
+    memcpy(m->xid, &xid, sizeof(m->xid));
+    m->secs = 0;
+    m->flags = HTONS(BOOTP_BROADCAST); /*  Broadcast bit. */
+    /*  uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/
+    if(rea == 0 )  memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr));
+    else memset(m->ciaddr, 0, sizeof(m->ciaddr));
+    memset(m->yiaddr, 0, sizeof(m->yiaddr));
+    memset(m->siaddr, 0, sizeof(m->siaddr));
+    memset(m->giaddr, 0, sizeof(m->giaddr));
+    memcpy(m->chaddr, s.mac_addr, s.mac_len);
+    memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len);
+#ifndef UIP_CONF_DHCP_LIGHT
+    memset(m->sname, 0, sizeof(m->sname));
+    memset(m->file, 0, sizeof(m->file));
+#endif
+
+    memcpy(m->options, magic_cookie, sizeof(magic_cookie));
+}
+/*---------------------------------------------------------------------------*/
+static void
+send_discover(void)
+{
+    u8_t *end;
+    struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+
+    create_msg(m, 0);
+
+    end = add_msg_type(&m->options[4], DHCPDISCOVER);
+    end = add_req_options(end);
+    end = add_end(end);
+
+    uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+}
+/*---------------------------------------------------------------------------*/
+static void
+send_request(int rea)
+{
+    u8_t *end;
+    struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+
+    create_msg(m, rea);
+
+    end = add_msg_type(&m->options[4], DHCPREQUEST);
+    end = add_server_id(end);
+    end = add_req_ipaddr(end);
+    end = add_end(end);
+
+    uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+parse_options(u8_t *optptr, int len)
+{
+    u8_t *end = optptr + len;
+    u8_t type = 0;
+
+    while (optptr < end) {
+        switch (*optptr) {
+            case DHCP_OPTION_SUBNET_MASK:
+                memcpy(&s.netmask, optptr + 2, 4);
+                break;
+            case DHCP_OPTION_ROUTER:
+                memcpy(&s.default_router, optptr + 2, 4);
+                break;
+            case DHCP_OPTION_DNS_SERVER:
+                memcpy(&s.dnsaddr, optptr + 2, 4);
+                break;
+            case DHCP_OPTION_MSG_TYPE:
+                type = *(optptr + 2);
+                break;
+            case DHCP_OPTION_SERVER_ID:
+                memcpy(s.serverid, optptr + 2, 4);
+                break;
+            case DHCP_OPTION_LEASE_TIME:
+                memcpy(&s.lease_time, optptr + 2, 4);
+                break;
+            case DHCP_OPTION_END:
+                return type;
+        }
+
+        optptr += optptr[1] + 2;
+    }
+    return type;
+}
+/*---------------------------------------------------------------------------*/
+u8_t
+parse_msg(void)
+{
+    struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+
+    if (m->op == DHCP_REPLY &&
+        memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
+        memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
+        memcpy(&s.ipaddr, m->yiaddr, 4);
+        return parse_options(&m->options[4], uip_datalen());
+    }
+    return 0;
+}
+/*---------------------------------------------------------------------------*/
+static
+PT_THREAD(handle_dhcp(void))
+{
+    PT_BEGIN(&s.pt);
+
+    /* try_again:*/
+    s.state = STATE_SENDING;
+    s.ticks = CLOCK_SECOND;
+    xid++;
+
+    send_discover();
+    do {
+        timer_set(&s.timer, s.ticks);
+        PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+        // if we timed out then increase time out and send discover again
+        if (timer_expired(&s.timer)) {
+            if (s.ticks < CLOCK_SECOND * 60) {
+                s.ticks *= 2;
+            }
+            send_discover();
+        }else{
+            // we may have gotten some other UDP packet in which case just wait some more for the right packet
+            if (uip_newdata() && parse_msg() == DHCPOFFER) {
+                s.state = STATE_OFFER_RECEIVED;
+                break;
+            }
+        }
+        PT_YIELD(&s.pt);
+
+    } while (s.state != STATE_OFFER_RECEIVED);
+
+    s.ticks = CLOCK_SECOND;
+    xid++;
+
+    send_request(0);
+    do {
+        timer_set(&s.timer, s.ticks);
+        PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+
+        if (timer_expired(&s.timer)) {
+            if (s.ticks <= CLOCK_SECOND * 10) {
+                s.ticks += CLOCK_SECOND;
+                send_request(0); // resend only on timeout
+            } else {
+                PT_RESTART(&s.pt);
+            }
+        }else{
+            if (uip_newdata() && parse_msg() == DHCPACK) {
+                s.state = STATE_CONFIG_RECEIVED;
+                break;
+            }
+        }
+        PT_YIELD(&s.pt);
+
+    } while (s.state != STATE_CONFIG_RECEIVED);
+
+    dhcpc_configured(&s);
+
+    // now we wait for close to expiration and renew the lease
+    do {
+        // we should reacquire expired leases here.
+        timer_set(&s.timer, (ntohl(s.lease_time) * 0.5)*CLOCK_SECOND); // half of lease expire time
+        PT_WAIT_UNTIL(&s.pt, timer_expired(&s.timer));
+
+        uip_log("reaquire dhcp lease");
+
+        // spec says send request direct to server that gave it to us, but seems to be unecessary
+        //uip_ipaddr_copy(&s.conn->ripaddr, s.serverid);
+
+        s.ticks = CLOCK_SECOND;
+        xid++;
+        send_request(0);
+        do {
+            timer_set(&s.timer, s.ticks);
+            PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+
+            if (timer_expired(&s.timer)) {
+                if (s.ticks <= CLOCK_SECOND * 10) {
+                    s.ticks += CLOCK_SECOND;
+                    send_request(0); // resend only on timeout
+                } else {
+                    // give up
+                    // TODO probably need to deal with upstream apps and stop them then reinit them
+                    PT_RESTART(&s.pt);
+                }
+            }else{
+                if (parse_msg() == DHCPACK) {
+                    uip_log("dhcp lease renewed");
+                    break;
+                }
+            }
+            PT_YIELD(&s.pt);
+        }while(1);
+
+    }while(1);
+
+    PT_END(&s.pt);
+}
+/*---------------------------------------------------------------------------*/
+void
+dhcpc_init(const void *mac_addr, int mac_len)
+{
+    uip_ipaddr_t addr;
+
+    s.mac_addr = mac_addr;
+    s.mac_len  = mac_len;
+
+    s.state = STATE_INITIAL;
+    uip_ipaddr(addr, 255, 255, 255, 255);
+    s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT));
+    if (s.conn != NULL) {
+        uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT));
+    }
+    PT_INIT(&s.pt);
+}
+/*---------------------------------------------------------------------------*/
+void
+dhcpc_appcall(void)
+{
+    handle_dhcp();
+}
+/*---------------------------------------------------------------------------*/
+void
+dhcpc_request(void)
+{
+    u16_t ipaddr[2];
+
+    if (s.state == STATE_INITIAL) {
+        uip_ipaddr(ipaddr, 0, 0, 0, 0);
+        uip_sethostaddr(ipaddr);
+        /*    handle_dhcp(PROCESS_EVENT_NONE, NULL);*/
+    }
+}
+/*---------------------------------------------------------------------------*/
+
+#endif
diff --git a/src/libs/Network/uip/dhcpc/dhcpc.h b/src/libs/Network/uip/dhcpc/dhcpc.h
new file mode 100644 (file)
index 0000000..b1b9430
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $
+ */
+#ifndef __DHCPC_H__
+#define __DHCPC_H__
+
+#include "timer.h"
+#include "pt.h"
+
+struct dhcpc_state {
+  struct pt pt;
+  char state;
+  struct uip_udp_conn *conn;
+  struct timer timer;
+  u16_t ticks;
+  const void *mac_addr;
+  int mac_len;
+
+  u8_t serverid[4];
+
+  uint32_t lease_time;
+  uint32_t ipaddr;
+  uint32_t netmask;
+  uint32_t dnsaddr;
+  uint32_t default_router;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void dhcpc_init(const void *mac_addr, int mac_len);
+void dhcpc_request(void);
+
+void dhcpc_appcall(void);
+
+void dhcpc_configured(const struct dhcpc_state *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+typedef struct dhcpc_state uip_udp_appstate_t;
+#define UIP_UDP_APPCALL dhcpc_appcall
+
+
+#endif /* __DHCPC_H__ */
diff --git a/src/libs/Network/uip/fifo.cpp b/src/libs/Network/uip/fifo.cpp
new file mode 100644 (file)
index 0000000..7f20f49
--- /dev/null
@@ -0,0 +1,39 @@
+// c accessibllity to the c++ fifo class
+#include "fifo.h"
+#include "c-fifo.h"
+
+void *new_fifo()
+{
+    return new Fifo<char*>;
+}
+
+void delete_fifo(void *fifo)
+{
+    if(fifo == NULL) return;
+    Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+    while(f->size() > 0) {
+        char *s= f->pop();
+        if (s != NULL) {
+            free(s);
+        }
+    }
+    delete f;
+}
+
+char *fifo_pop(void *fifo)
+{
+    Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+    return f->pop();
+}
+
+void fifo_push(void *fifo, char *str)
+{
+    Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+    f->push(str);
+}
+
+int fifo_size(void *fifo)
+{
+    Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+    return f->size();
+}
diff --git a/src/libs/Network/uip/fifo.h b/src/libs/Network/uip/fifo.h
new file mode 100644 (file)
index 0000000..cd23a3b
--- /dev/null
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * $Author: Jim Morris $
+ * $Date: 1999/02/05 21:05:00 $
+ *
+ * this code is Licensed LGPL
+ *
+ *************************************************************************/
+#ifndef _FIFO_H_
+#define _FIFO_H_
+
+#include <stdlib.h>
+
+// Doubly Linked list class
+
+template<class T> class LList;
+
+template<class T>
+class Tlink
+{
+public:
+    Tlink<T> *pnext;
+    Tlink<T> *pprev;
+
+public:
+    Tlink()
+    {
+        pnext = pprev = 0;
+    }
+    Tlink(Tlink *p, Tlink *n)
+    {
+        pprev = p;
+        pnext = n;
+    }
+    Tlink(const T &d) : data(d)
+    {
+        pnext = pprev = 0;
+    }
+    T data;
+};
+
+template<class T>
+class list_base
+{
+private:
+    Tlink<T> *head;
+    Tlink<T> *tail;
+    int cnt;
+
+protected:
+    list_base()
+    {
+        head = tail = NULL;
+        cnt = 0;
+    }
+
+    list_base(Tlink<T> *n) // link into head of list
+    {
+        cnt = 1;
+        n->pnext = NULL;
+        n->pprev = NULL;
+        head = n;
+        tail = n;
+    }
+
+    Tlink<T> *gethead(void) const
+    {
+        return head;
+    }
+    Tlink<T> *gettail(void) const
+    {
+        return tail;
+    }
+    Tlink<T> *getnext(Tlink<T> *n) const
+    {
+        return n->pnext;
+    }
+    Tlink<T> *getprev(Tlink<T> *n) const
+    {
+        return n->pprev;
+    }
+
+    void addtohead(Tlink<T> *n) // add at head of list
+    {
+        n->pnext = head;
+        n->pprev = NULL;
+        if (head) head->pprev = n;
+        head = n;
+        if (tail == NULL) // first one
+            tail = n;
+        cnt++;
+    }
+
+    void addtohead(int c, Tlink<T> *a, Tlink<T> *b) // add list at head of list
+    {
+        b->pnext = head;
+        a->pprev = NULL;
+        if (head) head->pprev = b;
+        head = a;
+        if (tail == NULL) // first one
+            tail = b;
+        cnt += c;
+    }
+
+    void addtotail(Tlink<T> *n)  // add to tail of list
+    {
+        n->pnext = NULL;
+        n->pprev = tail;
+        if (tail) tail->pnext = n;
+        tail = n;
+        if (head == NULL) // first one
+            head = n;
+        cnt++;
+    }
+
+    void remove(Tlink<T> *n) // remove it by relinking
+    {
+        cnt--;
+        if (n->pprev) n->pprev->pnext = n->pnext;
+        else head = n->pnext; // it must be the head
+        if (n->pnext) n->pnext->pprev = n->pprev;
+        else tail = n->pprev;
+    }
+
+    void reset()
+    {
+        head = tail = NULL;
+        cnt = 0;
+    }
+    int count() const
+    {
+        return cnt;
+    }
+};
+
+// fifo
+template<class T>
+class Fifo : private list_base<T>
+{
+public:
+    Fifo(){}
+
+    void push(const T &a);
+    T pop();
+    T peek();
+    int size() const;
+};
+
+template <class T>
+int Fifo<T>::size() const
+{
+    return list_base<T>::count();
+}
+
+// add to end of list (FIFO)
+template <class T>
+void Fifo<T>::push(const T &a)
+{
+    list_base<T>::addtotail(new Tlink<T>(a));
+}
+
+// return the first item in the list
+template <class T>
+T Fifo<T>::peek()
+{
+    Tlink<T> *p = list_base<T>::gethead();
+    return p->data;
+}
+
+// pop the first item off the fifo
+template <class T>
+T Fifo<T>::pop()
+{
+    Tlink<T> *p = list_base<T>::gethead();
+    T data = p->data;
+    list_base<T>::remove(p);
+    delete p;
+    return data;
+};
+#endif
diff --git a/src/libs/Network/uip/lib/memb.c b/src/libs/Network/uip/lib/memb.c
new file mode 100644 (file)
index 0000000..777b52f
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: memb.c,v 1.1 2006/06/12 08:21:43 adam Exp $
+ */
+
+/**
+ * \addtogroup memb
+ * @{
+ */
+
+ /**
+ * \file
+ * Memory block allocation routines.
+ * \author Adam Dunkels <adam@sics.se>
+ */
+#include <string.h>
+
+#include "memb.h"
+
+/*---------------------------------------------------------------------------*/
+void
+memb_init(struct memb_blocks *m)
+{
+  memset(m->count, 0, m->num);
+  memset(m->mem, 0, m->size * m->num);
+}
+/*---------------------------------------------------------------------------*/
+void *
+memb_alloc(struct memb_blocks *m)
+{
+  int i;
+
+  for(i = 0; i < m->num; ++i) {
+    if(m->count[i] == 0) {
+      /* If this block was unused, we increase the reference count to
+        indicate that it now is used and return a pointer to the
+        memory block. */
+      ++(m->count[i]);
+      return (void *)((char *)m->mem + (i * m->size));
+    }
+  }
+
+  /* No free block was found, so we return NULL to indicate failure to
+     allocate block. */
+  return NULL;
+}
+/*---------------------------------------------------------------------------*/
+char
+memb_free(struct memb_blocks *m, void *ptr)
+{
+  int i;
+  char *ptr2;
+
+  /* Walk through the list of blocks and try to find the block to
+     which the pointer "ptr" points to. */
+  ptr2 = (char *)m->mem;
+  for(i = 0; i < m->num; ++i) {
+    
+    if(ptr2 == (char *)ptr) {
+      /* We've found to block to which "ptr" points so we decrease the
+        reference count and return the new value of it. */
+      if(m->count[i] > 0) {
+       /* Make sure that we don't deallocate free memory. */
+       --(m->count[i]);
+      }
+      return m->count[i];
+    }
+    ptr2 += m->size;
+  }
+  return -1;
+}
+/*---------------------------------------------------------------------------*/
+
+/** @} */
diff --git a/src/libs/Network/uip/lib/memb.h b/src/libs/Network/uip/lib/memb.h
new file mode 100644 (file)
index 0000000..ea2e77c
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: memb.h,v 1.1 2006/06/12 08:21:43 adam Exp $
+ */
+
+/**
+ * \defgroup memb Memory block management functions
+ *
+ * The memory block allocation routines provide a simple yet powerful
+ * set of functions for managing a set of memory blocks of fixed
+ * size. A set of memory blocks is statically declared with the
+ * MEMB() macro. Memory blocks are allocated from the declared
+ * memory by the memb_alloc() function, and are deallocated with the
+ * memb_free() function.
+ *
+ * \note Because of namespace clashes only one MEMB() can be
+ * declared per C module, and the name scope of a MEMB() memory
+ * block is local to each C module.
+ *
+ * The following example shows how to declare and use a memory block
+ * called "cmem" which has 8 chunks of memory with each memory chunk
+ * being 20 bytes large.
+ *
+ * @{
+ */
+
+
+/**
+ * \file
+ *         Memory block allocation routines.
+ * \author
+ *         Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __MEMB_H__
+#define __MEMB_H__
+
+/*
+ * Here we define a C preprocessing macro for concatenating to
+ * strings. We need use two macros in order to allow concatenation of
+ * two #defined macros.
+ */
+#define MEMB_CONCAT2(s1, s2) s1##s2
+#define MEMB_CONCAT(s1, s2) MEMB_CONCAT2(s1, s2)
+
+/**
+ * Declare a memory block.
+ *
+ * This macro is used to staticall declare a block of memory that can
+ * be used by the block allocation functions. The macro statically
+ * declares a C array with a size that matches the specified number of
+ * blocks and their individual sizes.
+ *
+ * Example:
+ \code
+MEMB(connections, sizeof(struct connection), 16);
+ \endcode
+ *
+ * \param name The name of the memory block (later used with
+ * memb_init(), memb_alloc() and memb_free()).
+ *
+ * \param size The size of each memory chunk, in bytes.
+ *
+ * \param num The total number of memory chunks in the block.
+ *
+ */
+#define MEMB(name, structure, num)  static char MEMB_CONCAT(name,_memb_count)[num]; \
+                                    static structure MEMB_CONCAT(name,_memb_mem)[num]; \
+                                    static struct memb_blocks name = {sizeof(structure), num, MEMB_CONCAT(name,_memb_count), (void *)MEMB_CONCAT(name,_memb_mem) }
+
+
+
+struct memb_blocks {
+  unsigned short size;
+  unsigned short num;
+  char *count;
+  void *mem;
+};
+
+/**
+ * Initialize a memory block that was declared with MEMB().
+ *
+ * \param m A memory block previosly declared with MEMB().
+ */
+void  memb_init(struct memb_blocks *m);
+
+/**
+ * Allocate a memory block from a block of memory declared with MEMB().
+ *
+ * \param m A memory block previosly declared with MEMB().
+ */
+void *memb_alloc(struct memb_blocks *m);
+
+/**
+ * Deallocate a memory block from a memory block previously declared
+ * with MEMB().
+ *
+ * \param m m A memory block previosly declared with MEMB().
+ *
+ * \param ptr A pointer to the memory block that is to be deallocated.
+ *
+ * \return The new reference count for the memory block (should be 0
+ * if successfully deallocated) or -1 if the pointer "ptr" did not
+ * point to a legal memory block.
+ */
+char  memb_free(struct memb_blocks *m, void *ptr);
+
+/** @} */
+
+#endif /* __MEMB_H__ */
diff --git a/src/libs/Network/uip/sftp/sftpd.cpp b/src/libs/Network/uip/sftp/sftpd.cpp
new file mode 100644 (file)
index 0000000..02a76e1
--- /dev/null
@@ -0,0 +1,228 @@
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+
+#include "sftpd.h"
+#include "string.h"
+#include "stdlib.h"
+
+extern "C" {
+#include "uip.h"
+}
+
+#define ISO_nl 0x0a
+#define ISO_cr 0x0d
+#define ISO_sp 0x20
+
+#define DEBUG_PRINTF(...)
+
+Sftpd::Sftpd()
+{
+    fd = NULL;
+    state = STATE_NORMAL;
+    outbuf = NULL;
+    filename= NULL;
+}
+
+Sftpd::~Sftpd()
+{
+    if (fd != NULL) {
+        fclose(fd);
+    }
+}
+
+int Sftpd::senddata()
+{
+    if (outbuf != NULL) {
+        DEBUG_PRINTF("sftp: senddata %s\n", outbuf);
+        strcpy((char *)uip_appdata, outbuf);
+        uip_send(uip_appdata, strlen(outbuf));
+    }
+    return 0;
+}
+
+int Sftpd::handle_command()
+{
+    PSOCK_BEGIN(&sin);
+
+    do {
+        PSOCK_READTO(&sin, ISO_nl);
+        buf[PSOCK_DATALEN(&sin) - 1] = 0;
+        int len = PSOCK_DATALEN(&sin) - 1;
+        DEBUG_PRINTF("sftp: got command: %s, %d\n", buf, len);
+
+        if (state == STATE_CONNECTED) {
+            if (strncmp(buf, "USER", 4) == 0) {
+                outbuf = "!user logged in\n";
+
+            } else if (strncmp(buf, "KILL", 4) == 0) {
+                if (len < 6) {
+                    outbuf = "- incomplete KILL command\n";
+                } else {
+                    char *fn = &buf[5];
+                    int s = remove(fn);
+                    if (s == 0) outbuf = "+ deleted\n";
+                    else outbuf = "- delete failed\n";
+                }
+
+            } else if (strncmp(buf, "DONE", 4) == 0) {
+                outbuf = "+ exit\n";
+                state = STATE_CLOSE;
+
+            } else if (strncmp(buf, "STOR", 4) == 0) {
+                if (len < 11) {
+                    outbuf = "- incomplete STOR command\n";
+                } else {
+                    char *fn = &buf[9];
+                    if(this->filename != NULL) free(this->filename);
+                    this->filename= strdup(fn); // REMOVE when bug fixed
+                    // get { NEW|OLD|APP }
+                    if (strncmp(&buf[5], "OLD", 3) == 0) {
+                        DEBUG_PRINTF("sftp: Opening file: %s\n", fn);
+                        fd = fopen(fn, "w");
+                        if (fd != NULL) {
+                            outbuf = "+ new file\n";
+                            state = STATE_GET_LENGTH;
+                        } else {
+                            outbuf = "- failed\n";
+                        }
+                    } else if (strncmp(&buf[5], "APP", 3) == 0) {
+                        fd = fopen(fn, "a");
+                        if (fd != NULL) {
+                            outbuf = "+ append file\n";
+                            state = STATE_GET_LENGTH;
+                        } else {
+                            outbuf = "- failed\n";
+                        }
+                    } else {
+                        outbuf = "- Only OLD|APP supported\n";
+                    }
+                }
+
+            } else {
+                outbuf = "- Unknown command\n";
+            }
+
+        } else if (state == STATE_GET_LENGTH) {
+            if (len < 6 || strncmp(buf, "SIZE", 4) != 0) {
+                fclose(fd);
+                fd = NULL;
+                outbuf = "- Expected size\n";
+                state = STATE_CONNECTED;
+
+            } else {
+                filesize = atoi(&buf[5]);
+                if (filesize > 0) {
+                    outbuf = "+ ok, waiting for file\n";
+                    state = STATE_DOWNLOAD;
+                } else {
+                    fclose(fd);
+                    fd = NULL;
+                    outbuf = "- bad filesize\n";
+                    state = STATE_CONNECTED;
+                }
+            }
+
+        } else {
+            DEBUG_PRINTF("WTF state: %d\n", state);
+        }
+
+    } while(state == STATE_CONNECTED || state == STATE_GET_LENGTH);
+
+    PSOCK_END(&sin);
+}
+
+int Sftpd::handle_download()
+{
+    // Note this is not using PSOCK and it consumes all read data
+    char *readptr = (char *)uip_appdata;
+    unsigned int readlen = uip_datalen();
+    DEBUG_PRINTF("sftp: starting download, expecting %d bytes, read %d\n", filesize, readlen);
+
+    if (filesize > 0 && readlen > 0) {
+        if (readlen > filesize) readlen = filesize;
+        if (fwrite(readptr, 1, readlen, fd) != readlen) {
+            DEBUG_PRINTF("sftp: Error writing file\n");
+            fclose(fd);
+            fd = NULL;
+            outbuf = "- Error saving file\n";
+            state = STATE_CONNECTED;
+            return 0;
+        }
+        filesize -= readlen;
+        DEBUG_PRINTF("sftp: saved %d bytes %d left\n", readlen, filesize);
+        // HACK ALERT... to work around the fwrite/filesystem bug where writing large amounts of data corrupts the file
+        // we workaround by closing the file, the reopening for append until we are done
+        fclose(fd);
+        fd = fopen(this->filename, "a");
+    }
+    if (filesize == 0) {
+        DEBUG_PRINTF("sftp: download complete\n");
+        fclose(fd);
+        fd = NULL;
+        outbuf = "+ Saved file\n";
+        state = STATE_CONNECTED;
+        return 0;
+    }
+    return 1;
+}
+
+int Sftpd::acked()
+{
+    outbuf= NULL;
+    return 0;
+}
+
+
+void Sftpd::appcall(void)
+{
+    if (uip_connected()) {
+        // TODO check for other connections
+        PSOCK_INIT(&sin, buf, sizeof(buf));
+        state = STATE_CONNECTED;
+        outbuf = "+Smoothie SFTP Service\n";
+    }
+
+    if (state == STATE_CLOSE) {
+        DEBUG_PRINTF("sftp: state close\n");
+        state = STATE_NORMAL;
+        uip_close();
+        return;
+    }
+
+    if (uip_closed() || uip_aborted() || uip_timedout()) {
+        DEBUG_PRINTF("sftp: closed\n");
+        if (fd != NULL)
+            fclose(fd);
+        fd = NULL;
+        state = STATE_NORMAL;
+        return;
+    }
+
+    if (uip_acked()) {
+        DEBUG_PRINTF("sftp: acked\n");
+        this->acked();
+    }
+
+    if (uip_newdata()) {
+        DEBUG_PRINTF("sftp: newdata\n");
+        if (state == STATE_DOWNLOAD) {
+            if(handle_download() == 0) {
+                // we need to reset the input PSOCK again before using it after using the raw input buffer
+                PSOCK_INIT(&sin, buf, sizeof(buf));
+            }
+        } else {
+            handle_command();
+        }
+    }
+
+    if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) {
+        this->senddata();
+    }
+
+}
+
+void Sftpd::init(void)
+{
+
+}
+
+
diff --git a/src/libs/Network/uip/sftp/sftpd.h b/src/libs/Network/uip/sftp/sftpd.h
new file mode 100644 (file)
index 0000000..02abced
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __SFTPD_H__
+#define __SFTPD_H__
+
+/*
+ * Implement RFC913  Simple File Transfer
+ */
+
+
+#include <stdio.h>
+extern "C" {
+#include "psock.h"
+}
+
+class Sftpd
+{
+public:
+    Sftpd();
+    virtual ~Sftpd();
+
+    void appcall(void);
+    void init(void);
+
+private:
+    FILE *fd;
+    enum STATES { STATE_NORMAL, STATE_CONNECTED, STATE_GET_LENGTH, STATE_DOWNLOAD, STATE_CLOSE };
+    STATES state;
+    int acked();
+    int handle_command();
+    int handle_download();
+    int senddata();
+
+    struct psock sin;
+    char buf[80];
+    const char *outbuf;
+    unsigned int filesize;
+    char *filename;
+};
+
+#endif /* __sftpd_H__ */
diff --git a/src/libs/Network/uip/telnetd/shell.cpp b/src/libs/Network/uip/telnetd/shell.cpp
new file mode 100644 (file)
index 0000000..46b0f93
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+* Copyright (c) 2003, Adam Dunkels.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+* 3. The name of the author may not be used to endorse or promote
+*    products derived from this software without specific prior
+*    written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* This file is part of the uIP TCP/IP stack.
+*
+* $Id: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $
+*
+*/
+
+#include "stdlib.h"
+#include "shell.h"
+#include "uip.h"
+#include <string.h>
+#include "checksumm.h"
+#include "utils.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "telnetd.h"
+#include "CallbackStream.h"
+#include "Kernel.h"
+
+//#define DEBUG_PRINTF(...)
+#define DEBUG_PRINTF printf
+
+struct ptentry {
+    uint16_t command_cs;
+    void (* pfunc)(char *str, Shell *sh);
+};
+
+#define SHELL_PROMPT "> "
+
+/*---------------------------------------------------------------------------*/
+bool Shell::parse(register char *str, struct ptentry *t)
+{
+    struct ptentry *p;
+    for (p = t; p->command_cs != 0; ++p) {
+        if (get_checksum(str) == p->command_cs) {
+            break;
+        }
+    }
+
+    p->pfunc(str, this);
+
+    return p->command_cs != 0;
+}
+/*---------------------------------------------------------------------------*/
+static void help(char *str, Shell *sh)
+{
+    sh->output("Available commands: All others are passed on\n");
+    sh->output("netstat     - show network info\n");
+    sh->output("?           - show network help\n");
+    sh->output("help        - show command help\n");
+    sh->output("exit, quit  - exit shell\n");
+}
+
+/*---------------------------------------------------------------------------*/
+static const char *states[] = {
+    "CLOSED",
+    "SYN_RCVD",
+    "SYN_SENT",
+    "ESTABLISHED",
+    "FIN_WAIT_1",
+    "FIN_WAIT_2",
+    "CLOSING",
+    "TIME_WAIT",
+    "LAST_ACK",
+    "NONE",
+    "RUNNING",
+    "CALLED"
+};
+static void connections(char *str, Shell *sh)
+{
+    char istr[128];
+    struct uip_conn *connr;
+    snprintf(istr, sizeof(istr), "Initial MSS: %d, MSS: %d\n", uip_initialmss(), uip_mss());
+    sh->output(istr);
+    sh->output("Current connections: \n");
+
+    for (connr = &uip_conns[0]; connr <= &uip_conns[UIP_CONNS - 1]; ++connr) {
+        if(connr->tcpstateflags != UIP_CLOSED) {
+            snprintf(istr, sizeof(istr), "%d, %u.%u.%u.%u:%u, %s, %u, %u, %c %c\n",
+                     HTONS(connr->lport),
+                     uip_ipaddr1(connr->ripaddr), uip_ipaddr2(connr->ripaddr),  uip_ipaddr3(connr->ripaddr), uip_ipaddr4(connr->ripaddr),
+                     HTONS(connr->rport),
+                     states[connr->tcpstateflags & UIP_TS_MASK],
+                     connr->nrtx,
+                     connr->timer,
+                     (uip_outstanding(connr)) ? '*' : ' ',
+                     (uip_stopped(connr)) ? '!' : ' ');
+
+            sh->output(istr);
+        }
+    }
+}
+
+static void quit(char *str, Shell *sh)
+{
+    sh->close();
+}
+
+//#include "clock.h"
+static void test(char *str, Shell *sh)
+{
+    printf("In Test\n");
+
+    // struct timer t;
+    // u16_t ticks=  CLOCK_SECOND*5;
+    // timer_set(&t, ticks);
+    // printf("Wait....\n");
+    // while(!timer_expired(&t)) {
+
+    // }
+    // printf("Done\n");
+    /*
+        const char *fn= "/sd/test6.txt";
+        uint16_t *buf= (uint16_t *)malloc(200*2);
+        int cnt= 0;
+        FILE *fp;
+        for(int i=0;i<10;i++) {
+            fp= fopen(fn, i == 0 ? "w" : "a");
+            if(fp == NULL) {
+                printf("failed to open file\n");
+                return;
+            }
+            for (int x = 0; x < 200; ++x) {
+                buf[x]= x+cnt;
+            }
+            cnt+=200;
+            int n= fwrite(buf, 2, 200, fp);
+            printf("wrote %d, %d\n", i, n);
+            fclose(fp);
+        }
+
+        fp= fopen(fn, "r");
+        if(fp == NULL) {
+            printf("failed to open file for read\n");
+            return;
+        }
+        printf("Opened file %s for read\n", fn);
+        do {
+            int n= fread(buf, 2, 200, fp);
+            if(n <= 0) break;
+            for(int x=0;x<n;x++) {
+                printf("%04X, ", buf[x]);
+            }
+        }while(1);
+        fclose(fp);
+        free(buf);
+        */
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void unknown(char *str, Shell *sh)
+{
+    // its some other command, so queue it for mainloop to find
+    if (strlen(str) > 0) {
+        CommandQueue::getInstance()->add(str, sh->getStream());
+    }
+}
+/*---------------------------------------------------------------------------*/
+static struct ptentry parsetab[] = {
+    {CHECKSUM("netstat"), connections},
+    {CHECKSUM("exit"), quit},
+    {CHECKSUM("quit"), quit},
+    {CHECKSUM("test"), test},
+    {CHECKSUM("?"), help},
+
+    /* Default action */
+    {0, unknown}
+};
+/*---------------------------------------------------------------------------*/
+// this callback gets the results of a command, line by line
+// NULL means command completed
+// static
+int Shell::command_result(const char *str, void *p)
+{
+    // FIXME problem when shell is deleted and this gets called from slow command
+    // need a way to know this shell was closed or deleted
+    Shell *sh = (Shell *)p;
+    if (str == NULL) {
+        // indicates command is complete
+        // only prompt when command is completed
+        sh->telnet->output_prompt(SHELL_PROMPT);
+        return 0;
+
+    } else {
+        if (sh->telnet->can_output()) {
+            if (sh->telnet->output(str) == -1) return -1; // connection was closed
+            return 1;
+        }
+        // we are stalled
+        return 0;
+    }
+}
+
+/*---------------------------------------------------------------------------*/
+void Shell::start()
+{
+    telnet->output("Smoothie command shell\r\n> ");
+}
+
+int Shell::queue_size()
+{
+    return CommandQueue::getInstance()->size();
+}
+/*---------------------------------------------------------------------------*/
+void Shell::input(char *cmd)
+{
+    if (parse(cmd, parsetab)) {
+        telnet->output_prompt(SHELL_PROMPT);
+    }
+}
+/*---------------------------------------------------------------------------*/
+
+int Shell::output(const char *str)
+{
+    return telnet->output(str);
+}
+
+void Shell::close()
+{
+    telnet->close();
+}
+
+void Shell::setConsole()
+{
+    // add it to the kernels output stream if we are a console
+    // TODO do we do this for all connections? so pronterface will get file done when playing from M24?
+    // then we need to turn it off for the streaming app
+    DEBUG_PRINTF("Shell: Adding stream to kernel streams\n");
+    THEKERNEL->streams->append_stream(pstream);
+    isConsole= true;
+}
+
+Shell::Shell(Telnetd *telnet)
+{
+    DEBUG_PRINTF("Shell: ctor %p - %p\n", this, telnet);
+    this->telnet= telnet;
+    // create a callback StreamOutput for this connection
+    pstream = new CallbackStream(command_result, this);
+    isConsole= false;
+}
+
+Shell::~Shell()
+{
+    if(isConsole) {
+        DEBUG_PRINTF("Shell: Removing stream from kernel streams\n");
+        THEKERNEL->streams->remove_stream(pstream);
+    }
+    // we cannot delete this stream until it is no longer in any command queue entries
+    // so mark it as closed, and allow it to delete itself when it is no longer being used
+    static_cast<CallbackStream*>(pstream)->mark_closed(); // mark the stream as closed so we do not get any callbacks
+    DEBUG_PRINTF("Shell: dtor %p\n", this);
+}
diff --git a/src/libs/Network/uip/telnetd/shell.h b/src/libs/Network/uip/telnetd/shell.h
new file mode 100644 (file)
index 0000000..5bc797f
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * \file
+ * Interface for the Contiki shell.
+ * \author Adam Dunkels <adam@dunkels.com>
+ *
+ * Some of the functions declared in this file must be implemented as
+ * a shell back-end in the architecture specific files of a Contiki
+ * port.
+ */
+
+
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the Contiki desktop OS.
+ *
+ * $Id: shell.h,v 1.1 2006/06/07 09:43:54 adam Exp $
+ *
+ */
+#ifndef __SHELL_H__
+#define __SHELL_H__
+
+#include "telnetd.h"
+#include "CommandQueue.h"
+
+class Telnetd;
+
+class Shell
+{
+public:
+    Shell(Telnetd *telnet);
+    ~Shell();
+
+    /**
+     * Start the shell back-end.
+     *
+     * Called by the front-end when a new shell is started.
+     */
+    void start(void);
+
+    /**
+     * Process a shell command.
+     *
+     * This function will be called by the shell GUI / telnet server whan
+     * a command has been entered that should be processed by the shell
+     * back-end.
+     *
+     * \param command The command to be processed.
+     */
+    void input(char *command);
+
+    int output(const char *str);
+    void close();
+
+    /**
+     * Print a prompt to the shell window.
+     *
+     * This function can be used by the shell back-end to print out a
+     * prompt to the shell window.
+     *
+     * \param prompt The prompt to be printed.
+     *
+     */
+    void prompt(const char *prompt);
+
+    int queue_size();
+    int can_output();
+    static int command_result(const char *str, void *ti);
+    StreamOutput *getStream() { return pstream; }
+    void setConsole();
+
+private:
+    bool parse(register char *str, struct ptentry *t);
+    Telnetd *telnet; // telnet instance we are connected to
+    StreamOutput *pstream;
+    bool isConsole;
+};
+
+#endif /* __SHELL_H__ */
diff --git a/src/libs/Network/uip/telnetd/telnetd.cpp b/src/libs/Network/uip/telnetd/telnetd.cpp
new file mode 100644 (file)
index 0000000..e0bbf9a
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $
+ *
+ */
+
+#include "uip.h"
+#include "telnetd.h"
+#include "shell.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define ISO_nl       0x0a
+#define ISO_cr       0x0d
+
+#define STATE_NORMAL 0
+#define STATE_IAC    1
+#define STATE_WILL   2
+#define STATE_WONT   3
+#define STATE_DO     4
+#define STATE_DONT   5
+#define STATE_CLOSE  6
+
+#define TELNET_IAC   255
+#define TELNET_WILL  251
+#define TELNET_WONT  252
+#define TELNET_DO    253
+#define TELNET_DONT  254
+
+#define TELNET_LINEMODE 0x22
+#define TELNET_GA       0x03
+#define TELNET_X_PROMPT 0x55
+
+//#define DEBUG_PRINTF(...)
+#define DEBUG_PRINTF printf
+
+static char *alloc_line(int size)
+{
+    return (char *)malloc(size);
+}
+
+static void dealloc_line(char *line)
+{
+    free(line);
+}
+
+void Telnetd::close()
+{
+    state = STATE_CLOSE;
+}
+
+int Telnetd::sendline(char *line)
+{
+    int i;
+    for (i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+        if (lines[i] == NULL) {
+            lines[i] = line;
+            return i;
+        }
+    }
+    if (i == TELNETD_CONF_NUMLINES) {
+        dealloc_line(line);
+    }
+    return TELNETD_CONF_NUMLINES;
+}
+
+void Telnetd::output_prompt(const char *str)
+{
+    if(prompt) output(str);
+}
+
+int Telnetd::output(const char *str)
+{
+    if(state == STATE_CLOSE) return -1;
+
+    unsigned chunk = 256; // small chunk size so we don't allocate huge blocks, and must be less than mss
+    unsigned len = strlen(str);
+    char *line;
+    if (len < chunk) {
+        // can be sent in one tcp buffer
+        line = alloc_line(len + 1);
+        if (line != NULL) {
+            strcpy(line, str);
+            return sendline(line);
+        }else{
+            // out of memory treat like full
+            return TELNETD_CONF_NUMLINES;
+        }
+    } else {
+        // need to split line over multiple send lines
+        int size = chunk; // size to copy
+        int off = 0;
+        int n= 0;
+        while (len >= chunk) {
+            line = alloc_line(chunk + 1);
+            if (line != NULL) {
+                memcpy(line, str + off, size);
+                line[size] = 0;
+                n= sendline(line);
+                len -= size;
+                off += size;
+            }else{
+                // out of memory treat like full
+                return TELNETD_CONF_NUMLINES;
+            }
+        }
+        if (len > 0) {
+            // send rest
+            line = alloc_line(len + 1);
+            if (line != NULL) {
+                strcpy(line, str + off);
+                n= sendline(line);
+            }else{
+                // out of memory treat like full
+                return TELNETD_CONF_NUMLINES;
+            }
+        }
+        return n;
+    }
+}
+
+// check if we can queue or if queue is full
+int Telnetd::can_output()
+{
+    if(state == STATE_CLOSE) return -1;
+
+    int i;
+    int cnt = 0;
+    for (i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+        if (lines[i] == NULL) cnt++;
+    }
+    return cnt < 4 ? 0 : 1;
+}
+
+void Telnetd::acked(void)
+{
+    while (numsent > 0) {
+        dealloc_line(lines[0]);
+        for (int i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
+            lines[i - 1] = lines[i];
+        }
+        lines[TELNETD_CONF_NUMLINES - 1] = NULL;
+        --numsent;
+    }
+}
+
+void Telnetd::senddata(void)
+{
+    // NOTE this sends as many lines as it can fit in one tcp frame
+    // we need to keep the lines under the size of the tcp frame
+    char *bufptr, *lineptr;
+    int buflen, linelen;
+
+    bufptr = (char *)uip_appdata;
+    buflen = 0;
+    for (numsent = 0; numsent < TELNETD_CONF_NUMLINES && lines[numsent] != NULL ; ++numsent) {
+        lineptr = lines[numsent];
+        linelen = strlen(lineptr);
+        if (buflen + linelen < uip_mss()) {
+            memcpy(bufptr, lineptr, linelen);
+            bufptr += linelen;
+            buflen += linelen;
+        } else {
+            break;
+        }
+    }
+    uip_send(uip_appdata, buflen);
+}
+
+void Telnetd::get_char(u8_t c)
+{
+    if (c == ISO_cr) {
+        return;
+    }
+
+    buf[(int)bufptr] = c;
+    if (buf[(int)bufptr] == ISO_nl || bufptr == sizeof(buf) - 1) {
+        if (bufptr > 0) {
+            buf[(int)bufptr] = 0;
+        }
+        shell->input(buf);
+        bufptr = 0;
+
+    } else {
+        ++bufptr;
+    }
+}
+
+// static void sendopt(u8_t option, u8_t value)
+// {
+//     char *line;
+//     line = alloc_line(4);
+//     if (line != NULL) {
+//         line[0] = TELNET_IAC;
+//         line[1] = option;
+//         line[2] = value;
+//         line[3] = 0;
+//         sendline(line);
+//     }
+// }
+
+void Telnetd::newdata(void)
+{
+    u16_t len;
+    u8_t c;
+    char *dataptr;
+
+    len = uip_datalen();
+    dataptr = (char *)uip_appdata;
+
+    while (len > 0 && bufptr < sizeof(buf)) {
+        c = *dataptr;
+        ++dataptr;
+        --len;
+        switch (state) {
+            case STATE_IAC:
+                if (c == TELNET_IAC) {
+                    get_char(c);
+                    state = STATE_NORMAL;
+                } else {
+                    switch (c) {
+                        case TELNET_WILL:
+                            state = STATE_WILL;
+                            break;
+                        case TELNET_WONT:
+                            state = STATE_WONT;
+                            break;
+                        case TELNET_DO:
+                            state = STATE_DO;
+                            break;
+                        case TELNET_DONT:
+                            state = STATE_DONT;
+                            break;
+                        default:
+                            state = STATE_NORMAL;
+                            break;
+                    }
+                }
+                break;
+            case STATE_WILL:
+                if (c == TELNET_LINEMODE) {
+                    //sendopt(TELNET_DO, c);
+                }
+                state = STATE_NORMAL;
+                break;
+
+            case STATE_WONT:
+                /* Reply with a DONT */
+                //sendopt(TELNET_DONT, c);
+                state = STATE_NORMAL;
+                break;
+            case STATE_DO:
+               if (c == TELNET_X_PROMPT) {
+                    prompt= true;
+                }else if (c == TELNET_GA) {
+                    // enable prompt if telnet client running
+                    prompt= true;
+                    shell->setConsole(); // tell shell we are a console, as this is sent be telnet clients
+                }else{
+                     /* Reply with a WONT */
+                    //sendopt(TELNET_WONT, c);
+                }
+                state = STATE_NORMAL;
+                break;
+            case STATE_DONT:
+                if (c == TELNET_X_PROMPT) {
+                    prompt= false;
+                }else{
+                    /* Reply with a WONT */
+                    //sendopt(TELNET_WONT, c);
+                }
+                state = STATE_NORMAL;
+                break;
+            case STATE_NORMAL:
+                if (c == TELNET_IAC) {
+                    state = STATE_IAC;
+                } else {
+                    get_char(c);
+                }
+                break;
+        }
+    }
+
+    // if the command queue is getting too big we stop TCP
+    if(shell->queue_size() > 20) {
+        DEBUG_PRINTF("Telnet: stopped: %d\n", shell->queue_size());
+        uip_stop();
+    }
+}
+
+void Telnetd::poll()
+{
+    if(first_time) {
+        first_time= false;
+        shell->start();
+        senddata();
+    }
+}
+
+Telnetd::Telnetd()
+{
+    DEBUG_PRINTF("Telnetd: ctor %p\n", this);
+    for (int i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+        lines[i] = NULL;
+    }
+
+    first_time= true;
+    bufptr = 0;
+    state = STATE_NORMAL;
+    prompt= false;
+    shell= new Shell(this);
+}
+
+Telnetd::~Telnetd()
+{
+    DEBUG_PRINTF("Telnetd: dtor %p\n", this);
+    for (int i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+        if (lines[i] != NULL) dealloc_line(lines[i]);
+    }
+    delete shell;
+}
+
+// static
+void Telnetd::appcall(void)
+{
+    Telnetd *instance= reinterpret_cast<Telnetd *>(uip_conn->appstate);
+
+    if (uip_connected()) {
+        // create a new telnet class instance
+        instance= new Telnetd;
+        DEBUG_PRINTF("Telnetd new instance: %p\n", instance);
+        uip_conn->appstate= instance; // and store it in the appstate of the connection
+        instance->rport= uip_conn->rport;
+    }
+
+    if (uip_closed() || uip_aborted() || uip_timedout()) {
+        DEBUG_PRINTF("Telnetd: closed: %p\n", instance);
+        if(instance != NULL) {
+            delete instance;
+            uip_conn->appstate= NULL;
+        }
+        return;
+    }
+
+    // sanity check
+    if(instance == NULL || instance->rport != uip_conn->rport) {
+        DEBUG_PRINTF("Telnetd: ERROR Null instance or rport is wrong: %p - %u, %d\n", instance, HTONS(uip_conn->rport), uip_flags);
+        uip_abort();
+        return;
+    }
+
+    if (instance->state == STATE_CLOSE) {
+        uip_close();
+    }
+
+
+    if (uip_acked()) {
+        instance->acked();
+    }
+
+    if (uip_newdata()) {
+        instance->newdata();
+    }
+
+    if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) {
+        instance->senddata();
+    }
+
+    if(uip_poll() && uip_stopped(uip_conn) && instance->shell->queue_size() < 5) {
+        DEBUG_PRINTF("restarted %d - %p\n", instance->shell->queue_size(), instance);
+        uip_restart();
+    }
+
+    if(uip_poll()) {
+        instance->poll();
+    }
+}
+
+// static
+void Telnetd::init(void)
+{
+    uip_listen(HTONS(23));
+}
diff --git a/src/libs/Network/uip/telnetd/telnetd.h b/src/libs/Network/uip/telnetd/telnetd.h
new file mode 100644 (file)
index 0000000..51162b2
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: telnetd.h,v 1.2 2006/06/07 09:43:54 adam Exp $
+ *
+ */
+#ifndef __TELNETD_H__
+#define __TELNETD_H__
+
+#include "shell.h"
+#include "stdint.h"
+
+class Shell;
+
+class Telnetd
+{
+public:
+    Telnetd();
+    ~Telnetd();
+
+    static void init(void);
+    static void appcall(void);
+
+    void output_prompt(const char *str);
+    int output(const char *str);
+    int can_output();
+    void close();
+
+private:
+    static const int TELNETD_CONF_MAXCOMMANDLENGTH= 132;
+    static const int TELNETD_CONF_NUMLINES= 32;
+
+    Shell *shell;
+
+    // FIXME this needs to be a FIFO
+    char *lines[TELNETD_CONF_NUMLINES];
+    char buf[TELNETD_CONF_MAXCOMMANDLENGTH];
+    char bufptr;
+    uint8_t numsent;
+    uint8_t state;
+    uint16_t rport;
+
+    bool prompt;
+
+    bool first_time;
+
+    int sendline(char *line);
+    void acked(void);
+    void senddata(void);
+    void get_char(uint8_t c);
+    void newdata(void);
+    void poll(void);
+
+};
+
+#endif /* __TELNETD_H__ */
diff --git a/src/libs/Network/uip/uip-conf.h b/src/libs/Network/uip/uip-conf.h
new file mode 100644 (file)
index 0000000..c80e522
--- /dev/null
@@ -0,0 +1,168 @@
+/**
+ * \addtogroup uipopt
+ * @{
+ */
+
+/**
+ * \name Project-specific configuration options
+ * @{
+ *
+ * uIP has a number of configuration options that can be overridden
+ * for each project. These are kept in a project-specific uip-conf.h
+ * file and all configuration names have the prefix UIP_CONF.
+ */
+
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
+ */
+
+/**
+ * \file
+ *         An example uIP configuration file
+ * \author
+ *         Adam Dunkels <adam@sics.se>
+ */
+
+#ifndef __UIP_CONF_H__
+#define __UIP_CONF_H__
+
+#include <inttypes.h>
+
+/**
+ * 8 bit datatype
+ *
+ * This typedef defines the 8-bit type used throughout uIP.
+ *
+ * \hideinitializer
+ */
+typedef uint8_t u8_t;
+
+/**
+ * 16 bit datatype
+ *
+ * This typedef defines the 16-bit type used throughout uIP.
+ *
+ * \hideinitializer
+ */
+typedef uint16_t u16_t;
+
+/**
+ * Statistics datatype
+ *
+ * This typedef defines the dataype used for keeping statistics in
+ * uIP.
+ *
+ * \hideinitializer
+ */
+typedef unsigned short uip_stats_t;
+
+/**
+ * Maximum number of TCP connections.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_MAX_CONNECTIONS 6
+
+/**
+ * Maximum number of listening TCP ports.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_MAX_LISTENPORTS 6
+
+/**
+ * uIP buffer size.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_BUFFER_SIZE     400
+
+#define UIP_CONF_BROADCAST 1
+
+/**
+ * CPU byte order.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_BYTE_ORDER      LITTLE_ENDIAN
+
+/**
+ * Logging on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_LOGGING         1
+
+/**
+ * UDP support on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_UDP             1
+#define UIP_CONF_UDP_CONNS 4
+/**
+ * UDP checksums on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_UDP_CHECKSUMS   0
+
+/**
+ * uIP statistics on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_STATISTICS      0
+
+#ifdef __cplusplus
+extern "C" void app_select_appcall(void);
+#else
+extern void app_select_appcall(void);
+#endif
+
+#define UIP_APPCALL app_select_appcall
+typedef void* uip_tcp_appstate_t;
+
+/* Here we include the header file for the application(s) we use in
+   our project. */
+/*#include "smtp.h"*/
+//#include "hello-world.h"
+// #include "telnetd.h"
+// #include "webserver.h"
+#include "dhcpc.h"
+/*#include "resolv.h"*/
+/*#include "webclient.h"*/
+
+#endif /* __UIP_CONF_H__ */
+
+/** @} */
+/** @} */
diff --git a/src/libs/Network/uip/uip/clock.h b/src/libs/Network/uip/uip/clock.h
new file mode 100644 (file)
index 0000000..6a28503
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * \defgroup clock Clock interface
+ *
+ * The clock interface is the interface between the \ref timer "timer library"
+ * and the platform specific clock functionality. The clock
+ * interface must be implemented for each platform that uses the \ref
+ * timer "timer library".
+ *
+ * The clock interface does only one this: it measures time. The clock
+ * interface provides a macro, CLOCK_SECOND, which corresponds to one
+ * second of system time.
+ *
+ * \sa \ref timer "Timer library"
+ *
+ * @{
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $
+ */
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+#include "clock-arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize the clock library.
+ *
+ * This function initializes the clock library and should be called
+ * from the main() function of the system.
+ *
+ */
+void clock_init(void);
+
+/**
+ * Get the current clock time.
+ *
+ * This function returns the current system clock time.
+ *
+ * \return The current clock time, measured in system ticks.
+ */
+clock_time_t clock_time(void);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * A second, measured in system clock time.
+ *
+ * \hideinitializer
+ */
+#ifdef CLOCK_CONF_SECOND
+#define CLOCK_SECOND CLOCK_CONF_SECOND
+#else
+#define CLOCK_SECOND (clock_time_t)32
+#endif
+
+#endif /* __CLOCK_H__ */
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/lc-addrlabels.h b/src/libs/Network/uip/uip/lc-addrlabels.h
new file mode 100644 (file)
index 0000000..fe1387e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ * Thanks to dividuum for finding the nice local scope label
+ * implementation.
+ */
+
+#ifndef __LC_ADDRLABELS_H__
+#define __LC_ADDRLABELS_H__
+
+/** \hideinitializer */
+typedef void * lc_t;
+
+#define LC_INIT(s) s = NULL
+
+
+#define LC_RESUME(s)                            \
+  do {                                          \
+    if(s != NULL) {                             \
+      goto *s;                                  \
+    }                                           \
+  } while(0)
+
+#define LC_SET(s)                               \
+  do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0)
+
+#define LC_END(s)
+
+#endif /* __LC_ADDRLABELS_H__ */
+
+/**  @} */
diff --git a/src/libs/Network/uip/uip/lc-switch.h b/src/libs/Network/uip/uip/lc-switch.h
new file mode 100644 (file)
index 0000000..f32885f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statment
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statmenets.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef __LC_SWITCH_H__
+#define __LC_SWTICH_H__
+
+/* WARNING! lc implementation using switch() does not work if an
+   LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s) switch(s) { case 0:
+
+#define LC_SET(s) s = __LINE__; case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* __LC_SWITCH_H__ */
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/lc.h b/src/libs/Network/uip/uip/lc.h
new file mode 100644 (file)
index 0000000..a9e9d46
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef __LC_H__
+#define __LC_H__
+
+#ifdef LC_CONF_INCLUDE
+#include LC_CONF_INCLUDE
+#else
+#include "lc-switch.h"
+#endif /* LC_CONF_INCLUDE */
+
+#endif /* __LC_H__ */
+
+/** @} */
+/** @} */
diff --git a/src/libs/Network/uip/uip/psock.c b/src/libs/Network/uip/uip/psock.c
new file mode 100644 (file)
index 0000000..e226998
--- /dev/null
@@ -0,0 +1,373 @@
+#pragma GCC diagnostic ignored "-Wpointer-sign"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "uipopt.h"
+#include "psock.h"
+#include "uip.h"
+
+#define STATE_NONE 0
+#define STATE_ACKED 1
+#define STATE_READ 2
+#define STATE_BLOCKED_NEWDATA 3
+#define STATE_BLOCKED_CLOSE 4
+#define STATE_BLOCKED_SEND 5
+#define STATE_DATA_SENT 6
+
+/*
+ * Return value of the buffering functions that indicates that a
+ * buffer was not filled by incoming data.
+ *
+ */
+#define BUF_NOT_FULL 0
+#define BUF_NOT_FOUND 0
+
+/*
+ * Return value of the buffering functions that indicates that a
+ * buffer was completely filled by incoming data.
+ *
+ */
+#define BUF_FULL 1
+
+/*
+ * Return value of the buffering functions that indicates that an
+ * end-marker byte was found.
+ *
+ */
+#define BUF_FOUND 2
+
+/*---------------------------------------------------------------------------*/
+static void
+buf_setup(struct psock_buf *buf,
+          u8_t *bufptr, u16_t bufsize)
+{
+    buf->ptr = bufptr;
+    buf->left = bufsize;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+buf_bufdata(struct psock_buf *buf, u16_t len,
+            u8_t **dataptr, u16_t *datalen)
+{
+    if (*datalen < buf->left) {
+        memcpy(buf->ptr, *dataptr, *datalen);
+        buf->ptr += *datalen;
+        buf->left -= *datalen;
+        *dataptr += *datalen;
+        *datalen = 0;
+        return BUF_NOT_FULL;
+    } else if (*datalen == buf->left) {
+        memcpy(buf->ptr, *dataptr, *datalen);
+        buf->ptr += *datalen;
+        buf->left = 0;
+        *dataptr += *datalen;
+        *datalen = 0;
+        return BUF_FULL;
+    } else {
+        memcpy(buf->ptr, *dataptr, buf->left);
+        buf->ptr += buf->left;
+        *datalen -= buf->left;
+        *dataptr += buf->left;
+        buf->left = 0;
+        return BUF_FULL;
+    }
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+buf_bufto(register struct psock_buf *buf, u8_t endmarker,
+          register u8_t **dataptr, register u16_t *datalen)
+{
+    u8_t c;
+    while (buf->left > 0 && *datalen > 0) {
+        c = *buf->ptr = **dataptr;
+        ++*dataptr;
+        ++buf->ptr;
+        --*datalen;
+        --buf->left;
+
+        if (c == endmarker) {
+            return BUF_FOUND;
+        }
+    }
+
+    if (*datalen == 0) {
+        return BUF_NOT_FOUND;
+    }
+
+    while (*datalen > 0) {
+        c = **dataptr;
+        --*datalen;
+        ++*dataptr;
+
+        if (c == endmarker) {
+            return BUF_FOUND | BUF_FULL;
+        }
+    }
+
+    return BUF_FULL;
+}
+/*---------------------------------------------------------------------------*/
+static char
+send_data(register struct psock *s)
+{
+    if (s->state != STATE_DATA_SENT || uip_rexmit()) {
+        if (s->sendlen > uip_mss()) {
+            uip_send(s->sendptr, uip_mss());
+        } else {
+            uip_send(s->sendptr, s->sendlen);
+        }
+        s->state = STATE_DATA_SENT;
+        return 1;
+    }
+    return 0;
+}
+/*---------------------------------------------------------------------------*/
+static char
+data_acked(register struct psock *s)
+{
+    if (s->state == STATE_DATA_SENT && uip_acked()) {
+        if (s->sendlen > uip_mss()) {
+            s->sendlen -= uip_mss();
+            s->sendptr += uip_mss();
+        } else {
+            s->sendptr += s->sendlen;
+            s->sendlen = 0;
+        }
+        s->state = STATE_ACKED;
+        return 1;
+    }
+    return 0;
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_send(register struct psock *s, const char *buf,
+                     unsigned int len))
+{
+    PT_BEGIN(&s->psockpt);
+
+    /* If there is no data to send, we exit immediately. */
+    if (len == 0) {
+        PT_EXIT(&s->psockpt);
+    }
+
+    /* Save the length of and a pointer to the data that is to be
+       sent. */
+    s->sendptr = buf;
+    s->sendlen = len;
+
+    s->state = STATE_NONE;
+
+    /* We loop here until all data is sent. The s->sendlen variable is
+       updated by the data_sent() function. */
+    while (s->sendlen > 0) {
+
+        /*
+         * The condition for this PT_WAIT_UNTIL is a little tricky: the
+         * protothread will wait here until all data has been acknowledged
+         * (data_acked() returns true) and until all data has been sent
+         * (send_data() returns true). The two functions data_acked() and
+         * send_data() must be called in succession to ensure that all
+         * data is sent. Therefore the & operator is used instead of the
+         * && operator, which would cause only the data_acked() function
+         * to be called when it returns false.
+         */
+        PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+    }
+
+    s->state = STATE_NONE;
+
+    PT_END(&s->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_generator_send(register struct psock *s,
+                               unsigned short (*generate)(void *), void *arg))
+{
+    PT_BEGIN(&s->psockpt);
+
+    /* Ensure that there is a generator function to call. */
+    if (generate == NULL) {
+        PT_EXIT(&s->psockpt);
+    }
+
+    /* Call the generator function to generate the data in the
+       uip_appdata buffer. */
+    s->sendlen = generate(arg);
+    s->sendptr = uip_appdata;
+
+    s->state = STATE_NONE;
+    do {
+        /* Call the generator function again if we are called to perform a
+           retransmission. */
+        if (uip_rexmit()) {
+            generate(arg);
+        }
+        /* Wait until all data is sent and acknowledged. */
+        PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+    } while (s->sendlen > 0);
+
+    s->state = STATE_NONE;
+
+    PT_END(&s->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+u16_t
+psock_datalen(struct psock *psock)
+{
+    return psock->bufsize - psock->buf.left;
+}
+/*---------------------------------------------------------------------------*/
+char
+psock_newdata(struct psock *s)
+{
+    if (s->readlen > 0) {
+        /* There is data in the uip_appdata buffer that has not yet been
+           read with the PSOCK_READ functions. */
+        return 1;
+    } else if (s->state == STATE_READ) {
+        /* All data in uip_appdata buffer already consumed. */
+        s->state = STATE_BLOCKED_NEWDATA;
+        return 0;
+    } else if (uip_newdata()) {
+        /* There is new data that has not been consumed. */
+        return 1;
+    } else {
+        /* There is no new data. */
+        return 0;
+    }
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
+{
+    PT_BEGIN(&psock->psockpt);
+
+    buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+
+    /* XXX: Should add buf_checkmarker() before do{} loop, if
+       incoming data has been handled while waiting for a write. */
+
+    do {
+        if (psock->readlen == 0) {
+            PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+            psock->state = STATE_READ;
+            psock->readptr = (u8_t *)uip_appdata;
+            psock->readlen = uip_datalen();
+        }
+    } while ((buf_bufto(&psock->buf, c,
+                        &psock->readptr,
+                        &psock->readlen) & BUF_FOUND) == 0);
+
+    if (psock_datalen(psock) == 0) {
+        psock->state = STATE_NONE;
+        PT_RESTART(&psock->psockpt);
+    }
+    PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readbuf(register struct psock *psock))
+{
+    PT_BEGIN(&psock->psockpt);
+
+    buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+
+    /* XXX: Should add buf_checkmarker() before do{} loop, if
+       incoming data has been handled while waiting for a write. */
+
+    do {
+        if (psock->readlen == 0) {
+            PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+            //printf("Waited for newdata\n");
+            psock->state = STATE_READ;
+            psock->readptr = (u8_t *)uip_appdata;
+            psock->readlen = uip_datalen();
+        }
+    } while (buf_bufdata(&psock->buf, psock->bufsize,
+                         &psock->readptr,
+                         &psock->readlen) != BUF_FULL);
+
+    if (psock_datalen(psock) == 0) {
+        psock->state = STATE_NONE;
+        PT_RESTART(&psock->psockpt);
+    }
+    PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readbuf_len(register struct psock *psock, uint16_t len))
+{
+    PT_BEGIN(&psock->psockpt);
+
+    // setup to read the smaller of buffer size or len
+    if(len > psock->bufsize) len= psock->bufsize;
+    buf_setup(&psock->buf, psock->bufptr, len);
+
+    /* XXX: Should add buf_checkmarker() before do{} loop, if
+    incoming data has been handled while waiting for a write. */
+
+    /* read len bytes or to end of data */
+    do {
+        if (psock->readlen == 0) {
+            PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+            psock->state = STATE_READ;
+            psock->readptr = (uint8_t *)uip_appdata;
+            psock->readlen = uip_datalen();
+        }
+    } while (buf_bufdata(&psock->buf, psock->bufsize,
+                         &psock->readptr, &psock->readlen) != BUF_FULL);
+
+    if (psock_datalen(psock) == 0) {
+        psock->state = STATE_NONE;
+        PT_RESTART(&psock->psockpt);
+    }
+    PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+void
+psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
+{
+    psock->state = STATE_NONE;
+    psock->readlen = 0;
+    psock->bufptr = buffer;
+    psock->bufsize = buffersize;
+    buf_setup(&psock->buf, buffer, buffersize);
+    PT_INIT(&psock->pt);
+    PT_INIT(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
diff --git a/src/libs/Network/uip/uip/psock.h b/src/libs/Network/uip/uip/psock.h
new file mode 100644 (file)
index 0000000..857522b
--- /dev/null
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \defgroup psock Protosockets library
+ * @{
+ *
+ * The protosocket library provides an interface to the uIP stack that is
+ * similar to the traditional BSD socket interface. Unlike programs
+ * written for the ordinary uIP event-driven interface, programs
+ * written with the protosocket library are executed in a sequential
+ * fashion and does not have to be implemented as explicit state
+ * machines.
+ *
+ * Protosockets only work with TCP connections.
+ *
+ * The protosocket library uses \ref pt protothreads to provide
+ * sequential control flow. This makes the protosockets lightweight in
+ * terms of memory, but also means that protosockets inherits the
+ * functional limitations of protothreads. Each protosocket lives only
+ * within a single function. Automatic variables (stack variables) are
+ * not retained across a protosocket library function call.
+ *
+ * \note Because the protosocket library uses protothreads, local
+ * variables will not always be saved across a call to a protosocket
+ * library function. It is therefore advised that local variables are
+ * used with extreme care.
+ *
+ * The protosocket library provides functions for sending data without
+ * having to deal with retransmissions and acknowledgements, as well
+ * as functions for reading data without having to deal with data
+ * being split across more than one TCP segment.
+ *
+ * Because each protosocket runs as a protothread, the protosocket has to be
+ * started with a call to PSOCK_BEGIN() at the start of the function
+ * in which the protosocket is used. Similarly, the protosocket protothread can
+ * be terminated by a call to PSOCK_EXIT().
+ *
+ */
+
+/**
+ * \file
+ * Protosocket library header file
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PSOCK_H__
+#define __PSOCK_H__
+
+#include "uipopt.h"
+#include "pt.h"
+
+ /*
+ * The structure that holds the state of a buffer.
+ *
+ * This structure holds the state of a uIP buffer. The structure has
+ * no user-visible elements, but is used through the functions
+ * provided by the library.
+ *
+ */
+struct psock_buf {
+  u8_t *ptr;
+  unsigned short left;
+};
+
+/**
+ * The representation of a protosocket.
+ *
+ * The protosocket structrure is an opaque structure with no user-visible
+ * elements.
+ */
+struct psock {
+  struct pt pt, psockpt; /* Protothreads - one that's using the psock
+                           functions, and one that runs inside the
+                           psock functions. */
+  const u8_t *sendptr;   /* Pointer to the next data to be sent. */
+  u8_t *readptr;         /* Pointer to the next data to be read. */
+
+  char *bufptr;          /* Pointer to the buffer used for buffering
+                           incoming data. */
+
+  u16_t sendlen;         /* The number of bytes left to be sent. */
+  u16_t readlen;         /* The number of bytes left to be read. */
+
+  struct psock_buf buf;  /* The structure holding the state of the
+                           input buffer. */
+  unsigned int bufsize;  /* The size of the input buffer. */
+
+  unsigned char state;   /* The state of the protosocket. */
+};
+
+void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);
+/**
+ * Initialize a protosocket.
+ *
+ * This macro initializes a protosocket and must be called before the
+ * protosocket is used. The initialization also specifies the input buffer
+ * for the protosocket.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket to be
+ * initialized
+ *
+ * \param buffer (char *) A pointer to the input buffer for the
+ * protosocket.
+ *
+ * \param buffersize (unsigned int) The size of the input buffer.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_INIT(psock, buffer, buffersize) \
+  psock_init(psock, buffer, buffersize)
+
+/**
+ * Start the protosocket protothread in a function.
+ *
+ * This macro starts the protothread associated with the protosocket and
+ * must come before other protosocket calls in the function it is used.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket to be
+ * started.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
+
+PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));
+/**
+ * Send data.
+ *
+ * This macro sends data over a protosocket. The protosocket protothread blocks
+ * until all data has been sent and is known to have been received by
+ * the remote end of the TCP connection.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket over which
+ * data is to be sent.
+ *
+ * \param data (char *) A pointer to the data that is to be sent.
+ *
+ * \param datalen (unsigned int) The length of the data that is to be
+ * sent.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_SEND(psock, data, datalen)               \
+    PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))
+
+/**
+ * \brief      Send a null-terminated string.
+ * \param psock Pointer to the protosocket.
+ * \param str  The string to be sent.
+ *
+ *             This function sends a null-terminated string over the
+ *             protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_SEND_STR(psock, str)                     \
+    PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))
+
+PT_THREAD(psock_generator_send(struct psock *psock,
+                               unsigned short (*f)(void *), void *arg));
+
+/**
+ * \brief      Generate data with a function and send it
+ * \param psock Pointer to the protosocket.
+ * \param generator Pointer to the generator function
+ * \param arg   Argument to the generator function
+ *
+ *             This function generates data and sends it over the
+ *             protosocket. This can be used to dynamically generate
+ *             data for a transmission, instead of generating the data
+ *             in a buffer beforehand. This function reduces the need for
+ *             buffer memory. The generator function is implemented by
+ *             the application, and a pointer to the function is given
+ *             as an argument with the call to PSOCK_GENERATOR_SEND().
+ *
+ *             The generator function should place the generated data
+ *             directly in the uip_appdata buffer, and return the
+ *             length of the generated data. The generator function is
+ *             called by the protosocket layer when the data first is
+ *             sent, and once for every retransmission that is needed.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_GENERATOR_SEND(psock, generator, arg)     \
+    PT_WAIT_THREAD(&((psock)->pt),                                     \
+                  psock_generator_send(psock, generator, arg))
+
+
+/**
+ * Close a protosocket.
+ *
+ * This macro closes a protosocket and can only be called from within the
+ * protothread in which the protosocket lives.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket that is to
+ * be closed.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_CLOSE(psock) uip_close()
+
+PT_THREAD(psock_readbuf(struct psock *psock));
+/**
+ * Read data until the buffer is full.
+ *
+ * This macro will block waiting for data and read the data into the
+ * input buffer specified with the call to PSOCK_INIT(). Data is read
+ * until the buffer is full..
+ *
+ * \param psock (struct psock *) A pointer to the protosocket from which
+ * data should be read.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_READBUF(psock)        \
+  PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
+
+PT_THREAD(psock_readbuf_len(struct psock *psock,  uint16_t len));
+
+/**
+ * Read n bytes of data where n is the smaller of the buffer size or len
+ *
+ * This macro will block waiting for data and read the data into the
+ * input buffer specified with the call to PSOCK_INIT(). Data is read
+ * until either len bytes are read or size of the buffer, note len should
+ * be smaller or equel to the buffer size
+ *
+ * \param psock (struct psock *) A pointer to the protosocket from which
+ * data should be read.
+ *
+ * \param len (int) The number of bytes to be read.
+ * \hideinitializer
+ */
+#define PSOCK_READBUF_LEN(psock, len)                        \
+PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len))
+
+
+PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
+/**
+ * Read data up to a specified character.
+ *
+ * This macro will block waiting for data and read the data into the
+ * input buffer specified with the call to PSOCK_INIT(). Data is only
+ * read until the specifieed character appears in the data stream.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket from which
+ * data should be read.
+ *
+ * \param c (char) The character at which to stop reading.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_READTO(psock, c)                         \
+  PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))
+
+/**
+ * The length of the data that was previously read.
+ *
+ * This macro returns the length of the data that was previously read
+ * using PSOCK_READTO() or PSOCK_READ().
+ *
+ * \param psock (struct psock *) A pointer to the protosocket holding the data.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_DATALEN(psock) psock_datalen(psock)
+
+u16_t psock_datalen(struct psock *psock);
+
+/**
+ * Exit the protosocket's protothread.
+ *
+ * This macro terminates the protothread of the protosocket and should
+ * almost always be used in conjunction with PSOCK_CLOSE().
+ *
+ * \sa PSOCK_CLOSE_EXIT()
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))
+
+/**
+ * Close a protosocket and exit the protosocket's protothread.
+ *
+ * This macro closes a protosocket and exits the protosocket's protothread.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_CLOSE_EXIT(psock)                \
+  do {                                         \
+    PSOCK_CLOSE(psock);                        \
+    PSOCK_EXIT(psock);                 \
+  } while(0)
+
+/**
+ * Declare the end of a protosocket's protothread.
+ *
+ * This macro is used for declaring that the protosocket's protothread
+ * ends. It must always be used together with a matching PSOCK_BEGIN()
+ * macro.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_END(psock) PT_END(&((psock)->pt))
+
+char psock_newdata(struct psock *s);
+
+/**
+ * Check if new data has arrived on a protosocket.
+ *
+ * This macro is used in conjunction with the PSOCK_WAIT_UNTIL()
+ * macro to check if data has arrived on a protosocket.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_NEWDATA(psock) psock_newdata(psock)
+
+/**
+ * Wait until a condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true. The macro PSOCK_NEWDATA() can be used to check if new data
+ * arrives when the protosocket is waiting.
+ *
+ * Typically, this macro is used as follows:
+ *
+ \code
+ PT_THREAD(thread(struct psock *s, struct timer *t))
+ {
+   PSOCK_BEGIN(s);
+
+   PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
+
+   if(PSOCK_NEWDATA(s)) {
+     PSOCK_READTO(s, '\n');
+   } else {
+     handle_timed_out(s);
+   }
+
+   PSOCK_END(s);
+ }
+ \endcode
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ * \param condition The condition to wait for.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_WAIT_UNTIL(psock, condition)    \
+  PT_WAIT_UNTIL(&((psock)->pt), (condition));
+
+#define PSOCK_WAIT_THREAD(psock, condition)   \
+  PT_WAIT_THREAD(&((psock)->pt), (condition))
+
+
+/**
+ * return a pointer and length of whatever is left in the uip_appdata buffer
+ * after previous use of PSOCK_READTO() and mark the internal buffer as fully read
+ */
+#define PSOCK_GET_LENGTH_OF_REST_OF_BUFFER(psock) (psock)->readlen
+#define PSOCK_GET_START_OF_REST_OF_BUFFER(psock) (psock)->readptr
+#define PSOCK_MARK_BUFFER_READ(psock) do { (psock)->readlen= 0; (psock)->state = 0; } while(0)
+
+#endif /* __PSOCK_H__ */
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/pt.h b/src/libs/Network/uip/uip/pt.h
new file mode 100644 (file)
index 0000000..9f1f64d
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+struct pt {
+  lc_t lc;
+};
+
+#define PT_WAITING 0
+#define PT_EXITED  1
+#define PT_ENDED   2
+#define PT_YIELDED 3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt)   LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+                   PT_INIT(pt); return PT_ENDED; }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition)           \
+  do {                                         \
+    LC_SET((pt)->lc);                          \
+    if(!(condition)) {                         \
+      return PT_WAITING;                       \
+    }                                          \
+  } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread)            \
+  do {                                         \
+    PT_INIT((child));                          \
+    PT_WAIT_THREAD((pt), (thread));            \
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt)                         \
+  do {                                         \
+    PT_INIT(pt);                               \
+    return PT_WAITING;                 \
+  } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt)                            \
+  do {                                         \
+    PT_INIT(pt);                               \
+    return PT_EXITED;                  \
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) == PT_WAITING)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt)                           \
+  do {                                         \
+    PT_YIELD_FLAG = 0;                         \
+    LC_SET((pt)->lc);                          \
+    if(PT_YIELD_FLAG == 0) {                   \
+      return PT_YIELDED;                       \
+    }                                          \
+  } while(0)
+
+/**
+ * \brief      Yield from the protothread until a condition occurs.
+ * \param pt   A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ *             This function will yield the protothread, until the
+ *             specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond)               \
+  do {                                         \
+    PT_YIELD_FLAG = 0;                         \
+    LC_SET((pt)->lc);                          \
+    if((PT_YIELD_FLAG == 0) || !(cond)) {      \
+      return PT_YIELDED;                       \
+    }                                          \
+  } while(0)
+
+/** @} */
+
+#endif /* __PT_H__ */
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/timer.c b/src/libs/Network/uip/uip/timer.c
new file mode 100644 (file)
index 0000000..74eedf6
--- /dev/null
@@ -0,0 +1,127 @@
+/**
+ * \addtogroup timer
+ * @{
+ */
+
+/**
+ * \file
+ * Timer library implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include "clock.h"
+#include "timer.h"
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Set a timer.
+ *
+ * This function is used to set a timer for a time sometime in the
+ * future. The function timer_expired() will evaluate to true after
+ * the timer has expired.
+ *
+ * \param t A pointer to the timer
+ * \param interval The interval before the timer expires.
+ *
+ */
+void
+timer_set(struct timer *t, clock_time_t interval)
+{
+  t->interval = interval;
+  t->start = clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Reset the timer with the same interval.
+ *
+ * This function resets the timer with the same interval that was
+ * given to the timer_set() function. The start point of the interval
+ * is the exact time that the timer last expired. Therefore, this
+ * function will cause the timer to be stable over time, unlike the
+ * timer_rester() function.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_restart()
+ */
+void
+timer_reset(struct timer *t)
+{
+  t->start += t->interval;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Restart the timer from the current point in time
+ *
+ * This function restarts a timer with the same interval that was
+ * given to the timer_set() function. The timer will start at the
+ * current time.
+ *
+ * \note A periodic timer will drift if this function is used to reset
+ * it. For preioric timers, use the timer_reset() function instead.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_reset()
+ */
+void
+timer_restart(struct timer *t)
+{
+  t->start = clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Check if a timer has expired.
+ *
+ * This function tests if a timer has expired and returns true or
+ * false depending on its status.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return Non-zero if the timer has expired, zero otherwise.
+ *
+ */
+int
+timer_expired(struct timer *t)
+{
+  return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
+}
+/*---------------------------------------------------------------------------*/
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/timer.h b/src/libs/Network/uip/uip/timer.h
new file mode 100644 (file)
index 0000000..1b2ed12
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * \defgroup timer Timer library
+ *
+ * The timer library provides functions for setting, resetting and
+ * restarting timers, and for checking if a timer has expired. An
+ * application must "manually" check if its timers have expired; this
+ * is not done automatically.
+ *
+ * A timer is declared as a \c struct \c timer and all access to the
+ * timer is made by a pointer to the declared timer.
+ *
+ * \note The timer library uses the \ref clock "Clock library" to
+ * measure time. Intervals should be specified in the format used by
+ * the clock library.
+ *
+ * @{
+ */
+
+
+/**
+ * \file
+ * Timer library header file.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
+ */
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+#include "clock.h"
+
+/**
+ * A timer.
+ *
+ * This structure is used for declaring a timer. The timer must be set
+ * with timer_set() before it can be used.
+ *
+ * \hideinitializer
+ */
+struct timer {
+  clock_time_t start;
+  clock_time_t interval;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void timer_set(struct timer *t, clock_time_t interval);
+void timer_reset(struct timer *t);
+void timer_restart(struct timer *t);
+int timer_expired(struct timer *t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIMER_H__ */
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/uip-fw.c b/src/libs/Network/uip/uip/uip-fw.c
new file mode 100644 (file)
index 0000000..263fc46
--- /dev/null
@@ -0,0 +1,537 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \defgroup uipfw uIP packet forwarding
+ * @{
+ *
+ */
+
+/**
+ * \file
+ * uIP packet forwarding.
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This file implements a number of simple functions which do packet
+ * forwarding over multiple network interfaces with uIP.
+ *
+ */
+
+#include "uip.h"
+#include "uip_arch.h"
+#include "uip-fw.h"
+
+#include <string.h> /* for memcpy() */
+
+/*
+ * The list of registered network interfaces.
+ */
+static struct uip_fw_netif *netifs = NULL;
+
+/*
+ * A pointer to the default network interface.
+ */
+static struct uip_fw_netif *defaultnetif = NULL;
+
+struct tcpip_hdr {
+  /* IP header. */
+  u8_t vhl,
+    tos;
+  u16_t len,
+    ipid,
+    ipoffset;
+  u8_t ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+
+  /* TCP header. */
+  u16_t srcport,
+    destport;
+  u8_t seqno[4],
+    ackno[4],
+    tcpoffset,
+    flags,
+    wnd[2];
+  u16_t tcpchksum;
+  u8_t urgp[2];
+  u8_t optdata[4];
+};
+
+struct icmpip_hdr {
+  /* IP header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+  /* ICMP (echo) header. */
+  u8_t type, icode;
+  u16_t icmpchksum;
+  u16_t id, seqno;
+  u8_t payload[1];
+};
+
+/* ICMP ECHO. */
+#define ICMP_ECHO 8
+
+/* ICMP TIME-EXCEEDED. */
+#define ICMP_TE 11
+
+/*
+ * Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
+ */
+#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+/*
+ * Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
+ */
+#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+/*
+ * Certain fields of an IP packet that are used for identifying
+ * duplicate packets.
+ */
+struct fwcache_entry {
+  u16_t timer;
+
+  u16_t srcipaddr[2];
+  u16_t destipaddr[2];
+  u16_t ipid;
+  u8_t proto;
+  u8_t unused;
+
+#if notdef
+  u16_t payload[2];
+#endif
+
+#if UIP_REASSEMBLY > 0
+  u16_t len, offset;
+#endif
+};
+
+/*
+ * The number of packets to remember when looking for duplicates.
+ */
+#ifdef UIP_CONF_FWCACHE_SIZE
+#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
+#else
+#define FWCACHE_SIZE 2
+#endif
+
+
+/*
+ * A cache of packet header fields which are used for
+ * identifying duplicate packets.
+ */
+static struct fwcache_entry fwcache[FWCACHE_SIZE];
+
+/**
+ * \internal
+ * The time that a packet cache is active.
+ */
+#define FW_TIME 20
+
+/*------------------------------------------------------------------------------*/
+/**
+ * Initialize the uIP packet forwarding module.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_init(void)
+{
+  struct uip_fw_netif *t;
+  defaultnetif = NULL;
+  while(netifs != NULL) {
+    t = netifs;
+    netifs = netifs->next;
+    t->next = NULL;
+  }
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Check if an IP address is within the network defined by an IP
+ * address and a netmask.
+ *
+ * \param ipaddr The IP address to be checked.
+ * \param netipaddr The IP address of the network.
+ * \param netmask The netmask of the network.
+ *
+ * \return Non-zero if IP address is in network, zero otherwise.
+ */
+/*------------------------------------------------------------------------------*/
+static unsigned char
+ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask)
+{
+  return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
+    (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Send out an ICMP TIME-EXCEEDED message.
+ *
+ * This function replaces the packet in the uip_buf buffer with the
+ * ICMP packet.
+ */
+/*------------------------------------------------------------------------------*/
+static void
+time_exceeded(void)
+{
+  u16_t tmp16;
+
+  /* We don't send out ICMP errors for ICMP messages. */
+  if(ICMPBUF->proto == UIP_PROTO_ICMP) {
+    uip_len = 0;
+    return;
+  }
+  /* Copy fields from packet header into payload of this ICMP packet. */
+  memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
+
+  /* Set the ICMP type and code. */
+  ICMPBUF->type = ICMP_TE;
+  ICMPBUF->icode = 0;
+
+  /* Calculate the ICMP checksum. */
+  ICMPBUF->icmpchksum = 0;
+  ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
+
+  /* Set the IP destination address to be the source address of the
+     original packet. */
+  tmp16= BUF->destipaddr[0];
+  BUF->destipaddr[0] = BUF->srcipaddr[0];
+  BUF->srcipaddr[0] = tmp16;
+  tmp16 = BUF->destipaddr[1];
+  BUF->destipaddr[1] = BUF->srcipaddr[1];
+  BUF->srcipaddr[1] = tmp16;
+
+  /* Set our IP address as the source address. */
+  BUF->srcipaddr[0] = uip_hostaddr[0];
+  BUF->srcipaddr[1] = uip_hostaddr[1];
+
+  /* The size of the ICMP time exceeded packet is 36 + the size of the
+     IP header (20) = 56. */
+  uip_len = 56;
+  ICMPBUF->len[0] = 0;
+  ICMPBUF->len[1] = uip_len;
+
+  /* Fill in the other fields in the IP header. */
+  ICMPBUF->vhl = 0x45;
+  ICMPBUF->tos = 0;
+  ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
+  ICMPBUF->ttl  = UIP_TTL;
+  ICMPBUF->proto = UIP_PROTO_ICMP;
+
+  /* Calculate IP checksum. */
+  ICMPBUF->ipchksum = 0;
+  ICMPBUF->ipchksum = ~(uip_ipchksum());
+
+
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Register a packet in the forwarding cache so that it won't be
+ * forwarded again.
+ */
+/*------------------------------------------------------------------------------*/
+static void
+fwcache_register(void)
+{
+  struct fwcache_entry *fw;
+  int i, oldest;
+
+  oldest = FW_TIME;
+  fw = NULL;
+
+  /* Find the oldest entry in the cache. */
+  for(i = 0; i < FWCACHE_SIZE; ++i) {
+    if(fwcache[i].timer == 0) {
+      fw = &fwcache[i];
+      break;
+    } else if(fwcache[i].timer <= oldest) {
+      fw = &fwcache[i];
+      oldest = fwcache[i].timer;
+    }
+  }
+
+  fw->timer = FW_TIME;
+  fw->ipid = BUF->ipid;
+  fw->srcipaddr[0] = BUF->srcipaddr[0];
+  fw->srcipaddr[1] = BUF->srcipaddr[1];
+  fw->destipaddr[0] = BUF->destipaddr[0];
+  fw->destipaddr[1] = BUF->destipaddr[1];
+  fw->proto = BUF->proto;
+#if notdef
+  fw->payload[0] = BUF->srcport;
+  fw->payload[1] = BUF->destport;
+#endif
+#if UIP_REASSEMBLY > 0
+  fw->len = BUF->len;
+  fw->offset = BUF->ipoffset;
+#endif
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Find a network interface for the IP packet in uip_buf.
+ */
+/*------------------------------------------------------------------------------*/
+static struct uip_fw_netif *
+find_netif(void)
+{
+  struct uip_fw_netif *netif;
+
+  /* Walk through every network interface to check for a match. */
+  for(netif = netifs; netif != NULL; netif = netif->next) {
+    if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
+                     netif->netmask)) {
+      /* If there was a match, we break the loop. */
+      return netif;
+    }
+  }
+
+  /* If no matching netif was found, we use default netif. */
+  return defaultnetif;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Output an IP packet on the correct network interface.
+ *
+ * The IP packet should be present in the uip_buf buffer and its
+ * length in the global uip_len variable.
+ *
+ * \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
+ * transmission was attempted and that no packet was sent.
+ *
+ * \retval UIP_FW_NOROUTE No suitable network interface could be found
+ * for the outbound packet, and the packet was not sent.
+ *
+ * \return The return value from the actual network interface output
+ * function is passed unmodified as a return value.
+ */
+/*------------------------------------------------------------------------------*/
+u8_t
+uip_fw_output(void)
+{
+  struct uip_fw_netif *netif;
+
+  if(uip_len == 0) {
+    return UIP_FW_ZEROLEN;
+  }
+
+  fwcache_register();
+
+#if UIP_BROADCAST
+  /* Link local broadcasts go out on all interfaces. */
+  if(/*BUF->proto == UIP_PROTO_UDP &&*/
+     BUF->destipaddr[0] == 0xffff &&
+     BUF->destipaddr[1] == 0xffff) {
+    if(defaultnetif != NULL) {
+      defaultnetif->output();
+    }
+    for(netif = netifs; netif != NULL; netif = netif->next) {
+      netif->output();
+    }
+    return UIP_FW_OK;
+  }
+#endif /* UIP_BROADCAST */
+
+  netif = find_netif();
+  /*  printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
+        netif->output,
+        uip_len);*/
+
+  if(netif == NULL) {
+    return UIP_FW_NOROUTE;
+  }
+  /* If we now have found a suitable network interface, we call its
+     output function to send out the packet. */
+  return netif->output();
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Forward an IP packet in the uip_buf buffer.
+ *
+ *
+ *
+ * \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
+ * the packet should be processed locally.
+ */
+/*------------------------------------------------------------------------------*/
+u8_t
+uip_fw_forward(void)
+{
+  struct fwcache_entry *fw;
+
+  /* First check if the packet is destined for ourselves and return 0
+     to indicate that the packet should be processed locally. */
+  if(BUF->destipaddr[0] == uip_hostaddr[0] &&
+     BUF->destipaddr[1] == uip_hostaddr[1]) {
+    return UIP_FW_LOCAL;
+  }
+
+  /* If we use ping IP address configuration, and our IP address is
+     not yet configured, we should intercept all ICMP echo packets. */
+#if UIP_PINGADDRCONF
+  if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 &&
+     BUF->proto == UIP_PROTO_ICMP &&
+     ICMPBUF->type == ICMP_ECHO) {
+    return UIP_FW_LOCAL;
+  }
+#endif /* UIP_PINGADDRCONF */
+
+  /* Check if the packet is in the forwarding cache already, and if so
+     we drop it. */
+
+  for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
+    if(fw->timer != 0 &&
+#if UIP_REASSEMBLY > 0
+       fw->len == BUF->len &&
+       fw->offset == BUF->ipoffset &&
+#endif
+       fw->ipid == BUF->ipid &&
+       fw->srcipaddr[0] == BUF->srcipaddr[0] &&
+       fw->srcipaddr[1] == BUF->srcipaddr[1] &&
+       fw->destipaddr[0] == BUF->destipaddr[0] &&
+       fw->destipaddr[1] == BUF->destipaddr[1] &&
+#if notdef
+       fw->payload[0] == BUF->srcport &&
+       fw->payload[1] == BUF->destport &&
+#endif
+       fw->proto == BUF->proto) {
+      /* Drop packet. */
+      return UIP_FW_FORWARDED;
+    }
+  }
+
+  /* If the TTL reaches zero we produce an ICMP time exceeded message
+     in the uip_buf buffer and forward that packet back to the sender
+     of the packet. */
+  if(BUF->ttl <= 1) {
+    /* No time exceeded for broadcasts and multicasts! */
+    if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
+      return UIP_FW_LOCAL;
+    }
+    time_exceeded();
+  }
+
+  /* Decrement the TTL (time-to-live) value in the IP header */
+  BUF->ttl = BUF->ttl - 1;
+
+  /* Update the IP checksum. */
+  if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
+    BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
+  } else {
+    BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
+  }
+
+  if(uip_len > 0) {
+    uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
+    uip_fw_output();
+  }
+
+#if UIP_BROADCAST
+  if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
+    return UIP_FW_LOCAL;
+  }
+#endif /* UIP_BROADCAST */
+
+  /* Return non-zero to indicate that the packet was forwarded and that no
+     other processing should be made. */
+  return UIP_FW_FORWARDED;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Register a network interface with the forwarding module.
+ *
+ * \param netif A pointer to the network interface that is to be
+ * registered.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_register(struct uip_fw_netif *netif)
+{
+  netif->next = netifs;
+  netifs = netif;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Register a default network interface.
+ *
+ * All packets that don't go out on any of the other interfaces will
+ * be routed to the default interface.
+ *
+ * \param netif A pointer to the network interface that is to be
+ * registered.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_default(struct uip_fw_netif *netif)
+{
+  defaultnetif = netif;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Perform periodic processing.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_periodic(void)
+{
+  struct fwcache_entry *fw;
+  for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
+    if(fw->timer > 0) {
+      --fw->timer;
+    }
+  }
+}
+/*------------------------------------------------------------------------------*/
diff --git a/src/libs/Network/uip/uip/uip-fw.h b/src/libs/Network/uip/uip/uip-fw.h
new file mode 100644 (file)
index 0000000..9033850
--- /dev/null
@@ -0,0 +1,176 @@
+/**
+ * \addtogroup uipfw
+ * @{
+ */
+
+/**
+ * \file
+ * uIP packet forwarding header file.
+ * \author Adam Dunkels <adam@sics.se>
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+#ifndef __UIP_FW_H__
+#define __UIP_FW_H__
+
+#include "uip.h"
+
+/**
+ * Representation of a uIP network interface.
+ */
+struct uip_fw_netif {
+  struct uip_fw_netif *next;  /**< Pointer to the next interface when
+                                linked in a list. */
+  u16_t ipaddr[2];            /**< The IP address of this interface. */
+  u16_t netmask[2];           /**< The netmask of the interface. */
+  u8_t (* output)(void);
+                              /**< A pointer to the function that
+                                sends a packet. */
+};
+
+/**
+ * Intantiating macro for a uIP network interface.
+ *
+ * Example:
+ \code
+ struct uip_fw_netif slipnetif =
+   {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
+ \endcode
+ * \param ip1,ip2,ip3,ip4 The IP address of the network interface.
+ *
+ * \param nm1,nm2,nm3,nm4 The netmask of the network interface.
+ *
+ * \param outputfunc A pointer to the output function of the network interface.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
+        NULL, \
+       {HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
+       {HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
+        outputfunc
+
+/**
+ * Set the IP address of a network interface.
+ *
+ * \param netif A pointer to the uip_fw_netif structure for the network interface.
+ *
+ * \param addr A pointer to an IP address.
+ *
+ * \hideinitializer
+ */
+#define uip_fw_setipaddr(netif, addr) \
+        do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \
+             (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0)
+/**
+ * Set the netmask of a network interface.
+ *
+ * \param netif A pointer to the uip_fw_netif structure for the network interface.
+ *
+ * \param addr A pointer to an IP address representing the netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_fw_setnetmask(netif, addr) \
+        do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \
+             (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0)
+
+void uip_fw_init(void);
+u8_t uip_fw_forward(void);
+u8_t uip_fw_output(void);
+void uip_fw_register(struct uip_fw_netif *netif);
+void uip_fw_default(struct uip_fw_netif *netif);
+void uip_fw_periodic(void);
+
+
+/**
+ * A non-error message that indicates that a packet should be
+ * processed locally.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_LOCAL     0
+
+/**
+ * A non-error message that indicates that something went OK.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_OK        0
+
+/**
+ * A non-error message that indicates that a packet was forwarded.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_FORWARDED 1
+
+/**
+ * A non-error message that indicates that a zero-length packet
+ * transmission was attempted, and that no packet was sent.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_ZEROLEN   2
+
+/**
+ * An error message that indicates that a packet that was too large
+ * for the outbound network interface was detected.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_TOOLARGE  3
+
+/**
+ * An error message that indicates that no suitable interface could be
+ * found for an outbound packet.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_NOROUTE   4
+
+/**
+ * An error message that indicates that a packet that should be
+ * forwarded or output was dropped.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_DROPPED   5
+
+
+#endif /* __UIP_FW_H__ */
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/uip-neighbor.c b/src/libs/Network/uip/uip/uip-neighbor.c
new file mode 100644 (file)
index 0000000..115e9f0
--- /dev/null
@@ -0,0 +1,164 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \file
+ *         Database of link-local neighbors, used by IPv6 code and
+ *         to be used by a future ARP code rewrite.
+ * \author
+ *         Adam Dunkels <adam@sics.se>
+ */
+
+#include "uip-neighbor.h"
+
+#include "stdio.h"
+#include <string.h>
+
+#define MAX_TIME 128
+
+#ifdef UIP_NEIGHBOR_CONF_ENTRIES
+#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES
+#else /* UIP_NEIGHBOR_CONF_ENTRIES */
+#define ENTRIES 8
+#endif /* UIP_NEIGHBOR_CONF_ENTRIES */
+
+struct neighbor_entry {
+  uip_ipaddr_t ipaddr;
+  struct uip_neighbor_addr addr;
+  u8_t time;
+};
+static struct neighbor_entry entries[ENTRIES];
+
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_init(void)
+{
+  int i;
+
+  for(i = 0; i < ENTRIES; ++i) {
+    entries[i].time = MAX_TIME;
+  }
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_periodic(void)
+{
+  int i;
+
+  for(i = 0; i < ENTRIES; ++i) {
+    if(entries[i].time < MAX_TIME) {
+      entries[i].time++;
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
+{
+  int i, oldest;
+  u8_t oldest_time;
+
+  printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
+        addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
+        addr->addr.addr[4], addr->addr.addr[5]);
+
+  /* Find the first unused entry or the oldest used entry. */
+  oldest_time = 0;
+  oldest = 0;
+  for(i = 0; i < ENTRIES; ++i) {
+    if(entries[i].time == MAX_TIME) {
+      oldest = i;
+      break;
+    }
+    if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) {
+      oldest = i;
+      break;
+    }
+    if(entries[i].time > oldest_time) {
+      oldest = i;
+      oldest_time = entries[i].time;
+    }
+  }
+
+  /* Use the oldest or first free entry (either pointed to by the
+     "oldest" variable). */
+  entries[oldest].time = 0;
+  uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr);
+  memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
+}
+/*---------------------------------------------------------------------------*/
+static struct neighbor_entry *
+find_entry(uip_ipaddr_t ipaddr)
+{
+  int i;
+
+  for(i = 0; i < ENTRIES; ++i) {
+    if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) {
+      return &entries[i];
+    }
+  }
+  return NULL;
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_update(uip_ipaddr_t ipaddr)
+{
+  struct neighbor_entry *e;
+
+  e = find_entry(ipaddr);
+  if(e != NULL) {
+    e->time = 0;
+  }
+}
+/*---------------------------------------------------------------------------*/
+struct uip_neighbor_addr *
+uip_neighbor_lookup(uip_ipaddr_t ipaddr)
+{
+  struct neighbor_entry *e;
+
+  e = find_entry(ipaddr);
+  if(e != NULL) {
+    /*    printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
+          e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3],
+          e->addr.addr.addr[4], e->addr.addr.addr[5]);*/
+
+    return &e->addr;
+  }
+  return NULL;
+}
+/*---------------------------------------------------------------------------*/
diff --git a/src/libs/Network/uip/uip/uip-neighbor.h b/src/libs/Network/uip/uip/uip-neighbor.h
new file mode 100644 (file)
index 0000000..d3b351c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \file
+ *         Header file for database of link-local neighbors, used by
+ *         IPv6 code and to be used by future ARP code.
+ * \author
+ *         Adam Dunkels <adam@sics.se>
+ */
+
+#ifndef __UIP_NEIGHBOR_H__
+#define __UIP_NEIGHBOR_H__
+
+#include "uip.h"
+
+struct uip_neighbor_addr {
+#if UIP_NEIGHBOR_CONF_ADDRTYPE
+  UIP_NEIGHBOR_CONF_ADDRTYPE addr;
+#else
+  struct uip_eth_addr addr;
+#endif
+};
+
+void uip_neighbor_init(void);
+void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr);
+void uip_neighbor_update(uip_ipaddr_t ipaddr);
+struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr);
+void uip_neighbor_periodic(void);
+
+#endif /* __UIP-NEIGHBOR_H__ */
diff --git a/src/libs/Network/uip/uip/uip-split.c b/src/libs/Network/uip/uip/uip-split.c
new file mode 100644 (file)
index 0000000..07455f6
--- /dev/null
@@ -0,0 +1,152 @@
+//#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include "stdio.h"
+#include <string.h>
+
+#include "uip-split.h"
+#include "uip.h"
+//#include "uip-fw.h"
+//#include "uip_arch.h"
+
+void uip_add32(u8_t *op32, u16_t op16);
+void tcpip_output();
+
+#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+#ifdef UIP_SPLIT_CONF_SIZE
+#define UIP_SPLIT_SIZE UIP_SPLIT_CONF_SIZE
+#else /* UIP_SPLIT_CONF_SIZE */
+#define UIP_SPLIT_SIZE UIP_TCP_MSS
+#endif /* UIP_SPLIT_CONF_SIZE */
+
+/*-----------------------------------------------------------------------------*/
+void uip_split_output(void)
+{
+    u16_t tcplen, len1, len2;
+
+
+    /* We only try to split maximum sized TCP segments. */
+    if (BUF->proto == UIP_PROTO_TCP &&
+        uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {
+
+        tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
+        /* Split the segment in two. If the original packet length was
+           odd, we make the second packet one byte larger. */
+        len1 = len2 = tcplen / 2;
+        if (len1 + len2 < tcplen) {
+            ++len2;
+        }
+
+        /* Create the first packet. This is done by altering the length
+           field of the IP header and updating the checksums. */
+        uip_len = len1 + UIP_TCPIP_HLEN;
+#if UIP_CONF_IPV6
+        /* For IPv6, the IP length field does not include the IPv6 IP header
+           length. */
+        BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+        BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+        BUF->len[0] = uip_len >> 8;
+        BUF->len[1] = uip_len & 0xff;
+#endif /* UIP_CONF_IPV6 */
+
+        /* Recalculate the TCP checksum. */
+        BUF->tcpchksum = 0;
+        BUF->tcpchksum = ~(uip_tcpchksum());
+
+#if !UIP_CONF_IPV6
+        /* Recalculate the IP checksum. */
+        BUF->ipchksum = 0;
+        BUF->ipchksum = ~(uip_ipchksum());
+#endif /* UIP_CONF_IPV6 */
+
+        uip_len += UIP_LLH_LEN;
+
+        /* Transmit the first packet. */
+        /*    uip_fw_output();*/
+        tcpip_output();
+
+        /* Now, create the second packet. To do this, it is not enough to
+           just alter the length field, but we must also update the TCP
+           sequence number and point the uip_appdata to a new place in
+           memory. This place is detemined by the length of the first
+           packet (len1). */
+        uip_len = len2 + UIP_TCPIP_HLEN;
+#if UIP_CONF_IPV6
+        /* For IPv6, the IP length field does not include the IPv6 IP header
+           length. */
+        BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+        BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+        BUF->len[0] = uip_len >> 8;
+        BUF->len[1] = uip_len & 0xff;
+#endif /* UIP_CONF_IPV6 */
+
+        /*    uip_appdata += len1;*/
+        memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);
+
+        uip_add32(BUF->seqno, len1);
+        BUF->seqno[0] = uip_acc32[0];
+        BUF->seqno[1] = uip_acc32[1];
+        BUF->seqno[2] = uip_acc32[2];
+        BUF->seqno[3] = uip_acc32[3];
+
+        /* Recalculate the TCP checksum. */
+        BUF->tcpchksum = 0;
+        BUF->tcpchksum = ~(uip_tcpchksum());
+
+#if !UIP_CONF_IPV6
+        /* Recalculate the IP checksum. */
+        BUF->ipchksum = 0;
+        BUF->ipchksum = ~(uip_ipchksum());
+#endif /* UIP_CONF_IPV6 */
+
+        uip_len += UIP_LLH_LEN;
+        /* Transmit the second packet. */
+        /*    uip_fw_output();*/
+        tcpip_output();
+    } else {
+        /*    uip_fw_output();*/
+        tcpip_output();
+    }
+
+}
+/*-----------------------------------------------------------------------------*/
diff --git a/src/libs/Network/uip/uip/uip-split.h b/src/libs/Network/uip/uip/uip-split.h
new file mode 100644 (file)
index 0000000..c2c1789
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \defgroup uipsplit uIP TCP throughput booster hack
+ * @{
+ *
+ * The basic uIP TCP implementation only allows each TCP connection to
+ * have a single TCP segment in flight at any given time. Because of
+ * the delayed ACK algorithm employed by most TCP receivers, uIP's
+ * limit on the amount of in-flight TCP segments seriously reduces the
+ * maximum achievable throughput for sending data from uIP.
+ *
+ * The uip-split module is a hack which tries to remedy this
+ * situation. By splitting maximum sized outgoing TCP segments into
+ * two, the delayed ACK algorithm is not invoked at TCP
+ * receivers. This improves the throughput when sending data from uIP
+ * by orders of magnitude.
+ *
+ * The uip-split module uses the uip-fw module (uIP IP packet
+ * forwarding) for sending packets. Therefore, the uip-fw module must
+ * be set up with the appropriate network interfaces for this module
+ * to work.
+ */
+
+
+/**
+ * \file
+ * Module for splitting outbound TCP segments in two to avoid the
+ * delayed ACK throughput degradation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __UIP_SPLIT_H__
+#define __UIP_SPLIT_H__
+
+/**
+ * Handle outgoing packets.
+ *
+ * This function inspects an outgoing packet in the uip_buf buffer and
+ * sends it out using the uip_fw_output() function. If the packet is a
+ * full-sized TCP segment it will be split into two segments and
+ * transmitted separately. This function should be called instead of
+ * the actual device driver output function, or the uip_fw_output()
+ * function.
+ *
+ * The headers of the outgoing packet is assumed to be in the uip_buf
+ * buffer and the payload is assumed to be wherever uip_appdata
+ * points. The length of the outgoing packet is assumed to be in the
+ * uip_len variable.
+ *
+ */
+void uip_split_output(void);
+
+#endif /* __UIP_SPLIT_H__ */
+
+/** @} */
+/** @} */
diff --git a/src/libs/Network/uip/uip/uip.c b/src/libs/Network/uip/uip/uip.c
new file mode 100644 (file)
index 0000000..d010f54
--- /dev/null
@@ -0,0 +1,1923 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+#define DEBUG_PRINTF(...)
+//printf(__VA_ARGS__)
+
+/**
+ * \defgroup uip The uIP TCP/IP stack
+ * @{
+ *
+ * uIP is an implementation of the TCP/IP protocol stack intended for
+ * small 8-bit and 16-bit microcontrollers.
+ *
+ * uIP provides the necessary protocols for Internet communication,
+ * with a very small code footprint and RAM requirements - the uIP
+ * code size is on the order of a few kilobytes and RAM usage is on
+ * the order of a few hundred bytes.
+ */
+
+/**
+ * \file
+ * The uIP TCP/IP stack code.
+ * \author Adam Dunkels <adam@dunkels.com>
+ */
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $
+ *
+ */
+
+/*
+ * uIP is a small implementation of the IP, UDP and TCP protocols (as
+ * well as some basic ICMP stuff). The implementation couples the IP,
+ * UDP, TCP and the application layers very tightly. To keep the size
+ * of the compiled code down, this code frequently uses the goto
+ * statement. While it would be possible to break the uip_process()
+ * function into many smaller functions, this would increase the code
+ * size because of the overhead of parameter passing and the fact that
+ * the optimier would not be as efficient.
+ *
+ * The principle is that we have a small buffer, called the uip_buf,
+ * in which the device driver puts an incoming packet. The TCP/IP
+ * stack parses the headers in the packet, and calls the
+ * application. If the remote host has sent data to the application,
+ * this data is present in the uip_buf and the application read the
+ * data from there. It is up to the application to put this data into
+ * a byte stream if needed. The application will not be fed with data
+ * that is out of sequence.
+ *
+ * If the application whishes to send data to the peer, it should put
+ * its data into the uip_buf. The uip_appdata pointer points to the
+ * first available byte. The TCP/IP stack will calculate the
+ * checksums, and fill in the necessary header fields and finally send
+ * the packet back to the peer.
+*/
+
+#include "uip.h"
+#include "uipopt.h"
+#include "uip_arch.h"
+
+#if UIP_CONF_IPV6
+#include "uip-neighbor.h"
+#endif /* UIP_CONF_IPV6 */
+
+#include <string.h>
+
+/*---------------------------------------------------------------------------*/
+/* Variable definitions. */
+
+
+/* The IP address of this host. If it is defined to be fixed (by
+   setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
+   here. Otherwise, the address */
+#if UIP_FIXEDADDR > 0
+const uip_ipaddr_t uip_hostaddr = {
+    HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
+    HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)
+};
+const uip_ipaddr_t uip_draddr = {
+    HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
+    HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)
+};
+const uip_ipaddr_t uip_netmask = {
+    HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
+    HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)
+};
+#else
+uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
+#endif /* UIP_FIXEDADDR */
+
+static const uip_ipaddr_t all_ones_addr =
+#if UIP_CONF_IPV6
+{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
+#else /* UIP_CONF_IPV6 */
+    {
+        0xffff, 0xffff
+    };
+#endif /* UIP_CONF_IPV6 */
+static const uip_ipaddr_t all_zeroes_addr =
+#if UIP_CONF_IPV6
+{0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
+#else /* UIP_CONF_IPV6 */
+    {
+        0x0000, 0x0000
+    };
+#endif /* UIP_CONF_IPV6 */
+
+
+#if UIP_FIXEDETHADDR
+const struct uip_eth_addr uip_ethaddr = {{
+        UIP_ETHADDR0,
+        UIP_ETHADDR1,
+        UIP_ETHADDR2,
+        UIP_ETHADDR3,
+        UIP_ETHADDR4,
+        UIP_ETHADDR5
+    }
+};
+#else
+struct uip_eth_addr uip_ethaddr = {{0, 0, 0, 0, 0, 0}};
+#endif
+
+#ifndef UIP_CONF_EXTERNAL_BUFFER
+u8_t uip_buf[UIP_BUFSIZE + 2] __attribute__ ((section ("AHBSRAM1")));   /* The packet buffer that contains
+                    incoming packets. */
+#endif /* UIP_CONF_EXTERNAL_BUFFER */
+
+void *uip_appdata;               /* The uip_appdata pointer points to
+                    application data. */
+void *uip_sappdata;              /* The uip_appdata pointer points to
+                    the application data which is to
+                    be sent. */
+#if UIP_URGDATA > 0
+void *uip_urgdata;               /* The uip_urgdata pointer points to
+                    urgent data (out-of-band data), if
+                    present. */
+u16_t uip_urglen, uip_surglen;
+#endif /* UIP_URGDATA > 0 */
+
+u16_t uip_len, uip_slen;
+/* The uip_len is either 8 or 16 bits,
+depending on the maximum packet
+            size. */
+
+u8_t uip_flags;     /* The uip_flags variable is used for
+                communication between the TCP/IP stack
+                and the application program. */
+struct uip_conn *uip_conn;   /* uip_conn always points to the current
+                connection. */
+
+struct uip_conn uip_conns[UIP_CONNS]  __attribute__ ((section ("AHBSRAM1")));
+/* The uip_conns array holds all TCP
+connections. */
+u16_t uip_listenports[UIP_LISTENPORTS] __attribute__ ((section ("AHBSRAM1")));
+/* The uip_listenports list all currently
+listning ports. */
+#if UIP_UDP
+struct uip_udp_conn *uip_udp_conn;
+struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]  __attribute__ ((section ("AHBSRAM1")));
+#endif /* UIP_UDP */
+
+static u16_t ipid;           /* Ths ipid variable is an increasing
+                number that is used for the IP ID
+                field. */
+
+void uip_setipid(u16_t id)
+{
+    ipid = id;
+}
+
+static u8_t iss[4];          /* The iss variable is used for the TCP
+                initial sequence number. */
+
+#if UIP_ACTIVE_OPEN
+static u16_t lastport;       /* Keeps track of the last port used for
+                a new connection. */
+#endif /* UIP_ACTIVE_OPEN */
+
+/* Temporary variables. */
+u8_t uip_acc32[4];
+static u8_t c, opt;
+static u16_t tmp16;
+
+/* Structures and definitions. */
+#define TCP_FIN 0x01
+#define TCP_SYN 0x02
+#define TCP_RST 0x04
+#define TCP_PSH 0x08
+#define TCP_ACK 0x10
+#define TCP_URG 0x20
+#define TCP_CTL 0x3f
+
+#define TCP_OPT_END     0   /* End of TCP options list */
+#define TCP_OPT_NOOP    1   /* "No-operation" TCP option */
+#define TCP_OPT_MSS     2   /* Maximum segment size TCP option */
+
+#define TCP_OPT_MSS_LEN 4   /* Length of TCP MSS option. */
+
+#define ICMP_ECHO_REPLY 0
+#define ICMP_ECHO       8
+
+#define ICMP6_ECHO_REPLY             129
+#define ICMP6_ECHO                   128
+#define ICMP6_NEIGHBOR_SOLICITATION  135
+#define ICMP6_NEIGHBOR_ADVERTISEMENT 136
+
+#define ICMP6_FLAG_S (1 << 6)
+
+#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
+#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
+
+
+/* Macros. */
+#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
+#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+
+#if UIP_STATISTICS == 1
+struct uip_stats uip_stat;
+#define UIP_STAT(s) s
+#else
+#define UIP_STAT(s)
+#endif /* UIP_STATISTICS == 1 */
+
+#if UIP_LOGGING == 1
+void uip_log(char *msg);
+#define UIP_LOG(m) uip_log(m)
+#else
+#define UIP_LOG(m)
+#endif /* UIP_LOGGING == 1 */
+
+#if ! UIP_ARCH_ADD32
+void
+uip_add32(u8_t *op32, u16_t op16)
+{
+    uip_acc32[3] = op32[3] + (op16 & 0xff);
+    uip_acc32[2] = op32[2] + (op16 >> 8);
+    uip_acc32[1] = op32[1];
+    uip_acc32[0] = op32[0];
+
+    if (uip_acc32[2] < (op16 >> 8)) {
+        ++uip_acc32[1];
+        if (uip_acc32[1] == 0) {
+            ++uip_acc32[0];
+        }
+    }
+
+
+    if (uip_acc32[3] < (op16 & 0xff)) {
+        ++uip_acc32[2];
+        if (uip_acc32[2] == 0) {
+            ++uip_acc32[1];
+            if (uip_acc32[1] == 0) {
+                ++uip_acc32[0];
+            }
+        }
+    }
+}
+
+#endif /* UIP_ARCH_ADD32 */
+
+#if ! UIP_ARCH_CHKSUM
+/*---------------------------------------------------------------------------*/
+static u16_t
+chksum(u16_t sum, const u8_t *data, u16_t len)
+{
+    u16_t t;
+    const u8_t *dataptr;
+    const u8_t *last_byte;
+
+    dataptr = data;
+    last_byte = data + len - 1;
+
+    while (dataptr < last_byte) { /* At least two more bytes */
+        t = (dataptr[0] << 8) + dataptr[1];
+        sum += t;
+        if (sum < t) {
+            sum++;        /* carry */
+        }
+        dataptr += 2;
+    }
+
+    if (dataptr == last_byte) {
+        t = (dataptr[0] << 8) + 0;
+        sum += t;
+        if (sum < t) {
+            sum++;        /* carry */
+        }
+    }
+
+    /* Return sum in host byte order. */
+    return sum;
+}
+/*---------------------------------------------------------------------------*/
+u16_t
+uip_chksum(u16_t *data, u16_t len)
+{
+    return htons(chksum(0, (u8_t *)data, len));
+}
+/*---------------------------------------------------------------------------*/
+#ifndef UIP_ARCH_IPCHKSUM
+u16_t
+uip_ipchksum(void)
+{
+    u16_t sum;
+
+    sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
+    DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
+    return (sum == 0) ? 0xffff : htons(sum);
+}
+#endif
+/*---------------------------------------------------------------------------*/
+static u16_t
+upper_layer_chksum(u8_t proto)
+{
+    u16_t upper_layer_len;
+    u16_t sum;
+
+#if UIP_CONF_IPV6
+    upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
+#else /* UIP_CONF_IPV6 */
+    upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
+#endif /* UIP_CONF_IPV6 */
+
+    /* First sum pseudoheader. */
+
+    /* IP protocol and length fields. This addition cannot carry. */
+    sum = upper_layer_len + proto;
+    /* Sum IP source and destination addresses. */
+    sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
+
+    /* Sum TCP header and data. */
+    sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
+                 upper_layer_len);
+
+    return (sum == 0) ? 0xffff : htons(sum);
+}
+/*---------------------------------------------------------------------------*/
+#if UIP_CONF_IPV6
+u16_t
+uip_icmp6chksum(void)
+{
+    return upper_layer_chksum(UIP_PROTO_ICMP6);
+
+}
+#endif /* UIP_CONF_IPV6 */
+/*---------------------------------------------------------------------------*/
+u16_t
+uip_tcpchksum(void)
+{
+    return upper_layer_chksum(UIP_PROTO_TCP);
+}
+/*---------------------------------------------------------------------------*/
+#if UIP_UDP_CHECKSUMS
+u16_t
+uip_udpchksum(void)
+{
+    return upper_layer_chksum(UIP_PROTO_UDP);
+}
+#endif /* UIP_UDP_CHECKSUMS */
+#endif /* UIP_ARCH_CHKSUM */
+/*---------------------------------------------------------------------------*/
+void
+uip_init(void)
+{
+    DEBUG_PRINTF("In uip_init\n");
+
+    for (c = 0; c < UIP_LISTENPORTS; ++c) {
+        uip_listenports[c] = 0;
+    }
+    for (c = 0; c < UIP_CONNS; ++c) {
+        uip_conns[c].tcpstateflags = UIP_CLOSED;
+    }
+#if UIP_ACTIVE_OPEN
+    lastport = 1024;
+#endif /* UIP_ACTIVE_OPEN */
+
+#if UIP_UDP
+    for (c = 0; c < UIP_UDP_CONNS; ++c) {
+        uip_udp_conns[c].lport = 0;
+    }
+#endif /* UIP_UDP */
+
+
+    /* IPv4 initialization. */
+#if UIP_FIXEDADDR == 0
+    /*  uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
+#endif /* UIP_FIXEDADDR */
+
+}
+/*---------------------------------------------------------------------------*/
+#if UIP_ACTIVE_OPEN
+struct uip_conn *
+uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
+{
+    register struct uip_conn *conn, *cconn;
+
+    /* Find an unused local port. */
+again:
+    ++lastport;
+
+    if (lastport >= 32000) {
+        lastport = 4096;
+    }
+
+    /* Check if this port is already in use, and if so try to find
+       another one. */
+    for (c = 0; c < UIP_CONNS; ++c) {
+        conn = &uip_conns[c];
+        if (conn->tcpstateflags != UIP_CLOSED &&
+            conn->lport == htons(lastport)) {
+            goto again;
+        }
+    }
+
+    conn = 0;
+    for (c = 0; c < UIP_CONNS; ++c) {
+        cconn = &uip_conns[c];
+        if (cconn->tcpstateflags == UIP_CLOSED) {
+            conn = cconn;
+            break;
+        }
+        if (cconn->tcpstateflags == UIP_TIME_WAIT) {
+            if (conn == 0 ||
+                cconn->timer > conn->timer) {
+                conn = cconn;
+            }
+        }
+    }
+
+    if (conn == 0) {
+        return 0;
+    }
+
+    conn->tcpstateflags = UIP_SYN_SENT;
+
+    conn->snd_nxt[0] = iss[0];
+    conn->snd_nxt[1] = iss[1];
+    conn->snd_nxt[2] = iss[2];
+    conn->snd_nxt[3] = iss[3];
+
+    conn->initialmss = conn->mss = UIP_TCP_MSS;
+
+    conn->len = 1;   /* TCP length of the SYN is one. */
+    conn->nrtx = 0;
+    conn->timer = 1; /* Send the SYN next time around. */
+    conn->rto = UIP_RTO;
+    conn->sa = 0;
+    conn->sv = 16;   /* Initial value of the RTT variance. */
+    conn->lport = htons(lastport);
+    conn->rport = rport;
+    uip_ipaddr_copy(&conn->ripaddr, ripaddr);
+
+    return conn;
+}
+#endif /* UIP_ACTIVE_OPEN */
+/*---------------------------------------------------------------------------*/
+#if UIP_UDP
+struct uip_udp_conn *
+uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
+{
+    register struct uip_udp_conn *conn;
+
+    /* Find an unused local port. */
+again:
+    ++lastport;
+
+    if (lastport >= 32000) {
+        lastport = 4096;
+    }
+
+    for (c = 0; c < UIP_UDP_CONNS; ++c) {
+        if (uip_udp_conns[c].lport == htons(lastport)) {
+            goto again;
+        }
+    }
+
+
+    conn = 0;
+    for (c = 0; c < UIP_UDP_CONNS; ++c) {
+        if (uip_udp_conns[c].lport == 0) {
+            conn = &uip_udp_conns[c];
+            break;
+        }
+    }
+
+    if (conn == 0) {
+        return 0;
+    }
+
+    conn->lport = HTONS(lastport);
+    conn->rport = rport;
+    if (ripaddr == NULL) {
+        memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
+    } else {
+        uip_ipaddr_copy(&conn->ripaddr, ripaddr);
+    }
+    conn->ttl = UIP_TTL;
+
+    return conn;
+}
+#endif /* UIP_UDP */
+/*---------------------------------------------------------------------------*/
+void
+uip_unlisten(u16_t port)
+{
+    for (c = 0; c < UIP_LISTENPORTS; ++c) {
+        if (uip_listenports[c] == port) {
+            uip_listenports[c] = 0;
+            return;
+        }
+    }
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_listen(u16_t port)
+{
+    for (c = 0; c < UIP_LISTENPORTS; ++c) {
+        if (uip_listenports[c] == 0) {
+            uip_listenports[c] = port;
+            return;
+        }
+    }
+}
+/*---------------------------------------------------------------------------*/
+/* XXX: IP fragment reassembly: not well-tested. */
+
+#if UIP_REASSEMBLY && !UIP_CONF_IPV6
+#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
+static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
+static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
+static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
+                                    0x0f, 0x07, 0x03, 0x01
+                                   };
+static u16_t uip_reasslen;
+static u8_t uip_reassflags;
+#define UIP_REASS_FLAG_LASTFRAG 0x01
+static u8_t uip_reasstmr;
+
+#define IP_MF   0x20
+
+static u8_t
+uip_reass(void)
+{
+    u16_t offset, len;
+    u16_t i;
+
+    /* If ip_reasstmr is zero, no packet is present in the buffer, so we
+       write the IP header of the fragment into the reassembly
+       buffer. The timer is updated with the maximum age. */
+    if (uip_reasstmr == 0) {
+        memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
+        uip_reasstmr = UIP_REASS_MAXAGE;
+        uip_reassflags = 0;
+        /* Clear the bitmap. */
+        memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
+    }
+
+    /* Check if the incoming fragment matches the one currently present
+       in the reasembly buffer. If so, we proceed with copying the
+       fragment into the buffer. */
+    if (BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
+        BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
+        BUF->destipaddr[0] == FBUF->destipaddr[0] &&
+        BUF->destipaddr[1] == FBUF->destipaddr[1] &&
+        BUF->ipid[0] == FBUF->ipid[0] &&
+        BUF->ipid[1] == FBUF->ipid[1]) {
+
+        len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
+        offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
+
+        /* If the offset or the offset + fragment length overflows the
+           reassembly buffer, we discard the entire packet. */
+        if (offset > UIP_REASS_BUFSIZE ||
+            offset + len > UIP_REASS_BUFSIZE) {
+            uip_reasstmr = 0;
+            goto nullreturn;
+        }
+
+        /* Copy the fragment into the reassembly buffer, at the right
+           offset. */
+        memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
+               (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
+               len);
+
+        /* Update the bitmap. */
+        if (offset / (8 * 8) == (offset + len) / (8 * 8)) {
+            /* If the two endpoints are in the same byte, we only update
+            that byte. */
+
+            uip_reassbitmap[offset / (8 * 8)] |=
+                bitmap_bits[(offset / 8 ) & 7] &
+                ~bitmap_bits[((offset + len) / 8 ) & 7];
+        } else {
+            /* If the two endpoints are in different bytes, we update the
+            bytes in the endpoints and fill the stuff inbetween with
+             0xff. */
+            uip_reassbitmap[offset / (8 * 8)] |=
+                bitmap_bits[(offset / 8 ) & 7];
+            for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
+                uip_reassbitmap[i] = 0xff;
+            }
+            uip_reassbitmap[(offset + len) / (8 * 8)] |=
+                ~bitmap_bits[((offset + len) / 8 ) & 7];
+        }
+
+        /* If this fragment has the More Fragments flag set to zero, we
+           know that this is the last fragment, so we can calculate the
+           size of the entire packet. We also set the
+           IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
+           the final fragment. */
+
+        if ((BUF->ipoffset[0] & IP_MF) == 0) {
+            uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
+            uip_reasslen = offset + len;
+        }
+
+        /* Finally, we check if we have a full packet in the buffer. We do
+           this by checking if we have the last fragment and if all bits
+           in the bitmap are set. */
+        if (uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
+            /* Check all bytes up to and including all but the last byte in
+            the bitmap. */
+            for (i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
+                if (uip_reassbitmap[i] != 0xff) {
+                    goto nullreturn;
+                }
+            }
+            /* Check the last byte in the bitmap. It should contain just the
+            right amount of bits. */
+            if (uip_reassbitmap[uip_reasslen / (8 * 8)] !=
+                (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
+                goto nullreturn;
+            }
+
+            /* If we have come this far, we have a full packet in the
+            buffer, so we allocate a pbuf and copy the packet into it. We
+             also reset the timer. */
+            uip_reasstmr = 0;
+            memcpy(BUF, FBUF, uip_reasslen);
+
+            /* Pretend to be a "normal" (i.e., not fragmented) IP packet
+            from now on. */
+            BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
+            BUF->len[0] = uip_reasslen >> 8;
+            BUF->len[1] = uip_reasslen & 0xff;
+            BUF->ipchksum = 0;
+            BUF->ipchksum = ~(uip_ipchksum());
+
+            return uip_reasslen;
+        }
+    }
+
+nullreturn:
+    return 0;
+}
+#endif /* UIP_REASSEMBLY */
+/*---------------------------------------------------------------------------*/
+static void
+uip_add_rcv_nxt(u16_t n)
+{
+    uip_add32(uip_conn->rcv_nxt, n);
+    uip_conn->rcv_nxt[0] = uip_acc32[0];
+    uip_conn->rcv_nxt[1] = uip_acc32[1];
+    uip_conn->rcv_nxt[2] = uip_acc32[2];
+    uip_conn->rcv_nxt[3] = uip_acc32[3];
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_process(u8_t flag)
+{
+    register struct uip_conn *uip_connr = uip_conn;
+
+#if UIP_UDP
+    if (flag == UIP_UDP_SEND_CONN) {
+        goto udp_send;
+    }
+#endif /* UIP_UDP */
+
+    uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
+
+    /* Check if we were invoked because of a poll request for a
+       particular connection. */
+    if (flag == UIP_POLL_REQUEST) {
+        if ((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
+            !uip_outstanding(uip_connr)) {
+            uip_flags = UIP_POLL;
+            UIP_APPCALL();
+            goto appsend;
+        }
+        goto drop;
+
+        /* Check if we were invoked because of the perodic timer fireing. */
+    } else if (flag == UIP_TIMER) {
+#if UIP_REASSEMBLY
+        if (uip_reasstmr != 0) {
+            --uip_reasstmr;
+        }
+#endif /* UIP_REASSEMBLY */
+        /* Increase the initial sequence number. */
+        if (++iss[3] == 0) {
+            if (++iss[2] == 0) {
+                if (++iss[1] == 0) {
+                    ++iss[0];
+                }
+            }
+        }
+
+        /* Reset the length variables. */
+        uip_len = 0;
+        uip_slen = 0;
+
+        /* Check if the connection is in a state in which we simply wait
+           for the connection to time out. If so, we increase the
+           connection's timer and remove the connection if it times
+           out. */
+        if (uip_connr->tcpstateflags == UIP_TIME_WAIT ||
+            uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
+            ++(uip_connr->timer);
+            if (uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
+                uip_connr->tcpstateflags = UIP_CLOSED;
+            }
+        } else if (uip_connr->tcpstateflags != UIP_CLOSED) {
+            /* If the connection has outstanding data, we increase the
+            connection's timer and see if it has reached the RTO value
+             in which case we retransmit. */
+            if (uip_outstanding(uip_connr)) {
+                if (uip_connr->timer-- == 0) {
+                    if (uip_connr->nrtx == UIP_MAXRTX ||
+                        ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
+                          uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
+                         uip_connr->nrtx == UIP_MAXSYNRTX)) {
+                        uip_connr->tcpstateflags = UIP_CLOSED;
+
+                        /* We call UIP_APPCALL() with uip_flags set to
+                           UIP_TIMEDOUT to inform the application that the
+                           connection has timed out. */
+                        uip_flags = UIP_TIMEDOUT;
+                        UIP_APPCALL();
+
+                        /* We also send a reset packet to the remote host. */
+                        BUF->flags = TCP_RST | TCP_ACK;
+                        goto tcp_send_nodata;
+                    }
+
+                    /* Exponential backoff. */
+                    uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4 ?
+                                                   4 :
+                                                   uip_connr->nrtx);
+                    ++(uip_connr->nrtx);
+
+                    /* Ok, so we need to retransmit. We do this differently
+                       depending on which state we are in. In ESTABLISHED, we
+                       call upon the application so that it may prepare the
+                       data for the retransmit. In SYN_RCVD, we resend the
+                       SYNACK that we sent earlier and in LAST_ACK we have to
+                       retransmit our FINACK. */
+                    UIP_STAT(++uip_stat.tcp.rexmit);
+                    switch (uip_connr->tcpstateflags & UIP_TS_MASK) {
+                        case UIP_SYN_RCVD:
+                            /* In the SYN_RCVD state, we should retransmit our
+                                   SYNACK. */
+                            goto tcp_send_synack;
+
+#if UIP_ACTIVE_OPEN
+                        case UIP_SYN_SENT:
+                            /* In the SYN_SENT state, we retransmit out SYN. */
+                            BUF->flags = 0;
+                            goto tcp_send_syn;
+#endif /* UIP_ACTIVE_OPEN */
+
+                        case UIP_ESTABLISHED:
+                            /* In the ESTABLISHED state, we call upon the application
+                                   to do the actual retransmit after which we jump into
+                                   the code for sending out the packet (the apprexmit
+                                   label). */
+                            uip_flags = UIP_REXMIT;
+                            UIP_APPCALL();
+                            goto apprexmit;
+
+                        case UIP_FIN_WAIT_1:
+                        case UIP_CLOSING:
+                        case UIP_LAST_ACK:
+                            /* In all these states we should retransmit a FINACK. */
+                            goto tcp_send_finack;
+
+                    }
+                }
+            } else if ((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
+                /* If there was no need for a retransmission, we poll the
+                       application for new data. */
+                uip_flags = UIP_POLL;
+                UIP_APPCALL();
+                goto appsend;
+            }
+        }
+        goto drop;
+    }
+#if UIP_UDP
+    if (flag == UIP_UDP_TIMER) {
+        if (uip_udp_conn->lport != 0) {
+            uip_conn = NULL;
+            uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+            uip_len = uip_slen = 0;
+            uip_flags = UIP_POLL;
+            UIP_UDP_APPCALL();
+            goto udp_send;
+        } else {
+            goto drop;
+        }
+    }
+#endif
+
+    /* This is where the input processing starts. */
+    UIP_STAT(++uip_stat.ip.recv);
+
+    /* Start of IP input header processing code. */
+
+#if UIP_CONF_IPV6
+    /* Check validity of the IP header. */
+    if ((BUF->vtc & 0xf0) != 0x60)  { /* IP version and header length. */
+        UIP_STAT(++uip_stat.ip.drop);
+        UIP_STAT(++uip_stat.ip.vhlerr);
+        UIP_LOG("ipv6: invalid version.");
+        goto drop;
+    }
+#else /* UIP_CONF_IPV6 */
+    /* Check validity of the IP header. */
+    if (BUF->vhl != 0x45)  { /* IP version and header length. */
+        UIP_STAT(++uip_stat.ip.drop);
+        UIP_STAT(++uip_stat.ip.vhlerr);
+        UIP_LOG("ip: invalid version or header length.");
+        goto drop;
+    }
+#endif /* UIP_CONF_IPV6 */
+
+    /* Check the size of the packet. If the size reported to us in
+       uip_len is smaller the size reported in the IP header, we assume
+       that the packet has been corrupted in transit. If the size of
+       uip_len is larger than the size reported in the IP packet header,
+       the packet has been padded and we set uip_len to the correct
+       value.. */
+
+    if ((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
+        uip_len = (BUF->len[0] << 8) + BUF->len[1];
+#if UIP_CONF_IPV6
+        uip_len += 40; /* The length reported in the IPv6 header is the
+              length of the payload that follows the
+              header. However, uIP uses the uip_len variable
+              for holding the size of the entire packet,
+              including the IP header. For IPv4 this is not a
+              problem as the length field in the IPv4 header
+              contains the length of the entire packet. But
+              for IPv6 we need to add the size of the IPv6
+              header (40 bytes). */
+#endif /* UIP_CONF_IPV6 */
+    } else {
+        UIP_LOG("ip: packet shorter than reported in IP header.");
+        goto drop;
+    }
+
+#if !UIP_CONF_IPV6
+    /* Check the fragment flag. */
+    if ((BUF->ipoffset[0] & 0x3f) != 0 ||
+        BUF->ipoffset[1] != 0) {
+#if UIP_REASSEMBLY
+        uip_len = uip_reass();
+        if (uip_len == 0) {
+            goto drop;
+        }
+#else /* UIP_REASSEMBLY */
+        UIP_STAT(++uip_stat.ip.drop);
+        UIP_STAT(++uip_stat.ip.fragerr);
+        UIP_LOG("ip: fragment dropped.");
+        goto drop;
+#endif /* UIP_REASSEMBLY */
+    }
+#endif /* UIP_CONF_IPV6 */
+
+    if (uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
+        /* If we are configured to use ping IP address configuration and
+           hasn't been assigned an IP address yet, we accept all ICMP
+           packets. */
+#if UIP_PINGADDRCONF && !UIP_CONF_IPV6
+        if (BUF->proto == UIP_PROTO_ICMP) {
+            UIP_LOG("ip: possible ping config packet received.");
+            goto icmp_input;
+        } else {
+            UIP_LOG("ip: packet dropped since no address assigned.");
+            goto drop;
+        }
+#endif /* UIP_PINGADDRCONF */
+
+    } else {
+        /* If IP broadcast support is configured, we check for a broadcast
+           UDP packet, which may be destined to us. */
+#if UIP_BROADCAST
+        DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
+        if (BUF->proto == UIP_PROTO_UDP &&
+            uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
+            /*&&
+            uip_ipchksum() == 0xffff*/) {
+            goto udp_input;
+        }
+#endif /* UIP_BROADCAST */
+
+        /* Check if the packet is destined for our IP address. */
+#if !UIP_CONF_IPV6
+        if (!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
+            UIP_STAT(++uip_stat.ip.drop);
+            goto drop;
+        }
+#else /* UIP_CONF_IPV6 */
+        /* For IPv6, packet reception is a little trickier as we need to
+           make sure that we listen to certain multicast addresses (all
+           hosts multicast address, and the solicited-node multicast
+           address) as well. However, we will cheat here and accept all
+           multicast packets that are sent to the ff02::/16 addresses. */
+        if (!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
+            BUF->destipaddr[0] != HTONS(0xff02)) {
+            UIP_STAT(++uip_stat.ip.drop);
+            goto drop;
+        }
+#endif /* UIP_CONF_IPV6 */
+    }
+
+#if !UIP_CONF_IPV6
+    if (uip_ipchksum() != 0xffff) {
+        /* Compute and check the IP header
+                      checksum. */
+        UIP_STAT(++uip_stat.ip.drop);
+        UIP_STAT(++uip_stat.ip.chkerr);
+        UIP_LOG("ip: bad checksum.");
+        goto drop;
+    }
+#endif /* UIP_CONF_IPV6 */
+
+    if (BUF->proto == UIP_PROTO_TCP) {
+        /* Check for TCP packet. If so,
+                         proceed with TCP input
+                         processing. */
+        goto tcp_input;
+    }
+
+#if UIP_UDP
+    if (BUF->proto == UIP_PROTO_UDP) {
+        goto udp_input;
+    }
+#endif /* UIP_UDP */
+
+#if !UIP_CONF_IPV6
+    /* ICMPv4 processing code follows. */
+    if (BUF->proto != UIP_PROTO_ICMP) {
+        /* We only allow ICMP packets from
+                      here. */
+        UIP_STAT(++uip_stat.ip.drop);
+        UIP_STAT(++uip_stat.ip.protoerr);
+        UIP_LOG("ip: neither tcp nor icmp.");
+        goto drop;
+    }
+
+#if UIP_PINGADDRCONF
+icmp_input:
+#endif /* UIP_PINGADDRCONF */
+    UIP_STAT(++uip_stat.icmp.recv);
+
+    /* ICMP echo (i.e., ping) processing. This is simple, we only change
+       the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
+       checksum before we return the packet. */
+    if (ICMPBUF->type != ICMP_ECHO) {
+        UIP_STAT(++uip_stat.icmp.drop);
+        UIP_STAT(++uip_stat.icmp.typeerr);
+        UIP_LOG("icmp: not icmp echo.");
+        goto drop;
+    }
+
+    /* If we are configured to use ping IP address assignment, we use
+       the destination IP address of this ping packet and assign it to
+       ourself. */
+#if UIP_PINGADDRCONF
+    if ((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
+        uip_hostaddr[0] = BUF->destipaddr[0];
+        uip_hostaddr[1] = BUF->destipaddr[1];
+    }
+#endif /* UIP_PINGADDRCONF */
+
+    ICMPBUF->type = ICMP_ECHO_REPLY;
+
+    if (ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
+        ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
+    } else {
+        ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
+    }
+
+    /* Swap IP addresses. */
+    uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+    uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+
+    UIP_STAT(++uip_stat.icmp.sent);
+    goto send;
+
+    /* End of IPv4 input header processing code. */
+#else /* !UIP_CONF_IPV6 */
+
+    /* This is IPv6 ICMPv6 processing code. */
+    DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
+
+    if (BUF->proto != UIP_PROTO_ICMP6) {
+        /* We only allow ICMPv6 packets from
+                       here. */
+        UIP_STAT(++uip_stat.ip.drop);
+        UIP_STAT(++uip_stat.ip.protoerr);
+        UIP_LOG("ip: neither tcp nor icmp6.");
+        goto drop;
+    }
+
+    UIP_STAT(++uip_stat.icmp.recv);
+
+    /* If we get a neighbor solicitation for our address we should send
+       a neighbor advertisement message back. */
+    if (ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
+        if (uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
+
+            if (ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
+                /* Save the sender's address in our neighbor list. */
+                uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
+            }
+
+            /* We should now send a neighbor advertisement back to where the
+            neighbor solicication came from. */
+            ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
+            ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
+
+            ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
+
+            uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
+            uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
+            ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
+            ICMPBUF->options[1] = 1;  /* Options length, 1 = 8 bytes. */
+            memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
+            ICMPBUF->icmpchksum = 0;
+            ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+            goto send;
+
+        }
+        goto drop;
+    } else if (ICMPBUF->type == ICMP6_ECHO) {
+        /* ICMP echo (i.e., ping) processing. This is simple, we only
+           change the ICMP type from ECHO to ECHO_REPLY and update the
+           ICMP checksum before we return the packet. */
+
+        ICMPBUF->type = ICMP6_ECHO_REPLY;
+
+        uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+        uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+        ICMPBUF->icmpchksum = 0;
+        ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+
+        UIP_STAT(++uip_stat.icmp.sent);
+        goto send;
+    } else {
+        DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
+        UIP_STAT(++uip_stat.icmp.drop);
+        UIP_STAT(++uip_stat.icmp.typeerr);
+        UIP_LOG("icmp: unknown ICMP message.");
+        goto drop;
+    }
+
+    /* End of IPv6 ICMP processing. */
+
+#endif /* !UIP_CONF_IPV6 */
+
+#if UIP_UDP
+    /* UDP input processing. */
+udp_input:
+    /* UDP processing is really just a hack. We don't do anything to the
+       UDP/IP headers, but let the UDP application do all the hard
+       work. If the application sets uip_slen, it has a packet to
+       send. */
+#if UIP_UDP_CHECKSUMS
+    uip_len = uip_len - UIP_IPUDPH_LEN;
+    uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+    if (UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
+        UIP_STAT(++uip_stat.udp.drop);
+        UIP_STAT(++uip_stat.udp.chkerr);
+        UIP_LOG("udp: bad checksum.");
+        goto drop;
+    }
+#else /* UIP_UDP_CHECKSUMS */
+    uip_len = uip_len - UIP_IPUDPH_LEN;
+#endif /* UIP_UDP_CHECKSUMS */
+
+    /* Demultiplex this UDP packet between the UDP "connections". */
+    for (uip_udp_conn = &uip_udp_conns[0];
+         uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
+         ++uip_udp_conn) {
+        /* If the local UDP port is non-zero, the connection is considered
+           to be used. If so, the local port number is checked against the
+           destination port number in the received packet. If the two port
+           numbers match, the remote port number is checked if the
+           connection is bound to a remote port. Finally, if the
+           connection is bound to a remote IP address, the source IP
+           address of the packet is checked. */
+        if (uip_udp_conn->lport != 0 &&
+            UDPBUF->destport == uip_udp_conn->lport &&
+            (uip_udp_conn->rport == 0 ||
+             UDPBUF->srcport == uip_udp_conn->rport) &&
+            (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
+             uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
+             uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
+            goto udp_found;
+        }
+    }
+    UIP_LOG("udp: no matching connection found");
+    goto drop;
+
+udp_found:
+    uip_conn = NULL;
+    uip_flags = UIP_NEWDATA;
+    uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+    uip_slen = 0;
+    UIP_UDP_APPCALL();
+udp_send:
+    if (uip_slen == 0) {
+        goto drop;
+    }
+    uip_len = uip_slen + UIP_IPUDPH_LEN;
+
+#if UIP_CONF_IPV6
+    /* For IPv6, the IP length field does not include the IPv6 IP header
+       length. */
+    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+    BUF->len[0] = (uip_len >> 8);
+    BUF->len[1] = (uip_len & 0xff);
+#endif /* UIP_CONF_IPV6 */
+
+    BUF->ttl = uip_udp_conn->ttl;
+    BUF->proto = UIP_PROTO_UDP;
+
+    UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
+    UDPBUF->udpchksum = 0;
+
+    BUF->srcport  = uip_udp_conn->lport;
+    BUF->destport = uip_udp_conn->rport;
+
+    uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+    uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
+
+    uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
+
+#if UIP_UDP_CHECKSUMS
+    /* Calculate UDP checksum. */
+    UDPBUF->udpchksum = ~(uip_udpchksum());
+    if (UDPBUF->udpchksum == 0) {
+        UDPBUF->udpchksum = 0xffff;
+    }
+#endif /* UIP_UDP_CHECKSUMS */
+
+    goto ip_send_nolen;
+#endif /* UIP_UDP */
+
+    /* TCP input processing. */
+tcp_input:
+    UIP_STAT(++uip_stat.tcp.recv);
+
+    /* Start of TCP input header processing code. */
+
+    if (uip_tcpchksum() != 0xffff) {
+        /* Compute and check the TCP
+                         checksum. */
+        UIP_STAT(++uip_stat.tcp.drop);
+        UIP_STAT(++uip_stat.tcp.chkerr);
+        UIP_LOG("tcp: bad checksum.");
+        goto drop;
+    }
+
+
+    /* Demultiplex this segment. */
+    /* First check any active connections. */
+    for (uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
+         ++uip_connr) {
+        if (uip_connr->tcpstateflags != UIP_CLOSED &&
+            BUF->destport == uip_connr->lport &&
+            BUF->srcport == uip_connr->rport &&
+            uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
+            goto found;
+        }
+    }
+
+    /* If we didn't find and active connection that expected the packet,
+       either this packet is an old duplicate, or this is a SYN packet
+       destined for a connection in LISTEN. If the SYN flag isn't set,
+       it is an old packet and we send a RST. */
+    if ((BUF->flags & TCP_CTL) != TCP_SYN) {
+        goto reset;
+    }
+
+    tmp16 = BUF->destport;
+    /* Next, check listening connections. */
+    for (c = 0; c < UIP_LISTENPORTS; ++c) {
+        if (tmp16 == uip_listenports[c])
+            goto found_listen;
+    }
+
+    /* No matching connection found, so we send a RST packet. */
+    UIP_STAT(++uip_stat.tcp.synrst);
+reset:
+
+    /* We do not send resets in response to resets. */
+    if (BUF->flags & TCP_RST) {
+        goto drop;
+    }
+
+    UIP_STAT(++uip_stat.tcp.rst);
+
+    BUF->flags = TCP_RST | TCP_ACK;
+    uip_len = UIP_IPTCPH_LEN;
+    BUF->tcpoffset = 5 << 4;
+
+    /* Flip the seqno and ackno fields in the TCP header. */
+    c = BUF->seqno[3];
+    BUF->seqno[3] = BUF->ackno[3];
+    BUF->ackno[3] = c;
+
+    c = BUF->seqno[2];
+    BUF->seqno[2] = BUF->ackno[2];
+    BUF->ackno[2] = c;
+
+    c = BUF->seqno[1];
+    BUF->seqno[1] = BUF->ackno[1];
+    BUF->ackno[1] = c;
+
+    c = BUF->seqno[0];
+    BUF->seqno[0] = BUF->ackno[0];
+    BUF->ackno[0] = c;
+
+    /* We also have to increase the sequence number we are
+       acknowledging. If the least significant byte overflowed, we need
+       to propagate the carry to the other bytes as well. */
+    if (++BUF->ackno[3] == 0) {
+        if (++BUF->ackno[2] == 0) {
+            if (++BUF->ackno[1] == 0) {
+                ++BUF->ackno[0];
+            }
+        }
+    }
+
+    /* Swap port numbers. */
+    tmp16 = BUF->srcport;
+    BUF->srcport = BUF->destport;
+    BUF->destport = tmp16;
+
+    /* Swap IP addresses. */
+    uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+    uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+
+    /* And send out the RST packet! */
+    goto tcp_send_noconn;
+
+    /* This label will be jumped to if we matched the incoming packet
+       with a connection in LISTEN. In that case, we should create a new
+       connection and send a SYNACK in return. */
+found_listen:
+    /* First we check if there are any connections avaliable. Unused
+       connections are kept in the same table as used connections, but
+       unused ones have the tcpstate set to CLOSED. Also, connections in
+       TIME_WAIT are kept track of and we'll use the oldest one if no
+       CLOSED connections are found. Thanks to Eddie C. Dost for a very
+       nice algorithm for the TIME_WAIT search. */
+    uip_connr = 0;
+    for (c = 0; c < UIP_CONNS; ++c) {
+        if (uip_conns[c].tcpstateflags == UIP_CLOSED) {
+            uip_connr = &uip_conns[c];
+            break;
+        }
+        if (uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
+            if (uip_connr == 0 ||
+                uip_conns[c].timer > uip_connr->timer) {
+                uip_connr = &uip_conns[c];
+            }
+        }
+    }
+
+    if (uip_connr == 0) {
+        /* All connections are used already, we drop packet and hope that
+           the remote end will retransmit the packet at a time when we
+           have more spare connections. */
+        UIP_STAT(++uip_stat.tcp.syndrop);
+        UIP_LOG("tcp: found no unused connections.");
+        goto drop;
+    }
+    uip_conn = uip_connr;
+
+    /* Fill in the necessary fields for the new connection. */
+    uip_connr->rto = uip_connr->timer = UIP_RTO;
+    uip_connr->sa = 0;
+    uip_connr->sv = 4;
+    uip_connr->nrtx = 0;
+    uip_connr->lport = BUF->destport;
+    uip_connr->rport = BUF->srcport;
+    uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
+    uip_connr->tcpstateflags = UIP_SYN_RCVD;
+
+    uip_connr->snd_nxt[0] = iss[0];
+    uip_connr->snd_nxt[1] = iss[1];
+    uip_connr->snd_nxt[2] = iss[2];
+    uip_connr->snd_nxt[3] = iss[3];
+    uip_connr->len = 1;
+
+    /* rcv_nxt should be the seqno from the incoming packet + 1. */
+    uip_connr->rcv_nxt[3] = BUF->seqno[3];
+    uip_connr->rcv_nxt[2] = BUF->seqno[2];
+    uip_connr->rcv_nxt[1] = BUF->seqno[1];
+    uip_connr->rcv_nxt[0] = BUF->seqno[0];
+    uip_add_rcv_nxt(1);
+
+    /* Parse the TCP MSS option, if present. */
+    if ((BUF->tcpoffset & 0xf0) > 0x50) {
+        for (c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
+            opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
+            if (opt == TCP_OPT_END) {
+                /* End of options. */
+                break;
+            } else if (opt == TCP_OPT_NOOP) {
+                ++c;
+                /* NOP option. */
+            } else if (opt == TCP_OPT_MSS &&
+                       uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
+                /* An MSS option with the right option length. */
+                tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
+                        (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
+                uip_connr->initialmss = uip_connr->mss =
+                                            tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16;
+
+                /* And we are done processing options. */
+                break;
+            } else {
+                /* All other options have a length field, so that we easily
+                   can skip past them. */
+                if (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
+                    /* If the length field is zero, the options are malformed
+                       and we don't process them further. */
+                    break;
+                }
+                c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
+            }
+        }
+    }
+
+    /* Our response will be a SYNACK. */
+#if UIP_ACTIVE_OPEN
+tcp_send_synack:
+    BUF->flags = TCP_ACK;
+
+tcp_send_syn:
+    BUF->flags |= TCP_SYN;
+#else /* UIP_ACTIVE_OPEN */
+tcp_send_synack:
+    BUF->flags = TCP_SYN | TCP_ACK;
+#endif /* UIP_ACTIVE_OPEN */
+
+    /* We send out the TCP Maximum Segment Size option with our
+       SYNACK. */
+    BUF->optdata[0] = TCP_OPT_MSS;
+    BUF->optdata[1] = TCP_OPT_MSS_LEN;
+    BUF->optdata[2] = (UIP_TCP_MSS) / 256;
+    BUF->optdata[3] = (UIP_TCP_MSS) & 255;
+    uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
+    BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
+    goto tcp_send;
+
+    /* This label will be jumped to if we found an active connection. */
+found:
+    uip_conn = uip_connr;
+    uip_flags = 0;
+    /* We do a very naive form of TCP reset processing; we just accept
+       any RST and kill our connection. We should in fact check if the
+       sequence number of this reset is wihtin our advertised window
+       before we accept the reset. */
+    if (BUF->flags & TCP_RST) {
+        uip_connr->tcpstateflags = UIP_CLOSED;
+        UIP_LOG("tcp: got reset, aborting connection.");
+        uip_flags = UIP_ABORT;
+        UIP_APPCALL();
+        goto drop;
+    }
+    /* Calculated the length of the data, if the application has sent
+       any data to us. */
+    c = (BUF->tcpoffset >> 4) << 2;
+    /* uip_len will contain the length of the actual TCP data. This is
+       calculated by subtracing the length of the TCP header (in
+       c) and the length of the IP header (20 bytes). */
+    uip_len = uip_len - c - UIP_IPH_LEN;
+
+    /* First, check if the sequence number of the incoming packet is
+       what we're expecting next. If not, we send out an ACK with the
+       correct numbers in. */
+    if (!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
+          ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
+        if ((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
+            (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
+             BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
+             BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
+             BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
+            goto tcp_send_ack;
+        }
+    }
+
+    /* Next, check if the incoming segment acknowledges any outstanding
+       data. If so, we update the sequence number, reset the length of
+       the outstanding data, calculate RTT estimations, and reset the
+       retransmission timer. */
+    if ((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
+        uip_add32(uip_connr->snd_nxt, uip_connr->len);
+
+        if (BUF->ackno[0] == uip_acc32[0] &&
+            BUF->ackno[1] == uip_acc32[1] &&
+            BUF->ackno[2] == uip_acc32[2] &&
+            BUF->ackno[3] == uip_acc32[3]) {
+            /* Update sequence number. */
+            uip_connr->snd_nxt[0] = uip_acc32[0];
+            uip_connr->snd_nxt[1] = uip_acc32[1];
+            uip_connr->snd_nxt[2] = uip_acc32[2];
+            uip_connr->snd_nxt[3] = uip_acc32[3];
+
+
+            /* Do RTT estimation, unless we have done retransmissions. */
+            if (uip_connr->nrtx == 0) {
+                signed char m;
+                m = uip_connr->rto - uip_connr->timer;
+                /* This is taken directly from VJs original code in his paper */
+                m = m - (uip_connr->sa >> 3);
+                uip_connr->sa += m;
+                if (m < 0) {
+                    m = -m;
+                }
+                m = m - (uip_connr->sv >> 2);
+                uip_connr->sv += m;
+                uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
+
+            }
+            /* Set the acknowledged flag. */
+            uip_flags = UIP_ACKDATA;
+            /* Reset the retransmission timer. */
+            uip_connr->timer = uip_connr->rto;
+
+            /* Reset length of outstanding data. */
+            uip_connr->len = 0;
+        }
+
+    }
+
+    /* Do different things depending on in what state the connection is. */
+    switch (uip_connr->tcpstateflags & UIP_TS_MASK) {
+            /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
+            implemented, since we force the application to close when the
+            peer sends a FIN (hence the application goes directly from
+            ESTABLISHED to LAST_ACK). */
+        case UIP_SYN_RCVD:
+            /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
+               we are waiting for an ACK that acknowledges the data we sent
+               out the last time. Therefore, we want to have the UIP_ACKDATA
+               flag set. If so, we enter the ESTABLISHED state. */
+            if (uip_flags & UIP_ACKDATA) {
+                uip_connr->tcpstateflags = UIP_ESTABLISHED;
+                uip_flags = UIP_CONNECTED;
+                uip_connr->len = 0;
+                if (uip_len > 0) {
+                    uip_flags |= UIP_NEWDATA;
+                    uip_add_rcv_nxt(uip_len);
+                }
+                uip_slen = 0;
+                UIP_APPCALL();
+                goto appsend;
+            }
+            goto drop;
+#if UIP_ACTIVE_OPEN
+        case UIP_SYN_SENT:
+            /* In SYN_SENT, we wait for a SYNACK that is sent in response to
+               our SYN. The rcv_nxt is set to sequence number in the SYNACK
+               plus one, and we send an ACK. We move into the ESTABLISHED
+               state. */
+            if ((uip_flags & UIP_ACKDATA) &&
+                (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
+
+                /* Parse the TCP MSS option, if present. */
+                if ((BUF->tcpoffset & 0xf0) > 0x50) {
+                    for (c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
+                        opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
+                        if (opt == TCP_OPT_END) {
+                            /* End of options. */
+                            break;
+                        } else if (opt == TCP_OPT_NOOP) {
+                            ++c;
+                            /* NOP option. */
+                        } else if (opt == TCP_OPT_MSS &&
+                                   uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
+                            /* An MSS option with the right option length. */
+                            tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
+                                    uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
+                            uip_connr->initialmss =
+                                uip_connr->mss = tmp16 > UIP_TCP_MSS ? UIP_TCP_MSS : tmp16;
+
+                            /* And we are done processing options. */
+                            break;
+                        } else {
+                            /* All other options have a length field, so that we easily
+                               can skip past them. */
+                            if (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
+                                /* If the length field is zero, the options are malformed
+                                and we don't process them further. */
+                                break;
+                            }
+                            c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
+                        }
+                    }
+                }
+                uip_connr->tcpstateflags = UIP_ESTABLISHED;
+                uip_connr->rcv_nxt[0] = BUF->seqno[0];
+                uip_connr->rcv_nxt[1] = BUF->seqno[1];
+                uip_connr->rcv_nxt[2] = BUF->seqno[2];
+                uip_connr->rcv_nxt[3] = BUF->seqno[3];
+                uip_add_rcv_nxt(1);
+                uip_flags = UIP_CONNECTED | UIP_NEWDATA;
+                uip_connr->len = 0;
+                uip_len = 0;
+                uip_slen = 0;
+                UIP_APPCALL();
+                goto appsend;
+            }
+            /* Inform the application that the connection failed */
+            uip_flags = UIP_ABORT;
+            UIP_APPCALL();
+            /* The connection is closed after we send the RST */
+            uip_conn->tcpstateflags = UIP_CLOSED;
+            goto reset;
+#endif /* UIP_ACTIVE_OPEN */
+
+        case UIP_ESTABLISHED:
+            /* In the ESTABLISHED state, we call upon the application to feed
+            data into the uip_buf. If the UIP_ACKDATA flag is set, the
+            application should put new data into the buffer, otherwise we are
+            retransmitting an old segment, and the application should put that
+            data into the buffer.
+
+            If the incoming packet is a FIN, we should close the connection on
+            this side as well, and we send out a FIN and enter the LAST_ACK
+            state. We require that there is no outstanding data; otherwise the
+            sequence numbers will be screwed up. */
+
+            if (BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
+                if (uip_outstanding(uip_connr)) {
+                    goto drop;
+                }
+                uip_add_rcv_nxt(1 + uip_len);
+                uip_flags |= UIP_CLOSE;
+                if (uip_len > 0) {
+                    uip_flags |= UIP_NEWDATA;
+                }
+                UIP_APPCALL();
+                uip_connr->len = 1;
+                uip_connr->tcpstateflags = UIP_LAST_ACK;
+                uip_connr->nrtx = 0;
+tcp_send_finack:
+                BUF->flags = TCP_FIN | TCP_ACK;
+                goto tcp_send_nodata;
+            }
+
+            /* Check the URG flag. If this is set, the segment carries urgent
+               data that we must pass to the application. */
+            if ((BUF->flags & TCP_URG) != 0) {
+#if UIP_URGDATA > 0
+                uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
+                if (uip_urglen > uip_len) {
+                    /* There is more urgent data in the next segment to come. */
+                    uip_urglen = uip_len;
+                }
+                uip_add_rcv_nxt(uip_urglen);
+                uip_len -= uip_urglen;
+                uip_urgdata = uip_appdata;
+                uip_appdata += uip_urglen;
+            } else {
+                uip_urglen = 0;
+#else /* UIP_URGDATA > 0 */
+                uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
+                uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
+#endif /* UIP_URGDATA > 0 */
+            }
+
+            /* If uip_len > 0 we have TCP data in the packet, and we flag this
+               by setting the UIP_NEWDATA flag and update the sequence number
+               we acknowledge. If the application has stopped the dataflow
+               using uip_stop(), we must not accept any data packets from the
+               remote host. */
+            if (uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
+                uip_flags |= UIP_NEWDATA;
+                uip_add_rcv_nxt(uip_len);
+            }
+
+            /* Check if the available buffer space advertised by the other end
+               is smaller than the initial MSS for this connection. If so, we
+               set the current MSS to the window size to ensure that the
+               application does not send more data than the other end can
+               handle.
+
+               If the remote host advertises a zero window, we set the MSS to
+               the initial MSS so that the application will send an entire MSS
+               of data. This data will not be acknowledged by the receiver,
+               and the application will retransmit it. This is called the
+               "persistent timer" and uses the retransmission mechanim.
+            */
+            tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
+            if (tmp16 > uip_connr->initialmss ||
+                tmp16 == 0) {
+                tmp16 = uip_connr->initialmss;
+            }
+            uip_connr->mss = tmp16;
+
+            /* If this packet constitutes an ACK for outstanding data (flagged
+               by the UIP_ACKDATA flag, we should call the application since it
+               might want to send more data. If the incoming packet had data
+               from the peer (as flagged by the UIP_NEWDATA flag), the
+               application must also be notified.
+
+               When the application is called, the global variable uip_len
+               contains the length of the incoming data. The application can
+               access the incoming data through the global pointer
+               uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
+               bytes into the uip_buf array.
+
+               If the application wishes to send any data, this data should be
+               put into the uip_appdata and the length of the data should be
+               put into uip_len. If the application don't have any data to
+               send, uip_len must be set to 0. */
+            if (uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
+                uip_slen = 0;
+                UIP_APPCALL();
+
+appsend:
+
+                if (uip_flags & UIP_ABORT) {
+                    uip_slen = 0;
+                    uip_connr->tcpstateflags = UIP_CLOSED;
+                    BUF->flags = TCP_RST | TCP_ACK;
+                    goto tcp_send_nodata;
+                }
+
+                if (uip_flags & UIP_CLOSE) {
+                    uip_slen = 0;
+                    uip_connr->len = 1;
+                    uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
+                    uip_connr->nrtx = 0;
+                    BUF->flags = TCP_FIN | TCP_ACK;
+                    goto tcp_send_nodata;
+                }
+
+                /* If uip_slen > 0, the application has data to be sent. */
+                if (uip_slen > 0) {
+
+                    /* If the connection has acknowledged data, the contents of
+                       the ->len variable should be discarded. */
+                    if ((uip_flags & UIP_ACKDATA) != 0) {
+                        uip_connr->len = 0;
+                    }
+
+                    /* If the ->len variable is non-zero the connection has
+                       already data in transit and cannot send anymore right
+                       now. */
+                    if (uip_connr->len == 0) {
+
+                        /* The application cannot send more than what is allowed by
+                           the mss (the minumum of the MSS and the available
+                           window). */
+                        if (uip_slen > uip_connr->mss) {
+                            uip_slen = uip_connr->mss;
+                        }
+
+                        /* Remember how much data we send out now so that we know
+                           when everything has been acknowledged. */
+                        uip_connr->len = uip_slen;
+                    } else {
+
+                        /* If the application already had unacknowledged data, we
+                           make sure that the application does not send (i.e.,
+                           retransmit) out more than it previously sent out. */
+                        uip_slen = uip_connr->len;
+                    }
+                }
+                uip_connr->nrtx = 0;
+apprexmit:
+                uip_appdata = uip_sappdata;
+
+                /* If the application has data to be sent, or if the incoming
+                   packet had new data in it, we must send out a packet. */
+                if (uip_slen > 0 && uip_connr->len > 0) {
+                    /* Add the length of the IP and TCP headers. */
+                    uip_len = uip_connr->len + UIP_TCPIP_HLEN;
+                    /* We always set the ACK flag in response packets. */
+                    BUF->flags = TCP_ACK | TCP_PSH;
+                    /* Send the packet. */
+                    goto tcp_send_noopts;
+                }
+                /* If there is no data to send, just send out a pure ACK if
+                there is newdata. */
+                if (uip_flags & UIP_NEWDATA) {
+                    uip_len = UIP_TCPIP_HLEN;
+                    BUF->flags = TCP_ACK;
+                    goto tcp_send_noopts;
+                }
+            }
+            goto drop;
+        case UIP_LAST_ACK:
+            /* We can close this connection if the peer has acknowledged our
+               FIN. This is indicated by the UIP_ACKDATA flag. */
+            if (uip_flags & UIP_ACKDATA) {
+                uip_connr->tcpstateflags = UIP_CLOSED;
+                uip_flags = UIP_CLOSE;
+                UIP_APPCALL();
+            }
+            break;
+
+        case UIP_FIN_WAIT_1:
+            /* The application has closed the connection, but the remote host
+               hasn't closed its end yet. Thus we do nothing but wait for a
+               FIN from the other side. */
+            if (uip_len > 0) {
+                uip_add_rcv_nxt(uip_len);
+            }
+            if (BUF->flags & TCP_FIN) {
+                if (uip_flags & UIP_ACKDATA) {
+                    uip_connr->tcpstateflags = UIP_TIME_WAIT;
+                    uip_connr->timer = 0;
+                    uip_connr->len = 0;
+                } else {
+                    uip_connr->tcpstateflags = UIP_CLOSING;
+                }
+                uip_add_rcv_nxt(1);
+                uip_flags = UIP_CLOSE;
+                UIP_APPCALL();
+                goto tcp_send_ack;
+            } else if (uip_flags & UIP_ACKDATA) {
+                uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
+                uip_connr->len = 0;
+                goto drop;
+            }
+            if (uip_len > 0) {
+                goto tcp_send_ack;
+            }
+            goto drop;
+
+        case UIP_FIN_WAIT_2:
+            if (uip_len > 0) {
+                uip_add_rcv_nxt(uip_len);
+            }
+            if (BUF->flags & TCP_FIN) {
+                uip_connr->tcpstateflags = UIP_TIME_WAIT;
+                uip_connr->timer = 0;
+                uip_add_rcv_nxt(1);
+                uip_flags = UIP_CLOSE;
+                UIP_APPCALL();
+                goto tcp_send_ack;
+            }
+            if (uip_len > 0) {
+                goto tcp_send_ack;
+            }
+            goto drop;
+
+        case UIP_TIME_WAIT:
+            goto tcp_send_ack;
+
+        case UIP_CLOSING:
+            if (uip_flags & UIP_ACKDATA) {
+                uip_connr->tcpstateflags = UIP_TIME_WAIT;
+                uip_connr->timer = 0;
+            }
+    }
+    goto drop;
+
+
+    /* We jump here when we are ready to send the packet, and just want
+       to set the appropriate TCP sequence numbers in the TCP header. */
+tcp_send_ack:
+    BUF->flags = TCP_ACK;
+tcp_send_nodata:
+    uip_len = UIP_IPTCPH_LEN;
+tcp_send_noopts:
+    BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
+tcp_send:
+    /* We're done with the input processing. We are now ready to send a
+       reply. Our job is to fill in all the fields of the TCP and IP
+       headers before calculating the checksum and finally send the
+       packet. */
+    BUF->ackno[0] = uip_connr->rcv_nxt[0];
+    BUF->ackno[1] = uip_connr->rcv_nxt[1];
+    BUF->ackno[2] = uip_connr->rcv_nxt[2];
+    BUF->ackno[3] = uip_connr->rcv_nxt[3];
+
+    BUF->seqno[0] = uip_connr->snd_nxt[0];
+    BUF->seqno[1] = uip_connr->snd_nxt[1];
+    BUF->seqno[2] = uip_connr->snd_nxt[2];
+    BUF->seqno[3] = uip_connr->snd_nxt[3];
+
+    BUF->proto = UIP_PROTO_TCP;
+
+    BUF->srcport  = uip_connr->lport;
+    BUF->destport = uip_connr->rport;
+
+    uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+    uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
+
+    if (uip_connr->tcpstateflags & UIP_STOPPED) {
+        /* If the connection has issued uip_stop(), we advertise a zero
+           window so that the remote host will stop sending data. */
+        BUF->wnd[0] = BUF->wnd[1] = 0;
+    } else {
+        BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
+        BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
+    }
+
+tcp_send_noconn:
+    BUF->ttl = UIP_TTL;
+#if UIP_CONF_IPV6
+    /* For IPv6, the IP length field does not include the IPv6 IP header
+       length. */
+    BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+    BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+    BUF->len[0] = (uip_len >> 8);
+    BUF->len[1] = (uip_len & 0xff);
+#endif /* UIP_CONF_IPV6 */
+
+    BUF->urgp[0] = BUF->urgp[1] = 0;
+
+    /* Calculate TCP checksum. */
+    BUF->tcpchksum = 0;
+    BUF->tcpchksum = ~(uip_tcpchksum());
+
+ip_send_nolen:
+
+#if UIP_CONF_IPV6
+    BUF->vtc = 0x60;
+    BUF->tcflow = 0x00;
+    BUF->flow = 0x00;
+#else /* UIP_CONF_IPV6 */
+    BUF->vhl = 0x45;
+    BUF->tos = 0;
+    BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
+    ++ipid;
+    BUF->ipid[0] = ipid >> 8;
+    BUF->ipid[1] = ipid & 0xff;
+    /* Calculate IP checksum. */
+    BUF->ipchksum = 0;
+    BUF->ipchksum = ~(uip_ipchksum());
+    DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
+#endif /* UIP_CONF_IPV6 */
+
+    UIP_STAT(++uip_stat.tcp.sent);
+send:
+    DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
+                 (BUF->len[0] << 8) | BUF->len[1]);
+
+    UIP_STAT(++uip_stat.ip.sent);
+    /* Return and let the caller do the actual transmission. */
+    uip_flags = 0;
+    return;
+drop:
+    uip_len = 0;
+    uip_flags = 0;
+    return;
+}
+/*---------------------------------------------------------------------------*/
+u16_t
+htons(u16_t val)
+{
+    return HTONS(val);
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_send(const void *data, int len)
+{
+    if (len > 0) {
+        uip_slen = len;
+        if (data != uip_sappdata) {
+            memcpy(uip_sappdata, (data), uip_slen);
+        }
+    }
+}
+/** @} */
diff --git a/src/libs/Network/uip/uip/uip.h b/src/libs/Network/uip/uip/uip.h
new file mode 100644 (file)
index 0000000..6cb1293
--- /dev/null
@@ -0,0 +1,1638 @@
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \file
+ * Header file for the uIP TCP/IP stack.
+ * \author Adam Dunkels <adam@dunkels.com>
+ *
+ * The uIP TCP/IP stack header file contains definitions for a number
+ * of C macros that are used by uIP programs as well as internal uIP
+ * structures, TCP/IP header structures and function declarations.
+ *
+ */
+
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $
+ *
+ */
+
+#ifndef __UIP_H__
+#define __UIP_H__
+
+#include "uipopt.h"
+
+/**
+ * Repressentation of an IP address.
+ *
+ */
+typedef u16_t uip_ip4addr_t[2];
+typedef u16_t uip_ip6addr_t[8];
+#if UIP_CONF_IPV6
+typedef uip_ip6addr_t uip_ipaddr_t;
+#else /* UIP_CONF_IPV6 */
+typedef uip_ip4addr_t uip_ipaddr_t;
+#endif /* UIP_CONF_IPV6 */
+
+/*---------------------------------------------------------------------------*/
+/* First, the functions that should be called from the
+ * system. Initialization, the periodic timer and incoming packets are
+ * handled by the following three functions.
+ */
+
+/**
+ * \defgroup uipconffunc uIP configuration functions
+ * @{
+ *
+ * The uIP configuration functions are used for setting run-time
+ * parameters in uIP such as IP addresses.
+ */
+
+/**
+ * Set the IP address of this host.
+ *
+ * The IP address is represented as a 4-byte array where the first
+ * octet of the IP address is put in the first member of the 4-byte
+ * array.
+ *
+ * Example:
+ \code
+
+ uip_ipaddr_t addr;
+
+ uip_ipaddr(&addr, 192,168,1,2);
+ uip_sethostaddr(&addr);
+
+ \endcode
+ * \param addr A pointer to an IP address of type uip_ipaddr_t;
+ *
+ * \sa uip_ipaddr()
+ *
+ * \hideinitializer
+ */
+#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
+
+/**
+ * Get the IP address of this host.
+ *
+ * The IP address is represented as a 4-byte array where the first
+ * octet of the IP address is put in the first member of the 4-byte
+ * array.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t hostaddr;
+
+ uip_gethostaddr(&hostaddr);
+ \endcode
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the currently configured IP address.
+ *
+ * \hideinitializer
+ */
+#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)
+
+/**
+ * Set the default router's IP address.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable containing the IP
+ * address of the default router.
+ *
+ * \sa uip_ipaddr()
+ *
+ * \hideinitializer
+ */
+#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
+
+/**
+ * Set the netmask.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable containing the IP
+ * address of the netmask.
+ *
+ * \sa uip_ipaddr()
+ *
+ * \hideinitializer
+ */
+#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))
+
+
+/**
+ * Get the default router's IP address.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the IP address of the default router.
+ *
+ * \hideinitializer
+ */
+#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
+
+/**
+ * Get the netmask.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the value of the netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @} */
+
+/**
+ * \defgroup uipinit uIP initialization functions
+ * @{
+ *
+ * The uIP initialization functions are used for booting uIP.
+ */
+
+/**
+ * uIP initialization function.
+ *
+ * This function should be called at boot up to initilize the uIP
+ * TCP/IP stack.
+ */
+void uip_init(void);
+
+/**
+ * uIP initialization function.
+ *
+ * This function may be used at boot time to set the initial ip_id.
+ */
+void uip_setipid(u16_t id);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+/**
+ * \defgroup uipdevfunc uIP device driver functions
+ * @{
+ *
+ * These functions are used by a network device driver for interacting
+ * with uIP.
+ */
+
+/**
+ * Process an incoming packet.
+ *
+ * This function should be called when the device driver has received
+ * a packet from the network. The packet from the device driver must
+ * be present in the uip_buf buffer, and the length of the packet
+ * should be placed in the uip_len variable.
+ *
+ * When the function returns, there may be an outbound packet placed
+ * in the uip_buf packet buffer. If so, the uip_len variable is set to
+ * the length of the packet. If no packet is to be sent out, the
+ * uip_len variable is set to 0.
+ *
+ * The usual way of calling the function is presented by the source
+ * code below.
+ \code
+  uip_len = devicedriver_poll();
+  if(uip_len > 0) {
+    uip_input();
+    if(uip_len > 0) {
+      devicedriver_send();
+    }
+  }
+ \endcode
+ *
+ * \note If you are writing a uIP device driver that needs ARP
+ * (Address Resolution Protocol), e.g., when running uIP over
+ * Ethernet, you will need to call the uIP ARP code before calling
+ * this function:
+ \code
+  #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+  uip_len = ethernet_devicedrver_poll();
+  if(uip_len > 0) {
+    if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
+      uip_arp_ipin();
+      uip_input();
+      if(uip_len > 0) {
+        uip_arp_out();
+       ethernet_devicedriver_send();
+      }
+    } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
+      uip_arp_arpin();
+      if(uip_len > 0) {
+       ethernet_devicedriver_send();
+      }
+    }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define uip_input()        uip_process(UIP_DATA)
+
+/**
+ * Periodic processing for a connection identified by its number.
+ *
+ * This function does the necessary periodic processing (timers,
+ * polling) for a uIP TCP conneciton, and should be called when the
+ * periodic uIP timer goes off. It should be called for every
+ * connection, regardless of whether they are open of closed.
+ *
+ * When the function returns, it may have an outbound packet waiting
+ * for service in the uIP packet buffer, and if so the uip_len
+ * variable is set to a value larger than zero. The device driver
+ * should be called to send out the packet.
+ *
+ * The ususal way of calling the function is through a for() loop like
+ * this:
+ \code
+  for(i = 0; i < UIP_CONNS; ++i) {
+    uip_periodic(i);
+    if(uip_len > 0) {
+      devicedriver_send();
+    }
+  }
+ \endcode
+ *
+ * \note If you are writing a uIP device driver that needs ARP
+ * (Address Resolution Protocol), e.g., when running uIP over
+ * Ethernet, you will need to call the uip_arp_out() function before
+ * calling the device driver:
+ \code
+  for(i = 0; i < UIP_CONNS; ++i) {
+    uip_periodic(i);
+    if(uip_len > 0) {
+      uip_arp_out();
+      ethernet_devicedriver_send();
+    }
+  }
+ \endcode
+ *
+ * \param conn The number of the connection which is to be periodically polled.
+ *
+ * \hideinitializer
+ */
+#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
+                                uip_process(UIP_TIMER); } while (0)
+
+/**
+ *
+ *
+ */
+#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
+
+/**
+ * Perform periodic processing for a connection identified by a pointer
+ * to its structure.
+ *
+ * Same as uip_periodic() but takes a pointer to the actual uip_conn
+ * struct instead of an integer as its argument. This function can be
+ * used to force periodic processing of a specific connection.
+ *
+ * \param conn A pointer to the uip_conn struct for the connection to
+ * be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_periodic_conn(conn) do { uip_conn = conn; \
+                                     uip_process(UIP_TIMER); } while (0)
+
+/**
+ * Reuqest that a particular connection should be polled.
+ *
+ * Similar to uip_periodic_conn() but does not perform any timer
+ * processing. The application is polled for new data.
+ *
+ * \param conn A pointer to the uip_conn struct for the connection to
+ * be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_poll_conn(conn) do { uip_conn = conn; \
+                                 uip_process(UIP_POLL_REQUEST); } while (0)
+
+
+#if UIP_UDP
+/**
+ * Periodic processing for a UDP connection identified by its number.
+ *
+ * This function is essentially the same as uip_periodic(), but for
+ * UDP connections. It is called in a similar fashion as the
+ * uip_periodic() function:
+ \code
+  for(i = 0; i < UIP_UDP_CONNS; i++) {
+    uip_udp_periodic(i);
+    if(uip_len > 0) {
+      devicedriver_send();
+    }
+  }
+ \endcode
+ *
+ * \note As for the uip_periodic() function, special care has to be
+ * taken when using uIP together with ARP and Ethernet:
+ \code
+  for(i = 0; i < UIP_UDP_CONNS; i++) {
+    uip_udp_periodic(i);
+    if(uip_len > 0) {
+      uip_arp_out();
+      ethernet_devicedriver_send();
+    }
+  }
+ \endcode
+ *
+ * \param conn The number of the UDP connection to be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
+                                uip_process(UIP_UDP_TIMER); } while (0)
+
+/**
+ * Periodic processing for a UDP connection identified by a pointer to
+ * its structure.
+ *
+ * Same as uip_udp_periodic() but takes a pointer to the actual
+ * uip_conn struct instead of an integer as its argument. This
+ * function can be used to force periodic processing of a specific
+ * connection.
+ *
+ * \param conn A pointer to the uip_udp_conn struct for the connection
+ * to be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
+                                         uip_process(UIP_UDP_TIMER); } while (0)
+
+
+#endif /* UIP_UDP */
+
+/**
+ * The uIP packet buffer.
+ *
+ * The uip_buf array is used to hold incoming and outgoing
+ * packets. The device driver should place incoming data into this
+ * buffer. When sending data, the device driver should read the link
+ * level headers and the TCP/IP headers from this buffer. The size of
+ * the link level headers is configured by the UIP_LLH_LEN define.
+ *
+ * \note The application data need not be placed in this buffer, so
+ * the device driver must read it from the place pointed to by the
+ * uip_appdata pointer as illustrated by the following example:
+ \code
+ void
+ devicedriver_send(void)
+ {
+    hwsend(&uip_buf[0], UIP_LLH_LEN);
+    if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
+      hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
+    } else {
+      hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
+      hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
+    }
+ }
+ \endcode
+ */
+
+#ifdef __cplusplus
+extern "C" u8_t uip_buf[UIP_BUFSIZE+2];
+#else
+extern u8_t uip_buf[UIP_BUFSIZE+2];
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/** @} */
+
+/*---------------------------------------------------------------------------*/
+/* Functions that are used by the uIP application program. Opening and
+ * closing connections, sending and receiving data, etc. is all
+ * handled by the functions below.
+*/
+/**
+ * \defgroup uipappfunc uIP application functions
+ * @{
+ *
+ * Functions used by an application running of top of uIP.
+ */
+
+/**
+ * Start listening to the specified port.
+ *
+ * \note Since this function expects the port number in network byte
+ * order, a conversion using HTONS() or htons() is necessary.
+ *
+ \code
+ uip_listen(HTONS(80));
+ \endcode
+ *
+ * \param port A 16-bit port number in network byte order.
+ */
+void uip_listen(u16_t port);
+
+/**
+ * Stop listening to the specified port.
+ *
+ * \note Since this function expects the port number in network byte
+ * order, a conversion using HTONS() or htons() is necessary.
+ *
+ \code
+ uip_unlisten(HTONS(80));
+ \endcode
+ *
+ * \param port A 16-bit port number in network byte order.
+ */
+void uip_unlisten(u16_t port);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * Connect to a remote host using TCP.
+ *
+ * This function is used to start a new connection to the specified
+ * port on the specied host. It allocates a new connection identifier,
+ * sets the connection to the SYN_SENT state and sets the
+ * retransmission timer to 0. This will cause a TCP SYN segment to be
+ * sent out the next time this connection is periodically processed,
+ * which usually is done within 0.5 seconds after the call to
+ * uip_connect().
+ *
+ * \note This function is avaliable only if support for active open
+ * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
+ *
+ * \note Since this function requires the port number to be in network
+ * byte order, a conversion using HTONS() or htons() is necessary.
+ *
+ \code
+ uip_ipaddr_t ipaddr;
+
+ uip_ipaddr(&ipaddr, 192,168,1,2);
+ uip_connect(&ipaddr, HTONS(80));
+ \endcode
+ *
+ * \param ripaddr The IP address of the remote hot.
+ *
+ * \param port A 16-bit port number in network byte order.
+ *
+ * \return A pointer to the uIP connection identifier for the new connection,
+ * or NULL if no connection could be allocated.
+ *
+ */
+struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
+
+
+
+/**
+ * \internal
+ *
+ * Check if a connection has outstanding (i.e., unacknowledged) data.
+ *
+ * \param conn A pointer to the uip_conn structure for the connection.
+ *
+ * \hideinitializer
+ */
+#define uip_outstanding(conn) ((conn)->len)
+
+/**
+ * Send data on the current connection.
+ *
+ * This function is used to send out a single segment of TCP
+ * data. Only applications that have been invoked by uIP for event
+ * processing can send data.
+ *
+ * The amount of data that actually is sent out after a call to this
+ * funcion is determined by the maximum amount of data TCP allows. uIP
+ * will automatically crop the data so that only the appropriate
+ * amount of data is sent. The function uip_mss() can be used to query
+ * uIP for the amount of data that actually will be sent.
+ *
+ * \note This function does not guarantee that the sent data will
+ * arrive at the destination. If the data is lost in the network, the
+ * application will be invoked with the uip_rexmit() event being
+ * set. The application will then have to resend the data using this
+ * function.
+ *
+ * \param data A pointer to the data which is to be sent.
+ *
+ * \param len The maximum amount of data bytes to be sent.
+ *
+ * \hideinitializer
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+void uip_send(const void *data, int len);
+#ifdef __cplusplus
+}
+#endif
+/**
+ * The length of any incoming data that is currently avaliable (if avaliable)
+ * in the uip_appdata buffer.
+ *
+ * The test function uip_data() must first be used to check if there
+ * is any data available at all.
+ *
+ * \hideinitializer
+ */
+/*void uip_datalen(void);*/
+#define uip_datalen()       uip_len
+
+/**
+ * The length of any out-of-band data (urgent data) that has arrived
+ * on the connection.
+ *
+ * \note The configuration parameter UIP_URGDATA must be set for this
+ * function to be enabled.
+ *
+ * \hideinitializer
+ */
+#define uip_urgdatalen()    uip_urglen
+
+/**
+ * Close the current connection.
+ *
+ * This function will close the current connection in a nice way.
+ *
+ * \hideinitializer
+ */
+#define uip_close()         (uip_flags = UIP_CLOSE)
+
+/**
+ * Abort the current connection.
+ *
+ * This function will abort (reset) the current connection, and is
+ * usually used when an error has occured that prevents using the
+ * uip_close() function.
+ *
+ * \hideinitializer
+ */
+#define uip_abort()         (uip_flags = UIP_ABORT)
+
+/**
+ * Tell the sending host to stop sending data.
+ *
+ * This function will close our receiver's window so that we stop
+ * receiving data for the current connection.
+ *
+ * \hideinitializer
+ */
+#define uip_stop()          (uip_conn->tcpstateflags |= UIP_STOPPED)
+
+/**
+ * Find out if the current connection has been previously stopped with
+ * uip_stop().
+ *
+ * \hideinitializer
+ */
+#define uip_stopped(conn)   ((conn)->tcpstateflags & UIP_STOPPED)
+
+/**
+ * Restart the current connection, if is has previously been stopped
+ * with uip_stop().
+ *
+ * This function will open the receiver's window again so that we
+ * start receiving data for the current connection.
+ *
+ * \hideinitializer
+ */
+#define uip_restart()         do { uip_flags |= UIP_NEWDATA; \
+                                   uip_conn->tcpstateflags &= ~UIP_STOPPED; \
+                              } while(0)
+
+
+/* uIP tests that can be made to determine in what state the current
+   connection is, and what the application function should do. */
+
+/**
+ * Is the current connection a UDP connection?
+ *
+ * This function checks whether the current connection is a UDP connection.
+ *
+ * \hideinitializer
+ *
+ */
+#define uip_udpconnection() (uip_conn == NULL)
+
+/**
+ * Is new incoming data available?
+ *
+ * Will reduce to non-zero if there is new data for the application
+ * present at the uip_appdata pointer. The size of the data is
+ * avaliable through the uip_len variable.
+ *
+ * \hideinitializer
+ */
+#define uip_newdata()   (uip_flags & UIP_NEWDATA)
+
+/**
+ * Has previously sent data been acknowledged?
+ *
+ * Will reduce to non-zero if the previously sent data has been
+ * acknowledged by the remote host. This means that the application
+ * can send new data.
+ *
+ * \hideinitializer
+ */
+#define uip_acked()   (uip_flags & UIP_ACKDATA)
+
+/**
+ * Has the connection just been connected?
+ *
+ * Reduces to non-zero if the current connection has been connected to
+ * a remote host. This will happen both if the connection has been
+ * actively opened (with uip_connect()) or passively opened (with
+ * uip_listen()).
+ *
+ * \hideinitializer
+ */
+#define uip_connected() (uip_flags & UIP_CONNECTED)
+
+/**
+ * Has the connection been closed by the other end?
+ *
+ * Is non-zero if the connection has been closed by the remote
+ * host. The application may then do the necessary clean-ups.
+ *
+ * \hideinitializer
+ */
+#define uip_closed()    (uip_flags & UIP_CLOSE)
+
+/**
+ * Has the connection been aborted by the other end?
+ *
+ * Non-zero if the current connection has been aborted (reset) by the
+ * remote host.
+ *
+ * \hideinitializer
+ */
+#define uip_aborted()    (uip_flags & UIP_ABORT)
+
+/**
+ * Has the connection timed out?
+ *
+ * Non-zero if the current connection has been aborted due to too many
+ * retransmissions.
+ *
+ * \hideinitializer
+ */
+#define uip_timedout()    (uip_flags & UIP_TIMEDOUT)
+
+/**
+ * Do we need to retransmit previously data?
+ *
+ * Reduces to non-zero if the previously sent data has been lost in
+ * the network, and the application should retransmit it. The
+ * application should send the exact same data as it did the last
+ * time, using the uip_send() function.
+ *
+ * \hideinitializer
+ */
+#define uip_rexmit()     (uip_flags & UIP_REXMIT)
+
+/**
+ * Is the connection being polled by uIP?
+ *
+ * Is non-zero if the reason the application is invoked is that the
+ * current connection has been idle for a while and should be
+ * polled.
+ *
+ * The polling event can be used for sending data without having to
+ * wait for the remote host to send data.
+ *
+ * \hideinitializer
+ */
+#define uip_poll()       (uip_flags & UIP_POLL)
+
+/**
+ * Get the initial maxium segment size (MSS) of the current
+ * connection.
+ *
+ * \hideinitializer
+ */
+#define uip_initialmss()             (uip_conn->initialmss)
+
+/**
+ * Get the current maxium segment size that can be sent on the current
+ * connection.
+ *
+ * The current maxiumum segment size that can be sent on the
+ * connection is computed from the receiver's window and the MSS of
+ * the connection (which also is available by calling
+ * uip_initialmss()).
+ *
+ * \hideinitializer
+ */
+#define uip_mss()             (uip_conn->mss)
+
+/**
+ * Set up a new UDP connection.
+ *
+ * This function sets up a new UDP connection. The function will
+ * automatically allocate an unused local port for the new
+ * connection. However, another port can be chosen by using the
+ * uip_udp_bind() call, after the uip_udp_new() function has been
+ * called.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t addr;
+ struct uip_udp_conn *c;
+
+ uip_ipaddr(&addr, 192,168,2,1);
+ c = uip_udp_new(&addr, HTONS(12345));
+ if(c != NULL) {
+   uip_udp_bind(c, HTONS(12344));
+ }
+ \endcode
+ * \param ripaddr The IP address of the remote host.
+ *
+ * \param rport The remote port number in network byte order.
+ *
+ * \return The uip_udp_conn structure for the new connection or NULL
+ * if no connection could be allocated.
+ */
+struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
+
+/**
+ * Removed a UDP connection.
+ *
+ * \param conn A pointer to the uip_udp_conn structure for the connection.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_remove(conn) (conn)->lport = 0
+
+/**
+ * Bind a UDP connection to a local port.
+ *
+ * \param conn A pointer to the uip_udp_conn structure for the
+ * connection.
+ *
+ * \param port The local port number, in network byte order.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_bind(conn, port) (conn)->lport = port
+
+/**
+ * Send a UDP datagram of length len on the current connection.
+ *
+ * This function can only be called in response to a UDP event (poll
+ * or newdata). The data must be present in the uip_buf buffer, at the
+ * place pointed to by the uip_appdata pointer.
+ *
+ * \param len The length of the data in the uip_buf buffer.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_send(len) uip_send((char *)uip_appdata, len)
+
+/** @} */
+
+/* uIP convenience and converting functions. */
+
+/**
+ * \defgroup uipconvfunc uIP conversion functions
+ * @{
+ *
+ * These functions can be used for converting between different data
+ * formats used by uIP.
+ */
+
+/**
+ * Construct an IP address from four bytes.
+ *
+ * This function constructs an IP address of the type that uIP handles
+ * internally from four bytes. The function is handy for specifying IP
+ * addresses to use with e.g. the uip_connect() function.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ struct uip_conn *c;
+
+ uip_ipaddr(&ipaddr, 192,168,1,2);
+ c = uip_connect(&ipaddr, HTONS(80));
+ \endcode
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the IP address.
+ *
+ * \param addr0 The first octet of the IP address.
+ * \param addr1 The second octet of the IP address.
+ * \param addr2 The third octet of the IP address.
+ * \param addr3 The forth octet of the IP address.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
+                     ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
+                     ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
+                  } while(0)
+
+/**
+ * Construct an IPv6 address from eight 16-bit words.
+ *
+ * This function constructs an IPv6 address.
+ *
+ * \hideinitializer
+ */
+#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
+                     ((u16_t *)(addr))[0] = HTONS((addr0)); \
+                     ((u16_t *)(addr))[1] = HTONS((addr1)); \
+                     ((u16_t *)(addr))[2] = HTONS((addr2)); \
+                     ((u16_t *)(addr))[3] = HTONS((addr3)); \
+                     ((u16_t *)(addr))[4] = HTONS((addr4)); \
+                     ((u16_t *)(addr))[5] = HTONS((addr5)); \
+                     ((u16_t *)(addr))[6] = HTONS((addr6)); \
+                     ((u16_t *)(addr))[7] = HTONS((addr7)); \
+                  } while(0)
+
+/**
+ * Copy an IP address to another IP address.
+ *
+ * Copies an IP address from one place to another.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr_copy(&ipaddr2, &ipaddr1);
+ \endcode
+ *
+ * \param dest The destination for the copy.
+ * \param src The source from where to copy.
+ *
+ * \hideinitializer
+ */
+#if !UIP_CONF_IPV6
+#define uip_ipaddr_copy(dest, src) do { \
+                     ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
+                     ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
+                  } while(0)
+#else /* !UIP_CONF_IPV6 */
+#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
+#endif /* !UIP_CONF_IPV6 */
+
+/**
+ * Compare two IP addresses
+ *
+ * Compares two IP addresses.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
+    printf("They are the same");
+ }
+ \endcode
+ *
+ * \param addr1 The first IP address.
+ * \param addr2 The second IP address.
+ *
+ * \hideinitializer
+ */
+#if !UIP_CONF_IPV6
+#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
+                                     ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
+#else /* !UIP_CONF_IPV6 */
+#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
+#endif /* !UIP_CONF_IPV6 */
+
+/**
+ * Compare two IP addresses with netmasks
+ *
+ * Compares two IP addresses with netmasks. The masks are used to mask
+ * out the bits that are to be compared.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2, mask;
+
+ uip_ipaddr(&mask, 255,255,255,0);
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr(&ipaddr2, 192,16,1,3);
+ if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
+    printf("They are the same");
+ }
+ \endcode
+ *
+ * \param addr1 The first IP address.
+ * \param addr2 The second IP address.
+ * \param mask The netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
+                          (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
+                            (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
+                           ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
+                            (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
+
+
+/**
+ * Mask out the network part of an IP address.
+ *
+ * Masks out the network part of an IP address, given the address and
+ * the netmask.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2, netmask;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr(&netmask, 255,255,255,0);
+ uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
+ \endcode
+ *
+ * In the example above, the variable "ipaddr2" will contain the IP
+ * address 192.168.1.0.
+ *
+ * \param dest Where the result is to be placed.
+ * \param src The IP address.
+ * \param mask The netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr_mask(dest, src, mask) do { \
+                     ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
+                     ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
+                  } while(0)
+
+/**
+ * Pick the first octet of an IP address.
+ *
+ * Picks out the first octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr1(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 1.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8)
+
+/**
+ * Pick the second octet of an IP address.
+ *
+ * Picks out the second octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr2(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 2.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff)
+
+/**
+ * Pick the third octet of an IP address.
+ *
+ * Picks out the third octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr3(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 3.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8)
+
+/**
+ * Pick the fourth octet of an IP address.
+ *
+ * Picks out the fourth octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr4(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 4.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff)
+
+/**
+ * Convert 16-bit quantity from host byte order to network byte order.
+ *
+ * This macro is primarily used for converting constants from host
+ * byte order to network byte order. For converting variables to
+ * network byte order, use the htons() function instead.
+ *
+ * \hideinitializer
+ */
+#ifndef HTONS
+#   if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
+#      define HTONS(n) (n)
+#   else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+#      define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
+#   endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+#else
+#error "HTONS already defined!"
+#endif /* HTONS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Convert 16-bit quantity from host byte order to network byte order.
+ *
+ * This function is primarily used for converting variables from host
+ * byte order to network byte order. For converting constants to
+ * network byte order, use the HTONS() macro instead.
+ */
+#ifndef htons
+u16_t htons(u16_t val);
+#endif /* htons */
+#ifndef ntohs
+#define ntohs htons
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+/** @} */
+
+/**
+ * Pointer to the application data in the packet buffer.
+ *
+ * This pointer points to the application data when the application is
+ * called. If the application wishes to send data, the application may
+ * use this space to write the data into before calling uip_send().
+ */
+extern void *uip_appdata;
+
+#if UIP_URGDATA > 0
+/* u8_t *uip_urgdata:
+ *
+ * This pointer points to any urgent data that has been received. Only
+ * present if compiled with support for urgent data (UIP_URGDATA).
+ */
+extern void *uip_urgdata;
+#endif /* UIP_URGDATA > 0 */
+
+
+/**
+ * \defgroup uipdrivervars Variables used in uIP device drivers
+ * @{
+ *
+ * uIP has a few global variables that are used in device drivers for
+ * uIP.
+ */
+
+/**
+ * The length of the packet in the uip_buf buffer.
+ *
+ * The global variable uip_len holds the length of the packet in the
+ * uip_buf buffer.
+ *
+ * When the network device driver calls the uIP input function,
+ * uip_len should be set to the length of the packet in the uip_buf
+ * buffer.
+ *
+ * When sending packets, the device driver should use the contents of
+ * the uip_len variable to determine the length of the outgoing
+ * packet.
+ *
+ */
+extern u16_t uip_len;
+
+/** @} */
+
+#if UIP_URGDATA > 0
+extern u16_t uip_urglen, uip_surglen;
+#endif /* UIP_URGDATA > 0 */
+
+
+/**
+ * Representation of a uIP TCP connection.
+ *
+ * The uip_conn structure is used for identifying a connection. All
+ * but one field in the structure are to be considered read-only by an
+ * application. The only exception is the appstate field whos purpose
+ * is to let the application store application-specific state (e.g.,
+ * file pointers) for the connection. The type of this field is
+ * configured in the "uipopt.h" header file.
+ */
+struct uip_conn {
+  uip_ipaddr_t ripaddr;   /**< The IP address of the remote host. */
+
+  u16_t lport;        /**< The local TCP port, in network byte order. */
+  u16_t rport;        /**< The local remote TCP port, in network byte
+                        order. */
+
+  u8_t rcv_nxt[4];    /**< The sequence number that we expect to
+                        receive next. */
+  u8_t snd_nxt[4];    /**< The sequence number that was last sent by
+                         us. */
+  u16_t len;          /**< Length of the data that was previously sent. */
+  u16_t mss;          /**< Current maximum segment size for the
+                        connection. */
+  u16_t initialmss;   /**< Initial maximum segment size for the
+                        connection. */
+  u8_t sa;            /**< Retransmission time-out calculation state
+                        variable. */
+  u8_t sv;            /**< Retransmission time-out calculation state
+                        variable. */
+  u8_t rto;           /**< Retransmission time-out. */
+  u8_t tcpstateflags; /**< TCP state and flags. */
+  u8_t timer;         /**< The retransmission timer. */
+  u8_t nrtx;          /**< The number of retransmissions for the last
+                        segment sent. */
+
+  /** The application state. */
+  uip_tcp_appstate_t appstate;
+};
+
+
+/**
+ * Pointer to the current TCP connection.
+ *
+ * The uip_conn pointer can be used to access the current TCP
+ * connection.
+ */
+extern struct uip_conn *uip_conn;
+/* The array containing all uIP connections. */
+extern struct uip_conn uip_conns[UIP_CONNS];
+/**
+ * \addtogroup uiparch
+ * @{
+ */
+
+/**
+ * 4-byte array used for the 32-bit sequence number calculations.
+ */
+extern u8_t uip_acc32[4];
+
+/** @} */
+
+
+#if UIP_UDP
+/**
+ * Representation of a uIP UDP connection.
+ */
+struct uip_udp_conn {
+  uip_ipaddr_t ripaddr;   /**< The IP address of the remote peer. */
+  u16_t lport;        /**< The local port number in network byte order. */
+  u16_t rport;        /**< The remote port number in network byte order. */
+  u8_t  ttl;          /**< Default time-to-live. */
+
+  /** The application state. */
+  uip_udp_appstate_t appstate;
+};
+
+/**
+ * The current UDP connection.
+ */
+extern struct uip_udp_conn *uip_udp_conn;
+extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
+#endif /* UIP_UDP */
+
+/**
+ * The structure holding the TCP/IP statistics that are gathered if
+ * UIP_STATISTICS is set to 1.
+ *
+ */
+struct uip_stats {
+  struct {
+    uip_stats_t drop;     /**< Number of dropped packets at the IP
+                            layer. */
+    uip_stats_t recv;     /**< Number of received packets at the IP
+                            layer. */
+    uip_stats_t sent;     /**< Number of sent packets at the IP
+                            layer. */
+    uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong
+                            IP version or header length. */
+    uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
+                            IP length, high byte. */
+    uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
+                            IP length, low byte. */
+    uip_stats_t fragerr;  /**< Number of packets dropped since they
+                            were IP fragments. */
+    uip_stats_t chkerr;   /**< Number of packets dropped due to IP
+                            checksum errors. */
+    uip_stats_t protoerr; /**< Number of packets dropped since they
+                            were neither ICMP, UDP nor TCP. */
+  } ip;                   /**< IP statistics. */
+  struct {
+    uip_stats_t drop;     /**< Number of dropped ICMP packets. */
+    uip_stats_t recv;     /**< Number of received ICMP packets. */
+    uip_stats_t sent;     /**< Number of sent ICMP packets. */
+    uip_stats_t typeerr;  /**< Number of ICMP packets with a wrong
+                            type. */
+  } icmp;                 /**< ICMP statistics. */
+  struct {
+    uip_stats_t drop;     /**< Number of dropped TCP segments. */
+    uip_stats_t recv;     /**< Number of recived TCP segments. */
+    uip_stats_t sent;     /**< Number of sent TCP segments. */
+    uip_stats_t chkerr;   /**< Number of TCP segments with a bad
+                            checksum. */
+    uip_stats_t ackerr;   /**< Number of TCP segments with a bad ACK
+                            number. */
+    uip_stats_t rst;      /**< Number of recevied TCP RST (reset) segments. */
+    uip_stats_t rexmit;   /**< Number of retransmitted TCP segments. */
+    uip_stats_t syndrop;  /**< Number of dropped SYNs due to too few
+                            connections was avaliable. */
+    uip_stats_t synrst;   /**< Number of SYNs for closed ports,
+                            triggering a RST. */
+  } tcp;                  /**< TCP statistics. */
+#if UIP_UDP
+  struct {
+    uip_stats_t drop;     /**< Number of dropped UDP segments. */
+    uip_stats_t recv;     /**< Number of recived UDP segments. */
+    uip_stats_t sent;     /**< Number of sent UDP segments. */
+    uip_stats_t chkerr;   /**< Number of UDP segments with a bad
+                            checksum. */
+  } udp;                  /**< UDP statistics. */
+#endif /* UIP_UDP */
+};
+
+/**
+ * The uIP TCP/IP statistics.
+ *
+ * This is the variable in which the uIP TCP/IP statistics are gathered.
+ */
+extern struct uip_stats uip_stat;
+
+
+/*---------------------------------------------------------------------------*/
+/* All the stuff below this point is internal to uIP and should not be
+ * used directly by an application or by a device driver.
+ */
+/*---------------------------------------------------------------------------*/
+/* u8_t uip_flags:
+ *
+ * When the application is called, uip_flags will contain the flags
+ * that are defined in this file. Please read below for more
+ * infomation.
+ */
+extern u8_t uip_flags;
+
+/* The following flags may be set in the global variable uip_flags
+   before calling the application callback. The UIP_ACKDATA,
+   UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time,
+   whereas the others are mutualy exclusive. Note that these flags
+   should *NOT* be accessed directly, but only through the uIP
+   functions/macros. */
+
+#define UIP_ACKDATA   1     /* Signifies that the outstanding data was
+                              acked and the application should send
+                              out new data instead of retransmitting
+                              the last data. */
+#define UIP_NEWDATA   2     /* Flags the fact that the peer has sent
+                              us new data. */
+#define UIP_REXMIT    4     /* Tells the application to retransmit the
+                              data that was last sent. */
+#define UIP_POLL      8     /* Used for polling the application, to
+                              check if the application has data that
+                              it wants to send. */
+#define UIP_CLOSE     16    /* The remote host has closed the
+                              connection, thus the connection has
+                              gone away. Or the application signals
+                              that it wants to close the
+                              connection. */
+#define UIP_ABORT     32    /* The remote host has aborted the
+                              connection, thus the connection has
+                              gone away. Or the application signals
+                              that it wants to abort the
+                              connection. */
+#define UIP_CONNECTED 64    /* We have got a connection from a remote
+                               host and have set up a new connection
+                               for it, or an active connection has
+                               been successfully established. */
+
+#define UIP_TIMEDOUT  128   /* The connection has been aborted due to
+                              too many retransmissions. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* uip_process(flag):
+ *
+ * The actual uIP function which does all the work.
+ */
+void uip_process(u8_t flag);
+#ifdef __cplusplus
+}
+#endif
+
+/* The following flags are passed as an argument to the uip_process()
+   function. They are used to distinguish between the two cases where
+   uip_process() is called. It can be called either because we have
+   incoming data that should be processed, or because the periodic
+   timer has fired. These values are never used directly, but only in
+   the macrose defined in this file. */
+
+#define UIP_DATA          1     /* Tells uIP that there is incoming
+                                  data in the uip_buf buffer. The
+                                  length of the data is stored in the
+                                  global variable uip_len. */
+#define UIP_TIMER         2     /* Tells uIP that the periodic timer
+                                  has fired. */
+#define UIP_POLL_REQUEST  3     /* Tells uIP that a connection should
+                                  be polled. */
+#define UIP_UDP_SEND_CONN 4     /* Tells uIP that a UDP datagram
+                                  should be constructed in the
+                                  uip_buf buffer. */
+#if UIP_UDP
+#define UIP_UDP_TIMER     5
+#endif /* UIP_UDP */
+
+/* The TCP states used in the uip_conn->tcpstateflags. */
+#define UIP_CLOSED      0
+#define UIP_SYN_RCVD    1
+#define UIP_SYN_SENT    2
+#define UIP_ESTABLISHED 3
+#define UIP_FIN_WAIT_1  4
+#define UIP_FIN_WAIT_2  5
+#define UIP_CLOSING     6
+#define UIP_TIME_WAIT   7
+#define UIP_LAST_ACK    8
+#define UIP_TS_MASK     15
+
+#define UIP_STOPPED      16
+
+/* The TCP and IP headers. */
+struct uip_tcpip_hdr {
+#if UIP_CONF_IPV6
+  /* IPv6 header. */
+  u8_t vtc,
+    tcflow;
+  u16_t flow;
+  u8_t len[2];
+  u8_t proto, ttl;
+  uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+  /* IPv4 header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+
+  /* TCP header. */
+  u16_t srcport,
+    destport;
+  u8_t seqno[4],
+    ackno[4],
+    tcpoffset,
+    flags,
+    wnd[2];
+  u16_t tcpchksum;
+  u8_t urgp[2];
+  u8_t optdata[4];
+};
+
+/* The ICMP and IP headers. */
+struct uip_icmpip_hdr {
+#if UIP_CONF_IPV6
+  /* IPv6 header. */
+  u8_t vtc,
+    tcf;
+  u16_t flow;
+  u8_t len[2];
+  u8_t proto, ttl;
+  uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+  /* IPv4 header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+
+  /* ICMP (echo) header. */
+  u8_t type, icode;
+  u16_t icmpchksum;
+#if !UIP_CONF_IPV6
+  u16_t id, seqno;
+#else /* !UIP_CONF_IPV6 */
+  u8_t flags, reserved1, reserved2, reserved3;
+  u8_t icmp6data[16];
+  u8_t options[1];
+#endif /* !UIP_CONF_IPV6 */
+};
+
+
+/* The UDP and IP headers. */
+struct uip_udpip_hdr {
+#if UIP_CONF_IPV6
+  /* IPv6 header. */
+  u8_t vtc,
+    tcf;
+  u16_t flow;
+  u8_t len[2];
+  u8_t proto, ttl;
+  uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+  /* IP header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+
+  /* UDP header. */
+  u16_t srcport,
+    destport;
+  u16_t udplen;
+  u16_t udpchksum;
+};
+
+
+
+/**
+ * The buffer size available for user data in the \ref uip_buf buffer.
+ *
+ * This macro holds the available size for user data in the \ref
+ * uip_buf buffer. The macro is intended to be used for checking
+ * bounds of available user data.
+ *
+ * Example:
+ \code
+ snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+
+
+#define UIP_PROTO_ICMP  1
+#define UIP_PROTO_TCP   6
+#define UIP_PROTO_UDP   17
+#define UIP_PROTO_ICMP6 58
+
+/* Header sizes. */
+#if UIP_CONF_IPV6
+#define UIP_IPH_LEN    40
+#else /* UIP_CONF_IPV6 */
+#define UIP_IPH_LEN    20    /* Size of IP header */
+#endif /* UIP_CONF_IPV6 */
+#define UIP_UDPH_LEN    8    /* Size of UDP header */
+#define UIP_TCPH_LEN   20    /* Size of TCP header */
+#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)    /* Size of IP +
+                                                         UDP
+                                                         header */
+#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN)    /* Size of IP +
+                                                         TCP
+                                                         header */
+#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
+
+
+#if UIP_FIXEDADDR
+extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+#else /* UIP_FIXEDADDR */
+extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+#endif /* UIP_FIXEDADDR */
+
+
+
+/**
+ * Representation of a 48-bit Ethernet address.
+ */
+struct uip_eth_addr {
+  u8_t addr[6];
+};
+
+/**
+ * Calculate the Internet checksum over a buffer.
+ *
+ * The Internet checksum is the one's complement of the one's
+ * complement sum of all 16-bit words in the buffer.
+ *
+ * See RFC1071.
+ *
+ * \param buf A pointer to the buffer over which the checksum is to be
+ * computed.
+ *
+ * \param len The length of the buffer over which the checksum is to
+ * be computed.
+ *
+ * \return The Internet checksum of the buffer.
+ */
+u16_t uip_chksum(u16_t *buf, u16_t len);
+
+/**
+ * Calculate the IP header checksum of the packet header in uip_buf.
+ *
+ * The IP header checksum is the Internet checksum of the 20 bytes of
+ * the IP header.
+ *
+ * \return The IP header checksum of the IP header in the uip_buf
+ * buffer.
+ */
+u16_t uip_ipchksum(void);
+
+/**
+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
+ *
+ * The TCP checksum is the Internet checksum of data contents of the
+ * TCP segment, and a pseudo-header as defined in RFC793.
+ *
+ * \return The TCP checksum of the TCP segment in uip_buf and pointed
+ * to by uip_appdata.
+ */
+u16_t uip_tcpchksum(void);
+
+/**
+ * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
+ *
+ * The UDP checksum is the Internet checksum of data contents of the
+ * UDP segment, and a pseudo-header as defined in RFC768.
+ *
+ * \return The UDP checksum of the UDP segment in uip_buf and pointed
+ * to by uip_appdata.
+ */
+u16_t uip_udpchksum(void);
+
+
+#endif /* __UIP_H__ */
+
+
+/** @} */
diff --git a/src/libs/Network/uip/uip/uip_arch.h b/src/libs/Network/uip/uip/uip_arch.h
new file mode 100644 (file)
index 0000000..71fd84b
--- /dev/null
@@ -0,0 +1,138 @@
+/**
+ * \addtogroup uip
+ * {@
+ */
+
+/**
+ * \defgroup uiparch Architecture specific uIP functions
+ * @{
+ *
+ * The functions in the architecture specific module implement the IP
+ * check sum and 32-bit additions.
+ *
+ * The IP checksum calculation is the most computationally expensive
+ * operation in the TCP/IP stack and it therefore pays off to
+ * implement this in efficient assembler. The purpose of the uip-arch
+ * module is to let the checksum functions to be implemented in
+ * architecture specific assembler.
+ *
+ */
+
+/**
+ * \file
+ * Declarations of architecture specific functions.
+ * \author Adam Dunkels <adam@dunkels.com>
+ */
+
+/*
+ * Copyright (c) 2001, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $
+ *
+ */
+
+#ifndef __UIP_ARCH_H__
+#define __UIP_ARCH_H__
+
+#include "uip.h"
+
+/**
+ * Carry out a 32-bit addition.
+ *
+ * Because not all architectures for which uIP is intended has native
+ * 32-bit arithmetic, uIP uses an external C function for doing the
+ * required 32-bit additions in the TCP protocol processing. This
+ * function should add the two arguments and place the result in the
+ * global variable uip_acc32.
+ *
+ * \note The 32-bit integer pointed to by the op32 parameter and the
+ * result in the uip_acc32 variable are in network byte order (big
+ * endian).
+ *
+ * \param op32 A pointer to a 4-byte array representing a 32-bit
+ * integer in network byte order (big endian).
+ *
+ * \param op16 A 16-bit integer in host byte order.
+ */
+void uip_add32(u8_t *op32, u16_t op16);
+
+/**
+ * Calculate the Internet checksum over a buffer.
+ *
+ * The Internet checksum is the one's complement of the one's
+ * complement sum of all 16-bit words in the buffer.
+ *
+ * See RFC1071.
+ *
+ * \note This function is not called in the current version of uIP,
+ * but future versions might make use of it.
+ *
+ * \param buf A pointer to the buffer over which the checksum is to be
+ * computed.
+ *
+ * \param len The length of the buffer over which the checksum is to
+ * be computed.
+ *
+ * \return The Internet checksum of the buffer.
+ */
+u16_t uip_chksum(u16_t *buf, u16_t len);
+
+/**
+ * Calculate the IP header checksum of the packet header in uip_buf.
+ *
+ * The IP header checksum is the Internet checksum of the 20 bytes of
+ * the IP header.
+ *
+ * \return The IP header checksum of the IP header in the uip_buf
+ * buffer.
+ */
+u16_t uip_ipchksum(void);
+
+/**
+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
+ *
+ * The TCP checksum is the Internet checksum of data contents of the
+ * TCP segment, and a pseudo-header as defined in RFC793.
+ *
+ * \note The uip_appdata pointer that points to the packet data may
+ * point anywhere in memory, so it is not possible to simply calculate
+ * the Internet checksum of the contents of the uip_buf buffer.
+ *
+ * \return The TCP checksum of the TCP segment in uip_buf and pointed
+ * to by uip_appdata.
+ */
+u16_t uip_tcpchksum(void);
+
+u16_t uip_udpchksum(void);
+
+/** @} */
+/** @} */
+
+#endif /* __UIP_ARCH_H__ */
diff --git a/src/libs/Network/uip/uip/uip_arp.c b/src/libs/Network/uip/uip/uip_arp.c
new file mode 100644 (file)
index 0000000..fda566c
--- /dev/null
@@ -0,0 +1,428 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \defgroup uiparp uIP Address Resolution Protocol
+ * @{
+ *
+ * The Address Resolution Protocol ARP is used for mapping between IP
+ * addresses and link level addresses such as the Ethernet MAC
+ * addresses. ARP uses broadcast queries to ask for the link level
+ * address of a known IP address and the host which is configured with
+ * the IP address for which the query was meant, will respond with its
+ * link level address.
+ *
+ * \note This ARP implementation only supports Ethernet.
+ */
+
+/**
+ * \file
+ * Implementation of the ARP Address Resolution Protocol.
+ * \author Adam Dunkels <adam@dunkels.com>
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
+ *
+ */
+
+
+#include "uip_arp.h"
+
+#include <string.h>
+
+struct arp_hdr {
+  struct uip_eth_hdr ethhdr;
+  u16_t hwtype;
+  u16_t protocol;
+  u8_t hwlen;
+  u8_t protolen;
+  u16_t opcode;
+  struct uip_eth_addr shwaddr;
+  u16_t sipaddr[2];
+  struct uip_eth_addr dhwaddr;
+  u16_t dipaddr[2];
+};
+
+struct ethip_hdr {
+  struct uip_eth_hdr ethhdr;
+  /* IP header. */
+  u8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  u16_t ipchksum;
+  u16_t srcipaddr[2],
+    destipaddr[2];
+};
+
+#define ARP_REQUEST 1
+#define ARP_REPLY   2
+
+#define ARP_HWTYPE_ETH 1
+
+struct arp_entry {
+  u16_t ipaddr[2];
+  struct uip_eth_addr ethaddr;
+  u8_t time;
+};
+
+static const struct uip_eth_addr broadcast_ethaddr =
+  {{0xff,0xff,0xff,0xff,0xff,0xff}};
+static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
+
+static struct arp_entry arp_table[UIP_ARPTAB_SIZE]  __attribute__ ((section ("AHBSRAM1")));
+static u16_t ipaddr[2];
+static u8_t i, c;
+
+static u8_t arptime;
+static u8_t tmpage;
+
+#define BUF   ((struct arp_hdr *)&uip_buf[0])
+#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
+/*-----------------------------------------------------------------------------------*/
+/**
+ * Initialize the ARP module.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_init(void)
+{
+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+    memset(arp_table[i].ipaddr, 0, 4);
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+/**
+ * Periodic ARP processing function.
+ *
+ * This function performs periodic timer processing in the ARP module
+ * and should be called at regular intervals. The recommended interval
+ * is 10 seconds between the calls.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_timer(void)
+{
+  struct arp_entry *tabptr;
+
+  ++arptime;
+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+    tabptr = &arp_table[i];
+    if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
+       arptime - tabptr->time >= UIP_ARP_MAXAGE) {
+      memset(tabptr->ipaddr, 0, 4);
+    }
+  }
+
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
+{
+  register struct arp_entry *tabptr;
+  /* Walk through the ARP mapping table and try to find an entry to
+     update. If none is found, the IP -> MAC address mapping is
+     inserted in the ARP table. */
+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+
+    tabptr = &arp_table[i];
+    /* Only check those entries that are actually in use. */
+    if(tabptr->ipaddr[0] != 0 &&
+       tabptr->ipaddr[1] != 0) {
+
+      /* Check if the source IP address of the incoming packet matches
+         the IP address in this ARP table entry. */
+      if(ipaddr[0] == tabptr->ipaddr[0] &&
+        ipaddr[1] == tabptr->ipaddr[1]) {
+
+       /* An old entry found, update this and return. */
+       memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+       tabptr->time = arptime;
+
+       return;
+      }
+    }
+  }
+
+  /* If we get here, no existing ARP table entry was found, so we
+     create one. */
+
+  /* First, we try to find an unused entry in the ARP table. */
+  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+    tabptr = &arp_table[i];
+    if(tabptr->ipaddr[0] == 0 &&
+       tabptr->ipaddr[1] == 0) {
+      break;
+    }
+  }
+
+  /* If no unused entry is found, we try to find the oldest entry and
+     throw it away. */
+  if(i == UIP_ARPTAB_SIZE) {
+    tmpage = 0;
+    c = 0;
+    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+      tabptr = &arp_table[i];
+      if(arptime - tabptr->time > tmpage) {
+       tmpage = arptime - tabptr->time;
+       c = i;
+      }
+    }
+    i = c;
+    tabptr = &arp_table[i];
+  }
+
+  /* Now, i is the ARP table entry which we will fill with the new
+     information. */
+  memcpy(tabptr->ipaddr, ipaddr, 4);
+  memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+  tabptr->time = arptime;
+}
+/*-----------------------------------------------------------------------------------*/
+/**
+ * ARP processing for incoming IP packets
+ *
+ * This function should be called by the device driver when an IP
+ * packet has been received. The function will check if the address is
+ * in the ARP cache, and if so the ARP cache entry will be
+ * refreshed. If no ARP cache entry was found, a new one is created.
+ *
+ * This function expects an IP packet with a prepended Ethernet header
+ * in the uip_buf[] buffer, and the length of the packet in the global
+ * variable uip_len.
+ */
+/*-----------------------------------------------------------------------------------*/
+#if 0
+void
+uip_arp_ipin(void)
+{
+  uip_len -= sizeof(struct uip_eth_hdr);
+
+  /* Only insert/update an entry if the source IP address of the
+     incoming IP packet comes from a host on the local network. */
+  if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
+     (uip_hostaddr[0] & uip_netmask[0])) {
+    return;
+  }
+  if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
+     (uip_hostaddr[1] & uip_netmask[1])) {
+    return;
+  }
+  uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
+
+  return;
+}
+#endif /* 0 */
+/*-----------------------------------------------------------------------------------*/
+/**
+ * ARP processing for incoming ARP packets.
+ *
+ * This function should be called by the device driver when an ARP
+ * packet has been received. The function will act differently
+ * depending on the ARP packet type: if it is a reply for a request
+ * that we previously sent out, the ARP cache will be filled in with
+ * the values from the ARP reply. If the incoming ARP packet is an ARP
+ * request for our IP address, an ARP reply packet is created and put
+ * into the uip_buf[] buffer.
+ *
+ * When the function returns, the value of the global variable uip_len
+ * indicates whether the device driver should send out a packet or
+ * not. If uip_len is zero, no packet should be sent. If uip_len is
+ * non-zero, it contains the length of the outbound packet that is
+ * present in the uip_buf[] buffer.
+ *
+ * This function expects an ARP packet with a prepended Ethernet
+ * header in the uip_buf[] buffer, and the length of the packet in the
+ * global variable uip_len.
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_arpin(void)
+{
+
+  if(uip_len < sizeof(struct arp_hdr)) {
+    uip_len = 0;
+    return;
+  }
+  uip_len = 0;
+
+  switch(BUF->opcode) {
+  case HTONS(ARP_REQUEST):
+    /* ARP request. If it asked for our address, we send out a
+       reply. */
+    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+      /* First, we register the one who made the request in our ARP
+        table, since it is likely that we will do more communication
+        with this host in the future. */
+      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+
+      /* The reply opcode is 2. */
+      BUF->opcode = HTONS(2);
+
+      memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
+      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+      memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
+
+      BUF->dipaddr[0] = BUF->sipaddr[0];
+      BUF->dipaddr[1] = BUF->sipaddr[1];
+      BUF->sipaddr[0] = uip_hostaddr[0];
+      BUF->sipaddr[1] = uip_hostaddr[1];
+
+      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+      uip_len = sizeof(struct arp_hdr);
+    }
+    break;
+  case HTONS(ARP_REPLY):
+    /* ARP reply. We insert or update the ARP table if it was meant
+       for us. */
+    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+    }
+    break;
+  }
+
+  return;
+}
+/*-----------------------------------------------------------------------------------*/
+/**
+ * Prepend Ethernet header to an outbound IP packet and see if we need
+ * to send out an ARP request.
+ *
+ * This function should be called before sending out an IP packet. The
+ * function checks the destination IP address of the IP packet to see
+ * what Ethernet MAC address that should be used as a destination MAC
+ * address on the Ethernet.
+ *
+ * If the destination IP address is in the local network (determined
+ * by logical ANDing of netmask and our IP address), the function
+ * checks the ARP cache to see if an entry for the destination IP
+ * address is found. If so, an Ethernet header is prepended and the
+ * function returns. If no ARP cache entry is found for the
+ * destination IP address, the packet in the uip_buf[] is replaced by
+ * an ARP request packet for the IP address. The IP packet is dropped
+ * and it is assumed that they higher level protocols (e.g., TCP)
+ * eventually will retransmit the dropped packet.
+ *
+ * If the destination IP address is not on the local network, the IP
+ * address of the default router is used instead.
+ *
+ * When the function returns, a packet is present in the uip_buf[]
+ * buffer, and the length of the packet is in the global variable
+ * uip_len.
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_out(void)
+{
+  struct arp_entry *tabptr;
+
+  /* Find the destination IP address in the ARP table and construct
+     the Ethernet header. If the destination IP addres isn't on the
+     local network, we use the default router's IP address instead.
+
+     If not ARP table entry is found, we overwrite the original IP
+     packet with an ARP request for the IP address. */
+
+  /* First check if destination is a local broadcast. */
+  if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
+    memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
+  } else {
+    /* Check if the destination address is on the local network. */
+    if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
+      /* Destination address was not on the local network, so we need to
+        use the default router's IP address instead of the destination
+        address when determining the MAC address. */
+      uip_ipaddr_copy(ipaddr, uip_draddr);
+    } else {
+      /* Else, we use the destination IP address. */
+      uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
+    }
+
+    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+      tabptr = &arp_table[i];
+      if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
+       break;
+      }
+    }
+
+    if(i == UIP_ARPTAB_SIZE) {
+      /* The destination address was not in our ARP table, so we
+        overwrite the IP packet with an ARP request. */
+
+      memset(BUF->ethhdr.dest.addr, 0xff, 6);
+      memset(BUF->dhwaddr.addr, 0x00, 6);
+      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+
+      uip_ipaddr_copy(BUF->dipaddr, ipaddr);
+      uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
+      BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
+      BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
+      BUF->protocol = HTONS(UIP_ETHTYPE_IP);
+      BUF->hwlen = 6;
+      BUF->protolen = 4;
+      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+
+      uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
+
+      uip_len = sizeof(struct arp_hdr);
+      return;
+    }
+
+    /* Build an ethernet header. */
+    memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
+  }
+  memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+
+  IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
+
+  uip_len += sizeof(struct uip_eth_hdr);
+}
+/*-----------------------------------------------------------------------------------*/
+
+/** @} */
+/** @} */
diff --git a/src/libs/Network/uip/uip/uip_arp.h b/src/libs/Network/uip/uip/uip_arp.h
new file mode 100644 (file)
index 0000000..8e98cce
--- /dev/null
@@ -0,0 +1,150 @@
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \addtogroup uiparp
+ * @{
+ */
+
+/**
+ * \file
+ * Macros and definitions for the ARP module.
+ * \author Adam Dunkels <adam@dunkels.com>
+ */
+
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $
+ *
+ */
+
+#ifndef __UIP_ARP_H__
+#define __UIP_ARP_H__
+
+#include "uip.h"
+
+
+extern struct uip_eth_addr uip_ethaddr;
+
+/**
+ * The Ethernet header.
+ */
+struct uip_eth_hdr {
+  struct uip_eth_addr dest;
+  struct uip_eth_addr src;
+  u16_t type;
+};
+
+#define UIP_ETHTYPE_ARP 0x0806
+#define UIP_ETHTYPE_IP  0x0800
+#define UIP_ETHTYPE_IP6 0x86dd
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The uip_arp_init() function must be called before any of the other
+   ARP functions. */
+void uip_arp_init(void);
+
+/* The uip_arp_ipin() function should be called whenever an IP packet
+   arrives from the Ethernet. This function refreshes the ARP table or
+   inserts a new mapping if none exists. The function assumes that an
+   IP packet with an Ethernet header is present in the uip_buf buffer
+   and that the length of the packet is in the uip_len variable. */
+/*void uip_arp_ipin(void);*/
+#define uip_arp_ipin()
+
+/* The uip_arp_arpin() should be called when an ARP packet is received
+   by the Ethernet driver. This function also assumes that the
+   Ethernet frame is present in the uip_buf buffer. When the
+   uip_arp_arpin() function returns, the contents of the uip_buf
+   buffer should be sent out on the Ethernet if the uip_len variable
+   is > 0. */
+void uip_arp_arpin(void);
+
+/* The uip_arp_out() function should be called when an IP packet
+   should be sent out on the Ethernet. This function creates an
+   Ethernet header before the IP header in the uip_buf buffer. The
+   Ethernet header will have the correct Ethernet MAC destination
+   address filled in if an ARP table entry for the destination IP
+   address (or the IP address of the default router) is present. If no
+   such table entry is found, the IP packet is overwritten with an ARP
+   request and we rely on TCP to retransmit the packet that was
+   overwritten. In any case, the uip_len variable holds the length of
+   the Ethernet frame that should be transmitted. */
+void uip_arp_out(void);
+
+/* The uip_arp_timer() function should be called every ten seconds. It
+   is responsible for flushing old entries in the ARP table. */
+void uip_arp_timer(void);
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+/**
+ * \addtogroup uipconffunc
+ * @{
+ */
+
+
+/**
+ * Specifiy the Ethernet MAC address.
+ *
+ * The ARP code needs to know the MAC address of the Ethernet card in
+ * order to be able to respond to ARP queries and to generate working
+ * Ethernet headers.
+ *
+ * \note This macro only specifies the Ethernet MAC address to the ARP
+ * code. It cannot be used to change the MAC address of the Ethernet
+ * card.
+ *
+ * \param eaddr A pointer to a struct uip_eth_addr containing the
+ * Ethernet MAC address of the Ethernet card.
+ *
+ * \hideinitializer
+ */
+#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr[0]; \
+                              uip_ethaddr.addr[1] = eaddr[1];\
+                              uip_ethaddr.addr[2] = eaddr[2];\
+                              uip_ethaddr.addr[3] = eaddr[3];\
+                              uip_ethaddr.addr[4] = eaddr[4];\
+                              uip_ethaddr.addr[5] = eaddr[5];} while(0)
+
+/** @} */
+/** @} */
+
+#endif /* __UIP_ARP_H__ */
diff --git a/src/libs/Network/uip/uip/uiplib.c b/src/libs/Network/uip/uip/uiplib.c
new file mode 100644 (file)
index 0000000..30c7d6a
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of
+ * Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uiplib.c,v 1.2 2006/06/12 08:00:31 adam Exp $
+ *
+ */
+
+
+#include "uip.h"
+#include "uiplib.h"
+
+
+/*-----------------------------------------------------------------------------------*/
+unsigned char
+uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr)
+{
+  unsigned char tmp;
+  char c;
+  unsigned char i, j;
+
+  tmp = 0;
+
+  for(i = 0; i < 4; ++i) {
+    j = 0;
+    do {
+      c = *addrstr;
+      ++j;
+      if(j > 4) {
+       return 0;
+      }
+      if(c == '.' || c == 0) {
+       *ipaddr = tmp;
+       ++ipaddr;
+       tmp = 0;
+      } else if(c >= '0' && c <= '9') {
+       tmp = (tmp * 10) + (c - '0');
+      } else {
+       return 0;
+      }
+      ++addrstr;
+    } while(c != '.' && c != 0);
+  }
+  return 1;
+}
+
+/*-----------------------------------------------------------------------------------*/
diff --git a/src/libs/Network/uip/uip/uiplib.h b/src/libs/Network/uip/uip/uiplib.h
new file mode 100644 (file)
index 0000000..c676849
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * \file
+ * Various uIP library functions.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * Copyright (c) 2002, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uiplib.h,v 1.1 2006/06/07 09:15:19 adam Exp $
+ *
+ */
+#ifndef __UIPLIB_H__
+#define __UIPLIB_H__
+
+/**
+ * \addtogroup uipconvfunc
+ * @{
+ */
+
+/**
+ * Convert a textual representation of an IP address to a numerical representation.
+ *
+ * This function takes a textual representation of an IP address in
+ * the form a.b.c.d and converts it into a 4-byte array that can be
+ * used by other uIP functions.
+ *
+ * \param addrstr A pointer to a string containing the IP address in
+ * textual form.
+ *
+ * \param addr A pointer to a 4-byte array that will be filled in with
+ * the numerical representation of the address.
+ *
+ * \retval 0 If the IP address could not be parsed.
+ * \retval Non-zero If the IP address was parsed.
+ */
+unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr);
+
+/** @} */
+
+#endif /* __UIPLIB_H__ */
diff --git a/src/libs/Network/uip/uip/uipopt.h b/src/libs/Network/uip/uip/uipopt.h
new file mode 100644 (file)
index 0000000..46f8f4f
--- /dev/null
@@ -0,0 +1,546 @@
+/**
+ * \defgroup uipopt Configuration options for uIP
+ * @{
+ *
+ * uIP is configured using the per-project configuration file
+ * uipopt.h. This file contains all compile-time options for uIP and
+ * should be tweaked to match each specific project. The uIP
+ * distribution contains a documented example "uipopt.h" that can be
+ * copied and modified for each project.
+ *
+ * \note Most of the configuration options in the uipopt.h should not
+ * be changed, but rather the per-project uip-conf.h file.
+ */
+
+/**
+ * \file
+ * Configuration options for uIP.
+ * \author Adam Dunkels <adam@dunkels.com>
+ *
+ * This file is used for tweaking various configuration options for
+ * uIP. You should make a copy of this file into one of your project's
+ * directories instead of editing this example "uipopt.h" file that
+ * comes with the uIP distribution.
+ */
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $
+ *
+ */
+
+#ifndef __UIPOPT_H__
+#define __UIPOPT_H__
+
+#ifndef UIP_LITTLE_ENDIAN
+#define UIP_LITTLE_ENDIAN  3412
+#endif /* UIP_LITTLE_ENDIAN */
+#ifndef UIP_BIG_ENDIAN
+#define UIP_BIG_ENDIAN     1234
+#endif /* UIP_BIG_ENDIAN */
+
+#include "uip-conf.h"
+
+/*------------------------------------------------------------------------------*/
+
+/**
+ * \name Static configuration options
+ * @{
+ *
+ * These configuration options can be used for setting the IP address
+ * settings statically, but only if UIP_FIXEDADDR is set to 1. The
+ * configuration options for a specific node includes IP address,
+ * netmask and default router as well as the Ethernet address. The
+ * netmask, default router and Ethernet address are appliciable only
+ * if uIP should be run over Ethernet.
+ *
+ * All of these should be changed to suit your project.
+*/
+
+/**
+ * Determines if uIP should use a fixed IP address or not.
+ *
+ * If uIP should use a fixed IP address, the settings are set in the
+ * uipopt.h file. If not, the macros uip_sethostaddr(),
+ * uip_setdraddr() and uip_setnetmask() should be used instead.
+ *
+ * \hideinitializer
+ */
+#define UIP_FIXEDADDR    0
+
+/**
+ * Ping IP address asignment.
+ *
+ * uIP uses a "ping" packets for setting its own IP address if this
+ * option is set. If so, uIP will start with an empty IP address and
+ * the destination IP address of the first incoming "ping" (ICMP echo)
+ * packet will be used for setting the hosts IP address.
+ *
+ * \note This works only if UIP_FIXEDADDR is 0.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_PINGADDRCONF
+#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
+#else /* UIP_CONF_PINGADDRCONF */
+#define UIP_PINGADDRCONF 0
+#endif /* UIP_CONF_PINGADDRCONF */
+
+
+/**
+ * Specifies if the uIP ARP module should be compiled with a fixed
+ * Ethernet MAC address or not.
+ *
+ * If this configuration option is 0, the macro uip_setethaddr() can
+ * be used to specify the Ethernet address at run-time.
+ *
+ * \hideinitializer
+ */
+#define UIP_FIXEDETHADDR 0
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name IP configuration options
+ * @{
+ *
+ */
+/**
+ * The IP TTL (time to live) of IP packets sent by uIP.
+ *
+ * This should normally not be changed.
+ */
+#define UIP_TTL         64
+
+/**
+ * Turn on support for IP packet reassembly.
+ *
+ * uIP supports reassembly of fragmented IP packets. This features
+ * requires an additonal amount of RAM to hold the reassembly buffer
+ * and the reassembly code size is approximately 700 bytes.  The
+ * reassembly buffer is of the same size as the uip_buf buffer
+ * (configured by UIP_BUFSIZE).
+ *
+ * \note IP packet reassembly is not heavily tested.
+ *
+ * \hideinitializer
+ */
+#define UIP_REASSEMBLY 0
+
+/**
+ * The maximum time an IP fragment should wait in the reassembly
+ * buffer before it is dropped.
+ *
+ */
+#define UIP_REASS_MAXAGE 40
+
+/** @} */
+
+/*------------------------------------------------------------------------------*/
+/**
+ * \name UDP configuration options
+ * @{
+ */
+
+/**
+ * Toggles wether UDP support should be compiled in or not.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_UDP
+#define UIP_UDP UIP_CONF_UDP
+#else /* UIP_CONF_UDP */
+#define UIP_UDP           0
+#endif /* UIP_CONF_UDP */
+
+/**
+ * Toggles if UDP checksums should be used or not.
+ *
+ * \note Support for UDP checksums is currently not included in uIP,
+ * so this option has no function.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_UDP_CHECKSUMS
+#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
+#else
+#define UIP_UDP_CHECKSUMS 0
+#endif
+
+/**
+ * The maximum amount of concurrent UDP connections.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_UDP_CONNS
+#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
+#else /* UIP_CONF_UDP_CONNS */
+#define UIP_UDP_CONNS    10
+#endif /* UIP_CONF_UDP_CONNS */
+
+/**
+ * The name of the function that should be called when UDP datagrams arrive.
+ *
+ * \hideinitializer
+ */
+
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name TCP configuration options
+ * @{
+ */
+
+/**
+ * Determines if support for opening connections from uIP should be
+ * compiled in.
+ *
+ * If the applications that are running on top of uIP for this project
+ * do not need to open outgoing TCP connections, this configration
+ * option can be turned off to reduce the code size of uIP.
+ *
+ * \hideinitializer
+ */
+#define UIP_ACTIVE_OPEN 1
+
+/**
+ * The maximum number of simultaneously open TCP connections.
+ *
+ * Since the TCP connections are statically allocated, turning this
+ * configuration knob down results in less RAM used. Each TCP
+ * connection requires approximatly 30 bytes of memory.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_MAX_CONNECTIONS
+#define UIP_CONNS       10
+#else /* UIP_CONF_MAX_CONNECTIONS */
+#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
+#endif /* UIP_CONF_MAX_CONNECTIONS */
+
+
+/**
+ * The maximum number of simultaneously listening TCP ports.
+ *
+ * Each listening TCP port requires 2 bytes of memory.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_MAX_LISTENPORTS
+#define UIP_LISTENPORTS 20
+#else /* UIP_CONF_MAX_LISTENPORTS */
+#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
+#endif /* UIP_CONF_MAX_LISTENPORTS */
+
+/**
+ * Determines if support for TCP urgent data notification should be
+ * compiled in.
+ *
+ * Urgent data (out-of-band data) is a rarely used TCP feature that
+ * very seldom would be required.
+ *
+ * \hideinitializer
+ */
+#define UIP_URGDATA      0
+
+/**
+ * The initial retransmission timeout counted in timer pulses.
+ *
+ * This should not be changed.
+ */
+#define UIP_RTO         3
+
+/**
+ * The maximum number of times a segment should be retransmitted
+ * before the connection should be aborted.
+ *
+ * This should not be changed.
+ */
+#define UIP_MAXRTX      8
+
+/**
+ * The maximum number of times a SYN segment should be retransmitted
+ * before a connection request should be deemed to have been
+ * unsuccessful.
+ *
+ * This should not need to be changed.
+ */
+#define UIP_MAXSYNRTX      5
+
+/**
+ * The TCP maximum segment size.
+ *
+ * This is should not be to set to more than
+ * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
+ */
+#define UIP_TCP_MSS     (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+
+/**
+ * The size of the advertised receiver's window.
+ *
+ * Should be set low (i.e., to the size of the uip_buf buffer) is the
+ * application is slow to process incoming data, or high (32768 bytes)
+ * if the application processes data quickly.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_RECEIVE_WINDOW
+#define UIP_RECEIVE_WINDOW UIP_TCP_MSS
+#else
+#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
+#endif
+
+/**
+ * How long a connection should stay in the TIME_WAIT state.
+ *
+ * This configiration option has no real implication, and it should be
+ * left untouched.
+ */
+#define UIP_TIME_WAIT_TIMEOUT 120
+
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name ARP configuration options
+ * @{
+ */
+
+/**
+ * The size of the ARP table.
+ *
+ * This option should be set to a larger value if this uIP node will
+ * have many connections from the local network.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_ARPTAB_SIZE
+#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
+#else
+#define UIP_ARPTAB_SIZE 8
+#endif
+
+/**
+ * The maxium age of ARP table entries measured in 10ths of seconds.
+ *
+ * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
+ * default).
+ */
+#define UIP_ARP_MAXAGE 120
+
+/** @} */
+
+/*------------------------------------------------------------------------------*/
+
+/**
+ * \name General configuration options
+ * @{
+ */
+
+/**
+ * The size of the uIP packet buffer.
+ *
+ * The uIP packet buffer should not be smaller than 60 bytes, and does
+ * not need to be larger than 1500 bytes. Lower size results in lower
+ * TCP throughput, larger size results in higher TCP throughput.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_BUFFER_SIZE
+#define UIP_BUFSIZE     400
+#else /* UIP_CONF_BUFFER_SIZE */
+#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
+#endif /* UIP_CONF_BUFFER_SIZE */
+
+
+/**
+ * Determines if statistics support should be compiled in.
+ *
+ * The statistics is useful for debugging and to show the user.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_STATISTICS
+#define UIP_STATISTICS  0
+#else /* UIP_CONF_STATISTICS */
+#define UIP_STATISTICS UIP_CONF_STATISTICS
+#endif /* UIP_CONF_STATISTICS */
+
+/**
+ * Determines if logging of certain events should be compiled in.
+ *
+ * This is useful mostly for debugging. The function uip_log()
+ * must be implemented to suit the architecture of the project, if
+ * logging is turned on.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_LOGGING
+#define UIP_LOGGING     0
+#else /* UIP_CONF_LOGGING */
+#define UIP_LOGGING     UIP_CONF_LOGGING
+#endif /* UIP_CONF_LOGGING */
+
+/**
+ * Broadcast support.
+ *
+ * This flag configures IP broadcast support. This is useful only
+ * together with UDP.
+ *
+ * \hideinitializer
+ *
+ */
+#ifndef UIP_CONF_BROADCAST
+#define UIP_BROADCAST 0
+#else /* UIP_CONF_BROADCAST */
+#define UIP_BROADCAST UIP_CONF_BROADCAST
+#endif /* UIP_CONF_BROADCAST */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print out a uIP log message.
+ *
+ * This function must be implemented by the module that uses uIP, and
+ * is called by uIP whenever a log message is generated.
+ */
+void uip_log(char *msg);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * The link level header length.
+ *
+ * This is the offset into the uip_buf where the IP header can be
+ * found. For Ethernet, this should be set to 14. For SLIP, this
+ * should be set to 0.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_LLH_LEN
+#define UIP_LLH_LEN UIP_CONF_LLH_LEN
+#else /* UIP_CONF_LLH_LEN */
+#define UIP_LLH_LEN     14
+#endif /* UIP_CONF_LLH_LEN */
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name CPU architecture configuration
+ * @{
+ *
+ * The CPU architecture configuration is where the endianess of the
+ * CPU on which uIP is to be run is specified. Most CPUs today are
+ * little endian, and the most notable exception are the Motorolas
+ * which are big endian. The BYTE_ORDER macro should be changed to
+ * reflect the CPU architecture on which uIP is to be run.
+ */
+
+/**
+ * The byte order of the CPU architecture on which uIP is to be run.
+ *
+ * This option can be either BIG_ENDIAN (Motorola byte order) or
+ * LITTLE_ENDIAN (Intel byte order).
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_BYTE_ORDER
+#define UIP_BYTE_ORDER     UIP_CONF_BYTE_ORDER
+#else /* UIP_CONF_BYTE_ORDER */
+#define UIP_BYTE_ORDER     UIP_LITTLE_ENDIAN
+#endif /* UIP_CONF_BYTE_ORDER */
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+
+/**
+ * \name Appication specific configurations
+ * @{
+ *
+ * An uIP application is implemented using a single application
+ * function that is called by uIP whenever a TCP/IP event occurs. The
+ * name of this function must be registered with uIP at compile time
+ * using the UIP_APPCALL definition.
+ *
+ * uIP applications can store the application state within the
+ * uip_conn structure by specifying the type of the application
+ * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
+ *
+ * The file containing the definitions must be included in the
+ * uipopt.h file.
+ *
+ * The following example illustrates how this can look.
+ \code
+
+void httpd_appcall(void);
+#define UIP_APPCALL     httpd_appcall
+
+struct httpd_state {
+  u8_t state;
+  u16_t count;
+  char *dataptr;
+  char *script;
+};
+typedef struct httpd_state uip_tcp_appstate_t
+ \endcode
+ */
+
+/**
+ * \var #define UIP_APPCALL
+ *
+ * The name of the application function that uIP should call in
+ * response to TCP/IP events.
+ *
+ */
+
+/**
+ * \var typedef uip_tcp_appstate_t
+ *
+ * The type of the application state that is to be stored in the
+ * uip_conn structure. This usually is typedef:ed to a struct holding
+ * application state information.
+ */
+
+/**
+ * \var typedef uip_udp_appstate_t
+ *
+ * The type of the application state that is to be stored in the
+ * uip_conn structure. This usually is typedef:ed to a struct holding
+ * application state information.
+ */
+/** @} */
+/** @} */
+
+#endif /* __UIPOPT_H__ */
diff --git a/src/libs/Network/uip/webserver/http-strings b/src/libs/Network/uip/webserver/http-strings
new file mode 100644 (file)
index 0000000..a1af19d
--- /dev/null
@@ -0,0 +1,41 @@
+http_http "http://"
+http_200 "200 "
+http_301 "301 "
+http_302 "302 "
+http_get "GET "
+http_post "POST "
+http_10 "HTTP/1.0"
+http_11 "HTTP/1.1"
+http_content_type "content-type: "
+http_content_length "Content-Length: "
+http_cache_control "Cache-Control: "
+http_no_cache "no-cache"
+http_texthtml "text/html"
+http_location "location: "
+http_host "host: "
+http_crnl "\r\n"
+http_index_html "/index.html"
+http_404_html "/404.html"
+http_referer "Referer:"
+http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0\r\nConnection: close\r\n"
+http_header_304 "HTTP/1.0 304 Not Modified\r\nServer: uIP/1.0\r\nConnection: close\r\nExpires: Thu, 31 Dec 2037 23:55:55 GMT\r\nCache-Control: max-age=315360000\r\nX-Cache: HIT\r\n"
+http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0\r\nConnection: close\r\n"
+http_header_503 "HTTP/1.0 503 Failed\r\nServer: uIP/1.0\r\nConnection: close\r\n"
+http_content_type_plain "Content-type: text/plain\r\n\r\n"
+http_content_type_html "Content-type: text/html\r\n\r\n"
+http_content_type_css  "Content-type: text/css\r\n\r\n"
+http_content_type_text "Content-type: text/text\r\n\r\n"
+http_content_type_png  "Content-type: image/png\r\n\r\n"
+http_content_type_gif  "Content-type: image/gif\r\n\r\n"
+http_content_type_jpg  "Content-type: image/jpeg\r\n\r\n"
+http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"
+http_html ".html"
+http_shtml ".shtml"
+http_htm ".htm"
+http_css ".css"
+http_png ".png"
+http_gif ".gif"
+http_jpg ".jpg"
+http_text ".txt"
+http_txt ".txt"
+
diff --git a/src/libs/Network/uip/webserver/http-strings.c b/src/libs/Network/uip/webserver/http-strings.c
new file mode 100644 (file)
index 0000000..5fbcb61
--- /dev/null
@@ -0,0 +1,120 @@
+const char http_http[8] = 
+/* "http://" */
+{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
+const char http_200[5] = 
+/* "200 " */
+{0x32, 0x30, 0x30, 0x20, };
+const char http_301[5] = 
+/* "301 " */
+{0x33, 0x30, 0x31, 0x20, };
+const char http_302[5] = 
+/* "302 " */
+{0x33, 0x30, 0x32, 0x20, };
+const char http_get[5] = 
+/* "GET " */
+{0x47, 0x45, 0x54, 0x20, };
+const char http_post[6] = 
+/* "POST " */
+{0x50, 0x4f, 0x53, 0x54, 0x20, };
+const char http_10[9] = 
+/* "HTTP/1.0" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };
+const char http_11[9] = 
+/* "HTTP/1.1" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };
+const char http_content_type[15] = 
+/* "content-type: " */
+{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, };
+const char http_content_length[17] = 
+/* "Content-Length: " */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, };
+const char http_cache_control[16] = 
+/* "Cache-Control: " */
+{0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x20, };
+const char http_no_cache[9] = 
+/* "no-cache" */
+{0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, };
+const char http_texthtml[10] = 
+/* "text/html" */
+{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_location[11] = 
+/* "location: " */
+{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };
+const char http_host[7] = 
+/* "host: " */
+{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };
+const char http_crnl[3] = 
+/* "\r\n" */
+{0xd, 0xa, };
+const char http_index_html[12] = 
+/* "/index.html" */
+{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_404_html[10] = 
+/* "/404.html" */
+{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_referer[9] = 
+/* "Referer:" */
+{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };
+const char http_header_200[54] = 
+/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0\r\nConnection: close\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
+const char http_header_304[152] = 
+/* "HTTP/1.0 304 Not Modified\r\nServer: uIP/1.0\r\nConnection: close\r\nExpires: Thu, 31 Dec 2037 23:55:55 GMT\r\nCache-Control: max-age=315360000\r\nX-Cache: HIT\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x33, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x33, 0x31, 0x20, 0x44, 0x65, 0x63, 0x20, 0x32, 0x30, 0x33, 0x37, 0x20, 0x32, 0x33, 0x3a, 0x35, 0x35, 0x3a, 0x35, 0x35, 0x20, 0x47, 0x4d, 0x54, 0xd, 0xa, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, 0x3d, 0x33, 0x31, 0x35, 0x33, 0x36, 0x30, 0x30, 0x30, 0x30, 0xd, 0xa, 0x58, 0x2d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x3a, 0x20, 0x48, 0x49, 0x54, 0xd, 0xa, };
+const char http_header_404[61] = 
+/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0\r\nConnection: close\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
+const char http_header_503[58] = 
+/* "HTTP/1.0 503 Failed\r\nServer: uIP/1.0\r\nConnection: close\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x35, 0x30, 0x33, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
+const char http_content_type_plain[29] = 
+/* "Content-type: text/plain\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_html[28] = 
+/* "Content-type: text/html\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_css [27] = 
+/* "Content-type: text/css\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_text[28] = 
+/* "Content-type: text/text\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_png [28] = 
+/* "Content-type: image/png\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_gif [28] = 
+/* "Content-type: image/gif\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_jpg [29] = 
+/* "Content-type: image/jpeg\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_binary[43] = 
+/* "Content-type: application/octet-stream\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, };
+const char http_html[6] = 
+/* ".html" */
+{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_shtml[7] = 
+/* ".shtml" */
+{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_htm[5] = 
+/* ".htm" */
+{0x2e, 0x68, 0x74, 0x6d, };
+const char http_css[5] = 
+/* ".css" */
+{0x2e, 0x63, 0x73, 0x73, };
+const char http_png[5] = 
+/* ".png" */
+{0x2e, 0x70, 0x6e, 0x67, };
+const char http_gif[5] = 
+/* ".gif" */
+{0x2e, 0x67, 0x69, 0x66, };
+const char http_jpg[5] = 
+/* ".jpg" */
+{0x2e, 0x6a, 0x70, 0x67, };
+const char http_text[5] = 
+/* ".txt" */
+{0x2e, 0x74, 0x78, 0x74, };
+const char http_txt[5] = 
+/* ".txt" */
+{0x2e, 0x74, 0x78, 0x74, };
diff --git a/src/libs/Network/uip/webserver/http-strings.h b/src/libs/Network/uip/webserver/http-strings.h
new file mode 100644 (file)
index 0000000..cea506b
--- /dev/null
@@ -0,0 +1,40 @@
+extern const char http_http[8];
+extern const char http_200[5];
+extern const char http_301[5];
+extern const char http_302[5];
+extern const char http_get[5];
+extern const char http_post[6];
+extern const char http_10[9];
+extern const char http_11[9];
+extern const char http_content_type[15];
+extern const char http_content_length[17];
+extern const char http_cache_control[16];
+extern const char http_no_cache[9];
+extern const char http_texthtml[10];
+extern const char http_location[11];
+extern const char http_host[7];
+extern const char http_crnl[3];
+extern const char http_index_html[12];
+extern const char http_404_html[10];
+extern const char http_referer[9];
+extern const char http_header_200[54];
+extern const char http_header_304[152];
+extern const char http_header_404[61];
+extern const char http_header_503[58];
+extern const char http_content_type_plain[29];
+extern const char http_content_type_html[28];
+extern const char http_content_type_css [27];
+extern const char http_content_type_text[28];
+extern const char http_content_type_png [28];
+extern const char http_content_type_gif [28];
+extern const char http_content_type_jpg [29];
+extern const char http_content_type_binary[43];
+extern const char http_html[6];
+extern const char http_shtml[7];
+extern const char http_htm[5];
+extern const char http_css[5];
+extern const char http_png[5];
+extern const char http_gif[5];
+extern const char http_jpg[5];
+extern const char http_text[5];
+extern const char http_txt[5];
diff --git a/src/libs/Network/uip/webserver/httpd-fs.c b/src/libs/Network/uip/webserver/httpd-fs.c
new file mode 100644 (file)
index 0000000..a322121
--- /dev/null
@@ -0,0 +1,137 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"\r
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"\r
+#pragma GCC diagnostic ignored "-Wcast-align"\r
+#pragma GCC diagnostic ignored "-Wcast-qual"\r
+\r
+/*\r
+ * Copyright (c) 2001, Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the Institute nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ * $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $\r
+ */\r
+\r
+#include "httpd.h"\r
+#include "httpd-fs.h"\r
+#include "httpd-fsdata.h"\r
+\r
+#ifndef NULL\r
+#define NULL 0\r
+#endif /* NULL */\r
+\r
+#include "httpd-fsdata2.h"\r
+\r
+#if HTTPD_FS_STATISTICS\r
+static u16_t count[HTTPD_FS_NUMFILES];\r
+#endif /* HTTPD_FS_STATISTICS */\r
+\r
+/*-----------------------------------------------------------------------------------*/\r
+static u8_t\r
+httpd_fs_strcmp(const char *str1, const char *str2)\r
+{\r
+  u8_t i;\r
+  i = 0;\r
+ loop:\r
+\r
+  if(str2[i] == 0 ||\r
+     str1[i] == '\r' ||\r
+     str1[i] == '\n') {\r
+    return 0;\r
+  }\r
+\r
+  if(str1[i] != str2[i]) {\r
+    return 1;\r
+  }\r
+\r
+\r
+  ++i;\r
+  goto loop;\r
+}\r
+/*-----------------------------------------------------------------------------------*/\r
+int\r
+httpd_fs_open(const char *name, struct httpd_fs_file *file)\r
+{\r
+#if HTTPD_FS_STATISTICS\r
+  u16_t i = 0;\r
+#endif /* HTTPD_FS_STATISTICS */\r
+  struct httpd_fsdata_file_noconst *f;\r
+\r
+  for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;\r
+      f != NULL;\r
+      f = (struct httpd_fsdata_file_noconst *)f->next) {\r
+\r
+    if(httpd_fs_strcmp(name, f->name) == 0) {\r
+      file->data = f->data;\r
+      file->len = f->len;\r
+#if HTTPD_FS_STATISTICS\r
+      ++count[i];\r
+#endif /* HTTPD_FS_STATISTICS */\r
+      return 1;\r
+    }\r
+#if HTTPD_FS_STATISTICS\r
+    ++i;\r
+#endif /* HTTPD_FS_STATISTICS */\r
+\r
+  }\r
+  return 0;\r
+}\r
+/*-----------------------------------------------------------------------------------*/\r
+void\r
+httpd_fs_init(void)\r
+{\r
+#if HTTPD_FS_STATISTICS\r
+  u16_t i;\r
+  for(i = 0; i < HTTPD_FS_NUMFILES; i++) {\r
+    count[i] = 0;\r
+  }\r
+#endif /* HTTPD_FS_STATISTICS */\r
+}\r
+/*-----------------------------------------------------------------------------------*/\r
+#if HTTPD_FS_STATISTICS\r
+u16_t httpd_fs_count\r
+(char *name)\r
+{\r
+  struct httpd_fsdata_file_noconst *f;\r
+  u16_t i;\r
+\r
+  i = 0;\r
+  for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;\r
+      f != NULL;\r
+      f = (struct httpd_fsdata_file_noconst *)f->next) {\r
+\r
+    if(httpd_fs_strcmp(name, f->name) == 0) {\r
+      return count[i];\r
+    }\r
+    ++i;\r
+  }\r
+  return 0;\r
+}\r
+#endif /* HTTPD_FS_STATISTICS */\r
+/*-----------------------------------------------------------------------------------*/\r
diff --git a/src/libs/Network/uip/webserver/httpd-fs.h b/src/libs/Network/uip/webserver/httpd-fs.h
new file mode 100644 (file)
index 0000000..b594eea
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Copyright (c) 2001, Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the Institute nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ * $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $\r
+ */\r
+#ifndef __HTTPD_FS_H__\r
+#define __HTTPD_FS_H__\r
+\r
+#define HTTPD_FS_STATISTICS 1\r
+\r
+struct httpd_fs_file {\r
+  char *data;\r
+  int len;\r
+};\r
+\r
+/* file must be allocated by caller and will be filled in\r
+   by the function. */\r
+int httpd_fs_open(const char *name, struct httpd_fs_file *file);\r
+\r
+#ifdef HTTPD_FS_STATISTICS\r
+#if HTTPD_FS_STATISTICS == 1\r
+u16_t httpd_fs_count(char *name);\r
+#endif /* HTTPD_FS_STATISTICS */\r
+#endif /* HTTPD_FS_STATISTICS */\r
+\r
+void httpd_fs_init(void);\r
+\r
+#endif /* __HTTPD_FS_H__ */\r
diff --git a/src/libs/Network/uip/webserver/httpd-fs/404.html b/src/libs/Network/uip/webserver/httpd-fs/404.html
new file mode 100644 (file)
index 0000000..60eab8f
--- /dev/null
@@ -0,0 +1,8 @@
+<html>
+  <body bgcolor="white">
+    <center>
+      <h1>404 - file not found</h1>
+      <h3>Go <a href="/">here</a> instead.</h3>
+    </center>
+  </body>
+</html>
diff --git a/src/libs/Network/uip/webserver/httpd-fs/img/control_xy.png b/src/libs/Network/uip/webserver/httpd-fs/img/control_xy.png
new file mode 100644 (file)
index 0000000..12dcda7
Binary files /dev/null and b/src/libs/Network/uip/webserver/httpd-fs/img/control_xy.png differ
diff --git a/src/libs/Network/uip/webserver/httpd-fs/img/control_z.png b/src/libs/Network/uip/webserver/httpd-fs/img/control_z.png
new file mode 100644 (file)
index 0000000..56553d7
Binary files /dev/null and b/src/libs/Network/uip/webserver/httpd-fs/img/control_z.png differ
diff --git a/src/libs/Network/uip/webserver/httpd-fs/index.html b/src/libs/Network/uip/webserver/httpd-fs/index.html
new file mode 100644 (file)
index 0000000..40364dc
--- /dev/null
@@ -0,0 +1,283 @@
+<!doctype html>
+<head>
+       <meta charset="utf-8">
+       <title>Single Command</title>
+       <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
+       <script type=text/javascript language=JavaScript>
+  var concentric_circle_radii = [11, 45, 69, 94, 115];
+  var center = [124, 121];
+  var spacer = 7;
+  var zbutton_ydistances = [7, 30, 55, 83];
+  var zcenter = [30, 118];
+
+function runCommand(cmd) {
+  // Get some values from elements on the page:
+  var $form = $( "#commandForm" );
+  cmd += "\n";
+  url = "/command_silent"; // $form.attr( "action" );
+  // Send the data using post
+  var posting = $.post( url, cmd );
+  // Put the results in a div
+  // posting.done(function( data ) {
+  //   $( "#result" ).empty();
+  //   $.each(data.split('\n'), function(index) {
+  //     $( "#result" ).append( this + '<br/>' );
+  //   });
+  // });
+}
+
+function lookupConcentric(radius){
+  var length = concentric_circle_radii.length;
+  for (i=0;i<=length;i++) {
+    if (radius < concentric_circle_radii[i]) return(i);
+  }
+  return(length);
+}
+
+function getQuadrantConcentricFromPosition(x,y) {
+  var rel_x = x - center[0]
+  var rel_y = y - center[1]
+  var radius = Math.sqrt(Math.pow(Math.abs(rel_x),2) + Math.pow(Math.abs(rel_y),2))
+  if (rel_x > rel_y && rel_x > -rel_y) {
+    quadrant = 0; // Right
+  } else if (rel_x <= rel_y && rel_x > -rel_y) {
+    quadrant = 3; // Down
+  } else if (rel_x > rel_y && rel_x < -rel_y) {
+    quadrant = 1; // Up
+  } else {
+    quadrant = 2; // Left
+  }
+  var idx = lookupConcentric(radius);
+  return [quadrant, idx]
+}
+
+function clickXY(event){
+  var pos_x = event.offsetX?(event.offsetX):event.pageX-document.getElementById("control_xy").offsetLeft;
+  var pos_y = event.offsetY?(event.offsetY):event.pageY-document.getElementById("control_xy").offsetTop;
+  var codes = getQuadrantConcentricFromPosition(pos_x,pos_y);
+  var quadrant = codes[0], concentric = codes[1];
+  if (concentric < 5) { // movement button pressed
+    var xdir = [1, 0, -1, 0, 0, 0][quadrant];
+    var ydir = [0, 1, 0, -1, 0, 0][quadrant];
+    var magnitude = Math.pow(10, concentric - 2);
+    if (xdir != 0) {
+      command = "G1 X" + (magnitude * xdir) + " F" + document.getElementById("xy_velocity").value;
+    } else {
+      command = "G1 Y" + (magnitude * ydir) + " F" + document.getElementById("xy_velocity").value;
+    }
+    runCommand("G91 " + command + " G90");
+  } else { // home button pressed
+    if (pos_x < 49 && pos_y < 49) { // home x button
+      command = "G28 X0";
+    } else if (pos_x > 200 && pos_y < 49) { //home y button
+      command = "G28 Y0";
+    } else if (pos_x < 49 && pos_y > 200) { // home all button
+      command = "G28";
+    } else { // home z button
+      command = "G28 Z0";
+    }
+    runCommand(command);
+  }
+}
+
+function lookupRange(ydist) {
+  var length = zbutton_ydistances.length;
+  for (i=0;i<length;i++) {
+    if (ydist < zbutton_ydistances[i]) return i;
+  }
+}
+
+function clickZ(event){
+  //var pos_x = event.offsetX?(event.offsetX):event.pageX-document.getElementById("control_z").offsetLeft;
+  var pos_y = event.offsetY?(event.offsetY):event.pageY-document.getElementById("control_z").offsetTop;
+  var ydelta = zcenter[1] - pos_y;
+  var range = lookupRange(Math.abs(ydelta));
+  var direction = (ydelta > 0)?1:-1;
+  if (range < 4) {
+    runCommand("G91 G1 Z" + (Math.pow(10,range-2) * direction) + " F" + document.getElementById("z_velocity").value + " G90");
+  }
+}
+
+function extrude(event,a,b) {
+  var length = document.getElementById("extrude_length").value;
+  var velocity = document.getElementById("extrude_velocity").value;
+  var direction = (event.currentTarget.id=='extrude')?1:-1;
+  runCommand("G91 G1 E" + (length * direction) + " F" + velocity + " G90");
+}
+
+function motorsOff(event) {
+  runCommand("M18");
+}
+
+function heatSet(event) {
+  var type = (event.currentTarget.id=='heat_set')?104:140;
+  var temperature = (type==104)?document.getElementById("heat_value").value:document.getElementById("bed_value").value;
+  runCommand("M" + type + " S" + temperature);
+}
+
+function heatOff(event) {
+  var type = (event.currentTarget.id=='heat_off')?104:140;
+  runCommand("M" + type + " S0");
+}
+
+</script>
+</head>
+
+<body>
+    <h1>Welcome to Smoothie web interface</h1>
+
+<button id=motors_off onclick=motorsOff(event)>Motors Off</button>
+XY:<input type=text id=xy_velocity size=4 value=3000 style=width:50px>mm/min
+Z:<input type=text id=z_velocity size=3 value=200 style=width:40px>
+<br>
+<img id=control_xy src=img/control_xy.png onclick=clickXY(event)>
+<img id=control_z src=img/control_z.png onclick=clickZ(event)>
+<br>
+<table><tr><td>
+<table>
+<tr>
+<td style=text-align:right>Heat:</td>
+<td><button id=heat_off onclick=heatOff(event)>Off</button></td>
+<td><input type=text id=heat_value size=3 style=width:40px value=0></td>
+<td><button id=heat_set onclick=heatSet(event)>Set</button></td>
+</tr>
+<tr>
+<td style=text-align:right>Bed:</td>
+<td><button id=bed_off onclick=heatOff(event)>Off</button></td>
+<td><input type=text id=bed_value size=3 style=width:40px value=0></td>
+<td><button id=bed_set onclick=heatSet(event)>Set</button></td>
+</tr>
+</table>
+</td><td valign=top>
+<button id=get_temperature onclick=runCommand("M105")>Get Temperature</button>
+</td></tr></table>
+<br>
+<button id=extrude onclick=extrude(event)>Extrude</button>
+<button id=reverse onclick=extrude(event)>Reverse</button><br>
+<input type=text id=extrude_length value=5 size=3 style=width:35px>
+mm @
+<input type=text id=extrude_velocity value=100 size=3 style=width:40px>
+mm/min
+
+    <h2>Commands</h2>
+       <form action="/command" id="commandForm">
+               <input type="text" name="commandText" placeholder="Send Command...">
+               <input type="submit" value="Send">
+       </form>
+       <!-- the result of the command will be rendered inside this div -->
+       <div id="result"></div>
+       <script>
+               // Attach a submit handler to the form
+               $( "#commandForm" ).submit(function( event ) {
+                       // Stop form from submitting normally
+                       event.preventDefault();
+                       // Get some values from elements on the page:
+                       var $form = $( this );
+                       command = $form.find( "input[name='commandText']" ).val();
+                       command += "\n";
+                       url = $form.attr( "action" );
+                       // Send the data using post
+                       var posting = $.post( url, command );
+                       // Put the results in a div
+                       posting.done(function( data ) {
+                               $( "#result" ).empty();
+                $.each(data.split('\n'), function(index) {
+                    $( "#result" ).append( this + '<br/>' );
+                });
+                       });
+               });
+       </script>
+
+       <h2> Upload File </h2>
+       <input type="file" id="files" name="files[]" onchange="upload();" />
+
+       <h3>Uploading file(s)</h3>
+       <output id="list"></output>
+    <div id="progress"></div>
+    <div id="uploadresult"></div>
+       <script>
+       function handleFileSelect(evt) {
+           var files = evt.target.files; // handleFileSelectist object
+
+           // files is a FileList of File objects. List some properties.
+           var output = [];
+           for (var i = 0, f; f = files[i]; i++) {
+               output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
+                       f.size, ' bytes, last modified: ',
+                       f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
+                       '</li>');
+           }
+           document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
+       }
+
+       document.getElementById('files').addEventListener('change', handleFileSelect, false);
+
+
+       function upload() {
+        // take the file from the input
+        var file = document.getElementById('files').files[0];
+        var reader = new FileReader();
+        reader.readAsBinaryString(file); // alternatively you can use readAsDataURL
+        reader.onloadend  = function(evt)
+        {
+            // create XHR instance
+            xhr = new XMLHttpRequest();
+
+            // send the file through POST
+            xhr.open("POST", 'upload', true);
+                       xhr.setRequestHeader('X-Filename', file.name);
+
+            // make sure we have the sendAsBinary method on all browsers
+            XMLHttpRequest.prototype.mySendAsBinary = function(text){
+                var data = new ArrayBuffer(text.length);
+                var ui8a = new Uint8Array(data, 0);
+                for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
+
+                if(typeof window.Blob == "function")
+                {
+                     var blob = new Blob([data]);
+                }else{
+                     var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
+                     bb.append(data);
+                     var blob = bb.getBlob();
+                }
+
+                this.send(blob);
+            }
+
+            // let's track upload progress
+            var eventSource = xhr.upload || xhr;
+            eventSource.addEventListener("progress", function(e) {
+                // get percentage of how much of the current file has been sent
+                var position = e.position || e.loaded;
+                var total = e.totalSize || e.total;
+                var percentage = Math.round((position/total)*100);
+
+                // here you should write your own code how you wish to proces this
+                $( "#progress" ).empty().append('uploaded ' + percentage + '%');
+            });
+
+            // state change observer - we need to know when and if the file was successfully uploaded
+            xhr.onreadystatechange = function()
+            {
+                if(xhr.readyState == 4)
+                {
+                    if(xhr.status == 200)
+                    {
+                        // process success
+                        $( "#uploadresult" ).empty().append( 'Uploaded Ok');
+                    }else{
+                        // process error
+                        $( "#uploadresult" ).empty().append( 'Uploaded Failed');
+                    }
+                }
+            };
+
+            // start sending
+            xhr.mySendAsBinary(evt.target.result);
+        };
+       }
+       </script>
+
+</body>
+</html>
diff --git a/src/libs/Network/uip/webserver/httpd-fsdata.h b/src/libs/Network/uip/webserver/httpd-fsdata.h
new file mode 100644 (file)
index 0000000..a2b00ab
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ * Copyright (c) 2001, Swedish Institute of Computer Science.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the Institute nor the names of its contributors\r
+ *    may be used to endorse or promote products derived from this software\r
+ *    without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ *\r
+ * This file is part of the lwIP TCP/IP stack.\r
+ *\r
+ * Author: Adam Dunkels <adam@sics.se>\r
+ *\r
+ * $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $\r
+ */\r
+#ifndef __HTTPD_FSDATA_H__\r
+#define __HTTPD_FSDATA_H__\r
+\r
+#undef HTTPD_FS_STATISTICS\r
+\r
+#include "uip.h"\r
+\r
+\r
+struct httpd_fsdata_file {\r
+  const struct httpd_fsdata_file *next;\r
+//  const char *name;\r
+//  const char *data;\r
+  const unsigned char *name;\r
+  const unsigned char *data;\r
+  const int len;\r
+#ifdef HTTPD_FS_STATISTICS\r
+#if HTTPD_FS_STATISTICS == 1\r
+  u16_t count;\r
+#endif /* HTTPD_FS_STATISTICS */\r
+#endif /* HTTPD_FS_STATISTICS */\r
+};\r
+\r
+struct httpd_fsdata_file_noconst {\r
+  struct httpd_fsdata_file *next;\r
+  char *name;\r
+  char *data;\r
+  int len;\r
+#ifdef HTTPD_FS_STATISTICS\r
+#if HTTPD_FS_STATISTICS == 1\r
+  u16_t count;\r
+#endif /* HTTPD_FS_STATISTICS */\r
+#endif /* HTTPD_FS_STATISTICS */\r
+};\r
+\r
+#endif /* __HTTPD_FSDATA_H__ */\r
diff --git a/src/libs/Network/uip/webserver/httpd-fsdata2.h b/src/libs/Network/uip/webserver/httpd-fsdata2.h
new file mode 100644 (file)
index 0000000..6f6af00
--- /dev/null
@@ -0,0 +1,8225 @@
+static const unsigned char data_index_html[] = {
+       /* /index.html */
+       0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
+       0x3c, 0x21, 0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65, 0x20, 
+       0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, 0x68, 0x65, 0x61, 
+       0x64, 0x3e, 0xa, 0x9, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 
+       0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x75, 
+       0x74, 0x66, 0x2d, 0x38, 0x22, 0x3e, 0xa, 0x9, 0x3c, 0x74, 
+       0x69, 0x74, 0x6c, 0x65, 0x3e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 
+       0x65, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x3c, 
+       0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x3c, 
+       0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 
+       0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 
+       0x6f, 0x64, 0x65, 0x2e, 0x6a, 0x71, 0x75, 0x65, 0x72, 0x79, 
+       0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x71, 0x75, 0x65, 0x72, 
+       0x79, 0x2d, 0x31, 0x2e, 0x39, 0x2e, 0x31, 0x2e, 0x6a, 0x73, 
+       0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 
+       0x3e, 0xa, 0x9, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 
+       0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x74, 0x65, 0x78, 0x74, 
+       0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 
+       0x74, 0x20, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 
+       0x3d, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 
+       0x74, 0x3e, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x63, 
+       0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x63, 0x5f, 
+       0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x5f, 0x72, 0x61, 0x64, 
+       0x69, 0x69, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x31, 0x2c, 0x20, 
+       0x34, 0x35, 0x2c, 0x20, 0x36, 0x39, 0x2c, 0x20, 0x39, 0x34, 
+       0x2c, 0x20, 0x31, 0x31, 0x35, 0x5d, 0x3b, 0xa, 0x20, 0x20, 
+       0x76, 0x61, 0x72, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 
+       0x20, 0x3d, 0x20, 0x5b, 0x31, 0x32, 0x34, 0x2c, 0x20, 0x31, 
+       0x32, 0x31, 0x5d, 0x3b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x72, 0x20, 0x3d, 0x20, 
+       0x37, 0x3b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x7a, 
+       0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x5f, 0x79, 0x64, 0x69, 
+       0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x3d, 0x20, 
+       0x5b, 0x37, 0x2c, 0x20, 0x33, 0x30, 0x2c, 0x20, 0x35, 0x35, 
+       0x2c, 0x20, 0x38, 0x33, 0x5d, 0x3b, 0xa, 0x20, 0x20, 0x76, 
+       0x61, 0x72, 0x20, 0x7a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 
+       0x20, 0x3d, 0x20, 0x5b, 0x33, 0x30, 0x2c, 0x20, 0x31, 0x31, 
+       0x38, 0x5d, 0x3b, 0xa, 0xa, 0x66, 0x75, 0x6e, 0x63, 0x74, 
+       0x69, 0x6f, 0x6e, 0x20, 0x72, 0x75, 0x6e, 0x43, 0x6f, 0x6d, 
+       0x6d, 0x61, 0x6e, 0x64, 0x28, 0x63, 0x6d, 0x64, 0x29, 0x20, 
+       0x7b, 0xa, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x47, 0x65, 0x74, 
+       0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 
+       0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x65, 0x6c, 
+       0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x6e, 0x20, 
+       0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3a, 0xa, 
+       0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x24, 0x66, 0x6f, 0x72, 
+       0x6d, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x20, 0x22, 0x23, 0x63, 
+       0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x46, 0x6f, 0x72, 0x6d, 
+       0x22, 0x20, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x63, 0x6d, 0x64, 
+       0x20, 0x2b, 0x3d, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x3b, 0xa, 
+       0x20, 0x20, 0x75, 0x72, 0x6c, 0x20, 0x3d, 0x20, 0x22, 0x2f, 
+       0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x69, 
+       0x6c, 0x65, 0x6e, 0x74, 0x22, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 
+       0x24, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x61, 0x74, 0x74, 0x72, 
+       0x28, 0x20, 0x22, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 
+       0x20, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x53, 
+       0x65, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 
+       0x74, 0x61, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x70, 
+       0x6f, 0x73, 0x74, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 
+       0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 
+       0x24, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x28, 0x20, 0x75, 0x72, 
+       0x6c, 0x2c, 0x20, 0x63, 0x6d, 0x64, 0x20, 0x29, 0x3b, 0xa, 
+       0x20, 0x20, 0x2f, 0x2f, 0x20, 0x50, 0x75, 0x74, 0x20, 0x74, 
+       0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 
+       0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x64, 0x69, 0x76, 0xa, 
+       0x20, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x69, 
+       0x6e, 0x67, 0x2e, 0x64, 0x6f, 0x6e, 0x65, 0x28, 0x66, 0x75, 
+       0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x20, 0x64, 0x61, 
+       0x74, 0x61, 0x20, 0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x2f, 
+       0x2f, 0x20, 0x20, 0x20, 0x24, 0x28, 0x20, 0x22, 0x23, 0x72, 
+       0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x20, 0x29, 0x2e, 0x65, 
+       0x6d, 0x70, 0x74, 0x79, 0x28, 0x29, 0x3b, 0xa, 0x20, 0x20, 
+       0x2f, 0x2f, 0x20, 0x20, 0x20, 0x24, 0x2e, 0x65, 0x61, 0x63, 
+       0x68, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x73, 0x70, 0x6c, 
+       0x69, 0x74, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x2c, 0x20, 
+       0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x69, 
+       0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 
+       0x2f, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x28, 0x20, 
+       0x22, 0x23, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x20, 
+       0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x20, 
+       0x74, 0x68, 0x69, 0x73, 0x20, 0x2b, 0x20, 0x27, 0x3c, 0x62, 
+       0x72, 0x2f, 0x3e, 0x27, 0x20, 0x29, 0x3b, 0xa, 0x20, 0x20, 
+       0x2f, 0x2f, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0xa, 0x20, 
+       0x20, 0x2f, 0x2f, 0x20, 0x7d, 0x29, 0x3b, 0xa, 0x7d, 0xa, 
+       0xa, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 
+       0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x63, 
+       0x65, 0x6e, 0x74, 0x72, 0x69, 0x63, 0x28, 0x72, 0x61, 0x64, 
+       0x69, 0x75, 0x73, 0x29, 0x7b, 0xa, 0x20, 0x20, 0x76, 0x61, 
+       0x72, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3d, 
+       0x20, 0x63, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 
+       0x63, 0x5f, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x5f, 0x72, 
+       0x61, 0x64, 0x69, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 
+       0x68, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x28, 
+       0x69, 0x3d, 0x30, 0x3b, 0x69, 0x3c, 0x3d, 0x6c, 0x65, 0x6e, 
+       0x67, 0x74, 0x68, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 
+       0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x3c, 0x20, 0x63, 0x6f, 
+       0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x63, 
+       0x69, 0x72, 0x63, 0x6c, 0x65, 0x5f, 0x72, 0x61, 0x64, 0x69, 
+       0x69, 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 
+       0x72, 0x6e, 0x28, 0x69, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x7d, 
+       0xa, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 
+       0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, 0xa, 0x7d, 
+       0xa, 0xa, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
+       0x20, 0x67, 0x65, 0x74, 0x51, 0x75, 0x61, 0x64, 0x72, 0x61, 
+       0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 
+       0x69, 0x63, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x6f, 0x73, 0x69, 
+       0x74, 0x69, 0x6f, 0x6e, 0x28, 0x78, 0x2c, 0x79, 0x29, 0x20, 
+       0x7b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 
+       0x6c, 0x5f, 0x78, 0x20, 0x3d, 0x20, 0x78, 0x20, 0x2d, 0x20, 
+       0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5b, 0x30, 0x5d, 0xa, 
+       0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x6c, 0x5f, 
+       0x79, 0x20, 0x3d, 0x20, 0x79, 0x20, 0x2d, 0x20, 0x63, 0x65, 
+       0x6e, 0x74, 0x65, 0x72, 0x5b, 0x31, 0x5d, 0xa, 0x20, 0x20, 
+       0x76, 0x61, 0x72, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 
+       0x20, 0x3d, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 
+       0x72, 0x74, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 
+       0x77, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, 
+       0x28, 0x72, 0x65, 0x6c, 0x5f, 0x78, 0x29, 0x2c, 0x32, 0x29, 
+       0x20, 0x2b, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 
+       0x77, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, 
+       0x28, 0x72, 0x65, 0x6c, 0x5f, 0x79, 0x29, 0x2c, 0x32, 0x29, 
+       0x29, 0xa, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 
+       0x6c, 0x5f, 0x78, 0x20, 0x3e, 0x20, 0x72, 0x65, 0x6c, 0x5f, 
+       0x79, 0x20, 0x26, 0x26, 0x20, 0x72, 0x65, 0x6c, 0x5f, 0x78, 
+       0x20, 0x3e, 0x20, 0x2d, 0x72, 0x65, 0x6c, 0x5f, 0x79, 0x29, 
+       0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x71, 0x75, 0x61, 
+       0x64, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x3b, 
+       0x20, 0x2f, 0x2f, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0xa, 
+       0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 
+       0x66, 0x20, 0x28, 0x72, 0x65, 0x6c, 0x5f, 0x78, 0x20, 0x3c, 
+       0x3d, 0x20, 0x72, 0x65, 0x6c, 0x5f, 0x79, 0x20, 0x26, 0x26, 
+       0x20, 0x72, 0x65, 0x6c, 0x5f, 0x78, 0x20, 0x3e, 0x20, 0x2d, 
+       0x72, 0x65, 0x6c, 0x5f, 0x79, 0x29, 0x20, 0x7b, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x71, 0x75, 0x61, 0x64, 0x72, 0x61, 0x6e, 
+       0x74, 0x20, 0x3d, 0x20, 0x33, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 
+       0x44, 0x6f, 0x77, 0x6e, 0xa, 0x20, 0x20, 0x7d, 0x20, 0x65, 
+       0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 
+       0x6c, 0x5f, 0x78, 0x20, 0x3e, 0x20, 0x72, 0x65, 0x6c, 0x5f, 
+       0x79, 0x20, 0x26, 0x26, 0x20, 0x72, 0x65, 0x6c, 0x5f, 0x78, 
+       0x20, 0x3c, 0x20, 0x2d, 0x72, 0x65, 0x6c, 0x5f, 0x79, 0x29, 
+       0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x71, 0x75, 0x61, 
+       0x64, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x3b, 
+       0x20, 0x2f, 0x2f, 0x20, 0x55, 0x70, 0xa, 0x20, 0x20, 0x7d, 
+       0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x71, 0x75, 0x61, 0x64, 0x72, 0x61, 0x6e, 0x74, 
+       0x20, 0x3d, 0x20, 0x32, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x4c, 
+       0x65, 0x66, 0x74, 0xa, 0x20, 0x20, 0x7d, 0xa, 0x20, 0x20, 
+       0x76, 0x61, 0x72, 0x20, 0x69, 0x64, 0x78, 0x20, 0x3d, 0x20, 
+       0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x63, 
+       0x65, 0x6e, 0x74, 0x72, 0x69, 0x63, 0x28, 0x72, 0x61, 0x64, 
+       0x69, 0x75, 0x73, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x72, 0x65, 
+       0x74, 0x75, 0x72, 0x6e, 0x20, 0x5b, 0x71, 0x75, 0x61, 0x64, 
+       0x72, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x69, 0x64, 0x78, 0x5d, 
+       0xa, 0x7d, 0xa, 0xa, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 
+       0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x58, 0x59, 
+       0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x7b, 0xa, 0x20, 
+       0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x73, 0x5f, 0x78, 
+       0x20, 0x3d, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 
+       0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x3f, 0x28, 0x65, 0x76, 
+       0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 
+       0x58, 0x29, 0x3a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 
+       0x61, 0x67, 0x65, 0x58, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 
+       0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 
+       0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 
+       0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x78, 0x79, 
+       0x22, 0x29, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x4c, 
+       0x65, 0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x70, 0x6f, 0x73, 0x5f, 0x79, 0x20, 0x3d, 0x20, 0x65, 
+       0x76, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 
+       0x74, 0x59, 0x3f, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 
+       0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x29, 0x3a, 0x65, 
+       0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x59, 
+       0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 
+       0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 
+       0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x63, 0x6f, 0x6e, 0x74, 
+       0x72, 0x6f, 0x6c, 0x5f, 0x78, 0x79, 0x22, 0x29, 0x2e, 0x6f, 
+       0x66, 0x66, 0x73, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x3b, 0xa, 
+       0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 
+       0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x51, 0x75, 0x61, 
+       0x64, 0x72, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x63, 0x65, 
+       0x6e, 0x74, 0x72, 0x69, 0x63, 0x46, 0x72, 0x6f, 0x6d, 0x50, 
+       0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x70, 0x6f, 
+       0x73, 0x5f, 0x78, 0x2c, 0x70, 0x6f, 0x73, 0x5f, 0x79, 0x29, 
+       0x3b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x71, 0x75, 
+       0x61, 0x64, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x63, 
+       0x6f, 0x64, 0x65, 0x73, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x63, 
+       0x6f, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x63, 0x20, 
+       0x3d, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5b, 0x31, 0x5d, 
+       0x3b, 0xa, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x63, 0x6f, 
+       0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x63, 0x20, 0x3c, 
+       0x20, 0x35, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x6d, 
+       0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x75, 
+       0x74, 0x74, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 
+       0x65, 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x78, 0x64, 0x69, 0x72, 0x20, 0x3d, 0x20, 0x5b, 0x31, 
+       0x2c, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2c, 0x20, 0x30, 
+       0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x5d, 0x5b, 0x71, 0x75, 
+       0x61, 0x64, 0x72, 0x61, 0x6e, 0x74, 0x5d, 0x3b, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x79, 0x64, 0x69, 
+       0x72, 0x20, 0x3d, 0x20, 0x5b, 0x30, 0x2c, 0x20, 0x31, 0x2c, 
+       0x20, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2c, 0x20, 0x30, 0x2c, 
+       0x20, 0x30, 0x5d, 0x5b, 0x71, 0x75, 0x61, 0x64, 0x72, 0x61, 
+       0x6e, 0x74, 0x5d, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x76, 
+       0x61, 0x72, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x74, 0x75, 
+       0x64, 0x65, 0x20, 0x3d, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 
+       0x70, 0x6f, 0x77, 0x28, 0x31, 0x30, 0x2c, 0x20, 0x63, 0x6f, 
+       0x6e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x63, 0x20, 0x2d, 
+       0x20, 0x32, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x69, 
+       0x66, 0x20, 0x28, 0x78, 0x64, 0x69, 0x72, 0x20, 0x21, 0x3d, 
+       0x20, 0x30, 0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 
+       0x3d, 0x20, 0x22, 0x47, 0x31, 0x20, 0x58, 0x22, 0x20, 0x2b, 
+       0x20, 0x28, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x74, 0x75, 0x64, 
+       0x65, 0x20, 0x2a, 0x20, 0x78, 0x64, 0x69, 0x72, 0x29, 0x20, 
+       0x2b, 0x20, 0x22, 0x20, 0x46, 0x22, 0x20, 0x2b, 0x20, 0x64, 
+       0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 
+       0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 
+       0x49, 0x64, 0x28, 0x22, 0x78, 0x79, 0x5f, 0x76, 0x65, 0x6c, 
+       0x6f, 0x63, 0x69, 0x74, 0x79, 0x22, 0x29, 0x2e, 0x76, 0x61, 
+       0x6c, 0x75, 0x65, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x7d, 
+       0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 
+       0x64, 0x20, 0x3d, 0x20, 0x22, 0x47, 0x31, 0x20, 0x59, 0x22, 
+       0x20, 0x2b, 0x20, 0x28, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x74, 
+       0x75, 0x64, 0x65, 0x20, 0x2a, 0x20, 0x79, 0x64, 0x69, 0x72, 
+       0x29, 0x20, 0x2b, 0x20, 0x22, 0x20, 0x46, 0x22, 0x20, 0x2b, 
+       0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 
+       0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 
+       0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x78, 0x79, 0x5f, 0x76, 
+       0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x22, 0x29, 0x2e, 
+       0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0xa, 0x20, 0x20, 0x20, 
+       0x20, 0x7d, 0xa, 0x20, 0x20, 0x20, 0x20, 0x72, 0x75, 0x6e, 
+       0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 0x22, 0x47, 
+       0x39, 0x31, 0x20, 0x22, 0x20, 0x2b, 0x20, 0x63, 0x6f, 0x6d, 
+       0x6d, 0x61, 0x6e, 0x64, 0x20, 0x2b, 0x20, 0x22, 0x20, 0x47, 
+       0x39, 0x30, 0x22, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x7d, 0x20, 
+       0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 
+       0x68, 0x6f, 0x6d, 0x65, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6f, 
+       0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0xa, 
+       0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x70, 0x6f, 
+       0x73, 0x5f, 0x78, 0x20, 0x3c, 0x20, 0x34, 0x39, 0x20, 0x26, 
+       0x26, 0x20, 0x70, 0x6f, 0x73, 0x5f, 0x79, 0x20, 0x3c, 0x20, 
+       0x34, 0x39, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x68, 
+       0x6f, 0x6d, 0x65, 0x20, 0x78, 0x20, 0x62, 0x75, 0x74, 0x74, 
+       0x6f, 0x6e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 
+       0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x22, 
+       0x47, 0x32, 0x38, 0x20, 0x58, 0x30, 0x22, 0x3b, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 
+       0x69, 0x66, 0x20, 0x28, 0x70, 0x6f, 0x73, 0x5f, 0x78, 0x20, 
+       0x3e, 0x20, 0x32, 0x30, 0x30, 0x20, 0x26, 0x26, 0x20, 0x70, 
+       0x6f, 0x73, 0x5f, 0x79, 0x20, 0x3c, 0x20, 0x34, 0x39, 0x29, 
+       0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x20, 
+       0x79, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 
+       0x6e, 0x64, 0x20, 0x3d, 0x20, 0x22, 0x47, 0x32, 0x38, 0x20, 
+       0x59, 0x30, 0x22, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x7d, 
+       0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 
+       0x70, 0x6f, 0x73, 0x5f, 0x78, 0x20, 0x3c, 0x20, 0x34, 0x39, 
+       0x20, 0x26, 0x26, 0x20, 0x70, 0x6f, 0x73, 0x5f, 0x79, 0x20, 
+       0x3e, 0x20, 0x32, 0x30, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 
+       0x2f, 0x20, 0x68, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x6c, 0x6c, 
+       0x20, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 
+       0x64, 0x20, 0x3d, 0x20, 0x22, 0x47, 0x32, 0x38, 0x22, 0x3b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 
+       0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x6f, 0x6d, 
+       0x65, 0x20, 0x7a, 0x20, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6d, 
+       0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x22, 0x47, 0x32, 
+       0x38, 0x20, 0x5a, 0x30, 0x22, 0x3b, 0xa, 0x20, 0x20, 0x20, 
+       0x20, 0x7d, 0xa, 0x20, 0x20, 0x20, 0x20, 0x72, 0x75, 0x6e, 
+       0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 0x63, 0x6f, 
+       0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x29, 0x3b, 0xa, 0x20, 0x20, 
+       0x7d, 0xa, 0x7d, 0xa, 0xa, 0x66, 0x75, 0x6e, 0x63, 0x74, 
+       0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 
+       0x52, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x79, 0x64, 0x69, 0x73, 
+       0x74, 0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3d, 0x20, 
+       0x7a, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x5f, 0x79, 0x64, 
+       0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x6c, 
+       0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0xa, 0x20, 0x20, 0x66, 
+       0x6f, 0x72, 0x20, 0x28, 0x69, 0x3d, 0x30, 0x3b, 0x69, 0x3c, 
+       0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, 0x2b, 0x2b, 
+       0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 
+       0x20, 0x28, 0x79, 0x64, 0x69, 0x73, 0x74, 0x20, 0x3c, 0x20, 
+       0x7a, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x5f, 0x79, 0x64, 
+       0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x5b, 0x69, 
+       0x5d, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 
+       0x69, 0x3b, 0xa, 0x20, 0x20, 0x7d, 0xa, 0x7d, 0xa, 0xa, 
+       0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 
+       0x6c, 0x69, 0x63, 0x6b, 0x5a, 0x28, 0x65, 0x76, 0x65, 0x6e, 
+       0x74, 0x29, 0x7b, 0xa, 0x20, 0x20, 0x2f, 0x2f, 0x76, 0x61, 
+       0x72, 0x20, 0x70, 0x6f, 0x73, 0x5f, 0x78, 0x20, 0x3d, 0x20, 
+       0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x66, 0x66, 0x73, 
+       0x65, 0x74, 0x58, 0x3f, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 
+       0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x29, 0x3a, 
+       0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x61, 0x67, 0x65, 
+       0x58, 0x2d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 
+       0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 
+       0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x63, 0x6f, 0x6e, 
+       0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x7a, 0x22, 0x29, 0x2e, 0x6f, 
+       0x66, 0x66, 0x73, 0x65, 0x74, 0x4c, 0x65, 0x66, 0x74, 0x3b, 
+       0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x73, 
+       0x5f, 0x79, 0x20, 0x3d, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 
+       0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x3f, 0x28, 
+       0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x66, 0x66, 0x73, 
+       0x65, 0x74, 0x59, 0x29, 0x3a, 0x65, 0x76, 0x65, 0x6e, 0x74, 
+       0x2e, 0x70, 0x61, 0x67, 0x65, 0x59, 0x2d, 0x64, 0x6f, 0x63, 
+       0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 
+       0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 
+       0x28, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 
+       0x7a, 0x22, 0x29, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 
+       0x54, 0x6f, 0x70, 0x3b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x79, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x20, 0x3d, 0x20, 
+       0x7a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x5b, 0x31, 0x5d, 
+       0x20, 0x2d, 0x20, 0x70, 0x6f, 0x73, 0x5f, 0x79, 0x3b, 0xa, 
+       0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x72, 0x61, 0x6e, 0x67, 
+       0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 
+       0x52, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x4d, 0x61, 0x74, 0x68, 
+       0x2e, 0x61, 0x62, 0x73, 0x28, 0x79, 0x64, 0x65, 0x6c, 0x74, 
+       0x61, 0x29, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
+       0x20, 0x3d, 0x20, 0x28, 0x79, 0x64, 0x65, 0x6c, 0x74, 0x61, 
+       0x20, 0x3e, 0x20, 0x30, 0x29, 0x3f, 0x31, 0x3a, 0x2d, 0x31, 
+       0x3b, 0xa, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x72, 0x61, 
+       0x6e, 0x67, 0x65, 0x20, 0x3c, 0x20, 0x34, 0x29, 0x20, 0x7b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x72, 0x75, 0x6e, 0x43, 0x6f, 
+       0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 0x22, 0x47, 0x39, 0x31, 
+       0x20, 0x47, 0x31, 0x20, 0x5a, 0x22, 0x20, 0x2b, 0x20, 0x28, 
+       0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x31, 
+       0x30, 0x2c, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x32, 0x29, 
+       0x20, 0x2a, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+       0x6f, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x22, 0x20, 0x46, 0x22, 
+       0x20, 0x2b, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 
+       0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 
+       0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x7a, 0x5f, 
+       0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x22, 0x29, 
+       0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x2b, 0x20, 0x22, 
+       0x20, 0x47, 0x39, 0x30, 0x22, 0x29, 0x3b, 0xa, 0x20, 0x20, 
+       0x7d, 0xa, 0x7d, 0xa, 0xa, 0x66, 0x75, 0x6e, 0x63, 0x74, 
+       0x69, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x74, 0x72, 0x75, 0x64, 
+       0x65, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2c, 0x61, 0x2c, 
+       0x62, 0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3d, 0x20, 
+       0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 
+       0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 
+       0x79, 0x49, 0x64, 0x28, 0x22, 0x65, 0x78, 0x74, 0x72, 0x75, 
+       0x64, 0x65, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 
+       0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0xa, 0x20, 
+       0x20, 0x76, 0x61, 0x72, 0x20, 0x76, 0x65, 0x6c, 0x6f, 0x63, 
+       0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 
+       0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 
+       0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 
+       0x22, 0x65, 0x78, 0x74, 0x72, 0x75, 0x64, 0x65, 0x5f, 0x76, 
+       0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x22, 0x29, 0x2e, 
+       0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0xa, 0x20, 0x20, 0x76, 
+       0x61, 0x72, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+       0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 
+       0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 
+       0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x69, 0x64, 0x3d, 0x3d, 
+       0x27, 0x65, 0x78, 0x74, 0x72, 0x75, 0x64, 0x65, 0x27, 0x29, 
+       0x3f, 0x31, 0x3a, 0x2d, 0x31, 0x3b, 0xa, 0x20, 0x20, 0x72, 
+       0x75, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 
+       0x22, 0x47, 0x39, 0x31, 0x20, 0x47, 0x31, 0x20, 0x45, 0x22, 
+       0x20, 0x2b, 0x20, 0x28, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 
+       0x20, 0x2a, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+       0x6f, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x22, 0x20, 0x46, 0x22, 
+       0x20, 0x2b, 0x20, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 
+       0x79, 0x20, 0x2b, 0x20, 0x22, 0x20, 0x47, 0x39, 0x30, 0x22, 
+       0x29, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x66, 0x75, 0x6e, 0x63, 
+       0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f, 0x74, 0x6f, 0x72, 
+       0x73, 0x4f, 0x66, 0x66, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 
+       0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x72, 0x75, 0x6e, 0x43, 
+       0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 0x22, 0x4d, 0x31, 
+       0x38, 0x22, 0x29, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x66, 0x75, 
+       0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x65, 0x61, 
+       0x74, 0x53, 0x65, 0x74, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 
+       0x29, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 
+       0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x28, 0x65, 0x76, 
+       0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 
+       0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x69, 0x64, 
+       0x3d, 0x3d, 0x27, 0x68, 0x65, 0x61, 0x74, 0x5f, 0x73, 0x65, 
+       0x74, 0x27, 0x29, 0x3f, 0x31, 0x30, 0x34, 0x3a, 0x31, 0x34, 
+       0x30, 0x3b, 0xa, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 
+       0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 
+       0x20, 0x3d, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 
+       0x31, 0x30, 0x34, 0x29, 0x3f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 
+       0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 
+       0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 
+       0x68, 0x65, 0x61, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 
+       0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x64, 
+       0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 
+       0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 
+       0x49, 0x64, 0x28, 0x22, 0x62, 0x65, 0x64, 0x5f, 0x76, 0x61, 
+       0x6c, 0x75, 0x65, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 
+       0x65, 0x3b, 0xa, 0x20, 0x20, 0x72, 0x75, 0x6e, 0x43, 0x6f, 
+       0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 0x22, 0x4d, 0x22, 0x20, 
+       0x2b, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x2b, 0x20, 0x22, 
+       0x20, 0x53, 0x22, 0x20, 0x2b, 0x20, 0x74, 0x65, 0x6d, 0x70, 
+       0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x29, 0x3b, 0xa, 
+       0x7d, 0xa, 0xa, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 
+       0x6e, 0x20, 0x68, 0x65, 0x61, 0x74, 0x4f, 0x66, 0x66, 0x28, 
+       0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x7b, 0xa, 0x20, 
+       0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 
+       0x3d, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x63, 
+       0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x72, 0x67, 
+       0x65, 0x74, 0x2e, 0x69, 0x64, 0x3d, 0x3d, 0x27, 0x68, 0x65, 
+       0x61, 0x74, 0x5f, 0x6f, 0x66, 0x66, 0x27, 0x29, 0x3f, 0x31, 
+       0x30, 0x34, 0x3a, 0x31, 0x34, 0x30, 0x3b, 0xa, 0x20, 0x20, 
+       0x72, 0x75, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 
+       0x28, 0x22, 0x4d, 0x22, 0x20, 0x2b, 0x20, 0x74, 0x79, 0x70, 
+       0x65, 0x20, 0x2b, 0x20, 0x22, 0x20, 0x53, 0x30, 0x22, 0x29, 
+       0x3b, 0xa, 0x7d, 0xa, 0xa, 0x3c, 0x2f, 0x73, 0x63, 0x72, 
+       0x69, 0x70, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x65, 0x61, 
+       0x64, 0x3e, 0xa, 0xa, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x57, 
+       0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x20, 
+       0x53, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x69, 0x65, 0x20, 0x77, 
+       0x65, 0x62, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 
+       0x63, 0x65, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0xa, 0x3c, 
+       0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x3d, 
+       0x6d, 0x6f, 0x74, 0x6f, 0x72, 0x73, 0x5f, 0x6f, 0x66, 0x66, 
+       0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x6d, 
+       0x6f, 0x74, 0x6f, 0x72, 0x73, 0x4f, 0x66, 0x66, 0x28, 0x65, 
+       0x76, 0x65, 0x6e, 0x74, 0x29, 0x3e, 0x4d, 0x6f, 0x74, 0x6f, 
+       0x72, 0x73, 0x20, 0x4f, 0x66, 0x66, 0x3c, 0x2f, 0x62, 0x75, 
+       0x74, 0x74, 0x6f, 0x6e, 0x3e, 0xa, 0x58, 0x59, 0x3a, 0x3c, 
+       0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 
+       0x3d, 0x74, 0x65, 0x78, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x78, 
+       0x79, 0x5f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 
+       0x20, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x34, 0x20, 0x76, 0x61, 
+       0x6c, 0x75, 0x65, 0x3d, 0x33, 0x30, 0x30, 0x30, 0x20, 0x73, 
+       0x74, 0x79, 0x6c, 0x65, 0x3d, 0x77, 0x69, 0x64, 0x74, 0x68, 
+       0x3a, 0x35, 0x30, 0x70, 0x78, 0x3e, 0x6d, 0x6d, 0x2f, 0x6d, 
+       0x69, 0x6e, 0xa, 0x5a, 0x3a, 0x3c, 0x69, 0x6e, 0x70, 0x75, 
+       0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x74, 0x65, 0x78, 
+       0x74, 0x20, 0x69, 0x64, 0x3d, 0x7a, 0x5f, 0x76, 0x65, 0x6c, 
+       0x6f, 0x63, 0x69, 0x74, 0x79, 0x20, 0x73, 0x69, 0x7a, 0x65, 
+       0x3d, 0x33, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x32, 
+       0x30, 0x30, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x77, 
+       0x69, 0x64, 0x74, 0x68, 0x3a, 0x34, 0x30, 0x70, 0x78, 0x3e, 
+       0xa, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x3c, 0x69, 0x6d, 0x67, 
+       0x20, 0x69, 0x64, 0x3d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 
+       0x6c, 0x5f, 0x78, 0x79, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x69, 
+       0x6d, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 
+       0x5f, 0x78, 0x79, 0x2e, 0x70, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 
+       0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x63, 0x6c, 0x69, 0x63, 
+       0x6b, 0x58, 0x59, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 
+       0x3e, 0xa, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x69, 0x64, 0x3d, 
+       0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x7a, 0x20, 
+       0x73, 0x72, 0x63, 0x3d, 0x69, 0x6d, 0x67, 0x2f, 0x63, 0x6f, 
+       0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x7a, 0x2e, 0x70, 0x6e, 
+       0x67, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 
+       0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5a, 0x28, 0x65, 0x76, 0x65, 
+       0x6e, 0x74, 0x29, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0xa, 
+       0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x3c, 0x74, 0x72, 
+       0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 
+       0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0xa, 0x3c, 
+       0x74, 0x64, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x74, 
+       0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 
+       0x72, 0x69, 0x67, 0x68, 0x74, 0x3e, 0x48, 0x65, 0x61, 0x74, 
+       0x3a, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 
+       0x3e, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x69, 
+       0x64, 0x3d, 0x68, 0x65, 0x61, 0x74, 0x5f, 0x6f, 0x66, 0x66, 
+       0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x68, 
+       0x65, 0x61, 0x74, 0x4f, 0x66, 0x66, 0x28, 0x65, 0x76, 0x65, 
+       0x6e, 0x74, 0x29, 0x3e, 0x4f, 0x66, 0x66, 0x3c, 0x2f, 0x62, 
+       0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 
+       0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6e, 0x70, 
+       0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x74, 0x65, 
+       0x78, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x68, 0x65, 0x61, 0x74, 
+       0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x73, 0x69, 0x7a, 
+       0x65, 0x3d, 0x33, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 
+       0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x34, 0x30, 0x70, 0x78, 
+       0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x30, 0x3e, 0x3c, 
+       0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 
+       0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x3d, 
+       0x68, 0x65, 0x61, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x20, 0x6f, 
+       0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x68, 0x65, 0x61, 
+       0x74, 0x53, 0x65, 0x74, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 
+       0x29, 0x3e, 0x53, 0x65, 0x74, 0x3c, 0x2f, 0x62, 0x75, 0x74, 
+       0x74, 0x6f, 0x6e, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 
+       0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 
+       0xa, 0x3c, 0x74, 0x64, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 
+       0x3d, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 
+       0x6e, 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3e, 0x42, 0x65, 
+       0x64, 0x3a, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 
+       0x64, 0x3e, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 
+       0x69, 0x64, 0x3d, 0x62, 0x65, 0x64, 0x5f, 0x6f, 0x66, 0x66, 
+       0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x68, 
+       0x65, 0x61, 0x74, 0x4f, 0x66, 0x66, 0x28, 0x65, 0x76, 0x65, 
+       0x6e, 0x74, 0x29, 0x3e, 0x4f, 0x66, 0x66, 0x3c, 0x2f, 0x62, 
+       0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 
+       0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6e, 0x70, 
+       0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x74, 0x65, 
+       0x78, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x62, 0x65, 0x64, 0x5f, 
+       0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, 
+       0x3d, 0x33, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x77, 
+       0x69, 0x64, 0x74, 0x68, 0x3a, 0x34, 0x30, 0x70, 0x78, 0x20, 
+       0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x30, 0x3e, 0x3c, 0x2f, 
+       0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x62, 
+       0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x3d, 0x62, 
+       0x65, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x63, 
+       0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x68, 0x65, 0x61, 0x74, 0x53, 
+       0x65, 0x74, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x3e, 
+       0x53, 0x65, 0x74, 0x3c, 0x2f, 0x62, 0x75, 0x74, 0x74, 0x6f, 
+       0x6e, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x2f, 
+       0x74, 0x72, 0x3e, 0xa, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 
+       0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 
+       0x64, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x74, 
+       0x6f, 0x70, 0x3e, 0xa, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 
+       0x6e, 0x20, 0x69, 0x64, 0x3d, 0x67, 0x65, 0x74, 0x5f, 0x74, 
+       0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 
+       0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x72, 
+       0x75, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 
+       0x22, 0x4d, 0x31, 0x30, 0x35, 0x22, 0x29, 0x3e, 0x47, 0x65, 
+       0x74, 0x20, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 
+       0x75, 0x72, 0x65, 0x3c, 0x2f, 0x62, 0x75, 0x74, 0x74, 0x6f, 
+       0x6e, 0x3e, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 
+       0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 
+       0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x75, 
+       0x74, 0x74, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x3d, 0x65, 0x78, 
+       0x74, 0x72, 0x75, 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 
+       0x69, 0x63, 0x6b, 0x3d, 0x65, 0x78, 0x74, 0x72, 0x75, 0x64, 
+       0x65, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x3e, 0x45, 
+       0x78, 0x74, 0x72, 0x75, 0x64, 0x65, 0x3c, 0x2f, 0x62, 0x75, 
+       0x74, 0x74, 0x6f, 0x6e, 0x3e, 0xa, 0x3c, 0x62, 0x75, 0x74, 
+       0x74, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x3d, 0x72, 0x65, 0x76, 
+       0x65, 0x72, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 
+       0x63, 0x6b, 0x3d, 0x65, 0x78, 0x74, 0x72, 0x75, 0x64, 0x65, 
+       0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x3e, 0x52, 0x65, 
+       0x76, 0x65, 0x72, 0x73, 0x65, 0x3c, 0x2f, 0x62, 0x75, 0x74, 
+       0x74, 0x6f, 0x6e, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x3c, 
+       0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 
+       0x3d, 0x74, 0x65, 0x78, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x65, 
+       0x78, 0x74, 0x72, 0x75, 0x64, 0x65, 0x5f, 0x6c, 0x65, 0x6e, 
+       0x67, 0x74, 0x68, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 
+       0x35, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x33, 0x20, 0x73, 
+       0x74, 0x79, 0x6c, 0x65, 0x3d, 0x77, 0x69, 0x64, 0x74, 0x68, 
+       0x3a, 0x33, 0x35, 0x70, 0x78, 0x3e, 0xa, 0x6d, 0x6d, 0x20, 
+       0x40, 0xa, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 
+       0x79, 0x70, 0x65, 0x3d, 0x74, 0x65, 0x78, 0x74, 0x20, 0x69, 
+       0x64, 0x3d, 0x65, 0x78, 0x74, 0x72, 0x75, 0x64, 0x65, 0x5f, 
+       0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x74, 0x79, 0x20, 0x76, 
+       0x61, 0x6c, 0x75, 0x65, 0x3d, 0x31, 0x30, 0x30, 0x20, 0x73, 
+       0x69, 0x7a, 0x65, 0x3d, 0x33, 0x20, 0x73, 0x74, 0x79, 0x6c, 
+       0x65, 0x3d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x34, 0x30, 
+       0x70, 0x78, 0x3e, 0xa, 0x6d, 0x6d, 0x2f, 0x6d, 0x69, 0x6e, 
+       0xa, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x32, 0x3e, 
+       0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x3c, 0x2f, 
+       0x68, 0x32, 0x3e, 0xa, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 
+       0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x2f, 
+       0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0x20, 0x69, 
+       0x64, 0x3d, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 
+       0x46, 0x6f, 0x72, 0x6d, 0x22, 0x3e, 0xa, 0x9, 0x9, 0x3c, 
+       0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 
+       0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x6e, 0x61, 
+       0x6d, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 
+       0x64, 0x54, 0x65, 0x78, 0x74, 0x22, 0x20, 0x70, 0x6c, 0x61, 
+       0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 
+       0x53, 0x65, 0x6e, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 
+       0x6e, 0x64, 0x2e, 0x2e, 0x2e, 0x22, 0x3e, 0xa, 0x9, 0x9, 
+       0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 
+       0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 
+       0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x53, 0x65, 
+       0x6e, 0x64, 0x22, 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 
+       0x72, 0x6d, 0x3e, 0xa, 0x9, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 
+       0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 
+       0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 
+       0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x6c, 0x6c, 
+       0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 
+       0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x20, 
+       0x74, 0x68, 0x69, 0x73, 0x20, 0x64, 0x69, 0x76, 0x20, 0x2d, 
+       0x2d, 0x3e, 0xa, 0x9, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 
+       0x64, 0x3d, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 
+       0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0x9, 0x3c, 
+       0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0xa, 0x9, 0x9, 
+       0x2f, 0x2f, 0x20, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x20, 
+       0x61, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x20, 0x68, 
+       0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 
+       0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0xa, 0x9, 
+       0x9, 0x24, 0x28, 0x20, 0x22, 0x23, 0x63, 0x6f, 0x6d, 0x6d, 
+       0x61, 0x6e, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x22, 0x20, 0x29, 
+       0x2e, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x28, 0x66, 0x75, 
+       0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x20, 0x65, 0x76, 
+       0x65, 0x6e, 0x74, 0x20, 0x29, 0x20, 0x7b, 0xa, 0x9, 0x9, 
+       0x9, 0x2f, 0x2f, 0x20, 0x53, 0x74, 0x6f, 0x70, 0x20, 0x66, 
+       0x6f, 0x72, 0x6d, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x73, 
+       0x75, 0x62, 0x6d, 0x69, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 
+       0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x6c, 0x79, 0xa, 0x9, 
+       0x9, 0x9, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 
+       0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 
+       0x6c, 0x74, 0x28, 0x29, 0x3b, 0xa, 0x9, 0x9, 0x9, 0x2f, 
+       0x2f, 0x20, 0x47, 0x65, 0x74, 0x20, 0x73, 0x6f, 0x6d, 0x65, 
+       0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x66, 0x72, 
+       0x6f, 0x6d, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 
+       0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 
+       0x61, 0x67, 0x65, 0x3a, 0xa, 0x9, 0x9, 0x9, 0x76, 0x61, 
+       0x72, 0x20, 0x24, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x3d, 0x20, 
+       0x24, 0x28, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x29, 0x3b, 
+       0xa, 0x9, 0x9, 0x9, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 
+       0x64, 0x20, 0x3d, 0x20, 0x24, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 
+       0x66, 0x69, 0x6e, 0x64, 0x28, 0x20, 0x22, 0x69, 0x6e, 0x70, 
+       0x75, 0x74, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x27, 0x63, 
+       0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x78, 0x74, 
+       0x27, 0x5d, 0x22, 0x20, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x28, 
+       0x29, 0x3b, 0xa, 0x9, 0x9, 0x9, 0x63, 0x6f, 0x6d, 0x6d, 
+       0x61, 0x6e, 0x64, 0x20, 0x2b, 0x3d, 0x20, 0x22, 0x5c, 0x6e, 
+       0x22, 0x3b, 0xa, 0x9, 0x9, 0x9, 0x75, 0x72, 0x6c, 0x20, 
+       0x3d, 0x20, 0x24, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x61, 0x74, 
+       0x74, 0x72, 0x28, 0x20, 0x22, 0x61, 0x63, 0x74, 0x69, 0x6f, 
+       0x6e, 0x22, 0x20, 0x29, 0x3b, 0xa, 0x9, 0x9, 0x9, 0x2f, 
+       0x2f, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 
+       0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x75, 0x73, 0x69, 0x6e, 
+       0x67, 0x20, 0x70, 0x6f, 0x73, 0x74, 0xa, 0x9, 0x9, 0x9, 
+       0x76, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 
+       0x67, 0x20, 0x3d, 0x20, 0x24, 0x2e, 0x70, 0x6f, 0x73, 0x74, 
+       0x28, 0x20, 0x75, 0x72, 0x6c, 0x2c, 0x20, 0x63, 0x6f, 0x6d, 
+       0x6d, 0x61, 0x6e, 0x64, 0x20, 0x29, 0x3b, 0xa, 0x9, 0x9, 
+       0x9, 0x2f, 0x2f, 0x20, 0x50, 0x75, 0x74, 0x20, 0x74, 0x68, 
+       0x65, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 
+       0x69, 0x6e, 0x20, 0x61, 0x20, 0x64, 0x69, 0x76, 0xa, 0x9, 
+       0x9, 0x9, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 
+       0x64, 0x6f, 0x6e, 0x65, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 
+       0x69, 0x6f, 0x6e, 0x28, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 
+       0x29, 0x20, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x9, 0x24, 0x28, 
+       0x20, 0x22, 0x23, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 
+       0x20, 0x29, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x29, 
+       0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x2e, 
+       0x65, 0x61, 0x63, 0x68, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 
+       0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x27, 0x5c, 0x6e, 0x27, 
+       0x29, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 
+       0x6e, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x7b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x24, 0x28, 0x20, 0x22, 0x23, 0x72, 0x65, 0x73, 0x75, 
+       0x6c, 0x74, 0x22, 0x20, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 
+       0x6e, 0x64, 0x28, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x2b, 
+       0x20, 0x27, 0x3c, 0x62, 0x72, 0x2f, 0x3e, 0x27, 0x20, 0x29, 
+       0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 
+       0x3b, 0xa, 0x9, 0x9, 0x9, 0x7d, 0x29, 0x3b, 0xa, 0x9, 
+       0x9, 0x7d, 0x29, 0x3b, 0xa, 0x9, 0x3c, 0x2f, 0x73, 0x63, 
+       0x72, 0x69, 0x70, 0x74, 0x3e, 0xa, 0xa, 0x9, 0x3c, 0x68, 
+       0x32, 0x3e, 0x20, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x20, 
+       0x46, 0x69, 0x6c, 0x65, 0x20, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 
+       0xa, 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 
+       0x79, 0x70, 0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x22, 
+       0x20, 0x69, 0x64, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x73, 
+       0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x66, 0x69, 
+       0x6c, 0x65, 0x73, 0x5b, 0x5d, 0x22, 0x20, 0x6f, 0x6e, 0x63, 
+       0x68, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x22, 0x75, 0x70, 0x6c, 
+       0x6f, 0x61, 0x64, 0x28, 0x29, 0x3b, 0x22, 0x20, 0x2f, 0x3e, 
+       0xa, 0xa, 0x9, 0x3c, 0x68, 0x33, 0x3e, 0x55, 0x70, 0x6c, 
+       0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x69, 0x6c, 
+       0x65, 0x28, 0x73, 0x29, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 
+       0x9, 0x3c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x69, 
+       0x64, 0x3d, 0x22, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x3e, 0x3c, 
+       0x2f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3e, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 
+       0x3d, 0x22, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 
+       0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 
+       0x3d, 0x22, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x72, 0x65, 
+       0x73, 0x75, 0x6c, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 
+       0x76, 0x3e, 0xa, 0x9, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 
+       0x74, 0x3e, 0xa, 0x9, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 
+       0x6f, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x46, 
+       0x69, 0x6c, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 
+       0x65, 0x76, 0x74, 0x29, 0x20, 0x7b, 0xa, 0x9, 0x20, 0x20, 
+       0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x66, 0x69, 0x6c, 0x65, 
+       0x73, 0x20, 0x3d, 0x20, 0x65, 0x76, 0x74, 0x2e, 0x74, 0x61, 
+       0x72, 0x67, 0x65, 0x74, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 
+       0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 
+       0x65, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 
+       0x74, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+       0x74, 0xa, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 
+       0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 
+       0x61, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 
+       0x20, 0x6f, 0x66, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6f, 
+       0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2e, 0x20, 0x4c, 0x69, 
+       0x73, 0x74, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x72, 
+       0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x2e, 0xa, 
+       0x9, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 
+       0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 
+       0x3b, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 
+       0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 
+       0x30, 0x2c, 0x20, 0x66, 0x3b, 0x20, 0x66, 0x20, 0x3d, 0x20, 
+       0x66, 0x69, 0x6c, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x3b, 0x20, 
+       0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0xa, 0x9, 0x20, 0x20, 
+       0x20, 0x20, 0x9, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 
+       0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x3c, 0x6c, 0x69, 0x3e, 
+       0x3c, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x27, 0x2c, 
+       0x20, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x28, 0x66, 0x2e, 
+       0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2c, 0x20, 0x27, 0x3c, 0x2f, 
+       0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x20, 0x28, 0x27, 
+       0x2c, 0x20, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7c, 
+       0x7c, 0x20, 0x27, 0x6e, 0x2f, 0x61, 0x27, 0x2c, 0x20, 0x27, 
+       0x29, 0x20, 0x2d, 0x20, 0x27, 0x2c, 0xa, 0x9, 0x20, 0x20, 
+       0x20, 0x20, 0x9, 0x9, 0x66, 0x2e, 0x73, 0x69, 0x7a, 0x65, 
+       0x2c, 0x20, 0x27, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2c, 
+       0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x6d, 0x6f, 0x64, 0x69, 
+       0x66, 0x69, 0x65, 0x64, 0x3a, 0x20, 0x27, 0x2c, 0xa, 0x9, 
+       0x20, 0x20, 0x20, 0x20, 0x9, 0x9, 0x66, 0x2e, 0x6c, 0x61, 
+       0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 
+       0x44, 0x61, 0x74, 0x65, 0x20, 0x3f, 0x20, 0x66, 0x2e, 0x6c, 
+       0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 
+       0x64, 0x44, 0x61, 0x74, 0x65, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 
+       0x63, 0x61, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x65, 0x53, 0x74, 
+       0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x27, 
+       0x6e, 0x2f, 0x61, 0x27, 0x2c, 0xa, 0x9, 0x20, 0x20, 0x20, 
+       0x20, 0x9, 0x9, 0x27, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x27, 
+       0x29, 0x3b, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x7d, 0xa, 
+       0x9, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 
+       0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 
+       0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 
+       0x6c, 0x69, 0x73, 0x74, 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 
+       0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x27, 
+       0x3c, 0x75, 0x6c, 0x3e, 0x27, 0x20, 0x2b, 0x20, 0x6f, 0x75, 
+       0x74, 0x70, 0x75, 0x74, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 
+       0x27, 0x27, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x3c, 0x2f, 0x75, 
+       0x6c, 0x3e, 0x27, 0x3b, 0xa, 0x9, 0x7d, 0xa, 0xa, 0x9, 
+       0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 
+       0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 
+       0x79, 0x49, 0x64, 0x28, 0x27, 0x66, 0x69, 0x6c, 0x65, 0x73, 
+       0x27, 0x29, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 
+       0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 
+       0x27, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x27, 0x2c, 0x20, 
+       0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 
+       0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x66, 0x61, 
+       0x6c, 0x73, 0x65, 0x29, 0x3b, 0xa, 0xa, 0xa, 0x9, 0x66, 
+       0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x70, 
+       0x6c, 0x6f, 0x61, 0x64, 0x28, 0x29, 0x20, 0x7b, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 
+       0x74, 0x61, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 
+       0x69, 0x6c, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 
+       0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x6f, 
+       0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 
+       0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 
+       0x64, 0x28, 0x27, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x27, 0x29, 
+       0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5b, 0x30, 0x5d, 0x3b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 
+       0x61, 0x72, 0x20, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 
+       0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x46, 0x69, 0x6c, 0x65, 
+       0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x29, 0x3b, 0xa, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 
+       0x61, 0x64, 0x65, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x41, 
+       0x73, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x53, 0x74, 0x72, 
+       0x69, 0x6e, 0x67, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x3b, 
+       0x20, 0x2f, 0x2f, 0x20, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 
+       0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x20, 0x79, 0x6f, 
+       0x75, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x20, 
+       0x72, 0x65, 0x61, 0x64, 0x41, 0x73, 0x44, 0x61, 0x74, 0x61, 
+       0x55, 0x52, 0x4c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x6f, 
+       0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x6e, 0x64, 0x20, 0x20, 
+       0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
+       0x28, 0x65, 0x76, 0x74, 0x29, 0xa, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 
+       0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x58, 0x48, 
+       0x52, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x78, 0x68, 0x72, 0x20, 0x3d, 0x20, 0x6e, 
+       0x65, 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 
+       0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x28, 0x29, 0x3b, 
+       0xa, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x6e, 
+       0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 
+       0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x50, 
+       0x4f, 0x53, 0x54, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x68, 0x72, 0x2e, 
+       0x6f, 0x70, 0x65, 0x6e, 0x28, 0x22, 0x50, 0x4f, 0x53, 0x54, 
+       0x22, 0x2c, 0x20, 0x27, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 
+       0x27, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x65, 0x29, 0x3b, 0xa, 
+       0x9, 0x9, 0x9, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 
+       0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 
+       0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x46, 0x69, 0x6c, 
+       0x65, 0x6e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x69, 
+       0x6c, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x3b, 0xa, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x6d, 0x61, 0x6b, 0x65, 
+       0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x77, 0x65, 0x20, 0x68, 
+       0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 
+       0x6e, 0x64, 0x41, 0x73, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 
+       0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x6f, 0x6e, 
+       0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 
+       0x65, 0x72, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x4d, 0x4c, 0x48, 
+       0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 
+       0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 
+       0x2e, 0x6d, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x73, 0x42, 
+       0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x66, 0x75, 
+       0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x65, 0x78, 
+       0x74, 0x29, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 
+       0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 
+       0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x74, 0x65, 0x78, 
+       0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 
+       0x20, 0x75, 0x69, 0x38, 0x61, 0x20, 0x3d, 0x20, 0x6e, 0x65, 
+       0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 
+       0x61, 0x79, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x30, 
+       0x29, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 
+       0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 
+       0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x74, 
+       0x65, 0x78, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 
+       0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x75, 0x69, 0x38, 
+       0x61, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x65, 
+       0x78, 0x74, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 
+       0x65, 0x41, 0x74, 0x28, 0x69, 0x29, 0x20, 0x26, 0x20, 0x30, 
+       0x78, 0x66, 0x66, 0x29, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 
+       0x6f, 0x66, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 
+       0x42, 0x6c, 0x6f, 0x62, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x66, 
+       0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0xa, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 
+       0x61, 0x72, 0x20, 0x62, 0x6c, 0x6f, 0x62, 0x20, 0x3d, 0x20, 
+       0x6e, 0x65, 0x77, 0x20, 0x42, 0x6c, 0x6f, 0x62, 0x28, 0x5b, 
+       0x64, 0x61, 0x74, 0x61, 0x5d, 0x29, 0x3b, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x62, 0x62, 0x20, 0x3d, 
+       0x20, 0x6e, 0x65, 0x77, 0x20, 0x28, 0x77, 0x69, 0x6e, 0x64, 
+       0x6f, 0x77, 0x2e, 0x4d, 0x6f, 0x7a, 0x42, 0x6c, 0x6f, 0x62, 
+       0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x7c, 0x7c, 
+       0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x57, 0x65, 
+       0x62, 0x4b, 0x69, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x42, 0x75, 
+       0x69, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x7c, 0x7c, 0x20, 0x77, 
+       0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 
+       0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x29, 0x28, 0x29, 
+       0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x62, 0x62, 0x2e, 0x61, 0x70, 0x70, 0x65, 
+       0x6e, 0x64, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0xa, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x76, 0x61, 0x72, 0x20, 0x62, 0x6c, 0x6f, 0x62, 0x20, 
+       0x3d, 0x20, 0x62, 0x62, 0x2e, 0x67, 0x65, 0x74, 0x42, 0x6c, 
+       0x6f, 0x62, 0x28, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x7d, 0xa, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64, 
+       0x28, 0x62, 0x6c, 0x6f, 0x62, 0x29, 0x3b, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x7d, 0xa, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x6c, 0x65, 
+       0x74, 0x27, 0x73, 0x20, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x20, 
+       0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x70, 0x72, 0x6f, 
+       0x67, 0x72, 0x65, 0x73, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 
+       0x72, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 
+       0x72, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x78, 0x68, 0x72, 0x2e, 
+       0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x7c, 0x7c, 0x20, 
+       0x78, 0x68, 0x72, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x76, 0x65, 
+       0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 
+       0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 
+       0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x70, 0x72, 0x6f, 
+       0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x20, 0x66, 0x75, 
+       0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x20, 
+       0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 
+       0x20, 0x67, 0x65, 0x74, 0x20, 0x70, 0x65, 0x72, 0x63, 0x65, 
+       0x6e, 0x74, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x68, 
+       0x6f, 0x77, 0x20, 0x6d, 0x75, 0x63, 0x68, 0x20, 0x6f, 0x66, 
+       0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 
+       0x6e, 0x74, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x68, 0x61, 
+       0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x6e, 
+       0x74, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 
+       0x72, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 
+       0x20, 0x3d, 0x20, 0x65, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 
+       0x69, 0x6f, 0x6e, 0x20, 0x7c, 0x7c, 0x20, 0x65, 0x2e, 0x6c, 
+       0x6f, 0x61, 0x64, 0x65, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x74, 
+       0x61, 0x6c, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x74, 0x6f, 0x74, 
+       0x61, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x20, 0x7c, 0x7c, 0x20, 
+       0x65, 0x2e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3b, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 
+       0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x20, 
+       0x3d, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 
+       0x6e, 0x64, 0x28, 0x28, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 
+       0x6f, 0x6e, 0x2f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x29, 0x2a, 
+       0x31, 0x30, 0x30, 0x29, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x72, 0x65, 
+       0x20, 0x79, 0x6f, 0x75, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 
+       0x64, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x79, 0x6f, 
+       0x75, 0x72, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x63, 0x6f, 0x64, 
+       0x65, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x79, 0x6f, 0x75, 0x20, 
+       0x77, 0x69, 0x73, 0x68, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 
+       0x6f, 0x63, 0x65, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0xa, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x28, 0x20, 0x22, 
+       0x23, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 
+       0x20, 0x29, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x29, 
+       0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x75, 
+       0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x27, 0x20, 
+       0x2b, 0x20, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 
+       0x67, 0x65, 0x20, 0x2b, 0x20, 0x27, 0x25, 0x27, 0x29, 0x3b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0xa, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x2f, 0x2f, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x63, 
+       0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x73, 0x65, 
+       0x72, 0x76, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x77, 0x65, 0x20, 
+       0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6b, 0x6e, 
+       0x6f, 0x77, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x6e, 
+       0x64, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 
+       0x69, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x73, 0x75, 
+       0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c, 0x79, 
+       0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0xa, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x6e, 0x72, 0x65, 
+       0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x63, 0x68, 
+       0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 
+       0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 
+       0x28, 0x78, 0x68, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 
+       0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 
+       0x29, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0xa, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x69, 0x66, 0x28, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x74, 0x61, 
+       0x74, 0x75, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x30, 0x30, 
+       0x29, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 
+       0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x73, 
+       0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0xa, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x24, 0x28, 0x20, 0x22, 0x23, 0x75, 0x70, 0x6c, 0x6f, 
+       0x61, 0x64, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x20, 
+       0x29, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x29, 0x2e, 
+       0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x20, 0x27, 0x55, 
+       0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x4f, 0x6b, 
+       0x27, 0x29, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x72, 
+       0x6f, 0x63, 0x65, 0x73, 0x73, 0x20, 0x65, 0x72, 0x72, 0x6f, 
+       0x72, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x28, 0x20, 0x22, 
+       0x23, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x72, 0x65, 0x73, 
+       0x75, 0x6c, 0x74, 0x22, 0x20, 0x29, 0x2e, 0x65, 0x6d, 0x70, 
+       0x74, 0x79, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 
+       0x64, 0x28, 0x20, 0x27, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 
+       0x65, 0x64, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x27, 
+       0x29, 0x3b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x7d, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x7d, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0xa, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x2f, 0x2f, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 
+       0x73, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0xa, 0x20, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x78, 0x68, 0x72, 0x2e, 0x6d, 0x79, 0x53, 0x65, 0x6e, 0x64, 
+       0x41, 0x73, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x28, 0x65, 
+       0x76, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 
+       0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x29, 0x3b, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0xa, 
+       0x9, 0x7d, 0xa, 0x9, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 
+       0x70, 0x74, 0x3e, 0xa, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 
+       0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 
+       0xa, 0};
+
+static const unsigned char data_404_html[] = {
+       /* /404.html */
+       0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
+       0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c, 
+       0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 
+       0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, 
+       0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e, 
+       0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 
+       0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 
+       0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 
+       0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 
+       0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, 
+       0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 
+       0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, 
+       0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 
+       0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20, 
+       0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 
+       0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 
+       0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 
+       0xa, 0};
+
+static const unsigned char data_img_control_xy_png[] = {
+       /* /img/control_xy.png */
+       0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x78, 0x79, 0x2e, 0x70, 0x6e, 0x67, 0,
+       0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 00, 00, 
+       00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, 00, 0xf7, 
+       00, 00, 00, 0xf8, 0x8, 0x6, 00, 00, 00, 0x30, 
+       0xda, 0x70, 0x86, 00, 00, 00, 0x9, 0x70, 0x48, 0x59, 
+       0x73, 00, 00, 0xb, 0x13, 00, 00, 0xb, 0x13, 0x1, 
+       00, 0x9a, 0x9c, 0x18, 00, 00, 0x20, 00, 0x49, 0x44, 
+       0x41, 0x54, 0x78, 0x1, 0xec, 0x7d, 0x7, 0x74, 0x1c, 0xc7, 
+       0x95, 0x6d, 0xf5, 0xcc, 0x60, 0x90, 0x41, 0x80, 00, 0x48, 
+       0x80, 00, 0x49, 0x80, 0x4, 0x73, 0x4e, 0x62, 0x14, 0x49, 
+       0xe5, 0x1c, 0x2c, 0x59, 0x72, 0x90, 0x6c, 0xc9, 0xb2, 0xec, 
+       0xd5, 0xfa, 0xcb, 0xd9, 0xc7, 0xeb, 0xb0, 0x6b, 0xcb, 0xb6, 
+       0x1c, 0xcf, 0xdf, 0xf5, 0x7a, 0x77, 0x9d, 0xbe, 0x2c, 0x59, 
+       0xb6, 0x15, 0xad, 0x68, 0x5, 0x4a, 0x94, 0x28, 0x91, 0x12, 
+       0x73, 0xe, 0x20, 0x41, 0x90, 0x44, 0x24, 0x72, 0x22, 0x72, 
+       0x9c, 0xd0, 0xff, 0xde, 0x9a, 0x79, 0xc3, 0xc6, 0x60, 0x6, 
+       0xc4, 0x80, 0x60, 0xb0, 0x97, 0xf, 0xa7, 0x50, 0xd5, 0xdd, 
+       0xd5, 0x55, 0xd5, 0xaf, 0xde, 0xad, 0xf7, 0x2a, 0x8e, 0x61, 
+       0x9a, 0xa6, 0xba, 0x44, 0x97, 0x38, 0x70, 0x89, 0x3, 0xff, 
+       0x78, 0x1c, 0xb0, 0xfd, 0xe3, 0x7d, 0xd2, 0xa5, 0x2f, 0xba, 
+       0xc4, 0x81, 0x4b, 0x1c, 0x20, 0x7, 0x2e, 0x81, 0xfb, 0x92, 
+       0x1c, 0x5c, 0xe2, 0xc0, 0x3f, 0x28, 0x7, 0x2e, 0x81, 0xfb, 
+       0x1f, 0xb4, 0x62, 0x2f, 0x7d, 0xd6, 0x25, 0xe, 0x38, 0x86, 
+       0xca, 0x2, 0x3, 0x14, 0x26, 0x6e, 0xb8, 0xfb, 0x61, 0xa2, 
+       0x9f, 0xb7, 0xdb, 0x61, 0x7, 0x13, 0x30, 0xce, 0x10, 0xf6, 
+       0xd9, 0x79, 0x2b, 0xdd, 0x8, 0x64, 0x14, 0xa2, 0x4e, 0xc2, 
+       0xd5, 0x45, 0xb8, 0xfb, 0x67, 0xe2, 0x83, 0x7e, 0xfe, 0x8f, 
+       0xc0, 0xaf, 0x10, 0xbc, 0xb2, 0xd6, 0x40, 0x38, 0xfe, 0x58, 
+       0xe3, 0x5c, 0x88, 0x70, 0xc8, 0xfa, 0x19, 0x6a, 0x7d, 0x18, 
+       0x83, 0xc9, 0x79, 0x8, 0x86, 0x50, 0xd3, 0x7, 0x33, 0x22, 
+       0xf8, 0xfa, 0x42, 0x30, 0x21, 0x54, 0x9e, 0xc1, 0x8c, 0xe1, 
+       0xb5, 0x38, 0x1d, 0x7f, 0xa8, 0x4c, 0xa, 0x95, 0xf8, 0xf9, 
+       0xb8, 0x17, 0xc4, 0x7f, 0xe1, 0xb3, 0xd5, 0x97, 0xb0, 0x14, 
+       0x87, 0xd7, 0xd6, 0x7b, 0xd6, 0xb0, 0xc4, 0x39, 0x93, 0xef, 
+       0xb5, 0x44, 0x10, 0x1e, 0x8a, 0xcf, 0x47, 0xd6, 0xe7, 0xbc, 
+       0x26, 0x1b, 0xad, 0xcf, 0x79, 0xef, 0xa2, 0xa1, 0x10, 0x3c, 
+       0x14, 0x9e, 0x88, 0xcf, 0xb2, 0x5a, 0xc3, 0x17, 0x4d, 0xd9, 
+       0x51, 0x90, 0x60, 0xbe, 0xf2, 0x3a, 0xc0, 0xff, 0x33, 0xf1, 
+       0x3d, 0x2c, 0xb8, 0x83, 0x98, 0x22, 0xa0, 0x16, 0x33, 0x5e, 
+       0x98, 0x21, 0xd7, 0xc2, 0x10, 0xde, 0x97, 0x67, 0x72, 0xef, 
+       0x7c, 0xf9, 0xc2, 0x8, 0xf1, 0x25, 0x5f, 0x32, 0x43, 0xee, 
+       0x9, 0x63, 0x2, 0x4c, 0x3a, 0x13, 0x83, 0x24, 0x91, 0x73, 
+       0xed, 0x5b, 0xf8, 0x2d, 0xfc, 0x13, 0x5f, 0x78, 0x2c, 0xbe, 
+       0x95, 0xc7, 0x72, 0x8f, 0xc5, 0x93, 0xb0, 0xbc, 0x27, 0x3e, 
+       0x9f, 0x49, 0x58, 0x7c, 0xe1, 0x7, 0x9f, 0x91, 0x78, 0x1d, 
+       0x7c, 0xcf, 0xca, 0x2b, 0x79, 0x26, 0xf7, 0xf8, 0x8e, 0x84, 
+       0x83, 0x7d, 0x3e, 0x23, 0xe2, 0xe5, 0xbe, 0xbe, 0xbe, 0x10, 
+       0xff, 0x2c, 0x3c, 0xb5, 0xf2, 0x86, 0x61, 0xe1, 0x3, 0x7d, 
+       0x9, 0xb3, 0x88, 0xc1, 0xd7, 0xbc, 0x77, 0x3e, 0x29, 0x54, 
+       0x3d, 0xc8, 0x3d, 0xfa, 0x56, 0x9e, 0x7a, 0xa4, 0x60, 0xe1, 
+       0x64, 0x38, 0x24, 0xb8, 0x83, 0x98, 0x22, 0x1f, 0xfc, 0x9, 
+       0x24, 0x36, 0xd5, 0x9f, 0xa0, 0xdc, 0x93, 0xf4, 0xad, 0xc, 
+       0x92, 0x7b, 0x17, 0xda, 0x17, 0x81, 0x64, 0x39, 0x18, 0x2e, 
+       0x82, 0x7b, 0x16, 0x8e, 0xc, 0xa2, 0xb, 0x30, 0x2b, 0x1c, 
+       0x73, 0x10, 0xe7, 0x9c, 0x91, 0x85, 0xc7, 0x56, 0x5e, 0x8a, 
+       0x10, 0x8a, 00, 0xf2, 0x99, 0xf5, 0x9e, 0x35, 0xcc, 0xb2, 
+       0x59, 0xe3, 0x59, 0xd3, 0x9, 0xe, 0xf, 0xe5, 0x3b, 0xac, 
+       0x82, 0x43, 0xde, 0x4, 0xf8, 0xe3, 0xf, 0x5b, 0xaf, 0x25, 
+       0xae, 0x95, 0x97, 0xf2, 0x4e, 0xa8, 0x78, 0xe7, 0x1d, 0xec, 
+       0x7e, 0xfe, 0x5a, 0xf9, 0x60, 0xc7, 0x77, 0x50, 0x86, 0xa7, 
+       0xc0, 0xf1, 0x3e, 0x29, 0xd8, 0xf7, 0xdd, 0xbd, 0x38, 0xfe, 
+       0x93, 0x8f, 0x42, 0xc2, 0x5b, 0xab, 0xc, 0xb, 0x9f, 0x29, 
+       0xbe, 0xd6, 0xb8, 0xf2, 0x8e, 0x1a, 0xac, 0xcf, 0x2d, 0x8c, 
+       0xa1, 00, 0xd1, 0x4d, 0x5d, 0xb9, 0x7c, 0xfa, 0xcc, 0xb4, 
+       0xf4, 0xa4, 0x34, 0x24, 0xe5, 0x67, 0x8a, 0x29, 0xcc, 0x9, 
+       0x24, 0x78, 0xf1, 0x5, 0xc, 0xfd, 0xe1, 0x47, 0xe, 0x97, 
+       0x8f, 0x29, 0x2e, 0xad, 0xfb, 0xab, 0xff, 0x5b, 0xdc, 0xf0, 
+       0x85, 0x21, 0x5e, 0xa, 0x42, 0x38, 0x6, 0x8d, 0xd4, 0xf7, 
+       0x84, 00, 0xb3, 0xf0, 0x57, 0x7c, 0xe1, 0x33, 0xaf, 0x43, 
+       0x85, 0x79, 0x2f, 0x54, 0x5c, 0x63, 0xdc, 0xb8, 0x71, 0xa3, 
+       0x63, 0x63, 0x63, 0xe3, 0x1c, 0xe, 0x47, 0xa2, 0xcd, 0x66, 
+       0x8b, 0xb5, 0xdb, 0xed, 0xf1, 0x8, 0xc7, 0x21, 0x7e, 0x1c, 
+       0xae, 0xe3, 0x79, 0xcf, 0x1f, 0x8e, 0xf3, 0x7a, 0xbd, 0x5d, 
+       0x8, 0x77, 0xd3, 0x87, 0xeb, 0xc4, 0x77, 0x77, 0xbb, 0xdd, 
+       0xee, 0x6e, 0x8f, 0xc7, 0xc3, 0x70, 0x67, 0x6f, 0x6f, 0x6f, 
+       0x77, 0x5f, 0x5f, 0x5f, 0x7b, 0x75, 0x75, 0x75, 0xb, 0xe2, 
+       0x85, 0x3, 0xb1, 0x15, 0xd4, 0xc, 0x8b, 0xa0, 0xc9, 0x7d, 
+       0xb9, 0x27, 0xf7, 0x4d, 0x7c, 0x3f, 0xcb, 0xcf, 0xfb, 0x9a, 
+       0x90, 0x57, 0x20, 0x2c, 0xf7, 0x46, 0xca, 0xf, 0xc1, 0x6b, 
+       0xe6, 0x6d, 0xb7, 0xd9, 0x9c, 0x33, 0x93, 0xd3, 0x16, 0x2c, 
+       0x47, 0x98, 0x7c, 0x14, 0xb2, 0x86, 0xe5, 0xde, 0xc5, 0xe4, 
+       0x6b, 0x39, 0x35, 0x4c, 0xaf, 0xbb, 0xa9, 0x61, 0x37, 0xcb, 
+       0x4a, 0xcc, 0x52, 0x6b, 0xd3, 0x69, 0x9e, 0xe2, 0x7b, 0x75, 
+       0xdf, 0x8, 0xd7, 0xfd, 0x68, 00, 0xb8, 0xc3, 0x30, 0x46, 
+       0x33, 0xc7, 0xf4, 0x9a, 0xc6, 0xff, 0xfc, 0xdf, 0x7, 0xb7, 
+       0x7b, 0x3c, 0x5e, 0x9b, 0x17, 0x61, 0xa6, 0x84, 0x4a, 0x32, 
+       0x24, 0xdc, 0x2f, 0xe5, 0xb, 0x7c, 0x61, 0xb3, 0x19, 0x14, 
+       0x28, 0x93, 0xfe, 0x97, 0xbe, 0xf1, 0xf8, 0x72, 0x34, 0x48, 
+       0x6c, 0xb9, 0x9d, 0x70, 0x2e, 0x38, 0x7e, 0x37, 0x1, 0xce, 
+       0xef, 0x22, 0x8d, 0xb8, 0xa0, 0x59, 0xf8, 0xc8, 0xf4, 0x25, 
+       0x1f, 0xfa, 0xe4, 0x1b, 0x1d, 0xcb, 0x43, 0x9f, 0xf7, 0xac, 
+       0xce, 0x7a, 0x9f, 0x61, 0x5b, 0x52, 0x52, 0x92, 0x33, 0x3d, 
+       0x3d, 0x7d, 0x42, 0x5c, 0x5c, 0xdc, 0x84, 0xa8, 0xa8, 0xa8, 
+       0x89, 0xd1, 0xd1, 0xd1, 0x93, 0x9c, 0x4e, 0xe7, 0x14, 0x80, 
+       0x76, 0x3c, 0x40, 0x39, 0x6, 0x60, 0xf6, 0x22, 0xec, 0x5, 
+       0xa0, 0xe9, 0x4c, 0x38, 0x85, 0xe7, 0xa, 0x71, 0x6d, 0x8, 
+       0xdb, 0x62, 0x62, 0x62, 0x6c, 0x8, 0x23, 0xe8, 0xb0, 0x3, 
+       0xc8, 0x1e, 0x97, 0xcb, 0xe5, 0xee, 0xe9, 0xe9, 0xf1, 0x22, 
+       0xec, 0x45, 0xd8, 0xb, 0x30, 0x2b, 0x84, 0xe9, 0xc, 0xa4, 
+       0x67, 0xa3, 0xcb, 0xcb, 0xcb, 0xb3, 0x21, 0xdd, 0x6, 0x34, 
+       00, 0x15, 00, 0x7c, 0x11, 0x5c, 0x9, 0xe2, 0x9e, 0xec, 
+       0xec, 0xec, 0x3c, 0xd9, 0xd8, 0xd8, 0x58, 0xd1, 0xde, 0xde, 
+       0xde, 0x87, 0xb2, 0x91, 0x6f, 0x74, 0x14, 0x34, 0xfa, 0x14, 
+       0x44, 0x9, 0xcb, 0x33, 0xeb, 0x7d, 0x1, 0x3b, 0x1b, 0x54, 
+       0x7e, 0x33, 0x9f, 0x91, 0x20, 0x46, 0xa1, 0xb5, 0x8f, 0xef, 
+       0xf1, 0xb0, 0xfe, 0xb, 0xaf, 0x35, 0xf, 0x91, 0x2, 0x7c, 
+       0x53, 0xf3, 0x76, 0xca, 0x9c, 0x87, 0xb6, 0x23, 0x47, 0xf0, 
+       0xde, 0x64, 0xa3, 0xe, 0xdf, 0xcb, 0x7a, 0xb8, 0xc8, 0xc8, 
+       0xe6, 0x3, 0x35, 0x64, 0x18, 0x62, 0x62, 0x16, 0xe5, 0xff, 
+       0x76, 0x9, 0xa, 0xc8, 0xf2, 0xd3, 0x9, 0x9, 0xc0, 0xe9, 
+       0xf, 0xa0, 0x1, 0xe0, 0xf6, 0xc7, 0xb0, 0xa, 0x1b, 0xc3, 
+       0x51, 0x70, 0xf0, 0xbd, 0xb6, 0x9e, 0xbe, 0x1e, 0x7, 0xc1, 
+       0x4c, 0xa6, 0xf4, 0x7, 0x79, 0xbf, 0xd6, 0x70, 0x40, 0x46, 
+       0xe7, 0xf3, 0x6, 0x1b, 0x32, 0x2b, 0xb8, 0x4d, 0x5c, 0xd2, 
+       0xa1, 0xc, 0xf2, 0xbd, 0x56, 0x80, 0x8f, 0x58, 0xd1, 0x2c, 
+       0x80, 0xa6, 0xb0, 0x58, 0x9d, 0x95, 0x9f, 0xbc, 0xcf, 0xa, 
+       0xe2, 0x3d, 0xf1, 0xa5, 0x6c, 0xb6, 0xb1, 0x63, 0xc7, 0x8e, 
+       0xca, 0xc8, 0xc8, 0x58, 0xc, 0x4d, 0x7c, 0x19, 0x40, 0xb9, 
+       0x12, 0x71, 0xb2, 0x1, 0xb6, 0x24, 00, 0xba, 0x37, 0x21, 
+       0x21, 0xc1, 0x93, 0x92, 0x92, 0x12, 0x95, 0x9c, 0x9c, 0x1c, 
+       0x93, 0x98, 0x98, 0xa8, 0xe8, 00, 0x7c, 0xd, 0x64, 0xc4, 
+       0x1b, 0x2a, 0x5, 0xb, 0x48, 0xc8, 0xf7, 0x8, 0xf8, 0xb6, 
+       0xb6, 0xb6, 0x2c, 0x80, 0x98, 0x6e, 0x59, 0x4b, 0x4b, 0x4b, 
+       0x4f, 0x73, 0x73, 0xb3, 0xab, 0xa3, 0xa3, 0xc3, 0x9e, 0x9d, 
+       0x9d, 0x1d, 0xd, 0xe0, 0xb7, 0xe3, 0xc5, 0xca, 0xee, 0xee, 
+       0xee, 0xed, 0x5d, 0x5d, 0x5d, 0xbb, 0x6b, 0x6a, 0x6a, 0xf6, 
+       0x2, 0xf4, 0xad, 0xb8, 0x47, 0xc0, 0x52, 0xd8, 0x4, 0xe4, 
+       0xd6, 0xb0, 00, 0x9e, 0xf7, 0x4, 0xe8, 0xda, 0x7, 0xef, 
+       0x4, 0xe8, 0x44, 0x7a, 0x20, 0x8c, 0x78, 0x11, 0x91, 0xbf, 
+       0xe, 0x4, 0xac, 0xc2, 0x77, 0x7e, 0x33, 0xeb, 0xde, 0xc6, 
+       0x46, 0xc5, 0x6e, 0x53, 0x76, 0xe4, 0x61, 0x23, 0xc0, 0xf9, 
+       0x87, 0x92, 0xf8, 0xe3, 0xfb, 0x14, 0x56, 0x44, 0x19, 0x9e, 
+       0xab, 0xc8, 0x50, 0xd5, 0x4c, 0x1a, 0x5, 0x63, 0xe9, 0x50, 
+       0x52, 0xdd, 0x18, 0xf2, 0x3b, 0x88, 0x45, 0xf9, 0x3e, 0x46, 
+       0x21, 0x2f, 0xf9, 0x5d, 0x5e, 0x7c, 0x93, 0x6e, 0x10, 0x78, 
+       0x93, 0x24, 0xc2, 0xee, 0xbb, 0xea, 0xff, 0x9f, 0x9, 0x8, 
+       0x53, 0xe8, 0xdb, 0xa8, 0xfd, 0x5c, 0xae, 0x3e, 0x3b, 0x41, 
+       0xed, 0xf1, 0x7a, 0x6d, 0xd4, 0xe4, 0x3e, 0xdf, 0x97, 0x19, 
+       0xd2, 0x26, 0x6f, 0xfb, 0x65, 0xd0, 0x3f, 0xc9, 0x73, 0x77, 
+       0xc5, 0xbc, 0x99, 0xba, 0xe4, 0x6f, 0xb7, 0x1b, 0xd4, 0xe, 
+       0xa6, 0xdd, 0x6e, 0xf3, 0x2a, 0xd3, 0x8b, 0x8a, 0xf4, 0xf2, 
+       0x1b, 0xa8, 0xb9, 0x49, 0x2c, 0xa3, 0x68, 0x6e, 0x86, 0x59, 
+       0x70, 0xa, 0xd5, 0xb0, 0xca, 0x8e, 0x77, 0x85, 0xd9, 0x14, 
+       0x26, 0x86, 0xe9, 0x44, 0xb0, 0xc4, 0xd7, 0x3c, 0xc4, 0x7d, 
+       0x2d, 0x64, 0xe2, 0x4f, 0x5, 0x1, 0xa4, 0x4, 0xf3, 0x4a, 
+       0x68, 0xd7, 0xc5, 0xd0, 0x94, 0xa9, 00, 0x70, 0x4f, 0x56, 
+       0x56, 0x56, 0x5c, 0x66, 0x66, 0xa6, 0x9d, 00, 0x6, 0xa8, 
+       0x15, 0x34, 0x33, 0xcd, 0xec, 0xf3, 0x46, 0xd4, 0xfc, 0x69, 
+       0x69, 0x69, 0xda, 0xf9, 0x33, 0x8d, 0x81, 0x4f, 0x47, 0x3e, 
+       0x29, 00, 0x3e, 0x99, 0xe, 0xa0, 0x9e, 0x51, 0x55, 0x55, 
+       0xf5, 0x89, 0xd1, 0xa3, 0x47, 0x47, 0xa3, 0x8c, 0xa7, 0xa0, 
+       0xdd, 0xf7, 0x40, 0xbb, 0xef, 0x40, 0xc3, 0xb0, 0xa7, 0xb2, 
+       0xb2, 0xb2, 0x18, 0x1a, 0x9f, 0x7c, 0xa6, 0xa0, 0x86, 0xf3, 
+       0xf9, 0x4c, 0x1c, 0xf9, 0xcf, 0x7a, 0x83, 0xa7, 0xf3, 0xd1, 
+       0x2, 0xae, 0x2f, 0x22, 0xfb, 0x17, 0x5c, 0x7, 0xe4, 0x39, 
+       0xeb, 0xde, 0x6, 0x41, 0xb0, 0x29, 0xaf, 0xdb, 0x41, 0x99, 
+       0x40, 0x1b, 0x82, 0xba, 0x21, 0xb8, 0x1, 0x71, 0xfa, 0x24, 
+       0xca, 0xd1, 0x5, 0x92, 0x61, 0x9d, 0xbf, 0xff, 0x1f, 0xa, 
+       0x1, 0x50, 0x43, 0x87, 0xc2, 0x7, 0xae, 0x29, 0xc0, 0x94, 
+       0x23, 0xab, 0xc, 0x93, 0x37, 0x9a, 0x5f, 0xf0, 0x7d, 0x65, 
+       0xf7, 0xbf, 0x2b, 0x5e, 0x28, 0x70, 0x33, 0x22, 0x13, 0x12, 
+       0x9f, 0x61, 0xb6, 0x16, 0x76, 0x34, 0xd, 0xb6, 0xee, 0x6e, 
+       0xb7, 0x3, 0x96, 0x1d, 0x5a, 0x3e, 0xa5, 0x35, 0x37, 0x41, 
+       0x45, 0x87, 0x67, 0xba, 0x24, 0x88, 0xa7, 0xde, 0xdd, 0x70, 
+       0x30, 0xf3, 0xc3, 0x6d, 0x85, 0xe3, 0xaf, 0xbe, 0x62, 0x76, 
+       0xd9, 0x9a, 0xcb, 0x67, 0xd5, 0xf3, 0xde, 0xf9, 0x22, 0xad, 
+       0xb5, 0xc1, 0x14, 0x8, 0x88, 0x89, 0x26, 0xda, 0x6b, 0x43, 
+       0xc9, 0x3c, 0x5e, 0x13, 0x8, 0xef, 0xc7, 0x18, 0xd, 0x68, 
+       0x94, 0x49, 0x84, 0x8a, 0xdf, 0x1a, 0x11, 0xb0, 0x83, 00, 
+       0xcd, 0xcf, 0x23, 0x9f, 0xac, 0x4e, 0xc0, 0xcc, 0x7b, 0xe4, 
+       0x33, 0x9d, 0x3d, 0x17, 0x4, 0x13, 0xfb, 0x66, 0x98, 0xd8, 
+       0x57, 00, 0xc8, 0xb3, 0xa0, 0x91, 0x4d, 0x68, 0x6b, 0x5, 
+       0x20, 0xc7, 0xd1, 0x7, 0x48, 0xd8, 0x40, 0x91, 0xdf, 0x17, 
+       0x2d, 0x11, 0x7c, 0xb4, 0x18, 0xe8, 0xd0, 0x8, 0xd9, 0x17, 
+       0x2f, 0x5e, 0x9c, 0x40, 0xc0, 0x43, 0xb3, 0x8f, 0xad, 0xad, 
+       0xad, 0xbd, 0x9, 0x80, 0xbf, 0xa2, 0xae, 0xae, 0x8e, 0xcf, 
+       0xa8, 0x51, 0xa, 00, 0xf6, 0xf, 0xea, 0xeb, 0xeb, 0xdf, 
+       0x3c, 0x9, 0xc2, 0x47, 0x11, 0xe4, 0xe2, 0x44, 0xab, 0x8b, 
+       0x2f, 0xf5, 0x41, 0xdf, 0x83, 0x77, 0xc9, 0x3b, 0x86, 0xd9, 
+       0xa0, 0x68, 0x9f, 0xe1, 0x21, 0x92, 0xd4, 0x5, 0xeb, 0x21, 
+       0xc0, 0x7f, 0xa4, 0x69, 0x38, 0xc, 0xd3, 0xe1, 0x55, 0x68, 
+       0xec, 0xa9, 0xb7, 0xfd, 00, 0xf7, 0x81, 0x9b, 0xc0, 0x1e, 
+       0x62, 0xea, 0x67, 0x19, 0xad, 0xbe, 0x66, 0x77, 0xe6, 0xa9, 
+       0xc6, 0xfc, 0xf1, 0x69, 0x63, 0x17, 0x95, 0xa5, 0x8d, 0x99, 
+       0x67, 0xc1, 0x88, 0x4f, 0x39, 0x12, 0xd0, 0x14, 0x49, 0xfa, 
+       0x10, 0x65, 0xe9, 0xc6, 0xf0, 0x3b, 0x28, 0x1b, 0x2, 0x6a, 
+       0x96, 0x82, 0x7c, 0xa1, 0xe3, 0xf7, 0x92, 0x8f, 0x1, 0x62, 
+       0xe4, 0x70, 0xc4, 0xc8, 0xfc, 0x54, 0x2d, 0x94, 0xf0, 0x69, 
+       0xda, 0x1a, 0x6e, 0x77, 0x1f, 0xfa, 0x6d, 0x5e, 0x3b, 0x4, 
+       0x53, 0x6b, 0x6f, 0xaf, 0x7, 0xc0, 0xf1, 0x3, 0x9c, 0x7d, 
+       0xb6, 0xff, 0xf9, 0xdd, 0xbb, 0xb3, 0xf7, 0x1d, 0x28, 0x1b, 
+       0x3f, 0x63, 0xda, 0xb8, 0x9a, 0x27, 0xfe, 0xb4, 0x71, 0xf1, 
+       0x91, 0xa3, 0x15, 0xe5, 0xf, 0xde, 0xb7, 0xf6, 0x98, 0x61, 
+       0xf3, 0x71, 0xd, 0xda, 0x5e, 0x49, 0x38, 0x5c, 0xc6, 0x67, 
+       0x7b, 0x1f, 0xf5, 0x67, 0x42, 0xaa, 00, 0x6e, 0xc3, 0x8b, 
+       0x51, 0x14, 0x68, 0x6e, 0x98, 0xe5, 0xa7, 0xfb, 0xdc, 0x64, 
+       00, 0xbf, 0x89, 0xbe, 0x7c, 0xe3, 0x90, 0xb3, 0xa4, 0x70, 
+       0xf8, 0x23, 0xcb, 0xbb, 0xf4, 0xad, 0x8e, 0x69, 0xf3, 0x9a, 
+       0xbe, 0x76, 0xe8, 0xbf, 0x4e, 0x87, 0x16, 0xbc, 0x5, 0x66, 
+       0xf6, 0x6d, 0x78, 0x3d, 0x7d, 0xd2, 0xa4, 0x49, 0xa, 0xa6, 
+       0x6d, 0xc, 0xc1, 0xc, 0x8d, 0x8d, 0x68, 0xe7, 0x9e, 0x60, 
+       0x32, 0xeb, 0x4c, 0xa8, 0x8d, 0xcf, 0x5, 0x91, 0x2d, 0x6c, 
+       0x98, 0xe8, 0x66, 0xce, 0x9c, 0xa9, 0xad, 0xc, 0x98, 0xec, 
+       0xa, 0xa0, 0x5e, 0x58, 0x51, 0x51, 0x31, 0xab, 0xa4, 0xa4, 
+       0xe4, 0xb, 0x93, 0x27, 0x4f, 0x6e, 0x4, 0xd0, 0x5f, 0x6f, 
+       0x68, 0x68, 0x58, 0x57, 0x5a, 0x5a, 0x7a, 0xc, 0xe5, 0x60, 
+       0xf7, 0x88, 0xf5, 0x60, 0x5, 0xbb, 0x68, 0x78, 0xde, 0x17, 
+       0xc1, 0x8d, 0x44, 0x9b, 0xb3, 0x7e, 0xc4, 0x21, 0x18, 0xe8, 
+       0xfa, 0xb0, 0x2e, 0xec, 0x40, 0x5, 0xe4, 0x95, 0xca, 0x89, 
+       0x4e, 0x5b, 0x74, 0x5a, 0xae, 0x29, 0x23, 0x8c, 0x7c, 0xae, 
+       0xc9, 0xeb, 0x75, 0x1b, 0xa5, 0x45, 0xaf, 0xcc, 0x6e, 0x6b, 
+       0x39, 0x3e, 0x3e, 0x3e, 0x31, 0xa7, 0xa6, 0xa2, 0xf4, 0xcd, 
+       0xc5, 0xed, 0x6d, 0xa5, 0xe5, 0x13, 0x72, 0x6e, 0x3a, 0x6, 
+       0xcb, 0x47, 0x67, 0x4f, 0xfb, 0x1a, 0x61, 0xb6, 0x34, 00, 
+       0x8b, 0xdd, 0xa3, 0x1b, 0xa1, 0xd3, 0x32, 0x46, 0x70, 0x93, 
+       0x47, 0x6c, 0xb4, 0x44, 0x86, 0xf9, 0x22, 0xc3, 0xfd, 0x88, 
+       0x1f, 0x1c, 0x8e, 0xf8, 0x82, 0x68, 0x1f, 0xc6, 0x83, 0x39, 
+       0x63, 0xda, 0x3c, 0x7d, 0x5e, 0x1b, 0x35, 0xb7, 0x17, 0xa6, 
+       0xb9, 0xdb, 0xe3, 0x65, 0xdf, 0x85, 0x3, 0x6a, 0xb6, 0xf2, 
+       0x8a, 0xc6, 0xb8, 0x5f, 0xfd, 0xfa, 0xed, 0x45, 0x6e, 0x8f, 
+       0xc7, 0xfe, 0xdd, 0x6f, 0x7c, 0x64, 0xeb, 0xe4, 0xdc, 0xf4, 
+       0xce, 0x63, 0x27, 0x6a, 0x12, 0x7f, 0xf7, 0xf8, 0x7b, 0xf3, 
+       0xbf, 0xff, 0xa3, 0x17, 0x53, 0xae, 0x5c, 0x3d, 0xab, 0xfc, 
+       0xd5, 0x37, 0xf7, 0x4c, 0xeb, 0xeb, 0x73, 0xdb, 0x6f, 0xb9, 
+       0x71, 0xd1, 0xb1, 0x6b, 0xae, 0x98, 0x5d, 0x6b, 0xcd, 0x78, 
+       0xc3, 0xc6, 0xc3, 0x19, 0xeb, 0xdf, 0x3b, 0x34, 0x99, 0xf7, 
+       0x66, 0x4d, 0xcf, 0xaa, 0xbf, 0xff, 0xde, 0x35, 0x27, 0x18, 
+       0x7e, 0xfa, 0xf9, 0xad, 0x93, 0xe, 0xe4, 0x97, 0x67, 0x32, 
+       0x7c, 0xdb, 0x8d, 0x8b, 0x8e, 0xaf, 0x5a, 0x31, 0xad, 0x81, 
+       0xe1, 0x70, 0x4, 0x21, 0xd3, 0x1a, 0x18, 0x7d, 0x6e, 0xe, 
+       0x32, 0x1, 0xe1, 0x3e, 0xcb, 0x82, 0x65, 0xc7, 0x3b, 0xd2, 
+       0x8a, 0x93, 0x39, 0xbc, 0x16, 0x21, 0x60, 0x98, 0x82, 0x14, 
+       0x92, 0x90, 0xa6, 00, 0xda, 0x1a, 0x5f, 0xd2, 0x13, 0x5f, 
+       0xd2, 0xd6, 0xfe, 0xf4, 0xe9, 0xd3, 0xe7, 0xa3, 0x6f, 0x7c, 
+       0x2b, 00, 0x7d, 0xb, 0xfa, 0xa7, 0x49, 00, 0xb4, 0x1d, 
+       0xce, 0x49, 0x40, 0x9f, 0x4e, 0x2e, 0x64, 0x76, 0x23, 0x7e, 
+       0xb3, 0xac, 0xac, 0x4c, 0xed, 0xdf, 0x7f, 0x50, 0xa7, 0xbb, 
+       0x60, 0xc1, 0x3c, 0x95, 0x93, 0x93, 0x33, 0xe2, 0x79, 0x84, 
+       0x4a, 0x90, 0xd, 0xd7, 0xc4, 0x89, 0x13, 0xe9, 0xa2, 0x57, 
+       0xae, 0x5c, 0x49, 0xa0, 0x67, 0x15, 0x17, 0x17, 0x3f, 00, 
+       0xa0, 0xdf, 0x8f, 0x7b, 0xed, 00, 0xff, 0x9b, 0x4d, 0x4d, 
+       0x4d, 0x6f, 0x16, 0x15, 0x15, 0x1d, 0xc2, 0xfb, 0x2, 0x70, 
+       0x2, 0x5e, 00, 0x4e, 0x9f, 0x42, 0x1b, 00, 0xba, 0xbf, 
+       0x2e, 0x74, 0x1d, 0x9f, 0x41, 0x9b, 0xb3, 0xae, 0x28, 0xb7, 
+       0xe2, 0xb3, 0x5e, 0x20, 0x11, 0xd0, 0x85, 0x36, 0xd3, 0x81, 
+       0xc6, 0x5e, 0x37, 0xf8, 0xf4, 0x9, 0x21, 0xfe, 0x5, 0x4c, 
+       0x73, 0x44, 0xc, 0x45, 0xc5, 0xc7, 0x5e, 0x9a, 0xd9, 0xd9, 
+       0x59, 0x95, 0xca, 0x67, 0x33, 0x67, 0x3f, 0xb8, 0xdd, 0xe1, 
+       0x8c, 0x63, 0xf9, 0x94, 0xdb, 0xd5, 0x63, 0x2f, 0xc8, 0xff, 
+       0x7f, 0x2b, 0x18, 0x4e, 0x4e, 0x99, 0x56, 0x3d, 0x21, 0xf7, 
+       0xba, 0x62, 0x86, 0x83, 0xa9, 0xab, 0xb3, 0x36, 0xae, 0xe4, 
+       0xd8, 0x8b, 0xb, 0x3d, 0x5e, 0xb7, 0x7d, 0xfa, 0xac, 0xfb, 
+       0xb7, 0xc6, 0x25, 0x8e, 0xeb, 0xec, 0x68, 0x3d, 0x99, 0x58, 
+       0x72, 0xe2, 0xd5, 0xf9, 0x27, 0x8e, 0xfe, 0x31, 0x25, 0x6d, 
+       0xcc, 0xa2, 0xf2, 0xda, 0xaa, 0xcd, 0xd3, 0x3c, 0x1e, 0x97, 
+       0x3d, 0x33, 0xfb, 0xf2, 0xc2, 0x8c, 0x71, 0xcb, 0xaa, 0x20, 
+       0x79, 0x14, 0x17, 0xf, 0xcb, 0x8d, 0xf4, 0xf8, 0xd, 0x22, 
+       0x67, 0xe4, 0x9, 0xc3, 0xba, 0xc, 0xf0, 0x7, 0x50, 0x28, 
+       0x70, 0x33, 0x11, 0xa, 0x2c, 0x49, 0xc2, 0xbc, 0xc6, 0x88, 
+       0x87, 0x69, 0xf4, 0x22, 0x63, 0x8e, 0xa6, 0x12, 0xd8, 0x4, 
+       0x35, 0x35, 0xf8, 0x86, 0xf7, 0x8f, 0x64, 0x3e, 0xf7, 0xc2, 
+       0xf6, 0x79, 0x33, 0xa7, 0x67, 0xd5, 0x3e, 0xfc, 0xd0, 0xb5, 
+       0xf9, 0xd5, 0x75, 0xcd, 0x31, 0x4f, 0x3e, 0xf3, 0xc1, 0x94, 
+       0x2b, 0xd6, 0xce, 0xac, 0xfa, 0xe1, 0xf7, 0xee, 0xd8, 0xfe, 
+       0xfb, 0xc7, 0x37, 0xce, 0xfa, 0xfd, 0x1f, 0xdf, 0x5f, 0xa2, 
+       0xfb, 0xe7, 0x68, 0xc, 0x4a, 0xca, 0xeb, 0x93, 0x5d, 0x5e, 
+       0xb7, 0xc5, 0x14, 0x51, 0x6a, 0xe9, 0xd2, 0x49, 0x8d, 0x4f, 
+       0x3e, 0xb3, 0x79, 0x51, 0x53, 0x53, 0x7b, 0xd2, 0xd1, 0x63, 
+       0xd5, 0x59, 0xcb, 0x57, 0x4c, 0xad, 0x8d, 0x89, 0x71, 0x78, 
+       0x9e, 0x7f, 0x69, 0xc7, 0x22, 0x97, 0xdb, 0xe3, 0x18, 0x97, 
+       0x99, 0xdc, 0xb4, 0x68, 0x51, 0xee, 0x29, 0xbc, 0x27, 0x65, 
+       0xd3, 0x5, 0x94, 0x7f, 0x6c, 0x64, 0x40, 0xba, 0xd2, 0xe9, 
+       0xb3, 0xc2, 0x6c, 0xd0, 0xdf, 0x76, 0x7c, 0xa, 0x9f, 0xf9, 
+       0xbf, 0xc5, 0xd7, 0x48, 0xf9, 0xbe, 0x8f, 0xe9, 0xe8, 0xef, 
+       0xf2, 0xa7, 0xc1, 0x38, 0xfa, 0x7d, 0xff, 0x35, 0xb9, 0xca, 
+       0x7b, 0x24, 0x89, 0x27, 0xfc, 0xd0, 0x82, 0x82, 0xfb, 0x4c, 
+       0x2f, 0xe0, 00, 0xe8, 0x59, 0xd0, 0x5c, 0x9f, 0x42, 0xdf, 
+       0xf9, 0x46, 0x98, 0xdb, 0xd1, 0xd0, 0xd8, 0xce, 0x9c, 0x9c, 
+       0x1c, 0x7, 0xcc, 0x70, 0xa6, 0x71, 0x41, 0xc8, 0x7, 0xec, 
+       0x43, 0xaa, 0xbb, 0x57, 0x2b, 0x53, 0xb5, 0xcf, 0xf, 0x72, 
+       0x94, 0xeb, 0xbc, 0x96, 0x87, 0xac, 0x64, 0xc3, 0x6, 0xe7, 
+       0x5c, 0xb1, 0x62, 0x85, 0x82, 0x25, 0x11, 0x3, 0xed, 0x7d, 
+       0x2f, 0x80, 0x7d, 0x37, 0xcc, 0xf7, 0x3e, 0xf4, 0xcd, 0xd7, 
+       0xe3, 0xde, 0xd3, 0xb8, 0xa6, 0x46, 0xe7, 0x48, 0x3c, 0x85, 
+       0xd6, 0xea, 0x28, 0xcc, 0xbc, 0x66, 0x23, 0xcc, 0x7a, 0x1a, 
+       0xaa, 0x36, 0x97, 0xba, 0xf3, 0xd5, 0x19, 0x45, 0x43, 0x77, 
+       0x61, 0x69, 0xcd, 0xb1, 0xdf, 0xed, 0xb1, 0x43, 0x40, 0x58, 
+       0xaf, 0x52, 0xd7, 0x8, 0x86, 0xa6, 0xa8, 0xe8, 0xf8, 0xbe, 
+       0x8e, 0xea, 0xf2, 0x6c, 0x3e, 0x6d, 0x68, 0xdc, 0x97, 0x99, 
+       0x99, 0xbd, 0xb2, 0x8a, 0xe1, 0x53, 0x4d, 0x7, 0xc7, 0x76, 
+       0xb4, 0xfa, 0xee, 0x8f, 0x19, 0xb7, 0xb4, 0x4, 0xcd, 0x6, 
+       0xf3, 0xec, 0x47, 0xf5, 0xd5, 0x7b, 0xc6, 0x56, 0x96, 0xbd, 
+       0x33, 0x2f, 0x61, 0x54, 0x6e, 0x6d, 0xde, 0x8c, 0xbb, 0xf2, 
+       0x7b, 0xba, 0x9a, 0x62, 0x4e, 0x96, 0xbd, 0x35, 0x25, 0x3d, 
+       0x63, 0x71, 0xd5, 0xcc, 0x85, 0xff, 0xb4, 0xbd, 0xec, 0xf8, 
+       0x2b, 0xb3, 0xca, 0x8a, 0x5f, 0x5b, 0xe2, 0xb3, 0x26, 0x4c, 
+       0xa3, 0xab, 0xab, 0x3a, 0x19, 0xaa, 0xb4, 0x16, 0xa5, 0xd5, 
+       0x86, 0x2e, 0x4b, 0x8d, 0x4, 0x59, 0x46, 0xca, 0x9b, 0xc8, 
+       0x1f, 0xaf, 0x5, 0xe0, 0x3, 0xca, 0xcf, 0x88, 0x83, 0x11, 
+       0x5f, 0xa0, 0x63, 0xc2, 0x40, 0x9, 0x4c, 0x1a, 0x8f, 0xcb, 
+       0x67, 0x8e, 0x3, 0xd4, 0xbd, 0x3d, 0x2e, 0xc7, 0x63, 0x7f, 
+       0xfc, 0x60, 0xc6, 0x9e, 0x7d, 0x65, 0x13, 0x6e, 0xbf, 0x65, 
+       0x41, 0xc1, 0xf5, 0xd7, 0xcd, 0xad, 0xde, 0xb8, 0xe9, 0xf0, 
+       0xb8, 0xbf, 0xbe, 0xb4, 0x6b, 0x76, 0x67, 0x57, 0x9f, 0x73, 
+       0xe7, 0xee, 0xe2, 0x9, 0x77, 0xdd, 0xb1, 0xa4, 0xe0, 0xff, 
+       0x3c, 0x74, 0x65, 0xc1, 0xdb, 0xeb, 0xf, 0xb5, 0xae, 0x5b, 
+       0x7f, 0x68, 0x4a, 0x7b, 0x47, 0x4f, 0xac, 0x13, 0x9d, 0x1e, 
+       0x4c, 0xc8, 0xb0, 0x50, 0x1, 0x72, 0x44, 0x19, 0xea, 0xa1, 
+       0x7, 0xd7, 0xec, 0xf9, 0xf1, 0xcf, 0xdf, 0xb8, 0x2, 0x3, 
+       0x76, 0xf6, 0xc7, 0x9e, 0x78, 0x7f, 0x7e, 0x6c, 0x6c, 0x14, 
+       0x26, 0x6d, 0x3c, 0xe, 0xc, 0x8a, 0x79, 0x1e, 0xfe, 0xe7, 
+       0xab, 0xf6, 0x28, 0x1b, 0x1b, 0x15, 0xd6, 0x71, 0x78, 0xa2, 
+       0x39, 0xce, 0xa7, 0xd4, 0xdc, 0x2c, 0x7a, 0x4d, 0x6d, 0x5b, 
+       0xb4, 0x9, 0x39, 0xf0, 0xb7, 0xca, 0xfc, 0xe, 0xe6, 0x2b, 
+       0xdf, 0xc5, 0xa8, 0x3, 0x28, 0x4, 0xa8, 0x7d, 0xdf, 0xef, 
+       0xe3, 0x83, 0x80, 0x99, 0xe9, 0x38, 0xa0, 0x99, 0xa3, 0x67, 
+       0xcc, 0x98, 0x71, 0xc3, 0xa8, 0x51, 0xa3, 0xbe, 00, 0x4b, 
+       0x21, 0x6f, 0xce, 0x9c, 0x39, 0x8e, 0x9, 0x13, 0x26, 0x38, 
+       0x68, 0x9e, 0x5e, 0x68, 0x22, 0xb0, 0x9, 0xe6, 0xde, 0xbe, 
+       0x38, 0x95, 0x37, 0x65, 0xb1, 0x2e, 0xce, 0x89, 0xe3, 0xbb, 
+       0xd5, 0xbe, 0x7d, 0x3e, 0x2d, 0x7e, 0xbe, 0x1, 0x6e, 0xe5, 
+       0x87, 0x7f, 0xb0, 0xce, 0xb1, 0x64, 0xc9, 0x12, 0x7, 0xfa, 
+       0xea, 0x71, 0xe5, 0xe5, 0xe5, 0x77, 0xe6, 0xe7, 0xe7, 0xdf, 
+       0xe, 0xa0, 0x17, 0x9f, 0x3a, 0x75, 0xea, 0xf, 0xc7, 0x8e, 
+       0x1d, 0x5b, 0x8f, 0x11, 0xfb, 0x5e, 0xbc, 0x23, 0x9a, 0x5c, 
+       0x7c, 0xa, 0x80, 0x38, 0x6d, 0xb6, 0x4b, 0x1b, 0x1c, 0xa4, 
+       0xc9, 0xa5, 0x8e, 0xa5, 0xee, 0xf4, 0x35, 0x15, 0x21, 0x3a, 
+       0x6a, 0x8, 0x7b, 0xed, 0x10, 0xa, 0x6a, 0x6f, 0x3a, 0x7f, 
+       0x5c, 0xd, 0x72, 0x6b, 0x31, 0xfb, 0x85, 0x33, 0x33, 0x97, 
+       0xd6, 0x54, 0x96, 0x6e, 0x40, 0x9e, 0xa6, 0xad, 0xa5, 0xa9, 
+       0x10, 0x45, 0x5d, 0xa1, 0xad, 0xcf, 0x96, 0xa6, 0x63, 0xe3, 
+       0x18, 0xd1, 0x66, 0x77, 0xf6, 0x65, 0x8c, 0x5d, 0xd0, 0x80, 
+       0x4, 0x3, 0xb2, 0xed, 0xf5, 0x7a, 0x54, 0xc9, 0x89, 0xd7, 
+       0xa6, 0x37, 0x37, 0x1e, 0xcd, 0xce, 0x9e, 0xb0, 0xf6, 0x68, 
+       0xe6, 0xf8, 0x15, 0x55, 0x75, 0x35, 0xbb, 0xc7, 0x9d, 0x2c, 
+       0xdb, 0x30, 0xdb, 0xe3, 0xea, 0x71, 0x36, 0x37, 0x1c, 0x99, 
+       0x30, 0x3e, 0xe7, 0xea, 0x82, 0xa9, 0x33, 0xee, 0x2e, 0xa8, 
+       0xa9, 0xd8, 0xd6, 0x5a, 0x53, 0xbd, 0x6d, 0x8a, 0xab, 0xaf, 
+       0x3, 0x6b, 0x15, 0x9c, 0x9c, 0xe2, 0x41, 0x67, 0x16, 0xe8, 
+       0xc6, 0x3f, 0x7e, 0x4, 0xb3, 0x80, 0x63, 0xda, 0xf4, 0xe5, 
+       0xfb, 0x10, 0xd4, 0xd7, 0xe4, 0x45, 0x3f, 0xa, 0x7, 0x6e, 
+       0xbe, 0x28, 0x9, 0x88, 0xcf, 0x29, 0x3, 0xe5, 0x72, 0xb3, 
+       0xdf, 0xed, 0xb5, 0x95, 0x9f, 0x6c, 0x8a, 0xff, 0xf5, 0xef, 
+       0xdf, 0x5d, 0x84, 0xc1, 0xd0, 0xa8, 0x6f, 0x7c, 0xf9, 0xfa, 
+       0x1d, 0x39, 0x39, 0x63, 0xba, 0x1e, 0x7b, 0xfc, 0x83, 0xe9, 
+       0xdb, 0x76, 0x9c, 0xc8, 0xc5, 0x94, 0xaa, 0x27, 0x3e, 0x2e, 
+       0xba, 0xaf, 0xa3, 0xb3, 0x37, 0xfa, 0xc9, 0xa7, 0xb6, 0x2e, 
+       0x28, 0x29, 0x69, 0x28, 0xfd, 0xd8, 0x5d, 0xcb, 0x4a, 0x72, 
+       0x72, 0xd2, 0xdb, 0xff, 0xfc, 0xf4, 0xb6, 0x59, 0x87, 0x8e, 
+       0x54, 0x8d, 0x5d, 0x5e, 0xd6, 0x54, 0x97, 0x95, 0x35, 0xba, 
+       0xdb, 0x5a, 0x9a, 0x79, 0x73, 0x72, 0x5a, 0x56, 0x2d, 0x9f, 
+       0x52, 0xb4, 0x65, 0xfb, 0x89, 0x29, 0x47, 0xa, 0xaa, 0xd8, 
+       0x42, 0x6a, 0xa0, 0x5e, 0x7b, 0xd5, 0xec, 0xa3, 0x79, 0x93, 
+       0x32, 0x3b, 0xdd, 0xae, 0x81, 0x2d, 0xa2, 0xf5, 0x7d, 0x1d, 
+       0xc6, 0x10, 0x9, 0x2a, 0xdb, 0xb4, 0x83, 0x21, 0xfb, 0xe, 
+       0x96, 0xa5, 0xee, 0xde, 0x5b, 0x32, 0x16, 0xe5, 0xe8, 0x6e, 
+       0xef, 0xe8, 0x3d, 0x89, 0xe7, 0xfc, 0x2e, 0x92, 0xf8, 0xbe, 
+       0x2b, 0xff, 0xff, 0x41, 0x40, 0x4d, 0x3e, 0x91, 0xf, 0xf4, 
+       0xd9, 0xe7, 0x71, 0xa0, 0x66, 0xd3, 0xd0, 0x6f, 0xfe, 0x14, 
+       0x4c, 0xcf, 0xcf, 0x62, 0x60, 0x29, 0x6a, 0xde, 0xbc, 0x79, 
+       0xf1, 0x4, 0xb, 00, 0x8e, 0xc7, 0x17, 0x9e, 0x7c, 0xc0, 
+       0x3e, 0xa4, 0xfa, 0x5c, 0xf1, 0x6a, 0xca, 0xd4, 0x45, 0x6a, 
+       0xc2, 0xc4, 0x99, 0x50, 0x50, 0x60, 0x28, 0xfe, 0x15, 0x1d, 
+       0xdf, 0x73, 0x51, 00, 0x5c, 0xb8, 0x84, 0xd9, 0x1, 0x5, 
+       0xe7, 0x98, 0x3b, 0x77, 0xae, 0x3, 0xe5, 0x9e, 0x79, 0xf0, 
+       0xe0, 0xc1, 0x1f, 0xa5, 0xa6, 0xa6, 0x7e, 0x1f, 0xd3, 0x6e, 
+       0x7f, 0xc1, 0x18, 0xdc, 0x33, 0x30, 0xe7, 0x9b, 0x10, 0x97, 
+       0xda, 0x9c, 00, 0xb7, 0x82, 0x5c, 0x34, 0x39, 0xc1, 0x2e, 
+       0x9a, 0x3c, 0x64, 0xdd, 0xe2, 0x39, 0xee, 0x7b, 0xfa, 0x3c, 
+       0x9e, 0xee, 0xee, 0xb2, 0xd2, 0x37, 0xa7, 0x64, 0x66, 0x2d, 
+       0xab, 0x8e, 0x8a, 0x49, 0x72, 0x73, 0xc6, 0x87, 0x60, 0xf5, 
+       0x5b, 0x77, 0x88, 0x16, 0x1e, 0xe0, 0xce, 0xb8, 0x44, 0x77, 
+       0x42, 0xd2, 0xf8, 0xba, 0x8e, 0xb6, 0x93, 0x99, 0xed, 0x2d, 
+       0x65, 0x19, 0x1e, 0x58, 0xcb, 0x50, 0x22, 0xaa, 0xad, 0xb5, 
+       0x2c, 0x3, 0x2f, 0xaa, 0x51, 0xa3, 0x27, 0x57, 0x19, 0xe, 
+       0x5a, 0xf9, 0xbe, 0x79, 0xf3, 0xae, 0xae, 0xc6, 0x98, 0x92, 
+       0x82, 0x97, 0xe6, 0xd1, 0xcc, 0x9e, 0x3e, 0xef, 0xd3, 0x3b, 
+       0x13, 0x92, 0xc6, 0x75, 0x16, 0x1f, 0x7b, 0x65, 0x7a, 0x63, 
+       0xed, 0xc1, 0x5c, 0xc3, 0x16, 0xe5, 0xb1, 0x47, 0xc5, 0xf4, 
+       0xb9, 0x5c, 0x3d, 0xd1, 0xa5, 0xc5, 0x6f, 0x2c, 0xe8, 0xe8, 
+       0xa8, 0x2e, 0x9d, 0x98, 0x77, 0x6d, 0x49, 0xdc, 0xa8, 0xac, 
+       0xf6, 0xb2, 0xa2, 0x37, 0x66, 0xb5, 0x34, 0x17, 0x8d, 0xed, 
+       0xec, 0xaa, 0xa9, 0x8e, 0x4f, 0x1a, 0xd7, 0x1, 0x70, 0xfb, 
+       0x3a, 0xe, 0xa7, 0x1, 0x2d, 0x98, 0x1c, 0x54, 0xd8, 0xec, 
+       0x8f, 0x3c, 0xf2, 0x8, 0xcb, 0x15, 0xa0, 0x1f, 0xfc, 0xe0, 
+       0x7, 0x7c, 0x81, 0xad, 0x83, 0xd6, 0x4c, 0xf0, 0x29, 0xd0, 
+       0x9c, 0x46, 0x58, 0x91, 0x99, 0x39, 0x2a, 0xed, 0xca, 0xb5, 
+       0xd3, 0xda, 0xde, 0xdb, 0x58, 0x90, 0xf5, 0xeb, 0xdf, 0xbd, 
+       0xbb, 0x6c, 0x42, 0xf6, 0xe8, 0x96, 0x7f, 0xf9, 0xfa, 0xf5, 
+       0x7b, 0xfb, 0x5c, 0x1e, 0xfb, 0x2f, 0xff, 0xeb, 0xed, 0x85, 
+       0xf9, 0x5, 0x95, 0x59, 0x31, 0xd1, 0x4e, 0x17, 0xc1, 0x85, 
+       0xf8, 0xba, 0xb3, 0x40, 0x4e, 0x97, 0x94, 0xd6, 0xa7, 0x1e, 
+       0x47, 0xff, 0x7b, 0xf9, 0xf2, 0x49, 0xb5, 0x57, 0xae, 0x99, 
+       0x5e, 0x79, 0xa2, 0xa8, 0x6e, 0xd4, 0xba, 0xf5, 0x7, 0xf3, 
+       0x52, 0x92, 0x63, 0x3a, 0xb2, 0xc6, 0x25, 0x3, 0xe0, 0x8c, 
+       0xee, 0x73, 0x73, 0xe6, 0x66, 0x37, 0x7e, 0xf0, 0xe1, 0xb1, 
+       0xec, 0x9e, 0x1e, 0x17, 0xf3, 0x34, 0x90, 0xe7, 0xa9, 0x6f, 
+       0x7e, 0xed, 0x86, 0xbd, 0x3e, 0xcc, 0xf8, 0xe2, 0xc0, 0x74, 
+       0x41, 0xb2, 0xa1, 0x1d, 0xf9, 0xd0, 0xd5, 0xd9, 0x6d, 0x7f, 
+       0xeb, 0xdd, 0x83, 0xd9, 0x47, 0x8f, 0x55, 0x8d, 0x3e, 0x59, 
+       0xd1, 0xd8, 0x90, 0x7f, 0xb8, 0x72, 0x43, 0x57, 0x57, 0xdf, 
+       0x7a, 0xa4, 0x47, 0x4d, 0x60, 0x35, 0xf9, 0xac, 0x1a, 0x80, 
+       0x89, 0xf3, 0xdb, 0xad, 0xdf, 0x4f, 0x20, 0x8b, 0x8b, 0x46, 
+       0x38, 0x6, 0x83, 0x45, 0xf3, 0xa7, 0x4d, 0x9b, 0xf6, 0x3, 
+       0x8, 0xdf, 0xcf, 0xa6, 0x4c, 0x99, 0xb2, 0xe4, 0xf2, 0xcb, 
+       0x2f, 0x4f, 0x58, 0xb8, 0x70, 0xa1, 0x93, 0x2, 0x2a, 0x1a, 
+       0x4, 0xf1, 0x2e, 0x28, 0x9d, 0x6, 0x76, 0x9c, 0x9a, 0x32, 
+       0x6d, 0x89, 0xca, 0xc9, 0xf1, 0x1, 0x9b, 0x85, 0x4a, 0x1a, 
+       0x95, 0xa6, 0xec, 0xe, 0xa7, 0xaa, 0xab, 0x6d, 0x80, 0x69, 
+       0x59, 0xa9, 0xe2, 0x62, 0x63, 0x14, 0xc6, 0x6, 0x2e, 0x68, 
+       0x79, 0x25, 0x73, 0xf2, 0x8f, 0x7c, 0x84, 0x25, 0xe4, 0x1c, 
+       0x3f, 0x7e, 0x7c, 0xc, 00, 0x37, 0x17, 0xb, 0x6f, 0x3e, 
+       0x83, 0x46, 0x74, 0x3a, 0x2c, 0xa4, 0x5a, 0x68, 0x74, 0xae, 
+       0x9a, 0x13, 0xd9, 0x94, 0xba, 0xa2, 0x88, 0xd1, 0xf1, 0x5a, 
+       0xc2, 0xf4, 0x45, 0xc3, 0x51, 0x7e, 0xb5, 0xc, 0x23, 0xbd, 
+       0xa6, 0xae, 0xce, 0xfa, 0x4, 0xd3, 0xe3, 0x4a, 0xec, 0xee, 
+       0x6c, 0x18, 0x4f, 0x2b, 0x2f, 0x2e, 0x36, 0xb5, 0x17, 0x91, 
+       0x21, 0x5e, 0xd0, 0xe8, 0xd0, 0x94, 0x36, 0xe8, 0x48, 0xf8, 
+       0xf8, 0x8f, 0x6b, 0x3a, 0x5e, 0x23, 0x59, 0x71, 0x1e, 0x77, 
+       0x8f, 0xd1, 0x7c, 0xea, 0x78, 0x16, 0x6, 0xc6, 0xa2, 0x52, 
+       0x52, 0x26, 0x55, 0x2b, 0x8f, 0xdb, 0x56, 0x51, 0xbe, 0x71, 
+       0x16, 0xf2, 0x50, 0xb9, 0x93, 0xaf, 0x3b, 0x9c, 0x90, 0x90, 
+       0xd9, 0xc5, 0xb8, 0xd, 0x35, 0xfb, 0xd3, 0x8b, 0xb, 0x5f, 
+       0x5c, 0x14, 0x97, 0x90, 0xd9, 0x32, 0x6b, 0xde, 0x7d, 0xfb, 
+       0xc, 0xaf, 0xc7, 0x28, 0xcc, 0x7f, 0x6a, 0x61, 0xcb, 0xa9, 
+       0xa2, 0x2c, 0xbb, 0x23, 0xba, 0x1f, 0x46, 0x58, 0xec, 0xce, 
+       0xf6, 0xaa, 0x54, 0x98, 0xf6, 0x49, 0xd0, 0xfc, 0x35, 0x19, 
+       0xe3, 0x96, 0x56, 0x32, 0x5c, 0x53, 0xb1, 0x65, 0xaa, 0x33, 
+       0x2a, 0xb1, 0x23, 0x11, 0x7d, 0xf3, 0xc6, 0xba, 0xfc, 0xf4, 
+       0x8e, 0xf6, 0x2a, 0x5a, 0xa, 0xbb, 0xe0, 0xd8, 0xa8, 0xd1, 
+       0x51, 0x7e, 0xe9, 0x53, 0x76, 0xbd, 0xc0, 0x72, 0x3f, 0xed, 
+       0xcd, 0x8f, 0x3e, 0x13, 0x91, 0x69, 0x9a, 0x98, 0xc2, 0x6b, 
+       0xaf, 0x1f, 0x18, 0xff, 0xc2, 0x2b, 0xbb, 0x17, 0xde, 0x76, 
+       0xd3, 0x82, 0x23, 0xd7, 0x5f, 0x3b, 0xb7, 0x7a, 0xfb, 0xce, 
+       0x13, 0x63, 0x9e, 0x7b, 0x71, 0xd7, 0x9c, 0xae, 0xae, 0x5e, 
+       0x27, 0x80, 0x4d, 0xe0, 0xc, 0x20, 0x2c, 0x8c, 0xf2, 0x1c, 
+       0x2f, 0xaa, 0x1b, 0xf3, 0x8b, 0x7f, 0x7f, 0x3b, 0xe1, 0x63, 
+       0x77, 0x5c, 0x56, 0xf0, 0x4f, 0x9f, 0xbd, 0xa2, 0xe0, 0xad, 
+       0x77, 0xe, 0x65, 0x3d, 0xf3, 0xfc, 0xae, 0x39, 0x7d, 0xbd, 
+       0xde, 0x23, 0xcb, 0x97, 0xe6, 0xf9, 0x86, 0x72, 0xf1, 0xa6, 
+       0xd3, 0xe6, 0x30, 0xe3, 0xe3, 0xa3, 0x7b, 0x9b, 0x5b, 0xba, 
+       0x12, 0x98, 0x50, 0x2c, 0x1a, 0xb, 0x34, 0xa6, 0x86, 0xc7, 
+       0xcd, 0xdc, 0xcf, 0x4c, 0xe5, 0x27, 0x1b, 0xe3, 0xb7, 0x6c, 
+       0x3b, 0x96, 0x79, 0xaa, 0xb9, 0xd3, 0x75, 0xf4, 0x78, 0x6d, 
+       0x61, 0x73, 0x73, 0xe7, 0x7b, 0x78, 0xab, 0x8, 0x8e, 0x2d, 
+       0xbe, 0x24, 0x42, 0x26, 0x30, 0x2c, 0xe, 0x41, 0x2d, 0xc, 
+       0x22, 0x24, 0xd2, 0xb0, 0xd1, 0x27, 0xb8, 0x9d, 0xf3, 0xe7, 
+       0xcf, 0xbf, 0x1, 0x20, 0xf8, 0xa, 0x9a, 0xea, 0x5c, 0x98, 
+       0xde, 0x51, 0x10, 0x40, 0x3b, 0xba, 0xd5, 0x7c, 0xef, 0xa2, 
+       0x22, 0x1, 0xb6, 0xcb, 0x9d, 0xa0, 0xa6, 0x4e, 0x5b, 0xa4, 
+       0x72, 0x72, 0x67, 0x29, 0x8c, 0x8b, 0xf4, 0x2b, 0xe3, 0x84, 
+       0x89, 0x33, 0x30, 0xcd, 0x6b, 0xaa, 0x13, 0x27, 0xf6, 0xa8, 
+       0xbd, 0x7b, 0x2f, 0xbc, 0x89, 0xde, 0xaf, 0x70, 0xfe, 0xb, 
+       0x34, 0x9e, 0x6a, 0xed, 0xda, 0xb5, 0x31, 0xcb, 0x97, 0x2f, 
+       0x57, 0x47, 0x8f, 0x1e, 0xbd, 0x6, 0x26, 0xfb, 0x5a, 0x2c, 
+       0xb3, 0x3d, 0x89, 0x1, 0xb8, 0x5f, 0x1f, 0x3e, 0x7c, 0xf8, 
+       0x1d, 0x44, 0xa3, 0xac, 0xd1, 0x89, 0x26, 0x17, 0x81, 0x97, 
+       0x8f, 0x15, 0xa0, 0x33, 0x45, 0xd6, 0x33, 0xef, 0x57, 0xc2, 
+       0x7b, 0x11, 0x9a, 0x76, 0x4d, 0x4f, 0x77, 0xe3, 0x3c, 0x97, 
+       0xbb, 0x73, 0x42, 0x47, 0x47, 0x65, 0x72, 0xe6, 0xb8, 0xcb, 
+       0x6a, 0xd0, 0x9f, 0xf6, 0xf8, 0xa4, 0x23, 0x58, 0x73, 0xf7, 
+       0xbf, 0xce, 0xc8, 0x5e, 0x5c, 0x53, 0x5a, 0xf4, 0x96, 0x87, 
+       0x7d, 0xf5, 0xa6, 0x86, 0xfc, 0x4c, 0x67, 0x74, 0x52, 0xf, 
+       0x33, 0x70, 0x38, 0x62, 0x7b, 0xd2, 0x33, 0xe6, 0x34, 0xa2, 
+       0xbd, 0x30, 0xaa, 0x2b, 0x76, 0x64, 0x9e, 0x2c, 0x7d, 0x7f, 
+       0xe6, 0xf8, 0xdc, 0x35, 0x85, 0x59, 0xe3, 0x57, 0x56, 0x35, 
+       0xd4, 0x1f, 0x4e, 0x2d, 0x3b, 0xb1, 0x6e, 0xb6, 0xcb, 0xd5, 
+       0xeb, 0x8c, 0x82, 0xb6, 0x3e, 0x2d, 0x86, 0x7c, 0xd3, 0x4f, 
+       0x76, 0xbb, 0xa7, 0xad, 0xf5, 0x64, 0xfa, 0xe1, 0x43, 0x4f, 
+       0x5e, 0x36, 0x69, 0xca, 0x75, 0x47, 0xa6, 0xcf, 0xfd, 0x58, 
+       0x41, 0x55, 0xf9, 0xe6, 0x71, 0x65, 0xc5, 0xeb, 0xe6, 0x63, 
+       0xb4, 0xeb, 00, 0xda, 0x3d, 0x12, 0xff, 0x53, 0x26, 0x49, 
+       0xbe, 0x3b, 0xa7, 0x7d, 0xdf, 0x5d, 0xcb, 0x7f, 0x18, 0xb1, 
+       0x22, 0xef, 0x88, 0xe5, 0x53, 0x3d, 0x22, 0xd8, 0xd4, 0x9c, 
+       0x74, 0x9c, 0xab, 0xa1, 0xfb, 0xea, 0xc2, 0x5, 0x13, 0xa7, 
+       0x7e, 0xfa, 0x93, 0x2b, 0x9a, 0xfb, 0x5c, 0xee, 0xa8, 0x49, 
+       0x13, 0xd3, 0xbb, 0x5f, 0x7f, 0xfb, 0xe0, 0x84, 0x57, 0xff, 
+       0xb6, 0x97, 0xad, 0xab, 0x7, 0xfd, 0x62, 0x61, 0x2a, 0xa2, 
+       0x86, 0x26, 0xe, 0xbe, 0xa1, 0x29, 0x34, 0x3f, 0x7a, 0xfb, 
+       0xe2, 0xc3, 0x97, 0xaf, 0x9c, 0x5a, 0x5f, 0x54, 0x52, 0x9f, 
+       0x10, 0x1b, 0x13, 0xe5, 0xc9, 0x1a, 0x97, 0x12, 0x30, 0xcf, 
+       0x9f, 0xfd, 0xeb, 0xce, 0xc9, 0xaf, 0xaf, 0x3b, 0x30, 0xd7, 
+       0x9a, 0xc2, 0xdd, 0x77, 0x2c, 0xde, 0x77, 0xfb, 0xad, 0x8b, 
+       0xca, 0xad, 0xf7, 0x82, 0xc3, 0x14, 0xe0, 0x1d, 0xbb, 0x4a, 
+       0xd2, 0xa, 0x8e, 0x56, 0xa7, 0x56, 0x54, 0x9d, 0x6a, 0x28, 
+       0x2e, 0x69, 0x38, 0x82, 0x7b, 0x1f, 0x22, 0x1e, 0x5b, 0x7b, 
+       0x56, 00, 0xf3, 0xa0, 0xe3, 0xda, 0x6a, 0x5e, 0xd3, 0x51, 
+       0x38, 0xb4, 0x49, 0x7, 0x9f, 0xc4, 0x86, 0x4c, 0x5a, 0x7a, 
+       0xd, 0xea, 0xd9, 0xb3, 0x67, 0x2f, 0x47, 0xff, 0xf0, 0x87, 
+       0xf1, 0xf1, 0xf1, 0xd9, 0x8b, 0x16, 0x2d, 0xd2, 0xa6, 0xb7, 
+       0x8f, 0x4d, 0x3a, 0xfe, 0x45, 0xf5, 0x8f, 0xc0, 0xde, 0xbf, 
+       0x3f, 0x5f, 0x9b, 0xe2, 0x53, 0xa7, 0x2f, 0x6, 0xb0, 0x7d, 
+       0x1a, 0x9b, 0xbc, 0xc1, 0xe0, 0xa7, 0x36, 0xcb, 0x19, 0x26, 
+       0x11, 0xdc, 0xa5, 0x65, 0x47, 0x54, 0xf1, 0x89, 0x7d, 0xd0, 
+       0xde, 0x3d, 0x6a, 0xf1, 0xa2, 0xf3, 0x37, 0x8a, 0x3e, 0x1c, 
+       0xa6, 0x51, 0x4e, 0xd1, 0x2f, 0x57, 0x7b, 0xf6, 0xec, 0xe9, 
+       0x82, 0xb9, 0x5e, 0x8d, 0x79, 0xf4, 0x47, 0xb, 0xb, 0xb, 
+       0xa9, 0xc5, 0xc4, 0x1a, 0x13, 0x93, 0xdd, 0x5a, 0x9f, 0x52, 
+       0x97, 0x94, 0x63, 0x2e, 0xc0, 0xe1, 0xa8, 0xa2, 0xc8, 0x73, 
+       0x1e, 0xaa, 0x7b, 0xd5, 0xa8, 0xe4, 0x9, 0x13, 0x13, 0x93, 
+       0xb2, 0xd3, 0xd2, 0xc7, 0xce, 0xab, 0x4d, 0x19, 0x3d, 0xb9, 
+       0xdd, 0x3f, 0xb8, 0x86, 0x68, 0xe1, 0x69, 0xff, 0x9e, 0xdf, 
+       0x2e, 0x69, 0x3e, 0x55, 0x94, 0x1d, 0x17, 0x3f, 0xf6, 0x94, 
+       0xd3, 0x99, 0xd0, 0xdd, 0xd2, 0x5c, 0x9c, 0x35, 0x66, 0xec, 
+       0xfc, 0xe2, 0xd9, 0xf3, 0x3e, 0xc5, 0x51, 0x7f, 0xd5, 0xd1, 
+       0x5e, 0x1d, 0x7, 0x8e, 0x1b, 0x49, 0x89, 0xd9, 0x9d, 0x15, 
+       0xe5, 0x9b, 0xb3, 0xca, 0x4a, 0xdf, 0x9b, 0x85, 0xa1, 0x5d, 
+       0xf, 0xd6, 0xf3, 0xe, 0x9, 0x23, 0xb4, 0x28, 0x60, 0x5, 
+       0xe4, 0x8f, 0xcb, 0x5e, 0x5a, 0xd3, 0xd6, 0x72, 0x32, 0xde, 
+       0x1e, 0x15, 0xd7, 0x57, 0x5e, 0xf2, 0xee, 0x84, 0xea, 0xaa, 
+       0x9d, 0x7, 0x90, 0xfc, 0xaf, 0x99, 0x5, 0x9c, 0xc8, 0xb4, 
+       0xb5, 0x91, 0x43, 0xa3, 0x73, 0x1a, 0xd0, 0xfc, 0xf8, 0xa1, 
+       0x13, 0x4, 0x22, 0x2f, 0x37, 0xbd, 0x3, 0x53, 0x61, 0xe, 
+       0xe, 0x7a, 0x15, 0x9d, 0xa8, 0x4d, 0xb5, 0xd9, 0xec, 0x5e, 
+       0xae, 0x6, 0x93, 0xd6, 0x8, 0x49, 0xb3, 0xc1, 0xf0, 0xb7, 
+       0x33, 0x18, 0xe2, 0xd3, 0x3d, 0x75, 0x5f, 0x16, 0x1c, 0xe4, 
+       0x72, 0xb9, 0x3c, 0x8e, 0x92, 0x92, 0xfa, 0xe4, 0xcb, 0x97, 
+       0xe7, 0xd5, 0xe7, 0xe5, 0xa4, 0xb1, 0x90, 0x68, 0x4c, 0x7d, 
+       0xdf, 0x5c, 0x56, 0xde, 0x18, 0xf, 0x8d, 0x3e, 0x93, 0xb7, 
+       0x30, 0x95, 0x56, 0xdb, 0xda, 0xd6, 0x1d, 0xd7, 0xd8, 0xd4, 
+       0x91, 0xf4, 0xea, 0x1b, 0x7, 0xe6, 0x2c, 0x5b, 0x92, 0x5b, 
+       0x97, 0x31, 0x36, 0x99, 0x1f, 0x34, 0x80, 0xba, 0xba, 0x5d, 
+       0xb6, 0xf7, 0x36, 0x15, 0x64, 0x55, 0x54, 0x36, 0x3b, 0x8f, 
+       0x14, 0x56, 0x95, 0x34, 0x37, 0x77, 0xed, 0x46, 0x24, 0x32, 
+       0x5a, 0x6, 0x64, 0xac, 0xad, 0xbb, 0xb5, 0xf2, 0xd9, 0x90, 
+       0xb1, 0x75, 0x13, 0x93, 0x8e, 0xfc, 0xa0, 0x20, 0x44, 0x61, 
+       0xa4, 0x7b, 0x26, 0xfa, 0xd5, 0x8f, 0xa0, 0xe1, 0x9a, 0xbf, 
+       0x6c, 0xd9, 0xb2, 0x58, 0x5c, 0xe3, 0xf6, 0xc5, 0x4b, 0x3e, 
+       0x8d, 0x9d, 0x8f, 0xf5, 0xe1, 0x9, 0x6a, 0x1a, 0x81, 0x3d, 
+       0x89, 0xc0, 0x3e, 0xdd, 0x70, 0x87, 0x2a, 0xf9, 0x84, 0x9, 
+       0xd3, 0xf5, 0xd7, 0x17, 0x1, 0xe0, 0x7b, 0xf6, 0x68, 0xb9, 
+       0x84, 0x9, 0x9f, 0x13, 0x2a, 0xea, 0x5, 0xbf, 0xc7, 0x6, 
+       0x95, 0x65, 0x83, 0x8b, 0xc3, 0x88, 0x7a, 0xde, 0x8e, 0x1d, 
+       0x3b, 0x7e, 0x37, 0x66, 0xcc, 0x98, 0x7c, 00, 0xfe, 0xa7, 
+       0x70, 0x85, 0x28, 0xa0, 0x15, 0xe4, 0xac, 0x63, 0x7e, 0x3c, 
+       0xe5, 0x50, 0xea, 0x98, 0x42, 0xc6, 0xfb, 0x94, 0x5, 0xd6, 
+       0x73, 0x29, 0x4, 0xaf, 0xa9, 0xb5, 0xa5, 0x6c, 0x45, 0x77, 
+       0xf7, 0xa9, 0xe9, 0x1e, 0x77, 0xd7, 0x84, 0xde, 0xde, 0xc6, 
+       0xb8, 0x8c, 0x71, 0x8b, 0xeb, 0x20, 0xd3, 0xe4, 0x9d, 0x4f, 
+       0x86, 0x11, 0x31, 0x98, 0xc6, 0x8e, 0x9b, 0x57, 0x49, 0x70, 
+       0x77, 0x75, 0xd6, 0xa5, 0xf4, 0x74, 0x37, 0x25, 0xf2, 0x79, 
+       0x46, 0xd6, 0xc2, 0x4a, 0x4c, 0xcd, 0x68, 0x4a, 0x4c, 0x1e, 
+       0x47, 0x5, 0xa2, 0xa9, 0xad, 0xbd, 0x3c, 0x5, 0x65, 0xc7, 
+       0x9a, 0xb, 0x2b, 0xb0, 0x4f, 0xef, 0xc7, 0xd0, 0xf8, 0x60, 
+       0x87, 0xc0, 0x4f, 0xb0, 0xc, 0xbd, 0xe8, 0xa3, 0x3b, 0xda, 
+       0xdb, 0x2b, 0x92, 0xd, 0xfb, 0xd2, 0x9a, 0xe4, 0xb4, 0x9c, 
+       0x76, 0x74, 0xe, 0x3c, 0x5a, 0x42, 0x25, 0x52, 0x68, 0x9f, 
+       0xe5, 0xa5, 0xb, 0xa4, 0x15, 0x19, 0xb8, 0x99, 0xa8, 0x9, 
+       0xfe, 0x60, 0x4, 0x90, 0x80, 0x74, 0x40, 0x5b, 0x1b, 0x16, 
+       0x16, 0x10, 0xd8, 0xb8, 0x36, 0x47, 0xa7, 0xc4, 0x77, 0x62, 
+       0x88, 0xdb, 0xdb, 0xd3, 0xe7, 0x72, 0xb4, 0xb6, 0x76, 0xc7, 
+       0x2, 0xd4, 0x81, 0xc, 0xf9, 0xa1, 0x76, 0x5e, 0x33, 0x1d, 
+       0xb, 0x51, 0xb3, 0xfc, 0xe6, 0xf, 0x1b, 0x17, 0x62, 0xb0, 
+       0xce, 0xc1, 0x46, 0xe0, 0xbe, 0x4f, 0x2e, 0xcb, 0xaf, 0xa9, 
+       0x6b, 0x8d, 0xfb, 0xed, 0x1f, 0x3e, 0x5c, 0x89, 0xb9, 0xf1, 
+       0xa8, 0x5f, 0x3f, 0xb6, 0x69, 0xc1, 0x8f, 0xbe, 0x7b, 0xcb, 
+       0x76, 0xcb, 0x2b, 0x3a, 0x58, 0x5b, 0xdf, 0x1e, 0xfd, 0xfe, 
+       0x7, 0x85, 0x59, 0xd5, 0x35, 0x2d, 0x3d, 0x87, 0x8f, 0x56, 
+       0x1f, 0xe9, 0xeb, 0xf3, 0x50, 0x5b, 0xb3, 0x6f, 0x62, 0x6d, 
+       0xd1, 0xa4, 0x55, 0xa7, 0xcf, 0x4a, 0x66, 0x79, 0x58, 0x72, 
+       0x56, 0x87, 0x7c, 0x1, 0x79, 0x11, 0x5, 0xe1, 0x99, 0x80, 
+       0x3e, 0xde, 0x77, 0x31, 0x9d, 0x75, 0x35, 0xfa, 0xd2, 0x51, 
+       0xe8, 0x63, 0x63, 0x1d, 0xc, 0xb1, 0x7f, 0xf1, 0x92, 0xf, 
+       0xd8, 0x87, 0x95, 0xdb, 0x93, 0xa0, 0xa6, 0xcf, 0x58, 0xac, 
+       0x26, 0xe6, 0xcc, 0xc2, 0x7, 0x6, 0x58, 0x3e, 0x68, 0xc1, 
+       0x9, 0x70, 0xb6, 0x1, 0x7f, 0xf, 00, 0x97, 0xf, 0x61, 
+       0x43, 0x8b, 0x35, 0x3, 0x31, 0x5, 0x5, 0x5, 0x8b, 0xb0, 
+       0x86, 0xe0, 0x59, 0x34, 0xc2, 0x9b, 0xc0, 0x83, 0x7f, 0xc7, 
+       0x4e, 0xb6, 0x93, 0x88, 0xc3, 0x7a, 0x67, 0x3d, 0x8b, 0x80, 
+       0x59, 0xeb, 0x99, 0xf7, 0xe8, 0x68, 0xc2, 0x33, 0x1e, 0x95, 
+       0xcb, 0xa6, 0xbe, 0xde, 0xb6, 0xda, 0xba, 0xba, 0xfc, 0xa5, 
+       0x6e, 0x77, 0xcf, 0x84, 0xde, 0x9e, 0xb6, 0x89, 0x59, 0x13, 
+       0x57, 0x54, 0xc5, 0xc4, 0x24, 0xb9, 00, 0xf0, 0x90, 0x15, 
+       0x9f, 0x99, 0xbd, 0xb4, 0xee, 0xf8, 0xd1, 0xd7, 0x5c, 0x98, 
+       0x39, 0x8a, 0x62, 0xdf, 0x3b, 0xca, 0x99, 0xd8, 0x99, 0x9e, 
+       0x39, 0xfb, 0x14, 0xfb, 0xe7, 0xc1, 0x64, 0xb7, 0x45, 0x61, 
+       0x70, 0xe8, 0xb4, 0xfc, 0xe3, 0x39, 0xca, 0x63, 0x98, 0xb1, 
+       0x71, 0x29, 0x9d, 0x88, 0xef, 0x75, 0x7b, 0xfb, 0x1c, 0xae, 
+       0xde, 0x76, 0x58, 0x13, 0xa7, 0xe3, 0xe8, 0x11, 0x72, 0xbb, 
+       0x83, 0xd, 0x2, 0x6e, 0xa3, 0xcf, 0xf, 0x47, 0x60, 0x45, 
+       0x4a, 0x11, 0x81, 0x9b, 0xe2, 0x62, 0xe5, 0xe, 0xaf, 0xc5, 
+       0x31, 0x63, 00, 0xd4, 0x58, 0xb5, 0x22, 0xaf, 0xf4, 0xd6, 
+       0x9b, 0xe7, 0x95, 0x1, 0xf8, 0x66, 0x67, 0x57, 0xaf, 0xe3, 
+       0x89, 0x3f, 0x6f, 0x9d, 0x55, 0x5a, 0xda, 0x94, 0xc6, 0xd5, 
+       0x62, 0x8c, 0x23, 0xf1, 0x85, 0xf3, 0xbc, 0x47, 0x7a, 0xfe, 
+       0xe5, 0x3d, 0x93, 0x2b, 0xab, 0x5a, 0xd2, 0x18, 0x5e, 0xba, 
+       0x24, 0xb7, 0x24, 0x77, 0x52, 0x7a, 0x7, 0xdd, 0x86, 0xf7, 
+       0x8f, 0xd6, 0x9c, 0x28, 0x69, 0xc8, 0x84, 0x99, 0x9d, 0xf1, 
+       0xea, 0x5b, 0xf9, 0x13, 0x6e, 0xb9, 0x61, 0xe, 0x2b, 0x90, 
+       0x1f, 0x6b, 0x1e, 0x2e, 0xa8, 0x4a, 0xde, 0xb5, 0xa7, 0x6c, 
+       0x4c, 0x49, 0x69, 0x43, 0x43, 0x59, 0x79, 0xd3, 0x71, 0xdc, 
+       0xde, 0xc, 0xc7, 0xa, 0x13, 0x60, 0x7, 0xfb, 0x2c, 0x83, 
+       0x2e, 0x7, 0x7c, 0x2, 0x9b, 0xc5, 0xa1, 0xef, 0xc0, 0xfc, 
+       0x6b, 0x2a, 0x56, 0x50, 0x7d, 0x15, 0xa0, 0xfe, 0x4, 0x4c, 
+       0x71, 0x3b, 0x46, 0xbf, 0x11, 0xa4, 0x65, 0x7e, 0x71, 0x13, 
+       0x81, 0xbd, 0x7f, 0xff, 0x61, 0xe5, 0xf1, 0x3, 0x7b, 0x12, 
+       0xfa, 0xd8, 0x58, 0x6e, 0x1b, 0x51, 0xa1, 0xc7, 0x3, 0xe0, 
+       0x6c, 0x5c, 0x8b, 0x8b, 0xf6, 0x5e, 0xf4, 0x1a, 0x5c, 0x3e, 
+       0x8c, 0xd, 0x2e, 0xea, 0xc9, 0x86, 0xc1, 0xcd, 0x68, 0x8c, 
+       0xae, 0x5f, 0x85, 0xba, 0x5a, 0x8b, 0x85, 0x31, 0x2f, 0x63, 
+       0xa, 0xed, 0x7f, 0x30, 0xf0, 0xc6, 0xd1, 0x75, 0x2, 0x98, 
+       0x62, 0x26, 0xcc, 0xb0, 0x8a, 0x1e, 0xc1, 0x4f, 0x24, 0x52, 
+       0x3e, 0x48, 0x85, 00, 0xea, 0xa9, 0x86, 0xfa, 0x82, 0xcb, 
+       0x7b, 0x7a, 0xdb, 0x72, 0xdc, 0x7d, 0x1d, 0x39, 0x19, 0x59, 
+       0x8b, 0x6b, 0x93, 0x47, 0xe7, 0x60, 0x73, 0xc, 0x66, 0x98, 
+       0x39, 0x56, 0x6d, 0xa1, 0x28, 0x87, 0xd3, 0x3b, 0x3a, 0x75, 
+       0x4a, 0x75, 0x63, 0x7d, 0xc1, 0x44, 0xde, 0x4e, 0x1f, 0x33, 
+       0xbd, 0xca, 0x1e, 0x2, 0xd8, 0x96, 0x57, 0x2, 0x9, 0x60, 
+       0xad, 0x87, 0x91, 0x35, 0x7e, 0x49, 0x69, 0x6e, 0xde, 0xd5, 
+       0x65, 0x36, 0x8c, 0x2f, 0xb9, 0x5c, 0xdd, 0x8e, 0x82, 0x43, 
+       0xcf, 0xcf, 0x6a, 0x6d, 0xa9, 0x48, 0xd3, 0xab, 0x29, 0x2d, 
+       0x2f, 0x31, 0x53, 0x71, 0x96, 0xdb, 0x43, 0xe, 0x46, 0x4, 
+       0x6e, 0x74, 0xd4, 0xc0, 0x32, 0xf0, 0x8b, 0x73, 0xcd, 0x1e, 
+       0x84, 0xb5, 0xd9, 0x47, 0xdf, 0xd7, 0x62, 0x51, 0x6b, 0xcf, 
+       0x9c, 0x36, 0xe6, 0x94, 0x93, 0x33, 0xe2, 0x88, 0x9b, 0x18, 
+       0x1b, 0xe5, 0xce, 0xce, 0x48, 0x6e, 0x2b, 0x2e, 0xae, 0x1f, 
+       0x83, 0xf, 0xf1, 0x83, 0x8a, 0xf1, 0xe1, 0x82, 0xe6, 0xab, 
+       0x3f, 0xf6, 0x91, 0x85, 0xc5, 0x74, 0x81, 0x92, 0xfb, 0x9f, 
+       0x7f, 0xef, 0x5b, 0x37, 0xee, 0x8, 0xdc, 0x63, 00, 0xf7, 
+       0x21, 0x88, 0xe6, 0xe6, 0x6d, 0x45, 0x19, 0x18, 0x30, 0x8b, 
+       0x2f, 0x28, 0xac, 0x2d, 0xc7, 0xe0, 0x1b, 0x6d, 0xca, 0x7d, 
+       0x70, 0xac, 0x2c, 0x56, 0x9c, 0x80, 0x9a, 0xa6, 0x1a, 0x9d, 
+       0x54, 0x34, 0x2b, 0x9b, 0xfc, 0x62, 0x81, 0x59, 0xd9, 0x76, 
+       0x8c, 0xc2, 0x3a, 00, 0xe4, 0xcf, 0xc3, 0xff, 0x32, 0xb4, 
+       0x1, 0xd7, 0x49, 0x47, 0x63, 0xdd, 0x37, 0x1e, 0x5d, 0xfc, 
+       0x24, 0xc0, 0x76, 0x7b, 0xa1, 0xb1, 0x67, 0x2e, 0x51, 0xb9, 
+       0x93, 0x30, 0x68, 0x1b, 0x21, 0xb0, 0xe5, 0x2b, 0x9, 0x70, 
+       0x4c, 0xe1, 0xa8, 0x92, 0xa2, 0xfd, 0x6a, 0xf7, 0xee, 0x8b, 
+       0xdb, 0x44, 0x97, 0x32, 0xd3, 0x67, 0x3, 0x8c, 0x3a, 0x73, 
+       0xc0, 0xc2, 0x72, 0xa0, 0x3f, 0x7e, 0x7, 0x36, 0xbc, 0xdc, 
+       0x8e, 0x25, 0xae, 0xbf, 0x3b, 0x74, 0xe8, 0xd0, 0x93, 0x98, 
+       0x27, 0xa7, 0x2c, 0xb0, 0xee, 0xfd, 0xb2, 0xa7, 0xeb, 0x9c, 
+       0x61, 0xca, 0x1, 0x65, 0x84, 0x32, 0x40, 0x79, 0xa0, 0x5f, 
+       0x7, 0xb7, 0xae, 0xbd, 0xb5, 0x72, 0x79, 0x5f, 0x4f, 0xdb, 
+       0x34, 0x68, 0xf1, 0xf1, 0x3d, 0x3d, 0x8d, 0xb1, 0xe3, 0xb2, 
+       0x17, 0xd7, 0x6b, 0x73, 0x34, 0xc8, 0x4c, 0x4f, 0x4d, 0x9d, 
+       0xd4, 0x28, 0xe0, 0x9e, 0x90, 0xbb, 0xea, 0x24, 0xba, 0xa6, 
+       0x78, 0x7d, 0x20, 0x69, 0xcc, 0x53, 0xeb, 0xfa, 0x1f, 0xd3, 
+       0x8a, 0x4d, 0x4b, 0x9f, 0x8a, 0xbe, 0x3a, 0x96, 0x5f, 0x80, 
+       0x1c, 0x8e, 0x4, 0x77, 0x52, 0x52, 0x66, 0x5b, 0x6b, 0x73, 
+       0xf9, 0x18, 0x68, 0x69, 0x5f, 0x39, 0x11, 0x9f, 0xc9, 0x61, 
+       0x1c, 0x4b, 0x6b, 0x6c, 0x98, 0xe5, 0xd0, 0xde, 0xa1, 0xd3, 
+       0x1f, 0x98, 0xe3, 0xe9, 0x3b, 0x91, 0x81, 0x1b, 0xef, 0x1, 
+       0x5a, 0xe0, 0x96, 0x9, 0x9f, 0xa2, 0x30, 0x90, 0xdc, 0x68, 
+       0x99, 0xfc, 0xc3, 0x8e, 0xfa, 0xa1, 0xdb, 0xf4, 0x9c, 0xb6, 
+       0x37, 0xfc, 0xd1, 0xf9, 0xdc, 0x1a, 0x67, 0x60, 0x2a, 0xe1, 
+       0xef, 0xf4, 0xf6, 0xba, 0x8c, 0x77, 0x37, 0x16, 0x8e, 0x2f, 
+       0x29, 0x6d, 0x54, 0x87, 0x8f, 0x54, 0x9f, 0x80, 0x19, 0xbe, 
+       0x13, 0xb1, 0x8b, 0xe0, 0x58, 0x89, 0xac, 0x4c, 0x1, 0xb7, 
+       0xb5, 0xf, 0xc6, 0x7b, 0x2c, 0xae, 0x66, 0x28, 0x7c, 0xaa, 
+       0x64, 0x3, 0x60, 0x9e, 0x8c, 0x5, 0x27, 0xff, 0x8d, 0xe9, 
+       0x97, 0x89, 0x6b, 0xd6, 0xac, 0x89, 0xc3, 0x42, 0x14, 0xdc, 
+       0xfe, 0xfb, 0x20, 0x1, 0xb6, 0xc7, 0x4c, 0x54, 0x33, 0xfc, 
+       0xc0, 0xae, 0xa9, 0x2e, 0x53, 0xef, 0xae, 0x7f, 0x46, 0xb7, 
+       0xb9, 0x77, 0xde, 0xfd, 0x25, 0x8, 0xbe, 0x53, 0x87, 0xd9, 
+       0xf7, 0x7e, 0x6f, 0xc3, 0xb3, 0xaa, 0xe2, 0xe4, 0x31, 0xcd, 
+       0x81, 0xbb, 0x3e, 0xfe, 0x75, 0xe5, 0x8c, 0x8a, 0xc5, 0x33, 
+       0x53, 0x61, 0x69, 0x98, 0x7a, 0xf1, 0x85, 0x7f, 0xd7, 0x3, 
+       0x6c, 0x93, 0xa7, 0x2c, 0x54, 0x39, 0xb9, 0xf3, 0x55, 0x49, 
+       0xf1, 0x7e, 0xb5, 0x6b, 0xf7, 0x41, 0xfd, 0x3c, 0x37, 0x37, 
+       0xf7, 0xef, 0x82, 0x21, 0x6c, 0x90, 0x57, 0xaf, 0x5e, 0x1d, 
+       0x8d, 0x86, 0x5a, 0x7d, 0xf0, 0xc1, 0x7, 0xf, 0x61, 00, 
+       0xf4, 0x66, 0x2c, 0x75, 0xfd, 0x17, 0xee, 0x4c, 0xc3, 0x7, 
+       0x10, 0xcc, 0xd6, 0xfa, 0xe7, 0xb5, 00, 0x9b, 0x72, 0x22, 
+       0xcf, 0xe8, 0x6f, 0xea, 0xed, 0x6d, 0x6b, 0xa8, 0xad, 0x39, 
+       0xb8, 0xd8, 0xed, 0xe9, 0x9b, 0xd8, 0xd7, 0xd3, 0x99, 0x9d, 
+       0x37, 0x79, 0x55, 0x83, 0x61, 0x77, 0x7a, 0x5c, 0x5e, 0xd3, 
+       0xdb, 0xdb, 0xd3, 0x1a, 0xd5, 0xd1, 0x5e, 0x1b, 0x57, 0x59, 
+       0xb1, 0x5b, 0x33, 0x26, 0x21, 0x31, 0xa3, 0x29, 0x65, 0xf4, 
+       0x24, 0x6e, 0x7f, 0xd, 0x43, 0xa1, 0x40, 0xc9, 0xfe, 0xbc, 
+       0x4f, 0x21, 0xf2, 0x25, 0xee, 0xcd, 0x18, 0xf8, 0x32, 0x9f, 
+       0xf3, 0x36, 0xfd, 0xd3, 0x71, 0x7, 0xc6, 0xb, 0x7f, 0x27, 
+       0x42, 0x70, 0x93, 0x1f, 0xfc, 0x7e, 0x9f, 0xc3, 0x7c, 0xb3, 
+       0x3f, 0x65, 0xc1, 0xc, 0x2f, 0x25, 0x8e, 0xff, 0x51, 0xc0, 
+       0x1b, 0x4a, 0x9c, 0x40, 0xe4, 0x1, 0x1, 0x9a, 0xe1, 0x2d, 
+       0xad, 0x5d, 0x51, 0xef, 0xbe, 0x7f, 0x6c, 0x3c, 0xcc, 0xfc, 
+       0xae, 0xa3, 0xc7, 0xea, 0x4a, 0x30, 0xf2, 0xfb, 0x1, 0x22, 
+       0x72, 0xad, 0x39, 0x81, 0xcd, 0x96, 0x98, 0x3e, 0x2b, 0x8b, 
+       0x4e, 0xc0, 0x4e, 0x5f, 0xa, 0xad, 0x39, 0x86, 0x29, 0x2c, 
+       0x2e, 0x3a, 0x79, 0x10, 0x2, 0xf1, 0x45, 0xb4, 0xfa, 0x51, 
+       0xb3, 0x66, 0xcd, 0xa2, 0x69, 0x7e, 0xd1, 0x12, 0x41, 0x48, 
+       0x12, 0x9f, 0xc0, 0x3e, 0x70, 0xb0, 00, 0xd7, 0x89, 0xba, 
+       0x8f, 0xcd, 0x51, 0x71, 0x8e, 0x82, 0xb7, 0xb6, 0x36, 0xaa, 
+       0x5d, 0x3b, 0xdf, 0xd1, 0x71, 0x6f, 0xbf, 0xf3, 0x9f, 0xa1, 
+       0x15, 0xa2, 0x10, 0xc7, 0xf7, 0x5e, 0x7c, 0x5c, 0x92, 0x3a, 
+       0x7a, 0xc4, 0x67, 0x4, 0x15, 0x1d, 0xdf, 0x8f, 0x6, 0x61, 
+       0xb9, 0x4e, 0xaf, 0xac, 0x34, 0x5f, 0x1d, 0x3b, 0xca, 0xf6, 
+       0x51, 0xa9, 0xf9, 0x8b, 0xae, 0x56, 0x59, 0xd9, 0x53, 0x21, 
+       0x6c, 0x5e, 0x55, 0x5a, 0x7c, 0x40, 0xed, 0xdc, 0x79, 0x50, 
+       0xa7, 0x9b, 0x93, 0x93, 0xd3, 0xaf, 0xcf, 0x47, 0x4d, 0x46, 
+       0x12, 0x5f, 0x5f, 0x5c, 0x24, 0xff, 0xd8, 0x40, 0xdf, 0x7a, 
+       0xeb, 0xad, 0xb1, 0x47, 0x8e, 0x1c, 0x99, 0x8c, 0xf2, 0x3d, 
+       0x83, 0xee, 0xd6, 0x63, 0xd0, 0xe2, 0x7f, 0xc6, 0x56, 0x54, 
+       0x69, 0xe0, 0x45, 0x68, 0xf9, 0x11, 0xbc, 0x27, 0xc4, 0xfb, 
+       0x64, 0xb4, 0x99, 0x18, 0x1d, 0x5d, 0xf0, 0x8b, 0xb5, 0x6b, 
+       0x3e, 0xf9, 0xea, 0x89, 0x13, 0xce, 0x23, 0xa7, 0xa, 0xdb, 
+       0xe2, 0x92, 0x1d, 0xd7, 0xcd, 0xcf, 0x5b, 0xdc, 0xbd, 0xbb, 
+       0x2b, 0x6e, 0x93, 0xa7, 0x72, 0xe7, 0xca, 0x5d, 0x7b, 0x5f, 
+       0x4f, 0x91, 0x97, 0x72, 0xf3, 0xd6, 0x9c, 0x60, 0xd7, 0x38, 
+       0x1c, 0xc1, 0xa6, 0xf7, 0x31, 0xcb, 0x1f, 0x81, 0x17, 0x64, 
+       0x9f, 0xf5, 0x1d, 0x3d, 0xa4, 0xd3, 0x2f, 0x16, 0x23, 0x7b, 
+       0x75, 0x1c, 0xc6, 0xa5, 0xf6, 0xf7, 0xb3, 0xdc, 0x9f, 0xca, 
+       0xd0, 0xbc, 0x8, 0xc1, 0x8d, 0x44, 0xc5, 0x24, 0x87, 0x59, 
+       0x9e, 0x91, 0x9e, 0xd0, 0x71, 0xf8, 0x8, 0x76, 0x87, 0xf9, 
+       0xf3, 0x62, 0x9f, 0xdb, 0x2b, 0x66, 0xbb, 0xff, 0x9e, 0x7, 
+       0x3b, 0xc5, 0xdc, 0x2e, 0xac, 0xe4, 0x81, 0xa5, 0xc1, 0x5b, 
+       0xdc, 0x45, 0x96, 0x96, 0x12, 0xdf, 0x15, 0x6c, 0x96, 0xfb, 
+       0xa3, 0x87, 0xf4, 0x8, 0x6c, 0x2c, 0x23, 0x8d, 0x7d, 0x7f, 
+       0x73, 0x51, 0x76, 0x51, 0x51, 0x5d, 0x63, 0x49, 0x79, 0x33, 
+       0x5b, 0xe3, 0xf, 0xe0, 0xda, 0xe0, 0x44, 0x53, 0x8b, 0x4f, 
+       0x90, 0x33, 0x4c, 0x50, 0xb3, 0x68, 0x74, 0xac, 0x38, 0xe6, 
+       0x6f, 0xe4, 0xe4, 0xe4, 0xe4, 0xc1, 0xfd, 0x12, 0x73, 0xd6, 
+       0x13, 0xaf, 0xb8, 0xe2, 0x8a, 0x18, 0x6e, 0x5b, 0xbc, 0x98, 
+       0x48, 00, 0x2c, 0xbe, 0x94, 0x4d, 0xa6, 0xb0, 0x8, 0xec, 
+       0x83, 0x87, 0xa, 0x21, 0x85, 0x1c, 0x3c, 0x5b, 0xa4, 0x4d, 
+       0x71, 0xf6, 0x97, 0x19, 0x9f, 0xbe, 0x10, 0xd6, 0xff, 0x83, 
+       0xc5, 0xb0, 0x8f, 0x70, 0x8b, 0xef, 0xce, 0x98, 0xb9, 0x4c, 
+       0xfd, 0xed, 0x95, 0xdf, 0x20, 0xec, 0x51, 0x85, 0x47, 0x77, 
+       0x61, 0xe, 0xfc, 0x32, 0xf4, 0xac, 0x3c, 0xea, 0xc4, 0x71, 
+       0xf6, 0x66, 0x30, 0x4f, 0x14, 0x93, 0x80, 0x81, 0xb8, 0x39, 
+       0x3a, 0x6e, 0xe6, 0xb8, 0x29, 0xa8, 0x27, 00, 0xbc, 0xf4, 
+       0x90, 0xda, 0xb9, 0xeb, 0x90, 0xbe, 0x7, 0x9e, 0xe9, 0x78, 
+       0x56, 0x40, 0x33, 0x3c, 0xd8, 0xb5, 0x7e, 0xe1, 0x2, 0xfd, 
+       0x43, 0x83, 0x6d, 0xe3, 0x42, 0x98, 0x8d, 0x1b, 0x37, 0x3e, 
+       0x88, 0xfd, 0xf0, 0x37, 0x60, 0x84, 0xfd, 0x3b, 0xd8, 0x77, 
+       0x5e, 0x8a, 0xe2, 0x48, 0x63, 0x4f, 0xb9, 0x60, 0x63, 0xcf, 
+       0x6b, 0x33, 0x29, 0x36, 0xd6, 0xf9, 0xca, 0xed, 0xb7, 0xfd, 
+       0x37, 0xe6, 0x92, 0xfa, 0x8e, 0x9f, 0x6a, 0xde, 0xbc, 0x60, 
+       0xec, 0xd8, 0xb9, 0x93, 0xb0, 0xb8, 0xe7, 0x6f, 0x27, 0x4e, 
+       0x74, 0x9c, 0xea, 0xac, 0x8c, 0xda, 0x7d, 0xac, 0x2f, 0x6a, 
+       0xfe, 0xa4, 0xc5, 0x57, 0x17, 0x25, 0x8e, 0x8a, 0x4b, 0x4d, 
+       0x4c, 0x55, 0x86, 0x23, 0xba, 0xe3, 0xb2, 0xc9, 0x8b, 0xed, 
+       0xab, 0xe6, 0xad, 0xce, 0xde, 0xd6, 0xac, 0x6a, 0x90, 0x46, 
+       0x48, 0x8a, 0x4f, 0x1c, 0xdb, 0x51, 0x5f, 0x5f, 0x88, 0x21, 
+       0x70, 0x1f, 0x7a, 0x65, 0xf5, 0x9a, 0x55, 0x1b, 0xa3, 0x31, 
+       0xc5, 0xe6, 0x2b, 0x37, 0x20, 0x82, 0x61, 0x7a, 0x10, 0xd7, 
+       0x97, 0xc7, 0xc5, 0xa7, 0x63, 0xc4, 0x9d, 0x97, 0x2c, 0xa2, 
+       0x16, 0x5d, 0x3e, 0x8a, 0x88, 0x22, 0x2, 0x37, 0x11, 0x22, 
+       0x68, 0xa1, 0x7f, 0xcd, 0xd5, 0xd3, 0x4e, 0xba, 00, 0xd6, 
+       0xda, 0xfa, 0xd6, 0x44, 0x8e, 0xe8, 0x71, 0x29, 0x5f, 0x42, 
+       0x42, 0x8c, 0x8b, 0xcf, 0x84, 0x32, 0x32, 0x92, 0x3b, 0xa6, 
+       0x4d, 0x1b, 0x5b, 0x1b, 0x85, 0x85, 0x2c, 0x7c, 0x3e, 0x2e, 
+       0x73, 0x54, 0xdb, 0xe5, 0xab, 0x26, 0xd5, 0x58, 0xe3, 0x48, 
+       0xdc, 0x50, 0x3e, 0x81, 0x5d, 0x54, 0xd2, 0x90, 0xb8, 0x75, 
+       0x7b, 0x69, 0xc6, 0xd1, 0xc2, 0xda, 0xea, 0xfa, 0x86, 0x8e, 
+       0xe3, 0x88, 0xb7, 0x19, 0x8e, 0x73, 0xd6, 0xac, 0x18, 0x1, 
+       0x35, 0xb5, 0x35, 0x81, 0xcd, 0xa4, 0x79, 0x5f, 0x57, 0x1a, 
+       0x7c, 0x92, 0xd, 0x7d, 0x31, 0x6a, 0xeb, 0xcf, 0xc2, 0x5c, 
+       0x7b, 0xf8, 0x62, 0xd2, 0xd6, 0x2, 0x62, 0xf1, 0x59, 0x58, 
+       0x1, 0xb2, 0xdc, 0x93, 0x6b, 0x2, 0xfb, 0x50, 0xfe, 0x71, 
+       0xb4, 0xe4, 0xd4, 0xd8, 0x58, 0xa0, 0x92, 0x33, 0x43, 0x3, 
+       0x98, 0xa0, 0x66, 0x1c, 0x89, 0xc7, 0x34, 0x30, 0x55, 0xd9, 
+       0xf, 0xdc, 0xd1, 0x31, 0xf1, 0x6a, 0x72, 0xde, 0x7c, 0x80, 
+       0x79, 0xaf, 0x3a, 0xe, 0xc7, 0x63, 0x95, 0xa8, 0xa1, 0x8b, 
+       0xd1, 0xc7, 0x26, 0x4d, 0x9b, 0xbe, 0x14, 0xff, 0xb1, 0xfd, 
+       0x88, 0x63, 0x1a, 0x68, 0x11, 0x32, 0xc6, 0xe5, 0x61, 0x78, 
+       0xc5, 0xab, 0xca, 0xcb, 00, 0xf0, 0x9d, 0x87, 0xf4, 0x7d, 
+       0x74, 0x61, 0x34, 0x98, 0x5, 0xd4, 0xe2, 0xf3, 0xfd, 0xe0, 
+       0x70, 0xf0, 0x3d, 0x5e, 0x9f, 0x6f, 0x62, 0xc3, 0x7d, 0xdb, 
+       0x6d, 0xb7, 0xc5, 0x62, 0x54, 0x7d, 0x12, 0xca, 0xf7, 0x17, 
+       0x68, 0xf1, 0xc7, 0xb1, 0x18, 0xe6, 0x2f, 0x50, 0xe2, 0x94, 
+       0x13, 0xa2, 0xcd, 0xfb, 0xad, 0x95, 0xcb, 0xa6, 0xcf, 0x4a, 
+       0x4d, 0x5b, 0x74, 0xb8, 0xae, 0xe1, 0x50, 0x7c, 0x54, 0x94, 
+       0x5e, 0x69, 0xb6, 0x18, 0xcb, 0xc4, 0x58, 0xd6, 0x51, 0xd1, 
+       0xd1, 0xea, 0xee, 0xe9, 0xd3, 0x13, 0xde, 0x2d, 0x2b, 0x33, 
+       0xcb, 0xbb, 0xaa, 0x8d, 0x7d, 0x45, 0xdb, 0xe3, 0xe6, 0xa3, 
+       0xdb, 0xf2, 0xd3, 0x7b, 0x7f, 0xc0, 0xc7, 0x7a, 0x91, 0x15, 
+       0x52, 0x19, 0x97, 0x12, 0x6d, 0xc4, 0x65, 0xc7, 0x98, 0xe3, 
+       0xaa, 0x7a, 0x8d, 0x9a, 0x56, 0x97, 0xd9, 0xc9, 0x87, 0x42, 
+       0x79, 0x53, 0xaf, 0xa8, 0x40, 0x27, 0xd4, 0xd6, 0xd9, 0x5e, 
+       0x97, 0x60, 0x18, 0xdc, 0x44, 0xe9, 0x35, 0x62, 0xe2, 0x92, 
+       0x5c, 0x56, 0xcd, 0x3d, 0x6a, 0x54, 0x66, 0x47, 0xf7, 0x98, 
+       0x29, 0xb5, 0x76, 0x9b, 0x13, 0x6d, 0x8b, 0xd7, 0x48, 0x1c, 
+       0x95, 0xd9, 0x96, 0x9b, 0xb7, 0xaa, 0x5a, 0xf, 0x96, 0xa3, 
+       0x94, 0x5a, 0x73, 0x13, 0xe3, 0x11, 0x52, 0x44, 0xe0, 0xf6, 
+       0x5b, 0x2d, 0xc8, 0xc2, 0x67, 0xc1, 0x60, 0x63, 0x87, 0xe7, 
+       0x23, 0xb7, 0xce, 0x2e, 0x45, 0x89, 0x83, 0x46, 0x14, 0x4f, 
+       0x6b, 0x90, 0x55, 0xcb, 0x73, 0xea, 0xe8, 0x6, 0x96, 0xeb, 
+       0x74, 0x9c, 0x81, 0xcf, 0x7c, 0x77, 0xa0, 0x18, 0xcc, 0xfc, 
+       0x23, 0xd5, 0x29, 0xbb, 0x76, 0x9f, 0x4c, 0x85, 0x5f, 0xd6, 
+       0xd6, 0xde, 0x7b, 0x4, 0x4f, 0x38, 0x87, 0x2d, 0xda, 0x99, 
+       0xbe, 0x38, 0x82, 0xdc, 0xaa, 0xb1, 0x71, 0xa9, 0x89, 0x5b, 
+       0x2d, 0xf3, 0x20, 0x98, 0xff, 0x1, 0x6d, 0x3d, 0xe1, 0x62, 
+       0xd0, 0xd6, 0x4, 0x2d, 0x9d, 0x90, 0x5c, 0x5b, 0x7d, 0x3e, 
+       0x23, 0x58, 0x79, 0x8f, 0x3e, 0xcf, 0x39, 0x38, 0x7c, 0xf8, 
+       0x4, 0xb6, 0xf7, 0x8e, 0xd2, 0x2b, 0xcf, 0x26, 0xfa, 0x81, 
+       0xfd, 0x93, 0x47, 0x1f, 0x54, 0x4d, 0x8d, 0x3e, 0xc5, 0x71, 
+       0xba, 0x9b, 0xa4, 0xd4, 0x8f, 0xbe, 0xff, 0x89, 0x40, 0xf2, 
+       0xd3, 0x67, 0x2c, 0x55, 0x37, 0xdf, 0xf6, 0x7f, 0xcc, 0x69, 
+       0xd3, 0x97, 0x11, 0xdc, 0xb6, 0x8e, 0xf6, 0x66, 0x55, 0x5a, 
+       0x52, 0xe0, 0x8d, 0x72, 0xc6, 0xd8, 0x9a, 0x9a, 0xaa, 0x75, 
+       0xbc, 0x89, 0xb9, 0xb, 0x14, 0x6, 0xa2, 0xf4, 0xb4, 0x8b, 
+       0x9e, 0x82, 0xc1, 0xdd, 0x31, 0x63, 0x27, 0x69, 0x50, 0x9f, 
+       0x2c, 0xcb, 0x7, 0xc0, 0x39, 0x87, 0xee, 0x56, 0xd0, 0x86, 
+       0x81, 0xf5, 0xf3, 0x1c, 0xb1, 0x16, 0x50, 0x8b, 0x2f, 0xd3, 
+       0x86, 0x72, 0x4d, 0x9f, 0x24, 0xd7, 0xfa, 0xe2, 0x3c, 0xff, 
+       0xc3, 0x60, 0x9b, 0xd, 0xd3, 0x9b, 0xd1, 0xd0, 0xe2, 0x9f, 
+       0xc1, 0xc9, 0x36, 0xd7, 0x95, 0x94, 0x94, 0xfc, 0x2b, 0xf6, 
+       0x98, 0x97, 0xa0, 0x18, 0xae, 0x6b, 0x26, 0xe6, 0x7c, 0x3d, 
+       0xde, 0x11, 0xb5, 0x64, 0x4a, 0x72, 0x8a, 0xd6, 0x37, 0x6c, 
+       0xd8, 0x64, 0xf0, 0xea, 0xb1, 0x83, 0x7, 0xd5, 0xa7, 0x66, 
+       0xcd, 0x32, 0xcb, 0x5a, 0xdb, 0x8c, 0x2e, 0x58, 0xf5, 0xb1, 
+       0x9e, 0x3e, 0xf3, 0xcd, 0x83, 0x2d, 0xc6, 0x75, 0xb3, 0x57, 
+       0xa8, 0x9c, 0x31, 0x13, 0xb5, 0x55, 0x4, 0x11, 0xb5, 0xad, 
+       0x49, 0x51, 0xd7, 00, 0x1b, 0xb6, 0x24, 0x87, 0x91, 0xb8, 
+       0xbb, 0x55, 0xf9, 0x5a, 0x4b, 0xff, 0x37, 0xda, 0x9d, 0xd1, 
+       0xde, 0xd9, 0xb3, 0x6f, 0xa2, 0xc5, 0x10, 0x96, 0x72, 0x73, 
+       0x97, 0xd5, 0xd1, 0x49, 0x4, 0xf0, 0xa, 0xc2, 0xc1, 0xed, 
+       0x60, 0xe4, 0x1b, 0x34, 0x13, 0x1, 0x2e, 0xf, 0x23, 0xf0, 
+       0x23, 0x2, 0x37, 0xe5, 0x91, 0xad, 0xb9, 0xc7, 0x83, 0xb6, 
+       0x8, 0xbe, 0x68, 0xc, 0xde, 0xb7, 0xa, 0x6b, 0x4, 0xf9, 
+       0x87, 0x8d, 0xca, 0xf, 0x3c, 0x70, 0xa8, 0x6a, 0xf4, 0x9e, 
+       0xfd, 0x15, 0x29, 0xf9, 0xf9, 0x35, 0xa5, 0x5d, 0xdd, 0x7d, 
+       0x4, 0x35, 0xc1, 0x2d, 0x9a, 0x5a, 0x40, 0x4d, 0x5f, 0x34, 
+       0x38, 0x2b, 0x48, 0x8c, 0x2, 0xf2, 0xc3, 0x58, 0xb0, 0x60, 
+       0xc1, 0xc7, 0xd0, 0xf, 0xfb, 0x36, 0x76, 0x1f, 0x39, 0x39, 
+       0x67, 0x8d, 0x7b, 0x17, 0x84, 0x4, 0xb8, 0x92, 0xb9, 00, 
+       0x97, 0xd7, 0xa2, 0x71, 0xe5, 0x9e, 0xd5, 0x67, 0x98, 0xc0, 
+       0x2e, 0x28, 0x80, 0x2c, 0x1a, 0xf1, 0x98, 0xdf, 0x9d, 0x81, 
+       0xa9, 0x97, 0x9, 0x26, 0xce, 0x2d, 0xc3, 0x2, 0x21, 0x1b, 
+       0x4e, 0xc3, 0x71, 0xa3, 0x2e, 0xdc, 0x3, 0xea, 0x9e, 0xe6, 
+       0xb7, 0x9f, 0xc, 0x2e, 0x93, 0xc5, 0xd2, 0x4d, 0x23, 0x2d, 
+       0xf5, 0x66, 0xf5, 0xf6, 0x5b, 0x8f, 0x61, 0xff, 0x71, 0x9f, 
+       0x6a, 0x68, 0x28, 0x86, 0xe9, 0x37, 0xa, 0x35, 0xa7, 0x60, 
+       0x6d, 0xa5, 0x98, 0xb3, 0xe7, 0x2c, 0xc3, 0x4e, 0x3d, 0xf, 
+       0x6, 0xd8, 0x5c, 0x3c, 0x3a, 0x4b, 0x97, 0x9, 0x8b, 0x95, 
+       0xcc, 0xe4, 0x94, 0x6c, 0xb3, 0xa0, 0xab, 0xb4, 00, 00, 
+       0x20, 00, 0x49, 0x44, 0x41, 0x54, 0xd5, 0xdd, 0xd5, 0xad, 
+       0x2a, 0x2b, 0x8f, 0xd8, 0xb6, 0x6c, 0xdb, 0xaf, 0x96, 0x2c, 
+       0xea, 0x55, 0xdc, 0xa3, 0x2d, 0x60, 0xc5, 0x3c, 0xb3, 0xce, 
+       0x46, 0x80, 0x2e, 0x3e, 0x9f, 0x5b, 0xc3, 0xbc, 0x26, 0xc9, 
+       0x7b, 0x72, 0xad, 0x6f, 0x9e, 0x87, 0x7f, 0x16, 0x2d, 0x9e, 
+       0x8b, 0xbc, 0xff, 0xf8, 0xf0, 0xdc, 0xd9, 0x5b, 0x31, 0xef, 
+       0x7a, 00, 0x40, 0xf6, 0x69, 0x60, 0x9f, 0xed, 0xab, 0x5e, 
+       0x2b, 0x2a, 0x52, 0x45, 0xcd, 0xcd, 0xaa, 0x13, 0x3, 0xed, 
+       0x6f, 0x95, 0x94, 0xa8, 0x3f, 0xe5, 0x1f, 0x36, 0x30, 0x48, 
+       0xac, 0x4b, 0x68, 0x67, 0xa1, 0x6d, 0x51, 0xca, 0x5, 0x3e, 
+       0xa5, 0xa7, 0xd7, 0xa8, 0x95, 0x79, 0x73, 0x55, 0x76, 0xa2, 
+       0x7e, 0x9d, 0x30, 0x54, 0x51, 0x36, 0x23, 0x66, 0x46, 0x82, 
+       0x2d, 0xaf, 0xcf, 0x54, 0xbd, 0xc5, 0xdd, 0xaa, 0x62, 0xf8, 
+       0x9f, 0x5, 0x5e, 0x91, 0x5f, 0xa2, 0xb2, 0x69, 0xad, 0x33, 
+       0x1c, 0x21, 0x45, 0x4, 0x6e, 0x9f, 0xc6, 0xa6, 0xd0, 0xf0, 
+       0x63, 0xe9, 0x28, 0x1b, 0xe2, 0x10, 0x1c, 0x21, 0xc2, 0x77, 
+       0x99, 0xbb, 0xf7, 0x56, 0xa4, 0x1d, 0x38, 0x54, 0x93, 0x4, 
+       0x8d, 0x5d, 0x8a, 0xa3, 0x9d, 0xb6, 0x21, 0xe9, 0x63, 0x70, 
+       0x2, 0x62, 0x2, 0x5a, 0xcc, 0x70, 0x82, 0x9d, 0x85, 0xe2, 
+       0x33, 0x91, 0x68, 0x9a, 0xe1, 0xd1, 0x30, 0xbf, 0xbf, 0x8f, 
+       0x4a, 0xbd, 0xe9, 0x86, 0x1b, 0x6e, 0x88, 0xbd, 0x10, 0x7d, 
+       0xeb, 0x33, 0x1, 0x5a, 0xb4, 0x72, 0x30, 0x98, 0x79, 0x1f, 
+       0xe7, 0x93, 0x69, 0x4d, 0x8a, 0x1d, 0x51, 0xde, 0xca, 0xaa, 
+       0x46, 0xc3, 0xe9, 0x1c, 0xad, 0x66, 0xcd, 0xb9, 0xcc, 0x9c, 
+       0x3a, 0x6d, 0x21, 0xe, 0x44, 0x8c, 0xc2, 0x81, 0x3, 0x86, 
+       0xcd, 0x61, 0x77, 0xa8, 0x7, 0x1e, 0xfc, 0x8e, 0xea, 0xc1, 
+       0x89, 0x27, 0xb0, 0x5, 0x54, 0x65, 0x45, 0x91, 0x7a, 0xf5, 
+       0xe5, 0xc7, 0xc0, 0x6, 0xa5, 0x3e, 0xfb, 0xb9, 0xef, 0x29, 
+       0x68, 0x66, 0x5d, 0x3d, 0x29, 0xa3, 0xc7, 0xe8, 0x73, 0xd8, 
+       0xcc, 0xf8, 0x4, 0x35, 0x6f, 0xde, 0xe5, 0x6a, 0xef, 0x9e, 
+       0xf7, 0xa0, 0xc1, 0xf7, 0x60, 0xc3, 0x48, 0xba, 0x46, 0xdc, 
+       0xa2, 0x25, 0x57, 0x19, 0x63, 0xc7, 0x66, 0xe0, 0x40, 0x2a, 
+       0x1e, 0x37, 0x7, 0x4b, 0x1, 0xf9, 0xd3, 0x3c, 0xc7, 0xe2, 
+       0x21, 0x83, 0x7, 0x25, 0x8e, 0x49, 0x1f, 0x6b, 0x26, 0x26, 
+       0x25, 0x7a, 0xa1, 0xf5, 0x8d, 0xfd, 0x7, 0x8e, 0x53, 0x83, 
+       0x9b, 0xfe, 0x99, 0x5, 0x1b, 0xcf, 0x77, 0xe3, 0x79, 0x6b, 
+       0x4, 0xb2, 0x80, 0x59, 0xc2, 0xc1, 0xd7, 0xc4, 0x86, 0x38, 
+       0x96, 0x51, 0xc2, 0xf4, 0xcf, 0x17, 0x51, 0x8b, 0x4f, 0x1a, 
+       0x93, 0x1e, 0xb3, 0x20, 0x3f, 0xff, 0x2a, 0xe4, 0x49, 0xa7, 
+       0xe9, 0x99, 0x82, 0xa3, 0xa, 0x1b, 0xba, 0xd4, 0x33, 0x5, 
+       0x5, 0xaa, 0xb6, 0xe3, 0xb4, 0x65, 0x2d, 0xc0, 0x66, 0x24, 
+       0xd8, 0xcc, 0xf8, 0xd7, 0xa7, 0xf2, 0x4b, 0xf6, 0xaa, 0xf4, 
+       0xce, 0x76, 0xd5, 0xd1, 0xd7, 0xa3, 0x96, 0x1, 0xe0, 0x38, 
+       0x2d, 0x52, 0x4d, 0x1d, 0x9d, 0xa2, 0x46, 0x3b, 0xcd, 0xc, 
+       0x3a, 0x4c, 0x8b, 0x7b, 0xcb, 0xfa, 0x8c, 0xb3, 00, 0xb7, 
+       0x1f, 0xdb, 0x7e, 0x8c, 0x73, 0xc0, 0x8d, 0xda, 0x3b, 0x52, 
+       0x8a, 0xc, 0xdc, 0xc0, 0x33, 0x17, 0x96, 0x89, 0x63, 0x83, 
+       0x46, 0xe7, 0xd3, 0xdc, 0x91, 0x66, 0x1d, 0x26, 0x3e, 0x24, 
+       0x7b, 0xe7, 0xde, 0xf2, 0x31, 0xf9, 0x47, 0xea, 0xe2, 0xe, 
+       0x1d, 0xae, 0x2e, 0xc1, 0x54, 0xd7, 0x16, 0xc4, 0x2c, 0x86, 
+       0xb, 0xd6, 0xd8, 0x4, 0x37, 0xc1, 0xcc, 0xfb, 0x4, 0x36, 
+       0x5b, 0x1b, 0xb2, 0xc0, 0x8e, 0xbe, 0xd5, 0x68, 0x2c, 0x6e, 
+       0x78, 0xc, 0xfe, 0xe4, 0xab, 0xaf, 0xbe, 0x3a, 0x96, 0xc2, 
+       0x77, 0x3e, 0xc9, 0xa, 0x6a, 0x9, 0xd3, 0x27, 0x88, 0x83, 
+       0x81, 0x2c, 0xf7, 0x8, 0x66, 0xac, 0x99, 0xf6, 0x62, 0xbe, 
+       0x5d, 0x61, 0x14, 0xdf, 0xe0, 0x29, 0x26, 00, 0x87, 0x59, 
+       0x56, 0x76, 0xd2, 0x36, 0x26, 0x3d, 0x3, 0x3b, 0xb9, 0x1c, 
+       0xaa, 0xae, 0xfa, 0xb0, 0x51, 0x5b, 0x7d, 0x58, 0x7f, 0xa, 
+       0xd3, 0x13, 0xc2, 0xec, 0xa3, 0x1a, 0x9d, 0x9a, 0xa3, 0x66, 
+       0xcd, 0x5e, 0x1a, 00, 0xf7, 0x65, 0x4b, 0xaf, 0x51, 0x31, 
+       0xb1, 0xf1, 0xba, 0x6e, 0x7c, 0x79, 0xf8, 0xe2, 0x5f, 0xb6, 
+       0xf4, 0x5a, 0xd, 0xee, 0xb2, 0xd2, 0x2, 0x80, 0x32, 0x56, 
+       0x27, 0xb1, 0x68, 0xf1, 0xd5, 0xda, 0xdf, 0xb3, 0xfb, 0x1d, 
+       0xd5, 0xd9, 0x56, 0x85, 0x51, 0x5a, 0x36, 0x15, 0x20, 0x7f, 
+       0x16, 0xc8, 0xa, 0x7c, 0x35, 0x8d, 0x9, 0xe3, 0x53, 0xb4, 
+       0x85, 0xd6, 0xda, 0xda, 0x6e, 0x60, 0x1, 0x9, 0xe2, 0xd9, 
+       0xbd, 0x38, 0x8, 0x11, 0xd6, 0x83, 0x87, 0x65, 0x37, 0x71, 
+       0xe0, 0x2, 0x1b, 0x11, 0x1b, 0x2d, 0x5, 0x2, 0x9b, 0x5a, 
+       0x5d, 0x80, 0x4e, 00, 0x4b, 0x98, 0xbe, 0x15, 0xd8, 0x2, 
+       0x6e, 0xb9, 0xa7, 0xb, 0x73, 0x8e, 0xfe, 0xd9, 0xdd, 0x2e, 
+       0x95, 0x14, 0x1f, 0xaf, 0x3c, 0xe0, 0x27, 0xce, 0xb, 0x53, 
+       0x3d, 0x70, 00, 0xa7, 0xf9, 0x61, 0xc5, 0x49, 0xe3, 0x40, 
+       0x5d, 0xfd, 0x90, 0x72, 0xc5, 0xf2, 0x50, 0x55, 0x5f, 0x77, 
+       0x4c, 0xf3, 0xa2, 0xa5, 0xa7, 0x5b, 0x2d, 0x9e, 0x34, 0x17, 
+       0xe0, 0x1e, 0xad, 0xd8, 0x10, 0x60, 0x79, 0xa5, 0xea, 0xf5, 
+       0xda, 0xda, 0x93, 0x1d, 0x46, 0x7c, 0xa7, 0xc7, 0xec, 0x75, 
+       0x61, 0x87, 0xf4, 0x90, 0x12, 0xed, 0x17, 0x89, 0x62, 0x4c, 
+       0x47, 0x6d, 0x2d, 0x61, 0xfa, 0x91, 0x51, 0x64, 0xe0, 0x46, 
+       0xda, 0x30, 0xca, 0xe1, 0x7c, 0x7f, 0x14, 0x81, 0xd3, 0x7f, 
+       0x91, 0x65, 0x1c, 0x2a, 0x36, 0x4, 0xd6, 0xdc, 0xb6, 0xa3, 
+       0x3c, 0xe3, 0x48, 0x61, 0x5d, 0x74, 0xfe, 0xe1, 0xba, 0x12, 
+       0x98, 0x85, 0x1f, 0x22, 0x5e, 0x39, 0x9c, 0x15, 0xd8, 0x4, 
+       0xb5, 0x15, 0xd8, 0x4, 0x38, 0xc5, 0x90, 0x5f, 0x6f, 0xc7, 
+       0x2a, 0xb3, 0x99, 0xe8, 0x5f, 0x3d, 0x8e, 0x16, 0x3a, 0x81, 
+       0xa6, 0xb8, 0x8, 0xe, 0x9e, 0x9d, 0x53, 0x22, 0xd8, 0xfa, 
+       0x3, 0xee, 0x74, 0x7f, 0x99, 0xf7, 0x5, 0xc4, 0x56, 0x1f, 
+       0x2b, 0xa9, 0x14, 0xce, 0xf, 0x37, 0xb9, 0xe5, 0x92, 0xa0, 
+       0xa6, 0xb9, 0x8b, 0x43, 0x1e, 0x6c, 0xd4, 0x8a, 0x5c, 0x9c, 
+       0x81, 0xe5, 0x94, 0x6, 0xfa, 0x86, 0x5a, 0x8b, 0xfa, 0x58, 
+       0x10, 0xfa, 0x13, 0xdc, 0x18, 0x89, 0xad, 0xad, 0x3d, 0x89, 
+       0x23, 0x7e, 0xd2, 0x43, 0x47, 0xb0, 0xdc, 0x9d, 0x35, 0x67, 
+       0x5, 0xce, 0x6d, 0x8b, 0x57, 0xdd, 0xdd, 0x9d, 0xaa, 0xb7, 
+       0xb7, 0xb, 0x8d, 0x42, 0x86, 0xca, 0xc9, 0x9d, 0xad, 0x1b, 
+       0x81, 0xc6, 0xfa, 0x4a, 0x95, 0x96, 0x6a, 0xa8, 0x68, 0xac, 
+       0x42, 0x1a, 0x8c, 0xec, 0xf6, 0x68, 0x85, 0x75, 0xdd, 0xfa, 
+       00, 0x44, 0xc6, 0xe3, 0x2c, 0x53, 0x6b, 0x6b, 0xab, 0x81, 
+       0xef, 0x31, 0xb1, 0xa1, 0xc3, 0xa4, 0xb6, 0x47, 0x63, 0x65, 
+       0xa2, 0x81, 0xb2, 0xb1, 0x91, 0x12, 0x90, 0x8b, 0xcf, 0x3a, 
+       0x11, 0xa0, 0xf3, 0x1e, 0x49, 0x80, 0x6d, 0xf5, 0xf5, 0x83, 
+       0x11, 0xfc, 0x87, 0x63, 0x83, 0x54, 0xde, 0xf6, 0xed, 0xa, 
+       0xe7, 0x84, 0x5, 0x52, 0xfd, 0x9f, 0x7d, 0xfb, 0xd4, 0xba, 
+       0xe2, 0x12, 0xdd, 0xa7, 0xe, 0xdc, 0x1c, 0x42, 0xc0, 0x8b, 
+       0xee, 0x50, 0x3, 00, 0xce, 0x5, 0x59, 0x7b, 0x80, 0x87, 
+       0x8a, 0xf6, 0x36, 0xb5, 0x30, 0x23, 0x43, 0xcd, 0x1d, 0x93, 
+       0x8e, 0x5f, 0x82, 0x30, 0x47, 0xad, 0x4c, 0x36, 0xaf, 0xed, 
+       0x35, 0x8d, 0x8e, 0x8d, 0x2d, 0xc6, 0xbb, 0x43, 0x48, 0x2e, 
+       0x28, 0xca, 0x69, 0xb, 0x47, 0x2f, 0x60, 0x61, 0x63, 0x18, 
+       0x14, 0x63, 0x28, 0x97, 0x11, 0x83, 0x5b, 0xeb, 0x4a, 0xc2, 
+       0x89, 0x8e, 0xba, 0x92, 0x8e, 0xd0, 0xf2, 0xb7, 0xf2, 0x8, 
+       0xd, 0x8b, 0x50, 0xdf, 0xe6, 0xf6, 0x9d, 0xe5, 0x63, 0xf, 
+       0x1f, 0xa9, 0x75, 0xe6, 0x17, 0xd4, 0x15, 0xa3, 0x4f, 0xbf, 
+       0x9, 0x9, 0x55, 0xc1, 0xd1, 0x4, 0x27, 0xb8, 0x5, 0xd4, 
+       0xf4, 0x59, 0x3b, 0x74, 0x52, 0x12, 0x4a, 0xa3, 0x1d, 0x9b, 
+       0xfd, 0x6f, 0xc4, 0x82, 0x94, 0x9f, 0x62, 0x41, 0x4a, 0x74, 
+       0x6e, 0x6e, 0xee, 0x70, 0xf8, 0x81, 0x64, 0x22, 0x23, 0x2b, 
+       0xa8, 0x25, 0x6c, 0x5, 0x33, 0xc3, 0x7a, 0x4, 0x1a, 0x82, 
+       0xc5, 0x1, 0x29, 0x2, 0x1a, 0x60, 0xf0, 0x2, 0xc0, 0x6, 
+       0xbb, 0xa, 0x38, 0x9a, 0x9, 0xfd, 0xb7, 0x74, 0x83, 0x47, 
+       0x18, 0x83, 0xfa, 0x95, 0x19, 0xfd, 0x64, 0x75, 0xff, 0xfd, 
+       0xf7, 0x9f, 0xb1, 0x40, 0xbf, 0xff, 0x7f, 0x4f, 0x9c, 0x31, 
+       0x8e, 0x44, 0xe0, 0xc2, 0x96, 0x5, 0xb, 0xaf, 0x50, 0xdb, 
+       0xb6, 0xbe, 0xa1, 0x6f, 0x2d, 0x5a, 0x74, 0x95, 0x6, 0x16, 
+       0xcb, 0x29, 0xf4, 0xd9, 0xcf, 0x7e, 0x56, 0x82, 0x43, 0xf2, 
+       0xd9, 0x10, 0xf9, 0x4f, 0x56, 0x31, 0x70, 0x52, 0xb3, 0xee, 
+       0x52, 0xe0, 0x10, 0x44, 0x36, 0x4e, 0x58, 0x5e, 0xe9, 0xe2, 
+       0xa9, 0xa8, 0x26, 0xe2, 0x68, 0x13, 0x9e, 0x60, 0x16, 0x90, 
+       0xd3, 0x67, 0x63, 0x27, 0x9a, 0x5c, 0x7c, 0x2b, 0xc0, 0x19, 
+       0x1e, 0x29, 0xc2, 0xa9, 0x83, 0xca, 0x83, 0xae, 0xc, 0xc1, 
+       0xed, 0x42, 0xbe, 0x38, 0xb9, 0x41, 0xd5, 0x74, 0x74, 0x28, 
+       0xe, 0x96, 0xd, 0x87, 0x38, 0xae, 0x51, 0x5f, 0x77, 0xdc, 
+       0xa7, 0x59, 0x50, 0xce, 0x36, 0x68, 0x6f, 0xa6, 0xcb, 0xa5, 
+       0xa8, 0x34, 0xa3, 0xa1, 0xb5, 0x43, 0x6e, 0x74, 0x1a, 0x4e, 
+       0x5e, 0xc3, 0x79, 0x27, 0x42, 0x70, 0x53, 00, 0x88, 0x29, 
+       0x2b, 0xa2, 0xcf, 0x1e, 0xd9, 0x4, 0xf6, 0xee, 0xbd, 0x95, 
+       0xe9, 0x87, 0xb, 0x6b, 0x63, 0x8e, 0xf8, 0x80, 0xbd, 0x11, 
+       0x99, 0x54, 0xfa, 0x33, 0x23, 0x98, 0xa5, 0x8f, 0x2d, 0x61, 
+       0x1, 0x36, 0xb, 0xa2, 0x6d, 0x17, 0xec, 0xfb, 0xfd, 0x17, 
+       0x98, 0xb3, 0xf7, 0xdc, 0x78, 0xe3, 0x8d, 0x31, 0xe7, 0xe3, 
+       0x88, 0x23, 0x1, 0x32, 0xf2, 0xd7, 0x1a, 0x9b, 0x42, 0x4a, 
+       0xa2, 0x2f, 0x60, 0x96, 0x30, 0x4f, 0x1, 0x5, 0xa8, 0xbd, 
+       0x68, 0x78, 0xc, 0xee, 0x53, 0xe6, 0xe0, 0x16, 0x1, 0x4d, 
+       0xad, 0x36, 0x92, 0x34, 0x6b, 0xf6, 0x65, 0xea, 0x99, 0xe7, 
+       0xe, 0xea, 0xb5, 0xe5, 0xda, 0xa2, 0xb2, 00, 0xd6, 0x9a, 
+       0xcf, 0x94, 0xa9, 0xb, 0x2, 0xe0, 0x5e, 0xb6, 0xfc, 0x46, 
+       0xeb, 0xa3, 0x11, 0x9, 0xb3, 0xa1, 0x82, 0xe3, 0xa, 0x40, 
+       0x58, 0x8, 0xdd, 0x18, 0xbc, 0x6b, 0x50, 0x98, 0x63, 0x36, 
+       0x61, 0xa5, 0x90, 0xf, 0xec, 0xaf, 0xf3, 0x97, 0x50, 0x34, 
+       0xc8, 0xad, 0x40, 0x17, 0x6d, 0x7e, 0x2e, 0x40, 0xee, 00, 
+       0x80, 0x93, 0xab, 0xaa, 0x94, 0x37, 0xa, 0x22, 0xf, 0x29, 
+       0x2a, 0x6b, 0x6d, 0x55, 0x9f, 0x7a, 0xdd, 0xd7, 0xc0, 0x9d, 
+       0xcd, 0x47, 0x73, 0x86, 0xa2, 0xb1, 0xfe, 0x84, 0x6e, 0xa0, 
+       0x76, 0x16, 0x3b, 0x54, 0x71, 0x4b, 0x8b, 0xfa, 0xc4, 0xcc, 
+       0x99, 0x66, 0xc, 0xd6, 0xa3, 0x2, 0xe2, 0x6a, 0x66, 0x82, 
+       0x91, 0x57, 0xdc, 0x63, 0x94, 0xe2, 0x38, 0x2, 0x2a, 0xa2, 
+       0x21, 0x92, 0x68, 0x6e, 0x76, 0x5f, 0x38, 0x96, 0x81, 0x53, 
+       0x98, 0x87, 0xd1, 0xc8, 0x45, 0x4, 0x6e, 0xa, 0xc, 0x96, 
+       0x46, 0xe0, 0x8f, 0xc6, 0x39, 0x4c, 0x4d, 0xbf, 0xf3, 0x99, 
+       0xe6, 0x43, 0x2c, 0x77, 0x50, 0x34, 0x2, 0x1b, 0x3, 0x67, 
+       0xa9, 0x7, 0xa, 0x6a, 0x13, 0xe, 0x1f, 0xae, 0x2f, 0x71, 
+       0x79, 0xf4, 0xaa, 0x33, 0x2, 0xdb, 0x6a, 0x8a, 0xb3, 0x5, 
+       0x24, 0xc0, 0xe9, 0xf3, 0x3e, 0x19, 0x25, 0xad, 0x8a, 0x1, 
+       0x4d, 0xfd, 0x4, 00, 0xbd, 0xe4, 0xda, 0x6b, 0xaf, 0x85, 
+       0x75, 0x8b, 0x41, 0xa4, 0x73, 0x48, 0x43, 0x1, 0x35, 0xc1, 
+       0x4d, 0x47, 0x2d, 0xd, 0x6d, 0xed, 0x85, 0xd9, 0x6d, 0x60, 
+       0xc, 0x40, 0xd1, 0x9a, 0xe0, 0x32, 0xc9, 0xb, 0x45, 0x9d, 
+       0x9d, 0x6d, 0xaa, 0x1, 0xa6, 0xf7, 0x87, 0x9b, 0x5e, 0xd6, 
+       0x45, 0xc8, 0x9d, 0x34, 0x5b, 0x65, 0x64, 0xe6, 0x60, 00, 
+       0xed, 0xdc, 0x95, 0x88, 0xd, 0x18, 0xa6, 0x21, 0xd, 0xce, 
+       0x91, 0x63, 0x84, 0x1f, 0xb, 0x63, 0x4a, 0x15, 0xe, 0x5c, 
+       0x30, 0xf1, 0xb, 0x26, 0x5a, 0x9b, 0xf3, 0x79, 0x30, 0xd0, 
+       0x9, 0x6e, 0x1, 0x7d, 0xb0, 0x16, 0x1f, 0x8e, 0x90, 0xf3, 
+       0xeb, 0x52, 0x2a, 0x2b, 0x54, 0x1a, 0xd6, 0x9, 0x8, 0xa5, 
+       0x21, 0xdf, 0x77, 0xde, 0x79, 0x47, 0x77, 0x2f, 0x56, 0xe2, 
+       0x64, 0x56, 0x4e, 0x3, 0xa, 0xb1, 0x4c, 0xdf, 0xff, 0xfe, 
+       0xf7, 0xd5, 0xaa, 0x55, 0xab, 0x74, 0x77, 0x69, 0xe7, 0xce, 
+       0x9d, 0xea, 0x91, 0x47, 0x1e, 0xd1, 0x8d, 0x54, 0xa8, 0x38, 
+       0x3c, 0xa3, 0xfd, 0xf1, 0xc7, 0xff, 0xa8, 0xa, 0x8e, 0x56, 
+       0xaa, 0x18, 0x58, 0x46, 0x4e, 0xfb, 0x1c, 0x80, 0x51, 0xa9, 
+       0x44, 0xbb, 0x37, 0x2d, 0xd1, 0xae, 0xd2, 0xdc, 0xca, 0xd1, 
+       0x57, 0xd2, 0xa3, 0x4e, 0xca, 0xbb, 0x67, 0xf2, 0x5, 0xc7, 
+       0x60, 0x83, 0x4e, 0x47, 0xf, 0x94, 0x53, 0x85, 0x45, 0x48, 
+       0x11, 0x81, 0x5b, 0xc3, 0x49, 0x74, 0xe6, 0x8, 0x98, 0xe5, 
+       0x4, 0x76, 0x41, 0x61, 0x43, 0xf2, 0x81, 0x3, 0xb5, 0xa3, 
+       0xe, 0x1f, 0xa9, 0x2b, 0xe9, 0x73, 0x7b, 0x36, 0xa3, 0xfc, 
+       0x64, 0x42, 0x38, 0x60, 0x13, 0xe0, 0xcc, 0x99, 0xa5, 0x20, 
+       0xd9, 0x71, 0x42, 0xca, 0x4d, 00, 0xd2, 0xea, 0xeb, 0xae, 
+       0xbb, 0x4e, 0x9d, 0xcb, 0x93, 0x51, 0xc2, 0x81, 0x3a, 0x58, 
+       0x4b, 0x73, 0x50, 0x9, 0x9a, 0xca, 0xe4, 0x28, 0x32, 0xcd, 
+       0x6e, 0x2, 0x1a, 0x3f, 0xf, 0x64, 0x40, 0x58, 0x47, 0xce, 
+       0xbe, 0xf4, 0x7d, 0x7b, 0xc4, 0xff, 0xb7, 0x6d, 0x79, 0x43, 
+       0xfd, 0xf5, 0xb9, 0x5f, 0x6, 0xde, 0xbb, 0xe6, 0xba, 0x7b, 
+       0x2, 0xe1, 0xf3, 0x11, 0x60, 0xc3, 0x86, 0x95, 0x63, 0x7a, 
+       00, 0xe, 0x3f, 0x5e, 0x40, 0xa0, 0x9b, 0xd0, 0xec, 0x26, 
+       0xfb, 0xeb, 0xec, 0xa6, 0x10, 0xd0, 0xe2, 0xc4, 0x5c, 0x17, 
+       0xa0, 0x9f, 0x2d, 0xc8, 0x5b, 0x33, 0x32, 0xd5, 0x68, 0x8c, 
+       0x5f, 0xe0, 0x87, 0xd0, 0xd4, 0x3b, 0xa5, 0x65, 0xca, 0xb3, 
+       0x7a, 0xb5, 0x7a, 0xe4, 0x1a, 0x4c, 0x4f, 0x83, 0x98, 0xa7, 
+       0x10, 0xf3, 0x79, 0xed, 0xb5, 0xd7, 0x14, 0x6, 0x62, 0xe5, 
+       0x96, 0xc2, 0x21, 0x1d, 0xa, 0xa, 0x44, 0xf1, 0xd4, 0x56, 
+       0xc, 0x20, 0x2, 0x70, 0x3, 0xe3, 0xb0, 0x3b, 0xf2, 0xeb, 
+       0x5f, 0xff, 0x56, 0xad, 0x7b, 0x7b, 0x87, 0xfa, 0xfd, 0x8e, 
+       0x8d, 0xc6, 0x1d, 0xf3, 0x96, 0xa9, 0xcc, 0x84, 0x78, 0xd5, 
+       0xe7, 0x35, 0xba, 0x6a, 0x5c, 0xf6, 0x1a, 0x2, 0x75, 0xe8, 
+       0x14, 0xa4, 0xb9, 0xf5, 0x46, 0xf1, 0xc8, 0xc5, 0x27, 0x22, 
+       0x70, 0xd3, 0xf0, 0x1c, 0x29, 0xcd, 0x4d, 0x60, 0x9f, 0x28, 
+       0x6e, 0x4a, 0xda, 0xb5, 0xbf, 0x2a, 0xf5, 0x50, 0x41, 0x5d, 
+       0x69, 0x6f, 0x9f, 0x87, 0xd3, 0x5d, 0xc5, 0x70, 0xc1, 0xc0, 
+       0xe, 0xa7, 0xb5, 0xc9, 0x2e, 0xfb, 0x81, 0x3, 0x7, 0xde, 
+       0xc2, 0x61, 0xa, 0xbf, 0x79, 0xe5, 0x95, 0x57, 0x1e, 0xb8, 
+       0xfd, 0xf6, 0xdb, 0xcf, 0x89, 0xe6, 0x16, 0x93, 0x1b, 0xf9, 
+       0xf5, 0x1b, 0xed, 0x16, 0x60, 0xb3, 0x2f, 0xcd, 0x41, 0x24, 
+       0x80, 0x5a, 0x9b, 0xde, 0x18, 0x18, 0x33, 0x1, 0x6a, 0x1b, 
+       0xcf, 0x3, 0xbb, 0x98, 0x28, 0x2e, 0x3e, 0x51, 0xa5, 0xa6, 
+       0x8d, 0x43, 0xa3, 0x33, 0x5a, 0x2d, 0x58, 0xb0, 0x56, 0xcd, 
+       0x9b, 0xbf, 0xfa, 0xac, 0xc7, 0x4a, 0x86, 0xf3, 0x7d, 0x4, 
+       0x13, 0xf6, 0x60, 0x1b, 0x70, 0xec, 0x8f, 0x1b, 0x4, 0x39, 
+       0x40, 0xa3, 0xb5, 0x79, 0xb0, 0xc9, 0xce, 0xb8, 0xe4, 0x3f, 
+       0xfd, 0xe1, 0x9a, 0xeb, 0x1c, 0x15, 0x1f, 0x5d, 0x59, 0xc1, 
+       0xd3, 0xba, 0xd4, 0xa4, 0x7, 0x3f, 0xa7, 0xbe, 0x3e, 0x79, 
+       0xb2, 0x8a, 0xc3, 0x78, 0x46, 0x28, 0x82, 0x2c, 0x69, 0x60, 
+       0xb3, 0x6e, 0xef, 0xb8, 0xe3, 0xe, 0x9e, 0xb5, 0xae, 0xde, 
+       0x7e, 0xfb, 0x6d, 0x36, 0x4a, 0xa, 0xf2, 0xa5, 0xfe, 0xfc, 
+       0xe7, 0x3f, 0xab, 0x70, 0x71, 0x3e, 0xff, 0xf9, 0x7, 0xd5, 
+       0xf6, 0xed, 0x3b, 0x70, 0x3e, 0xdd, 0x71, 0xe5, 0x9a, 0x32, 
+       0x45, 0xd9, 00, 0x6e, 0x7, 0x5a, 0x82, 0x29, 0x31, 0xde, 
+       0x49, 0x47, 0xbb, 0x6d, 0xc7, 0x42, 0xe5, 0x17, 0xee, 0x1e, 
+       0xa1, 0x2c, 0x8e, 0x82, 0x1e, 0x39, 0xb4, 0x7d, 0xfd, 0xd5, 
+       0x70, 0xe9, 0xf, 0xbc, 0xef, 0x43, 0xb7, 0x4f, 0x77, 0x52, 
+       0x7f, 0xe, 0xd3, 0x61, 0x67, 0xb7, 0x59, 0x5d, 0xd9, 0x1e, 
+       0xbb, 0x67, 0x6f, 0xcd, 0x98, 0x23, 0x47, 0xeb, 0xcb, 0x7a, 
+       0x7b, 0x3d, 0xdc, 0xd1, 0xc0, 0x8f, 0x17, 0x60, 0xb3, 0x6f, 
+       0x4d, 0x50, 0x5b, 0x81, 0x4d, 0xad, 0x4d, 0x27, 0xb6, 0x3, 
+       0x4b, 0x43, 0xa7, 0x78, 0x2a, 0x7, 0x4c, 0xe0, 0x67, 0x5f, 
+       0x7d, 0xf5, 0x55, 0x74, 0xeb, 0xf8, 0xca, 0xc8, 0x10, 0xb5, 
+       0xb5, 00, 0x9b, 0x3e, 0x2b, 0x9c, 0x8e, 0x60, 0xe6, 0x40, 
+       0x11, 0x1d, 0xf3, 0xc3, 0xce, 0x23, 0xe, 0x1c, 0x99, 0xec, 
+       0x63, 0xa2, 0xe2, 0xd, 0x1c, 0xf2, 0x70, 0xd1, 0x1, 0x9b, 
+       0x1c, 0x59, 0xb9, 0xea, 0x16, 0xf5, 0x93, 0x9f, 0xbf, 0xa2, 
+       0xbe, 0xf5, 0xdd, 0xc7, 0xd5, 0xb5, 0xd7, 0xdf, 0x3b, 0x32, 
+       0x4c, 0x3a, 0xcb, 0x54, 0xd8, 00, 0x82, 0x5f, 0x6, 0xf9, 
+       0x86, 0x46, 0x11, 0x6b, 0xac, 0xbd, 0x26, 0xcd, 0x76, 0x5a, 
+       0x40, 0x6c, 0x30, 0xe9, 0x84, 0xdf, 0xf4, 0xa5, 0x41, 0x15, 
+       0x4b, 0x4a, 0xea, 0x67, 0xb0, 0x62, 0x24, 0xc2, 0x6c, 0x4e, 
+       0xa9, 0xac, 0xd4, 0x53, 0x5f, 0x9, 0x33, 0x67, 0xe, 00, 
+       0x36, 0xd3, 0x12, 0xc2, 0x72, 0x55, 0x1d, 0xa4, 0xc9, 0x4e, 
+       0xd, 0xe, 0xd9, 0x52, 0x4f, 0x3d, 0xf5, 0x94, 0xbe, 0x47, 
+       0x70, 0x93, 0xc2, 0xc5, 0xc1, 0x82, 0x29, 0xf5, 0xf1, 0x8f, 
+       0xdf, 0xa5, 0x2a, 0xaa, 0x8e, 0xa8, 0xbf, 0xed, 0xff, 0x40, 
+       0x95, 0x9f, 0xaa, 0xc5, 0x81, 0x26, 0xde, 0xd8, 0xec, 0x18, 
+       0xcf, 0xcc, 0xb1, 0xd1, 0x66, 0xba, 0x5e, 0x22, 0x4e, 0x23, 
+       0x61, 0x38, 0x6e, 0x18, 0xe8, 0x8e, 0xc8, 0x58, 0xf0, 0x61, 
+       0x69, 0x98, 0x88, 0xf6, 0xb7, 0x4, 0x38, 0xea, 0x50, 0xef, 
+       0xee, 0xda, 0xb6, 0xeb, 0x64, 0x76, 0xe1, 0xb1, 0x86, 0xca, 
+       0xae, 0x2e, 0x37, 0x4f, 0xe8, 0x2b, 0x80, 0x23, 0x68, 0x9, 
+       0x5e, 0x2, 0x5b, 0xc0, 0xcd, 0x6b, 0x1, 0x38, 0x81, 0x2f, 
+       0x4e, 0x9a, 0x19, 0xd6, 0xa, 0x3f, 0xdb, 0xb6, 0x7b, 0xf7, 
+       0xee, 0x3f, 0xe2, 0x50, 0xfb, 0x57, 00, 0xf0, 0xde, 0xb3, 
+       0x5, 0xb8, 0x80, 0x5a, 0x4, 0x28, 0x14, 0xa8, 0x29, 0x74, 
+       0x18, 0x24, 0xe2, 0x80, 0x91, 0x89, 0xfe, 0xa4, 0x89, 0x69, 
+       0x37, 0x3, 0x6b, 0xd7, 0xf9, 0x73, 0xb9, 0x28, 0xce, 0x25, 
+       0x8a, 0x94, 0x3, 0xe4, 0x1b, 0xf8, 0x67, 0x90, 0x8f, 0x9c, 
+       0x25, 00, 0xcf, 0x4d, 0x8e, 0x59, 0x10, 0xe4, 0x2, 0x74, 
+       0x36, 0xa6, 0x4, 0x38, 0x1d, 0x41, 0x4d, 0x67, 0xad, 0xab, 
+       0x70, 0x79, 0xb6, 0xe1, 0xc7, 0x10, 0xba, 0xfc, 0x56, 0xd4, 
+       0x8e, 0x2f, 0x7d, 0x51, 0x4d, 0x46, 0x98, 0xfd, 0xec, 0x50, 
+       0x44, 0xf3, 0x9a, 0x84, 0x35, 0xe8, 0x81, 0xc7, 0xd8, 0x61, 
+       0xa6, 0xc3, 0x38, 0xed, 0x56, 0xfb, 0x83, 0xc5, 0xb9, 0xf9, 
+       0xe6, 0x9b, 0xd1, 0xe8, 0xf7, 0xa8, 0xc2, 0xd2, 0x83, 0x6a, 
+       0xf7, 0xb1, 0xdd, 0xde, 0x8e, 0xae, 0xe, 0xd5, 0xe9, 0xb1, 
+       0xd7, 0x35, 0x7b, 0x1c, 0xd, 0xb0, 0x3d, 0x80, 0xeb, 0x48, 
+       0x1d, 0x77, 0x5c, 0x71, 0x68, 0x2e, 0x42, 0xa8, 0xa2, 0xa4, 
+       0x11, 0xbe, 0xe1, 0x9b, 0xd6, 0xf1, 0x60, 0xe7, 0x97, 0x8, 
+       0x7c, 0x24, 0x3e, 0xa6, 0xe, 0xcc, 0xce, 0xce, 0x5e, 0xfb, 
+       0x87, 0x5b, 0xcb, 0xc7, 0x9f, 0x28, 0x3e, 0x55, 0xd7, 0xdc, 
+       0xda, 0x5b, 0x88, 0x32, 0x70, 0x5b, 0x12, 0x41, 0x4b, 0x40, 
+       0xb, 0xb8, 0x5, 0xd0, 0xe2, 0xb, 0xa8, 0x45, 0x6b, 0xd3, 
+       0x27, 0xc0, 0x65, 0x50, 0x4d, 0x87, 0xf7, 0xee, 0xdd, 0xfb, 
+       0x2c, 0x6, 0x37, 0xd6, 0x1, 0xe0, 0x7d, 0xc3, 0x5, 0xb8, 
+       00, 0x1a, 0x69, 0x7, 0x4, 0x48, 0xbe, 0x51, 0xb4, 0x35, 
+       0x41, 0x8d, 0x7e, 0xa2, 0x89, 0x1f, 0xef, 0x33, 0xb1, 0xa, 
+       0xce, 0x80, 0xd3, 0xd3, 0x3c, 0x7c, 0xe7, 0x12, 0x9d, 0x1d, 
+       0x7, 0x38, 0x56, 0x41, 0x9e, 0xa2, 0x9f, 0x6b, 0x60, 0x2e, 
+       0x9d, 0x16, 0x91, 0x17, 0x83, 0x6f, 0xfd, 00, 0x2e, 0xf5, 
+       0x60, 0x5, 0xb9, 0x80, 0x3d, 0x54, 0xee, 0x51, 0xf8, 0x6d, 
+       0x3, 0x98, 0x4, 0xfa, 0x51, 0x1c, 0x46, 0xe9, 0xf3, 00, 
+       0x6e, 0xd6, 0x73, 0x28, 0x92, 0x5f, 0x87, 0x61, 0x9e, 0x42, 
+       0xa8, 0x6b, 0x1d, 0x94, 0x67, 0xe2, 0xf, 0x16, 0x67, 0x72, 
+       0x42, 0xb4, 0x8a, 0xef, 0x6d, 0xb0, 0x6d, 0x2d, 0xdc, 0xa9, 
+       0xba, 0x3c, 0x2e, 0x77, 0x8c, 0xc3, 0x88, 0x56, 0x38, 0x9d, 
+       0xc8, 0x77, 0xa, 0x3, 0xf4, 0x91, 0x3e, 0x8d, 0x61, 0x28, 
+       0x3e, 0x20, 0xca, 0xb8, 0x54, 0x61, 0x11, 0x52, 0x84, 0xe0, 
+       0x8e, 0x30, 0x75, 0x4b, 0x74, 0xf6, 0xb1, 0x31, 0x70, 0x6c, 
+       0x6c, 0xde, 0x51, 0x99, 0x55, 0x5c, 0xde, 0xd2, 0x56, 0x53, 
+       0xd7, 0xc9, 0xfe, 0xf5, 0x56, 0x38, 0x1, 0xb5, 0x68, 0x69, 
+       0xb9, 0xe, 0x5, 0x6c, 0xab, 0xc6, 0x66, 0xed, 0x8, 0xc0, 
+       0xe9, 0x13, 0xf0, 0x6e, 0xf4, 0xc1, 0x5f, 0xc0, 0x60, 0xcd, 
+       0xbb, 0x91, 0x2, 0xdc, 0xaa, 0x1, 0x18, 0x16, 0x40, 0x8b, 
+       0xa6, 0xa0, 0xa6, 0xe6, 0x60, 0xa, 0xfb, 0xd5, 0x98, 0xd3, 
+       0x35, 0x29, 0x7c, 0x4b, 0x97, 0x2e, 0xe5, 0x40, 0x10, 0xb2, 
+       0xbd, 0x44, 0x23, 0xcd, 0x1, 0xf2, 0x95, 0xfc, 0xc5, 0x80, 
+       0xa9, 0xd, 0xb3, 0xd, 0x50, 0xa, 0x9d, 0x5e, 0x8e, 0xb6, 
+       0xb3, 0xd1, 0xb6, 0x82, 0x9b, 0xf5, 0xc3, 0xba, 0x1a, 0x4c, 
+       0x8b, 0x8f, 0x29, 0x2e, 0x56, 0xb1, 0x7e, 0x80, 0xbe, 0x8f, 
+       0x13, 0x54, 0xb1, 0xcb, 0x2b, 0x6c, 0x71, 0xd9, 0xb8, 0x90, 
+       0x58, 0xdf, 0x42, 0x12, 0x96, 0x67, 0xe2, 0xcb, 0x7d, 0x6b, 
+       0x7c, 0x79, 0x76, 0xb4, 0xa9, 0x49, 0xc5, 0x79, 0xba, 0x94, 
+       0xbb, 0xad, 0x5a, 0x15, 0x1c, 0xdf, 0x9e, 0x95, 0x1b, 0xd5, 
+       0x3b, 0x15, 0xdd, 0x6f, 0xc8, 0xec, 0x80, 0xb3, 0x4b, 0x24, 
+       0x9b, 0x11, 0xf7, 0x23, 0x1a, 0x50, 0x63, 0x63, 0xe7, 0xc6, 
+       0xc4, 0x3d, 0xf6, 0x6e, 0xea, 0xb9, 0x54, 0x74, 0x8f, 0xc0, 
+       0x54, 0xdf, 0x44, 0x58, 0x98, 0x86, 0x50, 0x17, 0x98, 0xc0, 
+       0xa6, 0x8e, 0xdd, 0xb1, 0xb7, 0x66, 0x6c, 0x69, 0x59, 0x8b, 
+       0xbb, 0xb4, 0xac, 0xb5, 0x4, 0xf, 0x36, 0xc2, 0x71, 0xdb, 
+       0xa6, 0x68, 0x6d, 0x1, 0x35, 0x7d, 0x2, 0x9b, 0xf7, 0x35, 
+       0x60, 0xe1, 0xb3, 0x2f, 0x40, 00, 0xd3, 0xb1, 0xd, 0x43, 
+       0x6a, 0x1, 0xa7, 0xe3, 0x40, 0x8, 0x52, 0xd1, 0xa2, 0xe6, 
+       0xc1, 0xbc, 0x9b, 0x88, 0x16, 0xf5, 0x28, 0x84, 0x21, 0xe9, 
+       0x6f, 0x7f, 0xfb, 0xdb, 0x52, 0xf4, 0x8f, 0x9c, 0x67, 0x32, 
+       0x95, 0xc3, 0x69, 0x6b, 0xa, 0xc, 0x5, 0x87, 0xc2, 0x84, 
+       0x6, 0xc3, 0xe4, 0xfc, 0x39, 0x47, 0x7b, 0x73, 0x31, 0x2, 
+       0x8e, 0xfc, 0x2f, 0xd1, 0x79, 0xe0, 0x80, 0x2c, 0x8e, 0xc1, 
+       0xa0, 0x1b, 0x37, 0xd0, 0x70, 0xd0, 0x8d, 0xb3, 0x10, 0x7a, 
+       0xc4, 0x9d, 0x53, 0x68, 0xd6, 0x69, 0x34, 0x16, 0x87, 0x23, 
+       0xd9, 0x1c, 0x78, 0x63, 0x9d, 0xd2, 0x27, 0x35, 0xe4, 0xe4, 
+       0xaa, 0x28, 0x34, 0xa, 0xd1, 0x58, 0xb0, 0x72, 0x25, 0x56, 
+       0x1, 0x5e, 0x31, 0xa1, 0x5c, 0xb, 0x9e, 0x7e, 0x18, 0xf4, 
+       0xf, 0x5d, 0x3b, 0x7d, 0x7, 0x5b, 0x83, 0x3, 0x4f, 0x64, 
+       0xfa, 0x12, 0x63, 0x1, 0xfa, 0xde, 0x50, 0xe2, 0xdc, 0x81, 
+       0xa9, 0xcf, 0xbb, 0x67, 0x4c, 0x57, 0x7f, 0x3b, 0x7e, 0x42, 
+       0x95, 0x35, 0x94, 0xb7, 0x95, 0xb9, 0x9d, 0xad, 0xb9, 0x33, 
+       0xae, 0x82, 0xdc, 0x2, 0xa, 0x5c, 0x2f, 0x3c, 0x18, 0xe1, 
+       0x1b, 0xf8, 0x1d, 0x9c, 0xe3, 0x3e, 0x6f, 0xf3, 0xdc, 0x83, 
+       0x95, 0xe7, 0x4c, 0xcf, 0xa, 0x8f, 0x9d, 0x4a, 0x2e, 0x2a, 
+       0x69, 0x8e, 0x39, 0x5e, 0xdc, 0x72, 0xc, 0x71, 0x3f, 0x80, 
+       0xe3, 0xd1, 0x34, 0x6c, 0x1e, 0xc5, 0x9, 0xb8, 0xc5, 0xe4, 
+       0x16, 0x30, 0x23, 0x8a, 0x6, 0x34, 0x19, 0x22, 0x96, 0x86, 
+       0x30, 0xc7, 0xb, 0x13, 0x2e, 0x1e, 0xfd, 0xb4, 0x7b, 0x51, 
+       0x1, 0x4b, 0xb0, 0x86, 0x3c, 0x1, 0xa3, 0xaa, 0xb1, 0xec, 
+       0xa3, 0x71, 0xde, 0x12, 0xe6, 0x54, 0xe5, 0xba, 0x75, 0xeb, 
+       0xc6, 0x63, 0x61, 0x4b, 0x54, 0x38, 0x80, 0x13, 0xc0, 0x24, 
+       0xd1, 0xdc, 0x62, 0xde, 0x89, 0xc6, 0xe6, 0x9a, 0x6f, 0xb4, 
+       0xd0, 0x5e, 0x98, 0xe0, 0x6, 0x56, 0xc0, 0x5d, 0xd0, 0x79, 
+       0x6a, 0x5d, 0xd0, 0xff, 0xa5, 0xff, 0xd8, 0xa0, 0x62, 0xaf, 
+       0x80, 0xc2, 0xa9, 0x2a, 0x26, 0x46, 0xd8, 0x71, 0x9c, 0xb6, 
+       0x5d, 0x8f, 0x6f, 0xb0, 0xbe, 0x8, 0x70, 0x69, 0xa0, 0x39, 
+       0xaa, 0x4e, 0x22, 0x38, 0xf8, 0x8c, 0x7e, 0x1f, 0x80, 0xda, 
+       0x87, 0x3e, 0x3d, 0xc1, 0xdd, 0x87, 0x7b, 0xd5, 0xf0, 0xc3, 
+       0xcd, 0x63, 0x70, 0x74, 0x9c, 0xc4, 0x7e, 0xbf, 0x10, 0xea, 
+       0x5e, 0x7, 0x39, 0x9f, 0x4d, 0x1a, 0x4a, 0x9c, 0x93, 0xb0, 
+       0xf2, 0xb0, 0x3f, 0xdc, 0xbc, 0x6e, 0x52, 0xae, 0xf1, 0x3f, 
+       0x7b, 0xf7, 0xd7, 0x16, 0xb5, 0xf5, 0x28, 0x47, 0xfc, 0xe8, 
+       0x94, 0xf1, 0x13, 0xe7, 0xb7, 0x18, 0x38, 0x35, 0x18, 0x8b, 
+       0x5f, 0x44, 0x96, 0x75, 0x9a, 0xfd, 0xfe, 0x89, 0x74, 0x33, 
+       0x86, 0x48, 0x7d, 0xf8, 0xd8, 0xfd, 0x5e, 0xb5, 0x5e, 0x44, 
+       0xf4, 0xa, 0x17, 0xad, 0x78, 0x4c, 0x98, 0x41, 0x5a, 0x7b, 
+       0x53, 0x83, 0xfb, 0x1d, 0xaf, 0xc3, 0x38, 0xfc, 0x16, 0xb2, 
+       0x89, 0x3, 0x16, 0xa2, 0xf, 0x16, 0xd4, 0xa7, 0x1f, 0x2f, 
+       0x3a, 0x55, 0x81, 0x65, 0xa5, 0x1c, 0x19, 0x27, 0x7, 0x5, 
+       0xd4, 0xd4, 0xd2, 0x4, 0xb6, 0x68, 0x69, 0xfa, 0xd4, 0xd4, 
+       0xd4, 0xce, 0x2c, 0x9f, 0x38, 0x5a, 0x19, 0xe2, 0xf4, 0xe7, 
+       0xdf, 0x79, 0xe7, 0x9d, 0x99, 0xd8, 0x9f, 0xfd, 0x1d, 0x54, 
+       0xc4, 0x2a, 0x8c, 0xb4, 0xa6, 0x63, 0xa0, 0xa3, 0xb, 0xbf, 
+       0x4, 0x52, 0x85, 0xa3, 0x6f, 0xdb, 0xb1, 0xc6, 0x3c, 0x6, 
+       0xf7, 0x5c, 0x98, 0x63, 0x6e, 0x5c, 0xbf, 0x7e, 0xbd, 0x3b, 
+       0xb8, 0xf, 0x2e, 0x60, 0x46, 0x9a, 0xfd, 0xfa, 0xd6, 0x4, 
+       0x35, 0x35, 0x35, 0x1b, 0x8, 0xf4, 0xad, 0xbd, 0x68, 0x30, 
+       0x4c, 0x6e, 0x92, 0xa0, 0x89, 0x28, 0x2d, 0x38, 0xdf, 0xb9, 
+       0x44, 0xe7, 0x9f, 0x3, 0xe4, 0x3f, 0xeb, 0x81, 0xd6, 0x13, 
+       0xd6, 0x34, 0x50, 0x8b, 0x7b, 0x65, 0xb0, 0x8d, 0x26, 0x32, 
+       0xeb, 0x2d, 0xd8, 0x4c, 0x67, 0x3d, 0x27, 0xd5, 0xd6, 0xa8, 
+       0x44, 0xbf, 0x46, 0x6e, 0xc2, 0x8a, 0xb9, 0x31, 0xf1, 0xe1, 
+       0x17, 0x12, 0xe1, 0xfc, 0x35, 0xfd, 0x61, 0x9c, 0xd7, 0x96, 
+       0x86, 0x2, 0x32, 0xa6, 0xef, 0xc9, 0x33, 0xf1, 0x7, 0x8b, 
+       0x33, 0x1a, 0x8d, 0x49, 0x6b, 0x6f, 0xaf, 0x91, 0x8a, 0x5, 
+       0x31, 0xf7, 0xce, 0x9a, 0x31, 0xd5, 0xd1, 0x52, 0xda, 0x5d, 
+       0x56, 0xb4, 0x2b, 0xbd, 0xb3, 0xa5, 0x36, 0x9a, 0xbb, 0xcf, 
+       0xa2, 0xb0, 0xe9, 0xc6, 0x1, 0xcd, 0x1c, 0xca, 0x61, 0xcf, 
+       0x9f, 0xde, 0xa1, 0x46, 0x5f, 0x5c, 0x44, 0x40, 0xf5, 0x57, 
+       0x4d, 0x44, 0x66, 0xb9, 0xcf, 0x2a, 0x16, 0xdc, 0x59, 0x2d, 
+       0x63, 0x86, 0x7, 0x12, 0x1a, 0x4d, 0x13, 0xf3, 0xd7, 0xc6, 
+       0xae, 0x3d, 0x35, 0xf8, 0xd5, 0x85, 0xd6, 0xea, 0xee, 0x6e, 
+       0xf, 0x87, 0x20, 0x4b, 0xe0, 0x8, 0x60, 0x1, 0x37, 0x7d, 
+       0x1, 0xb6, 0x98, 0xdf, 0x36, 0x80, 0x32, 0x6, 0xeb, 0xae, 
+       0x5f, 0x83, 0x59, 0xbc, 0x61, 0xf3, 0xe6, 0xcd, 0x3f, 0x46, 
+       0x1c, 0x66, 0xe2, 0x53, 0xb3, 0xf0, 0xd1, 0xf, 0xb3, 0xe5, 
+       0xe4, 0xe4, 0x7c, 0x1a, 0xcb, 0x39, 0x73, 00, 0xee, 0x2e, 
+       0x98, 0xe5, 0x3b, 0x61, 0x86, 0x71, 0x51, 0x84, 0x13, 0x5a, 
+       0x3b, 0x6, 0x2e, 0x16, 0x66, 0xdc, 0x54, 0x80, 0xd3, 0x81, 
+       0xa, 0xaf, 0xc5, 0xb4, 0xc6, 0x58, 0x9c, 0xad, 0xa5, 0x35, 
+       0xb8, 0xb4, 0xf2, 0x48, 0x4f, 0x9b, 0xdd, 0xbc, 0xb6, 0xf6, 
+       0xb1, 0xa9, 0xad, 0x21, 0x28, 0x26, 0xe, 0x26, 0xe0, 0xee, 
+       0x27, 0x2e, 0x13, 0xd5, 0x8d, 0x9, 0xe3, 0x5f, 0xa2, 0xb, 
+       0xcb, 0x1, 0x6a, 0x62, 0xae, 0x78, 0xe3, 0xa0, 0x16, 0x7e, 
+       0x56, 0x48, 0x2f, 0xeb, 0x45, 0x5d, 0x5, 0xb4, 0xb8, 0xd4, 
+       0x2d, 0x4d, 0x72, 0x6a, 0x74, 0xc6, 0x6f, 0x1b, 0x9d, 0xaa, 
+       0xe2, 0xb0, 0xa9, 0x23, 0x11, 0x5a, 0x39, 0x13, 0x5a, 0xfc, 
+       0x47, 0x97, 0x5f, 0xae, 0xbe, 0x55, 0x52, 0x1a, 0xf2, 0x43, 
+       0x5e, 0x7a, 0xe9, 0x25, 0xf5, 0xcb, 0x5f, 0xfe, 0x52, 0xaf, 
+       0xf9, 0xdf, 0xb0, 0x61, 0x83, 0x62, 0x37, 0x80, 0xb, 0xa4, 
+       0x68, 0x5, 0x3c, 0xfd, 0xf4, 0xd3, 0xfa, 0x9d, 0x33, 0xc5, 
+       0x21, 0xa0, 0xbf, 0xbd, 0x7c, 0x99, 0x8e, 0x8b, 0x6d, 0xa2, 
+       0xed, 0xe, 0x9b, 0x7d, 0x63, 0x55, 0x4b, 0xd3, 0xa1, 0x28, 
+       0x57, 0xe1, 0xa2, 0x98, 0xd8, 0xc4, 0xec, 0xcb, 0x56, 0x7c, 
+       0xb4, 0x4, 0x3f, 0x2b, 0x84, 0x53, 0xd1, 0x51, 0xda, 0xa0, 
+       0x33, 0xd6, 0xf8, 0x12, 0xcb, 0xdc, 0xcf, 0xe9, 0x1, 0xb5, 
+       0xc8, 0x45, 0x30, 0xb2, 0x6, 0x81, 0xf0, 0x22, 0xfc, 0x42, 
+       0x39, 0x31, 0xa2, 0xfd, 0x3e, 0xe7, 0xb2, 0x4d, 0x2c, 0xa8, 
+       0xdd, 0xbd, 0xab, 0x7e, 0xdc, 0xc9, 0x8a, 0x8e, 0x8e, 0x86, 
+       0xa6, 0x1e, 0x82, 0x5a, 0x4e, 0x51, 0x21, 0xa0, 0xc5, 0xc, 
+       0x67, 0x6a, 0x3, 0xb4, 0x35, 0xb4, 0xf0, 0x7f, 00, 0xe0, 
+       0x79, 0x58, 0xa3, 0xfc, 0x10, 0x96, 0x1, 0xfe, 0x10, 0x71, 
+       0x38, 0xc7, 0xc4, 0xc5, 0xd8, 0xdc, 0xbf, 0xe9, 0xbc, 0xfb, 
+       0xee, 0xbb, 0xd7, 0x62, 0xf0, 0x62, 0x26, 0xfa, 0xc1, 0x6, 
+       0x5a, 0xd6, 0xed, 0x98, 0x2f, 0xed, 0x82, 0xe9, 0xed, 0x42, 
+       0x8b, 0xee, 0x2, 0x18, 0x7b, 0xd1, 0x67, 0xea, 0x6, 0xf8, 
+       0xb, 0x71, 0xbf, 0x5, 0xd, 0x40, 0x1b, 0xee, 0x17, 0x61, 
+       0xa1, 0x8b, 0x8b, 0x6b, 0x9d, 0x45, 00, 0x64, 0x20, 0x46, 
+       0xfa, 0xd5, 0x6c, 0xf9, 0x6b, 0x6a, 0x6a, 0xd8, 0x62, 0x9b, 
+       0xf8, 0x3d, 0x30, 0x3d, 0xbd, 0xc5, 0xa5, 0x88, 0x97, 0xe8, 
+       0xe2, 0xe3, 00, 0xeb, 0x85, 0xd3, 0x66, 0x6c, 0x7c, 0x69, 
+       0x5d, 0x11, 0x84, 0xa2, 0xc5, 0x59, 0x8f, 0xac, 0x53, 0x6a, 
+       0x71, 0x82, 0xb2, 0xf, 0x20, 0xaf, 0x9d, 0x98, 0xa3, 0xdc, 
+       0xfe, 0xa3, 0x6a, 0x36, 0xe2, 0xf0, 0xb, 0xa7, 0xdf, 0x7c, 
+       0xf, 0xfe, 0x32, 0xf6, 0xab, 0xb1, 0xff, 0x5f, 0x2f, 0x1d, 
+       0x5e, 0xbb, 0x76, 0xad, 0x5e, 0xb8, 0x42, 0x99, 0xf9, 0xd4, 
+       0xa7, 0x3e, 0xa5, 0x30, 0x58, 0xab, 0xa3, 0x9f, 0x29, 0x4e, 
+       0xf, 0xf2, 0xde, 0xe7, 0x37, 0xe1, 0xb1, 0xd, 0xb4, 0xe5, 
+       0xdf, 0xb6, 0x6d, 0xfb, 0x5d, 0x47, 0x5f, 0xdf, 0xd6, 0xe6, 
+       0xe6, 0xaa, 0x62, 0x2c, 0x70, 0x69, 0x3b, 0x7c, 0x70, 0x43, 
+       0x16, 0x85, 0x10, 0x7, 0x45, 0xe0, 0xd7, 0x68, 0x7d, 0x3f, 
+       0xbc, 0x4d, 0x20, 0x5a, 0x1d, 0xa1, 0x6c, 0xbd, 0x66, 0x38, 
+       0x52, 0x8a, 0x50, 0x73, 0x33, 0x79, 0x62, 0xd1, 0xaa, 0x44, 
+       0x19, 0x26, 0x89, 0xcf, 0x6e, 0x82, 0x6f, 0x44, 0xf0, 0xe8, 
+       0xf1, 0xe6, 0x94, 0xb2, 0xca, 0x36, 0x47, 0x59, 0x45, 0x5b, 
+       0x11, 0x22, 0x6c, 0x86, 0x23, 0xa8, 0x65, 00, 0x4d, 0x34, 
+       0xb7, 0x55, 0x6b, 0xe3, 0xb1, 0xb2, 0xc3, 0xf4, 0xfa, 0xc, 
+       0xc0, 0x79, 0xdd, 0x55, 0x57, 0x5d, 0x15, 0xcb, 0xa, 0xc2, 
+       0xc0, 0xd8, 0x3, 0x98, 0x97, 0x34, 0xb7, 0x6e, 0xdd, 0xca, 
+       0xb5, 0x93, 0x3a, 0x3e, 0x80, 0x3c, 0x3, 0x66, 0xda, 0x28, 
+       0xcc, 0x3d, 0x16, 00, 0xb8, 0x88, 0xe6, 0xe6, 0x3e, 0x62, 
+       0xf0, 0xb2, 0xff, 0x60, 0x5, 0xb4, 0xef, 0x71, 0x8c, 0x72, 
+       0x2f, 0x46, 0x7a, 0x27, 0x4f, 0x9c, 0x38, 0x51, 0xd, 0x80, 
+       0xaf, 0xc6, 0x20, 0x5b, 0x14, 0x4, 0x42, 0x57, 0xbc, 0x8, 
+       0x1, 0x5, 0x2, 0x83, 0x66, 0x1c, 0x9, 0xd7, 0x7d, 0x6b, 
+       0x2e, 0x87, 0x64, 0x61, 0xfe, 0x1e, 0x88, 0x3f, 0xe0, 0x12, 
+       0xed, 0x74, 0xab, 0xd7, 0xff, 0xf6, 0xdf, 0xbe, 0x6a, 0x40, 
+       0x55, 0xe8, 0x11, 0x4c, 0x7f, 0xe1, 0x61, 0x98, 0x80, 0x7c, 
+       0xf5, 0xe3, 0xb, 0xfb, 0xae, 0x25, 0xec, 0x7b, 0x8c, 0x23, 
+       0x17, 0x13, 0x30, 0xa7, 0xea, 0xeb, 0xb2, 0xfa, 0xdf, 0xbc, 
+       0xf8, 0x3d, 0xae, 0x74, 0xe3, 0x8, 0x35, 0xfb, 0xe2, 0x5c, 
+       0xfc, 0x2, 0x65, 0x40, 0x7d, 0xa8, 0xeb, 0x96, 0x9a, 0x5b, 
+       0xa8, 0x67, 0xcf, 0xee, 0x6e, 0xa7, 0x69, 0xea, 0x96, 0xfa, 
+       0xfa, 0xdc, 0x5c, 0xb5, 0xa0, 0xb3, 0x2b, 0x30, 0xf0, 0x26, 
+       0x71, 0xc4, 0xff, 0xf0, 0xc3, 0xf, 0xb9, 0x53, 0x4f, 0x71, 
+       0x3f, 00, 0xc7, 0x6a, 0x68, 0x21, 0x50, 0x3e, 0xac, 0x14, 
+       0x2e, 0xce, 0xa8, 0x98, 0x68, 0xf5, 0xea, 0x47, 0x3e, 0x62, 
+       0xc6, 0x46, 0xe1, 0x7, 0xe7, 0x41, 0xd8, 0x2b, 0x3e, 0xfe, 
+       0x4b, 0xf3, 0xe7, 0xaf, 0x7a, 0xf8, 0xdd, 0x77, 0xdf, 0xc5, 
+       0xe5, 0xc6, 0xea, 0xaa, 0xc2, 0xa4, 0xd8, 0xb8, 0xe4, 0x19, 
+       0x65, 0xa5, 0x99, 0xa9, 0x93, 0xa7, 0x2c, 0xc5, 0x8, 0x9d, 
+       0x2e, 0x6b, 0x3f, 0x59, 0x3b, 0xad, 0xb5, 0x7d, 0x3, 0x6a, 
+       0x58, 0x97, 0x4b, 0x75, 0x6e, 0xcd, 0x7e, 0x48, 0xe1, 0xd3, 
+       0x5f, 0x3f, 0xa4, 0xe8, 0x80, 0x36, 0xa0, 0xc5, 0x3, 0x4e, 
+       0xd1, 0x20, 0x6, 0x1c, 0x85, 0xc4, 0x27, 0x3a, 0xbe, 0x44, 
+       0x58, 0x8c, 0xa6, 0xe6, 0x9e, 0xe8, 0x23, 0x85, 0xcd, 0xa9, 
+       0xc7, 0x8b, 0x5a, 0x8b, 0x11, 0x97, 0x53, 0x5e, 0x9c, 0x38, 
+       0x14, 0x40, 0xd3, 0xb7, 0x82, 0x9a, 0xfa, 0x9e, 0x8d, 0x93, 
+       0x81, 0x7d, 0xd8, 0xcb, 0x1, 0xda, 0x6f, 0xa2, 0xf5, 0x8c, 
+       0x61, 0xe5, 0xd0, 0x1, 0x8c, 0x31, 0x98, 0xda, 0x7a, 0x10, 
+       0xa0, 0xc7, 0x59, 0x5e, 0x3b, 0x7f, 0xc3, 0x74, 0x60, 0x76, 
+       0x4d, 0xc4, 0xb3, 0x58, 0xcc, 0x85, 0x36, 0xe3, 0x9a, 0xf1, 
+       0x98, 0x6, 0xf6, 0x2a, 0xc7, 0xf6, 0xab, 0x5, 0x68, 0xf6, 
+       0x66, 0x54, 0x90, 0x17, 0x2, 0x10, 0x87, 0xb3, 0xb3, 0xfe, 
+       0xca, 0x38, 0x48, 0x6b, 0xf5, 0x2d, 0xb7, 0xdc, 0x12, 0xc5, 
+       0xb4, 0xd9, 0x78, 0xb0, 0x65, 0xe6, 0x20, 0xd, 0xcc, 0x7b, 
+       0x1e, 0xcb, 0x44, 0x4d, 0xc0, 0x68, 0x7f, 0x37, 0x34, 0x61, 
+       0x42, 0xb6, 0xe2, 0xbe, 0xef, 0x70, 0x44, 0x61, 0xf, 0x45, 
+       0x14, 0xa2, 0x60, 0xe2, 0x19, 0x69, 0x12, 0x3f, 0xd4, 0xf3, 
+       0xe0, 0xf8, 0x17, 0xc3, 0xb5, 0x4c, 0x9b, 0x1d, 0xdc, 0xbb, 
+       0x57, 0xd5, 0x35, 0x35, 0x61, 0xb0, 0xca, 0xe4, 0x49, 0x3c, 
+       0xba, 0x68, 0xfc, 0x86, 0x7d, 0xfb, 0xf6, 0x35, 0x55, 0x1e, 
+       0x3f, 0x11, 0xdb, 0x1a, 0x13, 0x73, 0x68, 0x5e, 0x5a, 0x6a, 
+       0x26, 0xe, 0x3e, 0x4c, 0xef, 0x46, 0xbd, 0xcb, 0x77, 0x86, 
+       0xfa, 0x6, 0x6a, 0x7c, 0xfc, 0xba, 0x68, 0xa8, 0x47, 0x81, 
+       0x7b, 0xa1, 0xe2, 0xf4, 0x2, 0x1c, 0xb0, 0x10, 0x74, 0x9c, 
+       0x1e, 0xb7, 0xe7, 0x48, 0x63, 0x4f, 0xd7, 0x8e, 0x27, 0xe, 
+       0x1d, 0x7a, 0xf, 0x37, 0x28, 0xef, 0x2d, 0x78, 0x67, 0x73, 
+       0x79, 0xe9, 0x81, 0xf8, 0x68, 0x67, 0x7c, 0x5e, 0x6a, 0xda, 
+       0xf8, 0x8e, 0xe4, 0x94, 0x4c, 0xca, 0x32, 0x6e, 0xf, 0x32, 
+       0xc0, 0x16, 0xc8, 0x31, 0xb2, 0x40, 0x84, 0xe0, 0x66, 0xa1, 
+       0xa9, 0xb9, 0x89, 0x23, 0x11, 0x98, 0xfe, 0x3e, 0xb5, 0x36, 
+       0xcf, 0x57, 0xdb, 0x7b, 0x10, 0xe6, 0x78, 0x65, 0x7b, 0x2d, 
+       0x96, 0x96, 0xb2, 0x9f, 0x5d, 0xe, 0x47, 0xd0, 0xd1, 0x89, 
+       0xf6, 0x66, 0x98, 0x89, 0xd1, 0x69, 0xb, 0x4, 0x3, 0x60, 
+       0x13, 0xd0, 0x62, 0xfe, 0xe, 0x8b, 0xf6, 0x63, 0xb8, 0x6d, 
+       0x50, 0x88, 0xad, 0x27, 0xfa, 0xcb, 0xd1, 0xe8, 0x37, 0x13, 
+       0xe0, 0x6, 00, 0xfe, 0x18, 0x40, 0xc9, 0xa5, 0x8a, 0x34, 
+       0xc5, 0xf0, 0x7b, 0x4d, 0x5e, 0x1c, 0x3b, 0x64, 0x33, 0xc3, 
+       0x1, 0x9c, 0xcc, 0x83, 0xeb, 0x45, 0x65, 0xb6, 0x62, 0xb5, 
+       0xd1, 0x2b, 0xac, 0x54, 0xa4, 0x75, 0xf9, 0xf5, 0xd7, 0x5f, 
+       0xcf, 0xfe, 0x39, 0xfb, 0x37, 0x26, 0x7f, 0x7f, 0xa, 0x83, 
+       0x71, 0x8, 0xe, 0x14, 0x78, 0x29, 0xc7, 0x85, 0xf6, 0x45, 
+       0x18, 0x83, 0x7d, 0x6e, 0x72, 0xb0, 0xde, 0x93, 0x30, 0xcb, 
+       0x6b, 0xd, 0xf, 0x56, 0x7e, 0x7e, 0xb7, 0x38, 0x5a, 0x33, 
+       0x56, 0x2, 0xef, 0xf4, 0xa5, 0xf0, 0x46, 0x7c, 0x6b, 0x9c, 
+       0xb, 0x15, 0xb6, 0x7d, 0xb0, 0x49, 0x67, 0xed, 0x9c, 0x3a, 
+       0x4d, 0x2d, 0x3b, 0x9c, 0x6f, 0x9c, 0x4a, 0x1f, 0xa3, 0xca, 
+       0x3a, 0x3b, 0xcc, 0xdc, 0xca, 0x66, 0xa3, 0x78, 0xfc, 0x4, 
+       0xb5, 0xaf, 0xac, 0xac, 0x9, 0x5a, 0x3d, 0x16, 0x47, 0x1b, 
+       0x3f, 0xb3, 0xa1, 0xad, 0xad, 0xe2, 0xad, 0xbb, 0xef, 0x7a, 
+       0x98, 0x2f, 0x8c, 0x89, 0x8b, 0x55, 0xaf, 0xdc, 0x79, 0x87, 
+       0x7a, 0x74, 0xeb, 0x36, 0xb5, 0x17, 0x9b, 0x58, 0x46, 0x82, 
+       0x6e, 0x98, 0x3c, 0x49, 0xfd, 0x33, 0x96, 0xa0, 0xc2, 0xe4, 
+       0xd7, 0x42, 0x84, 0x35, 0x74, 0xed, 0x1f, 0x7d, 0xf9, 0x55, 
+       0x98, 0x53, 0x7a, 0xc1, 0x69, 0x14, 0x7c, 0xde, 0x2f, 0xeb, 
+       0xeb, 0xeb, 0x3a, 0x58, 0x5b, 0x53, 0x18, 0x7f, 0xf4, 0xf0, 
+       0xa6, 0xac, 0xe5, 0x97, 0xdf, 0x5d, 0x6a, 0xe7, 0x1e, 0x73, 
+       0xc8, 0x2f, 0x48, 0xbf, 0x27, 0xf5, 0x20, 0x53, 0x61, 0x98, 
+       0x18, 0x18, 0x8e, 0xe2, 0xd6, 0xa3, 0xcf, 0x81, 0xef, 0xd2, 
+       0xa9, 0xf, 0x22, 0xdc, 0x98, 0xde, 0x46, 0x5f, 0x86, 0x73, 
+       0xbf, 0xbe, 0xf9, 0xed, 0xc0, 0x3c, 0x37, 0xf0, 0x2d, 0x10, 
+       0xe7, 0x94, 0xf6, 0xc1, 0xc3, 0xa7, 0xd2, 0xab, 0x6b, 0x3a, 
+       0x7b, 0xeb, 0x1b, 0x7a, 0xca, 0x91, 0x38, 0x57, 0xa0, 0xb1, 
+       0xd5, 0x12, 0xad, 0xcd, 0xbe, 0x36, 0x81, 0xcd, 0x7b, 0x94, 
+       0x22, 0x7e, 0x90, 0x1d, 0xad, 0x6f, 0x22, 0xc0, 0xfd, 0x47, 
+       0xf4, 0xa3, 0x62, 0xa1, 0x41, 0x71, 0xab, 0x3f, 0x71, 0xa4, 
+       0x14, 0xda, 0x36, 0xfa, 0xf5, 0xd7, 0x5f, 0x7f, 0xf0, 0xb2, 
+       0xcb, 0x2e, 0xf3, 0x62, 0xd0, 0xab, 0x9, 0xc0, 0x76, 0xa3, 
+       0x8f, 0x8c, 0xf6, 0x20, 0xbd, 0xd, 0x87, 0x1, 0xe0, 0x70, 
+       0xf4, 0x81, 00, 0x87, 0xa9, 0x36, 0xa, 0x26, 0x55, 0x1f, 
+       0x5c, 0xd, 0x46, 0xcc, 0x69, 0x3d, 0x78, 0x70, 0xd4, 0xad, 
+       0x6, 0x38, 0x4c, 0xab, 0x35, 0xd8, 0x7, 0x6e, 0xa7, 0xf9, 
+       0x85, 0xfe, 0xfd, 0x70, 0xba, 0x35, 0xfd, 0xb, 0x39, 0xc2, 
+       0x57, 0x4, 0x26, 0x1d, 0xc9, 0xea, 0x7, 0xdf, 0xb7, 0x5e, 
+       0xb3, 0xc1, 0x13, 0xb2, 0xbe, 0x63, 0x4d, 0x23, 0x18, 0x9c, 
+       0x2, 0x5e, 0xc6, 0x91, 0x67, 0xf4, 0xe5, 0x3e, 0xc1, 0xce, 
+       0xb0, 0x3c, 0x63, 0x3c, 0x79, 0xc6, 0x7b, 0xd6, 0xfb, 0x7c, 
+       0x76, 0xae, 0xc9, 0x38, 0x74, 0x8, 0xeb, 0x8d, 0x77, 0x29, 
+       0x2f, 0xe, 0xba, 0x30, 0xa, 0xb, 0x75, 0x76, 0x76, 0x1c, 
+       0x6c, 0x48, 0x53, 0x72, 0x74, 0x5d, 0xad, 0x31, 0x1a, 0x72, 
+       0xc0, 0x70, 0x46, 0xd1, 0x89, 0xbe, 0x9b, 0x7a, 0x7a, 0x52, 
+       0x3e, 0x3a, 0x29, 0xb7, 0xed, 0x8e, 0x3, 0x7, 0x4e, 0x8e, 
+       0x8e, 0x8d, 0xed, 0x8e, 0x77, 0x3a, 0x93, 0xf9, 0x42, 0x1c, 
+       0xe, 0x98, 0xa0, 0xe3, 0xd9, 0xe4, 0xec, 0x1f, 0xb, 0xaf, 
+       0x86, 0x5b, 0x76, 0xf2, 0x60, 0x6a, 0xca, 0x68, 0x34, 0x1a, 
+       0xa7, 0x47, 0xe2, 0x9d, 0x76, 0x47, 0xe, 0xd2, 0x63, 0x85, 
+       0x50, 0xc6, 0x29, 0xef, 0x24, 0xca, 0xd9, 0xee, 0xc6, 0xc6, 
+       0x8a, 0x71, 0x89, 0xc9, 0x19, 0xa3, 0x8e, 0x1d, 0xdd, 0x96, 
+       0x3e, 0x73, 0xf6, 0x15, 0xf8, 0xc9, 0x22, 0xd6, 0xb5, 0x74, 
+       0x29, 0x81, 0x22, 0xdf, 0xef, 0x93, 0x21, 0x59, 0xbe, 0x4a, 
+       0x37, 0x24, 0xf1, 0x14, 0x18, 0x22, 0xbe, 0x6f, 0x6a, 0x49, 
+       0x7, 0x6, 0xf9, 0x67, 0x79, 0x41, 0x34, 0xb6, 0x5e, 0xd3, 
+       0xcb, 0x1c, 0x41, 0xf2, 0x98, 0xa5, 0x31, 0x30, 0xed, 0xd5, 
+       0x15, 0x5b, 0x52, 0xd6, 0x36, 0xaa, 0xec, 0x64, 0xfb, 0x9, 
+       0x3c, 0xdc, 0x6, 0x27, 0x3, 0x67, 0x4, 0x37, 0xc3, 0x4c, 
+       0x44, 0x80, 0xcd, 0x97, 0xd9, 0xcb, 0x73, 0x60, 00, 0xeb, 
+       0x3f, 0x73, 0x73, 0x73, 0xc7, 0x62, 0x9a, 0x23, 0x6c, 0xaf, 
+       0x8f, 0xb, 0xb, 00, 0x70, 0x27, 0xfa, 0xe0, 0xff, 0x84, 
+       0x85, 0x4, 0xaf, 0xc2, 0x24, 0xef, 0xc2, 0xe2, 0x86, 0x59, 
+       0x30, 0x25, 0x6b, 0x38, 0xa0, 0x16, 0xa, 0xe0, 0xf8, 0x49, 
+       0x99, 0xe9, 0xd0, 0xce, 0x2d, 0x38, 0xe3, 0x8b, 0xeb, 0xd7, 
+       0x7d, 0xeb, 0x8, 0x11, 0x80, 0xc9, 0xf5, 0xa, 0x8e, 0x63, 
+       0xea, 0x84, 0xb6, 0xbf, 0x9, 0x3, 0x6e, 0x61, 0xf3, 0x44, 
+       0xd4, 0xf3, 0x4a, 0x56, 0xa0, 0x4a, 0xd8, 0xea, 0xb, 0x78, 
+       0xe9, 0x5b, 0xef, 0x33, 0x2c, 0xcf, 0x18, 0x26, 0x49, 0x9c, 
+       0xc1, 0x3e, 0x80, 0xc2, 0xe3, 0x13, 0x20, 0x1f, 0xb0, 0xad, 
+       0xd7, 0x2, 0x68, 0xb9, 0x47, 0x5f, 0xa6, 0x87, 0x98, 0xb6, 
+       00, 0x9c, 0xe9, 0x5b, 0xe3, 0xe, 0x96, 0xdf, 0xd9, 0x3c, 
+       0x33, 0xb6, 0x6e, 0xd1, 0x62, 0xae, 0x38, 0x58, 0x5, 0xb3, 
+       0xda, 0x86, 0xbe, 0x70, 0x80, 0x68, 0x66, 0xe3, 0x42, 0xb, 
+       0xa5, 0x7f, 0xdc, 0x25, 0x9b, 0x83, 0xaf, 0xb0, 0xfa, 0x40, 
+       0xc9, 0x8f, 0xae, 0x5e, 0xbd, 0x3c, 0x27, 0x39, 0x29, 0xe3, 
+       0xa9, 0x82, 0xa3, 0x3f, 0xe9, 0x71, 0xb9, 0x9a, 0x1e, 0x9c, 
+       0x3b, 0xe7, 0x27, 0x3c, 0xf9, 0xf4, 0x81, 0xb9, 0x73, 0xd4, 
+       0x17, 0x17, 0x2f, 0x52, 0xf, 0xbd, 0xbd, 0x5e, 0x15, 0xf8, 
+       0xa7, 0xcb, 0x2, 0x69, 0xe, 0x31, 0x70, 0xc5, 0xc4, 0x9, 
+       0xa, 0xe9, 0xab, 0x76, 0xff, 0xaa, 0x36, 0x9c, 0xcb, 0x56, 
+       0xf6, 0x5a, 0x71, 0xc9, 0x8f, 0xa, 0x1a, 0x1a, 0xca, 0x91, 
+       0x4, 0x8b, 0x24, 0xc0, 0x21, 0x42, 0xa9, 0xd8, 0x78, 0xef, 
+       0xc3, 0xca, 0x93, 0xf9, 0x29, 0x9, 0x9, 0x49, 0xd3, 0x33, 
+       0x33, 0x27, 0xb7, 0xa7, 0x8d, 0x19, 0xdf, 0xc3, 0xdf, 0x11, 
+       0x3, 0xe9, 0xea, 0xc0, 0x3f, 0x6, 0xf4, 0xf1, 0xc6, 0x50, 
+       0xdc, 0x72, 0xf8, 0x29, 0x3f, 0xd1, 0x57, 0xb9, 0x21, 0x7c, 
+       0xbe, 0x8c, 0xe7, 0x1, 0xa, 0x65, 0x96, 0x4b, 0x4, 0xf1, 
+       0x19, 0x99, 0x85, 0xd3, 0xa9, 0xea, 0x79, 0x6e, 0xa, 0x12, 
+       0x12, 0x42, 0xfd, 0x52, 0xc0, 0x74, 0x8a, 0xfc, 0xc7, 0x63, 
+       0x8f, 0xf7, 0x1f, 0x3e, 0x95, 0x79, 0xb2, 0xb2, 0xb3, 0xba, 
+       0xaf, 0xcf, 0xdc, 0x8f, 0x57, 0x50, 0xb, 0x1, 0x8d, 0x4d, 
+       0x70, 0x13, 0xd4, 0x62, 0x8e, 0x23, 0xa8, 0x81, 0x6d, 0x87, 
+       0xb6, 0x7e, 0x18, 0xe0, 0x5c, 0x7c, 0xf9, 0xe5, 0x97, 0x47, 
+       0xf3, 0xe6, 0x60, 0xe4, 0x7, 0x78, 0x14, 0xcc, 0xea, 0xdb, 
+       0x31, 00, 0xb6, 0x3, 0xd7, 0xae, 0x6d, 0xdb, 0xb6, 0xad, 
+       0xc4, 0x72, 0xd0, 0xdd, 0xd0, 0xbe, 0x2d, 0x2, 0x70, 0x68, 
+       0x75, 0x7, 0xee, 0x2f, 0xc2, 0xe6, 0x83, 0x68, 0x68, 0xf9, 
+       0xa3, 0x98, 0xd6, 0x58, 0x87, 0x74, 0xf9, 0xbd, 0xc2, 0x6c, 
+       0x5, 0xcd, 0xbd, 0x1, 0x3, 0x32, 0xb1, 0x60, 0xe2, 0x1a, 
+       0x94, 0xc1, 0x89, 0x77, 0x7, 0xcb, 0xfa, 0x9c, 0x3d, 0x23, 
+       0x7, 0xc5, 0x31, 0x13, 0x86, 0x5, 0x98, 0x83, 0xf9, 0xf2, 
+       0x4c, 0xe2, 0x73, 0xd0, 0x87, 0xdd, 0xc, 0xce, 0xe9, 0xf3, 
+       0x19, 0x35, 0x2e, 0x9f, 0xf9, 0x92, 0xf4, 0x5, 0x78, 0x1, 
+       0xc2, 0x27, 0x6b, 0xd2, 0xa0, 0x24, 0x60, 0xd9, 0xf5, 0xa1, 
+       0x75, 0x24, 0x3c, 0xb0, 0x82, 0x95, 0x61, 0xb9, 0xe, 0xf6, 
+       0x5, 0xec, 0xcc, 0x7, 0x29, 0xea, 0xc4, 0x25, 0x8e, 0x5c, 
+       0xeb, 0x9b, 0x67, 0xfb, 0x2f, 0x18, 0xcc, 0x48, 0x8f, 0xb, 
+       0x52, 0xa2, 0x50, 0xb6, 0xc7, 0xf, 0x1e, 0x52, 0x2b, 0xb2, 
+       0xb3, 0xd4, 0x1f, 0xf, 0xe5, 0xab, 0xdb, 0xa6, 0xe4, 0xa9, 
+       0x3a, 0xc, 0x96, 0xcd, 0x48, 0x4b, 0x55, 0x33, 0x71, 0xea, 
+       0xd, 0x8f, 0x3d, 0x62, 0x9c, 0x55, 0xd9, 0x59, 0x37, 0xb0, 
+       0x8, 0x73, 0x52, 0x53, 0xf7, 0xbc, 0x51, 0x72, 0xe2, 0x90, 
+       0x1c, 0x69, 0x9c, 0xe2, 0x3, 0x3f, 0x9e, 0x67, 0x6b, 0xf7, 
+       0xd2, 0xb1, 0x63, 0x8a, 0x73, 0xe1, 0x43, 0xa1, 0x89, 0x58, 
+       0x22, 0x7b, 0x75, 0xce, 0x44, 0x95, 0x16, 0x1b, 0x87, 0xe5, 
+       0xdf, 0x86, 0x4a, 0xc6, 0xc1, 0x90, 0xa4, 0x68, 0x87, 0x63, 
+       0xc2, 0x7f, 0xed, 0xdd, 0x5b, 0x8c, 0xae, 0x23, 0x13, 0xa2, 
+       0xe2, 0xa0, 0xdc, 0x93, 0x39, 0xe2, 0x13, 0xe4, 0x75, 0xae, 
+       0xbe, 0x9e, 0xfd, 0x55, 0x27, 0xb, 0x13, 0x8f, 0xc4, 0xbd, 
+       0x9f, 0x79, 0xf9, 0xda, 0x4f, 0xc2, 0x3c, 0x8f, 0xa, 0x54, 
+       0x12, 0x23, 0x33, 0x12, 0xec, 0xa5, 0xfe, 0xbf, 0x47, 0x84, 
+       0x7b, 0x7e, 0x12, 0x7c, 0x8a, 0x2f, 0xf7, 0x3, 0x3e, 0x9b, 
+       0x8a, 0xc0, 0x5, 0x3, 0xa8, 0x10, 0x16, 0x86, 0x52, 0x4e, 
+       0x20, 0xb0, 0xd9, 0xe3, 0xc8, 0x4, 0x6d, 0x8d, 0xaf, 0x4d, 
+       0x9d, 0x9c, 0x34, 0x75, 0x54, 0x92, 0x23, 0x15, 0x61, 0xe, 
+       0x87, 0xf3, 0xb7, 0x3c, 0x59, 0x6, 0x86, 0x75, 0xad, 0xe2, 
+       0x9f, 0xd9, 0xd2, 0xe6, 0x6a, 0x2d, 0x2a, 0x69, 0xe7, 0x4e, 
+       0xaf, 0x37, 0xe1, 0xb8, 0x40, 0x45, 0x16, 0xa9, 0x88, 0x6, 
+       0x97, 0x7e, 0x36, 0xdf, 0xe1, 0xaf, 0x33, 0x5e, 0x89, 0x15, 
+       0x40, 0xff, 0x81, 0x5, 0x29, 0x18, 0xb, 0xd3, 0x83, 0x99, 
+       0xb8, 0x7d, 0x66, 0xe2, 0x3a, 0x6f, 0xac, 0x3e, 0x73, 0x41, 
+       0xfb, 0x1e, 0xc2, 0xfb, 0x5d, 0xd0, 0xbe, 0x89, 0x58, 0x96, 
+       0x78, 0xa, 0x7d, 0xf5, 0x16, 00, 0x1b, 0x4b, 0x89, 0x5b, 
+       0x53, 0x11, 0xa7, 0x3, 0x53, 0x24, 0x55, 0xf8, 0x59, 0xd7, 
+       0xc7, 0xa0, 0xed, 0x2b, 0x91, 0x2a, 0xd7, 0x14, 0x72, 0xf1, 
+       0x30, 0x7d, 0x76, 0xea, 0x93, 0xe0, 0xe2, 0xee, 0xbf, 0xff, 
+       0xfe, 0x3b, 0x60, 0x31, 0x9c, 0x57, 0x80, 0x93, 0xef, 0xc2, 
+       0x7b, 0x9, 0xb, 0x58, 0xe9, 0x4b, 0x98, 00, 0xd, 0xe, 
+       0xe3, 0xfb, 0x38, 00, 0xc8, 0xf1, 0x6, 0xbc, 0x8a, 0xd1, 
+       0x23, 0xfe, 0x58, 0x13, 0x88, 0x60, 0xc2, 0x8c, 0x1, 0x4f, 
+       0x20, 0x35, 0xe9, 0x3, 0xa8, 0x7a, 0x70, 0x10, 0xd6, 0x89, 
+       0xc1, 0xc1, 0x43, 0x3a, 0xe, 0x20, 0xfa, 0x9d, 0x3e, 0xdf, 
+       0xc, 0x8b, 0x3f, 0xf4, 0xf6, 0x4a, 0x58, 0x36, 0x6, 0xd3, 
+       0x65, 0x5e, 0x4c, 0x7, 0x3e, 0x35, 0x7, 0x17, 0x8b, 0xe8, 
+       0xb3, 0xde, 0x98, 0x1e, 0x41, 0x3b, 0x98, 0x13, 0xa0, 0x5b, 
+       0xc1, 0xcd, 0xb4, 0xc4, 0xb1, 0x8c, 0x11, 0x13, 0xca, 0x64, 
+       0x7f, 0xf1, 0x5, 0x40, 0x4, 0x62, 0xe9, 0x5f, 0x1f, 0x4e, 
+       0x89, 0x3d, 0x5, 00, 0x3e, 0xb4, 0xfe, 0x1d, 0xc5, 0x39, 
+       0xe5, 0x3, 0xfe, 0x69, 0x27, 0x6b, 0xda, 0x30, 0xc1, 0xb1, 
+       0x41, 0x24, 0x59, 0xcd, 0x1f, 0x33, 0x56, 0x51, 0x3b, 0xf3, 
+       0x1d, 0x32, 0x9, 0xd3, 0x29, 0xf5, 00, 0x62, 0x62, 0xb7, 
+       0xc7, 0xbd, 0xd, 0x1a, 0x76, 0x3f, 0x6, 0xd7, 0x6e, 0xc0, 
+       0x81, 0x48, 0xb3, 0xe4, 0xdd, 0x17, 0xa, 0x8f, 0xa9, 0x7c, 
+       0x1c, 0xb, 0xc5, 0x53, 0x51, 0x3f, 0xc4, 0x20, 0x25, 0xcb, 
+       0xce, 0xfa, 0x21, 0x49, 0xf8, 0x46, 0xec, 0x7, 0x6f, 0x41, 
+       0x3, 0xfa, 0xd1, 0xe9, 0xd3, 0xd4, 0xa, 0xec, 0x49, 0x17, 
+       0xea, 0x84, 0x59, 0xde, 0x8e, 0xbe, 0xfc, 0xde, 0xa3, 0x47, 
+       0x5d, 0xcf, 0x1e, 0x3e, 0xf2, 0x8, 0xfa, 0xf9, 0x9b, 0xf1, 
+       0x8c, 00, 0x27, 0xa8, 0x3, 0x63, 0x4b, 0x8, 0x13, 0x53, 
+       0xc4, 0x18, 0xf1, 0x75, 0xdb, 0xa4, 0x29, 0x8b, 0xe6, 0x27, 
+       0x25, 0x8d, 0x41, 0x77, 0x1, 0x38, 0xf6, 0x61, 0xa, 0xb7, 
+       0x41, 0xb8, 0x2, 0xf7, 0xb4, 0xd6, 0x87, 0x2a, 0x75, 0x1d, 
+       0xd8, 0xb7, 0x9e, 0xa, 0x93, 0x7d, 0x78, 0xa6, 0x49, 0x27, 
+       0xd8, 0xd2, 0x4a, 0x13, 0xe5, 0xa4, 0x1f, 0xa0, 0x33, 0x81, 
+       0x9b, 0x85, 0x60, 0x1, 0xe8, 0x3e, 0xa, 0x37, 0x5, 0xf5, 
+       0x4b, 0xd0, 0xd3, 0xb1, 0x11, 0xf0, 0x35, 0x2e, 0x8, 0xf8, 
+       0x89, 0xda, 0xbc, 0xb, 0xe1, 0xf5, 0x70, 0xd, 0x70, 0xd4, 
+       0xd6, 0x2, 0x70, 0x5d, 00, 0x5c, 0xcb, 0x68, 0x8d, 0x1d, 
+       0x80, 0x4c, 0x81, 0x39, 0xfe, 0xe, 0x6, 0x84, 0x92, 0xb9, 
+       0x71, 0x3f, 0x52, 0xe2, 0x6e, 0x9d, 0x37, 0xdf, 0x7c, 0xd3, 
+       0xd, 0xad, 0xbf, 0x1e, 00, 0xb7, 0x43, 0xf3, 0xd8, 0x21, 
+       0x84, 0x76, 00, 0x2, 0x32, 0xdb, 0xd7, 0xd, 0x4d, 0xb6, 
+       0x17, 0x3f, 0xeb, 0xfa, 0xc, 0x34, 0x74, 0x7, 0xd2, 0x16, 
+       0x66, 0xb2, 0xa1, 0x12, 0x70, 0x13, 0xe0, 0x74, 0x9, 00, 
+       0xf8, 0xed, 0xe7, 0x3, 0xe0, 0x14, 0x94, 0x50, 0x4e, 0x40, 
+       0x4c, 0x70, 0xd1, 0x59, 0xaf, 0x1, 0x3c, 0x7d, 0xf6, 0x18, 
+       0xee, 0x69, 0x20, 0x13, 0x3c, 0x4, 0x30, 0xbe, 0xd9, 0xc0, 
+       0xb7, 0x1b, 0xb4, 0x66, 0xe8, 0x8, 0xde, 0xb3, 0x25, 0x2, 
+       0x9f, 0xda, 0x9f, 0x9b, 0x34, 0xd0, 0x80, 0x98, 0x3c, 0xe4, 
+       0x10, 0x96, 0x8f, 0x96, 0x13, 0xe6, 0xcf, 0x86, 0x82, 0xd3, 
+       0x84, 0xd4, 0xf2, 0x4, 0x33, 0x1d, 0xcb, 0x23, 0xbe, 0x80, 
+       0x5f, 0x80, 0x2e, 0xbe, 0x15, 0xf0, 0x91, 0x94, 0xd1, 00, 
+       0x88, 0x6c, 0x7f, 0x7a, 0xb2, 0xdf, 0x2b, 0xf7, 0xe2, 0xec, 
+       0x33, 0x1e, 0x6a, 0xc8, 0x65, 0xa4, 0x67, 0x22, 0xac, 0x4, 
+       0x43, 0x5f, 0x38, 0x45, 0xaf, 0xf3, 0xbe, 0x2e, 0x37, 0x37, 
+       0x10, 0xbd, 0xb9, 0xa7, 0xf7, 0x97, 0x37, 0xfc, 0xf5, 0xaf, 
+       0xbf, 0xd8, 0x7c, 0xef, 0xbd, 0x2f, 0xe1, 0xc7, 0x4, 0x56, 
+       0xc8, 0x3, 0xd1, 0xf4, 0xb8, 0x36, 0xa1, 0x7d, 0x8d, 0xfb, 
+       0xe7, 0xcc, 0xd1, 0x96, 0x41, 0x6, 0xf8, 0x8b, 0xa5, 0xa4, 
+       0xfa, 0x5c, 0xf3, 0x87, 0x17, 0x2e, 0xd4, 0xd1, 0xe5, 0x28, 
+       0x63, 0x79, 0xb7, 0x5, 0xcb, 0x54, 0x6b, 0xa6, 0xcf, 0xe0, 
+       0xc1, 0x90, 0xa, 0xab, 0x22, 0xdb, 0xf7, 0xef, 0xdf, 0x7f, 
+       0x2f, 0x78, 0xc7, 0xc5, 0xea, 0xc4, 0x1, 0x2d, 0x56, 0xb6, 
+       0x12, 0x82, 0x19, 0xca, 0x23, 0xdd, 0x58, 0xb8, 0x1b, 0xc0, 
+       0x1f, 0xca, 0x24, 0x9f, 0xe9, 0x86, 0x1a, 0x3e, 0x49, 0xcc, 
+       0x79, 0xdd, 0x38, 0x40, 0x2e, 0x8a, 0x71, 0xef, 0x15, 0x38, 
+       0x62, 0x8c, 0xb8, 0x62, 0xba, 0x1, 0xa5, 0x39, 0x14, 0x70, 
+       0x33, 0x3, 0x4a, 0x9, 0x33, 0x26, 0xb8, 0x69, 0x6b, 0x10, 
+       0xdc, 0x54, 0xab, 0x74, 0xc, 0xf3, 0x9e, 0x3c, 0xb7, 0x16, 
+       0x48, 0xb4, 0x32, 0x33, 0x15, 0x27, 0x85, 0x60, 0x1, 0xe9, 
+       0xf8, 0x81, 0x4c, 0xdf, 0x89, 0xc5, 0x29, 0xbf, 0xc0, 0x3c, 
+       0xf5, 0xd5, 0xfc, 0xe9, 0x55, 0x5c, 0xf, 0x8b, 0xb8, 0x78, 
+       0xe1, 0x8d, 0x37, 0xde, 0x70, 0x43, 0x20, 0xff, 0x3, 0xd3, 
+       0x1f, 0xfb, 0x20, 0xf0, 0x89, 0x1c, 0x3c, 0x2b, 0x2b, 0x2b, 
+       0x2b, 0xc1, 0x14, 0x8, 0x19, 0xcb, 0x32, 0x49, 0x9e, 0x2c, 
+       0x33, 0xbf, 0x81, 00, 0xa7, 0xa3, 0xe6, 0xa6, 0x26, 0xd7, 
+       0x20, 0xbf, 0xef, 0xbe, 0xfb, 0x3e, 0x82, 0x45, 0x11, 0xab, 
+       0x61, 0xa2, 0x43, 0xe9, 0x31, 0xea, 0xc8, 0x51, 0x30, 0xa0, 
+       0x5, 0xc4, 0xbc, 0x2f, 0x40, 0xa6, 0x2f, 0x8e, 0xb, 0x25, 
+       0x78, 0x16, 0x38, 0xb5, 0x5, 0x1, 0x82, 0xef, 0x32, 0x39, 
+       0xe8, 0xc7, 0xcd, 0x2b, 0x9c, 0xd7, 0x3d, 0xdf, 0xe4, 0x6f, 
+       0x60, 0xf4, 0x5a, 00, 0xc, 0x62, 0x1a, 0x6c, 0x4, 0x50, 
+       0x76, 0x3d, 0xaf, 0xcc, 0xe3, 0xa4, 0x58, 0x46, 0xab, 0xb, 
+       0x5, 0x78, 0xd1, 0xe0, 0xf4, 0xf9, 0xfc, 0x4c, 0x64, 0xdb, 
+       0xba, 0x55, 0xe1, 0x6c, 0x67, 0xfc, 0xdc, 0x23, 0x86, 0x4a, 
+       0xc0, 0xa7, 0xd, 0x65, 0xe5, 0xea, 00, 0x56, 0x99, 0xbd, 
+       0xe8, 0x1f, 0x44, 0x3b, 0xd3, 0xfb, 0xd6, 0xe7, 0x53, 0xc0, 
+       0xb7, 0xeb, 0x72, 0x73, 0xd4, 0xed, 0xd8, 0xaf, 0x9d, 0x80, 
+       0xba, 0x85, 0x40, 0xd4, 0x22, 0xc9, 0xfa, 0xfa, 0xee, 0xce, 
+       0xff, 0xc6, 0x1a, 0xf0, 0xa9, 0xa5, 0xad, 0xed, 0x7b, 0xe6, 
+       0xa6, 0xa5, 0x3e, 0x6f, 0x7d, 0x47, 0xc2, 0xc1, 0x20, 0x96, 
+       0xfb, 0xda, 0xc7, 0xb7, 0x94, 0x2c, 0x5e, 0xa2, 0x46, 0xd5, 
+       0xd7, 0xa9, 0x56, 0x58, 0x9, 0xbd, 0xfe, 0xba, 0xc1, 0x12, 
+       0xd5, 0xbe, 0xc2, 0xc2, 0xc2, 0xad, 0x38, 0xec, 0xe1, 0xc7, 
+       0x88, 0x47, 0x30, 0x12, 0x84, 0x22, 0xff, 0x56, 0x8c, 0x51, 
+       0xd0, 0xac, 0x8e, 0x4a, 0x93, 0x44, 0x99, 0x25, 0xb8, 0xd9, 
+       0x28, 0x58, 0xb1, 0x24, 0x5a, 0x9b, 0x3e, 0xd3, 0xe4, 0x73, 
+       0x3a, 0xcc, 0xc0, 0xf1, 0x17, 0x5, 0x4e, 0xd3, 0x60, 0x4d, 
+       0xbd, 0x24, 0xce, 0xc, 0x4, 0xb4, 0x2, 0x50, 0x6b, 0xcd, 
+       0x58, 0xc1, 0x2d, 0xcf, 0xa5, 0x40, 0xd6, 0xcc, 0xa5, 0x15, 
+       0x62, 0xcb, 0x64, 0x87, 0x39, 0x7e, 0x39, 0xb4, 0xec, 0x55, 
+       0x18, 0xad, 0x1e, 0x36, 0xb0, 0xf9, 0x19, 0x3c, 0xf3, 0x1b, 
+       0x1b, 0x43, 0x1c, 0xd0, 0xe0, 0x5f, 0x83, 0xa6, 0xf9, 0x9, 
+       0xb4, 0xf4, 0xeb, 0xb8, 0xcd, 0xd3, 0xee, 0xf8, 0xf1, 0xfc, 
+       0x3e, 0xe6, 0xcb, 0x3c, 0x85, 0x51, 0xc1, 0x65, 0xc7, 0x23, 
+       0xfd, 0xdc, 0xf8, 0xd3, 0x9f, 0xfe, 0xf4, 0x2a, 00, 0xce, 
+       0xeb, 0x11, 0x3, 0x38, 0xc1, 0x6b, 0x75, 0xc1, 0x5a, 0x59, 
+       0xae, 0x9, 0x16, 0x36, 0x54, 0x9c, 0x6f, 0x87, 0xe0, 0xeb, 
+       0x9f, 00, 0xe2, 0xa1, 00, 0x5c, 0xa4, 0x41, 0x40, 0xfb, 
+       0xcb, 0x48, 0xff, 0x82, 0x10, 0x1b, 0x14, 0x3a, 0x2c, 0xfd, 
+       0xd4, 0xfc, 0xe3, 0x41, 0xa, 0xdc, 0xd7, 0xce, 0x9d, 0x5a, 
+       00, 0x3b, 0x1b, 0x25, 0x7d, 0xaa, 0x29, 0xa7, 0x30, 0x69, 
+       0x41, 0x10, 0xe8, 0xe2, 0x13, 0xc8, 0x2, 0x76, 0x1, 0x36, 
+       0x79, 0x22, 0xe1, 0x70, 0x1f, 0x64, 0x60, 0x4d, 0xb8, 0x6a, 
+       0xe5, 0x4, 0x87, 0x8f, 0xb8, 0x5d, 0x93, 0x6e, 0x38, 0x74, 
+       0x2, 0xe5, 0xa5, 0xbb, 0x1, 0xa7, 0xe5, 0x10, 0xdc, 0x10, 
+       0x88, 0xc, 0xe0, 0x32, 0xa3, 0xb5, 0xb7, 0xa7, 0xf6, 0xf6, 
+       0x17, 0x5f, 0x5e, 0x97, 0x9d, 0x94, 0x14, 0xff, 0xc4, 0xcd, 
+       0x37, 0xb5, 0x76, 0x29, 0x23, 0xd1, 0x3b, 0x69, 0x92, 0x6d, 
+       0xdc, 0x49, 0x5f, 0x3e, 0x6e, 0xc4, 0xe5, 0xc9, 0xa9, 0x24, 
+       0x6b, 0xb8, 0x16, 0x75, 0x93, 0x8a, 0x95, 0x6e, 0x7d, 0xe8, 
+       0x6f, 0x13, 0xd0, 0xf5, 0x7e, 0x50, 0x4b, 0xd9, 0x70, 0xde, 
+       0x9a, 0x13, 0x6b, 0xf, 0x56, 0x60, 0x8f, 0xc3, 0x32, 0xc, 
+       0xea, 0x6e, 0xc1, 0x7d, 0x62, 0x88, 0xf8, 0x20, 0x51, 0x16, 
+       0x9, 0x58, 0x92, 0xe0, 0x4c, 0xc2, 0x56, 0x3c, 0xc9, 0x3b, 
+       0x82, 0x2b, 0xfa, 0x82, 0x45, 0xa6, 0x41, 0xe2, 0xfb, 0x74, 
+       0x3, 0xc8, 0xfe, 0xc8, 0x23, 0x8f, 0xf4, 0xbb, 0xf9, 0x83, 
+       0x1f, 0xfc, 0x80, 0x40, 0xa0, 0x63, 0x26, 0xe2, 0x82, 0x4d, 
+       0x70, 0x3e, 0x97, 0x44, 0x99, 0x89, 0x14, 0x42, 0x40, 0x2d, 
+       0x3e, 0x3f, 0x80, 0x61, 0x16, 0x8a, 0xf1, 0xf8, 0x5e, 0x14, 
+       0xcd, 0x71, 0x1c, 0x49, 0xf4, 0x24, 0x56, 0xa0, 0x25, 0x10, 
+       0x9c, 0x67, 0x4b, 0xec, 0xab, 0x63, 0xfa, 0xcc, 0x6, 0x61, 
+       0x5b, 0x9, 0x2d, 0x52, 0x83, 0xdd, 0x3b, 0xe5, 0x48, 0x53, 
+       0xca, 0x27, 0xbe, 0xe4, 0x2f, 0xd7, 0xcc, 0x96, 0x61, 0x12, 
+       0xcb, 0x45, 0x67, 0xc3, 0x34, 0x59, 0x39, 0x46, 0xe1, 0xb9, 
+       0x32, 0x2e, 0x1b, 0x9a, 0x12, 0x32, 0x2a, 0xd, 0x29, 0xa3, 
+       0xd, 0x9d, 0xac, 0x80, 0x66, 0x98, 0x20, 0x26, 0x80, 0x45, 
+       0x33, 0x73, 0xf0, 0x8b, 0x8e, 0x83, 0x5f, 0x38, 0xa6, 0x49, 
+       0xaf, 0x91, 0xe6, 0x73, 0x58, 0x32, 0x6, 0xa6, 0xfa, 0xf4, 
+       0xe6, 0x8, 0xec, 0x82, 0x1a, 0xf1, 0xe3, 0x8f, 0x87, 0xfe, 
+       0x5, 0x83, 0xc7, 0x24, 0xcf, 0x59, 0x3e, 0x34, 0x40, 0x46, 
+       0x4e, 0x4e, 0xe, 0xd7, 0x19, 0xe8, 0xd3, 0x41, 0xd1, 0x55, 
+       0x32, 0xd9, 0x7f, 0xa7, 0xe5, 0x23, 0xd, 0x17, 0xbf, 0x9f, 
+       0x24, 0x3c, 0xb1, 0xa6, 0xcc, 0x7b, 0xa2, 0xd1, 0xad, 0xf7, 
+       0x8d, 0xe3, 0xc7, 0x94, 0xd1, 0x74, 0xa, 0xcd, 0x74, 0x87, 
+       0x6a, 0xc3, 0x28, 0xf4, 0xff, 0x79, 0xe7, 0x5d, 0xb5, 0x13, 
+       0xe6, 0x2e, 0xe9, 0x9b, 0xdf, 0xfc, 0x26, 0xe, 0x23, 0xfc, 
+       0x35, 0xad, 0x8, 0x5, 0xed, 0x68, 0x7d, 0x4d, 0x71, 0x93, 
+       0xcf, 0xcf, 0x7f, 0xfe, 0x73, 0xf5, 0xe8, 0xa3, 0x8f, 0xaa, 
+       0x8f, 0x7c, 0xe4, 0x23, 0xfa, 0x3c, 0x75, 0x1e, 0x95, 0x24, 
+       0xc4, 0xbd, 0xdc, 0x49, 0xce, 0x68, 0xfd, 0xb, 0x21, 0xc8, 
+       0xb7, 0x17, 0x95, 0x5e, 0x17, 0xed, 0x8c, 0xae, 0xe9, 0xcd, 
+       0xcc, 0xfc, 0xea, 0x1, 0x65, 0xcc, 0x1d, 0x77, 0xcd, 0x35, 
+       0x4e, 0x2f, 0x6, 0xe2, 0xe2, 0xd1, 0xd0, 0x76, 0xa1, 0xf, 
+       0x5d, 0x85, 0xb3, 0xd3, 0x52, 0xd0, 0xc8, 0xb8, 0x71, 0xaa, 
+       0x69, 0xd9, 0x65, 0x4b, 0x55, 0x34, 0xba, 0x2c, 0x58, 0xdb, 
+       0xac, 0xea, 0xf3, 0xa6, 0xa8, 0x53, 0x58, 0xf0, 0xd3, 0x8a, 
+       0x35, 0xeb, 0xa1, 0x88, 0x72, 0x83, 0xd5, 0x8e, 0xe, 0xec, 
+       0x20, 0x5b, 0x82, 0x86, 0x70, 0x3d, 0xba, 0x89, 0xb4, 0x60, 
+       0x45, 0xf6, 0x88, 0x17, 0x12, 0x7d, 0x91, 0x41, 0xfa, 0xbc, 
+       0xa6, 0x9c, 0xd2, 0x9, 0x90, 0x89, 0x9f, 0x60, 0x3c, 0xf1, 
+       0x9a, 0x71, 0xc5, 0xd7, 0xe9, 0x2, 0xcb, 0x92, 0x16, 0x1e, 
+       0xf9, 0x34, 0x9b, 0xe, 0x4, 0xfd, 0xd3, 0x91, 0x71, 0x8f, 
+       0x99, 0x48, 0x22, 0x94, 0x72, 0x6b, 0x6b, 0x43, 0xad, 0x28, 
+       0xa0, 0x47, 0x50, 0x13, 0xe3, 0xb2, 0x50, 0x52, 0x20, 0x29, 
+       0xa0, 0xa4, 0xc7, 0xf8, 0x51, 0x58, 0x2c, 0xf2, 0x6f, 0xb9, 
+       0xb9, 0xb9, 0xb1, 0xc3, 0xe9, 0x67, 0xeb, 0x5c, 0x2c, 0xff, 
+       0x44, 0x60, 0xd0, 0x60, 0x28, 0x1c, 0x6d, 0xec, 0xc0, 0x61, 
+       0x76, 0xff, 0x86, 0xad, 0x99, 0x2e, 0x2c, 0x5c, 0x78, 0x17, 
+       0xd1, 0x4, 0xb4, 0x64, 0x2c, 0xc3, 0xf2, 0x3d, 0x81, 0x14, 
+       0x60, 0xca, 0x1b, 0xd7, 0x5c, 0x73, 0xcd, 0x62, 0xbc, 0x3f, 
+       0x1f, 0x96, 0x44, 0x16, 0xd2, 0x4b, 0x80, 0x70, 0x76, 0x62, 
+       0x8a, 0xad, 0x8, 0xe1, 0x3c, 00, 0x2d, 0x22, 0x13, 0x5d, 
+       0xca, 0x23, 0xbe, 0x8, 0x38, 0x7d, 0x1, 0x38, 0x41, 0xcc, 
+       0x55, 0x71, 0xd0, 0x78, 0x5a, 0x4b, 0xf3, 0x30, 0x2, 0xcc, 
+       0xb5, 0xdb, 0x38, 0xbf, 0x4f, 0x41, 0xff, 0x7b, 0x23, 0x2, 
+       0x1d, 0x63, 0x27, 0xfa, 0x27, 0x86, 0xd0, 0xdf, 0x34, 0x30, 
+       0x80, 0xc9, 0x5f, 0x1e, 0xe1, 0xf7, 0x9a, 0x10, 0x70, 0xfd, 
+       0xab, 0x23, 0xa2, 0xc5, 0x5, 0xf4, 0xa2, 0xc9, 0xe9, 0x93, 
+       0x57, 0xf4, 0x5, 0xe4, 0x46, 0x4b, 0xb3, 0xb2, 0x6d, 0xdc, 
+       0x18, 0x60, 0x3, 0x7f, 0x8b, 0x8b, 0xe7, 0x81, 0x93, 0xd0, 
+       0x65, 0x52, 0xdf, 0xfe, 0xf6, 0xb7, 0xb5, 0xc5, 0xc6, 0x3a, 
+       0xb7, 0x12, 0x2d, 0x9d, 0x4d, 0x9b, 0x36, 0x29, 0xb9, 0x4f, 
+       0xa0, 0xa3, 0x6e, 0x15, 0x6, 0x5d, 0xd5, 0xd7, 0xbf, 0xfe, 
+       0x75, 0x1d, 0xb5, 0x81, 0x7, 0x3e, 0x70, 0x99, 0x25, 0x8, 
+       0xf9, 0x46, 0x8f, 0x8e, 0x89, 0xfd, 0xc6, 0xf2, 0xdc, 0xdc, 
+       0x9b, 0xab, 0xbb, 0xba, 0x26, 0xe2, 0x88, 0x24, 0xfd, 0xd3, 
+       0x53, 0x7c, 0x5a, 0x32, 0x7f, 0x41, 0xa0, 0x3c, 0xc5, 00, 
+       0xb5, 0x89, 0xf9, 0x28, 0x8f, 0x23, 0x4a, 0x55, 0xcc, 0x9d, 
+       0xa7, 0xdf, 0x1d, 0xca, 0x3f, 0xd6, 0x27, 0x94, 0x58, 0x34, 
+       0x80, 0xfd, 0x25, 0xbf, 0x79, 0x2e, 0xe0, 0xe5, 0xeb, 0x94, 
+       0x45, 0xc1, 0x85, 0x80, 0x99, 0x98, 0x12, 0x85, 0x2a, 0xcf, 
+       0x4, 0x53, 0xa2, 0x28, 0xe9, 0xb3, 0x88, 0x74, 0xb7, 0xbe, 
+       0xd1, 0x28, 00, 00, 0x20, 00, 0x49, 0x44, 0x41, 0x54, 
+       0x92, 0x6, 0xfd, 0x1, 0xc4, 0xc4, 0xc2, 0x11, 0x5f, 0x60, 
+       0xc2, 0x92, 0x19, 0x13, 0x95, 0xc, 0xf9, 0x8c, 00, 0xb6, 
+       0x82, 0x9b, 0xcf, 0x18, 0x5f, 0xa, 0xc3, 0xcc, 0x19, 0xe6, 
+       0x7d, 0x4a, 0x2c, 0xf3, 0x8a, 0x82, 0x39, 0xbe, 0x7a, 0x24, 
+       0xcc, 0x71, 0xa4, 0xd5, 0x4f, 0x13, 0x10, 0x38, 0x34, 0x5f, 
+       0x31, 0x38, 0xe7, 0xc0, 0x32, 0xde, 0x1f, 0x72, 0xe3, 0x7, 
+       0xce, 0xc1, 0xda, 0xc0, 0x78, 0x7e, 0x12, 0xe6, 0xb0, 0x5c, 
+       0x24, 0x13, 0x7d, 0xfe, 0x54, 0xec, 0x26, 0xbb, 0xf, 0xe6, 
+       0xe6, 0x1c, 0xb8, 0x54, 0x8, 0x1e, 0xc7, 0x13, 0x1c, 0xd4, 
+       0xa6, 0x18, 0x8, 0x71, 0x43, 0x33, 0xd4, 0x6f, 0xdf, 0xbe, 
+       0x7d, 0x2c, 0xba, 0xe, 0xe, 0xa, 0xe5, 0x99, 0x88, 0x65, 
+       0x20, 0xd1, 0xa7, 0xa3, 0xd0, 0x8a, 0xa6, 0x26, 0xa0, 0xad, 
+       0xa0, 0x46, 0xcb, 0xae, 0xf, 0xed, 0xc7, 0xce, 0x37, 0xe, 
+       0x4e, 0xfd, 0xfd, 0x21, 0x3a, 0x4, 0x33, 0x8, 0x4e, 0x36, 
+       0xd8, 0xec, 0x4a, 0x70, 0x40, 0x8e, 0x5a, 0xb5, 0xbc, 0xbc, 
+       0xdc, 0xe4, 0x51, 0xcf, 0xb0, 0x86, 0xf4, 0x6f, 0x88, 0x91, 
+       0x1f, 0xd4, 0x6a, 0x2, 0x72, 0x86, 0x9, 0x6c, 0x21, 0xd, 
+       0xf2, 0x51, 0xc9, 0xca, 0xc8, 0x44, 0x43, 0x57, 0x53, 0xad, 
+       0xa7, 0xa5, 0x3e, 0xf7, 0xd6, 0xdb, 0xea, 0x63, 0xf7, 0xdc, 
+       0xa3, 0x3e, 0xf7, 0xb9, 0xcf, 0x71, 0xcb, 0xa7, 0x7e, 0x5f, 
+       0xe2, 0x5b, 0xfd, 0x87, 0x1e, 0x7a, 0x48, 0x3, 0x9b, 0xe7, 
+       0x9f, 0x7d, 0xe2, 0x13, 0x9f, 0x50, 0x37, 0xdd, 0x74, 0x93, 
+       0xd6, 0xe2, 0xf, 0x3f, 0xfc, 0xb0, 0xfa, 0xe1, 0xf, 0x7f, 
+       0xc8, 0xfd, 0xfd, 0x3a, 0xfa, 0xaf, 0xf6, 0xec, 0xd5, 0x2, 
+       0x79, 0x27, 0x16, 0x2f, 0x41, 0x38, 0xbd, 0x5b, 0x7b, 0x7a, 
+       0x72, 0x64, 0xb9, 0xb3, 0xd4, 0x21, 0xbf, 0x45, 0x1a, 0x1e, 
+       0x37, 0x66, 0xa, 0x86, 0x4b, 0x7e, 0xf3, 0x7c, 0x79, 0x90, 
+       0x79, 0x4e, 0x5c, 0x10, 0x3f, 0x14, 0x18, 0xca, 0x23, 0xeb, 
+       0x9f, 0x4c, 0x10, 0x3c, 0x9, 0x43, 0x4, 0x3f, 0x12, 0x9f, 
+       0xef, 0x30, 0x3e, 0x1d, 0xef, 0xf1, 0x7d, 0xc1, 0x24, 0xfd, 
+       0x7e, 0x14, 0xa, 0xdc, 0x8c, 0xe4, 0x93, 0x52, 0x5f, 0xa6, 
+       0x4c, 0x44, 0x84, 0x4f, 0x9e, 0x31, 0x71, 0x29, 0x88, 0x35, 
+       0x41, 0x29, 0xac, 0x14, 0x8a, 0xcf, 0x2, 0x5, 0x47, 0x8b, 
+       0x9a, 0x8c, 0x4a, 0xfe, 0x29, 0x76, 0x71, 0xc5, 0xc, 0x5, 
+       0x2c, 0xd6, 0x84, 0x83, 0xc3, 0xa2, 0x19, 0xe9, 0xb, 0x90, 
+       0x18, 0xc6, 0xe8, 0xb1, 0x6, 0x38, 0x84, 0xe6, 0xa7, 0x18, 
+       0xa8, 0x5b, 0x1, 0xf3, 0xed, 0x47, 0x78, 0x57, 0x18, 0xc0, 
+       0x64, 0x18, 0xf6, 0xb0, 0x55, 0x85, 0x56, 0x7e, 00, 0x65, 
+       0x9a, 0x87, 0xd1, 0xdf, 0xd8, 0xdc, 0xdc, 0xdc, 0x7c, 00, 
+       0xbc, 0x1d, 00, 0xb4, 0xc3, 0x94, 0x4a, 0x83, 0xcb, 0x45, 
+       0xff, 0x37, 0x6, 0x26, 0x55, 0x13, 0x96, 0xbb, 0x8e, 0x86, 
+       0x50, 0xa1, 0xc8, 0xa1, 0x1, 0x1e, 0xaa, 0x2c, 0xc1, 0xa0, 
+       0xa6, 0xb0, 0x43, 0x53, 0x73, 0xb4, 0x5b, 0xe5, 0xe4, 0xe0, 
+       0x47, 0xfb, 0xb0, 0x27, 0x19, 0x1a, 0x4f, 0xf8, 0xca, 0x72, 
+       0xfd, 0x43, 0x11, 0x47, 0xd3, 0x79, 0xaa, 0x29, 0xac, 0x34, 
+       0xc5, 0x3, 0x6, 0xd1, 0xff, 0xd4, 0x27, 0xc4, 0x5a, 0x41, 
+       0x4e, 0x7e, 0x8a, 0x46, 0x27, 0xf, 0x5, 0xe4, 0x51, 0xd8, 
+       0x53, 0xad, 0xfb, 0xdb, 0xe0, 0x8, 0xa7, 0xb4, 0x48, 0xb0, 
+       0xc6, 0xf4, 0xb9, 0xe1, 0xfa, 0x22, 0xcc, 0x3f, 0x39, 0x9d, 
+       0x94, 0x5b, 0x36, 0x99, 0x27, 0xba, 0x58, 0x5a, 0x63, 0x23, 
+       0x4f, 0xbd, 0xd3, 0xeb, 0xb9, 0xe7, 0x9e, 0xd3, 0x6f, 0xf2, 
+       0x27, 0x78, 0xc7, 0xc0, 0xb4, 0x26, 0xa1, 0x2, 0x6c, 0xf7, 
+       0x65, 0x8c, 0x8d, 0xc1, 0x2f, 0x4e, 0xaa, 0x1e, 0x8c, 0x15, 
+       0x8, 0xa8, 0x59, 0x16, 0xca, 0x15, 0xaf, 0x59, 0x36, 0xfa, 
+       0xc3, 0x21, 0x7e, 0x23, 0xe4, 0x3d, 0x1a, 0xa, 0xe7, 0x9b, 
+       0x90, 0xa9, 0xc3, 0x50, 0x1a, 0xc1, 00, 0x25, 0x56, 0xac, 
+       0x44, 0x60, 0x5b, 0x33, 0xa3, 0xbc, 0xa, 0x98, 0xe9, 0x5b, 
+       0xdf, 0x27, 0xde, 0xf4, 0xfb, 0x28, 0xa3, 0x60, 0x16, 0xb7, 
+       0x7c, 0x24, 0x2d, 0x84, 0x5c, 0xf3, 0x43, 0x98, 0x18, 0x49, 
+       00, 0xc1, 0x97, 0x25, 0x51, 0x26, 0x4c, 0xd, 0x48, 0x33, 
+       0x57, 0x46, 0xed, 0x18, 0xb6, 0x5e, 0xcb, 0xd0, 0x3c, 0xe3, 
+       0xa, 0xc8, 0x59, 0x58, 0xc7, 0x48, 0x99, 0xe3, 0x2c, 0xa2, 
+       0x38, 0x56, 00, 0x1d, 0xc1, 0xc4, 0x3e, 0x2c, 0x41, 0x84, 
+       0x8a, 0xd0, 0x7, 0x2c, 0xc0, 0x24, 0xba, 0xf6, 0xab, 0x5f, 
+       0xfd, 0xea, 0x57, 0x90, 0x37, 0x6b, 0x92, 0xa3, 0xe3, 0x32, 
+       0x2a, 0x69, 0x60, 0x5e, 0xfd, 0x66, 0x80, 0x7a, 0xa, 0x2b, 
+       0x1e, 0xe6, 0xfc, 0x3b, 0x68, 0x59, 0x2b, 0x70, 0xdd, 0x89, 
+       0x29, 0xa5, 0x1e, 0xdc, 0x6b, 0xc4, 0x75, 0x3e, 0xfa, 0xdc, 
+       0x15, 0x58, 0xdc, 0xd1, 0xe, 0x50, 0xd6, 0xee, 0xda, 0xb5, 
+       0xb, 0xc9, 0xf3, 0x93, 0xfa, 0x93, 0x34, 0x2c, 0x52, 0x6, 
+       0x6a, 0x67, 0xc6, 0xa3, 0xe3, 0xbc, 0x31, 0xad, 00, 0x68, 
+       0x2f, 0x2f, 0x2a, 0x56, 0x9f, 0x92, 0xa, 0xd, 0xa1, 0xf, 
+       0x54, 0xa4, 0x29, 0xfb, 0xbf, 0x81, 0xf8, 0x9d, 0x3c, 0xf0, 
+       0x10, 0xeb, 0xf8, 0xd, 0x34, 0xa0, 0xfa, 0xc7, 0x2, 0x61, 
+       0xba, 0x7b, 0xc9, 0x17, 0x71, 0x30, 0x5b, 0xf5, 0x99, 0x65, 
+       0xe4, 0x1d, 0xeb, 0x91, 0x1a, 0x1b, 0x15, 0xac, 0xd9, 0xf3, 
+       0xe8, 0xb6, 0x6d, 0x7a, 0xca, 0xeb, 0x6b, 0x5f, 0xfb, 0x9a, 
+       0x6, 0x3f, 0x41, 0xc7, 0x81, 0xbc, 0x60, 0x62, 0x23, 0xc1, 
+       0x46, 0x93, 0x24, 0x27, 0x97, 0x52, 0x46, 0x8, 0x72, 0x12, 
+       0x4d, 0x76, 0x2b, 0xfd, 0x17, 0xb4, 0x37, 0x17, 0xc1, 0x90, 
+       0x30, 0xc0, 0xa2, 0x70, 0xa, 0xa3, 0xae, 0x33, 0x96, 0x41, 
+       0x9c, 0xd4, 0xad, 0xc8, 0x9a, 0xf5, 0xfd, 0x48, 0xc2, 0xb4, 
+       0x66, 0xf0, 0xed, 0xd1, 0x68, 0xd0, 0xbf, 0x8c, 0xf7, 0x68, 
+       0x1d, 0x52, 0xe, 0x5, 0x7b, 0x2, 0x5e, 0xc1, 0x95, 0xe0, 
+       0x49, 0x7c, 0x19, 0x69, 0xe7, 0x35, 0xe3, 0x10, 0x8b, 0x74, 
+       0x1, 0x60, 0x23, 0x2c, 0x98, 0x45, 0xf0, 0x34, 0x49, 0x6, 
+       0xa7, 0xef, 0xf8, 0x42, 0x2, 0x6c, 0x26, 0x40, 0x27, 0x9, 
+       0x52, 0xba, 0x5, 0xbc, 0xcc, 0x88, 0x61, 0x3a, 0x29, 0x88, 
+       0x3c, 0x93, 0xcc, 0x99, 0xe, 0x81, 0x1d, 0x85, 0x3e, 0xe5, 
+       0x22, 0x98, 0xe3, 0x57, 0x62, 0xeb, 0xe6, 0xf0, 0x6d, 0x1c, 
+       0x24, 0x44, 0x22, 0xb3, 0x49, 0x64, 0xbe, 0x80, 0x8a, 0x60, 
+       0xa2, 0x90, 0x60, 0xe1, 0x8a, 0x17, 0x6b, 0xd4, 0x4d, 0xf6, 
+       0xbb, 0xb0, 0x6a, 0x2d, 0x1a, 0xfd, 0xad, 0x3b, 0xbf, 0xf2, 
+       0x95, 0xaf, 0x7c, 0x11, 0xd1, 0x9, 0x70, 0x22, 0x2a, 0x1a, 
+       0x5a, 0xc5, 0x9, 0xa1, 0xbb, 0x12, 0x60, 0x4e, 0x87, 0xe0, 
+       0xed, 0x82, 0xc6, 0xee, 0xc5, 0xb5, 0xb, 0x40, 0xa6, 0xeb, 
+       0x43, 0x98, 0xd7, 0x3d, 0x78, 0xb7, 0x4, 0xfd, 0x61, 0x6c, 
+       0xcf, 0xf5, 0xb4, 0x60, 0xbb, 0xe8, 0x21, 0x1c, 0x9f, 0x8c, 
+       0x6c, 0x7c, 00, 0x67, 0x19, 0xa4, 0xf2, 0x45, 0x4b, 0xd3, 
+       0xa7, 0x60, 0xb0, 0x1c, 0x4, 0x36, 0xcc, 0x51, 0x6d, 0x96, 
+       0xa2, 0xc1, 0x60, 0xbf, 0x9e, 0x3, 0x65, 0xba, 0xff, 0x89, 
+       0x32, 0xfc, 0xaf, 0x23, 0xf0, 0x53, 0xef, 0xbf, 0x46, 0x43, 
+       0xca, 0x1f, 0x3d, 0x34, 0x38, 0xde, 0xc0, 0xe9, 0x3e, 0x2, 
+       0x9c, 0xbc, 0x22, 0xcf, 0xc8, 0x5b, 0xf2, 0xaf, 0x77, 0xe9, 
+       0xb2, 00, 0x7f, 0xe6, 0xa3, 0xf1, 0x15, 0x1a, 0xc, 0x64, 
+       0xdc, 0xa2, 0x29, 0xda, 0x95, 0xb3, 0xe, 0x42, 0x62, 0x8a, 
+       0xf3, 0xb9, 0x95, 0x66, 0xa7, 0xa7, 0x29, 0xa7, 0xbf, 0x3b, 
+       0xd0, 0x99, 0x9e, 0x6e, 0x9e, 0x34, 0xc, 0xdd, 0xe0, 0x48, 
+       0x39, 0xa4, 0x4e, 0x45, 0xc6, 0x6, 0xcb, 0xdb, 0x9a, 0x6e, 
+       0xb8, 0x30, 0xba, 0x80, 0x4e, 0xc8, 0xc1, 0x32, 0xc8, 0xe6, 
+       0x7c, 0xc4, 0x71, 0xc2, 0x49, 0xff, 0x9a, 0xaf, 0x58, 0x31, 
+       0x66, 0xc5, 0x12, 0xc3, 0x82, 0x39, 0xfa, 0xc4, 0x1c, 0x7d, 
+       0x2a, 0x4d, 0x51, 0x9c, 0x7a, 0xb1, 0x28, 0xae, 0x7, 0x50, 
+       0x28, 0xb3, 0x5c, 0x6b, 0x6f, 0x30, 0x8a, 0xa0, 0x64, 0xa6, 
+       0x44, 0x92, 0x34, 0x2, 0x2, 0x56, 0xde, 0x27, 0xc9, 0x7d, 
+       0xdf, 0x95, 0x2f, 0x3e, 0xdf, 0xa3, 0x23, 0xb1, 0x85, 0xa2, 
+       0xf9, 0xee, 0x80, 0x16, 0xfc, 0x57, 0x8, 0x37, 0x7e, 0x1f, 
+       0x8d, 0x97, 0xc3, 0x27, 0x32, 0x9b, 0x24, 0x4c, 0x17, 0x40, 
+       0x51, 0x28, 0x30, 0x88, 0xe3, 0xe5, 0x96, 0x45, 0x68, 0x6c, 
+       0x5d, 0x2e, 0x9a, 0x44, 0x4, 0x38, 0xa2, 0x7f, 0xec, 0xcb, 
+       0x5f, 0xfe, 0xb2, 0xe7, 0x57, 0xbf, 0xfa, 0xd5, 0x6f, 0x11, 
+       0xe6, 0xb6, 0xce, 0x54, 0x94, 0x63, 0x14, 0x1, 0x8c, 0x56, 
+       0xf5, 0xb4, 0x24, 0x30, 0xe1, 0x20, 0x2, 0xb8, 0x6b, 0x51, 
+       0x29, 0x99, 0x58, 0x8b, 0x7e, 0x4, 0x42, 0xd8, 0x86, 0xc7, 
+       0xab, 0xd0, 0x20, 0xe8, 0xed, 0xa2, 0xac, 0x70, 0xe6, 0x4f, 
+       0x9f, 0xf9, 0x33, 0x4c, 0xe1, 0xa0, 0xc0, 0xf2, 0x88, 0x26, 
+       0x68, 0x13, 0x6a, 0x69, 0x6a, 0x14, 0xe1, 0x47, 0x50, 0xea, 
+       0xff, 0xfb, 0x2e, 0xd1, 0x90, 0xd2, 0x52, 0x32, 0xb0, 0xe, 
+       0x81, 0x87, 0x1f, 0x98, 0xfc, 0x41, 0x7, 0x9a, 0xea, 0x5c, 
+       0xfe, 0xca, 0x3a, 0x35, 0x30, 0xa7, 0x1d, 0xbd, 0x69, 0xa3, 
+       0x66, 0xc, 0x57, 0x89, 0x71, 0x6e, 0x7b, 0x28, 0x84, 0x3a, 
+       0xa, 0x44, 0x63, 0x1d, 0x8, 0x49, 0x98, 0xf9, 0x5a, 0x69, 
+       0xd3, 0xc9, 0xa, 0xcc, 0x7b, 0x57, 0xab, 0x65, 0xe8, 0x9e, 
+       0xc5, 0x37, 0x34, 0x18, 0x8b, 0x71, 0x3e, 0xdb, 0x87, 0x38, 
+       0x2a, 0x8, 0x4a, 0x1, 0x3f, 0x85, 0x7e, 0xfa, 0x4c, 0x36, 
+       0xeb, 0x3b, 0xb4, 0x1a, 0xa4, 0x1, 0xb1, 0xde, 0x1f, 0x4a, 
+       0x98, 0x72, 0xf, 0xf9, 0xe7, 0xe0, 0xda, 0x17, 0x60, 0xc9, 
+       0x1d, 0xc2, 0x3b, 0x2, 0x54, 0x9f, 0xb6, 0xf0, 0x61, 0xc7, 
+       0x1a, 0x96, 0x64, 0x5, 0x6b, 0xc4, 0x1e, 0x1, 0x4d, 0xa, 
+       00, 0xdb, 0x77, 0x19, 0xfa, 0x7f, 0x30, 0x38, 0x3, 0xb1, 
+       0x20, 0xb0, 0xd6, 0x44, 0x19, 0x16, 0xed, 0xcd, 0x84, 0x59, 
+       0x8, 0x5e, 0xb3, 0x80, 0x56, 0x27, 0xad, 0xa, 0xb, 0x42, 
+       0xa2, 0x50, 0x47, 0xc1, 0x1c, 0xb9, 0x1a, 0xda, 0x72, 0x22, 
+       0xa7, 0x79, 0xf4, 0xdd, 0x61, 0xfe, 0x23, 0x88, 0x48, 0x2, 
+       0x6c, 0xfa, 0x4, 0x15, 0x5b, 0x7c, 00, 0x9b, 0x23, 0xb3, 
+       0x3c, 0x68, 0xa1, 0xdf, 0x37, 0x11, 0xe0, 0xe8, 0xfb, 0x45, 
+       0x3, 0xf4, 0xf7, 00, 0xe0, 0x9f, 0xc3, 0xeb, 0x71, 0xd0, 
+       0xd8, 0x59, 0xa8, 0x28, 0x18, 0x12, 0xd1, 0x5d, 0x48, 0x43, 
+       0x97, 0x9, 0x15, 0xea, 0x45, 0x5c, 0xf, 00, 0xaf, 0x35, 
+       0x38, 0xca, 0x4b, 0xed, 0x8d, 0x29, 0xcc, 0x84, 0x56, 0xc4, 
+       0x33, 0x31, 0xc5, 0xe6, 0xc4, 0x4f, 0xc9, 0xbc, 0x86, 0x51, 
+       0xf8, 0x2d, 0x34, 0xd1, 0xa9, 0x6d, 0x8, 0x66, 0x6b, 0x19, 
+       0x78, 0xf, 0xe6, 0xb7, 0xee, 0x5b, 0xb3, 0x4f, 0x4f, 0x13, 
+       0xfc, 0x12, 0xb0, 0x75, 0x95, 0xd, 0xf8, 0x47, 0xbe, 0x90, 
+       0x3f, 0x6c, 0x8c, 0x31, 0xae, 0x61, 0xf2, 0x44, 0x51, 0xce, 
+       0x20, 0xf4, 0xf2, 0x34, 0x5d, 0x7f, 0x97, 0x5, 0x1b, 0xfa, 
+       0x55, 0xce, 0x10, 0x8f, 0x8e, 0xa6, 0x15, 0x20, 0xc4, 0xfe, 
+       0xbe, 0x90, 0x84, 0xe5, 0xc4, 0xd2, 0xc0, 0x7d, 0xa4, 0x3d, 
+       0xcd, 0xb7, 0x7e, 00, 0x52, 0x6a, 0xa8, 0xd4, 0xbc, 0x3c, 
+       0x1e, 0xc0, 0x68, 0x43, 0xfd, 0x5, 0xce, 0x65, 0x13, 0x4b, 
+       0x42, 0x1a, 0x70, 0xca, 0x1f, 0xeb, 0x7b, 0xb8, 0x44, 0xf9, 
+       0x47, 0x23, 0x34, 0xe, 0xdb, 0x8b, 0x57, 0x21, 0xd, 0x31, 
+       0xcf, 0xa9, 0xed, 0x4, 0x17, 0x4c, 0x9c, 0x18, 0xa2, 0x13, 
+       0x5c, 0x9, 0xee, 0xe8, 0x13, 0x7b, 0xf4, 0x19, 0x8f, 0xe, 
+       0x45, 0xa, 0xe0, 0x14, 0x97, 0xfd, 0xa9, 0x1f, 0x10, 0xfa, 
+       0x3f, 0xd2, 0x6f, 0x8a, 0xca, 0xd7, 0x9, 0xe1, 0x39, 0x7d, 
+       0xc9, 0x4c, 00, 0x6e, 0xbd, 0x26, 0xfa, 0x18, 0x87, 0x85, 
+       0x65, 0xa1, 0xed, 0x98, 0x6a, 0x8a, 0x6, 0xe8, 0xbe, 0x8d, 
+       0x9f, 0x8b, 0xe1, 0x6, 0xd, 0xdc, 0x1a, 0x1e, 0x91, 0xb1, 
+       0x56, 0x47, 0x86, 0xb, 0xb0, 0x69, 0x86, 0x71, 0x20, 0xd, 
+       0x23, 0xdf, 0x7a, 0xd, 0x75, 0x70, 0xe, 0x28, 0x3, 0x35, 
+       0xb8, 0x13, 0x82, 0x74, 0xdf, 0x17, 0xbf, 0xf8, 0xc5, 0x7, 
+       0x30, 0xcd, 0xd5, 0x85, 0x16, 0xd4, 0x83, 0xfe, 0x79, 0x12, 
+       0x2a, 0xd0, 0x3e, 0x18, 0xc0, 0x91, 0x4f, 0x14, 0x5c, 0xf, 
+       0x80, 0x5b, 0x83, 0x74, 0xdb, 0xfe, 0xf2, 0x97, 0xbf, 0xbc, 
+       0x86, 0x93, 0x39, 0x36, 0xd3, 0x44, 0x17, 0x80, 0x53, 0x8, 
+       0xe8, 0xd8, 0xb7, 0x46, 0x9a, 0x26, 0x46, 0x48, 0xd, 0x38, 
+       0x3d, 0x3a, 0x1c, 0x5c, 0x96, 0x4b, 0xd7, 0xa7, 0x39, 0x80, 
+       0x46, 0x93, 0x83, 0x64, 0x36, 0x74, 0xd5, 0xb8, 0xe2, 0x8d, 
+       0x4b, 0x5d, 0xbd, 0x1d, 00, 0x4f, 0x33, 0x6, 0xe1, 0x84, 
+       0xb8, 0x76, 0x7c, 0x28, 0x84, 0xc1, 0x4f, 0x6d, 0x35, 0x31, 
+       0x2e, 0x1b, 0x56, 0x21, 0xac, 0xec, 0xd3, 0x41, 0x36, 0xba, 
+       0x56, 0xe2, 0x31, 0x4b, 0x49, 0xfe, 0x51, 0x70, 0x73, 0x5c, 
+       0x96, 0x32, 0x66, 0xce, 0xd2, 0xf2, 0xc3, 0xb9, 0x7b, 0x2e, 
+       0xd0, 0xa1, 0xc6, 0xb7, 0x82, 0x9b, 0xb2, 0x46, 0x60, 0x8b, 
+       0xc, 0x5a, 0xd3, 0x1a, 0x6a, 0x98, 0xf2, 0x8f, 0x99, 0x97, 
+       0x18, 0x94, 0xef, 0x9f, 0xa1, 0x4c, 0x74, 0x17, 0x11, 0xef, 
+       0x8a, 0x75, 0xcb, 0x64, 0x4, 0x3f, 0x2, 0x62, 0x2b, 0xb6, 
+       0x18, 0xe6, 0x7d, 0xe2, 0x4b, 0xe3, 0x12, 0x65, 0x11, 0x25, 
+       0x8a, 0x5b, 0x3, 0x69, 0x50, 0x70, 0x4b, 0x74, 0x26, 0x2, 
+       0xd2, 0x89, 0xe2, 0x9e, 0xd5, 0x67, 0x66, 0xe2, 0x98, 0x11, 
+       0x1d, 0x11, 0xcc, 0x74, 0x59, 0xe8, 0x68, 0xc, 0xa2, 0xdd, 
+       0x9, 0xd3, 0x36, 0x85, 0x3f, 0xe1, 0x7a, 0x36, 0x84, 0xfc, 
+       0xf5, 0xeb, 0x64, 0x30, 0x81, 0x2d, 0xe0, 0x66, 0x6b, 0x4f, 
+       0xcd, 0xa, 0xeb, 0x40, 0xaf, 0xaf, 0xe, 0x97, 0x7, 0x1, 
+       0xe, 0xd, 0xee, 0x44, 0x9f, 0xe7, 0xb3, 0x57, 0x5e, 0x79, 
+       0xe5, 0x6d, 0x30, 0x9d, 0x7b, 00, 0xc4, 0x58, 0x98, 0x85, 
+       0x69, 0xe1, 00, 0x8e, 0x74, 0xdd, 0xe8, 0xc3, 0xa7, 0xa3, 
+       0xa2, 0x3b, 0xe1, 0x97, 0x22, 0x6d, 0x9a, 0xe5, 0xad, 00, 
+       0xf8, 0xdf, 0x30, 0x68, 0xb3, 0x5, 0xeb, 0xd6, 0xf5, 0x2f, 
+       0x9b, 0x70, 0x2d, 0x76, 0x49, 0x49, 0x89, 0x17, 0x5a, 0xc2, 
+       0xa0, 0xc9, 0x89, 0x2e, 0x48, 0xb8, 0x62, 0x5c, 0xba, 0x1f, 
+       0x82, 0x3, 0xe4, 0x17, 0xf9, 0x6, 0xeb, 0xc8, 0xe0, 0x51, 
+       0x57, 0x29, 0xfe, 0xb3, 0xca, 0x18, 0x95, 0x4b, 0x3f, 0x87, 
+       0x4a, 0x58, 0x9d, 0xa8, 0xa3, 0x62, 0x71, 0x94, 0xf6, 0xd9, 
+       0xcf, 0xa6, 0x5c, 0x90, 0xe4, 0xc4, 0x52, 0x7d, 0x81, 0x7f, 
+       0x3c, 0x9d, 0x94, 0x73, 0xde, 0x24, 0xa3, 0xaa, 0x52, 0x19, 
+       0xd8, 0xf, 0x4e, 0xd3, 0x9e, 0xf1, 0xa1, 0x28, 0xf8, 0x23, 
+       0x8, 0xfd, 00, 0x4e, 0xf9, 0xb3, 0x82, 0x5b, 0xe4, 0x51, 
+       0x27, 0x10, 0xc1, 0x3f, 0xe2, 00, 0x78, 0x48, 0x84, 0xf6, 
+       0xbe, 0x11, 0xaf, 0x51, 0x7b, 0xb3, 0xdb, 0xc8, 0xee, 0xb1, 
+       0x56, 0x86, 0xf0, 0x89, 0x1f, 0xa, 0x3b, 0x3f, 0x5c, 0xb0, 
+       0xa5, 0x31, 0x47, 0xc, 0xfa, 0x9d, 0xf, 0xc, 0x88, 0x30, 
+       0x18, 0xd, 0x9, 0xdc, 0x92, 00, 0x12, 0xe, 0x49, 0xfe, 
+       0xe7, 0x4c, 0x8b, 0x8e, 0x85, 0x24, 0xb0, 0xa3, 0xc0, 0xac, 
+       0x44, 0x30, 0xea, 0xeb, 0x68, 0x9d, 0x87, 0xd6, 0xfc, 0xe2, 
+       0xa5, 0x50, 0x84, 0x4c, 0xf5, 0x6d, 0x32, 0x57, 0x1c, 0xc1, 
+       0xcd, 0x96, 0x15, 0x3, 0x26, 0x3c, 0x53, 0x9c, 0x3, 0x68, 
+       0x67, 0x34, 0xb, 0xa8, 0x29, 0xd0, 0xdf, 0x76, 0xe6, 0xe6, 
+       0xe6, 0x7e, 0x1e, 0x26, 0xb8, 0x3, 0xa6, 0xdc, 0x29, 0x2c, 
+       0xee, 0x5f, 0x82, 0x34, 0x62, 0x43, 0x1, 0x1c, 0x53, 0x29, 
+       0x53, 0x60, 0x15, 0x18, 0x58, 0xd4, 0x52, 0x8a, 0xfe, 0xe1, 
+       0x1, 0x14, 0x82, 0xe0, 0x6e, 0xa7, 0x7b, 0xe6, 0x99, 0x67, 
+       0x5e, 0x85, 0x6, 0xdf, 0x82, 0xdb, 0x3d, 0xd0, 0x38, 0x26, 
+       0xcc, 0x4c, 0x2e, 0x98, 0xd0, 0x9b, 0x38, 0x74, 0x61, 0x2f, 
+       0xfd, 0x8b, 0x88, 0x3, 0x4, 0x16, 0x1, 0x8e, 0xf1, 0x12, 
+       0x55, 0x9e, 0x91, 0x69, 0xf6, 0xfa, 0x8f, 0xcd, 0xe2, 0x8e, 
+       0xae, 0x2c, 0xcb, 0xa9, 0x3c, 0x83, 0x25, 0x8a, 0x46, 0x57, 
+       0x3f, 0xe6, 0x82, 0x15, 0xfe, 0x1a, 0xe7, 0xfb, 0xef, 0xbf, 
+       0xaf, 0xb7, 0xb2, 0x62, 0x51, 0x8d, 0x42, 0x57, 0xaa, 0xdf, 
+       0xab, 0xf, 0xce, 0x9f, 0xa7, 0xb8, 0x19, 0x84, 0x26, 0xb9, 
+       0x17, 0xbb, 0xbc, 0xb0, 0xae, 0x56, 0x3f, 0xa7, 0x1c, 0x41, 
+       0xb3, 0x9a, 0x68, 0xd0, 0xbd, 0x56, 0xed, 0x4d, 0xcd, 0x4d, 
+       0x99, 0x13, 0xf9, 0x13, 0x99, 0xec, 0x97, 0xe8, 0x10, 0x2f, 
+       0x30, 0xb8, 0x16, 0x3, 0xb, 0xe1, 0x1, 0xc8, 0x23, 0xf7, 
+       0x36, 0x88, 0x6, 0xb7, 0x82, 0x9c, 0x38, 0xd2, 0xf2, 0x6c, 
+       0x5, 0xdc, 0x10, 0x93, 0xf, 0x44, 0x8b, 0x8, 0xdc, 0x81, 
+       0xb7, 0x2c, 0x1, 0x98, 0x1a, 0x2c, 0x84, 0x38, 0x2, 0x9b, 
+       0xad, 0x10, 0x5d, 0x34, 0x16, 0xac, 0x7c, 0x6, 0x1f, 0xe1, 
+       0xe4, 0x74, 0xd3, 0x70, 0x89, 0x4c, 0xb4, 0x3a, 0x32, 0x57, 
+       0xcc, 0x71, 0x9a, 0x4f, 0xec, 0x67, 0xa3, 0x2f, 0x33, 0xe4, 
+       0xef, 0xe0, 0xc0, 0xd, 0xcc, 0xf7, 0x28, 0x34, 0x8, 0x37, 
+       0xa0, 0xf2, 0x62, 0x39, 0x8, 0x7, 0x21, 0xb8, 0x6, 0x9a, 
+       0x78, 0x12, 0x4c, 0xb7, 0x24, 0xb4, 0xd8, 0x4e, 0xc, 0xf6, 
+       0xa4, 0x63, 0x5e, 0x72, 0x15, 0xcc, 0xf7, 0xf1, 0x30, 0xf7, 
+       0x6a, 0xb1, 0x75, 0xef, 0x2f, 0x98, 0x9f, 0xe4, 0xc0, 0x1b, 
+       0xb7, 0x21, 0x11, 0xe0, 0x1a, 0xe4, 0x98, 0x37, 0x7d, 0xd, 
+       0x71, 0xf2, 0xc1, 0x2, 0x4e, 0xbd, 0xa1, 0x1b, 0x3f, 0xe4, 
+       0x62, 0xc, 0x97, 0x1d, 0xff, 0xd0, 0xef, 0x91, 0x7f, 0xd0, 
+       0x9c, 0xb6, 0x46, 0x8c, 0x5e, 0xbb, 0xfc, 0xd, 0x3a, 0xf7, 
+       0x56, 0xe7, 0x26, 0x8f, 0x1a, 0xd2, 0x77, 0x13, 0xd0, 0x3f, 
+       0xfe, 0xf1, 0x8f, 0xf5, 0xdc, 0x39, 0x4f, 0x2b, 0xe5, 0xa, 
+       0x35, 0xcc, 0x72, 0x70, 0xef, 0x41, 0xbf, 0xf7, 0xc7, 0x2, 
+       0xd4, 0xdc, 0x55, 0xa6, 0x89, 0xf9, 0xe4, 0x4d, 0x51, 0xa6, 
+       0x7f, 0x5f, 0x37, 0xef, 0x51, 0x9e, 0x68, 0x9e, 0xb3, 0xbb, 
+       0x27, 00, 0xa7, 0x22, 0xa1, 0xec, 0x11, 0xe0, 0x56, 0x79, 
+       0xf4, 0x25, 0x12, 0xd9, 0x7f, 0x5a, 0x14, 0x48, 0x3f, 0xa, 
+       0xb, 0x98, 0xee, 0xc2, 0x9b, 0xd4, 0xde, 0xd2, 0xff, 0xa6, 
+       0x52, 0x14, 0x2d, 0x1e, 00, 0x78, 0x64, 0xa9, 0x9f, 0x8e, 
+       0x3d, 0x60, 0xcb, 0xe7, 0xe9, 0x47, 0x43, 0xb, 0xf9, 0xc1, 
+       0x4d, 0x50, 0xd3, 0x71, 0x88, 0x9f, 0x5, 0x8d, 0xc3, 0x6a, 
+       0xb1, 0x4c, 0xac, 0x12, 0x7b, 0x1f, 0xeb, 0x7b, 0x63, 0x31, 
+       0x80, 0x85, 0x5b, 0xc3, 0x23, 0x32, 0x94, 0x24, 0x66, 0x38, 
+       0x7d, 0x32, 0x9c, 0xe6, 0x38, 0x9e, 0x99, 0x3c, 0xd0, 0xd0, 
+       0xbf, 0xb1, 0x22, 0xa2, 0xc, 0xf8, 0x3e, 0x76, 0x8d, 0xb9, 
+       0x60, 0x6, 0x6e, 0xc1, 0x48, 0xa6, 0x7, 0x16, 0x46, 0x22, 
+       0x5a, 0x52, 0xec, 0xeb, 0xb7, 0xb1, 0xf1, 0xe0, 0x2f, 0x85, 
+       0xb6, 0xc3, 0x14, 0x3f, 0x9, 0xad, 0xfc, 0xdc, 0xd3, 0x4f, 
+       0x3f, 0x5d, 0x88, 0xc4, 0xd9, 0xc2, 0xc6, 0xc1, 0x71, 0x58, 
+       0x56, 0x76, 0x93, 0x8d, 0x82, 0x5, 0x30, 0xea, 0xd3, 0x9f, 
+       0xfe, 0xf4, 0xd, 0xe8, 0xd3, 0xaf, 0xc1, 0xea, 0xb8, 0x33, 
+       0xfe, 0x74, 0x11, 0xde, 0xbd, 0x44, 0x61, 0x38, 0xc0, 0x3a, 
+       0x41, 0xa3, 0xea, 0x3a, 0xbe, 0x63, 0xc7, 0xbe, 0x4f, 0xda, 
+       0x8c, 0xcb, 0x10, 0x4d, 0x6b, 0x2f, 0x46, 0xbf, 0xf2, 0xd9, 
+       0xe7, 0x4e, 0x3, 0x32, 0xcc, 0xfb, 0x72, 0x9b, 0x83, 0x68, 
+       0x90, 0x3d, 0xbd, 0xf6, 0x1c, 0xe3, 0x20, 0x72, 0x3b, 0xe0, 
+       0xff, 0xdb, 0xca, 0x15, 0xea, 0x26, 0x6a, 0x6b, 0x3f, 0x79, 
+       0xb1, 0xa4, 0xd4, 0x5c, 0xbe, 0x5c, 0x2e, 0xb5, 0x4f, 0xc5, 
+       0x1, 0xab, 0x4e, 0x6f, 0x77, 0xa5, 0x55, 0x41, 0xab, 0x8f, 
+       0x8e, 0xdd, 0x3b, 0x8e, 0xa6, 0x73, 0xf4, 0x9b, 0xb2, 0x32, 
+       0xdc, 0x6, 0x9d, 0x53, 0x74, 0x38, 0x89, 0xb7, 0x7, 0x3f, 
+       0x5e, 0xf9, 0x69, 0x58, 0x86, 0x55, 0xc8, 0x54, 0xac, 0x42, 
+       0xf6, 0x15, 0x38, 0x5, 0xc6, 0x1, 0x35, 0xf6, 0xb3, 0x69, 
+       0x8a, 0xf, 0xc9, 0xc, 0x47, 0xdc, 0x7e, 0x34, 0x60, 0xe3, 
+       0x48, 0xbf, 0xa7, 0x67, 0xb8, 0xb0, 0x68, 0x6d, 0xb6, 0x32, 
+       0x4, 0x37, 0x5b, 0x1e, 0x82, 0x3b, 0x16, 0x3f, 0xc7, 0xfa, 
+       0x4d, 0x2c, 0x1c, 0x98, 0x85, 0xf9, 0x6d, 0xb6, 0x44, 0xc3, 
+       0x22, 0xf9, 0x26, 0x2, 0x5c, 0x1c, 0x5b, 0x50, 0x3a, 0x98, 
+       0xd4, 0x7a, 0xda, 0xb, 0xe6, 0x70, 0x40, 00, 0x22, 0xc9, 
+       0x84, 0xa3, 0xe8, 0x68, 0x41, 0xed, 0x60, 0x6c, 0x36, 0xd2, 
+       0xda, 0xe, 0xd, 0x5e, 0x80, 0x3e, 0x38, 0x2e, 0x3b, 0x9a, 
+       0xc1, 0xf8, 0x43, 00, 0xf6, 0x96, 0x8d, 0x1b, 0x37, 0xfe, 
+       0x1, 0xc2, 0x56, 0x89, 0x74, 0xc9, 0x5c, 0x5f, 0x2b, 0x63, 
+       0x11, 0x38, 0xe6, 0xc7, 0x6, 0x6, 0x42, 0x50, 0x8a, 0x7e, 
+       0x63, 0xc, 0x1a, 0x84, 0xf1, 0xe8, 0x53, 0xe9, 0xa9, 0x14, 
+       0x3e, 0xbb, 0x44, 0x43, 0xe7, 00, 0x78, 0x4f, 0x60, 0xbb, 
+       0xb1, 0xdc, 0x77, 0xf3, 0x1f, 0x9e, 0x7e, 0xfa, 0xbd, 0xc2, 
+       0x53, 0x4d, 0xfb, 0x66, 0xa4, 0xa6, 0x25, 0xe2, 0x30, 0x85, 
+       0xb1, 0xdc, 0x38, 0xd2, 0x89, 0x3a, 0xe7, 0xfa, 0xf2, 0xa1, 
+       0xf4, 0xc1, 0x29, 0x1f, 0x5c, 0xe8, 0x42, 00, 0x5, 0xd3, 
+       0x52, 0xc, 0xb6, 0x2d, 0xce, 0xcc, 0x50, 0xe3, 0xb1, 0x4d, 
+       0x15, 0x8, 0x55, 0xde, 0xeb, 0xaf, 0x57, 0x26, 0x7e, 0xb3, 
+       0x9b, 0xe6, 0xb9, 0x95, 0x38, 0x2f, 0xf, 0x59, 0x30, 0xd1, 
+       0xf8, 0x9b, 00, 0x32, 0x4e, 0x17, 0x3e, 0xd, 0x66, 0x1a, 
+       0xab, 0x74, 0x42, 0xd6, 0xb0, 0xdc, 0x3b, 0x93, 0x4f, 0xb, 
+       0x12, 0xe5, 0x83, 0xf8, 0x78, 0xe3, 0xa1, 0x40, 0xf6, 0x20, 
+       0xbe, 0xc, 0x98, 0x69, 0x40, 0xe3, 0x9a, 0xf2, 0x46, 0xb9, 
+       0x33, 0x1f, 0x9, 0xda, 0x10, 0x82, 0x7b, 0x43, 0xa2, 0x61, 
+       0x3, 0xcf, 0x92, 0x3a, 0x81, 0x6d, 0x5, 0x37, 0xcd, 0xf0, 
+       0x31, 0x68, 0xe5, 0xee, 0xe4, 0xbc, 0x9e, 0x25, 0x5e, 0xc4, 
+       0x41, 0xab, 0xf9, 0x43, 0x70, 0xd3, 0x1c, 0xa7, 0x13, 0x73, 
+       0x1c, 0x66, 0xff, 0x69, 0xe, 0x47, 0x9c, 0x3a, 0x5a, 0x20, 
+       0x54, 0x20, 0x1a, 0x21, 0x9c, 0x6d, 0x63, 0x7e, 0x12, 0xe6, 
+       0xdb, 0xcf, 0xfe, 0x1b, 0x84, 0x64, 0xb8, 0x5d, 0x54, 0x5a, 
+       0x4e, 0xda, 0x6e, 0x2, 0x6a, 0xc9, 0xc1, 0x9a, 0x67, 0xa0, 
+       0x45, 0x7d, 0xfc, 0xf1, 0xc7, 0x5f, 0xf3, 0x47, 0xb8, 0xa4, 
+       0xc1, 0x85, 0x53, 0x61, 0x7c, 0x1c, 0xfd, 0xa2, 0x3c, 0x1d, 
+       0xed, 0xca, 0x9e, 0x98, 0xa4, 0xba, 0xf6, 0xed, 0x53, 0xd8, 
+       0x62, 0xa9, 0xb6, 0x6c, 0xda, 0xe4, 0xde, 0xbf, 0x7b, 0xf7, 
+       0xb6, 0x67, 0x9e, 0x7f, 0xfe, 0x43, 0xbc, 0xd6, 0xb9, 0xa5, 
+       0xa2, 0xaa, 0xe1, 0x7, 0xab, 0x2e, 0xd7, 0xfd, 0xb9, 0x24, 
+       0x68, 0xcb, 0xaf, 0x2e, 0x59, 0x8c, 0xdd, 0x61, 0xbd, 0xea, 
+       0xad, 0xe2, 0x92, 0x30, 0xa9, 0xe, 0xed, 0xf6, 0x4f, 0xd7, 
+       0xac, 0xd6, 0x7, 0x23, 0xea, 0xd8, 0xb0, 0x2, 0xa1, 0x7a, 
+       0x7d, 0x2e, 0xc4, 0xeb, 0x90, 0x2f, 0x1b, 0x4c, 0x73, 0xce, 
+       0xc5, 0xf7, 0xd3, 0xd4, 0xd4, 0xd6, 0xb4, 0x20, 0x5, 0xd4, 
+       0x94, 0x53, 0x9, 0x87, 0x48, 0x26, 0xec, 0x2d, 0x2c, 0x69, 
+       0x76, 0x62, 0x20, 0xf6, 0x3a, 0xc, 0x24, 0x3e, 0xb, 0x65, 
+       0xc2, 0x5, 0x60, 0x74, 0xb4, 0x7e, 0x9, 0x70, 0x1, 0xbb, 
+       0x17, 0x69, 0xd3, 0xc2, 0xe, 0xc8, 0x1a, 0x9e, 0xd, 0x89, 
+       0x86, 0xad, 0xb9, 0x99, 0x21, 0x72, 0xa0, 0x13, 0x60, 0x8b, 
+       0x49, 0x1e, 0x83, 0x11, 0xf2, 0x7, 0x30, 0x1a, 0xb8, 0x8, 
+       0x7d, 0x97, 0x61, 0x37, 0x1e, 0xf2, 0x2d, 0x4, 0x35, 0x19, 
+       0x49, 0xc7, 0x16, 0x19, 0xda, 0x91, 0x8c, 0xe6, 0x2f, 0x82, 
+       0x70, 0xa5, 0xd3, 0x90, 0x3e, 0x72, 0xb0, 0x48, 0x34, 0xb3, 
+       0x30, 0x88, 0x62, 0x43, 0xda, 0x2b, 0x30, 0x92, 0x5e, 0xf, 
+       0x53, 0xbd, 0x14, 0xf1, 0x75, 0x8b, 0xe9, 0xf7, 0xf9, 0xba, 
+       00, 0x5c, 0x7c, 0x79, 0x2e, 0x40, 0xe7, 0x7d, 0x3, 0x1a, 
+       0xbc, 0xc, 0x1a, 0x3c, 0xfa, 0x92, 0x6, 0x27, 0xcb, 0x6, 
+       0x52, 0xd7, 0xfe, 0xfd, 0xa, 0xfd, 0x20, 0xd5, 0xbe, 0xe1, 
+       0x5d, 0xd5, 0xf6, 0xd6, 0x5b, 0xaa, 0xb7, 0xe8, 0x84, 0xea, 
+       0xda, 0xbb, 0x47, 0xb5, 0x1c, 0xca, 0x37, 0xb3, 0xaa, 0x2a, 
+       0x8d, 0xc9, 0x6e, 0x77, 0x3c, 0xe6, 0xb6, 0x1b, 0xf0, 0xb, 
+       0x99, 0xb9, 0x1b, 0xcb, 0xcb, 0xf, 0x4f, 0x4b, 0x4d, 0x6d, 
+       0x8e, 0x71, 0xd8, 0xdb, 0x12, 0x9d, 0xce, 0x1c, 0xa4, 0x66, 
+       0xcb, 0xc4, 0x42, 0x94, 0x5, 0x58, 0x6c, 0xf2, 0xc1, 0x20, 
+       0x67, 0xb4, 0xf, 0xcc, 0xd5, 0x77, 0x67, 0x2d, 0x6, 0xcc, 
+       0xbe, 0x8d, 0x9f, 0xf8, 0x49, 0x83, 0xc9, 0xce, 0x33, 0xd5, 
+       0xcc, 0xc, 0x4c, 0x91, 0xe1, 0x17, 0x3f, 0xcd, 0xa9, 0xd3, 
+       0xb4, 0x6, 0xf, 0xf5, 0x1e, 0x41, 0xcc, 0x19, 0x10, 0x68, 
+       0x58, 0x1e, 0x45, 0xa5, 0xb7, 0xb5, 0x52, 0x83, 0x53, 0xf4, 
+       0xad, 0x26, 0x39, 0xaf, 0x7d, 0x70, 0x8, 0x95, 0x4a, 0xf8, 
+       0x7b, 0x34, 0xef, 0x31, 0xa6, 0xc3, 0x63, 0x83, 0x5c, 0xb0, 
+       0x1c, 0xf3, 0x11, 0x53, 00, 0x2d, 0xbe, 0xc8, 0xd9, 0xb0, 
+       0xb4, 0xf7, 0xb0, 0xc1, 0xe7, 0x2f, 0x32, 0x81, 0x2d, 0xe0, 
+       0xd6, 0x23, 0xe4, 00, 0x4b, 0x34, 0xfa, 0x28, 0x9f, 0xc2, 
+       0x62, 0x12, 0x9a, 0xe7, 0xc3, 0x26, 0x82, 0x9b, 0x8e, 0xe0, 
+       0x16, 0x80, 0xfb, 0xb5, 0x36, 0x6, 0x37, 0x27, 0xeb, 0xdf, 
+       0x8a, 0x1a, 0x76, 0xe2, 0x41, 0x2f, 0xb2, 0x4f, 0x5, 0xd, 
+       0x4e, 0x5e, 0x7c, 0xf7, 0xfe, 0xfb, 0xef, 0xf7, 0x3c, 0xf9, 
+       0xe4, 0x93, 0x6f, 0x20, 0x2c, 0x8c, 0x65, 0x6c, 0x86, 0x5, 
+       0xd8, 0xec, 0xb, 0x9, 0xa8, 0xa5, 0x81, 0x63, 0x1c, 0xf2, 
+       0xc1, 0x80, 0x6, 0x7f, 0x1d, 0xe5, 0x66, 0x4b, 0xbb, 0x6, 
+       0xa3, 0xe7, 0x61, 0x7f, 0x5d, 0x94, 0x2f, 0x8c, 0x34, 0x91, 
+       0x5f, 0x24, 0xf1, 0x25, 0x6c, 0xbd, 0xd6, 0x11, 0xfc, 0xff, 
+       0x82, 0x85, 0x52, 0x4, 0x54, 0x7c, 0x6b, 0xdc, 0xb3, 0x9, 
+       0xf7, 0xf0, 0x70, 0x7f, 0x94, 0xad, 0xe5, 0xe5, 0x97, 0xb4, 
+       0x2f, 0x69, 0xb9, 0xfc, 0x6b, 0xc4, 0xe3, 0xba, 0xbb, 0x34, 
+       0x1f, 0x53, 0x62, 0xa2, 0xd3, 0x3f, 0x37, 0x6f, 0xee, 0xfd, 
+       0x7c, 0x6e, 0x18, 0xab, 0x6b, 0xa2, 0xc, 0xa3, 0xf3, 0x4f, 
+       0x87, 0x8f, 0xfc, 0xf6, 0xdb, 0xcb, 0x96, 0x5e, 0xc3, 0x7b, 
+       0x5c, 0x74, 0x42, 0xb7, 0x7, 0xd, 0x44, 0x63, 0x57, 0xb7, 
+       0xda, 0x1e, 0x62, 0x8d, 0x39, 0xe3, 0x59, 0x89, 0x1b, 0x4f, 
+       0xae, 0xcd, 0xc9, 0xd1, 0x7, 0x28, 0xce, 0xb3, 0xe, 0xec, 
+       0x8e, 0x1d, 0xa3, 0xbc, 0xcb, 0xfa, 0xf7, 0xb3, 0xad, 0xef, 
+       0x49, 0xd8, 0x3f, 0xf8, 0x65, 0x62, 0x85, 0x22, 0x8f, 0x98, 
+       0xb2, 0x49, 0x7f, 0x9b, 0xca, 0x46, 0xfa, 0xdb, 0xe4, 0x17, 
+       0x79, 0x3c, 0x1c, 0xbe, 0x1, 0x27, 0x4e, 0x8c, 0xb, 0xdc, 
+       0x8a, 0x46, 0xe3, 0x79, 0xa4, 0x49, 0x8b, 0x51, 0xb4, 0x37, 
+       0xad, 0xc6, 0xc0, 0x54, 0x18, 0xd2, 0x8e, 0x58, 0x7b, 0x9f, 
+       0x2d, 0xb8, 0xc9, 0x3, 0xa, 0x35, 0xd3, 0xa1, 0x73, 0x42, 
+       0x5b, 0x5f, 0xcb, 0xd5, 0x5c, 0x18, 0xc5, 0xc6, 0xe5, 0xf0, 
+       0x88, 0x60, 0x26, 0x9, 0xb0, 0xc5, 0x1c, 0xe7, 0xdc, 0x23, 
+       0x47, 0xc7, 0x61, 0x19, 0x8, 0xb8, 0x86, 0x97, 0x41, 0x88, 
+       0xb7, 0xb8, 0x3c, 0x11, 0xd6, 0x80, 0x3, 0x79, 0x7e, 0xef, 
+       0xde, 0x7b, 0xef, 0xf5, 0x3c, 0xf5, 0xd4, 0x53, 0x6f, 0x21, 
+       0x1a, 0xf3, 0x11, 0x60, 0x33, 0xcc, 0x82, 0x91, 0xe1, 0x4, 
+       0x38, 0xef, 0xf3, 0xdb, 0x79, 0xcf, 0x87, 0x2a, 0x4, 0x40, 
+       0xc6, 0x13, 0x4f, 0x3c, 0xf1, 0x3a, 0x7d, 0xb8, 0xd5, 0xe7, 
+       0xa, 0xe0, 0x14, 0x26, 0x1, 0x2d, 0xf9, 0x64, 0xbd, 0x96, 
+       0xfb, 0xe2, 0xb3, 0x50, 0x43, 0x21, 0xab, 0xb0, 0x52, 0x50, 
+       0x83, 0xaf, 0x87, 0x92, 0x46, 0x70, 0x1c, 0x2f, 0x6, 0xc9, 
+       0x4e, 0x3d, 0xfd, 0x54, 0xf0, 0x6d, 0xdd, 0x87, 0xc6, 0xf1, 
+       0x46, 0x8a, 0x3f, 0x52, 0x3f, 0x3, 0xfb, 00, 0x3a, 0x60, 
+       0x95, 0xf1, 0x84, 0x14, 0xa1, 0xab, 0x27, 0x4e, 0xfc, 0x12, 
+       0xc3, 0x8d, 0x7d, 0x7d, 0x77, 0xb5, 0xbb, 0xfa, 0xd6, 0x61, 
+       0xe8, 0xaa, 0x2f, 0x3e, 0xca, 0x71, 0x3b, 0xef, 0x7d, 0x17, 
+       0x83, 0x5f, 0x38, 0xeb, 0xcc, 0x7c, 0x64, 0xcb, 0x16, 0x23, 
+       0x23, 0x3e, 0x41, 0x9f, 0x6b, 0x16, 0xb, 0x2d, 0xc8, 0x11, 
+       0x70, 0xae, 0x6a, 0xeb, 0x5, 0xf0, 0x98, 0xe6, 0xf2, 0xac, 
+       0x71, 0x6a, 0x3c, 0x4c, 0xff, 0xeb, 0x71, 0xf6, 0x99, 0x10, 
+       0xce, 0xaa, 0x82, 0xa6, 0xc6, 0xf2, 0x52, 0xfc, 0x60, 0xc1, 
+       0x50, 0x9, 0xf2, 0x66, 0xa3, 0xf6, 0xe6, 0x5e, 0x1, 0x6a, 
+       0x6e, 0x3a, 0xd1, 0xdc, 0xc2, 0x27, 0xf2, 0x9a, 0xe1, 0x48, 
+       0x89, 0x38, 0xc1, 0x80, 0xb3, 0x23, 0x37, 0x37, 0x77, 0x25, 
+       0x66, 0x65, 0xde, 0xc1, 0xfb, 0x4, 0x37, 0x41, 0x4e, 0x66, 
+       0x50, 0x83, 0x6b, 0xa5, 0x1, 0x3f, 0x62, 0x1a, 0x16, 0xb8, 
+       0xf1, 0x11, 0xfc, 0xa, 0x3a, 0x66, 0x2c, 0x23, 0xe5, 0x5a, 
+       0x73, 0xa3, 0xb0, 0x9f, 0x85, 0x16, 0xe4, 0xa8, 0xf2, 0xb0, 
+       0x48, 0x4, 0x52, 0x80, 0x2d, 0x3e, 0x4d, 0x72, 0x80, 0xdb, 
+       0x9b, 0x93, 0x93, 0xc3, 0x51, 0xcb, 0xc8, 0xb9, 0x38, 0x48, 
+       0x69, 0x98, 0x27, 0x9d, 00, 0x1c, 0xe1, 0x1f, 0xf8, 0x1, 
+       0x4e, 0x66, 0x93, 0xf8, 0x9d, 0x4, 0xb4, 0x98, 0x4b, 0x4, 
+       0x38, 0x89, 0x23, 0x9b, 0xc, 0xf3, 0x39, 0x2b, 0xdd, 0x6, 
+       0xd3, 0x3e, 0xd, 0xd3, 0x1c, 0x19, 0x38, 0x5a, 0xa7, 0x14, 
+       0x56, 0x4c, 0x22, 0x5a, 0xe3, 0x5, 0xd8, 0x11, 0x75, 0xd6, 
+       0x1a, 0x5c, 0xf8, 0x42, 0xdf, 0xa, 0x66, 0xb9, 0x2f, 0x7c, 
+       0x62, 0x39, 0xe4, 0xb9, 0x84, 0xe9, 0x87, 0x23, 0x11, 0x48, 
+       0x11, 0x56, 0xc6, 0x63, 0xd8, 0x7a, 0x9f, 0x61, 0x3a, 0xeb, 
+       0x7d, 0x79, 0x1e, 0x2e, 0x5d, 0xde, 0x6f, 0x7e, 0xee, 0x59, 
+       0xd5, 0x87, 0xa3, 0x88, 0xac, 0xb4, 0xbb, 0xa6, 0x56, 0x95, 
+       0x61, 0xa0, 0xeb, 0x29, 0xff, 0x6e, 0xad, 0x3a, 0x34, 0xd8, 
+       0x32, 0x35, 0xc5, 0xb9, 0xe7, 0xb1, 0x71, 0xf1, 0x6a, 0xed, 
+       0x84, 0xf1, 0x81, 0x57, 0x6e, 0xcf, 0x9b, 0xfc, 0x1b, 0xfc, 
+       0x3c, 0x74, 0xf9, 0x57, 0xde, 0xdf, 0x74, 0xe7, 0x6f, 0xae, 
+       0xbe, 0xea, 0x36, 0xb4, 0xa2, 0xba, 0xee, 0x61, 0x5a, 0x1b, 
+       0x3f, 0xc6, 0x59, 0xe1, 0xa4, 0xa5, 0xe3, 0x32, 0xd5, 0x22, 
+       0x80, 0xf6, 0xb9, 0x82, 0xa3, 0x1a, 0xc8, 0x38, 0xfe, 0x16, 
+       0xa7, 0xad, 0x38, 0x55, 0xba, 0x65, 0x19, 0xaa, 0x24, 0x68, 
+       0xe6, 0xe6, 0x2a, 0x33, 0x82, 0x3, 0x17, 0xf8, 0x1e, 0x47, 
+       0xc9, 0xd1, 0xdd, 0xe2, 0x1, 0x14, 0xdc, 0xb6, 0x1a, 0xd0, 
+       0xde, 0x2, 0x72, 0xf2, 0x5b, 0x88, 0x3c, 0x8a, 0x94, 0x30, 
+       0x35, 0x1b, 0x8b, 0xbe, 0xfd, 0x5d, 00, 0xf7, 0x87, 0x78, 
+       0x97, 0xbb, 0x2d, 0xd9, 0xc5, 0xa5, 0xbc, 0x51, 0x7b, 0xd3, 
+       0x31, 0x51, 0x2a, 0x10, 0x91, 0x3b, 0x4, 0xcf, 0x4c, 0xc3, 
+       0x2, 0xb7, 0x3f, 0x59, 0x66, 0x48, 0x27, 0xa3, 0xe4, 0x51, 
+       0x58, 0x80, 0x30, 0x1d, 0x1f, 0x3c, 0x9, 0xad, 0xd0, 0x99, 
+       0x73, 0xe, 0x13, 0x83, 0xc2, 0x2a, 0x8e, 0x4c, 0x93, 0xbe, 
+       0x36, 0x46, 0x2e, 0xb5, 0xd6, 0x46, 0x1e, 0xe7, 0x4, 0xd8, 
+       0x92, 0x27, 0xa7, 0x51, 0x30, 0x90, 0xe2, 0x40, 0xbe, 0x8f, 
+       0x62, 0xc3, 0xbf, 0xf9, 0xec, 0xb3, 0xcf, 0x6e, 0xf0, 0x17, 
+       0x95, 0xf9, 0x8a, 0x23, 0xc8, 0x19, 0x66, 0x5, 0xd0, 0xef, 
+       0xc2, 0x6, 0x91, 0x74, 0x4c, 0xcb, 0xdd, 0xd, 0x13, 0x3f, 
+       0x17, 0x23, 0xf1, 0xf1, 0x10, 0x7e, 0xf6, 0xbd, 0x4d, 0xec, 
+       0x63, 0x6e, 0xc2, 0xb1, 0xca, 0x69, 0xf8, 0x31, 0x5, 0x7, 
+       0xd3, 0x8e, 0x94, 0xa4, 0x5c, 0x2, 0x5e, 0x5e, 0x93, 0xe4, 
+       0x5a, 0x7c, 0xde, 0x67, 0x58, 0x7c, 0x86, 0x49, 0x12, 0x5f, 
+       0x5f, 0x84, 0xf8, 0x27, 0x20, 0xa5, 0x4f, 0x27, 0x2, 0xcb, 
+       0xa8, 0x14, 0x54, 0xb9, 0x96, 0x78, 0xbc, 0x27, 0x4e, 0xde, 
+       0x9, 0x91, 0xac, 0xf2, 0xf0, 0x67, 0x90, 0x79, 0xb6, 0x1a, 
+       0x8e, 0xa0, 0x26, 0x61, 0x3e, 0x47, 0x3d, 0xb2, 0x65, 0xab, 
+       0xda, 0x8d, 0x7b, 0xcd, 0x18, 0x37, 0xb1, 0x12, 0x1, 0x4e, 
+       0xfa, 0xe5, 0xae, 0xdd, 0x7a, 0xb0, 0xeb, 0xfd, 0xf2, 0x6c, 
+       0xf5, 0x65, 0xfc, 0x50, 00, 0x97, 0x9e, 0x42, 0xc0, 0xd2, 
+       0xed, 0x76, 0x47, 0xfc, 0x6d, 0x79, 0x79, 0xa3, 0x2a, 0x3b, 
+       0x3a, 0xff, 0x19, 0xc6, 0xa9, 0x81, 0xd3, 0x53, 0xee, 0xc6, 
+       0xe, 0xa4, 0x2b, 0x24, 0x8d, 0xcb, 0xfc, 0x4b, 0x4c, 0xef, 
+       0x99, 0x85, 0x51, 0x6f, 0x50, 0xa8, 0x25, 0xab, 0x5e, 0xfc, 
+       0x72, 0x27, 0xd6, 0x95, 0x2a, 0x1c, 0x79, 0x23, 0xaf, 0x45, 
+       0xe4, 0x43, 0xee, 0x6c, 0x1c, 0x39, 0xc7, 0xc8, 0x76, 0x60, 
+       0x2a, 0x8c, 0xbc, 0xa1, 0xa3, 0x8c, 0xe, 0x7, 0xd4, 0x52, 
+       0x80, 0x9c, 0x9c, 0x1c, 0x1e, 0x5e, 0x91, 0x8d, 0xb5, 0x17, 
+       0x53, 0x6a, 0x6a, 0x6a, 0x78, 0x2c, 0x38, 0x7, 0xa2, 0xa9, 
+       0xc1, 0x89, 0x4f, 0x3a, 0x82, 0xda, 0x3, 0x7e, 0x47, 0x64, 
+       0x9a, 0x47, 0xc, 0x6e, 0x66, 0x80, 0x8c, 0xc4, 0x11, 0xd8, 
+       0x52, 00, 0x27, 0x5a, 0xb7, 0x7, 0xb0, 0x8, 0x41, 0xcf, 
+       0x15, 0xe3, 0x7e, 0xc4, 0x24, 0x82, 0x28, 0x2, 0x4a, 0xa6, 
+       0x89, 0xc3, 0x80, 0x86, 0x97, 0xe6, 0x38, 0xa7, 0xb0, 0x46, 
+       0x8a, 0x98, 0x8f, 0xe4, 0x65, 0x5, 0x6, 0x47, 0xd1, 0x39, 
+       0x18, 0x8, 0x30, 0xfe, 0x1c, 0x95, 0xfa, 0x26, 0x16, 0x46, 
+       0x7c, 0xf, 0x79, 0x4a, 0xeb, 0xc9, 0x6f, 0x27, 0x72, 0x4, 
+       0xe0, 0xea, 0xe3, 0x1f, 0xff, 0xf8, 0x7c, 0xac, 0x6a, 0x7a, 
+       00, 0x73, 0xe5, 0x19, 0xec, 0x92, 0xa0, 0xa5, 0x6f, 0x47, 
+       0x65, 0x77, 0x60, 0x7a, 0x67, 0x14, 0xac, 0x8d, 0x1e, 0x8c, 
+       0x84, 0x36, 0xbf, 0xfc, 0xf2, 0xcb, 0xa3, 0xf1, 0x7b, 0x67, 
+       0x76, 0x3c, 0x3f, 0x63, 0xf1, 0xa5, 0x5c, 0x8c, 0xc8, 0xef, 
+       0x97, 0x6b, 0x1, 0x32, 0xef, 0x31, 0x2c, 0xbe, 0xdc, 0xe7, 
+       0x60, 0x23, 0x16, 0xdd, 0xe1, 0x14, 0x99, 0x36, 0xec, 0x6b, 
+       0xef, 0xe6, 0xcc, 0x2, 0x5e, 0xf5, 0xb5, 0x6, 0xf0, 0x30, 
+       0x20, 0xa4, 0xfb, 0x86, 0xfa, 0xe, 0x6b, 0x91, 0x75, 0x9, 
+       0xe1, 0xc4, 0x61, 0x8c, 0x31, 0x30, 0xd, 0x93, 0xf4, 0x49, 
+       0x36, 0xd4, 0x52, 0xec, 0x57, 0x52, 0x58, 0x59, 0xd5, 0xf4, 
+       0x79, 0xcd, 0x30, 0x7d, 0xbe, 0xcc, 0xfc, 0xe4, 0x19, 0x85, 
+       0x9b, 0xc4, 0x6b, 0x3a, 0x12, 0x7, 0xca, 0x9a, 0x9e, 0x7c, 
+       0x52, 0x87, 0xf9, 0x8f, 0xe7, 0x80, 0x3f, 0x87, 0x7e, 0xf7, 
+       0x7b, 0x43, 0xd8, 0xe1, 0x45, 0xd3, 0xfa, 0x9d, 0xd2, 0x52, 
+       0xfe, 0x70, 0xbd, 0xfa, 0xf8, 0xcc, 0x19, 0x6a, 0x39, 0xa6, 
+       0xae, 0x90, 0x67, 0xdc, 0xb5, 0x39, 0x13, 0xf, 0xd5, 0x77, 
+       0x76, 0x7d, 0xed, 0xd6, 0x97, 0x5e, 0x7e, 0xe1, 0xf7, 0x37, 
+       0x5e, 0xe7, 0x9e, 0x3c, 0x7e, 0xe2, 0xdc, 0xda, 0x8c, 0xcc, 
+       0xd4, 0xbc, 0xd2, 0x12, 0x9d, 0x8f, 0x7, 0x83, 0xab, 0x76, 
+       0x34, 0x28, 0x98, 0xb7, 0xa2, 0xaa, 0x55, 0x38, 0xa, 0x46, 
+       0x79, 0x66, 0xcc, 0x84, 0xa0, 0xc2, 0x5c, 0xc6, 0x8f, 0x65, 
+       0x98, 0x13, 0x26, 0x6a, 0x17, 0x28, 0x54, 0x84, 0x1, 0xca, 
+       0x1d, 0xf6, 0x26, 0x70, 0x83, 0x8b, 0xd6, 0xde, 0xfc, 0x6e, 
+       0xe1, 0x13, 0x79, 0x44, 0x9e, 0x8, 0xf1, 0x3a, 0x12, 0x62, 
+       0x7c, 0xe0, 0x86, 0xd3, 0xb2, 0x77, 00, 0xdc, 0xc7, 0xf0, 
+       0x2e, 0x5b, 0x3f, 0xd1, 0xde, 0x54, 0x20, 0x64, 0x32, 0x33, 
+       0x60, 0xcb, 0xee, 0x6b, 0xdd, 0x11, 0x38, 0x13, 0x45, 0xc, 
+       0x6e, 0x7f, 0x82, 0x2c, 0x3d, 0x1d, 0x33, 0xa5, 0x73, 0x42, 
+       0xb0, 0x47, 0xe3, 0x63, 0xaf, 0x1, 00, 0x79, 0x3d, 0x2c, 
+       0xa2, 0xe0, 0x88, 0x13, 0xe1, 0x65, 0x7f, 0x9b, 0xf3, 0x95, 
+       0x5c, 0x16, 0x8, 0xe6, 0xfa, 0xa4, 0x67, 0x58, 0xa9, 0xf, 
+       0x7c, 0xc9, 0x9a, 0x97, 0xe4, 0x47, 0xc0, 0x70, 0x91, 0xc, 
+       0x98, 0xec, 0xe5, 0xa, 0x27, 0xac, 0x40, 0xbb, 0xea, 0x5f, 
+       0xff, 0xf5, 0x5f, 0xdb, 0x1f, 0x7d, 0xf4, 0xd1, 0x7f, 0xf7, 
+       0xa7, 0x40, 0xb3, 0x89, 0x8c, 0x26, 0xd3, 0xbd, 0x57, 0x5e, 
+       0x79, 0x65, 0x2, 0xca, 0x75, 0x17, 0x66, 0xff, 0xb2, 0x30, 
+       0xc7, 0x5d, 0x81, 0x59, 0x82, 0x62, 0x98, 0x6e, 0xe, 0x80, 
+       0x3a, 0x6, 0x8b, 0x32, 0x62, 0x50, 0xf6, 0x64, 0xcc, 0xb9, 
+       0x4e, 0x7, 0xd0, 0xd, 0x9c, 0xd0, 0x9a, 0x82, 0x45, 0x3d, 
+       0x76, 0xce, 0x71, 0x86, 0x22, 0x29, 0xf, 0x7d, 0x1, 0x35, 
+       0xe3, 0x91, 0x7, 0x2, 0x64, 0xfa, 0x12, 0x6e, 0x6d, 0x6d, 
+       0x43, 0x39, 0xab, 0xc9, 0x1f, 0x9c, 0x17, 0xef, 0xab, 0xf3, 
+       0x84, 0x84, 0x78, 0xae, 0x5d, 0x36, 0x79, 0x40, 0xc0, 0xe8, 
+       0xd1, 0xa9, 0xb6, 0xb8, 0xb8, 0x58, 0xff, 0x1c, 0x2d, 0x85, 
+       0xd1, 0xce, 0xb4, 0xc, 0x76, 0x71, 0x98, 0x26, 0x8e, 0x8a, 
+       0xd3, 0x7, 0x33, 0xb6, 0xe2, 0x84, 0xd1, 0xc6, 0xc6, 0x26, 
+       0xa3, 0xaa, 0xaa, 0x5a, 0x3, 0x94, 0xbc, 0x80, 0x5, 0x2, 
+       0x7e, 0x67, 0x2b, 0x39, 0xcd, 0x94, 0x2, 0x28, 0x2, 0x2d, 
+       0x40, 0xe7, 0x35, 0xcb, 0x42, 0x9f, 0x8e, 0xe5, 0xd6, 00, 
+       0xb7, 0x8, 0x3a, 0xb7, 0x6d, 0xbe, 0x88, 0xe5, 0x9f, 0x43, 
+       0x1, 0xb6, 0x95, 0x27, 0x3c, 0xc, 0x11, 0x3f, 0x5c, 0xaf, 
+       0xe6, 0x60, 0x35, 0x97, 0xf4, 0xc5, 0x31, 0xc7, 0x4d, 0x81, 
+       0x8f, 0xae, 0x5d, 0xba, 0x62, 0xad, 0x91, 0x99, 0x19, 0x97, 
+       0x93, 0x93, 0xe3, 0x2d, 0xf5, 0x7a, 0xd4, 0xe8, 0xd4, 0x34, 
+       0x9b, 0x1b, 0x8d, 0xc0, 0x28, 0x1c, 0x85, 0xec, 0xc2, 0xe2, 
+       0x14, 0x6f, 0x76, 0x96, 0x72, 0x9e, 0x28, 0x52, 0xde, 0x79, 
+       0xf3, 0x14, 0xce, 0xb0, 0xd2, 0x65, 0xb3, 0xa6, 0x3d, 0xdc, 
+       0x30, 0xba, 0x5c, 0x36, 0x9e, 0x28, 0xc3, 0x39, 0x74, 0x2, 
+       0x9b, 0x3c, 0xe4, 0x77, 0xd3, 0xe7, 0x77, 0x47, 0xa, 0x6a, 
+       0x6b, 0x39, 0x88, 0x9b, 0x83, 0x7, 0xf, 0x2e, 0x3, 0xdf, 
+       0x47, 0x43, 0x76, 0xd8, 0xdd, 0xe3, 0xb7, 0xea, 0xae, 0x2e, 
+       0x7c, 0x31, 0xcd, 0x91, 0xcd, 0xd0, 0xb5, 0xf7, 0x70, 0xc1, 
+       0x4d, 0x90, 0x9, 0xb0, 0x99, 0x46, 0x14, 0x18, 0x7d, 0x37, 
+       0x84, 0xdb, 0x4b, 0xad, 0x37, 0x1c, 0xa2, 0x60, 0x90, 0xe8, 
+       0x5b, 0x81, 0x46, 0xc6, 0x81, 0x30, 0x15, 0x3a, 0x29, 0xe4, 
+       0x8e, 0x2f, 0x3e, 0x1c, 0xe, 0x31, 0xf, 0x1, 0x91, 0xe4, 
+       0xc7, 0xbc, 0x28, 0xf8, 0xdc, 0x4, 0x82, 0xb1, 0x3, 0x13, 
+       0xcb, 0x3, 0xed, 0xc8, 0x37, 0x6, 0x3f, 0x45, 0xf4, 0x91, 
+       0xef, 0x7c, 0xe7, 0x3b, 0xee, 0x9f, 0xfc, 0xe4, 0x27, 0xff, 
+       0xe5, 0xcf, 0x4b, 0x5a, 0x4f, 0x17, 0x6, 0xe1, 0x3e, 0x8a, 
+       0x86, 0x6d, 0x1c, 0xe, 0x76, 0xa8, 0xc6, 0xce, 0xb7, 0x83, 
+       00, 0x74, 0x14, 0x34, 0x28, 0x92, 0x94, 0x1f, 0x75, 0x53, 
+       0x2d, 0x10, 0x80, 0x23, 0x68, 0x24, 0x16, 0x70, 0xda, 0x3, 
+       00, 0x1f, 0x8d, 0xb3, 0xbd, 0xfa, 0xf5, 0xc1, 0x59, 0xe, 
+       0xf9, 0x7e, 0x96, 0x41, 0xae, 0x5, 0xc8, 0xf4, 0x79, 0x9f, 
+       0x3e, 0x77, 0x3f, 0x95, 0x95, 0x95, 0x61, 0x4a, 0xb0, 0x97, 
+       0x8b, 0x2b, 0x14, 0x1a, 0x15, 0xbd, 0x4a, 0x8f, 0xcb, 0x25, 
+       0x2d, 0x53, 0x83, 0x91, 0x34, 0x82, 0x1, 0x35, 0xc3, 0x6f, 
+       0x6f, 0x68, 0x68, 0x84, 0xab, 0x37, 0xb, 0xb, 0x8f, 0x79, 
+       0x8f, 0x1d, 0x3b, 0x4e, 0x33, 0x90, 0x82, 0x6c, 0x4c, 0x40, 
+       0x3f, 0x18, 0xd, 0xac, 0x16, 0x6a, 0xe6, 0x6b, 0x5, 0x35, 
+       0x79, 0x22, 0xd7, 0x2e, 0xf4, 0xa5, 0x5b, 0xf8, 0xb, 0x21, 
+       0x7e, 0xfa, 0x4f, 0x9c, 0x78, 0xb2, 0xbe, 0xa4, 0x54, 0x2e, 
+       0xfb, 0xf9, 0x90, 0x17, 0x85, 0xdd, 0x75, 0xea, 0xaf, 0x7f, 
+       0xfd, 0xab, 0xc2, 0x6e, 0xbd, 0x7e, 0xcf, 0x78, 0xb1, 0x7, 
+       0x26, 0xfc, 0xbf, 0x7d, 0xb8, 0x59, 0xfd, 0xf2, 0xaa, 0x2b, 
+       0xf5, 0xb3, 0x71, 0x89, 0x9, 0x3f, 0x7b, 0xe1, 0x8b, 0xf, 
+       0x7f, 0xac, 0x39, 0x33, 0x73, 0x3a, 0x1a, 0x55, 0x7d, 0x98, 
+       0xe1, 0x26, 0x6c, 0x34, 0x29, 0x68, 0x6a, 0xf2, 0x8c, 0xb7, 
+       0xd9, 0xec, 0x7d, 0x6b, 0xd7, 0xea, 0xb3, 0xd9, 0x74, 0xf9, 
+       0xf0, 0x6b, 0x9b, 0x4, 0xa0, 0x1d, 0xe5, 0x97, 0xb2, 0xd, 
+       0xc8, 0x20, 0xc2, 0x1b, 0x4c, 0x17, 0x33, 0x35, 0xfa, 0xf8, 
+       0x69, 0x28, 0x80, 0x7e, 0x7d, 0x6f, 0xe6, 0x45, 0x39, 0x12, 
+       0x8a, 0x14, 0xe8, 0xc4, 0xd, 0xf8, 0x61, 0x62, 0xd, 0xc7, 
+       0xd, 0xd8, 0xb3, 0xf0, 0x17, 0xa4, 0x43, 0x25, 0x42, 0x70, 
+       0x8b, 0x65, 0x4c, 0xd3, 0x3c, 0x92, 0x7a, 0xd5, 0x2f, 0xe2, 
+       0x9d, 0xa1, 0x11, 0x5b, 0xd, 0xc4, 0xa4, 0xa3, 0x40, 0xd0, 
+       0x31, 0x63, 0x8c, 0x1b, 0x61, 0xe4, 0x28, 0x31, 0xf1, 0x5e, 
+       0xc, 0xa4, 0x85, 0x56, 0x49, 0x88, 0x74, 0x26, 0x12, 0x81, 
+       0xa6, 0x2f, 0x60, 0x63, 0xa5, 0xc8, 0x82, 0x15, 0x98, 0xbd, 
+       0x11, 0x7d, 0xd8, 0x60, 0xf9, 0x31, 0xf, 0x92, 0xe4, 0xc9, 
+       0x7c, 0xa8, 0xad, 0x9, 0x20, 0xb4, 0xcc, 0xfc, 0x20, 0x3, 
+       0x5b, 0xf3, 0xf8, 0x7d, 0x7a, 0xb9, 0x21, 0x76, 0x19, 0x45, 
+       0xbf, 0xf7, 0xde, 0x7b, 0x77, 0x7d, 0xeb, 0x5b, 0xdf, 0x32, 
+       0x7f, 0xf6, 0xb3, 0x9f, 0x9, 0xc0, 0xf9, 0x98, 0xcf, 0xa7, 
+       0xc3, 0x7c, 0x1f, 0x85, 0x53, 0x39, 0xb7, 0xc2, 0x74, 0xb, 
+       0x3b, 0xe0, 0x81, 0x6, 0xa0, 0x12, 0xc0, 0x1c, 0x8b, 0x86, 
+       0xa3, 0xe1, 0x9d, 0x77, 0xde, 0x99, 0x86, 0x4d, 0x12, 0x1a, 
+       0xe0, 0xd6, 0x32, 0x88, 0x70, 0x8, 0x90, 0xe9, 0xd3, 0xd1, 
+       0xdc, 0x2e, 0x83, 0x49, 0x8b, 0x95, 0x74, 0x9c, 0x8e, 0x51, 
+       0x68, 0x48, 0xcd, 0x45, 0x8b, 0x16, 0xda, 0xfc, 0xcb, 0x7a, 
+       0x47, 0x8c, 0x2f, 0x34, 0x3d, 0xc7, 0x61, 0x70, 0xa, 0xce, 
+       0x40, 0x5d, 0x6a, 0xd, 0x5f, 0x59, 0x59, 0xa5, 0xa0, 0x51, 
+       0x3c, 0xc8, 0xdf, 0x56, 0x54, 0x54, 0x4c, 0xf3, 0xdd, 0xa0, 
+       0x80, 0xe3, 0xbb, 0x35, 0x90, 0x58, 0x1e, 0x2b, 0x78, 0x3c, 
+       0xb0, 0xe, 0x84, 0x68, 0x8e, 0xef, 0xa8, 0xae, 0x92, 0xcb, 
+       0x80, 0xf, 0x60, 0x72, 0xb, 0xae, 0xba, 0xff, 0xfe, 0xfb, 
+       0xd9, 0x38, 0xa9, 0xc1, 0xba, 0x2a, 0x87, 0x91, 0xc6, 0x76, 
+       0x68, 0x71, 0x9a, 0xe7, 0x24, 0x7b, 0x5a, 0xfa, 0x2c, 0xbc, 
+       0x8f, 0xec, 0xa9, 0xd8, 0x94, 0xde, 0x32, 0x8a, 0x13, 0x6f, 
+       0xf5, 0x42, 0x13, 0x74, 0xb, 0xb5, 0xec, 0xb0, 0x4c, 0xf2, 
+       0x9c, 0x22, 0x4b, 0xa0, 0x91, 0xcf, 0x3e, 0xf1, 0xd5, 0xaf, 
+       0xd, 0xfb, 0x1f, 0xe5, 0x90, 0x8d, 0x1c, 0x1b, 0x58, 0xf2, 
+       0x8b, 0x8e, 0xdf, 0xcf, 0x7a, 0x92, 0xbc, 0x86, 0x9b, 0x38, 
+       0x78, 0x1e, 0x8d, 0x73, 0xe0, 0x65, 0x5a, 0x8c, 0xfd, 0x6e, 
+       0xd1, 0xde, 0xc4, 0x19, 0xb5, 0x1c, 0x65, 0x92, 0xc2, 0x1b, 
+       0x56, 0xce, 0xf0, 0x2c, 0x40, 0x7c, 0x29, 0x52, 0x62, 0x6, 
+       0x14, 0x28, 0xd6, 0x22, 0xdf, 0x8f, 0x82, 0xd6, 0x9a, 0x8b, 
+       0xbe, 0x5a, 0x2c, 0x87, 0xf5, 0x87, 0x43, 0x56, 0xb0, 0x59, 
+       0x81, 0x4d, 0x86, 0xa1, 0x62, 0xbc, 0xe8, 0xff, 0xea, 0x5, 
+       0x4, 0xc3, 0x49, 0x3b, 0xd4, 0x3b, 0xcc, 0x8f, 0xf9, 0xd0, 
+       0x9, 0x80, 0xe8, 0xb3, 0x21, 0x41, 0x45, 0x99, 0x38, 0x58, 
+       0x51, 0xff, 0xc6, 0x96, 0xbc, 0xcb, 0x7e, 0x28, 0x4, 0x2a, 
+       0x1a, 0x1b, 0x4c, 0x3e, 0x86, 0x33, 0xb3, 0xdd, 0xbf, 0xf8, 
+       0xc5, 0x2f, 0x7e, 0x8d, 0x67, 0x26, 00, 0x9d, 0x82, 0xd6, 
+       0x3c, 0x5, 0xcf, 0x7b, 0x21, 0xa0, 0xfd, 0x47, 0x89, 0xe4, 
+       0x65, 0xbf, 0x8f, 0xe7, 0x4d, 0x68, 0x9d, 0x33, 00, 0xee, 
+       0x72, 0x98, 0x5d, 0x75, 0xb8, 0xbd, 0x1a, 0x6b, 0xd1, 0xa3, 
+       0x98, 0x36, 0x85, 0x83, 0x65, 0x62, 0x19, 0x18, 0xa6, 0xa3, 
+       0x16, 0x45, 0x3c, 0x6c, 0x7c, 0x28, 0xa2, 0x6f, 0x62, 0xfd, 
+       0xbc, 0x79, 0xfb, 0xed, 0xb7, 0x19, 00, 0x3, 0x79, 0x3f, 
+       0x62, 0x80, 0xe, 0x2a, 0x66, 0xbf, 0x4b, 0xa, 0x6e, 0x6e, 
+       0x6e, 0xe, 0x9d, 0x9d, 0xd, 0xc, 0x46, 0x73, 0xbd, 0xbb, 
+       0x76, 0xed, 0xc6, 0x9a, 0xeb, 0x3, 0x10, 0x6a, 0x87, 0x1, 
+       0xcb, 0x46, 0xaf, 0xf2, 0x23, 0x90, 0x8, 0x28, 0x37, 0xe2, 
+       0xf4, 0xc1, 0x34, 0x16, 0xaa, 0x68, 0x6b, 0x57, 0xb5, 0x30, 
+       0xfd, 0x83, 0x89, 0x9b, 0x3a, 0xd0, 0xb8, 0xe9, 0x77, 0x83, 
+       0x9f, 0x5, 0x5f, 0xf3, 0x97, 0x33, 0x8f, 0x36, 0x36, 0x5, 
+       0xc0, 0x3d, 0xa1, 0xa3, 0xdd, 0x89, 0xc2, 0xb0, 0x55, 0xd5, 
+       0x51, 0x99, 0x37, 0x7e, 0x40, 0xd2, 0xc0, 0x52, 0x61, 0x93, 
+       0x3b, 0xf8, 0x38, 0xe3, 0x41, 0x9e, 0x92, 0xf8, 0x8c, 0xda, 
+       0x96, 0xa0, 0x63, 0x5d, 0x13, 0xe4, 0x67, 0xb, 0x70, 0xa6, 
+       0x1, 0x79, 0xd4, 0xcb, 0x9f, 0x51, 0x47, 0x5c, 0xfc, 0xa4, 
+       0xf3, 0x60, 0x3e, 0xe4, 0x1, 0xf3, 0x11, 0x62, 0xdc, 0x48, 
+       0x88, 0xf8, 0x41, 0xd9, 0x9d, 0xb0, 0xc2, 0x66, 0xfa, 0x97, 
+       0xa4, 0xf2, 0x23, 0x89, 0x31, 0x3a, 0xe2, 0x8d, 0x9, 0xe, 
+       0x79, 0x60, 0x2d, 0x52, 0x70, 0x8b, 0x60, 0x9, 0xb0, 0x75, 
+       0xc6, 0x68, 0xc9, 0xae, 0x47, 0x5f, 0x93, 0x26, 0xc4, 0xb0, 
+       0x88, 0x82, 0x2d, 0x8e, 0xcc, 0x11, 0x1, 0xc7, 0x4e, 0x2c, 
+       0xee, 0xad, 0xe5, 0x82, 0x95, 0x11, 0x13, 0x66, 0xa6, 0x6f, 
+       0x5, 0x37, 0xf3, 0xa2, 0xd6, 0xa6, 0xf0, 0x42, 0xb3, 0x7a, 
+       0xb1, 0xa8, 0x40, 0xe7, 0x19, 0xfc, 0x21, 0xec, 0x27, 0xe3, 
+       0x14, 0x4b, 0x27, 0xde, 0xbd, 0x7, 00, 0x77, 0x1, 0xe0, 
+       0x8f, 0x61, 0x90, 0xcf, 0x81, 0x6b, 0xdd, 0xd8, 0x21, 0x5d, 
+       0x36, 0x40, 0xd4, 0xac, 0xa7, 0x6b, 0xd7, 0x92, 0x8, 0x1b, 
+       00, 0x3c, 0x77, 0x43, 0x8, 0x7a, 0x31, 0xf, 0xbe, 0x81, 
+       0xe5, 0x80, 0x5b, 0x8d, 0x46, 0x43, 0x3, 0x9c, 0x42, 0x22, 
+       0xa0, 0x66, 0x59, 0x8, 0x6a, 0x94, 0xc7, 0x9c, 0x38, 0x71, 
+       0x82, 0x79, 0xdb, 0x6d, 0xb7, 0xda, 0x20, 0xb4, 0x23, 0xc6, 
+       0x3, 0x4b, 0xb1, 0x86, 0x1c, 0xe4, 0xf7, 0x73, 0xe7, 0x1b, 
+       0xf7, 0x3b, 0x3, 0xe4, 0xdc, 0x42, 0xe9, 0xcd, 0xcf, 0x3f, 
+       0x8c, 0x13, 0x5c, 0x63, 0xf8, 0xc3, 0x4, 0xfa, 0x17, 0x42, 
+       0x71, 0x26, 0xb4, 0x72, 0xfb, 0x17, 0x96, 0x70, 0xae, 0xf9, 
+       0xf7, 0x96, 0x7d, 0xd9, 0xd6, 0x8c, 0x3e, 0xf3, 0x99, 0xcf, 
+       0xe8, 0x4b, 0x82, 0x9c, 0x3b, 0xb9, 0xce, 0x44, 0x6f, 0x14, 
+       0x17, 0xab, 0xfb, 0xe6, 0xcc, 0xd6, 0xbf, 0xa4, 0xe9, 0xe6, 
+       0x79, 0xe8, 0x98, 0x39, 0xc1, 0xc8, 0x64, 0xe0, 0x35, 0xc8, 
+       0x8, 0x7, 0xa4, 0x4c, 0x6c, 0xbf, 0xd5, 0xb, 0x4d, 0xf8, 
+       0x80, 0xc0, 0x22, 0xe0, 0xc8, 0x57, 0x2, 0x5a, 00, 0xce, 
+       0x7b, 0x67, 0x4b, 0x94, 0x47, 0xe6, 0xc9, 0x91, 0xf3, 0x91, 
+       0xd6, 0xde, 0xc4, 0x11, 0xe6, 0xd3, 0x2f, 0x47, 0xda, 0x5c, 
+       0xb1, 0x46, 0x4c, 0x11, 0xe0, 0x1c, 0x39, 0xa7, 0x9c, 0xb1, 
+       0xf0, 0x94, 0xaf, 0x90, 0x32, 0x86, 0xfb, 0xfd, 0x88, 0x2f, 
+       0xc, 0x89, 0xc0, 0x1c, 0x1, 0xb6, 0x64, 0x22, 00, 0xe7, 
+       0xbe, 0xed, 0xeb, 0xd1, 0x37, 0x8d, 0xb4, 0xa1, 0xe8, 0x97, 
+       0xaf, 00, 0x4e, 0x80, 0x4d, 0x2d, 0x86, 0x41, 0x28, 0x9e, 
+       0xaf, 0xa5, 0xfb, 0x96, 0xfd, 0x22, 0xf, 0xf3, 0x82, 0x79, 
+       0x90, 0x24, 0x2f, 0xe6, 0xc1, 0xca, 0xa7, 0x63, 0x45, 0x71, 
+       0x10, 0x9, 0x82, 0x1a, 0x96, 0x27, 0xec, 0x17, 0xc1, 0x44, 
+       0xe7, 0x7e, 0xf0, 0xfb, 0xbf, 0xf1, 0x8d, 0x6f, 0x3c, 0x80, 
+       0x23, 0x97, 0x78, 0x58, 0x43, 0x27, 0xfa, 0xd9, 0xb1, 0x30, 
+       0x99, 0xe3, 0x9, 0x70, 0xa6, 0x4f, 0x80, 0xa3, 0xd2, 0xfb, 
+       0x1d, 0xd9, 0x84, 0x86, 0x20, 0xe, 0xf9, 0x75, 0xe3, 0x9b, 
+       0x2a, 0x11, 0xa5, 0xf5, 0x49, 0xac, 0x82, 0xc3, 0x8e, 0xa0, 
+       0xf, 0xd1, 0x9f, 0x77, 0x51, 0x43, 0x4b, 0x23, 0x43, 0x73, 
+       0xf, 0xda, 0x11, 0x42, 0x6a, 0xf7, 0xde, 0x73, 0xcf, 0x27, 
+       0x15, 0xe6, 0xc8, 0x9, 0x6c, 0x26, 0x7b, 0x51, 0x10, 0xc5, 
+       0x80, 0x9a, 0xeb, 0x9e, 0x7b, 0xee, 0xb1, 0xad, 0x5d, 0xbb, 
+       0x6, 0xd6, 0x86, 0xc7, 0xdc, 0xb7, 0x6f, 0xbf, 0x49, 0xc0, 
+       0xd3, 0x74, 0xc1, 0x49, 0x15, 0xba, 0x9c, 0xfc, 0x21, 0x1, 
+       0xce, 0x35, 0x8f, 0x4, 0xad, 0xc6, 0x8f, 0xa, 0xf0, 0x27, 
+       0x72, 0x49, 0x51, 0x38, 0xcf, 0xdc, 0x1e, 0x62, 0x97, 0x21, 
+       0xeb, 0xd, 0x5d, 0x43, 0x3, 0xc0, 0xd0, 0xd, 0x35, 0x1b, 
+       0x48, 0xf0, 0x5c, 0xf3, 0x95, 0xf5, 0xcc, 0xc6, 0x94, 0xf5, 
+       0x2e, 0x32, 0x70, 0x36, 0xe5, 0x62, 0x3, 0x1, 0xed, 0x6a, 
+       0xa2, 0xce, 0xbc, 0x22, 0x3f, 0x22, 0xb7, 0x22, 0x5b, 0x92, 
+       0x5f, 0xa4, 0xf9, 00, 0x47, 0xf8, 0xbc, 0x51, 0x2b, 0xf1, 
+       0x1e, 0x99, 0x47, 0x47, 0x80, 0x6b, 0x25, 0xa, 0x9f, 0xb2, 
+       0x29, 0xe, 0xc1, 0xc1, 0x29, 0xac, 0x20, 0x87, 0x79, 0x8d, 
+       0x1c, 0x96, 0xc4, 0x75, 0x86, 0x10, 0x74, 0xce, 0x6d, 0x27, 
+       0x8c, 0x94, 0x49, 0x4e, 0xa6, 0x90, 0x51, 0x64, 0x1a, 0x97, 
+       0xfe, 0x71, 0x84, 0x32, 0x4c, 0x59, 0x22, 0xbe, 0x6d, 0x65, 
+       0xbc, 0xe4, 0xc1, 0x8a, 0xe7, 0x1c, 0x3a, 0xb5, 0x2e, 0x6, 
+       0xc4, 0xfc, 0x6d, 0x58, 0xf8, 0xa4, 0x45, 0x83, 0xa3, 0x12, 
+       0x1e, 0xc4, 0x71, 0xbb, 0x9f, 0xc1, 0x34, 0xd7, 0x49, 0x58, 
+       0x18, 0x1d, 0x58, 0x93, 0x3e, 0x17, 0x65, 0xe, 0x79, 0x64, 
+       0x13, 0xf2, 0xb2, 0x41, 0xe8, 0xc6, 0x3, 0xd8, 0xad, 0xf0, 
+       0x8f, 0x22, 0xf5, 0x76, 0xb8, 0x56, 0xfc, 0x36, 0xd9, 0x1b, 
+       0x78, 0xef, 0x3, 0xec, 0x86, 0xea, 0x43, 0x3a, 0x4, 0x35, 
+       0xb6, 0x29, 0xd6, 0x99, 0x18, 0x51, 0xf7, 0xde, 0x71, 0xc7, 
+       0x1d, 0x17, 0x5c, 0x5b, 0x87, 0xe7, 0x82, 0xef, 0x9, 0xcc, 
+       0x72, 0xe3, 0xbe, 0xfb, 0x3e, 0x8d, 0x3, 0x27, 0xe7, 0x63, 
+       0x20, 0xa8, 0xd9, 0x2c, 0xc5, 0x9a, 0x71, 0x4c, 0x4, 0xeb, 
+       0x87, 0x15, 0xb0, 0xba, 0x4e, 0x60, 0xf0, 0x6f, 0x24, 0x68, 
+       0x5d, 0x49, 0x89, 0xaa, 0xf2, 0xff, 0xa2, 0xa7, 0xab, 0xa6, 
+       0x5a, 0x75, 0xee, 0xdc, 0x39, 0x20, 0x59, 0x36, 0x3a, 0xac, 
+       0x3f, 0xd4, 0x4f, 0xbf, 0x53, 0x54, 0x28, 0x47, 0xac, 0x6b, 
+       0x1, 0x1b, 0xfd, 0x91, 0x20, 0xc, 0x7e, 0xd9, 0xf8, 0xe3, 
+       0xb, 0x32, 0x56, 0x23, 0xd, 0x8, 0xd3, 0x97, 0x3c, 0x86, 
+       0xd3, 0x90, 0x10, 0x47, 0x50, 0xe, 0x71, 0x18, 0x3f, 0xc8, 
+       0x43, 0x39, 0x5, 0xdc, 0x4, 0x38, 0x95, 0x29, 0x9d, 0x56, 
+       0xb2, 0x67, 0x14, 0x54, 0x44, 0x8c, 0x4, 0x38, 0x3a, 0x51, 
+       0xff, 0x3b, 0x1, 0xad, 0xd, 0x93, 0xfc, 0x5a, 0xb6, 0x36, 
+       0xb8, 0x3f, 0x2c, 0x22, 0x3, 0x82, 0x41, 0xc7, 0xca, 0x80, 
+       0x26, 0xa4, 0x26, 0xc5, 0x59, 0x79, 0xc3, 0x1b, 0x7d, 0xf, 
+       0x2e, 0x8c, 0xe4, 0x23, 0x79, 0x31, 0xf, 0x56, 0x8, 0x2b, 
+       0x7, 0x80, 0xe3, 0xf6, 0x51, 0xf6, 0x6b, 0x83, 0x5f, 0xb, 
+       0x79, 0xcd, 0xc5, 0x28, 0x30, 0xd1, 0xa3, 0x30, 0xb0, 0xf4, 
+       0x4f, 0x98, 0x76, 0x4a, 0x42, 0x59, 0x1b, 0x30, 0x75, 0x96, 
+       0x89, 0xed, 0x8a, 0x73, 0x39, 0x5a, 0x8e, 0xca, 0xd5, 0x6a, 
+       0x86, 0x1a, 0x1c, 0xc0, 0x8f, 0x85, 0x86, 0x5e, 0x82, 0xfe, 
+       0x60, 0x3b, 0xdc, 0x6e, 0xfc, 0xac, 0xc, 0x17, 0x29, 0x70, 
+       0x65, 0x7, 0xf, 0x7e, 0x68, 0x85, 0x59, 0xfa, 0x26, 0xd6, 
+       0x2d, 0xef, 0xda, 0xbd, 0x7b, 0x8f, 0x89, 0xb1, 0xb, 0xcf, 
+       0xfd, 0xf7, 0xdf, 0x87, 0x7e, 0x75, 0xfa, 0xb0, 0xf9, 0x19, 
+       0xb2, 0xc0, 0xe7, 0xf0, 0x26, 0xbe, 0x51, 0xf, 0x6a, 0xa1, 
+       0xeb, 0x60, 0x74, 0x67, 0x66, 0x79, 0x5b, 0xb1, 0xc2, 0x8c, 
+       0x34, 0x1e, 0xf3, 0xce, 0x53, 0x60, 0xba, 0x8e, 0x4, 0x91, 
+       0x99, 0x59, 0x7e, 0xeb, 0xc5, 0x91, 0x3e, 0x46, 0xc5, 0x5f, 
+       0x76, 0x59, 0xc8, 0x64, 0x59, 0x7f, 0x1c, 0x71, 0x86, 0x25, 
+       0x34, 0xe0, 0x98, 0x62, 0x1, 0x9f, 0xd4, 0x7f, 0xc8, 0x4, 
+       0x22, 0xb8, 0x49, 0x19, 0xa0, 0x7c, 0xa2, 0xc1, 0xd6, 0x8a, 
+       0x88, 0xe9, 0x53, 0xa6, 0xa4, 0x21, 0x11, 0x80, 0x47, 0x90, 
+       0x64, 0x20, 0x2a, 0xf1, 0x4, 0xcb, 0x80, 0xda, 0x5b, 0x6, 
+       0xd5, 0x44, 0x73, 0x53, 0x2e, 0x44, 0xb9, 0x6, 0xe2, 0x87, 
+       0xb, 0xf0, 0xa5, 0x33, 0x92, 0xa5, 0x95, 0x60, 0xc2, 0xcc, 
+       0x80, 0x8e, 0xef, 0xf2, 0x2c, 0x66, 0xfc, 0x70, 0xe2, 0xa4, 
+       0x61, 0xf5, 0xb7, 0xc9, 0x68, 0x92, 0x30, 0x5c, 0x98, 0x43, 
+       0x46, 0xc1, 0xc4, 0x32, 0x91, 0x6e, 0x24, 0x8d, 0x8f, 0x4e, 
+       0x2b, 0xdc, 0x3f, 0xe6, 0x11, 0x9c, 0xf, 0x5b, 0x75, 00, 
+       0x9b, 0x47, 0xf1, 0x18, 0x3c, 0x5c, 0x31, 0xdc, 0xbb, 0xa1, 
+       0xee, 0xe3, 0xbb, 0x35, 0xc0, 0x91, 0xe6, 0x67, 0xb1, 0xf0, 
+       0xff, 0x45, 0x98, 0xf5, 0x35, 0x48, 0x2f, 0xb, 0xe9, 0x65, 
+       0x43, 0xc8, 0xea, 0xd0, 0x28, 0x75, 0x1, 0xd8, 0x49, 0xe8, 
+       0x37, 0xa7, 0x3, 0xd4, 0xcd, 0x70, 0x65, 00, 0xf6, 0x73, 
+       0x48, 0xcb, 0x3a, 0xd2, 0x49, 0x6, 0x70, 0x2d, 0xfa, 0x8b, 
+       0x5f, 0xf9, 0xca, 0x57, 0x93, 00, 0x94, 0x59, 0x58, 0x5, 
+       0xc5, 0x9f, 0xeb, 0xd, 0x95, 0xe5, 0x45, 0x7d, 0x8f, 0xd3, 
+       0x70, 0xe, 0xaf, 0xc7, 0x93, 0xd4, 0xcd, 0x29, 0x5a, 0x65, 
+       0x63, 0x9f, 0x9b, 0xb, 0x51, 0x46, 0x82, 0xb0, 0x14, 0x47, 
+       0x35, 0x62, 0x8d, 0x7a, 0x1a, 0x1a, 0x7a, 0x77, 0x43, 0x3d, 
+       0x56, 0xbf, 0xb5, 0x29, 0x98, 0x35, 0x21, 0x93, 0x46, 0x3d, 
+       0xf2, 0x7, 0x21, 0x39, 0xb8, 0xa6, 0x7, 0xb8, 0xd8, 0xf8, 
+       0xd0, 0x8c, 0x66, 0x1f, 0x9c, 0xda, 0x9d, 0x3e, 0xe5, 0x60, 
+       0x24, 0x88, 0xf2, 0x49, 0xc5, 0x80, 0x2e, 0x80, 0x8d, 0x32, 
+       0x4b, 0x79, 0x62, 0x5e, 0x74, 0x22, 0x6b, 0xcc, 0x87, 0x79, 
+       0x46, 0x42, 0x50, 0x1a, 0x8e, 0xe3, 0xc7, 0x8f, 0xaf, 0xc2, 
+       0x3b, 0x7f, 0x81, 0xb3, 0x6a, 0x6f, 0x62, 0x8e, 0x89, 0x51, 
+       0x56, 0xe9, 0x5b, 0x65, 0x9, 0x97, 0xfd, 0x29, 0x92, 0x5c, 
+       0xad, 0x89, 0xea, 0x96, 0x4, 0xd3, 0x2, 0x13, 0x51, 0xf0, 
+       0x54, 0xb4, 0x32, 0xfd, 0x53, 0x1d, 0xe2, 0x15, 0x19, 0x20, 
+       0x4c, 0x10, 0x9f, 00, 0xa7, 0x89, 0x4a, 0x61, 0xe1, 0x94, 
+       0xc3, 0x48, 0x90, 0xe4, 0x23, 0x79, 0xb0, 0x22, 0xa8, 0xb1, 
+       0x59, 0x19, 0xf0, 0x31, 0xad, 0xb4, 0x68, 0x58, 0x2b, 0xdf, 
+       0xd8, 0x17, 0xbe, 0x12, 0x3, 0x62, 0xe8, 0x3a, 0xdc, 0x5, 
+       0xc1, 0xa9, 0xc0, 0x34, 0xc6, 0x11, 00, 0xfd, 0x14, 0x7e, 
+       0x23, 0x2b, 0xe, 0xc7, 0x36, 0x8d, 0x61, 0x3f, 0x14, 0xa0, 
+       0x3f, 0x9, 0x1, 0x78, 0x15, 0x4b, 0x50, 0x7f, 0x8c, 0x5f, 
+       0xbf, 0x68, 0xc0, 0xf7, 0x70, 0xfe, 0x92, 0x8, 0xa0, 0x69, 
+       0x4e, 0xd, 0xae, 0xdd, 0x7f, 0xfe, 0xe7, 0x2f, 0x1f, 0x7f, 
+       0xe3, 0x8d, 0xd7, 0xff, 0xb2, 0x6e, 0xdd, 0x5b, 0x1e, 0x2, 
+       0xfc, 0xef, 0x89, 0x60, 0xad, 0xa8, 0x17, 0x5e, 0x78, 0xc1, 
+       0xb5, 0xf7, 0x50, 0xfe, 0xce, 0xfa, 0x8e, 0xce, 0x4a, 0x96, 
+       0x9d, 0x7d, 0xee, 0x7f, 0x5a, 0x30, 0x7f, 0x44, 0x3e, 0xe3, 
+       0x1e, 0x1c, 0xa6, 0x40, 0x60, 0x93, 0xa2, 0x20, 0x6b, 0x76, 
+       0x6c, 0x16, 0x9, 0x47, 0x1c, 0xe0, 0x62, 0x7d, 0x2, 0x60, 
+       0xdc, 0xa6, 0xa9, 0xfb, 0xdd, 0xac, 0x67, 0x3a, 0x31, 0x99, 
+       0x29, 0x7, 0x94, 0xb3, 0xb3, 0x25, 0xca, 0x27, 0xfb, 0xf9, 
+       0x1c, 0x33, 0x11, 0xcd, 0x2d, 0x79, 0xd0, 0x67, 0x3e, 0xc3, 
+       0x21, 0xe2, 0x9, 0xb8, 0x4a, 0x46, 0xfa, 0xd9, 0x78, 0x9f, 
+       0x8a, 0x53, 0xfa, 0xdd, 0xa2, 0x58, 0x35, 0x6e, 0x2d, 0x4a, 
+       0x37, 0x64, 0x36, 0x4, 0xe9, 0x50, 0x88, 0x2d, 0x5, 0x9d, 
+       0x24, 0xae, 0x35, 0x37, 0xfa, 0x5, 0xd7, 0xe6, 0xe6, 0xe6, 
+       0x9e, 0xd5, 0xf4, 0x82, 00, 0x8f, 0xcc, 0x10, 0xcd, 0xd, 
+       0xdf, 0xb, 0xf3, 0x8a, 0xe9, 0x46, 0xa4, 0x4d, 0xc3, 0x7d, 
+       0x48, 0x70, 0x1e, 0xd2, 0xca, 0x12, 0x44, 0xec, 0x43, 0xc3, 
+       0x24, 0xf, 0xf7, 0xea, 0x19, 0xef, 0x13, 0xe0, 0x30, 0xd1, 
+       0xc9, 0xc7, 0x7, 0xd1, 0xda, 0xfe, 0x5f, 0x4c, 0x97, 0xbd, 
+       0x9c, 0x93, 0x93, 0x93, 0x82, 0xa9, 0xaf, 0x18, 0x54, 0x3a, 
+       0xa6, 0xcd, 0x2b, 0x8a, 0xb7, 0x6d, 0xdb, 0x76, 0xa, 0xcf, 
+       0x59, 0x21, 0xe4, 0x9b, 0x95, 0xac, 0xdf, 0x67, 0x62, 0xbe, 
+       0x76, 0x1f, 0x2a, 0x95, 0x12, 0xf1, 0x69, 0x2c, 0x74, 0xb1, 
+       0x67, 0x64, 0xc, 0xaf, 0xd1, 0xb4, 0x66, 0x70, 0xae, 0xc3, 
+       0x2, 0x6c, 0x74, 0x2b, 0x76, 0xfc, 0xe1, 0xf, 0x8f, 0xad, 
+       0xeb, 0x9e, 0x3b, 0x77, 0xe2, 0xe7, 0xe7, 0xcf, 0x7b, 0x88, 
+       0xf9, 0x66, 0x63, 0x47, 0x16, 0x7f, 0x93, 0xab, 0xde, 0xbf, 
+       0x76, 0x7c, 0x38, 0x65, 0x49, 0xc0, 0xa0, 0x5c, 0xe0, 0x7c, 
+       0x71, 0x24, 0x10, 0x87, 0x6d, 0x9a, 0x36, 0xcb, 0x48, 0x79, 
+       0xa8, 0x34, 0x59, 0x9f, 0xb4, 0xac, 0x38, 0xb5, 0x49, 0xcd, 
+       0x2d, 0xce, 0xaa, 0xc1, 0x19, 0x3e, 0x5b, 0xa2, 0x78, 0xa2, 
+       0x61, 0xe7, 0xef, 0x93, 0xeb, 0x25, 0xa9, 0x6c, 0x58, 0x28, 
+       0x5b, 0x92, 0x1f, 0xe5, 0x8e, 0x72, 0xcd, 0x78, 0x91, 0x8a, 
+       0x32, 0x64, 0x88, 0x56, 0xe5, 0x4a, 0x74, 0xf9, 0x4a, 0x50, 
+       0x4e, 0x6a, 0x6f, 0xca, 0x18, 0xb, 0x4d, 0x39, 0x12, 0x59, 
+       0x1a, 0x74, 00, 0xe1, 0x8c, 0xe0, 0x46, 0xa1, 0x44, 00, 
+       0xad, 0x89, 0xf2, 0x3d, 0x7, 0x46, 0xf5, 0x6e, 0x82, 0x69, 
+       0xe2, 0x9b, 0x54, 0xc4, 0x8d, 0x48, 0x48, 0x5a, 0x35, 0x61, 
+       0x80, 0xb4, 0x78, 0x6c, 0x61, 0x61, 0xd6, 0xca, 0x7c, 0x6e, 
+       0x24, 0x49, 0x86, 0x8c, 0x2b, 0xc0, 0xa6, 0x4f, 0xc6, 0x5b, 
+       0x1d, 0xee, 0x99, 0x91, 0x9a, 0xe3, 0xa1, 0x32, 0xa1, 0x95, 
+       0xb1, 0x66, 0xcd, 0x1a, 0x4e, 0x8b, 0x7d, 0x3, 0xe9, 0x7b, 
+       0x7e, 0xf3, 0x9b, 0xdf, 0xbc, 0x8c, 0x78, 0xd6, 0x13, 0x5d, 
+       0x58, 0x29, 0x56, 0x55, 0x41, 0x9e, 0xa, 0x5f, 0xb5, 0x69, 
+       0x8e, 0x6b, 0xdd, 0xcc, 0xaf, 0x5b, 0xb7, 0x6e, 0x1f, 0xd2, 
+       0x21, 0xaf, 0xef, 0xc5, 0x4f, 0xca, 0xa2, 0xef, 0x35, 0x6, 
+       0xc1, 0x8b, 0x93, 0x4, 0xd8, 0xbb, 0x76, 0xed, 0xd9, 0xf9, 
+       0xf8, 0xe3, 0x8f, 0xad, 0x47, 0x29, 0xbb, 0xb1, 0xc3, 0x2b, 
+       0xd0, 0x45, 0x9b, 0x37, 0x26, 0x5d, 0xad, 0xc0, 0x32, 0xd8, 
+       0x57, 0x8f, 0x1f, 0xf, 0xf9, 0x1, 0x3c, 0xad, 0x54, 0x4e, 
+       0x2c, 0xd, 0x19, 0x1, 0x37, 0xe7, 0x62, 0x50, 0x75, 0x65, 
+       0x76, 0x56, 0xe0, 0xb1, 0x17, 0xbf, 0xd7, 0x3d, 0x14, 0xe2, 
+       0xd9, 0x7a, 0x5b, 0xb6, 0x6c, 0xe1, 0x29, 0xa6, 0xda, 0x2a, 
+       0x23, 0xf0, 0x8, 0x68, 0x2, 0xf, 0xfc, 0xd, 0x58, 0x8c, 
+       0x91, 0x9a, 0xcc, 0xc1, 0x79, 0x63, 0x36, 0xc7, 0xc6, 0x19, 
+       0x1d, 00, 0x51, 0xcb, 0x96, 0x28, 0x29, 0xca, 0x19, 0xd3, 
+       0xa6, 0x63, 0x7e, 0xa7, 0x61, 0x14, 0x9c, 0x42, 0xe8, 0x6b, 
+       0x98, 0xe6, 0x51, 0xd8, 0x59, 0xb8, 0x1a, 0x4f, 0x9f, 0x87, 
+       0x23, 0xde, 0x5d, 0x9b, 0xd, 0xc5, 00, 00, 0x20, 00, 
+       0x49, 0x44, 0x41, 0x54, 0x44, 0x7b, 0x33, 0xec, 0x82, 0x23, 
+       0x51, 0x4e, 0xac, 0x72, 0xa5, 0x6f, 0xca, 0x3f, 0x3e, 0x1c, 
+       0xa, 0x31, 0x1e, 0x85, 0x91, 0x3e, 0x5, 0xd5, 0x1, 0x93, 
+       0x21, 0x1d, 0x1a, 0x36, 0x13, 0xa6, 0x39, 0x2e, 0x23, 0x27, 
+       0x2b, 0x83, 0x19, 0x16, 0xad, 0xcd, 0x75, 0xe4, 0x5c, 0x7c, 
+       0x30, 0xd2, 0x3, 0x69, 0x4c, 0x9f, 0xf9, 0x90, 0xe9, 0x6c, 
+       0x40, 0xb0, 0x7d, 0x4f, 0xcf, 0xcd, 0x9e, 0x8d, 0xd6, 0xb6, 
+       0x7e, 0x35, 0x57, 0x8b, 0x51, 0x83, 0x63, 0x8d, 0xf0, 0xbf, 
+       0x7c, 0xe1, 0xb, 0x5f, 0xb8, 0x15, 0xcf, 0x38, 0xb2, 0x64, 
+       0x1d, 0x10, 0x21, 0xef, 0xd8, 0xd2, 0x72, 0xa5, 0x11, 0x3b, 
+       0xa3, 0x9c, 0x39, 0xa2, 0x79, 0xce, 0x46, 0x80, 0x12, 0x4b, 
+       0x47, 0x13, 0xbd, 0xfd, 0xad, 0xb7, 0xde, 0xda, 0xfb, 0xf6, 
+       0xdb, 0x6f, 0x3d, 0xfd, 0xc6, 0x1b, 0x6f, 0x78, 0x82, 0xf, 
+       0xd3, 0xc7, 0xf3, 0x8b, 0x82, 0x4e, 0x3, 0x7b, 0xf7, 0x2e, 
+       0x3f, 0xb0, 0xf9, 0x1d, 0x9d, 0x3f, 0xdd, 0xbe, 0x7d, 0xc3, 
+       0x2b, 0x27, 0x8e, 0xff, 0x50, 0xa, 0xf9, 0xc5, 0x45, 0xb, 
+       0x15, 0xcc, 0x3b, 0xb9, 0x8c, 0xc8, 0xe7, 0x36, 0xce, 0xef, 
+       0xaf, 0xe2, 0xb8, 0x92, 0x8f, 0x46, 0xdd, 0x72, 0xab, 0x4a, 
+       0x5c, 0x7b, 0x85, 0x5c, 0xe, 0xea, 0x63, 0x70, 0x52, 0x6f, 
+       0xe1, 0xa5, 0x3c, 0x49, 0x17, 0xcc, 0xda, 0xb0, 0x13, 0x84, 
+       0x94, 0x87, 0xb3, 0x25, 0xca, 0x29, 0x1b, 0xe, 0x99, 0xce, 
+       0x64, 0x1e, 0x92, 0xb6, 0xf8, 0xc3, 0xc9, 0x83, 0x7b, 0x3, 
+       0xd0, 0x20, 0xa4, 0x41, 0x71, 0xb0, 0x6f, 0x2a, 0x9a, 0x9b, 
+       0xc0, 0x26, 0xfe, 0x44, 0x83, 0x33, 0x8e, 0x28, 0x89, 0x1, 
+       0xd9, 0x50, 0xe0, 0x86, 0x42, 0x2, 0x6c, 0x49, 0xdc, 0x81, 
+       0x7e, 0xc1, 0x2, 0xc, 0xdb, 0xbb, 0x6, 0x49, 0xfb, 0x8c, 
+       0xe9, 0xa, 0x73, 0x9, 0x3c, 0x32, 0x82, 0x8c, 0xc1, 0x3d, 
+       0x9e, 0x43, 0x7e, 0xc6, 0x77, 0x87, 0x12, 0x81, 0xe9, 0x8b, 
+       0x63, 0x1e, 0x4c, 0x9f, 0x3e, 0x2b, 0x1b, 0xf7, 0x4d, 0x2e, 
+       0xb1, 0x1c, 0x4a, 0x3a, 0x43, 0x8d, 0xc3, 0x65, 0x94, 0xd4, 
+       0xe0, 00, 0xf8, 0x77, 0x1, 0xf0, 0x9b, 0xf0, 0x5e, 0x28, 
+       0x80, 0x33, 0x39, 0x82, 0x9c, 0x1b, 0x4f, 0xd8, 0xff, 0xa6, 
+       0x63, 0xff, 0x9b, 0xe0, 0xe, 0xf8, 00, 0x36, 0x1, 0xfe, 
+       0xdc, 0xeb, 0xaf, 0xbf, 0xe1, 0xa1, 0x56, 0xb8, 0x98, 0x48, 
+       0x80, 0xbd, 0x73, 0xe7, 0xae, 0x3d, 0x8f, 0x3f, 0xfe, 0x87, 
+       0xd, 0x28, 0x1b, 0x1b, 0x2b, 0x19, 0x4b, 0xe8, 0x8c, 0xb6, 
+       0x39, 0x2, 0xea, 0x95, 0x7, 0x32, 0xf0, 0x77, 0xb0, 0x79, 
+       0xcc, 0x51, 0x24, 0xb4, 0x4, 0x32, 0xc0, 0x2d, 0x9c, 0x38, 
+       0x20, 0xf1, 0xf4, 0x6b, 0x11, 0xe, 0x4c, 0xd1, 0x2a, 0xe3, 
+       0xd4, 0x18, 0xeb, 0x5b, 0x9c, 0x15, 0x7c, 0x94, 0xd, 0xca, 
+       0xdd, 0xd9, 0x12, 0x15, 0x1c, 0x16, 0x29, 0x79, 0x99, 0xb6, 
+       0xc8, 0x98, 0xc8, 0xb4, 0xe4, 0x31, 0x9c, 0x7c, 0xa0, 0x40, 
+       0xdd, 0x98, 0xe, 0x9e, 0x81, 0xf2, 0x59, 0xfb, 0xdd, 0xc4, 
+       0xa0, 0x28, 0xd9, 0x41, 0xe5, 0x77, 0x28, 0xe0, 0x96, 0x4, 
+       0x18, 0x97, 0x8e, 0x89, 0x3b, 0xd0, 0xa7, 0x59, 0x80, 0xd6, 
+       0x65, 0x58, 0xf3, 0x54, 0xfc, 0x60, 0x21, 0x7e, 0x34, 0x9d, 
+       0x30, 0xe3, 0x5c, 0x98, 0xe4, 0x4c, 0x9f, 0x79, 0x92, 0xf1, 
+       0xd4, 0xda, 0xfc, 0xdd, 0x28, 0xb6, 0xb8, 0x6c, 0xdd, 0x47, 
+       0x9a, 0x30, 0x35, 0xa6, 0x70, 0xe8, 0xbc, 0x3, 0xa7, 0xbe, 
+       0x7e, 0xef, 0xf3, 0x9f, 0xff, 0xfc, 0x8d, 0x48, 0x9f, 00, 
+       0xe7, 0x46, 0x6e, 0x4a, 0xa9, 0x54, 0xc, 0x82, 0xda, 0x9c, 
+       0xa2, 0x16, 0x17, 0xd, 0x4e, 0xad, 0x4d, 0xed, 0x27, 0x83, 
+       0x6c, 0xad, 00, 0xf8, 0xce, 0xf5, 0xeb, 0xdf, 0x7e, 0xfe, 
+       0xb5, 0xd7, 0x5e, 0xf7, 0x4, 0xff, 0xd6, 0x15, 0xe2, 0x5d, 
+       0x10, 0x12, 0x60, 0xef, 0xd8, 0xb1, 0x73, 0xdf, 0x13, 0x4f, 
+       0x3c, 0xfe, 0x3e, 0xa, 0x21, 0x83, 0x83, 0x62, 0x79, 0xb4, 
+       0xfd, 0x70, 0xeb, 0xd6, 0x4d, 0xbf, 0xda, 0xbb, 0xef, 0x2a, 
+       0xec, 0xea, 0x3a, 0xc9, 0x42, 0xd2, 0x3c, 0xff, 0xc9, 0x9a, 
+       0xd5, 0xe6, 0x95, 0x38, 0xb3, 0x2c, 0x39, 0xcc, 0x8e, 0x38, 
+       0xf9, 0x98, 0x58, 0x34, 0x6, 0x57, 0xe5, 0x4c, 0xd4, 0x1a, 
+       0x9b, 0x26, 0x3d, 0x9, 0x76, 0xb5, 0x1a, 0xf3, 0xf5, 0x6f, 
+       0xa8, 0xf8, 0x25, 0x4b, 0x24, 0xda, 0x90, 0x7c, 0xd6, 0x2f, 
+       0xfb, 0xde, 0x1c, 0xa0, 0x25, 0xb8, 0x29, 0x63, 0x2, 0x40, 
+       0xfa, 0x94, 0x9, 0xab, 0x2c, 0xe, 0x29, 0xd1, 0x10, 0x91, 
+       0xb8, 0x24, 0x18, 0xca, 0x8e, 0x3f, 0x89, 0x14, 0xc8, 0xc3, 
+       0x2a, 0xd7, 0x21, 0x5e, 0x19, 0xd2, 0x2d, 0xe0, 0x2b, 0x1a, 
+       0x9a, 0x9b, 0x9b, 0xd4, 0x43, 0x69, 0x6e, 0x51, 0xb8, 0x61, 
+       0xd3, 0xa2, 0xb0, 0x85, 0x25, 0x8b, 0xca, 0x17, 0x60, 0x8b, 
+       0x49, 0x60, 0x7, 0xd3, 0x2e, 0xc3, 0x7, 0xf1, 0x7e, 0xc4, 
+       0x24, 0x4c, 0x15, 0x40, 0xb, 0xb8, 0x59, 0x9, 0x5c, 0xb8, 
+       0x32, 0x12, 0x2b, 0xb2, 0x24, 0xf, 0xfa, 0x92, 0xfe, 0xff, 
+       0x67, 0xef, 0x3c, 00, 0xe5, 0xaa, 0xad, 0xf4, 0x7f, 0x67, 
+       0x5e, 0x75, 0xef, 0xc6, 0xc6, 0xc6, 0xf8, 0xd9, 0x60, 0xd3, 
+       0x5b, 0x68, 0x81, 0x40, 0x8c, 0xe9, 0xc5, 0xb4, 00, 0x9, 
+       0x29, 0x1b, 0xb2, 0x29, 0x9b, 0x6c, 0x7a, 0x1, 0x92, 0x6c, 
+       0x28, 0x9, 0x4, 0x8, 0x21, 0x5b, 0xd9, 0x4d, 0x1, 0x7, 
+       0x96, 0x9a, 0xb0, 0xf4, 0x1e, 0x30, 0xc5, 0x74, 0x1b, 0x9b, 
+       0x62, 0x7a, 0x33, 0xa6, 0x1a, 0xb0, 0x1, 0x1b, 0x1b, 0x5c, 
+       0x5e, 0x99, 0xff, 0xf7, 0xd3, 0xcc, 0x37, 0x4f, 0x33, 0x6f, 
+       0xe6, 0xbd, 0x99, 0x79, 0xcf, 0x90, 0xdd, 0x7f, 0x64, 0xeb, 
+       0x49, 0xa3, 0xab, 0x7b, 0x24, 0x1d, 0x9d, 0x4f, 0xe7, 0x48, 
+       0x57, 0x57, 0x97, 0xf2, 00, 0xb7, 0x3a, 0x5a, 0x6f, 0x3, 
+       0xf6, 0xad, 0xd6, 0x86, 0x9, 0x2e, 0x13, 0x80, 0xeb, 0xfb, 
+       0x57, 0x1c, 0xf8, 0x70, 0xf2, 0x31, 0xd9, 0x33, 0xd9, 0x6e, 
+       0xc9, 0x31, 0x9, 0xfe, 0x1, 0x66, 0xe6, 0x49, 0x78, 0xc0, 
+       0x6d, 0xe7, 0xce, 0x8a, 0x55, 0x49, 0xea, 0xba, 0xeb, 0xae, 
+       0x9b, 0x93, 0xeb, 0x87, 0xa3, 0xe, 0x39, 0xe4, 0x90, 0xba, 
+       0x91, 0x23, 0xb1, 0xd2, 0x3e, 0x64, 0x27, 0x1e, 0xb6, 0x6b, 
+       0xe5, 0x79, 0xe9, 0x3, 0xf, 0x24, 0xb, 0xee, 0xbe, 0xbb, 
+       0x7d, 0xe8, 0xab, 0xaf, 0x2d, 0xdf, 0x65, 0xe9, 0x5b, 0xfd, 
+       0xf5, 0x6, 0xc7, 0xc7, 0xf5, 0xd1, 0x80, 0xd7, 0x2e, 0x7c, 
+       0xf2, 0xc9, 0xbb, 0x96, 0xac, 0x5c, 0xb9, 0x42, 0x8f, 0xbf, 
+       00, 0x78, 0x98, 0x66, 0x5c, 0xaa, 0x27, 0x3, 0x5f, 0xdf, 
+       0x76, 0xeb, 0xc7, 0x75, 0x28, 0x30, 0x3, 0xdb, 0xc8, 0xb4, 
+       0x1a, 0x21, 0x80, 0x27, 0x73, 0xf5, 0xa6, 0xd7, 0x42, 0x3d, 
+       0xa6, 0xba, 0xe4, 0x89, 0x27, 0x93, 0x3a, 0x69, 0xe2, 0xc5, 
+       0xda, 0x9c, 0x32, 0x66, 0xe0, 0x80, 0x64, 0xe5, 0xda, 0xd6, 
+       0x84, 0xaf, 0x8b, 0x70, 0x2a, 0xcb, 0x9e, 0x1a, 0x4, 0xec, 
+       0xf4, 0xce, 0x6a, 0x52, 0xa7, 0xe7, 0xd7, 0xf5, 0x35, 0x3e, 
+       0x33, 0x67, 0xff, 0xbb, 0xf6, 0x1f, 0xf0, 0x71, 0xbf, 0x34, 
+       0xd3, 0xbd, 0x78, 0xd1, 0xb, 0xb9, 0xc0, 0xf2, 0xa4, 0xdf, 
+       0x8, 0x6b, 0x75, 0xc8, 0x2b, 0xb4, 0x19, 0xf8, 0xd8, 0xd7, 
+       0x8e, 0x9c, 0x59, 0xb6, 0x2d, 0x13, 0xb5, 0xd0, 0x6, 0x5f, 
+       0x9a, 0xee, 0x6d, 0xae, 0x7b, 0xc1, 0xa9, 0xe7, 0xdc, 0x36, 
+       0xc9, 0xc1, 0x9e, 0x65, 0xa6, 0xe4, 0xbc, 0xbb, 0x5b, 0x70, 
+       0xe7, 0x2a, 0x14, 0x13, 0x21, 0x5e, 0x2f, 0x6, 0x35, 0xab, 
+       0xf2, 0x13, 0x35, 0x62, 0xe5, 0xb2, 0x54, 0x1f, 0xd0, 0x68, 
+       0x5c, 0x3c, 0xc2, 0x9, 0x78, 0x1d, 0x6a, 0x10, 0xc9, 0xb5, 
+       0x73, 0x9a, 0xbb, 0xe5, 0xcc, 0x54, 0x3, 0xdb, 0x5a, 0x9b, 
+       0xdd, 0x68, 0xea, 00, 0xbd, 0xc2, 0x38, 0xa1, 0xd7, 0x65, 
+       0x64, 0x4b, 0xca, 0xfe, 0x8d, 0xcb, 0xa3, 0x4c, 0xe6, 0xe0, 
+       0x7a, 0xb3, 0xc, 0x80, 0x9f, 0xa2, 0xad, 0xaa, 0x53, 0xce, 
+       0x3a, 0xeb, 0xac, 0xff, 0xcc, 0xe5, 0xa7, 0xe1, 0x2c, 0x88, 
+       0x10, 0x2, 0x64, 0xe2, 0x84, 0xf6, 0x81, 0x31, 0x2c, 0xfc, 
+       0x68, 0xe4, 0xe6, 0x71, 0xc8, 0x30, 0x6d, 0x73, 0x7d, 0x56, 
+       0xb, 0x33, 0x3a, 0x5d, 0x30, 0xf9, 0x94, 0x5e, 0x1e, 0xa9, 
+       0x53, 0x9a, 0xa2, 0x1f, 0x8e, 0x5b, 0xf3, 0xc6, 0xe2, 0xe4, 
+       0xad, 0x5b, 0x67, 0x25, 0xef, 0xde, 0x7f, 0x5f, 0xc2, 0x4b, 
+       0xe3, 0xa3, 0x33, 0x19, 0x84, 0x6b, 0x24, 0xc7, 0xe2, 0xe4, 
+       0x6a, 0xd0, 0x76, 0xc8, 0xc6, 0x1b, 0x1d, 0xfd, 0xea, 0x8a, 
+       0x95, 0x37, 0xdf, 0xbc, 0xe8, 0x85, 0xff, 0x3e, 0xf7, 0xe1, 
+       0x5, 0xcc, 0x21, 0x30, 0xd3, 0xd7, 0x7c, 0xf2, 0xa2, 0x4b, 
+       0x8e, 0xf9, 0xfa, 0x36, 0xdb, 0xc, 0x38, 0x66, 0xab, 0x2d, 
+       0x5f, 0xcc, 0xe5, 0x4d, 0x38, 0x35, 0x5, 0x7f, 0xd0, 0x46, 
+       0x1b, 0x85, 0xf7, 0xb4, 0x9f, 0xd6, 0xe1, 0x12, 0x9b, 0x8c, 
+       0x18, 0x9e, 0xf0, 0x82, 0x88, 0x4e, 0x39, 0x75, 0xb6, 0x7c, 
+       0x38, 0xf2, 0xcb, 0x5f, 0x49, 0x34, 0x7, 0xcc, 0xff, 0xae, 
+       0x36, 0xa2, 0xd5, 0xec, 0x94, 0xf8, 0x17, 0x80, 0xc7, 0x93, 
+       0x11, 0x6, 0x77, 0x3, 0xdc, 0xb, 0x5e, 0xf4, 0x57, 0x6f, 
+       0x57, 0xcf, 0x25, 0xb7, 0x19, 0xbd, 0xd6, 0xcb, 0x96, 0xd4, 
+       0xb4, 0x81, 0x6d, 0xd9, 0x46, 0x36, 0x88, 0x53, 0x5e, 0x35, 
+       0xe, 0x7c, 0xe9, 0xde, 0xb1, 0xaa, 0x1b, 0x78, 0x8b, 0xc1, 
+       0x1d, 0x3, 0x3c, 0xcc, 0xbb, 0x95, 0x2f, 0xc8, 0x4d, 0x4c, 
+       0xbf, 0x12, 0x70, 0x7b, 0x74, 0x80, 0x60, 0xf0, 0x5a, 0x84, 
+       0xda, 0x54, 0x9a, 0x7b, 0xad, 0x98, 0x54, 0xc9, 0xfd, 0x71, 
+       0x79, 0x5, 0x71, 0x1a, 0x4c, 0x9d, 0xcc, 0xc, 0x69, 0xbc, 
+       0x60, 0xde, 0x14, 0x64, 0xea, 0xe5, 0xf, 0xe8, 0x53, 0x8e, 
+       0x4d, 0x26, 0x6d, 0x6e, 0xc8, 0x4c, 0xd4, 0x2b, 0x93, 0x1a, 
+       0x69, 0xfb, 0xc, 0xdc, 0x94, 0x11, 0xb7, 0x83, 0x38, 0xe5, 
+       0xb1, 0x8a, 0x3e, 0x69, 0xd2, 0x64, 0xad, 0xd0, 0x36, 0x7c, 
+       0xe9, 0xe4, 0x93, 0x4f, 0x1e, 0x27, 0xff, 0x4f, 0x6a, 0xe, 
+       0x3d, 0xcc, 0xfc, 0x14, 0x30, 0xa3, 0xb9, 0x1d, 0x2a, 0x9a, 
+       0x64, 0x18, 0xf9, 0xf, 0x3d, 0xf4, 0xd0, 0x4f, 0xa8, 0x63, 
+       0xf7, 0x51, 0xa7, 0xe, 0xa5, 0x63, 0xa5, 0x75, 0x52, 0x68, 
+       0x85, 0x47, 0x1f, 0x7d, 0x84, 0x95, 0xf4, 0xed, 0xe, 0x3f, 
+       0xfc, 0x30, 0x29, 0xb3, 0xe1, 0xe4, 0x5f, 0xa7, 0x6e, 0xf9, 
+       0xa3, 0x8f, 0x24, 0x8b, 0xfe, 0xeb, 0xbf, 0xe2, 0x32, 0x4a, 
+       0xf1, 0x2c, 0xc8, 0xc0, 0xf8, 0x41, 0x3, 0xf, 0xfa, 0xca, 
+       0x96, 0x5b, 0x1f, 0xb4, 0xcb, 0xd8, 0xf1, 0x5f, 0xfd, 0xfb, 
+       0x1b, 0x6f, 0xbc, 0x5e, 0x37, 0xd1, 0xb6, 0xf6, 0xdf, 0x3d, 
+       0xf2, 0xc8, 0x8a, 0xbd, 0x5a, 0x5a, 0xbe, 0xdc, 0xda, 0xde, 
+       0xde, 0x38, 0x69, 0xd8, 0xd0, 0xff, 0x54, 0xfd, 0x83, 0x84, 
+       0xfb, 00, 0x6, 0x80, 0x8d, 0x2b, 0x6, 0xf6, 0x90, 0x43, 
+       0xe, 0x4d, 0xf4, 0xb0, 0xba, 0x57, 0xc0, 0x86, 0x2e, 0x40, 
+       0xd6, 0x23, 0x5b, 0xbd, 0x9f, 0xfe, 0x34, 0x73, 0xef, 0xa0, 
+       0xbd, 0xe9, 0x1b, 0x6, 0x4f, 0x83, 0xaf, 0x5a, 0xd0, 0x41, 
+       0xb7, 0xd8, 0xa1, 0x65, 0xd5, 0x67, 0x19, 0x16, 0xf0, 0x90, 
+       0x67, 0xca, 0xa0, 0xec, 0xb8, 0xc, 0xe2, 0xd5, 0x94, 0xc5, 
+       0xfd, 0xc2, 0x59, 0x9b, 0x68, 0x4f, 0xd6, 0x7e, 0x9, 0x3e, 
+       0x67, 0x5, 0xaf, 0xf1, 0x31, 0xb8, 0x4b, 0xf5, 0x49, 0xa8, 
+       0x5e, 0x4f, 0xe0, 0xf4, 0x8d, 0x74, 0x8, 0x3e, 0x80, 0x5b, 
+       0x66, 0xc8, 0xd6, 0x5a, 0xf4, 0x22, 0x5e, 0xb5, 0x43, 0xf0, 
+       0xf1, 0x34, 0x94, 0xd0, 0xc0, 0x66, 0x1b, 0x1f, 0xe6, 0x2c, 
+       0x1a, 0xaf, 0xb7, 0x2e, 0x2e, 0x3, 0xfa, 0xf6, 0xcc, 0xbb, 
+       0x30, 0x9f, 0x64, 0xaa, 0x5, 0x1, 0xeb, 0x6d, 0x39, 0xbe, 
+       0xdf, 0xed, 0xa1, 0x4d, 0xee, 0x58, 0xe2, 0xda, 0x9d, 0xc6, 
+       0x26, 0x96, 0xba, 0xa3, 0x8f, 0xfe, 0x4c, 0x72, 0xc3, 0xd, 
+       0x37, 0xee, 0x7e, 0xc2, 0x9, 0x27, 0x1c, 0x7b, 0xca, 0x29, 
+       0xa7, 0xfc, 0xda, 0xf7, 0x29, 0xc4, 0x44, 0x67, 0x61, 0x8d, 
+       0x51, 0xb7, 0x4d, 0xb, 0x40, 0xfd, 0xb5, 0xe2, 0xfe, 0xd, 
+       0x6d, 0x6d, 0xdc, 0x52, 0x6f, 0x1d, 0xad, 0x27, 0xa0, 0xb7, 
+       0x4a, 0x8, 0x85, 0xed, 0x35, 0x3, 0xb4, 0xb, 0x6a, 0x90, 
+       0x56, 0xce, 0x57, 0x3f, 0xfb, 0xec, 0x33, 0xb, 0x2f, 0xbf, 
+       0xfc, 0x8a, 0x49, 0x47, 0x1e, 0x79, 0x44, 0x1d, 0x6f, 0x26, 
+       0xad, 0x2b, 0xf7, 0xd2, 0x1f, 0x7e, 0x9f, 0x2c, 0xd3, 0x39, 
+       0xe3, 0x76, 0x9c, 0x36, 0xfa, 0xc2, 0xbb, 0xcb, 0x52, 0x57, 
+       0xea, 0xb1, 0x16, 0xa7, 0xab, 0xe0, 0x9a, 0xf4, 0xee, 0xf6, 
+       0xa7, 0xa6, 0x4c, 0x4d, 0x26, 0xf, 0x1b, 0x9a, 0xe1, 0xc0, 
+       0x42, 0xd2, 0x36, 0x1b, 0x39, 0xe2, 0xb7, 0xb3, 0x3f, 0x77, 
+       0xf4, 0x8c, 0x4f, 0x5e, 0x7c, 0xe9, 0x97, 0xf8, 0x2d, 0x97, 
+       0x3a, 0xe2, 0xaa, 0xab, 0xfe, 0xa2, 0xb0, 0xf9, 0xe2, 0xef, 
+       0x7f, 0xff, 0xfe, 0x7e, 0x23, 0x46, 0xee, 0x30, 0xa9, 0xa3, 
+       0xad, 0x71, 0xcd, 0xf3, 0xcf, 0x67, 0x5a, 0x87, 0xd, 0x4f, 
+       0xd5, 0xbf, 0xfb, 0x4e, 0x92, 0x92, 0x11, 0xa0, 0xcd, 0xe9, 
+       0x49, 0x5a, 0xfd, 0x3f, 0x60, 0xfa, 0x9e, 0x49, 0x87, 0x4e, 
+       0x86, 0xe9, 0xa7, 0xf7, 0xbd, 0x7b, 0x63, 0x2a, 0x87, 0x92, 
+       0x73, 0x7f, 0xb4, 0xfe, 0x11, 0x76, 0xad, 0xd1, 0xff, 0x68, 
+       0x6e, 0x6b, 0x6f, 0xfa, 0xc8, 0x72, 0x48, 0x58, 0xd, 0xf0, 
+       0x62, 0xfa, 0xc4, 0x91, 0x5b, 0xb6, 0xa4, 0xf2, 0x74, 0x3, 
+       0xb, 0xc1, 0x72, 0x6d, 0x59, 0x24, 0xac, 0xc5, 0x81, 0x33, 
+       0x6d, 0x8c, 0xda, 0x44, 0x72, 0xc4, 0xb6, 0x65, 0x3, 0x3b, 
+       0xe0, 0x50, 0xbf, 0xe1, 0x39, 0xb2, 0x5c, 0x9d, 0x59, 0x2e, 
+       0xc6, 0x96, 0x4, 0xb6, 0x8, 0xd5, 0x9, 0x84, 0xfa, 0x2a, 
+       0xcb, 0xfa, 0xd1, 0x32, 0xa6, 0x52, 0x2b, 0x74, 0x6e, 0x64, 
+       0x31, 0x20, 0x78, 0x94, 0xa0, 0x86, 0xc0, 0x1, 0x97, 0x5b, 
+       0x21, 0xc5, 0xae, 0xd9, 0xcc, 0x50, 0x77, 0x1e, 0xa3, 0x28, 
+       0x9e, 0x45, 0x29, 0xe6, 0x47, 0x7d, 0xa9, 0xf5, 0x5c, 0x16, 
+       0x9d, 0x49, 0x9c, 0x72, 0x10, 0x1e, 0x4, 0xe9, 0xf1, 0xc7, 
+       0x9f, 0x68, 0xff, 0xe4, 0x27, 0x77, 0xf, 0x87, 0x2a, 0x7c, 
+       0xea, 0x53, 0x87, 0x37, 0x5f, 0x71, 0xc5, 0x95, 0x7, 0xeb, 
+       0xc8, 0xa6, 0xf4, 0xa9, 0xa7, 0x9e, 0x7a, 0x66, 0xae, 0x9d, 
+       0x6e, 0x2f, 0x66, 0x6c, 0xc7, 0xb4, 0x69, 0xd3, 0x8e, 0x50, 
+       0xdd, 0xb6, 0x96, 0xc5, 0xdb, 0x5f, 0x87, 0x34, 0xde, 0x2b, 
+       0x81, 0x59, 0x29, 0x60, 0x37, 0x88, 0x37, 0xcd, 0x1a, 0x28, 
+       0xb4, 0x70, 0xdc, 0xb4, 0x99, 0xda, 0xd0, 0x20, 0x80, 0xbf, 
+       0x70, 0xd5, 0x55, 0x57, 0x4f, 0x46, 0x83, 0x33, 0x20, 0xf6, 
+       0xb5, 0x7b, 0xe7, 0x81, 0xfb, 0x93, 0x15, 0x4f, 0x3f, 0xad, 
+       0x1a, 0x61, 0x54, 0x24, 0xc9, 0x13, 0xe2, 0xdb, 0x39, 0x8f, 
+       0x3e, 0x9a, 0x7a, 0x40, 0xc7, 0x30, 0x15, 0xbb, 0xeb, 0xf4, 
+       0x6a, 0xea, 0xce, 0xe3, 0xd6, 0x4f, 0x7d, 0x55, 0x47, 0x1a, 
+       0x6d, 0x9e, 0xb5, 0xd4, 0xeb, 0x1b, 0xeb, 0xea, 0x77, 0xbb, 
+       0xee, 0xa8, 0x4f, 0x1d, 0x35, 0xe3, 0xb2, 0x2b, 0x98, 0x4a, 
+       0x20, 0x90, 0xfd, 0x4e, 0x39, 0xe5, 0xd4, 0x9f, 0xad, 0x19, 
+       0x37, 0x6e, 0xbb, 0x3, 0xf, 0x3f, 0xac, 0x51, 0xe7, 0x47, 
+       0x27, 0xcf, 0x3f, 0xfa, 0x68, 0x32, 0xef, 0xd1, 0x47, 0x3b, 
+       0xb6, 0x11, 0xf0, 0xd2, 0x5a, 0x4d, 0xc7, 0xe6, 0xd4, 0x5e, 
+       0x66, 0xa9, 0xf0, 0x41, 0x49, 0x93, 0x34, 0x16, 0x7c, 0x44, 
+       0xbb, 0x76, 0x8a, 0x61, 0x71, 0xc9, 0x95, 0xff, 0x66, 0x1a, 
+       0x3, 0xf0, 0x78, 0xfc, 0x9, 0xf0, 0xdc, 0x47, 0xc, 0xf4, 
+       0x6, 0x37, 0x7d, 0xd7, 0x5b, 0xc7, 0xca, 0xbc, 0x68, 0x87, 
+       0x85, 0x35, 0xe8, 0x1a, 0xe0, 0xbd, 0x29, 0x43, 0x38, 0x6b, 
+       0xd0, 0x20, 0xbe, 0xa5, 0xea, 0x66, 0x5e, 0x1a, 0xe0, 0x56, 
+       0xb8, 0x65, 0x1, 0xde, 0x93, 0x6, 0xe3, 0x46, 0x7b, 0x13, 
+       0xab, 0x17, 0xc3, 0x37, 0xeb, 0xed, 0x7c, 0x1b, 0x66, 0xba, 
+       0xd1, 0x84, 0xa2, 0xc9, 0xeb, 0x9d, 0xbd, 0x6, 0xb6, 0x3b, 
+       0xc8, 0xf4, 0x61, 0x30, 0x3e, 0xd7, 0xa1, 0xe1, 0x68, 0x64, 
+       0xe7, 0xe9, 0x8b, 0xd0, 0xe5, 0x10, 0x2, 0x68, 0xb, 0xe, 
+       0x47, 0x35, 0x9, 0x9c, 0x69, 0xe, 0x9a, 0xa0, 0x1c, 0xcc, 
+       0x6d, 00, 0xde, 0xd2, 0x32, 0xe9, 0x20, 0x34, 0xb8, 0x92, 
+       0x78, 0xd2, 0x80, 0x67, 0xa2, 0xd9, 0xa0, 0x77, 0x9b, 0xb7, 
+       0x92, 0x9, 0xb6, 0x8b, 0x3a, 0x72, 0xf0, 0xf4, 0xe9, 0xd3, 
+       0xef, 0xd4, 0xd4, 0xe1, 0x2d, 0x9, 0xe4, 0x5a, 0xb4, 0xb7, 
+       0xd2, 0x57, 0x2b, 0x7d, 0xb9, 0x5e, 0x6b, 0x7c, 0x58, 0xe0, 
+       0x67, 0x3a, 0xb4, 0xe6, 0x91, 0x47, 0x1e, 0x9e, 0x77, 0xe5, 
+       0x95, 0x57, 0xb5, 0x2d, 0x5b, 0xb6, 0x5c, 0xb7, 0xf7, 0x9d, 
+       0xd3, 0x77, 0x6b, 0x93, 0x57, 0xce, 0x3b, 0x2f, 0x69, 0xcf, 
+       0xed, 0x2a, 0x9b, 0xad, 0x93, 0x58, 0x4e, 0x7b, 0xe4, 0xd1, 
+       0xa4, 0x14, 0xb0, 0x5d, 0xea, 0xe3, 0x3a, 0xcb, 0xed, 0xa4, 
+       0x7, 0xe6, 0x24, 0x77, 0xbe, 0xfc, 0x4a, 0x48, 0x52, 0x83, 
+       0x87, 0x8d, 0x6a, 0xee, 0xff, 0xdb, 0xe9, 0x1b, 0x6d, 0xc4, 
+       0x4b, 0xd7, 0xfd, 0x1, 0xb6, 0xd6, 0xf, 0x8e, 0xd2, 0x60, 
+       0xd4, 0xf, 0x3e, 0xd4, 0xe9, 0x49, 0xc5, 0x54, 0xbd, 0xc1, 
+       0x35, 0x78, 0xc4, 0xc8, 0x64, 0x41, 0x2a, 0xd5, 0xb1, 0x4a, 
+       0x7a, 0x64, 0xb5, 0xd2, 0xd7, 0xa, 0xcc, 0xee, 0x2f, 0x64, 
+       0xc2, 0xf2, 0xe1, 0x72, 0x7a, 0x13, 0x6a, 0xb3, 0x15, 0xb7, 
+       0x87, 0x57, 0x34, 0xe9, 0x23, 0xcb, 0x44, 0x5c, 0xe, 0x7d, 
+       0xd8, 0x1b, 0x27, 0xf3, 0x99, 0xa3, 0xc0, 0x98, 0x77, 0xe7, 
+       0x81, 0x4d, 0x1c, 0xba, 0xf6, 0x94, 0x57, 0x8d, 0x3, 0x67, 
+       0xea, 0xef, 0x16, 0xdd, 0x3, 0xa8, 0xd, 0x6c, 0x34, 0xb7, 
+       0xf1, 0x58, 0x16, 0x33, 0x95, 0x80, 0xdb, 0x44, 0x8, 0x79, 
+       0xbe, 0x3d, 0x46, 0xe6, 0x4b, 0x33, 0xcf, 0x74, 0x7b, 0xe3, 
+       0xdc, 0x71, 0x66, 0x84, 0x80, 0x90, 0x11, 0xcd, 0xb2, 0x15, 
+       0xad, 0xb4, 0xac, 0x98, 0x89, 0xc4, 0xdd, 0x89, 0x74, 0xa8, 
+       0x1e, 0x7f, 0xa5, 0x24, 0x64, 0xbd, 0x2e, 0xc3, 0x75, 0x89, 
+       0xcb, 0x82, 0x3e, 0x1e, 0x80, 0x33, 0xc5, 0x58, 0xb2, 0x64, 
+       0x69, 0x4a, 0xef, 0x3b, 0x17, 0x94, 0x65, 0x80, 0x4f, 0x9c, 
+       0xd8, 0x32, 0x43, 00, 0x3f, 0x4e, 0x74, 0x58, 0x49, 0x6, 
+       0xe0, 0x4d, 0x6a, 0xfb, 0xb6, 0xb2, 0x2a, 0x86, 0x4b, 0x8, 
+       0x9f, 0x16, 0x90, 0xdf, 0x57, 0x87, 0xb6, 0x2b, 0x7f, 0x5b, 
+       0xc, 0x70, 0xd5, 0x7f, 0xb5, 0x1e, 0xef, 0x3c, 0x2d, 0x80, 
+       0x37, 0x6b, 0x61, 0xf0, 0xbd, 0xd9, 0xb3, 0xef, 0xbc, 0x5e, 
+       0xa7, 0xaa, 0xb6, 0x31, 0xcf, 0xeb, 0x2b, 0xf7, 0xea, 0x25, 
+       0x17, 0x6b, 0x38, 0xcf, 0x56, 0x7b, 0xed, 0x36, 0xdb, 0x24, 
+       0xdf, 0xba, 0xee, 0xba, 0xe4, 0x7e, 0x1d, 0xba, 0xa0, 0x15, 
+       0x67, 0xe, 0xb1, 0x28, 0x28, 0x86, 0x35, 0x35, 0x7d, 0xf, 
+       0x2e, 0x9c, 0x83, 0xf6, 0xad, 0xe3, 0x8e, 0x4b, 0xfe, 0x59, 
+       0xdf, 0xc0, 0xe6, 0x23, 0x3, 0x38, 0xd, 0xd6, 0x1d, 0x3f, 
+       0xde, 0x7e, 0xbb, 0x33, 0x4e, 0x3d, 0xf5, 0x97, 0x5, 0xc0, 
+       0x8e, 0x9, 0xec, 0xb1, 0xc7, 0x34, 0x9d, 0x64, 0xd2, 0xc6, 
+       0xe7, 0x7a, 0xa, 0xde, 0xc1, 0xc6, 0xf2, 0x81, 0xb7, 0x96, 
+       0x91, 0xf8, 0x9e, 0x5a, 0xe3, 0xd2, 0x80, 0x29, 0xe4, 0xcb, 
+       0x56, 0x95, 0xe5, 0xce, 0xa1, 0xfb, 0xb2, 0x56, 0xfa, 0xdc, 
+       0x7, 0x7d, 0x59, 0x9, 0x5a, 0x77, 0xec, 0xdc, 0x4a, 0xed, 
+       0x76, 0x54, 0xb, 0x6a, 0xd7, 0x43, 0x34, 0xe1, 0x65, 0xa3, 
+       0x2c, 0x34, 0x56, 0xaf, 0xd, 0x70, 0xb0, 0x68, 0x80, 0xd3, 
+       0x59, 0xca, 0x92, 0xeb, 0x34, 0xdf, 0xa8, 0xb0, 0x12, 0x70, 
+       0x93, 0x3d, 0xf, 0x70, 0x81, 0x70, 0x8a, 0x84, 0x8b, 0x15, 
+       0xde, 0xaa, 0x9d, 0x19, 0x8, 0x43, 0xe3, 0x46, 0xb3, 0x58, 
+       0xa4, 0x43, 0xe1, 0xd8, 0x2e, 0x58, 0x35, 0xcd, 0xe2, 0x1b, 
+       0x5c, 0x6, 0x21, 0xe5, 0x98, 0xd1, 0x8, 0x90, 0x16, 0xa7, 
+       0xfa, 0x64, 0x4e, 0xef, 0x32, 0x5d, 0x86, 0x43, 0xc0, 0x2d, 
+       0x33, 0x9a, 0x53, 0x54, 0xda, 0x5b, 0x5a, 0x5a, 0x4a, 0xbe, 
+       0xf8, 0x52, 0x2, 0xe0, 0xb2, 0x45, 0x93, 0xfe, 0x1a, 0x30, 
+       0x5b, 0x4, 0xe8, 0x66, 0x9, 0x21, 0xab, 0xcd, 0x98, 0xa4, 
+       0xe1, 0xc0, 0x87, 0x62, 0x80, 0xb, 0x50, 0x4b, 0x5, 0xf2, 
+       0x8c, 0x6, 0x82, 0xfe, 0x7a, 0x19, 0xe5, 0xae, 0xd9, 0xb3, 
+       0xef, 0xba, 0x51, 0xe6, 0x7e, 0x1b, 0x8f, 0x11, 0xfb, 0xc2, 
+       0xad, 0xc4, 0x1c, 0x7, 0x58, 0x5a, 0xd9, 0xdd, 0xee, 0x2b, 
+       0x5f, 0x49, 0x8e, 0x3f, 0xfe, 0xf8, 0xf0, 0x96, 0x1a, 0xed, 
+       0xf9, 0xfa, 0xd7, 0xc3, 0x96, 0xf1, 0x7c, 0x31, 0xda, 0x1e, 
+       0x1b, 0xae, 0x6b, 0x45, 0x3a, 0xa4, 0xbd, 0xa5, 0x41, 0x8d, 
+       0x23, 0x8c, 0x39, 0xb5, 0x54, 0x3c, 0x49, 0xf7, 0xeb, 0xd7, 
+       0x7f, 0x7f, 0xb5, 0xe7, 0xd3, 0xd6, 0xd8, 0xf9, 0x1b, 0x73, 
+       0x11, 0xcc, 0xe5, 0x96, 0x96, 0x89, 0x99, 0x85, 0xb, 0x5f, 
+       0xc, 0xaf, 0x68, 0xc2, 0xbb, 0xd8, 0xfa, 0xa1, 0xef, 0xf0, 
+       0xf0, 0xb7, 0xb7, 0x4e, 0x72, 0x1b, 0x16, 0xb8, 0x18, 0x78, 
+       0x3d, 0x10, 0x13, 0xc6, 0xb2, 0xd8, 0xdb, 0x72, 0x90, 0xdf, 
+       0x27, 0x9f, 0x7c, 0x32, 0x2c, 0x7e, 0x5a, 0xf6, 0xe2, 0x36, 
+       0xd4, 0x4a, 0x5f, 0x78, 0x6b, 0x13, 0xb8, 0x5b, 0xc4, 0x3, 
+       0xc0, 0x5d, 0xc, 0xec, 0xb2, 0x18, 0x2e, 0x7b, 0x41, 0x44, 
+       0xac, 0x75, 0xc, 0xec, 0x30, 0x89, 0xd7, 0xbc, 0x62, 0x3, 
+       0x31, 0x8a, 0x29, 0x52, 0xd5, 0x2e, 0x6e, 0x1c, 0x71, 0x1a, 
+       0xce, 0x89, 0x19, 0x9c, 0x80, 0x99, 0x64, 0x56, 0x85, 0xc5, 
+       0x88, 0xaa, 0x89, 0x96, 0xb8, 0xc1, 0xb4, 0x61, 0xb0, 0xbd, 
+       0x3a, 0x35, 0x23, 0x41, 0xeb, 0xbd, 0x94, 0xe4, 0xca, 0xa3, 
+       0xc, 0xfb, 0x58, 0x20, 0x11, 0x1e, 0xd, 0x56, 0xe9, 0x9d, 
+       0x76, 0xda, 0xd1, 0xfc, 0xeb, 0x52, 0xc3, 0x8, 0xe0, 0x7, 
+       0xe7, 0x34, 0x38, 0xda, 0x9b, 0x57, 0x9d, 0xea, 0x5, 0xf2, 
+       0x76, 0xf1, 0x25, 0xdc, 0x5b, 0xa, 0xe0, 0x2, 0xf5, 0x2a, 
+       0xd, 0x52, 0xad, 0x1a, 0x8, 0xf4, 0xbd, 0xf8, 0xe6, 0x55, 
+       0x97, 0x5d, 0xf6, 0xa7, 0xdb, 0xee, 0xb9, 0xe7, 0xee, 0x9b, 
+       00, 0xb8, 0x5e, 0x31, 0xed, 0x52, 0x56, 0x35, 0x9, 0x6f, 
+       0xdd, 0x7b, 0x4f, 0x22, 0x3b, 0x3f, 0xf0, 0x68, 0xb5, 0xe6, 
+       0xa8, 0x3, 0xf4, 0xe2, 0x87, 0x16, 0x73, 0x2, 0xf, 0xb5, 
+       0xa0, 0xc3, 0x42, 0x64, 0x1, 0xb9, 0xf3, 0xcf, 0x3f, 0x5f, 
+       0x53, 0x8d, 0x4f, 0x85, 0x17, 0x34, 0x7c, 0x81, 0x93, 0x4e, 
+       0xfd, 0xaa, 0x67, 0x63, 0x47, 0x47, 0xff, 0x7d, 0xa6, 0x6e, 
+       0x1c, 0x4c, 0x71, 0x5f, 0x2f, 0xe, 0xf5, 0xa5, 0x4b, 0x4e, 
+       0x11, 0xcd, 0x6b, 0x6f, 0x34, 0x2b, 0xa0, 0x33, 0x28, 0x8, 
+       0xe1, 0x73, 0x5f, 0x38, 0x59, 0x6d, 0x68, 0xd5, 0xb0, 0x93, 
+       0xcc, 0x72, 0x1, 0x7d, 0xe2, 0xb8, 0xde, 0x96, 0x13, 0xb6, 
+       0xa, 0x4b, 0x8e, 0xf5, 0xf6, 0x5f, 0x18, 0xe4, 0xa1, 0x8d, 
+       0xb7, 0x9c, 0x38, 0xac, 0xb6, 0x2d, 0xb2, 0x98, 0xea, 0xd5, 
+       0xd7, 0x3c, 0xf, 0xb4, 0xe6, 0x36, 0xc8, 0xc1, 0x26, 0xb2, 
+       0x52, 0x12, 0xc7, 0x25, 0x13, 0xa3, 0xc2, 0x63, 0x60, 0x87, 
+       0xb8, 0xa, 0xd9, 0x50, 0xa3, 0x48, 0xd7, 0x7, 0x92, 0xd1, 
+       0x4d, 0xdd, 0x45, 0xdd, 0x40, 0x1a, 0xd, 0x28, 0x74, 0x12, 
+       0x49, 0xd2, 0xdc, 0xd4, 0x96, 0xc, 0x19, 0x5c, 0xd3, 0xfa, 
+       0x5c, 0x97, 0xa2, 0xdc, 0x41, 0x84, 0x94, 0xe1, 0x51, 0x1a, 
+       0x40, 0xe9, 0xd9, 0x76, 0x4f, 0xed, 0xed, 0x42, 0xaf, 0x5c, 
+       0x82, 0xe9, 0xbb, 0x3d, 0x8, 0x25, 0x9a, 0xe7, 0xa5, 0x97, 
+       0x5e, 0xee, 0x60, 0x67, 0x14, 0x8f, 0xc1, 0xba, 0x73, 0x11, 
+       0xc0, 0x31, 0xd1, 0x7f, 0x2c, 0x33, 0x7b, 0xa9, 0xee, 0x6f, 
+       0x13, 0x88, 0x46, 0xaa, 0xce, 0x69, 0xd5, 0xbd, 0x24, 0xc0, 
+       0x75, 0xad, 0x5e, 0x5e, 0x6f, 0x4e, 0xb7, 0x2f, 0x91, 0x35, 
+       0x82, 0x96, 0x7f, 0x8f, 0xaf, 0xa2, 0x48, 0x6b, 0xdc, 0xac, 
+       0x55, 0x74, 0x1, 0x9c, 0x7d, 0x24, 0xd5, 0x3b, 0xac, 0xa7, 
+       0x39, 0xf, 0xcc, 0xe1, 0x2b, 0x6, 0xa1, 0xdc, 0xdb, 0x73, 
+       0x27, 0xaa, 0x30, 0x58, 0xe1, 0xb8, 0xce, 0xa2, 0x54, 0x25, 
+       0xee, 0xc, 0x6d, 0x76, 0xc1, 0x41, 0xab, 0x2e, 0x77, 0x9e, 
+       0x7a, 0xb9, 0xfb, 0xe0, 0x93, 0x1e, 0xad, 0xea, 00, 0x97, 
+       0xc5, 0x5, 0xda, 0xdb, 0x3, 0x26, 0x7d, 0x88, 0x87, 0xcf, 
+       0xbd, 0x75, 0x2a, 0x27, 0x9c, 0x6e, 0x83, 0x4c, 0x40, 0xbf, 
+       0x14, 0xc0, 0x29, 0xab, 0x37, 0xe, 0x39, 0x1e, 0x34, 0x20, 
+       0x85, 0x25, 0x1a, 0x14, 0x57, 0x5c, 0x7f, 0xcb, 0x4a, 0xb5, 
+       0xf4, 0x85, 0xb7, 0x6, 0x59, 0x6b, 0xbc, 0xc4, 0x81, 0x82, 
+       0x35, 0xb0, 0x6d, 0x96, 0x23, 0xd3, 0xf4, 0x59, 0xe8, 0x37, 
+       0x85, 0x79, 0x57, 0x52, 0xd8, 0x73, 0xf6, 0xbb, 0x6f, 0x20, 
+       0xc, 0xc0, 0x56, 0x58, 0xaf, 0x42, 0x5a, 0x7a, 0x12, 0xdc, 
+       0x3c, 0xf5, 0x32, 0x11, 0x1a, 0x9, 0x73, 0xe7, 0xcd, 0x9b, 
+       0x27, 0x55, 0xb5, 0x3a, 0x19, 0x3f, 0x6e, 0x98, 0x4c, 0xd0, 
+       0xfa, 0x2e, 0x95, 0x2b, 0x73, 0x7b, 0xd9, 0x64, 0x33, 0x8f, 
+       0x4e, 0x33, 0x53, 0x89, 0x3, 0x3a, 0x4c, 0xf2, 0xde, 0x2c, 
+       0x2, 0xc6, 0x85, 0xba, 0x1c, 0xca, 0xb0, 0xa6, 0xa1, 0x1c, 
+       0xe2, 0xb2, 0x44, 0x52, 0xdd, 0x69, 0xed, 0x98, 0x4e, 0xc, 
+       0x70, 0x69, 0x95, 0x9d, 0x5, 0xf0, 0x55, 0xda, 0x8, 0xc1, 
+       0x7, 0xc, 0x1a, 0xcb, 0x1, 0x7c, 0xd1, 0xa2, 0x45, 0x2d, 
+       0x2, 0xda, 0xa, 0x95, 0xf3, 0x82, 0x68, 0x61, 0x8b, 0xa3, 
+       0xae, 0xdf, 0xbb, 0xe4, 0x92, 0x8b, 0x6f, 0xbd, 0xf7, 0xde, 
+       0x7b, 0xfe, 0x72, 0xf9, 0xe5, 0x97, 0x57, 0xad, 0xc1, 0x1, 
+       0x2e, 0xef, 0x63, 0xaf, 0x7d, 0xee, 0xf9, 0xec, 0x84, 0x59, 
+       0x4, 0x97, 0xe8, 0xc4, 0x51, 0x9c, 0xd6, 0x58, 0x42, 0x8, 
+       0xef, 0x38, 0x1d, 0xa7, 0x12, 0xb7, 0x7e, 0xf4, 0xbe, 0xf5, 
+       0xca, 0x67, 0x9f, 0xe9, 0xf1, 0x96, 0x9d, 0x77, 0xde, 0x29, 
+       0x2d, 0x4b, 0x24, 0x98, 0xb3, 0xc8, 0x5, 0xde, 0xfd, 0x7, 
+       0xaf, 0x89, 0x13, 0xf6, 0xd6, 0xd1, 0x6, 0x56, 0xc8, 0x91, 
+       0x7, 0xfa, 0xb, 0x90, 0xe3, 0xdd, 0x9f, 0xe, 0x7b, 0x53, 
+       0xe, 0xed, 0xd8, 0x70, 0xc2, 0xc8, 0x8e, 0xa6, 0xc6, 0xb6, 
+       0x84, 0xcd, 0x33, 0x94, 0xe5, 0x36, 0xd0, 0xe, 0x9c, 0xc3, 
+       0x4a, 0xcb, 0x1, 0x6f, 0x5a, 0x54, 0x35, 0xb8, 0x83, 0x5, 
+       0xad, 0x7b, 0x6b, 0x3, 0x77, 0x51, 0xa1, 0x1e, 00, 0x4c, 
+       0x6c, 0x7d, 0x26, 0xf9, 0xb5, 0x3a, 0x1a, 0x4a, 0xe7, 0x61, 
+       0x8a, 0x67, 0x3a, 0x56, 0x48, 0x78, 0x6, 0x26, 0xfb, 0xed, 
+       0xb3, 0x73, 0xf8, 0x2a, 0x46, 0xad, 0x34, 0x7d, 0x1f, 0xb4, 
+       0xed, 0x2c, 0x1c, 0x74, 0x22, 0xe6, 0x2a, 0xf3, 0xd4, 0x12, 
+       0x6b, 0xe, 0xce, 0x5e, 0x55, 0xe8, 0xce, 0x72, 0x88, 0x80, 
+       0xd0, 0x89, 0x98, 0xae, 0xf0, 0x46, 0x73, 0xa4, 0x8a, 0xe9, 
+       0x45, 00, 0xdf, 0x51, 0xf5, 0x1b, 0x23, 00, 0x35, 0xce, 
+       0x99, 0x33, 0xe7, 0x63, 0xaa, 0x73, 0x73, 0x31, 0xc0, 0x65, 
+       0xee, 0xb5, 0xe8, 0x1d, 0xf4, 0xb1, 0xda, 0x88, 0xf3, 0xba, 
+       0x2c, 0x1e, 0x36, 0x8a, 0x18, 0xdc, 0x1, 0xe0, 0x17, 0x5f, 
+       0x7c, 0xf1, 0x2d, 0xf7, 0xdd, 0x77, 0xef, 0xad, 0x57, 0x5c, 
+       0x81, 0x6, 0xaf, 0xcc, 0x44, 0x37, 0xb0, 0xef, 0xbf, 0x7f, 
+       0xce, 0xc3, 0x4f, 0x3c, 0xfb, 0xcc, 0x63, 0xae, 0x78, 0xfa, 
+       0x83, 0xf7, 0x83, 0x49, 0x8e, 0xd9, 0xad, 0xa3, 0x9e, 0xc3, 
+       0x3b, 0xef, 0x3a, 0xf1, 0x34, 0xd9, 0x6e, 0xbb, 0xed, 0x12, 
+       0x7d, 0x5e, 0xa9, 0x5b, 0xcb, 0x64, 0x58, 0xbf, 0x66, 0x93, 
+       0x49, 0x9a, 0x46, 0xf7, 0xbc, 0xbb, 0x8c, 0x85, 0x3a, 0x16, 
+       0x54, 0x79, 0x54, 0xc5, 0x34, 0xcd, 00, 0x67, 0xb0, 0xa4, 
+       0xff, 0xaa, 0x5, 0x43, 0xbe, 0xf0, 0xa2, 0x8, 0xfd, 0x2f, 
+       0xcb, 0x33, 0x1c, 0xe2, 00, 0x5d, 0x7b, 0xfa, 0xcf, 0xf2, 
+       0x52, 0x74, 0x4b, 0xd5, 0x3f, 0xeb, 0xf4, 0xec, 0x7f, 0xbf, 
+       0x7d, 0x77, 0x4e, 0x8d, 0x1d, 0xa3, 0x93, 0x69, 0xea, 0x56, 
+       0x27, 0x3a, 0x91, 0x35, 0xf, 0x70, 0x88, 0xc5, 0x32, 0x5a, 
+       0x29, 0x71, 0xc0, 0xad, 0xe9, 0xda, 0x28, 0xe5, 0x8f, 0xb5, 
+       0xb6, 0x95, 0x2e, 0x64, 0x4a, 0x2a, 0x46, 0x3, 0xb7, 0x54, 
+       0x39, 0xbe, 0x99, 0x3c, 0x6, 0x36, 0x7, 00, 0xe, 0xaf, 
+       0x45, 0x73, 0xd3, 0x28, 0x3c, 0x20, 0x40, 0x48, 0xda, 0x5a, 
+       0x97, 0x27, 0xeb, 0x8d, 0xd2, 0x3e, 0xe2, 0x69, 0xdb, 0x26, 
+       0x83, 0x6, 0xea, 0x83, 0x6f, 0xd9, 0x3d, 0x10, 0xa5, 0xea, 
+       0x51, 0x55, 0x9a, 0x1, 0x47, 0x67, 0xb9, 0xf3, 0x24, 0x2c, 
+       0x3c, 0x66, 0xab, 0x8a, 0x4e, 0x4f, 0x99, 0x2d, 0xc, 0x94, 
+       0x81, 0x70, 0x20, 0x88, 0x2, 0x9d, 0x8e, 0x46, 0xde, 0xb2, 
+       0x24, 0xa3, 0xbb, 0xa3, 0x7, 0xc0, 0x8f, 0x38, 0xe2, 0x53, 
+       0xcd, 0x1b, 0x6c, 0x30, 0xa1, 0x45, 0xfc, 0x19, 0x29, 0xed, 
+       0x3d, 0x5c, 0x1f, 0x41, 0xd8, 0xeb, 0xbe, 0xfb, 0xee, 0xdb, 
+       0x5a, 0xe6, 0xdd, 0x44, 0xf1, 0x6b, 0x53, 0x7d, 0xa9, 0x64, 
+       0xba, 0x16, 0x6b, 0x36, 0xd6, 0x73, 0xee, 0x57, 0x74, 0x8, 
+       0xc1, 0xff, 0xe8, 0xa4, 0x97, 0xd7, 0x44, 0x13, 0x9b, 0x99, 
+       0xa5, 0x72, 0x90, 0x1c, 00, 0xae, 0x4f, 0xf, 0xdf, 0xac, 
+       0xfb, 0x66, 0x1, 0x70, 0x59, 0x2, 0x4a, 0x2e, 0xef, 0x62, 
+       0x60, 0x9f, 0x7f, 0xfe, 0x1f, 0x67, 0xe9, 0x43, 0xf7, 0x3c, 
+       0x6f, 0xf, 0xae, 0x21, 0x5d, 0x97, 0xe8, 0x2b, 0x2b, 0x89, 
+       0x3e, 0x60, 0x98, 0xcc, 0x9e, 0x3d, 0x9b, 0xf, 0x13, 0xa0, 
+       0xdd, 0xf9, 0xcc, 0x71, 0x48, 0xef, 0x4e, 0x6, 0x1a, 0x75, 
+       0x6f, 0xde, 0x65, 0x2a, 0x33, 0x73, 0xb5, 0xd7, 0x5f, 0xdb, 
+       0x36, 0x3b, 0xf4, 0x24, 0xae, 0x73, 0xa3, 0x9, 0x3c, 0x86, 
+       0xb7, 0x38, 0xf8, 0x5c, 0xb, 0x30, 0xf2, 0xf5, 0xc8, 0x45, 
+       0x72, 0x96, 0x48, 0x78, 0x24, 0x6, 0x4d, 0xf7, 0xa3, 0xe5, 
+       0xb3, 0xb7, 0x65, 0x68, 0xf, 0x7d, 0x90, 0xe7, 0x4f, 0xee, 
+       0xb6, 0x55, 0x32, 0x66, 0xb4, 0x96, 0x51, 0x3a, 0x56, 0x26, 
+       0x3a, 0x43, 0x2f, 0xc, 0x58, 0xb5, 0xd2, 0x86, 0xd7, 0xba, 
+       0x17, 0x8d, 0xa, 0x63, 0x63, 0x80, 0xdb, 0xa2, 0x46, 0xe6, 
+       0x30, 0xb8, 0xb, 0x64, 0xaf, 0x27, 0x70, 0xe7, 0x58, 0x92, 
+       0x35, 0xcb, 0xb5, 0x52, 0x3b, 0x22, 0xb7, 0xc8, 0xe3, 0xf4, 
+       0xaa, 0x42, 0x3a, 0xa, 0x60, 0xaf, 0x5d, 0xf3, 0x6e, 0x32, 
+       0x7a, 0xa4, 0x8e, 0x9, 0xde, 0xe3, 0x63, 0x32, 0x93, 0xa8, 
+       0x6b, 0xa8, 0x59, 0x55, 0xb4, 0x4a, 0x65, 0x76, 0x7, 0xb9, 
+       0xc3, 0x1c, 0xaa, 0xce, 0x19, 0x75, 0x6a, 0x77, 0x6d, 0x2d, 
+       0x45, 0xae, 0x64, 0x9a, 0xcb, 0xe0, 0x22, 0xed, 0x41, 0x40, 
+       00, 0x36, 0x42, 0x99, 0x4a, 0xa5, 0x53, 0x93, 0x26, 0x4d, 
+       0x2e, 0x79, 0x5f, 0x4f, 0x89, 00, 0x5c, 0x3b, 0xd9, 0x9a, 
+       0x4, 0xf0, 0x31, 0x2, 0xf8, 0x40, 0x1d, 0xd9, 0xb4, 0x42, 
+       0x60, 0x1e, 0x2d, 0xb, 0x67, 0x33, 0x1, 0x6b, 0x9c, 00, 
+       0xbf, 0x56, 0x9a, 0x6d, 0x81, 0xce, 0x7, 0xfb, 0x8d, 0x4e, 
+       0x4d, 0x9d, 0x2d, 0x7a, 0x6c, 0x61, 0xc5, 0x3, 0xf0, 0x58, 
+       0x83, 0xaf, 0xd0, 0x1, 0x8, 0x37, 0xe9, 0xd1, 0xd5, 0x6d, 
+       0x9a, 0x83, 0x87, 0x63, 0x93, 0x75, 0xbd, 0x8b, 0x33, 0xb0, 
+       0x79, 0xbb, 0xb, 0x60, 0x2b, 0xc3, 0x8a, 0x5, 0x3a, 0x99, 
+       0x55, 0x3b, 0xd1, 0xc2, 0x88, 0x30, 0x63, 0xa3, 0xc9, 0x89, 
+       0xe6, 0xf2, 0xe1, 0xe9, 0x2, 0xef, 0xbc, 0x6b, 0xe1, 0x2b, 
+       0x58, 0x40, 0x2a, 0x1b, 0x29, 0xa, 0x56, 0x8a, 0x89, 0xb2, 
+       0xc6, 0xa0, 0xaf, 0xb1, 0x84, 0x9f, 0x5c, 0x9b, 0xb1, 0xf1, 
+       0x46, 0x21, 0xae, 0xb7, 0x8b, 0x92, 0xfe, 0x93, 0xb3, 0x71, 
+       0xe7, 0x2d, 0x17, 0x4e, 0x9e, 0x3c, 0x9, 0xad, 0xaa, 0x23, 
+       0x8b, 0x3a, 0xf, 0x1c, 0x84, 0xa7, 0xf4, 0xa1, 0x81, 0x5d, 
+       0x2b, 0x38, 0xe2, 0x32, 0x91, 0x3, 0x59, 0x71, 0xa1, 0xef, 
+       0xe8, 0x3f, 0xcb, 0x88, 0x81, 0x4e, 0x19, 0xa4, 0xd5, 0xea, 
+       0x8c, 0xaf, 0x26, 0xc9, 0xf5, 0x1e, 0x9f, 0xdc, 0x26, 0x59, 
+       0x6f, 0xf4, 0x80, 0xa4, 0xa3, 0x7d, 0x45, 0x1, 0xc0, 0xab, 
+       0x6d, 0x87, 0x4c, 0x7d, 0xa6, 0x95, 0x1d, 0xb2, 0xa, 0x79, 
+       0x16, 0x19, 0x2b, 0xdb, 00, 0x6a, 0xa5, 0x15, 0x80, 0xda, 
+       0x75, 0xef, 0x49, 0xe0, 0xb9, 0x8e, 0xe7, 0x66, 0x9d, 0x6e, 
+       0x33, 0x78, 0x3, 0xd9, 0xfe, 0x35, 0x3d, 0x6, 0x3, 00, 
+       0x3a, 0x20, 0x30, 0x59, 0xf5, 0xc1, 0xdb, 0xc9, 0x88, 0xe1, 
+       0x4d, 0xc9, 0x5e, 0x7b, 0xee, 0x90, 0xf4, 0x1f, 0xd0, 0x9c, 
+       0xac, 0x55, 0xba, 0xa4, 0x25, 0x7b, 0xc, 0x89, 0x6b, 0x55, 
+       0x43, 0x68, 0xd0, 0xb9, 0xb3, 0x2c, 0x14, 0x74, 0x1a, 0xfb, 
+       0xc8, 0x8b, 0x9f, 0xd1, 0xd6, 0x50, 0x44, 0xb8, 0xc5, 0x9d, 
+       0xef, 0x72, 0x6c, 0x3a, 0x62, 0x92, 0x8f, 0x1a, 0xc5, 0x17, 
+       0x23, 0x6a, 0x5e, 0x6b, 0xc, 0x1b, 0x5d, 0x8e, 0x3a, 0xea, 
+       0x48, 0x36, 0xba, 0x4c, 0x56, 0x9d, 0xdb, 0x5, 0xee, 0xab, 
+       0xb4, 0x19, 0x66, 0x96, 0x4e, 0xe4, 0xb8, 0x42, 0xe1, 0xbf, 
+       0xeb, 0x99, 0xf6, 0x69, 0x3a, 0x2d, 0xf5, 0x49, 0x55, 0x84, 
+       0xe5, 0x5d, 0x54, 0x9a, 0x1, 0xce, 0x9b, 0x58, 0xd6, 0xde, 
+       0x41, 0x83, 0x2b, 0xdf, 0x8d, 0xe2, 0xf7, 0x1d, 0xa5, 00, 
+       0xde, 0x9, 0xec, 0xb9, 0xf3, 0xcf, 0x3b, 0xef, 0x8f, 0xb7, 
+       0xe6, 0xee, 0x5d, 0x7e, 0xc5, 0xd3, 0xcf, 0x2c, 0xd0, 0xf9, 
+       0xe0, 0x41, 0x50, 0xd8, 0xeb, 0xcd, 0x5b, 0x5a, 0xe4, 0x7d, 
+       0xf5, 0xd5, 0x57, 0x95, 0xa5, 0x32, 0xc7, 0x3d, 0xde, 0x37, 
+       0x2e, 0x94, 0x24, 0x3, 0xb2, 0x9b, 0x47, 0x7a, 0xbc, 0x99, 
+       0xb9, 0xb0, 0xf8, 0x97, 0x61, 0xcb, 0x2e, 0xd6, 0x1d, 0xc0, 
+       0xf6, 0xc0, 0x9, 0x8f, 0xe1, 0x77, 0xb5, 0xa0, 0x28, 0x55, 
+       0x28, 0x72, 0x20, 0x70, 0xa7, 0xa0, 0x1d, 0x7b, 0xcb, 0x4f, 
+       0xa9, 0x7b, 0xaa, 0x4b, 0x93, 0x85, 0xaa, 0x1b, 0x64, 0x84, 
+       0x24, 0x4d, 0xcd, 0x8d, 0xc9, 0x1e, 0xd3, 0xb6, 0x4b, 0x46, 
+       0x49, 0x91, 0xad, 0x59, 0xfd, 0x6e, 0x58, 0x63, 0x62, 0x40, 
+       0xa9, 0xa5, 0x1d, 0x7a, 0x4a, 0xd2, 0x26, 0x3f, 0x46, 0xa4, 
+       0x6d, 0x45, 0x7, 0x4c, 0xea, 0xb7, 0xf1, 0xd9, 0x5, 0xe0, 
+       0x59, 0xb5, 0xd9, 0xb5, 0xf6, 0x64, 0x8c, 0x7d, 00, 0xb9, 
+       0x98, 0x32, 0x4e, 00, 0x27, 0x5e, 0x95, 0xb3, 0xc6, 0x7e, 
+       0x7f, 0xe5, 0x92, 0x64, 0xe4, 0x88, 0xc6, 0x64, 0xef, 0x3d, 
+       0xb7, 0xd7, 0xca, 0x6b, 0x63, 0x18, 0x3d, 0xf5, 0x60, 0x42, 
+       0xa3, 0x52, 0xa, 0x9b, 0xbd, 0x4b, 0xe5, 0xaa, 0x29, 0x24, 
+       0x66, 0x18, 0x71, 0x83, 0x9b, 0xd5, 0x5e, 0x16, 0xd3, 0x34, 
+       0x28, 0x55, 0x43, 0xae, 0xdb, 0xbc, 0x6, 0x36, 0xc2, 0x41, 
+       0x59, 0x8, 0xa2, 0xb6, 0x88, 0x76, 0x6c, 0xbb, 0xed, 0xb6, 
+       0x55, 0xf3, 0xa6, 0xb8, 0x20, 0x9b, 0xe8, 0x7a, 0xb4, 0xb5, 
+       0xbb, 0x70, 0xb6, 0x5c, 0x7b, 0xd1, 0x7f, 0xa5, 0x3c, 0x68, 
+       0xe7, 0xd5, 0xf2, 0xc, 0xac, 0x74, 0x6e, 0xbc, 0x97, 0x18, 
+       0x80, 0x17, 0xbb, 0xb0, 0xf8, 0xf0, 0xdf, 0xff, 0x7d, 0xfe, 
+       0xd, 0xfa, 0xb6, 0x35, 0xf1, 0xe9, 0xda, 0x8b, 0xde, 0xc0, 
+       0x6a, 0xb7, 0x81, 0x3d, 0x77, 0xee, 0x83, 0x73, 0xcf, 0x3b, 
+       0x6f, 0x26, 0xc0, 0x66, 0x60, 0xc0, 0xa3, 0xfd, 0xdf, 0x9f, 
+       0xf7, 0xc6, 0xe2, 0xdf, 0xed, 0xb4, 0xfe, 0xb8, 0xef, 0xab, 
+       0x5d, 0xe9, 0x43, 0xf4, 0xf1, 0x81, 0x39, 0xaf, 0x2f, 0x4e, 
+       0xf8, 0x5e, 0x57, 0x25, 0x6e, 0xb, 0xbd, 0xae, 0x7b, 0xa8, 
+       0xee, 0x9, 0x4e, 0x63, 0xc4, 0xfa, 0x47, 0x1c, 0x51, 0xc9, 
+       0x6d, 0xf9, 0x3c, 0xda, 0xcd, 0x97, 0xd6, 0xa3, 0x37, 0x4c, 
+       0xf3, 0xfc, 0x69, 0xa2, 0xd2, 0xe6, 0xe1, 0xba, 0xfb, 0x54, 
+       0x73, 0xcf, 0x60, 0x39, 0xe4, 0x6f, 0xaa, 0x32, 0x82, 0x1c, 
+       0x20, 0xf, 0xb1, 0x55, 0x60, 0x59, 0x71, 0xbf, 0x52, 0x46, 
+       0xad, 0x8e, 0x7a, 0xd6, 0xd7, 0xa7, 0x15, 0xb4, 0xa7, 0x90, 
+       0x6d, 0xe4, 0x7c, 0xfa, 0xb4, 0x6d, 0x92, 0x3b, 0xee, 0x7c, 
+       0x38, 0x59, 0xfa, 0xce, 0xd2, 0x60, 0xb9, 0xea, 0x7c, 0xf5, 
+       0x50, 0x7, 0x6b, 0xf9, 0x4a, 0xca, 0x92, 0x69, 0xae, 0xb7, 
+       0x5f, 0xfb, 0xaf, 0xa7, 0xbc, 0x6, 0xb7, 0xc3, 0x18, 0xa7, 
+       0x5, 0xa4, 0xca, 0x81, 0x9b, 0x4c, 0xbe, 0x89, 0x96, 0x12, 
+       0xe7, 0x8d, 0x9a, 0xf1, 0x1a, 0xf9, 0xaa, 0x7a, 0x66, 0x5, 
+       00, 0x30, 0xc5, 0xdf, 0x5b, 0xfe, 0x66, 0x32, 0x62, 0x58, 
+       0x83, 0x80, 0xbd, 0x83, 0x16, 0x63, 0xfa, 0xe7, 0x80, 0x1d, 
+       0x64, 0x50, 0x6f, 0x68, 0x35, 0x9, 0xdd, 0x59, 0x37, 0x73, 
+       0xe6, 0xcc, 0x5c, 0xac, 0xba, 00, 0xa6, 0x6a, 0xc5, 0x99, 
+       0x93, 0x50, 0x2, 0xb0, 0xe9, 0x28, 0xd2, 0x58, 0xa0, 0xd1, 
+       0xa3, 0x4, 0xc8, 0xf7, 0x6a, 0xf0, 0x70, 0x6d, 0xa0, 0x89, 
+       0xf3, 0xa8, 0x6f, 0xd, 0x83, 0x49, 0x8e, 0xf9, 0xda, 0x17, 
+       0xce, 0x8b, 0x6c, 0x2, 0xf8, 0x8c, 0x9f, 0xfd, 0xec, 0x84, 
+       0xd4, 0xa9, 0xa7, 0x9e, 0x72, 0x46, 0x44, 0xd7, 0x60, 0xee, 
+       0x9, 0xe0, 0xd8, 0x96, 0x1d, 0x7f, 0xfc, 0xe3, 0xb9, 0xd7, 
+       0x6a, 0xf0, 0x4, 0x10, 0x7b, 0x1c, 0x76, 0xd8, 0xa1, 0x8d, 
+       0x57, 0x5f, 0x7d, 0xf5, 0xda, 0x79, 0xf3, 0xe6, 0xdf, 0x3f, 
+       0x73, 0xe6, 0xb9, 0x37, 0xeb, 0x3a, 0x73, 0x6c, 0xe8, 0x5, 
+       0x60, 0x13, 0x9e, 0xfd, 0xc8, 0x82, 0x6b, 0x76, 0x1c, 0xbb, 
+       0xfe, 0xb7, 0x15, 0x6f, 0x1c, 0xad, 0xc1, 0xe0, 0x38, 0x99, 
+       0xe3, 0x67, 0xa9, 0xff, 0x16, 0xe8, 0x85, 0x88, 0xee, 0xdc, 
+       0xd6, 0x5a, 0xd3, 0xf8, 0xd1, 0x4e, 0x3b, 0x26, 0xa3, 0x72, 
+       0x8f, 0xcb, 0x78, 0xa3, 0x6b, 0xe8, 0x8e, 0x3b, 0x75, 0x77, 
+       0x4b, 0x97, 0x6b, 0x1c, 0x8a, 0xd9, 0xdc, 0xdc, 0x2f, 0xec, 
+       0x22, 0xb3, 0x45, 0x44, 0x88, 0x56, 0x77, 0x7f, 0xc2, 0xff, 
+       0x6a, 0x40, 0xd1, 0xa5, 0x10, 0x25, 0xb0, 0xa8, 0x26, 0x85, 
+       0x93, 0xd7, 0xde, 0xd0, 0xc4, 0x6b, 0x9d, 0x23, 0xec, 0x3f, 
+       0x7, 0xdc, 0xbd, 0x1, 0x38, 0xf2, 0x2c, 0xc7, 0x1b, 0xb2, 
+       0x2, 0x78, 0x46, 0xef, 0x33, 0xf4, 0xd7, 0x29, 0xb9, 0xdb, 
+       0x27, 0xb7, 0xdf, 0x31, 0x3f, 0x79, 0xe7, 0xdd, 0x25, 0x61, 
+       0x31, 0x59, 0xaf, 0x3, 0x87, 0xbd, 0xf3, 0xa5, 0xea, 0x57, 
+       0x2a, 0x4d, 0x1b, 0x7e, 0xf8, 0x70, 0x24, 0x8b, 0x6a, 0xe0, 
+       0x31, 0xf6, 0xc6, 0xa9, 0x43, 0x43, 0x29, 0x4c, 0xce, 0x4b, 
+       0xd1, 0x72, 0x46, 0x3, 0x22, 0x10, 0x93, 0xd0, 0xa9, 0xbf, 
+       0xfb, 0x13, 0xaf, 0xc8, 0x19, 0xd8, 0xcb, 0x97, 0xbd, 0x91, 
+       0xc, 0x1f, 0x56, 0x9f, 0xec, 0xbb, 0xf7, 0x8e, 0x1, 0xd8, 
+       0x41, 0xe3, 0x9, 0x7c, 0xe2, 0xa8, 0x5e, 0xd8, 0xaf, 0xcb, 
+       0x34, 0x68, 0xa8, 0x9b, 0x38, 0x61, 0x74, 0xb2, 0xe8, 0xa5, 
+       0xca, 0x34, 0x44, 0xa9, 0xc2, 0xc5, 0xc7, 0xf0, 0x85, 0x4e, 
+       0x83, 0xcf, 0xa3, 0x31, 0x56, 0x43, 0x5f, 0x69, 0x6d, 0xb, 
+       0x1, 0xa1, 0xe9, 0x13, 0xb2, 0xfb, 0x8d, 0x79, 0x11, 0x2b, 
+       0xe5, 0x7d, 0xe5, 0x22, 0x80, 0x1f, 0x24, 0x80, 0x27, 0x55, 
+       0x2, 0x1c, 0x60, 0xd3, 0xc9, 0x84, 0xed, 0xe7, 0x9c, 0x73, 
+       0xce, 0x15, 0xab, 0x56, 0xad, 0x79, 0x47, 0x56, 0xcc, 0xd1, 
+       0x3a, 0xa1, 0xf5, 0xae, 0x73, 0xce, 0xf9, 0x3, 0x2b, 0xed, 
+       0xbc, 0x8d, 0x86, 0x35, 00, 0xb8, 0x31, 0xe5, 0xd1, 0xde, 
+       0x2b, 0x9f, 0x5d, 0xb2, 0xe4, 0x83, 0xcb, 0x9f, 0x7f, 0x66, 
+       0xff, 0x4f, 0x6d, 0x34, 0xf5, 0x62, 0x75, 0xfe, 0x98, 0x29, 
+       0xc3, 0x87, 0x25, 0xa7, 0xee, 0xbe, 0x9b, 0xe, 0x39, 0x7c, 
+       0x2e, 0xb9, 0x54, 0xbb, 0xcf, 0x56, 0x31, 0x8d, 0x8a, 0x1c, 
+       0x27, 0xa7, 0x7c, 0x76, 0xb3, 0x4d, 0x13, 0xb4, 0x3c, 0x83, 
+       0x1, 0x4e, 0x6f, 0x3a, 0x24, 0x93, 0x7f, 0xf0, 0x3, 0xb4, 
+       0x41, 0x94, 0xb3, 0xe7, 0x28, 0xb, 0x47, 00, 0x99, 0x85, 
+       0x40, 0xfa, 0x2c, 0x6, 0x38, 0xfc, 0x85, 0xd7, 0x7d, 0xe1, 
+       0xa0, 0x1d, 0xf7, 0x1f, 0xf2, 0xc8, 0x6f, 0xbe, 0xbb, 0xdd, 
+       0xbf, 0xb9, 0x55, 0xc0, 0x16, 0x7a, 0x6a, 0xd4, 0xde, 0x1b, 
+       0x4a, 0x8e, 0x25, 0xcf, 0xa9, 0x86, 0x7a, 0xbe, 0x4d, 0xa1, 
+       0xbd, 0xa, 0xc, 0x1c, 0xa2, 0x3d, 0x44, 0xa, 0xd, 0xc5, 
+       0x36, 0xeb, 0xb6, 0x79, 0xc9, 0x3b, 0xcb, 0xde, 0x4c, 0xf4, 
+       0x44, 0x84, 0x2f, 0xa4, 0x4, 0xd, 0x5e, 0x49, 0x9b, 0xc0, 
+       0x9d, 0x2c, 0xe7, 0x11, 0xca, 0x6b, 0x60, 0x1b, 0xa3, 0xfc, 
+       0x76, 0xbc, 0x80, 0x54, 0x17, 0xcd, 0xcd, 0x90, 0x53, 0x90, 
+       0x23, 0x22, 0x26, 0x73, 0x66, 0xa0, 0x16, 0xa7, 0x8a, 0x2e, 
+       0x97, 0xfe, 0x9, 0xb3, 0x78, 0xdc, 0xf5, 0xee, 0x3b, 0x8b, 
+       0x93, 0xe1, 0x43, 0xd3, 0xc9, 0x3e, 0x7b, 0xed, 0x20, 0xe1, 
+       0xcf, 0x32, 0xd5, 0x20, 0x21, 0xf, 0xf4, 0x30, 0x93, 0xe, 
+       0xdc, 0x7f, 0xd7, 0xd2, 0x84, 0x2a, 0x4c, 0x3d, 0xfb, 0xb7, 
+       0x57, 0x28, 0x67, 0x53, 0x18, 0x81, 0xc3, 0xe0, 0x21, 0xa6, 
+       0x12, 0xca, 0xf1, 0x25, 0x91, 0xe2, 0x36, 0x55, 0x48, 0xb5, 
+       0x30, 0x9b, 0xeb, 0xed, 0x90, 0xfa, 0x23, 0x80, 0xef, 0xbe, 
+       0xbb, 0x4c, 0x5b, 0x4d, 0x87, 0xf7, 0x99, 0x75, 0xe0, 0x52, 
+       0x7b, 0x9, 0x70, 0xea, 0x3, 0x3, 0x40, 0xc4, 0x9a, 0x8b, 
+       0x2e, 0xba, 0xe0, 0x86, 0xc5, 0x8b, 0x17, 0xbf, 0x78, 0xdb, 
+       0x6d, 0xb7, 0x3e, 0x9f, 0x4b, 0x7, 0xa5, 0x80, 0x1b, 0x8f, 
+       0xd9, 0xf, 0xb8, 0x9, 0x57, 0x9d, 0x75, 0xdf, 0xdc, 0xa7, 
+       0xf7, 0x9c, 0x30, 0xf1, 0xf7, 0x43, 0x1a, 0x9a, 0x3e, 0xa3, 
+       0x87, 0x18, 0x53, 0x1, 0xad, 0x8e, 0x2b, 0xc6, 0x67, 0x6e, 
+       0x7e, 0xf1, 0xc5, 0x94, 0xde, 0xcd, 0x56, 0x36, 0x81, 0x58, 
+       0xfd, 0xb6, 0x6f, 0x4b, 0x4b, 0x81, 0x49, 0xd4, 0x34, 0x66, 
+       0x6c, 0x32, 0x7c, 0xd7, 0x5d, 0x92, 0x4a, 0x1e, 0x81, 0x5, 
+       0x22, 0x45, 0x7f, 0x86, 0xf, 0x1f, 0xa6, 0xef, 0x8e, 0xbd, 
+       0x90, 0x62, 0x87, 0x33, 0xfc, 0xf5, 0x1c, 0x95, 0xbe, 0x34, 
+       0xc0, 0x6b, 0x5, 0x9e, 0x8b, 0x92, 0xf5, 0x19, 0x34, 0xab, 
+       0x68, 0x4a, 0xb3, 0x76, 0x6e, 0x92, 0xa1, 0x5f, 0x53, 0xa9, 
+       0xf6, 0xe4, 0x9b, 0x5f, 0xff, 0x54, 0xcd, 0xe0, 0xa6, 0xc, 
+       0xac, 0x45, 0xe4, 0x9a, 0x10, 0xfa, 0x96, 0x97, 0xc1, 0x2, 
+       0xf8, 0x5e, 0xd2, 0xe0, 0xb3, 0x6e, 0x17, 0xc0, 0xdf, 0x7d, 
+       0x23, 0xe0, 0x83, 0xbd, 0xf9, 0x95, 0xb4, 0x7, 0x7a, 0xca, 
+       0xc7, 0x4e, 0x46, 0x83, 0x3b, 0x6, 0xb5, 0xe5, 0xdb, 0x61, 
+       0x68, 0x2a, 0x19, 0xba, 0x73, 0xbe, 0xce, 0x4d, 0xa2, 0x9d, 
+       0xee, 0xf, 0x83, 0x7b, 0x72, 0x34, 0x8, 0x60, 0xbf, 0xbd, 
+       0xf4, 0xb5, 0x64, 0xa8, 0x5e, 0xcf, 0xde, 0x5b, 0xc0, 0x1e, 
+       0x3a, 0x74, 0x60, 0xd2, 0xa1, 0xc7, 0x22, 0xf8, 0xf6, 0xe, 
+       0x2d, 0x66, 0xe4, 0xbc, 0x24, 0x3, 0x8b, 0x36, 0x7f, 0xcd, 
+       0x79, 0xaa, 0xd, 0xcd, 0x40, 0x87, 0x39, 0x60, 0x63, 0xc2, 
+       0x65, 0x34, 0x52, 0x17, 0x34, 0xba, 0xa7, 0xfa, 0x77, 0x77, 
+       0x9d, 0xb6, 0x59, 0xa3, 0x20, 0x78, 0xfc, 0x56, 0x27, 0x76, 
+       0x8c, 0x1b, 0x37, 0xbe, 0xcf, 0xca, 0x88, 0xcb, 0x37, 0xc0, 
+       0x5b, 0x5a, 0x5a, 0xd0, 0xe0, 0x3f, 0xd6, 0x35, 0xd4, 0x23, 
+       0x13, 0x51, 0x3a, 0x9a, 0x79, 0x17, 0x3e, 0x68, 0x68, 0x85, 
+       0x5e, 0x64, 0x3, 0xa4, 0x78, 0x34, 0x32, 0x2f, 0xf9, 0xf3, 
+       0xb8, 0xec, 0x5d, 0x1, 0x7b, 0xae, 0xc2, 0x77, 0x72, 0x69, 
+       0x7c, 0xc8, 0x8b, 0x74, 0xae, 0x63, 0x96, 0xb3, 0x4a, 0x8e, 
+       0x16, 0x7, 0xec, 0x6d, 0xfb, 0xff, 0xe9, 0xb2, 0x7f, 0x7f, 
+       0xee, 0x9d, 0x77, 0xbe, 0xa5, 0x38, 0x3b, 0x57, 0x48, 0xc7, 
+       0xa5, 0xf6, 0x13, 0x98, 0x67, 0xe8, 0x14, 0x15, 0x3c, 0x71, 
+       0x37, 0x1a, 0x2d, 0x5d, 0xaf, 0xd7, 0x69, 0x27, 0x7c, 0xe9, 
+       0x4b, 0xc9, 0xe8, 0x7d, 0xf6, 0xcd, 0xe6, 0xae, 0xe1, 0xaf, 
+       0xa6, 0x36, 0xa9, 0x4c, 0xa6, 0x23, 0xbc, 0x59, 0x65, 0x3e, 
+       0xbb, 0x2f, 0xdd, 0xb7, 0x84, 0xbd, 0x71, 0xb2, 0x10, 0x52, 
+       0xe2, 0x6b, 0x28, 0x83, 0xfe, 0xc3, 0xc7, 0x65, 0x58, 0x46, 
+       0xab, 0x95, 0x41, 0xe7, 0x47, 0x9e, 0xd3, 0x75, 0xe9, 0x94, 
+       0x65, 0xdc, 0x21, 0xd7, 0x87, 0xc, 0x1d, 0xa0, 0xc5, 0xe4, 
+       0xed, 0x85, 0x8b, 0x54, 0xc0, 0x7, 0x38, 0xa1, 0xfc, 0x9e, 
+       0x5c, 0x4e, 0x9, 0xd2, 0xef, 0x9e, 0x6b, 0xc7, 0xe0, 0xe6, 
+       0x76, 0x77, 0x45, 0x9e, 0x94, 0xc1, 0x9b, 0x4f, 0x88, 0x22, 
+       0xce, 0x6c, 0x22, 00, 0xa5, 0x1f, 0x85, 0x74, 0xe7, 0xa8, 
+       0x28, 0xcf, 0xf5, 0x96, 0x2e, 0x79, 0x35, 0x19, 0xaa, 0x97, 
+       0xbc, 0x30, 0x45, 0x86, 0xd, 0xb, 0xcf, 0xe9, 0xc2, 0x8, 
+       0xc6, 0x75, 0x3a, 0xc7, 0xa1, 0xd, 0x85, 0xb8, 0xe3, 0x6a, 
+       0x8d, 0x53, 0x2f, 0xd3, 0x26, 0x4e, 0x87, 0x61, 0xe6, 0xf5, 
+       0xa5, 0x59, 0xe, 0x5d, 0x1c, 0xb4, 0xed, 0x79, 0x46, 0xaf, 
+       0xef, 0x7b, 0x99, 0x5f, 0xd9, 0xc, 0x7d, 0xf8, 0xb7, 0x6, 
+       0x80, 0x3, 0xd0, 0x60, 0x66, 0x2b, 0x4, 0xb8, 00, 0x18, 
+       0xf, 0xa0, 0xe3, 0xd0, 0x73, 0x6d, 0xf2, 0x72, 0xf, 0x1e, 
+       0xb5, 0xcc, 0x20, 0x91, 0xfa, 0xe2, 0xd, 0x37, 0x2c, 0xd8, 
+       0xf9, 0x82, 0xb, 0xb7, 0x7a, 0xe9, 0xbd, 0x15, 0xa7, 0xaf, 
+       0x6a, 0x6c, 0x5c, 0xda, 0x5e, 0xdf, 0xd0, 0x5, 0x55, 00, 
+       0xba, 0xff, 0xc4, 0x89, 0xc9, 0xfa, 0x47, 0x1e, 0x99, 0x6c, 
+       0xfe, 0x9b, 0x7f, 0xe, 0x71, 0xdd, 0x5b, 0xb3, 0xd3, 0x7e, 
+       0x4, 0x7d, 0x16, 0xb8, 0x1f, 0x87, 0xfc, 0x7, 0xfe, 0x22, 
+       0x27, 0xf0, 0xd9, 0x3, 0x29, 0xfd, 0xdb, 0x5b, 0xc7, 0xc2, 
+       0x22, 0xb, 0x75, 0xd0, 0xb6, 0x87, 0x66, 0x90, 0x3b, 0xcd, 
+       0x66, 0x2c, 0x9b, 0xbd, 0x91, 0x43, 0xe8, 0x95, 0xa3, 0x83, 
+       0xa2, 0x63, 0x51, 0x19, 0x7c, 0x80, 0x13, 0xf0, 0x42, 0xde, 
+       0xee, 0x1c, 0x4a, 0x55, 0x16, 0x6e, 0x76, 0x75, 0x31, 0xb, 
+       0x64, 0xe4, 0xcd, 0xbe, 0x24, 0x8e, 0xcb, 0x21, 0xd5, 0x37, 
+       0xc5, 0x21, 0x9a, 0x5b, 0x53, 0xac, 0xf2, 0x9a, 0x9b, 0xa, 
+       0xb2, 0x57, 0xfc, 0xcd, 0x37, 0x5f, 0xd6, 0x1c, 0x23, 0xa3, 
+       0x11, 0x6a, 0x3b, 0xed, 0xd6, 0x1a, 0x28, 0xa6, 0xf9, 0x9d, 
+       0x56, 0x80, 0xcd, 0xfc, 0x86, 0xc7, 0x1, 0xa4, 0xe1, 0xa9, 
+       0x57, 0x36, 0xbd, 0xbb, 0xc6, 0xf5, 0x7c, 0xad, 0xb0, 0xd3, 
+       0x11, 0x8, 0x3a, 0x47, 0xc, 0x49, 0xf5, 0x25, 0xb8, 0x8b, 
+       0x3b, 0x9c, 0x72, 0xc4, 0x97, 0xf0, 0xd1, 0xf7, 0x9e, 0xeb, 
+       0x58, 0x7b, 0xe, 0x3, 0x5c, 0x8b, 0x6c, 0x95, 0xce, 0xc1, 
+       0xad, 0xcd, 0x6d, 0x7e, 0xb3, 0x10, 0x4a, 0x7f, 0xe2, 0x60, 
+       0x96, 0x41, 0xcc, 0xdc, 0x1b, 0x30, 0x93, 0x8f, 0xd0, 0x52, 
+       0x86, 0x86, 0x40, 0x3e, 0x9a, 0x9f, 0xfd, 0xd8, 0xf6, 0x93, 
+       0xdf, 0x1f, 0x37, 0x6e, 0xc0, 0x1, 0x3b, 0x6e, 0x9f, 0x4a, 
+       0xaf, 0xd1, 0xf6, 0x50, 0xb6, 0xa1, 0x8a, 0xb7, 0x8d, 0x3a, 
+       0xac, 0xb1, 0x5e, 0xf3, 0xe4, 0x7e, 0x1b, 0x4c, 0x50, 0xb6, 
+       0xbe, 0x71, 0xf4, 0x95, 0x56, 0xf8, 0xc3, 0x62, 0x17, 0x80, 
+       0x36, 0xa8, 0x91, 0xad, 0x18, 0x2c, 0x56, 0xa, 0xb5, 0x94, 
+       0x4a, 0x19, 0x92, 0xe3, 0x14, 0x8f, 0xdc, 0xdc, 0x9f, 0x96, 
+       0x17, 0xda, 0x65, 0x79, 0xed, 0x64, 0x57, 0x75, 0xa5, 0xc8, 
+       0x58, 0xd4, 0xd, 0xb1, 0xac, 0xa7, 0x55, 0x77, 0x59, 0xa7, 
+       0xe2, 0x2c, 0xd7, 0x52, 0xa9, 0xba, 0x80, 0x8b, 0xbd, 0xf6, 
+       0xdc, 0x36, 0xb9, 0x65, 0xd6, 0xfc, 0xe4, 0x2d, 0xe1, 0xe5, 
+       0xa1, 0x87, 0x52, 0x61, 0xf7, 0x9f, 0x64, 0xa9, 0x64, 0x61, 
+       0x39, 0xa5, 0xca, 0x22, 0x6, 0x19, 0xf0, 0xf4, 0xa5, 0x43, 
+       0x45, 0xb3, 0x40, 0x17, 0x5f, 0x64, 0xf9, 0x64, 0x47, 0xc0, 
+       0xee, 0xc0, 0xed, 0x1b, 0x8, 0x71, 0x10, 0x6b, 0x2e, 0xa7, 
+       0xb9, 0x61, 0xfc, 0xc3, 0x3a, 0x96, 0xe7, 0x8d, 0xc5, 0x2f, 
+       0x9, 0xd8, 0x1d, 0xc9, 0xde, 0xd3, 0x3f, 0xa6, 0xc7, 0x5e, 
+       0xb2, 0xc9, 0x3, 0xb3, 0xb2, 0xab, 0x91, 0x2c, 0x2c, 0xe0, 
+       0x49, 0xb, 0xe9, 0x8a, 0x77, 0xc8, 0x3c, 0x3f, 0xed, 0x8c, 
+       0xff, 0xd6, 0xf1, 0xb3, 0xef, 0x63, 0x19, 0x24, 0x3f, 0x3e, 
+       0xf6, 0xb, 0x6a, 0xf8, 0xe0, 0xf0, 0xfb, 0xd4, 0x33, 0xce, 
+       0x57, 0xfe, 0x8c, 0x9e, 0x7f, 0xe, 0x4b, 0x8e, 0xfd, 0xc1, 
+       0x67, 0xc3, 0xf5, 0x50, 0x93, 0x92, 0x7f, 0xb2, 0x65, 0x58, 
+       00, 0xc8, 0x92, 0x6b, 0x63, 0x98, 0xd3, 0x97, 0xbc, 0xa5, 
+       0x8a, 0x44, 0xb, 0x81, 0x43, 0x84, 0xa1, 0x53, 0xe0, 0xf4, 
+       0x4a, 0x97, 0x34, 0xd8, 0xba, 0x76, 0xdd, 00, 0x1c, 0x69, 
+       0x42, 0xeb, 0xe2, 0x3c, 0xcf, 0xa6, 0xe3, 0x1, 0x2a, 0xa0, 
+       0x65, 0x44, 0xe6, 0x3a, 0x80, 0xa5, 0x1f, 0xd, 0x6e, 0x3, 
+       0x9c, 0xdf, 00, 0x9b, 0x10, 0x87, 0x5c, 0x4, 0x60, 0xeb, 
+       0xa0, 0x85, 0x13, 0xf5, 0x14, 0x22, 0x7f, 0xd0, 0x42, 0xb8, 
+       0xba, 0xe, 0xff, 0xc0, 0x47, 0x4, 0x1c, 0x50, 0x1b, 0x70, 
+       0xe6, 0xb9, 0xfb, 0xd6, 0xfd, 0x5a, 0x6b, 0x35, 0xa0, 0x8f, 
+       0x87, 0xbe, 0xcb, 0xc8, 0xd3, 0xca, 0xc9, 0x66, 0x90, 0xd1, 
+       0x7c, 0x62, 0x61, 0xe4, 0xc5, 0x45, 0xaf, 0x27, 0xe7, 0xfd, 
+       0xf7, 0xd, 0x21, 0xf1, 0xa7, 0xc7, 0x7f, 0x51, 0x56, 0x40, 
+       0xe7, 0xc2, 0xe1, 0xfd, 0xf, 0x3c, 0x9e, 0x5c, 0x71, 0xf5, 
+       0x9d, 0xe1, 0x9d, 0xfe, 0x49, 0x13, 0x47, 0x27, 0xfb, 0xef, 
+       0xbb, 0x43, 0x90, 0xf9, 0x5b, 0x67, 0xcd, 0x4b, 0x1e, 0x59, 
+       0xb0, 0x30, 0xc8, 0xf0, 0x61, 0x7, 0x7f, 0x22, 0xd9, 0x6a, 
+       0xcb, 0xc9, 0x1, 0x1f, 0x7b, 0x4f, 0xdf, 0x2e, 0xb9, 0xf5, 
+       0xf6, 0xf9, 0x1, 0x37, 0xf, 0x3f, 0x9c, 0x4a, 0xf4, 0x38, 
+       0x35, 0xd4, 0xad, 0xb0, 0x44, 0x75, 0x46, 0x76, 0xce, 0x6d, 
+       0x70, 0xd3, 0x87, 0xf8, 0xd8, 0x15, 0xff, 0xe, 0xc8, 0x8f, 
+       0x33, 0x94, 0x8a, 0x9b, 0x10, 0x61, 0x63, 0x29, 0xcd, 0xd, 
+       0xb3, 0xd9, 0x43, 0xbb, 0xf8, 0xf5, 0x45, 0xc9, 0xe0, 0x81, 
+       0xed, 0xda, 0x79, 0xb6, 0xad, 0xe, 0xc7, 0x1c, 0x12, 0xc0, 
+       0xe5, 0x8e, 0x29, 0x15, 0xd2, 0x59, 0x5a, 0x2d, 0x4f, 0xb6, 
+       0xd9, 0x7a, 0x4a, 0x58, 0x64, 0xb8, 0xf5, 0xb6, 0x7, 0x93, 
+       0xb3, 0x7f, 0x7b, 0x79, 0xb8, 0xef, 0x9c, 0x3f, 0x5e, 0x9b, 
+       0xdc, 0x3a, 0xeb, 0xc1, 0x90, 0xbe, 0xe3, 0xe, 0x9b, 0x86, 
+       0x7a, 0x95, 0xa2, 0x41, 0x5a, 0xb6, 0xd3, 0xb3, 0x55, 0x8f, 
+       0xf3, 0x90, 0x8e, 0x2b, 0x37, 0x1a, 0x66, 0xef, 0xa8, 0xfe, 
+       0x2f, 0x65, 0xe0, 0xa0, 0xcf, 0xe8, 0xf, 0xfd, 0x52, 0x7c, 
+       0xa9, 0x9e, 0x72, 0xcf, 0x77, 0x18, 0xe0, 0x2d, 0x9a, 0x83, 
+       0x9f, 0x70, 0xc2, 0x89, 0xc7, 0xeb, 0xe, 0xe6, 0xde, 0x78, 
+       0x34, 0x73, 0xc, 0x5e, 0xc0, 0xca, 0xa3, 0x2e, 0x7c, 0x58, 
+       0x28, 0x53, 0x88, 0xf9, 0x6d, 0xef, 0x34, 0xe7, 0x89, 0x7, 
+       0x5, 0xe8, 0x34, 0x9d, 0x7a, 0xea, 0x2f, 0x4f, 0xf8, 0x30, 
+       0x81, 0xad, 0x32, 0x3, 0x1f, 0x19, 0xe4, 0x31, 0xcb, 0xad, 
+       0xb5, 0x9, 0xdd, 0xaf, 0xe4, 0xe9, 0xad, 0x63, 0x1, 0x17, 
+       0x67, 0xd9, 0xc9, 0xca, 0x4f, 0xb6, 0x4f, 0xf9, 0xeb, 0x74, 
+       0x97, 0x59, 0x1c, 0x2e, 0x59, 0xb2, 0x2c, 0xb9, 0xee, 0x86, 
+       0x7b, 0x83, 0xd7, 0x61, 0x13, 0xf9, 0xba, 0x91, 0x6f, 0xbb, 
+       0x6d, 0xa7, 0x24, 0xb, 0x17, 0xbe, 0x96, 0xdc, 0xff, 0xc0, 
+       0x93, 0xa9, 0x3f, 0x5f, 0x7e, 0x57, 0xf2, 0xe6, 0x5b, 0xef, 
+       0xea, 0x95, 0xd8, 0xf7, 0x92, 0x99, 0xe7, 0xdf, 0x9c, 0xdc, 
+       0x77, 0xff, 0x13, 0x3a, 0xc4, 0x63, 0x59, 0xb2, 0xe9, 0x26, 
+       0x1b, 0xe6, 0xef, 0x1, 0x27, 0x6c, 0xc1, 0x6, 0x37, 0xe0, 
+       0x7, 0x1c, 0x41, 0xa7, 0xd8, 0xe5, 0xe4, 0xb, 0x70, 0x1b, 
+       0x8f, 0x64, 0x71, 0x9c, 0xb0, 0x8b, 0x63, 0x74, 0xef, 0xce, 
+       0xc5, 0x37, 0xa3, 0xee, 0x9b, 0x8a, 0x35, 0x37, 0x15, 0xa1, 
+       0x42, 0xaf, 0xbd, 0xb6, 0x48, 0xaf, 0xba, 0xb5, 0x69, 0x47, 
+       0xce, 0x36, 0xd2, 0xb4, 0x43, 0xf3, 0x95, 0xe7, 0x7a, 0xb1, 
+       0x87, 0x99, 0xf6, 0x5c, 0x3b, 0x70, 0xff, 0x8f, 0x27, 0xbb, 
+       0xee, 0xb2, 0x65, 0xa8, 0xc7, 0xd5, 0xd7, 0xde, 0x9d, 0xdc, 
+       0x7e, 0xe7, 0xfc, 0xe4, 0x4f, 0x97, 0xcd, 0xa, 0xbf, 0xf, 
+       0xd8, 0xef, 0xe3, 0xc9, 0xee, 0x9f, 0xd8, 0xa6, 0xb, 0x8d, 
+       0x62, 0x9a, 0x9d, 0x4a, 0xa7, 0x4b, 0xe7, 0x70, 0xf4, 0x4d, 
+       0x77, 0x6d, 0xac, 0xe8, 0x9a, 0xcb, 0x73, 0xbd, 0x1d, 0x2, 
+       0x6e, 0xb, 0x4b, 0x45, 0x84, 0xfa, 0x20, 0x93, 0x1, 0x3e, 
+       0x71, 0xe2, 0x44, 0xbd, 0x2e, 0x7a, 0x12, 00, 0x67, 0x2e, 
+       0x46, 0xc7, 0xd3, 0x50, 0xf7, 0x29, 0x12, 0x2, 0x60, 0xd1, 
+       0xdc, 0x98, 0xde, 0x80, 0x18, 0xed, 0xed, 0x45, 0x33, 0x7e, 
+       0xc7, 0xa6, 0x38, 0xf9, 0xe9, 0x6f, 0x24, 0xbf, 0x51, 0xc0, 
+       0x3e, 0xb1, 0xbb, 0x83, 0x16, 0x94, 0x67, 0x9d, 0x39, 0xf8, 
+       0xb9, 0x56, 0xe7, 0x98, 0xe3, 0xc, 0x6c, 0xf8, 0x6d, 0x47, 
+       0x5f, 0xf4, 0xc6, 0x79, 0x20, 0x36, 0x4d, 0xf7, 0x6d, 0xa0, 
+       0x2b, 0xda, 0xa4, 0xc7, 0x69, 0x5d, 0xe2, 0x79, 0x3, 0x7, 
+       0xa9, 0x2b, 0x94, 0x6f, 0xe, 0x4, 0x3e, 0xf1, 0x67, 0x7f, 
+       0x2f, 0xd, 0x9d, 0xe8, 0x59, 0x7a, 0x87, 0xe4, 0x78, 0x76, 
+       0x2, 0xc8, 0xd7, 0xac, 0x69, 0x95, 0xf6, 0xad, 0x4b, 0xbe, 
+       0xf7, 0x6d, 0x56, 0xe2, 0x79, 0x42, 0xd6, 0x79, 0x1f, 0x78, 
+       0x1, 0x37, 0xe0, 0xe7, 0xb5, 0x57, 0x5f, 0x2c, 0x9, 0x70, 
+       0x64, 0x58, 0xf7, 0x60, 0x81, 0x19, 0x93, 0xf4, 0x33, 0xde, 
+       0xbf, 0xbb, 0xb0, 0xc4, 0x82, 0xd0, 0xe5, 0x42, 0xee, 0x46, 
+       0xa7, 0x9b, 0x80, 0x1e, 0xe1, 0x15, 0x2, 0x45, 0x2f, 0x30, 
+       0x24, 0xaf, 0xbe, 0xb2, 0x30, 0x19, 0xd8, 0x6f, 0x6d, 0x6e, 
+       0x2f, 0xed, 0xb0, 0x82, 0x8a, 0xbb, 0x11, 0x8c, 0x70, 0xf, 
+       0x3d, 0xf2, 0x5c, 0xf2, 0xf0, 0x23, 0xcf, 0x27, 0x8f, 0x3c, 
+       0xfa, 0x42, 0xf2, 0xe8, 0x63, 0xb, 0x93, 0xc7, 0x1e, 0x7f, 
+       0x51, 0x79, 0xb3, 0x8c, 0xfc, 0xe9, 0xf1, 0x7f, 0x97, 0xc, 
+       0xe8, 0xdf, 0x1c, 0xee, 0x3d, 0xee, 0x27, 0xff, 0xa9, 0x4e, 
+       0x6d, 0xf, 0x66, 0xcb, 0x8f, 0xbe, 0x7f, 0x74, 0x49, 0x7a, 
+       0xa6, 0xdb, 0x19, 0xba, 0xaa, 0x59, 0x70, 0x93, 0x4e, 0x27, 
+       0x31, 0x5, 0xe9, 0x2b, 0xcd, 0xdd, 0x59, 0x56, 0xa7, 00, 
+       0xd0, 0xae, 0xbe, 0xa2, 0xdf, 0xd9, 0x82, 0x9e, 0x63, 0x9d, 
+       00, 0xdf, 0xf0, 0xe0, 0x13, 0x4f, 0x3c, 0xf9, 0x78, 0xed, 
+       0xfb, 0x1f, 0xa4, 0xbb, 0xe8, 0x7c, 0x3a, 0x88, 0xfe, 0x2a, 
+       0x6, 0x37, 0xc0, 0xb6, 0x96, 0x26, 0x34, 0xe0, 0xd1, 0xf0, 
+       0xc, 0x2, 0x38, 0x80, 0xdd, 0x70, 0xea, 0xa9, 0xa7, 0x9d, 
+       0xf4, 0x51, 0x1, 0x3b, 0x54, 0xa2, 0xe, 0x93, 0x39, 0xfb, 
+       0x24, 0xc2, 0x3c, 0x2f, 0x6, 0x1c, 0xf9, 0x6a, 0x75, 0x58, 
+       0x6, 0x38, 0xd3, 0x74, 0x48, 0x5a, 0x31, 0x58, 0x5d, 0x7e, 
+       0x1c, 0x4a, 0x20, 0xc9, 0x1a, 0x5c, 0x9c, 0xee, 0xf8, 0x96, 
+       0x9b, 0x4f, 0x4a, 0xe, 0x3a, 0x60, 0xe7, 0x70, 0xfd, 0xc1, 
+       0xf9, 0xcf, 0x25, 0x77, 0xde, 0xf5, 0x68, 0x88, 0x7f, 0xe6, 
+       0xa8, 0x69, 0x7a, 0xbd, 0x79, 0x64, 0xbe, 0x5c, 0xe7, 0x27, 
+       0x5c, 0x6f, 0xf4, 0xb0, 0x80, 0x9f, 0x81, 0xfd, 0x5b, 0x3, 
+       0x9e, 0xc0, 0x55, 0xec, 0x72, 0xb8, 0x33, 0xf8, 0xb2, 0xd, 
+       0xc8, 0x66, 0x28, 0x17, 0xf, 0x82, 0x10, 0xd3, 0x28, 0x15, 
+       0xcf, 0xdf, 0x2c, 0x26, 0xf0, 0x41, 0x82, 0x7c, 0x1e, 0x46, 
+       0x55, 0xed, 0x79, 0x4e, 0xfa, 0xf7, 0x5b, 0x93, 0x6c, 0xba, 
+       0xe9, 0x86, 0xc9, 0xe8, 0xf5, 0x86, 0x86, 0x47, 0x5a, 0xf9, 
+       0xc, 0xb9, 0x8, 0x95, 0x7f, 0x6f, 0xc5, 0xfb, 0xc9, 0xcf, 
+       0x4e, 0xfa, 0x63, 0xc1, 0x25, 0x5e, 0x1a, 0xb9, 0xe4, 0x82, 
+       0xa9, 0xe1, 0x1e, 0x46, 0xaf, 0xef, 0x7c, 0xfb, 0xc8, 0xe4, 
+       0xf4, 0x5f, 0x5d, 0xa8, 0xc6, 0x67, 0x99, 0xf7, 0xe3, 0xe3, 
+       0x3e, 0x9f, 0xc, 0x1c, 0xd4, 0xaf, 0x24, 0xcd, 0x98, 0x10, 
+       0xf4, 0x43, 0xb7, 0xe4, 0x98, 0x9e, 0xfd, 0x2d, 0x89, 0xcd, 
+       0x2e, 0x76, 0xc5, 0x59, 0x7b, 0x1d, 0x37, 0x6d, 0x42, 0x84, 
+       0x82, 0x35, 0x83, 0xf, 0x5b, 0x73, 0xbb, 0x11, 0x6, 0xb8, 
+       0xde, 0xd6, 0x3a, 0xf4, 0xab, 0x5f, 0xfd, 0xea, 0x6b, 0xa7, 
+       0x9f, 0x7e, 0xfa, 0x39, 0xba, 0x86, 0xca, 0xf3, 0xa0, 0x8d, 
+       0xba, 0x83, 0x39, 0x9d, 0x6a, 0x4f, 0x3f, 0x4a, 0xb8, 0xd0, 
+       0xc7, 0xfa, 0xda, 0x4b, 0xbd, 0xbe, 0x6a, 0xd2, 0xb2, 0xfe, 
+       0xfa, 0x63, 0x3f, 0x53, 0xee, 0x68, 0xa4, 0x12, 0xf7, 0xf6, 
+       0x79, 0x92, 0x16, 0xd4, 0xc2, 0x80, 0xee, 0xf9, 0x70, 0xcc, 
+       0x73, 0xc7, 0x7b, 0x5b, 0x28, 00, 0xcf, 0xf6, 0x5f, 0x21, 
+       0x6b, 0x42, 0xbf, 0x4a, 0xe1, 0x4, 0xae, 0x75, 0x62, 0x38, 
+       0x39, 0xea, 0xe8, 0x13, 0x92, 0x57, 0x5f, 0xcb, 0x6e, 0xb2, 
+       0x8a, 0xeb, 0xb0, 0xd7, 0x7e, 0xdf, 0xcd, 0x57, 0x85, 0x67, 
+       0xd8, 0xbf, 0x38, 0xf9, 0x2b, 0xe1, 0xf7, 0x67, 0x3e, 0xfd, 
+       0xc9, 0xe4, 0x81, 0x39, 0x4f, 0xea, 0xbd, 0xf8, 0xf7, 0xc2, 
+       0x58, 0x30, 0x69, 0xd2, 0xd8, 0xe4, 0xe0, 0x19, 0x1f, 0xf, 
+       0xb2, 0x9c, 0x62, 0xa7, 0x75, 0x56, 0x64, 0xf3, 0xf7, 0x12, 
+       0x1, 0x3f, 0x9b, 0x6e, 0xba, 0x41, 0xb2, 0xe0, 0xf1, 0x97, 
+       0x2, 0xae, 0x74, 0x2, 0x6e, 0x98, 0x6b, 0x73, 0xd, 0xdc, 
+       0xa9, 0xbe, 0xc, 0xbe, 0xc6, 0xa3, 0x43, 0x2e, 0x13, 0x8f, 
+       0x7f, 0x93, 0x96, 0x17, 0x82, 0xf0, 0xa3, 0xc4, 0x1f, 0xdf, 
+       0x10, 0x42, 0x35, 0xca, 0xbf, 0x43, 0x56, 0x46, 0x13, 0x9d, 
+       0xc8, 0x99, 0xac, 0x5e, 0xd3, 0xa4, 0xa3, 0x65, 0x5e, 0xd2, 
+       0x88, 0xa3, 0x2d, 0x8a, 00, 0xac, 0x9c, 0x2f, 0x51, 0x40, 
+       0x9c, 0x77, 0xec, 0x7a, 0xc3, 0xb, 0x72, 0xc, 0xd1, 0xa6, 
+       0x97, 0xf8, 0x7a, 0xf7, 0xf1, 0xec, 0xad, 0x74, 0x98, 0x5d, 
+       0xdc, 0x9, 0x4e, 0xeb, 0x6d, 0x8, 0xcd, 0xd8, 0xc7, 0xe5, 
+       0xf5, 0x96, 0x76, 0x2d, 0xf7, 0x67, 0x5, 0x94, 0xfd, 0xed, 
+       0x6d, 0x88, 0xb, 0x23, 0x3b, 0xa3, 0xaf, 0xcd, 0x35, 0x48, 
+       0x92, 0x8e, 0x66, 0x2e, 0xe5, 0xb9, 0x66, 0x97, 0xd2, 0x7, 
+       0x7, 0x53, 0x13, 0x27, 0x4e, 0xfa, 0xb2, 0x6, 0xed, 0xb0, 
+       0x5a, 0xed, 0xb, 0x1f, 0x76, 0x18, 0xf3, 0xd7, 0xf1, 0x6c, 
+       0x3b, 0x3b, 0xcd, 0xe5, 0xbe, 0xa8, 0x13, 0xb4, 0xed, 0x1c, 
+       0xf, 0x49, 0x25, 0xe4, 0x17, 0x4b, 0xd2, 0x5e, 0xaf, 0xa6, 
+       0xfa, 0xb6, 0x7c, 0x5a, 0xb8, 0x26, 0x65, 0x62, 0x19, 0x6d, 
+       0x94, 0x9, 0x3e, 0x48, 0x8a, 0xc9, 0x6e, 0x60, 0xff, 0xa6, 
+       0x2c, 0xd8, 0x4a, 0xd0, 0xf6, 0x3d, 0xe0, 0x7, 0x1c, 0x81, 
+       0x27, 0x70, 0x55, 0x6c, 0x25, 0xe7, 0x68, 0x81, 0x41, 0x7b, 
+       0x93, 0x2f, 0x19, 0x5a, 0xcd, 0x97, 0xbc, 0x58, 0x9c, 0x28, 
+       0xf3, 0x53, 0xeb, 0x1c, 0xad, 0x52, 0x18, 0x9d, 0xdb, 0xcb, 
+       0x19, 0x5d, 0x60, 0xfc, 0xc2, 0x85, 0xdd, 0x20, 0xed, 0x45, 
+       00, 00, 0x20, 00, 0x49, 0x44, 0x41, 0x54, 0xcf, 0x24, 
+       0xb3, 0xef, 0x5e, 0x90, 0x7c, 0x72, 0xb7, 0x2d, 0x93, 0x71, 
+       0xeb, 0x8f, 0x2c, 0xb8, 0x15, 0xc6, 0xd, 0xd4, 0x1b, 0x60, 
+       0xbf, 0x3f, 0xfb, 0xbb, 0xf9, 0x15, 0xca, 0x76, 0x69, 0xfd, 
+       0xb5, 0xad, 0xfa, 0xda, 0xa6, 0xee, 0xc5, 0xbf, 0xff, 0xc1, 
+       0xea, 0xe4, 0x97, 0x67, 0x5c, 0x50, 0x70, 0xdf, 0x2f, 0x4e, 
+       0x3b, 0x3f, 0xb9, 0xe8, 0xbc, 0x9f, 0xe9, 0x18, 0xa6, 0xce, 
+       0xd5, 0xc8, 0x82, 0xc, 0xb9, 0x1f, 0x41, 00, 0x82, 0xc, 
+       0x17, 0x5e, 0xc5, 0x5c, 0x5e, 0x17, 0xe0, 0x8b, 0x69, 0xa2, 
+       0x1, 0x30, 0x21, 0x3f, 0xa, 0xc7, 0x4b, 0x20, 0x3a, 0x79, 
+       0x65, 0x8d, 0xb6, 0x94, 0x5e, 0xf3, 0xbb, 0xdf, 0xfd, 0xf6, 
+       0x26, 0xd5, 0xc1, 0x73, 0xb2, 0x78, 0x84, 0xf, 0x12, 0x2c, 
+       0x1e, 0x75, 0x4a, 0xa4, 0x32, 0xaa, 0xde, 0x8, 0x8, 0xd7, 
+       0xf0, 0xc4, 0x19, 0x10, 0xea, 0xfe, 0xf9, 0x9f, 0xcf, 0xfa, 
+       0xf5, 0x37, 0xbe, 0xf1, 0xcd, 0x56, 0x1d, 0x9b, 0xfc, 0x79, 
+       0x69, 0xef, 0x66, 0x9e, 0x9, 0x7f, 0xd8, 0xe, 0x6b, 0x28, 
+       0xf4, 0xa9, 0xe4, 0xc6, 0x61, 0x5f, 0xd7, 0x1, 0xba, 0xb0, 
+       0x20, 0xa6, 0x4f, 0x1c, 0xa0, 0x5, 0x99, 0x54, 0x81, 0x81, 
+       0x71, 0xb9, 0x82, 0xbf, 0x27, 0xab, 0xf2, 0x3, 0xc9, 0x28, 
+       0x6e, 0xe1, 0xa2, 0xc5, 0xc9, 0xf9, 0x17, 0xc0, 0xee, 0x24, 
+       0xf9, 0xe9, 0xf1, 0x9f, 0xcf, 0xcb, 0xe7, 0x18, 0x29, 0xa7, 
+       0xf0, 0x34, 0x48, 0xe9, 0x37, 0xdc, 0x38, 0x37, 0x59, 0xf8, 
+       0xe2, 0x9b, 0x21, 0xf, 0x7f, 0x16, 0x3c, 0xbe, 0x48, 0x5b, 
+       0x4f, 0x1f, 0xd2, 0x16, 0xec, 0xed, 0x13, 0x9d, 0x1a, 0x92, 
+       0x67, 0xbc, 0x33, 0xbc, 0xf6, 0xfa, 0x52, 0xe1, 0xe7, 0xb1, 
+       0xe4, 0xfd, 0xd5, 0xcd, 0xfa, 0x4a, 0xcd, 0xd4, 0x4, 0x5c, 
+       0xc5, 0x8e, 0x5, 0x46, 0xc9, 0xb3, 0xa7, 0x4f, 0xf1, 0xa5, 
+       0xb2, 0x71, 0x9b, 0x6f, 0x65, 0x33, 0xc4, 0x17, 0xc4, 0xc, 
+       0xc0, 0x1d, 0x27, 0x85, 0xf8, 0x16, 0x5b, 0x6c, 0x91, 0xb4, 
+       0xb4, 0x4c, 0x9, 0x15, 0xa3, 0x82, 0xaf, 0x2f, 0x5e, 0xaa, 
+       0xca, 0x17, 0xfe, 0x4b, 0xeb, 0xe5, 0x85, 0x31, 0x63, 0x86, 
+       0x5, 0xbf, 0x9e, 0xcc, 0xf, 0x4c, 0x90, 0x51, 0xa3, 0x86, 
+       0x4, 0x33, 0x85, 0x9c, 0xff, 0x76, 0xf6, 0xff, 0x84, 0x95, 
+       0x45, 0x8, 0x7e, 0xf6, 0xd3, 0x7b, 0x5, 0xba, 0xaf, 0x68, 
+       0x24, 0xfb, 0xfd, 0x39, 0xd7, 0x16, 0x51, 0x2a, 0xa4, 0xeb, 
+       0x5f, 0x85, 0x5d, 0x11, 0x6e, 0xf7, 0x5c, 0x38, 0x6c, 0x31, 
+       0xcc, 0xa6, 0xf4, 0xed, 0x5f, 0x84, 0x1, 0x93, 0x3c, 0x1e, 
+       0xc9, 0xfb, 0xb6, 0x84, 0xf2, 0xd4, 0x72, 0xc0, 0x5e, 0xbb, 
+       0x60, 0xc1, 0xe3, 0xb7, 0xfe, 0xe6, 0x37, 0x67, 0x5d, 0xa6, 
+       0xb7, 0xd2, 0xc, 0x52, 0x80, 0x8d, 0x3, 0xb0, 0x76, 0xb1, 
+       0x9c, 0x3a, 0xcd, 0xa1, 0xf3, 0x11, 0xa6, 0x74, 0x10, 0x44, 
+       0xc7, 0x2f, 0x7f, 0x79, 0xca, 0xb9, 0x1a, 0x30, 0x74, 0xde, 
+       0xc3, 0x95, 0x6b, 0x7c, 0x86, 0x9a, 0x33, 0x7f, 0x18, 0x61, 
+       0x96, 0x9f, 0xae, 0x56, 0xdf, 0x97, 0xc8, 0xe0, 0xac, 0xbe, 
+       0x2b, 0x28, 0x20, 00, 0x5b, 0x45, 0x21, 0x4f, 0xec, 0x24, 
+       0xb3, 0x5c, 0x39, 0xfc, 0xc4, 0xae, 0x5b, 0x26, 0xfb, 0xec, 
+       0xbd, 0x43, 0xf0, 0x3b, 0x7c, 0x6c, 0x6a, 0xbe, 0x52, 0x7b, 
+       0xee, 0xa1, 0xef, 0x8f, 0xe7, 0xd2, 0xb7, 0xda, 0x6a, 0x72, 
+       0xb8, 0xef, 0xe5, 0x57, 0xdf, 0x4c, 0x2e, 0xb9, 0xec, 0xce, 
+       0x90, 0x67, 0x8b, 0xcd, 0x26, 0x48, 0xd9, 0x65, 0x2d, 0xd2, 
+       0xb, 0x2e, 0xbe, 0x4d, 0x6f, 0x86, 0x2d, 0xef, 0x42, 0x1b, 
+       0xbc, 0x18, 0xd8, 0xe0, 0x8, 0x3c, 0x15, 0x3b, 0xa6, 0xc0, 
+       0x72, 0xfc, 0x9, 0xfd, 0x54, 0x7c, 0xbd, 0xd4, 0xef, 0xaa, 
+       0xc0, 0x2d, 0x2, 0x6b, 0x99, 0x7, 0x95, 0x72, 0x9c, 0xd0, 
+       0xb1, 0xe1, 0x86, 0x1b, 0x9, 0xe0, 0x4d, 0x5a, 0x40, 0x58, 
+       0x90, 0x2c, 0x6, 0xe0, 0x30, 0xa9, 0x1b, 0x1f, 0x58, 0x29, 
+       0x26, 0xcf, 0x99, 0xfb, 0x44, 0x72, 0xcd, 0x75, 0xf7, 0x6, 
+       0xb2, 0xfb, 0xef, 0xbb, 0x63, 0xf2, 0xed, 0x6f, 0x1e, 0x96, 
+       0x6c, 0xb9, 0x45, 0x4b, 0xf8, 0x7d, 0xe9, 0x65, 0xb7, 0x69, 
+       0xe1, 0xed, 0x85, 0x6e, 0xe9, 0x64, 0xcb, 0x28, 0x55, 0x2b, 
+       0x71, 0x42, 0xb, 0x6a, 0x39, 0xc6, 0x94, 0xce, 0xd0, 0xcb, 
+       0x54, 0xe6, 0x87, 0xe5, 0x78, 0xd2, 0x4b, 0xd2, 0x65, 0x6f, 
+       0x37, 0xb0, 0x1f, 0x7a, 0xe8, 0xe1, 0xbb, 0xce, 0x3e, 0xfb, 
+       0xdf, 0xaf, 0x51, 0x46, 0x83, 0xd7, 0x21, 0xf7, 0xc6, 0xf1, 
+       0xb2, 0xb4, 0x72, 0x17, 0x2c, 0xe8, 0x16, 0x9c, 0xd4, 0xaf, 
+       0x7f, 0x7d, 0xe6, 0x45, 0x4f, 0x3c, 0xf1, 0xe4, 0xf5, 0x2, 
+       0xf8, 0xda, 0xf, 0x1b, 0xe0, 0xf0, 0x93, 0x95, 0xe5, 0x75, 
+       0xe5, 0x90, 0x7, 0xe4, 0xa2, 0x34, 0x7d, 0xc1, 0xb9, 0x1b, 
+       0x99, 0xcd, 0x5e, 0xeb, 0xbc, 0xb5, 0x38, 0x2f, 0x56, 0xdc, 
+       0x29, 0xa7, 0x5d, 0xc0, 0x34, 0x29, 0xc5, 0xaa, 0xf8, 0x51, 
+       0x47, 0xec, 0x92, 0x1c, 0x7d, 0xd4, 0x6e, 0xa1, 0xa8, 0xf, 
+       0x56, 0xad, 0x49, 0x7e, 0xfb, 0xfb, 0xeb, 0xb, 0xe8, 0x83, 
+       0x13, 0xf0, 0x2, 0x6e, 0xc0, 0xf, 0x38, 0x2a, 0xe5, 0x72, 
+       0x32, 0xdc, 0x55, 0xb3, 0x96, 0xca, 0x9c, 0x4b, 0xab, 0x16, 
+       0xdc, 0x6b, 0x4a, 0x69, 0x6e, 0xd3, 0xdf, 0x6a, 0xab, 0xad, 
+       0x74, 0xd6, 0xd6, 0xe4, 0xa0, 0xc1, 0xef, 0x90, 0x89, 0xbe, 
+       0xf8, 0xad, 0xb7, 0xb5, 0x92, 0xd3, 0xfd, 0xbf, 0x95, 0xab, 
+       0x3e, 0xc8, 0xfc, 0xf2, 0x57, 0x17, 0x7, 0x12, 0x6c, 0x6, 
+       0xf8, 0x87, 0x7f, 0x38, 0x38, 0xdc, 0xf1, 0x5d, 0x3d, 0x32, 
+       0xc0, 0x31, 0xa2, 0x9e, 0x72, 0xfa, 0x85, 0xc9, 0x2a, 0x3d, 
+       0x72, 0xea, 0x8e, 0x12, 0x23, 0x6c, 0x29, 0xc7, 0xfd, 0x7d, 
+       0xd, 0x3e, 0xcc, 0x39, 0x1c, 0x21, 0x8f, 0x3e, 0x28, 0x83, 
+       0x57, 0x3f, 0x3f, 0xc, 0xd7, 0xf9, 0x3e, 0xf6, 0xbc, 0x7, 
+       0x64, 0x8a, 0xdf, 0xa8, 0x32, 0x19, 0x6d, 0x69, 0xbc, 0xcd, 
+       0x6e, 0x87, 0x71, 0x75, 0xc, 0xde, 0x38, 0x2d, 0x8e, 0x9b, 
+       0x79, 0xdc, 0xb, 0xbd, 0x10, 0xfe, 0xdb, 0xbf, 0xfd, 0xcb, 
+       0x9f, 0x75, 0xa, 0xcc, 0x2d, 0x1f, 0x26, 0xc0, 0x91, 0x2f, 
+       0x34, 0x6b, 0xa9, 0x27, 0x10, 0xe6, 0x7b, 0x5c, 0xf1, 0x5a, 
+       0xe2, 0x39, 0xcd, 0x1d, 0xfa, 0xcf, 0xf7, 0x9b, 0x36, 0x8c, 
+       0xc8, 0x8, 0xf7, 0xdd, 0xc9, 0x1a, 0xd7, 0xec, 0x8a, 0xf3, 
+       0xfd, 0xf9, 0xf2, 0x3b, 0x92, 0x5, 0x8f, 0xbd, 0x10, 0x2e, 
+       0xef, 0xbe, 0xdb, 0xa6, 0xb2, 0x50, 0x7, 0x27, 0x9b, 0x6d, 
+       0xbe, 0x81, 0xf6, 0x72, 0xb4, 0x84, 0xb4, 0x87, 0x1e, 0x79, 
+       0x21, 0xb9, 0x4d, 0xef, 0x76, 0x73, 0x1f, 0xf8, 00, 0x27, 
+       0x98, 0xe2, 0xe0, 0x6, 0xfc, 0x94, 0x73, 0xf0, 0x45, 0x75, 
+       0x4, 0xdc, 0xa1, 0x8a, 0xe5, 0xf2, 0xc5, 0xe9, 0x55, 0xcd, 
+       0xb9, 0x75, 0x63, 0xb7, 0xe0, 0x86, 0x41, 0xfa, 0x98, 0x5d, 
+       0x10, 0xf6, 0x57, 0x5f, 0x79, 0x21, 0x99, 0x7d, 0xe7, 0x63, 
+       0xc9, 0x1e, 0xbb, 0x6f, 0xa5, 0xd, 0x2d, 0x7a, 0x15, 0x52, 
+       00, 0x90, 0xbd, 0x23, 0xd1, 0x29, 0xf4, 0xfd, 0x4, 0xe8, 
+       0xcb, 0x2f, 0x39, 0xb1, 0x70, 0xc5, 0x59, 0x79, 0x36, 0x9d, 
+       0x32, 0x21, 0xb9, 0xf7, 0x8e, 0x7f, 0x8f, 0xeb, 0x9a, 0xbd, 
+       0xb7, 0x30, 0x25, 0xfb, 0xb, 0xda, 0xf8, 0x12, 0xae, 0xaf, 
+       0xc1, 0x4d, 0x1b, 0x2d, 0x8, 0x14, 0xe7, 0x38, 0xaf, 0x29, 
+       0x56, 0x73, 0x30, 0x62, 0x89, 0xaa, 0xf6, 0x98, 0x64, 0x60, 
+       0xcf, 0x99, 0xf3, 0xe0, 0x83, 0x7a, 0x4f, 0xfb, 0x16, 0xdd, 
+       0xc0, 0x88, 0xe2, 0x47, 0x5a, 0x74, 0x3c, 0x66, 0x1b, 0x92, 
+       0x87, 0x37, 0x43, 0x2, 0xb0, 0x55, 0xcf, 0x62, 0x80, 0xc7, 
+       0xbf, 0xc9, 0x6b, 0xcf, 0xbd, 0xd0, 0xa, 0xf4, 0xfe, 0xf3, 
+       0x3f, 0xcf, 0xbe, 0xf2, 0xeb, 0x5f, 0xff, 0x6, 0x73, 0xf9, 
+       0x3d, 0xf4, 0x39, 0xa4, 0xc6, 0x75, 0x3d, 0x7, 0x87, 0x8f, 
+       0x68, 0x43, 0x3b, 0xaa, 0xdd, 0xb5, 0xea, 0xbe, 0x5a, 0x5b, 
+       0xc8, 0x60, 0x5f, 0xbc, 0x6e, 0x2, 0xa5, 0x50, 0xe, 0x72, 
+       0x84, 0x8c, 0x76, 0x23, 0x53, 0x1f, 0xdb, 0x7a, 0xe3, 0x42, 
+       0xd9, 0x24, 0x7f, 0xce, 0x7d, 0xfa, 0x53, 0xd3, 0x92, 0x23, 
+       0xe, 0xdd, 0x4d, 0xaf, 0x1f, 0xbf, 0x9c, 0x79, 0xfb, 0xed, 
+       0x77, 0xb4, 0x20, 0x93, 0xa5, 0xf7, 0xc3, 0xef, 0x1c, 0x12, 
+       0x16, 0xc8, 0x58, 0x24, 0x63, 0x2a, 0xb7, 0xe4, 0xcd, 0x65, 
+       0x32, 0xc5, 0x1f, 0x4f, 0x3e, 0x58, 0xd5, 0x9c, 0x8c, 0xdf, 
+       0x60, 0x52, 0xc0, 0x4d, 0x77, 0xed, 0x44, 0x73, 0xab, 0xce, 
+       0x55, 0x69, 0x90, 0x9e, 0x34, 0xb7, 0x6b, 0x1d, 0x42, 0x1, 
+       0x45, 0x1f, 0x78, 0xec, 0x7e, 0xf1, 0x88, 0xa, 0x2, 0xf0, 
+       0x71, 0xe3, 0x27, 0x65, 0x35, 0xb8, 0x4c, 0x8e, 0xb7, 0xb4, 
+       0x2b, 0x7, 0x90, 0x95, 0xf2, 0x30, 0xd9, 0x23, 0x69, 0xa9, 
+       0xeb, 0x95, 0xa6, 0x59, 0x94, 0x8b, 0x47, 0x7c, 0x75, 0x64, 
+       0x46, 0xf3, 0x51, 0xf3, 0xbe, 0xd7, 0x21, 0xed, 0x2b, 0xf6, 
+       0x6d, 0x6d, 0xad, 0x99, 0x95, 0x2b, 0xfb, 0xae, 0x8c, 0x52, 
+       0x95, 0x34, 0xb0, 0x1f, 0x78, 0x60, 0xee, 0x7c, 0x1, 0xfb, 
+       0x56, 0xe5, 0x61, 0x87, 0x19, 0x2b, 0x3c, 0x78, 0x83, 0x9c, 
+       0xce, 0x31, 0xc0, 0xdd, 0x77, 0x80, 0x98, 0x7e, 0x2e, 0xf6, 
+       0x4e, 0xd7, 0xa5, 0x30, 0x8f, 0x3, 0x51, 0xbe, 0x1f, 0xed, 
+       0xd, 0xcd, 0x40, 0x5f, 0x16, 0xc2, 0x35, 0x3a, 0x86, 0xfa, 
+       0x6e, 0x8e, 0x6c, 0x5a, 0xd7, 0x26, 0x3a, 0xe0, 0x5e, 0xb3, 
+       0x66, 0x6d, 0xd8, 0x9b, 0x10, 0xf7, 0xa5, 0x79, 0xae, 0x3a, 
+       0xf5, 0x1a, 0xec, 0x94, 0x21, 0x4d, 0x18, 0x4e, 0xc3, 0x85, 
+       0x6e, 0x1, 0x4d, 0x71, 0xad, 0x52, 0x99, 0x2b, 0x97, 0xcf, 
+       0x32, 0x1d, 0x8, 0xeb, 0x8f, 0xf3, 0xf1, 0x9b, 0xf8, 0x92, 
+       0xa5, 0xcb, 0x65, 0x8a, 0x6b, 0xf1, 0x6c, 0x55, 0x53, 0xc0, 
+       0x9, 0x78, 0x71, 0x3d, 0x7c, 0x4f, 0x71, 0x98, 0xb3, 0x68, 
+       0xe8, 0x13, 0xfa, 0xd5, 0x3e, 0xce, 0xe6, 0xfe, 0xce, 0xa7, 
+       0xf5, 0x4, 0x6e, 0x32, 0xe6, 0x6f, 0x52, 0xc5, 0x3e, 0xe8, 
+       0x9, 0xdc, 0xdc, 0x40, 0xa7, 0xb0, 0x47, 0x76, 0xfd, 0xf5, 
+       0x5b, 0x42, 0x3, 0x68, 0xc8, 0xd2, 0xb7, 0xb5, 0x90, 0x50, 
+       0x34, 0x97, 0x81, 0x34, 0x2b, 0xa3, 0xd9, 0xd5, 0xd1, 0xee, 
+       0xe7, 0xe7, 0xc5, 0xf7, 0x16, 0xff, 0x8e, 0xaa, 0x99, 0x67, 
+       0x14, 0xc, 0x63, 0x7, 0x59, 0x5f, 0x82, 0x9b, 0xf6, 0xe1, 
+       0x68, 0x23, 0x9e, 0x32, 0xd8, 0x4d, 0xb5, 0x64, 0xc9, 0x5b, 
+       0x79, 0x3e, 0x65, 0x73, 0xf4, 0xdd, 0xdf, 0x4e, 0x60, 0xcf, 
+       0x79, 0xe8, 0xbc, 0xf3, 0x66, 0xde, 0x26, 0xca, 0xde, 0x3a, 
+       0xca, 0x88, 0x42, 0x1c, 0xef, 0xd, 0x2a, 00, 0x14, 0x70, 
+       0xe2, 0x90, 0x5c, 0xbc, 0x1f, 0x91, 0xa1, 0x81, 0x63, 0x5f, 
+       0xbc, 0xaa, 0x6e, 0x80, 0x3, 0x6a, 0xe8, 0xb1, 0x9b, 0x2d, 
+       0x6c, 0x57, 0xfd, 0xc3, 0x1f, 0x7e, 0x7f, 0xb5, 0x4e, 0x70, 
+       0x11, 0xc0, 0x2f, 0x6f, 0xa5, 0x3e, 0xeb, 0xca, 0xe9, 0xab, 
+       0x1d, 0x61, 0x30, 0x86, 0xaf, 0xf8, 0x98, 0xcf, 0x4e, 0xeb, 
+       0x6d, 0xd9, 0xc, 0x50, 0x78, 0xd3, 0x2f, 0xa4, 0x57, 0xc9, 
+       0x9c, 0xbb, 0x7b, 0x59, 0x45, 0x9e, 0x99, 0x7b, 0xc7, 0x32, 
+       0x8a, 0x7c, 0xf2, 0xfb, 0x6d, 0xe1, 0x20, 0x2c, 0x9e, 0xad, 
+       0x6a, 0x4c, 0xc6, 0xa, 0x1f, 0xe5, 0xf6, 0x92, 0x17, 0xd6, 
+       0x49, 0xa3, 0xae, 0x94, 0xaa, 0xf0, 0x47, 0x9f, 0x58, 0xce, 
+       0x1c, 0x92, 0x35, 0x8e, 0xe7, 0x6f, 0xed, 0xce, 0x2c, 0xef, 
+       0xb4, 0x8d, 0xb2, 0x37, 0x6b, 0x95, 0xbf, 0x43, 0x7, 0x71, 
+       0x60, 0xad, 0xf5, 0xec, 0xe8, 0x14, 0xce, 0xb8, 0x66, 0xa4, 
+       0x5a, 0xfc, 0xfa, 0xc2, 0xb0, 0x68, 0xb0, 0xfb, 0x27, 0x36, 
+       0xd3, 0x97, 0x45, 0xfa, 0x17, 0x34, 0x5a, 0x95, 0xd6, 0xeb, 
+       0x7d, 0x6b, 0x53, 0xb7, 0xdf, 0xf9, 0x68, 0xf2, 0xda, 0x62, 
+       0x5e, 0x3f, 0xae, 0xde, 0x5, 0xb, 0x2a, 0xd5, 0x28, 0x29, 
+       0xee, 0x1c, 0x85, 0x2d, 0x8, 0xd2, 0xdc, 0x29, 0x8d, 0xd4, 
+       0x34, 0x3e, 0x7b, 0xb1, 0x7a, 0xf2, 0xf9, 0x3b, 0x4c, 0xd3, 
+       0x9, 0xfc, 0xc6, 0xc4, 0xaa, 0xab, 0x4b, 0xa7, 0x5f, 0x7e, 
+       0xf9, 0x95, 0x8e, 0x8f, 0x7d, 0xec, 0x63, 0xbd, 0x2e, 0xc3, 
+       0xb4, 0x1d, 0x1a, 0xd8, 0x9c, 0x2b, 0xae, 0x53, 0x4a, 0x1, 
+       0x36, 0xef, 0x5d, 0xc3, 0x28, 0xbf, 0xae, 0x69, 0xa0, 0xd3, 
+       0xf1, 0x6, 0xb6, 0x3b, 0x9b, 0xc1, 0xdb, 0x75, 0x4a, 0x9d, 
+       0x78, 0xe2, 0x89, 0xd3, 0x7e, 0xf1, 0x8b, 0x5f, 0xcc, 0x56, 
+       0x1a, 0xd7, 0x9d, 0x47, 0xd1, 0x7c, 0x1e, 0xd2, 0xe8, 0x60, 
+       0xe4, 0x2, 0x80, 0x3, 0x7e, 0xe2, 0xf8, 0xf4, 0x39, 0xe7, 
+       0xfc, 0x5e, 0x8b, 0x77, 0x5f, 0x83, 0xde, 0x27, 0x8e, 0x3c, 
+       0xf2, 0x48, 0xbe, 0x82, 0xa1, 0x68, 0xdf, 0x3a, 0x9d, 0xfa, 
+       0xaa, 0xf7, 0xac, 0xdb, 0x74, 0x42, 0x70, 0x2a, 0x98, 0xb1, 
+       0x84, 0x1e, 0x44, 0xcd, 0x7f, 0xc2, 0xde, 0x38, 0xe4, 0x41, 
+       0xe0, 0x4e, 0xf1, 0xda, 0x67, 0x4c, 0x1f, 0x9a, 0x19, 0xc9, 
+       0xd1, 0x79, 0x17, 0xce, 0xce, 0xa5, 0x57, 0x5f, 0xce, 0xb8, 
+       0xb1, 0x83, 0xb4, 0x5d, 0x7a, 0x33, 0xc0, 0x28, 0xd1, 0xef, 
+       0xe0, 0xdd, 0x74, 0xa8, 0x6, 0x99, 0x67, 0x8f, 0xf9, 0xbd, 
+       0xf, 0x3c, 0x93, 0x7c, 0xb0, 0xba, 0x5f, 0x32, 0x66, 0xec, 
+       0xc4, 0x6e, 0xdf, 0x2, 0x2b, 0x6e, 0x1f, 0xb8, 0x93, 0x2c, 
+       0xd3, 0x27, 0xb8, 0xb8, 0xef, 0xca, 0xc5, 0x43, 0xa7, 0x65, 
+       0xb3, 0x97, 0xfe, 0xcb, 0x8d, 0x79, 0xaf, 0xa, 0xaf, 0x64, 
+       0x4, 0xa9, 0xd4, 0xd1, 0x29, 0x12, 0xf8, 0x64, 0xae, 0xe6, 
+       0x38, 0x6f, 0xbe, 0xf1, 0x62, 0x32, 0xfb, 0x9e, 0x27, 0x92, 
+       0xdd, 0x76, 0xd9, 0x54, 0xf, 0xf7, 0xb5, 0xcd, 0x34, 0xf7, 
+       0x8f, 0x67, 0xdd, 0xad, 0x6d, 0xda, 0x72, 0xf7, 0xba, 0x3e, 
+       0xbe, 0x5e, 0x3f, 0xb6, 0x52, 0xd2, 0x85, 0xf9, 0x2, 0xba, 
+       0x75, 0x86, 0xda, 0x98, 0x31, 0x21, 0x3d, 0xee, 0x30, 0xc0, 
+       0xad, 0x13, 0x35, 0xe1, 0x70, 0xf5, 0x3d, 0x15, 0x95, 0x12, 
+       0xb, 0x16, 0xed, 0x2, 0xd4, 0x4e, 0x63, 0x1e, 0xaa, 0x32, 
+       0x7a, 0x45, 0x3f, 0x2a, 0x2a, 0x1f, 0x2d, 0x2, 0xf6, 0x2c, 
+       0x5d, 00, 0xd4, 0xcb, 0x73, 0x21, 0x1a, 0x95, 0xdf, 0x84, 
+       0x74, 0xba, 0x4d, 0x73, 0xb4, 0x36, 0x7d, 0x66, 0x33, 0x9c, 
+       0x7a, 0xa5, 0xcf, 0x3c, 0xf3, 0xac, 0xd3, 0xb4, 0xf8, 0xf7, 
+       0xb5, 0x33, 0xcf, 0x3c, 0xf3, 0x17, 0xc7, 0x1d, 0x77, 0xdc, 
+       0xd9, 0xb9, 0x3c, 0xf0, 0x25, 0x1e, 0xc4, 0xfd, 0x9b, 0x81, 
+       0xc2, 0xf7, 0x17, 0x84, 0x3a, 0xa2, 0xe9, 0x9a, 0x4c, 0xe6, 
+       0xab, 0xd0, 0xdc, 0x75, 0x5d, 00, 0x1c, 0x3e, 0xc2, 0x5b, 
+       0xe6, 0xa6, 0xf0, 0xd7, 0x7c, 0x26, 0xc4, 0x91, 0xd6, 0x5b, 
+       0xa7, 0xc7, 0x7d, 0x28, 0x2a, 0x75, 0x23, 0x4d, 0xeb, 0xa4, 
+       0xa9, 0x2d, 0xb7, 0xb2, 0xc0, 0xb4, 0xb, 0x4d, 0x2f, 0x33, 
+       0x69, 0xa9, 0x3b, 0xf8, 0x6a, 0xcb, 0x7a, 0xf5, 0xf5, 0x37, 
+       0xc2, 0xfe, 0x8d, 0x35, 0x6b, 0xf5, 0x3a, 0x29, 0xdd, 0xa0, 
+       0xea, 0x12, 0xbe, 0xbb, 0x7c, 0xa5, 0x5e, 0x26, 0x79, 0x2e, 
+       0x58, 0xb2, 0x63, 0xc6, 0x4e, 0x8, 0xc0, 0x76, 0x9b, 0x2a, 
+       0x29, 0x3, 0xdc, 0xc9, 0x63, 0x32, 0x19, 0x8f, 0xee, 0x2b, 
+       0xff, 0xee, 0x42, 0xa6, 0x3b, 0xcd, 0xed, 0xcc, 0xbe, 0x99, 
+       0x2f, 0x35, 0x2c, 0xd1, 0x88, 0x7, 0xd1, 0x2c, 0x57, 0x9c, 
+       0xa3, 0x9b, 0x10, 0x6, 0x6e, 0xbf, 0xfd, 0xf6, 0x3a, 0x33, 
+       0xaa, 0x5d, 0xef, 0xad, 0x2e, 0x92, 0x49, 0xf2, 0x44, 0xb2, 
+       0xeb, 0xc7, 0xa7, 0xea, 00, 0x85, 0xc6, 0xa0, 0xd5, 0x45, 
+       0x33, 0xbd, 0x76, 0xed, 0x1a, 0x8d, 0x72, 0xd9, 0xe7, 0x8e, 
+       0x5f, 0xfe, 0xf2, 0x97, 0xbb, 0xa1, 0x56, 0xfa, 0x12, 0xd6, 
+       0x81, 0x40, 0x1c, 0xde, 0x24, 0xc2, 0xc, 0x37, 0xe8, 0xc, 
+       0xc2, 0xbe, 0x34, 0xcb, 0x4d, 0x9b, 0x9a, 0x40, 0x1f, 0xf, 
+       0xb8, 0xf9, 0x46, 0x17, 0x67, 0xa9, 0xf1, 0x35, 0xc9, 0xbe, 
+       0x70, 0x65, 0x80, 0x8d, 0xb6, 0x46, 0x73, 0xe3, 0x1d, 0x37, 
+       0xb8, 0xe9, 0x78, 0x3, 0x3b, 00, 0x5a, 0xbf, 0xe9, 0xa7, 
+       0xba, 0x33, 0xcf, 0xfc, 0xf5, 0xc9, 0x3a, 0x72, 0xfe, 0xf3, 
+       0x7, 0x1f, 0x3c, 0x23, 0xb9, 0xf6, 0xda, 0xeb, 0x7e, 0x74, 
+       0xc6, 0x19, 0x67, 0xac, 0xa7, 0x73, 0xc6, 0x4f, 0xd3, 0x35, 
+       0x46, 0x6a, 0xfa, 0x93, 0xfb, 0x7c, 0x2f, 0x21, 0xf7, 0x33, 
+       0x60, 0x18, 0x49, 0xe, 0x95, 0x94, 0xa4, 0xce, 0x3d, 0xf7, 
+       0x9c, 0xab, 0x89, 0xc8, 0xf5, 0x29, 0xc0, 0xe1, 0x1f, 0x53, 
+       0x1c, 0xb6, 0x5a, 0xba, 0xef, 0x8, 0xcd, 0x73, 0x3, 0x9b, 
+       0xb4, 0xde, 0x38, 0xe4, 0x81, 0x79, 0x31, 0xf4, 0xa0, 0x65, 
+       0x3f, 0x6d, 0xda, 0xb4, 0x70, 0xbc, 0x34, 0x9b, 0xb4, 0xbc, 
+       0xf0, 0x55, 0x4d, 0x39, 0x33, 0x67, 0xce, 0x14, 0xf4, 0x78, 
+       0x72, 0xb2, 0x26, 0xa3, 0xfe, 0x13, 0xd9, 0xec, 0x26, 0xaa, 
+       0x65, 0xcb, 0x56, 0x26, 0x73, 0xe7, 0x2d, 0x4c, 0x56, 0x7e, 
+       0xd0, 0xa4, 0xd5, 0xf3, 0xd, 0xaa, 0xd2, 0xd8, 0x2e, 0x5f, 
+       0xf4, 0xf8, 0x96, 0x1a, 0x7, 0x6d, 0x18, 0x8f, 0x5c, 0x72, 
+       0x9c, 0xb0, 0x8b, 0x2b, 0xc7, 0x25, 0x67, 0x76, 0xc8, 0x8d, 
+       0x80, 0xfb, 0x75, 0x8d, 0x7a, 0x8c, 0xea, 0x55, 0x39, 0x46, 
+       0x28, 00, 0x3e, 0x72, 0xd4, 0x4, 0x35, 0xb0, 0x21, 0xb9, 
+       0xe7, 0xbe, 0xa7, 0xb4, 0xd7, 0xbc, 0x73, 0xde, 0xb6, 0x7a, 
+       0xf5, 0x9a, 0xb8, 0x9c, 0xaa, 0x68, 0xc7, 0x99, 0x8b, 0x85, 
+       0x80, 0xdf, 0x9c, 0xc4, 0x22, 0xa6, 0xc4, 0xc2, 0x19, 0xdf, 
+       0x52, 0x71, 0x3c, 0xa6, 0x6d, 0xa1, 0x40, 00, 0xec, 0x35, 
+       0xe8, 0x65, 0x5e, 0x7d, 0xf5, 0xd5, 0x3e, 0x69, 0x47, 0x37, 
+       0xc0, 0x46, 0x53, 0x5b, 0x7b, 0x3, 0x70, 0x4c, 0x72, 0x40, 
+       0x48, 0x9f, 0x18, 0xa0, 0x8a, 0x6, 0x8b, 0x8c, 0xb9, 0x75, 
+       0xf3, 0xe9, 0xa7, 0xff, 0xea, 0x14, 0xbd, 0x54, 0xf2, 0x5, 
+       0xed, 0x36, 0xeb, 0xcf, 0x21, 0x5, 0x3a, 0x1, 0xb5, 0xff, 
+       0xe8, 0xd1, 0xeb, 0xfd, 0xdd, 0xa9, 0xa7, 0x9e, 0xfa, 0x4f, 
+       0xba, 0xae, 0xfd, 0xbd, 0xe1, 0x8d, 0x32, 0xb6, 0x1c, 0xb2, 
+       0xd, 0x10, 0x79, 0xa0, 0xd, 0xd0, 0x2, 0xf8, 0xd0, 0xa6, 
+       0xa3, 0x18, 0x40, 0x3c, 0xa0, 0x60, 0x39, 0xac, 0x4, 0xe0, 
+       0xf, 0x3e, 0x38, 0xef, 0x5e, 0xed, 0x6b, 0xef, 0xb3, 0x39, 
+       0x38, 0xfc, 0xd3, 0xa7, 0x88, 0xc3, 0x62, 0x1a, 00, 0x47, 
+       0x6e, 0xec, 0x55, 0x66, 00, 0x21, 0xbc, 0xef, 0xad, 0x93, 
+       0x1c, 0x7, 0x22, 0x80, 0xcf, 0xfd, 0x6a, 0x9a, 0xa4, 0xf5, 
+       0xd6, 0x21, 0xcf, 0xc, 0x1e, 0xb8, 0x95, 0xef, 0xaf, 0x49, 
+       0x1e, 0x98, 0xfb, 0x7c, 0xf2, 0xde, 0xca, 0xfa, 0x64, 0xd8, 
+       0xf0, 0x71, 0xf9, 0x39, 0x76, 0xb5, 0xed, 0xd0, 0x97, 0x66, 
+       0xe0, 0xf3, 0x52, 0x91, 0x84, 0x30, 0x7d, 0x54, 0x2c, 0x6b, 
+       0xc5, 0xbf, 0xcb, 0x6a, 0x60, 0xdf, 0x1c, 0x87, 0x1d, 0x22, 
+       0xbe, 0x58, 0xa3, 0x6b, 0x17, 0x22, 0x2a, 0xa8, 0x47, 0x7, 
+       0x8, 0x30, 0xd1, 0x87, 0xd, 0x1f, 0x9f, 0xac, 0x78, 0xbf, 
+       0x3e, 0xb9, 0x57, 00, 0x5f, 0xb9, 0x42, 0xb2, 0xa9, 0x39, 
+       0x49, 0xeb, 0x5a, 0x81, 0xf, 0xd3, 0xba, 0xf, 0x9c, 0x99, 
+       0x86, 0x50, 0x10, 0xa7, 0x5c, 0x34, 0x7b, 0x5f, 0x68, 0x6f, 
+       0xb, 0x2, 0x2, 0x60, 0x21, 0x20, 0x8d, 0xb2, 0xd4, 0x90, 
+       0xf4, 0x33, 0xcf, 0x3c, 0xdb, 0xeb, 0x46, 0x54, 0x1, 0x6c, 
+       00, 0x7, 0xf0, 00, 0x36, 0x40, 0xb4, 0xc6, 0xc5, 0x1a, 
+       0xb, 0xc0, 0xd6, 0xdb, 0x5d, 0x3f, 0x5f, 0x6f, 0xbd, 0xd1, 
+       0x9f, 0x3, 0xd8, 0xde, 0x32, 0xcc, 0x3c, 0x53, 00, 0xef, 
+       0x37, 0x66, 0xcc, 0x98, 0xbf, 0x3b, 0xe9, 0xa4, 0x93, 0x8e, 
+       0x53, 0x5e, 0x3, 0x1c, 0x70, 0x73, 0x1f, 0x8d, 0xb1, 0x36, 
+       0x67, 0xfe, 0xd, 0xc0, 0x19, 0x44, 0x62, 0x8b, 0x61, 0x9d, 
+       00, 0xfc, 0xe9, 0xa7, 0x9f, 0xd1, 0x40, 0xbc, 0x8a, 0x8f, 
+       0x2, 0x6, 0xfe, 0xc2, 0x57, 0xf3, 0x9a, 0x7e, 0x24, 0xee, 
+       0x3e, 0x50, 0x7d, 0x6a, 0x72, 0xc8, 0x1, 0x26, 0xae, 0xe9, 
+       0x99, 0xa6, 0xcb, 0x32, 0x7d, 0xc2, 0x5a, 0x1c, 0x4f, 0xc8, 
+       0x91, 0xe7, 0xe, 0x2d, 0xa8, 0xe9, 0xbb, 0x8e, 0x7a, 0x79, 
+       0xe4, 0xd9, 0x64, 0xf9, 0x7b, 0xe9, 0x64, 0xf0, 0x90, 0xb1, 
+       0xe1, 0x29, 0x12, 0xe5, 0xba, 0x8c, 0x6a, 0xe8, 0x33, 0xe8, 
+       0x45, 0xe0, 0x36, 0xc0, 0x1d, 0x42, 0x2a, 0x60, 0x15, 0x13, 
+       0xd8, 0x74, 0xbb, 0x1b, 0xa6, 0x9c, 0x29, 0x4f, 0x40, 0x5, 
+       0x2c, 0x16, 0x73, 0x2a, 0x31, 0xe5, 0x4d, 0xbf, 0x20, 0x84, 
+       0x81, 0x68, 0xf0, 0xc1, 0x43, 0xd6, 0x97, 0xe6, 0xae, 0x4b, 
+       0xee, 0x9f, 0xf3, 0x9c, 0xbe, 0x40, 0x92, 0xdd, 0x5f, 0x5e, 
+       0x90, 0xb1, 0xca, 0x1f, 0x66, 0x96, 0x43, 0x3, 0x8f, 0x90, 
+       0x32, 0xd1, 0xaa, 0x95, 0x7e, 0xa1, 0xb2, 0xbb, 0xa2, 0xdd, 
+       0xe1, 0xa6, 0xb, 0x6d, 0x4, 0x91, 0xe, 0xe3, 0x58, 0x63, 
+       0x95, 0x11, 0x8e, 0xee, 0xe9, 0x8e, 0x46, 0x77, 0xd7, 0x7a, 
+       0x1, 0x6c, 0xc0, 0x8d, 0x34, 0x2, 0x4c, 0xfa, 0x87, 0x83, 
+       0x16, 0xf4, 0xda, 0x66, 0xe9, 0xb7, 0xbb, 00, 0xf8, 0xe1, 
+       0x87, 0x1f, 0xde, 0x3c, 0x7e, 0xfc, 0x6, 0x5f, 0xf8, 0xa7, 
+       0x7f, 0xfa, 0xa7, 0xef, 0x29, 0x3f, 00, 0x8f, 0xf, 0x7c, 
+       0xf8, 0xd0, 0x1, 0xce, 0x74, 0x4a, 0xda, 0x29, 0xf0, 0x32, 
+       0xe6, 0x2b, 0x71, 0xf8, 0x8d, 0x37, 0xff, 0x55, 0xd7, 0x9a, 
+       0x1d, 0x72, 0xa0, 0x8f, 0x24, 0x86, 0xc7, 0x60, 0xee, 0x47, 
+       0x42, 0x9c, 0xc3, 0x5e, 0x95, 0x23, 0xd4, 0x48, 0x6d, 0x4b, 
+       0x99, 0xac, 0x49, 0xe6, 0xcd, 0x7f, 0x31, 0x59, 0xf6, 0x5e, 
+       0x2a, 0xe9, 0x3f, 0x70, 0x74, 0xd8, 0xa0, 0x62, 0x60, 0xd7, 
+       0x52, 0x79, 0xc9, 0x70, 0x9d, 0xea, 0xad, 0x5, 0x81, 0xe0, 
+       0x2, 0x90, 0x15, 0x73, 0x8, 0x46, 0xbb, 0xb8, 0xee, 0xc0, 
+       0x4d, 0x66, 0xdf, 0x4, 0x91, 0xe, 0x99, 0xe4, 0xef, 0x6a, 
+       0x60, 0xe0, 0xed, 0x91, 0x2e, 0x84, 0xba, 0x4b, 0x88, 0x99, 
+       0x45, 0x67, 0xb1, 0x8a, 0x3e, 0x70, 0xf0, 0xd8, 0x64, 0xd9, 
+       0x8a, 0x54, 0x32, 0x47, 0xc, 0x58, 0xae, 0xd7, 0x41, 0x39, 
+       0x21, 0xb2, 0xb7, 0x8e, 0x72, 0xec, 0x29, 0x87, 0x38, 0x1d, 
+       0x86, 0x59, 0xae, 0x47, 0x2c, 0x6e, 0x4b, 0xaf, 0x8a, 0x31, 
+       0x7d, 0x42, 0x77, 0x16, 0x65, 0x1, 0x98, 0xf, 0x3e, 0x78, 
+       0x3f, 0xf3, 0xc2, 0xb, 0x2f, 0xc0, 0xab, 0xaa, 0x5d, 0x1f, 
+       0x2, 0xbb, 0x59, 0xc0, 0xee, 0xf1, 0xa0, 0x5, 0x56, 0xba, 
+       0xa5, 0xd1, 0x9b, 0x36, 0xdc, 0x70, 0xe2, 0x17, 0x7e, 0xf2, 
+       0x93, 0x9f, 0x7c, 0x53, 0x15, 0x6, 0xe0, 0xbc, 0x25, 0xe2, 
+       0x13, 0x36, 0x3f, 0x54, 0x80, 0xbf, 0xf0, 0xc2, 0xc2, 0x8c, 
+       0x84, 0xb7, 0x3, 0x9e, 0x32, 0x95, 0x82, 0xa7, 0xf6, 0xe6, 
+       0xb3, 0xc1, 0x8, 0xef, 0x6b, 0x75, 0xc8, 0x81, 0xac, 0xcf, 
+       0xb0, 0x68, 0x17, 0xcb, 0x8, 0x71, 0x5c, 0xdc, 0xbf, 0xb5, 
+       0x94, 0xc1, 0x67, 0x84, 0x90, 0xe7, 0xf9, 0x8f, 0xbc, 0x94, 
+       0x68, 0x1b, 0x79, 0xd2, 0xdc, 0x6f, 0x54, 0xd8, 0x52, 0x4a, 
+       0x1b, 0xec, 0xaa, 0xad, 0x7f, 0xee, 0x19, 0x37, 0x4f, 0x7d, 
+       0x58, 0x67, 0x1, 0x28, 0xc8, 0x32, 0xde, 0xe0, 0x56, 0xb4, 
+       0x8b, 0x99, 0xde, 0xd5, 0x2c, 0x8f, 0xd5, 0x3a, 0x77, 0xc8, 
+       0xc5, 0x84, 0x58, 0x62, 0x7c, 0x57, 0x1a, 0x3c, 0x7b, 0xa5, 
+       0x8a, 0xbf, 0x31, 0xd3, 0x68, 0x28, 0xf, 0xee, 0xfb, 0xe9, 
+       0xeb, 0x28, 0xcb, 0x44, 0xea, 0xee, 0x7b, 0x9e, 0xd6, 0xc7, 
+       0xd2, 0x7a, 0x7, 0xee, 0x98, 0xbe, 0x47, 0x60, 0x3a, 0x8c, 
+       0xb8, 0x7c, 0x8a, 0xcf, 0xc3, 0xf6, 0xd6, 0xb9, 0xc, 0x68, 
+       0x9a, 0x36, 0x9a, 0xdb, 0xda, 0x5b, 0x8b, 0x7a, 0x69, 0x4e, 
+       0xa5, 0xa9, 0xd6, 0xf5, 0x25, 0xb0, 0x39, 0xf3, 0xac, 0xd2, 
+       0x83, 0x16, 0x58, 0x8, 0xd4, 0xae, 0xb3, 0xa6, 0x96, 0x96, 
+       0x49, 0x5f, 0xd4, 0x2, 0xdb, 0x3f, 0xa8, 0xde, 0x68, 0x6f, 
+       0xfc, 0x87, 0xe, 0x70, 0xf8, 0x26, 0xe1, 0xad, 0x43, 0x36, 
+       0xf0, 00, 0xdc, 0x71, 0xf8, 0xee, 0x3e, 0x25, 0xde, 0x1b, 
+       0xa7, 0x4f, 0x20, 0xb3, 0xf0, 0x9a, 0x7, 0x77, 0x4e, 0x3e, 
+       0xf2, 0x8a, 0xc0, 0xf4, 0x1d, 0x56, 0x5b, 0x16, 0x72, 0x7c, 
+       0x97, 0xe4, 0xf9, 0x9d, 0x65, 0x99, 0xa4, 0xa1, 0x71, 0x78, 
+       0x78, 0xbb, 0x8b, 0x76, 0xc4, 0xe5, 0x54, 0x4b, 0x53, 0x83, 
+       0x1e, 0xb7, 0x30, 0x2d, 0x32, 0x16, 0x1d, 0x1a, 0xdc, 0x56, 
+       0x28, 0xe, 0x43, 0x11, 0xe5, 0x34, 0x77, 0xf1, 0x4d, 0x79, 
+       0x62, 0x5a, 0x28, 0x78, 0x33, 0x57, 0x58, 0x20, 0x50, 0xcd, 
+       0x9f, 0xb8, 0x83, 00, 0x4, 0x9b, 0xe4, 0x9b, 0xf4, 0x85, 
+       0x94, 0xa5, 0xef, 0xe8, 0x5d, 0xd9, 0x5e, 0x82, 0xdb, 0xf5, 
+       0xa0, 0x53, 0xf0, 0x80, 0xcf, 0x9e, 0xf9, 0x26, 0x8b, 0x28, 
+       0x5e, 0xe4, 0x70, 0xde, 0x5a, 0x42, 0x68, 0xbb, 0xa3, 0x4c, 
+       0x9f, 0x90, 0xe, 0xe4, 0x23, 0x73, 0xac, 0x9a, 0x63, 0x5e, 
+       0x56, 0xea, 0xfa, 0x1a, 0xd8, 0xd5, 0x9e, 0x79, 0x6, 0xc0, 
+       0xa5, 0xc1, 0x1b, 0x27, 0x4d, 0x9a, 0x7c, 0xcc, 0xb1, 0xc7, 
+       0x1e, 0xff, 0x35, 0xd5, 0xdb, 00, 0x67, 0x91, 0xd, 0x75, 
+       0xb6, 0xce, 0x35, 0x38, 0xfc, 0x62, 0xa5, 0x9c, 0x97, 0x45, 
+       00, 0xb5, 0x7, 0x4b, 0x83, 0xc2, 0xa1, 0xe5, 0xa7, 0x52, 
+       0xde, 0x16, 0xe7, 0xa3, 0xff, 0x91, 0x3, 0xcb, 0x47, 0x1c, 
+       0x42, 0xdb, 0x7d, 0x5b, 0x7c, 0x5f, 0x35, 0xbf, 0x99, 0xcf, 
+       0x2f, 0x79, 0x5b, 0xfb, 0xc0, 0xd3, 0x43, 0x92, 0xa9, 0x53, 
+       0xa7, 0xe6, 0x57, 0xfe, 0xa1, 0x1, 0xfd, 0x38, 0xc, 0x3f, 
+       0x2a, 0xf8, 0x83, 0x32, 0x15, 0x5d, 0xce, 0x9b, 0x37, 0xe, 
+       0x9, 0x8d, 0xd1, 0x38, 0x5e, 0x40, 0xad, 0x1c, 0xb8, 0xc9, 
+       0x54, 0x7c, 0x33, 0x44, 0xda, 0x65, 0xfb, 0xbf, 0x5c, 0x2b, 
+       0xb8, 0x21, 0x4a, 0x3, 0xed, 0x1, 0x1d, 0xef, 0xad, 0xb6, 
+       0x75, 0xc, 0x48, 0xad, 0x5e, 0x5d, 0x57, 0x30, 0xea, 0x90, 
+       0xb7, 0x5a, 0xe7, 0xce, 0x31, 0xf8, 0xf8, 0x6d, 0xe0, 0xe9, 
+       0xc5, 0x8e, 0x8c, 0x4c, 0xb2, 0x6a, 0x49, 0x16, 0xe4, 0x37, 
+       0x7d, 0x12, 0x5d, 0x6, 0x82, 0x87, 0x30, 0x22, 0x94, 0xf8, 
+       0xe5, 0xcb, 0x97, 0x65, 0xf4, 0x75, 0x4d, 0x78, 0xd5, 0xa3, 
+       0xfb, 0xa8, 0x81, 0xed, 0xa, 0xe6, 0x56, 0xd1, 0x1b, 0x37, 
+       0xda, 0x68, 0xf2, 0x97, 0x8e, 0x3d, 0xf6, 0xd8, 0xaf, 0x28, 
+       0x1d, 0x80, 0x63, 0xa2, 0x7f, 0x28, 00, 0xd7, 0x67, 0x84, 
+       0xe9, 0x1b, 0x7d, 0x33, 0x2e, 0xcb, 0xc3, 0x18, 0xdc, 0xc4, 
+       0xe9, 0x43, 0x83, 0x8f, 0x3e, 0xa8, 0xd5, 0xf1, 0xc, 0x5b, 
+       0x53, 0xb4, 0xbc, 0x45, 00, 0xdd, 0x52, 0xb4, 0x7b, 0x53, 
+       0xc6, 0xaa, 0x35, 0x75, 0x19, 0x1d, 0xb6, 0x90, 0xda, 0x48, 
+       0x1f, 0x6d, 0xa0, 0xee, 0xd0, 0x8a, 0xe5, 0xc6, 0xb4, 0x1d, 
+       0x56, 0xd2, 0x16, 0xf0, 0x26, 0xdc, 0xbd, 0xa1, 0xbc, 0xc8, 
+       0x55, 0xb1, 0x37, 0x4e, 0x1d, 0xe6, 0x49, 0x96, 0x3, 0xb7, 
+       0x33, 0x3a, 0x34, 0x41, 0xc0, 0xcd, 0xc7, 0xdf, 0xd9, 0x30, 
+       0x51, 0x93, 0x8b, 0x1b, 0x4b, 0x9c, 0xe, 0x65, 0x84, 0x6b, 
+       0xea, 0x37, 0x52, 0xaf, 0xbc, 0x6d, 0x58, 0x13, 0x4d, 0x6e, 
+       0x8a, 0x99, 0x45, 0x1c, 0x61, 0x70, 0xe7, 0x1, 0x40, 0x46, 
+       0x3f, 0xed, 0x7e, 0xaa, 0x8, 0x74, 0x3d, 0x55, 0x22, 0xa6, 
+       0x4d, 0x19, 0x6, 0x37, 0x21, 0x5f, 0x41, 0x7d, 0xfd, 0xf5, 
+       0xc5, 0xa9, 0x9e, 0x6, 0xc0, 0xbf, 0x16, 0x60, 0xbb, 0xad, 
+       0x1c, 0x29, 0xcc, 0x87, 0x2, 0xf5, 0xa5, 0xcd, 0x2f, 0xff, 
+       0xf0, 0x87, 0x3f, 0xfc, 0x7b, 0xa5, 0x17, 0x3, 0x1c, 0x59, 
+       0x81, 0x7f, 0xcc, 0x9f, 0xfa, 0x6c, 0x15, 0x1d, 0x3e, 0xf1, 
+       0x8d, 0x2e, 0xed, 0xe4, 0xa, 0xab, 0xe4, 0xc8, 0x3, 0x83, 
+       0x3e, 0x21, 0xfc, 0xf4, 0x20, 0xea, 0x30, 0xee, 0x67, 0xd5, 
+       0xa3, 0x2a, 0xb7, 0x68, 0xd1, 0xa2, 0xe, 0x1, 0x3c, 0x13, 
+       0xcb, 0x85, 0xfb, 0xb2, 0x2f, 0xe8, 0x23, 0xbf, 0xcd, 0x92, 
+       0x63, 0x3e, 0x8, 0x49, 0xfd, 0xa1, 0x69, 0x59, 0xa4, 0xa2, 
+       0xfe, 0x4d, 0xbc, 0x9a, 0x76, 0x68, 0x63, 0xf, 0x7b, 0xfa, 
+       0x59, 0x4c, 0x83, 0xf7, 0x9e, 0x73, 0x3b, 0x34, 0x46, 0x9, 
+       0xb, 0x5c, 0x39, 0x70, 0x3b, 0x93, 0x41, 0xcd, 0x8d, 0x21, 
+       0xae, 0x91, 0x8f, 0xc7, 0x61, 0xac, 0xce, 0xd6, 0xe4, 0x68, 
+       0x54, 0xec, 0x61, 0x34, 0x9a, 0x63, 0x5b, 0xed, 0x45, 0xe7, 
+       0xb, 0x9d, 0xb5, 0xba, 0x98, 0xa6, 0x99, 0x8, 0x6d, 0xd2, 
+       0x9, 0x95, 0x26, 0xd0, 0xbd, 0x5e, 0xfb, 0xb0, 0x9f, 0xab, 
+       0x98, 0xcb, 0xa1, 0xc, 0xe8, 0x32, 0x70, 0x10, 0x22, 0x88, 
+       0x8, 0x25, 0xb, 0x55, 0x68, 0xef, 0x7b, 0xee, 0xb9, 0xb7, 
+       0xec, 0x40, 0x62, 0x60, 0xc7, 0x1f, 0xbe, 0x17, 0x79, 0x16, 
+       0x32, 0x8a, 0x9f, 0x63, 0x17, 0x3f, 0xee, 0x2a, 0x5e, 0x15, 
+       0x6f, 0xee, 0xcb, 0x73, 0xc5, 0xf9, 0x10, 0xdf, 0xa1, 0x87, 
+       0x1e, 0x2a, 0xd, 0xbe, 0xf1, 0xd7, 0x7e, 0xf0, 0x83, 0x1f, 
+       0x7c, 0x51, 0xf5, 0x89, 0x4d, 0x74, 0x56, 0x84, 0xfa, 0x1c, 
+       0xe0, 0xf7, 0xdc, 0x73, 0x4f, 0x6, 0xc0, 0xc1, 0xbb, 0x18, 
+       0xd4, 0x6, 0xb6, 0x4d, 0x72, 0xf3, 0x5d, 0x75, 0xa8, 0xd9, 
+       0xd1, 0xff, 0xe2, 0x7d, 0xda, 0x7d, 0x46, 0xbf, 0xd9, 0x5b, 
+       0x66, 0x7a, 0x53, 0xce, 0xb4, 0x69, 0xd3, 0xc2, 0x5a, 0x92, 
+       0xeb, 0x6e, 0xd9, 0xa3, 0xc2, 0xd0, 0xc7, 0xd5, 0x42, 0x5f, 
+       0x78, 0x6b, 0x57, 0xbd, 0x99, 0xeb, 0xc5, 0xe0, 0xce, 0x63, 
+       0x52, 0xe9, 0xc4, 0xf1, 0x5, 0xae, 0x3b, 0x70, 0xc7, 0x99, 
+       0xd, 0xf2, 0xe, 0x8d, 0x22, 0xcf, 0x4b, 0x73, 0xf3, 0x3c, 
+       0xb4, 0x2a, 0x17, 0x37, 0xca, 0xd, 0x25, 0xb4, 0xd7, 0x8, 
+       0xce, 0x6a, 0x69, 0x55, 0x34, 0x8b, 0x33, 0x53, 0x6, 0xf4, 
+       0xcc, 0x54, 0xe2, 0xee, 0x48, 0x56, 0xb3, 0x59, 0x75, 0x54, 
+       0xfd, 0x8b, 0x6f, 0xab, 0xea, 0xb7, 0xcb, 0xe0, 0x26, 0xe8, 
+       0x23, 0x1c, 0x8c, 0xd2, 0x94, 0x43, 0x88, 0x97, 0x16, 0xd4, 
+       0x5e, 0xf3, 0x97, 0x59, 0xa1, 0xef, 0x42, 0x3b, 0x6, 0xb6, 
+       0x3e, 0x7c, 0x3f, 0x4b, 0x19, 0x68, 0xf4, 0x47, 0xe, 0x6c, 
+       0x57, 0x14, 0x80, 0x6b, 0x91, 0xad, 0x61, 0xe3, 0x8d, 0xa7, 
+       0x7c, 0x43, 00, 0xff, 0x82, 0xd2, 0x31, 0xcf, 0x1, 0x39, 
+       0x26, 0x7a, 0xd5, 00, 0xd7, 0xcb, 0x26, 0xf7, 0x94, 0xdb, 
+       0xe8, 0x82, 0x99, 0xfc, 0xd2, 0x4b, 0x2f, 0xf3, 0x92, 0x45, 
+       0x3a, 0x6, 0x37, 0x71, 0xf3, 0x13, 0xfe, 0x12, 0x8f, 0xe5, 
+       0x47, 0xf5, 0xa8, 0xda, 0xd1, 0xef, 0xbc, 0x73, 0xf, 0xf0, 
+       0xa0, 0x87, 0x8f, 0x81, 0x6d, 0x39, 0x8c, 0xfb, 0xb7, 0xda, 
+       0x42, 0xb0, 0xe, 0xe5, 0x83, 0x65, 0x60, 0x19, 0x34, 0x3d, 
+       0x87, 0xd0, 0x24, 0x5e, 0x8d, 0xd3, 0xe3, 0xbb, 0x7a, 0xd5, 
+       0xff, 0x65, 0xdd, 0x63, 0x6d, 0xed, 0xd0, 0xa0, 0x8e, 0xb1, 
+       0x9a, 0x27, 0xdd, 0x13, 0xb8, 0xd, 0x6a, 0x13, 0x6b, 0x57, 
+       0x21, 0x6f, 0xeb, 0xee, 0x55, 0x2c, 0x80, 0x54, 0xe3, 0x68, 
+       0x50, 0xec, 0xd, 0x42, 0x37, 0x5a, 0x3, 0x46, 0x4a, 0x34, 
+       0x4b, 0x56, 0xb2, 0xda, 0x72, 0x4c, 0xdb, 0xe0, 0x73, 0x67, 
+       0x42, 0x5f, 0x26, 0x60, 0xaf, 0xcb, 0xa0, 0x3e, 0x31, 0x6d, 
+       0x3, 0x1c, 0x60, 0x33, 0x88, 0xe4, 0xb4, 0x77, 0x72, 0xfb, 
+       0xed, 0x77, 0x14, 0x94, 0x55, 0x2, 0xd8, 0x68, 0x66, 0x18, 
+       0xf9, 0x91, 0x6a, 0x6c, 0xda, 0x13, 0x3b, 00, 0xae, 0x45, 
+       0xb6, 0x86, 0x29, 0x53, 0xa6, 0x7e, 0x53, 00, 0xff, 0x9c, 
+       0xae, 0xf5, 0x4, 0x70, 0x36, 0xd3, 0x94, 0xda, 0xe8, 0xf2, 
+       0x1e, 0x7b, 0xd1, 0xcb, 0xed, 0x64, 0xbb, 0xed, 0xb6, 0xdb, 
+       0xa5, 0xb5, 0xdf, 0xa, 0x1a, 0x1b, 0xbe, 0x1, 0x6a, 0x42, 
+       0xfa, 0xb, 0x5e, 0xc2, 0x63, 0x3c, 0xe, 0x1e, 0x57, 0xb, 
+       0x8a, 0x70, 0x63, 0xee, 0xf, 0xfd, 0x6e, 0x93, 0x1c, 0x80, 
+       0x7b, 0xd0, 0x70, 0x19, 0x84, 0x96, 0xcf, 0xf8, 0xbe, 0x6a, 
+       0xe2, 0xc8, 0x97, 0x6, 0xf4, 0x2e, 0x2b, 0xf1, 0x94, 0x55, 
+       0x2b, 0xfd, 0x1c, 0xce, 0xd6, 0xe8, 0x49, 0x2, 0x72, 0x2, 
+       0xe, 0xb1, 0xde, 0xc0, 0xa5, 0x31, 0x49, 0x1c, 0x39, 0xe3, 
+       0x41, 0x57, 0x81, 0xbc, 0x75, 0x7, 0x6e, 0xe5, 0xf, 0x8e, 
+       0x9b, 0x71, 0x26, 0xd6, 0x26, 0xd, 0xf8, 0x6c, 0xad, 0x8f, 
+       0x96, 0xdc, 0x59, 0x31, 0x53, 0x69, 0x3c, 0x2f, 0x78, 0xb0, 
+       0xa8, 0x92, 0x2d, 0xaa, 0xb6, 0xbf, 0xee, 0x7c, 0xf, 0x18, 
+       0xd0, 0xb5, 0x47, 0x60, 0xb4, 0xe2, 0x98, 0x7e, 0xf1, 0xc5, 
+       0x17, 0x6b, 0x23, 0x1e, 0xdd, 0x65, 0x21, 0xa0, 0xd, 0xd0, 
+       0xb7, 0x30, 0x22, 0x34, 0x16, 0xd0, 0xa1, 0x43, 0x87, 0xa6, 
+       0xde, 0x7e, 0x7b, 0x69, 0xf2, 0xd4, 0x53, 0x4f, 0x85, 0x36, 
+       0x19, 0xd8, 0x73, 0xe6, 0xcc, 0x9d, 0x27, 0x8d, 0x7d, 0xab, 
+       0xc8, 0x1, 0x68, 0x3a, 0xcc, 0x5a, 0x9b, 0x38, 0x8f, 0x3b, 
+       0x3e, 0x54, 0x53, 0x5c, 0xe5, 0x95, 0x74, 0x6c, 0xca, 0x39, 
+       0xf4, 0xd0, 0x43, 0xd0, 0xe0, 0xdf, 0xfe, 0xde, 0xf7, 0x7e, 
+       0x70, 0xb4, 0x32, 0x75, 0x7, 0x70, 0x4, 0xae, 0x14, 0xc0, 
+       0x83, 0x55, 0xa2, 0xad, 0xaa, 0x7a, 0x1f, 0xbc, 0x50, 0x83, 
+       0xc3, 0x97, 0xa5, 0x4b, 0x97, 0x64, 0xc4, 0xbb, 0xf0, 0x2d, 
+       0x37, 0x40, 0x6d, 0x80, 0x3, 0x6c, 0x78, 0x49, 0x8, 0x7f, 
+       0xd, 0x8c, 0x92, 0x15, 0xad, 0x30, 0x71, 0xe1, 0xc2, 0x85, 
+       0x6c, 0x5e, 0x9, 0xf3, 0x7a, 0xf7, 0x99, 0x65, 0xa3, 0xaf, 
+       0xca, 0x40, 0x7e, 0x35, 0x37, 0xd6, 0x3b, 0x27, 0x59, 0xb9, 
+       0xb0, 0x8c, 0x53, 0xc5, 0x58, 0x36, 0x2b, 0xac, 0x72, 0xc8, 
+       0x86, 0xf5, 0xa7, 0x15, 0xfe, 0x57, 0xf4, 0x3, 0x1e, 0xc7, 
+       0xc0, 0x46, 0xae, 0x8c, 0xcd, 0x92, 0xb8, 0x29, 0x9, 0xee, 
+       0xdc, 0x8, 0xc0, 0xd, 0xf6, 0x10, 0xc1, 0x43, 0xbc, 0x5d, 
+       0xa3, 0xc9, 0x23, 0x9a, 0xbf, 0xf4, 0xc9, 0xa2, 0x9a, 0x19, 
+       0x40, 0x67, 0xf2, 0x98, 0x42, 0xf4, 0x6b, 0x76, 0x31, 0xe8, 
+       0x4c, 0xd7, 0x1d, 0x9, 00, 0x79, 0xec, 0x3, 0xc8, 0xaa, 
+       0x79, 0x54, 0x55, 0xaa, 0x32, 0x1e, 0x3c, 0x8, 0x63, 0xfa, 
+       00, 0x1b, 0x8f, 0xe6, 0x66, 0x1d, 0x41, 0x83, 0x49, 0x4a, 
+       0x73, 0x6f, 0x7d, 0x4e, 0xe6, 0x9d, 0x4, 0xd3, 0x74, 0xee, 
+       0xdc, 0x7, 0xe7, 0xfe, 0xf1, 0x8f, 0x33, 0x1, 0x36, 0x20, 
+       0xb6, 0x39, 0x4e, 0xfc, 0xaf, 0xa, 0xd8, 0x6e, 0x33, 0x2f, 
+       0xc1, 0x68, 0xe, 0xde, 0x30, 0x75, 0xea, 0x94, 0xef, 0x7e, 
+       0xff, 0xfb, 0xdf, 0x3f, 0x4a, 0xe9, 0xb5, 00, 0x3c, 0xb4, 
+       0x4f, 0x1a, 0xfc, 0x5a, 0x3, 0x1c, 0x6d, 0x74, 0xf7, 0xdd, 
+       0xf7, 0x68, 0x5, 0x78, 0x55, 0x9a, 0x3e, 0xc1, 0xc3, 0x2f, 
+       0xc0, 0xd, 0xa0, 0xe1, 0x61, 0xdc, 0x7f, 0xc4, 0xd, 0xe, 
+       0xd7, 0xad, 0x9a, 0x90, 0xfe, 0x16, 0xe8, 0x2, 0x4d, 0xe4, 
+       00, 0x59, 0x23, 0xb4, 0x8f, 0xe5, 0xa6, 0x37, 0xe5, 0xf8, 
+       0x71, 0xab, 0x7, 0xb, 0xea, 0x1d, 0xc7, 0xf9, 0x8d, 0xab, 
+       0xa6, 0xc, 0xe1, 0xac, 0x55, 0x66, 0xf9, 0x73, 0xba, 0x2d, 
+       0x60, 0x4f, 0x21, 0x4a, 0xd6, 0xde, 0xb8, 0x34, 0x4e, 0x75, 
+       0xa9, 0xd3, 0x95, 0x4, 0x77, 0xe7, 0xe5, 0xec, 0x22, 0x9a, 
+       0x7e, 0x5b, 0x6b, 0x7, 0x80, 0x2f, 0x5b, 0xb6, 0xec, 0xc9, 
+       0xc5, 0x8b, 0x17, 0x93, 0x56, 0x93, 0x73, 0x67, 0x11, 0x9a, 
+       0x1, 0x30, 0x9c, 0x7d, 0xbf, 0xa2, 0x5d, 0x13, 0x4d, 0xdf, 
+       0x14, 0x77, 0x94, 0x69, 0xbb, 0x13, 0x9, 0x35, 0xad, 0xc8, 
+       0x48, 0x6b, 0xd0, 0x8e, 0x5e, 0xbb, 0xb8, 0xfe, 0xd0, 0xb6, 
+       0x60, 0x2, 0x6e, 0x4, 0x75, 0xc4, 0x88, 0x11, 0x6a, 0xcf, 
+       0xbb, 0x99, 0xcb, 0x2e, 0xfb, 0x9f, 0x4, 0x60, 0xcf, 0x9c, 
+       0x19, 0x8e, 0x46, 0x8a, 0x81, 0x8d, 0xd6, 0xc6, 0x93, 0xf6, 
+       0x57, 0xa1, 0xb1, 0x8b, 0x99, 0x32, 0x54, 0x1f, 0x58, 0xd7, 
+       0x87, 0xa, 0xd0, 0xe0, 0x3f, 0xf8, 0xce, 0x77, 0xbe, 0x73, 
+       0x84, 0xae, 0x97, 0x3, 0xb8, 0x35, 0x4b, 0xac, 0xc1, 0x3d, 
+       0x80, 0x5, 0xeb, 0x44, 00, 0xbf, 0x7a, 0xee, 0xdc, 0x79, 
+       0x73, 0x2e, 0xbd, 0xf4, 0x4f, 0x61, 0x37, 0xdf, 0x80, 0x1, 
+       0xfd, 0xc3, 0x7, 0x14, 0xe1, 0x97, 0x3d, 0x3c, 0x44, 0x16, 
+       00, 0x38, 0xc0, 0xa0, 0x3f, 0xe1, 0x73, 0x35, 0x80, 0x28, 
+       0x6e, 0x3, 0xfd, 0xfd, 0xca, 0x2b, 0xaf, 0x84, 0xfe, 0x89, 
+       0x81, 0x6d, 0xe0, 0x11, 0xe2, 0x71, 0x94, 0x55, 0x8b, 0x43, 
+       0x6e, 0x65, 0x3a, 0x87, 0x1, 0x3, 0x1a, 0xc8, 0x43, 0x5c, 
+       0x7f, 0x68, 0x5a, 0x36, 0xab, 0x69, 0x8b, 0xc0, 0xdd, 0x21, 
+       0xda, 0x2f, 0xea, 0x76, 0x83, 0xdb, 0x61, 0x8c, 0xc9, 0xaa, 
+       0xc1, 0xcd, 0xd, 0x38, 0x8f, 0xe, 0xf9, 0xd1, 0x42, 0xbb, 
+       0x7c, 0x5e, 0xd0, 0xaa, 0x79, 0x43, 0xb5, 0x87, 0x2, 0xba, 
+       0x71, 0x10, 0x75, 0x87, 0x99, 0xc1, 0x30, 0x3, 0xb3, 0x46, 
+       0xb4, 0x7b, 0xd, 0x3c, 0xca, 0x81, 0xbe, 0x3b, 0x8d, 0xd0, 
+       0xe0, 0x53, 0x7a, 0x5a, 0xe5, 0xa4, 0xaa, 0xad, 0x3b, 0x75, 
+       0x8e, 0x9d, 0xcb, 0x20, 0x84, 0x36, 0xde, 0x42, 0x9, 0xb0, 
+       0xd1, 0x44, 0xa4, 0x69, 0xae, 0xd7, 0x7e, 0xc7, 0x1d, 0xb7, 
+       0xcf, 0x12, 0xb0, 0x6f, 0xd6, 0xfd, 0x9e, 0x97, 0xc6, 0xa0, 
+       0xfe, 0xab, 0x5, 0xb6, 0xdb, 0x3b, 0x6c, 0xd8, 0xd0, 0x60, 
+       0xa2, 0x6f, 0xb2, 0xc9, 0xa6, 0xc7, 0x7e, 0xfb, 0xdb, 0xdf, 
+       0x3e, 0x4c, 0xe9, 0xd5, 00, 0xdc, 0x83, 0x57, 0xb0, 0x4e, 
+       0x66, 0xce, 0x3c, 0xe7, 0x7f, 0x64, 0xa6, 0xcf, 0x7c, 0xfa, 
+       0xe9, 0xa7, 0x83, 0x7c, 0xf1, 0x8, 0xe, 0x5e, 0xa1, 0xbd, 
+       0xad, 0xb9, 0xe1, 0x5b, 0xdc, 0x7f, 0xf0, 0xb8, 0x56, 0x47, 
+       0x3f, 0xd3, 0xdf, 0x68, 0x55, 0xf7, 0x91, 0x1, 0x6e, 0xf9, 
+       0xa0, 0x2c, 0x5c, 0x6f, 0xca, 0x41, 0x6e, 0x79, 0xab, 0x2d, 
+       0xa6, 0x9, 0x5d, 0x7c, 0x2c, 0x2b, 0xd5, 0x94, 0x41, 0xdd, 
+       0x85, 0xb3, 0x7a, 0x69, 0xee, 0xd8, 0x2c, 0x37, 0xb8, 0x8d, 
+       0x4b, 0xf8, 0x58, 0x12, 0x33, 0x3d, 0xd, 0x53, 0xc5, 00, 
+       0x87, 0x88, 0x36, 0x93, 0xb5, 0xb7, 0x2a, 0x7c, 0x85, 0xf9, 
+       0x40, 0x35, 0x8e, 0x86, 0xc5, 0xd, 0x75, 0xe3, 0x9, 0x61, 
+       0x8a, 0x76, 0x10, 0x5, 0xe0, 0x55, 0x43, 0xb3, 0x38, 0xaf, 
+       0xcb, 0x70, 0x39, 0x66, 0xb6, 0x3b, 0x14, 0x8d, 0xc0, 0x8a, 
+       0xe6, 0xa2, 0x45, 0x8b, 0xdc, 0xb6, 0x62, 0x12, 0x15, 0xfd, 
+       0x86, 0x3e, 0xce, 0x6d, 0x40, 0x70, 0xf0, 0xd0, 0x47, 0x48, 
+       0x29, 0xf7, 0xc9, 0x27, 0x9f, 0x6c, 0x55, 0x39, 0xf, 0x5c, 
+       0x7b, 0xed, 0xb5, 0x77, 0x29, 0x2b, 0xc0, 0xb6, 0x26, 0x23, 
+       0xb4, 0xb7, 0xc6, 0xe6, 0xed, 0x2b, 0x6b, 0x3f, 0x88, 0xa3, 
+       0x4a, 0x58, 0x9d, 0xee, 0xd3, 0xc7, 0x5d, 0xa2, 0x57, 0x93, 
+       0x63, 0xf7, 0xdd, 0x21, 0x87, 0x1c, 0x5c, 0xbf, 0xe9, 0xa6, 
+       0x9b, 0xfd, 0xf8, 0x5b, 0xdf, 0xfa, 0xd6, 0xa1, 0x22, 0x52, 
+       0xc, 0x70, 0xea, 0x1b, 0xe4, 0x43, 0x21, 0xed, 0x40, 0x83, 
+       0xfb, 0x8d, 0x32, 0xda, 0xc8, 0x20, 0x16, 0x34, 0xf8, 0x13, 
+       0x4f, 0x3c, 0xf1, 0x88, 0x4e, 0x55, 0xbd, 0x40, 0xeb, 0x1f, 
+       0x12, 0xa5, 0xf6, 0xbc, 0x49, 0xe, 0xef, 0xf0, 0xf4, 0x15, 
+       0xfc, 0x73, 0x1f, 0x9a, 0xd7, 0xba, 0xbf, 0x6a, 0x27, 0xfe, 
+       0x6b, 0x6e, 0xbf, 0x34, 0x3c, 0x6a, 0x83, 0xae, 0xe5, 0xc0, 
+       0x65, 0xb8, 0xff, 0x8, 0x7b, 0x53, 0xe, 0x3, 0x88, 0x2c, 
+       0xcf, 0x2e, 0x8f, 0xd9, 0x2c, 0xdb, 0xd0, 0xae, 0x96, 0x3e, 
+       0xf8, 0x62, 0x47, 0xa8, 0x3c, 0x78, 0x43, 0xb9, 0xc2, 0x57, 
+       0x78, 0x6c, 0xad, 0x5d, 0x16, 0xd8, 0xca, 0xd3, 0x75, 0x6f, 
+       0x39, 0x89, 0x91, 0xf3, 0xcd, 0x10, 0x74, 0xc7, 0x85, 0x42, 
+       0xb4, 0x38, 0xb1, 0x40, 0x8b, 0x6a, 0xa4, 0x55, 0xed, 0xdc, 
+       0x50, 0x33, 0x94, 0x8e, 0x24, 0xe, 0x28, 0x34, 0xc2, 0xb2, 
+       0xf0, 0x51, 0x35, 0x4d, 0xdf, 0x10, 0xd3, 0x86, 0x26, 0xde, 
+       0xc0, 0x73, 0xe7, 0x6a, 0x34, 0x4c, 0x4b, 0x73, 0xf8, 0x96, 
+       0x9a, 0x43, 0xca, 0x8a, 0xdb, 0x60, 0xc1, 0x81, 0xe0, 0x43, 
+       0xf, 0x3d, 0xb4, 0x56, 0x65, 0xcc, 0xf9, 0xcb, 0x5f, 0xfe, 
+       0x32, 0x4b, 0x3f, 0x2d, 0xdc, 0x34, 0x8c, 0x38, 0x42, 0xe, 
+       0xd8, 0xf1, 00, 00, 0xef, 0xce, 0xfb, 0xab, 0x3, 0xb6, 
+       0xea, 0x16, 0x1c, 0xa7, 0xbb, 0xea, 0xc0, 0x7, 00, 0xfe, 
+       0x93, 0x7f, 0xfc, 0xc7, 0x7f, 0x9c, 0xa1, 0x44, 0x3, 0x9c, 
+       0xd7, 0x45, 0xe3, 0xc7, 0x64, 0x1e, 0xa4, 00, 0xb8, 0xdb, 
+       0xe, 0xb8, 0x3d, 0xa0, 0xad, 0xd4, 0x5e, 0xf2, 0x87, 0x1e, 
+       0x7c, 0xf0, 0xc1, 0x8b, 0x9e, 0x79, 0xe6, 0x19, 0x2d, 0x4d, 
+       0xb4, 0x85, 0xbe, 0x7, 0xd8, 0x98, 0xe5, 0x1e, 0x90, 0x9, 
+       0x7b, 0xeb, 0xe8, 0x67, 0xad, 0x92, 0x87, 0x85, 0x34, 0xf, 
+       0x1c, 0x6, 0x36, 0x72, 0xe1, 0xb2, 0x2c, 0x37, 0xb5, 0x94, 
+       0x87, 0xbc, 0xb2, 0x96, 0x83, 0x2c, 0x98, 0x9e, 0x65, 0xcf, 
+       0xf2, 0x41, 0x58, 0xad, 0x3, 0x5f, 0x5a, 0x9f, 0x78, 0x41, 
+       0xf7, 0xc1, 0x4f, 00, 0x6e, 0xbe, 0x16, 0x3, 0xbc, 0xcb, 
+       0x4a, 0x39, 0x65, 0xf5, 0x54, 0x22, 0xe0, 0xb6, 0x8f, 0x1, 
+       0xde, 0x26, 0xed, 0xf7, 0x84, 0xcc, 0x90, 0xaa, 0xf, 0x6e, 
+       0xa0, 0x50, 0x9c, 0x1b, 0xd, 0x33, 0x88, 0x9b, 0x29, 0x6c, 
+       0xec, 0xd7, 0x88, 0x45, 0x99, 0xbd, 0x72, 0x6, 0x9e, 0xe9, 
+       0x12, 0x1a, 0xdc, 0xc, 0x22, 0xcc, 0x8f, 0x5e, 0x7a, 0xe9, 
+       0xa5, 0x5e, 0x97, 0x1, 0x1, 0xea, 0x8f, 0x47, 0x58, 0x70, 
+       0xf7, 0xdd, 0x77, 0x5f, 0xeb, 0xe3, 0x8f, 0x3f, 0x3e, 0xf7, 
+       0xba, 0xeb, 0xae, 0x3, 0xd8, 0x6, 0xb1, 0x85, 0x1c, 0xf3, 
+       0xd4, 0x71, 0x6b, 0x37, 0x77, 0xdc, 0x5f, 0x2d, 0xb0, 0x69, 
+       0x17, 0x8e, 0x75, 0x84, 0x83, 0xf, 0x3e, 0xb8, 0x7e, 0xf3, 
+       0xcd, 0xb7, 0xf8, 0x99, 0x34, 0xf8, 0x81, 0x4a, 0x8a, 0x1, 
+       0xce, 0xfe, 0x7, 0x64, 0xca, 0x8a, 0x80, 0x76, 0x19, 0xe0, 
+       00, 0xbb, 00, 0xe0, 0x73, 0x35, 0x1, 0xd7, 0x56, 0xdd, 
+       0x4b, 0xa4, 0xc5, 0xdb, 0x34, 0xe0, 0xe6, 0x81, 0x4d, 0x3f, 
+       0x99, 0xa7, 0x84, 0xb5, 0x3a, 0xed, 0x35, 0xc8, 0xed, 0x59, 
+       0xcf, 0x4e, 0x99, 0xdc, 0xff, 0x31, 0xa8, 0x91, 0xb, 0x5c, 
+       0x6f, 0xc0, 0x8d, 0xbc, 0x32, 0xa7, 0x2f, 0x35, 0x68, 0x50, 
+       0xff, 0x98, 0x76, 0x35, 0xed, 0x11, 0xcd, 0x56, 0xcd, 0xb7, 
+       0xd, 0x6e, 0x3, 0x1b, 0x25, 0x80, 0x37, 0x1e, 0xcb, 0x62, 
+       0xa5, 0x2c, 0xe7, 0xa2, 0x67, 0x66, 0x26, 0x62, 0xa2, 0x84, 
+       0x6d, 0x1a, 0xd, 0x9f, 0xd2, 0xe2, 0x54, 0x7d, 0xd1, 0xa3, 
+       0x35, 0x5d, 0xea, 0xde, 0x15, 0x37, 0x94, 0xc6, 0xc6, 00, 
+       0xd4, 0x3c, 0x23, 0xa5, 0x45, 0x84, 0xee, 0x89, 0xf4, 0x70, 
+       0xd5, 0x65, 0xc4, 0xb4, 0xdd, 0xa1, 0x68, 0x6, 0xbc, 0xea, 
+       0x9e, 0x92, 0x50, 0x45, 0xcd, 0xec, 0x81, 0x68, 0x99, 0xcb, 
+       0x94, 0x61, 0x8f, 0x6, 0x9a, 0x3d, 0x7b, 0x76, 0xab, 0xb4, 
+       0xd2, 0x83, 0x3a, 0x25, 0xf4, 0x76, 0xdd, 0x2, 0xb0, 0x6d, 
+       0x8e, 0x6, 0x93, 0x54, 0xbf, 0x1, 0x36, 0x9e, 0x6b, 0x3c, 
+       0x71, 0xa0, 0xd3, 0xe0, 0x31, 0xee, 0xaf, 0xca, 0x14, 0xcf, 
+       0x56, 0xa9, 0xeb, 0xdf, 0x91, 0x23, 0x47, 0x24, 0x33, 0x66, 
+       0x1c, 0x84, 0x6, 0x3f, 0xf1, 0x9b, 0xdf, 0xfc, 0xe6, 0x1, 
+       0xca, 0xc1, 0xeb, 0xa2, 0x6c, 0x74, 0xf1, 0x81, 0xf, 0xc, 
+       0x52, 0xb4, 0xc9, 0x2, 0x89, 0x12, 0xf0, 0x80, 0x6, 0x3f, 
+       0x18, 0xe0, 0x2, 0x3f, 0xee, 0xba, 0xeb, 0xae, 0xb9, 0xf2, 
+       0x97, 0xcd, 0x9f, 0x3f, 0xbf, 0x8d, 0x1, 0x97, 0xbe, 0xa1, 
+       0xff, 0x90, 0x9, 0xc2, 0x5a, 0x1d, 0x72, 0xf9, 0xf0, 0xc3, 
+       0xf, 0x33, 0xfd, 0x4a, 0xb9, 0xcf, 0x63, 0x70, 0x5b, 0x1e, 
+       0x28, 0x83, 0xfe, 0xeb, 0x4d, 0x59, 0xc8, 0xab, 0x94, 0x5d, 
+       0xfe, 0xec, 0x37, 0xcb, 0x9d, 0xe5, 0xc2, 0xf4, 0x9, 0x2b, 
+       0x75, 0xd4, 0x5f, 0xc0, 0xae, 0xd3, 0x7c, 0x7b, 0x91, 0xee, 
+       0xf1, 0xe0, 0x6f, 0x7e, 0x16, 0x83, 0xdb, 0xf2, 0x53, 0x40, 
+       0xbe, 0xa7, 0xd2, 0x3c, 0x2a, 0x70, 0x33, 0xde, 00, 0x47, 
+       0x73, 0xf3, 0x96, 0xca, 0x1b, 0x5a, 0x30, 0x2a, 0x20, 0x58, 
+       0xc9, 0xf, 0x33, 0xd4, 0x8d, 0xa7, 0x23, 0xcd, 0x6c, 0x56, 
+       0x4d, 0xd9, 0x49, 0x86, 0x99, 0x53, 0xab, 0x83, 0xbe, 0x3d, 
+       0x65, 0x98, 0x3e, 0x9d, 0xec, 0xe, 0xc6, 0x44, 0x63, 0xee, 
+       0xad, 0xd1, 0xd1, 0x6d, 0xac, 0xb5, 0xb8, 0x50, 0x16, 0x8b, 
+       0x1f, 0xb7, 0xdf, 0x7e, 0x7b, 0xab, 0xce, 0xf7, 0x9e, 0xf7, 
+       0xe7, 0x3f, 0xff, 0xf9, 0x76, 0x11, 0x8b, 0x85, 0x19, 0x81, 
+       0xb6, 0x27, 0xdd, 0x1a, 0xdb, 0xa7, 0xa8, 0x50, 0x7, 0xfa, 
+       0x2, 0x70, 0x37, 0xe9, 0x7d, 0xec, 0x13, 0xaa, 0x7d, 0xbb, 
+       0x4b, 0xf7, 0x7d, 0xa8, 0x4e, 0x9f, 0xfb, 0x4d, 0xe, 0x3a, 
+       0xe8, 0xc0, 0xfa, 0xcd, 0x36, 0xdb, 0xfc, 0xa4, 0x6f, 0x7c, 
+       0xe3, 0x1b, 0xfb, 0xa9, 0xf0, 0x58, 0x83, 0x3, 0x72, 0xda, 
+       0x83, 0xcc, 0x20, 0x90, 0x4c, 0x3b, 0x68, 0xab, 0x7, 0x3b, 
+       0x87, 0x41, 0x9b, 0x8b, 0x6f, 0xf, 0xdc, 0x71, 0xc7, 0x1d, 
+       0x97, 0xcd, 0xd1, 0x41, 0x7b, 0x98, 0xb8, 0x6, 0x76, 0x6f, 
+       00, 0x27, 0xad, 0x9d, 0x11, 0x38, 0xc2, 0x2, 0x17, 0xfd, 
+       0x1e, 0x9b, 0xe4, 0xd6, 0xb0, 0x96, 0xd, 0xcb, 0xa3, 0xea, 
+       0x57, 0xb5, 0x43, 0x4e, 0xe9, 0x7b, 0xea, 0x6c, 0x8f, 0x2c, 
+       0x9b, 0x36, 0xa1, 0x65, 0xb1, 0x1a, 0xe2, 0xe0, 0x4a, 0xeb, 
+       0x11, 0xef, 0xe8, 0x11, 0x1e, 0x3, 0x61, 0xc, 0x6e, 0x63, 
+       0x90, 0x10, 0xb9, 0x81, 0xc7, 0x25, 0x5d, 0x4f, 0xe0, 0xe6, 
+       0x26, 0x13, 0x88, 0x89, 0x86, 0x11, 0x44, 0xa3, 0xca, 0x6c, 
+       0x1d, 0x4e, 0x50, 0xd5, 0xf3, 0x6e, 0x77, 0x98, 0x1b, 0x6c, 
+       0xc6, 0xc2, 0x4, 0x3, 0x5c, 0xa6, 0xf9, 0x3a, 0x59, 0x35, 
+       0x87, 0xbe, 0x47, 0x71, 0x42, 0x75, 0x7e, 0x5a, 0xa3, 0x7b, 
+       0x38, 0x86, 0xa9, 0x24, 0x77, 0x2a, 0x4c, 0x64, 0x9d, 0x60, 
+       0xd6, 0xac, 0x59, 0xad, 0x12, 0xce, 0x79, 0x97, 0x5c, 0x72, 
+       0xc9, 0x1d, 0xba, 0xcd, 0x73, 0xcb, 0xd8, 0x14, 0x45, 0xa0, 
+       0xf1, 00, 0x1b, 0x9e, 0xc1, 0x4f, 0x77, 0xc, 0xa0, 0xc6, 
+       0xa4, 0x65, 0xf1, 0xec, 0x23, 0xfd, 0xf0, 0xbd, 0xea, 0x50, 
+       0xb1, 0x1b, 0x3d, 0x7a, 0x74, 0x72, 0xe0, 0x81, 0x7, 0xd6, 
+       0x6f, 0xb1, 0xc5, 0x96, 0x3f, 0xff, 0xda, 0xd7, 0xbe, 0xb6, 
+       0xaf, 0x6e, 0x1c, 0x28, 0xf, 0xc8, 0xd9, 0xaa, 0xa, 0xc0, 
+       0x69, 0x97, 0xb5, 0x38, 0x2, 0x6a, 0x80, 0x33, 0xc0, 0x99, 
+       0x37, 0xc1, 0xb2, 0xd1, 0xda, 0xc4, 0x3, 0xb7, 0xdd, 0x76, 
+       0xdb, 0xe5, 0x77, 0xdf, 0x7d, 0x77, 0x3b, 0x1a, 0xdc, 0x72, 
+       0xa2, 0x7c, 0x55, 0x3b, 0xb4, 0x9e, 0xac, 0x27, 0xa6, 0x5d, 
+       0x69, 0xf, 0xe8, 0x71, 0xbf, 0x23, 0x7, 0x6, 0xa0, 0xc1, 
+       0x57, 0x75, 0x21, 0xb9, 0x1b, 0xe2, 0x55, 0x72, 0xcb, 0xaf, 
+       0xc3, 0x58, 0xb6, 0xc9, 0x5e, 0x4d, 0x9b, 0x9e, 0x7f, 0xfe, 
+       0xf9, 0x36, 0x2d, 0x4, 0x3e, 0xac, 0xdb, 0xc, 0x6c, 0x87, 
+       0x60, 0xcf, 0xb2, 0x83, 0xfc, 0x80, 0xcf, 0x92, 0xae, 0x12, 
+       0x70, 0x9b, 00, 0x21, 0x1e, 0xe2, 0x14, 0xd4, 0xaa, 0x86, 
+       0xdd, 0x8b, 0xd9, 0x3, 0x33, 0xab, 0x75, 0x34, 0x14, 0xcf, 
+       0x68, 0xe7, 0x51, 0x8e, 0x38, 0x8c, 0xd1, 0x68, 0x98, 0x96, 
+       0x46, 0xad, 0x89, 0xae, 0xeb, 0x61, 0xfa, 0xee, 0x3c, 0xe8, 
+       0xda, 0xd3, 0xd1, 0x8c, 0xe4, 0xcc, 0xbd, 0xa5, 0x29, 0x32, 
+       0x12, 0x82, 0xea, 0x1b, 0x90, 0x2b, 0x88, 0xb9, 0xe2, 0xad, 
+       0xb7, 0xde, 0xaa, 0xd, 0x2a, 0x73, 0xe7, 0x5d, 0x7c, 0xf1, 
+       0xc5, 0xb7, 0x2b, 0x39, 0x16, 0x5a, 0xe2, 0x8c, 0xbc, 0x84, 
+       0x78, 0x83, 0x1b, 0x4d, 0x6, 0x1f, 0x29, 0x97, 0x89, 0x3a, 
+       0x60, 0xe8, 0xc7, 0x9, 0x2a, 0x7f, 0xed, 0x1a, 0x5b, 0xf5, 
+       0x2c, 0x70, 0x3a, 0xa3, 0x2d, 0x39, 0xe0, 0x80, 0x3, 0xea, 
+       0xb7, 0xde, 0x7a, 0x9b, 0x53, 0x4, 0xf0, 0x3d, 0x75, 0x11, 
+       0x70, 0xe3, 0x39, 0xf0, 0xc1, 0x1a, 0x5c, 0xd1, 0x20, 0x33, 
+       0xb4, 0x9b, 0xc1, 0xcd, 0x56, 0xc, 0xa6, 0xb9, 0xfd, 0x8a, 
+       0x1b, 0x6f, 0xbc, 0xf1, 0x5e, 0x69, 0xf1, 0x2b, 0xee, 0xbc, 
+       0xf3, 0xce, 0xa0, 0xc1, 0x75, 0xad, 0x26, 0x87, 0xd6, 0xd6, 
+       0xb4, 0x2b, 0xc8, 0x16, 0x7d, 0x4d, 0x3f, 0x1b, 0xdc, 0x96, 
+       0x31, 0x87, 0x96, 0x93, 0x5a, 0xa, 0x42, 0xee, 0x91, 0x53, 
+       0x29, 0xb9, 0x82, 0x9d, 0x6f, 0x96, 0x67, 0x42, 0xcb, 0x9f, 
+       0xc3, 0x4a, 0xca, 0x81, 0x2e, 0xeb, 0x41, 0xda, 0x4b, 0xc2, 
+       0xc9, 0x1f, 0xc8, 0x9, 0xca, 0xc0, 0xe0, 0xb6, 0x92, 0x35, 
+       0x1e, 0xc3, 0xbe, 0xd3, 0x52, 0x74, 0xbb, 0x5, 0xb7, 0xa, 
+       0xb1, 0xd0, 0x9b, 0x90, 0x9, 0x13, 0x32, 0xb2, 0xbc, 0xae, 
+       0x65, 0xfa, 0x77, 0x58, 0x4, 0xab, 0xc6, 0x99, 0xa1, 0x6e, 
+       0xb0, 0x1, 0xee, 0x11, 0xf, 0xd3, 0x5c, 0xab, 0x84, 0xec, 
+       0x5, 0xae, 0x86, 0x6c, 0x41, 0x5e, 0x97, 0x41, 0x8, 0x7d, 
+       0x77, 0x66, 0x6c, 0x96, 0xd3, 0xe1, 0x12, 0x82, 0xa0, 0xbd, 
+       0x31, 0xad, 0xaa, 0x75, 0x6, 0xf6, 0xfd, 0xf7, 0xdf, 0x3f, 
+       0xff, 0xc2, 0xb, 0x2f, 0xbc, 0x43, 0xf7, 0x7, 0x2d, 0xa4, 
+       0x10, 0x81, 0xf5, 0xbc, 0x12, 0x2d, 0x5, 0xa8, 0x6d, 0x9a, 
+       0xd2, 0x59, 0xf0, 0x13, 0x87, 0x66, 0xb, 0x8f, 0xbb, 0xf4, 
+       0xc1, 0x80, 0x1f, 0xe9, 0xd0, 0xc2, 0xcf, 0x68, 0x4f, 0x77, 
+       0x3f, 0x6, 0x9e, 0xff, 0x4d, 0x6e, 0xcc, 0x98, 0xf5, 0x4, 
+       0xf0, 0xfd, 0x1, 0xf8, 0x69, 0x3f, 0xfd, 0xe9, 0x4f, 0xff, 
+       0x55, 0x75, 0x67, 0xe, 0x6e, 0x70, 0x67, 0x57, 0x19, 0xb3, 
+       0x1a, 0x1c, 0xb9, 0x81, 0xd1, 0x68, 0x70, 0x40, 0x6e, 0xd, 
+       0x9e, 0x1f, 0x4, 0xf5, 0xd8, 0xf0, 0x1e, 0x81, 0xfb, 0x2a, 
+       0x81, 0xbc, 0xd, 0x13, 0xbd, 0x5a, 0x47, 0x3f, 0x6a, 0xfe, 
+       0xe, 0x38, 0x52, 0xf0, 0xd1, 0xa0, 0x26, 0xa4, 0xef, 0x9, 
+       0x2d, 0x67, 0x96, 0x11, 0xe4, 0xb0, 0x16, 0x87, 0x7c, 0x4a, 
+       0x7e, 0xf2, 0xcf, 0xb6, 0x6d, 0xee, 0x5b, 0xde, 0x8, 0x29, 
+       0xa3, 0x5a, 0xfa, 0x6c, 0xed, 0x96, 0x49, 0xfe, 0x9e, 0x30, 
+       0xc0, 0x9b, 0x60, 0xf0, 0xcb, 0xa, 0x95, 0x10, 0x1e, 0x1a, 
+       0x8f, 0xe0, 0xd3, 0xb2, 0xa4, 0x68, 0xa1, 0xab, 0xa4, 0x55, 
+       0xc5, 00, 0xa7, 00, 0x17, 0xc6, 0x6a, 0xde, 0xdd, 0xda, 
+       0xb7, 0xcb, 0xa8, 0x52, 0xb1, 0xa3, 0xc1, 0x38, 0x37, 0x9c, 
+       0xd0, 0xc, 0x31, 0xe3, 0xd5, 0xc0, 0xb4, 0xe8, 0xba, 0xec, 
+       0x8a, 0x69, 0xc7, 0x19, 0xa1, 0xeb, 0x32, 0x60, 0x30, 0x65, 
+       0xb8, 0x83, 0xe9, 0x64, 0x3a, 0x9f, 0x81, 0x84, 0xd5, 0x4e, 
+       0x4d, 0x95, 0xcb, 0x32, 0x29, 0xa6, 0xe9, 0x78, 0xc, 0xec, 
+       0x8b, 0x2e, 0xba, 0xe8, 0x76, 0xa5, 0x5b, 0x3b, 0x87, 0x85, 
+       0x22, 0xfd, 0x76, 0x68, 0x8d, 0xd, 0xb8, 0xdd, 0x51, 0x30, 
+       00, 0xde, 0x63, 0x8a, 0x37, 0x49, 0xe3, 0xed, 0x35, 0x64, 
+       0xc8, 0xd0, 0xaf, 0x49, 0x30, 0x1b, 0xf4, 0xf1, 0x38, 0x25, 
+       0xfd, 0xef, 0x73, 0xeb, 0xad, 0xb7, 0x5e, 0x32, 0x76, 0xec, 
+       0x58, 0x7d, 0xf4, 0x71, 0xd4, 0xae, 0xda, 0xc9, 0xf6, 0x73, 
+       0xb5, 00, 0x80, 0xa3, 0xc1, 0x8b, 0x17, 0xd9, 0xc, 0x70, 
+       0x83, 0xbb, 0xb, 0xc0, 0xaf, 0xbc, 0xf2, 0xca, 0xbb, 0xb5, 
+       0x30, 0x79, 0x2d, 00, 0xc7, 0x44, 0xaf, 0xc6, 0xd1, 0x8f, 
+       0x6c, 0x26, 0x71, 0x3f, 0xa3, 0xb5, 0xd, 0x72, 0xd2, 0x2c, 
+       0x5f, 0xc8, 0x42, 0xb5, 0xa0, 0x2b, 0xae, 0x87, 0xe4, 0xb3, 
+       0x43, 0xcf, 0xea, 0x83, 0xd6, 0x36, 0x5d, 0x3, 0x1c, 0xda, 
+       0xf6, 0xc5, 0xf7, 0xf5, 0xf4, 0x5b, 0x53, 0xdd, 0x36, 0x59, 
+       0x3, 0x8f, 0x2a, 0x1f, 0xb8, 0x42, 0x66, 0x2c, 0x37, 0x6, 
+       0x37, 0x3c, 0xec, 0x16, 0xd8, 0xba, 0x1e, 0x4, 0x8c, 0xb0, 
+       0x27, 0x67, 0x42, 0x26, 0x6e, 0x80, 0xaf, 0x95, 0xe9, 0x70, 
+       0x4f, 0xad, 0x20, 0x34, 0xf8, 0xcc, 0x68, 0x42, 0x98, 0x84, 
+       0x87, 0x49, 0xec, 0x7, 0xc6, 0xd7, 0xea, 0x4c, 0xdf, 0xc0, 
+       0x8e, 0x69, 0x1b, 0xdc, 0x74, 0xbc, 0x56, 0xb9, 0xd3, 0x5a, 
+       0xc0, 0x48, 0xb1, 0x7, 0xb9, 0x12, 0xd7, 0xd, 0xb0, 0x63, 
+       0x13, 0xdc, 0x1a, 0x1b, 0x21, 0x46, 0x53, 0xd1, 0x41, 0x74, 
+       0xa, 0x2e, 0xf, 0x6c, 0x2d, 0x46, 0x1d, 0xa0, 0x97, 0xfb, 
+       0xcf, 0x9e, 0x32, 0x65, 0xe3, 0x3a, 0xbd, 0x7, 0x5e, 0x77, 
+       0xc3, 0xd, 0x37, 0x64, 0xb4, 0x7a, 0xdc, 0xc6, 0x3c, 0xfe, 
+       0x7f, 0x8b, 0xd3, 0x6a, 0x71, 0xdb, 0x1f, 0xfe, 0x70, 0xe, 
+       0xd3, 0x9b, 0xba, 0x71, 0xe3, 0xd6, 0x4f, 0xeb, 0xa5, 0x99, 
+       0xe9, 0x5a, 0x45, 0xff, 0xb1, 0xea, 0x6f, 0x13, 0x1d, 0x53, 
+       0x4, 0xd, 0x8e, 0xa5, 0xc2, 0x20, 0xa, 0x1f, 0x10, 0x5c, 
+       0xcf, 0xc1, 0xe9, 0xe4, 0x78, 0x70, 0x7c, 0xef, 0x8a, 0x2b, 
+       0xae, 0x98, 0x2d, 0x3e, 0x5c, 0xaf, 0xb5, 0x8c, 0x36, 0xb6, 
+       0x25, 0x57, 0xe2, 0xe8, 0x3f, 0x1, 0x3b, 0xa5, 0xbd, 0xfc, 
+       0x69, 0x40, 0xcd, 0xc0, 0x1d, 0x3, 0xbb, 0x2f, 0xb5, 0x76, 
+       0x4e, 0x36, 0xc3, 0xd1, 0x5d, 0x56, 0x1a, 0x6, 0xb8, 0xe5, 
+       0x19, 0xb9, 0x8b, 0x95, 0x4b, 0x25, 0x6d, 0x20, 0xf, 0x87, 
+       0x6c, 0xca, 0x1a, 0x6, 0xdc, 0x6, 0x35, 0xbc, 0xc2, 0x1b, 
+       0x77, 0xe6, 0x61, 0xb7, 0xca, 0xaf, 0xee, 0xe4, 0x93, 0x4f, 
+       0xd6, 0x3d, 0xe5, 0xdd, 0xcf, 0x7f, 0xfe, 0xf3, 0xac, 0x9a, 
+       0xcd, 0xa, 0x24, 0x42, 0x69, 0x53, 0x92, 0xce, 0x6a, 0x52, 
+       0x23, 0xd7, 0x4c, 0x98, 0x30, 0x61, 0x3f, 0x1d, 0xca, 0x17, 
+       0xe, 0xbd, 0x2f, 0x4f, 0xa9, 0xfc, 0x15, 0xac, 0x7f, 0xbc, 
+       0x4c, 0xfc, 0xbc, 0x67, 0xe7, 0x12, 0x26, 0x8f, 0xb6, 0x25, 
+       0x66, 0xb4, 0x70, 0xe3, 0x3a, 0x94, 0x27, 0x52, 0xc1, 0x15, 
+       0x97, 0x53, 0x5c, 0x16, 0xe5, 0x6a, 0xa4, 0x64, 0x87, 0x51, 
+       0x46, 0x27, 0x91, 0xa8, 0x3f, 0xca, 0x17, 0x57, 0x21, 0xb0, 
+       0x11, 0x54, 0x24, 0x12, 0x6d, 0x8d, 0xa7, 0x53, 0xe8, 0x10, 
+       0x8, 0xc3, 0x43, 0x78, 0xd7, 0xef, 0xbb, 0xdf, 0xfd, 0xee, 
+       0xc, 0xcd, 0xb1, 0xff, 0x45, 0xc7, 0x3d, 0xd7, 0xb3, 0xfd, 
+       0x92, 0x4d, 0x22, 0x6f, 0xbf, 0xbd, 0x34, 0xf5, 0xe2, 0x8b, 
+       0x8b, 0x52, 0xcf, 0x3e, 0xfb, 0x2c, 0xda, 0x27, 0x23, 0x8d, 
+       0x58, 0xbe, 0x32, 0x22, 0xf2, 0x51, 0x3a, 0x9e, 0x36, 0xe8, 
+       0x91, 0x5f, 0xe6, 0xd1, 0x47, 0x17, 0xa4, 0xc5, 0xd3, 0xd4, 
+       0x90, 0x21, 0x83, 0xc3, 0xfc, 0x56, 0xf2, 0x50, 0xaf, 0x75, 
+       0x93, 0x49, 0x5b, 0x6c, 0xb1, 0xc5, 0x7a, 0x5a, 0x64, 0x9c, 
+       0xab, 0x3a, 0x2, 0x66, 0xda, 0x1, 0xf, 0x70, 0x8, 0x65, 
+       0xb1, 0x77, 0x3a, 0x61, 0x70, 0xda, 0xe1, 0xf7, 0x86, 0xb6, 
+       0xa7, 0xb6, 0x4a, 0x16, 0x36, 0x1a, 0x3f, 0x7e, 0x7c, 0x58, 
+       0x1c, 0xf3, 0xb5, 0xe2, 0x90, 0x3e, 0x94, 0xa6, 0xcf, 0x68, 
+       0x7f, 0x41, 0x78, 0xf4, 0xe5, 0x2d, 0xad, 0xf0, 0x15, 0x90, 
+       0x5b, 0x83, 0xa3, 0x34, 0xac, 0x5d, 0xd, 0xbc, 0x62, 0x5a, 
+       0x95, 0xfc, 0x56, 0xff, 0x74, 0xe8, 0x51, 0x2a, 0xf2, 0x9a, 
+       0x32, 0x7d, 0xcf, 0xed, 0x19, 0x50, 0x5c, 0x6, 0x80, 0xa7, 
+       0x9c, 0xee, 0x64, 0x2a, 0x2e, 0xf, 0x53, 0x5f, 0x1b, 0x7b, 
+       0xde, 0xd7, 0xe6, 0x9b, 0x1b, 0x94, 0xee, 0xb5, 0x9, 0x42, 
+       0x94, 0x44, 0xac, 0x28, 0x90, 0x29, 0xb1, 0x3d, 0x7c, 0x8c, 
+       0x4c, 0xd1, 0xae, 0xe, 0x41, 0xeb, 0xd6, 0x71, 0x77, 0x2e, 
+       0x3, 0x1d, 0xe3, 0x11, 0xc3, 0x23, 0x8, 0x23, 0xb, 0xa6, 
+       0xf9, 0x7d, 0x32, 0x4f, 0x48, 0xab, 0xd8, 0xb9, 0xb1, 0x66, 
+       0xb0, 0xb5, 0xab, 0x43, 0x98, 0xa3, 0x4e, 0x4d, 0x3, 0x3a, 
+       0x80, 0x5e, 0xab, 0x33, 0x63, 0x4d, 0xd7, 0xda, 0x3b, 0xd6, 
+       0xdc, 0xee, 0x78, 0x95, 0xd5, 0xed, 0x4b, 0x25, 0x35, 00, 
+       0x9b, 0xce, 0x80, 0x2f, 0x6e, 00, 0xfc, 0xc6, 0x4c, 0x6d, 
+       0xfa, 0xde, 0xf7, 0xbe, 0x77, 0x98, 0x40, 0xf0, 0x9b, 0x5d, 
+       0x77, 0xdd, 0xb5, 0x9e, 0xad, 0x9d, 0x76, 0x59, 0xd3, 0x76, 
+       0x44, 0xea, 0xb5, 0xd7, 0x5e, 0x4d, 0x4b, 0x6b, 0xa5, 0xce, 
+       0x3b, 0xef, 0xfc, 0x8e, 0xa7, 0x9e, 0x7a, 0x5a, 0x1f, 0xc7, 
+       0x33, 0x9, 0xe7, 0xfc, 0xe8, 0x42, 0x99, 0xca, 0x2, 0xf5, 
+       0x15, 0x1d, 0x17, 0x5d, 0x74, 0x31, 0xb, 0x4a, 0x69, 0x1, 
+       0x59, 0xfb, 0xb6, 0x3b, 0x9f, 0x4b, 0xd3, 0x77, 0x1f, 0xff, 
+       0xf8, 0xc7, 0x9b, 0x65, 0x91, 0x1c, 0xa0, 0xf7, 0xc1, 0x8f, 
+       0x57, 0x4d, 0x7, 0xc9, 0xfb, 0xc0, 0x7, 0x6f, 0x74, 0xa1, 
+       0x1, 0x34, 0xa, 0x8d, 0xc4, 00, 0x88, 0xf6, 0xc6, 0x7b, 
+       0xdd, 0x82, 0x1, 0x72, 0xb9, 0xde, 0xa6, 0xbb, 0x43, 0xa7, 
+       0xb5, 0xdc, 0xa4, 0x95, 0xf4, 0x6e, 0x35, 0x38, 0x2f, 0x87, 
+       0xb0, 0xf6, 0x43, 0x7f, 0xc7, 0x20, 0x3, 0x68, 0xd6, 0xde, 
+       0xd6, 0xac, 0xc8, 0x82, 0xbd, 0xca, 0xa8, 0xda, 0xd1, 0x17, 
+       0xb2, 0x12, 0x38, 0x4a, 0x2b, 0x6f, 0x92, 0x5b, 0xae, 0x8, 
+       0x4d, 0x9b, 0xb0, 0x5a, 0x27, 0xad, 0xdd, 0x2e, 0x39, 0x5c, 
+       0xa0, 0xfb, 0xc0, 0x96, 0x3d, 0x32, 0x54, 0xac, 0xb9, 0x21, 
+       0xed, 0xc1, 0x92, 0x78, 0x17, 0x87, 0x6, 0xa9, 0xc4, 0x79, 
+       0x94, 0xa5, 0x33, 0xec, 0x5d, 0xe0, 0x5a, 0x8d, 0x36, 0x77, 
+       0x6b, 0xe9, 0x7e, 0x9f, 0x9d, 0x76, 0xda, 0xa9, 0x52, 0x7a, 
+       0xf9, 0x32, 0xd, 0x72, 0x4c, 0x99, 0x62, 0xb3, 0x1c, 00, 
+       0x32, 0x1f, 0xa6, 0xd3, 0xa4, 0xe1, 0x6a, 0xd6, 0x60, 0x31, 
+       0xc0, 0x61, 0x38, 0x1d, 0x80, 00, 0x1a, 0xe0, 0x3c, 0x57, 
+       0x67, 0x21, 0x46, 0x9a, 0x28, 0x2d, 0x21, 0x41, 0x5b, 0x6a, 
+       0xee, 0x38, 0x32, 0x5f, 0x47, 0x22, 0x6, 0xb6, 0x76, 0x54, 
+       0xcd, 0xcb, 0xcd, 0xb1, 0x11, 0xc2, 0x20, 0x80, 0xb9, 0xd0, 
+       0x66, 0xa5, 0x35, 0xb6, 0x81, 0xed, 0xe, 0xc0, 0xe2, 0x41, 
+       0xb0, 0x1b, 0x75, 0x8, 0xe1, 0x11, 0xb2, 0x74, 0x4e, 0x17, 
+       00, 0xea, 0x79, 0x71, 0x2, 0xda, 0xae, 0x17, 0x21, 0x9a, 
+       0x40, 0x9a, 0x2a, 0x6c, 0xb4, 0x51, 0x7d, 0x98, 0x2e, 0x64, 
+       0x64, 0xea, 0x66, 0x74, 0xde, 0x7b, 0x66, 0xea, 0xd4, 0x29, 
+       0x69, 0xee, 0xf9, 0x28, 0x9c, 0xce, 0x86, 0xeb, 0x60, 0xc0, 
+       0x61, 0xa1, 0x4b, 0x75, 0xd2, 0xf9, 0xf5, 0x6b, 0x43, 0x5d, 
+       0xfb, 0xf7, 0xcf, 0x4e, 0xa5, 0xdc, 0x7f, 0x84, 0xf0, 0x76, 
+       0xb7, 0xdd, 0x76, 0xeb, 0x27, 0xcd, 0x7d, 0xe0, 0xf1, 0xc7, 
+       0x1f, 0x9f, 0xf9, 0x95, 0x9c, 0xea, 0x6c, 0x45, 0x41, 0xf5, 
+       0x11, 0x56, 0x7e, 0xf7, 0x38, 0x6a, 0x69, 0xdf, 0xc0, 0x6d, 
+       0xa2, 0x49, 0xff, 0xef, 0xb7, 0xf7, 0xde, 0x7b, 0x7, 0x2b, 
+       0x47, 0xf1, 0xbc, 0xc3, 0x1c, 0x87, 0x4f, 0x4c, 0xad, 0xd0, 
+       0xd8, 0xf0, 0xf, 0x8d, 0x6d, 0x50, 0xd3, 0xd7, 0x6, 0xb6, 
+       0xc1, 0xc7, 0xcd, 0x96, 0xbd, 0x3c, 0xa1, 0xa, 0x23, 0x92, 
+       0x47, 0x64, 0x32, 0xbc, 0x8b, 0x6e, 0x59, 0x8a, 0xcb, 0xa0, 
+       0xfd, 0xf4, 0x63, 0xec, 0x2b, 0x24, 0x8d, 0x49, 0xde, 0x2e, 
+       0x99, 0xb7, 0x49, 0x6e, 0x70, 0x13, 0x5a, 0x49, 0xc4, 0x4a, 
+       0x7b, 0xa0, 0xe0, 0x3f, 00, 00, 0x20, 00, 0x49, 0x44, 
+       0x41, 0x54, 0xb6, 0x5b, 0xb2, 0x3d, 0x9a, 0xe5, 0xdc, 0x5d, 
+       0x64, 0x9a, 0x23, 0xa4, 0x36, 0x2d, 0x11, 0xd6, 0x6, 0x75, 
+       0xf6, 0x2a, 0x46, 0x69, 0x9, 0x6c, 0x3f, 0x98, 0x5b, 0x8b, 
+       0xc3, 0x40, 0xc0, 0xdb, 0x34, 0x67, 0x74, 0x24, 0xae, 0x15, 
+       0xc3, 0xf0, 0xf2, 0xbb, 0xe8, 0xab, 0x2f, 0x6a, 0xc3, 0x77, 
+       0x7c, 0x9f, 0xe3, 0x36, 0x48, 0x5c, 0xae, 0x43, 0x2c, 0x5, 
+       0xcc, 0xcd, 0x96, 0x96, 0x96, 0xf0, 0x16, 0x11, 0x6d, 0x89, 
+       0x80, 0xfd, 0x60, 0x6e, 0x55, 0x1c, 0x20, 0x3, 0xee, 0x78, 
+       0x8e, 0x4d, 0x5a, 0x29, 0x60, 0x23, 0xc0, 0x6, 0x76, 0x93, 
+       0xce, 0x7, 0xff, 0xb4, 0x80, 0x7b, 0x9a, 0x4, 0xbf, 0x5e, 
+       0x80, 0xc5, 0x3a, 0x9, 0xed, 0xa4, 0x7c, 0xc7, 0xcd, 0x3, 
+       0xdd, 0x17, 0x4, 0xf4, 0xfd, 0xf7, 0x57, 0xa6, 0x78, 0xe4, 
+       0xc2, 0x76, 0xca, 0x85, 0xb, 0x5f, 0x4c, 0x9e, 0x7f, 0xfe, 
+       0x5, 0x4e, 0xa, 0x4d, 0x21, 0xc0, 0x8, 0xd5, 0xba, 0x74, 
+       0x3c, 0x52, 0xd2, 0x6, 0x93, 0xe, 0x9d, 0x2a, 0xc3, 0xb3, 
+       0x63, 0xd5, 0xe3, 0x65, 0x1e, 0xfd, 0x84, 0xc7, 0x94, 0x36, 
+       0x79, 0x9, 0xd1, 0x96, 0xfe, 0xed, 0x41, 0x93, 0x34, 0x1d, 
+       0x1a, 0x58, 0x2f, 0x7e, 0x4e, 0xd2, 0x31, 0xd6, 0x63, 0xee, 
+       0xbd, 0xf7, 0xde, 0xfb, 0x55, 0xd7, 0xd8, 0x3c, 0xf7, 0xc0, 
+       0x67, 0xe5, 0xe1, 0x30, 0x6e, 0x12, 0xf9, 0x33, 0x8f, 0x3d, 
+       0xf6, 0xd8, 0x6b, 0xda, 0xfa, 0xca, 0xdb, 0x7c, 0x13, 0x65, 
+       0xf1, 0xd4, 0xb9, 0xdd, 0xac, 0x4d, 0x60, 0x8e, 0xeb, 0x65, 
+       0x94, 0xf0, 0x49, 0x5e, 0xea, 0x10, 0x7b, 0x80, 0x6e, 0xed, 
+       0x6d, 0x80, 0x1b, 0x74, 0x96, 0x85, 0xb8, 0xb0, 0x9e, 0xe2, 
+       0xf4, 0xd, 0xe6, 0xb8, 0x6, 0x93, 0x30, 0xaf, 0xa7, 0x8d, 
+       0xf6, 0xb4, 0x1b, 0x4f, 0xdd, 00, 0x38, 0x9e, 0x32, 0x2a, 
+       0x2d, 0x47, 0xa0, 0x86, 0xee, 0x7, 0xf2, 0xd7, 0xaa, 0x1e, 
+       0xc8, 0x17, 0x1e, 0x99, 0xb2, 0x5c, 0x79, 0xed, 0x6, 0xa0, 
+       0x77, 0x48, 0x66, 0xcc, 0x3f, 0xfd, 0xec, 0xea, 0x2a, 0xd2, 
+       0xb4, 0x22, 0xc2, 0xe7, 0x57, 0xdc, 0x29, 0xb1, 0xe6, 0xce, 
+       0x8f, 0x2c, 0x1a, 0x3d, 0xaf, 0x57, 0xe7, 0x1f, 0xb5, 0xcf, 
+       0x3e, 0xfb, 0x54, 0xfc, 0x1c, 0x7, 0x92, 0x22, 0x1d, 0x1a, 
+       0xf, 0xc3, 0xcd, 0x10, 0x8f, 0x86, 0x84, 0x30, 0x4e, 0x2b, 
+       0xe7, 0xe1, 0x23, 0x7b, 0xea, 0xd4, 0xea, 0xed, 0x9c, 0x5c, 
+       0x9b, 0x29, 0xb, 0x4f, 0x39, 0xd0, 0x35, 0x80, 0xe8, 0xc, 
+       0xb6, 0x8d, 0xe2, 0x1, 0x17, 0x9e, 0x51, 0x59, 0x9b, 0x29, 
+       0x32, 0x7b, 0xed, 0xb5, 0x57, 0xba, 0x8, 0xd8, 0xb7, 0x8b, 
+       0x9c, 0x99, 0xce, 0x8b, 0xe7, 0xc4, 0x2b, 0xd5, 0xd8, 0x4d, 
+       0xfa, 0xb2, 0xc7, 0xd1, 0xb2, 0x40, 0x4e, 0xde, 0x7d, 0xf7, 
+       0xdd, 0x83, 0xc6, 0xa6, 0xac, 0xe2, 0x36, 0xd3, 0x5e, 0xd7, 
+       0x23, 0x57, 0xf5, 0x50, 0x67, 0xea, 0x89, 0xf9, 0xfb, 0xec, 
+       0xb3, 0xcf, 0xe8, 0x7a, 0x47, 0xea, 0xa5, 0x97, 0x16, 0x49, 
+       0x9b, 0xf, 0x43, 0x4b, 0xa1, 0xcd, 0x53, 0x32, 0xe7, 0x53, 
+       0xec, 0x1a, 0x43, 0x98, 0x6b, 0x75, 0xf4, 0x85, 0xa6, 0x58, 
+       0xb4, 0xbf, 0x63, 0xc1, 0x82, 0xc7, 0x88, 0x87, 0xcf, 0x23, 
+       0x49, 0xe8, 0x64, 0x7a, 0x7f, 0x10, 0xfa, 0xa, 0xc1, 0xa5, 
+       0xc, 0xb, 0x34, 0x56, 0x84, 0xc1, 0x44, 0x9a, 0xb5, 0xa5, 
+       0x81, 0x44, 0xfe, 0x69, 0xd3, 0xa6, 0x35, 0x8b, 0x9f, 0x7, 
+       0xe8, 0x31, 0x59, 0xe6, 0xb4, 0xd3, 0x4e, 0x3b, 0x23, 0x57, 
+       0x3f, 0x8f, 0xd4, 0x3d, 0x69, 0x70, 00, 0x8f, 0x4b, 0xc9, 
+       0x62, 0xfa, 0x8b, 0xfa, 0x10, 0x19, 0xd8, 0x53, 0x1a, 0x3c, 
+       0x7c, 0x1f, 0x5c, 0x74, 0x3b, 0xb4, 0x90, 0x47, 0xb9, 0x61, 
+       0xee, 0x4b, 0xdd, 0x5c, 0x3f, 0x3, 0xcd, 0x60, 0xa3, 0x4e, 
+       0xf4, 0x7f, 0x20, 0x16, 0xc4, 0x39, 0x44, 0xab, 0xfa, 0xa3, 
+       0x5, 0xbb, 0xe, 0xb6, 0x9b, 0xaa, 0xdf, 0x4a, 0xbe, 0x42, 
+       0xea, 0x81, 0xa3, 0x96, 0x72, 0x84, 0x9f, 0x56, 0xc9, 0xfa, 
+       0x3d, 0xaa, 0x50, 0x1e, 0x57, 0xb9, 0x38, 0x3c, 0xb2, 0x59, 
+       0xe, 0xa0, 0xe1, 0x49, 0xb7, 0xc0, 0xd6, 0xf5, 0xb0, 0xb0, 
+       0x43, 0x58, 0x89, 0xf3, 0xa8, 0xa, 0x51, 00, 0x6e, 0xb3, 
+       0x9c, 0x42, 0xd7, 0x2e, 0x5a, 0xb4, 0x68, 0x96, 0x46, 0xd6, 
+       0x4f, 0xb3, 0x8a, 0x48, 0x67, 0x57, 0xea, 0xc, 0x38, 0x4, 
+       0xb, 0x86, 0x14, 0xb, 0x3b, 0x1d, 0xc3, 0xb3, 0x68, 0xd1, 
+       0xcf, 0xc8, 0x32, 0x8, 0xc0, 0xac, 0x94, 0x76, 0x9c, 0xcf, 
+       0xe0, 0x76, 0x48, 0x39, 0x74, 0x36, 0x2, 0x60, 0x30, 0x19, 
+       0xf0, 0x2, 0x51, 0x3a, 0x2b, 0xe0, 0xb, 0x10, 0x9c, 0x76, 
+       0x99, 0x96, 0x73, 0xa4, 0xb1, 0x1, 0x36, 0x23, 0x68, 0xc, 
+       0x68, 0x6b, 0x70, 0x8f, 0xac, 0xc5, 0xa6, 0x38, 0x92, 0x84, 
+       0x6a, 0x5, 0xd8, 0x5f, 0x10, 0xb0, 0x7f, 0x26, 0x41, 0x6f, 
+       0xe0, 0x8c, 0x32, 0xca, 0x72, 0xdb, 0x5d, 0x17, 0x80, 0x1, 
+       0x1f, 0xcc, 0xb, 0x5f, 0x87, 0x7, 0x78, 0xea, 0xa, 0x80, 
+       0x98, 0x42, 0x60, 0xd1, 0xa8, 0x8e, 0xa2, 0x93, 0x49, 0x69, 
+       0xa4, 0xcf, 0x68, 0x1a, 0x91, 0x19, 0x38, 0x70, 0x80, 0xf8, 
+       0x57, 0xcf, 0x2b, 0x94, 0x98, 0xf1, 0x89, 0xc0, 0x9e, 0x52, 
+       0x59, 0x61, 0xcf, 0xb3, 0xbe, 0xcd, 0x1d, 0x68, 0xb4, 0xb5, 
+       0x31, 0x80, 0xb5, 0x85, 0xf2, 0x59, 0x40, 0x64, 0xda, 0x3, 
+       0xa0, 0xdf, 0x7b, 0x6f, 0x45, 0x8a, 0xe9, 0x9, 0x9a, 0x50, 
+       0xfc, 0x4e, 0xe9, 0xd3, 0x48, 0x2, 0x36, 0x32, 0x96, 0x9, 
+       0x7c, 0xa2, 0x6e, 0x71, 0x1d, 0xc, 0x6e, 0x42, 0xac, 0x35, 
+       0xff, 0xa6, 0x8e, 0x78, 0x3, 0x89, 0xb6, 0xf1, 0x7b, 0xfa, 
+       0xf4, 0xe9, 0xcd, 0xb2, 00, 0xe, 0x14, 0xc0, 0x53, 0x2, 
+       0xf8, 0xe9, 0x22, 0x1c, 0xbb, 0x52, 00, 0x37, 0xf8, 0xe3, 
+       0x7c, 0x19, 0xf5, 0xc3, 0x8d, 0xa2, 0xc9, 0xb5, 0xe9, 0x13, 
+       0x27, 0x4e, 0xac, 0x5b, 0xbc, 0x78, 0x31, 0xdb, 0x95, 0xc3, 
+       0x89, 0x2e, 0x6, 0x35, 0x75, 0xa1, 0xbe, 0xf6, 0x1e, 0x68, 
+       0x90, 0x2f, 0x78, 0x4a, 0x9d, 0x6a, 0x71, 0x28, 00, 0xad, 
+       0x2d, 0x5, 0x2b, 0x8a, 0xb2, 0xa0, 0xb, 0x4f, 0x8, 0xed, 
+       0xa1, 0xed, 0x7e, 0x73, 0x79, 0x95, 0x94, 0x5, 0x6e, 0x98, 
+       0x56, 0xc8, 0x3a, 0x63, 0x1, 0xd2, 0xe0, 0x8e, 0x35, 0x75, 
+       0xb1, 0x59, 0xde, 0x23, 0xd9, 0x8a, 0x34, 0x77, 0x44, 0xc5, 
+       0x23, 0x6, 00, 0xa7, 0x30, 0x3c, 0x15, 0x59, 0x23, 0x41, 
+       0x79, 0x4f, 0xa0, 0x78, 0x40, 0xe6, 0xd1, 0xae, 0x3b, 0xec, 
+       0xb0, 0x43, 0xc5, 0xdc, 0x83, 0x11, 0x8, 0xb3, 0x19, 0x2, 
+       0x73, 0xf0, 0x66, 0x1c, 0xcc, 0xa3, 0x93, 0xd4, 0x70, 0x5e, 
+       0x2, 0x48, 0x74, 0xd8, 0x7b, 0xa9, 0x4e, 0x57, 0x15, 0x7a, 
+       0x76, 0x94, 0x81, 0x87, 0x3e, 0x65, 0x42, 0x1b, 0x90, 0x15, 
+       0x83, 0x9b, 0x3c, 0x6a, 0x4f, 0x5a, 0xab, 0xb5, 0x1d, 0x2a, 
+       0xf3, 0xc5, 0xb, 0x2e, 0xb8, 0x60, 0x96, 0xa8, 0x7b, 0xb1, 
+       0x7, 0x70, 0xf3, 0xc, 0xdb, 0x1a, 0xbc, 0x47, 0x60, 0x9f, 
+       0x70, 0xc2, 0x9, 0xc7, 0x68, 0x83, 0xca, 0x4f, 0xc, 0x6c, 
+       0xb7, 0xd7, 0x6d, 0xa6, 0xad, 0x38, 0xea, 0x42, 0x5b, 0x71, 
+       0xbe, 0x66, 0xb0, 0x90, 0x8e, 0xd0, 0x62, 0x49, 00, 0x6e, 
+       0x4, 0xd, 0x50, 0xe5, 0xe2, 0x3a, 0x7f, 0xee, 0x4d, 0x3d, 
+       0x6, 0x5a, 0x8b, 0x56, 0x57, 0xfb, 0xd2, 0xb9, 0x97, 0x18, 
+       0x1a, 0x78, 0xda, 0xd0, 0x41, 0x3b, 0xb3, 0x3c, 0xad, 0xd3, 
+       0x7d, 0x4c, 0x3, 0xf4, 0x85, 0x17, 0x85, 0x58, 0x2, 0xa2, 
+       0x93, 0x36, 0xd8, 0x29, 0x1f, 0x67, 0xfe, 0x73, 0x52, 0x4a, 
+       0xdc, 0xf, 0xae, 0xb, 0xf5, 0x20, 0x4e, 0x9d, 0xc, 0x28, 
+       0xd7, 0x8f, 0xd0, 0x82, 0xee, 0x76, 0xd1, 0x16, 0xf2, 0xef, 
+       0xb9, 0xe7, 0x9e, 0xcd, 0x32, 0xa1, 0xd1, 0xe0, 0x49, 0xf, 
+       00, 0xa7, 0x8f, 0x19, 0x28, 0xed, 0x90, 0x3b, 0xd2, 0x42, 
+       0x78, 0xfe, 0xf9, 0xe7, 0xdf, 0xa0, 0x78, 0x3f, 0xb5, 0x7d, 
+       0x77, 0x8e, 0xb0, 0xc2, 0x7a, 0xa0, 0x5c, 0x3c, 0x8a, 0x85, 
+       0x3a, 0x11, 0xa7, 0x4c, 0xd7, 0x85, 0x36, 0x99, 0xa7, 0x26, 
+       0x5a, 0x6d, 0xb8, 0x48, 0xa, 0x86, 0xdd, 0x6f, 0xa2, 0x95, 
+       0x82, 0xa7, 0xd0, 0x27, 0xa4, 0xc, 0xe8, 0xc7, 0xbe, 0x5a, 
+       0xda, 0xc2, 0x4d, 0x87, 0x16, 0x2a, 0x1f, 0x53, 0xff, 0x22, 
+       0x57, 0x80, 0x9a, 0x45, 0x46, 0xb0, 0x65, 0xad, 0x6d, 0x8b, 
+       0x39, 0x28, 0x59, 0xc9, 0x10, 0x61, 0xb7, 0xae, 0x62, 0x70, 
+       0x43, 0x4c, 0xcc, 0x81, 0xa0, 0x35, 0x77, 0xac, 0xbd, 0x3, 
+       0xc0, 0x35, 0xaa, 0x5d, 0x2b, 0x81, 0xfb, 0xb8, 0x3e, 0xd5, 
+       0x5b, 0x67, 0xb3, 0xa4, 0xdb, 0xd2, 0xa3, 0x8b, 0x30, 0xde, 
+       0xcc, 0x87, 0x59, 00, 0xe, 0xc6, 0x99, 0x89, 0x6a, 0x38, 
+       0xcf, 0xa2, 0x33, 0x32, 0xcd, 0x3, 0x53, 0xa3, 0x5b, 0x2b, 
+       0x8e, 0xba, 0xc, 0x6e, 0xa0, 0x7e, 0x78, 0xe8, 0x23, 0xd4, 
+       0x16, 0x6c, 0xae, 0x11, 0xd7, 0xa3, 0x8e, 0x56, 0xcd, 0xf3, 
+       0x1e, 0xd5, 0x8e, 0xa9, 0xeb, 0x94, 0x4, 0x80, 0xf1, 0xc5, 
+       0x5a, 0x9b, 0x34, 0x84, 0x30, 0x7e, 0xdc, 0xa5, 0x9f, 0xf9, 
+       0xe7, 0xd8, 0xcd, 0xfa, 0x8a, 0xe6, 0x97, 0x5, 0xec, 0x63, 
+       0xa5, 0xb9, 0x1a, 00, 0x23, 0x8e, 0x7a, 0xd0, 0x37, 0xe5, 
+       0x78, 0x44, 0x3a, 0x82, 0x2, 0x1f, 0xdc, 0x7e, 0x84, 0x15, 
+       0xad, 0x8a, 0xf0, 0x12, 0x2, 0x6a, 0x2f, 0x4, 0x2, 0x74, 
+       0xe2, 0xf0, 0x8c, 0x38, 0x21, 0x6d, 0x50, 0xa8, 0x8f, 0xc7, 
+       0xad, 0x8, 0xf3, 0xe3, 0xb8, 0x7d, 0x94, 0x6d, 0x5e, 0x13, 
+       0x52, 0x16, 0x82, 0xea, 0x72, 0x5d, 0xb6, 0xd3, 0xb9, 0xe6, 
+       0xb8, 0x41, 0x64, 0xf0, 0xf8, 0x37, 0x75, 0x25, 0xee, 0x3e, 
+       0x23, 0x34, 0x3d, 0x42, 0xca, 0x81, 0xe, 0x1a, 0xbc, 0x2, 
+       0x80, 0xa3, 0x34, 0x70, 0x31, 0xc0, 0xb3, 0x29, 0xd9, 0xbf, 
+       0x1d, 0xe7, 0x9f, 0x7f, 0xfe, 0x65, 0x9b, 0x6e, 0xba, 0xe9, 
+       0x73, 0x5a, 0x64, 0x3c, 0xa6, 0xa5, 0xa5, 0xa5, 0xe, 0xde, 
+       0x42, 0x3f, 0x6, 0x36, 0x75, 0xa0, 0x5e, 0x78, 0xd7, 0x81, 
+       0x7a, 0xd4, 0xe2, 0xe0, 0xb7, 0xe4, 0x8f, 0x29, 0x4b, 0x9a, 
+       0x32, 0xe2, 0x76, 0x3a, 0xe, 0x8f, 0x5c, 0xe, 0x21, 0xbe, 
+       0x12, 0x47, 0xdf, 0xe4, 0x14, 0xc9, 0xdd, 0xca, 0xf, 0xb0, 
+       0xad, 0xb1, 0xd, 0x6e, 0x2b, 0x52, 0xb0, 0x67, 0xdf, 0x23, 
+       0xe9, 0x8a, 0xc1, 0x9d, 0xa3, 0x14, 0x46, 0xd, 0xc5, 0xd, 
+       0x6c, 0x17, 0x4a, 0x25, 0xd6, 0x6a, 0xde, 0xfd, 0x92, 0x84, 
+       0xec, 0x65, 0x6d, 0x6a, 0x99, 0xcc, 0xe7, 0x54, 0x2a, 0x75, 
+       0x66, 0xb8, 0x19, 0x42, 0x8, 0xa3, 0xf0, 0x30, 0x8e, 0x4e, 
+       0xc3, 0x33, 0x6a, 0xea, 0x99, 0x77, 0x46, 0x9d, 0x5a, 0x19, 
+       0xd7, 0x4a, 0x54, 00, 0xda, 0x30, 0xd3, 0x65, 0x20, 0xe8, 
+       0x94, 0x41, 0x88, 0x3, 0x18, 0x32, 0xc5, 0x5b, 0xd5, 0x91, 
+       0x73, 0xb5, 0x67, 0xfc, 0x2f, 0x4a, 0x42, 0x63, 0x1b, 0xdc, 
+       0xc5, 0x1a, 0xbb, 0x5b, 0x60, 0x6b, 0x4b, 0xe9, 0xd7, 0x4, 
+       0xec, 0xef, 0x4f, 0x93, 0x29, 0x6e, 0x60, 0x53, 0x6, 0x2e, 
+       0xae, 0x47, 0x36, 0x25, 0x9b, 0x46, 0x3c, 0xae, 0x9f, 0x1, 
+       0xe, 0x70, 00, 0x30, 0xc0, 0x36, 0xa8, 0x73, 0x5a, 0x3b, 
+       00, 0x9a, 0x34, 0x3, 0x9b, 0x36, 0x44, 00, 0xf, 0x6d, 
+       0x73, 0xfb, 0x5c, 0x16, 0x21, 0x7c, 0xc7, 0x9b, 0x17, 0x16, 
+       0x4e, 0x3, 0x2, 0xbe, 0xc4, 0x7d, 0x40, 0xba, 0xfb, 0xc2, 
+       0xa1, 0x5, 0x9b, 0x90, 0xeb, 0xe4, 0xe7, 0x1a, 0x74, 0x89, 
+       0xe3, 0x5d, 0x16, 0x21, 0xd7, 0x7a, 0x1, 0xf0, 0xb8, 0xdf, 
+       0x79, 0x6c, 0x39, 0x5f, 0x7c, 0xc1, 0x3a, 0xf9, 0x92, 0xe, 
+       0x73, 0xcc, 0x3, 0x1c, 0x5e, 0x51, 0x8e, 0xeb, 0x4f, 0xfb, 
+       0xec, 0x43, 0x65, 0x6a, 0xf8, 0xa3, 0x55, 0xec, 0xe, 0x79, 
+       0xda, 0x98, 0xd7, 0xda, 0x94, 0x61, 0x5e, 0xd1, 0x4e, 0xf3, 
+       0xd1, 0xf2, 0x5c, 0x69, 0x31, 0xc2, 0xb, 0xfd, 0xfa, 0xa6, 
+       0xac, 0x90, 0xc5, 0xba, 0xc7, 0xe0, 0x26, 0xc, 0x53, 0x5e, 
+       0x85, 0xe0, 0x2c, 0x56, 0xaa, 0xfa, 0xd9, 0xb3, 0xab, 0x16, 
+       0xdc, 0x50, 0xa4, 0x10, 0x90, 0x60, 0x80, 0xdb, 0x6c, 0x8, 
+       0x95, 0xd2, 0x62, 0xc3, 0x35, 0x7a, 0xd3, 0xea, 0x1f, 0x5, 
+       0x6e, 0xf6, 0x16, 0x57, 0xe4, 0x60, 0x46, 0xac, 0x4d, 0x60, 
+       0x14, 0x4c, 0xa3, 0x73, 0x10, 0x52, 0x42, 0x18, 0x89, 0xf6, 
+       0x66, 0x8e, 0x38, 0x71, 0xe2, 0xc4, 0x30, 0x42, 0x57, 0x44, 
+       0xbc, 0x44, 0x26, 0xca, 0xb3, 0xf0, 0x51, 0xae, 0x3d, 00, 
+       0x91, 0xc6, 0x5e, 0x2b, 0xb, 0x64, 0x9e, 0x80, 0x7d, 0xab, 
+       0x6e, 0xf5, 0xb3, 0x57, 0xcf, 0xad, 0x6d, 0x9a, 0x3b, 0x9d, 
+       0x36, 0x9b, 0xf1, 0x94, 0xe4, 0x39, 0x76, 0xb3, 0x4c, 0xf1, 
+       0x6f, 0x6a, 0x91, 0xeb, 0x5b, 0x7b, 0xec, 0xb1, 0x47, 0x23, 
+       0xda, 0xb6, 0x94, 0x43, 0x18, 00, 0xb2, 0x1, 0x40, 0x9c, 
+       0x76, 0x2, 0x52, 0xae, 0x99, 0x7, 0x6, 0x2e, 0xe9, 0x8, 
+       0x2e, 0xa1, 0x1, 0xe, 0x7f, 0xe2, 0xeb, 0x5c, 0x83, 0x8e, 
+       0x1, 0xee, 0xb6, 0x91, 0x46, 0xdc, 0xe, 0xfa, 0x38, 0xf8, 
+       0x60, 0xa1, 0x74, 0x99, 0xe6, 0xbf, 0xcb, 0xe7, 0xb7, 0xc1, 
+       0x4b, 0x9a, 0x81, 0x43, 0x3c, 0xce, 0xe3, 0xfb, 0xcc, 0x5b, 
+       0xe8, 0x99, 0xd7, 0x2e, 0x97, 0x90, 0xfb, 0x7b, 0x1, 0x70, 
+       0x93, 0xa, 0x1a, 0x4c, 0x8b, 0x50, 0xf, 0x89, 0x5e, 0x5a, 
+       0x83, 0xe7, 0xdf, 0x69, 0x9d, 0xa1, 0xde, 0x53, 0x6, 0x3, 
+       0x9b, 0x3a, 0xb9, 0xe, 0x84, 0xb5, 0x38, 0xa6, 0x42, 0x5a, 
+       0xe8, 0xe2, 0x91, 0x64, 0xfe, 0x9, 0x85, 0xf9, 0x41, 0x58, 
+       0x5c, 0x96, 0xdb, 0x5d, 0x69, 0x59, 0xc2, 0xcb, 0x5a, 0x3d, 
+       0xd, 0xb9, 0x4b, 0xf9, 0xb1, 00, 0x91, 0x29, 0x9b, 0xe4, 
+       0x28, 0x4d, 0x2b, 0x50, 0xf0, 0x46, 0x9b, 0xe9, 0xc7, 0xce, 
+       0x8e, 0x24, 0xa1, 0x8c, 0xab, 0xa, 0xdc, 0x10, 0xcd, 0x31, 
+       0x28, 0x30, 0x56, 0x34, 0x29, 0x38, 0x68, 0xed, 0x5c, 0xb8, 
+       0x5a, 0xda, 0xf5, 0x41, 0x3d, 0xea, 0x59, 0x2b, 0x10, 0x36, 
+       0xf3, 0x4a, 0x60, 0xa5, 0xce, 0x8c, 0x37, 0x63, 0x8, 0xe9, 
+       0x18, 0xb, 0x16, 0x2, 0x81, 0xd7, 0x28, 0xa7, 0x85, 0xa3, 
+       0x81, 0x19, 0x99, 0xfe, 0xf1, 0x28, 0x5e, 0x69, 0x31, 0x21, 
+       0x9f, 0x3b, 0x9b, 0x1f, 0x94, 0x83, 0x80, 0x2, 0x10, 0xed, 
+       0x6e, 0x6a, 0xd5, 0xee, 0xa0, 0xf9, 0xd7, 0x5f, 0x7f, 0x3d, 
+       0xc0, 0x46, 0x2b, 0xdb, 0x14, 0x27, 0x8c, 0x1, 0xce, 0x35, 
+       0x9b, 0x4c, 0x66, 0x74, 0x1e, 0xd8, 0x27, 0x9d, 0x74, 0xd2, 
+       0x77, 0xa5, 0xb1, 0xbf, 0x2e, 0x1, 0x6e, 0xc4, 0x84, 0xeb, 
+       0xce, 0x51, 0x3e, 0x7d, 0x45, 0x3b, 0x89, 0x3, 0x42, 0xea, 
+       0xe7, 0x34, 0x83, 0x7, 0xd0, 0xe2, 0xd, 0xe6, 0x38, 0x74, 
+       0xba, 0x81, 0xed, 0x10, 0x1a, 0xe4, 0x83, 0xa6, 0x1d, 0x69, 
+       0xe6, 0x35, 0x69, 0x94, 0x19, 0x7b, 0xf3, 0x9c, 0x72, 0x49, 
+       0x47, 0x70, 0x9, 0xe1, 0xbd, 0x7f, 0x73, 0xcd, 0x9e, 0x34, 
+       0xee, 0xe1, 0x37, 0xce, 0xed, 0x30, 0x8f, 0xe3, 0xb2, 0x42, 
+       0x86, 0xdc, 0x1f, 0xe8, 0x55, 0x1, 0x70, 0x78, 0x6c, 0x64, 
+       0x3a, 0x74, 0x5a, 0x8a, 0x37, 0xf2, 0x34, 0xe8, 0xd5, 0x9, 
+       0xd8, 0x9f, 0xd7, 0x23, 0xb7, 0x3a, 0xe6, 0xe0, 0xae, 0x13, 
+       0xf5, 0xa3, 0xe, 0x84, 0xb5, 0x3a, 0xe6, 0xc3, 0x92, 0xb, 
+       0x78, 0x11, 0x76, 0xbf, 0xc5, 0x96, 0x1, 0xed, 0x76, 0x9b, 
+       0x5d, 0x16, 0xe5, 0x94, 0x6b, 0x77, 0x71, 0x1d, 0xd8, 0x91, 
+       0x26, 0xa5, 0xd5, 0x2a, 0xa5, 0xf8, 0x84, 0xae, 0xc5, 0xc0, 
+       0x26, 0x6e, 0x19, 0x3, 0x67, 0x6, 0x77, 0x67, 0x67, 0x16, 
+       0x13, 0x2b, 0xfa, 0x5d, 0x15, 0xb8, 0xa3, 0x7b, 0x61, 0x2c, 
+       0x85, 0xc5, 0xda, 0x9b, 0xca, 0xac, 0x91, 0x30, 0xad, 0x92, 
+       0x79, 0x71, 0x93, 0x9e, 0x5, 0x1e, 0xa6, 0xc7, 0x15, 0xec, 
+       0xc6, 0xaa, 0xc8, 0xc1, 0xc, 0xb, 0x1e, 0xcc, 0x22, 0xe, 
+       0xe3, 0x10, 0x2e, 0x4, 0x94, 0x10, 0xa6, 0xb2, 0xd0, 0xc5, 
+       0xa3, 0x31, 0x34, 0x78, 0x6f, 0xb6, 0xa5, 0xd2, 0x11, 0x8, 
+       0x3d, 0x21, 0xc0, 0x56, 0x7d, 0x5b, 0xb5, 0xe5, 0x6f, 0xfe, 
+       0x55, 0x57, 0x5d, 0x75, 0x9b, 0x2a, 0x8c, 0x66, 0x36, 0x98, 
+       0x1d, 0x5a, 0x5b, 0x13, 0x7a, 0x44, 0xa5, 0xfd, 0x48, 0x4d, 
+       0x1e, 0xd8, 0x32, 0xc5, 0x7f, 0x20, 0x60, 0x7f, 0x45, 0x82, 
+       0xdb, 0x23, 0xb0, 0x75, 0x5f, 0x70, 0xb4, 0x3d, 0x6e, 0xbf, 
+       0xeb, 0x46, 0x1a, 0xbc, 0xa0, 0xfd, 0x84, 0xf0, 00, 0xe0, 
+       0x2, 0xc, 0x3, 0x98, 0xba, 0xd3, 0xe, 0x3c, 0x69, 0xf0, 
+       0xcd, 0xd7, 0x88, 0xfb, 0x1a, 0x5, 0xf1, 0xdb, 0xce, 0x65, 
+       0x3a, 0xa4, 0x4c, 0xb, 0x29, 0x69, 0xf0, 0x9e, 0x34, 0xb, 
+       0xaf, 0x7f, 0x93, 0x87, 0x38, 0x79, 0xa8, 0xf, 0x79, 0x70, 
+       0xf1, 0xbd, 0xa6, 0xe9, 0xb2, 0xca, 0x85, 0xdd, 00, 0xdc, 
+       0x15, 0xc5, 0x2a, 0x44, 0x98, 0xe1, 0x33, 0x3c, 0x7, 0xd8, 
+       0x5c, 0xb3, 0x57, 0x34, 0xbb, 0xc8, 0xa6, 0x47, 0x62, 0x73, 
+       0x55, 0x1f, 0x9e, 0x3d, 0x7f, 0x76, 0xeb, 0xad, 0xb7, 0xae, 
+       0xe3, 0xcc, 0x75, 0xea, 0x66, 0x4f, 0xc6, 0x5a, 0x1c, 0x72, 
+       0xa6, 0x79, 0x36, 0x5f, 0xc3, 0x9, 0x1b, 0x64, 0xa8, 0x33, 
+       0xed, 0x8e, 0x3d, 0x6d, 0x77, 0xfb, 0x29, 0x8f, 0xf6, 0x57, 
+       0xea, 0x78, 0xfc, 0x25, 0xfa, 0xf7, 0xab, 0x9f, 0xc, 0x6c, 
+       0xb4, 0xb6, 0x35, 0x37, 0xed, 0xb7, 0xe6, 0x86, 0xf, 0xe6, 
+       0x4b, 0x45, 0xe4, 0x6b, 0x5, 0x37, 0x5, 0xd1, 0x2, 0x98, 
+       0x6e, 0xc6, 0xc3, 0xfc, 0xe0, 0x65, 0xd6, 0xde, 0xa6, 0xc7, 
+       0x62, 0x87, 0x69, 0x35, 0xb6, 0x2a, 0xf3, 0xd9, 0x4c, 0x71, 
+       0x87, 0x98, 0x69, 0x8, 0x13, 0xcc, 0x84, 0xb1, 0x8, 0xb3, 
+       0xac, 0x3, 0x18, 0x9d, 0x61, 0xdb, 0x26, 0xe9, 0xb5, 0x3a, 
+       0xca, 0x3, 0x38, 0x3a, 0xcc, 0x90, 0xc5, 0xb3, 0x87, 0x2e, 
+       0xbb, 0xec, 0xb2, 0xdb, 0x44, 0xcb, 0xf3, 0x6b, 0x16, 0xcf, 
+       0xac, 0xb9, 0x89, 0x1b, 0xdc, 0xb4, 0x11, 0xa6, 0xd3, 0xee, 
+       0x2, 0x60, 0x9f, 0x7c, 0xf2, 0xc9, 0xc7, 0x9, 0xd8, 0xc7, 
+       0x8, 0xd8, 0x4d, 0x98, 0x87, 0xd5, 0x3a, 0x83, 0x2, 0x10, 
+       0x12, 0x87, 0xf, 0x80, 0x93, 0x38, 0x3c, 0x20, 0xee, 0x90, 
+       0x7a, 0xe3, 0xe1, 0x9, 0xe9, 0xc4, 0xd, 0x6c, 0x83, 0x9a, 
+       0xf2, 0x49, 0xc7, 0x91, 0xa7, 0xd8, 0x41, 0x1f, 0x67, 0x81, 
+       0x74, 0x68, 0x41, 0x8d, 0x43, 0xe2, 0xae, 0x93, 0xc1, 0xed, 
+       0xdf, 0xbe, 0x8f, 0xdf, 0xf8, 0x6a, 0x5c, 0xc, 0x70, 0x2d, 
+       0x3e, 0x66, 0x7e, 0xf9, 0xcb, 0x5f, 0xf2, 0x98, 0xc, 0x21, 
+       0x36, 0xa1, 0x18, 0xe0, 00, 0xa0, 0xd8, 0xe5, 0xf3, 0x6a, 
+       0xa1, 0x6e, 0xae, 0xea, 0xd9, 0xa0, 0xfa, 0x1d, 0xa9, 0xf, 
+       0x4b, 0x6, 0xd, 0xee, 0xba, 0x15, 0xdf, 0x54, 0xc9, 0x6f, 
+       0x64, 0x4d, 0xf3, 0x7a, 0x16, 0xbb, 0xf2, 0xaf, 0x8f, 0x5a, 
+       0xe, 0xa9, 0x37, 0x7c, 0x30, 0x8f, 0xe2, 0x72, 0x2a, 0xe5, 
+       0x1, 0xf8, 0xd0, 0x73, 0x73, 0xe4, 0x99, 0xc7, 0x5f, 0x36, 
+       0xc9, 0xad, 0xb1, 0x2d, 0x67, 0x6e, 0x7f, 00, 0xb7, 0xfa, 
+       0xb6, 0x62, 0x80, 0x57, 0xd, 0x6e, 0x88, 0xe7, 0x2a, 0x4f, 
+       0x21, 0x48, 0x8e, 0x47, 0x16, 0x2a, 0x13, 0x46, 0x1d, 0x3d, 
+       0xb3, 0x7b, 0x5b, 0xbb, 0x92, 0x66, 0xe9, 0x3d, 0xe7, 0xbd, 
+       0xd0, 0x60, 0x4a, 0xaf, 0xc8, 0x41, 0x97, 0xba, 0x13, 0xc2, 
+       0x2c, 0x3c, 0xc, 0xb4, 0x10, 0x5b, 0x6b, 0xc1, 0xf4, 0x45, 
+       0x7a, 0x2c, 0xa1, 0x4f, 0xde, 0x64, 0xd4, 0x89, 0x59, 0x9, 
+       0xad, 0xa8, 0x84, 0xc2, 0x4c, 0xd0, 0xd3, 0x2b, 0x82, 0xad, 
+       0xd2, 0xda, 0xf, 0xff, 0xe9, 0x4f, 0x7f, 0x2, 0xd8, 0xd6, 
+       0xd8, 0xd6, 0xd6, 0x5e, 0x40, 0x3, 0xe4, 0xf1, 0x68, 0xa, 
+       0xc3, 0x59, 0x29, 0x42, 00, 0x19, 0x5d, 0x9a, 0x5, 0xec, 
+       0x9f, 0x6a, 0x8e, 0xfd, 0x59, 0x80, 0x8d, 0x85, 0xd1, 0x1b, 
+       0x47, 0xfb, 0x63, 0x5e, 0x20, 0x40, 0x80, 0xd3, 0x3c, 0x81, 
+       0xb6, 0x1, 0x4d, 0x8, 0xcf, 0x8, 0x4b, 0xc5, 0xb9, 0x86, 
+       0x2f, 0xe7, 0x5c, 0x96, 0x43, 0x97, 0xe1, 0x90, 0xfb, 0xe8, 
+       0x3, 0x7e, 0x93, 0x7, 0x17, 0x3, 0x9d, 0xdf, 0xbe, 0x97, 
+       0x78, 0x2d, 0x2e, 0x2, 0xf8, 0x81, 0x2, 0x78, 0x22, 0x80, 
+       0xb3, 0xd1, 0x25, 0xee, 0x57, 0x64, 0xc, 0xe1, 0x46, 0xde, 
+       0x10, 0x7e, 0x1a, 0xe4, 0x46, 0x11, 0x3a, 0x6f, 0x4a, 0x4b, 
+       0x25, 0xf7, 0x9, 0x80, 0xec, 0x6a, 0x3c, 0x42, 0x2b, 0xe9, 
+       0x75, 0xec, 0x29, 0xa8, 0xd5, 0x69, 0x9a, 0xd6, 0xf1, 0xdc, 
+       0x73, 0xcf, 0xd1, 0xf6, 0x82, 0x45, 0x34, 00, 0xe, 0x4f, 
+       0x8, 0xe1, 0x45, 0x29, 0x80, 0x57, 0x52, 0xa6, 0xb6, 0x32, 
+       0xb7, 0xca, 0xca, 0x7d, 0x50, 0x73, 0x7a, 0x36, 0x44, 0x5, 
+       0xec, 0xe4, 0x42, 0x3, 0xdc, 0x4a, 0x84, 0x76, 0xe3, 0xdd, 
+       0x66, 0x45, 0x7b, 0x76, 0x55, 0x83, 0x3b, 0x22, 0x9, 0xb3, 
+       0xcd, 0x70, 0x2a, 0x61, 0x4f, 0x25, 0x57, 0x69, 0x61, 0xea, 
+       0x4a, 0x81, 0x6f, 0x3a, 0xdb, 0x17, 0xe3, 0x17, 0x23, 0xa2, 
+       0xfb, 0x4b, 0x46, 0x2d, 0x40, 0x8, 0x93, 0x85, 0xba, 0x18, 
+       0xe0, 0x80, 0x12, 0xf3, 0x5c, 0xb, 0x1c, 0x9c, 0x49, 0xdd, 
+       0x65, 0x1f, 0x78, 0x49, 0xc2, 0x45, 0x89, 0xc, 0x10, 0x3a, 
+       0x5a, 0x97, 0xc3, 0xc, 0x1f, 0xbe, 0xf4, 0xd2, 0x4b, 0x1, 
+       0xb6, 0x1f, 0x73, 0xb1, 0xa5, 0xd4, 0x71, 0x6b, 0x6e, 0x98, 
+       0xcd, 0x3c, 0xdb, 0x73, 0x1f, 0xf8, 0x16, 0x80, 0xad, 0xfd, 
+       0xf4, 0xe3, 0x75, 0xd4, 0xd0, 0x37, 0xb4, 0x1f, 0xfd, 0x28, 
+       0x9e, 0xe3, 0x22, 0xa8, 0x7d, 0xe5, 0x62, 0xd0, 0x10, 0x7, 
+       0xa4, 0xf0, 0xc5, 0x21, 0x71, 0x9c, 0x1, 0x1c, 0x3, 0x9c, 
+       0x74, 0x83, 0x9d, 0x38, 0x2e, 0x6, 0xb9, 0xf9, 0x5c, 0x1c, 
+       0xc6, 0xc0, 0x8d, 0xaf, 0x51, 0x16, 0xbf, 0x8b, 0x7d, 0x96, 
+       0x72, 0xef, 0xff, 0xc6, 00, 0x67, 0xa3, 0xcb, 0xef, 0x7e, 
+       0xf7, 0xbb, 0xdf, 0xf0, 0xc, 0x5b, 0xe, 0x3e, 0x23, 0x53, 
+       0x8, 0xb7, 0xf9, 0x8f, 0x22, 0xc1, 0x65, 0x47, 0x9b, 0x6c, 
+       0x3c, 0x68, 0x36, 0xa2, 0x9c, 0xe8, 0xa2, 0x7a, 0xa6, 0xd5, 
+       0x96, 0xc3, 0x79, 0x2c, 0xdb, 0xd3, 0xba, 0x47, 0xf6, 0xf6, 
+       0xc2, 0xbf, 0xc8, 0x95, 0x4c, 0xf2, 0xfc, 0x22, 0x1a, 0xf5, 
+       0x8b, 0xe7, 0xda, 0x6, 0x36, 0xb2, 0x69, 0x9e, 0x41, 0xc1, 
+       0x3c, 0x2b, 0xa4, 0xd6, 0xf5, 0x17, 0x1b, 0x87, 0x50, 0x50, 
+       0x7a, 0x27, 0xe3, 0xe, 0x5d, 0x45, 0xb6, 0xf0, 0xb4, 0x13, 
+       0x59, 0xc3, 0x83, 0x27, 0x2b, 0x4e, 0xda, 0x46, 0xff, 0xad, 
+       0x7b, 0x70, 0x53, 0x48, 0xae, 0x11, 0x6, 0x37, 0x8c, 0xa7, 
+       0x32, 0x30, 0x3d, 0x54, 0x4e, 0xda, 0x7b, 0x99, 0x16, 0xb, 
+       0xae, 0xb9, 0xef, 0xbe, 0xfb, 0xe, 0x95, 0xf0, 0x57, 0xac, 
+       0xca, 0xa0, 0x4b, 0x1b, 0x8, 0xd, 0x70, 0x83, 0x1b, 0x86, 
+       0xc2, 0x64, 0xc0, 0x8d, 0xd7, 00, 0x82, 0xb9, 0x94, 0xd1, 
+       0xb, 0x18, 0x61, 0x64, 0x55, 0xd9, 0x15, 0x39, 0x3, 0x5b, 
+       0xab, 0x94, 0xf, 0xeb, 0xcc, 0xb3, 0x18, 0xd8, 0xd6, 0xd4, 
+       0x68, 0x6e, 0xe2, 0x66, 0xba, 0x99, 0x4d, 0x7b, 0x11, 0x28, 
+       0x50, 0xd5, 0xb8, 0xcb, 0x2e, 0xbb, 0x4c, 0xd4, 0x37, 0xc5, 
+       0xaf, 0xd5, 0xab, 0x9a, 0x3, 0xb5, 0x55, 0x35, 0xbf, 0xdf, 
+       0x59, 0xd7, 0xfa, 0xdc, 0xc1, 0x8f, 0x1c, 0xcf, 0xf3, 0x60, 
+       0x46, 0xa8, 0xe0, 0x55, 0xb1, 0x77, 0xe1, 0x4e, 0x8f, 0x7f, 
+       0x3b, 0x6e, 0x5a, 0xfc, 0x2e, 0x8e, 0xbb, 0xac, 0x38, 0x74, 
+       0xbe, 0x38, 0xaf, 0x69, 0xf5, 0x55, 0x68, 0x80, 0xdf, 0x7c, 
+       0xf3, 0xcd, 0x87, 0x7c, 0xee, 0x73, 0x9f, 0xdb, 0xec, 0x3f, 
+       0xfe, 0xe3, 0x3f, 0xfe, 0x4e, 0xb4, 0x2d, 0xd0, 0xf4, 0x1, 
+       0x71, 0x83, 0x9c, 0xb8, 0xaf, 0x5, 0xe1, 0xd7, 0x6f, 0xfa, 
+       0x26, 0x78, 0xbd, 0x17, 0x7f, 0xb7, 0xf8, 0x83, 0x75, 0x75, 
+       0xb0, 0x34, 0x78, 0x97, 0x97, 0x4d, 0x94, 0x5e, 0xd6, 0x21, 
+       0x1f, 0x32, 0xc5, 0xf5, 0x2a, 0xeb, 0xa3, 0xc1, 0x1c, 0x7, 
+       0xd4, 0x78, 0xcb, 0x1f, 0xa1, 0x35, 0x37, 0xfc, 0x40, 0x4e, 
+       0xed, 0xcb, 0x12, 0x2d, 0xba, 0xa0, 0x7d, 0xf6, 0xad, 0xda, 
+       0x5d, 0x37, 0x5b, 0x5a, 0x1b, 0x39, 0x8b, 0xb5, 0x36, 0x18, 
+       0xc2, 0x1b, 0xdc, 0xb4, 0xcd, 0x5e, 0xd1, 0xca, 0x9d, 0xcd, 
+       0x99, 0xca, 0xef, 0xe8, 0x9a, 0x93, 0x82, 0x3d, 0xc2, 0x18, 
+       0xdc, 0xa1, 0xb2, 0x1a, 0x95, 0x6e, 0xd2, 0xe8, 0xb7, 0x96, 
+       0x6d, 0x92, 0xd5, 0xb8, 0x58, 0xa8, 0xc, 0x70, 0x33, 0xd4, 
+       0x23, 0x28, 0xcc, 0x66, 0x5e, 0xab, 0xf9, 0x4a, 0x46, 0x2b, 
+       0x99, 0xee, 0xdc, 0x1e, 0x8b, 0x29, 0x1, 0x6c, 0xb4, 0x33, 
+       0xc, 0x6, 0xd0, 0x7e, 0x11, 0x24, 0x9e, 0x63, 0x1b, 0xd8, 
+       0x8, 0x92, 0x81, 0xdd, 0x74, 0xd8, 0x61, 0x87, 0x6d, 0xaf, 
+       0x3d, 0xe2, 0x57, 0x6b, 0x8e, 0xbd, 0x42, 0x34, 0x53, 0x3a, 
+       0xda, 0x47, 0xb3, 0x7, 0xe4, 0x6e, 0xdd, 0xbb, 0x58, 0xa0, 
+       0x90, 0x5f, 0x7b, 0xb, 0x9c, 0xb5, 0x9, 0x61, 0xec, 0xe1, 
+       0xa1, 0x7d, 0x9c, 0x4e, 0xdc, 0xe9, 0xe6, 0xb3, 0x69, 0x12, 
+       0x5a, 0x70, 0xd7, 0x25, 0xb0, 0xe1, 0x1a, 0xfc, 0x13, 0x1f, 
+       0x3b, 0xf4, 0xcc, 0x97, 0x8d, 0x22, 0x13, 0x8e, 0x39, 0xe6, 
+       0x98, 0x63, 0x95, 0xcc, 0xce, 0x1f, 0x1e, 0x39, 0x30, 0xfd, 
+       0xc1, 0x5b, 0x66, 0x61, 0x36, 0xf2, 0xe6, 0x1, 0x38, 0x9e, 
+       0x52, 0x85, 0x7e, 0xd4, 0x6, 0xa4, 0xd9, 0x9a, 0x1a, 0x5e, 
+       0xaf, 0x35, 0x95, 0x36, 0xe6, 0xb7, 0x95, 0x3a, 0xe4, 0x89, 
+       0xa7, 0x32, 0xb4, 0xd7, 0xc0, 0x46, 0xee, 0xf0, 0xe6, 0x13, 
+       0x3c, 0xb3, 0x6c, 0x56, 0x4a, 0xd7, 0xf9, 0xc0, 0x3, 0xb8, 
+       0xd0, 0xda, 0xd4, 0xfd, 0x4a, 0x33, 0xb0, 0x63, 0xcd, 0x6d, 
+       0x2b, 0x98, 0x36, 0x22, 0xdb, 0x1e, 0xc4, 0x4c, 0xa2, 0xa2, 
+       0xb0, 0xa2, 0xb7, 0xc2, 0x4a, 0x51, 0x8a, 0xde, 0x14, 0xcb, 
+       0x8f, 0x96, 0xca, 0xc7, 0x48, 0x89, 0xc7, 0x6c, 0xad, 0x97, 
+       0x59, 0xc8, 0xfb, 0xae, 0x6b, 0xc4, 0xd8, 0xcd, 0x37, 0xdb, 
+       0x6c, 0xb3, 0x8a, 0xa7, 00, 0x30, 0xd5, 0xda, 0x5b, 0x74, 
+       0x42, 0x9c, 0x10, 0x47, 0xba, 0xcd, 0x4d, 0xe2, 0x7a, 0x8c, 
+       0x10, 0xb6, 0x5a, 0xf2, 0xc9, 0x59, 0x2d, 0xb2, 0x51, 0x97, 
+       0xb2, 0xae, 0xc, 0xb0, 0xd, 0x68, 0x9b, 0xe3, 00, 0x1b, 
+       0xc0, 0xc3, 0x6c, 0x84, 0x87, 0x81, 0xcb, 0x83, 0x7, 0x6d, 
+       0x68, 0xd4, 0x87, 0xf1, 0xb6, 0xde, 0x7c, 0xf3, 0xcd, 0xcf, 
+       0xd3, 0x1b, 0x4f, 0xcb, 0xb5, 0x7f, 0x7b, 0x82, 0xea, 0xcb, 
+       0x59, 0xeb, 0x1c, 0x93, 0x9c, 0x12, 0xd8, 0xc3, 0x68, 0xaf, 
+       0x7c, 0x1f, 0x9a, 0x83, 0x5f, 0xb1, 0x37, 0x18, 0x2b, 0xd, 
+       0x8b, 0x1, 0x1c, 0xd3, 0xfa, 0xb0, 0x1a, 0xa1, 0x35, 0x9a, 
+       0x44, 0xef, 0x6c, 0x87, 0xef, 0xa7, 0xab, 0xde, 0x69, 0xed, 
+       0x95, 0x6f, 0x50, 0x7f, 0x4d, 0x16, 0x9f, 0x47, 0xa, 0x9c, 
+       0xf, 0xaa, 0x1e, 0xf4, 0xad, 0xb5, 0x75, 0xb1, 0xc0, 0x3b, 
+       0x9d, 0xea, 0x16, 00, 0x41, 0x4f, 0x40, 0xde, 0xd0, 0xbc, 
+       0xbb, 0x4d, 0x6d, 0x9c, 0xac, 0xa7, 0x2b, 0xe1, 0x73, 0x3f, 
+       0x64, 0x2a, 0xe7, 0x58, 0x1d, 0x17, 0xb8, 0x53, 0x52, 0x4c, 
+       0x61, 0x27, 0x1a, 0xa, 0x4, 0x8f, 0x69, 0x8f, 0xb7, 0x72, 
+       0x1, 0xdc, 0x1e, 00, 0xcd, 0xe7, 0x72, 0x34, 0x8b, 0xd3, 
+       0x75, 0xd2, 0xeb, 0x5a, 0xcd, 0xe5, 0x6f, 0xd1, 0xb4, 0x63, 
+       0xa1, 0xae, 0x79, 0x7d, 0x87, 0xd0, 0x72, 0x17, 0xcb, 0x5e, 
+       00, 0xb8, 0x64, 0xbd, 0xa0, 0x5d, 0xc5, 0x34, 0x4b, 0xfd, 
+       0xf6, 0x28, 0x58, 0xea, 0x5a, 0xb7, 0x69, 0xb9, 0xc2, 0xcc, 
+       0x54, 0x98, 0xd, 0x8, 0x3c, 0xe2, 0xa0, 0xed, 0xc2, 0x88, 
+       0xa4, 0xd1, 0x69, 0xb6, 0x1e, 0x23, 0x2c, 0xd7, 0xfc, 0x42, 
+       0x49, 0x95, 0x3b, 0x4, 0xc, 0x67, 0xc6, 0xc1, 0x48, 0x6b, 
+       0x18, 0x8f, 0xa2, 0x84, 0x30, 0x5c, 0x3b, 0x87, 0x52, 0x32, 
+       0xa3, 0xba, 0xfd, 0xc, 0x51, 0x5, 0xc0, 0x36, 0x93, 0x61, 
+       0xb0, 0x1f, 0x77, 0xd1, 0x1e, 0x98, 0x4b, 0x65, 0x18, 0xb4, 
+       0x1a, 0x74, 0xd2, 0xe7, 0xe6, 0x7a, 0xd4, 0x72, 0x5e, 0x4b, 
+       0x4b, 0xcb, 0x7b, 0x5a, 0x40, 0x9b, 0xa8, 0xb4, 0x50, 0x47, 
+       0x6d, 0x54, 0xa9, 0x43, 0x30, 0xf4, 0xbe, 0x73, 0x78, 0x83, 
+       0x8d, 0xf4, 0xbf, 0x6, 0x17, 0x3, 0xb5, 0x5c, 0xfc, 0xa3, 
+       0xae, 0xa7, 0x56, 0x8c, 0x3, 0xdf, 0x24, 0x2b, 0x19, 0xed, 
+       0xba, 0x83, 0xcf, 0x1, 0x38, 0xda, 0x89, 0xc8, 0x5e, 0x89, 
+       0x83, 0xf5, 0xe9, 0x22, 0x6b, 0x70, 0x1e, 0x41, 0x30, 0xc5, 
+       0x43, 0x83, 0x93, 0xf, 0xf9, 0xa3, 0x7f, 0xe8, 0x27, 0xe4, 
+       0xcd, 0x4f, 0x34, 0xe8, 0xcb, 0xbc, 0x35, 0xa6, 0xc7, 0x9b, 
+       0xb7, 0x6b, 0x7d, 0xe5, 0x66, 0x3e, 0x7c, 0xc0, 0xe, 0xbf, 
+       0x72, 0x4e, 0x8a, 0x2, 0x73, 0x3c, 0x59, 0xb0, 0x60, 0x41, 
+       0x81, 0x39, 0x8e, 0xf6, 0x8e, 0xb5, 0x76, 0xc, 0x6a, 0xf3, 
+       0xb4, 0x1c, 0xcd, 0xe2, 0x74, 0x70, 0xa0, 0xf9, 0xf6, 0xfb, 
+       0xb2, 0x38, 0x1f, 0xd2, 0x35, 0xea, 0xc, 0x90, 0xf1, 0x54, 
+       0xcc, 0x1e, 0x2c, 0xd1, 0xae, 00, 0x6c, 0x85, 0x55, 0x3, 
+       0x5b, 0xf7, 0x24, 0x35, 0x6b, 0x6e, 0x6e, 0x2e, 0xd2, 0xde, 
+       0xc, 0x14, 0x80, 0x80, 0x10, 0xf, 0xf3, 0xeb, 0x34, 0x8, 
+       0xd4, 0x8b, 0x1, 0xef, 0x4a, 0x7b, 0x6f, 0xa7, 0x51, 0x98, 
+       0xb8, 0x92, 0x7b, 0x76, 0x71, 0x3e, 0xc7, 0x3d, 0x78, 0x11, 
+       0x3a, 0x8e, 0x16, 0xc7, 0x69, 0xfe, 0xc2, 0x1e, 0x6a, 0xde, 
+       0x1c, 0xb, 0x9a, 0x3c, 0x2e, 0xa1, 0x4, 0xb0, 0xb, 0x3a, 
+       0x5f, 0x79, 0x2b, 0x1, 0x76, 0xa3, 0x9e, 0xdb, 0x4f, 0xd1, 
+       0xc9, 0x29, 0x97, 0x48, 0x63, 0xaf, 0xd2, 0x1b, 0x5e, 0x13, 
+       0x28, 0x9b, 0xb9, 0x3f, 0xf4, 0x9, 0x65, 0x56, 0x72, 0x7e, 
+       0x57, 0x8a, 0x8d, 0x9, 0x2c, 0xf6, 0x71, 0x44, 0x12, 0x66, 
+       0xdc, 0xdf, 0x5c, 0x69, 0xe, 0x60, 0x2a, 0x6b, 0xee, 0xd9, 
+       0xc1, 0xa3, 0x26, 0x6, 0x68, 0xd, 0xde, 0xe1, 0x9d, 0x6c, 
+       0x6b, 0x47, 0x34, 0xa6, 0x2c, 0xa1, 0x7a, 0x1, 0x72, 0xb2, 
+       0x36, 0xa7, 0x8c, 0x60, 0xb3, 0x8a, 0x28, 0x59, 0xa1, 0x40, 
+       0xd4, 0x42, 0xef, 0x34, 0x87, 0x2e, 0x90, 0xdf, 0x8, 0x5c, 
+       0x46, 0x65, 0xbc, 0xce, 0x9b, 0x72, 0x72, 0x2d, 0xea, 0x97, 
+       0x2e, 0x1a, 0x9c, 0x3e, 0xd4, 0x93, 0x93, 0x8c, 0x6, 00, 
+       0x89, 0x5b, 0xf6, 0x34, 0x17, 0x14, 0x87, 0x35, 0x37, 0xa1, 
+       0xe7, 0xdd, 0x9e, 0xba, 0x58, 0xf1, 0x10, 0x56, 0xe2, 0x90, 
+       0x97, 0x9b, 0x6e, 0xba, 0xa9, 0x55, 0x6b, 0x45, 0xd7, 0xca, 
+       0x52, 0x79, 0x55, 0xf7, 0x30, 00, 0xe1, 0x63, 0x6b, 0xd1, 
+       0x5a, 0xdb, 0x8a, 0x85, 0xf7, 0xb6, 0xdd, 0xce, 0x4a, 0x8a, 
+       0xc9, 0xe7, 0xa9, 0xac, 0x56, 0xf9, 0xec, 0x85, 0x91, 0x5c, 
+       0xa1, 0x66, 0xa8, 0x47, 0x1a, 0x2a, 0x85, 0x39, 0x1b, 0x34, 
+       0xb7, 0xc2, 0x55, 0xda, 0xab, 0xfd, 0x90, 0x56, 0xb7, 0x5f, 
+       0x97, 0x29, 0x92, 0x45, 0x62, 0x21, 0x99, 0xb2, 0xbf, 0xc, 
+       0x6a, 0x42, 0x18, 0xe8, 0x11, 0x13, 0xe6, 0x7a, 0x24, 0xf5, 
+       0x9c, 0x88, 0x34, 0xe6, 0x49, 0x5a, 0x4, 0x81, 0x19, 0x79, 
+       0x9a, 0x6, 0x36, 0xdb, 0x14, 0xb5, 0x78, 0x36, 0x4b, 0x17, 
+       00, 0xb2, 0xbd, 0x4d, 0x72, 0x33, 0xd7, 0x1a, 0x9b, 0xfa, 
+       0xd3, 0x1e, 0x6b, 0xec, 0x46, 0xad, 0x84, 0x4f, 0xd4, 0x1c, 
+       0xfb, 0x62, 0x80, 0x2d, 0xcf, 0xc9, 0x11, 0xc1, 0x14, 0xa6, 
+       0x5e, 0x36, 0xd1, 0xa8, 0x3, 0xf5, 0x91, 0x6, 0x4f, 0xe9, 
+       0x31, 0xa, 0xab, 0xb6, 0x98, 0x78, 0xb5, 0xf6, 0x8d, 0x8a, 
+       0xff, 0xbf, 0xe9, 0xe8, 0x1f, 0xf8, 0x2, 0x7f, 0x4, 0xa6, 
+       0x44, 0xa6, 0x73, 0xfe, 0xdd, 0x68, 0x78, 0x49, 0xdf, 0xd2, 
+       0xd7, 0xf0, 0x96, 0xb8, 0x2c, 0xa5, 0x66, 0x59, 0x49, 0x7, 
+       0xeb, 0x68, 0xaa, 0x1f, 0x89, 0x23, 0x9e, 0x83, 0xf3, 0x58, 
+       0x82, 0x91, 0xd3, 0xda, 0x82, 0xfe, 0x8a, 0x35, 0x38, 0x16, 
+       0x18, 0xfd, 0x9a, 0xd7, 0xe0, 0x3a, 0xb2, 0xe9, 0x16, 0x95, 
+       0x37, 0x4b, 0xbe, 0x95, 0x7d, 0xf9, 0x76, 0xd4, 0x47, 0xf2, 
+       0xc1, 0x63, 0xaf, 0xc, 00, 0xb4, 0x4c, 0x79, 0x90, 0x31, 
+       0xa8, 0x6d, 0x3d, 0x5a, 0x1e, 0xa9, 0x9f, 0x65, 0xd4, 0xb4, 
+       0xba, 0xb, 0x5, 0xea, 0x8c, 0xac, 0x83, 0x25, 0x9a, 0xc2, 
+       0x3d, 0xa5, 0x7c, 0xb6, 0x32, 0x8c, 0x13, 0x6b, 0x6d, 0xda, 
+       0x61, 0xcd, 0xd, 0x5e, 0x3a, 0x85, 0xb9, 0x3b, 0xe2, 0x25, 
+       0xae, 0xf5, 0x4a, 0x73, 0x43, 0xaf, 0x48, 0x7b, 0xc3, 0x68, 
+       0x7c, 0x5e, 0x73, 0x2b, 0x1e, 0x34, 0xb8, 0x34, 0xdb, 0x52, 
+       0x31, 0xf4, 0xe3, 0x9a, 0x7b, 0x8b, 0x47, 0xc1, 0xf2, 0xd2, 
+       0xa5, 0xea, 0x5d, 0xcc, 0x4c, 0x83, 0xd8, 0xa1, 0x46, 0x78, 
+       0xce, 0x5b, 0xe3, 0x95, 0xbc, 0xc, 0xa7, 0x76, 0xc4, 0xc0, 
+       0xbe, 0xf8, 0xe2, 0x8b, 0x6f, 0x53, 0x69, 0x74, 0xb8, 0x3b, 
+       0xdb, 0x61, 0x29, 0x60, 0xc3, 0x54, 0xb7, 0xa3, 0x49, 0xa0, 
+       0x1e, 0x2f, 0x70, 0x5f, 0xa6, 0xd3, 0x60, 0x3a, 0x5a, 0x5a, 
+       0x5a, 0xc6, 0x53, 0x6b, 0x84, 0x80, 0x72, 0x9, 0xf1, 0x2c, 
+       0x6, 0x39, 0x4e, 0xba, 0x56, 0x41, 0xf5, 0x1a, 0xe6, 0x5b, 
+       0x29, 0x99, 0x60, 0x19, 0x75, 0x66, 0x82, 0x16, 0x67, 0xf4, 
+       0xff, 0xff, 0xdd, 0x69, 0x86, 0x16, 0xe6, 0xd6, 0xbc, 0x83, 
+       0x2e, 0xaf, 0xa3, 0x9a, 0x5a, 0xc3, 0x7e, 0x6d, 0xcf, 0x69, 
+       0xd9, 0x87, 0x6f, 0x70, 0x19, 0x54, 0x84, 0x68, 0x70, 0x3d, 
+       0x81, 0x99, 0x2c, 0xa0, 0x8f, 0xd4, 0x22, 0x19, 0x9b, 0x3e, 
+       0xe8, 0x1f, 0x2b, 0x16, 0x2b, 0xd, 0xff, 0x36, 0x20, 0xfc, 
+       0x1b, 0xb6, 0x87, 0xfc, 0xda, 0x4a, 0xfa, 0x8a, 0xd6, 0x49, 
+       0xf8, 0xc6, 0xdd, 0x86, 0xea, 0x93, 0x20, 0x8b, 0x28, 0x1d, 
+       0x5e, 0xa, 0xd1, 0x42, 0x57, 0x9a, 0xb2, 0xe8, 0x27, 0xd7, 
+       0xc7, 0x1a, 0x1b, 0xa0, 0xe3, 0x3d, 0x90, 0x1b, 0xd8, 0x84, 
+       0x95, 0x38, 0x64, 0x51, 0x73, 0xed, 0x36, 0xd, 0x64, 0x57, 
+       0xa8, 0x1d, 0xac, 0x30, 0x23, 0x77, 0x56, 0x32, 0xc8, 0x25, 
+       0x1e, 0xa0, 0x33, 0xea, 0xf4, 0x5a, 0x6b, 0x8b, 0x46, 0x55, 
+       0x87, 0x35, 0x90, 0xbf, 0x8b, 0x13, 0x93, 0xfc, 0x58, 0xc, 
+       0x46, 0x7a, 0xd4, 0x61, 0xe4, 0x61, 0x24, 0x62, 0x74, 0xc5, 
+       0xcc, 0x68, 0x96, 0xd9, 0xfc, 0xa4, 0x4c, 0xe6, 0xb9, 0xda, 
+       0x26, 0xb8, 0xd3, 0x74, 0xbd, 0xfe, 0xa8, 0xb4, 0x8a, 0x1c, 
+       0x60, 0x6, 0x2c, 0x30, 0x91, 0x10, 0x7, 0x88, 0x60, 0x32, 
+       0x9a, 0x92, 0x34, 0x83, 0x8a, 0x6b, 0xda, 0x9a, 0xca, 0x19, 
+       0x63, 0xec, 0x5e, 0xcb, 0xa8, 0xd3, 0xda, 0x34, 0x22, 0xf3, 
+       0x25, 0x10, 0x3, 0xdb, 0xc, 0xed, 0x9, 0xd8, 0x90, 0xa2, 
+       0xd7, 0x1a, 0xf5, 0x98, 0x6d, 0x8c, 0xcc, 0xf1, 0x4b, 0xf4, 
+       0xaa, 0x69, 0x6a, 0xf2, 0xe4, 0xc9, 0xeb, 0x53, 0x16, 0x75, 
+       0x62, 0x80, 0x2, 0xd0, 0xae, 0x7, 0x1d, 0xcf, 0xef, 0x18, 
+       0xe4, 0x10, 0x51, 0xbb, 0x39, 0xf8, 0x21, 0xa3, 0xe, 0xc5, 
+       0x4c, 0xf, 0x9b, 0x6e, 0x7a, 0xb3, 0xb1, 0x2, 0x9a, 0xff, 
+       0x1b, 0x1d, 0xe7, 0xae, 0xe9, 0xc9, 0x63, 0x7, 0x2f, 0x60, 
+       0x30, 0xaf, 0xd5, 0xe0, 0x97, 0x3f, 0xa6, 0x8, 0x40, 0xdb, 
+       0x4, 0x36, 0xb0, 0xd, 0x24, 0xf8, 0x4b, 0xdf, 0xd3, 0xd7, 
+       0x7a, 0x66, 0xdd, 0x2c, 0x1a, 0x7, 0xff, 0xe8, 0x47, 0x3f, 
+       0x4a, 0xce, 0x3a, 0xeb, 0xac, 0x5f, 0x17, 0xf1, 0x1, 0x40, 
+       0x58, 0x6, 0x8b, 0x2e, 0x85, 0x9f, 0x59, 0xe1, 0x51, 0x54, 
+       0x16, 0xdc, 0x8d, 0xa2, 0x49, 0xff, 0x4e, 0xd3, 0x69, 0xb7, 
+       0xf5, 0xec, 0x78, 0xc4, 0x3, 0x64, 0xca, 0x25, 0x8c, 0x41, 
+       0x4d, 0xd9, 0xd4, 0x3, 0x4f, 0xbf, 0x73, 0x2b, 0x32, 0x90, 
+       0x25, 0x51, 0xaa, 0xa8, 0xae, 0x69, 0x92, 0xfb, 0x56, 0xed, 
+       0xf9, 0x78, 0x52, 0x53, 0xb6, 0x85, 0xba, 0x6a, 0xad, 0x4d, 
+       0x68, 0xcd, 0x4d, 0xfd, 0xf1, 0x7d, 0xa2, 0xb5, 0x45, 0xa7, 
+       0x77, 0x73, 0x6e, 0x8, 0xe0, 0xba, 0xd1, 0xde, 0x8c, 0x96, 
+       0x41, 0x73, 0x13, 0xb2, 0x3a, 0x28, 0xe0, 0x4d, 0xd7, 0x4a, 
+       0x68, 0x13, 0x7b, 0x7f, 0x2b, 0x75, 0x6, 0x38, 0x61, 0x77, 
+       0xce, 0xc, 0x47, 0x63, 0x32, 0xe6, 0x68, 0xe, 0x35, 0x57, 
+       0x87, 0xeb, 0xdd, 0xa2, 0x7b, 0x18, 0x60, 0x3c, 0x4a, 0xc6, 
+       0x21, 0xa3, 0xa5, 0xe7, 0x38, 0x8c, 0x98, 0xd6, 00, 0xd4, 
+       0xb9, 0x71, 0xab, 0xad, 0xb6, 0x1a, 0xa5, 0x95, 0xf1, 0x4b, 
+       0xf5, 0x22, 0xcc, 0x80, 0x29, 0x53, 0xa6, 0x8c, 0x51, 0x5a, 
+       0xde, 0x79, 0xa0, 0x71, 0x2, 0xbf, 0xe3, 0xfa, 0xb9, 0x2e, 
+       0x5c, 0x17, 0xe0, 0x53, 0x8, 0xb5, 0x3a, 0x36, 0x6c, 0xba, 
+       0x11, 0x1f, 0x32, 0x7a, 0x36, 0x1e, 0x5e, 0x42, 0xf0, 0xfd, 
+       0xff, 0x57, 0x43, 0x16, 0xa9, 0x34, 0x57, 0xee, 0xd0, 0x20, 
+       0xcb, 0x42, 0x15, 0x27, 0x99, 0xa4, 0xc5, 0x9b, 0x70, 0x24, 
+       0x12, 0xa0, 0xc6, 0xf3, 0x3a, 0x2c, 0xe0, 0x76, 0x68, 0x90, 
+       0x1, 0x34, 0x80, 0x5, 0x88, 00, 0x15, 0xe0, 0x92, 0x79, 
+       0x5e, 0x2f, 0x9a, 0x93, 0xe9, 0x9b, 0xfb, 0xee, 0xbb, 0x8f, 
+       0x55, 0x74, 0x40, 0x6b, 0xef, 0xfe, 0x2b, 0xf5, 0x1b, 0x16, 
+       0x93, 0x1e, 0x84, 0x48, 0x75, 0x59, 0xa4, 0x39, 0xf8, 0x50, 
+       0xd1, 0xdc, 0x90, 0x69, 0x81, 0xc1, 0x1c, 0x3, 0xbb, 0xb8, 
+       0x1e, 0xd4, 0x21, 0x6, 0x77, 0xdc, 0xdf, 0x10, 0x2f, 0xe7, 
+       0xf4, 0x14, 0x85, 0x81, 0x6d, 0xb5, 0xfc, 0x85, 0x92, 0x5, 
+       0x2b, 0x16, 0xcb, 0x21, 0xa, 0x7, 0x90, 0x5b, 0xe, 0xf3, 
+       0xe0, 0x96, 0x4c, 0x51, 0xdf, 0x9a, 0x5d, 0x78, 0x91, 0xbf, 
+       0xda, 0xbb, 0xe9, 0x9c, 0x32, 0xf7, 00, 0x8a, 0xa0, 0xf1, 
+       0x14, 0xb2, 0xaa, 0xc9, 0xf3, 0x49, 0xf6, 0xff, 0xe1, 0x41, 
+       0xf3, 0x70, 0x1, 0x65, 0x7b, 0x1, 0xe5, 0x3b, 0x9f, 0xfe, 
+       0xf4, 0xa7, 0xd5, 0x77, 0x95, 0xef, 0xe6, 0xa2, 0x9d, 0xf6, 
+       0xd6, 0x90, 0x98, 0x3a, 0xcc, 0x9d, 0xf0, 0xac, 0x82, 0x12, 
+       0x22, 0x4c, 0x6c, 0x10, 0xd0, 0xfb, 0xd8, 0xd7, 0xb, 0xe4, 
+       0xb, 0x54, 0x26, 00, 0x86, 0x79, 0x84, 0x9e, 0x63, 0xc3, 
+       0x58, 0x98, 0x6a, 0x86, 0x76, 0x1, 0xb6, 0xea, 0x38, 0xfc, 
+       0xf3, 0x9f, 0xff, 0xfc, 0x9f, 0x24, 0x4c, 0x23, 0x34, 0x95, 
+       0x18, 0xa5, 0xbc, 0xc1, 0xa1, 0xb9, 0xa9, 0x87, 0x35, 0x34, 
+       0xa1, 0xeb, 0xe0, 0x7a, 0xb0, 0x50, 0x44, 0x7d, 0x8, 0xa5, 
+       0xa1, 0xf2, 0x9e, 0x34, 0xea, 0xac, 0x1, 0xae, 0x3, 0x4b, 
+       0x40, 0x8b, 0x72, 0x19, 0x2d, 0x32, 0xa6, 0x79, 0x8c, 0xf7, 
+       0x7f, 0xcd, 0xf1, 0x68, 0x8b, 0xb7, 0xa9, 0xd4, 0xf, 0x29, 
+       0xd6, 0x42, 0x74, 0xa8, 0x62, 0x58, 0xc4, 0x2a, 0xd6, 0x8c, 
+       0xd6, 0xd8, 0xe, 0x63, 0xcd, 0x4d, 0x5e, 0x6b, 0x4c, 00, 
+       0x6e, 0xcf, 0xe2, 0xa5, 0xe6, 0xcd, 0xab, 0x65, 0x15, 0x5d, 
+       0x27, 0xd, 0x7e, 0xa6, 0x78, 0xe7, 0x41, 0x1a, 0x6b, 0xd1, 
+       0x1a, 0x1c, 0x96, 0x86, 0x47, 0xb2, 0xa, 0x91, 0x43, 0x3c, 
+       0xc7, 0xc6, 0x22, 0x8b, 0x84, 0x30, 0x7d, 0xa0, 0x4c, 0xf4, 
+       0x6d, 0xb5, 0x22, 0xff, 0x45, 0x5e, 0x36, 0xd1, 0x54, 0x2e, 
+       0x68, 0x6e, 0x6, 0x14, 0x9b, 0xe7, 0xc4, 0x8b, 0xeb, 0x81, 
+       0xf8, 0x57, 0xaa, 0xb5, 0x91, 0x9, 0x6d, 0x6d, 0x6e, 0x95, 
+       0xb5, 0x72, 0x99, 0x6, 0xf8, 0xc7, 0x55, 0xe6, 0xbb, 0x39, 
+       0xcf, 0x96, 0x53, 0xe4, 0x11, 0x6f, 0x19, 0x45, 0x8b, 0x3, 
+       0x6e, 0xbc, 0x7, 0x2a, 0x45, 0xb3, 0x4e, 0x72, 0x57, 0x15, 
+       0xd8, 0x7b, 0x7c, 0xf6, 0x1c, 0x1, 0xd9, 0x80, 0x26, 0x74, 
+       0xdc, 0xe5, 0x3a, 0x74, 0xe1, 0x54, 0x8c, 0xa, 0xc2, 0x68, 
+       0x18, 0x8e, 0x19, 0xe, 0x92, 0x3f, 0xd0, 0x63, 0x8f, 0x5, 
+       0x9a, 0x3f, 0xcd, 0x13, 00, 0x77, 0xd0, 0xbb, 0xce, 0x55, 
+       0x99, 0xe7, 0xba, 0x3f, 0x38, 0x18, 0x4b, 0x3b, 0xe9, 0xf8, 
+       0xb8, 0xbd, 00, 0x87, 0x2d, 0xa5, 0xd2, 0x8c, 0xf, 0xa, 
+       0xd8, 0x8f, 0x2a, 0xb3, 0x41, 0x6d, 0x73, 0xbc, 0x78, 0xb4, 
+       0xf4, 0xfc, 0x86, 0xfa, 0x52, 0xf7, 0x20, 0xc, 0x32, 0xbf, 
+       0x87, 0x8, 0xd8, 0x17, 0xaa, 0x9e, 0x23, 0x5, 0xec, 0x91, 
+       0xa1, 0xd0, 0xdc, 0x1f, 0x8f, 0x6b, 0xee, 0x5c, 0xca, 0x47, 
+       00, 0x70, 0xa4, 0xb9, 0xe3, 0x2d, 0x94, 0x84, 0x5c, 0xb7, 
+       0x90, 00, 0x76, 0x81, 0x3e, 0xcd, 0x82, 0x1b, 0x1b, 0x70, 
+       0x78, 0xc, 0x84, 0x99, 0xae, 0xc7, 0x3e, 0x29, 0xd, 0x7c, 
+       0x41, 0x33, 0xe4, 0x8a, 0xfa, 0x5f, 0x17, 0x30, 0xd0, 0x71, 
+       0x5a, 0x89, 0x40, 0xcd, 0xc2, 0x11, 0x5a, 0x3a, 0x7c, 0xec, 
+       0x41, 0x3c, 0x8, 0xf3, 0x6a, 0x40, 0x2, 0x68, 00, 0xb2, 
+       0x41, 0xee, 0xdf, 0xc5, 0xa0, 0xe6, 0xba, 0xb5, 0x75, 0xcc, 
+       0x57, 0xf8, 0xb, 0x2f, 0x31, 0xd1, 0x5, 0xf0, 0x19, 0x39, 
+       0x13, 0x1d, 0x80, 0xc7, 0xce, 00, 0x47, 0x6, 0x71, 0xc, 
+       0xe2, 0xf4, 0x2f, 0x72, 0x4b, 0x68, 0x39, 0x6d, 0x97, 0x35, 
+       0x35, 0x5f, 0xf4, 0x59, 0x4d, 0x3f, 0x66, 0xc7, 0x1d, 0x77, 
+       0xac, 0x63, 0xa0, 0xa5, 0x6c, 0xf7, 0x19, 0xa1, 0x35, 0x36, 
+       0x65, 0xbb, 0x7f, 0x45, 0xa3, 0x22, 0xa7, 0x33, 0xd7, 0xdb, 
+       0xb4, 0xee, 0xf2, 0x94, 0x80, 0xfd, 0x8c, 0x6e, 0xb0, 0x86, 
+       0x76, 0x48, 0xbd, 0x3c, 0x20, 0x31, 0xa5, 0x75, 0xdd, 0x50, 
+       0x90, 0x31, 0xc6, 0x42, 0x7d, 0x55, 0xb6, 0xeb, 0xad, 0xcb, 
+       0x88, 0x7e, 0xf7, 0x60, 0xef, 0x16, 0xdc, 0x22, 0x66, 0x20, 
+       0x13, 0x52, 0x20, 0xce, 0x5, 0xc7, 0x85, 0x67, 0xaf, 0x64, 
+       0x2b, 0x17, 0xa7, 0x53, 0x61, 00, 0xc4, 0x88, 0x14, 0xc0, 
+       0x4d, 0xa8, 0x37, 0xb0, 0x2e, 0x92, 0x39, 0xb6, 0xa5, 0xcc, 
+       0x95, 0x6, 0x2d, 0x52, 0x29, 0xa9, 0x32, 0x47, 0x75, 0x68, 
+       0xf, 0x9d, 0x4d, 0x88, 0x87, 0xf1, 0x38, 0xb4, 0xa2, 0xe6, 
+       0x35, 0x9c, 0x6, 0x33, 0x5f, 0xab, 0xf3, 0xb7, 0x28, 0xc9, 
+       0xc0, 0x8e, 0x1, 0xcd, 0x8, 0x69, 0x8d, 0x6d, 0xa6, 0x9a, 
+       0xa1, 0x1, 0xd8, 0xd2, 0xa8, 0x43, 0xbe, 0xf0, 0x85, 0x2f, 
+       0x9c, 0xaf, 0xd1, 0x7c, 0x9c, 0xb4, 0xea, 0x70, 0x68, 0xc7, 
+       0x2e, 0xcb, 0x92, 0x2c, 0x90, 0x8b, 0xd3, 0x5d, 0x17, 0xb, 
+       0x83, 0x43, 0x84, 0x5, 0x90, 0x5b, 0x68, 0x8, 0x73, 0x9a, 
+       0x3d, 0x80, 0x9c, 0x6b, 0xd2, 0x42, 0x1d, 0x9a, 0xaa, 0xa4, 
+       0xb4, 0x12, 0x1f, 0xce, 0x89, 0xab, 0x66, 0xda, 0x12, 0xd7, 
+       0xe3, 0xa3, 0x88, 0xb3, 0x48, 0xc6, 0x4a, 0xb3, 0x6, 0xab, 
+       0xf0, 0x95, 0x18, 0xf1, 0x9f, 0xf, 0x15, 00, 0xe4, 0x2, 
+       0x50, 0xd3, 0x6e, 0x9b, 0xbf, 0x80, 0xd9, 0x71, 0xd2, 0xf1, 
+       0xa4, 0x79, 0x30, 0x84, 0x77, 0xc4, 0x8b, 0x81, 0xed, 0xf6, 
+       0xd5, 00, 0x70, 0x64, 0x10, 0xd9, 0xa5, 0xbf, 0x91, 0x51, 
+       0xf7, 0x3b, 0x53, 0xa6, 0xf9, 0x2a, 0x8b, 0xf, 0x42, 0x7e, 
+       0xc1, 0x27, 0xd3, 0x1a, 0xdc, 0xd4, 0x81, 0xba, 0x50, 0xf, 
+       0xd7, 0x45, 0xf7, 0x56, 0xe4, 0x30, 0xc7, 0x17, 0x2d, 0x5a, 
+       0xb4, 0x56, 0x83, 0xdd, 0x8d, 0xba, 0x1, 0x79, 0xb4, 0x4c, 
+       0x2, 0x6a, 0x3, 0xdb, 0x5a, 0xda, 0xf5, 0x42, 0xa0, 0x89, 
+       0xc7, 0xce, 0x75, 0x75, 0x3a, 0x61, 0x47, 0xe, 0x9f, 0x82, 
+       0x41, 0x69, 0x90, 0x97, 0x35, 0xcb, 0x75, 0xa3, 0xc1, 0x4c, 
+       0x61, 0x30, 0xe3, 0xb3, 0xf2, 0x1b, 0xe7, 0xe2, 0xa, 0x42, 
+       0x5a, 0xc, 0x64, 0x57, 0xe0, 0x55, 0x5d, 0xbb, 0x54, 0x1e, 
+       0x6d, 0x8, 0x60, 00, 0x35, 0x26, 0x51, 0x7f, 0x79, 0xcc, 
+       0xa1, 0x61, 0xf2, 0x43, 0x65, 0x92, 0x62, 0x9e, 0x7f, 0xfb, 
+       0x33, 0x9f, 0xf9, 0x4c, 0x3, 0x1d, 0x5b, 0xa9, 0xa3, 0x1d, 
+       0xf6, 0x98, 0xc8, 0x68, 0xb, 0x3d, 0x66, 0x4b, 0x74, 0xc0, 
+       0x2, 0xa6, 0xf8, 0x3c, 0x9, 0x19, 0x8b, 0x67, 0xcc, 0x6b, 
+       00, 0x32, 0xc0, 0x26, 0xc4, 0xf4, 0x31, 0xa8, 0xcd, 0x64, 
+       0x6, 0x1d, 0x1c, 0xf5, 0xe, 0xc0, 0x96, 0x59, 0x36, 0x48, 
+       0x1f, 0xb1, 0xfb, 0xa3, 0x4c, 0xb5, 0x4d, 0x65, 0xa6, 0x85, 
+       0x87, 0xa2, 0x21, 0x47, 0x89, 0x3f, 0xae, 0x3, 0xa1, 0x17, 
+       0xf4, 0x72, 0xcf, 0xba, 0x43, 0x9d, 0x30, 0xc7, 0x8a, 0xa7, 
+       0xd, 00, 0x9a, 0x74, 0xb4, 0xb7, 0x4d, 0x78, 0x42, 0x7b, 
+       0x68, 0x69, 0x1a, 0xd8, 0x21, 0xde, 0x84, 0xf9, 0x38, 0x9a, 
+       0x1c, 0xf3, 0x9d, 0xf, 0x24, 0x20, 0x58, 0x7f, 0x2d, 0x8e, 
+       0x7a, 0xf2, 0x2c, 0x5f, 0x20, 0xe, 0x66, 0x37, 0xed, 0x52, 
+       0x3c, 0x68, 0x69, 0x6, 0x3f, 0x3, 0xc3, 0xa0, 0x35, 0x70, 
+       0xad, 0x9d, 0x9, 0xe3, 0x34, 0xe7, 0x8f, 0x81, 0x4d, 0x7b, 
+       0x1, 0x15, 0xf4, 0xba, 0x3, 0x15, 0x3c, 0xae, 0xd0, 0x44, 
+       0x47, 0x8e, 0x11, 0x34, 0x1e, 0x59, 0x20, 0x8b, 0xb1, 0x99, 
+       0x1e, 0x4c, 0x75, 0x29, 0x9a, 0x9d, 0xc4, 0xf3, 0xcf, 0xe9, 
+       0x3d, 0x81, 0x7a, 0x78, 0x6e, 0x60, 0x57, 0x52, 0xf, 0xd1, 
+       0x2b, 0x70, 0xf4, 0x69, 0xce, 0x1c, 0xff, 0x9f, 0x9c, 0x39, 
+       0x8e, 0xc, 0xda, 0x24, 0xf7, 0xbc, 0x1b, 0x59, 0x44, 0xe, 
+       0xf, 0x95, 0x5f, 0x5f, 0xde, 0x18, 0x52, 0x34, 0xaf, 0xb9, 
+       0x49, 0xb3, 0x23, 0xfe, 0xbc, 0xfc, 0x25, 0xf2, 0xc4, 0x6d, 
+       0x71, 0xaa, 0x4b, 0xd4, 0x29, 0x45, 0xae, 0x24, 0xb8, 0x73, 
+       0x23, 0x2, 0xc0, 0x85, 0x21, 0x48, 0x15, 0xe1, 0xcf, 0xb4, 
+       0x6a, 0xbc, 0xb5, 0x56, 0x7c, 0xc7, 0x2a, 0x1e, 0x9c, 0xe8, 
+       0xc5, 0xe0, 0xa6, 0x23, 0x32, 0x5a, 0xee, 0xbf, 0x5f, 0x1d, 
+       0xff, 0x17, 0x65, 0xb8, 0x47, 0xde, 0xf7, 0x9a, 0xa9, 0x9e, 
+       0xf3, 0x4, 0x80, 0xeb, 0x1b, 0x59, 0xff, 0x20, 0xb3, 0x77, 
+       0xfb, 0x6a, 0xcc, 0x73, 0xa, 0xa6, 0x1d, 0xf6, 0x5a, 0x85, 
+       0x4e, 0xae, 0xb9, 0xe6, 0x9a, 0x56, 0x8d, 0x92, 0xf3, 0xf5, 
+       0x1c, 0xf1, 0x56, 0x5d, 0x86, 0x61, 0x80, 0x1a, 0x6, 0x2, 
+       0x68, 0x3, 0xdd, 0xa3, 0x26, 0x23, 0x38, 0x66, 0x1b, 0x56, 
+       0x5, 0x2e, 00, 0x5b, 0xe6, 0x58, 0x7f, 0x3d, 0x47, 0x3d, 
+       0x47, 0xed, 0xdb, 0x46, 0xc0, 0x1e, 0x82, 0x50, 0xf5, 0xe4, 
+       0x5c, 0x7, 0x87, 0x1e, 0x6c, 0x8, 0x1, 0x3a, 0x82, 0x47, 
+       0x68, 0xf0, 0xf2, 0xdb, 00, 0x77, 0xc8, 0x35, 0xe2, 0xbe, 
+       0xe6, 0xfb, 0x28, 0x5b, 0xe6, 0x7a, 0x7, 0xc7, 0x39, 0xcb, 
+       0x8c, 0x5, 0xe0, 0x19, 0x9, 0x5e, 0x9a, 0x37, 0xec, 0x7c, 
+       0x10, 0x41, 0x4f, 0xf5, 0xeb, 0xab, 0xeb, 0xb4, 0x8f, 0xb7, 
+       0x98, 0x34, 0xdd, 0xc1, 0xec, 0xee, 0x50, 0xff, 0xa6, 0xa4, 
+       0x99, 0x99, 0x52, 0x70, 0xc4, 0x72, 0x9a, 0xf6, 0x2, 0x4, 
+       0x3c, 0xa0, 0x5, 0xac, 0x71, 0x58, 0xc, 0xea, 0xf8, 0x9a, 
+       0xf3, 0x2, 0x20, 0x3c, 0x34, 0xc, 0x66, 0x87, 0x3d, 0xf5, 
+       0x45, 0x19, 0x80, 0x1b, 0x38, 0x36, 0xd1, 0x11, 0x7e, 0xfa, 
+       0x9a, 0xb5, 0x20, 0xaf, 0x7, 0xf1, 0xcc, 0x1c, 0xf, 0xb8, 
+       0x43, 0x28, 0xcb, 0x69, 0x57, 0xd, 0xa8, 0x47, 0xef, 0xbb, 
+       0xef, 0xbe, 0x75, 0x1e, 0x54, 0x5d, 0xf, 0xc2, 0x4a, 0x9d, 
+       0xde, 0x2d, 0x6f, 0xd3, 0xd4, 0xeb, 0x49, 0x59, 0x3, 0x57, 
+       0xea, 0x1e, 0xe6, 0xd7, 0x78, 0xc0, 0x6d, 0x60, 0x23, 0x9b, 
+       0xc8, 0xe2, 0x76, 0x49, 0x43, 0x7a, 0xf7, 0xa6, 0xd, 0x9a, 
+       0xc6, 0x2b, 0x5e, 0xd6, 0x61, 0xb4, 0xb6, 0xbf, 0xdf, 0xbe, 
+       0xb2, 0xf5, 0x8d, 0xb5, 0x8b, 0x95, 0xe9, 0x97, 0xf2, 0xc8, 
+       0x2f, 0xe0, 0x2e, 0xb, 0x70, 0x1a, 0x5b, 0xca, 0x21, 0xd9, 
+       0xb4, 0xc4, 0xe0, 0x24, 0x5f, 0x5a, 0x8d, 0x9e, 0x7c, 0xee, 
+       0xb9, 0xe7, 0x4e, 0x2d, 0x75, 0x3, 0x69, 0x98, 0x65, 0x32, 
+       0xb7, 0x87, 0xfc, 0xe1, 0xf, 0x7f, 0x40, 0x5b, 0xbe, 0x20, 
+       0xbf, 0x94, 0x74, 0x39, 0x2a, 0x80, 0xf9, 0x81, 0x29, 0xcc, 
+       0x4, 0x95, 0xeb, 0xd, 0x39, 0xf3, 0x7c, 0x8b, 0x5a, 0xcc, 
+       0x73, 0xdd, 0x1f, 0x34, 0xe0, 0x75, 0xd7, 0x5d, 0xc7, 0x11, 
+       0x35, 0xf, 0x9, 0xd8, 0xb7, 0x2b, 0xc9, 0xc0, 0xb6, 0x29, 
+       0x4e, 0x8, 0x13, 0x49, 0xc7, 0xc, 0x62, 0x94, 0xb4, 0x19, 
+       0x44, 0xdb, 0x68, 0x67, 0x83, 0xc0, 0xd2, 0xa4, 0x8f, 0xf2, 
+       0xfd, 0x87, 0x4c, 0xf1, 0x6d, 0x5, 0xec, 0xc1, 0x3d, 0x9, 
+       0x93, 0xee, 0x9, 0x8e, 0x7c, 0x78, 0x83, 0xdb, 0xf7, 0xc5, 
+       0xc2, 0x10, 0xb, 0x2d, 0x42, 0x88, 0x30, 0x3, 0x68, 0x4, 
+       0xdc, 0x80, 0x46, 0xf8, 0x49, 0x23, 0x4, 0xdc, 0x80, 0x1d, 
+       0x8b, 0x44, 0x3, 0x57, 0x5a, 0x9b, 0x3d, 0x82, 0x65, 0x20, 
+       0xbe, 0xea, 0x43, 0x7b, 0x43, 0x3a, 0xbc, 0xca, 0x8e, 0x49, 
+       0xab, 0x35, 0x81, 0x70, 0x36, 0x39, 0x73, 0x58, 0x2d, 0xd2, 
+       0x85, 0xb9, 0xac, 0xeb, 0x56, 0x6b, 0x88, 0x39, 0xcd, 0x7c, 
+       0x99, 0x90, 0x5d, 0x76, 0x9a, 0x2e, 0xe4, 0x2d, 0xd, 0x2d, 
+       0x8a, 0x65, 0x4, 0xf0, 0x34, 0x96, 0x92, 0x5c, 0xd8, 0x78, 
+       0x42, 0x3b, 0x68, 0xa3, 0x1, 0x6b, 0xb0, 0xfa, 0x37, 0xa1, 
+       0x35, 0xb5, 0xaf, 0x11, 0xe2, 0x1, 0x32, 0xa1, 0x79, 0x4, 
+       0xdf, 0x88, 0x9b, 0xaf, 0x95, 0x82, 0x9, 0x1a, 0xd1, 0x1c, 
+       0x3c, 0x93, 0x7b, 0x4c, 0x6, 0x98, 0x3d, 0x42, 0x1b, 0xe0, 
+       00, 0x2, 0x19, 0x30, 0x20, 0x8, 0xed, 0x42, 0x7e, 0x59, 
+       0x20, 0xf7, 0xa9, 0xe, 0x69, 0xbd, 0x17, 0xfe, 0xe9, 0x83, 
+       0xe, 0x3a, 0xa8, 0x8e, 0xc1, 0x94, 0xfa, 0x54, 0x5a, 0x17, 
+       0x88, 0xe5, 0xcc, 0xf1, 0x35, 0x32, 0xc7, 0x6f, 0xd2, 0x4f, 
+       0x98, 0x65, 0x8f, 0xc, 0x2, 0x68, 0xea, 0x40, 0x5d, 0x58, 
+       0x64, 0xde, 0xb9, 0xff, 0xe4, 0x7e, 0x1b, 0x8d, 0x3c, 0x78, 
+       0xf4, 0xeb, 0xfd, 0x26, 0xf5, 0x5f, 0xae, 0xef, 0x88, 0x48, 
+       0xe1, 0xe6, 0xeb, 0xad, 0xcb, 0x6a, 0x84, 0x44, 0x2c, 0x49, 
+       0xa7, 0x32, 0xaf, 0xfc, 0xcb, 0x8b, 0x53, 0x5, 0xee, 0xb7, 
+       0x94, 0x4, 0x1e, 0x69, 0x1b, 0x34, 0x70, 0x6e, 0x47, 0x81, 
+       0xf6, 0xee, 0x2, 0x6e, 0x35, 0x84, 0x9b, 0xf0, 0x31, 0xb0, 
+       0x1, 0xa4, 0x9, 0x2a, 0x5a, 0xda, 0x9, 0xfc, 0xc9, 0x8c, 
+       0x19, 0x33, 0x26, 0x49, 0x20, 0xb7, 0xd6, 0xf7, 0x95, 0xf, 
+       0x54, 0x2e, 0xcc, 0x7, 0x17, 0x4c, 0x48, 0xa3, 00, 0x38, 
+       0x60, 0x6b, 0x90, 0x10, 0xbf, 0xab, 0x45, 0x97, 0x73, 0x75, 
+       0x58, 0xfd, 0x37, 0x8f, 0x38, 0xe2, 0x88, 0xb2, 0x7, 0x9, 
+       0x2a, 0x6f, 0x17, 0x7, 00, 0xd0, 0xd8, 0xd2, 0x1e, 0xf, 
+       0x6b, 0x33, 0xc4, 0x6d, 0xca, 00, 0x3, 0xd, 0x66, 0x6b, 
+       0x6d, 0xca, 0xb1, 0xa7, 0x6c, 0x3a, 0x99, 0x7a, 0x78, 0xe0, 
+       0x6a, 0x90, 0xe0, 0x35, 0xcb, 0x14, 0xff, 0x8d, 0x46, 0xe9, 
+       0x5d, 0x5, 0xec, 0x81, 0xd9, 0xe6, 0x2b, 0x47, 0x15, 0x2e, 
+       0xbe, 0x7, 0xe1, 0x4, 0xec, 0xa4, 0xe1, 0x2d, 0xb0, 0x16, 
+       0x64, 0x40, 0x8c, 0x30, 0x22, 0xf4, 0x80, 0xdb, 0xc0, 0x26, 
+       0x1d, 0x6f, 0xcd, 0xed, 0x38, 0x21, 0x40, 0x27, 0xaf, 0x16, 
+       0x9, 0xd3, 0x80, 0xd, 0xfa, 0xd0, 0x10, 0xc0, 0x79, 0x9e, 
+       0xdf, 0xce, 0xb, 0x33, 0xa2, 0x13, 0x3e, 0xbb, 0x44, 0xf9, 
+       0x2, 0x7b, 0x6, 0xba, 0xe4, 0x21, 0x3d, 0x57, 0x5e, 0xd8, 
+       0x96, 0x9b, 0xa3, 0xc5, 0x1e, 0x6e, 0x6, 0x91, 0x8c, 0x7, 
+       0x18, 0x81, 0x39, 0x7c, 0x70, 0x11, 0x2d, 0xac, 0x69, 0x43, 
+       0x6, 00, 0xb, 0xc8, 0xfa, 0x38, 0xc1, 0x7, 0x7c, 0xc2, 
+       0xc7, 0x6d, 0x9, 0x80, 0x66, 0x30, 0xa1, 0x3d, 0xf6, 0xd0, 
+       0x27, 0x6e, 0x40, 0xe7, 0xca, 0xcb, 0xb7, 0x33, 0x4e, 0x77, 
+       0x5e, 0xea, 0x89, 0xe7, 0x3e, 0x42, 0xf8, 0x64, 0x7e, 0x99, 
+       0x77, 0x55, 0x74, 0x41, 0x28, 0x2b, 0x7, 0x70, 0x9e, 0x83, 
+       0xa7, 0x72, 00, 0xf7, 00, 0xe, 0x29, 0x6, 0x75, 0x84, 
+       0x9f, 0x10, 0x87, 0x1c, 0xe2, 0x90, 0x75, 0xd2, 0x91, 0x8b, 
+       0x10, 0xd7, 0xea, 0xfe, 0xbd, 0xaa, 0x53, 0x5a, 0x3b, 0xe8, 
+       0x8e, 0x90, 0x3c, 0x17, 0x7c, 0xa8, 0x51, 0x79, 0xba, 0x75, 
+       0x58, 0x92, 0xd2, 0xda, 0xad, 0x7a, 0xf1, 0xe4, 0x1a, 0xf1, 
+       0xd, 0x53, 0x1c, 0xf9, 0x43, 0x36, 0x9, 0x1, 0xb6, 0x2d, 
+       0x47, 0xea, 0xb1, 0x4f, 0xe3, 0x98, 0xc6, 0xb1, 0x3, 0x37, 
+       0x1f, 0xd8, 0x3e, 0x70, 0x62, 0xff, 0x95, 0x19, 0x6d, 0x9b, 
+       0x48, 0xb4, 0x6b, 0x44, 0xb5, 0xa1, 0x1e, 0x9d, 0x4e, 0x29, 
+       0x4a, 0xd0, 0x63, 0x9a, 0x30, 0x55, 0xa6, 0x4d, 0xc6, 0x2d, 
+       0xf5, 0x36, 0xa0, 0xdb, 0xc5, 0x37, 0x2c, 0x71, 0xff, 0xce, 
+       0x67, 0xea, 0x24, 0x94, 0x6d, 0x20, 0xc4, 0x63, 0x70, 0x63, 
+       0x56, 0xb3, 0x4f, 0x9c, 0xb4, 0x6e, 0x9d, 0xe6, 0x2b, 0x1c, 
+       0x34, 0xb8, 0xbb, 0xfc, 0x6b, 0x1a, 0xe9, 0x77, 0x54, 0xe6, 
+       0xf9, 0xf2, 0x30, 0xe, 0x4f, 0x83, 0x60, 0x2a, 0x66, 0x3e, 
+       0x15, 0x6c, 0xd0, 0x28, 0xf7, 0x88, 0xcc, 0xcf, 0x1b, 0xf5, 
+       0xfe, 0xed, 0x1, 0x7a, 0x8d, 0xb2, 0x91, 0xce, 0xee, 0xc9, 
+       0x31, 0x67, 0xbd, 0xfa, 0xea, 0xab, 0x8b, 0x81, 0x6d, 0x73, 
+       0xc7, 0xc0, 0x6, 0xe8, 0x30, 0xd5, 0x23, 0xa5, 0x47, 0x6c, 
+       0xb7, 0xad, 0x41, 0x83, 0xd1, 0x4, 0xad, 0x8a, 0x7f, 0x5f, 
+       0x73, 0xed, 0xe9, 0xdb, 0x6c, 0xb3, 0xcd, 0x80, 0x6a, 0x46, 
+       0xe7, 0xe2, 0x3a, 0x5a, 0x20, 0xe1, 0x2d, 0x9e, 0xdf, 0xd0, 
+       0x3, 0x2c, 0x6, 0xb8, 0x85, 0xd9, 00, 0x26, 0x4, 0x38, 
+       0x6, 0xb8, 0x7f, 0x93, 0xe6, 0x3c, 0x80, 0x91, 0xdf, 0x6, 
+       0x38, 0xa1, 0xbd, 0xf8, 0x90, 0xd2, 0xe0, 0x56, 0xc7, 0x6f, 
+       0x97, 0x9b, 0x3, 0x4b, 00, 0x21, 0x75, 0xa4, 0xec, 0x9c, 
+       0xe7, 0xfb, 0x62, 0x80, 0x1a, 0x10, 0x87, 0xef, 0x4a, 0xeb, 
+       0x9e, 0x10, 0x72, 0x3f, 0x20, 0x27, 0xc4, 0x21, 0x24, 0xdc, 
+       0x3, 0x2d, 0x42, 0x9e, 0x45, 0xbb, 0xee, 0x71, 0x8, 0x68, 
+       0xc9, 0x63, 0xc0, 0x3a, 0x2c, 0x5, 0x66, 0x5f, 0xe3, 0x7e, 
+       0x7b, 0xee, 0x35, 0x9f, 0xe2, 0x30, 0x54, 0xa2, 0x86, 0x3f, 
+       0x94, 0x61, 0xd, 0xfe, 0xc3, 0x1f, 0xfe, 0x30, 0x25, 0xb, 
+       0xf2, 0x5f, 0xb5, 0x79, 0x86, 0xfe, 0xc6, 0x23, 0x77, 0x1e, 
+       0xdc, 0xd, 0x70, 0x83, 0x23, 0xf, 0x8, 0xe5, 0x9, 0x20, 
+       0xd7, 0xda, 0xcd, 0x5d, 0x8a, 0xd7, 0x6b, 0x2d, 0xe7, 0xd0, 
+       0x83, 0xf, 0x3e, 0xb8, 0xbe, 0x92, 0x5, 0x4e, 0xf8, 0x87, 
+       0x25, 0xa9, 0x1, 0xf8, 0x5e, 0xf9, 0xa7, 0x75, 0x3f, 0xf2, 
+       0x17, 0x5b, 0x8e, 0x68, 0x6e, 0xea, 0x40, 0xf9, 0x5b, 0xa5, 
+       0x9b, 0xd2, 0x13, 0xfb, 0x4f, 0x1a, 0x30, 0x7e, 0xf8, 0x2e, 
+       0x23, 0x9e, 0x48, 0x65, 0x52, 0x3a, 0x6e, 0x27, 0x49, 0x67, 
+       0x3a, 0x84, 0xb1, 0x18, 0xdc, 00, 0x1b, 0xb8, 0x27, 0x29, 
+       0x2d, 0xa0, 0x5, 0x4c, 0x6, 0xdc, 0xe8, 0x7e, 0x5c, 0x5c, 
+       0x7f, 0xda, 0x88, 0xcb, 0xb7, 0xa5, 0x1c, 0x92, 0xc, 00, 
+       0x40, 0x88, 0xd6, 0x6, 0xdc, 0xd, 0x12, 0x86, 0x1e, 0xc1, 
+       0x8d, 0xb9, 0x78, 0xe8, 0xa1, 0x87, 0x36, 0x4b, 0x23, 0xef, 
+       0x29, 0xe6, 0x2, 0xb4, 0x45, 0xf2, 0xef, 0xc8, 0xc3, 0x34, 
+       0xa, 0xa6, 0x71, 0x30, 0x9a, 0xb2, 0x69, 0x7c, 0x83, 0x1e, 
+       0x43, 0x5c, 0x2f, 0xed, 0x33, 0x51, 0x1a, 0x7c, 0x73, 0xcd, 
+       0xeb, 0x29, 0xaf, 0xac, 0x33, 0xb0, 0x35, 0x28, 0x3c, 0xac, 
+       0xfb, 0x6e, 0x57, 0x46, 0xcf, 0xab, 0x19, 0x25, 0x6d, 0x8e, 
+       0x93, 0x86, 0x87, 0x99, 0xee, 0x54, 0xca, 0xa6, 0x5d, 0x94, 
+       0x5b, 0xcf, 0x1b, 0x5d, 0x1a, 0x95, 0x6f, 0x99, 0x34, 0x69, 
+       0xd2, 0x2a, 0x2d, 0xec, 0xd, 0x40, 0xe0, 0xfa, 0xc2, 0x21, 
+       0xa4, 0x78, 0x83, 0x2d, 0xfe, 0xd, 0x50, 0x62, 0xc1, 0x6, 
+       0xc0, 0x8, 0x24, 0x21, 0x80, 0xb0, 0x26, 0x37, 0xb0, 0xe3, 
+       0x30, 0x6, 0x20, 0xe9, 0xfc, 0xb6, 0x67, 00, 0xc1, 0x93, 
+       0x8e, 0x23, 0xce, 0x35, 0xea, 0x40, 0x3c, 0xe7, 0x68, 0xbb, 
+       0x5, 0xc0, 0x69, 0xa1, 0xae, 0xd4, 0x91, 0x1, 0x86, 0xfa, 
+       0x11, 0xa7, 0x8e, 0x84, 0x71, 0x7d, 0x89, 0x3, 0xc6, 0xd8, 
+       0x93, 0xcf, 0xa0, 0xa5, 0xfe, 0xfc, 0xe6, 0x7a, 0x1c, 0x77, 
+       0x7e, 0xb7, 0xdb, 0x21, 0xf4, 0x5c, 0x9e, 0x79, 0x44, 0xd8, 
+       0x5b, 0x67, 0x80, 0xab, 0xfd, 0x87, 0x4e, 0x9b, 0x36, 0x6d, 
+       0x73, 0x81, 0xed, 0x8b, 0xb9, 0x76, 0x5b, 0xe8, 0x91, 0x3f, 
+       0x46, 0x31, 0x98, 0x65, 0x99, 0x54, 0x34, 0x38, 0xd2, 0x2d, 
+       0x27, 0x3c, 0x1, 0xb8, 0x43, 0xf5, 0xad, 0x13, 0xc0, 0x67, 
+       00, 0xf0, 0x9e, 0x76, 0x16, 0xea, 0x95, 0xd5, 0x56, 0xad, 
+       0x47, 0x2c, 0x94, 0xe5, 0xca, 0xc0, 0x60, 0x8d, 0x8d, 0x8c, 
+       0xe3, 0xf9, 0x6d, 0x73, 0x9c, 0x5, 0xbd, 0x4f, 0xf4, 0x9f, 
+       0xdc, 0x7f, 0xa3, 0x61, 0x3b, 0xc, 0x7d, 0xad, 0xa1, 0x51, 
+       0xd6, 0x5e, 0x5b, 0xa6, 0x41, 0xf, 0xba, 0x4, 0x6e, 0x1, 
+       0xb8, 0x18, 0xdc, 0xe9, 0x94, 0xb4, 0x76, 0xa8, 0x2b, 0x42, 
+       0x8a, 0x7, 0x8f, 0xd4, 0x13, 0xef, 0x36, 0x38, 0x54, 0x52, 
+       0xd6, 0x95, 0x3, 0x37, 0x20, 0xc6, 0x1b, 0xdc, 0x2c, 0x40, 
+       0xb0, 0x1f, 0xb7, 0x22, 0xee, 0x6f, 0xb2, 0xc9, 0x26, 0x7c, 
+       0x3a, 0x66, 0x82, 0x1a, 0xb9, 0xad, 0xcc, 0x73, 0xe6, 0x8, 
+       0x97, 0xcb, 0xc3, 0x4c, 0x7b, 0x1a, 0xe9, 0x32, 0x82, 0xc9, 
+       0xaf, 0x1d, 0x4c, 0xe7, 0x4a, 0x28, 0x4e, 0xd0, 0x8b, 0x1f, 
+       0x23, 0x65, 0x1e, 0x97, 0x44, 0x5a, 0x9, 0x60, 0x3, 0x66, 
+       0x6b, 0x6c, 0xc7, 0x1, 0x35, 0xcc, 0xf4, 0xfc, 0x86, 0xce, 
+       0xb4, 0xa3, 0xfe, 0xd, 0x2, 0xf3, 0x76, 0x1a, 0x89, 0xff, 
+       0x28, 0xb3, 0xf4, 0x2d, 0xad, 0x64, 0x8e, 0x67, 0x53, 0x89, 
+       0x56, 0x4a, 0xa9, 0x4f, 0x9f, 0xb9, 0x58, 0x50, 0x11, 0x68, 
+       0x80, 0x46, 0x1a, 0x61, 0xc, 0x1a, 0x84, 0x1f, 0x20, 0x2, 
+       0x4c, 0x40, 0x61, 0xe0, 0x12, 0x3a, 0xe, 0xe8, 0x1d, 0x77, 
+       0xe8, 0x7b, 0xc, 0x6c, 0x7e, 0x3b, 0x6e, 0x50, 0x13, 0x3a, 
+       0x5e, 0xaa, 0x61, 0x6, 0x15, 0xd7, 0xa8, 0x23, 0xbf, 0xd, 
+       0xb8, 0xb8, 0x8e, 0x5c, 0xb3, 0x8f, 0xc1, 0x4a, 0x9c, 0x74, 
+       0xa7, 0x39, 0x8c, 0xf3, 0x3a, 0x4e, 0x68, 0xda, 0xc4, 0x71, 
+       0xfe, 0x1d, 0xf3, 0x2a, 0x5c, 0xe8, 0xe5, 0x1f, 0x6d, 0xf7, 
+       0xed, 0x10, 0xcf, 0xea, 0x44, 0x77, 0x82, 0x1e, 0x67, 0x1e, 
+       0xa7, 0xb9, 0xef, 0x99, 0x39, 0x92, 0x6, 0x38, 0x3f, 0xd, 
+       0xf0, 0x62, 0x90, 0x70, 0xd, 0x39, 0x9, 0x79, 0xb5, 0x7b, 
+       0x6d, 0x96, 0xe8, 0xa4, 0x75, 0xf0, 0xc3, 0x81, 0xda, 0xad, 
+       0x18, 0x3e, 0xe0, 0x48, 0x86, 0x62, 0x27, 0xb9, 0x6d, 0xd7, 
+       0x7c, 0xfd, 0x3d, 0x85, 0x57, 0xe9, 0x1a, 0x40, 0xb6, 0x82, 
+       0x41, 0x16, 0x6d, 0x3d, 0x7a, 0x60, 0xd9, 0xbb, 0x79, 0x6c, 
+       0xe3, 0xf8, 0x81, 0x1b, 0xd, 0xcc, 0xc, 0xde, 0x78, 0xe0, 
+       0xf2, 0x4c, 0x7b, 0x46, 0xa7, 0x5f, 0x66, 00, 0x76, 0x9d, 
+       0xec, 0xea, 0x54, 00, 0xb8, 0x6e, 0x42, 0x5c, 0x54, 0x13, 
+       0x75, 0x62, 0x30, 0xc8, 0xdb, 0x1, 0xbf, 0x92, 0x61, 0x1e, 
+       0xb8, 0xa5, 0xfe, 00, 0x9a, 0xdf, 0x84, 0x5d, 0xb0, 0x59, 
+       0xa, 0xdc, 0x64, 0xc2, 0xc7, 0x84, 00, 0x20, 0x44, 0x2a, 
+       0x6, 0x80, 0xde, 0x7b, 0xd6, 0xa7, 0x66, 0x9f, 0xdf, 0x59, 
+       0xfe, 0xd, 0xad, 0xb0, 0xbe, 0xa6, 0x7b, 0xef, 0x97, 0x87, 
+       0x61, 0x54, 0xa, 0xf, 0xc0, 0xa1, 0x9, 0x13, 0xea, 0xd5, 
+       0x19, 0xf5, 0x32, 0xe5, 0xff, 0x4d, 0x1d, 0x7e, 0x82, 0x16, 
+       0x8d, 0xfa, 0x15, 0x3f, 0x3d, 0xf5, 0x5d, 0xe8, 00, 00, 
+       0x20, 00, 0x49, 0x44, 0x41, 0x54, 0xff, 0x8e, 0x80, 0x3d, 
+       0x3f, 0xa7, 0xb1, 0x61, 0x9a, 0x81, 0xed, 0x90, 0x34, 0x3, 
+       0x1b, 0x8d, 0x4d, 0x39, 0x94, 0xe9, 0xf6, 0x34, 0x4a, 0x53, 
+       0x6f, 0x21, 0xfa, 0x33, 0x65, 0xbe, 0x2d, 0xd3, 0xea, 0xf3, 
+       0x44, 0x16, 0x8f, 0x78, 0x89, 0x41, 0xfb, 0x7e, 0x3b, 0xb6, 
+       0xd8, 0x62, 0xb, 0x15, 0x5f, 0x71, 0x13, 0x45, 0xb6, 0x7b, 
+       0x87, 0xd0, 0xe2, 0x1, 0x18, 0xe, 0xa1, 0x26, 0xee, 0x34, 
+       0xca, 0x22, 0xd, 0x50, 0xa2, 0x71, 00, 0xa8, 0x7d, 0x29, 
+       0x10, 0x3b, 0x8d, 0xfc, 0xce, 0x17, 0x83, 0xda, 0x71, 0x3, 
+       0x9a, 0x30, 0xf6, 0x71, 0x6d, 0xa9, 0x3, 0xce, 0x21, 0xc0, 
+       0xc4, 0x19, 0x78, 0x84, 0x78, 0xae, 0x13, 0x1a, 0xc8, 0xd4, 
+       0xd9, 0x71, 0xe7, 0xf1, 0x75, 0xb7, 0xc7, 0xd7, 0xf9, 0xed, 
+       0x34, 0xe8, 0x10, 0xc7, 0x11, 0xf2, 0xdb, 0x65, 0x87, 0xc4, 
+       0x3e, 0xf8, 0x3, 0x5f, 0x24, 0x43, 0xe1, 0x2b, 0x9c, 0x7c, 
+       0x66, 0x78, 0xea, 0xd4, 0xa9, 0x3, 0xd4, 0xaf, 0x7, 0x69, 
+       0xab, 0x2a, 0x5b, 0x5f, 0xd, 0x70, 0x6, 0x7d, 0x9c, 0x1, 
+       0x41, 0x88, 0xd2, 0xb1, 0xdc, 0x73, 0xcd, 0x2e, 0xa4, 0x49, 
+       0x3e, 0x6e, 0x55, 0x5d, 0xd3, 0x5a, 0xe3, 0xd9, 0x4f, 0x56, 
+       0x69, 0x97, 0xaf, 0xc7, 0xf0, 0xd4, 0x80, 0xd3, 0x5e, 0x54, 
+       0xc6, 0xc5, 0xea, 0x23, 0x2c, 0xc8, 0x62, 0x60, 0x7b, 0x9e, 
+       0x8d, 0x3c, 0x6e, 0x5b, 0xd7, 0xbf, 0x6e, 0xca, 0xc0, 0x96, 
+       0x81, 0xe3, 0x47, 0xed, 0x32, 0xe2, 0xe9, 0x74, 0x26, 0xcd, 
+       0x74, 0xb7, 0x4e, 0xe6, 0xb8, 0x84, 0xa3, 0xd3, 0x2c, 0xb7, 
+       0x98, 0xa8, 0x56, 0x9a, 0x69, 0xa3, 0xb9, 0x55, 0x95, 0xec, 
+       0xe3, 0x69, 0x98, 0x48, 0x67, 0x51, 0x67, 0xe2, 0xf6, 0x5d, 
+       0xea, 0x5f, 0xa, 0xdc, 0xca, 0x1f, 0x1c, 0x99, 0xb9, 0xd1, 
+       0x23, 0x5, 0x95, 0x20, 0xad, 0x22, 0xc7, 0xea, 0xed, 0x51, 
+       0x47, 0x1d, 0xd5, 0xa8, 0x45, 0xa0, 0xbd, 0x75, 0xd8, 0xdd, 
+       0x7b, 0xd2, 0x92, 0xaf, 0xea, 0xc6, 0x97, 0xe4, 0xd, 0x70, 
+       0xe8, 0x40, 0x9b, 0x86, 0xc3, 0x8c, 0xb4, 0x1e, 0xab, 0xbc, 
+       0xa6, 0xb7, 0x73, 0xfe, 0x4b, 0x9d, 0xff, 0x1d, 0xcd, 0xbf, 
+       0x59, 0xc5, 0x56, 0xb2, 0x32, 0x74, 0xce, 0xb1, 0xe7, 0x9, 
+       0xd8, 0xb3, 0x94, 0xe4, 0x91, 0xd1, 0xa0, 0x26, 0x34, 0x43, 
+       0x6d, 0x8a, 0xd3, 0x78, 0x98, 0x49, 0x9d, 0x29, 0xa7, 0x51, 
+       0x53, 0xec, 0xa9, 0x5a, 0x11, 0x3f, 0x5f, 0xc0, 0x5e, 0xa1, 
+       0x5d, 0x68, 0x13, 0x59, 0x94, 0x43, 0x30, 0xb5, 0x98, 0x94, 
+       0xd6, 0x20, 0xd4, 0x2e, 0xa0, 0xf3, 0x62, 0x47, 0xd8, 0xf7, 
+       0xac, 0xfc, 0x7d, 0xe6, 0x62, 0x41, 0x46, 00, 0x29, 0x13, 
+       0xd0, 0x21, 0xe4, 0xfc, 0xc6, 0xf3, 0xdb, 0xe0, 0x74, 0x9a, 
+       0x1, 0xc, 0xa8, 0xe3, 0xeb, 0x4e, 0x77, 0x7e, 0xae, 0xf9, 
+       0x1e, 0xd3, 0x22, 0xc4, 0xf9, 0x77, 0xa9, 0xc6, 0xc4, 0xf5, 
+       0x32, 0xe0, 0xe2, 0x90, 0x38, 0x9e, 0xfa, 0xc6, 0x71, 0x7e, 
+       0xdb, 0x43, 0xc3, 0x71, 0xe7, 0x23, 0x24, 0xdd, 0xf7, 0xb8, 
+       0x9c, 0x38, 0x2c, 0x55, 0x9f, 0xde, 0xa4, 0xb1, 0xba, 0xaf, 
+       0xc7, 0x4e, 0x61, 0x23, 0x8d, 0x16, 0x3, 0x79, 0x79, 0x28, 
+       0xd4, 0x4b, 0x9b, 0x52, 0x9a, 0xb5, 0x1b, 0xf2, 0x20, 0xad, 
+       0xa9, 0x64, 0x64, 0x1d, 0xfe, 0x46, 0x65, 0x20, 0x7f, 0x78, 
+       0x83, 0x1a, 0x19, 0x21, 0x1e, 0x5b, 0x78, 0xfa, 0x19, 0xe4, 
+       0x86, 0x30, 0x38, 0xc9, 0xdd, 0xcd, 0xaa, 0x7f, 0x4a, 00, 
+       0xdf, 0x17, 0x80, 0xb3, 0xe, 0x81, 0x63, 0x3, 0x8f, 0xe, 
+       0xe8, 0xe0, 0xcc, 0xfb, 0x4b, 0x25, 0x3f, 0x7e, 0xdb, 0xcb, 
+       0xf2, 0x88, 0x9c, 0xe2, 0x51, 0x34, 0xc8, 0xe3, 0x68, 0x21, 
+       0x6a, 0xd7, 0x41, 0x1b, 0xf, 0x9c, 0x32, 0x62, 0x97, 0x91, 
+       0x2f, 0x35, 0xe, 0x68, 0x6c, 0xef, 0x68, 0x93, 0xd6, 0xd6, 
+       0xb1, 0xf4, 0x82, 0x2f, 00, 0x97, 0x40, 0x84, 0x45, 0x33, 
+       0x71, 0x2f, 0x38, 0x96, 0xd0, 00, 0x36, 0x43, 0x21, 0x15, 
+       0x22, 0xd9, 0xe0, 0x46, 0xa6, 0xf9, 0x9d, 0xcb, 0x1a, 0xf2, 
+       0x17, 0xfc, 0x29, 0x5, 0x6e, 0xdf, 0xe0, 0x11, 0x21, 0xf, 
+       0xee, 0xee, 0x8, 0x15, 0x50, 0xcd, 0xfd, 0xe0, 0x7b, 0x61, 
+       0xd2, 0xe0, 0xc3, 0x34, 0xf, 0xd9, 0x5d, 0x6f, 0xe2, 0xd0, 
+       0xe0, 0xb, 0xe5, 0x1, 0x21, 0x8c, 0x84, 0xa1, 0x68, 0x6f, 
+       0x57, 0x98, 0x72, 0xea, 0xf4, 0x58, 0xeb, 0x31, 0xcd, 0xbf, 
+       0x2f, 0xd3, 0x4b, 0xed, 0x47, 0x1e, 0x7e, 0xf8, 0xe1, 0x8d, 
+       0x8, 0xa7, 0x18, 0xba, 0x56, 0xca, 0x9f, 0x2f, 0x88, 0x2, 
+       0x6c, 0xc0, 0x8b, 0x76, 0x86, 0x4e, 0xb9, 0x39, 0x76, 0x31, 
+       0xb0, 0x1b, 0xa4, 0xa5, 0x5b, 0xb4, 0x39, 0xe4, 0x22, 0x1, 
+       0x7b, 0xb5, 0xa6, 0xd, 0x13, 0x30, 0x75, 0x71, 0xb0, 0xd, 
+       0x27, 0xa0, 0xd7, 0x9, 0xe0, 0x98, 0x73, 0x89, 0xe, 0x6, 
+       0x48, 0x49, 0xbb, 0x87, 0xf4, 0xbe, 0xfe, 0x83, 0xc0, 0xe3, 
+       00, 0x24, 0x9e, 0xf2, 0x49, 0x23, 0xe, 0x28, 0x68, 0xaf, 
+       0xbd, 0x41, 0x6b, 0x10, 0x3b, 0x1d, 0xb0, 0xe3, 0x9c, 0xae, 
+       0x2d, 0x8e, 0xec, 0x70, 0xb, 0x69, 0xdc, 0x83, 0x23, 0x74, 
+       0xdc, 0xbf, 0xc3, 0x85, 0xdc, 0x1f, 0xb7, 0x9b, 0x9f, 0x8e, 
+       0x13, 0xf2, 0x78, 0x4d, 0x6f, 0xc2, 0x85, 0xba, 0xf0, 0x9b, 
+       0x3a, 0xe1, 0x8, 0xd, 0x5a, 0x42, 0x3, 0x37, 0xe, 0x9d, 
+       0x9f, 0xd0, 0xed, 0x24, 0xe4, 0x37, 0x7e, 0x5d, 0x39, 0x9e, 
+       0xbf, 0xeb, 0xb1, 0x2a, 0xaf, 0x90, 0xf2, 0x3e, 0x76, 0xf8, 
+       0x9c, 0xaf, 0xcb, 0x62, 0xaa, 0xc3, 0xa9, 0xb4, 0x77, 0xde, 
+       0x79, 0xe7, 0xc, 0x6, 0x6e, 0xd, 00, 0x67, 0xe9, 0x1a, 
+       0x95, 0x81, 0x51, 0x80, 0xe, 0x87, 0x2c, 0x96, 0x2, 0x78, 
+       0xb8, 0x98, 0xfb, 0x93, 0x91, 0xfc, 0xdd, 0xa0, 0x78, 0x4a, 
+       0x8b, 0xb9, 0xfb, 00, 0x70, 0xac, 0x2d, 0xc9, 0x29, 0xb2, 
+       0xc9, 0x59, 0x81, 0x4f, 0xe9, 0x1a, 0x40, 0x46, 0x26, 0x91, 
+       0xcd, 0xd8, 0x82, 0xa4, 0xc3, 0x60, 0xe4, 0x7e, 0x83, 0x26, 
+       0xf, 0x9a, 0x34, 0x6c, 0xf3, 0x21, 0x2b, 0x86, 0xb4, 0xc, 
+       0xd2, 0xea, 0x78, 0x6, 0x33, 0x5c, 0x4a, 0x33, 0x25, 0xcf, 
+       0x82, 0x75, 0x56, 0xb, 0xab, 0xdf, 0x2, 0xb3, 0xc4, 0x33, 
+       0x75, 0x22, 0xac, 0xd3, 0x62, 0x9a, 0x16, 0xd4, 0xe8, 0x29, 
+       0xd1, 0xc0, 0xc7, 0xd8, 0x74, 0x9a, 0x43, 0x5d, 0xce, 0xba, 
+       0x52, 0xe0, 0xe6, 0xa, 0x19, 0x71, 0x5, 0x44, 0x5c, 0x68, 
+       0xf6, 0x52, 0x65, 0x7f, 0xc5, 0x58, 0x76, 0x2f, 0x4d, 0xd1, 
+       0x33, 0xf0, 0x8f, 0x49, 0x8, 0x99, 0x7f, 0x5f, 0x23, 0xef, 
+       0xd1, 0x92, 0xd0, 0xe6, 0xb9, 0x2b, 0xcd, 0x42, 0xc6, 0x2d, 
+       0xda, 0x54, 0x32, 0x41, 0xcf, 0x1a, 0x77, 0xe2, 0x55, 0x41, 
+       0x1, 0xfe, 0x6e, 0x99, 0x5b, 0x37, 0xe5, 0xf2, 0x2, 0x6e, 
+       0xbc, 0x35, 0xb5, 0x43, 0xd2, 0x3c, 0x42, 0x16, 0x6b, 0x6c, 
+       0x59, 0xf9, 0x1b, 0x5c, 0xa2, 0xb9, 0x7c, 0xab, 0x4c, 0xef, 
+       0xf1, 0x80, 0x2, 0x61, 0xb3, 0x60, 0x5a, 0x70, 0x5, 0xf0, 
+       0xb4, 0x46, 0x60, 0x40, 0x93, 0x91, 0xf9, 0x9e, 0xd1, 0x86, 
+       0x6, 0xde, 0x60, 0x12, 0xd9, 0xbe, 0x77, 0xd0, 0xc5, 0xc7, 
+       0x20, 0x24, 0x4e, 0x9d, 0x9c, 0x6, 0x98, 0x89, 0x17, 0x87, 
+       0xd4, 0x3f, 0x4e, 0x7f, 0xfb, 0xed, 0x65, 0x49, 0xba, 0x6e, 
+       0xb0, 0xf2, 0x65, 0xa7, 0x68, 0x3a, 0xad, 0x22, 0xd7, 0x83, 
+       0x39, 0xa0, 0xab, 0xfa, 0xe4, 0xc7, 0x21, 0x2d, 0x38, 0xad, 
+       0xce, 0x76, 0xa6, 0x65, 0x93, 0xc2, 0x3d, 0x4b, 0x96, 0xbc, 
+       0x1b, 0x9e, 0x99, 0xbb, 0x7e, 0x6, 0xa7, 0x79, 0x45, 0xba, 
+       0xe3, 0xf1, 0x35, 0x68, 0xc2, 0x47, 0x9c, 0xef, 0x75, 0x18, 
+       0x12, 0xd7, 0xc1, 0x1f, 0xda, 0x24, 0xb9, 0xe2, 0x5d, 0xec, 
+       0x94, 0xcc, 0x62, 0x1e, 0xf5, 0x85, 0xed, 0xae, 0xd4, 0x2b, 
+       0x1e, 0x80, 0x58, 0xe4, 0xd5, 0xa6, 0x94, 0x66, 0x69, 0xd8, 
+       0x83, 0x34, 0xb8, 0xb3, 0xa3, 0xd, 0x80, 0x3, 0x66, 0x77, 
+       0xae, 0x95, 0x4d, 0x31, 0xc0, 0x7d, 0x9d, 0xda, 0x73, 0xad, 
+       0x43, 00, 0xbf, 0x5a, 0xed, 0xca, 0x68, 0xe, 0xbe, 0xf, 
+       0x6f, 0xb1, 0x49, 0x71, 0x3d, 0x24, 0xa5, 0x70, 0x87, 0xae, 
+       0x21, 0x7b, 00, 0xda, 0x8a, 0xc7, 0x72, 0xa, 0x6d, 0xc0, 
+       0xbd, 0x5f, 0xf3, 0xd8, 0xe6, 0x49, 0x83, 0x26, 0xd, 0x1a, 
+       0x30, 0x6a, 0xe7, 0xd1, 0xcf, 0xa, 0xae, 0x98, 0x6f, 0x1, 
+       0xd8, 0x84, 0xea, 0xd, 0x3a, 0x1e, 0x6, 0x52, 0x66, 0x28, 
+       0x57, 0x7f, 00, 0xb4, 0x64, 0x10, 0xa3, 0x5c, 0xf, 0x30, 
+       0xb2, 0xe9, 0xc6, 0xa4, 0xeb, 0xc6, 0xef, 0xfc, 0x3d, 0x8a, 
+       0xe7, 0x5d, 0x77, 0xe0, 0xf6, 0xd, 0xdc, 0x4c, 0xa1, 0x84, 
+       0x55, 0x3b, 0x98, 0xac, 0x67, 0xd8, 0xbc, 0x67, 0xbd, 0x8b, 
+       0x3a, 0x62, 0x89, 0x3c, 0xe6, 0xf9, 0x5c, 0x79, 0x6b, 0x57, 
+       0x68, 0x62, 0x9a, 0xe3, 0x28, 0x3, 0x51, 0xc3, 0x84, 0xfa, 
+       0xad, 0xe6, 0x6e, 0x9c, 0x2c, 0xda, 0xa4, 0x51, 0xf9, 0x32, 
+       0xa5, 0x91, 0x1f, 0x46, 0x99, 0x89, 0x8c, 0x92, 0x66, 0xa6, 
+       0x81, 0xed, 0x4e, 0xa2, 0xee, 0xd0, 0x6a, 0x90, 0x26, 0x1a, 
+       0x23, 0x73, 0xfc, 0x12, 0x81, 0x3a, 0xa5, 0x23, 0x6e, 0xc3, 
+       0xfb, 0xd8, 0x80, 0x5, 0xc1, 0xa3, 0x6e, 0xf6, 0xcc, 0x13, 
+       0x19, 0x89, 0xd1, 0x8a, 0xd2, 00, 0x29, 0xd, 0x2a, 0x6c, 
+       0xe0, 0xc8, 0x68, 0xbe, 0x16, 0x3e, 0x23, 0x23, 0x5a, 0xeb, 
+       0xc4, 0xc5, 00, 0x40, 0x58, 0xf3, 0x20, 0x54, 0x1c, 0x21, 
+       0xc5, 0x51, 0x5f, 0x1c, 0xa0, 0xc6, 0x19, 0xec, 0xce, 0x5f, 
+       0x57, 0xa7, 0x8d, 0x31, 0x6d, 0xcd, 0xc9, 0xc1, 0x87, 0x7d, 
+       0x45, 0x17, 0xf5, 0x39, 0x21, 0x7d, 0xa3, 0x1b, 0x10, 0x67, 
+       0xaf, 0x5b, 0xc3, 0xf3, 0xbb, 0x93, 0x96, 0x4c, 0xc0, 0xa4, 
+       0x5d, 0xdf, 0xe9, 0x86, 0xdb, 0xc, 0x9, 0xc, 0xc, 0xb7, 
+       0xde, 0x72, 0x41, 0x32, 0xa0, 0x7f, 0x7b, 0xd8, 0xc, 0x43, 
+       0xbd, 0x70, 0x6, 0x30, 0xbf, 0x5d, 0x1f, 0x78, 0x86, 0x8b, 
+       0xd3, 0x7c, 0x2d, 0x6e, 0x4f, 0xc8, 0xb4, 0x8e, 0xfe, 0xf0, 
+       0x1c, 0x5e, 0x73, 0xdc, 0x8c, 0xe4, 0x2a, 0xff, 0x45, 0x10, 
+       0xfa, 0xcf, 0x9e, 0xfe, 0xf4, 0xdc, 0x9f, 0x3a, 0x1, 0x70, 
+       0x59, 0x91, 0xcd, 0x3a, 0x36, 0xf9, 0x20, 0xed, 0x8c, 0xe4, 
+       0x48, 0xa5, 0x33, 0x69, 0x42, 0xae, 0x7a, 0x84, 0x28, 0x99, 
+       00, 0x60, 0x85, 0xc8, 0x51, 0xec, 0x82, 0x4c, 0x2a, 0x81, 
+       0xeb, 0xad, 0x52, 0x34, 0x7f, 0x16, 0xcd, 0xd5, 0x5a, 0x3d, 
+       0xdf, 0x42, 0x60, 0xbf, 0x48, 0x69, 0xc8, 0x21, 0x72, 0x89, 
+       0x4c, 0x1a, 0xd4, 0xc4, 0xa1, 0x83, 0xdf, 0xa2, 0x6e, 0x60, 
+       0xdd, 0x96, 0x83, 0x27, 0xf, 0x9a, 0x30, 0x66, 0x8f, 0x51, 
+       0xcf, 0xd4, 0x35, 0x4a, 0x15, 0xb7, 0x1, 0xe4, 00, 0x6a, 
+       0x99, 0x41, 0x5a, 0x4c, 0x43, 0x8b, 0x6b, 0x16, 0xa4, 0x3e, 
+       0xa3, 0xba, 0xc1, 0x29, 0x22, 0xb3, 0x27, 0xc3, 0x1e, 0xf2, 
+       0x74, 0x30, 0xcf, 0x85, 0x70, 0x5d, 0xc0, 0x23, 0x18, 0xe, 
+       0xc9, 0x9b, 0xbb, 0x83, 0x68, 0xa7, 0x2b, 0x7, 0x6e, 0x72, 
+       0x98, 0x50, 0x71, 0xd8, 0x79, 0x77, 0x85, 0x31, 0x76, 0xf9, 
+       0x60, 0xc6, 0xc8, 0x7c, 0xda, 0x4b, 0x8f, 0xc7, 0x56, 0xa8, 
+       0x63, 0xd8, 0xb9, 0xf6, 0x82, 0x3c, 0xd2, 0xa, 0xc3, 00, 
+       0x2e, 0xcc, 0xc5, 0xc1, 0x48, 0xc9, 0x71, 0xfb, 0x5a, 0x81, 
+       0xec, 0xcf, 0x7a, 0x75, 0x10, 0x26, 0x51, 0x7, 0xf2, 0xc2, 
+       0x28, 0x98, 0xc8, 0x60, 0x40, 0x3a, 0x9e, 0x38, 0x69, 0x5c, 
+       0x83, 0x16, 0x79, 0x69, 0x7c, 0xa3, 0x36, 0xa6, 0x8c, 0xd2, 
+       0xdc, 0xfa, 0x62, 0xbd, 0x71, 0xd5, 0xb4, 0xc3, 0xe, 0x3b, 
+       0xac, 0xa7, 0xb4, 0xe0, 0xe0, 0x1e, 0xc2, 0x88, 0x47, 0x50, 
+       0x11, 0x8, 0x80, 0x83, 0x37, 0x70, 0x34, 0x8, 0x71, 0xc8, 
+       0x2, 0xc7, 0xec, 0x26, 0x2c, 0xee, 0x49, 0x93, 0xeb, 0x36, 
+       0x48, 0xaf, 0x3b, 0x7, 0xfd, 0xb8, 0xc, 0x83, 0x97, 0x7a, 
+       0x12, 0x37, 0x80, 0xc, 0xf6, 0xfc, 0xf5, 0xba, 0x6c, 0x5b, 
+       0x10, 0x66, 0xc0, 0x8d, 0x5, 0x7, 0xb8, 0xb3, 0x6d, 0xd1, 
+       0x4f, 0xd1, 0x5, 0xbc, 0xc5, 0xe0, 0xc6, 0xd8, 0x83, 0xdb, 
+       0x6, 0x37, 0xf4, 0xeb, 0xa5, 0x43, 0x30, 0x65, 0x5d, 0x17, 
+       0x97, 0x49, 0xab, 0x89, 0xbb, 0x7e, 0xbe, 0x1e, 0xff, 0x5e, 
+       0x77, 0x9c, 0xe9, 0xa4, 0x4c, 0x9b, 0xf5, 0x98, 0x35, 0xc3, 
+       0x5e, 0x76, 0xde, 0x11, 0x67, 0x17, 0x1f, 0x8f, 0xf1, 0xf0, 
+       00, 0x98, 0xba, 0xe3, 0xe9, 0x53, 0x83, 0x9b, 0x90, 0xba, 
+       0x93, 0xa6, 0x5d, 0x67, 0xcd, 0xda, 0x53, 0x71, 0x90, 0xde, 
+       00, 0xe3, 0x3d, 0x73, 0x34, 0x78, 0xec, 0xca, 0x1, 0xdc, 
+       0xe0, 0x46, 0x6, 0xc9, 0x83, 0xc2, 0xb9, 0x54, 0x21, 0xa3, 
+       0x1c, 0x32, 0x47, 0x3a, 0x32, 0xc8, 0x35, 0x64, 0xd2, 0x71, 
+       0x64, 0x72, 0x5c, 0xba, 0x2e, 0x3d, 0x7d, 0xe8, 0x94, 0xc1, 
+       0x53, 0x46, 0xed, 0x3c, 0xf2, 0x95, 0x7e, 0xc3, 0x9b, 0x5b, 
+       0x99, 0x67, 0xcb, 0xe0, 0x66, 0x1, 0x2d, 0xab, 0x34, 0x1d, 
+       0x86, 0xae, 0xa, 0x1b, 0x51, 0xc4, 0x56, 0xe5, 0x90, 0x23, 
+       0x22, 0x89, 0x26, 0x50, 0x67, 0x65, 0x7, 0x7b, 0xd2, 0xe5, 
+       0x7a, 0x14, 0xc6, 0x2, 0x70, 0x67, 0x9, 0x64, 0xef, 0x8c, 
+       0xfe, 0x42, 0xc4, 0x3e, 0x4a, 0xae, 0x2e, 0x2a, 0xcd, 0x99, 
+       0xec, 0xbf, 0xff, 0xfe, 0x43, 0xb5, 0xe8, 0xb0, 0xf7, 0xcc, 
+       0x99, 0x33, 0xdf, 0x97, 0xe0, 0x5d, 0x2c, 0xa, 0x98, 0xe9, 
+       0x30, 0xc6, 0x4c, 0x83, 0x51, 0x34, 0xa, 0xb0, 0xaf, 0x11, 
+       0xb0, 0x19, 0x5, 0xb3, 0x6a, 0xa2, 0x73, 0x10, 0x80, 0x71, 
+       0xf6, 00, 0x1b, 0x86, 0x76, 0x1, 0xb6, 0x5e, 0xfe, 0x18, 
+       0xa1, 0x47, 0x5e, 0x17, 0xca, 0xf, 0xd1, 0xc7, 0x3, 0x46, 
+       0x19, 0x8, 0xf0, 0x8, 0xf, 0xa8, 0x11, 0x7e, 0x3a, 0x9c, 
+       0x10, 0x81, 0xc8, 0x82, 0x21, 0xf0, 0x34, 0x80, 0x49, 0xb, 
+       0x79, 0x69, 0x4, 0x48, 0xdb, 0x30, 0x3b, 0x4, 0xf4, 0x4, 
+       0x2d, 0xde, 0xd3, 0xb3, 0x4e, 0xd5, 0xa5, 0xcf, 0x9c, 0xeb, 
+       0x6a, 0x82, 0x6e, 0x3, 0x82, 0x4a, 0xdc, 0xae, 0x2e, 0xdd, 
+       0xb9, 0xaa, 0xcd, 0xe3, 0x50, 0xfd, 0x12, 0x13, 0x6d, 0xe2, 
+       0x8b, 0xb9, 0x1a, 0xb4, 0xc2, 0xf4, 0x4d, 0xb7, 0x40, 0x13, 
+       0xa7, 0x7, 0x2e, 0x18, 0x7c, 0x81, 0xdb, 0x61, 0x3c, 0xe0, 
+       0xb7, 0xae, 0xe9, 0xcb, 0x39, 0x79, 0x70, 0x9b, 0x3e, 0xa1, 
+       0x41, 0xee, 0xfb, 0x1d, 0xc6, 0x79, 0xd6, 0x75, 0x9c, 0x29, 
+       0x1a, 0xda, 0x5a, 0xd3, 0xb4, 0x8c, 0xa6, 0x4f, 0x7c, 0x51, 
+       0x24, 0xff, 0x66, 0x19, 0xc0, 0x36, 0xc0, 0x9, 0x63, 0x80, 
+       0x7b, 0x50, 0x22, 0x24, 0x9f, 0xf6, 0x37, 0x34, 0xeb, 0xd9, 
+       0x75, 0x25, 00, 0x47, 0xe, 0x71, 0x30, 0xdb, 0x20, 0x46, 
+       0xde, 0xc2, 0xbe, 0xf, 0x85, 0x46, 0x5b, 0x6c, 0x55, 0x5a, 
+       0x51, 0x11, 0xe, 0x52, 0x8e, 0x3, 0x86, 0x6c, 0x36, 0x64, 
+       0xca, 0xf0, 0xad, 0x87, 0x2f, 0x1f, 0xbe, 0xe9, 0xd0, 0x65, 
+       0x11, 0xb0, 0xb9, 0x37, 0xeb, 0x3, 0x7c, 0x73, 0x18, 0xb, 
+       0xdd, 0xa0, 0x7e, 0xc9, 0x21, 0x8e, 0x3e, 0x82, 0xd7, 0xd9, 
+       0x30, 0xa4, 0xea, 0x36, 0x5f, 0xcd, 0x87, 0xa4, 0x5, 0xa7, 
+       0xbc, 0xf9, 0x5d, 0x6a, 0x5, 0xe0, 0xf6, 0xf5, 0x28, 0xcc, 
+       0x4a, 0x42, 0x96, 0x58, 0x2e, 0xb9, 0xf6, 0x80, 0xf9, 0xb7, 
+       0x80, 0x32, 0x5e, 0x2b, 0x8c, 0xd3, 0xf5, 0xd1, 0x3d, 0x4c, 
+       0x99, 0x4b, 0xe4, 0x99, 0x33, 0xc3, 0x8, 0xbc, 0x19, 0x48, 
+       0x1c, 00, 0x3, 0xde, 0x62, 0x70, 0x3, 0x64, 0x7b, 0x3, 
+       0xdb, 0x92, 0xe, 0xb3, 0x1a, 0x64, 0x29, 0xc, 0x11, 0xa8, 
+       0xcf, 0x97, 0xd6, 0x5e, 0x4f, 0xab, 0xa5, 0x23, 0x94, 0x16, 
+       0x18, 0x4, 0x20, 0x60, 0x94, 0x5, 0x15, 0xe1, 0x30, 0x60, 
+       0xc8, 0x63, 0xc0, 0x90, 0x7, 0x47, 0x3e, 0x34, 0x77, 0x4e, 
+       0x8b, 0x67, 0x14, 0xe7, 0xe5, 0x8d, 0x44, 0x47, 0xf3, 0xc0, 
+       0xc3, 0x90, 0xe7, 0xc3, 0xfc, 0x43, 0x99, 0xc5, 0xe5, 0xba, 
+       0x4d, 0xd4, 0x23, 0x5c, 0x7, 0xf8, 0xfe, 0xa7, 0xf6, 0x76, 
+       0x8e, 0x1, 0xcc, 0xdf, 0x3b, 0x6b, 0x1b, 0xf2, 0x80, 0x6a, 
+       0x39, 0x26, 0x75, 0xc8, 0x2f, 0xf7, 0x3, 0x6e, 0xf8, 0xe2, 
+       0x72, 0x1c, 0x86, 0x8c, 0x1f, 0xd1, 0x1f, 0xda, 0xa8, 0x75, 
+       0x98, 0xf0, 0xa2, 0x8a, 0xe6, 0xcb, 0x3c, 0x3d, 0xe1, 0x3c, 
+       0xfc, 0xbc, 0xa6, 0x8e, 0x81, 0x6d, 0xcd, 0x1d, 0x83, 0x9b, 
+       0xf6, 0x18, 0xe0, 0xb4, 0x87, 0xfc, 0xda, 0x94, 0xd2, 0xac, 
+       0x79, 0x73, 0x4f, 00, 0x47, 0xe9, 0xe0, 0x60, 0x14, 0xde, 
+       0x72, 0x9, 0xb8, 0x91, 0x4b, 0x3c, 0xe9, 0xb1, 0xdc, 0x5a, 
+       0x96, 0xc9, 0x33, 0x63, 0xf0, 0xe4, 0xc1, 0x53, 0x87, 0x4e, 
+       0x19, 0x94, 0x8c, 0xd9, 0x75, 0xbd, 0xd7, 0xa4, 0xc2, 0xea, 
+       0x53, 0x32, 0xbf, 0xb5, 0xcd, 0x94, 0xdd, 0x68, 0x3a, 0xa7, 
+       0x8b, 0xe7, 0xda, 0xaa, 0x10, 0xac, 0xcf, 0xe1, 0x96, 0x7e, 
+       0xc1, 0xf9, 0xb7, 0x43, 0xd9, 0x4c, 0x21, 0xbd, 0x87, 0x3f, 
+       0x5, 0x99, 0x4a, 0x81, 0xbb, 0x87, 0xfb, 0x6b, 0xbf, 0xc, 
+       0x83, 0xb5, 0x2, 0xce, 0x1b, 0x46, 0x9b, 0xe9, 0x39, 0xe4, 
+       0x32, 0xed, 0xe8, 0x61, 0x65, 0xf1, 0x72, 0x79, 0x98, 0x63, 
+       0x70, 0x9b, 0x39, 0x30, 0xe, 0xb0, 0x12, 0x52, 0xe9, 0x62, 
+       0x6, 0x5a, 0xe3, 0x9b, 0xf1, 0xb4, 0xa5, 0x41, 0x8f, 0x40, 
+       0x6, 0xcb, 0xc, 0x9f, 0xc9, 0xd6, 0x52, 0xbd, 0x6d, 0x36, 
+       0x4c, 0x69, 0x79, 0x67, 0x41, 0x2d, 0x6, 0x77, 0x3e, 0x83, 
+       0x22, 0x16, 0x2, 0x42, 0x84, 0xc2, 0x5e, 0xc0, 0x66, 0xa5, 
+       0x95, 0xfd, 0xdd, 0x9c, 0x3, 0x96, 0x68, 0xf0, 0x48, 0xe9, 
+       0xd, 0xb2, 0xf8, 0xd6, 0x8f, 0x24, 0x1e, 0xda, 0x24, 0xee, 
+       0x10, 0x76, 0xc6, 0xb, 0xab, 0x42, 0x3a, 0xed, 0xe9, 0x2, 
+       0x6e, 0x4, 0x49, 0xff, 0xb3, 0x9a, 0x3b, 0xcb, 0x64, 0x38, 
+       0x6d, 0xfe, 0x14, 0x52, 0xf9, 0x68, 0x7e, 0xc1, 0x6b, 0x4e, 
+       0xd, 0xd5, 00, 0x9b, 0xd1, 0xc2, 0x59, 0x38, 0xcd, 0x85, 
+       0xbd, 0xed, 0x80, 0x17, 0x90, 0x12, 0xda, 0x2c, 0x77, 0x68, 
+       0x60, 0xc7, 0xa6, 0xb9, 0xfb, 0x95, 0x56, 0xc0, 0xf, 0xf2, 
+       0x56, 0x1, 0x70, 0x64, 0xcf, 0x32, 0x8a, 0x62, 0x41, 0xf1, 
+       0x58, 0x3e, 0xb3, 0x68, 0xcc, 0x5e, 0x27, 0x8f, 0x7f, 0xef, 
+       0x3f, 0x70, 0x83, 0x1, 0x9b, 0xc, 0xd9, 0x68, 0xf0, 0xe0, 
+       0xd, 0xf6, 0xd9, 0xe0, 0x19, 0xed, 0xa8, 0xa9, 0xeb, 0xc8, 
+       0x74, 0xd4, 0x9, 0xc7, 0xd8, 0x4b, 0x69, 0x65, 0x4a, 0xb3, 
+       0x4a, 0xa6, 0x3e, 0x41, 0xc6, 0x59, 0xdf, 0x44, 0xc6, 0xe9, 
+       0x44, 0x5, 0x21, 0x96, 0x4d, 0xe0, 0xb7, 0xee, 0x60, 00, 
+       0xce, 0x66, 0xc9, 0x5e, 0xae, 0xe4, 0xef, 0x87, 0xa, 0x6e, 
+       0x2a, 0x4, 0x53, 0x8f, 0x3e, 0xfa, 0x68, 0x3e, 0x20, 0xb0, 
+       0xb3, 0xe6, 0xe0, 0xcb, 0x5, 0x18, 0x5e, 0x85, 0xbb, 0x45, 
+       0x1e, 0xa6, 0xc0, 0x38, 0x42, 00, 0x4e, 0xa3, 0x71, 0xe, 
+       0x49, 0x37, 0xc0, 0xcd, 0x44, 0xd2, 0xe0, 0x6, 0x8c, 0xe6, 
+       0x25, 0x90, 0xfe, 0x32, 0x9d, 0x7f, 0x2b, 0xed, 0x3a, 0x55, 
+       0xdb, 0x58, 0xb3, 0xf, 0xc9, 0x75, 0xc1, 0x8e, 0x4e, 0xb5, 
+       0xa6, 0x8b, 0x5, 0x98, 0x74, 0x7b, 0xb, 0x81, 0x41, 0xed, 
+       0x90, 0x79, 0x1b, 0x5a, 0x5c, 0x26, 0x61, 0x5a, 00, 0xe7, 
+       0xf9, 0x66, 0x87, 0x2c, 0x84, 0x94, 0x1e, 0xab, 0xa5, 0x38, 
+       0x9e, 0xe7, 0x6f, 0xae, 0x6f, 0x39, 0xa0, 0xc1, 0x9f, 0x23, 
+       0x8f, 0x39, 0x9e, 0x29, 0x2c, 0x98, 0x69, 0xa1, 0x33, 0x7f, 
+       0x80, 0x21, 0xe0, 0x2d, 0x5, 0x6e, 0xc0, 0x6c, 0x60, 0xd3, 
+       0x5f, 0x9e, 0x73, 0xd3, 0xa7, 0xee, 0x57, 0xfa, 0xd9, 0xae, 
+       0x4, 0xc0, 0x7f, 0xed, 0x6b, 0xa, 0x2d, 0x8f, 0x28, 0x11, 
+       0xe4, 0xcd, 0xb2, 0x87, 0x8c, 0x5a, 0xe9, 0x28, 0x5a, 0x20, 
+       0x9f, 0x10, 0xc7, 0x4f, 0x6f, 0x1e, 0xd5, 0xbc, 0xd5, 0x90, 
+       0x8d, 0x87, 0x8c, 0x9f, 0xb8, 0xff, 0x84, 0xa7, 0x1a, 0x9a, 
+       0x35, 0xf5, 0x6b, 0xeb, 0xd0, 0x6a, 0x86, 0x56, 0xc8, 0x13, 
+       0x1, 0x3c, 0x95, 0x61, 0x81, 0x4c, 0xf9, 0x4, 0xe9, 0xe0, 
+       0x73, 0x90, 0xa6, 0x44, 0x3b, 0xa8, 0xc8, 0x5, 0x73, 0x1c, 
+       0xd3, 0x5c, 0x77, 0x7, 0xca, 0xd9, 0xe4, 0x8a, 0xfe, 0x7e, 
+       0xe8, 0xe0, 0xa6, 0x56, 0x1c, 0xe, 0x2f, 0x80, 0xa7, 0x35, 
+       0xff, 0xde, 0x53, 0x5a, 0xfc, 0x7d, 0x2d, 0x90, 0x60, 0x9a, 
+       0xdf, 0x23, 0xf, 0x23, 0x61, 0x1e, 0x8c, 0xb4, 0x26, 0xcf, 
+       0x35, 0x33, 0x30, 0x9b, 0x74, 0x9c, 0xd9, 0x60, 0x26, 0xd7, 
+       0x6b, 0x14, 0x6f, 0xd4, 0x63, 0x8e, 0xb3, 0xb5, 0x67, 0x7c, 
+       0x1b, 0x3d, 0xf6, 0x28, 0xfb, 0xda, 0x26, 0x9d, 0xcc, 0xdc, 
+       0x9a, 0x4e, 0x26, 0x8e, 0x33, 0xb0, 0x89, 0x5b, 0x10, 0x1c, 
+       0x1a, 0xdc, 0x84, 0x16, 0x16, 0x5e, 0xe4, 0x60, 0xce, 0x87, 
+       0x20, 0x69, 0x90, 0xea, 0x50, 0x7b, 0x52, 0x1c, 0x93, 0xe4, 
+       0x4d, 0x37, 0xd0, 0xf9, 0x9b, 0xab, 0x8d, 0x3, 0x6c, 0xa, 
+       0xe1, 0x79, 0x75, 0xee, 0xd9, 0x75, 0x8a, 0x1, 0x15, 0x3e, 
+       0x5b, 0x5b, 0x3, 0x48, 0xbc, 0xcd, 0x72, 0x42, 0xff, 0x26, 
+       0x9f, 0x41, 0x4d, 0xe8, 0x3e, 0x24, 0x8c, 0xfb, 0x3b, 0xae, 
+       0x59, 0x9, 0x80, 0xb3, 0x8a, 0x8e, 0x7c, 0x21, 0x6b, 0x84, 
+       0x78, 0x64, 0x11, 0xd9, 0xb4, 0x2c, 0x5a, 0xe1, 0xa0, 0x54, 
+       0x70, 0x84, 0x5c, 0x23, 0x7d, 0xd7, 0x86, 0x41, 0xd, 0xbb, 
+       0xc, 0x9b, 0x3a, 0x64, 0xa3, 0x9, 0x7b, 0x8f, 0x7f, 0xbe, 
+       0x79, 0x48, 0x93, 0x1e, 0x4a, 0x68, 0x25, 0xbc, 0x5d, 0xc0, 
+       0xe, 0x5b, 0x4c, 0x5, 0x57, 0xb4, 0x75, 0x6e, 0xf, 0x39, 
+       0xda, 0x38, 0x98, 0xe2, 0x52, 0xe9, 0xba, 0xb7, 0xc0, 0x71, 
+       0x8d, 0x7f, 0x38, 0xd, 0x4f, 0xfa, 0xdb, 0x25, 0x4b, 0xb8, 
+       0x56, 0xee, 0xcf, 0x47, 0x2, 0x6e, 0x2a, 0xc3, 0xa, 0x34, 
+       0x87, 0x24, 0xea, 0x51, 0xd7, 0x1, 0x17, 0x5c, 0x70, 0x41, 
+       0x9b, 0x34, 0x22, 0xf3, 0xeb, 0xb9, 0xf2, 0x36, 0xb7, 0x61, 
+       0x28, 0x8c, 0xe5, 0x37, 0x61, 0xb1, 0x33, 0x63, 0x39, 0x22, 
+       0xb7, 0x41, 0x8f, 0xb9, 0xfe, 0x59, 0xbb, 0xcf, 0x76, 0xde, 
+       0x6f, 0xbf, 0xfd, 0x6, 0xd1, 0x99, 0xdd, 0x39, 0xae, 0x7b, 
+       0x7e, 0x1d, 0xe7, 0xb5, 00, 0x38, 0x8c, 0x1, 0x4d, 0x1c, 
+       0x50, 0x93, 0xdf, 0xe6, 0x1e, 0x1b, 0x5e, 0xb4, 0xc0, 0x13, 
+       0xbe, 0x29, 0xc5, 0xa3, 0x33, 0x9e, 0xa, 0xe8, 0xf0, 0x89, 
+       0xf0, 0xac, 0xb5, 0xbb, 0xf2, 0xff, 0x76, 0xad, 0x2b, 0x7, 
+       0x78, 0x55, 0x52, 0xbb, 0xc0, 0x3a, 0xb4, 0x5d, 0x34, 0xa5, 
+       0x45, 0x4c, 0x5e, 0x35, 0xd, 0x7c, 0x36, 0xa8, 0x1, 0x2e, 
+       0x40, 0x74, 0x68, 0x50, 0xf3, 0xdb, 0xfd, 0xe1, 0x90, 0x3e, 
+       0x2, 0xdc, 0x1e, 0xb4, 0xdd, 0x9f, 0x5d, 0x4b, 0xcd, 0xa6, 
+       0x14, 0x1, 0x3c, 0xa3, 0x55, 0xf4, 0x33, 0x74, 0x5, 0xb9, 
+       0xb3, 0xb6, 0x26, 0x23, 0x32, 0xc8, 0x6f, 0x3c, 0x28, 0xc3, 
+       0xdb, 0xc2, 0x24, 0xd, 0x2c, 0x6d, 0xaf, 0xad, 0xa5, 0x7b, 
+       0x8c, 0xdc, 0x72, 0xc4, 0x26, 0xe3, 0x3e, 0x39, 0xee, 0xe5, 
+       0xc1, 0x1b, 0xc, 0x5e, 0x95, 0x69, 0x97, 0xc6, 0xe, 0x1b, 
+       0x54, 0xd8, 0x5e, 0x2a, 0xfd, 0xeb, 0x95, 0xf1, 0x2c, 0x6a, 
+       0x3, 0x9d, 0x30, 0xef, 0x2e, 0xc6, 0x6d, 0xae, 0x84, 0xec, 
+       0x42, 0x9a, 0x32, 0xa3, 0xbd, 0x55, 0x40, 0x35, 0xee, 0x23, 
+       0x3, 0x37, 0x95, 0xd4, 0xa6, 0x7e, 0xb6, 0xa8, 0xf6, 0x97, 
+       0xc9, 0x75, 0x10, 00, 0x97, 0xb9, 0xcb, 0x5c, 0xe6, 0x21, 
+       0x79, 0x33, 0xd5, 0xda, 0xdb, 00, 0x77, 0xfb, 00, 0x36, 
+       0xcc, 0xe6, 0x77, 0x9d, 0x80, 0x7d, 0xba, 0x1e, 0x7b, 0xed, 
+       0xa5, 0xe7, 0x98, 0x15, 0xbf, 0xdd, 0x45, 0x87, 0xdb, 0x1, 
+       0x5c, 0xb, 0x80, 0x5, 0x2, 0x1, 0x29, 0xf6, 0xd6, 0xa, 
+       0x80, 0x9c, 0x7b, 00, 0x37, 0x69, 0xfc, 0x46, 0x20, 0x79, 
+       0x1, 0x5, 0xcd, 0xc3, 0x8a, 0x3a, 0x8f, 0xce, 0x30, 0xd7, 
+       0xe3, 0x72, 0x5c, 0xde, 0xdf, 0xc2, 0x2c, 0x7, 0x18, 0x60, 
+       0x31, 0xbb, 0x35, 0x97, 0xee, 0x90, 0x15, 0x97, 0xd2, 0xe3, 
+       0xa5, 0x94, 0xf8, 0x17, 0xde, 0x3f, 0x67, 0x7b, 0x27, 0x60, 
+       0x5, 0xbc, 0x6, 0x30, 0x73, 0x6c, 0x83, 0x9a, 0xd0, 0xde, 
+       0xfd, 0x42, 0x48, 0xbf, 0xd0, 0x6f, 0xc5, 0xfd, 0xd9, 0x13, 
+       0xcf, 0x23, 0x80, 0xcf, 0xd0, 0x63, 0xb2, 0xb5, 0x2, 0x38, 
+       0x1a, 0x1c, 0xf9, 0xb3, 0x19, 0x6e, 0xa5, 0x83, 0x6c, 0xe2, 
+       0x10, 0xa0, 0x58, 0x9d, 0x6e, 0x51, 0xd7, 0xaf, 0x6e, 0xdf, 
+       0x51, 0x5b, 0x8f, 0xda, 0x4c, 0xc0, 0x7e, 0x75, 0xd4, 0x66, 
+       0xc3, 0x97, 0xa3, 0xb1, 0xb5, 0x9d, 0x14, 0x8d, 0xcd, 0xc2, 
+       0x19, 0x79, 0x31, 0xc6, 0xc3, 0x2, 0x5a, 0xee, 0xfe, 0x4e, 
+       0x88, 0x2b, 0xa1, 0xd8, 0x59, 0x16, 0x29, 0x5, 0x3b, 0xbe, 
+       0x5a, 0xf7, 0x91, 0x82, 0x9b, 0xca, 0x6a, 0x4b, 0x20, 0x73, 
+       0xd9, 0x81, 0xea, 0xe8, 0x19, 0xe7, 0x9d, 0x77, 0x5e, 0xbb, 
+       0xcc, 0x31, 00, 0xbe, 0x40, 0xde, 0xcc, 0x34, 0xb0, 0x61, 
+       0x2a, 0x80, 0x8e, 0x81, 0x9d, 0x96, 0x29, 0x7e, 0x88, 0xc0, 
+       0xa4, 0xa7, 0x1b, 0x33, 0x6, 0xd0, 0xb9, 0xd5, 0x38, 0x33, 
+       0xf, 0x33, 0x1d, 0x81, 0xb0, 0x36, 0xb7, 0x60, 0x18, 0xdc, 
+       0x8, 0xc, 0x3e, 0x16, 0x22, 0x4, 0xb, 0x93, 0x91, 0x90, 
+       0x74, 0x80, 0xce, 0x1e, 0x75, 0x56, 0x73, 0xd1, 0x36, 0x5a, 
+       0x8, 0xa, 0x7, 0x1e, 0x6a, 0x5d, 0x2f, 0xe1, 0x4c, 0x34, 
+       0xf2, 0xfd, 0xcd, 0x65, 0x39, 00, 0xaf, 0xb4, 0x65, 0xd3, 
+       0x7, 0x2a, 0xb2, 0x60, 0x16, 0xe, 0x54, 0x84, 0x8f, 0xf0, 
+       0xe, 0x5e, 0x19, 0xd0, 0x80, 0x8e, 0xdf, 0xe, 0x9d, 0x4e, 
+       0x1a, 0x9e, 0x7b, 0xdc, 0x3f, 0x31, 0xb0, 0xdd, 0xb7, 0x84, 
+       0x95, 0x3a, 0x3, 0xfc, 0xa2, 0x8b, 0x2e, 0xfa, 0x9c, 0xee, 
+       0xf9, 0x57, 0x79, 0x2f, 0x9c, 0x99, 0x8, 0xf2, 0x87, 0xc7, 
+       0x59, 0xb9, 0x10, 0xdf, 0xa4, 0xbe, 0xa9, 0x7e, 0xc6, 0xe8, 
+       0xad, 0x47, 0x6e, 0x3e, 0x6e, 0xd7, 0xf5, 0xdf, 0x1c, 0xb3, 
+       0xf5, 0xe8, 0x65, 0x1, 0xd8, 0x2c, 0xa0, 0xb1, 0xeb, 0xc, 
+       0xcd, 0xad, 0x1d, 0x68, 0x8a, 0x6b, 0x21, 0x4d, 0x3b, 0xd1, 
+       0x4, 0x69, 0x85, 0x59, 0x60, 0x97, 0x30, 0xc7, 0x21, 0xc8, 
+       0xd0, 0x11, 0xda, 0xc0, 0xf2, 0x9b, 0xfe, 0x67, 0x65, 0xd1, 
+       0xd5, 0x8, 0x39, 0xfe, 0x5f, 0x7b, 0x67, 0x1e, 0x5c, 0xd7, 
+       0x71, 0xa5, 0xf7, 0xb, 0xe0, 0x1, 0xe0, 0x6, 0x92, 0x20, 
+       0x40, 0x6c, 0x24, 0x48, 00, 0x24, 0x41, 0x82, 0x4, 0x37, 
+       0x8b, 0xa2, 0x64, 0x49, 0xb4, 0x68, 0xda, 0x96, 0x97, 0xb1, 
+       0x34, 0x96, 0x34, 0xce, 0xb8, 0x94, 0xc4, 0x55, 0xb2, 0xa3, 
+       0xd8, 0x71, 0xca, 0x51, 0x2a, 0x35, 0x95, 0x54, 0x92, 0xf9, 
+       0xc3, 0xc9, 0x1f, 0xae, 0xa4, 0x52, 0xe5, 0xd4, 0x68, 0x92, 
+       0x4a, 0x55, 0x2a, 0xa9, 0x91, 0xe3, 0xd8, 0x9e, 0x29, 0xc7, 
+       0x56, 0x79, 0xd1, 0xd8, 0x9e, 0x19, 0xcb, 0x9e, 0xd1, 0x6e, 
+       0x8b, 0xa2, 0x24, 0x52, 0x5c, 0xc0, 0xd, 0x20, 0x9, 0x82, 
+       0x24, 0xb8, 0x8a, 0x8b, 0x40, 0xac, 0xf9, 0x7e, 0x7d, 0xdf, 
+       0x7, 0x36, 0x1e, 0x1f, 0x48, 0x80, 0x4, 0x41, 0x68, 0x8a, 
+       0xd, 0xf4, 0x3b, 0xdd, 0x7d, 0xfb, 0xf6, 0xed, 0x3e, 0x7d, 
+       0xbe, 0x3e, 0xbd, 0xdd, 0xbe, 0xd7, 0xfd, 0x19, 0x1f, 0x1a, 
+       0xae, 0x9b, 0xdc, 0x8d, 0x45, 0xb8, 0xf7, 0xde, 0x7b, 0x1, 
+       0xca, 0x1c, 0xad, 0xc7, 0x3e, 0xac, 0x35, 0xf0, 0x7e, 0x75, 
+       0x71, 0x61, 0xea, 0x6e, 0x59, 0x18, 0x68, 0x50, 0x9b, 0xa9, 
+       0xf8, 0xdd, 0x25, 0xe7, 0xbb, 0xd8, 0x3f, 0xdf, 0xb4, 0x69, 
+       0xd3, 0x63, 0x5a, 0xd6, 0xb8, 0x5f, 0x5d, 0xf2, 0xe9, 0xde, 
+       0xd0, 0xaf, 0x38, 0x63, 0x36, 0x31, 0xb0, 0x11, 0x10, 0x83, 
+       0xdb, 0x2, 0xc2, 0xf5, 0x58, 0x80, 0x70, 0x1b, 0xe8, 0x6, 
+       0x38, 0xda, 0x1b, 0x61, 0x43, 0x70, 0xb1, 0x1a, 0x37, 0x86, 
+       0x75, 0x58, 0x6d, 0xb6, 0x18, 0x4, 0xe0, 0x1a, 0x97, 0xf, 
+       0x35, 0x36, 0x36, 0xfe, 0xbd, 0x3c, 0xa3, 0x7c, 0xac, 0x8c, 
+       0xa6, 0x57, 0xd3, 0xde, 0xde, 0x3e, 0xa8, 0x79, 0x96, 0x2, 
+       0x36, 0xa2, 0x8, 0xe0, 0x85, 0xac, 0xc1, 0xc3, 0x37, 0x40, 
+       0xd, 0x4f, 0xd, 0x5e, 0xa8, 0xdd, 0x5c, 0x37, 0xb8, 0xd, 
+       0x68, 0x83, 0x1a, 0xea, 0xfa, 0x71, 0xbd, 0x91, 0x1f, 0xc2, 
+       0xc6, 0x6b, 0x18, 0xa, 0x68, 0xaf, 0x78, 0x8f, 0x40, 0x88, 
+       0xec, 0xf9, 0x4d, 0x48, 0x64, 0xd, 0xb, 0xb2, 0x6c, 0x91, 
+       0x45, 0x1e, 0x40, 0xf8, 0xb2, 0x4c, 0x71, 0xe1, 0x63, 0x95, 
+       0x6b, 0x2b, 0x57, 0xd7, 0x6c, 0xac, 0x3d, 0x5d, 0x77, 0x77, 
+       0xed, 0x49, 0x4d, 0x9e, 0x65, 0x92, 0xec, 0xb, 0x21, 0x52, 
+       0x51, 0x7a, 0x29, 0x24, 0xec, 0x2f, 0x23, 0x7e, 0xaa, 0xb5, 
+       0xb3, 0x4b, 0x5f, 0x7a, 0xce, 0xa8, 0x68, 0x4d, 0x91, 0xcf, 
+       0xd, 0xe9, 0x1f, 0x2d, 0xc2, 0x78, 0xcd, 0x94, 00, 0x37, 
+       0x99, 0x7e, 0xf0, 0xc1, 0x7, 0x1, 0xf8, 0x3c, 0x75, 0xd1, 
+       0x1f, 0x7e, 0xf6, 0xd9, 0x67, 0xe9, 0xa6, 0xfd, 0x40, 0xc1, 
+       0xef, 0xca, 0x1a, 0xd4, 0x44, 0x43, 0x8b, 0xdb, 0x50, 0x5a, 
+       0x18, 0x56, 0xa8, 0x23, 0x8d, 0xff, 0x48, 0x1a, 0xfc, 0xeb, 
+       0x3f, 0xfc, 0xe1, 0xf, 0xff, 0x91, 0x26, 0xd3, 0x4a, 0x35, 
+       0xf6, 0x76, 0x9c, 0x31, 0x53, 0x4, 0x3, 0x23, 0x86, 0x8f, 
+       0x59, 0x8b, 0x5b, 0xd0, 00, 0xb3, 0x5, 0x13, 0x90, 0x63, 
+       0xd, 0x72, 0x6d, 0x7e, 0x29, 0x94, 0x10, 0x27, 0x9c, 0x87, 
+       0xad, 0x61, 0xc7, 0x10, 0x5d, 0x4b, 0x69, 0xf2, 0x70, 0xf6, 
+       0xd9, 0x64, 0x6e, 0x88, 0x19, 0x33, 0x23, 0x26, 0x38, 0xa2, 
+       0x1a, 0x6a, 0xf6, 0x5f, 0x3, 0xe4, 0xf0, 0x76, 0x1f, 0x5b, 
+       0x7b, 0x19, 0x57, 0xb, 0x7c, 0xe1, 0xb4, 0x98, 0x5c, 0xd0, 
+       0x1a, 0xd0, 0xa6, 0xf0, 0x38, 0xb6, 0x34, 0xac, 0xf8, 0xd, 
+       0xe8, 0x7c, 0x8d, 0xb1, 0xeb, 0x72, 0x3c, 0x45, 0x61, 0x5, 
+       0x84, 0xef, 0x66, 0x6b, 0x1f, 0xc6, 0xf3, 0x9a, 0x47, 0x79, 
+       0x56, 0xf7, 0x1a, 0xd4, 0x6e, 0x25, 0x52, 0x70, 0x5e, 0x1, 
+       0x38, 0xd8, 0x69, 0x29, 0x2c, 0x29, 0xfc, 0x7, 0xea, 0x8a, 
+       0xaf, 0xa9, 0xdd, 0x50, 0x7d, 0x7e, 0xd1, 0x83, 0xb, 0x8f, 
+       0xf, 0xf6, 0x9, 0xd8, 0x61, 0x56, 0x9c, 0xf9, 0x6d, 0xad, 
+       0x69, 0x93, 0xe, 0x2b, 0x59, 0xf4, 0xab, 0x1, 0xb5, 0xe4, 
+       0xc, 0x19, 0xb, 0xee, 0x6b, 0x1, 0x56, 0xe2, 0x48, 0x5c, 
+       0xc6, 0xda, 0x44, 0x2b, 0xd0, 0x2e, 0xc4, 0x54, 0xdc, 0x45, 
+       0xc6, 0x68, 0xa6, 0xc, 0xb8, 0xc9, 0xef, 0x43, 0xf, 0x3d, 
+       0xc4, 0x6e, 0xaa, 0x2a, 0x55, 0xd8, 0xa3, 0xdf, 0xfe, 0xf6, 
+       0xb7, 0x8b, 0xd4, 0xc2, 0xb3, 0x6, 0xfe, 0x76, 0x9e, 0xb2, 
+       0xa4, 0x48, 0xc, 0xc5, 0x4e, 0x39, 0x24, 0xd, 0xfe, 0x7f, 
+       0xf4, 0x16, 0x5a, 0xa7, 0xce, 0xbd, 0xfa, 0x37, 0xda, 0x91, 
+       0xc6, 0x81, 0xc, 0xae, 0x94, 0x3c, 0xb7, 0xe7, 0xf, 0xa, 
+       0xcc, 0x34, 0xf3, 0x15, 0x25, 0x16, 0x1c, 0x84, 0x29, 0xb6, 
+       0x80, 0x99, 0x7d, 0xe8, 0xc4, 0xc1, 0x8d, 0xc0, 0xe5, 0x82, 
+       0x1c, 0x3f, 0x71, 0xa0, 0xd2, 0xa, 0xf4, 0x32, 0x42, 0x3c, 
+       0x4d, 0xbc, 0x71, 0x38, 0x44, 0xd0, 0x46, 0xac, 0x95, 0xcb, 
+       0x86, 0x99, 0x76, 0x9e, 0xff, 0x41, 0x37, 0x8, 0x2e, 0x1a, 
+       0x9a, 0xad, 0xbb, 0x2, 0x4c, 0x98, 0xed, 0x46, 0x4b, 0xb, 
+       0xe0, 0x41, 0x4b, 0xc3, 0x2f, 0x8f, 0x9d, 0x71, 0x3, 0x62, 
+       0xf3, 0xf, 0x1e, 0xe6, 0x82, 0x9a, 0x6b, 0xbe, 0x6e, 0x5e, 
+       0x1b, 0xd8, 0x50, 0x78, 0x6, 0xc5, 0x98, 0x8e, 0x97, 0x87, 
+       0x1a, 0x16, 0xc, 0xea, 0xb5, 0xd0, 0x7e, 0xf5, 0x2a, 0xfe, 
+       0x4c, 0xeb, 0xe9, 0xaf, 0xe8, 0x7e, 0x2a, 0xc2, 0x96, 0xe4, 
+       0xac, 0xb9, 0x63, 0x80, 0xaf, 0x55, 0x57, 0xfc, 0xf1, 0xaa, 
+       0x75, 0xf3, 0x57, 0x57, 0xaf, 0x9f, 0x7f, 0xb1, 0xe1, 0x13, 
+       0xd, 0x47, 0x87, 0xb4, 0xdc, 0x25, 0xd0, 0x32, 0xc6, 0xd6, 
+       0x59, 0x68, 0xa2, 0x4c, 0xa0, 0x65, 0x15, 0x50, 0x94, 0x5e, 
+       0x9a, 0x2e, 0xbf, 0xd7, 0x30, 0x41, 0x16, 0x14, 0x27, 0xc8, 
+       0xa4, 00, 0x9e, 0x96, 0xf5, 0x1a, 0x37, 0xe4, 0xb9, 0x34, 
+       0xa5, 0xc0, 0x4d, 0xfe, 0xb4, 0x45, 0x95, 0xa, 0xae, 0x54, 
+       0x45, 0x3e, 0xfa, 0x9d, 0xef, 0x7c, 0xa7, 0x48, 0x42, 0xc1, 
+       0x4e, 0x9f, 0xdf, 0x45, 0x79, 0x77, 0x97, 0x88, 0x20, 0xdc, 
+       0x74, 0xd3, 0x83, 0xd5, 0xdb, 0x39, 0xbf, 0xd5, 0x96, 0xd5, 
+       0x3f, 0x96, 0x80, 0xfd, 0x3b, 0xb5, 0xc0, 0x65, 0xea, 0xee, 
+       0x67, 0x6e, 0xa4, 0xc2, 0x3, 0x43, 0x25, 0x34, 0xf9, 0xc6, 
+       0xe2, 0x5c, 0x43, 0xc8, 0xc, 0x6c, 0xb, 0x1c, 0x7e, 0xb, 
+       0x21, 0x60, 0x46, 0x50, 0xd, 0x6c, 0xfc, 0xb6, 0x74, 0x43, 
+       0x35, 0x89, 0x54, 0xc8, 0xe6, 0xc, 0xe2, 0x4b, 0x7b, 0xf, 
+       0xea, 0xed, 0xb3, 0x21, 0xe, 0x39, 0x14, 0xe8, 0x87, 0xd4, 
+       0xeb, 0x8, 0x5d, 0x77, 0xba, 0xa9, 0x1f, 0x14, 0xc3, 0xbb, 
+       0xd4, 0x7c, 0x3e, 0x48, 0x75, 0x35, 0xa8, 0xb2, 0x15, 0xa8, 
+       0xd7, 0x45, 0xf7, 0x9b, 0xf, 0x14, 0x84, 0x43, 0x17, 0xc5, 
+       0xa3, 0x61, 0x2d, 0x6d, 0xb0, 0x9a, 0x57, 0xa6, 0xf0, 0x2b, 
+       0xb6, 0x8e, 0x47, 0x18, 0x3c, 0xa6, 0x1e, 0x9, 0x83, 0xe2, 
+       0x77, 0x1d, 0xc5, 0x74, 0xbc, 0xfc, 0xa2, 0x7e, 0x5f, 0x7b, 
+       0xed, 0x35, 0xbe, 0xbc, 0xf9, 0xbe, 0x5e, 00, 0xf9, 0xdf, 
+       0x9a, 0xef, 0xd9, 0xa7, 0x34, 0xe8, 0x1d, 0x5a, 0xa6, 0x90, 
+       0x2f, 0x60, 0x68, 0x99, 0x3, 0xe4, 0x98, 0x75, 0x99, 0xe9, 
+       0x99, 0x47, 0xab, 0xd7, 0x57, 0xad, 0xae, 0xbb, 0xbb, 0xe6, 
+       0xec, 0xe2, 0x2d, 0x8b, 0xbb, 0xe8, 0x8a, 0x73, 0xc0, 0x61, 
+       0x78, 0x2f, 0x9b, 0xe3, 0x15, 0xd4, 0x1, 0x94, 0x1c, 0x32, 
+       0xc7, 0x9d, 0x4e, 0xa2, 0x5d, 0x69, 0x2c, 0x94, 0xe5, 0xeb, 
+       0x20, 0x9b, 0x27, 0x44, 0xc0, 0xb6, 0x9b, 0xe0, 0xf1, 0x98, 
+       0x29, 0x7, 0x6e, 0x32, 0xcf, 0x36, 0x55, 0x75, 0xd7, 0xca, 
+       0x55, 0x91, 0x8f, 0x7e, 0xf7, 0xbb, 0xdf, 0x2d, 0xd2, 0xdb, 
+       0x59, 0x8c, 0x7f, 0xdc, 0xa2, 0x9a, 0xf9, 0x30, 0x1a, 0xa6, 
+       0xe3, 0x67, 0x56, 0x33, 0xcc, 0x6c, 0x4a, 0x5b, 0x1c, 0x52, 
+       0x57, 0xf0, 0x3f, 0x8, 0x4c, 0x5f, 0x97, 0xb0, 0xd5, 0x6b, 
+       0x1c, 0x5e, 0x42, 0xd7, 0xef, 0x46, 0xc, 0x82, 0x14, 0xba, 
+       0x50, 0xba, 0x19, 0x81, 0xc2, 0x4d, 0xc5, 0x78, 0x9d, 0x9c, 
+       0x30, 0x2c, 0x42, 0x7, 0x90, 0x11, 0x44, 0x40, 0x8c, 0xf6, 
+       0x31, 0x98, 0x9, 0x8f, 0x41, 0x6e, 0x37, 0x20, 0x27, 0x8e, 
+       0x40, 0x11, 0xf6, 0xaf, 0xf3, 0x2c, 0x5e, 0x21, 0x94, 0x16, 
+       0x1f, 0xd4, 0x2c, 0x7b, 00, 0x3, 0x63, 0x40, 0x8e, 0x36, 
+       0x56, 0xfa, 0x9c, 0x6e, 0x1a, 0x9e, 0x9d, 0xbf, 0x1c, 0x63, 
+       0x10, 0x96, 0xfc, 0x37, 0xe6, 0xd, 0xd5, 0xbc, 0x47, 0xde, 
+       0x70, 0x2, 0xe1, 0x1, 0x79, 0xd7, 0x30, 0x8, 0xde, 0x73, 
+       0x4a, 0x6a, 0x1, 0x65, 0x52, 0x63, 0x3a, 0x24, 0x6d, 0x5d, 
+       0xa0, 0xf2, 0xb0, 0xb7, 0x19, 0x10, 0x86, 0x32, 0xa0, 0xa5, 
+       0x29, 0x9b, 0x41, 0x6a, 00, 0xc3, 0x37, 0xbb, 0xe1, 0x1f, 
+       0x6e, 0x68, 0x6c, 0xcd, 0xdf, 0x98, 0x92, 0x7, 0xd2, 0xbb, 
+       0x19, 0x50, 0x93, 0x6, 0x73, 0x25, 0x7a, 0x43, 0x8c, 0xc3, 
+       0xc, 0x8f, 0x6b, 0xa5, 0xe3, 0x7b, 0xf2, 0xf3, 0x9e, 0x3, 
+       0xdb, 0x99, 0xbd, 0xa5, 0x19, 0x79, 0x32, 0xc8, 0x61, 0x30, 
+       0x16, 0xbc, 0xdc, 0x55, 0x3c, 0xa3, 0xf8, 0xb3, 0xd5, 0xeb, 
+       0xab, 0x5b, 0xeb, 0x1f, 0x58, 0x78, 0x52, 0xf6, 0x44, 0xe8, 
+       0x8a, 0xf, 0x14, 0x48, 0x5b, 0x6b, 0x93, 0x7f, 0xd0, 0xd8, 
+       0x4c, 0xa2, 0x69, 0x9, 0x2c, 0xf4, 0xcc, 0xc3, 0xb8, 0x5a, 
+       0xf7, 0x66, 0xe9, 0x18, 0xab, 0x2a, 0xe0, 0x5f, 0x3f, 0xa1, 
+       0x9c, 0xea, 0x2f, 0x50, 0xe6, 0x34, 0xb, 0x22, 0x63, 0x34, 
+       0x53, 0x12, 0xdc, 0xe4, 0xfd, 0x81, 0x7, 0x1e, 00, 0x24, 
+       0xb3, 0x55, 0xa8, 0x47, 0xf5, 0xa5, 0xce, 0x8c, 0x26, 0xa6, 
+       0x40, 0xe8, 0xaf, 0x65, 0xd, 0x64, 0xa2, 0x61, 0xc, 0x70, 
+       0x26, 0xe1, 0xb0, 0x3d, 0xd2, 0x24, 0xa7, 0x5e, 0x7f, 0xfd, 
+       0xf5, 0xff, 0xaa, 0x43, 0x17, 0xfe, 0x50, 0x1f, 0x5c, 0xbf, 
+       0x57, 0x6f, 0x2, 0x15, 0xb3, 0x71, 0xe6, 0x46, 0x8c, 0x85, 
+       0x28, 0x6, 0x39, 0x61, 0x30, 0xdb, 0x9a, 0x1d, 0x37, 0x2, 
+       0x88, 0xd0, 0x9b, 0x22, 0xac, 0x80, 0xd7, 0xe0, 0xce, 0x5, 
+       0x35, 0xd7, 0x88, 0x4f, 0xb8, 0xa9, 0xf2, 0x5d, 0xc0, 0xbb, 
+       0xc9, 0xea, 0x26, 0x86, 0x74, 0x88, 0x73, 0xe2, 0xc4, 0xc9, 
+       0xa1, 0xb9, 0xe5, 0xb5, 0x43, 0x99, 0xcc, 0xfb, 0xa1, 0xa2, 
+       0x8b, 0x8a, 0x52, 0x20, 0xe8, 0x39, 0xe1, 0xa8, 0x62, 0xcd, 
+       0xda, 0x49, 0xea, 0x8a, 0x74, 0xc8, 0xc2, 0xa2, 0xbc, 0xc5, 
+       0x3b, 0x71, 0xe2, 0x48, 0xf2, 0xbd, 0xff, 0xab, 0x3, 0x48, 
+       0x4, 0xb8, 0x35, 0x6b, 0x37, 0x25, 0xf7, 0x6f, 0x7a, 0x64, 
+       0x38, 0xde, 0xab, 0x2f, 0x3f, 0x9f, 0xbc, 0xf3, 0xf6, 0x8b, 
+       0xc1, 0xff, 0xc4, 0x3f, 0xfe, 0xf7, 0x49, 0x65, 0xd5, 0xc2, 
+       0xe4, 0xc2, 0xb9, 0x23, 0xc9, 0x25, 0x8d, 0x14, 0xc9, 0xd3, 
+       0x40, 0x7f, 0xfa, 0xa6, 0x5c, 0x5f, 0x5f, 0xbf, 0x8e, 0x40, 
+       0xd6, 0x3c, 0x82, 0xfc, 0x83, 0x7a, 0x4d, 0xb4, 0xa8, 0xe0, 
+       0x12, 0xc3, 0x8c, 0x21, 0xe5, 0xbd, 0x90, 0x53, 0x72, 0xb2, 
+       0x7c, 0x8, 0xf9, 0x31, 0x48, 0xd, 0x48, 0x3, 0x17, 0xbf, 
+       0x81, 0x4b, 0x1c, 0xfc, 0x8e, 0xeb, 0x70, 0x87, 0x41, 0xcd, 
+       0x53, 0x68, 0x6c, 0xe1, 0x3d, 0x86, 0xb0, 0x1b, 0x35, 0xc, 
+       0x1b, 0x74, 0x70, 0x22, 0x4b, 0xaf, 0xdb, 0xa5, 0xb1, 0x7f, 
+       0xa1, 0xfc, 0xb3, 0xd, 0x9a, 0x7d, 0x16, 0xbc, 0xa8, 0x4, 
+       0x45, 0x8e, 0x58, 0x2, 0x43, 0xd6, 0x90, 0x2f, 0x1e, 0x8a, 
+       0x32, 0x79, 0xa0, 0x78, 0x76, 0xf1, 0x96, 0x9a, 0xb5, 0x35, 
+       0xab, 0x1a, 0x1e, 0x5c, 0x74, 0x6c, 0xc1, 0x87, 0x17, 0x9c, 
+       0x4, 0xd8, 0x3a, 0xf3, 0x4c, 0x67, 0xa0, 0xd1, 0x1d, 0xbf, 
+       0x62, 0x81, 0xa5, 0xe2, 0x5f, 0xd1, 0xda, 00, 0x55, 0x75, 
+       0x30, 0x66, 0x43, 0x7c, 0xa5, 0x90, 0x8e, 0xb9, 0x71, 0xd3, 
+       0xa0, 0x8d, 0xf9, 0xee, 0x10, 0xf1, 0x96, 0x80, 0x5b, 0x63, 
+       0xac, 0xa0, 0x71, 0xb4, 0xa1, 0x83, 0xcf, 0xe1, 0x8c, 0x2f, 
+       0x47, 0x51, 0x6c, 0x5e, 0xcb, 0x13, 0xc0, 0x59, 0xbb, 0xfe, 
+       0xfd, 0xe7, 0x9e, 0x7b, 0xae, 0x44, 0xdd, 0x27, 0x10, 0xfa, 
+       0x33, 0x59, 0x98, 0x4f, 0xab, 0x4a, 0x71, 0xd1, 0xdc, 0x54, 
+       0x4, 0x2d, 0x2e, 0x15, 0x43, 0x99, 0x8a, 0x54, 0x61, 0x45, 
+       0x3a, 0xac, 0xee, 0x7, 0xd, 0xd, 0xd, 0x47, 0x74, 0x72, 
+       0xc6, 0xe3, 0x3a, 0x66, 0xa7, 0x88, 0x83, 0x17, 0x2d, 0x1c, 
+       0x8a, 0x33, 0x2e, 0x13, 0x83, 0xdc, 0x82, 0x65, 0x90, 0xe3, 
+       0x47, 0xc0, 0x11, 0x4a, 0x2c, 0xc0, 0xb0, 0x3f, 0x80, 0x24, 
+       0x2, 0x71, 0xc, 0xea, 0x18, 0xf8, 0x6, 0xb8, 0xe3, 0x43, 
+       0x49, 0x6b, 0xe6, 0xcc, 0xe9, 0x5, 0xdd, 0x27, 0xba, 0x92, 
+       0xb2, 0xd9, 0x75, 0x49, 0xe3, 0x92, 0xd6, 0x64, 0x61, 0xfd, 
+       0x72, 0x85, 0x67, 0x74, 0x4c, 0x71, 0x66, 0xb0, 0xa4, 0x58, 
+       0x27, 0x8e, 0x66, 0x8a, 0x95, 0x8d, 0xb4, 0x87, 0xa1, 0xb3, 
+       0xbc, 0xc2, 0x3a, 0x4b, 0xe8, 0x9, 0xd2, 0x21, 0x94, 0x29, 
+       0x2e, 0x9e, 0x99, 0x1c, 0xdc, 0xff, 0xae, 0xd6, 0x8f, 0x4f, 
+       0x6a, 0x79, 0xee, 0x48, 0xb2, 0x66, 0xdd, 0x47, 0x83, 0xf6, 
+       0x1d, 0x1c, 0x18, 0x1c, 0xfa, 0xf5, 0xb, 0x3f, 0x48, 0x3a, 
+       0x8f, 0xec, 0x2d, 0xa8, 0xad, 0x5b, 0xa2, 0x33, 0xe4, 0xde, 
+       0x1b, 0xaa, 0xa9, 0x5d, 0x99, 0xf4, 0x57, 0x2e, 0x2f, 0xe0, 
+       0xb0, 0x7, 0xf2, 0xd6, 0xdb, 0xdb, 0x37, 0x4, 0x78, 0xdf, 
+       0xbf, 0xd4, 0x53, 0xd0, 0xd5, 0xd5, 0x56, 0x70, 0xfc, 0xc4, 
+       0x5e, 0x7d, 0xf6, 0xe2, 0x74, 0x52, 0x5d, 0x35, 0x2b, 0xcc, 
+       0x21, 0x50, 0x6e, 0x3, 0xd5, 0x65, 0x27, 0x2c, 0x6, 0x2b, 
+       0x6e, 0xae, 0x39, 0xcc, 0x94, 0x30, 0xdf, 0xeb, 0x38, 0x84, 
+       0x71, 0xbf, 0x29, 0x6e, 0x2c, 0x7c, 0xce, 0xb5, 0xe3, 0xaa, 
+       0xbc, 0x6c, 0x64, 0x1a, 0x68, 0xc9, 0x4, 0x9f, 0x13, 0x1e, 
+       0x90, 0x8c, 0xfe, 0xb5, 0xc6, 0xd7, 0x6f, 0xe9, 0x92, 0xf, 
+       0xfb, 0x80, 0xf2, 0x32, 0x93, 0x1, 0x8e, 0x4c, 0x21, 0x5b, 
+       0x20, 0x12, 0x99, 0xfa, 0xf4, 0xb4, 0x79, 0xd3, 0x36, 0xd6, 
+       0xac, 0xae, 0x5a, 0xd1, 0xb8, 0xa5, 0xb1, 0xb3, 0x76, 0x43, 
+       0xed, 0xe9, 0x1, 0x80, 0xcd, 0xac, 0xb8, 0xa6, 0x5e, 0x14, 
+       0x33, 0xb5, 0x9a, 0x19, 0x57, 0x97, 0x9c, 0x59, 0xf1, 0x30, 
+       0x81, 0x26, 0x1a, 0x30, 0xa9, 0x47, 0x3, 0x55, 0x25, 0x73, 
+       0xc5, 0xf4, 0xf7, 0xf4, 0x17, 0xca, 0x16, 0x65, 0x66, 0x64, 
+       0x6, 0x32, 0xaa, 0xcf, 0x2b, 0x57, 0x1c, 0x53, 0xe5, 0xe, 
+       0x7f, 0x69, 0x2b, 0xe1, 0xd0, 0x38, 0xde, 0xb5, 0xdc, 0x13, 
+       0xa, 0x6e, 0x4, 0x9a, 0x23, 0x7f, 0xb4, 0x9c, 0x10, 0xb4, 
+       0x96, 0x36, 0x2, 0x24, 0xea, 0x16, 0x27, 0x7a, 0x97, 0x3a, 
+       0x54, 0xe, 0x19, 0x81, 0xc1, 0x54, 0xd4, 0x58, 0x8d, 0x40, 
+       0xc9, 0xb9, 0xd9, 0x1a, 0x82, 0x4e, 0x7f, 0x44, 0xb3, 0x99, 
+       0x65, 0x9a, 0xf8, 0xe0, 0xd3, 0x2f, 0x9c, 0x30, 0x49, 0x6b, 
+       0x1b, 0x3, 0x1c, 0xc0, 0x53, 0x1e, 0x9a, 0xf4, 0xe1, 0x3e, 
+       0x8c, 0xc6, 0x7e, 0x2f, 0x6b, 0xec, 0x77, 0x58, 0xa0, 0x7a, 
+       0x42, 0x5a, 0xb1, 0x4a, 0x5d, 0xfe, 0x92, 0x1b, 0xd5, 0xe2, 
+       0x4a, 0x77, 0x58, 0xc8, 0x28, 0x2b, 0x82, 0xe7, 0x30, 0xdc, 
+       0xe, 0x43, 0x58, 0x1, 0x7, 0x42, 0x1a, 0x83, 0x95, 0x30, 
+       0x4, 0x9a, 0x78, 0x6, 0x79, 0xc, 0x6a, 0xc2, 0xb8, 0x16, 
+       0xdf, 0x43, 0xb7, 0x76, 0xda, 0xb4, 0x53, 0x1a, 0xcf, 0x1e, 
+       0x4f, 0xda, 0xf, 0xaa, 0xc0, 0x2a, 0x71, 0x6d, 0x5d, 0x93, 
+       0x3e, 0xe7, 0x33, 0x58, 0x20, 0x80, 0xea, 0xc0, 0x5, 0xde, 
+       0xdb, 0x4e, 0x35, 0x82, 0xf2, 0xa0, 0x31, 0x3, 0x9b, 0x19, 
+       0x91, 0x2d, 0x6b, 0x89, 0x82, 0xa4, 0xa1, 0x69, 0xdd, 0xd0, 
+       0xdb, 0xdb, 0xfe, 0xa6, 0xa0, 0xeb, 0xe8, 0x1, 0x9, 0xf7, 
+       0x1b, 0x83, 0xd3, 0xa7, 0xcf, 0x29, 0xb8, 0x78, 0xfe, 0x6c, 
+       0x41, 0xe7, 0x91, 0x7d, 0x21, 0xff, 0x2, 0x75, 0x81, 0xf8, 
+       0x54, 0xc0, 0xe1, 0xd, 0xfd, 0x7d, 0xea, 0x49, 0xe8, 0x21, 
+       0xd4, 0x93, 0x48, 0xa8, 0xa8, 0x33, 0xa7, 0xe, 0x25, 0xdd, 
+       0x27, 0xf6, 0x49, 0x63, 0x9f, 0x4b, 0xea, 0xea, 0x2b, 0x12, 
+       0x8e, 0xa0, 0x32, 00, 0x63, 0x8a, 0x3b, 0x6, 0xaa, 0xfd, 
+       0xe, 0xcb, 0xa5, 0xbe, 0x97, 0x70, 0xf8, 0x67, 0x3f, 0xf2, 
+       0x81, 0x3f, 0x17, 0xd0, 0xe3, 0x91, 0x9b, 0x50, 0xb0, 0xe8, 
+       0x47, 0x93, 0xb3, 0xe1, 0xac, 0x33, 0xcd, 0x9, 0x9c, 0x92, 
+       0xb6, 0xfe, 0x99, 0x86, 0x6e, 0x9c, 0x77, 0x6, 0x98, 0x1, 
+       0xb5, 0xcf, 0x3c, 0xc3, 0x8f, 0x45, 0x96, 0xdc, 0x2d, 0xe7, 
+       0xdb, 0x62, 0xf, 0xcf, 0xae, 0x2f, 0x5b, 0x33, 0x7f, 0xc5, 
+       0xfc, 0xa6, 0x65, 0x9f, 0x59, 0xba, 0xbf, 0xa2, 0xb9, 0xe2, 
+       0xa2, 0x78, 0xaf, 0xb3, 0xcf, 0x38, 0xb5, 0x54, 0xa0, 0xe, 
+       0x5d, 0x71, 0xb1, 0x67, 0x58, 0xf6, 0xd4, 0xda, 0xa6, 0x48, 
+       0xa4, 0x55, 0x42, 0xe8, 0xaf, 0xca, 0x7a, 0xcf, 0xf9, 0xcb, 
+       0x99, 0xae, 0xad, 0xc7, 0xaa, 0x4e, 0xef, 0x3d, 0x55, 0x31, 
+       0xbf, 0xa5, 0xb2, 0xbb, 0x66, 0x5d, 0xcd, 0xc9, 0x92, 0x59, 
+       0x25, 0x3c, 0x33, 0x35, 0xba, 0x8f, 0x5b, 0xc3, 0x8d, 0x61, 
+       0xe4, 0x9e, 0xca, 0x9a, 0x2f, 0x8f, 0x85, 0x4e, 0x18, 0xb8, 
+       0xe9, 0xea, 0x68, 0xa6, 0x3a, 0xf9, 0xcd, 0x6f, 0x7e, 0xc3, 
+       0xee, 0x2c, 0xc6, 0x64, 0xe1, 0x65, 0xfa, 0xef, 0x7f, 0xff, 
+       0xfb, 0x2c, 0x1, 0x71, 0x2e, 0x19, 0x93, 0x17, 0x41, 0xa8, 
+       0x59, 0xd7, 0xe6, 0x7c, 0xb5, 0xb1, 0x1a, 0xcd, 0x7c, 0x27, 
+       0x4f, 0x3d, 0xf5, 0x54, 0x46, 0x63, 0xd2, 0x4f, 0x68, 0x27, 
+       0x5a, 0xb9, 0xce, 0x54, 0x9b, 0xa5, 0x7b, 0x1, 0x38, 0xe3, 
+       0x24, 0xb7, 0x78, 0xb4, 0xb2, 0x68, 0x6e, 0xc, 0x92, 0x8d, 
+       0xe5, 0x1a, 0xbb, 0xc6, 0xda, 0x5f, 0x79, 0xe5, 0x95, 0x3f, 
+       0xd1, 0x33, 0x1f, 0xd4, 0x98, 0xf0, 0x93, 0xda, 0x38, 0x83, 
+       0x16, 0xd7, 0x8b, 0x36, 0x41, 0x76, 0x15, 0x65, 0xfc, 0x6, 
+       0xe1, 0xc3, 0x18, 0xd0, 0xb8, 0x49, 0x8f, 0x70, 0x87, 0x41, 
+       0xd, 0x56, 0x53, 0x80, 0x8b, 0x1b, 0x90, 0xdb, 0xd, 0xe8, 
+       0x63, 0x40, 0xdb, 0x4d, 0x38, 0x71, 0x99, 0x5c, 0x2b, 0x2d, 
+       0xed, 0xd6, 0x39, 0x69, 0xdd, 0xc9, 0xe1, 0x43, 0xbb, 0x4, 
+       0x82, 0xc2, 0xa4, 0x6e, 0xc1, 0x92, 0x64, 0xb0, 0x50, 0xd, 
+       0x4c, 0x16, 0xdc, 0x34, 0xc, 0x87, 0x3a, 0x76, 0x86, 0x12, 
+       0x7, 0x70, 0xaa, 0xf8, 0xe4, 0xa7, 0xa6, 0x76, 0x59, 0xb2, 
+       0x68, 0xf1, 0xea, 0x2, 0x81, 0x9b, 0x2c, 0x26, 0x6d, 0xbb, 
+       0xdf, 0x28, 0x5c, 0xb6, 0xfc, 0xde, 0xa4, 0xbd, 0x7d, 0x87, 
+       0x7c, 0x69, 0x3, 0xb0, 0x70, 0x51, 0x6b, 0x78, 0xe, 0xd7, 
+       0x1, 0x58, 0x38, 0xd0, 0x87, 0xab, 0x1a, 0x26, 0x9e, 0x3a, 
+       0xd9, 0x9e, 0x9c, 0x3e, 0xd5, 0x9e, 0x14, 0x67, 0x2e, 0x24, 
+       0x8b, 0xea, 0x6b, 0x12, 0xf1, 0x7f, 0x4, 0x10, 0xd, 0x48, 
+       0x68, 0xae, 0x35, 0x98, 0x1d, 0x27, 0xd7, 0xef, 0x70, 0x78, 
+       0x86, 0xc5, 0x8f, 0x31, 0x6f, 0xc9, 0xbf, 0x6d, 0xb8, 0x70, 
+       0x3, 0x3f, 0xd6, 0xd6, 0x7a, 0x41, 0x69, 0x40, 0x3d, 0x9b, 
+       0x97, 0xf4, 0x35, 0x91, 0x37, 0x94, 0xc, 00, 0xe6, 0x50, 
+       0x5, 0x80, 0x8d, 0x92, 0xb0, 0xd6, 0x36, 0xb0, 0x3d, 0xee, 
+       0x46, 0x91, 0x7c, 0xae, 0x62, 0x79, 0x45, 0xab, 0x6c, 0xd5, 
+       0x8a, 0xdf, 0x5f, 0xb1, 0x67, 0x76, 0x5d, 0xd9, 0x65, 0xb6, 
+       0x94, 0xa6, 0x5f, 0x7, 0xb9, 0xd2, 0xd, 0xd7, 0x90, 0x1a, 
+       0x4d, 0x2d, 0x18, 0x5e, 0xe9, 0x8a, 0x23, 0x5e, 0x41, 0x63, 
+       0xe3, 0xc8, 0x1a, 0xdd, 0x9b, 0x5c, 0x3a, 0x75, 0xa9, 0x74, 
+       0xef, 0xcf, 0xf7, 0x35, 0x9d, 0x3b, 0x7c, 0xae, 0x7c, 0xde, 
+       0xd2, 0x8a, 0xee, 0xc3, 0xaf, 0x1c, 0x59, 0x7c, 0xfe, 0xe8, 
+       0x85, 0xb2, 0xa6, 0x87, 0x9a, 0x3a, 00, 0x78, 0xef, 0x85, 
+       0x5e, 0x1a, 0x8d, 0xa4, 0x74, 0x76, 0x69, 0xaf, 0xc6, 0xf7, 
+       0x7c, 0x8c, 0x20, 0xbc, 0x15, 0x36, 0x5e, 0x78, 0x4f, 0x8, 
+       0xb8, 0xa5, 0x11, 0x93, 0x1f, 0xfd, 0xe8, 0x47, 0xec, 0x34, 
+       0x4a, 0xf4, 0xfe, 0x74, 0xb0, 0x9a, 0xcc, 0x4a, 0x3e, 0xff, 
+       0xf9, 0xcf, 0xf3, 0x59, 0xdd, 0x44, 0x1f, 0x1b, 0x8, 0x54, 
+       00, 0xb, 0x13, 0x19, 0x54, 0xd8, 0x78, 0xc0, 0xd, 0x5f, 
+       0x38, 0xb8, 0x4f, 00, 0x67, 0xd2, 0x69, 0x83, 0x34, 0xc7, 
+       0x5c, 0x1d, 0xb8, 0x58, 0xa6, 0x49, 0x10, 0x3e, 0xb2, 0xd6, 
+       0x21, 0xb, 0xb0, 0xdd, 0x3d, 0x97, 0xf3, 0xa, 0xb0, 0xb3, 
+       0xe1, 0xb4, 0x88, 0xfd, 0x9a, 0x4d, 0xff, 0x95, 0xf2, 0xb5, 
+       0x5b, 0x40, 0xf8, 0x82, 0xdc, 0xd5, 0xd2, 0xe2, 0xbc, 0xfb, 
+       0x4d, 0xfc, 0x1b, 0x36, 0x16, 0x44, 0x84, 0xc8, 0x6e, 0x28, 
+       0xa0, 0x44, 0x58, 0xa1, 0xf8, 0x53, 0x4d, 0x78, 0x5, 0xec, 
+       0xb9, 0xe0, 0xe6, 0xba, 0xc1, 0x6c, 0x70, 0x73, 0xaf, 0xdd, 
+       0x6c, 0xce, 0x41, 0x8b, 0x1f, 0x3e, 0x72, 0x5c, 0x20, 0x4e, 
+       0x1, 0xbe, 0x60, 0xc1, 0xb2, 0x61, 0xcd, 0xdd, 0x7b, 0xf9, 
+       0x52, 0xf2, 0x93, 0xe7, 0x9e, 0x19, 0x51, 0x8e, 0x4c, 0xa6, 
+       0x38, 0x79, 0xea, 0x9f, 0x3d, 0xa3, 0x86, 0x60, 0xa9, 0xd6, 
+       0xd9, 0x2b, 0x35, 0x79, 0x77, 0x32, 0x39, 0xda, 0xb9, 0x3b, 
+       0x59, 0xd9, 0xba, 0x29, 0x39, 0x71, 0x7c, 0x5f, 0x88, 0x5b, 
+       0x55, 0xdd, 0xa8, 0xf, 0xb, 0xce, 0x47, 0x8, 0xa5, 0xf4, 
+       0x25, 0x51, 0x81, 0xa6, 0xa0, 0xef, 0x3e, 0xde, 0x9e, 0x9c, 
+       0xea, 0x3e, 0x90, 0x94, 0x16, 0x5f, 0x48, 0x1a, 0x1b, 0xeb, 
+       0x13, 0xf6, 0xf, 0x50, 0x26, 0xea, 0x8f, 0x32, 0x19, 0x9c, 
+       0xd0, 0x5c, 0x77, 0xae, 0x3f, 0x8e, 0x6f, 0xb7, 0xd3, 0xc1, 
+       0x6f, 0x10, 0x43, 0x31, 0xf6, 0x7, 0xcf, 0xd, 0xfe, 0xe4, 
+       0xd1, 0xd6, 0xdd, 0x4a, 0x2a, 0x6, 0x36, 0xa0, 0x36, 0xb0, 
+       0xe9, 0x8e, 0x63, 0x3d, 0xa9, 0x56, 0xab, 0x7c, 0x7d, 0xb6, 
+       0x6a, 0x4d, 0xd5, 0x4a, 0x69, 0xea, 0x99, 0xad, 0x9f, 0x5f, 
+       0xb5, 0xab, 0xb4, 0x4c, 0xe7, 0x75, 0x86, 0x59, 0x71, 0xb6, 
+       0x95, 0x66, 0x81, 0x2d, 0xad, 0xd, 0xf6, 0x74, 0x9f, 0xec, 
+       0xb5, 0x35, 0x76, 0xff, 0xe5, 0xfe, 0xc2, 0xd3, 0xfb, 0xce, 
+       0xcc, 0xde, 0xf3, 0x7c, 0xdb, 0xb2, 0xa2, 0x92, 0xa2, 0x81, 
+       0xbb, 0x9e, 0xfc, 0xd0, 0x5b, 0xd3, 0xca, 0xa7, 0x5d, 0xbe, 
+       0x74, 0xf2, 0xd2, 0xd1, 0x5d, 0x3f, 0xde, 0xd3, 0xbc, 0xf3, 
+       0x2f, 0xde, 0x6d, 0xa9, 0x5c, 0x55, 0x75, 0xe2, 0xf0, 0x4b, 
+       0x87, 0x17, 0x6b, 0xbe, 0xa3, 0xa8, 0x69, 0x4b, 0xe3, 0xbe, 
+       0xa6, 0x8f, 0x36, 0x76, 0xd2, 0x64, 0xc0, 0x23, 0xfd, 0xe8, 
+       0x31, 0x63, 0x37, 0x37, 0x5, 0x6e, 0x84, 0x4f, 0xdd, 0x64, 
+       0x4e, 0x27, 0xd, 0x82, 0xa9, 0xcf, 0xf1, 0x86, 0x17, 0x42, 
+       0x34, 0x1, 0xc6, 0xd8, 0x26, 0xd1, 0x7a, 0x73, 0x58, 0xda, 
+       0xe2, 0x4b, 0x95, 0x1a, 0x33, 0xf3, 0x6, 0x55, 0x58, 0x32, 
+       0x51, 0x37, 0x79, 0xec, 0x39, 0x8c, 0x62, 0xb2, 0xe9, 0xe3, 
+       0xc9, 0x27, 0x9f, 0xe4, 0x2b, 0x97, 0x4b, 0xb5, 0x8f, 0xfb, 
+       0xf, 0x35, 0x93, 0x3e, 0x4b, 0xcb, 0x17, 0xbf, 0x54, 0x94, 
+       0xdf, 0xca, 0x2, 0x6e, 0x40, 0x8c, 0x64, 0xa2, 0xb1, 0xa1, 
+       0x58, 0xc2, 0x7c, 0xad, 0x4f, 0x5a, 0xbc, 0xff, 0xd5, 0x57, 
+       0x5f, 0xfd, 0x53, 0x1d, 0xe4, 0xf0, 0x11, 0xe5, 0xe7, 0xa1, 
+       0x89, 0xd0, 0xe2, 0x4a, 0x7f, 0x58, 0x18, 0x1, 0x29, 0x6, 
+       0xe1, 0xc6, 0x6d, 0x1, 0x86, 0x57, 0x6, 0x38, 0xd7, 0xec, 
+       0x7, 0xbc, 0xee, 0xaa, 0xe3, 0x36, 0xa0, 0x89, 0x6b, 0x3f, 
+       0x61, 0x58, 0x3, 0xfc, 0x60, 0x7b, 0x67, 0xd2, 0xd1, 0xbe, 
+       0x33, 0xe1, 0x4, 0x96, 0x5, 0x1a, 0x83, 0xd3, 0x2d, 0x2f, 
+       0x2e, 0xc9, 0xb7, 0xbd, 0x35, 0x3d, 0x55, 0x85, 0x7b, 0x97, 
+       0x2d, 0xbf, 0x27, 0xd9, 0xfa, 0xbb, 0xe7, 0x93, 0xae, 0xa3, 
+       0x6d, 0x92, 0x91, 0x2, 0x6d, 0xff, 0xdc, 0x1d, 0xf2, 0xb9, 
+       0x74, 0x59, 0x98, 0xd7, 0x18, 0x1, 0x6e, 0x4a, 0x70, 0xfc, 
+       0xd8, 0x7e, 0xd, 0x5, 0xf6, 0x27, 0x33, 0xa6, 0xbd, 0xaf, 
+       0x86, 0xb8, 0x89, 0x59, 0xfc, 0x11, 0xc0, 0x46, 0xd8, 0xb0, 
+       0x6, 0xb1, 0xfd, 0x71, 0x58, 0xee, 0x35, 0xf3, 0xc2, 0x71, 
+       0xc8, 0x80, 0x41, 0x1c, 0xd3, 0x90, 0xb1, 0x9b, 0xf8, 0x81, 
+       0x77, 0x8c, 0xad, 0xd1, 0xd6, 0xfa, 0x32, 0xcd, 0xcb, 0x1a, 
+       0x5f, 0xb3, 0x94, 0xa, 0x70, 0xad, 0xad, 0x4d, 0x1, 0xb6, 
+       0xc3, 0xe9, 0xf5, 0x19, 0xd8, 0x77, 0x15, 0x4f, 0x2f, 0x7e, 
+       0x50, 0x13, 0x67, 0xcd, 0xea, 0x32, 0xf, 0xae, 0xfc, 0x83, 
+       0x95, 0xbb, 0x8a, 0x74, 0xfe, 0x94, 0xba, 0xe2, 0x1, 0xd4, 
+       0x41, 0x6b, 0x73, 0xce, 0xb8, 0xda, 0xed, 00, 0xf2, 0xb4, 
+       0xd7, 0xad, 0x16, 0x2a, 0xc, 0x63, 0x28, 0xa, 0xfc, 0x4c, 
+       0xfb, 0xd5, 0x4a, 0x14, 0xd3, 0xf3, 0x5e, 0x4f, 0xe6, 0xc8, 
+       0x6b, 0x9d, 0xd5, 0x1d, 0x2f, 0xb6, 0x37, 0x56, 0xb6, 0xcc, 
+       0x3f, 0xde, 0xf2, 0xc8, 0x8a, 0x3, 0x67, 0x3a, 0xce, 0x96, 
+       0xb5, 0xbf, 0x74, 0x68, 0xc1, 0xc2, 0xbb, 0xeb, 0x8e, 0x7d, 
+       0xe8, 0x9f, 0xac, 0xdf, 0xde, 0xf6, 0xb3, 0xb6, 0x86, 0x3, 
+       0x7f, 0x7d, 0x60, 0x59, 0x5f, 0x4f, 0x5f, 0x89, 0xce, 0x54, 
+       0x2b, 0xbc, 0x78, 0xe2, 0xd2, 0x4c, 0x7a, 0x51, 0xa4, 0xc7, 
+       0xbc, 0xca, 0x78, 0xcd, 0xd, 0x83, 0x9b, 0x75, 0x4d, 0xc6, 
+       0xd6, 0xfa, 0xe8, 0x59, 0xa2, 0x75, 0xda, 0x44, 0xe7, 0x8c, 
+       0xb3, 0x1c, 0x92, 0x3c, 0xf3, 0xcc, 0x33, 0x41, 0x4b, 0xb3, 
+       0xd4, 0x20, 0xed, 0x18, 0xbe, 0x78, 0xf8, 0xf8, 0xe3, 0x8f, 
+       0x27, 0x5f, 0xfb, 0xda, 0xd7, 0x2, 0xf0, 0x35, 0xb9, 0x15, 
+       0xbe, 0xe5, 0xcc, 0xfd, 0xec, 0xda, 0x1a, 0xaf, 0x61, 0x99, 
+       0x49, 0x2f, 0x9b, 0xd0, 0x3d, 0xac, 0x96, 0xb0, 0x7f, 0x41, 
+       0x43, 0x81, 0xa, 0xbd, 0x70, 0x50, 0xa7, 0x74, 0x7e, 0x2e, 
+       0x4b, 0x45, 0x1, 0xe4, 0x7c, 0xc0, 0x6, 0xe4, 0x9e, 0x1, 
+       0xed, 0x55, 0x6f, 0xe3, 0x5, 0xe5, 0x77, 0x17, 0x5a, 0x5c, 
+       0x5d, 0xb5, 0xaa, 0xcd, 0x9b, 0x37, 0x97, 0x4c, 0xc4, 0x71, 
+       0xc6, 0x16, 0x52, 0x4, 0xc, 0x13, 0x6a, 0x5a, 0x14, 0x81, 
+       0x6, 0x64, 0x31, 0xb0, 0xed, 0x37, 0xe8, 0xf1, 0x63, 0xed, 
+       0x8f, 0xc1, 0xed, 0xb0, 0xc6, 0xc6, 0xc6, 0xa0, 0xc1, 0xf7, 
+       0xee, 0x6d, 0x57, 0xd7, 0xfa, 0x5d, 0x9d, 0x7a, 0x9a, 0x9, 
+       0x93, 0x6c, 0x73, 0xe6, 0xcc, 0x4b, 0xfe, 0xf9, 0xd3, 0x7f, 
+       0x82, 0xfa, 0x55, 0x1a, 0x59, 0x2d, 0x2c, 0xa1, 0x80, 0x5f, 
+       0xa4, 0xb9, 0xaa, 0xf5, 0xbe, 00, 0xee, 0xfe, 0xfe, 0xde, 
+       0x64, 0xcf, 0xee, 0x97, 0x93, 0x4b, 0x17, 0xcf, 0x5, 0x81, 
+       0x59, 0xbe, 0xe2, 0xa, 0xb8, 0x19, 0xa7, 0x73, 0x70, 0x62, 
+       0x57, 0xd7, 0x3e, 0x69, 0xf6, 0xbd, 0xc9, 0xcc, 0xe9, 0x3d, 
+       0xc9, 0x8a, 0xe5, 0xcb, 0x12, 0xbd, 0x46, 0x1b, 0xca, 0x61, 
+       00, 0x53, 0xa6, 0x5c, 0x77, 0xc, 0xe4, 0xf8, 0x3a, 0xf1, 
+       0x62, 0x3f, 0xee, 0xd8, 0x9a, 0x47, 0x84, 0x4d, 0x84, 0xe1, 
+       0x55, 0x51, 0xd, 0xd, 0xf9, 0xac, 0x8f, 0xc7, 0xd6, 0x68, 
+       0x6b, 0xc0, 0x1c, 0x6b, 0x6c, 0x83, 0x1b, 0x79, 0xc1, 0x2, 
+       0x6a, 0xc6, 0xd9, 0x20, 0xe8, 0x33, 0x33, 0xe7, 0xcf, 0x5c, 
+       0x5f, 0xb5, 0xaa, 0xaa, 0xb9, 0x7e, 0xe3, 0x82, 0x13, 0x4d, 
+       0x1f, 0x5f, 0xd2, 0x5, 0x80, 0xd5, 0x9d, 0x2e, 0x4c, 0xfa, 
+       0x86, 0xb4, 0x96, 0x2d, 0x50, 0x87, 0xc9, 0x33, 0xa1, 0x8d, 
+       0x57, 0x39, 0xd3, 0x93, 0x54, 0x86, 0x27, 0xcf, 0x54, 0xe3, 
+       0x20, 0x7b, 0xb8, 0x34, 0xda, 0x63, 0xae, 0x6e, 0xf8, 0xc5, 
+       0x52, 0x69, 0xeb, 0xc6, 0x33, 0x1d, 0x67, 0x2a, 0x96, 0x7d, 
+       0xaa, 0xb9, 0x4d, 0x93, 0x72, 0xa7, 0x3b, 0x5e, 0x3a, 0x54, 
+       0x7b, 0xe0, 0x57, 0x7, 0x9a, 0xfb, 0x2e, 0xf7, 0x15, 0x77, 
+       0xef, 0xec, 0xae, 0x59, 0xf2, 0xb1, 0x25, 0xfb, 0x5a, 0x3e, 
+       0xdb, 0xd2, 0x3e, 0xb7, 0xbe, 0xfc, 0xbd, 0x83, 0xbf, 0x39, 
+       0xd8, 0x74, 0xf1, 0xe4, 0x45, 0x86, 0x9e, 0x52, 0x4d, 0xea, 
+       0xef, 0x17, 0x6b, 0xa2, 0x91, 0xb6, 0x22, 0x4, 0x8c, 0xfd, 
+       0xe7, 0x86, 0xc0, 0x2d, 0x30, 0x84, 0x6e, 0x38, 0x6b, 0xb0, 
+       0x74, 0xc3, 0x5, 0xc, 0xe, 0x9b, 0x4b, 0xd4, 0x55, 0xe6, 
+       0xb5, 0xbd, 0xa0, 0x89, 0x18, 0x27, 0x32, 0xd3, 0xaa, 0xb5, 
+       0x44, 0x9, 0x4b, 0x17, 0xaf, 0x77, 0x26, 0x4f, 0x3c, 0xf1, 
+       0x44, 0xa2, 0x83, 0x14, 0x60, 0x7e, 0xa2, 0x97, 0x44, 0x38, 
+       0x34, 0x31, 0x34, 0xc, 0x63, 0xcf, 0x6e, 0x1a, 0x13, 0x81, 
+       0xe1, 0x83, 0x83, 0x4a, 0x6b, 0x86, 0x1a, 0x88, 0x87, 0x1b, 
+       0x1a, 0x1a, 0x6a, 0x75, 0xe8, 0x5d, 0x85, 0x84, 0xf8, 0x27, 
+       0x8a, 0x71, 0x5c, 0x16, 0x64, 0x1, 0x66, 0x6b, 0x70, 0xdc, 
+       0x23, 0xc0, 0x8d, 0x5f, 0x5a, 0xbc, 0x57, 0x5a, 0xfc, 0xbf, 
+       0x69, 0x88, 0xf0, 0x80, 0xdc, 0x9f, 0xd0, 0xae, 0xb1, 0x42, 
+       0xcd, 0x7, 0x70, 0x9a, 0x8b, 0x2e, 0xdf, 0x9c, 0xb1, 00, 
+       0x93, 0x8a, 0x81, 0xe, 00, 0x30, 0x5c, 0x23, 0xcc, 0x40, 
+       0x27, 0x2c, 0x6, 0x75, 0xec, 0x36, 0xa8, 0xe3, 0x30, 0xe6, 
+       0x34, 00, 0xed, 0xee, 0xdd, 0xfb, 0x93, 0x83, 0x7, 0xb6, 
+       0xb, 0x68, 0x45, 0x1a, 0x57, 0xaf, 0x8, 0xcb, 0x61, 0x8c, 
+       0xe9, 0x98, 0x64, 0xe3, 0x2f, 0xbd, 0x27, 0x4d, 0xbb, 0xb6, 
+       0xae, 0x31, 0x99, 0x5f, 0xb5, 0x48, 0x13, 0x63, 0x87, 0x92, 
+       0xdf, 0xbd, 0xf6, 0x53, 0x1e, 0x99, 0xd4, 0x2f, 0x6a, 0x51, 
+       0x2f, 0xa8, 0x82, 0xf6, 0x40, 0xf9, 0x49, 0x1b, 0x84, 0xa3, 
+       0x47, 0xda, 0x92, 0x63, 0x47, 0xf7, 0x24, 0xb3, 0xa6, 0x5f, 
+       0xd6, 0x5b, 0x7b, 0x2b, 0x2, 0xb0, 0x63, 0x80, 0x72, 0x5f, 
+       0x2e, 0xb0, 0x29, 0x4f, 0xbe, 0x30, 0x87, 0x9b, 0x17, 0x50, 
+       0x4c, 0xae, 0x3f, 0x4, 0xde, 0xe4, 0xf, 0x1b, 0x67, 0x54, 
+       0x97, 0xfd, 0xd2, 0xd4, 0x83, 0xda, 0xea, 0xca, 0xd8, 0x7a, 
+       0xab, 0x92, 0x4, 0xc4, 0x80, 0xd7, 0x60, 0x36, 0x35, 0xa8, 
+       0xd1, 0xd6, 0x80, 0x9a, 0x46, 0x9f, 0x95, 0x98, 0xdf, 0xab, 
+       0x5c, 0x5e, 0xb9, 0xb2, 0x62, 0x59, 0x45, 0x6d, 0xf3, 0xa7, 
+       0x96, 0x1d, 0xac, 0x5e, 0x55, 0xf5, 0x1e, 0x87, 0x2c, 0xa8, 
+       0xc9, 0xd5, 0x7, 0x3, 0x78, 0xf9, 0x23, 0x29, 0x3a, 0xf8, 
+       0x77, 0x1d, 0x75, 0x7b, 0xfe, 0x72, 0x4f, 0x8b, 0xe2, 0xc6, 
+       0x58, 0x1b, 0x76, 0x2f, 0xfd, 0xd8, 0x92, 0x3, 0x8b, 0xee, 
+       0x5b, 0x44, 0x83, 0x92, 0x30, 0x1b, 0x7e, 0x6a, 0xff, 0xe9, 
+       0xb2, 0x5d, 0x3f, 0xd9, 0xd5, 0xac, 0xba, 0x1e, 0xbc, 0xfb, 
+       0xa9, 0xbb, 0xb7, 0x31, 0xa6, 0xde, 0xf1, 0x83, 0x9d, 0xcd, 
+       0x5d, 0xef, 0x74, 0x2d, 0xcc, 0x14, 0x17, 0xd, 0x94, 0x4c, 
+       0x2b, 0xee, 0x1d, 0xe8, 0x19, 0x28, 0x6e, 0xfb, 0xcb, 0xb6, 
+       0x96, 0xf3, 0x5d, 0xe7, 0xcb, 0x56, 0x3c, 0xdc, 0x7c, 0x70, 
+       0x6e, 0xfd, 0xec, 0xed, 0x3b, 0x7f, 0xbc, 0x6b, 0xd9, 0x99, 
+       0x83, 0x67, 0xe6, 0x75, 0xb7, 0x9d, 0x9a, 0x33, 0x7f, 0x79, 
+       0xe5, 0xd9, 0xa2, 0x69, 0x82, 0x6a, 0x96, 0x7f, 0xa4, 0x3d, 
+       0x16, 0x33, 0x6e, 0x70, 0x6b, 0x39, 0x2a, 0xd1, 0x37, 0xba, 
+       0xc3, 0xc4, 0x18, 0x80, 0x55, 0xf7, 0x36, 0xd1, 0x9e, 0xee, 
+       0xd0, 0xed, 0x66, 0xe2, 0x8c, 0x71, 0xa1, 0xd, 0x15, 0x8e, 
+       0x70, 0xb2, 0xed, 0x92, 0x31, 0x38, 0xda, 0x5d, 0x7b, 0xbf, 
+       0x43, 0x17, 0x8f, 0xc9, 0x37, 0xd2, 0xf9, 0xd2, 0x97, 0xbe, 
+       0x94, 0x34, 0x36, 0x36, 0xfa, 0x96, 0x71, 0x51, 0xbe, 0x49, 
+       0xf6, 0xd5, 0xaf, 0x7e, 0xb5, 0x50, 0x1a, 0x77, 0xa3, 0xba, 
+       0xfe, 0x75, 0x5a, 0xd3, 0xae, 0x52, 0xcb, 0xfd, 0x63, 0x25, 
+       0xb2, 0x53, 0xd6, 00, 0x87, 0xa2, 0xcd, 0xb1, 0x80, 0xdd, 
+       0xcb, 0x66, 0x80, 0x3d, 0x74, 0xc3, 0xd4, 0xc3, 0x78, 0x41, 
+       0xcb, 0x22, 0x5b, 0xa5, 0xc9, 0xb7, 0x48, 0x38, 0xee, 0xd5, 
+       0x67, 0x68, 0x38, 0x6, 0x99, 0x3, 0x20, 0x14, 0xe5, 0xe6, 
+       0x8d, 0x85, 0x99, 0x94, 0xe0, 0x7, 0x7c, 0xb1, 0x31, 0x8f, 
+       0x4c, 0xb9, 0x6e, 0x40, 0x13, 0x27, 0x6, 0x75, 0xec, 0x37, 
+       0xc0, 0x77, 0xbc, 0xbb, 0x27, 0x39, 0xb0, 0xff, 0x6d, 0xa5, 
+       0x59, 0x90, 0x2c, 0x6e, 0x58, 0x29, 0xe4, 0x29, 0x7d, 0xb4, 
+       0xb7, 0xa4, 0x31, 0x4d, 0x2b, 0x4d, 0x63, 0x40, 0xa0, 0x6f, 
+       0x5d, 0xfd, 0x40, 0xf2, 0xeb, 0x5f, 0x7d, 0x4f, 0xf3, 0x1e, 
+       0xc8, 0xb8, 0x36, 0x46, 0xaf, 0xba, 0x2f, 0xcc, 0x6e, 0xd3, 
+       0x83, 0xa4, 0x6b, 0x7f, 0xe4, 0xc8, 0xee, 0x30, 0x26, 0x9f, 
+       0x35, 0xb3, 0x37, 0x59, 0xb3, 0x7a, 0x55, 0xd8, 0x3, 0xef, 
+       0xbc, 0xba, 0xc, 0x50, 0xc2, 0xae, 0xe7, 0x27, 0xfd, 0x38, 
+       0x4e, 0xec, 0xc7, 0x3d, 0x51, 0x6, 0x5, 0x22, 0xf9, 0x1a, 
+       0xd0, 0x7c, 0xcf, 0x90, 0xe4, 0x6f, 0x9b, 0x7a, 0x64, 0xaf, 
+       0xaa, 0x37, 0xc6, 0x24, 0x99, 0x41, 0x4d, 0x61, 0x9d, 0xa9, 
+       0xd8, 0xd0, 00, 00, 0x16, 0x5a, 0x49, 0x44, 0x41, 0x54, 
+       0xd1, 0xda, 0xd6, 0xdc, 0xf8, 0x63, 0x6d, 0x8d, 0x1c, 0xf0, 
+       0x56, 0xd7, 0xc7, 0x6b, 0xd7, 0xd5, 0xb6, 0x94, 0x37, 0x95, 
+       0x17, 0xb7, 0xfe, 0x41, 0xeb, 0xce, 0x99, 0x15, 0x33, 0xfb, 
+       0x83, 0x96, 0xe, 0x5a, 0x3b, 0xab, 0xb1, 0xb5, 0xcc, 0x75, 
+       0xe1, 0xd8, 0x85, 0xb2, 0x53, 0x6d, 0xa7, 0x16, 0xea, 0x9e, 
+       0xbc, 0xa6, 0x76, 0x6d, 0xed, 0x31, 0xba, 0xd0, 0x7d, 0x97, 
+       0xfa, 0x8a, 0xda, 0x5f, 0xea, 0xa8, 0x39, 0xf8, 0xb7, 0x7, 
+       0x1b, 0x35, 0xcb, 0x7e, 0xa2, 0xf5, 0xf1, 0xd6, 0xfd, 0x67, 
+       0x3b, 0xce, 0xce, 0xdc, 0xf6, 0x9d, 0xdf, 0xb6, 0xa, 0xc4, 
+       0x73, 0x8b, 0x4b, 0x8b, 0x91, 0xc3, 0x60, 0x14, 0x1d, 0x19, 
+       0x4d, 0x8e, 0x6e, 0x3d, 0x5a, 0x7f, 0xb1, 0xfb, 0xe2, 0xcc, 
+       0x95, 0x9f, 0x5b, 0xb9, 0xf7, 0xee, 0x7f, 0xba, 0x71, 0xfb, 
+       0xae, 0xe7, 0x76, 0x35, 0xee, 0xf8, 0x8b, 0x1d, 0xad, 0x8d, 
+       0x9b, 0x1b, 0xf7, 0x2f, 0xfd, 0xd8, 0xd2, 0xc3, 0x69, 0xec, 
+       0xb1, 0xff, 0x8e, 0x1b, 0xdc, 0x8c, 0x97, 0x39, 0x71, 0x84, 
+       0xae, 0x36, 0xc2, 0x43, 0x37, 0x1c, 0x4d, 0xcc, 0xcb, 0x12, 
+       0xf9, 0xc0, 0x40, 0x5, 0x33, 0xa6, 0x14, 0x78, 0x82, 0xb6, 
+       0x16, 0x78, 0x92, 0x2f, 0x7e, 0xf1, 0x8b, 0x61, 0xec, 0xac, 
+       0x13, 0x28, 0xc3, 0x3e, 0xe4, 0xb1, 0x67, 0xf7, 0xea, 0x98, 
+       0x74, 0xa5, 0xbf, 0xfc, 0xe5, 0x2f, 0x27, 0xd2, 0xdc, 0xb, 
+       0xb5, 0xc4, 0xf5, 0xf, 0xd5, 0x68, 0x54, 0xa9, 0x9b, 0xfe, 
+       0x37, 0x8a, 0x89, 0xa5, 0x12, 0xd, 0x6a, 0x80, 0x8d, 0xa5, 
+       0x32, 0xb1, 0x6, 0x79, 00, 0xb8, 0xf2, 0xdf, 0xab, 0x5e, 
+       0xc7, 0x4f, 0xd4, 0xe3, 0x78, 0x85, 0x19, 0x75, 0x9, 0x4b, 
+       0xab, 0x66, 0xd4, 0xb, 0x34, 0xcb, 0x5f, 0xc4, 0x2c, 0xef, 
+       0x44, 0x19, 0xb, 0x3c, 0xe9, 0xc1, 0x3f, 0xfc, 0x50, 0x1b, 
+       0xc0, 0x8c, 0x49, 0x81, 0x99, 0x2, 0x1d, 0xbf, 0x41, 0x6e, 
+       0x37, 0x94, 0x46, 0x11, 0xde, 0x6e, 0xdf, 0xbe, 0x2b, 00, 
+       0x1c, 0xa1, 0x6a, 0x6a, 0x5c, 0xa5, 0x93, 0x8d, 0xaf, 0x6, 
+       0xb7, 0x4e, 0xca, 0x4e, 0x56, 0xaf, 0xf9, 0x48, 00, 0x37, 
+       0xf7, 0xb2, 0x19, 0x66, 0xa5, 0xc0, 0x1d, 0xc6, 0xfb, 0x7a, 
+       0x3c, 0x33, 0xed, 0x9d, 0x87, 0x77, 0x26, 0x65, 0x33, 0x2f, 
+       0x27, 0xeb, 0xd6, 0xad, 0xe, 0x3d, 0x2c, 0xe2, 0xc5, 0xf9, 
+       0xcd, 0x5, 0x35, 0xd7, 0x1d, 0x96, 0x1b, 0x97, 0xfb, 0x72, 
+       0xc3, 0x42, 0xc0, 0x4, 0xfd, 0x30, 0xf9, 0xa8, 0x7a, 0x1e, 
+       0x64, 0x6c, 0xad, 0x89, 0xb3, 0x36, 0xf5, 0x22, 0x5f, 0x14, 
+       0xd0, 0x99, 0xcc, 0x89, 0x41, 0x8d, 0x3b, 0x6, 0x36, 0x9a, 
+       0x3a, 0x1e, 0x5b, 0x53, 0xb1, 0x9f, 0xa6, 0x1b, 0x5e, 0xbd, 
+       0xba, 0x7a, 0x69, 0x4d, 0x6b, 0xcd, 0x7b, 0x2d, 0x8f, 0xb4, 
+       0xec, 0xcf, 0x14, 0x6b, 0xb2, 0x3a, 0xcc, 0x88, 0x73, 0x98, 
+       0x61, 0x76, 0xf2, 0x2c, 0x5d, 0xee, 0x2a, 0xac, 0x5b, 0x5f, 
+       0x77, 0x4a, 0x1d, 0x64, 0xc6, 0xf0, 0xf4, 0x8e, 0xa, 0x34, 
+       0xb3, 0x5d, 0x22, 0x4d, 0xde, 0x1a, 0x3e, 0x5, 0xa4, 0xa0, 
+       0xd9, 0xb5, 0xb3, 0x2f, 0xc2, 0x93, 0xce, 0x37, 0x3b, 0x2b, 
+       0x1, 0x76, 0xf3, 0x27, 0x9b, 0xf7, 0x2e, 0xdc, 0xb8, 0xf0, 
+       0x64, 0xc7, 0xcb, 0x1d, 0xd5, 0x6d, 0xbf, 0x68, 0x6b, 0xd6, 
+       0x78, 0xba, 0x38, 0x6, 0x36, 0xe9, 0xd8, 0xe8, 0x8, 0xe4, 
+       0xc1, 0x73, 0x87, 0xce, 0xcd, 0xdb, 0xf6, 0xec, 0xb6, 0xb5, 
+       0xcd, 0x9f, 0x6a, 0xde, 0xbb, 0xe6, 0xb, 0x6b, 0xf6, 0x1d, 
+       0x7a, 0xe5, 0xd0, 0xb9, 0xfd, 0xbf, 0xde, 0xdf, 0x34, 0x63, 
+       0xde, 0x8c, 0x4b, 0xe3, 0xed, 0x98, 0x8f, 0x5b, 0x6a, 0xd1, 
+       0x96, 0xd2, 0x6c, 0x61, 0xad, 0xf3, 0x5b, 0xdf, 0xfa, 0x16, 
+       0x3b, 0x7d, 0xc2, 0x44, 0xf, 0xdd, 0x44, 0x1b, 0xb, 0x68, 
+       0x2c, 0x18, 0x8, 0x11, 0x5d, 0x27, 0xb4, 0x3c, 0x42, 0xc9, 
+       0xc4, 0x18, 0x63, 0x39, 0xc2, 0x6f, 0xd6, 0x90, 0x6, 0x5d, 
+       0x7c, 0x6d, 0x98, 0x99, 0xa9, 0x2e, 0xf5, 0x23, 0xca, 0x63, 
+       0x83, 0x5e, 0x1, 0x5d, 0xac, 0x71, 0x3f, 0xfd, 0xcf, 0xe, 
+       0x59, 0x83, 0xda, 0x1a, 0xfc, 0x2a, 0x70, 0x2b, 0x4e, 0x18, 
+       0x77, 0x69, 0x97, 0xd8, 0x65, 0x6d, 0x72, 0xf8, 0x73, 0x75, 
+       0xf7, 0x6b, 0xe5, 0xfe, 0x8c, 0x4, 0xa8, 0x51, 0x9b, 0x69, 
+       0x8a, 0xd0, 0xe6, 0x16, 0xd8, 0x9b, 0xcd, 0xaf, 0xef, 0x77, 
+       0x7a, 0xa6, 00, 0x1a, 0xc1, 0x88, 0x8d, 0x79, 0x19, 0x87, 
+       0x3b, 0x8c, 0x78, 0xf0, 0x92, 0xc6, 0xe7, 0xad, 0xb7, 0xdf, 
+       0x4d, 0xe, 0xec, 0x7b, 0x4b, 0x53, 0xb7, 0xd2, 0xe0, 0x8d, 
+       0xad, 0xe1, 0xc4, 0xbd, 0xb4, 0x81, 0x30, 0x40, 0xb, 0x93, 
+       0xca, 0xf9, 0x75, 0xc9, 0x9c, 0xb9, 0xf3, 0x93, 0x73, 0x67, 
+       0xbb, 0x93, 0xe5, 0x2b, 0xee, 0xd1, 0xca, 0x83, 0x56, 0x7a, 
+       0x4, 0xec, 0xc3, 0x9a, 0x9c, 0x3b, 0x7c, 0xe8, 0xdd, 0x4, 
+       0x8d, 0xfd, 0xa1, 0xf5, 0x6b, 0xc3, 0xdc, 0x88, 0xf3, 0x14, 
+       0x53, 0xdc, 0xb1, 0x9f, 0xe7, 0xe7, 0xf3, 0x3b, 0x8c, 0xeb, 
+       0x13, 0x6d, 0x28, 0x93, 0x80, 0xcc, 0x69, 0x29, 0x7c, 0xdb, 
+       0xed, 0xb0, 0x7a, 0x92, 0x7f, 0xab, 0x89, 0x51, 0x86, 0x62, 
+       0x80, 0x16, 0x30, 0xc7, 0xe0, 0xb6, 0xd6, 0xf6, 0xb5, 0xd0, 
+       0x90, 0x2b, 0xe, 0xd, 0xfb, 0xc2, 0xc2, 0x4c, 0xe1, 0xa7, 
+       0xaa, 0x5b, 0xaa, 0x57, 0x94, 0x37, 0x94, 0xcf, 0x6f, 0xfa, 
+       0x68, 0x53, 0x47, 0xfd, 0xc6, 0xfa, 0x33, 0x80, 0x94, 0xae, 
+       0xb8, 0x36, 0xa7, 0x4, 0x60, 0x3, 0xee, 0x2c, 0xc0, 0x99, 
+       0x3c, 0x2b, 0xac, 0x6c, 0xaa, 0xbc, 0x54, 0xd1, 0x58, 0xd1, 
+       0xa1, 0x7c, 0x14, 0xf4, 0xf7, 0xf6, 0x17, 0xfe, 0xd5, 0x1f, 
+       0xff, 0xd5, 0x3, 0x59, 0x60, 0x27, 0x2b, 0x1e, 0x5e, 0xb1, 
+       0x7d, 0xf1, 0x87, 0x17, 0x9f, 0x54, 0xda, 0x49, 0xe5, 0x92, 
+       0xca, 0xf7, 0x2a, 0xbe, 0x56, 0xf1, 0xe6, 0xdc, 0x45, 0x73, 
+       0x2f, 0xed, 0xfa, 0xe9, 0xae, 0xfa, 0x5d, 0xcf, 0xef, 0x6a, 
+       0x51, 0xa3, 0x31, 0x20, 0x8b, 0xec, 0x61, 0x86, 0xbb, 0xf2, 
+       0xa9, 0x37, 0xd5, 0xde, 00, 0xfc, 0xf2, 0xf9, 0xcb, 0xd3, 
+       0x76, 0xfc, 0xbf, 0x1d, 0xad, 0x6a, 0x60, 0xde, 0x6d, 0xfe, 
+       0x44, 0x73, 0x67, 0x65, 0x73, 0xe5, 0xd9, 0x92, 0x19, 0x25, 
+       0xbd, 0xba, 0x63, 0x5c, 0x5d, 0xc9, 0x71, 0x83, 0x3b, 0x5e, 
+       0x3a, 0xe2, 0x2c, 0x6f, 0xc6, 0x8d, 0x1e, 0x4b, 0x92, 0x49, 
+       0x98, 0x4f, 0x1c, 0x84, 0x11, 0x6d, 0xe, 0xa0, 0x5d, 0xd9, 
+       0xc4, 0x63, 0xa2, 0x8d, 0xee, 0x3b, 0x66, 0xa2, 0xf, 0x16, 
+       0x54, 0x57, 0x1a, 0x80, 0x17, 0x6a, 0x66, 0x7e, 0x9d, 0xc6, 
+       0xcf, 0xd, 0x1a, 0xef, 0x37, 0x4a, 0x1b, 0x3, 0xf0, 0x97, 
+       0x65, 0xa9, 0x58, 0x54, 0x24, 0x36, 0xd6, 0xde, 0x54, 0x34, 
+       0xe3, 0xae, 0xd8, 0xf6, 0x4a, 0x7b, 0x73, 0x1a, 0xc7, 0x9f, 
+       0x69, 0xe2, 0xae, 0x51, 0x1a, 0xe1, 0xf7, 0x4, 0xf8, 0x4a, 
+       0xad, 0xdd, 0xf3, 0x95, 0xd0, 0x11, 0xe5, 0xd5, 0x7d, 0x13, 
+       0x66, 0xe0, 0x93, 0x79, 0xe5, 0x44, 0xf1, 0xc3, 0xd3, 0xd8, 
+       0xc0, 0x47, 0x3, 0x1c, 0xb7, 0x1, 0xbe, 0x6d, 0xdb, 0x76, 
+       0x4d, 0x62, 0xbe, 0x15, 0xc6, 0xd0, 0x4d, 0x4b, 0x57, 0x67, 
+       0xb5, 0x7f, 0xa, 0xc0, 0x53, 0x27, 0x8f, 0xe8, 0xc4, 0x93, 
+       0x77, 0x2, 0xb0, 0x49, 0x6b, 0xc3, 0xdd, 0xf, 0x85, 0x72, 
+       0x74, 0x1c, 0x14, 0xb0, 0x3b, 0x76, 0x24, 0x65, 0xb3, 0x7a, 
+       0x93, 0xbb, 0x3e, 0xb4, 0x6e, 0xc4, 0x8e, 0xc2, 0x38, 0x2f, 
+       0x76, 0x9b, 0x92, 0x86, 0xdd, 0xa6, 0x84, 0xdd, 0x2a, 0xc3, 
+       0xe4, 0x22, 0x73, 0x3d, 0xfa, 0x52, 0x48, 0x9f, 0xea, 0xe6, 
+       0xb4, 0x7a, 0x56, 0x2f, 0x68, 0x8, 0x46, 0x57, 0x95, 0x7a, 
+       0x3, 0xbc, 0xee, 0x6e, 0x43, 0x6d, 0xd, 0x76, 0x6b, 0x6b, 
+       0x1a, 0x77, 0x98, 0xb9, 0x69, 0x46, 0xe5, 0x8c, 0xfb, 0x6b, 
+       0x5b, 0x6b, 0x97, 0x8, 0xd8, 0xfd, 0xab, 0x1f, 0x5b, 0xbd, 
+       0x43, 0x9a, 0xb1, 0x5f, 0x3c, 0x2d, 0x1c, 0x62, 0xd2, 0x2c, 
+       0xb, 0x6c, 0xf5, 0xf9, 0x34, 0x69, 0xa6, 0xf6, 0x32, 0xfb, 
+       0x3e, 0x76, 00, 0x31, 0x9d, 0x2d, 0x70, 0x29, 0xfa, 0xe2, 
+       0x7f, 0x79, 0xf1, 0x2e, 0x75, 0xb5, 0xe7, 0x2b, 0xbd, 0x64, 
+       0xf1, 0x7d, 0x8b, 0xf7, 0xdd, 0xf5, 0xc4, 0x5d, 0xfb, 0x71, 
+       0x63, 0xca, 0x17, 0x96, 0xf3, 0xec, 0x60, 0xce, 0x1e, 0x3a, 
+       0x3b, 0x87, 0x7d, 0x6b, 0xb2, 0x69, 0xb7, 0x2c, 0x5, 0xf6, 
+       0xc8, 0x4a, 0x8d, 0xc2, 0x88, 0xa7, 0xcd, 0x44, 0x19, 0xad, 
+       0x83, 0xcf, 0xd6, 0xb3, 0x3a, 0x2b, 0x1b, 0x2b, 0x2f, 0xaa, 
+       0x21, 0x72, 0xa3, 0xe0, 0x64, 0xaf, 0x4b, 0xc7, 0xd, 0xee, 
+       0x38, 0x45, 0x4, 0x2b, 0xae, 0x58, 0xba, 0x4a, 0xf7, 0xdc, 
+       0x73, 0x4f, 0xb2, 0x65, 0xcb, 0x96, 0x30, 0xe1, 0xc3, 0xd2, 
+       0x17, 0x9a, 0x9a, 0x2e, 0x39, 0x71, 0x31, 0xc4, 0x8f, 0xb5, 
+       0x50, 0x9c, 0xde, 0x44, 0xb8, 0xd9, 0x64, 0xc1, 0x38, 0x5e, 
+       0xeb, 0xeb, 0x73, 0xa5, 0x7d, 0x1f, 0xd3, 0x6e, 0xa4, 0x25, 
+       0xea, 0x5d, 0x2c, 0x15, 0x40, 0x19, 0x8b, 0x1f, 0x93, 0x5, 
+       0xcc, 0x54, 0x72, 0xac, 0xbd, 0xe3, 0x2e, 0xba, 0x41, 0x8e, 
+       0x40, 0x4c, 0xd7, 0x38, 0xbc, 0x47, 0xb6, 0x5d, 0xbd, 0x8c, 
+       0x95, 0x2a, 0xcf, 0x83, 0x5a, 0xab, 0xaf, 0xe1, 0x9c, 0x34, 
+       0x1d, 0x11, 0x55, 0xc4, 0xd2, 0xd4, 0xad, 0x36, 0xf0, 0x2b, 
+       0xe6, 0xb1, 0x9f, 0xe7, 0x30, 0x3, 0xbf, 0xa1, 0xa1, 0x21, 
+       0xf0, 0x78, 0xeb, 0xd6, 0xb7, 0xd5, 0x45, 0x7f, 0x4b, 0x2b, 
+       0xae, 0x5, 0x49, 0xd3, 0x92, 0xd5, 0x61, 0x2c, 0x4d, 0xdc, 
+       0xff, 0xfe, 0xcc, 0xd3, 0x6a, 0x58, 0x53, 0x79, 0xd3, 0xe, 
+       0xb7, 0x64, 0xe9, 0xb2, 0xf5, 0x2, 0xcb, 0x76, 0xad, 0x5c, 
+       0xbc, 0x23, 0x8d, 0x7d, 0x39, 0xd9, 0xb0, 0x61, 0xfd, 0x8, 
+       0x8d, 0xed, 0xe7, 0x40, 0xfd, 0x2c, 0xd3, 0xf8, 0xda, 0xad, 
+       0x76, 0xf3, 0xf2, 0x8c, 0xea, 0x70, 0x90, 0xf3, 0xd5, 0xa4, 
+       0x2c, 0xba, 0x35, 0xa6, 0x7e, 0x4d, 0x6f, 0xd4, 0xed, 0xd3, 
+       0x73, 0xa9, 0x1f, 0x5b, 0x3, 0x3b, 0xd6, 0xda, 0x5c, 0x23, 
+       0x9c, 0x46, 0x9d, 0xfa, 0xa5, 0xbe, 0x7, 0x24, 0x7b, 0x5f, 
+       0xa8, 0x5a, 0x59, 0xb5, 0x71, 0xee, 0xa2, 0xf2, 0xda, 0x86, 
+       0xf, 0x2f, 0xee, 0x5c, 0xfa, 0xf1, 0xe6, 0x63, 0xd2, 0xc8, 
+       0x45, 0xa1, 0x1b, 0xde, 0xaf, 0xf, 0xf2, 0xe9, 0xcd, 0x2e, 
+       0x7d, 0xc0, 0x47, 0x5a, 0x3a, 0x7c, 0x9c, 0x4f, 0xa3, 0x61, 
+       0x4e, 0x2c, 0x15, 0x3, 0x87, 0x6, 0xc5, 0x51, 0x2d, 0x69, 
+       0x7, 0x7d, 0x3b, 0x54, 0xf0, 0xfa, 0xff, 0x7c, 0xb5, 0x45, 
+       0x93, 0x62, 0x8b, 0x94, 0x66, 0x52, 0xd5, 0x52, 0xd5, 0xf9, 
+       0xc0, 0xd7, 0x37, 0x6d, 0xf7, 0xe6, 0x1f, 0xc2, 0x62, 0x53, 
+       0x98, 0x29, 0xe2, 0x93, 0x40, 0x2, 0xb3, 0x95, 0xb5, 0xfa, 
+       0xf8, 0xa5, 0x99, 0xfe, 0xd9, 0x35, 0x65, 0xe7, 0xf5, 0x9e, 
+       0xf6, 0x60, 0x7f, 0x4f, 0x5f, 0xe6, 0xc2, 0xf1, 0xb, 0xb3, 
+       0x95, 0x7, 0x75, 0xdb, 0x88, 0x17, 0x78, 0x3e, 0xa4, 0xbc, 
+       0xca, 0xb2, 0xa9, 0x8, 0xcc, 0x30, 0x63, 0x3e, 0xb2, 0x57, 
+       0x17, 0x3f, 0x23, 0x9f, 0xfb, 0xa6, 0xc0, 0x9d, 0x2f, 0x41, 
+       0x7d, 0xa0, 0x9c, 0x6f, 0x32, 0x5, 00, 0xb3, 0x6b, 0x8a, 
+       0xcf, 0xbe, 0xb0, 0xc9, 0xc5, 0xe0, 0xce, 0x77, 0xcf, 0x44, 
+       0x87, 0xf1, 0xac, 0xcd, 0x9b, 0x37, 0xb3, 0x51, 0x6, 0x2d, 
+       0xbe, 0x5e, 0xda, 0xbc, 0x41, 0x6b, 0xf1, 0xb5, 0x9a, 0x38, 
+       0xfb, 0x8f, 0x7a, 0x16, 0xc0, 0xa6, 0xb2, 0xe1, 0xb4, 0xdd, 
+       0x54, 0xbc, 0xbb, 0x6c, 0x8, 0x5, 00, 0x47, 0x50, 0x40, 
+       0x6f, 0x10, 0x20, 0xcd, 0xf8, 0xbf, 0x29, 0xbb, 0x53, 0xe3, 
+       0xfa, 0x3a, 0x8d, 0xf1, 0xee, 0xd7, 0xf7, 0xa2, 0x5a, 0x35, 
+       0x87, 0x37, 0xa4, 0xed, 0xb1, 0xc5, 0xac, 0x1, 0x4f, 0xb6, 
+       0x31, 0xd0, 0x4c, 0x79, 0x3e, 0x4b, 0x92, 0xf8, 0xb7, 0x6e, 
+       0x7d, 0x2b, 0xd9, 0xbf, 0x6f, 0x5b, 0xc8, 0x52, 0xd3, 0x92, 
+       0x35, 0x81, 0xce, 0x9b, 0x57, 0xa3, 0x6f, 0x88, 0xf5, 0xeb, 
+       0x90, 0x88, 0x85, 0xc9, 0x27, 0x3f, 0xfd, 0x64, 0x18, 0x63, 
+       0x1f, 0x2, 0xd8, 0x33, 0x7a, 0x5, 0xec, 0xd0, 0xe3, 0x9, 
+       0xf1, 0xa6, 0xca, 0xf, 0xaf, 0xc4, 0xaa, 0xb7, 0xd4, 0xa7, 
+       0x83, 0x33, 0x39, 0x57, 0xad, 0x8d, 0xb5, 0x6a, 0x69, 0x6c, 
+       0xba, 0xdf, 0xd6, 0xd4, 0x31, 0xb0, 0x1, 0xb1, 0xc1, 0xc, 
+       0xa5, 0xee, 0xa0, 0xc4, 0xa5, 0x6e, 0xb1, 0x80, 0x66, 0x68, 
+       0xce, 0xa2, 0x39, 0xab, 0xb4, 0xdc, 0x54, 0xb7, 0xf1, 0x4b, 
+       0xf7, 0xec, 0x98, 0xb7, 0x78, 0x5e, 0xcf, 0xa0, 0x36, 0x8b, 
+       0x68, 0x47, 0x9f, 0xba, 0xe1, 0xec, 0x13, 0x67, 0xe7, 0x19, 
+       0x4b, 0x5d, 0x3a, 0xe, 0x29, 0x5d, 0xc3, 0x6, 0xdc, 0xcc, 
+       0xa, 0x8b, 0xad, 0x62, 0x6c, 0x16, 0x9d, 0x3b, 0x9e, 0xdb, 
+       0xbe, 0x78, 0xef, 0xaf, 0xf6, 0x32, 0x63, 0x9e, 0xcc, 0x59, 
+       0x38, 0xf7, 0xd4, 0x96, 0x7f, 0xfb, 0xf1, 0x37, 0xae, 0x25, 
+       0xdf, 0x86, 0xb4, 0xa9, 0x26, 0x2f, 0xb, 0x9a, 0xee, 0x6b, 
+       0x3c, 0xd4, 0xf2, 0xc8, 0xaa, 0x43, 0xd2, 0xc8, 0x43, 0xbd, 
+       0x17, 0x7b, 0x8b, 0x5e, 0xff, 0x5f, 0xaf, 0xad, 0x3a, 0xb9, 
+       0xa7, 0x7b, 0x7e, 0x21, 0x47, 0x28, 0xe, 0x1b, 0x26, 0x2e, 
+       0xb3, 0x4b, 0x89, 0xe1, 0xf1, 0xc3, 0x17, 0xc6, 0xe4, 0x98, 
+       0x50, 0x70, 0x53, 0x7e, 0x4e, 0x19, 0x71, 0x41, 0x19, 0x87, 
+       0xeb, 0xb3, 0x3e, 0x61, 0x33, 0xc6, 0x98, 0x72, 0x33, 0xc1, 
+       0x91, 0x58, 0x76, 0xfb, 0xca, 0x57, 0xbe, 0x92, 0x7c, 0xf3, 
+       0x9b, 0xdf, 0x2c, 0x97, 0xe0, 0x2f, 0x11, 0xb8, 0x19, 0xe0, 
+       0xbb, 0x6b, 0x64, 0xed, 0xd, 0xcf, 0xdd, 0xb2, 0xc7, 0x1a, 
+       0x9c, 0xf1, 0x8d, 0x5, 0xc9, 0x40, 0x9f, 0x26, 0x60, 0xf7, 
+       0x48, 0xe8, 0x8e, 0xaa, 0x6c, 0xbf, 0x50, 0x9a, 0x77, 0x49, 
+       0xf8, 0x3e, 0xac, 0x5d, 0x73, 0x25, 0x2, 0x79, 0x9, 0x2b, 
+       0x7, 0x2e, 0xfb, 0x4, 0x17, 0x65, 0xcc, 0xc9, 0xf1, 0xa2, 
+       0xe, 0xf5, 0xf0, 0xc6, 0x1b, 0xdb, 0x92, 0x7d, 0x7b, 0xdf, 
+       0xc, 0x5d, 0xf3, 0xc6, 0xa6, 0xd5, 0xc9, 0xbf, 0xfc, 0xa3, 
+       0xff, 0x21, 0x77, 0x3a, 0x31, 0xc7, 0xf2, 0xd9, 0xc1, 0x83, 
+       0x6f, 0x6b, 0x1d, 0x3b, 0xd5, 0xd8, 0xdc, 0x33, 0x15, 0xc, 
+       0x5d, 0x6f, 0x14, 0x81, 0x36, 0x9f, 0xf4, 0x49, 0x63, 0xf7, 
+       0x8a, 0xb7, 0x5b, 0xa5, 0x1c, 0xb6, 0x4b, 0x49, 0x30, 0x29, 
+       0x66, 0xb0, 0x42, 0xb1, 0xb9, 0x80, 0x26, 0x2c, 0x6, 0xb5, 
+       0x81, 0x4d, 0x3d, 0x53, 0xe7, 0xc3, 0xe0, 0x14, 0x7b, 0xa, 
+       0x2a, 0x1b, 0x2a, 0x7a, 0x6, 0x58, 0xe6, 0xd2, 0x8b, 0x1f, 
+       0xa1, 0x1b, 0xce, 0xac, 0xb8, 0xad, 0xa6, 0x3e, 0xd4, 0x14, 
+       0x48, 0x5f, 0xfa, 0x9e, 0x80, 0xac, 00, 0xef, 0x83, 0x2f, 
+       0x1f, 0x98, 0xbf, 0xed, 0xcf, 0xb7, 0xad, 0x57, 0x7a, 0x49, 
+       0xe9, 0x9c, 0x69, 0x97, 0x3e, 0xf2, 0x2f, 0x36, 0x6d, 0x1d, 
+       0xb8, 0x3c, 0x50, 0xf4, 0xbe, 0x2c, 0x61, 0xc5, 0xa5, 0x99, 
+       0x81, 0xe2, 0xe9, 0x25, 0x96, 0x31, 0x82, 0x94, 0xa, 0x1a, 
+       0x57, 0x36, 0x8b, 0x6e, 0x25, 0x34, 0x34, 0x7f, 0x45, 0xf5, 
+       0x59, 0x6d, 0x3c, 0xa, 0x40, 0x9e, 0x5e, 0x36, 0x7d, 0x60, 
+       0x6e, 0xdd, 0x9c, 0xf3, 0x27, 0x76, 0x1d, 0xaf, 0x16, 0xd8, 
+       0xb3, 0xf7, 0xb2, 0x49, 0x88, 0x9, 0x4b, 0x65, 0x36, 0x58, 
+       0x3c, 0xd9, 0x4, 0x42, 0xa2, 0xd7, 0xff, 0xb9, 0x29, 0x70, 
+       0xbb, 0x4b, 0x18, 0x3f, 0x26, 0x37, 0xcc, 0x63, 0xc3, 0x6b, 
+       0xc5, 0x89, 0xaf, 0x4d, 0xb4, 0xdb, 0x13, 0x7d, 0xca, 0x17, 
+       0xcc, 0xe7, 0xb5, 0x51, 0x98, 0xe7, 0xa, 0x87, 0xb9, 0xf8, 
+       0xdd, 0xba, 0x5b, 0x7b, 0x3, 0x72, 0x84, 0xc3, 0x16, 0xa0, 
+       0x23, 0x3c, 0xd3, 0x65, 0x11, 0xa0, 0x69, 0xea, 0x22, 0xbe, 
+       0xaf, 0x4f, 0xdc, 0xbc, 0x20, 0x61, 0x7c, 0x45, 0x5b, 0x63, 
+       0x97, 0x6b, 0x15, 0xe1, 0x7e, 0xad, 0xb3, 0xd6, 0x32, 0xf1, 
+       0x26, 0x90, 0x17, 0xd1, 0xa8, 0xdd, 0x2e, 0xc3, 0x29, 0x2f, 
+       0x98, 0x37, 0xb6, 0x6e, 0xb, 0x1a, 0x9c, 0x65, 0x2e, 00, 
+       0x8e, 0x39, 0xb0, 0x7f, 0xbb, 0x5e, 0x40, 0x79, 0x2b, 0x6c, 
+       0x50, 0x41, 0x63, 0x3b, 0x6e, 0xb8, 0x78, 0x9b, 0x7e, 0x58, 
+       0x26, 0x15, 0x1f, 0x7, 0x98, 0x28, 0xd3, 0xf0, 0xe9, 0x84, 
+       00, 0xfd, 0x3b, 0xba, 0xde, 0x92, 0x1d, 0xea, 0x1, 0xbe, 
+       0x53, 0x2f, 0x6, 0x2e, 0x7e, 0x5b, 0xc2, 0x1c, 0xee, 0x86, 
+       0x98, 0xb8, 0xb8, 0xb9, 0x37, 0x6, 0x19, 0xb2, 0xe, 0x68, 
+       0xc1, 0xac, 0xbe, 0x9d, 0xc9, 0xc6, 0x94, 0xf4, 0xc5, 0xf, 
+       0x68, 0x34, 0x69, 0x86, 0xee, 0xcc, 0x7e, 0x9, 0x84, 0x21, 
+       0x91, 0x1, 0x9e, 0x42, 0x73, 0xe7, 0xf3, 0x3b, 0x97, 0x79, 
+       0x2, 0xed, 0xf2, 0xb9, 0x9e, 0x19, 0x3f, 0xfd, 0xd7, 0x3f, 
+       0x7d, 0x48, 0xe9, 0xe, 0x9b, 0xc6, 0xfb, 0x9b, 0xf6, 0x6d, 
+       0xfe, 0x57, 0x9b, 0xb7, 0xf, 0x7, 0x4, 0x7, 0xc3, 0xed, 
+       0x91, 0x21, 0xf4, 0x6, 00, 0xae, 0x8d, 0x16, 0x49, 0xd2, 
+       0x27, 0x65, 0x3, 0xd2, 0x4b, 0x3c, 0xff, 0x8a, 0xe6, 0xbe, 
+       0x12, 0xdb, 0x77, 0x5d, 0x9b, 0xde, 0x14, 0xb8, 0x59, 0x86, 
+       0xa2, 0xb5, 0x65, 0xac, 0x8d, 0xc1, 0x9d, 0xf, 0xdc, 0x5c, 
+       0x8f, 0xe3, 0xdc, 0x8e, 0xc3, 0xfb, 0x95, 0x2f, 0xca, 0xa, 
+       0x48, 0xc9, 0x2c, 0x2, 00, 0xaf, 0xc, 0x6a, 0x39, 0x87, 
+       0xdd, 0xd6, 0xe8, 0x4c, 0xff, 0x1b, 0xec, 0x8, 0xd0, 0x30, 
+       0xb0, 0x63, 0xb7, 0x4, 0xb0, 0x54, 0x1a, 0x66, 0x9b, 0xec, 
+       0x4e, 0x8d, 0xf1, 0xab, 0x25, 0xa8, 0x1b, 0x74, 0x4e, 0xd8, 
+       0x4a, 0x69, 0xf0, 0x69, 0x9a, 0x7c, 0x2b, 0xd4, 0xd0, 0xa0, 
+       0x88, 0x6e, 0x7b, 0x68, 0xf6, 0x75, 0xe3, 0x64, 0x19, 0x83, 
+       0x16, 0xd, 0x7e, 0x60, 0xff, 0xb6, 0x50, 0x2f, 0x68, 0x6e, 
+       0x80, 0xcd, 0x96, 0xd2, 0xdb, 0x9, 0x6c, 0x64, 0x84, 0x6e, 
+       0xb7, 0x7a, 0x52, 0x3, 0x9a, 0x24, 0x1b, 0x92, 0xdc, 0xf4, 
+       0xe8, 0x65, 0xad, 0x3d, 0x9a, 0x9b, 0x79, 0x47, 0xf3, 0x1a, 
+       0xcc, 0x36, 0x1b, 0xa0, 0x6, 0x76, 0xc, 0x66, 0xdc, 0x80, 
+       0x97, 0x3a, 0xc9, 0x5, 0xb4, 0xeb, 0xcb, 0xf5, 0x4a, 0xe3, 
+       0x9d, 0x55, 0x9b, 0xa1, 0x5b, 0x4e, 0x9d, 0x87, 0x53, 0x52, 
+       0xa, 0xd4, 0x1d, 0x2f, 0x90, 0xe6, 0x4e, 0xfa, 0x6, 0xf4, 
+       0xfd, 0x2e, 0x1d, 0xac, 0x80, 0x5b, 0x33, 0xe5, 0xda, 0x23, 
+       0x10, 0x3e, 0xa3, 0xcb, 0x87, 0xb3, 0x15, 0x97, 0xde, 0xe, 
+       0x33, 0x9a, 0x63, 0xc6, 0x15, 0x11, 0xd3, 0xd9, 0x25, 0xee, 
+       0x4e, 0x8d, 0xbe, 0xcd, 0x9b, 0x36, 0x32, 0xa1, 0x61, 0x9, 
+       0x61, 0x41, 0x97, 0xc7, 0xf1, 0xc8, 0x64, 0x3a, 0x70, 0x48, 
+       0x1b, 0x11, 0xbc, 0x2, 0x78, 0xd0, 0x48, 0xf9, 0xd2, 0xe4, 
+       0xfa, 0xf5, 0xcc, 0x4d, 0x81, 0x9b, 0x43, 0xd, 0xb5, 0x54, 
+       0xc4, 0xb7, 0xbf, 0xc2, 0x18, 0x1b, 0x70, 0xe7, 0xae, 0x75, 
+       0xd3, 00, 0xd0, 0x5d, 0x65, 0xf2, 0x89, 0x4a, 0xc5, 0xcf, 
+       0x5b, 0x61, 0x93, 0x6d, 0xf4, 0x6c, 0x78, 0x9, 0x40, 0x69, 
+       0xd1, 0xb1, 0x80, 0x18, 0x61, 0xb0, 0xf6, 0xc6, 0x6f, 0xeb, 
+       0x38, 0x50, 0xe2, 00, 0x74, 0x4, 0x9, 0xcd, 0x4f, 0x3, 
+       0x81, 0x60, 0x41, 0xed, 0xc7, 0x3d, 0x4d, 0x63, 0xc2, 0x8b, 
+       0x9a, 0xfc, 0x39, 0x2a, 0xf7, 0x2f, 0xb4, 0x62, 0x50, 0xa3, 
+       0xd5, 0x84, 0x55, 0xac, 0x97, 0xb, 0xe8, 0xb3, 0x18, 0xf, 
+       0xb, 0xe8, 0x19, 0xf6, 0xd9, 0xdf, 0xca, 0x9, 0x45, 0x3d, 
+       0x7b, 0xd8, 0x5c, 0x1, 0xf8, 0x9b, 0x1, 0xe0, 0x5c, 0xb8, 
+       0x5d, 0xc0, 0xa6, 0x7, 0xa7, 0x6, 0x10, 0x40, 0xf7, 0x33, 
+       0xf, 0x23, 0x59, 0xb9, 0xa8, 0x55, 0x93, 0x3d, 0x2, 0xf9, 
+       0x2e, 0xc9, 0x8f, 0x1, 0x6d, 0x50, 0x43, 0xd, 0xe2, 0x98, 
+       0xe2, 0xb6, 0x9f, 0xfa, 0x88, 0xe3, 0xbb, 0xce, 00, 0x36, 
+       0xf5, 0x8, 0xa0, 0xc, 0x4a, 0xea, 0x1e, 0x77, 0x46, 0xba, 
+       0x90, 0xb7, 0x1, 0xb5, 0x6b, 0x47, 0x33, 0x54, 0x61, 0x7f, 
+       0xb8, 0x8e, 0x4b, 0x11, 0xa6, 0x75, 0x51, 0xf8, 0xd2, 0xeb, 
+       0xf0, 0x1a, 0x64, 0xa7, 0xd6, 0xf7, 0xca, 0xef, 0x54, 0x94, 
+       0xc0, 0xe7, 0xfe, 0xd3, 0xe7, 0x5e, 0x15, 0x19, 0x97, 0xd1, 
+       0xd8, 0xfe, 0x7c, 0xd7, 0x8e, 0xae, 0xec, 0xa4, 0x5a, 0x7a, 
+       0x2b, 0x13, 0x64, 0x3a, 0xa9, 0x65, 0x38, 0x1d, 0xb2, 0xc4, 
+       0x4, 0x9a, 0x28, 0xf2, 0xa8, 0xf7, 0xf4, 0x8b, 0x6, 0xca, 
+       0xeb, 0xe7, 0x5d, 0x8, 0xf1, 0x94, 0xbb, 0xb0, 0xc7, 0x3c, 
+       0xce, 0xc8, 0xf0, 0x9d, 0xa3, 0x3b, 0x6e, 0xa, 0xdc, 0xbc, 
+       0xd6, 0xf9, 0xf4, 0xd3, 0x4f, 0x87, 0x83, 0xe5, 0xc9, 0x1c, 
+       0xe0, 0x65, 0xcc, 0x1d, 0x1b, 0x80, 0xcc, 0x92, 0x17, 0x6b, 
+       0xb1, 0x5c, 0xa7, 0xbb, 0xca, 0xe7, 0x7c, 0x27, 0xdb, 0xe8, 
+       0xd9, 0x34, 0x8e, 0x80, 0x10, 0xe1, 0xb0, 0x56, 0x86, 0xbb, 
+       0x8, 0x3, 0x82, 0x80, 0x25, 0xe, 0x34, 0x6, 0x39, 0xe3, 
+       0x74, 0x83, 0xdc, 0x9a, 0x82, 0xfb, 0x3, 0xa0, 0x45, 0x1, 
+       0xb8, 0x41, 0xee, 0xf0, 0x12, 0x75, 0xd3, 0x2f, 0xca, 0x1e, 
+       0xd6, 0xb5, 0x17, 0xa4, 0xd1, 0x2b, 0xb5, 0x25, 0x72, 0xa5, 
+       0xba, 0x9e, 00, 0xbd, 0x5c, 0xa0, 0xe3, 0xdc, 0xb4, 0x30, 
+       0x11, 0x77, 0xab, 0x4f, 0x40, 0x8d, 0x1, 0xae, 0xbc, 0x4c, 
+       0xaa, 0xc6, 0x66, 0xb5, 0x4, 0xd, 0x2d, 0x8d, 0xdc, 0x27, 
+       0x5b, 0xa8, 0xde, 0xdb, 0x39, 0x1, 0x7a, 0xa7, 0x1a, 0xbd, 
+       0x36, 0x5d, 0x63, 0xc3, 0x89, 0xf9, 0xa, 0x48, 0x6d, 0xa9, 
+       0x1f, 0x83, 0xdb, 0x34, 0x6, 0xb4, 0x41, 0xed, 0xf8, 0xa4, 
+       0x61, 0x4d, 0x1d, 0x3, 0x5b, 0xc1, 0xc3, 0x4a, 0x14, 0x78, 
+       0x52, 0xd7, 0x42, 0x94, 0xea, 0x58, 0x58, 0xa1, 0xb1, 0xc7, 
+       0xe2, 0xd7, 0x66, 0x94, 0x34, 0x9c, 0xfa, 0xd7, 0xb5, 0xf4, 
+       0x9f, 0xdb, 0x69, 0x11, 0x22, 0x64, 0xa7, 0x41, 0xe3, 0xfe, 
+       0x6d, 0xf9, 0x74, 0xcb, 0x51, 0xd2, 0x39, 0x77, 0xec, 0xdc, 
+       0x2c, 0xc0, 0x2b, 0x93, 0xcc, 0xac, 0x9c, 0x79, 0x59, 0x6b, 
+       0xda, 0xc3, 0x69, 0xb1, 0x2e, 0xde, 0x73, 0xbe, 0xa7, 0x53, 
+       0xa0, 0xd6, 0x59, 0x19, 0x43, 0xc9, 0x9c, 0x5, 0x73, 0x2e, 
+       0x34, 0x6f, 0x6e, 0x3e, 0xce, 0x49, 0x4d, 0x61, 0xb6, 0x9c, 
+       0xb8, 0xe3, 0xcc, 0xca, 0x8, 0x70, 0xf3, 0x54, 0xb7, 0x1c, 
+       0x7a, 0x2a, 0x2d, 0x48, 0x68, 0x45, 0x22, 0x3a, 0x9c, 0x19, 
+       0x1c, 00, 0x76, 0xc3, 0x86, 0xd, 0x23, 0xc2, 0x72, 0x3d, 
+       0xfa, 0xdc, 0x2d, 0x9f, 0xbc, 0xcd, 0xd, 0x9e, 0x74, 0xbf, 
+       0x8a, 0x46, 0xe5, 0x2, 0x3e, 0xc0, 0x9a, 0x56, 0x74, 0x4a, 
+       0x61, 0x99, 0xb5, 0xb7, 0xa9, 0x1, 0xe, 0x7f, 00, 0x3a, 
+       0x2, 0xc4, 0x7d, 0x8, 0x14, 0x94, 0x74, 0x62, 0xa0, 0xf, 
+       0x83, 0x5a, 0xe1, 0x80, 0x1e, 0xbf, 0x41, 0x5f, 0x82, 0x46, 
+       0x97, 0x3d, 0xaa, 0x31, 0xfa, 0xdf, 0x69, 0xf2, 0x6d, 0xae, 
+       0x76, 0xe9, 0xad, 0x94, 0x7b, 0x89, 0xce, 0x45, 0xe3, 0xb5, 
+       0xc2, 0x8c, 0x96, 0xef, 0x6, 0x35, 0xf9, 0x57, 0xac, 0xb1, 
+       0x7b, 0x1, 0x4b, 0x79, 0x13, 0x3d, 0x29, 0x7, 0xc0, 0xbd, 
+       0x5f, 0x3e, 0xde, 0xa7, 0xa0, 0x3c, 0x4e, 0x98, 0xa1, 0xd7, 
+       0xa6, 0x25, 0x43, 0x4e, 0x3d, 0xe5, 0x18, 0x63, 0x5e, 0xdc, 
+       0x28, 0x94, 0xb6, 0xee, 0xd7, 0xbe, 0x86, 0xe3, 0x2c, 0x25, 
+       0x76, 0x75, 0x75, 0xed, 0xd1, 0x24, 0xd9, 0x39, 0x3d, 0x10, 
+       00, 0xc2, 0xcf, 0x18, 0xd8, 0x31, 0x60, 0x73, 0xc1, 0xcd, 
+       0x35, 0x5f, 0x87, 0xfa, 0x5e, 0x68, 0xc, 0x6a, 0xd7, 0x19, 
+       0x14, 0x4b, 0x1d, 0x53, 0x9f, 0xd4, 0x2f, 0x16, 0x24, 0x11, 
+       0x96, 0x82, 0x97, 0x9, 0xb3, 0xa0, 0x91, 0xe8, 0xfd, 0x6, 
+       0xc4, 0xa5, 0x7e, 0xe2, 0x66, 0x41, 0x4, 0x1c, 0x14, 0x3f, 
+       0xaf, 0x89, 0x70, 0x92, 0xf7, 0x7a, 0x1c, 0x58, 0x3a, 0xbd, 
+       0x74, 0x70, 0xed, 0x63, 0x6b, 0x8f, 0xc4, 0x61, 0xb9, 0xee, 
+       0xa5, 0x9b, 0x96, 0x9e, 0xc4, 0xc6, 0xe1, 0x2, 0xb5, 0xd6, 
+       0xdf, 0xd2, 0x31, 0xf7, 0xd5, 0x83, 0xf6, 0x38, 0xe6, 0xb0, 
+       0x1b, 0x8, 0x1b, 0xb3, 0xe1, 0xe4, 0x92, 0xe1, 0x2b, 0x79, 
+       0x1c, 0x44, 0x8c, 0x6d, 0x9e, 0x28, 0x1f, 0x98, 0x20, 0x2a, 
+       0xa, 0xb0, 0x1a, 0xd8, 0x6e, 0x36, 0x9, 0x77, 0x25, 0x22, 
+       0x14, 0x18, 0xca, 0x6c, 0x21, 0x21, 0x1e, 0xf7, 0x59, 0x28, 
+       0x63, 0x90, 0xbb, 0x17, 00, 0x98, 0xe9, 0xaa, 0x43, 0xd, 
+       0x6c, 0x28, 0x40, 0x77, 0x63, 0x10, 0xae, 0xe9, 0x40, 0xc1, 
+       0xb, 0x1a, 0x67, 0x9e, 0x90, 0x7d, 0x49, 0xd7, 0x32, 0x2, 
+       0x9d, 0x46, 0x2a, 0xf3, 0xea, 0xd5, 0x7d, 0x5f, 0xac, 0xb9, 
+       0x88, 0x7a, 0xd5, 0xcd, 0x1c, 0x69, 0xfa, 0x7e, 0xf5, 0x80, 
+       0x8a, 0xd4, 0x85, 0x2f, 0x92, 0x3b, 0xbc, 0x3d, 0x77, 0xb3, 
+       0x5b, 0x60, 0x27, 0x12, 0xd4, 0xcc, 0x9f, 0xa8, 0xb1, 0xa, 
+       0xaf, 0xf0, 0xa, 0xc8, 0x3, 0xea, 0x6e, 0xf, 0x68, 0xb9, 
+       0x2a, 0x23, 0x81, 0x7f, 0x4f, 0xb4, 0x93, 0x1e, 0x8b, 0x36, 
+       0x98, 0x74, 0xaa, 0xac, 0x67, 0x55, 0x46, 0x3, 0x30, 0x6, 
+       0xa5, 0xb5, 0x2e, 0x94, 0x70, 0x83, 0xd7, 0xc0, 0x8e, 0xaf, 
+       0x3b, 0x8e, 0xa9, 0x41, 0x4d, 0xa3, 0x4b, 0xda, 0xd4, 0x93, 
+       0xbb, 0xe1, 0xae, 0x3f, 0x5, 0x5, 0xe3, 0x7a, 0x75, 0x1d, 
+       0x9b, 0xa, 0xe9, 0xac, 0x70, 0x49, 0x97, 0xe9, 0x5f, 0xb5, 
+       0x2d, 0x8, 0x31, 0xd7, 0xc6, 0xa0, 0xd8, 0xb7, 0xe8, 0x7e, 
+       0xae, 0xdc, 0x2e, 0xa3, 0x67, 0x93, 0x17, 0xfe, 0x4, 0x70, 
+       0x75, 0x3b, 0xc3, 0x9f, 0xf3, 0x13, 0x63, 0xd2, 0x61, 0x57, 
+       0xe5, 0x14, 0xa1, 0x1d, 0xcd, 0xf8, 0x26, 0xb, 0x79, 0x48, 
+       0xf0, 0x1b, 0xdf, 0xf8, 0xc6, 0x68, 0xf1, 0x3f, 0x8, 0xe1, 
+       0xd4, 0x1c, 0x60, 0x75, 0x25, 0xdb, 0x1d, 0xf2, 0xee, 0x56, 
+       0x4f, 0x42, 0x6a, 0x21, 0xa1, 0xcc, 0x2e, 0x3f, 0x71, 0x2d, 
+       0xa8, 0xf0, 0xd, 0x61, 0x83, 0x2, 0x5e, 0x3, 0x18, 0xbf, 
+       0x1, 0x7e, 0x2d, 0x3a, 0x7c, 0x8f, 0x76, 0xf0, 0x61, 0xba, 
+       0xd4, 0x6d, 0x7d, 0x93, 0xf4, 0x64, 0x4a, 0x35, 0x8c, 0x59, 
+       0xa8, 0xb1, 0xe9, 0x2, 0x81, 0xbe, 0x41, 0xb3, 0xfd, 0xe5, 
+       0xca, 0xd7, 0xc, 0x69, 0xf3, 0x41, 0xcd, 0x5b, 0x84, 0x2f, 
+       0x8a, 0xa, 0xa8, 0x19, 0x35, 0x4, 0x5, 0x74, 0xe9, 0x1, 
+       0xff, 0xad, 0xd8, 0x4c, 0xc3, 0xe6, 0x11, 0x3, 0x58, 0x80, 
+       0xd5, 0x19, 0x6b, 0x67, 0xfa, 0x35, 0x36, 0x1e, 0x52, 0x38, 
+       0xe7, 0x8f, 0xc3, 0x8b, 0x4b, 0x5a, 0xa2, 0x3a, 0xa7, 0xf0, 
+       0xe, 0xd9, 0xa3, 0x58, 0xf9, 0xe1, 0x89, 0x41, 0x67, 0x5e, 
+       0x41, 0x9, 0x37, 0x35, 0x48, 0xa1, 0xa3, 0x59, 00, 0xec, 
+       0x78, 0x6, 0xb3, 0x29, 0xe9, 0xdb, 0xba, 0x6e, 0x42, 0x7d, 
+       0x89, 0x4f, 0x81, 0xaa, 0xfe, 0xc8, 0x9f, 0x8d, 0xeb, 0x1a, 
+       0x7f, 0x40, 0xae, 0xae, 0x27, 0xbf, 0xfc, 0xcf, 0xbf, 0x5c, 
+       0x17, 0xb0, 0x2c, 0x79, 00, 0xe4, 0xd9, 0x6b, 0xe1, 0xba, 
+       0x6f, 0xbc, 0xcd, 0xd4, 0xf8, 0xa3, 0x37, 0x4d, 0xb9, 0x68, 
+       0x79, 0x18, 0xca, 0x4, 0x1c, 0x46, 0x74, 0xd4, 0x6c, 0x22, 
+       0x8c, 0xf9, 0x8c, 0x13, 0x30, 0xf3, 0x60, 0xe6, 0x61, 0xed, 
+       0x12, 0x3a, 0xa4, 0x31, 0xd4, 0x5, 0x31, 0x23, 0x93, 0xb5, 
+       0x30, 0x6, 0x4d, 0x18, 0x33, 0x28, 0x5f, 0x7a, 0x93, 0x15, 
+       0xe6, 0x61, 0x5, 0x93, 0x17, 0x21, 0xef, 0xea, 0xf6, 0xf6, 
+       0xcb, 0x3d, 0x20, 0xe1, 0xdb, 0xa7, 0x4c, 0x98, 0x61, 0xd7, 
+       0xcc, 0x8f, 0xca, 0x14, 0xe2, 0x65, 0xd3, 0x20, 0x2e, 0x7e, 
+       0xd2, 0xa3, 0xf2, 0x2d, 0xbc, 0x8, 0x10, 0xfc, 0x43, 0xe8, 
+       0xa0, 0x68, 0x1f, 0x40, 0x8b, 0xdb, 0xe0, 0x35, 0x35, 0xd0, 
+       0x73, 0xfd, 0xc4, 0xe5, 0xda, 0xf0, 0x3d, 0xd2, 0x8a, 0x45, 
+       0xe2, 0xf1, 0x19, 0x26, 0x9a, 0xb2, 0xe1, 0xe1, 0x39, 0x2, 
+       0x70, 0x99, 0xb4, 0x7c, 0xb9, 0x68, 0xb9, 0x5e, 0x6e, 0x29, 
+       0x97, 0xbb, 0x52, 0x93, 0x97, 0x73, 0x95, 0xc7, 0x32, 0xea, 
+       0x42, 0xe5, 0x1c, 0x54, 0x3, 0xa0, 0x53, 0x52, 0x33, 0x43, 
+       0x59, 0xca, 0x2e, 0xc1, 0xf0, 0x8d, 0x32, 0xed, 0xbd, 0xe7, 
+       0xdb, 0xd6, 0xb8, 0xb, 0x5, 0xc0, 0x41, 0x75, 0x95, 0x87, 
+       0xb4, 0x94, 0xa7, 0x13, 0x4d, 0xfb, 0xd8, 0x22, 0xcc, 0x29, 
+       0xa6, 0x4c, 0x70, 0x15, 0xc8, 0x5f, 0xa0, 0xae, 0x34, 0x96, 
+       0x2e, 0x2a, 0xdb, 0x31, 0x2f, 0x28, 0xee, 0x59, 0x8d, 0x8f, 
+       0x4f, 0x69, 0x89, 0xea, 0x2c, 0x9a, 0x58, 0xf6, 0x8c, 00, 
+       0xce, 0x5b, 0x57, 0xf0, 0x3, 0x5e, 0x40, 0x1, 0xae, 0xf9, 
+       0x2, 0x35, 0x10, 0xd, 0x68, 0x53, 0xc2, 0xb1, 0x6, 0x75, 
+       0xae, 0x9f, 0x78, 0x8e, 0x6b, 0xb7, 0xa9, 0xd3, 0xe7, 0x79, 
+       0xae, 0xf, 0xdc, 0x68, 0xe0, 0x40, 0x71, 0xe7, 0x31, 0x71, 
+       0x9d, 0xf, 0xf5, 0xbf, 0x3f, 0xd0, 0xd6, 0xbd, 0xaf, 0x7b, 
+       0xba, 0x52, 0xc8, 0x48, 0x53, 0x87, 0xf5, 0x6c, 0xdd, 0x3, 
+       0x8f, 0x83, 0x6, 0xcf, 0x73, 0xff, 0xed, 0xb, 0x4a, 0x7b, 
+       0xe, 0x94, 0x2d, 0xc8, 0x73, 0xcf, 0xc5, 0x1e, 0xd6, 0xf6, 
+       0xf, 0xe1, 0x97, 0xa5, 0x5c, 0xb9, 0x56, 0x41, 0x57, 0xc, 
+       0xa3, 0xfb, 0x2b, 0x3e, 0xb9, 0x54, 0xa9, 0x80, 0x15, 0x81, 
+       0x63, 0xcc, 0xc8, 0xe, 0xad, 0x99, 0xb2, 0xb3, 0x64, 0xe7, 
+       0xc8, 0x96, 0xcb, 0xf2, 0xde, 0x2b, 0x6e, 0xc2, 0xb8, 0xe6, 
+       0x31, 0x26, 0xf7, 0xa4, 0x4c, 0x92, 0xe3, 0x36, 0x19, 0xa, 
+       0x6d, 0xe1, 0x40, 0x80, 0x60, 0x6, 0xa7, 0x6d, 0x20, 0x8c, 
+       0x1c, 0x82, 0x77, 0x5a, 0x96, 0x71, 0x5f, 0x7c, 0x20, 0x9e, 
+       0x27, 0x6b, 0xfa, 0x47, 0x13, 0x12, 0xf1, 0xc4, 0x2d, 0xba, 
+       0x5b, 0x78, 0xca, 0x89, 0xd, 0xd, 0x5b, 0x96, 0xe2, 0x6, 
+       0xa4, 0xa6, 00, 0xd9, 0xbc, 0x24, 0x3c, 0x6, 0xb2, 0x1, 
+       0x6d, 0x6a, 0xd0, 0x3b, 0x1e, 0x7e, 0xbb, 0xa1, 0x3c, 0xcb, 
+       0xd4, 0xcf, 0xf4, 0xf3, 0x39, 0x1f, 0x5c, 0xb8, 0x2d, 0x9e, 
+       0x96, 0xa5, 0xa5, 0x2, 0x7a, 0xb1, 0xdc, 0x25, 0xf8, 0x71, 
+       0xb, 0xec, 0xd8, 0x12, 0xdc, 0x2, 0x6c, 0x9f, 0x80, 0xdc, 
+       0x27, 0x40, 0xf7, 0x65, 0xdd, 0xbd, 0xb8, 0xb3, 0x61, 0xb8, 
+       0x7b, 0xd1, 0xc0, 0x84, 0xe9, 0x99, 0x16, 0x1e, 0x83, 0x38, 
+       0x8, 0x9a, 0xc2, 0xcd, 0x67, 0x53, 0x3, 0xcf, 0x40, 0x34, 
+       0x68, 0xed, 0xa7, 0x2e, 0x5c, 0x2f, 0x31, 0x8d, 0xe3, 0xe1, 
+       0x8e, 0x1b, 0x86, 0x38, 0xed, 0xdc, 0xe7, 0x7, 0xa1, 0xbd, 
+       0x46, 0x7d, 0x99, 0x37, 0xf0, 0xc, 0x5e, 0xc2, 0x67, 0xe4, 
+       0x94, 0xd5, 0x12, 0x64, 0xda, 0x6e, 0xc2, 0xb1, 0xae, 0x33, 
+       0xee, 0xc3, 0x50, 0xcf, 0x23, 0x81, 0x11, 0x82, 0x27, 0xf5, 
+       0x87, 0xf2, 0x53, 0x6e, 0xf3, 0xd6, 0x43, 0x17, 0x86, 0x7f, 
+       0x58, 0x6f, 0xe2, 0x89, 0x1b, 0x4a, 0x64, 0x98, 0xf8, 0xc1, 
+       0x50, 0xf8, 0x7c, 0x86, 0x82, 0x39, 0x71, 0x2a, 0x83, 0x1b, 
+       0x60, 0x3e, 0xf, 00, 0xc, 0x30, 0xc, 0x46, 0x10, 0x8f, 
+       0xeb, 0x16, 0x52, 0xc2, 0xcc, 0x20, 0x39, 0x27, 0xd5, 0x90, 
+       0x17, 0xac, 0xf3, 0x4a, 0xa1, 0x61, 0x82, 0xc1, 0x4b, 0xde, 
+       0x29, 0x83, 0xcb, 0x43, 0x3c, 0xdf, 0x3, 0x1d, 0xd5, 0x88, 
+       0x61, 0xbe, 0x4e, 0xcf, 0x80, 0x8a, 0x87, 0x37, 0x94, 0x93, 
+       0x34, 0x5c, 0x66, 0x53, 0x83, 0x10, 0x8a, 0xe5, 0xb9, 0x50, 
+       0x4, 0x28, 0x6, 0x6d, 0xec, 0xe6, 0x7a, 0xae, 0xdf, 0xf7, 
+       0x9b, 0x92, 0x3e, 0x6e, 0x28, 0x69, 0xd, 0x83, 0x5c, 0x40, 
+       0xe4, 0xc3, 00, 0x7e, 0xbe, 0x1b, 0x20, 0x53, 0x45, 0x1d, 
+       0xb5, 0x4e, 0x5c, 0x2e, 0xca, 0x63, 0x83, 0x1b, 0x6b, 0xde, 
+       0xd8, 0x4f, 0x59, 0xed, 0x86, 0x87, 0xb8, 0xcd, 0x4b, 0xe8, 
+       0x68, 0xd6, 0x3c, 0x37, 0x8d, 0xe3, 0x11, 0x46, 0xba, 0xe, 
+       0xb3, 0x9b, 0xb4, 0xe3, 0xe7, 0xf9, 0xb9, 0xd7, 0xd3, 0xd2, 
+       0xba, 0x2d, 0x18, 0xe7, 0xdd, 0x94, 0x40, 0xa7, 0x49, 0xba, 
+       0x58, 0x9e, 0xd, 0x8f, 0x30, 0xf0, 0x95, 0xeb, 0xf0, 0xd0, 
+       0x61, 0x72, 0x6, 0x1e, 0x40, 0x6f, 0x87, 0x21, 0xef, 0x71, 
+       0x5e, 0xc9, 0x6f, 0xcc, 0x43, 0xf2, 0xeb, 0xf2, 0x99, 0x8e, 
+       0xc8, 0x27, 0x85, 0xca, 0x35, 0x8e, 0xe8, 0xc4, 0x61, 0x3c, 
+       0x89, 0xe6, 0x2, 0x9b, 0xfb, 0xb8, 0x6, 0x88, 0x2c, 0x98, 
+       0xb9, 0xcc, 0x21, 0xce, 0x64, 0x9a, 0x38, 0xcf, 0xe4, 0x8b, 
+       0x3c, 0xd3, 0xc2, 0xb9, 0x95, 0xc3, 0x4f, 0x38, 0xf9, 0xb6, 
+       0xf0, 0x70, 0xcf, 0x98, 0x8d, 0x81, 0x2e, 0x8c, 0xc3, 0x5c, 
+       0x8c, 0x9f, 0xe9, 0xb2, 0x93, 0x2e, 0x6e, 0x78, 0x66, 00, 
+       0x1a, 0xa0, 0xf8, 0x71, 0x8f, 0x46, 0x1d, 0xcf, 0x71, 0x1c, 
+       0xf, 0x3f, 0x69, 0xe6, 0x52, 0xc2, 0x88, 0x83, 0x40, 0x9a, 
+       0xe2, 0x26, 0x1c, 0x63, 0x4a, 0x58, 0x2c, 0xb4, 0x5c, 0x8b, 
+       0xcb, 0xed, 0xb2, 0xc4, 0xd4, 0xc2, 0x43, 0x79, 0x5c, 0x46, 
+       0xf3, 0xc, 0xfe, 0x71, 0xdd, 0x7c, 0x24, 0x1c, 0xb7, 0xfd, 
+       0xf9, 0xdc, 0x84, 0xf9, 0x9e, 0xf8, 0xba, 0xef, 0xe5, 0x5a, 
+       0x6c, 0x9, 0xc7, 0x10, 0x36, 0x56, 0x50, 0x13, 0x35, 0xd7, 
+       0xc4, 0x79, 0x27, 0xcd, 0xb8, 0x5e, 0x88, 0xeb, 0xeb, 0xf0, 
+       0xf, 0x3b, 0x55, 0x8c, 0x79, 0x61, 0x5e, 0x91, 0x6f, 0x2c, 
+       0x7e, 0xca, 0x11, 0x5b, 0xca, 0x60, 0x2b, 0x67, 0x6a, 0x10, 
+       0x96, 0x7c, 0x86, 0x88, 0x24, 0xee, 0x4, 00, 0x4, 0x71, 
+       0xd1, 0x84, 0x16, 0x18, 0xae, 0xa1, 0x15, 0xd1, 0xda, 0x80, 
+       0x1b, 0xc6, 0x70, 0x2d, 0x57, 0x88, 0x14, 0x34, 0x69, 0xc6, 
+       0xf9, 0x86, 0x1, 0x30, 0x82, 0x7c, 0x93, 0x47, 0xf2, 0x1d, 
+       0xef, 0x4f, 0xe6, 0x9a, 0xcb, 0x46, 0x39, 0xaf, 0x62, 0x8c, 
+       0xc2, 0xae, 0x69, 0xc, 0x72, 0x45, 0x1a, 0xc8, 0xd1, 0xe6, 
+       0xa4, 0x67, 0x80, 0xc1, 0xf, 0x2c, 0xcf, 0x33, 0x7f, 0x72, 
+       0x1, 0x9a, 0xcf, 0x6f, 0x41, 0xcb, 0xbd, 0x46, 0x5a, 0xbe, 
+       0xe6, 0xb4, 0xf1, 0xc7, 0xcf, 0xc3, 0x6d, 0x4b, 0x1c, 0x8c, 
+       0xfd, 0xa9, 0x2f, 0xfd, 0xa5, 0xcc, 0x36, 0xe4, 0x19, 0x13, 
+       0xf3, 0x2, 0xb7, 0x2d, 0x71, 0x63, 0x7e, 0x11, 0x1e, 0xfb, 
+       0xe1, 0x37, 0x61, 0x16, 0x44, 0xbb, 0xc7, 0x42, 0x89, 0x63, 
+       0xeb, 0xfa, 0xc3, 0x7f, 0x33, 0x80, 0xe, 0xb7, 0x47, 0xe9, 
+       0x92, 0x1e, 0xf9, 0xb5, 0x5c, 0x98, 0x2f, 0xe, 0x37, 0x9f, 
+       0x1d, 0xe, 0xbf, 0x62, 0xfe, 0xc8, 0x3b, 0xe9, 0xc6, 0xbc, 
+       0x88, 0xf3, 0x8d, 0x1c, 0x61, 0x29, 0x87, 0xf9, 0xef, 0x78, 
+       0x57, 0x65, 0x90, 0x42, 0xe5, 0x33, 0xdc, 0xe0, 0x9b, 0x1, 
+       0x88, 0x5, 0x9, 0xca, 0x35, 0x12, 0x8f, 0x81, 0x1d, 0x33, 
+       0x7, 0xc6, 0xdc, 0x2e, 0xe3, 0x82, 0xc6, 0xc, 0x41, 0x5b, 
+       0x63, 0x3d, 0x4e, 0xb1, 0xf6, 0x36, 0xc0, 0xa9, 0x60, 0xee, 
+       0xbb, 0x61, 0x63, 0xa0, 0x47, 0xda, 0x9c, 0xb4, 0xe0, 0x95, 
+       0x41, 0x65, 0xfe, 0xe1, 0xc7, 0x6d, 0xa0, 0x9b, 0x12, 0x16, 
+       0xf3, 0x30, 0x17, 0xc0, 0xf1, 0x35, 0xa7, 0xe5, 0x74, 0x9c, 
+       0x66, 0x4c, 0xfd, 0x5c, 0x53, 0x25, 0x1f, 0xf2, 0x2, 0xb5, 
+       0xc9, 0x2d, 0xb3, 0xf9, 0x60, 0x1e, 0x12, 0x8f, 0x30, 0x5b, 
+       0xc2, 0xe1, 0xab, 0xfd, 0x50, 0xfb, 0x2d, 0x2b, 0xbe, 0x16, 
+       0xfb, 0x63, 0x77, 0x7c, 0xdd, 0xcf, 0x31, 0xe5, 0x1a, 0x6, 
+       0x76, 0x12, 0x76, 0xc3, 0x86, 0xfb, 0x55, 0x17, 0xa4, 0xe1, 
+       0xb4, 0xc9, 0x3, 0xfc, 0xa2, 0xce, 0xcd, 0x13, 0xe7, 0xdf, 
+       0x75, 00, 0xf5, 0x35, 0x39, 0x6f, 0xab, 0x89, 0xf3, 0xee, 
+       0x7c, 0xba, 0xe1, 0xcc, 0x5, 0x38, 0xd7, 0x1d, 0x7f, 0x44, 
+       0xa6, 0xf3, 0x81, 0xdb, 0x11, 0xa1, 0x30, 0x85, 0x44, 0x1, 
+       0x38, 0x5, 0x77, 0x18, 0xfe, 0x58, 0x63, 0x5b, 0x18, 0x15, 
+       0x7c, 0x95, 0x10, 0x11, 0x36, 0x59, 0xc6, 0x79, 0x37, 0x43, 
+       0xcc, 0x8, 0xa8, 0xc7, 0xde, 0x50, 0xf2, 0xef, 0xd6, 0x2f, 
+       0x30, 0xe7, 0x66, 0x5, 0x8a, 0x2, 0xe6, 0xa4, 0x61, 0x8d, 
+       0xce, 0x25, 0x4, 0xb, 0x3, 0xb5, 00, 0xe1, 0xce, 0x67, 
+       0x2d, 0x64, 0x5c, 0xb3, 0xe0, 0xe5, 0x8b, 0x47, 0x3a, 0xe, 
+       0x8f, 0xd3, 0x54, 0xf0, 0xf0, 0xf3, 0x1c, 0x4e, 0x18, 0x6, 
+       0x7f, 0x6c, 0xcc, 0x2f, 0x87, 0xc1, 0xb, 0x4c, 0x4c, 0x3, 
+       0x7f, 0x14, 0x46, 0x5c, 0xdc, 0xf9, 0x2c, 0x72, 0xe2, 0x78, 
+       0x76, 0xc7, 0xf1, 0x2c, 0x37, 0x71, 0x1a, 0xba, 0x25, 0x7d, 
+       0x8e, 0xf8, 0x46, 0xdc, 0x5b, 0x61, 0xfc, 0x3c, 0xf2, 0x14, 
+       0x97, 0x9d, 0x70, 0x64, 0x1f, 0x19, 0x30, 0x8f, 0xb9, 0xe, 
+       0x3f, 0x31, 0x71, 0xdc, 0x34, 0x64, 0xf2, 0x7e, 0xc9, 0x1b, 
+       0x6, 0x8a, 0x35, 0x3f, 0x2d, 0xaf, 0x50, 0xcb, 0x35, 0xd7, 
+       0x7c, 0xdd, 0xfc, 0x57, 0x50, 0x6a, 0xae, 0x2, 0x37, 0x2, 
+       0x9a, 0xd5, 0x40, 0x14, 0xd0, 0x4c, 0x71, 0x61, 0x49, 0x80, 
+       0x30, 0xc0, 0xc1, 0xbd, 0xd8, 0x98, 0x39, 0xc4, 0x73, 0x5c, 
+       0x39, 0x27, 0xdd, 0x98, 0x21, 0x16, 0x2c, 0xf2, 0xa, 0x33, 
+       0xcc, 0x10, 0xf2, 0x8d, 0x85, 0x39, 0x66, 0x8a, 0x99, 0xa9, 
+       0xa0, 0x89, 0x35, 0x11, 0xd8, 0xd, 0x74, 0xf2, 0x65, 0x1e, 
+       0xe5, 0xd2, 0x18, 0xa8, 0xd7, 0x72, 0x73, 0x5f, 0x7c, 0xdd, 
+       0x7e, 0x32, 0x6f, 0xe1, 0x34, 0x25, 0x8c, 0xeb, 0x18, 0xd3, 
+       0xd4, 0x97, 0xa, 0x8e, 0xdd, 0x50, 0xf3, 0xe, 0x37, 0xf9, 
+       0xc4, 0xc4, 0x14, 0xb7, 0xe3, 0xe0, 0xb6, 0xcd, 0x17, 0x96, 
+       0x1b, 0x37, 0x8e, 0x43, 0xba, 0x37, 0xdb, 0xe5, 0xe, 0x69, 
+       0x5c, 0xe7, 0x87, 0x67, 0x92, 0xf, 0xca, 0xd, 0xa5, 0xbe, 
+       0x6d, 0xec, 0x47, 0xe, 0x72, 0xe5, 0x97, 0x38, 0xdc, 0xc3, 
+       0xfd, 0xb7, 0xd3, 0xc4, 0x3c, 0xc3, 0x6d, 0x79, 0xb5, 0x3c, 
+       0x43, 0x1d, 0x16, 0xf2, 0x1a, 0xc9, 0x5b, 0xc8, 0xf7, 0x55, 
+       0xe0, 0x8e, 0x4a, 0x3, 0x3, 0x6c, 0xe2, 0x7, 0x91, 0xa0, 
+       0xc1, 0x6d, 0x21, 0x83, 0xc2, 0x90, 0x5c, 0x1, 0xf2, 0xfd, 
+       0x93, 0x49, 0x73, 0xf3, 0x4a, 0x7e, 0x6d, 0xa9, 0x4c, 0x33, 
+       0xc5, 0x8c, 0xa1, 0x9c, 0x81, 0x39, 0xb7, 0x32, 0x93, 0x11, 
+       0xe3, 0xc3, 0xb3, 0xb2, 0xe3, 0x74, 0x1e, 0x19, 0xf3, 0xcd, 
+       0xa0, 0x8c, 0xf9, 0x19, 0x87, 0xc5, 0x6e, 0xee, 0x8d, 0xe3, 
+       0xc5, 0xe9, 0xe4, 0xba, 0x89, 0x7b, 0x3d, 0x33, 0x5a, 0x7d, 
+       0x73, 0x5f, 0xcc, 0x53, 0xfc, 0xe6, 0x19, 0xe1, 0xb1, 0x3b, 
+       0x5f, 0x3c, 0xe2, 0x4f, 0x6, 0x98, 0xc3, 0x73, 0xfc, 0x3, 
+       0xbf, 0xb3, 0x3c, 0x8e, 0xcb, 0x15, 0xb2, 0xa2, 0x1f, 0xc2, 
+       0xa8, 0x7f, 0x80, 0xd, 0xaf, 0xcc, 0xd7, 0x98, 0x6f, 0xa, 
+       0xbe, 0xad, 0xc6, 0xbc, 0x34, 0x8f, 0xcd, 0x67, 0xcb, 0x72, 
+       0x2c, 0xbf, 0xbe, 0x36, 0x22, 0xc3, 0xa3, 0x81, 0x9b, 0x4, 
+       0x31, 0x50, 0x12, 0xb1, 0xc1, 0xd, 0x38, 0xcc, 0x14, 0xd3, 
+       0xa9, 0xc4, 0x14, 0xf2, 0x6a, 0x86, 0x98, 0xba, 0x32, 0xcd, 
+       0x18, 0xfc, 0xb6, 0xb9, 0xdd, 0x69, 0xee, 0xbf, 0xe5, 0x66, 
+       0x14, 0xb0, 0x93, 0x27, 0x78, 0x49, 0x3e, 0xa1, 0x18, 0xb, 
+       0x9e, 0x69, 0xcc, 0x6b, 0x87, 0xc5, 0xf1, 0x7c, 0x9f, 0x29, 
+       0xd7, 0xec, 0x36, 0x75, 0xfd, 0x72, 0xd, 0x83, 0x3f, 0x37, 
+       0x8c, 0xbc, 0x60, 0xe2, 0x6b, 0xe, 0x23, 0xdc, 0xee, 0x5c, 
+       0xca, 0xb5, 0x49, 0x7, 0x73, 0x78, 0xe8, 0xd5, 0x3f, 0x2e, 
+       0x93, 0xf3, 0x88, 0x1f, 0x9e, 0x41, 0xe1, 0x85, 0xf9, 0x8c, 
+       0xdb, 0xbc, 0x91, 0x73, 0xca, 0x18, 0xf3, 0xde, 0x94, 0x72, 
+       0x60, 0xf1, 0x93, 0x77, 0x68, 0x28, 0x5b, 0x24, 0x4f, 0xa, 
+       0x4a, 0xcd, 0x55, 0x9b, 0x58, 0x86, 0x2f, 0xa8, 0xd9, 0x93, 
+       0xdb, 0x16, 0x86, 0xe0, 0x86, 0xc6, 0x6e, 0x33, 0xc4, 0xf1, 
+       0x74, 0xf9, 0xb6, 0x32, 0x89, 0xc2, 0x62, 0xcc, 0xc, 0xdc, 
+       0x66, 0x86, 0xe9, 0x8, 0xa6, 0x10, 0x37, 0x1f, 0x63, 0xb8, 
+       0xf1, 0x76, 0x9b, 0x48, 0xbb, 0x93, 0x95, 0x98, 0xd7, 0xf6, 
+       0x3b, 0xcc, 0x59, 0x8d, 0xeb, 0xc1, 0x71, 0x7c, 0x6d, 0x2c, 
+       0x34, 0xe6, 0x1b, 0xf1, 0x63, 0x7e, 0xfa, 0xfe, 0x20, 0x4c, 
+       0xf6, 0x10, 0x67, 0xaa, 0xf2, 0x8f, 0x3c, 0x66, 0x79, 0x68, 
+       0x3e, 0x59, 0x76, 0xf1, 0xe3, 0xc6, 0x98, 0x67, 0x8e, 0x93, 
+       0x86, 0x4e, 0x8d, 0xdf, 0x98, 0xff, 0xae, 0x1b, 0x53, 0xcb, 
+       0x33, 0x39, 0xcd, 0x5b, 0x7, 0xa3, 0x82, 0x9b, 0x3b, 0x22, 
+       0xe1, 0x8a, 0x19, 0x60, 0x26, 0xc4, 0x61, 0x44, 0x9f, 0x8a, 
+       0xc6, 0x8c, 0x30, 0x93, 0xae, 0xcb, 0x90, 0xa9, 0x58, 0x88, 
+       0xd1, 0xf2, 0x14, 0xd5, 0x8f, 0xa3, 0xb8, 0x6e, 0xec, 0x37, 
+       0x1d, 0x2d, 0xdc, 0x7c, 0x71, 0xbc, 0x5c, 0x1a, 0xae, 0x4f, 
+       0x65, 0xf0, 0xe6, 0x66, 0x78, 0x34, 0x7f, 0xe, 0xc8, 0x47, 
+       0x93, 0xdd, 0xd1, 0xf8, 0x34, 0x5a, 0xb2, 0xb7, 0x3a, 0x3c, 
+       0xae, 0x1f, 0xbb, 0xa1, 0xc3, 0xee, 0x6b, 0xd5, 0xcd, 0x35, 
+       0xc1, 0x1d, 0xe7, 0x3c, 0x12, 0xa4, 0xd1, 0x18, 0x30, 0x5a, 
+       0x78, 0x9c, 0xcc, 0x64, 0xb9, 0x5d, 0xf8, 0xdc, 0xe7, 0xe5, 
+       0x6d, 0xe1, 0x72, 0x23, 0xdd, 0xf1, 0xff, 0xfd, 0xe6, 0xc0, 
+       0x18, 0x64, 0x79, 0xaa, 0x32, 0x20, 0xc8, 0xf5, 0xb5, 00, 
+       0x1d, 0x67, 0x7c, 0xcc, 0xe0, 0x8e, 0x6f, 0xba, 0xe3, 0xbe, 
+       0xc3, 0x81, 0x3b, 0x1c, 0x98, 0xfa, 0x1c, 0xf0, 0xb8, 0x63, 
+       0xea, 0xe7, 0xf4, 0x4e, 0xe, 0xef, 0x70, 0xe0, 0xe, 0x7, 
+       0xc6, 0xc5, 0x81, 0x3b, 0xe0, 0x1e, 0x17, 0xbb, 0xee, 0x44, 
+       0xbe, 0xc3, 0x81, 0xf, 0xe, 0x7, 0xfe, 0x3f, 0xd2, 0x6d, 
+       0x85, 0xb4, 0xe8, 0xe9, 0xe0, 0x3, 00, 00, 00, 00, 
+       0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0};
+
+static const unsigned char data_img_control_z_png[] = {
+       /* /img/control_z.png */
+       0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x7a, 0x2e, 0x70, 0x6e, 0x67, 0,
+       0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 00, 00, 
+       00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, 00, 0x3b, 
+       00, 00, 00, 0xf4, 0x8, 0x6, 00, 00, 00, 0x25, 
+       0x9b, 0x5e, 0xd2, 00, 00, 00, 0x9, 0x70, 0x48, 0x59, 
+       0x73, 00, 00, 0xb, 0x13, 00, 00, 0xb, 0x13, 0x1, 
+       00, 0x9a, 0x9c, 0x18, 00, 00, 0x20, 00, 0x49, 0x44, 
+       0x41, 0x54, 0x78, 0x1, 0xed, 0x5d, 0x79, 0x78, 0x9c, 0x47, 
+       0x79, 0xff, 0xed, 0xae, 0xee, 0xfb, 0xb6, 0x25, 0x5f, 0xf2, 
+       0x21, 0xcb, 0x96, 0xcf, 0x24, 0x76, 0x7c, 0x3b, 0x3e, 0x62, 
+       0x97, 0x1c, 0x8e, 0x4d, 0x38, 0x4b, 0xe, 0x92, 0xa7, 0x94, 
+       0xd2, 0x3e, 0xd0, 0x14, 0x78, 0x42, 0x1b, 0x68, 0x49, 0xd2, 
+       0x34, 0x9, 0x14, 0xda, 0x3f, 0x1a, 0xfa, 0x40, 0x81, 0x4, 
+       0xda, 0xc4, 0x21, 0x9, 0x14, 0x48, 0xc0, 0x5, 0x72, 0x38, 
+       0x76, 0x20, 0x3e, 0x92, 0xd8, 0x96, 0x6f, 0x5b, 0xb6, 0xe4, 
+       0x43, 0x96, 0x25, 0x4b, 0x96, 0xac, 0x5b, 0x5a, 0x69, 0xb5, 
+       0xdb, 0xf7, 0x37, 0xbb, 0xb3, 0xfe, 0x56, 0x7b, 0x68, 0x3f, 
+       0xed, 0xa7, 0x48, 0x7e, 0xbc, 0xaf, 0x9e, 0xd1, 0xcc, 0x37, 
+       0xf7, 0x6f, 0xde, 0xf9, 0x66, 0xde, 0x79, 0x67, 0xf6, 0x1b, 
+       0x9b, 0xc7, 0xe3, 0xc1, 0xf5, 0x42, 0xf6, 0xeb, 0x5, 0x28, 
+       0x71, 0x5e, 0x57, 0x60, 0x13, 0xac, 0xe2, 0xac, 0x4d, 0xc8, 
+       0xaa, 0xbc, 0x6, 0xe7, 0x23, 0xaf, 0x9a, 0x25, 0xef, 0x9a, 
+       0xcd, 0x4c, 0x3e, 0x6, 0x40, 0x1a, 0x98, 0xee, 0x19, 0xfa, 
+       0x59, 0xdb, 0x83, 0xeb, 0x1b, 0xeb, 0xb3, 0x6, 0x4b, 0xdb, 
+       0x6d, 0xc8, 0x8c, 0xed, 0xa0, 0xc3, 0xc, 0xde, 0xa1, 0x9d, 
+       0x51, 0x81, 0xf5, 0x81, 0x24, 0x10, 0x1a, 0x2, 0xd4, 0xee, 
+       0x50, 0x76, 0xe8, 0x92, 0x62, 0xf3, 0x25, 0x20, 0x23, 0x50, 
+       0xfd, 0x4c, 0x7b, 0xc0, 0x97, 0xf5, 0x90, 0xc0, 0x23, 0x76, 
+       0xe3, 0x41, 0x20, 0x1d, 0x92, 0xa9, 0x6, 0xc7, 0x74, 0x74, 
+       0x1b, 0xfd, 0x74, 0x98, 0xb6, 0x7d, 0x75, 0x8, 0xb2, 0x18, 
+       0x9e, 0x22, 0xa6, 0x27, 0x28, 0x24, 0xd8, 0xc3, 0x8, 0x4a, 
+       0x83, 0xd5, 00, 0xb5, 0xcd, 0xfc, 0xc8, 0x6d, 0x37, 0xdf, 
+       0xa4, 0x48, 0x9c, 0xe, 0xcb, 0xd9, 0x10, 0x40, 0xc9, 0x51, 
+       0x82, 0x4c, 0xb8, 0xf7, 0xde, 0x7b, 0x2b, 0x4a, 0x4a, 0x4a, 
+       0x1e, 0x73, 0x38, 0x1c, 0xb7, 0xc8, 0x73, 0x92, 0x98, 0xa8, 
+       0xc8, 0xe5, 0x72, 0xe1, 0xf0, 0xe1, 0xc3, 0xe8, 0xea, 0xee, 
+       0xc2, 0xac, 0xf2, 0x59, 0x28, 0x28, 0x28, 0x88, 0x2a, 0x9d, 
+       0x21, 0x52, 0xbf, 0xdb, 0xed, 0x3e, 0x2d, 0xf9, 0xfc, 0xdf, 
+       0xb3, 0xcf, 0x3e, 0xfb, 0x2f, 0xad, 0xad, 0xad, 0x4, 0xe9, 
+       0x12, 0xa3, 0xc0, 0xfa, 0xdc, 0x61, 0x39, 0x1c, 0x9, 0xac, 
+       0xee, 0xae, 0x4, 0x48, 0x77, 0xa2, 0x18, 0x2, 0xbd, 0x69, 
+       0xd2, 0xa4, 0x49, 0xaf, 0x8e, 0x1b, 0x37, 0xce, 0x95, 0x95, 
+       0x95, 0x95, 0xc9, 0xd6, 0x8c, 0x86, 0x8, 0x74, 0xd7, 0xae, 
+       0x5d, 0xa8, 0xef, 0xa8, 0x47, 0x7f, 0x42, 0x1f, 0x32, 0x9d, 
+       0x59, 0x58, 0xba, 0x64, 0x29, 0x24, 0x9f, 0x68, 0x92, 0xfb, 
+       0xe3, 0x74, 0x77, 0x77, 0xa3, 0xb1, 0xb1, 0xb1, 0xbb, 0xbf, 
+       0xbf, 0x1f, 0x5b, 0xb7, 0x6e, 0x9d, 0x71, 0xee, 0xdc, 0xb9, 
+       0x6e, 0x9, 0x64, 0x57, 0x26, 0x68, 0xda, 0x34, 0x21, 0x1, 
+       0x13, 0x44, 0x10, 0x19, 0xb8, 0xca, 0x6e, 0xca, 0x38, 0xe4, 
+       0x5e, 0xe2, 0xed, 0xb7, 0xdf, 0x3e, 0x4d, 0x80, 0xbe, 0x3e, 
+       0x71, 0xe2, 0xc4, 0xd4, 0xec, 0xec, 0xec, 0xa8, 0x81, 0xe, 
+       0xc, 0xc, 0x60, 0xef, 0xde, 0xbd, 0x68, 0x68, 0x6f, 0x80, 
+       0x27, 0xd7, 0x83, 0xc2, 0xb2, 0x42, 0x74, 0x24, 0xb5, 0x63, 
+       0xef, 0x7b, 0x7b, 0xd1, 0xdc, 0xdc, 0x1c, 0x54, 0x7e, 0x24, 
+       0x8f, 0xb4, 0xb4, 0x34, 0x94, 0x96, 0x96, 0xa6, 0xa5, 0xa4, 
+       0xa4, 0x24, 0xdc, 0x7d, 0xf7, 0xdd, 0xdf, 0x94, 0xb8, 0xc9, 
+       0x62, 0x58, 0x4f, 0x6d, 0x34, 0x93, 0x82, 0xb2, 0x9, 0x9, 
+       0x56, 0x62, 0x91, 0x5d, 0xc, 0xd3, 0x40, 0xc9, 0xdd, 0x94, 
+       0xf2, 0xf2, 0xf2, 0x87, 0x73, 0x72, 0x72, 0x9a, 0x58, 0x60, 
+       0xb4, 0x24, 0xdd, 0xe, 0x1f, 0x7c, 0xf0, 0x1, 0xea, 0xaf, 
+       0xd4, 0x63, 0x20, 0x67, 00, 0xb, 0x6f, 0x5d, 0x80, 0xf2, 
+       0xa5, 0xe5, 0x28, 0x28, 0xcb, 0x47, 0x7b, 0x42, 0x1b, 0x76, 
+       0xef, 0xde, 0x8d, 0x2b, 0x57, 0xae, 0x44, 0x9b, 0x9d, 0x3f, 
+       0xde, 0xf8, 0xf1, 0xe3, 0x93, 0x52, 0x53, 0x53, 0xef, 0x11, 
+       0xf, 0xbe, 0xff, 0x4, 0xac, 0x7b, 0xa0, 0x1a, 0x47, 0x7c, 
+       0xc, 0xf3, 0xc7, 0xa7, 0x23, 0x8, 0xac, 0x81, 0xab, 0xc, 
+       0xd3, 0x19, 0x90, 0xb3, 0x49, 0xc9, 0xc9, 0xc9, 0x1f, 0x91, 
+       0xf7, 0x2c, 0x8f, 0x9, 0xa3, 0x21, 0xe9, 0x4b, 0xd8, 0xbf, 
+       0x7f, 0x3f, 0x6a, 0x1b, 0x6b, 0xd1, 0x9f, 0xd5, 0xaf, 0x80, 
+       0xa6, 0x65, 0xa5, 0x81, 0x5d, 0xbf, 0xfc, 0xe6, 0x99, 0xc8, 
+       0x29, 0xcd, 0x41, 0xab, 0xfd, 0x8a, 0x2, 0xdc, 0xde, 0xde, 
+       0x1e, 0x4d, 0x96, 0xfe, 0x38, 0x9, 0x9, 0xac, 0x1a, 0xd2, 
+       0xc5, 0x10, 0x28, 0xd, 0x5f, 0x33, 0x1a, 0x32, 0x4a, 0x1b, 
+       0x71, 0x5e, 0xa5, 0x20, 0xb0, 0xbe, 0x20, 0x1d, 0x99, 0x39, 
+       0x32, 0x3, 0x66, 0x96, 0x26, 0x95, 0xcc, 0xb2, 0xdb, 0xed, 
+       0x6c, 0xb9, 0xa8, 0xe8, 0xe0, 0xc1, 0x83, 0x38, 0x77, 0xf1, 
+       0x9c, 00, 0xed, 0xc3, 0x82, 0xf5, 0xf3, 0x91, 0x91, 0x9b, 
+       0xe1, 0x4f, 0x67, 0xb3, 0xdb, 0x30, 0x6b, 0x59, 0x39, 0xd2, 
+       0x27, 0xa5, 0xe3, 0x8a, 0xa7, 0x45, 0xbd, 0xcf, 0x5d, 0x5d, 
+       0x5d, 0xfe, 0xf0, 0xa1, 0x1c, 0x6c, 0x30, 0x69, 0x4c, 0xd6, 
+       0x3f, 0x55, 0x8c, 0x7a, 0xcd, 0xc4, 0x66, 0xbd, 0x15, 0x67, 
+       0xc5, 0xe, 0xa2, 0x50, 0x60, 0x8d, 0x40, 0xe9, 0x26, 0x58, 
+       0x9d, 0x59, 0x50, 0x6, 0xe1, 0x3c, 0x8e, 0x1c, 0x39, 0x82, 
+       0x9a, 0xf3, 0x35, 0xe8, 0x13, 0xa0, 0xf3, 0xd6, 0xce, 0x43, 
+       0x76, 0x61, 0x76, 0x50, 0x54, 0xbb, 0xc3, 0x8e, 0xd9, 0x2b, 
+       0x67, 0x23, 0xb9, 0x38, 0x19, 0x2d, 0xae, 0x16, 0xbc, 0xfb, 
+       0xee, 0xbb, 0xe8, 0xe9, 0x89, 0x66, 0x46, 0xa, 0xc8, 0x4a, 
+       0x73, 0x95, 0x75, 0xd4, 0x3d, 0x31, 0x24, 0xe0, 0x50, 0x60, 
+       0x99, 0x13, 0x23, 0x33, 0x8c, 0xb6, 0xee, 0x1e, 0x6c, 0xc1, 
+       0xa8, 0xe8, 0xe4, 0xc9, 0x93, 0x38, 0x55, 0x73, 0xa, 0xce, 
+       0xcc, 0x5e, 0xcc, 0x5d, 0x33, 0x17, 0x79, 0xc5, 0xe1, 0x7b, 
+       0xbe, 0x23, 0xc1, 0x81, 0x8a, 0xd5, 0xb3, 0x61, 0x2f, 0xb2, 
+       0xa3, 0xd9, 0x79, 0x59, 0x1, 0x76, 0x3a, 0x9d, 0x51, 0x95, 
+       0xe3, 0x8b, 0xc4, 0x7a, 0x11, 0x30, 0xeb, 0xaa, 0xc1, 0x32, 
+       0x88, 0x8c, 0xa, 0xa0, 0x50, 0x60, 0x75, 0x24, 0x86, 0x11, 
+       0xa8, 0xee, 0xca, 0x1c, 0x8, 0x86, 0xa4, 0xea, 0xea, 0x6a, 
+       0x1c, 0x3b, 0x71, 0xc, 0xbd, 0x19, 0xbd, 0x2, 0xa2, 0x2, 
+       0x85, 0x93, 0x86, 0x9e, 0x4b, 0x13, 0x12, 0x13, 0x30, 0xe7, 
+       0x96, 0xa, 0xa0, 0xc0, 0x83, 0xcb, 0xdd, 0x4d, 0xaa, 0x4b, 
+       0x73, 0x6a, 0x89, 0x92, 0x34, 0x33, 0x34, 0x50, 0xdd, 0x33, 
+       0x39, 0x36, 0x68, 0x2c, 0x2a, 0xab, 0x50, 0x60, 0x19, 0x40, 
+       0x7f, 0x46, 0xa4, 0xad, 0xc1, 0x32, 0xd3, 0x88, 0x74, 0xfe, 
+       0xfc, 0x79, 0x1c, 0x3a, 0x7c, 0x8, 0xce, 0xc, 0x27, 0x66, 
+       0xad, 0x9c, 0x85, 0xf1, 0x53, 0xc7, 0x47, 0x8c, 0x6f, 0xc, 
+       0x4c, 0x4c, 0x4e, 0x54, 0x80, 0x5d, 0x39, 0xfd, 0x68, 0x6c, 
+       0xbf, 0xa4, 0x6, 0x2d, 0xce, 0xcd, 0x51, 0x10, 0xeb, 0x65, 
+       0xec, 0x89, 0xac, 0xb3, 0xae, 0x7f, 0x40, 0x72, 0x2, 0x19, 
+       0x4c, 0xba, 0x65, 0x68, 0xeb, 0x4c, 0x18, 0x2f, 0x54, 0x5c, 
+       0x7f, 0xda, 0xba, 0xba, 0x3a, 0xec, 0x3f, 0xb0, 0x1f, 0x7d, 
+       0x99, 0x7d, 0x98, 0xb1, 0x6c, 0x6, 0x12, 0x53, 0x12, 0xf1, 
+       0xca, 0xb7, 0x7f, 0x2e, 0xe1, 0x1e, 0xdc, 0xf5, 0xa5, 0xbb, 
+       0x90, 0x90, 0x74, 0x35, 0x79, 0x4d, 0xe5, 0x19, 0xec, 0x7d, 
+       0x75, 0x8f, 0x12, 0x76, 0x3d, 0xfc, 0x2f, 0xa3, 0x36, 0x65, 
+       0x3f, 0xda, 0x3, 0xae, 0x1, 0x64, 0x16, 0x64, 0x4a, 0x4b, 
+       0xdb, 0xf1, 0xde, 0x7b, 0xef, 0x61, 0xc9, 0x92, 0x25, 0x10, 
+       0x49, 0xcd, 0x5f, 0x4e, 0x8, 0x87, 0x6, 0xcb, 0x2, 0x42, 
+       0x82, 0xd4, 0x69, 0xae, 0xd6, 0x40, 0xfb, 0x78, 0x6d, 0xd, 
+       0x58, 0xb7, 0x12, 0xed, 0x70, 0x71, 0xd1, 0xd0, 0xd0, 0x80, 
+       0x7d, 0xfb, 0xf6, 0xa1, 0x2f, 0xbd, 0xf, 0x53, 0x17, 0x4f, 
+       0x45, 0xe9, 0x9c, 0x52, 0x9c, 0xda, 0x7f, 0xa, 0xfb, 0x5f, 
+       0xdf, 0xaf, 0x72, 0xbb, 0xe3, 0xaf, 0xef, 0x8, 00, 0xdb, 
+       0xd6, 0xd4, 0x86, 0x93, 0x7b, 0xab, 0x2, 0x4b, 0x34, 0x3c, 
+       0xad, 0x79, 0x60, 0x35, 0xba, 0x5c, 0x9d, 0xa8, 0x6b, 0xac, 
+       0x53, 0x73, 0xf4, 0xe2, 0xc5, 0x8b, 0x21, 0xb3, 0x80, 0x21, 
+       0x46, 0x80, 0x93, 0x1, 0x1a, 0xb0, 0xae, 0x37, 0xed, 0x20, 
+       0xa, 0x5, 0x40, 0x47, 0xd4, 0xb9, 0x6b, 0xa0, 0x21, 0x9b, 
+       0xf7, 0xf2, 0xe5, 0xcb, 0x8a, 0x3, 0xce, 0x54, 0x27, 0x26, 
+       0x2f, 0x9c, 0x8c, 0xe9, 0xb, 0xa7, 0x73, 0x4a, 0x8, 0x2a, 
+       0xc8, 0xe8, 0x31, 0x79, 0xce, 0x64, 0x6c, 0xfe, 0xbb, 0x4d, 
+       0x70, 0xbb, 0xc9, 0x51, 0xf, 0x7a, 0x3a, 0x7b, 0xf0, 0xf6, 
+       0xff, 0xec, 0x80, 0xdb, 0x25, 0x22, 0xae, 0x94, 0x5e, 0x38, 
+       0xa5, 0x10, 0xb9, 0x13, 0x72, 0x71, 0x6c, 0xfb, 0x9, 0xd4, 
+       0xd6, 0xd7, 0xc2, 0xb1, 0xdf, 0x81, 0x9b, 0x6e, 0xba, 0x49, 
+       0xcd, 0xcf, 0xc6, 0x7c, 0x7c, 0x6e, 0x63, 0xbd, 0x8c, 0x60, 
+       0x35, 0xe, 0x7f, 0x92, 0x50, 0x60, 0x19, 0xa8, 0x13, 0x19, 
+       0xdd, 0x41, 0x89, 0x29, 0xf9, 0xec, 0xd9, 0xb3, 0x7, 0x7d, 
+       0xa9, 0x7d, 0x28, 0x9e, 0x5f, 0x82, 0x59, 0x4b, 0x66, 0x61, 
+       0xc0, 0xa3, 0x57, 0x5c, 0xfe, 0x32, 0x82, 0x1c, 0xf9, 0x25, 
+       0x79, 0xc8, 0x1b, 0x9f, 0xad, 0xc0, 0xf6, 0xc9, 0x40, 0xf4, 
+       0xb3, 0x47, 0x7f, 0xe6, 0x5, 0x2a, 0x31, 0xd7, 0xde, 0x7f, 
+       0xb, 0x26, 0xcf, 0x9d, 0x4, 0xb7, 0x34, 0xd8, 0xcc, 0x55, 
+       0x65, 0x38, 0xb9, 0xb3, 0xa, 0xe7, 0x2e, 0x9c, 0x3, 0x85, 
+       0x88, 0x85, 0xb, 0x17, 0x6, 0xe5, 0x25, 0x1e, 0xba, 0xae, 
+       0x46, 0x3b, 0x54, 0xbc, 0xf0, 0x5d, 0xd3, 0x17, 0xdb, 0x98, 
+       0x41, 00, 0x58, 0x4a, 0x3c, 0xbb, 0x44, 0xb0, 0x77, 0x26, 
+       0x3a, 0x51, 0x54, 0x31, 0xe, 0x15, 0xcb, 0x2a, 0xf0, 0xf4, 
+       0x7d, 0x4f, 0xa3, 0xb9, 0xce, 0x2b, 0xeb, 0x7a, 0x84, 0x6b, 
+       0x9a, 0x9e, 0xfa, 0xc4, 0xd3, 0xda, 0x89, 0x39, 0xab, 0x2a, 
+       0x70, 0xf7, 0xc3, 0x77, 0xfb, 0x9f, 0xb7, 0x3d, 0xf3, 0x7f, 
+       0x38, 0x7f, 0xa4, 0x56, 0x3d, 0x2f, 0xba, 0xf3, 0x46, 0x2c, 
+       0xda, 0x74, 0x93, 00, 0xe5, 0x22, 0x6, 0xc8, 0xcc, 0xcf, 
+       0xc4, 0xf4, 0x15, 0xd3, 0x51, 0xfd, 0xc7, 0x6a, 0xd4, 0x9c, 
+       0xad, 0x51, 0x80, 0xe7, 0xce, 0x9d, 0xab, 0xc2, 0xc, 0xff, 
+       0x2, 0xea, 0x65, 0xf0, 0xf, 0x72, 0xea, 0xae, 0x1a, 0x14, 
+       0x10, 0xc9, 0xa3, 0xb3, 0xb3, 0xd3, 0x3b, 0x1f, 0x3a, 0x9c, 
+       0xc8, 0x9f, 0x95, 0x8f, 0x79, 0xab, 0xe7, 0xab, 0x77, 0x8a, 
+       0xdd, 0x90, 0x3, 0xc, 0xd, 0x65, 0x62, 0x4d, 0xda, 0x4f, 
+       0xf9, 0xf, 0x5c, 0xf5, 0xdf, 0xb1, 0x75, 0x27, 0x8e, 0xec, 
+       0x38, 0xa2, 0xa2, 0xcd, 0x5c, 0x3a, 0x13, 0xeb, 0x1e, 0x58, 
+       0xab, 0x93, 0xf8, 0xed, 0xec, 0xa2, 0x2c, 0x94, 0x2e, 0x2b, 
+       0x45, 0xb3, 0xa3, 0x19, 0x55, 0xa7, 0xab, 0xc0, 0x39, 0xdc, 
+       0x4, 0x5, 0x34, 0x44, 0x40, 0x37, 0x1e, 0x3c, 0x2f, 0xf9, 
+       0x32, 0xd, 0x48, 0xc0, 0x25, 0x16, 0x39, 0xda, 0x23, 0x7f, 
+       0xd9, 0x65, 0xd9, 0xb8, 0x61, 0xad, 0x74, 0x2d, 0x91, 0x84, 
+       0x3c, 0x2, 0x6e, 0xf3, 0x17, 0x37, 0xa3, 0xb7, 0xbb, 0x57, 
+       0xbd, 0xb3, 0xd, 0x67, 0x1b, 0xb0, 0xfd, 0x85, 0xed, 0x2a, 
+       0x8b, 0x8f, 0x7e, 0x79, 0xb, 0x12, 0x64, 0x6a, 0xf1, 0x8, 
+       0xc7, 0xb4, 0x24, 0x55, 0xf9, 0xe6, 0x41, 0xfc, 0xf1, 0xe5, 
+       0x3f, 0xa9, 0xf0, 0x9, 0xb3, 0x26, 0x60, 0xd3, 0x97, 0xef, 
+       0x4, 0x45, 0x48, 0x63, 0x8f, 0xd0, 0xa0, 0x72, 0x8b, 0x73, 
+       0xe0, 0x5a, 0x3c, 0x11, 0xb5, 0xef, 0x5d, 0xc0, 0xb1, 0xe3, 
+       0xc7, 0x14, 0x87, 0xa7, 0x4f, 0x9f, 0xae, 0x83, 0x43, 0xd9, 
+       0x1, 0x75, 0xd6, 0x11, 0x2, 0xc0, 0x6a, 0x4f, 0xb1, 0x19, 
+       0x59, 0x1b, 0xbf, 0x77, 0x5f, 0x5f, 0x9f, 0x57, 0x86, 0x75, 
+       0x75, 0xc1, 0x9d, 0x23, 0x15, 0x2f, 0xc8, 0x46, 0xf5, 0xc1, 
+       0x6a, 0xb5, 0x72, 0xe6, 0xa0, 0x94, 0x9c, 0x9a, 0x8c, 0xd4, 
+       0xac, 0x54, 0x94, 0xcc, 0x28, 0x41, 0x46, 0x5e, 0x86, 0x1f, 
+       0xec, 0xdc, 0xd5, 0x73, 0x91, 0x9c, 0x96, 0xac, 0xba, 0x27, 
+       0xe3, 0x55, 0x1f, 0xa8, 0xc1, 0x6f, 0x9e, 0xd9, 0xa6, 0xf2, 
+       0xcd, 0x2a, 0xcc, 0xc2, 0xa6, 0x87, 0xee, 0x80, 0xab, 0xdf, 
+       0x5, 0x57, 0x9f, 0x1b, 0x7d, 0xbd, 0xfd, 0x68, 0xba, 0xd0, 
+       0xc4, 0x19, 0x4b, 0xbd, 0xb7, 0x8c, 0x4f, 0xc3, 0x77, 0xd8, 
+       0x9e, 0xed, 0xc0, 0xe5, 0xd6, 0x66, 0x35, 0x97, 0x27, 0x26, 
+       0x6, 0x4c, 0xfb, 0xa1, 0xc0, 0x5, 0xf9, 0x85, 0x3, 0xeb, 
+       0x7, 0x68, 0x74, 0x34, 0x35, 0x35, 0xa1, 0xa3, 0xbb, 0x3, 
+       0xee, 0x2c, 0xe9, 0x8a, 0x22, 0xe0, 0x9c, 0x3d, 0x70, 0x56, 
+       0x8d, 0xa6, 0x7a, 0x8e, 0x54, 0x15, 0x14, 0xe8, 0xac, 0x5c, 
+       0x24, 0xda, 0xfd, 0xcb, 0x5d, 0x70, 0xfb, 0xba, 0x73, 0x7b, 
+       0x53, 0x3b, 0x7e, 0xf0, 0xd7, 0x3f, 0xc, 0x88, 0x5e, 0x3c, 
+       0xa3, 0x58, 0x8d, 0xea, 0x92, 0x91, 0xca, 0x4b, 0xe7, 0xcf, 
+       0x17, 0x80, 0xa3, 0x77, 0x7, 0x3a, 0x71, 0xe2, 0xc4, 0x9, 
+       0x94, 0x96, 0x96, 0x6, 0xa4, 0x1b, 0xea, 0xc1, 0x14, 0xd8, 
+       0xa2, 0xa2, 0x22, 0x4c, 0x98, 0x30, 0x1, 0x5c, 0x8c, 0x87, 
+       0x22, 0x4e, 0x43, 0x4d, 0x57, 0x9a, 0x14, 0x97, 0x42, 0x85, 
+       0x47, 0xeb, 0xe7, 0x10, 0x59, 0x66, 0x66, 0xd6, 0xcc, 0xb0, 
+       0x6a, 0x1b, 0x4a, 0x81, 0x54, 0xe9, 0xb4, 0xb4, 0xb4, 0x44, 
+       0x9b, 0xa5, 0x8a, 0x67, 0xa, 0x2c, 0xbb, 0xce, 0xcc, 0x99, 
+       0x33, 0xc3, 0x16, 0x70, 0xfc, 0xf8, 0x71, 0x5, 0x96, 0x11, 
+       0xa6, 0xdf, 0x30, 0x1d, 0xdf, 0x7a, 0xeb, 0x69, 0x6f, 0x17, 
+       0x94, 0xf7, 0xd9, 0xc8, 0xed, 0x7b, 0xfe, 0xf9, 0x1e, 0x79, 
+       0x37, 0x39, 0x88, 0x89, 0xc4, 0xc4, 0x9e, 0x20, 0xe1, 0xec, 
+       0xa6, 0xe2, 0xc0, 0xd9, 0x43, 0x67, 0xd1, 0x74, 0xa8, 0x59, 
+       0x81, 0x99, 0x3d, 0x7b, 0x76, 0xd8, 0xb2, 0x18, 0x60, 0x16, 
+       0xec, 0xb0, 0x46, 0xe3, 0x88, 0x35, 0x18, 0xc3, 0x81, 0x71, 
+       0xb0, 0x63, 0x98, 0x39, 0x31, 0x55, 0x2d, 0xce, 0xd9, 0x98, 
+       0x9a, 0x6f, 0xc, 0x27, 0x8e, 0x73, 0x76, 0xc, 0x33, 0x27, 
+       0xa6, 0xaa, 0x5d, 0x57, 0x9c, 0x35, 0x25, 0x54, 0x14, 0x16, 
+       0x16, 0x46, 0xd4, 0xde, 0x77, 0x74, 0x74, 0xa0, 0xb7, 0xb7, 
+       0x17, 0x8d, 0xb5, 0x8d, 0xa0, 0x86, 0x90, 0xc2, 0x2, 0xc5, 
+       0x3b, 0xa, 0xf7, 0x69, 0xb2, 0x99, 0xe5, 0x12, 0xc9, 0xa7, 
+       0x5f, 0x54, 0x2c, 0x19, 0xb2, 0x6a, 0xea, 0x4e, 0x4e, 0x92, 
+       0xcd, 0x19, 0x1b, 0x92, 0xfa, 0x9c, 0xe8, 0x48, 0x49, 0xc1, 
+       00, 0x25, 0x59, 0x11, 0x2c, 0xda, 0x1a, 0xdb, 0x40, 0x19, 
+       0x9c, 0x79, 0xd, 0xb5, 0x53, 0xc0, 0xfa, 0x98, 0x21, 0x53, 
+       0x60, 0x99, 0x31, 0x75, 0x42, 0xe1, 0x88, 0xdb, 0x22, 0x4a, 
+       0xd, 0xda, 0x2a, 0x31, 0xc4, 0xd8, 0x1a, 0x1a, 0x1, 0x11, 
+       0x21, 0x91, 0x97, 0x7, 0xd7, 0xc5, 0x8b, 0x2a, 0x59, 0xa2, 
+       0x2c, 0xc2, 0x9d, 0xa2, 0x48, 0x73, 0x88, 0x9a, 0xc5, 0x21, 
+       0xd, 0x21, 0xa2, 0x13, 0xb2, 0x58, 0xe9, 0x1e, 0xd9, 0x9f, 
+       0x4a, 0x4a, 0x42, 0xce, 0x34, 0x59, 0xcd, 0x14, 0x1, 0xb, 
+       0x16, 0x2c, 0xc0, 0xbc, 0x79, 0xf3, 0xc2, 0x15, 0xa5, 0xfc, 
+       0xb9, 0x7f, 0x64, 0x86, 0x4c, 0x83, 0x8d, 0x94, 0xb9, 0x12, 
+       0x25, 0x85, 0x3b, 0xfd, 0xb2, 0xe5, 0x61, 0x4b, 0x4e, 0x56, 
+       0x6, 0x39, 0xa2, 0x1c, 0x17, 0xd1, 0x10, 0xe3, 0x87, 0xd8, 
+       0xad, 0xcb, 0xf0, 0xee, 0x16, 0x78, 0xb2, 0xb3, 0x91, 0xd8, 
+       0xd1, 0x8e, 0xb2, 0x49, 0x93, 0x22, 0x15, 0x35, 0xac, 0x30, 
+       0x4b, 0xc1, 0x26, 0x8b, 0xec, 0x3c, 0x6f, 0xca, 0x14, 0x38, 
+       0x76, 0xef, 0x2, 0x9c, 0xbd, 0xa2, 0x6a, 0x10, 00, 0x62, 
+       0x6, 0x28, 0xf7, 0xa, 0xbd, 0x74, 0xec, 0x38, 0x56, 0x4c, 
+       0x9c, 0x88, 0x67, 0xf, 0x1d, 0xc4, 0x3d, 0x15, 0x73, 0x70, 
+       0xf4, 0x72, 0x13, 0x56, 0xb, 0xa8, 0x42, 0xe9, 0x11, 0x8c, 
+       0xe3, 0x90, 0x6e, 0x8e, 0x66, 0xe9, 0x9, 0x42, 0x6e, 0x9, 
+       0xf3, 0x64, 0x65, 0x89, 0xbe, 0xd0, 0xba, 0x61, 0xc5, 0x32, 
+       0xb0, 0xb6, 0xb6, 0x36, 0xd8, 0x7f, 0x21, 0xaa, 0x53, 0xef, 
+       0x86, 0x93, 0xaa, 0x30, 0xff, 0x55, 0xb7, 0xb6, 0xe2, 0x91, 
+       0x9d, 0x3b, 0x91, 0x91, 0x98, 0x84, 0x63, 0xd2, 0xa5, 0x9f, 
+       0x11, 0x2d, 0x24, 0xe9, 0x8d, 0x33, 0x67, 0x95, 0xfd, 0xa2, 
+       0x34, 0x40, 0xae, 0xbc, 0xb3, 0x9b, 0x66, 0xcc, 0xc0, 0xe6, 
+       0xb2, 0x19, 0xec, 0xd8, 0x6a, 0x21, 0x6d, 0x97, 0xad, 0x10, 
+       0x6c, 0xdf, 0xe, 0xf7, 0xad, 0x1b, 0xe0, 0x99, 0x36, 0x4d, 
+       0xc5, 0x8d, 0xf5, 0x9f, 0x65, 0x60, 0x41, 0x85, 0xb6, 0x36, 
+       0x52, 0xab, 0x1e, 0x71, 0xdf, 0xfb, 0x9b, 0xdf, 0xa2, 0x57, 
+       0xec, 0xe6, 0x8, 0xfb, 0x37, 0x75, 0x32, 0x10, 0xd1, 0x9c, 
+       0x16, 0xe5, 0xdd, 0x2f, 0x44, 0xe5, 0xf2, 0xb7, 0xa2, 0x45, 
+       0x5c, 0x5c, 0x2c, 0xca, 0x75, 0x19, 0xe8, 0x14, 0xb1, 0x87, 
+       0xb0, 0x67, 0x90, 0xeb, 0x31, 0x92, 0x25, 0x60, 0xc9, 0x51, 
+       0x9b, 0x61, 0x53, 0xf9, 0x15, 0x59, 0x58, 0xef, 0xa9, 0xbb, 
+       0xa8, 0x40, 0x44, 0x5b, 0x3f, 0x36, 0xca, 0x29, 0x59, 0x9f, 
+       0xfe, 0x87, 0x70, 0x7e, 0x69, 0x49, 0x9, 0xfe, 0xe6, 0xc6, 
+       0x1b, 0xbc, 0x1c, 0x7e, 0xe7, 0x1d, 0xc8, 0x4e, 0x36, 0x6, 
+       0x3e, 0xf1, 0x49, 0xd9, 0xa0, 0xe4, 0xe, 0xe5, 0xf0, 0xc9, 
+       0x92, 0x17, 0xc2, 0x26, 0xa, 0x36, 0x4d, 0x2e, 0x99, 0x6e, 
+       0x5e, 0x3d, 0x75, 0x1a, 0xbb, 0x64, 0x87, 0x60, 0x38, 0x44, 
+       0xc0, 0x2f, 0xcb, 0xba, 0xb8, 0xc5, 0xd8, 0x1b, 0xb8, 0xef, 
+       0x63, 0x1, 0x67, 0x63, 0x3, 0x2b, 0x5d, 0xcd, 0xfe, 0xbb, 
+       0xdf, 0x49, 0x97, 0xf3, 0x6e, 0x33, 0x36, 0x8a, 0x32, 0xee, 
+       0xd6, 0x97, 0x5e, 0x46, 0xb5, 0x6f, 0x27, 0xfd, 0x6b, 0x5f, 
+       0xfb, 0x1a, 0x2a, 0x2b, 0x2b, 0xb1, 0x65, 0xcb, 0x96, 0x20, 
+       0xdc, 0x72, 0x36, 0x3, 0xaf, 0xbd, 0xf6, 0x1a, 0x8e, 0x1e, 
+       0x3d, 0x8a, 0x97, 0x5e, 0x7a, 0x9, 0x6b, 0xd6, 0xac, 0xf1, 
+       0xc7, 0xe9, 0x13, 0x4d, 0xc8, 0x96, 0x5f, 0xfe, 0xa, 0x3b, 
+       0x6b, 0xbd, 0x2a, 0x56, 0x2, 0xb5, 0xbf, 0xf9, 0x6, 0xd0, 
+       0x24, 0x53, 0x59, 0xc, 0x14, 0x5b, 0x37, 0x6e, 0x6b, 0x85, 
+       0xed, 0xfc, 0x39, 0x7f, 0xf1, 0x67, 0x65, 0x90, 0x62, 0x77, 
+       0x24, 0x71, 0xcb, 0xe2, 0x91, 0x47, 0x1e, 0x81, 0x1c, 0x4b, 
+       0x40, 0x7e, 0x7e, 0xbe, 0x3f, 0xe, 0x1d, 0x5f, 0xf8, 0xc2, 
+       0x17, 0xf0, 0xfd, 0xef, 0x7f, 0xdf, 0xef, 0x57, 0x51, 0x51, 
+       0x81, 0xcd, 0x9b, 0x37, 0xe3, 0xb6, 0xdb, 0x6e, 0xc3, 0x8e, 
+       0x1d, 0x3b, 0x94, 0x7f, 0xbf, 00, 0xae, 0x91, 0xc1, 0x6d, 
+       0xa5, 0x8c, 0xde, 0xe, 0x71, 0xdb, 0xea, 0xeb, 0x95, 0xf1, 
+       0x14, 0xca, 0x24, 0x3c, 0x4c, 0x8a, 0x89, 0xb3, 0x9c, 0x4b, 
+       0x91, 0x99, 0xa9, 0x8a, 0x26, 0x57, 0xbf, 0xba, 0xfd, 0x6d, 
+       0x3c, 0xf0, 0xc0, 0x3, 0x4a, 0xa7, 0xcc, 0xb3, 0x12, 0x4, 
+       0x3a, 0x98, 0xa8, 0x3f, 0xfa, 0xfa, 0xd7, 0xbf, 0xae, 0xbc, 
+       0xbf, 0xf7, 0xbd, 0xef, 0x61, 0xd6, 0xac, 0x59, 0x78, 0xfd, 
+       0xf5, 0xd7, 0x21, 0x7, 0x42, 0xf0, 0xd5, 0xaf, 0x7e, 0x35, 
+       0x20, 0xfa, 0x7f, 0x1d, 0xa8, 0xc4, 0xae, 0xb, 0xbe, 0xd7, 
+       0x41, 0x24, 0x2f, 0xa, 0x27, 0xb1, 0xd0, 0xf0, 0xc1, 0x8a, 
+       0x48, 0x67, 0xff, 0xc5, 0x2f, 0x20, 0x72, 0x9d, 0x2a, 0xbf, 
+       0xa5, 0xc7, 0xab, 0x2f, 0x9e, 0x3f, 0x7f, 0x3e, 0x96, 0x2f, 
+       0x5f, 0x1e, 0x76, 0xe7, 0xed, 0xc6, 0x1b, 0x6f, 0x84, 0x9c, 
+       0xb8, 0x51, 0x4a, 0xf4, 0x6f, 0x7c, 0xe3, 0x1b, 0x4a, 0xe9, 
+       0xfd, 0xd4, 0x53, 0x4f, 0xa9, 0x3c, 0x36, 0x6c, 0xd8, 0x20, 
+       0x63, 0x50, 0xe0, 0x20, 0xd4, 0xec, 0x7b, 0x45, 0x44, 0xcb, 
+       0x7, 0xfb, 0xb6, 0x6d, 0xc2, 0x5d, 0xaf, 0x24, 0x36, 0x1c, 
+       0xd0, 0xc3, 0x7, 0x4b, 0xbd, 0xed, 0xa4, 0xc9, 0xfe, 0x32, 
+       0x7f, 0x50, 0x79, 00, 0x1c, 0x9c, 0xbe, 0xf2, 0x95, 0xaf, 
+       0xa8, 0xdd, 0x1, 0xee, 0xba, 0x71, 0x1b, 0x73, 0x30, 0x95, 
+       0x95, 0x95, 0x29, 0x2f, 0x39, 0xbf, 0x4, 0x7d, 0x68, 0x84, 
+       0xef, 0x2d, 0x49, 0xe, 0xa8, 0xa8, 0x86, 0x50, 0xf, 0xbe, 
+       0x7f, 0xdf, 0x3f, 0x70, 00, 0xf5, 0xfa, 0xac, 0x85, 0x48, 
+       0x57, 0x9e, 0xdc, 0xe1, 0x73, 0x77, 0xf8, 0x60, 0x29, 0xe8, 
+       0x8b, 0x10, 0xaf, 0xa9, 0xdc, 0xd0, 0xc5, 0xb4, 0x62, 0x5b, 
+       0x87, 0x19, 0x6d, 0xaa, 0x63, 0x49, 0x6d, 0xf2, 0x7e, 0x6b, 
+       0x92, 0x93, 0x6a, 0xda, 0x9, 0x1d, 0xae, 0x3d, 0x36, 0x94, 
+       0x4e, 0x45, 0xb1, 0x8f, 0xdb, 0x1e, 0x69, 0x40, 0x9b, 0x2c, 
+       0x22, 0x86, 0x4b, 0xc3, 0x6, 0x6b, 0x6b, 0xbc, 0x4, 0x9b, 
+       0x4f, 0xb8, 0xa7, 00, 0xf1, 0xf6, 0xb9, 0xf3, 0x51, 0xd5, 
+       0x41, 0x77, 0x53, 0xae, 0x6c, 0x34, 0x71, 0x87, 0x5d, 0xab, 
+       0x5a, 0x75, 0xb8, 0xe, 0xfb, 0x7d, 0x4d, 0xd, 0x9c, 0xd2, 
+       0x85, 0x49, 0x36, 0x8e, 0xf2, 0xd5, 0xd5, 0x3a, 0xc8, 0xb4, 
+       0x3d, 0x6c, 0xb0, 0x9e, 0xc9, 0x53, 0xe0, 0x5e, 0x78, 0x83, 
+       0x2a, 0x30, 0x55, 0x44, 0xc4, 0x3b, 0x66, 0xc8, 0x6a, 0x25, 
+       0xa, 0xd2, 0x27, 0xda, 0x8c, 0x7, 0xc7, 0xe4, 0xf0, 0x96, 
+       0x7f, 0xef, 0x55, 0x87, 0xeb, 0xac, 0x6e, 0x90, 0xe3, 0x7e, 
+       0xc9, 0x1c, 0x9c, 0x84, 0x3c, 0xf2, 0xae, 0x7b, 0x44, 0xc2, 
+       0x1a, 0x2e, 0xd, 0x1b, 0xac, 0x8d, 0xd3, 0xc1, 0x89, 0xe3, 
+       0xfe, 0x72, 0x8f, 0x36, 0x79, 0x5, 0x78, 0xbf, 0x47, 0x18, 
+       0x87, 0x9c, 0x3b, 0x54, 0x21, 0x72, 0xd0, 0xd3, 0x1f, 0xa3, 
+       0xb8, 0xb8, 0xd8, 0xef, 0xbe, 0x74, 0xe9, 0x92, 0xdf, 0x4d, 
+       0xc7, 0x19, 0xe9, 0xe2, 0x72, 0x50, 0xd1, 0xeb, 0x77, 0xe1, 
+       0x2, 0xfb, 0x7f, 0x40, 0xb8, 0x99, 0x87, 0x61, 0x83, 0xf5, 
+       0x50, 0xa2, 0xe1, 0xaa, 0xc4, 0x47, 0x4f, 0xac, 0x5e, 0x85, 
+       0xb4, 0xc0, 0xcd, 0x26, 0x1d, 0x14, 0x60, 0xf3, 0xac, 0x13, 
+       0xbb, 0x6d, 0x9e, 0xbc, 0xe3, 0x7a, 0x73, 0x79, 0xed, 0xda, 
+       0xb5, 0x2a, 0xe, 0x7, 0x2d, 0x1e, 0x42, 0x31, 0xd2, 0xe3, 
+       0xab, 0x56, 0xfa, 0xf3, 0xb5, 0xf1, 0x18, 0xe1, 0xa0, 0x85, 
+       0x86, 0x31, 0xee, 0x50, 0xee, 0x61, 0x83, 0xe5, 0xd2, 0xcb, 
+       0xbd, 0xe9, 0x2e, 0xff, 0x3c, 0xdb, 0xda, 0x2b, 0x7b, 0xb5, 
+       0xd2, 0x1d, 0x87, 0x22, 0x6e, 0x8e, 0xfd, 0xfe, 0xf7, 0xbf, 
+       0x57, 0xd1, 0x7e, 0xfd, 0xeb, 0x5f, 0xe3, 0xb9, 0xe7, 0x9e, 
+       0xc3, 0x77, 0xbf, 0xfb, 0x5d, 0xf5, 0xfc, 0xfc, 0xf3, 0xcf, 
+       0xfb, 0xdf, 0x5d, 0x7a, 0x64, 0xa7, 0x24, 0xa3, 0x4b, 0x73, 
+       0x55, 0xba, 0xb2, 0xfb, 0xce, 0x4d, 0xe2, 0x19, 0x7c, 0x78, 
+       0x4c, 0x25, 0x8e, 0xe2, 0xdf, 0xf0, 0xc1, 0x4a, 0xe6, 0x36, 
+       0x76, 0x49, 0xdf, 0x3c, 0x3b, 0x2e, 0x3d, 0xd, 0x3f, 0xbe, 
+       0xed, 0x23, 0x51, 0x14, 0x9, 0xdc, 0x7f, 0xff, 0xfd, 0x6a, 
+       0xeb, 0x73, 0x8a, 0xac, 0x7d, 0x1f, 0x7c, 0xf0, 0x41, 0xa9, 
+       0x7f, 0x36, 0x5e, 0x78, 0xe1, 0x5, 0x3c, 0xfe, 0xf8, 0xe3, 
+       0x1, 0xe9, 0xbf, 0xb9, 0x7c, 0x5, 0x6e, 0xd6, 0x5d, 0x9c, 
+       0x83, 0x94, 0xc, 0x56, 0xb1, 0x50, 0x4c, 0xe2, 0xa2, 0x47, 
+       0xde, 0x3b, 0xf7, 0xfa, 0x5b, 0x61, 0x97, 0x23, 0x41, 0xb2, 
+       0xcb, 0x84, 0x3e, 0x99, 0x67, 0x6f, 0x9b, 0x3e, 0xd, 0x7f, 
+       0xa8, 0x39, 0xa3, 0x36, 0xaa, 0xe4, 0xa8, 0x6e, 0xc8, 0xba, 
+       0x51, 0xb7, 0xb4, 0x62, 0xc5, 0xa, 0xc8, 0xc9, 0x52, 0x4c, 
+       0x93, 0xb5, 0x2a, 0xe7, 0x59, 0xe3, 0x54, 0xc4, 0x44, 0xcb, 
+       0x64, 0xb7, 0x30, 0x53, 0xf4, 0x54, 0x8a, 0xe4, 0xf5, 0x70, 
+       0x2f, 0x5d, 0x6, 0x8f, 0xac, 0x79, 0x63, 0xa1, 0x98, 0xc0, 
+       0xb2, 0x60, 0x55, 0x81, 0x3f, 0xbe, 0xa3, 0xea, 0x50, 0x28, 
+       0xdd, 0xf8, 0x51, 0x1, 0xd1, 0xd4, 0xdd, 0x83, 0xf, 0x44, 
+       0x96, 0x1d, 0x8a, 0x78, 0xa4, 0x88, 0x66, 0x30, 0xf1, 0xdd, 
+       0xff, 0xf7, 0xf5, 0xeb, 0xd4, 0x12, 0x4f, 0x85, 0xb1, 0x2b, 
+       0x93, 0xc3, 0xa2, 0xa3, 0x8a, 0x85, 0x62, 0x6, 0xcb, 0xc2, 
+       0x39, 0x5, 0xd9, 0xd9, 0xa5, 0xcf, 0x9e, 0x51, 0x75, 0xf9, 
+       0xf2, 0xe2, 0x45, 0x4a, 0x2b, 0xf1, 0xe4, 0xae, 0xdd, 0xa6, 
+       0xeb, 0xf6, 0xc9, 0xd9, 0xb3, 0x70, 0xfb, 0x34, 0xc3, 0x34, 
+       0x26, 0x20, 0x3d, 0x32, 0x98, 0x79, 0x7c, 0x32, 0xb8, 0xe9, 
+       0xc, 0xd, 0x9, 0x2c, 0x1, 0xeb, 0xb9, 0xe1, 0x6, 0xb8, 
+       0x85, 0x43, 0x76, 0x1f, 0xd8, 0xe9, 0xb2, 00, 0x28, 0x95, 
+       0xf7, 0xb0, 0xae, 0xa3, 0x13, 0x67, 0x64, 0xaa, 0xd8, 0x39, 
+       0x68, 0x84, 0x35, 0x94, 0xef, 0x77, 0xce, 0x14, 0x40, 0x1b, 
+       0xa6, 0x96, 0xaa, 0x55, 0xce, 0x54, 0xc3, 0x20, 0xe4, 0x29, 
+       0x2d, 0x85, 0x7b, 0xfe, 0x2, 0x7f, 0xbc, 0x58, 0x1c, 0x96, 
+       0x80, 0x65, 0x5, 0x54, 0xeb, 0x97, 0x97, 0x8b, 0xcb, 0x6, 
+       0xdb, 0xc9, 0x13, 0x4a, 0x79, 0xf6, 0x85, 0x1b, 0x16, 0xa2, 
+       0x5b, 0xa6, 0x99, 0xe7, 0x8f, 0x64, 0x2b, 0x1d, 0xd4, 0x8f, 
+       0xe4, 0xfc, 0x31, 0x1b, 0xe2, 0xa8, 0xe8, 0xa2, 0x66, 0xe4, 
+       0xe6, 0xe2, 0x92, 0xc8, 0xbc, 0xeb, 0x5, 0xc, 0xfd, 0xe6, 
+       0x14, 0x16, 0xa0, 0xc2, 0xb0, 0x14, 0x24, 0x48, 0xf, 0x85, 
+       0x9, 0x11, 0x5e, 0xac, 0x22, 0xcb, 0xc0, 0xf2, 0x7d, 0x72, 
+       0xaf, 0x59, 0xb, 0x8, 00, 0x87, 0x80, 0x55, 0x24, 0xd3, 
+       0x53, 0x9a, 0xcc, 0x8b, 0x7f, 0xe5, 0x3b, 0xac, 0xb5, 0xbe, 
+       0x74, 0xa, 0xc6, 0x8b, 0x9c, 0xbb, 0x5b, 0xc4, 0x4c, 0xaa, 
+       0x5e, 0x2e, 0x8b, 0x36, 0x22, 0x4f, 0x96, 0x76, 0x4a, 0xab, 
+       0xa8, 0x11, 0x49, 0x1a, 0x59, 0x12, 0xc1, 0x33, 0xb3, 0x1c, 
+       0x9e, 0xa9, 0x53, 0xb5, 0xaf, 0x25, 0xb6, 0x75, 0x60, 0x75, 
+       0x75, 0x4, 0xcc, 0xc0, 0x5d, 0x9b, 0x61, 0x4b, 0x4d, 0x81, 
+       0x4d, 0xf4, 0x47, 0x5c, 0x74, 0x2b, 0x75, 0xa8, 00, 0x20, 
+       0x50, 0xd2, 0x32, 0x9f, 0xf4, 0xc4, 0x1, 0x4d, 0x91, 0x6, 
+       0x28, 0x9c, 0xf4, 0xfc, 0xf9, 0x67, 0x94, 0x3a, 0xd5, 0x63, 
+       0x58, 0x51, 0x79, 0x23, 0xc5, 0xfe, 0xdf, 0x7a, 0xb0, 0xac, 
+       0x13, 0x7, 0x15, 0xb1, 0x3c, 0xb2, 0x7b, 0x60, 0x13, 0x11, 
+       0xcf, 0x23, 0x2b, 0x17, 0xfb, 0xff, 0xca, 0xda, 0x97, 0xa3, 
+       0xa9, 0xc8, 0xba, 0x36, 0xbe, 0xc3, 0x5c, 0x25, 0x51, 0xa, 
+       0x13, 0x45, 0x9d, 0x7b, 0xdd, 0x3a, 0x51, 0xed, 0xc8, 0xa, 
+       0x4a, 0x84, 0x8, 0xf, 0x1b, 0xc4, 0xd7, 0x28, 0xb1, 0xc3, 
+       0xb, 0xcc, 0xc1, 0x14, 0x58, 0x1e, 0x20, 0xe1, 0xf, 0x1c, 
+       0x4c, 0x91, 0x4d, 0xba, 0xa5, 0x88, 0x81, 0xe9, 0xb3, 0x2b, 
+       0x54, 0xb2, 0x5e, 0xe9, 0xb6, 0x53, 0xba, 0xba, 0x51, 0x2f, 
+       0x73, 0xec, 0x80, 0x70, 0x32, 0x2d, 0x2f, 0x1f, 0xad, 0x6d, 
+       0xed, 0xde, 0x2c, 0x79, 0x82, 0xdc, 0x44, 0xfe, 0x83, 0xce, 
+       0x42, 0xd, 0x59, 0x2d, 0x53, 0x60, 0x99, 0x1b, 0x75, 0x45, 
+       0x66, 0xa8, 0x57, 0xd4, 0xaa, 0x5c, 0xf7, 0x3a, 0xab, 0x4e, 
+       0xa1, 0xfb, 0x60, 0x25, 0x92, 0xe5, 0x64, 0x9a, 0x53, 0xb4, 
+       0xfe, 0xc5, 0x69, 0xa9, 0xe8, 0x97, 0x81, 0xca, 0x21, 0x5c, 
+       0xcc, 0xb9, 0x65, 0x35, 0xfa, 0x2f, 0x35, 0x22, 0x3d, 0xc2, 
+       0x3e, 0x52, 0xa8, 0x32, 0x5f, 0x7d, 0xf5, 0xd5, 0x50, 0xde, 
+       0x61, 0xfd, 0x4c, 0x83, 0xd, 0x9b, 0xd3, 0xa0, 0x80, 0x5e, 
+       0xe, 0x52, 0x22, 0xe2, 0xb5, 0xbc, 0xf2, 0x8a, 0x57, 0x79, 
+       0xee, 0xb, 0x77, 0x9e, 0x3e, 0xad, 0x5c, 0x7d, 0x3e, 0xcd, 
+       0xa1, 0x4b, 0x6, 0xa9, 0xcb, 0x3f, 0xfe, 0xb1, 0x37, 0x54, 
+       0x7a, 0xb5, 0xcd, 0x91, 0x80, 0xb4, 0x18, 0x96, 0x71, 0x83, 
+       0xaa, 0x11, 0xf0, 0x38, 0x22, 0x60, 0x3d, 0x22, 0xf1, 0xb4, 
+       0x88, 0xac, 0xab, 0x34, 0xf9, 0x86, 0xe2, 0xb8, 0x54, 0xa3, 
+       0x74, 0x54, 0xd5, 0x72, 0x5, 0x33, 0xf3, 0x72, 0x95, 0x90, 
+       0x9f, 0x2e, 0xcf, 0x9a, 0xda, 0x44, 0xb5, 0x4a, 0x4a, 0x28, 
+       0xc8, 0x47, 0x12, 0xa7, 0x1c, 0xbe, 0xd3, 0x16, 0x92, 0xe5, 
+       0x60, 0x5b, 0xb6, 0xbe, 00, 0xe7, 0xa9, 0x53, 0x1, 0x40, 
+       0xf7, 0x89, 0xc0, 0x71, 0xb0, 0xb1, 0x9, 0xdb, 0x44, 0xcb, 
+       0xc0, 0xc3, 0x5d, 0xf5, 0xa2, 0x5a, 0x19, 0x9f, 0x91, 0x8e, 
+       0x76, 0x67, 0x1f, 0xfe, 0xbc, 0x62, 0x36, 0x4a, 0x64, 0x7, 
+       0xef, 0xe, 0xc3, 0xc1, 0xcb, 0xe6, 0x9f, 0xfc, 0x4, 0xf6, 
+       0xf4, 0xc, 0x14, 0x89, 0x3e, 0xcb, 0xc6, 0xb9, 0xd6, 0x22, 
+       0xb2, 0x14, 0xac, 0xb3, 0xfa, 0xb4, 0xbc, 0x7b, 0x97, 0xe0, 
+       0x11, 0x41, 0x82, 0x44, 0x60, 0xff, 0xb0, 0x63, 0x27, 0xe, 
+       0xc9, 0xb2, 0xae, 0x55, 0x14, 0xea, 0x46, 0x6a, 0xe8, 0xec, 
+       0x52, 0x8f, 0xcf, 0x1e, 0x3c, 0x84, 0x4, 0x99, 0x7a, 0xde, 
+       0x96, 0x11, 0xfa, 0x8b, 0xa2, 0x79, 0xa4, 0xe4, 0xc5, 0xf4, 
+       0x3, 0xed, 0x6d, 0x70, 0xca, 0xde, 0x4f, 0xa, 0x4f, 0xd4, 
+       0xc5, 0xb0, 0x86, 0x35, 0x96, 0x69, 0x19, 0x58, 0x72, 0xb3, 
+       0xf9, 0xbf, 0x7f, 0xea, 0xcf, 0xfb, 0xa0, 0xc8, 0xca, 0x3f, 
+       0x12, 0x20, 0xd1, 0x2c, 0x8, 0xa8, 0x95, 0xfc, 0x53, 0xed, 
+       0x5, 0x5c, 0x14, 0xf1, 0xf2, 0x9e, 0x39, 0x15, 0x5e, 0x2e, 
+       0x4b, 0x43, 0xb5, 0xbc, 0xb8, 0x15, 0x99, 0x6b, 0xd7, 0x21, 
+       0x73, 0xfd, 0x7a, 0x7f, 0xbe, 0xb1, 0x38, 0x64, 0x5e, 0x88, 
+       0x9d, 0xc8, 0x9, 0x97, 0x28, 0xe0, 0x34, 0xd5, 0xb6, 0x77, 
+       0xe0, 0xa7, 0x87, 0x8f, 0x84, 0x4, 0x3a, 0x79, 0xf2, 0x64, 
+       0x50, 0xf5, 0xf2, 0xcc, 0x33, 0xcf, 0xe8, 0xe8, 0x7e, 0x9b, 
+       0x3b, 00, 0x3f, 0x39, 0x74, 0x18, 0x87, 0xa5, 0x27, 0x68, 
+       0x72, 0xc9, 0xae, 0x83, 0x5b, 0xab, 0x52, 0xb5, 0xe7, 0x30, 
+       0x6d, 0x4b, 0xc0, 0x76, 0xcb, 0xdc, 0xd8, 0xc6, 0x3d, 0x1f, 
+       0x1f, 0xfd, 0xfa, 0x54, 0x15, 0x76, 0xf, 0xd2, 0x19, 0xaf, 
+       0x13, 0xc1, 0xe1, 0xe1, 0x87, 0x1f, 0xc6, 0xef, 0x24, 0x1e, 
+       0xd5, 0xa5, 0xf2, 0xdb, 0x5b, 0x1d, 0x3d, 0xc0, 0xbe, 0x20, 
+       0xca, 0x80, 0x67, 0xf6, 0x5d, 0x9d, 0xcb, 0x7b, 0x24, 0xef, 
+       0x76, 0x9f, 0x66, 0x23, 0x20, 0xe2, 0x30, 0x1e, 0x2c, 0xe9, 
+       0xc6, 0xe, 0x11, 0xea, 0x35, 0xbd, 0x5f, 0xdf, 0x80, 0xff, 
+       0x3d, 0x59, 0xa5, 0x1f, 0xfd, 0xf6, 0x7d, 0xf7, 0xdd, 0x87, 
+       0x8d, 0x1b, 0x37, 0x82, 0x9a, 0xc4, 0xa1, 0xe8, 0x90, 0xbc, 
+       0x2, 0xdc, 0xa4, 0xfe, 0x8c, 0xc, 0x5e, 0x24, 0x87, 0x8c, 
+       0xdc, 0x56, 0x50, 0xcc, 0x9c, 0x75, 0xcb, 0xc1, 0x8f, 0x2b, 
+       0x2f, 0x3c, 0xef, 0xaf, 0xb, 0x37, 0x95, 0xf5, 0xe6, 0x96, 
+       0xdf, 0x53, 0x1c, 0x54, 0xbf, 0xf0, 0xac, 0xf2, 0x43, 0xf, 
+       0x3d, 0x64, 0xf4, 0xe, 0xeb, 0xe6, 0x11, 0x4, 0x4d, 0x1d, 
+       0x6f, 0xbd, 0x85, 0x5e, 0x8e, 0xf0, 0x31, 0x52, 0xcc, 0x60, 
+       0xed, 0xc9, 0x29, 0x48, 0x2c, 0x99, 0xa0, 0xaa, 0x41, 0x79, 
+       0xf8, 0xe7, 0x22, 0x31, 0x59, 0x41, 0x1f, 0x48, 0xf, 0xe1, 
+       0x14, 0x45, 0x72, 0xc8, 0xc2, 0x3d, 0xc9, 0xe4, 0xcf, 0xc5, 
+       0x43, 0xd5, 0x21, 0x66, 0xb0, 0xfd, 0x32, 0x87, 0xf6, 0xf9, 
+       0x36, 0x9b, 0xb8, 0xaf, 0x6a, 0xb7, 0x48, 0x10, 0xb8, 0x4d, 
+       0x74, 0x53, 0xc5, 0xbe, 0x13, 0x34, 0x3, 0x2, 0x7a, 0x4c, 
+       0x70, 0xd6, 0x26, 0x73, 0xa4, 0xfe, 0x31, 0x23, 0x6d, 0xbb, 
+       0xdd, 0x1a, 0xa9, 0xe7, 0x4d, 0x59, 0x3c, 0x70, 0x4a, 0x52, 
+       0x24, 0xd3, 0x90, 0x5a, 0x26, 0x86, 0x62, 0x97, 0x9, 0xbf, 
+       0x98, 0x39, 0xeb, 0x90, 0x3, 0x5b, 0x9, 0xbe, 0x2e, 0x96, 
+       0x28, 0xc0, 0xc9, 0x5d, 0x2b, 0x88, 0x87, 0x4e, 0x5a, 0x7c, 
+       0x82, 0x88, 0x5d, 0x16, 0xb, 0xc9, 0xd3, 0xa6, 0xc6, 0x9c, 
+       0x6d, 0xcc, 0x60, 0xe5, 0xec, 0x1d, 0xd8, 0x95, 0x49, 0xe4, 
+       0x29, 0xcf, 0x37, 0x59, 0x41, 0x1b, 0x4a, 0x4b, 0x51, 0xc4, 
+       0x1d, 00, 0x21, 0xce, 0xb3, 0xae, 0xcb, 0xcd, 0x31, 0x67, 
+       0x1b, 0x33, 0x58, 0x9b, 0x4c, 0x25, 0xf9, 0xf7, 0xdd, 0xef, 
+       0xaf, 0xc8, 0x34, 0x39, 0xd1, 0x16, 0xcd, 0x36, 0x88, 0x3f, 
+       0x41, 0x18, 0x7, 0x75, 0x52, 0x9a, 0x32, 0x6f, 0xbd, 0x55, 
+       0x2d, 0xd, 0xf5, 0xf3, 0x70, 0xed, 0x98, 0xc1, 0xb2, 0x60, 
+       0x97, 0x28, 0xc8, 0x35, 0xdd, 0x24, 0x8b, 0xf2, 0x8f, 0x46, 
+       0xf8, 0x85, 0x8, 0xb7, 0x38, 0xf8, 0x6e, 0x7f, 0xf6, 0xb3, 
+       0x9f, 0xd5, 0x49, 0x82, 0xec, 0x5, 0x22, 0x74, 0x7c, 0x4a, 
+       0x8e, 0x1f, 0x68, 0x1a, 0x30, 0xe4, 0xaf, 0xfd, 0x86, 0x63, 
+       0x5b, 0x2, 0x36, 0x4d, 0x4, 0xf8, 0xec, 0x3b, 0xef, 0xf4, 
+       0x97, 0xff, 0xf1, 0xf2, 0x99, 0xea, 0x98, 0x9e, 0xdf, 0xc3, 
+       0x84, 0x63, 0x8a, 0x2c, 0x4, 0xbe, 0x7c, 0xf3, 0x62, 0x7f, 
+       0x8a, 0xb4, 0x45, 0x8b, 0x91, 0x75, 0xdb, 0xed, 0xfe, 0xe7, 
+       0x58, 0x1c, 0x96, 0x48, 0x50, 0x5c, 0x86, 0x39, 0xf2, 0xaf, 
+       0x76, 0x3b, 0x4e, 0x19, 0xf7, 0xcd, 0x9d, 0xa3, 0x46, 0x53, 
+       0x33, 0xe7, 0xa1, 0xca, 0xf3, 0xf3, 0xd4, 0x3b, 0x3f, 0x8b, 
+       0xfa, 0x29, 0x1f, 0x39, 0x44, 0xac, 0xb4, 0x47, 0x21, 0x75, 
+       0xe9, 0xf8, 0x91, 0x6c, 0x4b, 0x38, 0xcb, 0x2, 0x52, 0xe4, 
+       0xac, 0x44, 0xc1, 0x5f, 0x7e, 0x1e, 0x9, 0x3e, 0xd0, 0xf3, 
+       0x64, 0x94, 0xfe, 0x37, 0xd9, 0xc2, 0xd8, 0x30, 0xb5, 0x74, 
+       0xc8, 0xdd, 0xbd, 0x24, 0x69, 0x2c, 0xaa, 0x59, 0x9f, 0x58, 
+       0xb5, 0xa, 0x1b, 0x25, 0xbe, 0x22, 0xe9, 0xea, 0xf9, 0xf7, 
+       0x7f, 0x16, 0x19, 0xab, 0x57, 0x7b, 0x9f, 0x2d, 0xf8, 0x6f, 
+       0x9, 0x67, 0x75, 0x3d, 0x92, 0x64, 0x57, 0x2e, 0xb1, 0xa4, 
+       0x18, 0x3, 0x72, 0x84, 0xd6, 0x23, 0xa3, 0x34, 0x47, 0x67, 
+       0x2, 0xe0, 0xc2, 0xfd, 0x88, 0xac, 0x64, 0x5e, 0x13, 0x95, 
+       0xc, 0xa7, 0x27, 0xae, 0x6e, 0xb8, 0x6e, 0xe5, 0xf4, 0x72, 
+       0xcf, 0x9c, 0x39, 0x22, 0x3c, 0xa4, 0x83, 0xa3, 0xaf, 0x26, 
+       0x9b, 0x68, 0x21, 0xed, 0xd2, 0x3b, 0x92, 0x64, 0x41, 0x3f, 
+       0x66, 0x17, 0xef, 0xac, 0x6c, 0xee, 0xa7, 0x3e, 0xd, 0x8f, 
+       0xcc, 0xb5, 0xf5, 0x8f, 0x3f, 0xa6, 0x94, 0xdd, 0xf4, 0x5b, 
+       0x50, 0x54, 0xa8, 0xcc, 0xc7, 0x67, 0x95, 0xab, 0x23, 0x3, 
+       0xb5, 0xb2, 0xb2, 0x99, 0x24, 0x22, 0x20, 0xcf, 0x4a, 0xe8, 
+       0x23, 0x4, 0x8c, 0xa7, 0x29, 0x5f, 0xe4, 0xe8, 0xa4, 0x6b, 
+       0x45, 0x6f, 0x4c, 0x6e, 0xb0, 0xb, 0x52, 0xb3, 0xdf, 0xf2, 
+       0xb3, 0x17, 0x41, 0x9d, 0x14, 0x49, 0x3, 0x23, 0x50, 0xe3, 
+       0xb3, 0x7a, 0x90, 0x7f, 0x39, 0x77, 0x7f, 0xc, 0x36, 0xf9, 
+       0x48, 0xc7, 0x48, 00, 0x65, 0x19, 0x96, 0x76, 0x63, 0x5d, 
+       0x69, 0xda, 0xc9, 0xbe, 0xbd, 0xd4, 0xdc, 0xcf, 0xdc, 0x23, 
+       0x3f, 0x3f, 0xed, 0x7, 0xb5, 0x8d, 0x3d, 0x72, 0x8e, 0x31, 
+       0x45, 0xb6, 0x35, 0x7a, 0xe4, 0x7, 0xbf, 0x49, 0x53, 0x4a, 
+       0x45, 0x50, 0x68, 0x12, 0x5d, 0x93, 0xa8, 0x52, 0x3f, 0x7a, 
+       0x37, 0x5c, 0xd2, 0xcd, 0x39, 0xaa, 0x8f, 0x24, 0x99, 0x6, 
+       0x6b, 0x56, 0x57, 0xeb, 0xaf, 0xbc, 0xdd, 0x81, 0x84, 0x5, 
+       0xb, 0xe1, 0x12, 0xae, 0xe7, 0xc8, 0x3c, 0xdc, 0x9e, 0x21, 
+       0xdc, 0x95, 0x9f, 0x85, 0x92, 0xdc, 0x5a, 0x31, 0xae, 0xf, 
+       0x66, 0xfa, 0x13, 0x59, 0xeb, 0x30, 0xd, 0xf6, 0x73, 0x9f, 
+       0xfb, 0xdc, 0xb0, 0x6a, 0x30, 0x20, 0x67, 0x1b, 0x3b, 0x84, 
+       0xa3, 0x29, 0xc5, 0x25, 0xe8, 0x14, 0x45, 0x5a, 0xa6, 0xec, 
+       0xc3, 0xf6, 0x89, 0x8, 0x98, 0x19, 0xfc, 0x83, 0xfd, 0xa8, 
+       0xf3, 0xff, 0xb1, 0xd6, 0x37, 0x47, 0x99, 0xc2, 0x34, 0xd8, 
+       0x28, 0xf3, 0xf5, 0x47, 0xeb, 0x95, 0x1d, 0xbb, 0xf3, 0xcf, 
+       0x3d, 0xab, 0x54, 0xab, 0x3d, 0x3c, 0xda, 0xc3, 0x25, 0x20, 
+       0x57, 0x31, 0x3e, 0x3b, 0x43, 0xba, 0x75, 0x82, 0xfc, 0x8e, 
+       0x60, 0xca, 0xe7, 0xff, 0xca, 0x9f, 0x66, 0xa4, 0x1c, 0x23, 
+       0x6, 0x96, 0x23, 0xf2, 0x89, 0x6f, 0xfe, 0x13, 0x5c, 0xf2, 
+       0x89, 0x7, 0xb7, 0xe1, 0x34, 0x9b, 0x5f, 0x71, 0x4e, 0xc0, 
+       0x42, 0x9d, 0x55, 0x27, 0x95, 0xdd, 0xfe, 0xa5, 0x2f, 0xa2, 
+       0x70, 0xc3, 0x46, 0x8c, 0xbf, 0xeb, 0x2e, 0xf5, 0x3c, 0x12, 
+       0xff, 0x46, 0x4, 0x6c, 0xbb, 0x7c, 0x81, 0xef, 0xe2, 0xcf, 
+       0x5f, 0x91, 0x6e, 0x7a, 0xf5, 0x20, 0x18, 0x77, 0x3, 0x8e, 
+       0xc8, 0xf3, 0x65, 0x39, 0x6f, 0x71, 0x4e, 0x74, 0xc2, 0xe3, 
+       0x64, 0x60, 0x5a, 0x25, 0x27, 0xd6, 0xb2, 0x64, 0x4e, 0xe5, 
+       0x28, 0xcd, 0x6, 0x69, 0x7a, 0xeb, 0x4d, 0x74, 0x9, 0xf8, 
+       0xa9, 0x5f, 0xfc, 0x12, 0xec, 0xb2, 0x1, 0x66, 0x35, 0x59, 
+       0xe, 0x96, 0xdd, 0xb6, 0xf1, 0xf5, 0x3f, 0xc0, 0xe9, 0x3b, 
+       0xa9, 0xc6, 0x5, 0xf8, 0xaf, 0xaa, 0x4e, 0xe1, 0x7b, 0x72, 
+       0xf6, 0x5f, 0x9f, 0x41, 0xd4, 0x20, 0xfe, 0x75, 0xcf, 0x5e, 
+       0xcc, 0x93, 0x39, 0x98, 0x9b, 0xd5, 0x8b, 0x64, 0x1, 0xe1, 
+       0x96, 0xf5, 0x6b, 0xa7, 0xe8, 0x9a, 0x9a, 0xde, 0x78, 0x3, 
+       0x45, 0x1f, 0xf9, 0x8, 0x6c, 0x86, 0xad, 0x11, 0x9d, 0x26, 
+       0x16, 0xdb, 0x32, 0x71, 0x51, 0x57, 0xa2, 0xee, 0x95, 0x97, 
+       0x85, 0x3b, 0x5e, 0xed, 0x22, 0x25, 0xa4, 0x6f, 0x8b, 0xfe, 
+       0xf8, 0xdf, 0xdf, 0x7f, 0x3f, 0x8, 0xa8, 0x8e, 0x5f, 0x25, 
+       0xdb, 0x95, 0x4f, 0x88, 0xea, 0x94, 0xda, 0x44, 0x4d, 0xd, 
+       0xbf, 0xfd, 0xd, 0x5a, 0x79, 0xdc, 0xc8, 0x62, 0xb2, 0x94, 
+       0xb3, 0x57, 0xe4, 0x63, 0x1d, 0xdd, 0xbe, 0x83, 0x59, 0x9, 
+       0xa2, 0x49, 0xbc, 0xf9, 0x6f, 0x1f, 0x2, 0x67, 0x4e, 0x9e, 
+       0x38, 0xbd, 0x53, 0x56, 0x45, 0xc6, 0xbd, 0x5d, 0x9e, 0x3e, 
+       0xe5, 0x87, 0x35, 0x78, 0xc0, 0x9a, 0x87, 0xbf, 0x56, 0xc8, 
+       0x81, 0xec, 0xac, 0xe4, 0x24, 0xdc, 0xe9, 0xdb, 0xf3, 0xb9, 
+       0x24, 0x7, 0xa9, 0xd3, 0xcb, 0x66, 0x22, 0xc9, 0xa0, 0xa6, 
+       0x8d, 0x15, 0xbb, 0xa5, 0x9c, 0xed, 0x3a, 0x23, 0x87, 0xbd, 
+       0x7c, 0x9f, 0x24, 0xcb, 0x96, 0xa3, 0x6, 0x3b, 0xe5, 0x9c, 
+       0x22, 0xf, 0x61, 0xf2, 0x8b, 0x25, 0x4f, 0x3f, 0xfd, 0x74, 
+       0x40, 0x5d, 0xf9, 0xbb, 0x80, 0x47, 0x1f, 0x7d, 0x14, 0xcb, 
+       0x96, 0x2d, 0x53, 0xfe, 0x3, 0xd2, 0xdd, 0x7f, 0x54, 0x79, 
+       0x50, 0x9d, 0xb3, 0xa0, 0x87, 0x53, 0xb4, 0x1f, 0x2e, 0x91, 
+       0xa1, 0xad, 0x24, 0xcb, 0xc0, 0x72, 0x30, 0x6a, 0xd9, 0xf5, 
+       0xae, 0xbf, 0x6e, 0xa9, 0x72, 0x6e, 0x82, 0x7, 0x2f, 0x49, 
+       0x3c, 0x7c, 0xc9, 0xdf, 0x2, 0x18, 0xe9, 0x7d, 0xe9, 0xda, 
+       0x1f, 0xfb, 0xd8, 0xc7, 0xf0, 0xe, 0x7f, 0xb7, 0xe3, 0x23, 
+       0x9e, 0x9e, 0xd9, 0x61, 0x38, 0x46, 0xd4, 0xe0, 0xdb, 0xc2, 
+       0xd4, 0xe1, 0xb1, 0xda, 0x96, 0x81, 0xb5, 0xcb, 0x81, 0x11, 
+       0x35, 0x77, 0x4a, 0x8d, 0xf8, 0x93, 0xb4, 0x44, 0x19, 0x4d, 
+       0xf9, 0x1d, 0x1a, 0x12, 0xbf, 0xb8, 0x67, 0x3c, 0x5f, 0xac, 
+       0x3c, 0xc3, 0xfc, 0xe3, 0xf6, 0x87, 0x26, 0x87, 0xec, 0xce, 
+       0x5b, 0x49, 0x96, 0x81, 0xed, 0x90, 0xf3, 0x87, 0x5a, 0xe0, 
+       0x6f, 0x12, 0x90, 0x3c, 0x24, 0xad, 0xbf, 0x83, 0xca, 0xbd, 
+       0x9d, 0xc1, 0x87, 0xa6, 0xc3, 0x81, 0xe0, 0xb9, 0x47, 0x3d, 
+       0x6a, 0xb7, 0x1f, 0x3a, 0x14, 0xb0, 0xcf, 0x1b, 0x2e, 0x4d, 
+       0xb4, 0xfe, 0x96, 0x81, 0xa5, 0x24, 0xa4, 0xa7, 0x8a, 0x9, 
+       0xb2, 0xaa, 0xe1, 0xf7, 0xd7, 0xd6, 0xac, 0x59, 0xa3, 0xce, 
+       0x14, 0xdf, 0x72, 0xcb, 0x2d, 0xea, 0x99, 0x3f, 0x7d, 0x79, 
+       0xf2, 0xc9, 0x27, 0xd5, 0x6f, 0x63, 0xc3, 0x55, 0x70, 0x92, 
+       0x68, 0x26, 0xf4, 0xea, 0x28, 0x9b, 0xe7, 0xa7, 0x28, 0x69, 
+       0x59, 0x44, 0x96, 0x81, 0x75, 0x89, 0xd6, 0x5e, 0x73, 0x96, 
+       0x82, 0xc2, 0x73, 0xf2, 0x9b, 0x1d, 0xee, 0xd4, 0x1d, 0x90, 
+       0x5f, 0x6f, 0xf0, 0x88, 0xed, 0x77, 0xbe, 0xf3, 0x1d, 0x65, 
+       0xf3, 0x37, 0x3d, 0x73, 0x64, 0xc1, 0x1e, 0x8e, 0xca, 0xc, 
+       0xa3, 0x6f, 0x6f, 0x14, 0x87, 0x3d, 0xc3, 0xe5, 0x13, 0xca, 
+       0xdf, 0xb2, 0xa9, 0x27, 0x55, 0x8e, 0xdb, 0xe6, 0xc8, 0xc1, 
+       0x8f, 0x56, 0x11, 0x1e, 0xb2, 0x93, 0x93, 0x51, 0x22, 0x3f, 
+       0xfb, 0xe6, 0x46, 0x16, 0x8f, 0xe1, 0x5e, 0x10, 0x99, 0x58, 
+       0x7f, 0x7c, 0x47, 0xef, 0x1e, 0xe8, 0xca, 0xf0, 0x67, 0x6a, 
+       0x9a, 0xc8, 0xd1, 0xdb, 0xa7, 0x4f, 0xd3, 0x8f, 0x18, 0x6f, 
+       0xf2, 0x64, 0x8e, 0x3f, 0x61, 0x18, 0x87, 0x65, 0x9c, 0x65, 
+       0xfe, 0x9, 0xbe, 0x45, 0x39, 0xdd, 0xf, 0xc8, 0x4f, 0xb8, 
+       0xb3, 0x85, 0xc3, 0x1c, 0x91, 0x35, 0x50, 0xfa, 0x47, 0xa2, 
+       0x8d, 0x72, 0x7c, 0x6f, 0x8e, 0x6f, 0xd9, 0xc7, 0x78, 0x9, 
+       0x99, 0x59, 0x91, 0xa2, 0x9b, 0xe, 0xb3, 0x14, 0xec, 0x4, 
+       0x51, 0xc9, 0xa4, 0xfb, 0x7e, 0xd8, 0x9b, 0x23, 0xdc, 0xfd, 
+       0xb7, 0x75, 0x6b, 0x45, 0x50, 0x48, 0x8e, 0xaa, 0x52, 0xb, 
+       0x65, 0xb, 0xe5, 0x1b, 0xcb, 0xbd, 0x73, 0x2e, 0x13, 0x4c, 
+       0x90, 0x63, 0x7d, 0x69, 0x6, 0xbd, 0x54, 0x54, 0x99, 0xc, 
+       0x11, 0xc9, 0x52, 0xb0, 0xdc, 0x7c, 0xca, 0x5b, 0xb1, 0x12, 
+       0x89, 0xbe, 0xf7, 0x6e, 0xb6, 0x9c, 0x32, 0xdd, 0xba, 0xe9, 
+       0x4e, 0x50, 0x71, 0x1e, 0x8e, 0xd8, 0x18, 0x3c, 0x47, 0xf1, 
+       0x83, 0x3f, 0xdb, 0xe8, 0x8f, 0x92, 0x3e, 0x6d, 0x3a, 0xb2, 
+       0x62, 0x58, 0xe7, 0xfa, 0x33, 0x1a, 0xe4, 0xb0, 0xec, 0x9d, 
+       0xd5, 0xf9, 0xe6, 0xad, 0x5c, 0x9, 0xe, 0x56, 0xf5, 0xbf, 
+       0xfa, 0xa5, 0xf2, 0xe2, 0xef, 0xd9, 0xff, 0x73, 0xe3, 0x6, 
+       0xbc, 0x71, 0xf6, 0x2c, 0xf6, 0x37, 0x5c, 0x42, 0xab, 0xfc, 
+       0xd2, 0xf9, 0xac, 0xc8, 0xc3, 0xdc, 0xc7, 0x59, 0x31, 0x71, 
+       0x2, 0xa8, 0x72, 0x65, 0xa3, 0x68, 0xa2, 0xfe, 0x6a, 0xca, 
+       0xe7, 0x3f, 0xef, 0x6f, 0x30, 0xed, 0x6f, 0x85, 0x6d, 0x39, 
+       0x58, 0x56, 0x8a, 0x2b, 0x96, 0x4c, 0x19, 0x71, 0xab, 0x9e, 
+       0x7a, 0xd2, 0xaf, 0x61, 0xa4, 0xaa, 0xd4, 0xa8, 0x2e, 0xd, 
+       0x55, 0xf9, 0x2c, 0xf9, 0xd1, 0xe2, 0xc4, 0x7b, 0xee, 0x45, 
+       0xa2, 0x4c, 0x51, 0x23, 0x41, 0x23, 0x2, 0x96, 0x15, 0x4d, 
+       0x95, 0xb5, 0x6a, 0xd9, 0xdf, 0xff, 0x83, 0x2c, 0xce, 0xab, 
+       0x50, 0xcf, 0x13, 0xa9, 0xd2, 0xc5, 0xa9, 0x6d, 0xc, 0x22, 
+       0xf1, 0x4f, 0x90, 0x45, 0xc1, 0xe4, 0x7, 0x1e, 0x44, 0xaa, 
+       0x2c, 0x8, 0x8c, 0x83, 0x5c, 0x50, 0xdc, 0x18, 0x3d, 0x46, 
+       0xc, 0x2c, 0xeb, 0xc5, 0x1, 0x86, 0x26, 0x47, 0xb4, 0x86, 
+       0xfd, 0xa2, 0xb1, 0xb8, 0x2c, 0x67, 0x23, 0x92, 0x65, 0x77, 
+       0xae, 0x4d, 0x24, 0xa3, 0x9c, 0x45, 0x8b, 0xd4, 0xe2, 0xbe, 
+       0x78, 0xcb, 0x47, 0x55, 0x43, 0x24, 0xf8, 0x76, 0xd9, 0x63, 
+       0xc4, 0x13, 0x31, 0xb9, 0x69, 0xb0, 0x66, 0x95, 0x5c, 0x1, 
+       0xa5, 0x53, 0x1a, 0xe2, 0x3e, 0x2b, 0xcf, 0x60, 0x5c, 0xac, 
+       0xf7, 0x6, 0xf1, 0x20, 0xe7, 0x87, 0x44, 0xa6, 0xc1, 0xf2, 
+       0xdb, 0x31, 0x63, 0x85, 0xf8, 0x6b, 0x6a, 0x33, 0x64, 0xed, 
+       0xd4, 0x63, 0xa6, 0xe4, 0x51, 0x88, 0x1b, 0x7, 0x3b, 0xa, 
+       0x8d, 0xfe, 0xa1, 0x14, 0x19, 0xe7, 0xec, 0x87, 0xd2, 0xcc, 
+       0xa3, 0x50, 0x48, 0x9c, 0xb3, 0xa3, 0xd0, 0xe8, 0x1f, 0x4a, 
+       0x91, 0x71, 0xce, 0x7e, 0x28, 0xcd, 0x3c, 0xa, 0x85, 0xc4, 
+       0x39, 0x3b, 0xa, 0x8d, 0xfe, 0xa1, 0x14, 0x69, 0x5a, 0x36, 
+       0x36, 0x2b, 0x8f, 0x7e, 0x28, 0x28, 0xa2, 0x2c, 0xc4, 0x34, 
+       0xd8, 0xe1, 0x1e, 0x33, 0x88, 0xb2, 0x3e, 0xa6, 0xa2, 0x99, 
+       0x5d, 0x81, 0xc5, 0xdf, 0x59, 0x53, 0xcd, 0x7b, 0xd, 0x45, 
+       0x8e, 0x73, 0xf6, 0x1a, 0x62, 0x96, 0xa9, 0xaa, 0xc6, 0x39, 
+       0x6b, 0xaa, 0xb9, 0xae, 0xa1, 0xc8, 0x71, 0xce, 0x5e, 0x43, 
+       0xcc, 0x32, 0x55, 0xd5, 0x38, 0x67, 0x4d, 0x35, 0xd7, 0x35, 
+       0x14, 0x39, 0xce, 0xd9, 0x6b, 0x88, 0x59, 0xa6, 0xaa, 0x1a, 
+       0xe7, 0xac, 0xa9, 0xe6, 0xba, 0x86, 0x22, 0xc7, 0x39, 0x7b, 
+       0xd, 0x31, 0xcb, 0x54, 0x55, 0xe3, 0x9c, 0x35, 0xd5, 0x5c, 
+       0xd7, 0x50, 0xe4, 0x38, 0x67, 0xaf, 0x21, 0x66, 0x99, 0xaa, 
+       0xea, 0x75, 0xc5, 0x59, 0xd3, 0xda, 0x45, 0xb3, 0x1a, 0x3d, 
+       0x53, 0x4d, 0x3f, 0xc2, 0x91, 0x4d, 0x83, 0x35, 0xfb, 0x59, 
+       0xb3, 0x91, 0xac, 0xbf, 0xd9, 0x9f, 0xca, 0x5d, 0x57, 0xdd, 
+       0x38, 0xe, 0x76, 0x24, 0xbb, 0xde, 0x68, 0xe6, 0x1d, 0xe7, 
+       0xec, 0x68, 0xb6, 0xfe, 0x48, 0x96, 0x1d, 0xe7, 0xec, 0x48, 
+       0xb6, 0xee, 0x68, 0xe6, 0x1d, 0xe7, 0xec, 0x68, 0xb6, 0xfe, 
+       0x48, 0x96, 0x1d, 0xe7, 0xec, 0x48, 0xb6, 0xee, 0x68, 0xe6, 
+       0x1d, 0xe7, 0xec, 0x68, 0xb6, 0xfe, 0x48, 0x96, 0x1d, 0xe7, 
+       0xec, 0x48, 0xb6, 0xee, 0x68, 0xe6, 0x1d, 0xe7, 0xec, 0x68, 
+       0xb6, 0xfe, 0x48, 0x96, 0x1d, 0xe7, 0xec, 0x48, 0xb6, 0xee, 
+       0x68, 0xe6, 0x1d, 0xe7, 0xec, 0x68, 0xb6, 0xfe, 0x48, 0x96, 
+       0x7d, 0x5d, 0x71, 0xd6, 0xb4, 0x2a, 0xd5, 0xac, 0xfa, 0x72, 
+       0x24, 0x39, 0x65, 0x36, 0x6f, 0x53, 0x60, 0xfb, 0xe5, 0x33, 
+       0x47, 0x91, 0xae, 0x3e, 0x37, 0x5b, 0x78, 0xac, 0xf1, 0xcd, 
+       0x5e, 0x7d, 0x7e, 0x5d, 0x75, 0xe3, 0x38, 0xd8, 0x58, 0xbb, 
+       0xd7, 0x58, 0x4d, 0x1f, 0xe7, 0xec, 0x58, 0xe5, 0x4c, 0xac, 
+       0xf5, 0x8a, 0x73, 0x36, 0xd6, 0x16, 0x1c, 0xab, 0xe9, 0xe3, 
+       0x9c, 0x1d, 0xab, 0x9c, 0x89, 0xb5, 0x5e, 0x71, 0xce, 0xc6, 
+       0xda, 0x82, 0x63, 0x35, 0x7d, 0x9c, 0xb3, 0x63, 0x95, 0x33, 
+       0xb1, 0xd6, 0x2b, 0xce, 0xd9, 0x58, 0x5b, 0x70, 0xac, 0xa6, 
+       0x8f, 0x73, 0x76, 0xac, 0x72, 0x26, 0xd6, 0x7a, 0xc5, 0x39, 
+       0x1b, 0x6b, 0xb, 0x8e, 0xd5, 0xf4, 0x71, 0xce, 0x8e, 0x55, 
+       0xce, 0xc4, 0x5a, 0xaf, 0x38, 0x67, 0x63, 0x6d, 0xc1, 0xb1, 
+       0x9a, 0x3e, 0xce, 0xd9, 0xb1, 0xca, 0x99, 0x58, 0xeb, 0x75, 
+       0x5d, 0x71, 0xd6, 0xd4, 0xf6, 0xc7, 0x50, 0x2d, 0xeb, 0x94, 
+       0x2f, 0xcd, 0x57, 0xc9, 0x17, 0x34, 0xfb, 0x8c, 0xd7, 0x5f, 
+       0xc, 0x95, 0x28, 0x44, 0x78, 0x92, 0x7c, 0x2a, 0x78, 0xa6, 
+       0xdc, 0xfc, 0x92, 0x1c, 0xe5, 0x17, 0x74, 0x43, 0x64, 0x11, 
+       0xd2, 0xcb, 0x34, 0xd8, 0x48, 0xfb, 0x2b, 0x67, 0xe4, 0xd3, 
+       0xfa, 0x27, 0xe5, 0xc6, 0x16, 0xb7, 0x3d, 0xc4, 0x67, 0x42, 
+       0xd, 0xc5, 0xcb, 0xa7, 0x26, 0x23, 0x7e, 0x7e, 0xdb, 0xe6, 
+       0xb1, 0xa1, 0xbc, 0xac, 0x1c, 0x53, 0xe5, 0x7b, 0xc7, 0x56, 
+       0x92, 0x29, 0xb0, 0x4d, 0x72, 0x81, 0x10, 0x5b, 0x3c, 0x1c, 
+       0x35, 0xc8, 0xb7, 0xff, 0x13, 0x53, 0x13, 0x31, 0x30, 0xa1, 
+       0x1f, 0xd9, 0x45, 0x39, 0xf2, 0x39, 0x71, 0xdf, 0xdd, 0x96, 
+       0x72, 0xb1, 0xbd, 0x83, 0x37, 0x6e, 0xc9, 0x3d, 0x97, 0xfc, 
+       0x53, 0x97, 0x7b, 0xca, 0x37, 0x52, 0xe5, 0x16, 0x4c, 0x15, 
+       0x87, 0xfe, 0x7c, 0x9f, 0x6c, 0x36, 0x7, 0x5a, 0x2f, 0xb5, 
+       0xa2, 0xa3, 0xb6, 0x43, 0xdd, 0x53, 0x9b, 0x6b, 0xf8, 0x64, 
+       0x77, 0xa8, 0x32, 0xd9, 0x8b, 0xcc, 0x90, 0x29, 0xb0, 0xd1, 
+       0x66, 0x9c, 0x5d, 0x94, 0x85, 0x29, 0xf3, 0x26, 0xfb, 0xc0, 
+       0xa, 0x24, 0x1, 0xe6, 0x20, 0x34, 0x82, 0x15, 0xe0, 0x4, 
+       0x4b, 0x3f, 0xbb, 0xb8, 0xd9, 0x20, 0x5e, 0xb7, 0x17, 0x6c, 
+       0x4d, 0x65, 0x8d, 0x2, 0x1b, 0x6d, 0x59, 0x66, 0xe2, 0x5d, 
+       0x57, 0x3, 0x54, 0x1c, 0xac, 0x99, 0xae, 0x71, 0x2d, 0xc5, 
+       0x8d, 0x73, 0xf6, 0x5a, 0xe2, 0x96, 0x99, 0xba, 0xc6, 0x39, 
+       0x6b, 0xa6, 0xb5, 0xae, 0xa5, 0xb8, 0xa6, 0xe6, 0x59, 0x9e, 
+       0x96, 0xe1, 0x44, 0x1e, 0xee, 0xc6, 0x87, 0xcb, 0x86, 0xb, 
+       0xc4, 0x62, 0x6d, 0x4, 0xe6, 0x75, 0xfc, 0xf8, 0xd5, 0xab, 
+       0xa8, 0x8c, 0xf9, 0x71, 0x6e, 0x2e, 0x30, 0xdc, 0x24, 0x61, 
+       0xc, 0x8b, 0xe4, 0x36, 0x5, 0xb6, 0xb1, 0xb1, 0x11, 0x6d, 
+       0x6d, 0x6d, 0xf0, 0xc8, 0x5f, 0x58, 0x12, 0x41, 0xc9, 0x91, 
+       0x10, 0x3a, 0xdb, 0xdf, 0x3c, 0xb3, 0xd, 0xdd, 0x6d, 0xde, 
+       0x3b, 0x7c, 0xa4, 0xbe, 0x42, 0x22, 0x50, 0x28, 0xcb, 0x86, 
+       0xf4, 0xac, 0x34, 0x7c, 0xe2, 0x6b, 0x9f, 0x44, 0x42, 0xa2, 
+       0x37, 0x2d, 0xaf, 0xbc, 0x89, 0x74, 0xed, 0xd, 0xef, 0xff, 
+       0x29, 0x2d, 0x2d, 0x65, 0xea, 0xa8, 0x29, 0x74, 0xad, 0xc2, 
+       0x24, 0x2f, 0x94, 0xb, 0xe, 0x7a, 0x5d, 0xbd, 0xa8, 0xe9, 
+       0x3e, 0x23, 0x88, 0x80, 0xe2, 0xb2, 0xf1, 0x70, 0x38, 0x58, 
+       0x61, 0x79, 0xf5, 0x7d, 0x22, 0x5f, 0x9a, 0x8, 0xef, 0xe3, 
+       0xa6, 0x15, 0x85, 0xcc, 0xa1, 0x66, 0x7f, 0xd, 0xda, 0x9a, 
+       0xda, 0x42, 0x86, 0x65, 0x15, 0x78, 0xef, 0xf9, 0x98, 0x30, 
+       0x73, 0x82, 0x92, 0xb4, 0x6, 0xfa, 0x79, 0xab, 0x38, 0xc5, 
+       0x4d, 0xa, 0x95, 0xcc, 0xde, 0x86, 0xe6, 0xfa, 0x16, 0x5c, 
+       0x69, 0x6c, 0x85, 0xa3, 0xd3, 0x8e, 0xf2, 0xf2, 0x72, 0x70, 
+       0xe1, 0x61, 0x86, 0x4c, 0x81, 0xe5, 0x6a, 0x64, 0xf5, 0xf2, 
+       0xd5, 0xe8, 0x7f, 0xa7, 0x1f, 0x17, 0xfa, 0xeb, 0xe0, 0xec, 
+       0x72, 0xa2, 0x6c, 0xe9, 0x74, 0xa9, 0x88, 0x48, 0xbe, 0x4a, 
+       0xfc, 0xe3, 0x57, 0xf2, 0x6d, 0x70, 0xc8, 0x73, 0x28, 0xda, 
+       0xf0, 0x17, 0xb7, 0xa2, 0xbf, 0xb7, 0xdf, 0x2b, 0x22, 0x4a, 
+       0xe5, 0xf, 0xed, 0x38, 0x8c, 0xea, 0xfd, 0xd5, 0x2a, 0x6a, 
+       0xc1, 0x44, 0xef, 0xbd, 0x96, 0x89, 0x49, 0x89, 0x28, 0x9d, 
+       0x5b, 0xaa, 0x44, 0x49, 0x5, 0x56, 0x6e, 0x8c, 0xe0, 0x28, 
+       0xda, 0x52, 0xdf, 0x8c, 0x9a, 0x43, 0x67, 0xe0, 0xe8, 0xb6, 
+       0x63, 0x4e, 0xe9, 0x1c, 0x75, 0x9, 0xd9, 0x88, 0xcb, 0xc6, 
+       0xbc, 0xf5, 0x6c, 0xf5, 0xb2, 0xd5, 0xd8, 0xfe, 0xee, 0x76, 
+       0x34, 0x5c, 0x68, 0xc0, 0xf9, 0x83, 0xe7, 0x51, 0xba, 0x70, 
+       0x6a, 00, 0xb6, 0xe6, 0xba, 0x16, 0x74, 0x36, 0x77, 0x9, 
+       0x28, 0xa9, 0x2e, 0x39, 0x23, 0x8e, 0x82, 0x92, 0x2, 0x54, 
+       0xac, 0x9c, 0x2d, 0x6e, 0xaf, 0x6c, 0x7c, 0x6a, 0x5f, 0x35, 
+       0x28, 0x7, 0x93, 0xf2, 0x8a, 0xf3, 0xf0, 0x99, 0x7f, 0xfa, 
+       0x74, 0x40, 0x1e, 0xc6, 0x87, 0xf6, 0xe6, 0x76, 0xec, 0x7b, 
+       0x53, 0xae, 0x8e, 0x93, 0x37, 0x60, 0x7a, 0xd1, 0x74, 0xc5, 
+       0x55, 0x63, 0x78, 0xb4, 0x6e, 0x53, 0x9c, 0xd5, 0x99, 0xf2, 
+       0x46, 0xa5, 0x55, 0x37, 0xaf, 0xc2, 0xdb, 0xbb, 0xdf, 0xc6, 
+       0xa5, 0xd3, 0x8d, 0x72, 0x9f, 0x56, 0x32, 0x26, 0x56, 0x4c, 
+       0xd4, 0xc1, 0xd8, 0xbf, 0x6d, 0x3f, 0x2a, 0x5f, 0x97, 0x2b, 
+       0xa3, 0xc, 0xb4, 0xfe, 0x81, 0x75, 0x58, 0xf1, 0xf1, 0xe5, 
+       0xca, 0xa7, 0xbe, 0xba, 0x1, 0xaf, 0x3c, 0xf9, 0xa, 0x3c, 
+       0x6e, 0xf, 0xd2, 0xe4, 0x5d, 0x7d, 0xf0, 0x5b, 0xf, 0x22, 
+       0x23, 0x27, 0xc3, 0x10, 0xfb, 0xaa, 0xb3, 0xbb, 0xbd, 0x1b, 
+       0xef, 0xff, 0xe1, 0x7d, 0xb8, 0x3b, 0xdd, 0x98, 0x92, 0x3d, 
+       0x5, 0xf3, 0xe5, 0xca, 0x8c, 0xe1, 0xd2, 0xb0, 0xe7, 0x59, 
+       0xbe, 0xbf, 0x2b, 0x6e, 0x5a, 0x81, 0x3c, 0x4f, 0x1e, 0x2e, 
+       0x1c, 0xb9, 0x80, 0xc6, 0x33, 0x8d, 0x51, 0xd5, 0xa1, 0xfd, 
+       0x72, 0x3b, 0xb6, 0x3e, 0xf6, 0x22, 0xfa, 0x7a, 0xfb, 0x90, 
+       0x90, 0x94, 0x80, 0xfb, 0x9e, 0xb8, 0xf, 0xf9, 0x13, 0xae, 
+       0x5e, 0x74, 0x62, 0xcc, 0xc4, 0xd9, 0xe3, 0x54, 0x40, 0xfb, 
+       0xdb, 0xfa, 0x31, 0x3e, 0x65, 0x3c, 0x6e, 0x94, 0x9b, 0x26, 
+       0xd8, 0x4b, 0x86, 0x4b, 0xc3, 0xe2, 0xac, 0x2e, 0x8c, 0x37, 
+       0x2d, 0x2d, 0x76, 0xde, 0x8c, 0xbd, 0x87, 0xf7, 0xe0, 0xcc, 
+       0xbe, 0x33, 0x48, 0x4e, 0x49, 0x44, 0xfe, 0xc4, 0x3c, 0xac, 
+       0xf8, 0xf4, 0xa, 0x2c, 0xde, 0x7c, 0xb3, 0xea, 0xc6, 0x6a, 
+       0x19, 0x27, 0x5d, 0x39, 0x23, 0x33, 0x1d, 0xce, 0x6e, 0x27, 
+       0xb6, 0x3e, 0xfa, 0x22, 0x3a, 0x9a, 0x3b, 0x54, 0xa5, 0x3f, 
+       0xf5, 0xc8, 0x27, 0x31, 0x79, 0xf6, 0x24, 0x9d, 0x5d, 0x80, 
+       0xed, 0xea, 0x73, 0x61, 0xff, 0x1b, 0xfb, 0xd0, 0xdb, 0xd2, 
+       0x83, 0x42, 0x47, 0x1, 0x96, 0xdc, 0xbc, 0x44, 0x6, 0xc3, 
+       0xd0, 0x63, 0x41, 0x40, 0xc2, 0x8, 0xf, 0x31, 0x81, 0x65, 
+       0xbe, 0xd3, 0xe4, 0x32, 0x22, 0xde, 0x1a, 0x71, 0xe0, 0xf4, 
+       0x1, 0x54, 0xed, 0x39, 0x85, 0xb9, 0x6b, 0x2a, 0x90, 0x53, 
+       0x98, 0x83, 0xf4, 0xec, 0x74, 0x5, 0x48, 0x8d, 0xa6, 0x7c, 
+       0x6f, 0x65, 0x70, 0x7d, 0xe9, 0x89, 0x97, 0xd1, 0x78, 0xd6, 
+       0xdb, 0x3, 0xd6, 0xdd, 0xbf, 0x16, 0xa5, 0xf3, 0x4b, 0xd1, 
+       0xd3, 0xd9, 0xe3, 0x1f, 0xdc, 0xd2, 0xe4, 0x6a, 0x56, 0x92, 
+       0x7b, 0xc0, 0x8d, 0xca, 0xb7, 0x2b, 0xd1, 0x71, 0xa9, 0x3, 
+       0xb9, 0xee, 0x5c, 0x2c, 0x5b, 0xb9, 0xc, 0x89, 0x16, 0xdc, 
+       0x6b, 0x19, 0x33, 0x58, 0x56, 0x8e, 0xb7, 0x17, 0x72, 0x1a, 
+       0x38, 0x52, 0x7b, 0x4, 0xc7, 0xff, 0x74, 0x12, 0xb, 0xd6, 
+       0xcd, 0x43, 0xfa, 0xa0, 0x77, 0xb0, 0xa1, 0xa6, 0x41, 0x46, 
+       0x5e, 0xef, 0x80, 0xc4, 0x34, 0x6f, 0xfd, 0xf7, 0x76, 0x65, 
+       0xe8, 0xd6, 0xf4, 0xd8, 0x6b, 0x8f, 0x21, 0x2d, 0x23, 0xd, 
+       0x47, 0xfe, 0x74, 0x4, 0x2d, 0xb5, 0x2d, 0xc8, 0xe8, 0xcb, 
+       0xc0, 0xf2, 0x95, 0xcb, 0x61, 0xd5, 0x67, 0x86, 0xa3, 0x79, 
+       0x67, 0x23, 0x48, 0x10, 0xba, 0x9a, 0x72, 0xe3, 0xf7, 0x82, 
+       0x5, 0x28, 0x2b, 0x2a, 0x43, 0x52, 0x4f, 0x12, 0x8e, 0xbe, 
+       0x73, 0x5c, 0x75, 0xd9, 0xab, 0xa1, 0xd1, 0xbb, 0xaa, 0xde, 
+       0xaf, 0x42, 0xc3, 0xe9, 0x6, 0xa4, 0xf6, 0xa4, 0x62, 0xf9, 
+       0x92, 0xe5, 0xc8, 0xb0, 0xf0, 0xb6, 0x97, 0x70, 0x9c, 0x25, 
+       0x40, 0x6d, 0xa2, 0xaa, 0x29, 0xbb, 0xeb, 0x22, 0x5e, 0x4b, 
+       0xb3, 0xab, 0xf, 0x67, 0xdb, 0xcf, 0xe0, 0xe8, 0xce, 0x63, 
+       0x98, 0xbf, 0x7e, 0x1e, 0x92, 0x53, 0xbd, 0x77, 0x6c, 0x95, 
+       0x94, 0x95, 0xe0, 0x9b, 0xbf, 0xfd, 0x47, 0xe9, 0xda, 0xe1, 
+       0xd5, 0x32, 0xe7, 0x8e, 0xd6, 0xe2, 0xdc, 0xd1, 0x73, 0x48, 
+       0xeb, 0x4e, 0xc3, 0xd2, 0xc5, 0x4b, 0x31, 0x94, 0xe, 0xca, 
+       0x50, 0xb1, 0x50, 0xc, 0x9, 0xf2, 0x8b, 0x86, 0xb3, 0x86, 
+       0x3c, 0x23, 0x3b, 0x13, 0x44, 0x4c, 0x5c, 0xba, 0x74, 0x29, 
+       0x4a, 0x52, 0x27, 0xc8, 0xa5, 0x9b, 0x3, 0x38, 0xf6, 0xc7, 
+       0xe3, 0x18, 0x70, 0x51, 0x12, 0x1a, 0x9a, 0x2e, 0x9e, 0xbe, 
+       0x88, 0x53, 0xef, 0x9f, 0x42, 0x4a, 0x67, 0xa, 0x16, 0x2d, 
+       0x58, 0x4, 0xde, 0x92, 0x68, 0x35, 0x5, 0x80, 0x95, 0xab, 
+       0x53, 0x83, 0x5a, 0xc3, 0x50, 0x60, 0xa4, 0x30, 0x7f, 0x34, 
+       0x4a, 0x59, 0x2b, 0x96, 0xaf, 0xc0, 0xb8, 0x84, 0x71, 0xe8, 
+       0x6d, 0xea, 0xc5, 0x89, 0x5d, 0x27, 0xd5, 0x7c, 0xea, 0x8f, 
+       0x10, 0xc2, 0x71, 0xf9, 0x82, 0x8, 0xfd, 0xbb, 0x4e, 0x20, 
+       0xa5, 0x3b, 0x5, 0xb, 0x2a, 0x16, 0xa8, 0xbb, 0xf4, 0x42, 
+       0x44, 0x33, 0xe3, 0xa5, 0xeb, 0xaa, 0x6d, 0x95, 0x36, 00, 
+       0xec, 0xa0, 0xdc, 0x18, 0x51, 0x1b, 0xb2, 0x47, 0x25, 0xc, 
+       0xb7, 0xe2, 0x31, 0xa6, 0x4d, 0x4d, 0x95, 0xf7, 0x6d, 0xd9, 
+       0x72, 0xe4, 0xa3, 00, 0xed, 0x17, 0xda, 0x15, 0xc7, 0x8c, 
+       0xe1, 0x46, 0x37, 0x65, 0xe5, 0xc3, 0x3b, 0xf, 0x23, 0xa9, 
+       0x2b, 0x19, 0xb3, 0xa7, 0xcd, 0x56, 0x77, 0xd2, 0x1a, 0xc3, 
+       0x87, 0x70, 0xeb, 0xfa, 0xd, 0x11, 0xcd, 0x1b, 0x1c, 0xe, 
+       0xac, 0x31, 0x13, 0x6a, 0xbc, 0x15, 0xd0, 0xfa, 0xfa, 0xfa, 
+       0x1d, 0xa2, 0x3b, 0xee, 0x8f, 0x26, 0x67, 0x5e, 0xed, 0xb8, 
+       0x6c, 0xc9, 0x32, 0xe4, 0xc, 0xe4, 0xa2, 0xe9, 0xf4, 0x65, 
+       0x9c, 0x39, 0x78, 0x26, 0x28, 0x59, 0x57, 0x5b, 0x17, 0x2a, 
+       0xb7, 0x1f, 0x44, 0x62, 0x47, 0x22, 0xa6, 0x15, 0x4f, 0x53, 
+       0xa3, 0x7a, 0x50, 0xa4, 0x30, 0x1e, 0x6c, 0x74, 0x11, 0x30, 
+       0xc8, 0x4, 0xd6, 0x4f, 0xd7, 0xd1, 0x58, 0xef, 0xa0, 0x94, 
+       0xa1, 0xc0, 0x2a, 0x60, 0x12, 0x53, 0x27, 0xa4, 0xcd, 0x4c, 
+       0xfb, 0x4f, 0x9c, 0x38, 0xb1, 0xb7, 0xbd, 0xbd, 0x5d, 0xee, 
+       0xc5, 0x65, 0xde, 0x43, 0x53, 0xbe, 0x5c, 0x1, 0xb7, 0x64, 
+       0xd1, 0x12, 0x64, 0xf7, 0x65, 0xa3, 0xf6, 0x48, 0x1d, 0xea, 
+       0x4e, 0xd6, 0xf9, 0x13, 0xf5, 0x76, 0xf5, 0xa2, 0xf2, 0xad, 
+       0x4a, 0x38, 0xda, 0xed, 0x98, 0x98, 0x37, 0x51, 0x5d, 0xf0, 
+       0xe9, 0xf, 0x8c, 0xc2, 0xc1, 0xb9, 0xdd, 0xe5, 0x72, 0x75, 
+       0x4a, 0x54, 0x23, 0xe0, 0x88, 0xa0, 0x43, 0x81, 0x65, 0x51, 
+       0x4, 0xa8, 0x5b, 0xcc, 0xe5, 0x73, 0xbb, 0xf6, 0xec, 0xd9, 
+       0x73, 0x58, 0xb4, 0xfe, 0x1f, 0xc8, 0x36, 0xc7, 00, 0xf7, 
+       0x73, 0x22, 0xbf, 0xe2, 0xcc, 0x6, 0x18, 0x2f, 0x17, 00, 
+       0xde, 0xb8, 0xe0, 0x46, 0x64, 0x3a, 0x33, 0x51, 0xfd, 0x41, 
+       0xd, 0x1a, 0xcf, 0x35, 0xa2, 0xdf, 0xd9, 0x8f, 0x83, 0xdb, 
+       0xf, 0xc1, 0x73, 0x45, 0xc2, 0x33, 0x8a, 0xb1, 0x78, 0xf1, 
+       0x62, 0xb5, 0x94, 0xf3, 0xa6, 0x88, 0xfc, 0x9f, 0xd, 0xdd, 
+       0x29, 0xf7, 0xee, 0xd5, 0xd5, 0xd5, 0x61, 0xdb, 0xb6, 0x6d, 
+       0xdf, 0x92, 0xd8, 0x4, 0xab, 0x1, 0x33, 0xb1, 0x66, 0x12, 
+       0xdd, 0x1, 0x64, 0x1b, 0x5c, 0x61, 0xe9, 0x1a, 0x94, 0xc9, 
+       0x92, 0xc4, 0x70, 0xce, 0x48, 0x13, 0x43, 0xb1, 0x26, 0x53, 
+       0xc, 0x2f, 0xab, 0xcb, 0xa3, 0xbd, 0x65, 0xcb, 0x96, 0x4d, 
+       0x72, 0x53, 0xf0, 0x46, 0x99, 0x6e, 0x12, 0x25, 0x7d, 0xb8, 
+       0x6, 0x93, 0xa8, 0x57, 0xa9, 0xb6, 0xb6, 0x16, 0x35, 0x17, 
+       0x6a, 0x30, 0x90, 0x3b, 0x80, 0xb4, 0xec, 0x14, 0xf4, 0x5e, 
+       0x72, 0x22, 0x73, 0x20, 0x4b, 0x9, 0xf6, 0x26, 0xa4, 0x23, 
+       0x29, 0xce, 0xe3, 0x16, 0x8e, 0x76, 0x6c, 0xdf, 0xbe, 0xfd, 
+       0x87, 0x72, 0x7, 0x75, 0xa5, 0x94, 0x20, 0x37, 0x94, 0xa1, 
+       0x55, 0xc, 0x17, 0xca, 0xb2, 0x2e, 0x42, 0x97, 0x18, 0x2e, 
+       0x74, 0xfb, 0xc4, 0xb8, 0x98, 0x40, 0x6c, 0x45, 0xe1, 0xc0, 
+       0x72, 0xfe, 0xe5, 0x6d, 0x5d, 0xbc, 0xda, 0x97, 0x76, 0xb6, 
+       0x18, 0xae, 0xae, 0x9, 0x98, 0x86, 0xcf, 0xe9, 0x62, 0xd8, 
+       0x18, 0x34, 0x6c, 0x9c, 0x44, 0x31, 0x6c, 0x28, 0x4a, 0xea, 
+       0xe1, 0xa4, 0xf5, 0x89, 0xc9, 0xd9, 0x49, 0x13, 0xd3, 0x8a, 
+       0xd2, 0x53, 0xaf, 0x9c, 0xba, 0xd2, 0x24, 0xf1, 0x4e, 0x8a, 
+       0x89, 0x34, 0x6, 0xe8, 0x1e, 0xc6, 0x38, 0x34, 0x3d, 0x62, 
+       0x8, 0x88, 0xdd, 0xb7, 0x5d, 0xc, 0x41, 0x4a, 0xff, 0x50, 
+       0x40, 0xe9, 0x47, 0xc3, 0x70, 0xc6, 0x25, 0xd8, 0x1, 0x23, 
+       0xd8, 0x50, 0x42, 0x85, 0xee, 0x6, 0xec, 0xc6, 0xba, 0xb, 
+       0x33, 0x21, 0xaf, 0x4d, 0x63, 0x61, 0x4, 0x45, 0x6e, 0x1a, 
+       0xe3, 0xd1, 0x8f, 0x79, 0x11, 0xac, 0xe6, 0x74, 0x28, 0xc0, 
+       0xc7, 0x9d, 0x6d, 0x7d, 0xbd, 0x62, 0xd8, 0x70, 0x55, 0x62, 
+       0x98, 0x5f, 0x38, 0xd2, 0xf9, 0xd3, 0x66, 0xe5, 0xc9, 0x2d, 
+       0x1a, 0xa6, 0x21, 0xf7, 0x68, 0x58, 0x27, 0xfa, 0xa9, 0x31, 
+       0xc5, 0x67, 0x8b, 0xa5, 0x9e, 0xf9, 0x9a, 0x31, 0xad, 0x9f, 
+       0x42, 0x81, 0x65, 0x20, 0x23, 0x69, 0xb0, 0xba, 0x20, 0x2, 
+       0x62, 0x41, 0x9a, 0x7b, 0xe2, 0x54, 0x95, 0x60, 0x81, 0x83, 
+       0x39, 0xcb, 0xb0, 0x70, 0x44, 0x4e, 0x44, 0x4b, 0xba, 0x1e, 
+       0xac, 0x83, 0xe6, 0x16, 0x39, 0xc7, 0x7a, 0xd0, 0xd0, 0x4d, 
+       0xb0, 0xac, 0x43, 0xa8, 0x77, 0x57, 0xbc, 0xaf, 0x52, 0x28, 
+       0xb0, 0x2c, 0x80, 0x86, 0x5c, 0x65, 0x38, 0xb, 0xa1, 0xcd, 
+       0xcc, 0x35, 0xd7, 0x74, 0x43, 0x10, 0x24, 0xbb, 0x3a, 0xc3, 
+       0x69, 0x18, 0x4e, 0x13, 0xe8, 0x2c, 0xf4, 0xd8, 00, 00, 
+       0x1, 0x79, 0x49, 0x44, 0x41, 0x54, 0x8a, 0xab, 0xe2, 0x6d, 
+       0x9a, 0x58, 0xf, 0x82, 0x60, 0x5d, 0x68, 0x58, 0x17, 0x2, 
+       0xa3, 0x21, 0x67, 0x9, 0x96, 0x6e, 0x2, 0x56, 0xef, 0xa8, 
+       0xd8, 0x7a, 0xb0, 0x62, 0xda, 00, 0x62, 0x5, 0x3, 0x88, 
+       0xac, 0x97, 0x41, 0x8a, 0x60, 0x58, 0x61, 0x66, 0x4e, 0x9b, 
+       0x99, 0x69, 00, 0xcc, 0x44, 0xb7, 0x32, 0xc1, 0xb2, 0x50, 
+       0xdd, 0x8d, 0x75, 0x63, 0x88, 0x97, 0x3f, 0x3e, 0xdd, 0xc3, 
+       0x21, 0x5d, 0x59, 0xda, 0x4, 0xaa, 0xbb, 0xaa, 0x6, 0xc6, 
+       0xc6, 0xa7, 0x9b, 0x36, 0x81, 0xd2, 0xb0, 0xde, 0x8c, 0xa7, 
+       0xd3, 0x8a, 0xf3, 0x2a, 0x5, 0x81, 0xbd, 0x1a, 0xa4, 0x12, 
+       0xe8, 0x56, 0xa5, 0x37, 0xc1, 0x32, 0x13, 0xcd, 0x55, 0x66, 
+       0x4e, 0xb0, 0xec, 0xd6, 0xfa, 0x3d, 0x66, 0x1c, 0xab, 0x38, 
+       0xab, 0x2b, 0xac, 0x2b, 0xaf, 0x1, 0x6b, 0xe, 0x12, 0xa8, 
+       0xd1, 0xe8, 0xba, 0xb2, 0x7e, 0x34, 0x3a, 0xbd, 0x38, 0xbd, 
+       0x14, 0xe, 0xac, 0x6, 0xc5, 0xca, 0x93, 0x8b, 0x9a, 0x74, 
+       0x86, 0x2c, 0x98, 00, 0x9, 0x94, 0x79, 0xe8, 0x81, 0x89, 
+       0xf1, 0x69, 0xac, 0x24, 0x96, 0x49, 0x62, 0x9d, 0x58, 0x2e, 
+       0xd, 0xeb, 0xa4, 0x6d, 0x2, 0x66, 0x1c, 0xfa, 0xf9, 0x41, 
+       0xe, 0x1e, 0x9c, 0x24, 0x4c, 0x55, 0x94, 0x76, 00, 0xf9, 
+       0xba, 0x32, 0x2b, 0xcd, 0xc4, 0x24, 0x63, 0x46, 0xcc, 0x98, 
+       0x86, 0x2d, 0x4c, 0x90, 0x34, 0x1a, 0xa4, 0x76, 0x8b, 0x97, 
+       0x25, 0x44, 0x80, 0x34, 0x2c, 0xcf, 0xe8, 0xe6, 0xb3, 0x6, 
+       0xcb, 0x3a, 0xd2, 0x4d, 0x5b, 0x1b, 0xc6, 0xd, 0xa2, 0x70, 
+       0x9c, 0xe5, 0xb0, 0xed, 0x96, 0x77, 0x97, 0x5d, 0x52, 0x3, 
+       0x66, 0x62, 0xba, 0xb5, 0x1f, 0x1, 0xd2, 0xad, 0x8d, 0x38, 
+       0xfd, 0x5c, 0x35, 0x72, 0xd7, 0xe8, 0x66, 0x9c, 0xa1, 0xc8, 
+       0x58, 0x51, 0xd, 0x90, 0x69, 0xe8, 0x66, 0xf9, 0x46, 0xe0, 
+       0x4, 0xa9, 0x9f, 0xfd, 0x40, 0x43, 0x71, 0x55, 0xe2, 0x21, 
+       0x48, 0xa8, 0xa0, 0xa7, 0x91, 0x4, 0xb0, 0xe6, 0x9a, 0x6, 
+       0xa7, 0x9f, 0x9, 0xd2, 0xe8, 0x66, 0x32, 0xfa, 0x59, 0x4d, 
+       0x1a, 0xb0, 0xd1, 0x26, 0xb0, 0x90, 0xcf, 0xe1, 0x80, 0xb2, 
+       0x52, 0x43, 0x82, 0x55, 0x91, 0xbc, 0x80, 0x95, 0x93, 0xff, 
+       0x84, 0x34, 0x50, 0xba, 0x35, 0x60, 0xba, 0x47, 0x92, 0x8, 
+       0x8e, 0xa4, 0x6d, 0xd, 0x58, 0xf9, 0x45, 0x2, 0xa9, 0x52, 
+       0xc9, 0xbf, 0xa8, 0xc0, 0xea, 0xc8, 0xda, 0xf6, 0x71, 0x9b, 
+       0x8f, 0x4, 0x3a, 0x1a, 0xa4, 00, 0x47, 0x3, 0xd0, 0x58, 
+       0xb9, 0x61, 0x81, 0x35, 0x66, 0x70, 0x2d, 0xb9, 0x47, 0xe2, 
+       0x1d, 0x1b, 0xb3, 0xf8, 0xaf, 0x2b, 0xb0, 0xff, 0xf, 0x4f, 
+       0x13, 0xcb, 0x14, 0x29, 0x9f, 0x25, 0xc5, 00, 00, 00, 
+       00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0};
+
+const struct httpd_fsdata_file file_index_html[] = {{NULL, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
+
+const struct httpd_fsdata_file file_404_html[] = {{file_index_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
+
+const struct httpd_fsdata_file file_img_control_xy_png[] = {{file_404_html, data_img_control_xy_png, data_img_control_xy_png + 20, sizeof(data_img_control_xy_png) - 20}};
+
+const struct httpd_fsdata_file file_img_control_z_png[] = {{file_img_control_xy_png, data_img_control_z_png, data_img_control_z_png + 19, sizeof(data_img_control_z_png) - 19}};
+
+#define HTTPD_FS_ROOT file_img_control_z_png
+
+#define HTTPD_FS_NUMFILES 4
diff --git a/src/libs/Network/uip/webserver/httpd.c b/src/libs/Network/uip/webserver/httpd.c
new file mode 100644 (file)
index 0000000..67d03c8
--- /dev/null
@@ -0,0 +1,680 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+
+/**
+ * \addtogroup apps
+ * @{
+ */
+
+/**
+ * \defgroup httpd Web server
+ * @{
+ * The uIP web server is a very simplistic implementation of an HTTP
+ * server. It can serve web pages and files from a read-only ROM
+ * filesystem, and provides a very small scripting language.
+
+ */
+
+/**
+ * \file
+ *         Web server
+ * \author
+ *         Adam Dunkels <adam@sics.se>
+ */
+
+
+/*
+ * Copyright (c) 2004, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $
+ */
+
+#include <stdio.h>
+
+#include "uip.h"
+#include "httpd.h"
+#include "httpd-fs.h"
+#include "http-strings.h"
+
+#include <string.h>
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "CommandQueue.h"
+#include "CallbackStream.h"
+
+#include "c-fifo.h"
+
+#define STATE_WAITING 0
+#define STATE_HEADERS 1
+#define STATE_BODY    2
+#define STATE_OUTPUT  3
+#define STATE_UPLOAD  4
+
+#define GET  1
+#define POST 2
+
+#define ISO_nl      0x0a
+#define ISO_space   0x20
+#define ISO_bang    0x21
+#define ISO_percent 0x25
+#define ISO_period  0x2e
+#define ISO_slash   0x2f
+#define ISO_colon   0x3a
+
+#define DEBUG_PRINTF printf
+//#define DEBUG_PRINTF(...)
+
+
+// this callback gets the results of a command, line by line. need to check if
+// we need to stall the upstream sender return 0 if stalled 1 if ok to keep
+// providing more -1 if the connection has closed or is not in output state.
+// need to see which connection to send to based on state and add result to
+// that fifo for each connection. NOTE this will not get called if the
+// connection has been closed and the stream will get deleted when the last
+// command has been executed
+static int command_result(const char *str, void *state)
+{
+    struct httpd_state *s = (struct httpd_state *)state;
+    if (s == NULL) {
+        // connection was closed so discard, this should never happen
+        DEBUG_PRINTF("ERROR: command result for closed state %d\n", (int)state);
+        return -1;
+    }
+
+    if (str == NULL) {
+        DEBUG_PRINTF("End of command (%p)\n", state);
+        fifo_push(s->fifo, NULL);
+
+    } else {
+        if (fifo_size(s->fifo) < 10) {
+            DEBUG_PRINTF("Got command result (%p): %s", state, str);
+            fifo_push(s->fifo, strdup(str));
+            return 1;
+        } else {
+            DEBUG_PRINTF("command result fifo is full (%p)\n", state);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static void create_callback_stream(struct httpd_state *s)
+{
+    // need to create a callback stream here, but do one per connection pass
+    // the state to the callback, also create the fifo for the command results
+    s->fifo = new_fifo();
+    s->pstream = new_callback_stream(command_result, s);
+}
+
+// Used to save files to SDCARD during upload
+static FILE *fd;
+static char *output_filename = NULL;
+static int file_cnt = 0;
+static int open_file(const char *fn)
+{
+    if (output_filename != NULL) free(output_filename);
+    output_filename = malloc(strlen(fn) + 5);
+    strcpy(output_filename, "/sd/");
+    strcat(output_filename, fn);
+    fd = fopen(output_filename, "w");
+    if (fd == NULL) {
+        free(output_filename);
+        output_filename = NULL;
+        return 0;
+    }
+    return 1;
+}
+
+static int close_file()
+{
+    free(output_filename);
+    output_filename = NULL;
+    fclose(fd);
+    return 1;
+}
+
+static int save_file(uint8_t *buf, unsigned int len)
+{
+    if (fwrite(buf, 1, len, fd) == len) {
+        file_cnt += len;
+        // HACK alert work around bug causing file corruption when writing large amounts of data
+        if (file_cnt >= 400) {
+            file_cnt = 0;
+            fclose(fd);
+            fd = fopen(output_filename, "a");
+        }
+        return 1;
+
+    } else {
+        close_file();
+        return 0;
+    }
+}
+
+static int fs_open(struct httpd_state *s)
+{
+    if (strncmp(s->filename, "/sd/", 4) == 0) {
+        DEBUG_PRINTF("Opening file %s\n", s->filename);
+        s->fd = fopen(s->filename, "r");
+        if (s->fd == NULL) {
+            DEBUG_PRINTF("Failed to open: %s\n", s->filename);
+            return 0;
+        }
+        return 1;
+
+    } else {
+        s->fd = NULL;
+        return httpd_fs_open(s->filename, &s->file);
+    }
+}
+
+/*---------------------------------------------------------------------------*/
+static PT_THREAD(send_command_response(struct httpd_state *s))
+{
+    PSOCK_BEGIN(&s->sout);
+
+    do {
+        PSOCK_WAIT_UNTIL( &s->sout, fifo_size(s->fifo) > 0 );
+        s->strbuf = fifo_pop(s->fifo);
+        if (s->strbuf != NULL) {
+            // send it
+            DEBUG_PRINTF("Sending response: %s", s->strbuf);
+            // TODO send as much as we can in one packet
+            PSOCK_SEND_STR(&s->sout, s->strbuf);
+            // free the strdup
+            free(s->strbuf);
+        }else if(--s->command_count <= 0) {
+            // when all commands have completed exit
+            break;
+        }
+    } while (1);
+
+    PSOCK_END(&s->sout);
+}
+
+/*---------------------------------------------------------------------------*/
+static unsigned short generate_part_of_file(void *state)
+{
+    struct httpd_state *s = (struct httpd_state *)state;
+
+    if (s->file.len > uip_mss()) {
+        s->len = uip_mss();
+    } else {
+        s->len = s->file.len;
+    }
+    memcpy(uip_appdata, s->file.data, s->len);
+
+    return s->len;
+}
+/*---------------------------------------------------------------------------*/
+static unsigned short generate_part_of_sd_file(void *state)
+{
+    struct httpd_state *s = (struct httpd_state *)state;
+
+    int len = fread(uip_appdata, 1, uip_mss(), s->fd);
+    if (len <= 0) {
+        // we need to send something
+        strcpy(uip_appdata, "\r\n");
+        len = 2;
+        s->len = 0;
+    } else {
+        s->len = len;
+    }
+    return len;
+}
+/*---------------------------------------------------------------------------*/
+static
+PT_THREAD(send_file(struct httpd_state *s))
+{
+    PSOCK_BEGIN(&s->sout);
+
+    do {
+        PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s);
+        s->file.len -= s->len;
+        s->file.data += s->len;
+    } while (s->file.len > 0);
+
+    PSOCK_END(&s->sout);
+}
+
+/*---------------------------------------------------------------------------*/
+static PT_THREAD(send_sd_file(struct httpd_state *s))
+{
+    PSOCK_BEGIN(&s->sout);
+
+    do {
+        PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_sd_file, s);
+    } while (s->len > 0);
+
+    fclose(s->fd);
+    s->fd = NULL;
+
+    PSOCK_END(&s->sout);
+}
+
+/*---------------------------------------------------------------------------*/
+static PT_THREAD(send_headers_3(struct httpd_state *s, const char *statushdr, char send_content_type))
+{
+    char *ptr;
+
+    PSOCK_BEGIN(&s->sout);
+
+    PSOCK_SEND_STR(&s->sout, statushdr);
+
+    if (send_content_type) {
+        ptr = strrchr(s->filename, ISO_period);
+        if (ptr == NULL) {
+            PSOCK_SEND_STR(&s->sout, http_content_type_plain); // http_content_type_binary);
+        } else if (strncmp(http_html, ptr, 5) == 0 || strncmp(http_shtml, ptr, 6) == 0) {
+            PSOCK_SEND_STR(&s->sout, http_content_type_html);
+        } else if (strncmp(http_css, ptr, 4) == 0) {
+            PSOCK_SEND_STR(&s->sout, http_content_type_css);
+        } else if (strncmp(http_png, ptr, 4) == 0) {
+            PSOCK_SEND_STR(&s->sout, http_content_type_png);
+        } else if (strncmp(http_gif, ptr, 4) == 0) {
+            PSOCK_SEND_STR(&s->sout, http_content_type_gif);
+        } else if (strncmp(http_jpg, ptr, 4) == 0) {
+            PSOCK_SEND_STR(&s->sout, http_content_type_jpg);
+        } else {
+            PSOCK_SEND_STR(&s->sout, http_content_type_plain);
+        }
+    }
+    PSOCK_END(&s->sout);
+}
+static PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr))
+{
+    return send_headers_3(s, statushdr, 1);
+}
+/*---------------------------------------------------------------------------*/
+static
+PT_THREAD(handle_output(struct httpd_state *s))
+{
+    PT_BEGIN(&s->outputpt);
+
+    if (s->method == POST) {
+        if (strcmp(s->filename, "/command") == 0) {
+            DEBUG_PRINTF("Executed command post\n");
+            PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200));
+            // send response as we get it
+            PT_WAIT_THREAD(&s->outputpt, send_command_response(s));
+
+        } else if (strcmp(s->filename, "/command_silent") == 0) {
+            DEBUG_PRINTF("Executed silent command post\n");
+            PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200));
+
+        } else if (strcmp(s->filename, "/upload") == 0) {
+            DEBUG_PRINTF("upload output: %d\n", s->uploadok);
+            if (s->uploadok == 0) {
+                PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_503));
+                PSOCK_SEND_STR(&s->sout, "FAILED\r\n");
+            } else {
+                PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200));
+                PSOCK_SEND_STR(&s->sout, "OK\r\n");
+            }
+
+        } else {
+            DEBUG_PRINTF("Unknown POST: %s\n", s->filename);
+            httpd_fs_open(http_404_html, &s->file);
+            strcpy(s->filename, http_404_html);
+            PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404));
+            PT_WAIT_THREAD(&s->outputpt, send_file(s));
+        }
+
+    } else {
+        // Presume method GET
+        if (!fs_open(s)) { // Note this has the side effect of opening the file
+            DEBUG_PRINTF("404 file not found\n");
+            httpd_fs_open(http_404_html, &s->file);
+            strcpy(s->filename, http_404_html);
+            PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404));
+            PT_WAIT_THREAD(&s->outputpt, send_file(s));
+
+        } else if (s->cache_page) {
+            if (s->fd != NULL) {
+                // if it was an sd file then we need to close it
+                fclose(s->fd);
+                s->fd = NULL;
+            }
+            // tell it it has not changed
+            DEBUG_PRINTF("304 Not Modified\n");
+            PT_WAIT_THREAD(&s->outputpt, send_headers_3(s, http_header_304, 0));
+
+        } else {
+            DEBUG_PRINTF("sending file %s\n", s->filename);
+            PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200));
+            if (s->fd != NULL) {
+                // send from sd card
+                PT_WAIT_THREAD(&s->outputpt, send_sd_file(s));
+
+            } else {
+                // send from FLASH
+                PT_WAIT_THREAD(&s->outputpt, send_file(s));
+            }
+        }
+    }
+
+    PSOCK_CLOSE(&s->sout);
+    PT_END(&s->outputpt);
+}
+
+/*---------------------------------------------------------------------------*/
+// this forces us to yield every other call as we read all data everytime
+static char has_newdata(struct httpd_state *s)
+{
+    if (s->upload_state == 1) {
+        /* All data in uip_appdata buffer already consumed. */
+        s->upload_state = 0;
+        return 0;
+    } else if (uip_newdata()) {
+        /* There is new data that has not been consumed. */
+        return 1;
+    } else {
+        /* There is no new data. */
+        return 0;
+    }
+}
+
+/*
+ * handle trhe uploaded data, as there may be part of that buffer still in the last packet buffer
+ * write that first from the buf/len parameters
+ */
+static PT_THREAD(handle_uploaded_data(struct httpd_state *s, uint8_t *buf, int len))
+{
+    PT_BEGIN(&s->inputpt);
+
+    DEBUG_PRINTF("Uploading file: %s, %d\n", s->upload_name, s->content_length);
+
+    // The body is the raw data to be stored to the file
+    if (!open_file(s->upload_name)) {
+        DEBUG_PRINTF("failed to open file\n");
+        s->uploadok = 0;
+        PT_EXIT(&s->inputpt);
+    }
+
+    DEBUG_PRINTF("opened file: %s\n", s->upload_name);
+
+    if (len > 0) {
+        // write the first part of the buffer
+        if (!save_file(buf, len)) {
+            DEBUG_PRINTF("initial write failed\n");
+            s->uploadok = 0;
+            PT_EXIT(&s->inputpt);
+        }
+        s->content_length -= len;
+    }
+
+    s->upload_state = 1; // first time through we need to yield to get new data
+
+    // save the entire input buffer
+    while (s->content_length > 0) {
+        PT_WAIT_UNTIL(&s->inputpt, has_newdata(s));
+        s->upload_state = 1;
+
+        u8_t *readptr = (u8_t *)uip_appdata;
+        int readlen = uip_datalen();
+        //DEBUG_PRINTF("read %d bytes of data\n", readlen);
+
+        if (readlen > 0) {
+            if (!save_file(readptr, readlen)) {
+                DEBUG_PRINTF("write failed\n");
+                s->uploadok = 0;
+                PT_EXIT(&s->inputpt);
+            }
+            s->content_length -= readlen;
+        }
+    }
+
+    close_file();
+    s->uploadok = 1;
+    DEBUG_PRINTF("finished upload\n");
+
+    PT_END(&s->inputpt);
+}
+/*---------------------------------------------------------------------------*/
+static
+PT_THREAD(handle_input(struct httpd_state *s))
+{
+    PSOCK_BEGIN(&s->sin);
+
+    PSOCK_READTO(&s->sin, ISO_space);
+
+    if (strncmp(s->inputbuf, http_get, 4) == 0) {
+        s->method = GET;
+    } else if (strncmp(s->inputbuf, http_post, 4) == 0) {
+        s->method = POST;
+    } else {
+        DEBUG_PRINTF("Unexpected method: %s\n", s->inputbuf);
+        PSOCK_CLOSE_EXIT(&s->sin);
+    }
+
+    DEBUG_PRINTF("Method: %s\n", s->method == POST ? "POST" : "GET");
+
+    PSOCK_READTO(&s->sin, ISO_space);
+
+    if (s->inputbuf[0] != ISO_slash) {
+        PSOCK_CLOSE_EXIT(&s->sin);
+    }
+
+    if (s->inputbuf[1] == ISO_space) {
+        strncpy(s->filename, http_index_html, sizeof(s->filename));
+    } else {
+        s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
+        strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
+    }
+
+    DEBUG_PRINTF("filename: %s\n", s->filename);
+
+    /*  httpd_log_file(uip_conn->ripaddr, s->filename);*/
+
+    s->state = STATE_HEADERS;
+    s->content_length = 0;
+    s->cache_page = 0;
+    while (1) {
+        if (s->state == STATE_HEADERS) {
+            // read the headers of the request
+            PSOCK_READTO(&s->sin, ISO_nl);
+            s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
+            if (s->inputbuf[0] == '\r') {
+                DEBUG_PRINTF("end of headers\n");
+                if (s->method == GET) {
+                    s->state = STATE_OUTPUT;
+                    break;
+                } else if (s->method == POST) {
+                    if (strcmp(s->filename, "/upload") == 0) {
+                        s->state = STATE_UPLOAD;
+                    } else {
+                        s->state = STATE_BODY;
+                    }
+                }
+            } else {
+                DEBUG_PRINTF("reading header: %s\n", s->inputbuf);
+                // handle headers here
+                if (strncmp(s->inputbuf, http_content_length, sizeof(http_content_length) - 1) == 0) {
+                    s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
+                    s->content_length = atoi(&s->inputbuf[sizeof(http_content_length) - 1]);
+                    DEBUG_PRINTF("Content length= %s, %d\n", &s->inputbuf[sizeof(http_content_length) - 1], s->content_length);
+
+                } else if (strncmp(s->inputbuf, "X-Filename: ", 11) == 0) {
+                    s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
+                    strncpy(s->upload_name, &s->inputbuf[12], sizeof(s->upload_name) - 1);
+                    DEBUG_PRINTF("Upload name= %s\n", s->upload_name);
+
+                } else if (strncmp(s->inputbuf, http_cache_control, sizeof(http_cache_control) - 1) == 0) {
+                    s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
+                    s->cache_page = strncmp(http_no_cache, &s->inputbuf[sizeof(http_cache_control) - 1], sizeof(http_no_cache) - 1) != 0;
+                    DEBUG_PRINTF("cache page= %d\n", s->cache_page);
+                }
+            }
+
+        } else if (s->state == STATE_BODY) {
+            if (s->method == POST && strcmp(s->filename, "/command") == 0) {
+                // create a callback stream and fifo for the results as it is a command
+                create_callback_stream(s);
+
+            } else if (s->method == POST && strcmp(s->filename, "/command_silent") == 0) {
+                // stick the command  on the command queue specifying null output stream
+                s->pstream = NULL;
+
+            } else { // unknown POST
+                DEBUG_PRINTF("Unknown Post URL: %s\n", s->filename);
+                s->state = STATE_OUTPUT;
+                break;
+            }
+            s->command_count= 0;
+            // read the Body of the request, each line is a command
+            if (s->content_length > 0) {
+                DEBUG_PRINTF("start reading body %d...\n", s->content_length);
+                while (s->content_length > 2) {
+                    PSOCK_READTO(&s->sin, ISO_nl);
+                    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
+                    s->content_length -= PSOCK_DATALEN(&s->sin);
+                    // stick the command  on the command queue, with this connections stream output
+                    DEBUG_PRINTF("Adding command: %s, left: %d\n", s->inputbuf, s->content_length);
+                    network_add_command(s->inputbuf, s->pstream);
+                    s->command_count++; // count number of command lines we submit
+                }
+                DEBUG_PRINTF("Read body done\n");
+                s->state = STATE_OUTPUT;
+
+            } else {
+                s->state = STATE_OUTPUT;
+            }
+            break;
+
+        } else if (s->state == STATE_UPLOAD) {
+            PSOCK_WAIT_THREAD(&s->sin, handle_uploaded_data(s, PSOCK_GET_START_OF_REST_OF_BUFFER(&s->sin), PSOCK_GET_LENGTH_OF_REST_OF_BUFFER(&s->sin)));
+            PSOCK_MARK_BUFFER_READ(&s->sin);
+            s->state = STATE_OUTPUT;
+            break;
+
+        } else {
+            DEBUG_PRINTF("WTF State: %d", s->state);
+            break;
+        }
+    }
+
+    PSOCK_END(&s->sin);
+}
+/*---------------------------------------------------------------------------*/
+static void
+handle_connection(struct httpd_state *s)
+{
+    if (s->state != STATE_OUTPUT) {
+        handle_input(s);
+    }
+    if (s->state == STATE_OUTPUT) {
+        handle_output(s);
+    }
+}
+/*---------------------------------------------------------------------------*/
+void
+httpd_appcall(void)
+{
+    struct httpd_state *s = (struct httpd_state *)(uip_conn->appstate);
+
+    if (uip_connected()) {
+        s = malloc(sizeof(struct httpd_state));
+        if (s == NULL) {
+            DEBUG_PRINTF("Connection: Out of memory\n");
+            uip_abort();
+            return;
+        }
+        uip_conn->appstate = s;
+        DEBUG_PRINTF("Connection: %d.%d.%d.%d:%d\n",
+                     uip_ipaddr1(uip_conn->ripaddr), uip_ipaddr2(uip_conn->ripaddr),
+                     uip_ipaddr3(uip_conn->ripaddr), uip_ipaddr4(uip_conn->ripaddr),
+                     HTONS(uip_conn->rport));
+
+        PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
+        PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
+        PT_INIT(&s->outputpt);
+        PT_INIT(&s->inputpt);
+        s->state = STATE_WAITING;
+        /*    timer_set(&s->timer, CLOCK_SECOND * 100);*/
+        s->timer = 0;
+        s->fd = NULL;
+        s->strbuf = NULL;
+        s->fifo = NULL;
+        s->pstream = NULL;
+    }
+
+    if (s == NULL) {
+        DEBUG_PRINTF("ERROR no state context: %d\n", uip_flags);
+        uip_abort();
+        return;
+    }
+
+    // check for timeout on connection here so we can cleanup if we abort
+    if (uip_poll()) {
+        ++s->timer;
+        if (s->timer >= 20 * 2) { // we have a 0.5 second poll and we want 20 second timeout
+            DEBUG_PRINTF("Timer expired, aborting\n");
+            uip_abort();
+        }
+    } else {
+        s->timer = 0;
+    }
+
+    if (uip_closed() || uip_aborted() || uip_timedout()) {
+        DEBUG_PRINTF("Closing connection: %d\n", HTONS(uip_conn->rport));
+        if (s->fd != NULL) fclose(fd); // clean up
+        if (s->strbuf != NULL) free(s->strbuf);
+        if (s->pstream != NULL) {
+            // free these if they were allocated
+            delete_fifo(s->fifo);
+            delete_callback_stream(s->pstream); // this will mark it as closed and will get deleted when no longer needed
+        }
+        free(s) ;
+        uip_conn->appstate = NULL;
+
+    } else {
+        handle_connection(s);
+    }
+}
+
+/*---------------------------------------------------------------------------*/
+/**
+ * \brief      Initialize the web server
+ *
+ *             This function initializes the web server and should be
+ *             called at system boot-up.
+ */
+void httpd_init(void)
+{
+    uip_listen(HTONS(80));
+}
+/*---------------------------------------------------------------------------*/
+/** @} */
diff --git a/src/libs/Network/uip/webserver/httpd.h b/src/libs/Network/uip/webserver/httpd.h
new file mode 100644 (file)
index 0000000..216e853
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001-2005, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $
+ *
+ */
+
+#ifndef __HTTPD_H__
+#define __HTTPD_H__
+
+#include "psock.h"
+#include "httpd-fs.h"
+#include "stdio.h"
+
+struct httpd_state {
+  unsigned char timer;
+  struct psock sin, sout;
+  struct pt outputpt, inputpt;
+  char inputbuf[100];
+  char filename[60];
+  char upload_name[32];
+  char method;
+  char state;
+  struct httpd_fs_file file;
+  FILE *fd;
+  uint16_t len;
+  char *strbuf;
+  int content_length;
+  uint16_t count;
+  uint8_t uploadok;
+  uint8_t upload_state;
+  uint8_t cache_page;
+  void *pstream;
+  void *fifo;
+  uint16_t command_count;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void httpd_init(void);
+void httpd_appcall(void);
+
+void httpd_log(char *msg);
+void httpd_log_file(u16_t *requester, char *file);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HTTPD_H__ */
diff --git a/src/libs/Network/uip/webserver/makefsdata.pl b/src/libs/Network/uip/webserver/makefsdata.pl
new file mode 100644 (file)
index 0000000..aeee6e4
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/perl\r
+\r
+open(OUTPUT, "> httpd-fsdata2.h");\r
+\r
+chdir("httpd-fs");\r
+\r
+opendir(DIR, ".");\r
+@files =  grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);\r
+closedir(DIR);\r
+\r
+foreach $file (@files) {  \r
+   \r
+    if(-d $file && $file !~ /^\./) {\r
+       print "Processing directory $file\n";\r
+       opendir(DIR, $file);\r
+       @newfiles =  grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);\r
+       closedir(DIR);\r
+       printf "Adding files @newfiles\n";\r
+       @files = (@files, map { $_ = "$file/$_" } @newfiles);\r
+       next;\r
+    }\r
+}\r
+\r
+foreach $file (@files) {\r
+    if(-f $file) {\r
+       \r
+       print "Adding file $file\n";\r
+       \r
+       open(FILE, $file) || die "Could not open file $file\n";\r
+\r
+       $file =~ s-^-/-;\r
+       $fvar = $file;\r
+       $fvar =~ s-/-_-g;\r
+       $fvar =~ s-\.-_-g;\r
+       # for AVR, add PROGMEM here\r
+       print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");\r
+       print(OUTPUT "\t/* $file */\n\t");\r
+       for($j = 0; $j < length($file); $j++) {\r
+           printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));\r
+       }\r
+       printf(OUTPUT "0,\n");\r
+       \r
+       \r
+       $i = 0;        \r
+       while(read(FILE, $data, 1)) {\r
+           if($i == 0) {\r
+               print(OUTPUT "\t");\r
+           }\r
+           printf(OUTPUT "%#02x, ", unpack("C", $data));\r
+           $i++;\r
+           if($i == 10) {\r
+               print(OUTPUT "\n");\r
+               $i = 0;\r
+           }\r
+       }\r
+       print(OUTPUT "0};\n\n");\r
+       close(FILE);\r
+       push(@fvars, $fvar);\r
+       push(@pfiles, $file);\r
+    }\r
+}\r
+\r
+for($i = 0; $i < @fvars; $i++) {\r
+    $file = $pfiles[$i];\r
+    $fvar = $fvars[$i];\r
+\r
+    if($i == 0) {\r
+        $prevfile = "NULL";\r
+    } else {\r
+        $prevfile = "file" . $fvars[$i - 1];\r
+    }\r
+    print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");\r
+    print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");\r
+    print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");\r
+}\r
+\r
+print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n");\r
+print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n");\r
diff --git a/src/libs/Network/uip/webserver/makestrings b/src/libs/Network/uip/webserver/makestrings
new file mode 100755 (executable)
index 0000000..20f0e24
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+
+
+sub stringify {
+  my $name = shift(@_);
+  open(OUTPUTC, "> $name.c");
+  open(OUTPUTH, "> $name.h");
+  
+  open(FILE, "$name");
+  
+  while(<FILE>) {
+    if(/(.+) "(.+)"/) {
+      $var = $1;
+      $data = $2;
+      
+      $datan = $data;
+      $datan =~ s/\\r/\r/g;
+      $datan =~ s/\\n/\n/g;
+      $datan =~ s/\\01/\01/g;      
+      $datan =~ s/\\0/\0/g;
+      
+      printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1);
+      printf(OUTPUTC "/* \"$data\" */\n");
+      printf(OUTPUTC "{");
+      for($j = 0; $j < length($datan); $j++) {
+       printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1)));
+      }
+      printf(OUTPUTC "};\n");
+      
+      printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1);
+      
+    }
+  }
+  close(OUTPUTC);
+  close(OUTPUTH);
+}
+stringify("http-strings");
+
+exit 0;
+
diff --git a/src/libs/Network/uip/webserver/webserver.h b/src/libs/Network/uip/webserver/webserver.h
new file mode 100644 (file)
index 0000000..f6f7bc1
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * Copyright (c) 2002, Adam Dunkels.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above\r
+ *    copyright notice, this list of conditions and the following\r
+ *    disclaimer in the documentation and/or other materials provided\r
+ *    with the distribution.\r
+ * 3. The name of the author may not be used to endorse or promote\r
+ *    products derived from this software without specific prior\r
+ *    written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\r
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\r
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * This file is part of the uIP TCP/IP stack\r
+ *\r
+ * $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $\r
+ *\r
+ */\r
+#ifndef __WEBSERVER_H__\r
+#define __WEBSERVER_H__\r
+\r
+#include "httpd.h"\r
+\r
+//typedef struct httpd_state uip_tcp_appstate_t;\r
+/* UIP_APPCALL: the name of the application function. This function\r
+   must return void and take no arguments (i.e., C type "void\r
+   appfunc(void)"). */\r
+#ifndef UIP_APPCALL\r
+#define UIP_APPCALL     httpd_appcall\r
+#endif\r
+\r
+\r
+#endif /* __WEBSERVER_H__ */\r
index b104f2d..5845e6e 100644 (file)
@@ -110,18 +110,19 @@ Pin* Pin::as_repeater(){
     if( this->port_number == 4 && this->pin >= 16 ){ LPC_PINCON->PINMODE9 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE9 &= ~(2<<((this->pin-16)*2)); }
     return this;
 }
+
 // Configure this pin as no pullup or pulldown
 Pin* Pin::pull_none(){
-    if (this->pin >= 32) return this;
-    // Set the two bits for this pin as 10
-    if( this->port_number == 0 && this->pin < 16  ){ LPC_PINCON->PINMODE0 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE0 &= ~(1<<( this->pin    *2)); }
-    if( this->port_number == 0 && this->pin >= 16 ){ LPC_PINCON->PINMODE1 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE1 &= ~(1<<((this->pin-16)*2)); }
-    if( this->port_number == 1 && this->pin < 16  ){ LPC_PINCON->PINMODE2 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE2 &= ~(1<<( this->pin    *2)); }
-    if( this->port_number == 1 && this->pin >= 16 ){ LPC_PINCON->PINMODE3 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE3 &= ~(1<<((this->pin-16)*2)); }
-    if( this->port_number == 2 && this->pin < 16  ){ LPC_PINCON->PINMODE4 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE4 &= ~(1<<( this->pin    *2)); }
-    if( this->port_number == 3 && this->pin >= 16 ){ LPC_PINCON->PINMODE7 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE7 &= ~(1<<((this->pin-16)*2)); }
-    if( this->port_number == 4 && this->pin >= 16 ){ LPC_PINCON->PINMODE9 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE9 &= ~(1<<((this->pin-16)*2)); }
-    return this;
+       if (this->pin >= 32) return this;
+       // Set the two bits for this pin as 10
+       if( this->port_number == 0 && this->pin < 16  ){ LPC_PINCON->PINMODE0 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE0 &= ~(1<<( this->pin    *2)); }
+       if( this->port_number == 0 && this->pin >= 16 ){ LPC_PINCON->PINMODE1 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE1 &= ~(1<<((this->pin-16)*2)); }
+       if( this->port_number == 1 && this->pin < 16  ){ LPC_PINCON->PINMODE2 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE2 &= ~(1<<( this->pin    *2)); }
+       if( this->port_number == 1 && this->pin >= 16 ){ LPC_PINCON->PINMODE3 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE3 &= ~(1<<((this->pin-16)*2)); }
+       if( this->port_number == 2 && this->pin < 16  ){ LPC_PINCON->PINMODE4 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE4 &= ~(1<<( this->pin    *2)); }
+       if( this->port_number == 3 && this->pin >= 16 ){ LPC_PINCON->PINMODE7 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE7 &= ~(1<<((this->pin-16)*2)); }
+       if( this->port_number == 4 && this->pin >= 16 ){ LPC_PINCON->PINMODE9 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE9 &= ~(1<<((this->pin-16)*2)); }
+       return this;
 }
 
 // Configure this pin as a pullup
index 44a1047..d64592f 100644 (file)
@@ -40,6 +40,7 @@ class Pin {
         Pin* pull_none(void);
 
         inline bool get(){
+
             if (this->pin >= 32) return false;
             return this->inverting ^ (( this->port->FIOPIN >> this->pin ) & 1);
         }
index f1a53af..20c1128 100644 (file)
@@ -26,10 +26,11 @@ template<class kind, int length> class RingBuffer {
         void         delete_first();
 
         kind         buffer[length];
-        int          head;
-        int          tail;
+        volatile int          head;
+        volatile int          tail;
 };
 
+#include "sLPC17xx.h"
 
 template<class kind, int length> RingBuffer<kind, length>::RingBuffer(){
     this->head = this->tail = 0;
@@ -40,7 +41,11 @@ template<class kind, int length>  int RingBuffer<kind, length>::capacity(){
 }
 
 template<class kind, int length>  int RingBuffer<kind, length>::size(){
-return((this->head>this->tail)?length:0)+this->tail-head;
+       //return((this->head>this->tail)?length:0)+this->tail-head;
+       __disable_irq();
+       int i = tail - head + ((head > tail)?length:0);
+       __enable_irq();
+       return i;
 }
 
 template<class kind, int length> int RingBuffer<kind, length>::next_block_index(int index){
index db17a60..2a2dfac 100644 (file)
@@ -16,14 +16,10 @@ using namespace std;
 
 #include "libs/StreamOutput.h"
 
-#define PRINTF_DEFAULT_BUFFER_SIZE 32
-
 class StreamOutputPool : public StreamOutput {
-private:
-    char *printf_default_buffer;
+
 public:
     StreamOutputPool(){
-        printf_default_buffer = new char[PRINTF_DEFAULT_BUFFER_SIZE];
     }
 
     int puts(const char* s)
@@ -48,6 +44,7 @@ public:
         this->streams.erase(stream);
     }
 
+private:
     set<StreamOutput*> streams;
 };
 
index 4a2bf0c..531d12f 100644 (file)
@@ -20,6 +20,7 @@
 #define CIRCBUFFER_H
 
 #include <stdlib.h>
+#include "sLPC17xx.h"
 #include <ahbmalloc.h>
 
 template <class T>
@@ -32,8 +33,11 @@ public:
         buf = (T *)ahbmalloc(size * sizeof(T), AHB_BANK_0);
     };
 
-    bool isFull() {
-        return ((write + 1) % size == read);
+       bool isFull() {
+               __disable_irq();
+               bool b= ((write + 1) % size == read);
+               __enable_irq();
+               return b;
     };
 
     bool isEmpty() {
@@ -41,16 +45,21 @@ public:
     };
 
     void queue(T k) {
+               __disable_irq();
         if (isFull()) {
             read++;
             read %= size;
         }
         buf[write++] = k;
         write %= size;
+               __enable_irq();
     }
 
     uint16_t available() {
-        return (write >= read) ? write - read : (size - read) + write;
+               __disable_irq();
+               uint16_t i= (write >= read) ? write - read : (size - read) + write;
+               __enable_irq();
+               return i;
     };
     uint16_t free() {
         return size - available() - 1;
index 01b40c8..3cb0d00 100644 (file)
@@ -20,6 +20,7 @@
 #include "modules/utils/pausebutton/PauseButton.h"
 #include "modules/utils/PlayLed/PlayLed.h"
 #include "modules/utils/panel/Panel.h"
+#include "libs/Network/uip/Network.h"
 
 // #include "libs/ChaNFSSD/SDFileSystem.h"
 #include "libs/Config.h"
@@ -34,7 +35,6 @@
 #include "libs/USBDevice/USBMSD/SDCard.h"
 #include "libs/USBDevice/USBSerial/USBSerial.h"
 #include "libs/USBDevice/DFU.h"
-
 #include "libs/SDFAT.h"
 
 #include "libs/Watchdog.h"
@@ -108,6 +108,9 @@ int main() {
     kernel->add_module( new Player() );
     kernel->add_module( new Panel() );
     kernel->add_module( new Touchprobe() );
+#ifndef NONETWORK
+    kernel->add_module( new Network() );
+#endif
 
     // Create and initialize USB stuff
     u.init();
index 421acde..186d805 100644 (file)
@@ -28,7 +28,7 @@ class Conveyor : public Module {
         void wait_for_empty_queue();
         bool is_queue_empty();
 
-        RingBuffer<Block,16> queue;  // Queue of Blocks
+        RingBuffer<Block,32> queue;  // Queue of Blocks
         Block* current_block;
         bool looking_for_new_block;
 
index a808d89..c2dd1b8 100644 (file)
@@ -236,17 +236,29 @@ void Robot::on_gcode_received(void * argument){
                 return;
 
             // TODO I'm not sure if the following is safe to do here, or should it go on the block queue?
-            // case 204: // M204 Snnn - set acceleration to nnn, NB only Snnn is currently supported
-            //     gcode->mark_as_taken();
-            //     if (gcode->has_letter('S'))
-            //     {
-            //         double acc= gcode->get_value('S') * 60 * 60; // mm/min^2
-            //         // enforce minimum
-            //         if (acc < 1.0)
-            //             acc = 1.0;
-            //         this->kernel->planner->acceleration= acc;
-            //     }
-            //     break;
+            case 204: // M204 Snnn - set acceleration to nnn, NB only Snnn is currently supported
+                gcode->mark_as_taken();
+                if (gcode->has_letter('S'))
+                {
+                    double acc= gcode->get_value('S') * 60 * 60; // mm/min^2
+                    // enforce minimum
+                    if (acc < 1.0)
+                        acc = 1.0;
+                    this->kernel->planner->acceleration= acc;
+                }
+                break;
+
+            case 205: // M205 Xnnn - set junction deviation
+                gcode->mark_as_taken();
+                if (gcode->has_letter('X'))
+                {
+                    double jd= gcode->get_value('X');
+                    // enforce minimum
+                    if (jd < 0.0)
+                        jd = 0.0;
+                    this->kernel->planner->junction_deviation= jd;
+                }
+                break;
 
             case 220: // M220 - speed override percentage
                 gcode->mark_as_taken();
@@ -269,6 +281,8 @@ void Robot::on_gcode_received(void * argument){
             case 503: // M503 just prints the settings
                 this->arm_solution->get_steps_per_millimeter(steps);
                 gcode->stream->printf(";Steps per unit:\nM92 X%1.5f Y%1.5f Z%1.5f\n", steps[0], steps[1], steps[2]);
+                gcode->stream->printf(";Acceleration mm/sec^2:\nM204 S%1.5f\n", this->kernel->planner->acceleration/3600);
+                gcode->stream->printf(";Junction Deviation:\nM205 X%1.5f\n", this->kernel->planner->junction_deviation);
                 gcode->mark_as_taken();
                 break;
 
index 5359cbd..b65b0f8 100644 (file)
@@ -514,6 +514,29 @@ void Endstops::on_gcode_received(void *argument)
             }
             break;
 
+            // NOTE this is to test accuracy of lead screws etc.
+            case 910: { // M910 - move specific number of raw steps
+                int x= 0, y=0 , z= 0, f= 200*16;
+                if (gcode->has_letter('F')) f = gcode->get_value('F');
+                if (gcode->has_letter('X')) {
+                    x = gcode->get_value('X');
+                    this->steppers[X_AXIS]->set_speed(f);
+                    this->steppers[X_AXIS]->move(x<0, abs(x));
+                }
+                if (gcode->has_letter('Y')) {
+                    y = gcode->get_value('Y');
+                    this->steppers[Y_AXIS]->set_speed(f);
+                    this->steppers[Y_AXIS]->move(y<0, abs(y));
+                }
+                if (gcode->has_letter('Z')) {
+                    z = gcode->get_value('Z');
+                    this->steppers[Z_AXIS]->set_speed(f);
+                    this->steppers[Z_AXIS]->move(z<0, abs(z));
+                }
+                gcode->stream->printf("Moved X %d Y %d Z %d F %d steps\n", x, y, z, f);
+                gcode->mark_as_taken();
+                break;
+            }
         }
     }
 }
index 3e95b3e..8d46a00 100644 (file)
@@ -181,11 +181,6 @@ void VikiLCD::init(){
     data[1]= 0x00; // all pins output
     i2c->write(this->i2c_address, data, 2);
 
-    // turn leds off
-    setLed(0, false);
-    setLed(1, false);
-    setLed(2, false);
-    
     //put the LCD into 4 bit mode
     // start with a non-standard command to make it realize we're speaking 4-bit here
     // per LCD datasheet, first command is a single 4-bit burst, 0011.
index 3397f23..796abbf 100644 (file)
@@ -15,6 +15,7 @@
 #include "modules/tools/temperaturecontrol/TemperatureControlPublicAccess.h"
 #include "modules/robot/RobotPublicAccess.h"
 #include "modules/utils/player/PlayerPublicAccess.h"
+#include "NetworkPublicAccess.h"
 
 #include <string>
 using namespace std;
@@ -46,6 +47,7 @@ WatchScreen::WatchScreen()
 {
     speed_changed = false;
     issue_change_speed = false;
+    ipstr = NULL;
 }
 
 void WatchScreen::on_enter()
@@ -235,7 +237,12 @@ const char *WatchScreen::get_status()
     if (panel->is_playing())
         return panel->get_playing_file();
 
-    return "Smoothie ready";
+    const char *ip = get_network();
+    if (ip == NULL) {
+        return "Smoothie ready";
+    } else {
+        return ip;
+    }
 }
 
 void WatchScreen::set_speed()
@@ -246,3 +253,24 @@ void WatchScreen::set_speed()
     string g(buf, n);
     send_gcode(g);
 }
+
+const char *WatchScreen::get_network()
+{
+    void *returned_data;
+
+    bool ok = THEKERNEL->public_data->get_value( network_checksum, get_ip_checksum, &returned_data );
+    if (ok) {
+        uint8_t *ipaddr = (uint8_t *)returned_data;
+        char buf[20];
+        int n = snprintf(buf, sizeof(buf), "IP %d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+        buf[n] = 0;
+        if (this->ipstr == NULL) {
+            this->ipstr = (char *)malloc(n + 1);
+        }
+        strcpy(this->ipstr, buf);
+
+        return this->ipstr;
+    }
+
+    return NULL;
+}
index d4c03c6..4f62fde 100644 (file)
@@ -26,6 +26,7 @@ private:
     void get_current_pos(double *cp);
     void get_sd_play_info();
     const char *get_status();
+    const char *get_network();
 
     bool speed_changed;
     bool issue_change_speed;
@@ -37,6 +38,8 @@ private:
     double pos[3];
     unsigned long elapsed_time;
     unsigned int sd_pcnt_played;
+
+    char *ipstr;
 };
 
 #endif
index bccee00..43baf25 100644 (file)
@@ -80,8 +80,10 @@ void Player::on_gcode_received(void *argument) {
             gcode->mark_as_taken();
             if (this->current_file_handler != NULL) {
                 this->playing_file = true;
-                // FIXME this is a problem if the stream goes away before the file has finished
-                this->reply_stream= gcode->stream;
+                // this would be a problem if the stream goes away before the file has finished,
+                // so we attach it to the kernel stream, however network connections from pronterface
+                // do not connect to the kernel streams so won't see this FIXME
+                this->reply_stream= THEKERNEL->streams;
             }
 
         }else if (gcode->m == 25) { // pause print
@@ -186,7 +188,8 @@ void Player::play_command( string parameters, StreamOutput* stream ){
     if( options.find_first_of("Vv") == string::npos ){
         this->current_stream = &(StreamOutput::NullStream);
     }else{
-        this->current_stream = stream;
+        // we send to the kernels stream as it cannot go away
+        this->current_stream = THEKERNEL->streams;
     }
 
     // get size of file
@@ -247,6 +250,7 @@ void Player::abort_command( string parameters, StreamOutput* stream ){
     played_cnt= 0;
     file_size= 0;
     this->filename= "";
+    this->current_stream= NULL;
     fclose(current_file_handler);
     stream->printf("Aborted playing file\r\n");
 }
@@ -292,7 +296,7 @@ void Player::on_main_loop(void* argument){
                 this->current_stream->printf("%s\n", buffer.c_str());
                 struct SerialMessage message;
                 message.message = buffer;
-                message.stream = this->current_stream;
+                message.stream = &(StreamOutput::NullStream); // we don't really need to see the ok
                 // wait for the queue to have enough room that a serial message could still be received before sending
                 this->kernel->conveyor->wait_for_queue(2);
                 this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
@@ -309,6 +313,7 @@ void Player::on_main_loop(void* argument){
         played_cnt= 0;
         file_size= 0;
         fclose(this->current_file_handler);
+        this->current_stream= NULL;
 
         if(this->reply_stream != NULL) {
             // if we were printing from an M command from pronterface we need to send this back
index 0d926ca..1b62c47 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "modules/tools/temperaturecontrol/TemperatureControlPublicAccess.h"
 #include "modules/robot/RobotPublicAccess.h"
+#include "NetworkPublicAccess.h"
 
 extern unsigned int g_maximumHeapAddress;
 
@@ -46,11 +47,12 @@ SimpleShell::ptentry_t SimpleShell::commands_table[] = {
     {CHECKSUM("dfu"),      &SimpleShell::dfu_command},
     {CHECKSUM("break"),    &SimpleShell::break_command},
     {CHECKSUM("help"),     &SimpleShell::help_command},
+    {CHECKSUM("?"),        &SimpleShell::help_command},
     {CHECKSUM("version"),  &SimpleShell::version_command},
     {CHECKSUM("mem"),      &SimpleShell::mem_command},
     {CHECKSUM("get"),      &SimpleShell::get_command},
     {CHECKSUM("set_temp"), &SimpleShell::set_temp_command},
-    {CHECKSUM("test"),     &SimpleShell::test_command},
+    {CHECKSUM("net"),      &SimpleShell::net_command},
 
     // unknown command
     {0, NULL}
@@ -115,10 +117,10 @@ void SimpleShell::on_module_loaded()
 {
     this->current_path = "/";
     this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
-    this->reset_delay_secs = 0;
+       this->register_for_event(ON_GCODE_RECEIVED);
+       this->register_for_event(ON_SECOND_TICK);
 
-    this->register_for_event(ON_SECOND_TICK);
-    this->register_for_event(ON_GCODE_RECEIVED);
+    this->reset_delay_secs = 0;
 }
 
 void SimpleShell::on_second_tick(void *)
@@ -142,8 +144,8 @@ void SimpleShell::on_gcode_received(void *argument)
             gcode->stream->printf("Begin file list\r\n");
             ls_command("/sd", gcode->stream);
             gcode->stream->printf("End file list\r\n");
-        }
-        else if (gcode->m == 30) { // remove file
+
+        else if (gcode->m == 30) { // remove file
             gcode->mark_as_taken();
             rm_command("/sd/" + args, gcode->stream);
         }
@@ -175,7 +177,6 @@ void SimpleShell::on_console_line_received( void *argument )
 
     //new_message.stream->printf("Received %s\r\n", possible_command.c_str());
 
-    // We don't compare to a string but to a checksum of that string, this saves some space in flash memory
     unsigned short check_sum = get_checksum( possible_command.substr(0, possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient
 
     // find command and execute it
@@ -246,7 +247,6 @@ void SimpleShell::pwd_command( string parameters, StreamOutput *stream )
 // Output the contents of a file, first parameter is the filename, second is the limit ( in number of lines to output )
 void SimpleShell::cat_command( string parameters, StreamOutput *stream )
 {
-
     // Get parameters ( filename and line limit )
     string filename          = this->absolute_from_relative(shift_parameter( parameters ));
     string limit_paramater   = shift_parameter( parameters );
@@ -314,6 +314,21 @@ static uint32_t getDeviceType()
     return result[1];
 }
 
+// get network config
+void SimpleShell::net_command( string parameters, StreamOutput *stream)
+{
+    void *returned_data;
+    bool ok= THEKERNEL->public_data->get_value( network_checksum, get_ipconfig_checksum, &returned_data );
+    if(ok) {
+        char *str= (char *)returned_data;
+        stream->printf("%s\r\n", str);
+        free(str);
+
+    }else{
+        stream->printf("No network detected\n");
+    }
+}
+
 // print out build version
 void SimpleShell::version_command( string parameters, StreamOutput *stream)
 {
@@ -389,58 +404,6 @@ void SimpleShell::set_temp_command( string parameters, StreamOutput *stream)
     }
 }
 
-#if 0
-#include "mbed.h"
-#include "BaseSolution.h"
-#include "RostockSolution.h"
-#include "JohannKosselSolution.h"
-#endif
-void SimpleShell::test_command( string parameters, StreamOutput *stream)
-{
-#if 0
-    double millimeters[3]= {100.0, 200.0, 300.0};
-    int steps[3];
-    BaseSolution* r= new RostockSolution(THEKERNEL->config);
-    BaseSolution* k= new JohannKosselSolution(THEKERNEL->config);
-    Timer timer;
-    timer.start();
-    for(int i=0;i<10;i++) r->millimeters_to_steps(millimeters, steps);
-    timer.stop();
-    float tr= timer.read();
-    timer.reset();
-    timer.start();
-    for(int i=0;i<10;i++) k->millimeters_to_steps(millimeters, steps);
-    timer.stop();
-    float tk= timer.read();
-    stream->printf("time RostockSolution: %f, time JohannKosselSolution: %f\n", tr, tk);
-    delete kr;
-    delete tk;
-#endif
-#if 0
-// time idle loop
-#include "mbed.h"
-static int tmin = 1000000;
-static int tmax = 0;
-void time_idle()
-void time_idle()
-{
-    Timer timer;
-    timer.start();
-    int begin, end;
-    for (int i = 0; i < 1000; ++i) {
-        begin = timer.read_us();
-        THEKERNEL->call_event(ON_IDLE);
-        end = timer.read_us();
-        int d = end - begin;
-        if (d < tmin) tmin = d;
-        if (d > tmax) tmax = d;
-    }
-}
-static Timer timer;
-static int lastt = 0;
-#endif
-}
-
 void SimpleShell::help_command( string parameters, StreamOutput *stream )
 {
     stream->printf("Commands:\r\n");
@@ -463,5 +426,6 @@ void SimpleShell::help_command( string parameters, StreamOutput *stream )
     stream->printf("get temp [bed|hotend]\r\n");
     stream->printf("set_temp bed|hotend 185\r\n");
     stream->printf("get pos\r\n");
+    stream->printf("net\r\n");
 }
 
index def30ea..39039df 100644 (file)
@@ -40,7 +40,8 @@ private:
     void get_command(string parameters, StreamOutput *stream );
     void set_temp_command(string parameters, StreamOutput *stream );
     void mem_command(string parameters, StreamOutput *stream );
-    void test_command(string parameters, StreamOutput *stream );
+
+    void net_command( string parameters, StreamOutput *stream);
 
     bool parse_command(unsigned short cs, string args, StreamOutput *stream);
 
diff --git a/webif/404.html b/webif/404.html
new file mode 100644 (file)
index 0000000..60eab8f
--- /dev/null
@@ -0,0 +1,8 @@
+<html>
+  <body bgcolor="white">
+    <center>
+      <h1>404 - file not found</h1>
+      <h3>Go <a href="/">here</a> instead.</h3>
+    </center>
+  </body>
+</html>
diff --git a/webif/css/font-awesome-ie7.css b/webif/css/font-awesome-ie7.css
new file mode 120000 (symlink)
index 0000000..3773588
--- /dev/null
@@ -0,0 +1 @@
+../../../Font-Awesome/css/font-awesome-ie7.css
\ No newline at end of file
diff --git a/webif/css/font-awesome.css b/webif/css/font-awesome.css
new file mode 120000 (symlink)
index 0000000..ba16a27
--- /dev/null
@@ -0,0 +1 @@
+../../../Font-Awesome/css/font-awesome.css
\ No newline at end of file
diff --git a/webif/css/style.css b/webif/css/style.css
new file mode 100644 (file)
index 0000000..d7805f2
--- /dev/null
@@ -0,0 +1,215 @@
+body {
+       padding: 0;
+       margin: 0;
+       border: 0;
+}
+
+div.toolbar > div {
+       float: left;
+       display: inline;
+       margin: 0.2em 0;
+       padding: 0 0.5em;
+       border-right: 1px solid #DDD;
+}
+
+.clear {
+       clear: both;
+}
+
+.tabs {
+}
+
+.tabcontent {
+       position: relative;
+       background-color: #EEF;
+       border-top: none;
+       top: -1px;
+       min-height: 300px
+}
+
+.tabcontent.hidden {
+       display: none
+}
+
+.tabbutton {
+       float: left;
+       background-color: #DDD;
+       padding: 0.5em 1em;
+       border: 3px outset grey;
+       cursor: pointer;
+       border-top-left-radius: 1em;
+       border-top-right-radius: 1em;
+       border-bottom: 1px solid grey;
+       z-index: 100;
+}
+
+.tabbutton.current {
+       background-color: #EEF;
+       border: 3px inset grey;
+       border-bottom: 1px solid white;
+}
+
+#printerbar {
+
+}
+
+#printerbar input {
+       float: right;
+}
+
+#printerbar .printer {
+    float: left;
+    border: 3px outset #DDD;
+    background-color: #DDD;
+    padding: 0.5em;
+       border-radius: 10px 10px 20px 10px;
+       width: 120px;
+       overflow: hidden;
+}
+
+#printerbar .printer:hover {
+       border-color: #FFF;
+       background-color: #FFF;
+}
+
+#printerbar .current {
+    border: inset;
+    background-color: white;
+}
+
+div.toolbar > div#printername {
+       font-weight: bold;
+       font-family: "sans serif";
+       font-size: 120%;
+       border: none;
+       margin: 0.5em;
+       height: 2em;
+       width: 100%;
+       display: block;
+}
+
+.uploadingfile {
+       border: 1px solid black;
+       margin: 2px;
+       padding: 0;
+       width: 90%;
+       height: 3em;
+       overflow: hidden;
+/*     background-image: url(../images/upload_stripe.png);
+       background-repeat: repeat-x;*/
+}
+
+.uploadingfile .background {
+       position: relative;
+       padding: 0;
+       margin: 0;
+       width: 200%;
+       height: 3em;
+       left: -100%;
+       background-image: url(../images/upload_stripe.png);
+       background-repeat: repeat-x;
+}
+
+.uploadingfile .background .slider {
+       position: relative;
+       left: 50%;
+       width: 50%;
+       height: 100%;
+       padding: 0;
+       margin: 0;
+       background-color: white;
+       opacity: 0.7;
+       filter:alpha(opacity=70);
+}
+
+.uploadingfile .text {
+       z-index: 1000;
+       margin: 1em;
+       position: relative;
+       top: -3em;
+       vertical-align: middle;
+}
+
+#FileList {
+       list-style-type: none;
+       text-indent: 0;
+       padding-left: 1em;
+}
+
+#FileList > li {
+       clear: both;
+}
+
+#FileList > li > a {
+       margin-left: 1em;
+}
+
+.filesize {
+       display: inline;
+       padding-left: 2em;
+}
+
+.fileaction {
+       float: left;
+       display: block;
+       border: 2px outset gray;
+       border-radius: 4px;
+}
+
+.fileaction:active {
+       border-style: inset;
+       opacity: 0.8;
+}
+
+.fileaction_load {
+       background-color: #8F8;
+       font-size: 133%;
+       padding: 0 0.5em;
+}
+
+.fileaction_delete {
+       background-color: #FD8;
+       float: right;
+}
+
+#shadow {
+       position: absolute;
+       background-color: black;
+       opacity: 0.5;
+       width: 100%;
+       height: 100%;
+       z-index: 10000;
+       display: none;
+}
+#shadow.visible {
+       display: block;
+}
+
+#addprinter {
+       position: absolute;
+       left: 30%;
+       top: 40%;
+       opacity: 1;
+       border: 3px outset gray;
+       background-color: white;
+       border-radius: 5px;
+       z-index: 10001;
+       padding: 1em 1em 1em 0;
+       display: none;
+}
+
+#addprinter.visible {
+       display: block;
+}
+
+#addprinter > div {
+       float: left;
+       padding: 0 1em 0 2em;
+       margin-right: 1em;
+       border-left: 1px solid #EEE;
+}
+
+#addprinter #submit_addprinter {
+       clear: both;
+       float: right;
+}
diff --git a/webif/images/control_e.png b/webif/images/control_e.png
new file mode 100755 (executable)
index 0000000..8084bca
Binary files /dev/null and b/webif/images/control_e.png differ
diff --git a/webif/images/control_xy.png b/webif/images/control_xy.png
new file mode 100755 (executable)
index 0000000..12dcda7
Binary files /dev/null and b/webif/images/control_xy.png differ
diff --git a/webif/images/control_z.png b/webif/images/control_z.png
new file mode 100755 (executable)
index 0000000..56553d7
Binary files /dev/null and b/webif/images/control_z.png differ
diff --git a/webif/images/prusa_icon.png b/webif/images/prusa_icon.png
new file mode 100644 (file)
index 0000000..ac84d6f
Binary files /dev/null and b/webif/images/prusa_icon.png differ
diff --git a/webif/images/upload_stripe.png b/webif/images/upload_stripe.png
new file mode 100644 (file)
index 0000000..a439718
Binary files /dev/null and b/webif/images/upload_stripe.png differ
diff --git a/webif/img/control_xy.png b/webif/img/control_xy.png
new file mode 100644 (file)
index 0000000..12dcda7
Binary files /dev/null and b/webif/img/control_xy.png differ
diff --git a/webif/img/control_z.png b/webif/img/control_z.png
new file mode 100644 (file)
index 0000000..56553d7
Binary files /dev/null and b/webif/img/control_z.png differ
diff --git a/webif/index.html b/webif/index.html
new file mode 100644 (file)
index 0000000..66c156c
--- /dev/null
@@ -0,0 +1,283 @@
+<!doctype html>
+<head>
+       <meta charset="utf-8">
+       <title>Single Command</title>
+       <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
+       <script type=text/javascript language=JavaScript>
+  var concentric_circle_radii = [11, 45, 69, 94, 115];
+  var center = [124, 121];
+  var spacer = 7;
+  var zbutton_ydistances = [7, 30, 55, 83];
+  var zcenter = [30, 118];
+
+function runCommand(cmd) {
+  // Get some values from elements on the page:
+  var $form = $( "#commandForm" );
+  cmd += "\n";
+  url = $form.attr( "action" );
+  // Send the data using post
+  var posting = $.post( url, cmd );
+  // Put the results in a div
+  posting.done(function( data ) {
+    $( "#result" ).empty();
+    $.each(data.split('\n'), function(index) {
+      $( "#result" ).append( this + '<br/>' );
+    });
+  });
+}
+
+function lookupConcentric(radius){
+  var length = concentric_circle_radii.length;
+  for (i=0;i<=length;i++) {
+    if (radius < concentric_circle_radii[i]) return(i);
+  }
+  return(length);
+}
+
+function getQuadrantConcentricFromPosition(x,y) {
+  var rel_x = x - center[0]
+  var rel_y = y - center[1]
+  var radius = Math.sqrt(Math.pow(Math.abs(rel_x),2) + Math.pow(Math.abs(rel_y),2))
+  if (rel_x > rel_y && rel_x > -rel_y) {
+    quadrant = 0; // Right
+  } else if (rel_x <= rel_y && rel_x > -rel_y) {
+    quadrant = 3; // Down
+  } else if (rel_x > rel_y && rel_x < -rel_y) {
+    quadrant = 1; // Up
+  } else {
+    quadrant = 2; // Left
+  }
+  var idx = lookupConcentric(radius);
+  return [quadrant, idx]
+}
+
+function clickXY(event){
+  var pos_x = event.offsetX?(event.offsetX):event.pageX-document.getElementById("control_xy").offsetLeft;
+  var pos_y = event.offsetY?(event.offsetY):event.pageY-document.getElementById("control_xy").offsetTop;
+  var codes = getQuadrantConcentricFromPosition(pos_x,pos_y);
+  var quadrant = codes[0], concentric = codes[1];
+  if (concentric < 5) { // movement button pressed
+    var xdir = [1, 0, -1, 0, 0, 0][quadrant];
+    var ydir = [0, 1, 0, -1, 0, 0][quadrant];
+    var magnitude = Math.pow(10, concentric - 2);
+    if (xdir != 0) {
+      command = "G1 X" + (magnitude * xdir) + " F" + document.getElementById("xy_velocity").value;
+    } else {
+      command = "G1 Y" + (magnitude * ydir) + " F" + document.getElementById("xy_velocity").value;
+    }
+    runCommand("G91 " + command + " G90");
+  } else { // home button pressed
+    if (pos_x < 49 && pos_y < 49) { // home x button
+      command = "G28 X0";
+    } else if (pos_x > 200 && pos_y < 49) { //home y button
+      command = "G28 Y0";
+    } else if (pos_x < 49 && pos_y > 200) { // home all button
+      command = "G28";
+    } else { // home z button
+      command = "G28 Z0";
+    }
+    runCommand(command);
+  }
+}
+
+function lookupRange(ydist) {
+  var length = zbutton_ydistances.length;
+  for (i=0;i<length;i++) {
+    if (ydist < zbutton_ydistances[i]) return i;
+  }
+}
+
+function clickZ(event){
+  //var pos_x = event.offsetX?(event.offsetX):event.pageX-document.getElementById("control_z").offsetLeft;
+  var pos_y = event.offsetY?(event.offsetY):event.pageY-document.getElementById("control_z").offsetTop;
+  var ydelta = zcenter[1] - pos_y;
+  var range = lookupRange(Math.abs(ydelta));
+  var direction = (ydelta > 0)?1:-1;
+  if (range < 4) {
+    runCommand("G91 G1 Z" + (Math.pow(10,range-2) * direction) + " F" + document.getElementById("z_velocity").value + " G90");
+  }
+}
+
+function extrude(event,a,b) {
+  var length = document.getElementById("extrude_length").value;
+  var velocity = document.getElementById("extrude_velocity").value;
+  var direction = (event.currentTarget.id=='extrude')?1:-1;
+  runCommand("G91 G1 E" + (length * direction) + " F" + velocity + " G90");
+}
+
+function motorsOff(event) {
+  runCommand("M18");
+}
+
+function heatSet(event) {
+  var type = (event.currentTarget.id=='heat_set')?104:140;
+  var temperature = (type==104)?document.getElementById("heat_value").value:document.getElementById("bed_value").value;
+  runCommand("M" + type + " S" + temperature);
+}
+
+function heatOff(event) {
+  var type = (event.currentTarget.id=='heat_off')?104:140;
+  runCommand("M" + type + " S0");
+}
+
+</script>
+</head>
+
+<body>
+    <h1>Welcome to Smoothie web interface</h1>
+
+<button id=motors_off onclick=motorsOff(event)>Motors Off</button>
+XY:<input type=text id=xy_velocity size=4 value=3000 style=width:50px>mm/min
+Z:<input type=text id=z_velocity size=3 value=200 style=width:40px>
+<br>
+<img id=control_xy src=img/control_xy.png onclick=clickXY(event)>
+<img id=control_z src=img/control_z.png onclick=clickZ(event)>
+<br>
+<table><tr><td>
+<table>
+<tr>
+<td style=text-align:right>Heat:</td>
+<td><button id=heat_off onclick=heatOff(event)>Off</button></td>
+<td><input type=text id=heat_value size=3 style=width:40px value=0></td>
+<td><button id=heat_set onclick=heatSet(event)>Set</button></td>
+</tr>
+<tr>
+<td style=text-align:right>Bed:</td>
+<td><button id=bed_off onclick=heatOff(event)>Off</button></td>
+<td><input type=text id=bed_value size=3 style=width:40px value=0></td>
+<td><button id=bed_set onclick=heatSet(event)>Set</button></td>
+</tr>
+</table>
+</td><td valign=top>
+<button id=get_temperature onclick=runCommand("M105")>Get Temperature</button>
+</td></tr></table>
+<br>
+<button id=extrude onclick=extrude(event)>Extrude</button>
+<button id=reverse onclick=extrude(event)>Reverse</button><br>
+<input type=text id=extrude_length value=5 size=3 style=width:35px>
+mm @
+<input type=text id=extrude_velocity value=100 size=3 style=width:40px>
+mm/min
+
+    <h2>Commands</h2>
+       <form action="/command" id="commandForm">
+               <input type="text" name="commandText" placeholder="Send Command...">
+               <input type="submit" value="Send">
+       </form>
+       <!-- the result of the command will be rendered inside this div -->
+       <div id="result"></div>
+       <script>
+               // Attach a submit handler to the form
+               $( "#commandForm" ).submit(function( event ) {
+                       // Stop form from submitting normally
+                       event.preventDefault();
+                       // Get some values from elements on the page:
+                       var $form = $( this );
+                       command = $form.find( "input[name='commandText']" ).val();
+                       command += "\n";
+                       url = $form.attr( "action" );
+                       // Send the data using post
+                       var posting = $.post( url, command );
+                       // Put the results in a div
+                       posting.done(function( data ) {
+                               $( "#result" ).empty();
+                $.each(data.split('\n'), function(index) {
+                    $( "#result" ).append( this + '<br/>' );
+                });
+                       });
+               });
+       </script>
+
+       <h2> Upload File </h2>
+       <input type="file" id="files" name="files[]" onchange="upload();" />
+
+       <h3>Uploading file(s)</h3>
+       <output id="list"></output>
+    <div id="progress"></div>
+    <div id="uploadresult"></div>
+       <script>
+       function handleFileSelect(evt) {
+           var files = evt.target.files; // handleFileSelectist object
+
+           // files is a FileList of File objects. List some properties.
+           var output = [];
+           for (var i = 0, f; f = files[i]; i++) {
+               output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
+                       f.size, ' bytes, last modified: ',
+                       f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
+                       '</li>');
+           }
+           document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
+       }
+
+       document.getElementById('files').addEventListener('change', handleFileSelect, false);
+
+
+       function upload() {
+        // take the file from the input
+        var file = document.getElementById('files').files[0];
+        var reader = new FileReader();
+        reader.readAsBinaryString(file); // alternatively you can use readAsDataURL
+        reader.onloadend  = function(evt)
+        {
+            // create XHR instance
+            xhr = new XMLHttpRequest();
+
+            // send the file through POST
+            xhr.open("POST", 'upload', true);
+                       xhr.setRequestHeader('X-Filename', file.name);
+
+            // make sure we have the sendAsBinary method on all browsers
+            XMLHttpRequest.prototype.mySendAsBinary = function(text){
+                var data = new ArrayBuffer(text.length);
+                var ui8a = new Uint8Array(data, 0);
+                for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
+
+                if(typeof window.Blob == "function")
+                {
+                     var blob = new Blob([data]);
+                }else{
+                     var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
+                     bb.append(data);
+                     var blob = bb.getBlob();
+                }
+
+                this.send(blob);
+            }
+
+            // let's track upload progress
+            var eventSource = xhr.upload || xhr;
+            eventSource.addEventListener("progress", function(e) {
+                // get percentage of how much of the current file has been sent
+                var position = e.position || e.loaded;
+                var total = e.totalSize || e.total;
+                var percentage = Math.round((position/total)*100);
+
+                // here you should write your own code how you wish to proces this
+                $( "#progress" ).empty().append('uploaded ' + percentage + '%');
+            });
+
+            // state change observer - we need to know when and if the file was successfully uploaded
+            xhr.onreadystatechange = function()
+            {
+                if(xhr.readyState == 4)
+                {
+                    if(xhr.status == 200)
+                    {
+                        // process success
+                        $( "#uploadresult" ).empty().append( 'Uploaded Ok');
+                    }else{
+                        // process error
+                        $( "#uploadresult" ).empty().append( 'Uploaded Failed');
+                    }
+                }
+            };
+
+            // start sending
+            xhr.mySendAsBinary(evt.target.result);
+        };
+       }
+       </script>
+
+</body>
+</html>
diff --git a/webif/js/boundvalue.js b/webif/js/boundvalue.js
new file mode 100644 (file)
index 0000000..a0dcd72
--- /dev/null
@@ -0,0 +1,86 @@
+// constructor for numeric values bound to input fields
+function boundValue(inputElement, defaultValue, min, max, integer) {
+       var self = this;
+
+       this.input = $(inputElement);
+       this.defaultValue = defaultValue;
+       this.value = undefined;
+       this.normalBackground = this.input.style.backgroundColor;
+       this.lastValidValue = defaultValue;
+       this.max = max;
+       this.min = min;
+       this.integer = integer;
+
+       this.input.observe('blur', function(e) {
+               try {
+                       self.set(this.value);
+                       this.style.backgroundColor = self.normalBackground;
+               }
+               catch (e) {
+                       self.normalBackground = this.style.backgroundColor;
+                       this.style.backgroundColor = 'orange';
+                       alert(e);
+                       this.value = self.lastValidValue;
+                       this.focus();
+               }
+       });
+
+       this.input.observe('change', function(e) {
+               this.style.backgroundColor = self.normalBackground;
+       });
+
+       this.set(this.defaultValue);
+}
+
+boundValue.prototype = {
+       checkValue: function(newvalue) {
+               if (!isNaN(newvalue) && isFinite(newvalue)) {
+                       if (!isNaN(this.max) && newvalue > this.max) {
+                               newvalue = this.max;
+                       }
+                       if (!isNaN(this.min) && newvalue < this.min) {
+                               newvalue = this.min;
+                       }
+                       if (this.integer)
+                               newvalue = parseInt(newvalue);
+                       else
+                               newvalue = parseFloat(newvalue);
+                       return newvalue;
+               }
+               else
+                       throw newvalue + " is not numeric!";
+       },
+       set: function(newvalue) {
+               newvalue = this.checkValue(newvalue);
+               this.value = newvalue
+               this.input.value = newvalue;
+               this.lastValidValue = newvalue;
+       },
+       setMin: function(newvalue) {
+               if (!isNaN(newvalue) && isFinite(newvalue)) {
+                       if (this.integer)
+                               newvalue = parseInt(newvalue);
+                       else
+                               newvalue = parseFloat(newvalue);
+                       this.min = newvalue;
+                       this.set(this.value);
+               }
+               else
+                       throw newvalue + " is not numeric!";
+       },
+       setMax: function(newvalue) {
+               if (!isNaN(newvalue) && isFinite(newvalue)) {
+                       if (this.integer)
+                               newvalue = parseInt(newvalue);
+                       else
+                               newvalue = parseFloat(newvalue);
+                       this.max = newvalue;
+                       this.set(this.value);
+               }
+               else
+                       throw newvalue + " is not numeric!";
+       },
+       toString: function() {
+               return this.value + "";
+       }
+};
diff --git a/webif/js/jog.js b/webif/js/jog.js
new file mode 100644 (file)
index 0000000..1e7ad24
--- /dev/null
@@ -0,0 +1,334 @@
+Math.sign = function (num) {
+       if (num > 0) {
+               return 1;
+       }
+       if (num < 0) {
+               return -1;
+       }
+       return 0;
+};
+
+// from http://www.webmasterworld.com/javascript/3551991.htm
+function pointInPolygon(p, x, y) {
+       var npol = p.length, i, j, c = 0;
+       for (i = 0, j = npol - 1; i < npol; j = i++) {
+               if ((((p[i].y <= y) && (y < p[j].y)) ||
+                       ((p[j].y <= y) && (y < p[i].y))) &&
+                       (x < (p[j].x - p[i].x) * (y - p[i].y) / (p[j].y - p[i].y) + p[i].x)) {
+                       c = !c;
+               }
+       }
+       return c;
+}
+
+/*
+ * Now for some actual objects
+ */
+
+function Point(x, y) {
+       var self = this;
+       this.x = x;
+       this.y = y;
+}
+
+function Button(description, gcode) {
+       var self = this;
+       this.description = description;
+       this.gcode = gcode;
+
+       this.points = [];
+}
+
+Button.prototype = {
+       check: function(x, y) {
+               return pointInPolygon(this.points, x, y);
+       },
+       toString: function() {
+               return this.description;
+       },
+       highlight: function(context) {
+               var i;
+               context.save();
+               context.lineWidth = 2;
+               context.strokeStyle = "rgba(255, 255, 64, 1)";
+               context.fillStyle = "rgba(255, 255, 64, 0.25)";
+               context.beginPath();
+               context.moveTo(this.points[this.points.length - 1].x, this.points[this.points.length - 1].y);
+               for (i = 0; i < this.points.length; i++) {
+                       context.lineTo(this.points[i].x, this.points[i].y);
+               }
+               context.stroke();
+               context.fill();
+               context.restore();
+       }
+};
+
+function Jog(canvas) {
+       var self = this;
+       this.eventListeners = {
+               click: []
+       };
+       this.fireEvent = function(name, e) {
+               if (self.eventListeners[name]) {
+                       if (self.eventListeners[name].length > 0) {
+                               var a, f;
+                               for (f = 0; f < self.eventListeners[name].length; f++) {
+                                       self.eventListeners[name][f](e);
+                               }
+                       }
+               }
+       };
+       
+       this.buttons = [];
+       this.canvas = canvas;
+
+       if (!canvas) {
+               return this;
+       }
+       
+       this.context = canvas.getContext('2d');
+       this.context.circle = function(x, y, radius) {
+               this.save();
+               this.beginPath();
+               this.arc(x, y, radius, 0, Math.PI * 2, true);
+               this.stroke();
+               this.restore();
+       };
+       this.context.line = function(x1, y1, x2, y2) {
+               this.save();
+               this.beginPath();
+               this.moveTo(x1, y1);
+               this.lineTo(x2, y2);
+               this.stroke();
+               this.restore();
+       };
+       
+       this.canvas.onmousemove = function(e) {
+               var x = e.clientX - $(self.canvas).viewportOffset().left;
+               var y = e.clientY - $(self.canvas).viewportOffset().top;
+               var b;
+               self.draw();
+               for (b = 0; b < self.buttons.length; b++) {
+                       if (self.buttons[b].check(x, y)) {
+                               // TODO: highlight
+                               self.buttons[b].highlight(self.context);
+                       }
+               }
+       };
+       this.canvas.onclick = function(e) {
+               var x = e.clientX - $(self.canvas).viewportOffset().left;
+               var y = e.clientY - $(self.canvas).viewportOffset().top;
+               var b;
+               for (b = 0; b < self.buttons.length; b++) {
+                       var button = self.buttons[b];
+                       if (button.check(x, y)) {
+                               e.description = button.description;
+                               e.gcode = button.gcode;
+                               self.fireEvent('click', e);
+                       }
+               }
+       };
+       this.canvas.onmouseout = function(e) {
+               self.draw();
+       };
+}
+
+Jog.prototype = {
+       draw: function() {
+               var canvas = this.canvas;
+               var context = this.context;
+               context.clearRect(0, 0, canvas.width, canvas.height);
+       },
+       observe: function(event, callback) {
+               if (this.eventListeners[event]) {
+                       this.eventListeners[event].push(callback);
+               }
+       }
+};
+
+/*
+ * XY jog buttons
+ */
+
+ButtonXY.prototype = new Button();
+ButtonXY.prototype.constructor = ButtonXY;
+function ButtonXY(axis, length, canvas) {
+       var self = this, a;
+
+       Button.call(this, axis + length, [ "G91", "G1 " + axis + length, "G90" ]);
+       
+       var innerR;
+       var outerR;
+       var centerX = 247 * 0.5;
+       var centerY = 242 * 0.5;
+       var quadrant;
+       if (length == 0.1 || length == -0.1) {
+               innerR = 0;
+               outerR = 32.3;
+       }
+       if (length == 1   || length == -1  ) {
+               innerR = 32.3;
+               outerR = 57.75;
+       }
+       if (length == 10  || length == -10 ) {
+               innerR = 57.76;
+               outerR = 82;
+       }
+       if (length == 100 || length == -100) {
+               innerR = 82;
+               outerR = 103;
+       }
+       
+       if (axis == 'X') {
+               quadrant = 1;
+               centerX += 10;
+       }
+       else if (axis == 'Y') {
+               quadrant = 0;
+               centerY -= 10;
+       }
+       if (length < 0) {
+               if (quadrant == 1) {
+                       centerX -= 20;
+               }
+               else if (quadrant == 0) {
+                       centerY += 20;
+               }
+               quadrant += 2;
+       }
+       
+       this.innerR = innerR;
+       this.outerR = outerR;
+       this.quadrant = quadrant;
+
+       for (a = 45; a <= 135; a += 5) {
+               this.points.push(new Point(centerX + innerR * Math.cos((quadrant * 90 - a) * Math.PI / 180), centerY + innerR * Math.sin((quadrant * 90 - a) * Math.PI / 180)));
+       }
+       for (a = 135; a >= 45; a -= 5) {
+               this.points.push(new Point(centerX + outerR * Math.cos((quadrant * 90 - a) * Math.PI / 180), centerY + outerR * Math.sin((quadrant * 90 - a) * Math.PI / 180)));
+       }
+}
+
+JogXY.prototype = new Jog();
+JogXY.prototype.constructor = JogXY;
+function JogXY(canvas) {
+       var self = this, d;
+       
+       Jog.call(this, canvas);
+       
+       for (d = 0.1; d < 101; d *= 10) {
+               this.buttons.push(new ButtonXY('X',  d));
+               this.buttons.push(new ButtonXY('X', -d));
+               this.buttons.push(new ButtonXY('Y',  d));
+               this.buttons.push(new ButtonXY('Y', -d));
+       }
+       var Xhome = new Button("Home X", [ "G28 X0" ]);
+       Xhome.points.push(new Point(11     , 8));
+       Xhome.points.push(new Point(11 + 47, 8));
+       Xhome.points.push(new Point(11 + 47, 8 +  9));
+       Xhome.points.push(new Point(11 + 26, 8 + 26));
+       Xhome.points.push(new Point(11 +  9, 8 + 47));
+       Xhome.points.push(new Point(11     , 8 + 47));
+       this.buttons.push(Xhome);
+       
+       var Yhome = new Button("Home Y", [ "G28 Y0" ]);
+       Yhome.points.push(new Point(235     , 8));
+       Yhome.points.push(new Point(235 - 47, 8));
+       Yhome.points.push(new Point(235 - 47, 8 +  9));
+       Yhome.points.push(new Point(235 - 26, 8 + 26));
+       Yhome.points.push(new Point(235 -  9, 8 + 47));
+       Yhome.points.push(new Point(235     , 8 + 47));
+       this.buttons.push(Yhome);
+
+       var Zhome = new Button("Home Z", [ "G28 Z0" ]);
+       Zhome.points.push(new Point(236     , 232));
+       Zhome.points.push(new Point(236 - 47, 232));
+       Zhome.points.push(new Point(236 - 47, 232 -  9));
+       Zhome.points.push(new Point(236 - 26, 232 - 26));
+       Zhome.points.push(new Point(236 -  9, 232 - 47));
+       Zhome.points.push(new Point(236     , 232 - 47));
+       this.buttons.push(Zhome);
+       
+       var Allhome = new Button("Home All", [ "G28 X0 Y0 Z0" ]);
+       Allhome.points.push(new Point(11     , 232));
+       Allhome.points.push(new Point(11 + 47, 232));
+       Allhome.points.push(new Point(11 + 47, 232 -  9));
+       Allhome.points.push(new Point(11 + 26, 232 - 26));
+       Allhome.points.push(new Point(11 +  9, 232 - 47));
+       Allhome.points.push(new Point(11     , 232 - 47));
+       this.buttons.push(Allhome);
+}
+
+/*
+ * Z and E jog buttons
+ */
+
+ButtonZE.prototype = new Button();
+ButtonZE.prototype.constructor = ButtonZE;
+function ButtonZE(axis, length, x1, y1, x2, y2) {
+       Button.call(this, axis + length, [ "G91", "G1 " + axis + length, "G90" ]);
+       
+       this.points.push(new Point(x1, y1));
+       this.points.push(new Point(x2, y1));
+       this.points.push(new Point(x2, y2));
+       this.points.push(new Point(x1, y2));
+}
+
+ButtonZ.prototype = new ButtonZE();
+ButtonZ.prototype.constructor = ButtonZ;
+function ButtonZ(axis, length) {
+       var x1 = 12;
+       var x2 = 47;
+       var y = [200, 172, 148, 126, 111, 90, 65, 38];
+       var q = ((Math.round(Math.log(Math.abs(length)) / Math.log(10))) + 2) * Math.sign(length) + 3;
+
+       var y1 = y[q];
+       var y2 = y[q + 1];
+       
+       ButtonZE.call(this, axis, length, x1, y1, x2, y2);
+}
+
+JogZ.prototype = new Jog();
+JogZ.prototype.constructor = JogZ;
+function JogZ(canvas) {
+       var self = this, d;
+
+       Jog.call(this, canvas);
+       
+       this.axis = 'Z';
+       
+       for (d = 0.1; d < 11; d *= 10) {
+               this.buttons.push(new ButtonZ(this.axis, d));
+               this.buttons.push(new ButtonZ(this.axis, -d));
+       }
+}
+
+ButtonE.prototype = new ButtonZE();
+function ButtonE(axis, length) {
+       var x1 = 12;
+       var x2 = 47;
+       var q = (((Math.abs(length) == 1)?0:((Math.abs(length) == 5)?1:2)) + 1) * Math.sign(length) + 3;
+
+       var y = [200, 172, 148, 126, 111, 90, 65, 38];
+       
+       var y1 = y[q];
+       var y2 = y[q + 1];
+       
+       ButtonZE.call(this, axis, length, x1, y1, x2, y2);
+}
+
+JogE.prototype = new Jog();
+JogE.prototype.constructor = JogE;
+function JogE(canvas, axis) {
+       var self = this, d;
+       
+       Jog.call(this, canvas);
+       
+       this.axis = 'E';
+       
+       for (d = 0; d < 3; d++) {
+               var v = (d == 0)?1:((d == 1)?5:10);
+               this.buttons.push(new ButtonE(this.axis, v));
+               this.buttons.push(new ButtonE(this.axis, -v));
+       }
+}
diff --git a/webif/js/netrap.js b/webif/js/netrap.js
new file mode 100644 (file)
index 0000000..f4ea688
--- /dev/null
@@ -0,0 +1,358 @@
+function netrapUplink(jsonuri) {
+       var self = this;
+
+       this.jsonuri = jsonuri;
+
+       this.printers = [ 'default' ];
+       this.currentPrinter = 'default';
+       this.files = [];
+       this.temperatures = {
+               hotend: 0,
+               bed: 0,
+       };
+       this.lastPos = {
+               X: 0,
+               Y: 0,
+               Z: 0,
+               E: 0,
+       };
+       this.queue = [];
+       this.eventListeners = {
+               printerListUpdated: [],
+               temperatureListUpdated: [],
+               positionUpdated: [],
+       }
+
+       this.fireEvent = function(name, dataObject) {
+               if (self.eventListeners[name]) {
+                       if (self.eventListeners[name].length > 0) {
+                               var e = new Event(name);
+                               for (var a in dataObject) {
+                                       e[a] = dataObject[a];
+                               }
+                               for (var f = 0; f < self.eventListeners[name].length; f++) {
+                                       self.eventListeners[name][f](e);
+                               }
+                       }
+               }
+       };
+}
+
+netrapUplink.prototype = {
+       sendCmd: function(cmd) {
+               this.queueCmd(cmd);
+               this.queueCommit();
+       },
+       queueCmd: function(cmd) {
+               this.queue[this.queue.length] = cmd;
+       },
+       queueCommit: function() {
+               var self = this;
+               try {
+                       var r = new Ajax.Request("json/printer-query?printer=" + self.currentPrinter, {
+                               contentType: "text/plain",
+                               parameters: this.queue.join("\n") + "\n",
+                               onSuccess: function (response) {
+                               },
+                       });
+               } catch (e) {
+                       alert(e);
+               }
+               this.queue = [];
+       },
+       query: function(query) {
+               var self = this;
+               var r = new Ajax.Request("json/printer-query?printer=" + self.currentPrinter, {
+                       contentType: "text/plain",
+                       parameters: query + "\n",
+                       onSuccess: function (response) {
+                               try {
+                                       var responseText = response.responseText;
+                                       var replies = response.responseText.split("\n");
+                                       if (replies[replies.length-1] === "")
+                                               replies.pop();
+                               } catch (e) {
+                                       alert(e);
+                               }
+                               //                              alert('AJAX: Success: ' + response);
+                               if (replies) {
+                                       var queries = response.request.body.split("\n");
+                                       if (queries[queries.length - 1] === "")
+                                               queries.pop();
+                                       for (var i = 0; i < replies.length; i++) {
+                                               $('log').value += "< " + replies[i] + "\n";
+                                               $('log').scrollTop = $('log').scrollHeight;
+                                               try {
+                                                       self.parseReply(queries[i], replies[i]);
+                                               } catch (e) {
+                                                       alert(e);
+                                               }
+                                       }
+                               }
+                       },
+                       onFailure: function (response) {
+                               //                              alert('AJAX: Failure: ' + response);
+                       },
+               });
+       },
+       refreshPrinterList: function(callback) {
+               // TODO: json: listPrinters
+//             this.sendCmd("TODO: listPrinters");
+               var self = this;
+               var r = new Ajax.Request("json/printer-list", {
+                       onSuccess: function (response) {
+                               try {
+                                       var json = response.responseText.evalJSON(true);
+                               } catch (e) {
+                                       alert(e);
+                               }
+                               //                              alert('AJAX: Success: ' + response);
+                               if (json) {
+                                       if (json.printers && json.printers.length >= 0) {
+                                               self.printers = json.printers;
+//                                             for (var i = 0; i < json.printers.length; i++) {
+//                                                     var printer = json.printers[i];
+//                                                     if (printer) {
+                                                               if (callback) {
+                                                                       callback(self.printers);
+                                                               }
+//                                                     }
+//                                             }
+                                       }
+                               }
+                       },
+                       onFailure: function (response) {
+                               //                              alert('AJAX: Failure: ' + response);
+                       },
+               });
+       },
+       refreshFileList: function(callback_FileList) {
+               var self = this;
+               var r = new Ajax.Request("json/file-list", {
+                       onSuccess: function (response) {
+                               try {
+                                       var json = response.responseText.evalJSON(true);
+                               } catch (e) {
+                                       alert(e);
+                               }
+                               if (json) {
+                                       if (json.files instanceof Array) {
+                                               self.files = json.files;
+//                                             while ($("FileList").childNodes.length) {
+//                                                     $("FileList").removeChild($("FileList").childNodes[0]);
+//                                             }
+//                                             for (var i = 0; i < json.files.length; i++) {
+//                                                     self.files.push(json.files[i]);
+//                                             }
+                                               callback_FileList(self.files);
+                                       }
+                               }
+                       },
+                       onFailure: function (response) {
+                               alert('AJAX: Failure: ' + response);
+                       }
+               });
+       },
+       uploadFile: function(file, callback_FileComplete, callback_FileProgress, callback_FileFailure) {
+               var self = this;
+               var xhr = new XMLHttpRequest();
+               if (xhr.upload) {
+                       xhr.open("POST", 'json/file-upload', true);
+                       $(xhr).upload.addEventListener('progress', function(e) { callback_FileProgress(e, xhr); }, false);
+                       $(xhr).onreadystatechange = function(e) {
+                               if (xhr.readyState == 4) {
+                                       if (xhr.status == 200) {
+                                               if (callback_FileComplete) callback_FileComplete(e, xhr);
+                                       }
+                                       else {
+                                               if (callback_FileFailure) callback_FileFailure(e, xhr);
+                                       }
+                               }
+                       };
+                       xhr.setRequestHeader('filename', file.name);
+                       xhr.setRequestHeader('remaining', file.size);
+                       xhr.send(file);
+               }
+       },
+       loadFile: function(file, printer, callback) {
+               var self = this;
+               var filename = file.name;
+
+               var realprinter = self.currentPrinter;
+               for (var i = 0, p; p = this.printers[i]; i++) {
+                       if (p.name === printer || p === printer) {
+                               realprinter = p.name;
+                       }
+               }
+
+               // TODO: sanitise filename
+               filename.replace(/"/, '\\"');
+               var r = new Ajax.Request("json/printer-load", {
+                       contentType: 'application/json',
+                       parameters: '{"printer":"' + realprinter + '","file":"' + filename + '"}',
+                       onSuccess: function(response) {
+//                             alert(response.responseJSON.file || response.responseJSON.error);
+                               if (callback)
+                                       callback(response);
+                       },
+                       onFailure: function(response) {
+                       },
+               });
+       },
+       deleteFile: function(file, callback) {
+               var self = this;
+               var filename = file.name;
+               var r = new Ajax.Request("json/file-delete", {
+                       contentType: 'application/json',
+                       parameters: '{"file":"' + filename + '"}',
+                       onSuccess: function(response) {
+                               if (callback)
+                                       callback(response, filename);
+                       },
+               });
+       },
+       printerList: function() {
+               return this.printers;
+       },
+       printerStart: function(printer, callback) {
+               var self = this;
+               var realprinter = self.currentPrinter
+               for (var i = 0, p; p = this.printers[i]; i++) {
+                       if (p.name === printer || p === printer) {
+                               realprinter = p.name;
+                       }
+               }
+//             alert("Starting " + realprinter);
+               var r = new Ajax.Request("json/printer-start", {
+                       contentType: 'application/json',
+                       parameters: '{"printer":"' + realprinter + '"}',
+                       onSuccess: function(response) {
+                               if (response && response.responseJSON && response.responseJSON.error)
+                                       alert(response.responseJSON.error)
+                               else if (callback)
+                                       callback(response);
+                       },
+               });
+       },
+       selectPrinter: function(printer) {
+               // TODO: json: select printer
+               for (var i = 0, p; p = this.printers[i]; i++) {
+                       if (p.name == printer) {
+                               this.currentPrinter = p.name;
+                               return;
+                       }
+               }
+       },
+       selectedPrinter: function() {
+               return this.currentPrinter;
+       },
+       addSerialPrinter: function(device, baud, callback) {
+               var self = this;
+               var r = new Ajax.Request("json/printer-add", {
+                       contentType: "application/json",
+                       parameters: '{"device":"' + device + '","baud":' + parseInt(baud) + '}',
+                       onSuccess: function(response) {
+                               self.refreshPrinterList();
+                               if (callback)
+                                       callback(this);
+                       },
+                       onFailure: function(response) {
+                               alert("Could not add Serial Printer " + device + ": " + response.responseText);
+                       }
+               });
+       },
+       addTCPPrinter: function(device, port, callback) {
+               var self = this;
+               var r = new Ajax.Request("json/printer-add", {
+                       contentType: "application/json",
+                       parameters: '{"device":"' + device + '","port":' + parseInt(port) + '}',
+                       onSuccess: function(response) {
+                               self.refreshPrinterList();
+                               if (callback)
+                                       callback(this);
+                       },
+                       onFailure: function(response) {
+                               alert("Could not add TCP Printer " + device + ": " + response.responseText);
+                       }
+               });
+       },
+       refreshTemperatureList: function() {
+               this.query('M105');
+       },
+       temperatureList: function() {
+               return this.temperatures;
+       },
+       refreshPosition: function() {
+               this.query('M114');
+       },
+       position: function() {
+               return this.lastPos;
+       },
+       jog: function(x, y, z, e) {
+               var l = [ 'G1' ];
+               if (!isNaN(x) && isFinite(x)) {
+                       l.push('X' + x);
+                       this.lastPos.X += x;
+               }
+               if (!isNaN(y) && isFinite(y)) {
+                       l.push('Y' + y);
+                       this.lastPos.Y += y;
+               }
+               if (!isNaN(z) && isFinite(z)) {
+                       l.push('Z' + z);
+                       this.lastPos.Z += z;
+               }
+               if (!isNaN(e) && isFinite(e)) {
+                       l.push('E' + e);
+                       this.lastPos.E += e;
+               }
+               if (l.length > 1) {
+                       this.queueCmd('G91');
+                       this.queueCmd(l.join(" "))
+                       this.queueCmd('G90');
+//                     alert(this.queue.join("\n"));
+                       this.queueCommit();
+                       this.fireEvent('positionUpdated', this.lastPos);
+               }
+       },
+       moveTo: function(x, y, z, e) {
+               var l = [ 'G1' ];
+               if (!isNaN(x) && isFinite(x)) {
+                       l.push('X' + x);
+                       this.lastPos.X = x;
+               }
+               if (!isNaN(y) && isFinite(y)) {
+                       l.push('Y' + y);
+                       this.lastPos.Y = y;
+               }
+               if (!isNaN(z) && isFinite(z)) {
+                       this.lastPos.Z = z;
+                       l.push('Z' + z);
+               }
+               if (!isNaN(e) && isFinite(e)) {
+                       this.lastPos.E = e;
+                       l.push('E' + e);
+               }
+               if (l.length > 1) {
+                       this.sendCmd(l.join(" "));
+                       this.fireEvent('positionUpdated', this.lastPos);
+               }
+       },
+       parseReply: function(query, reply) {
+               // check for printers
+               if (reply.printerList) {
+                       this.printers = reply.printerList;
+                       this.fireEvent('printerListUpdated', this.printers);
+               }
+               // check for temperatures
+               if (reply.temperatureList) {
+                       this.temperatureList =reply.temperatureList;
+                       this.fireEvent('temperatureListUpdated', this.temperatures);
+               }
+               // check for position
+               if (reply.position) {
+                       this.lastPos =reply.position;
+                       this.fireEvent('positionUpdated', this.lastPos);
+               }
+       }
+};
diff --git a/webif/js/prototype.js b/webif/js/prototype.js
new file mode 100644 (file)
index 0000000..474b223
--- /dev/null
@@ -0,0 +1,6082 @@
+/*  Prototype JavaScript framework, version 1.7
+ *  (c) 2005-2010 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+
+  Version: '1.7',
+
+  Browser: (function(){
+    var ua = navigator.userAgent;
+    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
+    return {
+      IE:             !!window.attachEvent && !isOpera,
+      Opera:          isOpera,
+      WebKit:         ua.indexOf('AppleWebKit/') > -1,
+      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
+      MobileSafari:   /Apple.*Mobile/.test(ua)
+    }
+  })(),
+
+  BrowserFeatures: {
+    XPath: !!document.evaluate,
+
+    SelectorsAPI: !!document.querySelector,
+
+    ElementExtensions: (function() {
+      var constructor = window.Element || window.HTMLElement;
+      return !!(constructor && constructor.prototype);
+    })(),
+    SpecificElementExtensions: (function() {
+      if (typeof window.HTMLDivElement !== 'undefined')
+        return true;
+
+      var div = document.createElement('div'),
+          form = document.createElement('form'),
+          isSupported = false;
+
+      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
+        isSupported = true;
+      }
+
+      div = form = null;
+
+      return isSupported;
+    })()
+  },
+
+  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+  emptyFunction: function() { },
+
+  K: function(x) { return x }
+};
+
+if (Prototype.Browser.MobileSafari)
+  Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+
+var Abstract = { };
+
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) { }
+    }
+
+    return returnValue;
+  }
+};
+
+/* Based on Alex Arnell's inheritance implementation. */
+
+var Class = (function() {
+
+  var IS_DONTENUM_BUGGY = (function(){
+    for (var p in { toString: 1 }) {
+      if (p === 'toString') return false;
+    }
+    return true;
+  })();
+
+  function subclass() {};
+  function create() {
+    var parent = null, properties = $A(arguments);
+    if (Object.isFunction(properties[0]))
+      parent = properties.shift();
+
+    function klass() {
+      this.initialize.apply(this, arguments);
+    }
+
+    Object.extend(klass, Class.Methods);
+    klass.superclass = parent;
+    klass.subclasses = [];
+
+    if (parent) {
+      subclass.prototype = parent.prototype;
+      klass.prototype = new subclass;
+      parent.subclasses.push(klass);
+    }
+
+    for (var i = 0, length = properties.length; i < length; i++)
+      klass.addMethods(properties[i]);
+
+    if (!klass.prototype.initialize)
+      klass.prototype.initialize = Prototype.emptyFunction;
+
+    klass.prototype.constructor = klass;
+    return klass;
+  }
+
+  function addMethods(source) {
+    var ancestor   = this.superclass && this.superclass.prototype,
+        properties = Object.keys(source);
+
+    if (IS_DONTENUM_BUGGY) {
+      if (source.toString != Object.prototype.toString)
+        properties.push("toString");
+      if (source.valueOf != Object.prototype.valueOf)
+        properties.push("valueOf");
+    }
+
+    for (var i = 0, length = properties.length; i < length; i++) {
+      var property = properties[i], value = source[property];
+      if (ancestor && Object.isFunction(value) &&
+          value.argumentNames()[0] == "$super") {
+        var method = value;
+        value = (function(m) {
+          return function() { return ancestor[m].apply(this, arguments); };
+        })(property).wrap(method);
+
+        value.valueOf = method.valueOf.bind(method);
+        value.toString = method.toString.bind(method);
+      }
+      this.prototype[property] = value;
+    }
+
+    return this;
+  }
+
+  return {
+    create: create,
+    Methods: {
+      addMethods: addMethods
+    }
+  };
+})();
+(function() {
+
+  var _toString = Object.prototype.toString,
+      NULL_TYPE = 'Null',
+      UNDEFINED_TYPE = 'Undefined',
+      BOOLEAN_TYPE = 'Boolean',
+      NUMBER_TYPE = 'Number',
+      STRING_TYPE = 'String',
+      OBJECT_TYPE = 'Object',
+      FUNCTION_CLASS = '[object Function]',
+      BOOLEAN_CLASS = '[object Boolean]',
+      NUMBER_CLASS = '[object Number]',
+      STRING_CLASS = '[object String]',
+      ARRAY_CLASS = '[object Array]',
+      DATE_CLASS = '[object Date]',
+      NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
+        typeof JSON.stringify === 'function' &&
+        JSON.stringify(0) === '0' &&
+        typeof JSON.stringify(Prototype.K) === 'undefined';
+
+  function Type(o) {
+    switch(o) {
+      case null: return NULL_TYPE;
+      case (void 0): return UNDEFINED_TYPE;
+    }
+    var type = typeof o;
+    switch(type) {
+      case 'boolean': return BOOLEAN_TYPE;
+      case 'number':  return NUMBER_TYPE;
+      case 'string':  return STRING_TYPE;
+    }
+    return OBJECT_TYPE;
+  }
+
+  function extend(destination, source) {
+    for (var property in source)
+      destination[property] = source[property];
+    return destination;
+  }
+
+  function inspect(object) {
+    try {
+      if (isUndefined(object)) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : String(object);
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  }
+
+  function toJSON(value) {
+    return Str('', { '': value }, []);
+  }
+
+  function Str(key, holder, stack) {
+    var value = holder[key],
+        type = typeof value;
+
+    if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
+      value = value.toJSON(key);
+    }
+
+    var _class = _toString.call(value);
+
+    switch (_class) {
+      case NUMBER_CLASS:
+      case BOOLEAN_CLASS:
+      case STRING_CLASS:
+        value = value.valueOf();
+    }
+
+    switch (value) {
+      case null: return 'null';
+      case true: return 'true';
+      case false: return 'false';
+    }
+
+    type = typeof value;
+    switch (type) {
+      case 'string':
+        return value.inspect(true);
+      case 'number':
+        return isFinite(value) ? String(value) : 'null';
+      case 'object':
+
+        for (var i = 0, length = stack.length; i < length; i++) {
+          if (stack[i] === value) { throw new TypeError(); }
+        }
+        stack.push(value);
+
+        var partial = [];
+        if (_class === ARRAY_CLASS) {
+          for (var i = 0, length = value.length; i < length; i++) {
+            var str = Str(i, value, stack);
+            partial.push(typeof str === 'undefined' ? 'null' : str);
+          }
+          partial = '[' + partial.join(',') + ']';
+        } else {
+          var keys = Object.keys(value);
+          for (var i = 0, length = keys.length; i < length; i++) {
+            var key = keys[i], str = Str(key, value, stack);
+            if (typeof str !== "undefined") {
+               partial.push(key.inspect(true)+ ':' + str);
+             }
+          }
+          partial = '{' + partial.join(',') + '}';
+        }
+        stack.pop();
+        return partial;
+    }
+  }
+
+  function stringify(object) {
+    return JSON.stringify(object);
+  }
+
+  function toQueryString(object) {
+    return $H(object).toQueryString();
+  }
+
+  function toHTML(object) {
+    return object && object.toHTML ? object.toHTML() : String.interpret(object);
+  }
+
+  function keys(object) {
+    if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
+    var results = [];
+    for (var property in object) {
+      if (object.hasOwnProperty(property)) {
+        results.push(property);
+      }
+    }
+    return results;
+  }
+
+  function values(object) {
+    var results = [];
+    for (var property in object)
+      results.push(object[property]);
+    return results;
+  }
+
+  function clone(object) {
+    return extend({ }, object);
+  }
+
+  function isElement(object) {
+    return !!(object && object.nodeType == 1);
+  }
+
+  function isArray(object) {
+    return _toString.call(object) === ARRAY_CLASS;
+  }
+
+  var hasNativeIsArray = (typeof Array.isArray == 'function')
+    && Array.isArray([]) && !Array.isArray({});
+
+  if (hasNativeIsArray) {
+    isArray = Array.isArray;
+  }
+
+  function isHash(object) {
+    return object instanceof Hash;
+  }
+
+  function isFunction(object) {
+    return _toString.call(object) === FUNCTION_CLASS;
+  }
+
+  function isString(object) {
+    return _toString.call(object) === STRING_CLASS;
+  }
+
+  function isNumber(object) {
+    return _toString.call(object) === NUMBER_CLASS;
+  }
+
+  function isDate(object) {
+    return _toString.call(object) === DATE_CLASS;
+  }
+
+  function isUndefined(object) {
+    return typeof object === "undefined";
+  }
+
+  extend(Object, {
+    extend:        extend,
+    inspect:       inspect,
+    toJSON:        NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
+    toQueryString: toQueryString,
+    toHTML:        toHTML,
+    keys:          Object.keys || keys,
+    values:        values,
+    clone:         clone,
+    isElement:     isElement,
+    isArray:       isArray,
+    isHash:        isHash,
+    isFunction:    isFunction,
+    isString:      isString,
+    isNumber:      isNumber,
+    isDate:        isDate,
+    isUndefined:   isUndefined
+  });
+})();
+Object.extend(Function.prototype, (function() {
+  var slice = Array.prototype.slice;
+
+  function update(array, args) {
+    var arrayLength = array.length, length = args.length;
+    while (length--) array[arrayLength + length] = args[length];
+    return array;
+  }
+
+  function merge(array, args) {
+    array = slice.call(array, 0);
+    return update(array, args);
+  }
+
+  function argumentNames() {
+    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
+      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
+      .replace(/\s+/g, '').split(',');
+    return names.length == 1 && !names[0] ? [] : names;
+  }
+
+  function bind(context) {
+    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
+    var __method = this, args = slice.call(arguments, 1);
+    return function() {
+      var a = merge(args, arguments);
+      return __method.apply(context, a);
+    }
+  }
+
+  function bindAsEventListener(context) {
+    var __method = this, args = slice.call(arguments, 1);
+    return function(event) {
+      var a = update([event || window.event], args);
+      return __method.apply(context, a);
+    }
+  }
+
+  function curry() {
+    if (!arguments.length) return this;
+    var __method = this, args = slice.call(arguments, 0);
+    return function() {
+      var a = merge(args, arguments);
+      return __method.apply(this, a);
+    }
+  }
+
+  function delay(timeout) {
+    var __method = this, args = slice.call(arguments, 1);
+    timeout = timeout * 1000;
+    return window.setTimeout(function() {
+      return __method.apply(__method, args);
+    }, timeout);
+  }
+
+  function defer() {
+    var args = update([0.01], arguments);
+    return this.delay.apply(this, args);
+  }
+
+  function wrap(wrapper) {
+    var __method = this;
+    return function() {
+      var a = update([__method.bind(this)], arguments);
+      return wrapper.apply(this, a);
+    }
+  }
+
+  function methodize() {
+    if (this._methodized) return this._methodized;
+    var __method = this;
+    return this._methodized = function() {
+      var a = update([this], arguments);
+      return __method.apply(null, a);
+    };
+  }
+
+  return {
+    argumentNames:       argumentNames,
+    bind:                bind,
+    bindAsEventListener: bindAsEventListener,
+    curry:               curry,
+    delay:               delay,
+    defer:               defer,
+    wrap:                wrap,
+    methodize:           methodize
+  }
+})());
+
+
+
+(function(proto) {
+
+
+  function toISOString() {
+    return this.getUTCFullYear() + '-' +
+      (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+      this.getUTCDate().toPaddedString(2) + 'T' +
+      this.getUTCHours().toPaddedString(2) + ':' +
+      this.getUTCMinutes().toPaddedString(2) + ':' +
+      this.getUTCSeconds().toPaddedString(2) + 'Z';
+  }
+
+
+  function toJSON() {
+    return this.toISOString();
+  }
+
+  if (!proto.toISOString) proto.toISOString = toISOString;
+  if (!proto.toJSON) proto.toJSON = toJSON;
+
+})(Date.prototype);
+
+
+RegExp.prototype.match = RegExp.prototype.test;
+
+RegExp.escape = function(str) {
+  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+var PeriodicalExecuter = Class.create({
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  execute: function() {
+    this.callback(this);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.execute();
+        this.currentlyExecuting = false;
+      } catch(e) {
+        this.currentlyExecuting = false;
+        throw e;
+      }
+    }
+  }
+});
+Object.extend(String, {
+  interpret: function(value) {
+    return value == null ? '' : String(value);
+  },
+  specialChar: {
+    '\b': '\\b',
+    '\t': '\\t',
+    '\n': '\\n',
+    '\f': '\\f',
+    '\r': '\\r',
+    '\\': '\\\\'
+  }
+});
+
+Object.extend(String.prototype, (function() {
+  var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
+    typeof JSON.parse === 'function' &&
+    JSON.parse('{"test": true}').test;
+
+  function prepareReplacement(replacement) {
+    if (Object.isFunction(replacement)) return replacement;
+    var template = new Template(replacement);
+    return function(match) { return template.evaluate(match) };
+  }
+
+  function gsub(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = prepareReplacement(replacement);
+
+    if (Object.isString(pattern))
+      pattern = RegExp.escape(pattern);
+
+    if (!(pattern.length || pattern.source)) {
+      replacement = replacement('');
+      return replacement + source.split('').join(replacement) + replacement;
+    }
+
+    while (source.length > 0) {
+      if (match = source.match(pattern)) {
+        result += source.slice(0, match.index);
+        result += String.interpret(replacement(match));
+        source  = source.slice(match.index + match[0].length);
+      } else {
+        result += source, source = '';
+      }
+    }
+    return result;
+  }
+
+  function sub(pattern, replacement, count) {
+    replacement = prepareReplacement(replacement);
+    count = Object.isUndefined(count) ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  }
+
+  function scan(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return String(this);
+  }
+
+  function truncate(length, truncation) {
+    length = length || 30;
+    truncation = Object.isUndefined(truncation) ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : String(this);
+  }
+
+  function strip() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  }
+
+  function stripTags() {
+    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
+  }
+
+  function stripScripts() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  }
+
+  function extractScripts() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
+        matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  }
+
+  function evalScripts() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  }
+
+  function escapeHTML() {
+    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+  }
+
+  function unescapeHTML() {
+    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
+  }
+
+
+  function toQueryParams(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return { };
+
+    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var key = decodeURIComponent(pair.shift()),
+            value = pair.length > 1 ? pair.join('=') : pair[0];
+
+        if (value != undefined) value = decodeURIComponent(value);
+
+        if (key in hash) {
+          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+          hash[key].push(value);
+        }
+        else hash[key] = value;
+      }
+      return hash;
+    });
+  }
+
+  function toArray() {
+    return this.split('');
+  }
+
+  function succ() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  }
+
+  function times(count) {
+    return count < 1 ? '' : new Array(count + 1).join(this);
+  }
+
+  function camelize() {
+    return this.replace(/-+(.)?/g, function(match, chr) {
+      return chr ? chr.toUpperCase() : '';
+    });
+  }
+
+  function capitalize() {
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  }
+
+  function underscore() {
+    return this.replace(/::/g, '/')
+               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
+               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+               .replace(/-/g, '_')
+               .toLowerCase();
+  }
+
+  function dasherize() {
+    return this.replace(/_/g, '-');
+  }
+
+  function inspect(useDoubleQuotes) {
+    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
+      if (character in String.specialChar) {
+        return String.specialChar[character];
+      }
+      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
+    });
+    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  }
+
+  function unfilterJSON(filter) {
+    return this.replace(filter || Prototype.JSONFilter, '$1');
+  }
+
+  function isJSON() {
+    var str = this;
+    if (str.blank()) return false;
+    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
+    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
+    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
+    return (/^[\],:{}\s]*$/).test(str);
+  }
+
+  function evalJSON(sanitize) {
+    var json = this.unfilterJSON(),
+        cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+    if (cx.test(json)) {
+      json = json.replace(cx, function (a) {
+        return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+      });
+    }
+    try {
+      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+    } catch (e) { }
+    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+  }
+
+  function parseJSON() {
+    var json = this.unfilterJSON();
+    return JSON.parse(json);
+  }
+
+  function include(pattern) {
+    return this.indexOf(pattern) > -1;
+  }
+
+  function startsWith(pattern) {
+    return this.lastIndexOf(pattern, 0) === 0;
+  }
+
+  function endsWith(pattern) {
+    var d = this.length - pattern.length;
+    return d >= 0 && this.indexOf(pattern, d) === d;
+  }
+
+  function empty() {
+    return this == '';
+  }
+
+  function blank() {
+    return /^\s*$/.test(this);
+  }
+
+  function interpolate(object, pattern) {
+    return new Template(this, pattern).evaluate(object);
+  }
+
+  return {
+    gsub:           gsub,
+    sub:            sub,
+    scan:           scan,
+    truncate:       truncate,
+    strip:          String.prototype.trim || strip,
+    stripTags:      stripTags,
+    stripScripts:   stripScripts,
+    extractScripts: extractScripts,
+    evalScripts:    evalScripts,
+    escapeHTML:     escapeHTML,
+    unescapeHTML:   unescapeHTML,
+    toQueryParams:  toQueryParams,
+    parseQuery:     toQueryParams,
+    toArray:        toArray,
+    succ:           succ,
+    times:          times,
+    camelize:       camelize,
+    capitalize:     capitalize,
+    underscore:     underscore,
+    dasherize:      dasherize,
+    inspect:        inspect,
+    unfilterJSON:   unfilterJSON,
+    isJSON:         isJSON,
+    evalJSON:       NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
+    include:        include,
+    startsWith:     startsWith,
+    endsWith:       endsWith,
+    empty:          empty,
+    blank:          blank,
+    interpolate:    interpolate
+  };
+})());
+
+var Template = Class.create({
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    if (object && Object.isFunction(object.toTemplateReplacements))
+      object = object.toTemplateReplacements();
+
+    return this.template.gsub(this.pattern, function(match) {
+      if (object == null) return (match[1] + '');
+
+      var before = match[1] || '';
+      if (before == '\\') return match[2];
+
+      var ctx = object, expr = match[3],
+          pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+
+      match = pattern.exec(expr);
+      if (match == null) return before;
+
+      while (match != null) {
+        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
+        ctx = ctx[comp];
+        if (null == ctx || '' == match[3]) break;
+        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+        match = pattern.exec(expr);
+      }
+
+      return before + String.interpret(ctx);
+    });
+  }
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+
+var $break = { };
+
+var Enumerable = (function() {
+  function each(iterator, context) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        iterator.call(context, value, index++);
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  }
+
+  function eachSlice(number, iterator, context) {
+    var index = -number, slices = [], array = this.toArray();
+    if (number < 1) return array;
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.collect(iterator, context);
+  }
+
+  function all(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!iterator.call(context, value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  }
+
+  function any(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!iterator.call(context, value, index))
+        throw $break;
+    });
+    return result;
+  }
+
+  function collect(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var results = [];
+    this.each(function(value, index) {
+      results.push(iterator.call(context, value, index));
+    });
+    return results;
+  }
+
+  function detect(iterator, context) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator.call(context, value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  }
+
+  function findAll(iterator, context) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator.call(context, value, index))
+        results.push(value);
+    });
+    return results;
+  }
+
+  function grep(filter, iterator, context) {
+    iterator = iterator || Prototype.K;
+    var results = [];
+
+    if (Object.isString(filter))
+      filter = new RegExp(RegExp.escape(filter));
+
+    this.each(function(value, index) {
+      if (filter.match(value))
+        results.push(iterator.call(context, value, index));
+    });
+    return results;
+  }
+
+  function include(object) {
+    if (Object.isFunction(this.indexOf))
+      if (this.indexOf(object) != -1) return true;
+
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  }
+
+  function inGroupsOf(number, fillWith) {
+    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  }
+
+  function inject(memo, iterator, context) {
+    this.each(function(value, index) {
+      memo = iterator.call(context, memo, value, index);
+    });
+    return memo;
+  }
+
+  function invoke(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  }
+
+  function max(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator.call(context, value, index);
+      if (result == null || value >= result)
+        result = value;
+    });
+    return result;
+  }
+
+  function min(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator.call(context, value, index);
+      if (result == null || value < result)
+        result = value;
+    });
+    return result;
+  }
+
+  function partition(iterator, context) {
+    iterator = iterator || Prototype.K;
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      (iterator.call(context, value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  }
+
+  function pluck(property) {
+    var results = [];
+    this.each(function(value) {
+      results.push(value[property]);
+    });
+    return results;
+  }
+
+  function reject(iterator, context) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator.call(context, value, index))
+        results.push(value);
+    });
+    return results;
+  }
+
+  function sortBy(iterator, context) {
+    return this.map(function(value, index) {
+      return {
+        value: value,
+        criteria: iterator.call(context, value, index)
+      };
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  }
+
+  function toArray() {
+    return this.map();
+  }
+
+  function zip() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (Object.isFunction(args.last()))
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  }
+
+  function size() {
+    return this.toArray().length;
+  }
+
+  function inspect() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+
+
+
+
+
+
+
+
+
+  return {
+    each:       each,
+    eachSlice:  eachSlice,
+    all:        all,
+    every:      all,
+    any:        any,
+    some:       any,
+    collect:    collect,
+    map:        collect,
+    detect:     detect,
+    findAll:    findAll,
+    select:     findAll,
+    filter:     findAll,
+    grep:       grep,
+    include:    include,
+    member:     include,
+    inGroupsOf: inGroupsOf,
+    inject:     inject,
+    invoke:     invoke,
+    max:        max,
+    min:        min,
+    partition:  partition,
+    pluck:      pluck,
+    reject:     reject,
+    sortBy:     sortBy,
+    toArray:    toArray,
+    entries:    toArray,
+    zip:        zip,
+    size:       size,
+    inspect:    inspect,
+    find:       detect
+  };
+})();
+
+function $A(iterable) {
+  if (!iterable) return [];
+  if ('toArray' in Object(iterable)) return iterable.toArray();
+  var length = iterable.length || 0, results = new Array(length);
+  while (length--) results[length] = iterable[length];
+  return results;
+}
+
+
+function $w(string) {
+  if (!Object.isString(string)) return [];
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+Array.from = $A;
+
+
+(function() {
+  var arrayProto = Array.prototype,
+      slice = arrayProto.slice,
+      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
+
+  function each(iterator, context) {
+    for (var i = 0, length = this.length >>> 0; i < length; i++) {
+      if (i in this) iterator.call(context, this[i], i, this);
+    }
+  }
+  if (!_each) _each = each;
+
+  function clear() {
+    this.length = 0;
+    return this;
+  }
+
+  function first() {
+    return this[0];
+  }
+
+  function last() {
+    return this[this.length - 1];
+  }
+
+  function compact() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  }
+
+  function flatten() {
+    return this.inject([], function(array, value) {
+      if (Object.isArray(value))
+        return array.concat(value.flatten());
+      array.push(value);
+      return array;
+    });
+  }
+
+  function without() {
+    var values = slice.call(arguments, 0);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  }
+
+  function reverse(inline) {
+    return (inline === false ? this.toArray() : this)._reverse();
+  }
+
+  function uniq(sorted) {
+    return this.inject([], function(array, value, index) {
+      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+        array.push(value);
+      return array;
+    });
+  }
+
+  function intersect(array) {
+    return this.uniq().findAll(function(item) {
+      return array.detect(function(value) { return item === value });
+    });
+  }
+
+
+  function clone() {
+    return slice.call(this, 0);
+  }
+
+  function size() {
+    return this.length;
+  }
+
+  function inspect() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+
+  function indexOf(item, i) {
+    i || (i = 0);
+    var length = this.length;
+    if (i < 0) i = length + i;
+    for (; i < length; i++)
+      if (this[i] === item) return i;
+    return -1;
+  }
+
+  function lastIndexOf(item, i) {
+    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+    var n = this.slice(0, i).reverse().indexOf(item);
+    return (n < 0) ? n : i - n - 1;
+  }
+
+  function concat() {
+    var array = slice.call(this, 0), item;
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      item = arguments[i];
+      if (Object.isArray(item) && !('callee' in item)) {
+        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
+          array.push(item[j]);
+      } else {
+        array.push(item);
+      }
+    }
+    return array;
+  }
+
+  Object.extend(arrayProto, Enumerable);
+
+  if (!arrayProto._reverse)
+    arrayProto._reverse = arrayProto.reverse;
+
+  Object.extend(arrayProto, {
+    _each:     _each,
+    clear:     clear,
+    first:     first,
+    last:      last,
+    compact:   compact,
+    flatten:   flatten,
+    without:   without,
+    reverse:   reverse,
+    uniq:      uniq,
+    intersect: intersect,
+    clone:     clone,
+    toArray:   clone,
+    size:      size,
+    inspect:   inspect
+  });
+
+  var CONCAT_ARGUMENTS_BUGGY = (function() {
+    return [].concat(arguments)[0][0] !== 1;
+  })(1,2)
+
+  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
+
+  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
+  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
+})();
+function $H(object) {
+  return new Hash(object);
+};
+
+var Hash = Class.create(Enumerable, (function() {
+  function initialize(object) {
+    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+  }
+
+
+  function _each(iterator) {
+    for (var key in this._object) {
+      var value = this._object[key], pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  }
+
+  function set(key, value) {
+    return this._object[key] = value;
+  }
+
+  function get(key) {
+    if (this._object[key] !== Object.prototype[key])
+      return this._object[key];
+  }
+
+  function unset(key) {
+    var value = this._object[key];
+    delete this._object[key];
+    return value;
+  }
+
+  function toObject() {
+    return Object.clone(this._object);
+  }
+
+
+
+  function keys() {
+    return this.pluck('key');
+  }
+
+  function values() {
+    return this.pluck('value');
+  }
+
+  function index(value) {
+    var match = this.detect(function(pair) {
+      return pair.value === value;
+    });
+    return match && match.key;
+  }
+
+  function merge(object) {
+    return this.clone().update(object);
+  }
+
+  function update(object) {
+    return new Hash(object).inject(this, function(result, pair) {
+      result.set(pair.key, pair.value);
+      return result;
+    });
+  }
+
+  function toQueryPair(key, value) {
+    if (Object.isUndefined(value)) return key;
+    return key + '=' + encodeURIComponent(String.interpret(value));
+  }
+
+  function toQueryString() {
+    return this.inject([], function(results, pair) {
+      var key = encodeURIComponent(pair.key), values = pair.value;
+
+      if (values && typeof values == 'object') {
+        if (Object.isArray(values)) {
+          var queryValues = [];
+          for (var i = 0, len = values.length, value; i < len; i++) {
+            value = values[i];
+            queryValues.push(toQueryPair(key, value));
+          }
+          return results.concat(queryValues);
+        }
+      } else results.push(toQueryPair(key, values));
+      return results;
+    }).join('&');
+  }
+
+  function inspect() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  }
+
+  function clone() {
+    return new Hash(this);
+  }
+
+  return {
+    initialize:             initialize,
+    _each:                  _each,
+    set:                    set,
+    get:                    get,
+    unset:                  unset,
+    toObject:               toObject,
+    toTemplateReplacements: toObject,
+    keys:                   keys,
+    values:                 values,
+    index:                  index,
+    merge:                  merge,
+    update:                 update,
+    toQueryString:          toQueryString,
+    inspect:                inspect,
+    toJSON:                 toObject,
+    clone:                  clone
+  };
+})());
+
+Hash.from = $H;
+Object.extend(Number.prototype, (function() {
+  function toColorPart() {
+    return this.toPaddedString(2, 16);
+  }
+
+  function succ() {
+    return this + 1;
+  }
+
+  function times(iterator, context) {
+    $R(0, this, true).each(iterator, context);
+    return this;
+  }
+
+  function toPaddedString(length, radix) {
+    var string = this.toString(radix || 10);
+    return '0'.times(length - string.length) + string;
+  }
+
+  function abs() {
+    return Math.abs(this);
+  }
+
+  function round() {
+    return Math.round(this);
+  }
+
+  function ceil() {
+    return Math.ceil(this);
+  }
+
+  function floor() {
+    return Math.floor(this);
+  }
+
+  return {
+    toColorPart:    toColorPart,
+    succ:           succ,
+    times:          times,
+    toPaddedString: toPaddedString,
+    abs:            abs,
+    round:          round,
+    ceil:           ceil,
+    floor:          floor
+  };
+})());
+
+function $R(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+}
+
+var ObjectRange = Class.create(Enumerable, (function() {
+  function initialize(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  }
+
+  function _each(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  }
+
+  function include(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+
+  return {
+    initialize: initialize,
+    _each:      _each,
+    include:    include
+  };
+})());
+
+
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new XMLHttpRequest()},
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+};
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (Object.isFunction(responder[callback])) {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) { }
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate:   function() { Ajax.activeRequestCount++ },
+  onComplete: function() { Ajax.activeRequestCount-- }
+});
+Ajax.Base = Class.create({
+  initialize: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   '',
+      evalJSON:     true,
+      evalJS:       true
+    };
+    Object.extend(this.options, options || { });
+
+    this.options.method = this.options.method.toLowerCase();
+
+    if (Object.isHash(this.options.parameters))
+      this.options.parameters = this.options.parameters.toObject();
+  }
+});
+Ajax.Request = Class.create(Ajax.Base, {
+  _complete: false,
+
+  initialize: function($super, url, options) {
+    $super(options);
+    this.transport = Ajax.getTransport();
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = Object.isString(this.options.parameters) ?
+          this.options.parameters :
+          Object.toQueryString(this.options.parameters);
+
+    if (!['get', 'post'].include(this.method)) {
+      params += (params ? '&' : '') + "_method=" + this.method;
+      this.method = 'post';
+    }
+
+    if (params && this.method === 'get') {
+      this.url += (this.url.include('?') ? '&' : '?') + params;
+    }
+
+    this.parameters = params.toQueryParams();
+
+    try {
+      var response = new Ajax.Response(this);
+      if (this.options.onCreate) this.options.onCreate(response);
+      Ajax.Responders.dispatch('onCreate', this, response);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+      this.transport.send(this.body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (Object.isFunction(extras.push))
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    var status = this.getStatus();
+    return !status || (status >= 200 && status < 300) || status == 304;
+  },
+
+  getStatus: function() {
+    try {
+      if (this.transport.status === 1223) return 204;
+      return this.transport.status || 0;
+    } catch (e) { return 0 }
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + response.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(response, response.headerJSON);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      var contentType = response.getHeader('Content-type');
+      if (this.options.evalJS == 'force'
+          || (this.options.evalJS && this.isSameOrigin() && contentType
+          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+        this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  isSameOrigin: function() {
+    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
+    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
+      protocol: location.protocol,
+      domain: document.domain,
+      port: location.port ? ':' + location.port : ''
+    }));
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name) || null;
+    } catch (e) { return null; }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval((this.transport.responseText || '').unfilterJSON());
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+
+
+
+
+
+
+
+Ajax.Response = Class.create({
+  initialize: function(request){
+    this.request = request;
+    var transport  = this.transport  = request.transport,
+        readyState = this.readyState = transport.readyState;
+
+    if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+      this.status       = this.getStatus();
+      this.statusText   = this.getStatusText();
+      this.responseText = String.interpret(transport.responseText);
+      this.headerJSON   = this._getHeaderJSON();
+    }
+
+    if (readyState == 4) {
+      var xml = transport.responseXML;
+      this.responseXML  = Object.isUndefined(xml) ? null : xml;
+      this.responseJSON = this._getResponseJSON();
+    }
+  },
+
+  status:      0,
+
+  statusText: '',
+
+  getStatus: Ajax.Request.prototype.getStatus,
+
+  getStatusText: function() {
+    try {
+      return this.transport.statusText || '';
+    } catch (e) { return '' }
+  },
+
+  getHeader: Ajax.Request.prototype.getHeader,
+
+  getAllHeaders: function() {
+    try {
+      return this.getAllResponseHeaders();
+    } catch (e) { return null }
+  },
+
+  getResponseHeader: function(name) {
+    return this.transport.getResponseHeader(name);
+  },
+
+  getAllResponseHeaders: function() {
+    return this.transport.getAllResponseHeaders();
+  },
+
+  _getHeaderJSON: function() {
+    var json = this.getHeader('X-JSON');
+    if (!json) return null;
+    json = decodeURIComponent(escape(json));
+    try {
+      return json.evalJSON(this.request.options.sanitizeJSON ||
+        !this.request.isSameOrigin());
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  },
+
+  _getResponseJSON: function() {
+    var options = this.request.options;
+    if (!options.evalJSON || (options.evalJSON != 'force' &&
+      !(this.getHeader('Content-type') || '').include('application/json')) ||
+        this.responseText.blank())
+          return null;
+    try {
+      return this.responseText.evalJSON(options.sanitizeJSON ||
+        !this.request.isSameOrigin());
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  }
+});
+
+Ajax.Updater = Class.create(Ajax.Request, {
+  initialize: function($super, container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    };
+
+    options = Object.clone(options);
+    var onComplete = options.onComplete;
+    options.onComplete = (function(response, json) {
+      this.updateContent(response.responseText);
+      if (Object.isFunction(onComplete)) onComplete(response, json);
+    }).bind(this);
+
+    $super(url, options);
+  },
+
+  updateContent: function(responseText) {
+    var receiver = this.container[this.success() ? 'success' : 'failure'],
+        options = this.options;
+
+    if (!options.evalScripts) responseText = responseText.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (options.insertion) {
+        if (Object.isString(options.insertion)) {
+          var insertion = { }; insertion[options.insertion] = responseText;
+          receiver.insert(insertion);
+        }
+        else options.insertion(receiver, responseText);
+      }
+      else receiver.update(responseText);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+  initialize: function($super, container, url, options) {
+    $super(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = { };
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(response) {
+    if (this.options.decay) {
+      this.decay = (response.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = response.responseText;
+    }
+    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+
+
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (Object.isString(element))
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(Element.extend(query.snapshotItem(i)));
+    return results;
+  };
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!Node) var Node = { };
+
+if (!Node.ELEMENT_NODE) {
+  Object.extend(Node, {
+    ELEMENT_NODE: 1,
+    ATTRIBUTE_NODE: 2,
+    TEXT_NODE: 3,
+    CDATA_SECTION_NODE: 4,
+    ENTITY_REFERENCE_NODE: 5,
+    ENTITY_NODE: 6,
+    PROCESSING_INSTRUCTION_NODE: 7,
+    COMMENT_NODE: 8,
+    DOCUMENT_NODE: 9,
+    DOCUMENT_TYPE_NODE: 10,
+    DOCUMENT_FRAGMENT_NODE: 11,
+    NOTATION_NODE: 12
+  });
+}
+
+
+
+(function(global) {
+  function shouldUseCache(tagName, attributes) {
+    if (tagName === 'select') return false;
+    if ('type' in attributes) return false;
+    return true;
+  }
+
+  var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
+    try {
+      var el = document.createElement('<input name="x">');
+      return el.tagName.toLowerCase() === 'input' && el.name === 'x';
+    }
+    catch(err) {
+      return false;
+    }
+  })();
+
+  var element = global.Element;
+
+  global.Element = function(tagName, attributes) {
+    attributes = attributes || { };
+    tagName = tagName.toLowerCase();
+    var cache = Element.cache;
+
+    if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
+      tagName = '<' + tagName + ' name="' + attributes.name + '">';
+      delete attributes.name;
+      return Element.writeAttribute(document.createElement(tagName), attributes);
+    }
+
+    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+
+    var node = shouldUseCache(tagName, attributes) ?
+     cache[tagName].cloneNode(false) : document.createElement(tagName);
+
+    return Element.writeAttribute(node, attributes);
+  };
+
+  Object.extend(global.Element, element || { });
+  if (element) global.Element.prototype = element.prototype;
+
+})(this);
+
+Element.idCounter = 1;
+Element.cache = { };
+
+Element._purgeElement = function(element) {
+  var uid = element._prototypeUID;
+  if (uid) {
+    Element.stopObserving(element);
+    element._prototypeUID = void 0;
+    delete Element.Storage[uid];
+  }
+}
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    element = $(element);
+    element.style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    element = $(element);
+    element.style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: (function(){
+
+    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
+      var el = document.createElement("select"),
+          isBuggy = true;
+      el.innerHTML = "<option value=\"test\">test</option>";
+      if (el.options && el.options[0]) {
+        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
+      }
+      el = null;
+      return isBuggy;
+    })();
+
+    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
+      try {
+        var el = document.createElement("table");
+        if (el && el.tBodies) {
+          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
+          var isBuggy = typeof el.tBodies[0] == "undefined";
+          el = null;
+          return isBuggy;
+        }
+      } catch (e) {
+        return true;
+      }
+    })();
+
+    var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
+      try {
+        var el = document.createElement('div');
+        el.innerHTML = "<link>";
+        var isBuggy = (el.childNodes.length === 0);
+        el = null;
+        return isBuggy;
+      } catch(e) {
+        return true;
+      }
+    })();
+
+    var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
+     TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
+
+    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
+      var s = document.createElement("script"),
+          isBuggy = false;
+      try {
+        s.appendChild(document.createTextNode(""));
+        isBuggy = !s.firstChild ||
+          s.firstChild && s.firstChild.nodeType !== 3;
+      } catch (e) {
+        isBuggy = true;
+      }
+      s = null;
+      return isBuggy;
+    })();
+
+
+    function update(element, content) {
+      element = $(element);
+      var purgeElement = Element._purgeElement;
+
+      var descendants = element.getElementsByTagName('*'),
+       i = descendants.length;
+      while (i--) purgeElement(descendants[i]);
+
+      if (content && content.toElement)
+        content = content.toElement();
+
+      if (Object.isElement(content))
+        return element.update().insert(content);
+
+      content = Object.toHTML(content);
+
+      var tagName = element.tagName.toUpperCase();
+
+      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
+        element.text = content;
+        return element;
+      }
+
+      if (ANY_INNERHTML_BUGGY) {
+        if (tagName in Element._insertionTranslations.tags) {
+          while (element.firstChild) {
+            element.removeChild(element.firstChild);
+          }
+          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+            .each(function(node) {
+              element.appendChild(node)
+            });
+        } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
+          while (element.firstChild) {
+            element.removeChild(element.firstChild);
+          }
+          var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
+          nodes.each(function(node) { element.appendChild(node) });
+        }
+        else {
+          element.innerHTML = content.stripScripts();
+        }
+      }
+      else {
+        element.innerHTML = content.stripScripts();
+      }
+
+      content.evalScripts.bind(content).defer();
+      return element;
+    }
+
+    return update;
+  })(),
+
+  replace: function(element, content) {
+    element = $(element);
+    if (content && content.toElement) content = content.toElement();
+    else if (!Object.isElement(content)) {
+      content = Object.toHTML(content);
+      var range = element.ownerDocument.createRange();
+      range.selectNode(element);
+      content.evalScripts.bind(content).defer();
+      content = range.createContextualFragment(content.stripScripts());
+    }
+    element.parentNode.replaceChild(content, element);
+    return element;
+  },
+
+  insert: function(element, insertions) {
+    element = $(element);
+
+    if (Object.isString(insertions) || Object.isNumber(insertions) ||
+        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+          insertions = {bottom:insertions};
+
+    var content, insert, tagName, childNodes;
+
+    for (var position in insertions) {
+      content  = insertions[position];
+      position = position.toLowerCase();
+      insert = Element._insertionTranslations[position];
+
+      if (content && content.toElement) content = content.toElement();
+      if (Object.isElement(content)) {
+        insert(element, content);
+        continue;
+      }
+
+      content = Object.toHTML(content);
+
+      tagName = ((position == 'before' || position == 'after')
+        ? element.parentNode : element).tagName.toUpperCase();
+
+      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+      if (position == 'top' || position == 'after') childNodes.reverse();
+      childNodes.each(insert.curry(element));
+
+      content.evalScripts.bind(content).defer();
+    }
+
+    return element;
+  },
+
+  wrap: function(element, wrapper, attributes) {
+    element = $(element);
+    if (Object.isElement(wrapper))
+      $(wrapper).writeAttribute(attributes || { });
+    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+    else wrapper = new Element('div', wrapper);
+    if (element.parentNode)
+      element.parentNode.replaceChild(wrapper, element);
+    wrapper.appendChild(element);
+    return wrapper;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(),
+          attribute = pair.last(),
+          value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property, maximumLength) {
+    element = $(element);
+    maximumLength = maximumLength || -1;
+    var elements = [];
+
+    while (element = element[property]) {
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+      if (elements.length == maximumLength)
+        break;
+    }
+
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return Element.recursivelyCollect(element, 'parentNode');
+  },
+
+  descendants: function(element) {
+    return Element.select(element, "*");
+  },
+
+  firstDescendant: function(element) {
+    element = $(element).firstChild;
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    return $(element);
+  },
+
+  immediateDescendants: function(element) {
+    var results = [], child = $(element).firstChild;
+    while (child) {
+      if (child.nodeType === 1) {
+        results.push(Element.extend(child));
+      }
+      child = child.nextSibling;
+    }
+    return results;
+  },
+
+  previousSiblings: function(element, maximumLength) {
+    return Element.recursivelyCollect(element, 'previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return Element.recursivelyCollect(element, 'nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return Element.previousSiblings(element).reverse()
+      .concat(Element.nextSiblings(element));
+  },
+
+  match: function(element, selector) {
+    element = $(element);
+    if (Object.isString(selector))
+      return Prototype.Selector.match(element, selector);
+    return selector.match(element);
+  },
+
+  up: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(element.parentNode);
+    var ancestors = Element.ancestors(element);
+    return Object.isNumber(expression) ? ancestors[expression] :
+      Prototype.Selector.find(ancestors, expression, index);
+  },
+
+  down: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return Element.firstDescendant(element);
+    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
+      Element.select(element, expression)[index || 0];
+  },
+
+  previous: function(element, expression, index) {
+    element = $(element);
+    if (Object.isNumber(expression)) index = expression, expression = false;
+    if (!Object.isNumber(index)) index = 0;
+
+    if (expression) {
+      return Prototype.Selector.find(element.previousSiblings(), expression, index);
+    } else {
+      return element.recursivelyCollect("previousSibling", index + 1)[index];
+    }
+  },
+
+  next: function(element, expression, index) {
+    element = $(element);
+    if (Object.isNumber(expression)) index = expression, expression = false;
+    if (!Object.isNumber(index)) index = 0;
+
+    if (expression) {
+      return Prototype.Selector.find(element.nextSiblings(), expression, index);
+    } else {
+      var maximumLength = Object.isNumber(index) ? index + 1 : 1;
+      return element.recursivelyCollect("nextSibling", index + 1)[index];
+    }
+  },
+
+
+  select: function(element) {
+    element = $(element);
+    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
+    return Prototype.Selector.select(expressions, element);
+  },
+
+  adjacent: function(element) {
+    element = $(element);
+    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
+    return Prototype.Selector.select(expressions, element.parentNode).without(element);
+  },
+
+  identify: function(element) {
+    element = $(element);
+    var id = Element.readAttribute(element, 'id');
+    if (id) return id;
+    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
+    Element.writeAttribute(element, 'id', id);
+    return id;
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (Prototype.Browser.IE) {
+      var t = Element._attributeTranslations.read;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name]) name = t.names[name];
+      if (name.include(':')) {
+        return (!element.attributes || !element.attributes[name]) ? null :
+         element.attributes[name].value;
+      }
+    }
+    return element.getAttribute(name);
+  },
+
+  writeAttribute: function(element, name, value) {
+    element = $(element);
+    var attributes = { }, t = Element._attributeTranslations.write;
+
+    if (typeof name == 'object') attributes = name;
+    else attributes[name] = Object.isUndefined(value) ? true : value;
+
+    for (var attr in attributes) {
+      name = t.names[attr] || attr;
+      value = attributes[attr];
+      if (t.values[attr]) name = t.values[attr](element, value);
+      if (value === false || value === null)
+        element.removeAttribute(name);
+      else if (value === true)
+        element.setAttribute(name, name);
+      else element.setAttribute(name, value);
+    }
+    return element;
+  },
+
+  getHeight: function(element) {
+    return Element.getDimensions(element).height;
+  },
+
+  getWidth: function(element) {
+    return Element.getDimensions(element).width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    return (elementClassName.length > 0 && (elementClassName == className ||
+      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    if (!Element.hasClassName(element, className))
+      element.className += (element.className ? ' ' : '') + className;
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    element.className = element.className.replace(
+      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    return Element[Element.hasClassName(element, className) ?
+      'removeClassName' : 'addClassName'](element, className);
+  },
+
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.blank();
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+
+    if (element.compareDocumentPosition)
+      return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+    if (ancestor.contains)
+      return ancestor.contains(element) && ancestor !== element;
+
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = Element.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    style = style == 'float' ? 'cssFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value || value == 'auto') {
+      var css = document.defaultView.getComputedStyle(element, null);
+      value = css ? css[style] : null;
+    }
+    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+    return value == 'auto' ? null : value;
+  },
+
+  getOpacity: function(element) {
+    return $(element).getStyle('opacity');
+  },
+
+  setStyle: function(element, styles) {
+    element = $(element);
+    var elementStyle = element.style, match;
+    if (Object.isString(styles)) {
+      element.style.cssText += ';' + styles;
+      return styles.include('opacity') ?
+        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+    }
+    for (var property in styles)
+      if (property == 'opacity') element.setOpacity(styles[property]);
+      else
+        elementStyle[(property == 'float' || property == 'cssFloat') ?
+          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
+            property] = styles[property];
+
+    return element;
+  },
+
+  setOpacity: function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+    return element;
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      if (Prototype.Browser.Opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+    if (element._overflow !== 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  },
+
+  clonePosition: function(element, source) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || { });
+
+    source = $(source);
+    var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
+
+    element = $(element);
+
+    if (Element.getStyle(element, 'position') == 'absolute') {
+      parent = Element.getOffsetParent(element);
+      delta = Element.viewportOffset(parent);
+    }
+
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
+    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+    return element;
+  }
+};
+
+Object.extend(Element.Methods, {
+  getElementsBySelector: Element.Methods.select,
+
+  childElements: Element.Methods.immediateDescendants
+});
+
+Element._attributeTranslations = {
+  write: {
+    names: {
+      className: 'class',
+      htmlFor:   'for'
+    },
+    values: { }
+  }
+};
+
+if (Prototype.Browser.Opera) {
+  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
+    function(proceed, element, style) {
+      switch (style) {
+        case 'height': case 'width':
+          if (!Element.visible(element)) return null;
+
+          var dim = parseInt(proceed(element, style), 10);
+
+          if (dim !== element['offset' + style.capitalize()])
+            return dim + 'px';
+
+          var properties;
+          if (style === 'height') {
+            properties = ['border-top-width', 'padding-top',
+             'padding-bottom', 'border-bottom-width'];
+          }
+          else {
+            properties = ['border-left-width', 'padding-left',
+             'padding-right', 'border-right-width'];
+          }
+          return properties.inject(dim, function(memo, property) {
+            var val = proceed(element, property);
+            return val === null ? memo : memo - parseInt(val, 10);
+          }) + 'px';
+        default: return proceed(element, style);
+      }
+    }
+  );
+
+  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
+    function(proceed, element, attribute) {
+      if (attribute === 'title') return element.title;
+      return proceed(element, attribute);
+    }
+  );
+}
+
+else if (Prototype.Browser.IE) {
+  Element.Methods.getStyle = function(element, style) {
+    element = $(element);
+    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value && element.currentStyle) value = element.currentStyle[style];
+
+    if (style == 'opacity') {
+      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if (value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+
+    if (value == 'auto') {
+      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+        return element['offset' + style.capitalize()] + 'px';
+      return null;
+    }
+    return value;
+  };
+
+  Element.Methods.setOpacity = function(element, value) {
+    function stripAlpha(filter){
+      return filter.replace(/alpha\([^\)]*\)/gi,'');
+    }
+    element = $(element);
+    var currentStyle = element.currentStyle;
+    if ((currentStyle && !currentStyle.hasLayout) ||
+      (!currentStyle && element.style.zoom == 'normal'))
+        element.style.zoom = 1;
+
+    var filter = element.getStyle('filter'), style = element.style;
+    if (value == 1 || value === '') {
+      (filter = stripAlpha(filter)) ?
+        style.filter = filter : style.removeAttribute('filter');
+      return element;
+    } else if (value < 0.00001) value = 0;
+    style.filter = stripAlpha(filter) +
+      'alpha(opacity=' + (value * 100) + ')';
+    return element;
+  };
+
+  Element._attributeTranslations = (function(){
+
+    var classProp = 'className',
+        forProp = 'for',
+        el = document.createElement('div');
+
+    el.setAttribute(classProp, 'x');
+
+    if (el.className !== 'x') {
+      el.setAttribute('class', 'x');
+      if (el.className === 'x') {
+        classProp = 'class';
+      }
+    }
+    el = null;
+
+    el = document.createElement('label');
+    el.setAttribute(forProp, 'x');
+    if (el.htmlFor !== 'x') {
+      el.setAttribute('htmlFor', 'x');
+      if (el.htmlFor === 'x') {
+        forProp = 'htmlFor';
+      }
+    }
+    el = null;
+
+    return {
+      read: {
+        names: {
+          'class':      classProp,
+          'className':  classProp,
+          'for':        forProp,
+          'htmlFor':    forProp
+        },
+        values: {
+          _getAttr: function(element, attribute) {
+            return element.getAttribute(attribute);
+          },
+          _getAttr2: function(element, attribute) {
+            return element.getAttribute(attribute, 2);
+          },
+          _getAttrNode: function(element, attribute) {
+            var node = element.getAttributeNode(attribute);
+            return node ? node.value : "";
+          },
+          _getEv: (function(){
+
+            var el = document.createElement('div'), f;
+            el.onclick = Prototype.emptyFunction;
+            var value = el.getAttribute('onclick');
+
+            if (String(value).indexOf('{') > -1) {
+              f = function(element, attribute) {
+                attribute = element.getAttribute(attribute);
+                if (!attribute) return null;
+                attribute = attribute.toString();
+                attribute = attribute.split('{')[1];
+                attribute = attribute.split('}')[0];
+                return attribute.strip();
+              };
+            }
+            else if (value === '') {
+              f = function(element, attribute) {
+                attribute = element.getAttribute(attribute);
+                if (!attribute) return null;
+                return attribute.strip();
+              };
+            }
+            el = null;
+            return f;
+          })(),
+          _flag: function(element, attribute) {
+            return $(element).hasAttribute(attribute) ? attribute : null;
+          },
+          style: function(element) {
+            return element.style.cssText.toLowerCase();
+          },
+          title: function(element) {
+            return element.title;
+          }
+        }
+      }
+    }
+  })();
+
+  Element._attributeTranslations.write = {
+    names: Object.extend({
+      cellpadding: 'cellPadding',
+      cellspacing: 'cellSpacing'
+    }, Element._attributeTranslations.read.names),
+    values: {
+      checked: function(element, value) {
+        element.checked = !!value;
+      },
+
+      style: function(element, value) {
+        element.style.cssText = value ? value : '';
+      }
+    }
+  };
+
+  Element._attributeTranslations.has = {};
+
+  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
+    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+  });
+
+  (function(v) {
+    Object.extend(v, {
+      href:        v._getAttr2,
+      src:         v._getAttr2,
+      type:        v._getAttr,
+      action:      v._getAttrNode,
+      disabled:    v._flag,
+      checked:     v._flag,
+      readonly:    v._flag,
+      multiple:    v._flag,
+      onload:      v._getEv,
+      onunload:    v._getEv,
+      onclick:     v._getEv,
+      ondblclick:  v._getEv,
+      onmousedown: v._getEv,
+      onmouseup:   v._getEv,
+      onmouseover: v._getEv,
+      onmousemove: v._getEv,
+      onmouseout:  v._getEv,
+      onfocus:     v._getEv,
+      onblur:      v._getEv,
+      onkeypress:  v._getEv,
+      onkeydown:   v._getEv,
+      onkeyup:     v._getEv,
+      onsubmit:    v._getEv,
+      onreset:     v._getEv,
+      onselect:    v._getEv,
+      onchange:    v._getEv
+    });
+  })(Element._attributeTranslations.read.values);
+
+  if (Prototype.BrowserFeatures.ElementExtensions) {
+    (function() {
+      function _descendants(element) {
+        var nodes = element.getElementsByTagName('*'), results = [];
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.tagName !== "!") // Filter out comment nodes.
+            results.push(node);
+        return results;
+      }
+
+      Element.Methods.down = function(element, expression, index) {
+        element = $(element);
+        if (arguments.length == 1) return element.firstDescendant();
+        return Object.isNumber(expression) ? _descendants(element)[expression] :
+          Element.select(element, expression)[index || 0];
+      }
+    })();
+  }
+
+}
+
+else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1) ? 0.999999 :
+      (value === '') ? '' : (value < 0.00001) ? 0 : value;
+    return element;
+  };
+}
+
+else if (Prototype.Browser.WebKit) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+
+    if (value == 1)
+      if (element.tagName.toUpperCase() == 'IMG' && element.width) {
+        element.width++; element.width--;
+      } else try {
+        var n = document.createTextNode(' ');
+        element.appendChild(n);
+        element.removeChild(n);
+      } catch (e) { }
+
+    return element;
+  };
+}
+
+if ('outerHTML' in document.documentElement) {
+  Element.Methods.replace = function(element, content) {
+    element = $(element);
+
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) {
+      element.parentNode.replaceChild(content, element);
+      return element;
+    }
+
+    content = Object.toHTML(content);
+    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+    if (Element._insertionTranslations.tags[tagName]) {
+      var nextSibling = element.next(),
+          fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+      parent.removeChild(element);
+      if (nextSibling)
+        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
+      else
+        fragments.each(function(node) { parent.appendChild(node) });
+    }
+    else element.outerHTML = content.stripScripts();
+
+    content.evalScripts.bind(content).defer();
+    return element;
+  };
+}
+
+Element._returnOffset = function(l, t) {
+  var result = [l, t];
+  result.left = l;
+  result.top = t;
+  return result;
+};
+
+Element._getContentFromAnonymousElement = function(tagName, html, force) {
+  var div = new Element('div'),
+      t = Element._insertionTranslations.tags[tagName];
+
+  var workaround = false;
+  if (t) workaround = true;
+  else if (force) {
+    workaround = true;
+    t = ['', '', 0];
+  }
+
+  if (workaround) {
+    div.innerHTML = '&nbsp;' + t[0] + html + t[1];
+    div.removeChild(div.firstChild);
+    for (var i = t[2]; i--; ) {
+      div = div.firstChild;
+    }
+  }
+  else {
+    div.innerHTML = html;
+  }
+  return $A(div.childNodes);
+};
+
+Element._insertionTranslations = {
+  before: function(element, node) {
+    element.parentNode.insertBefore(node, element);
+  },
+  top: function(element, node) {
+    element.insertBefore(node, element.firstChild);
+  },
+  bottom: function(element, node) {
+    element.appendChild(node);
+  },
+  after: function(element, node) {
+    element.parentNode.insertBefore(node, element.nextSibling);
+  },
+  tags: {
+    TABLE:  ['<table>',                '</table>',                   1],
+    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
+    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
+    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
+    SELECT: ['<select>',               '</select>',                  1]
+  }
+};
+
+(function() {
+  var tags = Element._insertionTranslations.tags;
+  Object.extend(tags, {
+    THEAD: tags.TBODY,
+    TFOOT: tags.TBODY,
+    TH:    tags.TD
+  });
+})();
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    attribute = Element._attributeTranslations.has[attribute] || attribute;
+    var node = $(element).getAttributeNode(attribute);
+    return !!(node && node.specified);
+  }
+};
+
+Element.Methods.ByTag = { };
+
+Object.extend(Element, Element.Methods);
+
+(function(div) {
+
+  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
+    window.HTMLElement = { };
+    window.HTMLElement.prototype = div['__proto__'];
+    Prototype.BrowserFeatures.ElementExtensions = true;
+  }
+
+  div = null;
+
+})(document.createElement('div'));
+
+Element.extend = (function() {
+
+  function checkDeficiency(tagName) {
+    if (typeof window.Element != 'undefined') {
+      var proto = window.Element.prototype;
+      if (proto) {
+        var id = '_' + (Math.random()+'').slice(2),
+            el = document.createElement(tagName);
+        proto[id] = 'x';
+        var isBuggy = (el[id] !== 'x');
+        delete proto[id];
+        el = null;
+        return isBuggy;
+      }
+    }
+    return false;
+  }
+
+  function extendElementWith(element, methods) {
+    for (var property in methods) {
+      var value = methods[property];
+      if (Object.isFunction(value) && !(property in element))
+        element[property] = value.methodize();
+    }
+  }
+
+  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
+
+  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
+    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
+      return function(element) {
+        if (element && typeof element._extendedByPrototype == 'undefined') {
+          var t = element.tagName;
+          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
+            extendElementWith(element, Element.Methods);
+            extendElementWith(element, Element.Methods.Simulated);
+            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
+          }
+        }
+        return element;
+      }
+    }
+    return Prototype.K;
+  }
+
+  var Methods = { }, ByTag = Element.Methods.ByTag;
+
+  var extend = Object.extend(function(element) {
+    if (!element || typeof element._extendedByPrototype != 'undefined' ||
+        element.nodeType != 1 || element == window) return element;
+
+    var methods = Object.clone(Methods),
+        tagName = element.tagName.toUpperCase();
+
+    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+    extendElementWith(element, methods);
+
+    element._extendedByPrototype = Prototype.emptyFunction;
+    return element;
+
+  }, {
+    refresh: function() {
+      if (!Prototype.BrowserFeatures.ElementExtensions) {
+        Object.extend(Methods, Element.Methods);
+        Object.extend(Methods, Element.Methods.Simulated);
+      }
+    }
+  });
+
+  extend.refresh();
+  return extend;
+})();
+
+if (document.documentElement.hasAttribute) {
+  Element.hasAttribute = function(element, attribute) {
+    return element.hasAttribute(attribute);
+  };
+}
+else {
+  Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
+}
+
+Element.addMethods = function(methods) {
+  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+  if (!methods) {
+    Object.extend(Form, Form.Methods);
+    Object.extend(Form.Element, Form.Element.Methods);
+    Object.extend(Element.Methods.ByTag, {
+      "FORM":     Object.clone(Form.Methods),
+      "INPUT":    Object.clone(Form.Element.Methods),
+      "SELECT":   Object.clone(Form.Element.Methods),
+      "TEXTAREA": Object.clone(Form.Element.Methods),
+      "BUTTON":   Object.clone(Form.Element.Methods)
+    });
+  }
+
+  if (arguments.length == 2) {
+    var tagName = methods;
+    methods = arguments[1];
+  }
+
+  if (!tagName) Object.extend(Element.Methods, methods || { });
+  else {
+    if (Object.isArray(tagName)) tagName.each(extend);
+    else extend(tagName);
+  }
+
+  function extend(tagName) {
+    tagName = tagName.toUpperCase();
+    if (!Element.Methods.ByTag[tagName])
+      Element.Methods.ByTag[tagName] = { };
+    Object.extend(Element.Methods.ByTag[tagName], methods);
+  }
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!Object.isFunction(value)) continue;
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = value.methodize();
+    }
+  }
+
+  function findDOMClass(tagName) {
+    var klass;
+    var trans = {
+      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+      "FrameSet", "IFRAME": "IFrame"
+    };
+    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName.capitalize() + 'Element';
+    if (window[klass]) return window[klass];
+
+    var element = document.createElement(tagName),
+        proto = element['__proto__'] || element.constructor.prototype;
+
+    element = null;
+    return proto;
+  }
+
+  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
+   Element.prototype;
+
+  if (F.ElementExtensions) {
+    copy(Element.Methods, elementPrototype);
+    copy(Element.Methods.Simulated, elementPrototype, true);
+  }
+
+  if (F.SpecificElementExtensions) {
+    for (var tag in Element.Methods.ByTag) {
+      var klass = findDOMClass(tag);
+      if (Object.isUndefined(klass)) continue;
+      copy(T[tag], klass.prototype);
+    }
+  }
+
+  Object.extend(Element, Element.Methods);
+  delete Element.ByTag;
+
+  if (Element.extend.refresh) Element.extend.refresh();
+  Element.cache = { };
+};
+
+
+document.viewport = {
+
+  getDimensions: function() {
+    return { width: this.getWidth(), height: this.getHeight() };
+  },
+
+  getScrollOffsets: function() {
+    return Element._returnOffset(
+      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
+  }
+};
+
+(function(viewport) {
+  var B = Prototype.Browser, doc = document, element, property = {};
+
+  function getRootElement() {
+    if (B.WebKit && !doc.evaluate)
+      return document;
+
+    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
+      return document.body;
+
+    return document.documentElement;
+  }
+
+  function define(D) {
+    if (!element) element = getRootElement();
+
+    property[D] = 'client' + D;
+
+    viewport['get' + D] = function() { return element[property[D]] };
+    return viewport['get' + D]();
+  }
+
+  viewport.getWidth  = define.curry('Width');
+
+  viewport.getHeight = define.curry('Height');
+})(document.viewport);
+
+
+Element.Storage = {
+  UID: 1
+};
+
+Element.addMethods({
+  getStorage: function(element) {
+    if (!(element = $(element))) return;
+
+    var uid;
+    if (element === window) {
+      uid = 0;
+    } else {
+      if (typeof element._prototypeUID === "undefined")
+        element._prototypeUID = Element.Storage.UID++;
+      uid = element._prototypeUID;
+    }
+
+    if (!Element.Storage[uid])
+      Element.Storage[uid] = $H();
+
+    return Element.Storage[uid];
+  },
+
+  store: function(element, key, value) {
+    if (!(element = $(element))) return;
+
+    if (arguments.length === 2) {
+      Element.getStorage(element).update(key);
+    } else {
+      Element.getStorage(element).set(key, value);
+    }
+
+    return element;
+  },
+
+  retrieve: function(element, key, defaultValue) {
+    if (!(element = $(element))) return;
+    var hash = Element.getStorage(element), value = hash.get(key);
+
+    if (Object.isUndefined(value)) {
+      hash.set(key, defaultValue);
+      value = defaultValue;
+    }
+
+    return value;
+  },
+
+  clone: function(element, deep) {
+    if (!(element = $(element))) return;
+    var clone = element.cloneNode(deep);
+    clone._prototypeUID = void 0;
+    if (deep) {
+      var descendants = Element.select(clone, '*'),
+          i = descendants.length;
+      while (i--) {
+        descendants[i]._prototypeUID = void 0;
+      }
+    }
+    return Element.extend(clone);
+  },
+
+  purge: function(element) {
+    if (!(element = $(element))) return;
+    var purgeElement = Element._purgeElement;
+
+    purgeElement(element);
+
+    var descendants = element.getElementsByTagName('*'),
+     i = descendants.length;
+
+    while (i--) purgeElement(descendants[i]);
+
+    return null;
+  }
+});
+
+(function() {
+
+  function toDecimal(pctString) {
+    var match = pctString.match(/^(\d+)%?$/i);
+    if (!match) return null;
+    return (Number(match[1]) / 100);
+  }
+
+  function getPixelValue(value, property, context) {
+    var element = null;
+    if (Object.isElement(value)) {
+      element = value;
+      value = element.getStyle(property);
+    }
+
+    if (value === null) {
+      return null;
+    }
+
+    if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
+      return window.parseFloat(value);
+    }
+
+    var isPercentage = value.include('%'), isViewport = (context === document.viewport);
+
+    if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
+      var style = element.style.left, rStyle = element.runtimeStyle.left;
+      element.runtimeStyle.left = element.currentStyle.left;
+      element.style.left = value || 0;
+      value = element.style.pixelLeft;
+      element.style.left = style;
+      element.runtimeStyle.left = rStyle;
+
+      return value;
+    }
+
+    if (element && isPercentage) {
+      context = context || element.parentNode;
+      var decimal = toDecimal(value);
+      var whole = null;
+      var position = element.getStyle('position');
+
+      var isHorizontal = property.include('left') || property.include('right') ||
+       property.include('width');
+
+      var isVertical =  property.include('top') || property.include('bottom') ||
+        property.include('height');
+
+      if (context === document.viewport) {
+        if (isHorizontal) {
+          whole = document.viewport.getWidth();
+        } else if (isVertical) {
+          whole = document.viewport.getHeight();
+        }
+      } else {
+        if (isHorizontal) {
+          whole = $(context).measure('width');
+        } else if (isVertical) {
+          whole = $(context).measure('height');
+        }
+      }
+
+      return (whole === null) ? 0 : whole * decimal;
+    }
+
+    return 0;
+  }
+
+  function toCSSPixels(number) {
+    if (Object.isString(number) && number.endsWith('px')) {
+      return number;
+    }
+    return number + 'px';
+  }
+
+  function isDisplayed(element) {
+    var originalElement = element;
+    while (element && element.parentNode) {
+      var display = element.getStyle('display');
+      if (display === 'none') {
+        return false;
+      }
+      element = $(element.parentNode);
+    }
+    return true;
+  }
+
+  var hasLayout = Prototype.K;
+  if ('currentStyle' in document.documentElement) {
+    hasLayout = function(element) {
+      if (!element.currentStyle.hasLayout) {
+        element.style.zoom = 1;
+      }
+      return element;
+    };
+  }
+
+  function cssNameFor(key) {
+    if (key.include('border')) key = key + '-width';
+    return key.camelize();
+  }
+
+  Element.Layout = Class.create(Hash, {
+    initialize: function($super, element, preCompute) {
+      $super();
+      this.element = $(element);
+
+      Element.Layout.PROPERTIES.each( function(property) {
+        this._set(property, null);
+      }, this);
+
+      if (preCompute) {
+        this._preComputing = true;
+        this._begin();
+        Element.Layout.PROPERTIES.each( this._compute, this );
+        this._end();
+        this._preComputing = false;
+      }
+    },
+
+    _set: function(property, value) {
+      return Hash.prototype.set.call(this, property, value);
+    },
+
+    set: function(property, value) {
+      throw "Properties of Element.Layout are read-only.";
+    },
+
+    get: function($super, property) {
+      var value = $super(property);
+      return value === null ? this._compute(property) : value;
+    },
+
+    _begin: function() {
+      if (this._prepared) return;
+
+      var element = this.element;
+      if (isDisplayed(element)) {
+        this._prepared = true;
+        return;
+      }
+
+      var originalStyles = {
+        position:   element.style.position   || '',
+        width:      element.style.width      || '',
+        visibility: element.style.visibility || '',
+        display:    element.style.display    || ''
+      };
+
+      element.store('prototype_original_styles', originalStyles);
+
+      var position = element.getStyle('position'),
+       width = element.getStyle('width');
+
+      if (width === "0px" || width === null) {
+        element.style.display = 'block';
+        width = element.getStyle('width');
+      }
+
+      var context = (position === 'fixed') ? document.viewport :
+       element.parentNode;
+
+      element.setStyle({
+        position:   'absolute',
+        visibility: 'hidden',
+        display:    'block'
+      });
+
+      var positionedWidth = element.getStyle('width');
+
+      var newWidth;
+      if (width && (positionedWidth === width)) {
+        newWidth = getPixelValue(element, 'width', context);
+      } else if (position === 'absolute' || position === 'fixed') {
+        newWidth = getPixelValue(element, 'width', context);
+      } else {
+        var parent = element.parentNode, pLayout = $(parent).getLayout();
+
+        newWidth = pLayout.get('width') -
+         this.get('margin-left') -
+         this.get('border-left') -
+         this.get('padding-left') -
+         this.get('padding-right') -
+         this.get('border-right') -
+         this.get('margin-right');
+      }
+
+      element.setStyle({ width: newWidth + 'px' });
+
+      this._prepared = true;
+    },
+
+    _end: function() {
+      var element = this.element;
+      var originalStyles = element.retrieve('prototype_original_styles');
+      element.store('prototype_original_styles', null);
+      element.setStyle(originalStyles);
+      this._prepared = false;
+    },
+
+    _compute: function(property) {
+      var COMPUTATIONS = Element.Layout.COMPUTATIONS;
+      if (!(property in COMPUTATIONS)) {
+        throw "Property not found.";
+      }
+
+      return this._set(property, COMPUTATIONS[property].call(this, this.element));
+    },
+
+    toObject: function() {
+      var args = $A(arguments);
+      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
+       args.join(' ').split(' ');
+      var obj = {};
+      keys.each( function(key) {
+        if (!Element.Layout.PROPERTIES.include(key)) return;
+        var value = this.get(key);
+        if (value != null) obj[key] = value;
+      }, this);
+      return obj;
+    },
+
+    toHash: function() {
+      var obj = this.toObject.apply(this, arguments);
+      return new Hash(obj);
+    },
+
+    toCSS: function() {
+      var args = $A(arguments);
+      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
+       args.join(' ').split(' ');
+      var css = {};
+
+      keys.each( function(key) {
+        if (!Element.Layout.PROPERTIES.include(key)) return;
+        if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
+
+        var value = this.get(key);
+        if (value != null) css[cssNameFor(key)] = value + 'px';
+      }, this);
+      return css;
+    },
+
+    inspect: function() {
+      return "#<Element.Layout>";
+    }
+  });
+
+  Object.extend(Element.Layout, {
+    PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
+
+    COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
+
+    COMPUTATIONS: {
+      'height': function(element) {
+        if (!this._preComputing) this._begin();
+
+        var bHeight = this.get('border-box-height');
+        if (bHeight <= 0) {
+          if (!this._preComputing) this._end();
+          return 0;
+        }
+
+        var bTop = this.get('border-top'),
+         bBottom = this.get('border-bottom');
+
+        var pTop = this.get('padding-top'),
+         pBottom = this.get('padding-bottom');
+
+        if (!this._preComputing) this._end();
+
+        return bHeight - bTop - bBottom - pTop - pBottom;
+      },
+
+      'width': function(element) {
+        if (!this._preComputing) this._begin();
+
+        var bWidth = this.get('border-box-width');
+        if (bWidth <= 0) {
+          if (!this._preComputing) this._end();
+          return 0;
+        }
+
+        var bLeft = this.get('border-left'),
+         bRight = this.get('border-right');
+
+        var pLeft = this.get('padding-left'),
+         pRight = this.get('padding-right');
+
+        if (!this._preComputing) this._end();
+
+        return bWidth - bLeft - bRight - pLeft - pRight;
+      },
+
+      'padding-box-height': function(element) {
+        var height = this.get('height'),
+         pTop = this.get('padding-top'),
+         pBottom = this.get('padding-bottom');
+
+        return height + pTop + pBottom;
+      },
+
+      'padding-box-width': function(element) {
+        var width = this.get('width'),
+         pLeft = this.get('padding-left'),
+         pRight = this.get('padding-right');
+
+        return width + pLeft + pRight;
+      },
+
+      'border-box-height': function(element) {
+        if (!this._preComputing) this._begin();
+        var height = element.offsetHeight;
+        if (!this._preComputing) this._end();
+        return height;
+      },
+
+      'border-box-width': function(element) {
+        if (!this._preComputing) this._begin();
+        var width = element.offsetWidth;
+        if (!this._preComputing) this._end();
+        return width;
+      },
+
+      'margin-box-height': function(element) {
+        var bHeight = this.get('border-box-height'),
+         mTop = this.get('margin-top'),
+         mBottom = this.get('margin-bottom');
+
+        if (bHeight <= 0) return 0;
+
+        return bHeight + mTop + mBottom;
+      },
+
+      'margin-box-width': function(element) {
+        var bWidth = this.get('border-box-width'),
+         mLeft = this.get('margin-left'),
+         mRight = this.get('margin-right');
+
+        if (bWidth <= 0) return 0;
+
+        return bWidth + mLeft + mRight;
+      },
+
+      'top': function(element) {
+        var offset = element.positionedOffset();
+        return offset.top;
+      },
+
+      'bottom': function(element) {
+        var offset = element.positionedOffset(),
+         parent = element.getOffsetParent(),
+         pHeight = parent.measure('height');
+
+        var mHeight = this.get('border-box-height');
+
+        return pHeight - mHeight - offset.top;
+      },
+
+      'left': function(element) {
+        var offset = element.positionedOffset();
+        return offset.left;
+      },
+
+      'right': function(element) {
+        var offset = element.positionedOffset(),
+         parent = element.getOffsetParent(),
+         pWidth = parent.measure('width');
+
+        var mWidth = this.get('border-box-width');
+
+        return pWidth - mWidth - offset.left;
+      },
+
+      'padding-top': function(element) {
+        return getPixelValue(element, 'paddingTop');
+      },
+
+      'padding-bottom': function(element) {
+        return getPixelValue(element, 'paddingBottom');
+      },
+
+      'padding-left': function(element) {
+        return getPixelValue(element, 'paddingLeft');
+      },
+
+      'padding-right': function(element) {
+        return getPixelValue(element, 'paddingRight');
+      },
+
+      'border-top': function(element) {
+        return getPixelValue(element, 'borderTopWidth');
+      },
+
+      'border-bottom': function(element) {
+        return getPixelValue(element, 'borderBottomWidth');
+      },
+
+      'border-left': function(element) {
+        return getPixelValue(element, 'borderLeftWidth');
+      },
+
+      'border-right': function(element) {
+        return getPixelValue(element, 'borderRightWidth');
+      },
+
+      'margin-top': function(element) {
+        return getPixelValue(element, 'marginTop');
+      },
+
+      'margin-bottom': function(element) {
+        return getPixelValue(element, 'marginBottom');
+      },
+
+      'margin-left': function(element) {
+        return getPixelValue(element, 'marginLeft');
+      },
+
+      'margin-right': function(element) {
+        return getPixelValue(element, 'marginRight');
+      }
+    }
+  });
+
+  if ('getBoundingClientRect' in document.documentElement) {
+    Object.extend(Element.Layout.COMPUTATIONS, {
+      'right': function(element) {
+        var parent = hasLayout(element.getOffsetParent());
+        var rect = element.getBoundingClientRect(),
+         pRect = parent.getBoundingClientRect();
+
+        return (pRect.right - rect.right).round();
+      },
+
+      'bottom': function(element) {
+        var parent = hasLayout(element.getOffsetParent());
+        var rect = element.getBoundingClientRect(),
+         pRect = parent.getBoundingClientRect();
+
+        return (pRect.bottom - rect.bottom).round();
+      }
+    });
+  }
+
+  Element.Offset = Class.create({
+    initialize: function(left, top) {
+      this.left = left.round();
+      this.top  = top.round();
+
+      this[0] = this.left;
+      this[1] = this.top;
+    },
+
+    relativeTo: function(offset) {
+      return new Element.Offset(
+        this.left - offset.left,
+        this.top  - offset.top
+      );
+    },
+
+    inspect: function() {
+      return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
+    },
+
+    toString: function() {
+      return "[#{left}, #{top}]".interpolate(this);
+    },
+
+    toArray: function() {
+      return [this.left, this.top];
+    }
+  });
+
+  function getLayout(element, preCompute) {
+    return new Element.Layout(element, preCompute);
+  }
+
+  function measure(element, property) {
+    return $(element).getLayout().get(property);
+  }
+
+  function getDimensions(element) {
+    element = $(element);
+    var display = Element.getStyle(element, 'display');
+
+    if (display && display !== 'none') {
+      return { width: element.offsetWidth, height: element.offsetHeight };
+    }
+
+    var style = element.style;
+    var originalStyles = {
+      visibility: style.visibility,
+      position:   style.position,
+      display:    style.display
+    };
+
+    var newStyles = {
+      visibility: 'hidden',
+      display:    'block'
+    };
+
+    if (originalStyles.position !== 'fixed')
+      newStyles.position = 'absolute';
+
+    Element.setStyle(element, newStyles);
+
+    var dimensions = {
+      width:  element.offsetWidth,
+      height: element.offsetHeight
+    };
+
+    Element.setStyle(element, originalStyles);
+
+    return dimensions;
+  }
+
+  function getOffsetParent(element) {
+    element = $(element);
+
+    if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
+      return $(document.body);
+
+    var isInline = (Element.getStyle(element, 'display') === 'inline');
+    if (!isInline && element.offsetParent) return $(element.offsetParent);
+
+    while ((element = element.parentNode) && element !== document.body) {
+      if (Element.getStyle(element, 'position') !== 'static') {
+        return isHtml(element) ? $(document.body) : $(element);
+      }
+    }
+
+    return $(document.body);
+  }
+
+
+  function cumulativeOffset(element) {
+    element = $(element);
+    var valueT = 0, valueL = 0;
+    if (element.parentNode) {
+      do {
+        valueT += element.offsetTop  || 0;
+        valueL += element.offsetLeft || 0;
+        element = element.offsetParent;
+      } while (element);
+    }
+    return new Element.Offset(valueL, valueT);
+  }
+
+  function positionedOffset(element) {
+    element = $(element);
+
+    var layout = element.getLayout();
+
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if (isBody(element)) break;
+        var p = Element.getStyle(element, 'position');
+        if (p !== 'static') break;
+      }
+    } while (element);
+
+    valueL -= layout.get('margin-top');
+    valueT -= layout.get('margin-left');
+
+    return new Element.Offset(valueL, valueT);
+  }
+
+  function cumulativeScrollOffset(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return new Element.Offset(valueL, valueT);
+  }
+
+  function viewportOffset(forElement) {
+    element = $(element);
+    var valueT = 0, valueL = 0, docBody = document.body;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == docBody &&
+        Element.getStyle(element, 'position') == 'absolute') break;
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (element != docBody) {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+    return new Element.Offset(valueL, valueT);
+  }
+
+  function absolutize(element) {
+    element = $(element);
+
+    if (Element.getStyle(element, 'position') === 'absolute') {
+      return element;
+    }
+
+    var offsetParent = getOffsetParent(element);
+    var eOffset = element.viewportOffset(),
+     pOffset = offsetParent.viewportOffset();
+
+    var offset = eOffset.relativeTo(pOffset);
+    var layout = element.getLayout();
+
+    element.store('prototype_absolutize_original_styles', {
+      left:   element.getStyle('left'),
+      top:    element.getStyle('top'),
+      width:  element.getStyle('width'),
+      height: element.getStyle('height')
+    });
+
+    element.setStyle({
+      position: 'absolute',
+      top:    offset.top + 'px',
+      left:   offset.left + 'px',
+      width:  layout.get('width') + 'px',
+      height: layout.get('height') + 'px'
+    });
+
+    return element;
+  }
+
+  function relativize(element) {
+    element = $(element);
+    if (Element.getStyle(element, 'position') === 'relative') {
+      return element;
+    }
+
+    var originalStyles =
+     element.retrieve('prototype_absolutize_original_styles');
+
+    if (originalStyles) element.setStyle(originalStyles);
+    return element;
+  }
+
+  if (Prototype.Browser.IE) {
+    getOffsetParent = getOffsetParent.wrap(
+      function(proceed, element) {
+        element = $(element);
+
+        if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
+          return $(document.body);
+
+        var position = element.getStyle('position');
+        if (position !== 'static') return proceed(element);
+
+        element.setStyle({ position: 'relative' });
+        var value = proceed(element);
+        element.setStyle({ position: position });
+        return value;
+      }
+    );
+
+    positionedOffset = positionedOffset.wrap(function(proceed, element) {
+      element = $(element);
+      if (!element.parentNode) return new Element.Offset(0, 0);
+      var position = element.getStyle('position');
+      if (position !== 'static') return proceed(element);
+
+      var offsetParent = element.getOffsetParent();
+      if (offsetParent && offsetParent.getStyle('position') === 'fixed')
+        hasLayout(offsetParent);
+
+      element.setStyle({ position: 'relative' });
+      var value = proceed(element);
+      element.setStyle({ position: position });
+      return value;
+    });
+  } else if (Prototype.Browser.Webkit) {
+    cumulativeOffset = function(element) {
+      element = $(element);
+      var valueT = 0, valueL = 0;
+      do {
+        valueT += element.offsetTop  || 0;
+        valueL += element.offsetLeft || 0;
+        if (element.offsetParent == document.body)
+          if (Element.getStyle(element, 'position') == 'absolute') break;
+
+        element = element.offsetParent;
+      } while (element);
+
+      return new Element.Offset(valueL, valueT);
+    };
+  }
+
+
+  Element.addMethods({
+    getLayout:              getLayout,
+    measure:                measure,
+    getDimensions:          getDimensions,
+    getOffsetParent:        getOffsetParent,
+    cumulativeOffset:       cumulativeOffset,
+    positionedOffset:       positionedOffset,
+    cumulativeScrollOffset: cumulativeScrollOffset,
+    viewportOffset:         viewportOffset,
+    absolutize:             absolutize,
+    relativize:             relativize
+  });
+
+  function isBody(element) {
+    return element.nodeName.toUpperCase() === 'BODY';
+  }
+
+  function isHtml(element) {
+    return element.nodeName.toUpperCase() === 'HTML';
+  }
+
+  function isDocument(element) {
+    return element.nodeType === Node.DOCUMENT_NODE;
+  }
+
+  function isDetached(element) {
+    return element !== document.body &&
+     !Element.descendantOf(element, document.body);
+  }
+
+  if ('getBoundingClientRect' in document.documentElement) {
+    Element.addMethods({
+      viewportOffset: function(element) {
+        element = $(element);
+        if (isDetached(element)) return new Element.Offset(0, 0);
+
+        var rect = element.getBoundingClientRect(),
+         docEl = document.documentElement;
+        return new Element.Offset(rect.left - docEl.clientLeft,
+         rect.top - docEl.clientTop);
+      }
+    });
+  }
+})();
+window.$$ = function() {
+  var expression = $A(arguments).join(', ');
+  return Prototype.Selector.select(expression, document);
+};
+
+Prototype.Selector = (function() {
+
+  function select() {
+    throw new Error('Method "Prototype.Selector.select" must be defined.');
+  }
+
+  function match() {
+    throw new Error('Method "Prototype.Selector.match" must be defined.');
+  }
+
+  function find(elements, expression, index) {
+    index = index || 0;
+    var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
+
+    for (i = 0; i < length; i++) {
+      if (match(elements[i], expression) && index == matchIndex++) {
+        return Element.extend(elements[i]);
+      }
+    }
+  }
+
+  function extendElements(elements) {
+    for (var i = 0, length = elements.length; i < length; i++) {
+      Element.extend(elements[i]);
+    }
+    return elements;
+  }
+
+
+  var K = Prototype.K;
+
+  return {
+    select: select,
+    match: match,
+    find: find,
+    extendElements: (Element.extend === K) ? K : extendElements,
+    extendElement: Element.extend
+  };
+})();
+Prototype._original_property = window.Sizzle;
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+       done = 0,
+       toString = Object.prototype.toString,
+       hasDuplicate = false,
+       baseHasDuplicate = true;
+
+[0, 0].sort(function(){
+       baseHasDuplicate = false;
+       return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+       results = results || [];
+       var origContext = context = context || document;
+
+       if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+               return [];
+       }
+
+       if ( !selector || typeof selector !== "string" ) {
+               return results;
+       }
+
+       var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
+               soFar = selector;
+
+       while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+               soFar = m[3];
+
+               parts.push( m[1] );
+
+               if ( m[2] ) {
+                       extra = m[3];
+                       break;
+               }
+       }
+
+       if ( parts.length > 1 && origPOS.exec( selector ) ) {
+               if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+                       set = posProcess( parts[0] + parts[1], context );
+               } else {
+                       set = Expr.relative[ parts[0] ] ?
+                               [ context ] :
+                               Sizzle( parts.shift(), context );
+
+                       while ( parts.length ) {
+                               selector = parts.shift();
+
+                               if ( Expr.relative[ selector ] )
+                                       selector += parts.shift();
+
+                               set = posProcess( selector, set );
+                       }
+               }
+       } else {
+               if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+                               Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+                       var ret = Sizzle.find( parts.shift(), context, contextXML );
+                       context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+               }
+
+               if ( context ) {
+                       var ret = seed ?
+                               { expr: parts.pop(), set: makeArray(seed) } :
+                               Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+                       set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+                       if ( parts.length > 0 ) {
+                               checkSet = makeArray(set);
+                       } else {
+                               prune = false;
+                       }
+
+                       while ( parts.length ) {
+                               var cur = parts.pop(), pop = cur;
+
+                               if ( !Expr.relative[ cur ] ) {
+                                       cur = "";
+                               } else {
+                                       pop = parts.pop();
+                               }
+
+                               if ( pop == null ) {
+                                       pop = context;
+                               }
+
+                               Expr.relative[ cur ]( checkSet, pop, contextXML );
+                       }
+               } else {
+                       checkSet = parts = [];
+               }
+       }
+
+       if ( !checkSet ) {
+               checkSet = set;
+       }
+
+       if ( !checkSet ) {
+               throw "Syntax error, unrecognized expression: " + (cur || selector);
+       }
+
+       if ( toString.call(checkSet) === "[object Array]" ) {
+               if ( !prune ) {
+                       results.push.apply( results, checkSet );
+               } else if ( context && context.nodeType === 1 ) {
+                       for ( var i = 0; checkSet[i] != null; i++ ) {
+                               if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+                                       results.push( set[i] );
+                               }
+                       }
+               } else {
+                       for ( var i = 0; checkSet[i] != null; i++ ) {
+                               if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+                                       results.push( set[i] );
+                               }
+                       }
+               }
+       } else {
+               makeArray( checkSet, results );
+       }
+
+       if ( extra ) {
+               Sizzle( extra, origContext, results, seed );
+               Sizzle.uniqueSort( results );
+       }
+
+       return results;
+};
+
+Sizzle.uniqueSort = function(results){
+       if ( sortOrder ) {
+               hasDuplicate = baseHasDuplicate;
+               results.sort(sortOrder);
+
+               if ( hasDuplicate ) {
+                       for ( var i = 1; i < results.length; i++ ) {
+                               if ( results[i] === results[i-1] ) {
+                                       results.splice(i--, 1);
+                               }
+                       }
+               }
+       }
+
+       return results;
+};
+
+Sizzle.matches = function(expr, set){
+       return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+       var set, match;
+
+       if ( !expr ) {
+               return [];
+       }
+
+       for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+               var type = Expr.order[i], match;
+
+               if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+                       var left = match[1];
+                       match.splice(1,1);
+
+                       if ( left.substr( left.length - 1 ) !== "\\" ) {
+                               match[1] = (match[1] || "").replace(/\\/g, "");
+                               set = Expr.find[ type ]( match, context, isXML );
+                               if ( set != null ) {
+                                       expr = expr.replace( Expr.match[ type ], "" );
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       if ( !set ) {
+               set = context.getElementsByTagName("*");
+       }
+
+       return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+       var old = expr, result = [], curLoop = set, match, anyFound,
+               isXMLFilter = set && set[0] && isXML(set[0]);
+
+       while ( expr && set.length ) {
+               for ( var type in Expr.filter ) {
+                       if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+                               var filter = Expr.filter[ type ], found, item;
+                               anyFound = false;
+
+                               if ( curLoop == result ) {
+                                       result = [];
+                               }
+
+                               if ( Expr.preFilter[ type ] ) {
+                                       match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+                                       if ( !match ) {
+                                               anyFound = found = true;
+                                       } else if ( match === true ) {
+                                               continue;
+                                       }
+                               }
+
+                               if ( match ) {
+                                       for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+                                               if ( item ) {
+                                                       found = filter( item, match, i, curLoop );
+                                                       var pass = not ^ !!found;
+
+                                                       if ( inplace && found != null ) {
+                                                               if ( pass ) {
+                                                                       anyFound = true;
+                                                               } else {
+                                                                       curLoop[i] = false;
+                                                               }
+                                                       } else if ( pass ) {
+                                                               result.push( item );
+                                                               anyFound = true;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               if ( found !== undefined ) {
+                                       if ( !inplace ) {
+                                               curLoop = result;
+                                       }
+
+                                       expr = expr.replace( Expr.match[ type ], "" );
+
+                                       if ( !anyFound ) {
+                                               return [];
+                                       }
+
+                                       break;
+                               }
+                       }
+               }
+
+               if ( expr == old ) {
+                       if ( anyFound == null ) {
+                               throw "Syntax error, unrecognized expression: " + expr;
+                       } else {
+                               break;
+                       }
+               }
+
+               old = expr;
+       }
+
+       return curLoop;
+};
+
+var Expr = Sizzle.selectors = {
+       order: [ "ID", "NAME", "TAG" ],
+       match: {
+               ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+               CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+               NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+               ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+               TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+               CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+               POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+               PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+       },
+       leftMatch: {},
+       attrMap: {
+               "class": "className",
+               "for": "htmlFor"
+       },
+       attrHandle: {
+               href: function(elem){
+                       return elem.getAttribute("href");
+               }
+       },
+       relative: {
+               "+": function(checkSet, part, isXML){
+                       var isPartStr = typeof part === "string",
+                               isTag = isPartStr && !/\W/.test(part),
+                               isPartStrNotTag = isPartStr && !isTag;
+
+                       if ( isTag && !isXML ) {
+                               part = part.toUpperCase();
+                       }
+
+                       for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+                               if ( (elem = checkSet[i]) ) {
+                                       while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+                                       checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+                                               elem || false :
+                                               elem === part;
+                               }
+                       }
+
+                       if ( isPartStrNotTag ) {
+                               Sizzle.filter( part, checkSet, true );
+                       }
+               },
+               ">": function(checkSet, part, isXML){
+                       var isPartStr = typeof part === "string";
+
+                       if ( isPartStr && !/\W/.test(part) ) {
+                               part = isXML ? part : part.toUpperCase();
+
+                               for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+                                       var elem = checkSet[i];
+                                       if ( elem ) {
+                                               var parent = elem.parentNode;
+                                               checkSet[i] = parent.nodeName === part ? parent : false;
+                                       }
+                               }
+                       } else {
+                               for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+                                       var elem = checkSet[i];
+                                       if ( elem ) {
+                                               checkSet[i] = isPartStr ?
+                                                       elem.parentNode :
+                                                       elem.parentNode === part;
+                                       }
+                               }
+
+                               if ( isPartStr ) {
+                                       Sizzle.filter( part, checkSet, true );
+                               }
+                       }
+               },
+               "": function(checkSet, part, isXML){
+                       var doneName = done++, checkFn = dirCheck;
+
+                       if ( !/\W/.test(part) ) {
+                               var nodeCheck = part = isXML ? part : part.toUpperCase();
+                               checkFn = dirNodeCheck;
+                       }
+
+                       checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+               },
+               "~": function(checkSet, part, isXML){
+                       var doneName = done++, checkFn = dirCheck;
+
+                       if ( typeof part === "string" && !/\W/.test(part) ) {
+                               var nodeCheck = part = isXML ? part : part.toUpperCase();
+                               checkFn = dirNodeCheck;
+                       }
+
+                       checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+               }
+       },
+       find: {
+               ID: function(match, context, isXML){
+                       if ( typeof context.getElementById !== "undefined" && !isXML ) {
+                               var m = context.getElementById(match[1]);
+                               return m ? [m] : [];
+                       }
+               },
+               NAME: function(match, context, isXML){
+                       if ( typeof context.getElementsByName !== "undefined" ) {
+                               var ret = [], results = context.getElementsByName(match[1]);
+
+                               for ( var i = 0, l = results.length; i < l; i++ ) {
+                                       if ( results[i].getAttribute("name") === match[1] ) {
+                                               ret.push( results[i] );
+                                       }
+                               }
+
+                               return ret.length === 0 ? null : ret;
+                       }
+               },
+               TAG: function(match, context){
+                       return context.getElementsByTagName(match[1]);
+               }
+       },
+       preFilter: {
+               CLASS: function(match, curLoop, inplace, result, not, isXML){
+                       match = " " + match[1].replace(/\\/g, "") + " ";
+
+                       if ( isXML ) {
+                               return match;
+                       }
+
+                       for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+                               if ( elem ) {
+                                       if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+                                               if ( !inplace )
+                                                       result.push( elem );
+                                       } else if ( inplace ) {
+                                               curLoop[i] = false;
+                                       }
+                               }
+                       }
+
+                       return false;
+               },
+               ID: function(match){
+                       return match[1].replace(/\\/g, "");
+               },
+               TAG: function(match, curLoop){
+                       for ( var i = 0; curLoop[i] === false; i++ ){}
+                       return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+               },
+               CHILD: function(match){
+                       if ( match[1] == "nth" ) {
+                               var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+                                       match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+                                       !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+                               match[2] = (test[1] + (test[2] || 1)) - 0;
+                               match[3] = test[3] - 0;
+                       }
+
+                       match[0] = done++;
+
+                       return match;
+               },
+               ATTR: function(match, curLoop, inplace, result, not, isXML){
+                       var name = match[1].replace(/\\/g, "");
+
+                       if ( !isXML && Expr.attrMap[name] ) {
+                               match[1] = Expr.attrMap[name];
+                       }
+
+                       if ( match[2] === "~=" ) {
+                               match[4] = " " + match[4] + " ";
+                       }
+
+                       return match;
+               },
+               PSEUDO: function(match, curLoop, inplace, result, not){
+                       if ( match[1] === "not" ) {
+                               if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+                                       match[3] = Sizzle(match[3], null, null, curLoop);
+                               } else {
+                                       var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+                                       if ( !inplace ) {
+                                               result.push.apply( result, ret );
+                                       }
+                                       return false;
+                               }
+                       } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+                               return true;
+                       }
+
+                       return match;
+               },
+               POS: function(match){
+                       match.unshift( true );
+                       return match;
+               }
+       },
+       filters: {
+               enabled: function(elem){
+                       return elem.disabled === false && elem.type !== "hidden";
+               },
+               disabled: function(elem){
+                       return elem.disabled === true;
+               },
+               checked: function(elem){
+                       return elem.checked === true;
+               },
+               selected: function(elem){
+                       elem.parentNode.selectedIndex;
+                       return elem.selected === true;
+               },
+               parent: function(elem){
+                       return !!elem.firstChild;
+               },
+               empty: function(elem){
+                       return !elem.firstChild;
+               },
+               has: function(elem, i, match){
+                       return !!Sizzle( match[3], elem ).length;
+               },
+               header: function(elem){
+                       return /h\d/i.test( elem.nodeName );
+               },
+               text: function(elem){
+                       return "text" === elem.type;
+               },
+               radio: function(elem){
+                       return "radio" === elem.type;
+               },
+               checkbox: function(elem){
+                       return "checkbox" === elem.type;
+               },
+               file: function(elem){
+                       return "file" === elem.type;
+               },
+               password: function(elem){
+                       return "password" === elem.type;
+               },
+               submit: function(elem){
+                       return "submit" === elem.type;
+               },
+               image: function(elem){
+                       return "image" === elem.type;
+               },
+               reset: function(elem){
+                       return "reset" === elem.type;
+               },
+               button: function(elem){
+                       return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+               },
+               input: function(elem){
+                       return /input|select|textarea|button/i.test(elem.nodeName);
+               }
+       },
+       setFilters: {
+               first: function(elem, i){
+                       return i === 0;
+               },
+               last: function(elem, i, match, array){
+                       return i === array.length - 1;
+               },
+               even: function(elem, i){
+                       return i % 2 === 0;
+               },
+               odd: function(elem, i){
+                       return i % 2 === 1;
+               },
+               lt: function(elem, i, match){
+                       return i < match[3] - 0;
+               },
+               gt: function(elem, i, match){
+                       return i > match[3] - 0;
+               },
+               nth: function(elem, i, match){
+                       return match[3] - 0 == i;
+               },
+               eq: function(elem, i, match){
+                       return match[3] - 0 == i;
+               }
+       },
+       filter: {
+               PSEUDO: function(elem, match, i, array){
+                       var name = match[1], filter = Expr.filters[ name ];
+
+                       if ( filter ) {
+                               return filter( elem, i, match, array );
+                       } else if ( name === "contains" ) {
+                               return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+                       } else if ( name === "not" ) {
+                               var not = match[3];
+
+                               for ( var i = 0, l = not.length; i < l; i++ ) {
+                                       if ( not[i] === elem ) {
+                                               return false;
+                                       }
+                               }
+
+                               return true;
+                       }
+               },
+               CHILD: function(elem, match){
+                       var type = match[1], node = elem;
+                       switch (type) {
+                               case 'only':
+                               case 'first':
+                                       while ( (node = node.previousSibling) )  {
+                                               if ( node.nodeType === 1 ) return false;
+                                       }
+                                       if ( type == 'first') return true;
+                                       node = elem;
+                               case 'last':
+                                       while ( (node = node.nextSibling) )  {
+                                               if ( node.nodeType === 1 ) return false;
+                                       }
+                                       return true;
+                               case 'nth':
+                                       var first = match[2], last = match[3];
+
+                                       if ( first == 1 && last == 0 ) {
+                                               return true;
+                                       }
+
+                                       var doneName = match[0],
+                                               parent = elem.parentNode;
+
+                                       if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+                                               var count = 0;
+                                               for ( node = parent.firstChild; node; node = node.nextSibling ) {
+                                                       if ( node.nodeType === 1 ) {
+                                                               node.nodeIndex = ++count;
+                                                       }
+                                               }
+                                               parent.sizcache = doneName;
+                                       }
+
+                                       var diff = elem.nodeIndex - last;
+                                       if ( first == 0 ) {
+                                               return diff == 0;
+                                       } else {
+                                               return ( diff % first == 0 && diff / first >= 0 );
+                                       }
+                       }
+               },
+               ID: function(elem, match){
+                       return elem.nodeType === 1 && elem.getAttribute("id") === match;
+               },
+               TAG: function(elem, match){
+                       return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+               },
+               CLASS: function(elem, match){
+                       return (" " + (elem.className || elem.getAttribute("class")) + " ")
+                               .indexOf( match ) > -1;
+               },
+               ATTR: function(elem, match){
+                       var name = match[1],
+                               result = Expr.attrHandle[ name ] ?
+                                       Expr.attrHandle[ name ]( elem ) :
+                                       elem[ name ] != null ?
+                                               elem[ name ] :
+                                               elem.getAttribute( name ),
+                               value = result + "",
+                               type = match[2],
+                               check = match[4];
+
+                       return result == null ?
+                               type === "!=" :
+                               type === "=" ?
+                               value === check :
+                               type === "*=" ?
+                               value.indexOf(check) >= 0 :
+                               type === "~=" ?
+                               (" " + value + " ").indexOf(check) >= 0 :
+                               !check ?
+                               value && result !== false :
+                               type === "!=" ?
+                               value != check :
+                               type === "^=" ?
+                               value.indexOf(check) === 0 :
+                               type === "$=" ?
+                               value.substr(value.length - check.length) === check :
+                               type === "|=" ?
+                               value === check || value.substr(0, check.length + 1) === check + "-" :
+                               false;
+               },
+               POS: function(elem, match, i, array){
+                       var name = match[2], filter = Expr.setFilters[ name ];
+
+                       if ( filter ) {
+                               return filter( elem, i, match, array );
+                       }
+               }
+       }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+       Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+       Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
+}
+
+var makeArray = function(array, results) {
+       array = Array.prototype.slice.call( array, 0 );
+
+       if ( results ) {
+               results.push.apply( results, array );
+               return results;
+       }
+
+       return array;
+};
+
+try {
+       Array.prototype.slice.call( document.documentElement.childNodes, 0 );
+
+} catch(e){
+       makeArray = function(array, results) {
+               var ret = results || [];
+
+               if ( toString.call(array) === "[object Array]" ) {
+                       Array.prototype.push.apply( ret, array );
+               } else {
+                       if ( typeof array.length === "number" ) {
+                               for ( var i = 0, l = array.length; i < l; i++ ) {
+                                       ret.push( array[i] );
+                               }
+                       } else {
+                               for ( var i = 0; array[i]; i++ ) {
+                                       ret.push( array[i] );
+                               }
+                       }
+               }
+
+               return ret;
+       };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+       sortOrder = function( a, b ) {
+               if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+                       if ( a == b ) {
+                               hasDuplicate = true;
+                       }
+                       return 0;
+               }
+
+               var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+               if ( ret === 0 ) {
+                       hasDuplicate = true;
+               }
+               return ret;
+       };
+} else if ( "sourceIndex" in document.documentElement ) {
+       sortOrder = function( a, b ) {
+               if ( !a.sourceIndex || !b.sourceIndex ) {
+                       if ( a == b ) {
+                               hasDuplicate = true;
+                       }
+                       return 0;
+               }
+
+               var ret = a.sourceIndex - b.sourceIndex;
+               if ( ret === 0 ) {
+                       hasDuplicate = true;
+               }
+               return ret;
+       };
+} else if ( document.createRange ) {
+       sortOrder = function( a, b ) {
+               if ( !a.ownerDocument || !b.ownerDocument ) {
+                       if ( a == b ) {
+                               hasDuplicate = true;
+                       }
+                       return 0;
+               }
+
+               var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+               aRange.setStart(a, 0);
+               aRange.setEnd(a, 0);
+               bRange.setStart(b, 0);
+               bRange.setEnd(b, 0);
+               var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+               if ( ret === 0 ) {
+                       hasDuplicate = true;
+               }
+               return ret;
+       };
+}
+
+(function(){
+       var form = document.createElement("div"),
+               id = "script" + (new Date).getTime();
+       form.innerHTML = "<a name='" + id + "'/>";
+
+       var root = document.documentElement;
+       root.insertBefore( form, root.firstChild );
+
+       if ( !!document.getElementById( id ) ) {
+               Expr.find.ID = function(match, context, isXML){
+                       if ( typeof context.getElementById !== "undefined" && !isXML ) {
+                               var m = context.getElementById(match[1]);
+                               return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+                       }
+               };
+
+               Expr.filter.ID = function(elem, match){
+                       var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+                       return elem.nodeType === 1 && node && node.nodeValue === match;
+               };
+       }
+
+       root.removeChild( form );
+       root = form = null; // release memory in IE
+})();
+
+(function(){
+
+       var div = document.createElement("div");
+       div.appendChild( document.createComment("") );
+
+       if ( div.getElementsByTagName("*").length > 0 ) {
+               Expr.find.TAG = function(match, context){
+                       var results = context.getElementsByTagName(match[1]);
+
+                       if ( match[1] === "*" ) {
+                               var tmp = [];
+
+                               for ( var i = 0; results[i]; i++ ) {
+                                       if ( results[i].nodeType === 1 ) {
+                                               tmp.push( results[i] );
+                                       }
+                               }
+
+                               results = tmp;
+                       }
+
+                       return results;
+               };
+       }
+
+       div.innerHTML = "<a href='#'></a>";
+       if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+                       div.firstChild.getAttribute("href") !== "#" ) {
+               Expr.attrHandle.href = function(elem){
+                       return elem.getAttribute("href", 2);
+               };
+       }
+
+       div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) (function(){
+       var oldSizzle = Sizzle, div = document.createElement("div");
+       div.innerHTML = "<p class='TEST'></p>";
+
+       if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+               return;
+       }
+
+       Sizzle = function(query, context, extra, seed){
+               context = context || document;
+
+               if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+                       try {
+                               return makeArray( context.querySelectorAll(query), extra );
+                       } catch(e){}
+               }
+
+               return oldSizzle(query, context, extra, seed);
+       };
+
+       for ( var prop in oldSizzle ) {
+               Sizzle[ prop ] = oldSizzle[ prop ];
+       }
+
+       div = null; // release memory in IE
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+       var div = document.createElement("div");
+       div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+       if ( div.getElementsByClassName("e").length === 0 )
+               return;
+
+       div.lastChild.className = "e";
+
+       if ( div.getElementsByClassName("e").length === 1 )
+               return;
+
+       Expr.order.splice(1, 0, "CLASS");
+       Expr.find.CLASS = function(match, context, isXML) {
+               if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+                       return context.getElementsByClassName(match[1]);
+               }
+       };
+
+       div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+       var sibDir = dir == "previousSibling" && !isXML;
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+               var elem = checkSet[i];
+               if ( elem ) {
+                       if ( sibDir && elem.nodeType === 1 ){
+                               elem.sizcache = doneName;
+                               elem.sizset = i;
+                       }
+                       elem = elem[dir];
+                       var match = false;
+
+                       while ( elem ) {
+                               if ( elem.sizcache === doneName ) {
+                                       match = checkSet[elem.sizset];
+                                       break;
+                               }
+
+                               if ( elem.nodeType === 1 && !isXML ){
+                                       elem.sizcache = doneName;
+                                       elem.sizset = i;
+                               }
+
+                               if ( elem.nodeName === cur ) {
+                                       match = elem;
+                                       break;
+                               }
+
+                               elem = elem[dir];
+                       }
+
+                       checkSet[i] = match;
+               }
+       }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+       var sibDir = dir == "previousSibling" && !isXML;
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+               var elem = checkSet[i];
+               if ( elem ) {
+                       if ( sibDir && elem.nodeType === 1 ) {
+                               elem.sizcache = doneName;
+                               elem.sizset = i;
+                       }
+                       elem = elem[dir];
+                       var match = false;
+
+                       while ( elem ) {
+                               if ( elem.sizcache === doneName ) {
+                                       match = checkSet[elem.sizset];
+                                       break;
+                               }
+
+                               if ( elem.nodeType === 1 ) {
+                                       if ( !isXML ) {
+                                               elem.sizcache = doneName;
+                                               elem.sizset = i;
+                                       }
+                                       if ( typeof cur !== "string" ) {
+                                               if ( elem === cur ) {
+                                                       match = true;
+                                                       break;
+                                               }
+
+                                       } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+                                               match = elem;
+                                               break;
+                                       }
+                               }
+
+                               elem = elem[dir];
+                       }
+
+                       checkSet[i] = match;
+               }
+       }
+}
+
+var contains = document.compareDocumentPosition ?  function(a, b){
+       return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+       return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+       return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+               !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
+};
+
+var posProcess = function(selector, context){
+       var tmpSet = [], later = "", match,
+               root = context.nodeType ? [context] : context;
+
+       while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+               later += match[0];
+               selector = selector.replace( Expr.match.PSEUDO, "" );
+       }
+
+       selector = Expr.relative[selector] ? selector + "*" : selector;
+
+       for ( var i = 0, l = root.length; i < l; i++ ) {
+               Sizzle( selector, root[i], tmpSet );
+       }
+
+       return Sizzle.filter( later, tmpSet );
+};
+
+
+window.Sizzle = Sizzle;
+
+})();
+
+;(function(engine) {
+  var extendElements = Prototype.Selector.extendElements;
+
+  function select(selector, scope) {
+    return extendElements(engine(selector, scope || document));
+  }
+
+  function match(element, selector) {
+    return engine.matches(selector, [element]).length == 1;
+  }
+
+  Prototype.Selector.engine = engine;
+  Prototype.Selector.select = select;
+  Prototype.Selector.match = match;
+})(Sizzle);
+
+window.Sizzle = Prototype._original_property;
+delete Prototype._original_property;
+
+var Form = {
+  reset: function(form) {
+    form = $(form);
+    form.reset();
+    return form;
+  },
+
+  serializeElements: function(elements, options) {
+    if (typeof options != 'object') options = { hash: !!options };
+    else if (Object.isUndefined(options.hash)) options.hash = true;
+    var key, value, submitted = false, submit = options.submit, accumulator, initial;
+
+    if (options.hash) {
+      initial = {};
+      accumulator = function(result, key, value) {
+        if (key in result) {
+          if (!Object.isArray(result[key])) result[key] = [result[key]];
+          result[key].push(value);
+        } else result[key] = value;
+        return result;
+      };
+    } else {
+      initial = '';
+      accumulator = function(result, key, value) {
+        return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
+      }
+    }
+
+    return elements.inject(initial, function(result, element) {
+      if (!element.disabled && element.name) {
+        key = element.name; value = $(element).getValue();
+        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
+            submit !== false && (!submit || key == submit) && (submitted = true)))) {
+          result = accumulator(result, key, value);
+        }
+      }
+      return result;
+    });
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, options) {
+    return Form.serializeElements(Form.getElements(form), options);
+  },
+
+  getElements: function(form) {
+    var elements = $(form).getElementsByTagName('*'),
+        element,
+        arr = [ ],
+        serializers = Form.Element.Serializers;
+    for (var i = 0; element = elements[i]; i++) {
+      arr.push(element);
+    }
+    return arr.inject([], function(elements, child) {
+      if (serializers[child.tagName.toLowerCase()])
+        elements.push(Element.extend(child));
+      return elements;
+    })
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('disable');
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('enable');
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    var elements = $(form).getElements().findAll(function(element) {
+      return 'hidden' != element.type && !element.disabled;
+    });
+    var firstByIndex = elements.findAll(function(element) {
+      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+    }).sortBy(function(element) { return element.tabIndex }).first();
+
+    return firstByIndex ? firstByIndex : elements.find(function(element) {
+      return /^(?:input|select|textarea)$/i.test(element.tagName);
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    var element = form.findFirstElement();
+    if (element) element.activate();
+    return form;
+  },
+
+  request: function(form, options) {
+    form = $(form), options = Object.clone(options || { });
+
+    var params = options.parameters, action = form.readAttribute('action') || '';
+    if (action.blank()) action = window.location.href;
+    options.parameters = form.serialize(true);
+
+    if (params) {
+      if (Object.isString(params)) params = params.toQueryParams();
+      Object.extend(options.parameters, params);
+    }
+
+    if (form.hasAttribute('method') && !options.method)
+      options.method = form.method;
+
+    return new Ajax.Request(action, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+};
+
+Form.Element.Methods = {
+
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = { };
+        pair[element.name] = value;
+        return Object.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  setValue: function(element, value) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    Form.Element.Serializers[method](element, value);
+    return element;
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    try {
+      element.focus();
+      if (element.select && (element.tagName.toLowerCase() != 'input' ||
+          !(/^(?:button|reset|submit)$/i.test(element.type))))
+        element.select();
+    } catch (e) { }
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.disabled = false;
+    return element;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+
+var $F = Form.Element.Methods.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = (function() {
+  function input(element, value) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return inputSelector(element, value);
+      default:
+        return valueSelector(element, value);
+    }
+  }
+
+  function inputSelector(element, value) {
+    if (Object.isUndefined(value))
+      return element.checked ? element.value : null;
+    else element.checked = !!value;
+  }
+
+  function valueSelector(element, value) {
+    if (Object.isUndefined(value)) return element.value;
+    else element.value = value;
+  }
+
+  function select(element, value) {
+    if (Object.isUndefined(value))
+      return (element.type === 'select-one' ? selectOne : selectMany)(element);
+
+    var opt, currentValue, single = !Object.isArray(value);
+    for (var i = 0, length = element.length; i < length; i++) {
+      opt = element.options[i];
+      currentValue = this.optionValue(opt);
+      if (single) {
+        if (currentValue == value) {
+          opt.selected = true;
+          return;
+        }
+      }
+      else opt.selected = value.include(currentValue);
+    }
+  }
+
+  function selectOne(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? optionValue(element.options[index]) : null;
+  }
+
+  function selectMany(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(optionValue(opt));
+    }
+    return values;
+  }
+
+  function optionValue(opt) {
+    return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
+  }
+
+  return {
+    input:         input,
+    inputSelector: inputSelector,
+    textarea:      valueSelector,
+    select:        select,
+    selectOne:     selectOne,
+    selectMany:    selectMany,
+    optionValue:   optionValue,
+    button:        valueSelector
+  };
+})();
+
+/*--------------------------------------------------------------------------*/
+
+
+Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
+  initialize: function($super, element, frequency, callback) {
+    $super(callback, frequency);
+    this.element   = $(element);
+    this.lastValue = this.getValue();
+  },
+
+  execute: function() {
+    var value = this.getValue();
+    if (Object.isString(this.lastValue) && Object.isString(value) ?
+        this.lastValue != value : String(this.lastValue) != String(value)) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+});
+
+Form.Element.Observer = Class.create(Abstract.TimedObserver, {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create(Abstract.TimedObserver, {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = Class.create({
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback, this);
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+});
+
+Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create(Abstract.EventObserver, {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+(function() {
+
+  var Event = {
+    KEY_BACKSPACE: 8,
+    KEY_TAB:       9,
+    KEY_RETURN:   13,
+    KEY_ESC:      27,
+    KEY_LEFT:     37,
+    KEY_UP:       38,
+    KEY_RIGHT:    39,
+    KEY_DOWN:     40,
+    KEY_DELETE:   46,
+    KEY_HOME:     36,
+    KEY_END:      35,
+    KEY_PAGEUP:   33,
+    KEY_PAGEDOWN: 34,
+    KEY_INSERT:   45,
+
+    cache: {}
+  };
+
+  var docEl = document.documentElement;
+  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
+    && 'onmouseleave' in docEl;
+
+
+
+  var isIELegacyEvent = function(event) { return false; };
+
+  if (window.attachEvent) {
+    if (window.addEventListener) {
+      isIELegacyEvent = function(event) {
+        return !(event instanceof window.Event);
+      };
+    } else {
+      isIELegacyEvent = function(event) { return true; };
+    }
+  }
+
+  var _isButton;
+
+  function _isButtonForDOMEvents(event, code) {
+    return event.which ? (event.which === code + 1) : (event.button === code);
+  }
+
+  var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
+  function _isButtonForLegacyEvents(event, code) {
+    return event.button === legacyButtonMap[code];
+  }
+
+  function _isButtonForWebKit(event, code) {
+    switch (code) {
+      case 0: return event.which == 1 && !event.metaKey;
+      case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
+      case 2: return event.which == 3;
+      default: return false;
+    }
+  }
+
+  if (window.attachEvent) {
+    if (!window.addEventListener) {
+      _isButton = _isButtonForLegacyEvents;
+    } else {
+      _isButton = function(event, code) {
+        return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
+         _isButtonForDOMEvents(event, code);
+      }
+    }
+  } else if (Prototype.Browser.WebKit) {
+    _isButton = _isButtonForWebKit;
+  } else {
+    _isButton = _isButtonForDOMEvents;
+  }
+
+  function isLeftClick(event)   { return _isButton(event, 0) }
+
+  function isMiddleClick(event) { return _isButton(event, 1) }
+
+  function isRightClick(event)  { return _isButton(event, 2) }
+
+  function element(event) {
+    event = Event.extend(event);
+
+    var node = event.target, type = event.type,
+     currentTarget = event.currentTarget;
+
+    if (currentTarget && currentTarget.tagName) {
+      if (type === 'load' || type === 'error' ||
+        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
+          && currentTarget.type === 'radio'))
+            node = currentTarget;
+    }
+
+    if (node.nodeType == Node.TEXT_NODE)
+      node = node.parentNode;
+
+    return Element.extend(node);
+  }
+
+  function findElement(event, expression) {
+    var element = Event.element(event);
+
+    if (!expression) return element;
+    while (element) {
+      if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
+        return Element.extend(element);
+      }
+      element = element.parentNode;
+    }
+  }
+
+  function pointer(event) {
+    return { x: pointerX(event), y: pointerY(event) };
+  }
+
+  function pointerX(event) {
+    var docElement = document.documentElement,
+     body = document.body || { scrollLeft: 0 };
+
+    return event.pageX || (event.clientX +
+      (docElement.scrollLeft || body.scrollLeft) -
+      (docElement.clientLeft || 0));
+  }
+
+  function pointerY(event) {
+    var docElement = document.documentElement,
+     body = document.body || { scrollTop: 0 };
+
+    return  event.pageY || (event.clientY +
+       (docElement.scrollTop || body.scrollTop) -
+       (docElement.clientTop || 0));
+  }
+
+
+  function stop(event) {
+    Event.extend(event);
+    event.preventDefault();
+    event.stopPropagation();
+
+    event.stopped = true;
+  }
+
+
+  Event.Methods = {
+    isLeftClick:   isLeftClick,
+    isMiddleClick: isMiddleClick,
+    isRightClick:  isRightClick,
+
+    element:     element,
+    findElement: findElement,
+
+    pointer:  pointer,
+    pointerX: pointerX,
+    pointerY: pointerY,
+
+    stop: stop
+  };
+
+  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
+    m[name] = Event.Methods[name].methodize();
+    return m;
+  });
+
+  if (window.attachEvent) {
+    function _relatedTarget(event) {
+      var element;
+      switch (event.type) {
+        case 'mouseover':
+        case 'mouseenter':
+          element = event.fromElement;
+          break;
+        case 'mouseout':
+        case 'mouseleave':
+          element = event.toElement;
+          break;
+        default:
+          return null;
+      }
+      return Element.extend(element);
+    }
+
+    var additionalMethods = {
+      stopPropagation: function() { this.cancelBubble = true },
+      preventDefault:  function() { this.returnValue = false },
+      inspect: function() { return '[object Event]' }
+    };
+
+    Event.extend = function(event, element) {
+      if (!event) return false;
+
+      if (!isIELegacyEvent(event)) return event;
+
+      if (event._extendedByPrototype) return event;
+      event._extendedByPrototype = Prototype.emptyFunction;
+
+      var pointer = Event.pointer(event);
+
+      Object.extend(event, {
+        target: event.srcElement || element,
+        relatedTarget: _relatedTarget(event),
+        pageX:  pointer.x,
+        pageY:  pointer.y
+      });
+
+      Object.extend(event, methods);
+      Object.extend(event, additionalMethods);
+
+      return event;
+    };
+  } else {
+    Event.extend = Prototype.K;
+  }
+
+  if (window.addEventListener) {
+    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
+    Object.extend(Event.prototype, methods);
+  }
+
+  function _createResponder(element, eventName, handler) {
+    var registry = Element.retrieve(element, 'prototype_event_registry');
+
+    if (Object.isUndefined(registry)) {
+      CACHE.push(element);
+      registry = Element.retrieve(element, 'prototype_event_registry', $H());
+    }
+
+    var respondersForEvent = registry.get(eventName);
+    if (Object.isUndefined(respondersForEvent)) {
+      respondersForEvent = [];
+      registry.set(eventName, respondersForEvent);
+    }
+
+    if (respondersForEvent.pluck('handler').include(handler)) return false;
+
+    var responder;
+    if (eventName.include(":")) {
+      responder = function(event) {
+        if (Object.isUndefined(event.eventName))
+          return false;
+
+        if (event.eventName !== eventName)
+          return false;
+
+        Event.extend(event, element);
+        handler.call(element, event);
+      };
+    } else {
+      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
+       (eventName === "mouseenter" || eventName === "mouseleave")) {
+        if (eventName === "mouseenter" || eventName === "mouseleave") {
+          responder = function(event) {
+            Event.extend(event, element);
+
+            var parent = event.relatedTarget;
+            while (parent && parent !== element) {
+              try { parent = parent.parentNode; }
+              catch(e) { parent = element; }
+            }
+
+            if (parent === element) return;
+
+            handler.call(element, event);
+          };
+        }
+      } else {
+        responder = function(event) {
+          Event.extend(event, element);
+          handler.call(element, event);
+        };
+      }
+    }
+
+    responder.handler = handler;
+    respondersForEvent.push(responder);
+    return responder;
+  }
+
+  function _destroyCache() {
+    for (var i = 0, length = CACHE.length; i < length; i++) {
+      Event.stopObserving(CACHE[i]);
+      CACHE[i] = null;
+    }
+  }
+
+  var CACHE = [];
+
+  if (Prototype.Browser.IE)
+    window.attachEvent('onunload', _destroyCache);
+
+  if (Prototype.Browser.WebKit)
+    window.addEventListener('unload', Prototype.emptyFunction, false);
+
+
+  var _getDOMEventName = Prototype.K,
+      translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
+
+  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
+    _getDOMEventName = function(eventName) {
+      return (translations[eventName] || eventName);
+    };
+  }
+
+  function observe(element, eventName, handler) {
+    element = $(element);
+
+    var responder = _createResponder(element, eventName, handler);
+
+    if (!responder) return element;
+
+    if (eventName.include(':')) {
+      if (element.addEventListener)
+        element.addEventListener("dataavailable", responder, false);
+      else {
+        element.attachEvent("ondataavailable", responder);
+        element.attachEvent("onlosecapture", responder);
+      }
+    } else {
+      var actualEventName = _getDOMEventName(eventName);
+
+      if (element.addEventListener)
+        element.addEventListener(actualEventName, responder, false);
+      else
+        element.attachEvent("on" + actualEventName, responder);
+    }
+
+    return element;
+  }
+
+  function stopObserving(element, eventName, handler) {
+    element = $(element);
+
+    var registry = Element.retrieve(element, 'prototype_event_registry');
+    if (!registry) return element;
+
+    if (!eventName) {
+      registry.each( function(pair) {
+        var eventName = pair.key;
+        stopObserving(element, eventName);
+      });
+      return element;
+    }
+
+    var responders = registry.get(eventName);
+    if (!responders) return element;
+
+    if (!handler) {
+      responders.each(function(r) {
+        stopObserving(element, eventName, r.handler);
+      });
+      return element;
+    }
+
+    var i = responders.length, responder;
+    while (i--) {
+      if (responders[i].handler === handler) {
+        responder = responders[i];
+        break;
+      }
+    }
+    if (!responder) return element;
+
+    if (eventName.include(':')) {
+      if (element.removeEventListener)
+        element.removeEventListener("dataavailable", responder, false);
+      else {
+        element.detachEvent("ondataavailable", responder);
+        element.detachEvent("onlosecapture", responder);
+      }
+    } else {
+      var actualEventName = _getDOMEventName(eventName);
+      if (element.removeEventListener)
+        element.removeEventListener(actualEventName, responder, false);
+      else
+        element.detachEvent('on' + actualEventName, responder);
+    }
+
+    registry.set(eventName, responders.without(responder));
+
+    return element;
+  }
+
+  function fire(element, eventName, memo, bubble) {
+    element = $(element);
+
+    if (Object.isUndefined(bubble))
+      bubble = true;
+
+    if (element == document && document.createEvent && !element.dispatchEvent)
+      element = document.documentElement;
+
+    var event;
+    if (document.createEvent) {
+      event = document.createEvent('HTMLEvents');
+      event.initEvent('dataavailable', bubble, true);
+    } else {
+      event = document.createEventObject();
+      event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
+    }
+
+    event.eventName = eventName;
+    event.memo = memo || { };
+
+    if (document.createEvent)
+      element.dispatchEvent(event);
+    else
+      element.fireEvent(event.eventType, event);
+
+    return Event.extend(event);
+  }
+
+  Event.Handler = Class.create({
+    initialize: function(element, eventName, selector, callback) {
+      this.element   = $(element);
+      this.eventName = eventName;
+      this.selector  = selector;
+      this.callback  = callback;
+      this.handler   = this.handleEvent.bind(this);
+    },
+
+    start: function() {
+      Event.observe(this.element, this.eventName, this.handler);
+      return this;
+    },
+
+    stop: function() {
+      Event.stopObserving(this.element, this.eventName, this.handler);
+      return this;
+    },
+
+    handleEvent: function(event) {
+      var element = Event.findElement(event, this.selector);
+      if (element) this.callback.call(this.element, event, element);
+    }
+  });
+
+  function on(element, eventName, selector, callback) {
+    element = $(element);
+    if (Object.isFunction(selector) && Object.isUndefined(callback)) {
+      callback = selector, selector = null;
+    }
+
+    return new Event.Handler(element, eventName, selector, callback).start();
+  }
+
+  Object.extend(Event, Event.Methods);
+
+  Object.extend(Event, {
+    fire:          fire,
+    observe:       observe,
+    stopObserving: stopObserving,
+    on:            on
+  });
+
+  Element.addMethods({
+    fire:          fire,
+
+    observe:       observe,
+
+    stopObserving: stopObserving,
+
+    on:            on
+  });
+
+  Object.extend(document, {
+    fire:          fire.methodize(),
+
+    observe:       observe.methodize(),
+
+    stopObserving: stopObserving.methodize(),
+
+    on:            on.methodize(),
+
+    loaded:        false
+  });
+
+  if (window.Event) Object.extend(window.Event, Event);
+  else window.Event = Event;
+})();
+
+(function() {
+  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
+     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
+
+  var timer;
+
+  function fireContentLoadedEvent() {
+    if (document.loaded) return;
+    if (timer) window.clearTimeout(timer);
+    document.loaded = true;
+    document.fire('dom:loaded');
+  }
+
+  function checkReadyState() {
+    if (document.readyState === 'complete') {
+      document.stopObserving('readystatechange', checkReadyState);
+      fireContentLoadedEvent();
+    }
+  }
+
+  function pollDoScroll() {
+    try { document.documentElement.doScroll('left'); }
+    catch(e) {
+      timer = pollDoScroll.defer();
+      return;
+    }
+    fireContentLoadedEvent();
+  }
+
+  if (document.addEventListener) {
+    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
+  } else {
+    document.observe('readystatechange', checkReadyState);
+    if (window == top)
+      timer = pollDoScroll.defer();
+  }
+
+  Event.observe(window, 'load', fireContentLoadedEvent);
+})();
+
+Element.addMethods();
+
+/*------------------------------- DEPRECATED -------------------------------*/
+
+Hash.toQueryString = Object.toQueryString;
+
+var Toggle = { display: Element.toggle };
+
+Element.Methods.childOf = Element.Methods.descendantOf;
+
+var Insertion = {
+  Before: function(element, content) {
+    return Element.insert(element, {before:content});
+  },
+
+  Top: function(element, content) {
+    return Element.insert(element, {top:content});
+  },
+
+  Bottom: function(element, content) {
+    return Element.insert(element, {bottom:content});
+  },
+
+  After: function(element, content) {
+    return Element.insert(element, {after:content});
+  }
+};
+
+var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+
+var Position = {
+  includeScrollOffsets: false,
+
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = Element.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = Element.cumulativeScrollOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = Element.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+
+  cumulativeOffset: Element.Methods.cumulativeOffset,
+
+  positionedOffset: Element.Methods.positionedOffset,
+
+  absolutize: function(element) {
+    Position.prepare();
+    return Element.absolutize(element);
+  },
+
+  relativize: function(element) {
+    Position.prepare();
+    return Element.relativize(element);
+  },
+
+  realOffset: Element.Methods.cumulativeScrollOffset,
+
+  offsetParent: Element.Methods.getOffsetParent,
+
+  page: Element.Methods.viewportOffset,
+
+  clone: function(source, target, options) {
+    options = options || { };
+    return Element.clonePosition(target, source, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
+  function iter(name) {
+    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+  }
+
+  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+  function(element, className) {
+    className = className.toString().strip();
+    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+  } : function(element, className) {
+    className = className.toString().strip();
+    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+    if (!classNames && !className) return elements;
+
+    var nodes = $(element).getElementsByTagName('*');
+    className = ' ' + className + ' ';
+
+    for (var i = 0, child, cn; child = nodes[i]; i++) {
+      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+          (classNames && classNames.all(function(name) {
+            return !name.toString().blank() && cn.include(' ' + name + ' ');
+          }))))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  };
+
+  return function(className, parentElement) {
+    return $(parentElement || document.body).getElementsByClassName(className);
+  };
+}(Element.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+
+/*--------------------------------------------------------------------------*/
+
+(function() {
+  window.Selector = Class.create({
+    initialize: function(expression) {
+      this.expression = expression.strip();
+    },
+
+    findElements: function(rootElement) {
+      return Prototype.Selector.select(this.expression, rootElement);
+    },
+
+    match: function(element) {
+      return Prototype.Selector.match(element, this.expression);
+    },
+
+    toString: function() {
+      return this.expression;
+    },
+
+    inspect: function() {
+      return "#<Selector: " + this.expression + ">";
+    }
+  });
+
+  Object.extend(Selector, {
+    matchElements: function(elements, expression) {
+      var match = Prototype.Selector.match,
+          results = [];
+
+      for (var i = 0, length = elements.length; i < length; i++) {
+        var element = elements[i];
+        if (match(element, expression)) {
+          results.push(Element.extend(element));
+        }
+      }
+      return results;
+    },
+
+    findElement: function(elements, expression, index) {
+      index = index || 0;
+      var matchIndex = 0, element;
+      for (var i = 0, length = elements.length; i < length; i++) {
+        element = elements[i];
+        if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
+          return Element.extend(element);
+        }
+      }
+    },
+
+    findChildElements: function(element, expressions) {
+      var selector = expressions.toArray().join(', ');
+      return Prototype.Selector.select(selector, element || document);
+    }
+  });
+})();
diff --git a/webif/netrap.html b/webif/netrap.html
new file mode 100644 (file)
index 0000000..17d5b56
--- /dev/null
@@ -0,0 +1,425 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>NetRap</title>
+               <script src="js/prototype.js"></script>
+               <script src="js/netrap.js"></script>
+               <script src="js/boundvalue.js"></script>
+               <script src="js/jog.js"></script>
+               <link rel="stylesheet" type="text/css" href="css/style.css">
+               <link rel="stylesheet" type="text/css" href="css/font-awesome.css">
+               <link rel="icon" type="image/png" href="favicon.png">
+       </head>
+       <body>
+               <div id="shadow"></div>
+               <form id="addprinter">
+                       <div id="add_serialprinter">
+                               <h3>Serial Printer</h3>
+                               <label for="input_serialport">Device:</label>
+                               <input type="text" name="serialport" id="input_serialport" placeholder="/dev/ttyACM0" pattern="/dev/.*|COM\d+"><br>
+                               <label for="input_baud">Baud:</label>
+                               <select name="baud" id="input_baud">
+                                       <option>38400</option>
+                                       <option>57600</option>
+                                       <option selected>115200</option>
+                                       <option>250000</option>
+                               </select>
+                       </div>
+                       <div id="add_tcpprinter">
+                               <h3>TCP Printer</h3>
+                               <label for="input_hostname">Host:</label>
+                               <input type="text" name="hostname" id="input_hostname" placeholder="192.168.1.73"><br>
+                               <label for="input_port">Port:</label>
+                               <input type="number" name="port" id="input_port" placeholder="2560" min="0" max="65535">
+                       </div>
+                       <br>
+                       <input type="submit" value="Add" id="submit_addprinter">
+               </form>
+               <div class="toolbar">
+                       <div class="printerbar" id="printerbar"><input type="button" id="refreshPrinters" value="R" /><input type="button" id="button_addPrinter" value="+" /></div><br />
+                       <div style="overflow: visible; white-space: nowrap;" id="printername"></div><br style="clear: right;" />
+                       <div><input type="checkbox" id="monitor" /><span label="monitor">Monitor Printer</span></div>
+                       <div><input type="button" id="getpos" value="Get Pos" /></div>
+                       <div><input type="button" id="gettemp" value="Get Temp" /></div>
+                       <div><input type="button" id="turnon" value="On" style="background-color: #8D8;" /></div>
+                       <div><input type="button" id="turnoff" value="Off" style="background-color: #D88;" /></div>
+               </div>
+               <br class="clear" />
+               <div class="tabs" id="tabbar">
+                       <div class="tabbutton" id="PrinterTabButton">Printer</div>
+                       <div class="tabbutton" id="FilesTabButton">Files</div>
+                       <div class="tabbutton" id="SliceTabButton">Slice</div>
+               </div>
+               <br class="clear" />
+               <div class="tabcontent" id="PrinterTab" name="Printer">
+                       <table>
+                               <tr><td>
+                                       <canvas id="jogXYCanvas" width="247" height="242" style="width: 247px; height: 242px; background-image: url('images/control_xy.png'); background-repeat: none; float:left;"></canvas>
+                               </td><td>
+                                       <canvas id="jogZCanvas" width="59" height="242" style="width: 59px; height: 242px; background-image: url('images/control_z.png'); background-repeat: none; float:left;"></canvas>
+                               </td><td>
+                                       <canvas id="jogECanvas" width="59" height="242" style="width: 59px; height: 242px; background-image: url('images/control_e.png'); background-repeat: none; float:left;"></canvas>
+                               </td><td>
+                                       <textarea id="log" rows="16" cols="40" readonly="readonly"></textarea><br />
+                                       <form id="manual_entry">
+                                               <input type="text" id="send" style="width: 80%; float: left;" />
+                                               <input type="submit" id="sendBtn" value="Send" />
+                                               <input type="button" id="clearlog" value="Clear" />
+                                       </form>
+                               </td></tr>
+                       </table>
+               </div>
+               <div class="tabcontent" id="FilesTab" name="Files">
+                       <div id="FileUploads"></div>
+                       <input type="file" id="fileupload" multiple="multiple" />
+                       <ul class="FileList" id="FileList"></ul>
+               </div>
+               <div class="tabcontent" id="SliceTab" name="Slice">
+                       <em>Not implemented yet</em>
+               </div>
+
+               <script type="text/javascript">
+                       document.observe('dom:loaded', function() {
+                               var netrap = new netrapUplink('netrap-json');
+
+                               function nicesize(size) {
+                                       if (size > Math.pow(2,30))
+                                               return Math.round(size / 10000000) / 100 + 'Gb';
+                                       if (size > Math.pow(2,20))
+                                               return Math.round(size / 10000) / 100 + 'Mb';
+                                       if (size > Math.pow(2,10))
+                                               return Math.round(size / 10) / 100 + 'Kb';
+                                       return size + 'b';
+                               }
+
+                               function callback_LoadFile(file) {
+                                       netrap.loadFile(file);
+                               }
+
+                               function callback_DeleteFile(file) {
+                                       netrap.deleteFile(file, function(response) {
+                                               if (response && response.responseJSON && response.responseJSON.file) {
+                                                       for (var i = 0, lia; lia = $('FileList').childNodes[i]; i++) {
+                                                               if (lia.childNodes[0].innerHTML == response.responseJSON.file) {
+                                                                       $('FileList').removeChild($('FileList').childNodes[i]);
+                                                                       i--;
+                                                               }
+                                                       }
+                                               }
+                                       });
+                               }
+
+                               function callback_PlayFile() {
+                                       netrap.printerStart();
+                               }
+
+                               function addFile(file) {
+                                       var li = document.createElement('li');
+                                       var a = document.createElement('a');
+
+                                       a.innerHTML = file.name;
+                                       a.href = '#file=' + file.name;
+                                       a.file = file;
+                                       a.filename = file.name;
+                                       a.observe('click', function() {
+                                               callback_LoadFile(file);
+                                       });
+                                       li.appendChild(a);
+
+                                       var sz = document.createElement('div');
+                                       sz.className = 'filesize';
+                                       sz.innerHTML = nicesize(file.size);
+
+                                       li.appendChild(sz);
+
+                                       if ($('printername').innerHTML) {
+                                               var act_play = document.createElement('div');
+                                               act_play.className = 'fileaction fileaction_load icon-play';
+                                               act_play.title = 'Play';
+                                               act_play.observe('click', function() {
+                                                       netrap.loadFile(file, undefined, callback_PlayFile);
+                                               });
+
+                                               li.appendChild(act_play);
+
+                                               var act_load = document.createElement('div');
+                                               act_load.className = 'fileaction fileaction_load icon-link';
+                                               act_load.title = 'Load';
+                                               act_load.observe('click', function() {
+                                                       callback_LoadFile(file);
+                                               });
+
+                                               li.appendChild(act_load);
+                                       }
+
+                                       var act_del = document.createElement('div');
+                                       act_del.className = 'fileaction fileaction_delete icon-remove';
+                                       act_del.title = 'Delete';
+                                       act_del.observe('click', function() {
+                                               callback_DeleteFile(file);
+                                       });
+
+                                       li.appendChild(act_del);
+
+                                       $("FileList").appendChild(li);
+                               }
+
+                               function callback_FileList(files) {
+                                       while ($("FileList").childNodes.length) {
+                                               $("FileList").removeChild($("FileList").childNodes[0]);
+                                       }
+                                       for (var i = 0, file; file = files[i]; i++) {
+                                               addFile(file);
+                                       }
+                               }
+
+                               function tabActivate(n) {
+       //                              alert(n);
+                                       var tabbar = $("tabbar");
+                                       for (var i = 0; i < tabbar.children.length; i++) {
+                                               var regex = /^(.*)Button/.exec(tabbar.children[i].id);
+                                               if (regex) {
+                                                       if (i == n) {
+                                                               $(regex[1]).className = "tabcontent current";
+                                                               tabbar.children[i].className = "tabbutton current";
+                                                               if (/FilesTabButton/.test(tabbar.children[i].id)) {
+                                                                       netrap.refreshFileList(callback_FileList);
+                                                               }
+                                                       }
+                                                       else {
+                                                               $(regex[1]).className = "tabcontent hidden";
+                                                               tabbar.children[i].className = "tabbutton";
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               var tabbar = $("tabbar");
+                               for (var i = 0; i < tabbar.children.length; i++) {
+                                       tabbar.children[i].tabindex = i;
+                                       tabbar.children[i].observe("click", function() {
+                                               tabActivate(this.tabindex);
+                                       });
+                               }
+                               tabActivate(0);
+
+                               try {
+                                       var jogXY = new JogXY($('jogXYCanvas'));
+                                       var jogZ = new JogZ($('jogZCanvas'));
+                                       var jogE = new JogE($('jogECanvas'));
+                               } catch (e) {
+                                       alert(e);
+                               }
+
+                               jogXY.draw();
+                               jogZ.draw();
+                               jogE.draw();
+
+                               function callback_jogEvent(e) {
+                                       for (var i = 0; i < e.gcode.length; i++) {
+                                               netrap.queueCmd(e.gcode[i]);
+                                       }
+                                       netrap.queueCommit();
+                               };
+
+                               function refreshPrinterList() {
+//                                     var printerdivs = $$('#printerbar > .printer');
+//                                     for (var i = 0; i < printerdivs.length; i++) {
+//                                             $('printerbar').removeChild(printerdivs[i]);
+//                                     }
+                                       netrap.refreshPrinterList(callback_printersList);
+                               }
+
+                               function callback_printerclick() {
+                                       var oldcurrent = $$('#printerbar > .current')[0];
+                                       if (oldcurrent) {
+                                               var a = oldcurrent.className.split(" ");
+                                               var i = a.indexOf('current');
+                                               a.splice(i, 1);
+                                               oldcurrent.className = a.join(" ");
+                                       }
+                                       this.className += " current";
+                                       $('printername').innerHTML = this.printername;
+                                       netrap.selectPrinter(this.printername);
+                               };
+
+                               function callback_printersList(printers) {
+                                       var printerdivs = $$('#printerbar > .printer');
+                                       var existingprinters = [];
+                                       for (var i = 0; i < printerdivs.length; i++) {
+                                               if (printers.indexOf(printerdivs[i].printername) < 0)
+                                                       $('printerbar').removeChild(printerdivs[i]);
+                                               else
+                                                       existingprinters.push(printerdivs[i].printername);
+                                       }
+                                       for (var i = 0; i < printers.length; i++) {
+                                               var printer = printers[i];
+
+                                               if (existingprinters.indexOf(printer.name) < 0) {
+                                                       var printerdiv = document.createElement('div');
+                                                       printerdiv.className = 'printer';
+
+                                                       var newimg = document.createElement('img');
+                                                       newimg.src = 'images/prusa_icon.png';
+
+                                                       printerdiv.appendChild(newimg);
+                                                       printerdiv.innerHTML += '<br />' + printer.name;
+
+                                                       printerdiv.printername = printer.name;
+                                                       printerdiv.observe('click', callback_printerclick);
+
+                                                       $('printerbar').appendChild(printerdiv);
+                                               }
+                                       }
+                               };
+
+                               function callback_FileUpload_NextFile() {
+                                       var uploads = $$('.uploading');
+                                       if (uploads.length) {
+                                               var uf = uploads[0];
+                                               uf.className = 'uploadingfile uploadingfile_current';
+                                               var file = uf.file;
+                                               netrap.uploadFile(file, function(response) {
+                                                       $$('.uploadingfile_current > .text')[0].innerHTML = 'Uploading: ' + file.name + ' [' + nicesize(file.size) + ' Complete]';
+                                                       uf.className = 'uploadingfile uploaded';
+                                                       window.setTimeout(function() {
+                                                               $('FileUploads').removeChild(uf);
+                                                       }, 1000);
+                                                       window.setTimeout(function() {
+                                                               callback_FileUpload_NextFile();
+                                                       }, 100);
+                                                       for (var i = 0, lia; lia = $('FileList').childNodes[i]; i++) {
+                                                               if (lia.childNodes[0].innerHTML == file.name) {
+                                                                       $('FileList').removeChild($('FileList').childNodes[i]);
+                                                                       i--;
+                                                               }
+                                                       }
+                                                       addFile(file);
+//                                                     netrap.files.push({'name': file.name, 'size':file.size});
+//                                                     callback_FileList(netrap.files);
+                                               },
+                                               function(response) {
+                                                       var percent = Math.round(response.loaded * 1000 / response.total) / 10;
+                                                       uf.childNodes[0].style.left = (percent - 100) + '%';
+                                                       $$('.uploadingfile_current > .text')[0].innerHTML = 'Uploading: ' + file.name + ' [' + nicesize(response.loaded) + ' of ' + nicesize(response.total) + ': ' + percent + '%]';
+                                               });
+                                       }
+                               };
+
+                               function callback_FileUpload(event) {
+                                       var files = event.target.files;
+//                                     var lastfilediv;
+                                       for (var i = 0, f; f = files[i]; i++) {
+                                               var uf = document.createElement('div');
+                                               uf.className = 'uploadingfile uploading';
+
+                                               var tx = document.createElement('div');
+                                               tx.innerHTML = "Uploading: " + f.name + ' [' + nicesize(f.size) + ']';
+                                               tx.className = 'text';
+
+                                               var sl = document.createElement('div');
+                                               sl.className = 'background';
+                                               sl.style.left = '-100%';
+
+                                               var sl2 = document.createElement('div');
+                                               sl2.className = 'slider';
+
+                                               var sl3 = document.createElement('div');
+                                               sl3.className = 'backgroundHolder';
+
+                                               sl.appendChild(sl2);
+                                               uf.appendChild(sl);
+                                               uf.appendChild(tx);
+                                               uf.file = f;
+                                               $('FileUploads').appendChild(uf);
+//                                             lastfilediv = uf;
+                                       }
+                                       callback_FileUpload_NextFile();
+                                       this.clear();
+                                       return false;
+                               };
+
+                               jogXY.observe('click', callback_jogEvent);
+                               jogZ.observe('click', callback_jogEvent);
+                               jogE.observe('click', callback_jogEvent);
+
+                               function printer_added(response) {
+                                       window.setTimeout(refreshPrinterList, 100);
+                               }
+
+                               $('button_addPrinter').observe('click', function() {
+                                       $('shadow').className = 'visible';
+                                       $('addprinter').className = 'visible';
+                                       $('shadow').showing = $('addprinter');
+                               });
+                               $('shadow').observe('click', function() {
+                                       if (this.showing)
+                                               this.showing.className = '';
+                                       this.className = '';
+                               });
+                               $('submit_addprinter').observe('click', function(e) {
+                                       $('shadow').className = '';
+                                       $('addprinter').className = '';
+                                       if ($('input_serialport').value && $('input_baud').value) {
+                                               netrap.addSerialPrinter($('input_serialport').value, $('input_baud').value, printer_added);
+                                       }
+                                       else if ($('input_hostname').value && $('input_port').value) {
+                                               netrap.addTCPPrinter($('input_hostname').value, $('input_port').value, printer_added);
+                                       }
+                                       delete $('shadow').showing;
+                                       e.preventDefault();
+                                       e.stopPropagation();
+                               });
+                               $('refreshPrinters').observe('click', refreshPrinterList);
+                               $('getpos').observe('click', function() {
+                                       $('log').value += "> M114\n";
+                                       netrap.refreshPosition();
+                               });
+                               $('clearlog').observe('click', function() {
+                                       $('log').value = "";
+                               });
+                               $('monitor').observe('change', function() {
+                                       if (this.checked) {
+                                               this.timer = setInterval(function() {
+                                                       netrap.refreshTemperatureList();
+                                               }, 5000);
+                                       }
+                                       else {
+                                               if (this.timer) {
+                                                       clearTimeout(this.timer);
+                                                       this.timer = undefined;
+                                               }
+                                       }
+                               });
+                               $('fileupload').observe('change', callback_FileUpload);
+                               $('manual_entry').onsubmit = function() {
+                                       var send = $('send');
+                                       if (send.value) {
+                                               send.value = send.value;
+                                               $('log').value += "> " + send.value + "\n";
+                                               netrap.query(send.value);
+                                       }
+                                       send.value = "";
+                                       return false;
+                               };
+
+                               $('gettemp').observe('click', function() {
+                                       $('log').value += "> M105\n";
+                                       netrap.query("M105");
+                               });
+                               $('turnon').observe('click', function() {
+                                       $('log').value += "> M80\n";
+                                       netrap.query("M80");
+                               });
+                               $('turnoff').observe('click', function() {
+                                       $('log').value += "> M81\n";
+                                       netrap.queueCmd("M81");
+                                       netrap.queueCmd("M84");
+                                       netrap.queueCommit();
+                               });
+
+                               window.setTimeout(refreshPrinterList, 100);
+                       });
+               </script>
+       </body>
+</html>
diff --git a/webif/netrap_old.html b/webif/netrap_old.html
new file mode 100644 (file)
index 0000000..17d5b56
--- /dev/null
@@ -0,0 +1,425 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>NetRap</title>
+               <script src="js/prototype.js"></script>
+               <script src="js/netrap.js"></script>
+               <script src="js/boundvalue.js"></script>
+               <script src="js/jog.js"></script>
+               <link rel="stylesheet" type="text/css" href="css/style.css">
+               <link rel="stylesheet" type="text/css" href="css/font-awesome.css">
+               <link rel="icon" type="image/png" href="favicon.png">
+       </head>
+       <body>
+               <div id="shadow"></div>
+               <form id="addprinter">
+                       <div id="add_serialprinter">
+                               <h3>Serial Printer</h3>
+                               <label for="input_serialport">Device:</label>
+                               <input type="text" name="serialport" id="input_serialport" placeholder="/dev/ttyACM0" pattern="/dev/.*|COM\d+"><br>
+                               <label for="input_baud">Baud:</label>
+                               <select name="baud" id="input_baud">
+                                       <option>38400</option>
+                                       <option>57600</option>
+                                       <option selected>115200</option>
+                                       <option>250000</option>
+                               </select>
+                       </div>
+                       <div id="add_tcpprinter">
+                               <h3>TCP Printer</h3>
+                               <label for="input_hostname">Host:</label>
+                               <input type="text" name="hostname" id="input_hostname" placeholder="192.168.1.73"><br>
+                               <label for="input_port">Port:</label>
+                               <input type="number" name="port" id="input_port" placeholder="2560" min="0" max="65535">
+                       </div>
+                       <br>
+                       <input type="submit" value="Add" id="submit_addprinter">
+               </form>
+               <div class="toolbar">
+                       <div class="printerbar" id="printerbar"><input type="button" id="refreshPrinters" value="R" /><input type="button" id="button_addPrinter" value="+" /></div><br />
+                       <div style="overflow: visible; white-space: nowrap;" id="printername"></div><br style="clear: right;" />
+                       <div><input type="checkbox" id="monitor" /><span label="monitor">Monitor Printer</span></div>
+                       <div><input type="button" id="getpos" value="Get Pos" /></div>
+                       <div><input type="button" id="gettemp" value="Get Temp" /></div>
+                       <div><input type="button" id="turnon" value="On" style="background-color: #8D8;" /></div>
+                       <div><input type="button" id="turnoff" value="Off" style="background-color: #D88;" /></div>
+               </div>
+               <br class="clear" />
+               <div class="tabs" id="tabbar">
+                       <div class="tabbutton" id="PrinterTabButton">Printer</div>
+                       <div class="tabbutton" id="FilesTabButton">Files</div>
+                       <div class="tabbutton" id="SliceTabButton">Slice</div>
+               </div>
+               <br class="clear" />
+               <div class="tabcontent" id="PrinterTab" name="Printer">
+                       <table>
+                               <tr><td>
+                                       <canvas id="jogXYCanvas" width="247" height="242" style="width: 247px; height: 242px; background-image: url('images/control_xy.png'); background-repeat: none; float:left;"></canvas>
+                               </td><td>
+                                       <canvas id="jogZCanvas" width="59" height="242" style="width: 59px; height: 242px; background-image: url('images/control_z.png'); background-repeat: none; float:left;"></canvas>
+                               </td><td>
+                                       <canvas id="jogECanvas" width="59" height="242" style="width: 59px; height: 242px; background-image: url('images/control_e.png'); background-repeat: none; float:left;"></canvas>
+                               </td><td>
+                                       <textarea id="log" rows="16" cols="40" readonly="readonly"></textarea><br />
+                                       <form id="manual_entry">
+                                               <input type="text" id="send" style="width: 80%; float: left;" />
+                                               <input type="submit" id="sendBtn" value="Send" />
+                                               <input type="button" id="clearlog" value="Clear" />
+                                       </form>
+                               </td></tr>
+                       </table>
+               </div>
+               <div class="tabcontent" id="FilesTab" name="Files">
+                       <div id="FileUploads"></div>
+                       <input type="file" id="fileupload" multiple="multiple" />
+                       <ul class="FileList" id="FileList"></ul>
+               </div>
+               <div class="tabcontent" id="SliceTab" name="Slice">
+                       <em>Not implemented yet</em>
+               </div>
+
+               <script type="text/javascript">
+                       document.observe('dom:loaded', function() {
+                               var netrap = new netrapUplink('netrap-json');
+
+                               function nicesize(size) {
+                                       if (size > Math.pow(2,30))
+                                               return Math.round(size / 10000000) / 100 + 'Gb';
+                                       if (size > Math.pow(2,20))
+                                               return Math.round(size / 10000) / 100 + 'Mb';
+                                       if (size > Math.pow(2,10))
+                                               return Math.round(size / 10) / 100 + 'Kb';
+                                       return size + 'b';
+                               }
+
+                               function callback_LoadFile(file) {
+                                       netrap.loadFile(file);
+                               }
+
+                               function callback_DeleteFile(file) {
+                                       netrap.deleteFile(file, function(response) {
+                                               if (response && response.responseJSON && response.responseJSON.file) {
+                                                       for (var i = 0, lia; lia = $('FileList').childNodes[i]; i++) {
+                                                               if (lia.childNodes[0].innerHTML == response.responseJSON.file) {
+                                                                       $('FileList').removeChild($('FileList').childNodes[i]);
+                                                                       i--;
+                                                               }
+                                                       }
+                                               }
+                                       });
+                               }
+
+                               function callback_PlayFile() {
+                                       netrap.printerStart();
+                               }
+
+                               function addFile(file) {
+                                       var li = document.createElement('li');
+                                       var a = document.createElement('a');
+
+                                       a.innerHTML = file.name;
+                                       a.href = '#file=' + file.name;
+                                       a.file = file;
+                                       a.filename = file.name;
+                                       a.observe('click', function() {
+                                               callback_LoadFile(file);
+                                       });
+                                       li.appendChild(a);
+
+                                       var sz = document.createElement('div');
+                                       sz.className = 'filesize';
+                                       sz.innerHTML = nicesize(file.size);
+
+                                       li.appendChild(sz);
+
+                                       if ($('printername').innerHTML) {
+                                               var act_play = document.createElement('div');
+                                               act_play.className = 'fileaction fileaction_load icon-play';
+                                               act_play.title = 'Play';
+                                               act_play.observe('click', function() {
+                                                       netrap.loadFile(file, undefined, callback_PlayFile);
+                                               });
+
+                                               li.appendChild(act_play);
+
+                                               var act_load = document.createElement('div');
+                                               act_load.className = 'fileaction fileaction_load icon-link';
+                                               act_load.title = 'Load';
+                                               act_load.observe('click', function() {
+                                                       callback_LoadFile(file);
+                                               });
+
+                                               li.appendChild(act_load);
+                                       }
+
+                                       var act_del = document.createElement('div');
+                                       act_del.className = 'fileaction fileaction_delete icon-remove';
+                                       act_del.title = 'Delete';
+                                       act_del.observe('click', function() {
+                                               callback_DeleteFile(file);
+                                       });
+
+                                       li.appendChild(act_del);
+
+                                       $("FileList").appendChild(li);
+                               }
+
+                               function callback_FileList(files) {
+                                       while ($("FileList").childNodes.length) {
+                                               $("FileList").removeChild($("FileList").childNodes[0]);
+                                       }
+                                       for (var i = 0, file; file = files[i]; i++) {
+                                               addFile(file);
+                                       }
+                               }
+
+                               function tabActivate(n) {
+       //                              alert(n);
+                                       var tabbar = $("tabbar");
+                                       for (var i = 0; i < tabbar.children.length; i++) {
+                                               var regex = /^(.*)Button/.exec(tabbar.children[i].id);
+                                               if (regex) {
+                                                       if (i == n) {
+                                                               $(regex[1]).className = "tabcontent current";
+                                                               tabbar.children[i].className = "tabbutton current";
+                                                               if (/FilesTabButton/.test(tabbar.children[i].id)) {
+                                                                       netrap.refreshFileList(callback_FileList);
+                                                               }
+                                                       }
+                                                       else {
+                                                               $(regex[1]).className = "tabcontent hidden";
+                                                               tabbar.children[i].className = "tabbutton";
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               var tabbar = $("tabbar");
+                               for (var i = 0; i < tabbar.children.length; i++) {
+                                       tabbar.children[i].tabindex = i;
+                                       tabbar.children[i].observe("click", function() {
+                                               tabActivate(this.tabindex);
+                                       });
+                               }
+                               tabActivate(0);
+
+                               try {
+                                       var jogXY = new JogXY($('jogXYCanvas'));
+                                       var jogZ = new JogZ($('jogZCanvas'));
+                                       var jogE = new JogE($('jogECanvas'));
+                               } catch (e) {
+                                       alert(e);
+                               }
+
+                               jogXY.draw();
+                               jogZ.draw();
+                               jogE.draw();
+
+                               function callback_jogEvent(e) {
+                                       for (var i = 0; i < e.gcode.length; i++) {
+                                               netrap.queueCmd(e.gcode[i]);
+                                       }
+                                       netrap.queueCommit();
+                               };
+
+                               function refreshPrinterList() {
+//                                     var printerdivs = $$('#printerbar > .printer');
+//                                     for (var i = 0; i < printerdivs.length; i++) {
+//                                             $('printerbar').removeChild(printerdivs[i]);
+//                                     }
+                                       netrap.refreshPrinterList(callback_printersList);
+                               }
+
+                               function callback_printerclick() {
+                                       var oldcurrent = $$('#printerbar > .current')[0];
+                                       if (oldcurrent) {
+                                               var a = oldcurrent.className.split(" ");
+                                               var i = a.indexOf('current');
+                                               a.splice(i, 1);
+                                               oldcurrent.className = a.join(" ");
+                                       }
+                                       this.className += " current";
+                                       $('printername').innerHTML = this.printername;
+                                       netrap.selectPrinter(this.printername);
+                               };
+
+                               function callback_printersList(printers) {
+                                       var printerdivs = $$('#printerbar > .printer');
+                                       var existingprinters = [];
+                                       for (var i = 0; i < printerdivs.length; i++) {
+                                               if (printers.indexOf(printerdivs[i].printername) < 0)
+                                                       $('printerbar').removeChild(printerdivs[i]);
+                                               else
+                                                       existingprinters.push(printerdivs[i].printername);
+                                       }
+                                       for (var i = 0; i < printers.length; i++) {
+                                               var printer = printers[i];
+
+                                               if (existingprinters.indexOf(printer.name) < 0) {
+                                                       var printerdiv = document.createElement('div');
+                                                       printerdiv.className = 'printer';
+
+                                                       var newimg = document.createElement('img');
+                                                       newimg.src = 'images/prusa_icon.png';
+
+                                                       printerdiv.appendChild(newimg);
+                                                       printerdiv.innerHTML += '<br />' + printer.name;
+
+                                                       printerdiv.printername = printer.name;
+                                                       printerdiv.observe('click', callback_printerclick);
+
+                                                       $('printerbar').appendChild(printerdiv);
+                                               }
+                                       }
+                               };
+
+                               function callback_FileUpload_NextFile() {
+                                       var uploads = $$('.uploading');
+                                       if (uploads.length) {
+                                               var uf = uploads[0];
+                                               uf.className = 'uploadingfile uploadingfile_current';
+                                               var file = uf.file;
+                                               netrap.uploadFile(file, function(response) {
+                                                       $$('.uploadingfile_current > .text')[0].innerHTML = 'Uploading: ' + file.name + ' [' + nicesize(file.size) + ' Complete]';
+                                                       uf.className = 'uploadingfile uploaded';
+                                                       window.setTimeout(function() {
+                                                               $('FileUploads').removeChild(uf);
+                                                       }, 1000);
+                                                       window.setTimeout(function() {
+                                                               callback_FileUpload_NextFile();
+                                                       }, 100);
+                                                       for (var i = 0, lia; lia = $('FileList').childNodes[i]; i++) {
+                                                               if (lia.childNodes[0].innerHTML == file.name) {
+                                                                       $('FileList').removeChild($('FileList').childNodes[i]);
+                                                                       i--;
+                                                               }
+                                                       }
+                                                       addFile(file);
+//                                                     netrap.files.push({'name': file.name, 'size':file.size});
+//                                                     callback_FileList(netrap.files);
+                                               },
+                                               function(response) {
+                                                       var percent = Math.round(response.loaded * 1000 / response.total) / 10;
+                                                       uf.childNodes[0].style.left = (percent - 100) + '%';
+                                                       $$('.uploadingfile_current > .text')[0].innerHTML = 'Uploading: ' + file.name + ' [' + nicesize(response.loaded) + ' of ' + nicesize(response.total) + ': ' + percent + '%]';
+                                               });
+                                       }
+                               };
+
+                               function callback_FileUpload(event) {
+                                       var files = event.target.files;
+//                                     var lastfilediv;
+                                       for (var i = 0, f; f = files[i]; i++) {
+                                               var uf = document.createElement('div');
+                                               uf.className = 'uploadingfile uploading';
+
+                                               var tx = document.createElement('div');
+                                               tx.innerHTML = "Uploading: " + f.name + ' [' + nicesize(f.size) + ']';
+                                               tx.className = 'text';
+
+                                               var sl = document.createElement('div');
+                                               sl.className = 'background';
+                                               sl.style.left = '-100%';
+
+                                               var sl2 = document.createElement('div');
+                                               sl2.className = 'slider';
+
+                                               var sl3 = document.createElement('div');
+                                               sl3.className = 'backgroundHolder';
+
+                                               sl.appendChild(sl2);
+                                               uf.appendChild(sl);
+                                               uf.appendChild(tx);
+                                               uf.file = f;
+                                               $('FileUploads').appendChild(uf);
+//                                             lastfilediv = uf;
+                                       }
+                                       callback_FileUpload_NextFile();
+                                       this.clear();
+                                       return false;
+                               };
+
+                               jogXY.observe('click', callback_jogEvent);
+                               jogZ.observe('click', callback_jogEvent);
+                               jogE.observe('click', callback_jogEvent);
+
+                               function printer_added(response) {
+                                       window.setTimeout(refreshPrinterList, 100);
+                               }
+
+                               $('button_addPrinter').observe('click', function() {
+                                       $('shadow').className = 'visible';
+                                       $('addprinter').className = 'visible';
+                                       $('shadow').showing = $('addprinter');
+                               });
+                               $('shadow').observe('click', function() {
+                                       if (this.showing)
+                                               this.showing.className = '';
+                                       this.className = '';
+                               });
+                               $('submit_addprinter').observe('click', function(e) {
+                                       $('shadow').className = '';
+                                       $('addprinter').className = '';
+                                       if ($('input_serialport').value && $('input_baud').value) {
+                                               netrap.addSerialPrinter($('input_serialport').value, $('input_baud').value, printer_added);
+                                       }
+                                       else if ($('input_hostname').value && $('input_port').value) {
+                                               netrap.addTCPPrinter($('input_hostname').value, $('input_port').value, printer_added);
+                                       }
+                                       delete $('shadow').showing;
+                                       e.preventDefault();
+                                       e.stopPropagation();
+                               });
+                               $('refreshPrinters').observe('click', refreshPrinterList);
+                               $('getpos').observe('click', function() {
+                                       $('log').value += "> M114\n";
+                                       netrap.refreshPosition();
+                               });
+                               $('clearlog').observe('click', function() {
+                                       $('log').value = "";
+                               });
+                               $('monitor').observe('change', function() {
+                                       if (this.checked) {
+                                               this.timer = setInterval(function() {
+                                                       netrap.refreshTemperatureList();
+                                               }, 5000);
+                                       }
+                                       else {
+                                               if (this.timer) {
+                                                       clearTimeout(this.timer);
+                                                       this.timer = undefined;
+                                               }
+                                       }
+                               });
+                               $('fileupload').observe('change', callback_FileUpload);
+                               $('manual_entry').onsubmit = function() {
+                                       var send = $('send');
+                                       if (send.value) {
+                                               send.value = send.value;
+                                               $('log').value += "> " + send.value + "\n";
+                                               netrap.query(send.value);
+                                       }
+                                       send.value = "";
+                                       return false;
+                               };
+
+                               $('gettemp').observe('click', function() {
+                                       $('log').value += "> M105\n";
+                                       netrap.query("M105");
+                               });
+                               $('turnon').observe('click', function() {
+                                       $('log').value += "> M80\n";
+                                       netrap.query("M80");
+                               });
+                               $('turnoff').observe('click', function() {
+                                       $('log').value += "> M81\n";
+                                       netrap.queueCmd("M81");
+                                       netrap.queueCmd("M84");
+                                       netrap.queueCommit();
+                               });
+
+                               window.setTimeout(refreshPrinterList, 100);
+                       });
+               </script>
+       </body>
+</html>