[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Proposal 132 - Browser Test Service - WIP Patch
Hi there,
This is an update on my work so far on proposal 132. Below is the current state
of the patch, and yes: it's a bit of a monster. (Though a major portion of the
linecount is due to storing the two test images in const char arrays.)
The flow of the browser test procedure has evolved a little since proposal 132
was first drafted, so I've updated and attached a new version.
Here are some videos showing the browser test in action. They show a mixture of
successful and unsuccessful test runs. In the automated test, the browser is
honouring a html refresh tag that redirects it to the next page in the test
sequence.
http://www.youtube.com/profile_videos?user=mwenge2
Areas I know that need work:
- The text and presentation of the html pages.
- A test image with a much lighter footprint.
- Fold the http_ functions into those used by dirserver.c. (Not sure that this
would save an awful lot in linecount though.)
- A test page for javascript, plugins and the like.
Potential issues:
- The Proxy Test uses a randomly generated IP as the 'location' of the test
image. In theory the random IP may have a HTTP service and my be serving an
image with a name such as /CC3B118B056F3A81.png, in which case the test would
produce a false positive. My implementation assumes that this possibility is
vanishingly small. I also assume that the possibility of a genuine user request
using the randomly generated IP while the Proxy Test is in progress is also
sufficiently remote.
For now, I just want to make sure that I haven't gone seriously awry, whether in
concept or implementation. So any feedback on what you see in the videos or
patch below would be greatly appreciated.
Thanks,
Robert
P.S. If you apply the patch, you can try it yourself:
telnet localhost 9051
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
authenticate
250 OK
setconf testserviceport=9999
250 OK
Then load up http://127.0.0.1:9999 in your browser.
Index: src/or/config.c
===================================================================
--- src/or/config.c (revision 16788)
+++ src/or/config.c (working copy)
@@ -302,6 +302,8 @@
V(StrictEntryNodes, BOOL, "0"),
V(StrictExitNodes, BOOL, "0"),
OBSOLETE("SysLog"),
+ V(TestServicePort, UINT, "0"),
+ V(TestServiceListenAddress, LINELIST, NULL),
V(TestSocks, BOOL, "0"),
OBSOLETE("TestVia"),
V(TrackHostExits, CSV, NULL),
@@ -2830,6 +2832,11 @@
if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
REJECT("NatdPort must be defined if NatdListenAddress is defined.");
+ if (options->TestServicePort == 0 &&
+ options->TestServiceListenAddress != NULL)
+ REJECT("TestServicePort must be defined if "
+ "TestServiceListenAddress is defined.");
+
/* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
* configuration does this. */
Index: src/or/connection_edge.c
===================================================================
--- src/or/connection_edge.c (revision 16788)
+++ src/or/connection_edge.c (working copy)
@@ -130,6 +130,15 @@
}
return 0;
case AP_CONN_STATE_OPEN:
+ /* If this is a test request we intercept and respond ourselves */
+ if (testservice_istestrequest(TO_CONN(conn))) {
+ /* (We already sent an end cell if possible) */
+ connection_edge_end(conn, END_STREAM_REASON_INTERNAL);
+ connection_mark_for_close(TO_CONN(conn));
+ return -1;
+ }
+ if (conn->_base.purpose == TEST_PURPOSE_AP)
+ return 0;
case EXIT_CONN_STATE_OPEN:
if (connection_edge_package_raw_inbuf(conn, package_partial) < 0) {
/* (We already sent an end cell if possible) */
@@ -1839,6 +1848,20 @@
return -1;
} /* else socks handshake is done, continue processing */
+ if (testservice_testaddress(socks->address)) {
+ char buf[256];
+ memset(buf,0,SOCKS4_NETWORK_LEN);
+ buf[1] = SOCKS4_GRANTED;
+ /* leave version, destport, destip zero */
+ connection_write_to_buf(buf, SOCKS4_NETWORK_LEN, TO_CONN(conn));
+ conn->socks_request->has_finished = 1;
+ conn->_base.state = AP_CONN_STATE_OPEN;
+ conn->_base.purpose = TEST_PURPOSE_AP;
+ return 0;
+ }
+
+
+
if (hostname_is_noconnect_address(socks->address))
{
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
Index: src/or/or.h
===================================================================
--- src/or/or.h (revision 16788)
+++ src/or/or.h (working copy)
@@ -207,7 +207,9 @@
#define CONN_TYPE_AP_NATD_LISTENER 14
/** Type for sockets listening for DNS requests. */
#define CONN_TYPE_AP_DNS_LISTENER 15
-#define _CONN_TYPE_MAX 15
+#define CONN_TYPE_TEST_SERVICE_LISTENER 16
+#define CONN_TYPE_TEST 17
+#define _CONN_TYPE_MAX 17
/* !!!! If _CONN_TYPE_MAX is ever over 15, we must grow the type field in
* connection_t. */
@@ -305,6 +307,13 @@
#define DIR_CONN_STATE_SERVER_WRITING 6
#define _DIR_CONN_STATE_MAX 6
+#define _TEST_CONN_STATE_MIN 1
+/** State for connection at test service server: waiting for HTTP request. */
+#define TEST_CONN_STATE_SERVER_COMMAND_WAIT 1
+/** State for connection at test service server: sending HTTP response. */
+#define TEST_CONN_STATE_SERVER_WRITING 2
+#define _TEST_CONN_STATE_MAX 2
+
/** True iff the purpose of <b>conn</b> means that it's a server-side
* directory connection. */
#define DIR_CONN_IS_SERVER(conn) ((conn)->purpose == DIR_PURPOSE_SERVER)
@@ -376,6 +385,12 @@
(p)==DIR_PURPOSE_UPLOAD_VOTE || \
(p)==DIR_PURPOSE_UPLOAD_SIGNATURES)
+#define _TEST_PURPOSE_MIN 1
+/** Purpose for connection at a test service server. */
+#define TEST_PURPOSE_SERVER 1
+#define TEST_PURPOSE_AP 2
+#define _TEST_PURPOSE_MAX 2
+
#define _EXIT_PURPOSE_MIN 1
/** This exit stream wants to do an ordinary connect. */
#define EXIT_PURPOSE_CONNECT 1
@@ -790,7 +805,8 @@
typedef struct socks_request_t socks_request_t;
/* Values for connection_t.magic: used to make sure that downcasts (casts from
-* connection_t to foo_connection_t) are safe. */
+* connection_t to foo_connection_t) are safe. These values are arbitrary. They
+ are not calculated or derived, just invented.*/
#define BASE_CONNECTION_MAGIC 0x7C3C304Eu
#define OR_CONNECTION_MAGIC 0x7D31FF03u
#define EDGE_CONNECTION_MAGIC 0xF0374013u
@@ -820,7 +836,7 @@
* *_CONNECTION_MAGIC. */
uint8_t state; /**< Current state of this connection. */
- unsigned int type:4; /**< What kind of connection is this? */
+ unsigned int type:5; /**< What kind of connection is this? */
unsigned int purpose:5; /**< Only used for DIR and EXIT types currently. */
/* The next fields are all one-bit booleans. Some are only applicable to
@@ -2105,6 +2121,8 @@
config_line_t *DirListenAddress;
/** Addresses to bind for listening for control connections. */
config_line_t *ControlListenAddress;
+ /** Addresses to bind for listening for control connections. */
+ config_line_t *TestServiceListenAddress;
/** Local address to bind outbound sockets */
char *OutboundBindAddress;
/** Directory server only: which versions of
@@ -2122,6 +2140,7 @@
int TransPort;
int NatdPort; /**< Port to listen on for transparent natd connections. */
int ControlPort; /**< Port to listen on for control connections. */
+ int TestServicePort; /**< Port to listen on for control connections. */
config_line_t *ControlSocket; /**< List of Unix Domain Sockets to listen on
* for control connections. */
int DirPort; /**< Port to listen on for directory connections. */
@@ -2506,7 +2525,7 @@
state->next_write = when;
}
-#define MAX_SOCKS_REPLY_LEN 1024
+#define MAX_SOCKS_REPLY_LEN 2056
#define MAX_SOCKS_ADDR_LEN 256
/** Please open a TCP connection to this addr:port. */
@@ -2572,6 +2591,7 @@
const char *data, size_t data_len, int done);
int move_buf_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen);
int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
+int buf_startswith(buf_t *buf, char *string, size_t len);
int fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto);
int fetch_from_buf_http(buf_t *buf,
char **headers_out, size_t max_headerlen,
@@ -4344,5 +4364,15 @@
size_t intro_points_encoded_size);
int rend_parse_client_keys(strmap_t *parsed_clients, const char *str);
+/********************************* testservice.c ************************/
+
+int testservice_istestrequest(connection_t *conn);
+int testservice_testaddress(const char *address);
+int testservice_handlebrowserusingtorasproxy(const char *buf,
+ socks_request_t *req);
+int connection_testserv_process_inbuf(connection_t *conn);
+int connection_testserv_finished_flushing(connection_t *conn);
+
#endif
+
Index: src/or/buffers.c
===================================================================
--- src/or/buffers.c (revision 16788)
+++ src/or/buffers.c (working copy)
@@ -962,6 +962,15 @@
}
}
+int
+buf_startswith(buf_t *buf, char *string, size_t len)
+{
+ if (buf->datalen < len) return 0;
+ buf_pullup(buf, len, 0);
+ if (!memcmp(buf->head->data, string, len)) return 1;
+ return 0;
+}
+
/** Remove <b>string_len</b> bytes from the front of <b>buf</b>, and store
* them into <b>string</b>. Return the new buffer size. <b>string_len</b>
* must be \<= the number of bytes on the buffer.
@@ -1574,7 +1583,8 @@
case 'H': /* head */
case 'P': /* put/post */
case 'C': /* connect */
- strlcpy(req->reply,
+ if (!testservice_handlebrowserusingtorasproxy(buf->head->data,req)) {
+ strlcpy(req->reply,
"HTTP/1.0 501 Tor is not an HTTP Proxy\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n\r\n"
"<html>\n"
@@ -1601,6 +1611,7 @@
"</html>\n"
, MAX_SOCKS_REPLY_LEN);
req->replylen = strlen(req->reply)+1;
+ }
/* fall through */
default: /* version is not socks4 or socks5 */
log_warn(LD_APP,
Index: src/or/connection.c
===================================================================
--- src/or/connection.c (revision 16788)
+++ src/or/connection.c (working copy)
@@ -54,9 +54,11 @@
return "Transparent pf/netfilter listener";
case CONN_TYPE_AP_NATD_LISTENER: return "Transparent natd listener";
case CONN_TYPE_AP_DNS_LISTENER: return "DNS listener";
+ case CONN_TYPE_TEST_SERVICE_LISTENER: return "Test Service listener";
case CONN_TYPE_AP: return "Socks";
case CONN_TYPE_DIR_LISTENER: return "Directory listener";
case CONN_TYPE_DIR: return "Directory";
+ case CONN_TYPE_TEST: return "Test";
case CONN_TYPE_CPUWORKER: return "CPU worker";
case CONN_TYPE_CONTROL_LISTENER: return "Control listener";
case CONN_TYPE_CONTROL: return "Control";
@@ -82,6 +84,7 @@
case CONN_TYPE_AP_NATD_LISTENER:
case CONN_TYPE_AP_DNS_LISTENER:
case CONN_TYPE_DIR_LISTENER:
+ case CONN_TYPE_TEST_SERVICE_LISTENER:
case CONN_TYPE_CONTROL_LISTENER:
if (state == LISTENER_STATE_READY)
return "ready";
@@ -130,6 +133,12 @@
case DIR_CONN_STATE_SERVER_WRITING: return "writing";
}
break;
+ case CONN_TYPE_TEST:
+ switch (state) {
+ case TEST_CONN_STATE_SERVER_COMMAND_WAIT: return "waiting for command";
+ case TEST_CONN_STATE_SERVER_WRITING: return "writing";
+ }
+ break;
case CONN_TYPE_CPUWORKER:
switch (state) {
case CPUWORKER_STATE_IDLE: return "idle";
@@ -1176,6 +1185,10 @@
conn->purpose = DIR_PURPOSE_SERVER;
conn->state = DIR_CONN_STATE_SERVER_COMMAND_WAIT;
break;
+ case CONN_TYPE_TEST:
+ conn->purpose = TEST_PURPOSE_SERVER;
+ conn->state = TEST_CONN_STATE_SERVER_COMMAND_WAIT;
+ break;
case CONN_TYPE_CONTROL:
conn->state = CONTROL_CONN_STATE_NEEDAUTH;
break;
@@ -1482,6 +1495,12 @@
replaced_conns, new_conns, 0,
AF_INET)<0)
return -1;
+ if (retry_listeners(CONN_TYPE_TEST_SERVICE_LISTENER,
+ options->TestServiceListenAddress,
+ options->TestServicePort, "127.0.0.1",
+ replaced_conns, new_conns, 0,
+ AF_INET)<0)
+ return -1;
if (retry_listeners(CONN_TYPE_CONTROL_LISTENER,
options->ControlListenAddress,
options->ControlPort, "127.0.0.1",
@@ -1930,6 +1949,8 @@
case CONN_TYPE_AP_TRANS_LISTENER:
case CONN_TYPE_AP_NATD_LISTENER:
return connection_handle_listener_read(conn, CONN_TYPE_AP);
+ case CONN_TYPE_TEST_SERVICE_LISTENER:
+ return connection_handle_listener_read(conn, CONN_TYPE_TEST);
case CONN_TYPE_DIR_LISTENER:
return connection_handle_listener_read(conn, CONN_TYPE_DIR);
case CONN_TYPE_CONTROL_LISTENER:
@@ -2602,6 +2623,7 @@
conn->type == CONN_TYPE_AP_TRANS_LISTENER ||
conn->type == CONN_TYPE_AP_DNS_LISTENER ||
conn->type == CONN_TYPE_AP_NATD_LISTENER ||
+ conn->type == CONN_TYPE_TEST_SERVICE_LISTENER ||
conn->type == CONN_TYPE_DIR_LISTENER ||
conn->type == CONN_TYPE_CONTROL_LISTENER)
return 1;
@@ -2769,6 +2791,8 @@
case CONN_TYPE_AP:
return connection_edge_process_inbuf(TO_EDGE_CONN(conn),
package_partial);
+ case CONN_TYPE_TEST:
+ return connection_testserv_process_inbuf(conn);
case CONN_TYPE_DIR:
return connection_dir_process_inbuf(TO_DIR_CONN(conn));
case CONN_TYPE_CPUWORKER:
@@ -2822,6 +2846,8 @@
case CONN_TYPE_AP:
case CONN_TYPE_EXIT:
return connection_edge_finished_flushing(TO_EDGE_CONN(conn));
+ case CONN_TYPE_TEST:
+ return connection_testserv_finished_flushing(conn);
case CONN_TYPE_DIR:
return connection_dir_finished_flushing(TO_DIR_CONN(conn));
case CONN_TYPE_CPUWORKER:
@@ -3014,7 +3040,8 @@
tor_assert(edge_conn->socks_request);
if (conn->state == AP_CONN_STATE_OPEN) {
tor_assert(edge_conn->socks_request->has_finished != 0);
- if (!conn->marked_for_close) {
+ if ((!conn->marked_for_close) &&
+ (!conn->purpose == TEST_PURPOSE_AP)){
tor_assert(edge_conn->cpath_layer);
assert_cpath_layer_ok(edge_conn->cpath_layer);
}
@@ -3025,6 +3052,7 @@
conn->purpose == EXIT_PURPOSE_RESOLVE);
}
} else if (conn->type == CONN_TYPE_DIR) {
+ } else if (conn->type == CONN_TYPE_TEST) {
} else {
/* Purpose is only used for dir and exit types currently */
tor_assert(!conn->purpose);
@@ -3039,6 +3067,7 @@
case CONN_TYPE_DIR_LISTENER:
case CONN_TYPE_CONTROL_LISTENER:
case CONN_TYPE_AP_DNS_LISTENER:
+ case CONN_TYPE_TEST_SERVICE_LISTENER:
tor_assert(conn->state == LISTENER_STATE_READY);
break;
case CONN_TYPE_OR:
@@ -3057,6 +3086,12 @@
tor_assert(conn->state <= _AP_CONN_STATE_MAX);
tor_assert(TO_EDGE_CONN(conn)->socks_request);
break;
+ case CONN_TYPE_TEST:
+ tor_assert(conn->state >= _TEST_CONN_STATE_MIN);
+ tor_assert(conn->state <= _TEST_CONN_STATE_MAX);
+ tor_assert(conn->purpose >= _TEST_PURPOSE_MIN);
+ tor_assert(conn->purpose <= _TEST_PURPOSE_MAX);
+ break;
case CONN_TYPE_DIR:
tor_assert(conn->state >= _DIR_CONN_STATE_MIN);
tor_assert(conn->state <= _DIR_CONN_STATE_MAX);
Index: src/or/testservice.c
===================================================================
--- src/or/testservice.c (revision 0)
+++ src/or/testservice.c (revision 0)
@@ -0,0 +1,710 @@
+/* Copyright (c) 2008, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+/* $Id: testservice.c $ */
+const char testservice_c_id[] =
+ "$Id: testservice.c $";
+
+#include "or.h"
+#include "testservice.h"
+
+/**
+ * \file testservice.c
+ * \brief Code to serve test html pages to browsers on localhost.
+ **/
+
+/* In-points to testservice.c:
+ *
+ */
+static int testservice_handle_command(connection_t *conn);
+
+/********* START VARIABLES **********/
+
+char *dnsleak_token=NULL, *proxytest_token=NULL, *connectivitytest_token=NULL;
+char *testip=NULL;
+char testpage[2056];
+uint32_t testresult;
+
+/********* END VARIABLES ************/
+char *random_token(int len);
+char *testservice_serve_page(uint32_t pagetype, int showingresult,
+ int automated);
+int random_ip(char **ip);
+char *html_redirectheader(uint32_t pagetype, int showingresult);
+
+/** There is no reason for us to receive a resource request greater than 1K
+ * long.
+ */
+#define MAX_RESOURCE_REQUEST_SIZE (1<<10)
+#define LEN_TOKEN 8
+
+/** Generate a random hexadecimal token of length LEN_TOKEN * 2.
+ * The return value must be freed by the caller.
+ */
+char *
+random_token(int len)
+{
+ char *data;
+ char *output;
+ int hexlen = (len*2);
+
+ output = tor_malloc_zero(hexlen+1);
+ tor_assert(output);
+ data = tor_malloc_zero(len);
+ tor_assert(data);
+ tor_assert(!crypto_seed_rng(0));
+ crypto_rand(data, len);
+ base16_encode(output, hexlen+1, data, len);
+ tor_free(data);
+ return output;
+}
+
+/**
+ * Generate a random, non-local IP address
+ */
+
+int
+random_ip(char **ip)
+{
+ tor_addr_t addr;
+ char tmpip[INET_NTOA_BUF_LEN];
+ uint64_t a;
+
+ repeat:
+ tor_assert(!crypto_seed_rng(0));
+ a = crypto_rand_uint64(UINT64_MAX-1);
+ tor_snprintf(tmpip, sizeof(tmpip), "%d.%d.%d.%d",
+ (int)(uint8_t)((a>>24)&0xff),
+ (int)(uint8_t)((a>>16)&0xff),
+ (int)(uint8_t)((a>>8 )&0xff),
+ (int)(uint8_t)((a )&0xff));
+ tor_addr_from_ipv4h(&addr, a);
+
+ if (is_local_addr(&addr))
+ goto repeat;
+
+ *ip = tor_malloc_zero(sizeof(tmpip));
+ strncpy(*ip,tmpip,sizeof(tmpip));
+ return 0;
+}
+
+/** Read handler for connections to the test service
+ */
+int
+connection_testserv_process_inbuf(connection_t *conn)
+{
+ tor_assert(conn);
+
+ /* Look for a command. */
+ if (conn->state == TEST_CONN_STATE_SERVER_COMMAND_WAIT) {
+ if (testservice_handle_command(conn) < 0) {
+ connection_mark_for_close(conn);
+ return -1;
+ }
+ return 0;
+ }
+
+ if (buf_datalen(conn->inbuf) > MAX_RESOURCE_REQUEST_SIZE) {
+ log_warn(LD_HTTP, "Too much data received from test server connection: "
+ "denial of service attempt, or you need to upgrade?");
+ connection_mark_for_close(conn);
+ return -1;
+ }
+
+ if (!conn->inbuf_reached_eof)
+ log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
+ return 0;
+}
+
+/** Create an http response for the client <b>conn</b> out of
+ * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
+ */
+static void
+write_http_status_line(connection_t *conn, int status,
+ const char *reason_phrase)
+{
+ char buf[256];
+ if (tor_snprintf(buf, sizeof(buf), "HTTP/1.0 %d %s\r\n\r\n",
+ status, reason_phrase ? reason_phrase : "OK") < 0) {
+ log_warn(LD_BUG,"status line too long.");
+ return;
+ }
+ connection_write_to_buf(buf, strlen(buf), conn);
+}
+
+/** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
+ * with <b>type</b> as the Content-Type.
+ *
+ * If <b>length</b> is nonnegative, it is the Content-Length.
+ * If <b>encoding</b> is provided, it is the Content-Encoding.
+ * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
+ * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
+static void
+write_http_response_header_impl(connection_t *conn, ssize_t length,
+ const char *type, const char *encoding,
+ const char *extra_headers,
+ long cache_lifetime)
+{
+ char date[RFC1123_TIME_LEN+1];
+ char tmp[1024];
+ char *cp;
+ time_t now = time(NULL);
+
+ tor_assert(conn);
+
+ format_rfc1123_time(date, now);
+ cp = tmp;
+ tor_snprintf(cp, sizeof(tmp),
+ "HTTP/1.0 200 OK\r\nDate: %s\r\n",
+ date);
+ cp += strlen(tmp);
+ if (type) {
+ tor_snprintf(cp, sizeof(tmp)-(cp-tmp), "Content-Type: %s\r\n", type);
+ cp += strlen(cp);
+ }
+
+ if (encoding) {
+ tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
+ "Content-Encoding: %s\r\n", encoding);
+ cp += strlen(cp);
+ }
+ if (length >= 0) {
+ tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
+ "Content-Length: %ld\r\n", (long)length);
+ cp += strlen(cp);
+ }
+ if (cache_lifetime > 0) {
+ char expbuf[RFC1123_TIME_LEN+1];
+ format_rfc1123_time(expbuf, now + cache_lifetime);
+ /* We could say 'Cache-control: max-age=%d' here if we start doing
+ * http/1.1 */
+ tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
+ "Expires: %s\r\n", expbuf);
+ cp += strlen(cp);
+ } else if (cache_lifetime == 0) {
+ /* We could say 'Cache-control: no-cache' here if we start doing
+ * http/1.1 */
+ strlcpy(cp, "Pragma: no-cache\r\n", sizeof(tmp)-(cp-tmp));
+ cp += strlen(cp);
+ }
+ if (extra_headers)
+ strlcpy(cp, extra_headers, sizeof(tmp)-(cp-tmp));
+ if (sizeof(tmp)-(cp-tmp) > 3)
+ memcpy(cp, "\r\n", 3);
+ else
+ tor_assert(0);
+
+ connection_write_to_buf(tmp, strlen(tmp), conn);
+}
+
+/** Parse an HTTP request string <b>headers</b> of the form
+ * \verbatim
+ * "\%s [http[s]://]\%s HTTP/1..."
+ * \endverbatim
+ * If it's well-formed, strdup the second \%s into *<b>url</b>, and
+ * nul-terminate it. Return 0.
+ * Otherwise, return -1.
+ */
+static int
+parse_http_url(const char *headers, char **url, char **stage, char **method)
+{
+ char *s, *start, *tmp;
+
+ s = (char *)eat_whitespace_no_nl(headers);
+ if (!*s) return -1;
+ s = (char *)find_whitespace(s); /* get past GET/POST */
+ if (!*s) return -1;
+ s = (char *)eat_whitespace_no_nl(s);
+ if (!*s) return -1;
+ start = s; /* this is it, assuming it's valid */
+ s = (char *)find_whitespace(start);
+ if (!*s) return -1;
+
+ /* tolerate the http[s] proxy style of putting the hostname in the url */
+ if (s-start >= 4 && !strcmpstart(start,"http")) {
+ tmp = start + 4;
+ if (*tmp == 's')
+ tmp++;
+ if (s-tmp >= 3 && !strcmpstart(tmp,"://")) {
+ tmp = strchr(tmp+3, '/');
+ if (tmp && tmp < s) {
+ log_debug(LD_DIR,"Skipping over 'http[s]://hostname' string");
+ start = tmp;
+ }
+ }
+ }
+
+ *url = tor_strndup(start, s-start);
+
+ /* Find the name of the next test, if present */
+ tmp = strchr(start, '?');
+ if ((tmp && tmp < s) && !strcmpstart(tmp,"?stage=")) {
+ log_debug(LD_DIR,"Found get method.");
+ start = tmp+7;
+ *stage = tor_strndup(start, s-start);
+ }
+
+ tmp = strchr(start, '&');
+ if ((tmp && tmp < s) && !strcmpstart(tmp,"&method=")) {
+ log_debug(LD_DIR,"Found get method.");
+ start = tmp+8;
+ *method = tor_strndup(start, s-start);
+ }
+
+ return 0;
+}
+
+/** As write_http_response_header_impl, but sets encoding and content-typed
+ * based on whether the response will be <b>compressed</b> or not. */
+static void
+write_http_response_header(connection_t *conn, ssize_t length,
+ int image, long cache_lifetime)
+{
+ write_http_response_header_impl(conn, length,
+ image?"image/png":"text/html",
+ "identity",
+ NULL,
+ cache_lifetime);
+}
+
+/**
+ * Return the html body text for the desired page.
+ */
+
+static const char *
+testservice_find_message(int type, int state, int part)
+{
+ int i;
+ for (i=0; status_messages[i].type; ++i) {
+ if ((status_messages[i].state == state) &&
+ (status_messages[i].type == type)) {
+ if (part == 1)
+ return status_messages[i].htmlpart1;
+ else
+ return status_messages[i].htmlpart2;
+ }
+ }
+ return " ";
+}
+
+/**
+ * Figure out the appropriate html page to serve and retrieve it's body.
+ */
+static int
+testservice_printmessage(char *htmlpart1, char *htmlpart2, size_t msglen,
+ uint32_t type, int showingresult)
+{
+ int result=0;
+
+ switch (type) {
+ case MAIN_PAGE:
+ case END_PAGE:
+ result=TEST_COMPLETE;
+ break;
+ default:
+ if (showingresult)
+ if (testresult & type)
+ result=TEST_SUCCESSFUL;
+ else
+ result=TEST_FAILED;
+ else
+ result=TEST_INPROGRESS;
+ }
+
+ strlcpy(htmlpart1, testservice_find_message(type,result,1),
+ msglen);
+ strlcpy(htmlpart2, testservice_find_message(type,result,2),
+ msglen);
+ return result;
+}
+
+
+/** Helper function: called when a test server gets a complete HTTP GET
+ * request. If the request is unrecognized, send a 400.
+ * Always return 0. */
+static int
+testservice_handle_command_get(connection_t *conn, const char *headers,
+ const char *body, size_t body_len)
+{
+ char *url, *stage=NULL, *method=NULL;
+ int pagetoserve=0, showingresult=0, automated=0;
+
+ /* We ignore the body of a GET request. */
+ (void)body;
+ (void)body_len;
+
+ log_debug(LD_TESTSERV,"Received GET command.");
+
+ conn->state = TEST_CONN_STATE_SERVER_WRITING;
+
+ if (parse_http_url(headers, &url, &stage, &method) < 0) {
+ write_http_status_line(conn, 400, "Bad request");
+ return 0;
+ }
+
+ if (stage)
+ showingresult = (!strncmp("check",stage,5));
+ if (method)
+ automated = (!strcmp("auto",method));
+
+ log_debug(LD_TESTSERV,"rewritten url as '%s'.", url);
+
+ if ((!strcmp(url,"/")) || (!strncmp(url,"/ind",4)))
+ pagetoserve=MAIN_PAGE;
+ else if (!strncmp(url,"/pro",4))
+ pagetoserve=PROXY_TEST;
+ else if (!strncmp(url,"/dns",4))
+ pagetoserve=DNS_TEST;
+ else if (!strncmp(url,"/tor",4))
+ pagetoserve=CONNECTIVITY_TEST;
+ else if (!strncmp(url,"/end",4))
+ pagetoserve=END_PAGE;
+
+ if (pagetoserve) {
+ char *bytes = testservice_serve_page(pagetoserve, showingresult, automated);
+ size_t len = strlen(bytes);
+ write_http_response_header(conn, len, 0, 0);
+ connection_write_to_buf(bytes, len, conn);
+ goto done;
+ }
+
+
+ /* we didn't recognize the url */
+ write_http_status_line(conn, 404, "Not found");
+
+ done:
+ control_event_client_status(LOG_NOTICE,
+ "TESTSERVICE_REQUEST TYPE=MAIN "
+ "RESOURCE=%s",url);
+ tor_free(url);
+ tor_free(stage);
+ tor_free(method);
+
+ return 0;
+}
+
+/** Called when a test server receives data; looks for an HTTP request.
+ * If the request is complete, remove it from the inbuf, try to process it;
+ * otherwise, leave it on the buffer. Return a 0 on success, or -1 on error.
+ */
+static int
+testservice_handle_command(connection_t *conn)
+{
+ char *headers=NULL, *body=NULL;
+ size_t body_len=0;
+ int r;
+
+ tor_assert(conn);
+ tor_assert(conn->type == CONN_TYPE_TEST);
+
+ switch (fetch_from_buf_http(conn->inbuf,
+ &headers, MAX_HEADERS_SIZE,
+ &body, &body_len, MAX_DIR_UL_SIZE, 0)) {
+ case -1: /* overflow */
+ log_warn(LD_TESTSERV,
+ "Invalid input from address '%s'. Closing.",
+ conn->address);
+ return -1;
+ case 0:
+ log_debug(LD_TESTSERV,"command not all here yet.");
+ return 0;
+ /* case 1, fall through */
+ }
+
+ if (!strncasecmp(headers,"GET",3))
+ r = testservice_handle_command_get(conn, headers, body, body_len);
+ else {
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ "Got headers %s with unknown command. Closing.",
+ escaped(headers));
+ r = -1;
+ }
+
+ tor_free(headers); tor_free(body);
+ return r;
+}
+
+/** Write handler for test service connections; called when all data has
+ * been flushed. Close the connection or wait for a response as
+ * appropriate.
+ */
+int
+connection_testserv_finished_flushing(connection_t *conn)
+{
+ tor_assert(conn);
+ tor_assert(conn->type == CONN_TYPE_TEST);
+
+ switch (conn->state) {
+ case TEST_CONN_STATE_SERVER_WRITING:
+ log_debug(LD_TESTSERV,"Finished writing server response. Closing.");
+ connection_mark_for_close(conn);
+ return 0;
+ default:
+ log_warn(LD_BUG,"called in unexpected state %d.",
+ conn->state);
+ tor_fragile_assert();
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * Return the appropriate html Refresh header, or NULL if none is required
+ */
+char *
+html_redirectheader(uint32_t pagetype, int showingresult)
+{
+ char redirecturl[24];
+ char *redirectheader=NULL,*args=NULL;
+
+ args=tor_malloc_zero(32);
+ tor_snprintf(args, 32,"?stage=%s&method=auto",
+ (showingresult)?"test":"check");
+
+ /* We write a redirect header if we are not doing a manual test,
+ have not failed a test, and are not serving a static page */
+ switch (pagetype) {
+ case CONNECTIVITY_TEST:
+ tor_snprintf(redirecturl,sizeof(redirecturl),"%s",
+ (showingresult)?"end.html":"tortest.html");
+ break;
+ case PROXY_TEST:
+ tor_snprintf(redirecturl,sizeof(redirecturl),"%s",
+ (showingresult)?"dnstest.html":"proxy.html");
+ break;
+ case DNS_TEST:
+ tor_snprintf(redirecturl,sizeof(redirecturl),"%s",
+ (showingresult)?"tortest.html":"dnstest.html");
+ break;
+ default:
+ return NULL;
+ }
+
+ redirectheader = tor_malloc_zero(1024);
+ tor_snprintf(redirectheader,1024,
+ "<title>Tor</title><META HTTP-EQUIV='Refresh'"
+ " CONTENT='3; URL=%s%s'></head>",
+ redirecturl,
+ (strcmp(redirecturl,"end.html"))?args:"");
+ tor_free(args);
+
+ return redirectheader;
+}
+
+/**
+ * Serve a web page
+ */
+char *
+testservice_serve_page(uint32_t pagetype, int showingresult, int automated)
+{
+ char testimage[2056];
+ char htmlpart1[2056];
+ char htmlpart2[2056];
+ int continuetesting=0;
+ char *redirectheader=NULL;
+
+ testimage[0]='\0';
+
+ /* Prepare the appropriate test image if this a test page, otherwise
+ reset the test results.*/
+ switch (pagetype) {
+ case MAIN_PAGE:
+ testresult=0;
+ break;
+ case END_PAGE:
+ if ((testresult & PROXY_TEST) &&
+ (testresult & DNS_TEST) &&
+ (testresult & CONNECTIVITY_TEST))
+ strlcpy(testimage,
+ "<div align='center'><h2>Successful!</h2></div>",
+ sizeof(testimage));
+ else
+ strlcpy(testimage,
+ "<div align='center'><h2>A Failure!</h2></div>",
+ sizeof(testimage));
+
+ testresult=0;
+ break;
+ case PROXY_TEST:
+ random_ip(&testip);
+ proxytest_token = random_token(LEN_TOKEN);
+ tor_snprintf(testimage, sizeof(testimage), "<IMG src="
+ "\"http://%s/%s.png\" "
+ "alt=\"If this page finishes loading or takes a long time "
+ "to load and you can still "
+ "see this text, your browser is not "
+ "configured to work with Tor.\" width=\"200\"
height=\"200\" "
+ "align=\"middle\" border=\"2\">\n",
+ testip,proxytest_token);
+ break;
+ case DNS_TEST:
+ dnsleak_token = random_token(LEN_TOKEN);
+ tor_snprintf(testimage, sizeof(testimage), "<IMG src="
+ "\"http://%s/%s.png\""
+ " alt=\"If this page finishes loading and you can still "
+ "see this text, your browser's DNS requests "
+ "are not being routed through Tor.\" width=\"200\" "
+ "height=\"200\" align=\"middle\" border=\"2\">\n",
+ dnsleak_token,dnsleak_token);
+ break;
+ case CONNECTIVITY_TEST:
+ connectivitytest_token = random_token(LEN_TOKEN);
+ tor_snprintf(testimage, sizeof(testimage), "<IMG src="
+ "\"http://roberthogan.net/images/%s-tortest.png\" "
+ "alt=\"If this page finishes loading and you can still "
+ "see this text, your Tor installation "
+ "cannot connect to the Internet.\" width=\"200\" "
+ "height=\"200\" align=\"middle\" border=\"2\">\n",
+ connectivitytest_token);
+ break;
+ default:
+ strlcpy(testpage,errorpage,sizeof(testpage));
+ return testpage;
+ }
+
+
+ /* Prepare the text for the page. If we're about to inform the user of
+ a failed test or if we're at the beginning or end of a test set,
+ then we don't want to write a redirect. */
+ continuetesting = testservice_printmessage(htmlpart1,
+ htmlpart2, sizeof(htmlpart2),
+ pagetype,
+ showingresult);
+
+ if ((continuetesting) && (automated))
+ redirectheader = html_redirectheader(pagetype, showingresult);
+
+ tor_snprintf(testpage,sizeof(testpage),"<HTML>%s<BODY>%s%s%s</BODY></HTML>",
+ (redirectheader)?redirectheader:"",
+ htmlpart1,testimage,htmlpart2);
+
+ tor_free(redirectheader);
+ return testpage;
+}
+
+/**
+ * Is the address in the SOCKS request one embedded in an image resource
+ * served by the test service?
+ */
+int
+testservice_testaddress(const char *address)
+{
+ if ((dnsleak_token) && (!strcasecmp(address,dnsleak_token))) {
+ return 1;
+ }
+
+ if ((testip) && (!strcasecmp(address,testip))) {
+ tor_free(testip);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * If we have received a GET request on the SOCKS Port, serve a warning image.
+ * XXXXX: SOCKS doesn't like responses greater than 2056, so the image served
+ * here should not exceed that.
+ */
+int
+testservice_handlebrowserusingtorasproxy(const char *buf,socks_request_t *req)
+{
+ char proxyrequest[256];
+ char proxyresponse[MAX_SOCKS_REPLY_LEN];
+ size_t len;
+ tor_snprintf(proxyrequest, sizeof(proxyrequest),
+ "GET http://%s/%s.png",testip,proxytest_token);
+ if (!strncmp(buf,proxyrequest,strlen(proxyrequest))) {
+ tor_snprintf(proxyresponse,sizeof(proxyresponse),
+ "HTTP/1.0 200 OK\r\n"
+ "Content-Type: image/png\r\n"
+ "Content-Encoding: identity\r\n"
+ "Content-Length: %i\r\n"
+ "Connection: close\r\n\r\n",
+ sizeof(proxytest_image));
+ len = strlcpy(req->reply,
+ proxyresponse,
+ sizeof(proxyresponse));
+ memcpy(req->reply+len,
+ proxytest_image,
+ sizeof(proxytest_image));
+ req->replylen = ((sizeof(proxytest_image)+len+1) > MAX_SOCKS_REPLY_LEN) ?
+ MAX_SOCKS_REPLY_LEN:(sizeof(proxytest_image)+len+1);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Is the GET request received on Tor's SOCKSPort for a test image? If so
+ * serve it. A return code of 1 tells the caller to close the conn on the
+ * SOCKSPort.
+ */
+int
+testservice_istestrequest(connection_t *conn)
+{
+ char dnsleak_resource[256], proxytest_resource[256];
+ char connectivitytest_resource[256];
+
+ tor_assert(conn);
+ tor_assert(conn->type == CONN_TYPE_AP);
+
+ if ((!dnsleak_token) &&
+ (!proxytest_token) &&
+ (!connectivitytest_token))
+ return 0;
+
+ if (dnsleak_token) {
+ tor_snprintf(dnsleak_resource, sizeof(dnsleak_resource),
+ "GET /%s.png",dnsleak_token);
+ if (buf_startswith(conn->inbuf,dnsleak_resource,25)) {
+ write_http_response_header(conn, sizeof(onion_image), 1, 1);
+ connection_write_to_buf(onion_image, sizeof(onion_image), conn);
+ tor_free(dnsleak_token);
+ dnsleak_token=NULL;
+ testresult = (testresult | DNS_TEST);
+ control_event_client_status(LOG_NOTICE,
+ "TESTSERVICE_REQUEST TYPE=DNS RESOURCE=%s",
+ dnsleak_resource);
+ return 1;
+ }
+ }
+
+ if (proxytest_token) {
+ tor_snprintf(proxytest_resource, sizeof(proxytest_resource),
+ "GET /%s.png",proxytest_token);
+ if (buf_startswith(conn->inbuf,proxytest_resource,25)) {
+ write_http_response_header(conn, sizeof(onion_image), 1, 1);
+ connection_write_to_buf(onion_image, sizeof(onion_image), conn);
+ tor_free(proxytest_token);
+ proxytest_token=NULL;
+ testresult = (testresult | PROXY_TEST);
+ control_event_client_status(LOG_NOTICE,
+ "TESTSERVICE_REQUEST TYPE=PROXY "
+ "RESOURCE=%s",
+ proxytest_resource);
+ return 1;
+ }
+ }
+
+ // If we see the connectivitytest_token it means a circuit has been built
+ // so we send the image back and close the connection.
+ if (connectivitytest_token) {
+ tor_snprintf(connectivitytest_resource, sizeof(connectivitytest_resource),
+ "GET /images/%s-tortest.png", connectivitytest_token);
+ if (buf_startswith(conn->inbuf,connectivitytest_resource,40)) {
+ write_http_response_header(conn, sizeof(onion_image), 1, 1);
+ connection_write_to_buf(onion_image,
+ sizeof(onion_image), conn);
+ tor_free(connectivitytest_token);
+ connectivitytest_token=NULL;
+ testresult = (testresult | CONNECTIVITY_TEST);
+ control_event_client_status(LOG_NOTICE,
+ "TESTSERVICE_REQUEST TYPE=PROXY "
+ "RESOURCE=%s",
+ connectivitytest_resource);
+ return 1;
+ }
+ }
+ return 0;
+}
+
Index: src/or/testservice.h
===================================================================
--- src/or/testservice.h (revision 0)
+++ src/or/testservice.h (revision 0)
@@ -0,0 +1,1066 @@
+/* Copyright (c) 2008, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+/* $Id: or.h 16785 2008-09-05 22:09:44Z nickm $ */
+
+/**
+ * \file testservice.h
+ * \brief Header file for the test service.
+ **/
+#ifndef __TESTSERVICE_H
+#define __TESTSERVICE_H
+#define TESTSERVICE_H_ID "$Id: testservice.h $"
+
+/** The result of the test. */
+#define TEST_COMPLETE 0
+#define TEST_FAILED 0
+#define TEST_SUCCESSFUL 1
+#define TEST_INPROGRESS 2
+
+/** The type of test. */
+#define PROXY_TEST 1
+#define DNS_TEST 2
+#define CONNECTIVITY_TEST 4
+#define MAIN_PAGE 8
+#define END_PAGE 16
+#define SOCKSPROXY_PAGE 32
+
+/** A PNG image of a green onion! */
+const char onion_image[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00,
+0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+0x80, 0x08, 0x06, 0x00, 0x00, 0x00, 0xc3, 0x3e, 0x61, 0xcb, 0x00, 0x00, 0x00,
+0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
+0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x0a, 0x4d, 0x69, 0x43, 0x43, 0x50,
+0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x49, 0x43, 0x43,
+0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x78, 0xda, 0x9d,
+0x53, 0x77, 0x58, 0x93, 0xf7, 0x16, 0x3e, 0xdf, 0xf7, 0x65, 0x0f, 0x56, 0x42,
+0xd8, 0xf0, 0xb1, 0x97, 0x6c, 0x81, 0x00, 0x22, 0x23, 0xac, 0x08, 0xc8, 0x10,
+0x59, 0xa2, 0x10, 0x92, 0x00, 0x61, 0x84, 0x10, 0x12, 0x40, 0xc5, 0x85, 0x88,
+0x0a, 0x56, 0x14, 0x15, 0x11, 0x9c, 0x48, 0x55, 0xc4, 0x82, 0xd5, 0x0a, 0x48,
+0x9d, 0x88, 0xe2, 0xa0, 0x28, 0xb8, 0x67, 0x41, 0x8a, 0x88, 0x5a, 0x8b, 0x55,
+0x5c, 0x38, 0xee, 0x1f, 0xdc, 0xa7, 0xb5, 0x7d, 0x7a, 0xef, 0xed, 0xed, 0xfb,
+0xd7, 0xfb, 0xbc, 0xe7, 0x9c, 0xe7, 0xfc, 0xce, 0x79, 0xcf, 0x0f, 0x80, 0x11,
+0x12, 0x26, 0x91, 0xe6, 0xa2, 0x6a, 0x00, 0x39, 0x52, 0x85, 0x3c, 0x3a, 0xd8,
+0x1f, 0x8f, 0x4f, 0x48, 0xc4, 0xc9, 0xbd, 0x80, 0x02, 0x15, 0x48, 0xe0, 0x04,
+0x20, 0x10, 0xe6, 0xcb, 0xc2, 0x67, 0x05, 0xc5, 0x00, 0x00, 0xf0, 0x03, 0x79,
+0x78, 0x7e, 0x74, 0xb0, 0x3f, 0xfc, 0x01, 0xaf, 0x6f, 0x00, 0x02, 0x00, 0x70,
+0xd5, 0x2e, 0x24, 0x12, 0xc7, 0xe1, 0xff, 0x83, 0xba, 0x50, 0x26, 0x57, 0x00,
+0x20, 0x91, 0x00, 0xe0, 0x22, 0x12, 0xe7, 0x0b, 0x01, 0x90, 0x52, 0x00, 0xc8,
+0x2e, 0x54, 0xc8, 0x14, 0x00, 0xc8, 0x18, 0x00, 0xb0, 0x53, 0xb3, 0x64, 0x0a,
+0x00, 0x94, 0x00, 0x00, 0x6c, 0x79, 0x7c, 0x42, 0x22, 0x00, 0xaa, 0x0d, 0x00,
+0xec, 0xf4, 0x49, 0x3e, 0x05, 0x00, 0xd8, 0xa9, 0x93, 0xdc, 0x17, 0x00, 0xd8,
+0xa2, 0x1c, 0xa9, 0x08, 0x00, 0x8d, 0x01, 0x00, 0x99, 0x28, 0x47, 0x24, 0x02,
+0x40, 0xbb, 0x00, 0x60, 0x55, 0x81, 0x52, 0x2c, 0x02, 0xc0, 0xc2, 0x00, 0xa0,
+0xac, 0x40, 0x22, 0x2e, 0x04, 0xc0, 0xae, 0x01, 0x80, 0x59, 0xb6, 0x32, 0x47,
+0x02, 0x80, 0xbd, 0x05, 0x00, 0x76, 0x8e, 0x58, 0x90, 0x0f, 0x40, 0x60, 0x00,
+0x80, 0x99, 0x42, 0x2c, 0xcc, 0x00, 0x20, 0x38, 0x02, 0x00, 0x43, 0x1e, 0x13,
+0xcd, 0x03, 0x20, 0x4c, 0x03, 0xa0, 0x30, 0xd2, 0xbf, 0xe0, 0xa9, 0x5f, 0x70,
+0x85, 0xb8, 0x48, 0x01, 0x00, 0xc0, 0xcb, 0x95, 0xcd, 0x97, 0x4b, 0xd2, 0x33,
+0x14, 0xb8, 0x95, 0xd0, 0x1a, 0x77, 0xf2, 0xf0, 0xe0, 0xe2, 0x21, 0xe2, 0xc2,
+0x6c, 0xb1, 0x42, 0x61, 0x17, 0x29, 0x10, 0x66, 0x09, 0xe4, 0x22, 0x9c, 0x97,
+0x9b, 0x23, 0x13, 0x48, 0xe7, 0x03, 0x4c, 0xce, 0x0c, 0x00, 0x00, 0x1a, 0xf9,
+0xd1, 0xc1, 0xfe, 0x38, 0x3f, 0x90, 0xe7, 0xe6, 0xe4, 0xe1, 0xe6, 0x66, 0xe7,
+0x6c, 0xef, 0xf4, 0xc5, 0xa2, 0xfe, 0x6b, 0xf0, 0x6f, 0x22, 0x3e, 0x21, 0xf1,
+0xdf, 0xfe, 0xbc, 0x8c, 0x02, 0x04, 0x00, 0x10, 0x4e, 0xcf, 0xef, 0xda, 0x5f,
+0xe5, 0xe5, 0xd6, 0x03, 0x70, 0xc7, 0x01, 0xb0, 0x75, 0xbf, 0x6b, 0xa9, 0x5b,
+0x00, 0xda, 0x56, 0x00, 0x68, 0xdf, 0xf9, 0x5d, 0x33, 0xdb, 0x09, 0xa0, 0x5a,
+0x0a, 0xd0, 0x7a, 0xf9, 0x8b, 0x79, 0x38, 0xfc, 0x40, 0x1e, 0x9e, 0xa1, 0x50,
+0xc8, 0x3c, 0x1d, 0x1c, 0x0a, 0x0b, 0x0b, 0xed, 0x25, 0x62, 0xa1, 0xbd, 0x30,
+0xe3, 0x8b, 0x3e, 0xff, 0x33, 0xe1, 0x6f, 0xe0, 0x8b, 0x7e, 0xf6, 0xfc, 0x40,
+0x1e, 0xfe, 0xdb, 0x7a, 0xf0, 0x00, 0x71, 0x9a, 0x40, 0x99, 0xad, 0xc0, 0xa3,
+0x83, 0xfd, 0x71, 0x61, 0x6e, 0x76, 0xae, 0x52, 0x8e, 0xe7, 0xcb, 0x04, 0x42,
+0x31, 0x6e, 0xf7, 0xe7, 0x23, 0xfe, 0xc7, 0x85, 0x7f, 0xfd, 0x8e, 0x29, 0xd1,
+0xe2, 0x34, 0xb1, 0x5c, 0x2c, 0x15, 0x8a, 0xf1, 0x58, 0x89, 0xb8, 0x50, 0x22,
+0x4d, 0xc7, 0x79, 0xb9, 0x52, 0x91, 0x44, 0x21, 0xc9, 0x95, 0xe2, 0x12, 0xe9,
+0x7f, 0x32, 0xf1, 0x1f, 0x96, 0xfd, 0x09, 0x93, 0x77, 0x0d, 0x00, 0xac, 0x86,
+0x4f, 0xc0, 0x4e, 0xb6, 0x07, 0xb5, 0xcb, 0x6c, 0xc0, 0x7e, 0xee, 0x01, 0x02,
+0x8b, 0x0e, 0x58, 0xd2, 0x76, 0x00, 0x40, 0x7e, 0xf3, 0x2d, 0x8c, 0x1a, 0x0b,
+0x91, 0x00, 0x10, 0x67, 0x34, 0x32, 0x79, 0xf7, 0x00, 0x00, 0x93, 0xbf, 0xf9,
+0x8f, 0x40, 0x2b, 0x01, 0x00, 0xcd, 0x97, 0xa4, 0xe3, 0x00, 0x00, 0xbc, 0xe8,
+0x18, 0x5c, 0xa8, 0x94, 0x17, 0x4c, 0xc6, 0x08, 0x00, 0x00, 0x44, 0xa0, 0x81,
+0x2a, 0xb0, 0x41, 0x07, 0x0c, 0xc1, 0x14, 0xac, 0xc0, 0x0e, 0x9c, 0xc1, 0x1d,
+0xbc, 0xc0, 0x17, 0x02, 0x61, 0x06, 0x44, 0x40, 0x0c, 0x24, 0xc0, 0x3c, 0x10,
+0x42, 0x06, 0xe4, 0x80, 0x1c, 0x0a, 0xa1, 0x18, 0x96, 0x41, 0x19, 0x54, 0xc0,
+0x3a, 0xd8, 0x04, 0xb5, 0xb0, 0x03, 0x1a, 0xa0, 0x11, 0x9a, 0xe1, 0x10, 0xb4,
+0xc1, 0x31, 0x38, 0x0d, 0xe7, 0xe0, 0x12, 0x5c, 0x81, 0xeb, 0x70, 0x17, 0x06,
+0x60, 0x18, 0x9e, 0xc2, 0x18, 0xbc, 0x86, 0x09, 0x04, 0x41, 0xc8, 0x08, 0x13,
+0x61, 0x21, 0x3a, 0x88, 0x11, 0x62, 0x8e, 0xd8, 0x22, 0xce, 0x08, 0x17, 0x99,
+0x8e, 0x04, 0x22, 0x61, 0x48, 0x34, 0x92, 0x80, 0xa4, 0x20, 0xe9, 0x88, 0x14,
+0x51, 0x22, 0xc5, 0xc8, 0x72, 0xa4, 0x02, 0xa9, 0x42, 0x6a, 0x91, 0x5d, 0x48,
+0x23, 0xf2, 0x2d, 0x72, 0x14, 0x39, 0x8d, 0x5c, 0x40, 0xfa, 0x90, 0xdb, 0xc8,
+0x20, 0x32, 0x8a, 0xfc, 0x8a, 0xbc, 0x47, 0x31, 0x94, 0x81, 0xb2, 0x51, 0x03,
+0xd4, 0x02, 0x75, 0x40, 0xb9, 0xa8, 0x1f, 0x1a, 0x8a, 0xc6, 0xa0, 0x73, 0xd1,
+0x74, 0x34, 0x0f, 0x5d, 0x80, 0x96, 0xa2, 0x6b, 0xd1, 0x1a, 0xb4, 0x1e, 0x3d,
+0x80, 0xb6, 0xa2, 0xa7, 0xd1, 0x4b, 0xe8, 0x75, 0x74, 0x00, 0x7d, 0x8a, 0x8e,
+0x63, 0x80, 0xd1, 0x31, 0x0e, 0x66, 0x8c, 0xd9, 0x61, 0x5c, 0x8c, 0x87, 0x45,
+0x60, 0x89, 0x58, 0x1a, 0x26, 0xc7, 0x16, 0x63, 0xe5, 0x58, 0x35, 0x56, 0x8f,
+0x35, 0x63, 0x1d, 0x58, 0x37, 0x76, 0x15, 0x1b, 0xc0, 0x9e, 0x61, 0xef, 0x08,
+0x24, 0x02, 0x8b, 0x80, 0x13, 0xec, 0x08, 0x5e, 0x84, 0x10, 0xc2, 0x6c, 0x82,
+0x90, 0x90, 0x47, 0x58, 0x4c, 0x58, 0x43, 0xa8, 0x25, 0xec, 0x23, 0xb4, 0x12,
+0xba, 0x08, 0x57, 0x09, 0x83, 0x84, 0x31, 0xc2, 0x27, 0x22, 0x93, 0xa8, 0x4f,
+0xb4, 0x25, 0x7a, 0x12, 0xf9, 0xc4, 0x78, 0x62, 0x3a, 0xb1, 0x90, 0x58, 0x46,
+0xac, 0x26, 0xee, 0x21, 0x1e, 0x21, 0x9e, 0x25, 0x5e, 0x27, 0x0e, 0x13, 0x5f,
+0x93, 0x48, 0x24, 0x0e, 0xc9, 0x92, 0xe4, 0x4e, 0x0a, 0x21, 0x25, 0x90, 0x32,
+0x49, 0x0b, 0x49, 0x6b, 0x48, 0xdb, 0x48, 0x2d, 0xa4, 0x53, 0xa4, 0x3e, 0xd2,
+0x10, 0x69, 0x9c, 0x4c, 0x26, 0xeb, 0x90, 0x6d, 0xc9, 0xde, 0xe4, 0x08, 0xb2,
+0x80, 0xac, 0x20, 0x97, 0x91, 0xb7, 0x90, 0x0f, 0x90, 0x4f, 0x92, 0xfb, 0xc9,
+0xc3, 0xe4, 0xb7, 0x14, 0x3a, 0xc5, 0x88, 0xe2, 0x4c, 0x09, 0xa2, 0x24, 0x52,
+0xa4, 0x94, 0x12, 0x4a, 0x35, 0x65, 0x3f, 0xe5, 0x04, 0xa5, 0x9f, 0x32, 0x42,
+0x99, 0xa0, 0xaa, 0x51, 0xcd, 0xa9, 0x9e, 0xd4, 0x08, 0xaa, 0x88, 0x3a, 0x9f,
+0x5a, 0x49, 0x6d, 0xa0, 0x76, 0x50, 0x2f, 0x53, 0x87, 0xa9, 0x13, 0x34, 0x75,
+0x9a, 0x25, 0xcd, 0x9b, 0x16, 0x43, 0xcb, 0xa4, 0x2d, 0xa3, 0xd5, 0xd0, 0x9a,
+0x69, 0x67, 0x69, 0xf7, 0x68, 0x2f, 0xe9, 0x74, 0xba, 0x09, 0xdd, 0x83, 0x1e,
+0x45, 0x97, 0xd0, 0x97, 0xd2, 0x6b, 0xe8, 0x07, 0xe9, 0xe7, 0xe9, 0x83, 0xf4,
+0x77, 0x0c, 0x0d, 0x86, 0x0d, 0x83, 0xc7, 0x48, 0x62, 0x28, 0x19, 0x6b, 0x19,
+0x7b, 0x19, 0xa7, 0x18, 0xb7, 0x19, 0x2f, 0x99, 0x4c, 0xa6, 0x05, 0xd3, 0x97,
+0x99, 0xc8, 0x54, 0x30, 0xd7, 0x32, 0x1b, 0x99, 0x67, 0x98, 0x0f, 0x98, 0x6f,
+0x55, 0x58, 0x2a, 0xf6, 0x2a, 0x7c, 0x15, 0x91, 0xca, 0x12, 0x95, 0x3a, 0x95,
+0x56, 0x95, 0x7e, 0x95, 0xe7, 0xaa, 0x54, 0x55, 0x73, 0x55, 0x3f, 0xd5, 0x79,
+0xaa, 0x0b, 0x54, 0xab, 0x55, 0x0f, 0xab, 0x5e, 0x56, 0x7d, 0xa6, 0x46, 0x55,
+0xb3, 0x50, 0xe3, 0xa9, 0x09, 0xd4, 0x16, 0xab, 0xd5, 0xa9, 0x1d, 0x55, 0xbb,
+0xa9, 0x36, 0xae, 0xce, 0x52, 0x77, 0x52, 0x8f, 0x50, 0xcf, 0x51, 0x5f, 0xa3,
+0xbe, 0x5f, 0xfd, 0x82, 0xfa, 0x63, 0x0d, 0xb2, 0x86, 0x85, 0x46, 0xa0, 0x86,
+0x48, 0xa3, 0x54, 0x63, 0xb7, 0xc6, 0x19, 0x8d, 0x21, 0x16, 0xc6, 0x32, 0x65,
+0xf1, 0x58, 0x42, 0xd6, 0x72, 0x56, 0x03, 0xeb, 0x2c, 0x6b, 0x98, 0x4d, 0x62,
+0x5b, 0xb2, 0xf9, 0xec, 0x4c, 0x76, 0x05, 0xfb, 0x1b, 0x76, 0x2f, 0x7b, 0x4c,
+0x53, 0x43, 0x73, 0xaa, 0x66, 0xac, 0x66, 0x91, 0x66, 0x9d, 0xe6, 0x71, 0xcd,
+0x01, 0x0e, 0xc6, 0xb1, 0xe0, 0xf0, 0x39, 0xd9, 0x9c, 0x4a, 0xce, 0x21, 0xce,
+0x0d, 0xce, 0x7b, 0x2d, 0x03, 0x2d, 0x3f, 0x2d, 0xb1, 0xd6, 0x6a, 0xad, 0x66,
+0xad, 0x7e, 0xad, 0x37, 0xda, 0x7a, 0xda, 0xbe, 0xda, 0x62, 0xed, 0x72, 0xed,
+0x16, 0xed, 0xeb, 0xda, 0xef, 0x75, 0x70, 0x9d, 0x40, 0x9d, 0x2c, 0x9d, 0xf5,
+0x3a, 0x6d, 0x3a, 0xf7, 0x75, 0x09, 0xba, 0x36, 0xba, 0x51, 0xba, 0x85, 0xba,
+0xdb, 0x75, 0xcf, 0xea, 0x3e, 0xd3, 0x63, 0xeb, 0x79, 0xe9, 0x09, 0xf5, 0xca,
+0xf5, 0x0e, 0xe9, 0xdd, 0xd1, 0x47, 0xf5, 0x6d, 0xf4, 0xa3, 0xf5, 0x17, 0xea,
+0xef, 0xd6, 0xef, 0xd1, 0x1f, 0x37, 0x30, 0x34, 0x08, 0x36, 0x90, 0x19, 0x6c,
+0x31, 0x38, 0x63, 0xf0, 0xcc, 0x90, 0x63, 0xe8, 0x6b, 0x98, 0x69, 0xb8, 0xd1,
+0xf0, 0x84, 0xe1, 0xa8, 0x11, 0xcb, 0x68, 0xba, 0x91, 0xc4, 0x68, 0xa3, 0xd1,
+0x49, 0xa3, 0x27, 0xb8, 0x26, 0xee, 0x87, 0x67, 0xe3, 0x35, 0x78, 0x17, 0x3e,
+0x66, 0xac, 0x6f, 0x1c, 0x62, 0xac, 0x34, 0xde, 0x65, 0xdc, 0x6b, 0x3c, 0x61,
+0x62, 0x69, 0x32, 0xdb, 0xa4, 0xc4, 0xa4, 0xc5, 0xe4, 0xbe, 0x29, 0xcd, 0x94,
+0x6b, 0x9a, 0x66, 0xba, 0xd1, 0xb4, 0xd3, 0x74, 0xcc, 0xcc, 0xc8, 0x2c, 0xdc,
+0xac, 0xd8, 0xac, 0xc9, 0xec, 0x8e, 0x39, 0xd5, 0x9c, 0x6b, 0x9e, 0x61, 0xbe,
+0xd9, 0xbc, 0xdb, 0xfc, 0x8d, 0x85, 0xa5, 0x45, 0x9c, 0xc5, 0x4a, 0x8b, 0x36,
+0x8b, 0xc7, 0x96, 0xda, 0x96, 0x7c, 0xcb, 0x05, 0x96, 0x4d, 0x96, 0xf7, 0xac,
+0x98, 0x56, 0x3e, 0x56, 0x79, 0x56, 0xf5, 0x56, 0xd7, 0xac, 0x49, 0xd6, 0x5c,
+0xeb, 0x2c, 0xeb, 0x6d, 0xd6, 0x57, 0x6c, 0x50, 0x1b, 0x57, 0x9b, 0x0c, 0x9b,
+0x3a, 0x9b, 0xcb, 0xb6, 0xa8, 0xad, 0x9b, 0xad, 0xc4, 0x76, 0x9b, 0x6d, 0xdf,
+0x14, 0xe2, 0x14, 0x8f, 0x29, 0xd2, 0x29, 0xf5, 0x53, 0x6e, 0xda, 0x31, 0xec,
+0xfc, 0xec, 0x0a, 0xec, 0x9a, 0xec, 0x06, 0xed, 0x39, 0xf6, 0x61, 0xf6, 0x25,
+0xf6, 0x6d, 0xf6, 0xcf, 0x1d, 0xcc, 0x1c, 0x12, 0x1d, 0xd6, 0x3b, 0x74, 0x3b,
+0x7c, 0x72, 0x74, 0x75, 0xcc, 0x76, 0x6c, 0x70, 0xbc, 0xeb, 0xa4, 0xe1, 0x34,
+0xc3, 0xa9, 0xc4, 0xa9, 0xc3, 0xe9, 0x57, 0x67, 0x1b, 0x67, 0xa1, 0x73, 0x9d,
+0xf3, 0x35, 0x17, 0xa6, 0x4b, 0x90, 0xcb, 0x12, 0x97, 0x76, 0x97, 0x17, 0x53,
+0x6d, 0xa7, 0x8a, 0xa7, 0x6e, 0x9f, 0x7a, 0xcb, 0x95, 0xe5, 0x1a, 0xee, 0xba,
+0xd2, 0xb5, 0xd3, 0xf5, 0xa3, 0x9b, 0xbb, 0x9b, 0xdc, 0xad, 0xd9, 0x6d, 0xd4,
+0xdd, 0xcc, 0x3d, 0xc5, 0x7d, 0xab, 0xfb, 0x4d, 0x2e, 0x9b, 0x1b, 0xc9, 0x5d,
+0xc3, 0x3d, 0xef, 0x41, 0xf4, 0xf0, 0xf7, 0x58, 0xe2, 0x71, 0xcc, 0xe3, 0x9d,
+0xa7, 0x9b, 0xa7, 0xc2, 0xf3, 0x90, 0xe7, 0x2f, 0x5e, 0x76, 0x5e, 0x59, 0x5e,
+0xfb, 0xbd, 0x1e, 0x4f, 0xb3, 0x9c, 0x26, 0x9e, 0xd6, 0x30, 0x6d, 0xc8, 0xdb,
+0xc4, 0x5b, 0xe0, 0xbd, 0xcb, 0x7b, 0x60, 0x3a, 0x3e, 0x3d, 0x65, 0xfa, 0xce,
+0xe9, 0x03, 0x3e, 0xc6, 0x3e, 0x02, 0x9f, 0x7a, 0x9f, 0x87, 0xbe, 0xa6, 0xbe,
+0x22, 0xdf, 0x3d, 0xbe, 0x23, 0x7e, 0xd6, 0x7e, 0x99, 0x7e, 0x07, 0xfc, 0x9e,
+0xfb, 0x3b, 0xfa, 0xcb, 0xfd, 0x8f, 0xf8, 0xbf, 0xe1, 0x79, 0xf2, 0x16, 0xf1,
+0x4e, 0x05, 0x60, 0x01, 0xc1, 0x01, 0xe5, 0x01, 0xbd, 0x81, 0x1a, 0x81, 0xb3,
+0x03, 0x6b, 0x03, 0x1f, 0x04, 0x99, 0x04, 0xa5, 0x07, 0x35, 0x05, 0x8d, 0x05,
+0xbb, 0x06, 0x2f, 0x0c, 0x3e, 0x15, 0x42, 0x0c, 0x09, 0x0d, 0x59, 0x1f, 0x72,
+0x93, 0x6f, 0xc0, 0x17, 0xf2, 0x1b, 0xf9, 0x63, 0x33, 0xdc, 0x67, 0x2c, 0x9a,
+0xd1, 0x15, 0xca, 0x08, 0x9d, 0x15, 0x5a, 0x1b, 0xfa, 0x30, 0xcc, 0x26, 0x4c,
+0x1e, 0xd6, 0x11, 0x8e, 0x86, 0xcf, 0x08, 0xdf, 0x10, 0x7e, 0x6f, 0xa6, 0xf9,
+0x4c, 0xe9, 0xcc, 0xb6, 0x08, 0x88, 0xe0, 0x47, 0x6c, 0x88, 0xb8, 0x1f, 0x69,
+0x19, 0x99, 0x17, 0xf9, 0x7d, 0x14, 0x29, 0x2a, 0x32, 0xaa, 0x2e, 0xea, 0x51,
+0xb4, 0x53, 0x74, 0x71, 0x74, 0xf7, 0x2c, 0xd6, 0xac, 0xe4, 0x59, 0xfb, 0x67,
+0xbd, 0x8e, 0xf1, 0x8f, 0xa9, 0x8c, 0xb9, 0x3b, 0xdb, 0x6a, 0xb6, 0x72, 0x76,
+0x67, 0xac, 0x6a, 0x6c, 0x52, 0x6c, 0x63, 0xec, 0x9b, 0xb8, 0x80, 0xb8, 0xaa,
+0xb8, 0x81, 0x78, 0x87, 0xf8, 0x45, 0xf1, 0x97, 0x12, 0x74, 0x13, 0x24, 0x09,
+0xed, 0x89, 0xe4, 0xc4, 0xd8, 0xc4, 0x3d, 0x89, 0xe3, 0x73, 0x02, 0xe7, 0x6c,
+0x9a, 0x33, 0x9c, 0xe4, 0x9a, 0x54, 0x96, 0x74, 0x63, 0xae, 0xe5, 0xdc, 0xa2,
+0xb9, 0x17, 0xe6, 0xe9, 0xce, 0xcb, 0x9e, 0x77, 0x3c, 0x59, 0x35, 0x59, 0x90,
+0x7c, 0x38, 0x85, 0x98, 0x12, 0x97, 0xb2, 0x3f, 0xe5, 0x83, 0x20, 0x42, 0x50,
+0x2f, 0x18, 0x4f, 0xe5, 0xa7, 0x6e, 0x4d, 0x1d, 0x13, 0xf2, 0x84, 0x9b, 0x85,
+0x4f, 0x45, 0xbe, 0xa2, 0x8d, 0xa2, 0x51, 0xb1, 0xb7, 0xb8, 0x4a, 0x3c, 0x92,
+0xe6, 0x9d, 0x56, 0x95, 0xf6, 0x38, 0xdd, 0x3b, 0x7d, 0x43, 0xfa, 0x68, 0x86,
+0x4f, 0x46, 0x75, 0xc6, 0x33, 0x09, 0x4f, 0x52, 0x2b, 0x79, 0x91, 0x19, 0x92,
+0xb9, 0x23, 0xf3, 0x4d, 0x56, 0x44, 0xd6, 0xde, 0xac, 0xcf, 0xd9, 0x71, 0xd9,
+0x2d, 0x39, 0x94, 0x9c, 0x94, 0x9c, 0xa3, 0x52, 0x0d, 0x69, 0x96, 0xb4, 0x2b,
+0xd7, 0x30, 0xb7, 0x28, 0xb7, 0x4f, 0x66, 0x2b, 0x2b, 0x93, 0x0d, 0xe4, 0x79,
+0xe6, 0x6d, 0xca, 0x1b, 0x93, 0x87, 0xca, 0xf7, 0xe4, 0x23, 0xf9, 0x73, 0xf3,
+0xdb, 0x15, 0x6c, 0x85, 0x4c, 0xd1, 0xa3, 0xb4, 0x52, 0xae, 0x50, 0x0e, 0x16,
+0x4c, 0x2f, 0xa8, 0x2b, 0x78, 0x5b, 0x18, 0x5b, 0x78, 0xb8, 0x48, 0xbd, 0x48,
+0x5a, 0xd4, 0x33, 0xdf, 0x66, 0xfe, 0xea, 0xf9, 0x23, 0x0b, 0x82, 0x16, 0x7c,
+0xbd, 0x90, 0xb0, 0x50, 0xb8, 0xb0, 0xb3, 0xd8, 0xb8, 0x78, 0x59, 0xf1, 0xe0,
+0x22, 0xbf, 0x45, 0xbb, 0x16, 0x23, 0x8b, 0x53, 0x17, 0x77, 0x2e, 0x31, 0x5d,
+0x52, 0xba, 0x64, 0x78, 0x69, 0xf0, 0xd2, 0x7d, 0xcb, 0x68, 0xcb, 0xb2, 0x96,
+0xfd, 0x50, 0xe2, 0x58, 0x52, 0x55, 0xf2, 0x6a, 0x79, 0xdc, 0xf2, 0x8e, 0x52,
+0x83, 0xd2, 0xa5, 0xa5, 0x43, 0x2b, 0x82, 0x57, 0x34, 0x95, 0xa9, 0x94, 0xc9,
+0xcb, 0x6e, 0xae, 0xf4, 0x5a, 0xb9, 0x63, 0x15, 0x61, 0x95, 0x64, 0x55, 0xef,
+0x6a, 0x97, 0xd5, 0x5b, 0x56, 0x7f, 0x2a, 0x17, 0x95, 0x5f, 0xac, 0x70, 0xac,
+0xa8, 0xae, 0xf8, 0xb0, 0x46, 0xb8, 0xe6, 0xe2, 0x57, 0x4e, 0x5f, 0xd5, 0x7c,
+0xf5, 0x79, 0x6d, 0xda, 0xda, 0xde, 0x4a, 0xb7, 0xca, 0xed, 0xeb, 0x48, 0xeb,
+0xa4, 0xeb, 0x6e, 0xac, 0xf7, 0x59, 0xbf, 0xaf, 0x4a, 0xbd, 0x6a, 0x41, 0xd5,
+0xd0, 0x86, 0xf0, 0x0d, 0xad, 0x1b, 0xf1, 0x8d, 0xe5, 0x1b, 0x5f, 0x6d, 0x4a,
+0xde, 0x74, 0xa1, 0x7a, 0x6a, 0xf5, 0x8e, 0xcd, 0xb4, 0xcd, 0xca, 0xcd, 0x03,
+0x35, 0x61, 0x35, 0xed, 0x5b, 0xcc, 0xb6, 0xac, 0xdb, 0xf2, 0xa1, 0x36, 0xa3,
+0xf6, 0x7a, 0x9d, 0x7f, 0x5d, 0xcb, 0x56, 0xfd, 0xad, 0xab, 0xb7, 0xbe, 0xd9,
+0x26, 0xda, 0xd6, 0xbf, 0xdd, 0x77, 0x7b, 0xf3, 0x0e, 0x83, 0x1d, 0x15, 0x3b,
+0xde, 0xef, 0x94, 0xec, 0xbc, 0xb5, 0x2b, 0x78, 0x57, 0x6b, 0xbd, 0x45, 0x7d,
+0xf5, 0x6e, 0xd2, 0xee, 0x82, 0xdd, 0x8f, 0x1a, 0x62, 0x1b, 0xba, 0xbf, 0xe6,
+0x7e, 0xdd, 0xb8, 0x47, 0x77, 0x4f, 0xc5, 0x9e, 0x8f, 0x7b, 0xa5, 0x7b, 0x07,
+0xf6, 0x45, 0xef, 0xeb, 0x6a, 0x74, 0x6f, 0x6c, 0xdc, 0xaf, 0xbf, 0xbf, 0xb2,
+0x09, 0x6d, 0x52, 0x36, 0x8d, 0x1e, 0x48, 0x3a, 0x70, 0xe5, 0x9b, 0x80, 0x6f,
+0xda, 0x9b, 0xed, 0x9a, 0x77, 0xb5, 0x70, 0x5a, 0x2a, 0x0e, 0xc2, 0x41, 0xe5,
+0xc1, 0x27, 0xdf, 0xa6, 0x7c, 0x7b, 0xe3, 0x50, 0xe8, 0xa1, 0xce, 0xc3, 0xdc,
+0xc3, 0xcd, 0xdf, 0x99, 0x7f, 0xb7, 0xf5, 0x08, 0xeb, 0x48, 0x79, 0x2b, 0xd2,
+0x3a, 0xbf, 0x75, 0xac, 0x2d, 0xa3, 0x6d, 0xa0, 0x3d, 0xa1, 0xbd, 0xef, 0xe8,
+0x8c, 0xa3, 0x9d, 0x1d, 0x5e, 0x1d, 0x47, 0xbe, 0xb7, 0xff, 0x7e, 0xef, 0x31,
+0xe3, 0x63, 0x75, 0xc7, 0x35, 0x8f, 0x57, 0x9e, 0xa0, 0x9d, 0x28, 0x3d, 0xf1,
+0xf9, 0xe4, 0x82, 0x93, 0xe3, 0xa7, 0x64, 0xa7, 0x9e, 0x9d, 0x4e, 0x3f, 0x3d,
+0xd4, 0x99, 0xdc, 0x79, 0xf7, 0x4c, 0xfc, 0x99, 0x6b, 0x5d, 0x51, 0x5d, 0xbd,
+0x67, 0x43, 0xcf, 0x9e, 0x3f, 0x17, 0x74, 0xee, 0x4c, 0xb7, 0x5f, 0xf7, 0xc9,
+0xf3, 0xde, 0xe7, 0x8f, 0x5d, 0xf0, 0xbc, 0x70, 0xf4, 0x22, 0xf7, 0x62, 0xdb,
+0x25, 0xb7, 0x4b, 0xad, 0x3d, 0xae, 0x3d, 0x47, 0x7e, 0x70, 0xfd, 0xe1, 0x48,
+0xaf, 0x5b, 0x6f, 0xeb, 0x65, 0xf7, 0xcb, 0xed, 0x57, 0x3c, 0xae, 0x74, 0xf4,
+0x4d, 0xeb, 0x3b, 0xd1, 0xef, 0xd3, 0x7f, 0xfa, 0x6a, 0xc0, 0xd5, 0x73, 0xd7,
+0xf8, 0xd7, 0x2e, 0x5d, 0x9f, 0x79, 0xbd, 0xef, 0xc6, 0xec, 0x1b, 0xb7, 0x6e,
+0x26, 0xdd, 0x1c, 0xb8, 0x25, 0xba, 0xf5, 0xf8, 0x76, 0xf6, 0xed, 0x17, 0x77,
+0x0a, 0xee, 0x4c, 0xdc, 0x5d, 0x7a, 0x8f, 0x78, 0xaf, 0xfc, 0xbe, 0xda, 0xfd,
+0xea, 0x07, 0xfa, 0x0f, 0xea, 0x7f, 0xb4, 0xfe, 0xb1, 0x65, 0xc0, 0x6d, 0xe0,
+0xf8, 0x60, 0xc0, 0x60, 0xcf, 0xc3, 0x59, 0x0f, 0xef, 0x0e, 0x09, 0x87, 0x9e,
+0xfe, 0x94, 0xff, 0xd3, 0x87, 0xe1, 0xd2, 0x47, 0xcc, 0x47, 0xd5, 0x23, 0x46,
+0x23, 0x8d, 0x8f, 0x9d, 0x1f, 0x1f, 0x1b, 0x0d, 0x1a, 0xbd, 0xf2, 0x64, 0xce,
+0x93, 0xe1, 0xa7, 0xb2, 0xa7, 0x13, 0xcf, 0xca, 0x7e, 0x56, 0xff, 0x79, 0xeb,
+0x73, 0xab, 0xe7, 0xdf, 0xfd, 0xe2, 0xfb, 0x4b, 0xcf, 0x58, 0xfc, 0xd8, 0xf0,
+0x0b, 0xf9, 0x8b, 0xcf, 0xbf, 0xae, 0x79, 0xa9, 0xf3, 0x72, 0xef, 0xab, 0xa9,
+0xaf, 0x3a, 0xc7, 0x23, 0xc7, 0x1f, 0xbc, 0xce, 0x79, 0x3d, 0xf1, 0xa6, 0xfc,
+0xad, 0xce, 0xdb, 0x7d, 0xef, 0xb8, 0xef, 0xba, 0xdf, 0xc7, 0xbd, 0x1f, 0x99,
+0x28, 0xfc, 0x40, 0xfe, 0x50, 0xf3, 0xd1, 0xfa, 0x63, 0xc7, 0xa7, 0xd0, 0x4f,
+0xf7, 0x3e, 0xe7, 0x7c, 0xfe, 0xfc, 0x2f, 0xf7, 0x84, 0xf3, 0xfb, 0x25, 0xd2,
+0x9f, 0x33, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1,
+0x8e, 0x7c, 0xfb, 0x51, 0x93, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d,
+0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, 0x83, 0x00, 0x00, 0xf9, 0xff, 0x00,
+0x00, 0x80, 0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00,
+0x3a, 0x98, 0x00, 0x00, 0x17, 0x6f, 0x92, 0x5f, 0xc5, 0x46, 0x00, 0x00, 0x14,
+0x3d, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec, 0x5d, 0x4d, 0x68, 0x23, 0xe7,
+0x96, 0x3d, 0x65, 0x79, 0x64, 0xac, 0x91, 0xb0, 0xa0, 0x8c, 0x9b, 0x32, 0x32,
+0x2e, 0xc8, 0xa3, 0x84, 0x83, 0x1b, 0x6b, 0xa8, 0x95, 0x1b, 0x06, 0xd7, 0x24,
+0xd0, 0x6f, 0x23, 0xd3, 0x9a, 0x34, 0xe4, 0xe1, 0xce, 0xc2, 0xca, 0x62, 0xdc,
+0x64, 0x15, 0xe7, 0xf9, 0xad, 0x1e, 0x6f, 0xb0, 0x1a, 0x86, 0xb7, 0x7a, 0x4e,
+0x34, 0xcb, 0xee, 0x59, 0xb4, 0x7a, 0xf1, 0xdc, 0xd0, 0x90, 0xc4, 0xc1, 0xde,
+0x4c, 0xc0, 0x93, 0xf2, 0xa6, 0x0d, 0x43, 0x44, 0x64, 0x6c, 0xd2, 0xa8, 0x92,
+0x26, 0x65, 0x64, 0xa4, 0xc4, 0xa8, 0x40, 0x8d, 0x14, 0x09, 0x3b, 0xf6, 0xd4,
+0x2c, 0x54, 0x25, 0x97, 0xa4, 0xaa, 0xd2, 0x8f, 0x25, 0x59, 0x3f, 0x75, 0xc1,
+0x74, 0xb7, 0x54, 0x72, 0xdb, 0x3a, 0xe7, 0x9e, 0x7b, 0xee, 0xfd, 0xbe, 0xaf,
+0x44, 0xc8, 0xb2, 0x0c, 0x2b, 0x06, 0x37, 0x86, 0xad, 0xb7, 0xa0, 0x3d, 0xf1,
+0xea, 0xd5, 0x2b, 0x1b, 0x80, 0xff, 0x7b, 0xfb, 0xed, 0xb7, 0xab, 0x32, 0xcc,
+0x28, 0xe9, 0x08, 0x82, 0x30, 0xfd, 0x9e, 0xed, 0x48, 0xd6, 0x21, 0x0b, 0xaa,
+0xf6, 0xc4, 0xcc, 0xcc, 0xcc, 0xe5, 0xcc, 0xcc, 0x8c, 0xfc, 0xed, 0xb7, 0xdf,
+0xae, 0xcb, 0xb2, 0x0c, 0xed, 0x97, 0x19, 0xc0, 0x9d, 0x56, 0x64, 0x4b, 0x01,
+0xda, 0x14, 0xd1, 0x68, 0x74, 0x0e, 0x40, 0x04, 0x40, 0xb0, 0xd1, 0xd7, 0xca,
+0xb2, 0x5c, 0x53, 0x0d, 0x2c, 0x05, 0xe8, 0x6e, 0xf0, 0xd7, 0x01, 0xc4, 0x00,
+0x84, 0x59, 0x96, 0x3d, 0xb0, 0x3c, 0xc0, 0xe0, 0x00, 0x3f, 0x0d, 0x60, 0x0b,
+0x80, 0x0f, 0xc0, 0x2a, 0xcb, 0xb2, 0xcf, 0x9a, 0xfd, 0x5e, 0x95, 0x2a, 0xd0,
+0xae, 0xd2, 0x40, 0x58, 0x5d, 0x40, 0xcb, 0xc0, 0x5f, 0x06, 0x10, 0x06, 0xe0,
+0x06, 0x10, 0x61, 0x59, 0xf6, 0x43, 0x93, 0x6b, 0x17, 0x94, 0xd2, 0x90, 0x61,
+0x59, 0xf6, 0x13, 0x53, 0x80, 0x14, 0x12, 0x58, 0x04, 0xe8, 0x5e, 0xe0, 0xc7,
+0x94, 0x5a, 0x1f, 0x50, 0x1e, 0xda, 0x62, 0x59, 0xf6, 0x5f, 0x4d, 0x48, 0xb2,
+0xaa, 0x28, 0x84, 0x29, 0x49, 0x3a, 0x45, 0x00, 0xab, 0x04, 0x5c, 0xdf, 0xe8,
+0x6d, 0x01, 0xa0, 0x95, 0x87, 0x62, 0x95, 0xa6, 0x4f, 0x21, 0x48, 0x50, 0x01,
+0x5e, 0xbd, 0xae, 0x2e, 0xf0, 0xdb, 0x2d, 0xff, 0x96, 0x02, 0xd4, 0x00, 0xd7,
+0xcc, 0xc0, 0x29, 0xd9, 0x1c, 0xd1, 0x3c, 0x24, 0x02, 0xf0, 0xb1, 0x2c, 0xfb,
+0x46, 0x03, 0xfc, 0xaa, 0xf2, 0xe5, 0xd6, 0x5c, 0x67, 0xa8, 0x10, 0x96, 0x09,
+0xec, 0x1e, 0xf0, 0x3f, 0x06, 0x90, 0x01, 0x70, 0x60, 0xf0, 0xfc, 0xd3, 0x8a,
+0x4c, 0xcf, 0x00, 0x08, 0x68, 0xc0, 0x5f, 0xd7, 0x01, 0x5e, 0x57, 0x21, 0x2c,
+0x02, 0x74, 0x67, 0x4d, 0x0f, 0x69, 0xe4, 0xba, 0xaa, 0xde, 0x27, 0x12, 0x89,
+0xc0, 0xd4, 0xd4, 0x94, 0xf6, 0x29, 0x8e, 0x65, 0xd9, 0x03, 0xc5, 0xdc, 0x45,
+0xf4, 0x5e, 0xab, 0x80, 0xcf, 0xa9, 0x24, 0xb1, 0x08, 0xd0, 0xbd, 0x11, 0x01,
+0x20, 0x56, 0x02, 0x15, 0x8d, 0x46, 0xc7, 0x2e, 0x2e, 0x2e, 0x78, 0x51, 0x14,
+0x7d, 0x6e, 0x77, 0x59, 0x62, 0x07, 0x01, 0x88, 0x3a, 0xaa, 0xd0, 0xf5, 0xe0,
+0x5b, 0x04, 0xd0, 0x6f, 0xcf, 0x02, 0x8a, 0x02, 0x54, 0x81, 0x2f, 0x08, 0x82,
+0xcf, 0x66, 0xb3, 0x61, 0x7c, 0x7c, 0x5c, 0x7d, 0x6a, 0x55, 0x01, 0x37, 0x66,
+0x90, 0xf5, 0x55, 0xe5, 0xa1, 0xdb, 0xc2, 0x9a, 0x04, 0x56, 0x67, 0x3f, 0x14,
+0x67, 0x5f, 0x8a, 0xf3, 0xf3, 0xf3, 0xb0, 0x20, 0x08, 0xbe, 0x42, 0xa1, 0x00,
+0x8d, 0xf4, 0x47, 0x14, 0x70, 0x63, 0xd9, 0x6c, 0x96, 0x16, 0x45, 0x11, 0x17,
+0x17, 0x17, 0x7a, 0xe0, 0x73, 0x2c, 0xcb, 0x1e, 0x77, 0xeb, 0x2f, 0x6c, 0x29,
+0xc0, 0x55, 0x96, 0xaf, 0x2b, 0x59, 0x9c, 0xd1, 0xba, 0xff, 0xfd, 0xfd, 0xfd,
+0xa7, 0x3f, 0xfe, 0xf8, 0x63, 0xb0, 0x50, 0x28, 0x60, 0x62, 0x62, 0x02, 0x0e,
+0x87, 0x43, 0x25, 0x48, 0x26, 0x9f, 0xcf, 0x47, 0x12, 0x89, 0x04, 0x72, 0xb9,
+0x1c, 0xa6, 0xa7, 0xa7, 0x31, 0x3c, 0x3c, 0xac, 0x07, 0xbe, 0x35, 0x0a, 0xee,
+0x11, 0xe3, 0xb7, 0x5a, 0x99, 0xfd, 0xd1, 0x68, 0xf4, 0xe9, 0x4f, 0x3f, 0xfd,
+0x14, 0x2c, 0x14, 0x0a, 0xb0, 0xd9, 0x6c, 0xa0, 0x28, 0x0a, 0x00, 0xc4, 0xdf,
+0x7e, 0xfb, 0x0d, 0x3f, 0xff, 0xfc, 0xf3, 0xea, 0xe9, 0xe9, 0x29, 0x00, 0x80,
+0x24, 0x49, 0x6d, 0x59, 0x28, 0x33, 0x86, 0xdd, 0xfe, 0xbb, 0x5b, 0x04, 0x00,
+0xf0, 0xeb, 0xaf, 0xbf, 0x86, 0x73, 0xb9, 0x9c, 0xfb, 0xd6, 0xad, 0x5b, 0x25,
+0x02, 0x44, 0xa3, 0xd1, 0xcf, 0x44, 0x51, 0x0c, 0xe6, 0x72, 0x39, 0x00, 0x80,
+0xc7, 0xe3, 0xc1, 0xf0, 0xf0, 0x70, 0xe6, 0xe2, 0xe2, 0x02, 0x3f, 0xfc, 0xf0,
+0x43, 0xa0, 0x50, 0x28, 0x00, 0x00, 0x46, 0x47, 0x47, 0x41, 0xd3, 0x55, 0xe5,
+0x3f, 0xd8, 0x0b, 0xe0, 0x03, 0xd6, 0x20, 0x08, 0xd1, 0x68, 0x74, 0x3a, 0x91,
+0x48, 0x88, 0x36, 0x9b, 0x0d, 0x93, 0x93, 0x93, 0x50, 0x7a, 0xf7, 0x40, 0x22,
+0x91, 0x88, 0xa8, 0x19, 0xee, 0x74, 0x3a, 0xe1, 0xf5, 0x7a, 0x91, 0xcd, 0x66,
+0xf1, 0xfa, 0xf5, 0x6b, 0x5c, 0x5e, 0x5e, 0x02, 0x00, 0x6c, 0x36, 0x1b, 0x66,
+0x67, 0x67, 0x2b, 0xa5, 0x3f, 0x78, 0x9d, 0x45, 0x20, 0xcb, 0x04, 0x76, 0x3e,
+0x42, 0x92, 0x24, 0xa9, 0x7f, 0xe7, 0x01, 0x04, 0xd2, 0xe9, 0x74, 0x09, 0x7c,
+0x00, 0x98, 0x9a, 0x9a, 0x42, 0x32, 0x99, 0x84, 0x20, 0x08, 0x25, 0xf0, 0x01,
+0x80, 0x61, 0x98, 0x9e, 0x06, 0x7f, 0xe0, 0x4b, 0x40, 0x34, 0x1a, 0x9d, 0xce,
+0xe7, 0xf3, 0xc1, 0xcb, 0xcb, 0x4b, 0xd8, 0x6c, 0x36, 0xa8, 0xc6, 0xee, 0xe4,
+0xe4, 0xa4, 0x74, 0xcd, 0xc4, 0xc4, 0x04, 0x92, 0xc9, 0x24, 0xde, 0xbc, 0x29,
+0xef, 0xe2, 0xa6, 0xa7, 0xa7, 0x55, 0x43, 0xa8, 0x46, 0xb8, 0xd7, 0xc0, 0xb7,
+0x3c, 0x00, 0x10, 0x54, 0xb3, 0xdf, 0xe1, 0x70, 0xe0, 0xe2, 0xe2, 0x22, 0x20,
+0x8a, 0x62, 0x59, 0x96, 0x4b, 0x92, 0x54, 0xf6, 0x6f, 0x03, 0xd3, 0x17, 0xa9,
+0xb5, 0xac, 0x6b, 0x95, 0x80, 0xee, 0x8c, 0xd5, 0x6c, 0x36, 0x5b, 0xfa, 0x47,
+0x2a, 0x95, 0x82, 0x6a, 0xee, 0xd4, 0xa8, 0x04, 0x5f, 0xc7, 0xf4, 0x35, 0xb4,
+0xb2, 0x67, 0x11, 0xa0, 0x7b, 0xe4, 0xff, 0xde, 0xd9, 0xd9, 0x99, 0x5b, 0x05,
+0x3c, 0x9b, 0xcd, 0x42, 0x5b, 0xf7, 0xf5, 0xc2, 0x66, 0xb3, 0x81, 0x61, 0x18,
+0xed, 0x43, 0x5b, 0xbd, 0x0c, 0xfe, 0xa0, 0x2b, 0x40, 0x20, 0x93, 0xc9, 0x94,
+0x65, 0x7f, 0x3d, 0xe0, 0x6b, 0x4c, 0x5f, 0x0c, 0x5d, 0xb6, 0xb2, 0x67, 0x11,
+0xa0, 0xb1, 0xe0, 0xb4, 0xf2, 0x5f, 0x2b, 0x3c, 0x1e, 0x8f, 0xd6, 0xf4, 0xc5,
+0xd0, 0xa5, 0x8b, 0x3b, 0x16, 0x01, 0xea, 0x74, 0xff, 0x00, 0x68, 0x75, 0xc8,
+0x53, 0x2b, 0x26, 0x26, 0x26, 0xb4, 0xa6, 0xaf, 0x6f, 0xc0, 0x1f, 0x64, 0x05,
+0xe0, 0xf2, 0xf9, 0x7c, 0x95, 0xc1, 0xd3, 0x8b, 0xb1, 0xb1, 0x31, 0xed, 0x02,
+0x50, 0x06, 0x5d, 0xbc, 0xb2, 0x67, 0x11, 0xa0, 0x41, 0x02, 0xd4, 0x8a, 0x0a,
+0xc7, 0x9f, 0x41, 0x97, 0xaf, 0xec, 0x59, 0x04, 0xa8, 0x3f, 0x7c, 0x95, 0xed,
+0x9e, 0x9e, 0xe9, 0x7b, 0xeb, 0xad, 0xb7, 0x54, 0xd3, 0xa7, 0x82, 0x7f, 0xd0,
+0x6f, 0x6f, 0xc4, 0xc0, 0x12, 0xc0, 0x4c, 0x01, 0x54, 0xc7, 0x3f, 0x32, 0x32,
+0x52, 0x52, 0x8c, 0x7e, 0x04, 0x7f, 0x20, 0x09, 0xa0, 0xec, 0xfa, 0x81, 0x99,
+0x01, 0xa4, 0x69, 0x5a, 0xeb, 0xf8, 0x83, 0xfd, 0x0a, 0x7e, 0x5f, 0x12, 0x80,
+0x20, 0x88, 0x69, 0x82, 0x20, 0xc6, 0x4c, 0x2e, 0xa1, 0xcd, 0xb2, 0x9f, 0xa2,
+0x28, 0x68, 0xf6, 0xfc, 0x05, 0x7b, 0x71, 0xbe, 0x3f, 0xe8, 0x0a, 0x20, 0x02,
+0xc8, 0x10, 0x04, 0xf1, 0xd4, 0x80, 0x08, 0x86, 0xf2, 0x3f, 0x36, 0x36, 0xa6,
+0x2e, 0x09, 0x0f, 0x04, 0xf8, 0xfd, 0x4a, 0x80, 0x18, 0xbb, 0x42, 0x61, 0x7a,
+0x61, 0x2c, 0x08, 0x40, 0x24, 0x08, 0xe2, 0xe3, 0x7a, 0x0c, 0xa0, 0xdd, 0x6e,
+0xd7, 0x3a, 0xfe, 0xf0, 0x20, 0x80, 0xdf, 0xaf, 0x04, 0x08, 0xc7, 0xb7, 0x25,
+0xfc, 0x7e, 0xe3, 0x77, 0xf0, 0x3f, 0x66, 0xdc, 0x4e, 0xca, 0x1e, 0x26, 0x08,
+0xe2, 0x1b, 0x82, 0x20, 0xa6, 0xcd, 0x4a, 0x00, 0x4d, 0xd3, 0xaa, 0xe3, 0xef,
+0xd9, 0x95, 0x3d, 0x8b, 0x00, 0x00, 0x64, 0x59, 0x7e, 0x96, 0x4b, 0x9d, 0x8b,
+0xf1, 0xed, 0x34, 0x26, 0x59, 0x17, 0xee, 0x6f, 0xce, 0x80, 0xf1, 0x93, 0x1c,
+0x80, 0x18, 0x41, 0x10, 0xf7, 0xa0, 0x33, 0x01, 0xa4, 0x28, 0x0a, 0x2e, 0x97,
+0x4b, 0x05, 0xff, 0x43, 0x0c, 0x50, 0xf4, 0xe5, 0x96, 0x30, 0x82, 0x20, 0xee,
+0x39, 0x29, 0xfb, 0xd6, 0xfd, 0xcd, 0x19, 0x8c, 0xb8, 0x8a, 0x8b, 0x37, 0x22,
+0x9f, 0x01, 0x1f, 0x12, 0xf1, 0xee, 0x3f, 0xdf, 0xc5, 0xdd, 0xbb, 0x77, 0x4b,
+0x2e, 0x5f, 0xdd, 0xee, 0x85, 0x2e, 0x3b, 0xb3, 0x67, 0x29, 0xc0, 0xf5, 0x54,
+0xe0, 0xab, 0x5c, 0xea, 0x9c, 0x3f, 0x7a, 0x7e, 0xb5, 0xbc, 0x4b, 0x73, 0x6e,
+0xdc, 0xdf, 0x9c, 0xc1, 0xff, 0xbe, 0xe6, 0xb1, 0xb1, 0xb1, 0x81, 0x44, 0x22,
+0x01, 0x9b, 0xcd, 0xa6, 0xd6, 0xfd, 0x18, 0xfa, 0x60, 0x65, 0xcf, 0x52, 0x80,
+0x72, 0x15, 0x58, 0xb0, 0x3b, 0x6d, 0x7c, 0x90, 0xf7, 0x55, 0x3d, 0xf7, 0x72,
+0x23, 0x01, 0x2d, 0x39, 0xa0, 0x1c, 0xf0, 0xa8, 0xb8, 0x8c, 0x97, 0x65, 0xf9,
+0x51, 0xbf, 0x13, 0xa0, 0x6f, 0xb7, 0x84, 0xc9, 0xb2, 0xbc, 0x47, 0x10, 0x04,
+0x1f, 0xdf, 0x4e, 0x73, 0xde, 0xc5, 0xf2, 0x3d, 0xfb, 0x34, 0xe7, 0xc6, 0x51,
+0xf4, 0x14, 0x58, 0x53, 0x1e, 0x88, 0xc0, 0x3d, 0xcf, 0x30, 0xdc, 0x7c, 0xb0,
+0xb8, 0xd9, 0xe3, 0x24, 0x26, 0xe1, 0xc5, 0x27, 0xfb, 0x00, 0x60, 0x11, 0xa0,
+0xc7, 0x23, 0x72, 0xf4, 0xfc, 0xb4, 0x8a, 0x00, 0x55, 0x41, 0x02, 0x24, 0xed,
+0x82, 0x97, 0x9b, 0x1c, 0xb8, 0x12, 0xd0, 0xd7, 0xa3, 0x60, 0x59, 0x96, 0x9f,
+0x49, 0x42, 0x21, 0x93, 0x4d, 0x9e, 0xc1, 0x8a, 0x01, 0x24, 0x80, 0x12, 0x5b,
+0x22, 0x9f, 0xb1, 0x90, 0x1e, 0x60, 0x02, 0xc4, 0x24, 0xa1, 0x60, 0x21, 0x3d,
+0xc8, 0x04, 0xc8, 0xa6, 0xac, 0x12, 0x30, 0xc8, 0x04, 0x70, 0x5b, 0x30, 0x0f,
+0x36, 0x01, 0x38, 0x92, 0x71, 0x34, 0xf4, 0x02, 0x87, 0xdb, 0x0e, 0x14, 0xef,
+0xe5, 0x67, 0x11, 0xa0, 0x0f, 0x22, 0x40, 0x73, 0x8d, 0x89, 0xc0, 0x94, 0x6f,
+0x1c, 0x00, 0xdc, 0x04, 0x41, 0x2c, 0x58, 0x04, 0xe8, 0xe1, 0x20, 0x08, 0x62,
+0xd9, 0x49, 0xd9, 0xe9, 0x49, 0xd6, 0xd5, 0xf0, 0x6b, 0x97, 0x9f, 0x2e, 0x60,
+0x74, 0xcc, 0xce, 0x13, 0x04, 0xb1, 0x6e, 0x11, 0xa0, 0x37, 0xc1, 0x1f, 0x03,
+0x10, 0xe6, 0x42, 0x74, 0xed, 0x8b, 0x49, 0x20, 0xb6, 0x25, 0x96, 0x3d, 0x74,
+0x27, 0xe8, 0xc5, 0x1a, 0xef, 0x87, 0x67, 0x8e, 0x0c, 0x11, 0x04, 0xf1, 0x9d,
+0x66, 0x39, 0xd9, 0x22, 0x40, 0xaf, 0xf4, 0xff, 0x8c, 0x9f, 0x74, 0xd7, 0x95,
+0xfd, 0x77, 0x80, 0x93, 0x13, 0x09, 0x2f, 0x23, 0xf1, 0xaa, 0x52, 0xf0, 0xef,
+0xb1, 0xfb, 0x78, 0xe7, 0xe3, 0x59, 0x1f, 0xae, 0x96, 0x93, 0x2d, 0x02, 0xf4,
+0x40, 0xf6, 0x3f, 0x25, 0x99, 0x51, 0x6e, 0x7e, 0xcd, 0xd3, 0x80, 0xe6, 0x03,
+0x2f, 0x56, 0xf7, 0x91, 0xcf, 0x54, 0xb7, 0x8c, 0x7f, 0x08, 0xdf, 0xc1, 0x47,
+0x5f, 0xde, 0x75, 0x8f, 0x8e, 0xd9, 0xb7, 0x4c, 0xb6, 0x9a, 0x59, 0x04, 0xe8,
+0x06, 0xd9, 0x57, 0xc0, 0x0f, 0xfa, 0x1f, 0x33, 0xa5, 0xbd, 0x00, 0x75, 0x85,
+0x17, 0x28, 0xdc, 0x3a, 0xc7, 0x6e, 0xf8, 0x48, 0xf7, 0x69, 0x5f, 0x80, 0xc6,
+0x5f, 0xc5, 0x25, 0x30, 0x0b, 0x54, 0x10, 0x00, 0x4f, 0x10, 0xc4, 0x9c, 0x45,
+0x80, 0xee, 0x02, 0x7f, 0x1a, 0x00, 0xdf, 0x14, 0xf8, 0x6a, 0xf8, 0x81, 0xdd,
+0xf0, 0xa1, 0xae, 0x0a, 0x14, 0xdb, 0xc3, 0x11, 0xac, 0xf1, 0x8b, 0xf0, 0xaf,
+0xb3, 0x3e, 0x85, 0x04, 0xcb, 0x16, 0x01, 0x6e, 0x1e, 0xf8, 0x05, 0x82, 0x20,
+0xbe, 0x01, 0x20, 0xce, 0x2e, 0x4d, 0xf8, 0xee, 0x6f, 0xbe, 0xdd, 0x1c, 0xf8,
+0x75, 0xa8, 0x80, 0x1a, 0x8b, 0x21, 0x16, 0x7f, 0xfc, 0xc6, 0xef, 0x1e, 0x1d,
+0xb3, 0x47, 0x08, 0x82, 0x78, 0x6a, 0x11, 0xe0, 0x06, 0x81, 0xb7, 0x3b, 0x6d,
+0x3c, 0xbb, 0x42, 0x71, 0xcb, 0xdf, 0xcc, 0xe1, 0xce, 0xda, 0xd4, 0xf5, 0xbf,
+0xb1, 0xa2, 0x02, 0x35, 0xb9, 0xc2, 0x4d, 0xe2, 0xaf, 0xe2, 0x12, 0x3c, 0x73,
+0x64, 0xb0, 0x97, 0xbb, 0x84, 0xa1, 0x1e, 0x04, 0x7e, 0x9a, 0x20, 0x88, 0x2f,
+0x55, 0xe0, 0x97, 0xb6, 0x67, 0xc1, 0xae, 0x4c, 0x36, 0x9f, 0xf5, 0x06, 0x2a,
+0x50, 0xd9, 0x11, 0x18, 0x95, 0x84, 0x8a, 0x2e, 0x61, 0xce, 0x22, 0x40, 0x7b,
+0xc1, 0x5f, 0x07, 0x10, 0x63, 0xfc, 0x64, 0xa0, 0xe5, 0xc0, 0x6b, 0x63, 0x1e,
+0xd8, 0x09, 0x45, 0xeb, 0xbe, 0xfc, 0x0f, 0xe1, 0x3b, 0x58, 0x7e, 0xba, 0xe0,
+0x56, 0x48, 0xb0, 0x6c, 0x11, 0xa0, 0x3d, 0x59, 0xff, 0x1d, 0xc9, 0x8c, 0x86,
+0xfc, 0x8f, 0x19, 0x37, 0x17, 0xa2, 0xdb, 0x03, 0xbc, 0x66, 0x2e, 0x20, 0xe5,
+0x72, 0x88, 0xf3, 0xc9, 0xfa, 0x5f, 0x12, 0xf4, 0xe2, 0x2f, 0xdf, 0xbd, 0x87,
+0x5e, 0xf3, 0x05, 0x43, 0x3d, 0x00, 0xfe, 0x32, 0x80, 0x98, 0x6a, 0xf0, 0x9a,
+0x19, 0xeb, 0x56, 0x46, 0x2a, 0x9a, 0x05, 0x3c, 0xb5, 0x55, 0x60, 0x3f, 0x22,
+0x34, 0xf4, 0x7d, 0xa7, 0x7c, 0xe3, 0xf8, 0x4b, 0xec, 0xbe, 0xea, 0x0b, 0xbe,
+0xec, 0x85, 0x79, 0xc1, 0x50, 0x97, 0x83, 0xff, 0xd4, 0xee, 0xb4, 0x45, 0xfc,
+0x8f, 0x19, 0x77, 0x4b, 0x0c, 0x5e, 0x59, 0x01, 0xaf, 0x83, 0x00, 0xcf, 0x04,
+0xc3, 0x96, 0xd0, 0x28, 0xc6, 0x69, 0x17, 0xd6, 0x78, 0x3f, 0x98, 0x05, 0x2a,
+0xa0, 0xb4, 0x8a, 0x63, 0x16, 0x01, 0x9a, 0x1b, 0xe8, 0x7c, 0x43, 0x32, 0xa3,
+0xc1, 0xfb, 0x9b, 0x33, 0x2d, 0xc9, 0xfa, 0x86, 0x63, 0x1c, 0xc0, 0x5c, 0xe3,
+0x2a, 0xa0, 0x9d, 0x17, 0xcc, 0x2f, 0x33, 0xbe, 0x6e, 0x27, 0xc1, 0x50, 0x37,
+0x82, 0x0f, 0x80, 0x9f, 0x5e, 0x18, 0xe3, 0xfc, 0x8f, 0x19, 0xb8, 0x26, 0x47,
+0xda, 0xf7, 0x9f, 0xa5, 0x01, 0xfc, 0x59, 0xf9, 0xd3, 0xc0, 0x0b, 0xbc, 0x6c,
+0x82, 0x00, 0x6a, 0x04, 0x23, 0x9c, 0x4a, 0x02, 0xb1, 0x5b, 0x3b, 0x84, 0xa1,
+0x6e, 0x04, 0x9f, 0xf1, 0x93, 0xbe, 0xdf, 0x6f, 0xfc, 0xee, 0xda, 0x46, 0x2f,
+0xfa, 0x24, 0x89, 0xff, 0x5e, 0xfb, 0xb1, 0x66, 0x96, 0xe3, 0x85, 0xc1, 0xf3,
+0x3e, 0xe0, 0x44, 0x90, 0x90, 0x88, 0xa5, 0xaf, 0x45, 0x82, 0x77, 0x3e, 0x9e,
+0x75, 0xa3, 0x4b, 0xc7, 0xc7, 0x43, 0xdd, 0x08, 0x7e, 0x5d, 0x4b, 0xb8, 0x66,
+0x89, 0x1d, 0xcf, 0xe3, 0xf3, 0x07, 0xdf, 0x43, 0xe4, 0x33, 0x60, 0x57, 0x6a,
+0xec, 0xf5, 0x5f, 0x04, 0x20, 0xa0, 0xfa, 0x5c, 0x90, 0x86, 0x04, 0xd7, 0x51,
+0x81, 0x8a, 0x36, 0xb1, 0xeb, 0x48, 0x30, 0xd4, 0x6f, 0xe0, 0x47, 0x9f, 0x24,
+0xf1, 0xc5, 0x07, 0xaf, 0x94, 0xb3, 0x80, 0x6f, 0x63, 0xdc, 0xeb, 0xa8, 0x6d,
+0x06, 0xdf, 0x37, 0x57, 0x81, 0x83, 0x8a, 0xbd, 0x02, 0x4d, 0x75, 0x96, 0x41,
+0x6f, 0x57, 0x92, 0xa0, 0x5b, 0x14, 0x20, 0x32, 0xbd, 0x30, 0x76, 0x2d, 0xf0,
+0xcf, 0xb2, 0x17, 0xd8, 0x7e, 0x18, 0x87, 0xc8, 0x67, 0xf0, 0xde, 0xdf, 0x67,
+0x6a, 0x67, 0x7e, 0x45, 0xad, 0x07, 0x09, 0x60, 0x5b, 0x9f, 0x00, 0xd2, 0x69,
+0xee, 0x5a, 0x65, 0x40, 0x4b, 0x82, 0xf9, 0x65, 0xc6, 0x0d, 0x60, 0xab, 0x5b,
+0x8c, 0xe1, 0x50, 0x17, 0x64, 0xff, 0x67, 0x24, 0x33, 0x1a, 0xb8, 0x0e, 0xf8,
+0xc9, 0x68, 0x16, 0xcf, 0x17, 0x8f, 0xe0, 0xa2, 0x46, 0xe0, 0x7f, 0xcc, 0xd4,
+0xce, 0x7a, 0xbd, 0xf0, 0x03, 0xd8, 0x05, 0x90, 0xd7, 0x27, 0x81, 0xc0, 0xa7,
+0x5a, 0xf2, 0xfb, 0x2a, 0xc6, 0x90, 0xee, 0x96, 0xee, 0x60, 0xe8, 0x86, 0xc1,
+0xbf, 0x67, 0x77, 0xda, 0x56, 0xef, 0xfe, 0xed, 0xad, 0xa6, 0x0d, 0x5f, 0xf4,
+0x49, 0x12, 0x3b, 0x0f, 0x05, 0xcc, 0xaf, 0x79, 0x70, 0xad, 0x09, 0xa1, 0x17,
+0x00, 0xa3, 0x90, 0xa0, 0x0d, 0x3e, 0xa0, 0x92, 0x04, 0x73, 0xf7, 0xa6, 0x7d,
+0x28, 0xff, 0xec, 0xe1, 0xc1, 0x22, 0x80, 0xc2, 0xfe, 0x08, 0x17, 0xa2, 0x9b,
+0x6a, 0xf5, 0xce, 0xb2, 0x17, 0xe0, 0x43, 0x22, 0x0e, 0x37, 0x4f, 0xf1, 0xde,
+0xdf, 0x67, 0x50, 0xf3, 0x00, 0x68, 0x3d, 0xf1, 0x3e, 0x80, 0x1d, 0x9d, 0xb6,
+0x90, 0x01, 0x4e, 0x0e, 0xa4, 0x86, 0x87, 0x42, 0xb5, 0x48, 0xe0, 0x99, 0x23,
+0x03, 0x04, 0x41, 0x7c, 0x36, 0xa8, 0x0a, 0x10, 0x61, 0xfc, 0xa4, 0xbb, 0xd1,
+0x2d, 0xdb, 0x2a, 0xf8, 0x3b, 0x0f, 0x05, 0x48, 0x42, 0x1e, 0x4b, 0xdb, 0xb3,
+0xcd, 0x49, 0xbe, 0x51, 0x5b, 0x38, 0xaf, 0x90, 0xa0, 0xd2, 0x28, 0x32, 0xad,
+0x2b, 0x03, 0xea, 0xb0, 0xe8, 0xa3, 0xad, 0xbb, 0x18, 0x1d, 0xb3, 0xaf, 0xde,
+0xe4, 0x5e, 0xc3, 0xa1, 0x1b, 0xca, 0xfe, 0x7b, 0x76, 0xa7, 0x2d, 0xd0, 0xd0,
+0x9e, 0x3d, 0x4d, 0x8b, 0xb7, 0xf3, 0x50, 0x00, 0xc9, 0x38, 0xd0, 0xf4, 0xce,
+0x9f, 0x5a, 0x5e, 0x60, 0x5f, 0xc7, 0x0b, 0x30, 0xd5, 0x3b, 0x87, 0xaf, 0xcd,
+0x37, 0xda, 0x85, 0x60, 0x84, 0x03, 0x80, 0xc8, 0x4d, 0xf9, 0x81, 0x9b, 0x52,
+0x80, 0xf0, 0xfc, 0x9a, 0xa7, 0x61, 0xf0, 0xb4, 0xe0, 0xb7, 0x6d, 0x45, 0x50,
+0x55, 0x81, 0xdd, 0x6a, 0x02, 0x08, 0x0d, 0xac, 0x0e, 0xd6, 0x1b, 0xbe, 0x00,
+0x5d, 0xea, 0x0c, 0x06, 0x82, 0x00, 0x04, 0x41, 0xac, 0x53, 0xac, 0x93, 0x6e,
+0xb4, 0x66, 0xab, 0xe0, 0xdf, 0x7e, 0x30, 0x81, 0xeb, 0xce, 0x0a, 0x6a, 0xc6,
+0xbb, 0x3a, 0x1d, 0x81, 0x17, 0x90, 0x8e, 0x73, 0x2d, 0xf5, 0x01, 0x25, 0xeb,
+0x11, 0x9e, 0x07, 0x39, 0xed, 0xe4, 0x6e, 0xa2, 0x14, 0x0c, 0x75, 0x18, 0xfc,
+0x31, 0x00, 0xab, 0x0d, 0xf5, 0xe8, 0x1a, 0xf0, 0xe7, 0xd7, 0x3c, 0x68, 0xf4,
+0xb5, 0x86, 0x91, 0x30, 0x79, 0x6e, 0x4a, 0xf9, 0x8a, 0xe9, 0xa9, 0x40, 0xaa,
+0xe5, 0xef, 0x8b, 0xc3, 0x3d, 0x82, 0xf7, 0xc3, 0x77, 0x00, 0x20, 0xdc, 0xe9,
+0x52, 0xd0, 0x69, 0x05, 0x58, 0xa5, 0x58, 0xa7, 0xbb, 0x91, 0xd5, 0x3d, 0x15,
+0x7c, 0x76, 0x85, 0x6a, 0xda, 0xe9, 0xeb, 0xde, 0x21, 0xe4, 0xc0, 0x60, 0xf0,
+0xa3, 0x86, 0x9e, 0x19, 0x64, 0x80, 0x44, 0x4c, 0x6a, 0xcb, 0x1b, 0xe3, 0x0b,
+0xd0, 0x60, 0x16, 0x28, 0x1a, 0x57, 0x9f, 0x61, 0xdc, 0x97, 0x04, 0x08, 0x36,
+0x92, 0xc1, 0x67, 0xd9, 0x0b, 0xec, 0x3d, 0x12, 0x41, 0x73, 0x6e, 0xdc, 0x7e,
+0x70, 0xab, 0xa9, 0xff, 0x50, 0xe4, 0x33, 0xf8, 0xfc, 0xc1, 0x2b, 0xa4, 0xe3,
+0x15, 0xae, 0x6e, 0x4e, 0x91, 0x79, 0xa3, 0xad, 0x7f, 0x77, 0x94, 0x12, 0x90,
+0x28, 0x57, 0x86, 0x76, 0xf8, 0x80, 0x92, 0xff, 0x0c, 0xb1, 0xe8, 0x5b, 0x02,
+0x28, 0x37, 0x6f, 0x6c, 0xe8, 0xa0, 0xa6, 0xd6, 0xf0, 0x35, 0x3b, 0x24, 0xe2,
+0x43, 0x22, 0xb8, 0x10, 0x5d, 0xdd, 0x2a, 0x4e, 0xa1, 0xb8, 0x10, 0xf4, 0x0c,
+0xfa, 0xd3, 0x3f, 0xe8, 0x98, 0x41, 0x0f, 0x20, 0xec, 0xa5, 0xda, 0xf6, 0x1e,
+0x79, 0xb9, 0x49, 0x78, 0xe6, 0x48, 0x77, 0x27, 0xf7, 0x15, 0x76, 0x52, 0x01,
+0x82, 0xb7, 0x97, 0x26, 0xea, 0xbe, 0xf8, 0xe5, 0x46, 0x31, 0xf5, 0x9a, 0x69,
+0x15, 0xd5, 0x21, 0x51, 0x7c, 0x5b, 0x82, 0xff, 0x31, 0x03, 0xc3, 0x59, 0xc3,
+0xbb, 0x28, 0xae, 0x01, 0xec, 0x9a, 0xa8, 0x40, 0xac, 0xa2, 0x43, 0x18, 0x05,
+0xd2, 0x62, 0xb6, 0x6d, 0x6f, 0xd2, 0xbb, 0xab, 0xb3, 0x00, 0x10, 0xe8, 0x2b,
+0x02, 0x28, 0xc6, 0x26, 0xc0, 0x2c, 0x92, 0x75, 0xcb, 0xb6, 0xb0, 0x2d, 0xa1,
+0x99, 0x11, 0xb1, 0x76, 0x48, 0x74, 0x7f, 0x73, 0x46, 0x77, 0x48, 0x94, 0x8e,
+0xe7, 0x8b, 0xc0, 0x03, 0xc0, 0x32, 0xf4, 0xa7, 0x7f, 0xaa, 0x4a, 0x38, 0x2a,
+0x48, 0x30, 0x55, 0xbc, 0x8f, 0x60, 0xbb, 0xc2, 0x17, 0xa0, 0xfb, 0x8f, 0x00,
+0x00, 0x02, 0xd3, 0x0b, 0x63, 0x75, 0x81, 0xa9, 0x66, 0x6f, 0x33, 0x23, 0x62,
+0xed, 0x9c, 0xc0, 0xec, 0x84, 0xd0, 0x79, 0xee, 0xf2, 0x8a, 0x00, 0xe3, 0x00,
+0xde, 0xd1, 0x31, 0x7c, 0x5a, 0xaf, 0x10, 0xeb, 0x8c, 0x11, 0x54, 0x3b, 0x02,
+0xcf, 0x1c, 0x89, 0x4e, 0xdd, 0x9c, 0xa2, 0x63, 0x04, 0xa8, 0xb7, 0xf6, 0xf3,
+0x21, 0x11, 0x14, 0xeb, 0x44, 0xa3, 0x23, 0xe2, 0xca, 0x21, 0x51, 0x43, 0xb1,
+0xa8, 0x80, 0x9c, 0x36, 0x28, 0x03, 0xda, 0x75, 0x20, 0x07, 0x5a, 0xb2, 0x34,
+0x6c, 0x16, 0x53, 0x3e, 0x12, 0xe8, 0xd0, 0x2d, 0x6a, 0x3a, 0x45, 0x00, 0xae,
+0x1e, 0x40, 0x93, 0xd1, 0x2c, 0x52, 0xd1, 0x5c, 0xc3, 0x00, 0xaa, 0xe0, 0xd3,
+0x9c, 0xbb, 0x39, 0xc3, 0xe8, 0x50, 0xfc, 0xc0, 0x8e, 0x41, 0x19, 0xc8, 0x6b,
+0xc8, 0xe1, 0x01, 0x0a, 0x99, 0xf3, 0xb6, 0xbe, 0x59, 0x24, 0xed, 0x02, 0x3a,
+0x74, 0x73, 0xab, 0xb6, 0x13, 0x80, 0x20, 0x88, 0x39, 0x27, 0x65, 0x77, 0xd7,
+0x23, 0xe7, 0xd1, 0x27, 0x49, 0xb0, 0x2b, 0x54, 0x43, 0x75, 0xff, 0xda, 0xe0,
+0x6b, 0x1d, 0xff, 0xbe, 0x81, 0x0a, 0x30, 0x1a, 0x15, 0x98, 0x6a, 0x6f, 0x27,
+0xa0, 0x09, 0x77, 0xbf, 0x28, 0x00, 0x47, 0x32, 0xa3, 0x75, 0x65, 0x7f, 0x36,
+0x79, 0xde, 0x50, 0xbf, 0x7f, 0x96, 0xbd, 0xc0, 0xd7, 0x7f, 0x7a, 0x7d, 0x7d,
+0xf0, 0x55, 0x2f, 0xa0, 0x92, 0xa0, 0xaa, 0x3f, 0xd3, 0x10, 0xc0, 0xd1, 0xfe,
+0x37, 0x8c, 0xe1, 0xa8, 0xbe, 0x2a, 0x01, 0x74, 0x3d, 0xcb, 0xb5, 0x87, 0x9b,
+0xbf, 0xc0, 0x5b, 0x67, 0x97, 0xa0, 0x75, 0xfb, 0x93, 0xac, 0xab, 0x75, 0x6b,
+0x03, 0xef, 0x1a, 0x10, 0xc0, 0x03, 0x40, 0xeb, 0xfb, 0x48, 0x34, 0x74, 0x6c,
+0xac, 0x9b, 0xa3, 0x13, 0x04, 0xf0, 0x51, 0x35, 0x0c, 0xe0, 0x59, 0xf6, 0x02,
+0xc7, 0x7b, 0x6f, 0x30, 0xdb, 0xc0, 0x9c, 0x80, 0x0f, 0x89, 0x45, 0x79, 0x69,
+0xe5, 0xc2, 0x90, 0x7a, 0xf8, 0x28, 0xa6, 0xf3, 0xb8, 0x50, 0x4e, 0x80, 0x7e,
+0x89, 0x8e, 0x10, 0xc0, 0x45, 0xd9, 0x4d, 0x2f, 0x48, 0x45, 0x73, 0xa0, 0x58,
+0x67, 0xdd, 0xb5, 0xff, 0x70, 0xf3, 0x17, 0x48, 0x42, 0x01, 0xfe, 0xc7, 0x4c,
+0x1b, 0x26, 0x31, 0x3a, 0x04, 0x70, 0xa0, 0x6f, 0xa3, 0x13, 0x04, 0xa8, 0x69,
+0x00, 0x93, 0xd1, 0x6c, 0xdd, 0xc7, 0xbf, 0xd2, 0xf1, 0x3c, 0xf6, 0x3f, 0x3d,
+0xc1, 0x75, 0xf6, 0x11, 0x02, 0x00, 0x4e, 0x8c, 0x0a, 0x30, 0xf4, 0xcf, 0x08,
+0x78, 0x50, 0xb6, 0x6e, 0xd0, 0xee, 0x4e, 0xa0, 0xdf, 0x06, 0x41, 0xa6, 0x21,
+0x09, 0x79, 0x50, 0x75, 0x12, 0x60, 0xef, 0x91, 0x08, 0x76, 0x85, 0x6a, 0x7a,
+0x1b, 0x58, 0x3a, 0x9e, 0x87, 0x14, 0x2f, 0x14, 0x57, 0x02, 0xf3, 0x06, 0x65,
+0xc0, 0x81, 0xea, 0xe5, 0x62, 0x47, 0xe7, 0x86, 0x41, 0x0a, 0xb9, 0x32, 0x03,
+0x43, 0x80, 0xf3, 0xec, 0x65, 0x5d, 0xd7, 0x45, 0x9f, 0x14, 0x8d, 0x57, 0xb3,
+0x7b, 0x02, 0xd4, 0xd5, 0xc5, 0xf3, 0xdc, 0x65, 0x11, 0xd0, 0x17, 0x0d, 0xaa,
+0x40, 0x87, 0x42, 0x21, 0x57, 0x6c, 0x80, 0x14, 0xa0, 0x80, 0x5a, 0x3e, 0xe1,
+0x2c, 0x7b, 0x81, 0xc3, 0xcd, 0x53, 0xcc, 0x5f, 0xe3, 0x98, 0xf8, 0xfe, 0xc6,
+0x09, 0xec, 0x2e, 0x1b, 0x28, 0xd6, 0x69, 0xbc, 0xf7, 0xaf, 0xb2, 0xef, 0xef,
+0xf3, 0xe8, 0x04, 0x01, 0x62, 0xc9, 0xa8, 0xf9, 0xea, 0x19, 0xc5, 0x3a, 0x91,
+0x4d, 0x99, 0xd7, 0xd4, 0xa3, 0xe7, 0xa7, 0xa0, 0x58, 0x67, 0xd3, 0x47, 0xc5,
+0x45, 0x3e, 0x03, 0x91, 0xcf, 0x80, 0x5b, 0xa7, 0xaf, 0x9c, 0xfc, 0x9c, 0x41,
+0xdb, 0xc7, 0xc0, 0x7c, 0xc7, 0x50, 0x02, 0x20, 0x69, 0x67, 0xdb, 0xde, 0x30,
+0x65, 0xcf, 0x41, 0xdf, 0x28, 0x40, 0xa6, 0x5e, 0x89, 0x37, 0x8b, 0xf8, 0xb6,
+0xd4, 0xf4, 0xa6, 0x10, 0xc3, 0x05, 0xa6, 0x3b, 0xd0, 0x5f, 0x0a, 0x1e, 0x07,
+0x50, 0x80, 0xf1, 0xb1, 0xf1, 0x42, 0x69, 0x5c, 0xdb, 0x96, 0xc8, 0xf7, 0x99,
+0x07, 0xe0, 0x25, 0x21, 0x6f, 0x7a, 0x81, 0x8b, 0x1a, 0x81, 0x14, 0xcf, 0x9b,
+0x66, 0x2f, 0x80, 0xa6, 0xb3, 0x3f, 0xfa, 0x24, 0x05, 0xd2, 0x3b, 0x5a, 0xbd,
+0xc0, 0xe4, 0x43, 0xf5, 0xae, 0x1f, 0xad, 0x0a, 0x68, 0x7d, 0x9e, 0xa0, 0x99,
+0x13, 0xb4, 0x39, 0x4e, 0x0e, 0x24, 0xc8, 0xb2, 0xbc, 0x37, 0x30, 0x25, 0xc0,
+0x35, 0x69, 0x37, 0x2d, 0x01, 0x92, 0x90, 0x47, 0x33, 0x07, 0x48, 0x54, 0xd7,
+0x7f, 0xf4, 0xfc, 0xf4, 0x4a, 0xfa, 0xab, 0xa6, 0x14, 0x06, 0xf5, 0x9e, 0xd4,
+0x69, 0x15, 0xd5, 0x4e, 0x20, 0xdf, 0xbe, 0x37, 0x2b, 0xde, 0x41, 0xf9, 0xef,
+0x18, 0x01, 0xa4, 0x78, 0xa1, 0x86, 0x07, 0x70, 0xc1, 0x4c, 0x25, 0x1a, 0x99,
+0x13, 0x54, 0x19, 0xbf, 0x4f, 0x13, 0x60, 0x57, 0x28, 0xe3, 0xbd, 0x05, 0x3e,
+0x83, 0xb7, 0x9b, 0xd4, 0x00, 0x9d, 0xaf, 0x9e, 0x21, 0xb4, 0xeb, 0x33, 0x06,
+0x95, 0xc3, 0x27, 0x7c, 0xdf, 0x10, 0x40, 0x96, 0xe5, 0xe3, 0xf3, 0xdc, 0xa5,
+0x98, 0x36, 0x91, 0x78, 0x92, 0x19, 0x45, 0x2a, 0x9a, 0x33, 0xfd, 0x3e, 0x76,
+0x97, 0xad, 0xe1, 0xff, 0x3b, 0x19, 0xcd, 0x42, 0x8a, 0x17, 0xcc, 0x47, 0xcc,
+0x66, 0x8e, 0x5f, 0xba, 0x32, 0x7d, 0x60, 0xda, 0x9f, 0xfd, 0x45, 0x03, 0x98,
+0xea, 0x2f, 0x02, 0xa8, 0x3e, 0xe0, 0x78, 0xcf, 0xd8, 0xd3, 0x8c, 0xb8, 0x86,
+0xe1, 0xa4, 0xec, 0xa8, 0x55, 0x2a, 0x1a, 0x8d, 0xc3, 0xcd, 0x5f, 0x70, 0xfb,
+0xc1, 0x84, 0xf9, 0xc4, 0xd0, 0xa1, 0x64, 0x7b, 0xdc, 0xc4, 0x03, 0x14, 0xca,
+0x3b, 0x00, 0x66, 0x81, 0x6a, 0xcb, 0x9b, 0x94, 0x16, 0xb3, 0x38, 0x39, 0x90,
+0x32, 0xb2, 0x2c, 0x7f, 0xd5, 0x6f, 0x04, 0xa8, 0xf9, 0xe1, 0x8d, 0x34, 0xe7,
+0x86, 0xd9, 0x35, 0x8d, 0x76, 0x12, 0xd9, 0xe4, 0x99, 0xe1, 0x02, 0x53, 0xd5,
+0xf7, 0xaa, 0x5c, 0xed, 0xd3, 0x69, 0xfb, 0x4a, 0x0a, 0x70, 0xd2, 0xbe, 0x0e,
+0x40, 0xb9, 0x47, 0xf1, 0x56, 0xbf, 0xcd, 0x01, 0x20, 0xcb, 0xf2, 0x57, 0x92,
+0x50, 0xc8, 0x98, 0x95, 0x81, 0x49, 0xd6, 0x65, 0x48, 0x00, 0x92, 0x71, 0xa0,
+0x56, 0x27, 0xa1, 0xd7, 0x39, 0x30, 0x7e, 0x52, 0x37, 0xfb, 0x25, 0xa1, 0x50,
+0x5c, 0xe3, 0x57, 0x63, 0xaa, 0x0e, 0x02, 0x90, 0x57, 0x7f, 0x57, 0xb6, 0x6c,
+0xb5, 0x3c, 0x94, 0x5b, 0xd1, 0x84, 0xfb, 0x8e, 0x00, 0x4a, 0x44, 0x84, 0x1d,
+0xc9, 0x54, 0x01, 0xce, 0xb3, 0x97, 0xd0, 0x23, 0x89, 0x19, 0x39, 0x0c, 0x09,
+0xb0, 0x97, 0xa9, 0xbf, 0x73, 0x98, 0xd2, 0xf1, 0x01, 0x85, 0x72, 0xd3, 0x57,
+0x22, 0x80, 0x50, 0xda, 0xb0, 0xd1, 0xd2, 0x78, 0x19, 0x89, 0x43, 0x3a, 0xce,
+0xf1, 0xb2, 0x2c, 0x1f, 0xf4, 0x2b, 0x01, 0xc2, 0xc2, 0xb6, 0x84, 0xb3, 0xec,
+0x85, 0xb1, 0x1f, 0x5b, 0x24, 0x71, 0xf4, 0xfc, 0x54, 0xa7, 0x4b, 0x70, 0x42,
+0x12, 0x0a, 0xa6, 0xaf, 0xad, 0xca, 0xf2, 0x78, 0x01, 0xf5, 0xec, 0x44, 0x02,
+0x00, 0x8c, 0x9a, 0xc8, 0x7e, 0x5e, 0x51, 0x07, 0x6f, 0x71, 0x30, 0x34, 0x7a,
+0x61, 0x57, 0x3f, 0x56, 0xae, 0xa5, 0xa1, 0xdc, 0x9c, 0x3a, 0x82, 0x0e, 0x47,
+0xc7, 0x08, 0xa0, 0x74, 0x03, 0xbc, 0x1e, 0xc0, 0x6a, 0xdc, 0x5e, 0x9a, 0x80,
+0xc8, 0x67, 0xaa, 0x80, 0x1e, 0x71, 0x0d, 0x83, 0x62, 0x9d, 0x0d, 0xa9, 0xc0,
+0x79, 0xee, 0xb2, 0xfe, 0x6d, 0xe5, 0x53, 0x26, 0x9d, 0x80, 0xa0, 0xa9, 0xff,
+0x07, 0xed, 0xc9, 0xfe, 0xdd, 0xf0, 0x21, 0xa4, 0xe3, 0x5c, 0x4c, 0x96, 0xe5,
+0x67, 0x7d, 0x4b, 0x00, 0x25, 0x42, 0x87, 0x9b, 0xa7, 0x86, 0x99, 0xec, 0x9a,
+0x1c, 0x01, 0xcd, 0xb9, 0x75, 0x55, 0x80, 0xf1, 0x93, 0x68, 0xdb, 0xa7, 0x80,
+0x3b, 0x0c, 0x80, 0x9f, 0x52, 0xba, 0x03, 0xf5, 0x70, 0x52, 0xbc, 0x74, 0x70,
+0xa3, 0x65, 0x91, 0xcf, 0x9c, 0x61, 0xbb, 0x98, 0xfd, 0xab, 0xb8, 0x81, 0xe8,
+0x28, 0x01, 0x64, 0x59, 0xde, 0x3b, 0xcf, 0x5d, 0x6e, 0x45, 0x9f, 0x18, 0xef,
+0xaa, 0x65, 0x57, 0x28, 0xe8, 0x91, 0x84, 0xe6, 0xdc, 0x38, 0xde, 0x7b, 0xa3,
+0x7f, 0xd2, 0x57, 0x27, 0x9c, 0x94, 0x1d, 0x66, 0xa6, 0xb3, 0x66, 0xa8, 0xc6,
+0x4f, 0xb8, 0x92, 0x7f, 0x1c, 0xb4, 0x9e, 0x00, 0x91, 0x20, 0x8f, 0xc2, 0x9b,
+0xf3, 0x48, 0xa7, 0x46, 0xbf, 0x37, 0xad, 0x00, 0x00, 0xb0, 0x7a, 0xf4, 0xfc,
+0xd4, 0xb0, 0x23, 0x50, 0x55, 0x60, 0x7f, 0xe3, 0xa4, 0xaa, 0x0c, 0x30, 0x7e,
+0x12, 0x66, 0x46, 0xb2, 0x72, 0xb8, 0xd4, 0x68, 0xe7, 0x70, 0xd5, 0x90, 0x6b,
+0xbc, 0xc1, 0x09, 0x8a, 0xd3, 0xc2, 0x03, 0x60, 0xee, 0xde, 0x34, 0x1c, 0xee,
+0xd6, 0xdd, 0xbb, 0xf8, 0x65, 0x24, 0x8e, 0x83, 0xaf, 0x8e, 0x33, 0x37, 0x95,
+0xfd, 0x37, 0x42, 0x00, 0x59, 0x96, 0x8f, 0x01, 0x84, 0xf7, 0x1e, 0x89, 0xa6,
+0x2a, 0x20, 0xf2, 0x99, 0xaa, 0xc1, 0xd0, 0xec, 0xd2, 0x04, 0xcc, 0x4a, 0x48,
+0x65, 0xe7, 0x50, 0x6b, 0xba, 0x68, 0x18, 0x6a, 0xdd, 0x3f, 0x40, 0x71, 0xc9,
+0x18, 0x00, 0x76, 0x8b, 0x37, 0x7a, 0x6c, 0x55, 0x24, 0x62, 0x69, 0xbc, 0x58,
+0xdd, 0x07, 0x80, 0x80, 0x2c, 0xcb, 0x6f, 0x06, 0x86, 0x00, 0x0a, 0x09, 0x1e,
+0x49, 0x42, 0x81, 0x57, 0x4f, 0x00, 0xeb, 0xa9, 0x00, 0xbb, 0x42, 0x81, 0x0f,
+0x89, 0x65, 0x60, 0x8f, 0x7b, 0x1d, 0x20, 0xbd, 0xa3, 0x30, 0x33, 0x92, 0xf5,
+0x0e, 0x96, 0x4c, 0x23, 0xa6, 0xc8, 0xfe, 0x4b, 0x94, 0xd6, 0x0a, 0x48, 0xa7,
+0xb3, 0x65, 0xf2, 0x9f, 0xcf, 0x9c, 0x61, 0x83, 0xdb, 0x41, 0xe1, 0xcd, 0xf9,
+0xea, 0x4d, 0x49, 0xff, 0x8d, 0x12, 0x40, 0x89, 0xc0, 0xd1, 0xf3, 0xd3, 0x4c,
+0x7c, 0x5b, 0x7f, 0xd1, 0xfd, 0xf6, 0x83, 0x5b, 0x70, 0x4d, 0xda, 0xab, 0x4a,
+0x01, 0xb7, 0x4e, 0x23, 0xfa, 0x24, 0x55, 0xd3, 0x0b, 0xb8, 0x26, 0x47, 0xe0,
+0x9a, 0xb4, 0x37, 0x4e, 0x82, 0xbc, 0x92, 0xf9, 0x1e, 0x8d, 0xfc, 0xef, 0x96,
+0x6e, 0xde, 0xd0, 0x4a, 0xf0, 0x23, 0xb2, 0x2c, 0xff, 0x27, 0x6e, 0x38, 0x6e,
+0x8c, 0x00, 0x8a, 0xec, 0x71, 0x7b, 0x8f, 0x8e, 0x0d, 0xcd, 0xda, 0xdd, 0xbf,
+0xbd, 0x05, 0x91, 0xcf, 0x40, 0x4b, 0x12, 0xd7, 0xe4, 0x08, 0x66, 0x97, 0x26,
+0xc0, 0x9b, 0x94, 0x90, 0xb2, 0x92, 0xf1, 0xfc, 0x97, 0xda, 0x3f, 0x8c, 0xd6,
+0xe9, 0xc7, 0x70, 0xb5, 0x40, 0x34, 0x5f, 0x34, 0x83, 0xe4, 0x99, 0xb3, 0x25,
+0xf2, 0xaf, 0x82, 0x7f, 0x72, 0x20, 0x45, 0x64, 0x59, 0xfe, 0x10, 0x5d, 0x10,
+0x37, 0xba, 0x27, 0x50, 0x99, 0x7a, 0x05, 0x77, 0x1e, 0x0a, 0xba, 0x24, 0x18,
+0x71, 0x0d, 0xc3, 0xff, 0x98, 0xc1, 0xfe, 0xc6, 0x49, 0x99, 0x1f, 0x60, 0x57,
+0x28, 0x9c, 0x67, 0x2f, 0x4b, 0x9b, 0x44, 0xcd, 0xca, 0x80, 0x14, 0x2f, 0xd4,
+0x5e, 0x64, 0x92, 0x70, 0x35, 0xe9, 0xdb, 0xc5, 0xd5, 0x9d, 0x41, 0xe6, 0x01,
+0x3c, 0x6b, 0x4d, 0xf6, 0x27, 0x62, 0xe9, 0xae, 0x03, 0xff, 0xc6, 0x09, 0xa0,
+0x90, 0xe0, 0xd9, 0x79, 0xee, 0xd2, 0x90, 0x04, 0xe3, 0x5e, 0x07, 0xe6, 0xd7,
+0x3c, 0xf8, 0x7a, 0xed, 0x75, 0xe9, 0xf9, 0x11, 0xd7, 0x30, 0x16, 0xd6, 0x69,
+0x1c, 0x6e, 0x9e, 0x9a, 0x4a, 0xfc, 0x88, 0x6b, 0x18, 0xb7, 0x1f, 0x4c, 0xd4,
+0x24, 0x0a, 0x12, 0x9a, 0x9e, 0x5f, 0xd2, 0x0c, 0x87, 0x4e, 0x00, 0x8f, 0x87,
+0xbc, 0x76, 0xf6, 0xc7, 0xf9, 0x64, 0x57, 0x82, 0xdf, 0x15, 0x04, 0xd0, 0x92,
+0xe0, 0x8b, 0x0f, 0x5e, 0x41, 0xcf, 0x13, 0x78, 0x17, 0xc7, 0x31, 0xbf, 0xe6,
+0x81, 0x96, 0x24, 0xe3, 0xde, 0xe2, 0x7d, 0x00, 0xf8, 0x90, 0x68, 0xda, 0xef,
+0xcf, 0x2e, 0x4d, 0xd4, 0x56, 0x01, 0xd5, 0xf5, 0xef, 0xe0, 0xea, 0x98, 0x38,
+0x03, 0x60, 0xbb, 0x78, 0x0f, 0xbf, 0xeb, 0xc4, 0x6e, 0xf8, 0x10, 0x9f, 0xfe,
+0xcb, 0x0e, 0x0a, 0x6f, 0xce, 0x83, 0xdd, 0x06, 0x7e, 0xd7, 0x10, 0x40, 0x25,
+0x01, 0x00, 0xdf, 0xde, 0xa3, 0xe3, 0x8c, 0x5e, 0x77, 0xa0, 0x25, 0x81, 0x0a,
+0x26, 0xcd, 0xb9, 0xab, 0x88, 0xa1, 0xa7, 0x02, 0xec, 0x0a, 0x85, 0x7d, 0x83,
+0x8e, 0x03, 0x69, 0x94, 0x6f, 0xfc, 0x70, 0x28, 0xfd, 0xbf, 0x00, 0xbc, 0xb3,
+0x32, 0xdb, 0xf4, 0xce, 0x9f, 0xb4, 0x98, 0xc5, 0x06, 0xb7, 0x8d, 0x17, 0x9f,
+0xec, 0x8b, 0x00, 0x7c, 0x37, 0x31, 0xe6, 0xed, 0x29, 0x02, 0x68, 0x3c, 0x81,
+0xef, 0xe8, 0xf9, 0x69, 0xec, 0xf3, 0x07, 0xdf, 0x57, 0x39, 0x7d, 0x2d, 0x09,
+0x54, 0xa5, 0x50, 0x1f, 0x33, 0x52, 0x0f, 0xb5, 0xa3, 0x00, 0xa0, 0x5f, 0x0a,
+0xf6, 0x15, 0xa7, 0xbf, 0xa3, 0xd4, 0xfc, 0xed, 0xa2, 0x1f, 0x20, 0xcf, 0x9c,
+0x58, 0x6c, 0xb2, 0xf6, 0xef, 0x86, 0x0f, 0xf1, 0x1f, 0xbe, 0xcf, 0x21, 0xec,
+0xa5, 0xc2, 0x0a, 0xf8, 0x07, 0xe8, 0xd2, 0x18, 0xee, 0xb6, 0x1f, 0x48, 0x19,
+0x14, 0xfd, 0x13, 0x41, 0x10, 0xeb, 0x9f, 0x3f, 0x78, 0x15, 0x62, 0x57, 0xa8,
+0xb2, 0xed, 0xe0, 0xde, 0xc5, 0x71, 0x90, 0x8c, 0x43, 0xb9, 0x11, 0x54, 0x01,
+0x77, 0xd6, 0xa6, 0xca, 0x1e, 0x4b, 0x45, 0x73, 0xd0, 0xbb, 0x0f, 0xf1, 0xc2,
+0x3a, 0x8d, 0x2f, 0x3e, 0x78, 0x85, 0xe9, 0x05, 0x77, 0x35, 0x01, 0x3c, 0x15,
+0x46, 0xf0, 0x00, 0xf8, 0xe8, 0xbb, 0xbb, 0x0d, 0x4f, 0xfd, 0xe2, 0x7c, 0x12,
+0xcf, 0x82, 0x3c, 0xa4, 0xe3, 0x9c, 0x08, 0x20, 0x78, 0xd3, 0x3d, 0x7e, 0x3d,
+0x41, 0xc8, 0xb2, 0xdc, 0xbd, 0x3f, 0x5c, 0xf1, 0xb3, 0x75, 0x22, 0x24, 0x33,
+0xea, 0x9b, 0x5f, 0x9b, 0x2a, 0xdb, 0x18, 0x9a, 0x4d, 0x9e, 0xe1, 0xeb, 0x3f,
+0xbd, 0x2e, 0x81, 0x3b, 0xee, 0x75, 0x94, 0xf6, 0xff, 0x4b, 0x42, 0x41, 0xf7,
+0xce, 0xa2, 0xd1, 0x27, 0x49, 0x88, 0x7c, 0xa6, 0xb8, 0x21, 0xe4, 0xb1, 0x32,
+0xe8, 0x51, 0x8f, 0x87, 0xcd, 0x03, 0xf8, 0x9f, 0xe2, 0x5f, 0x97, 0x9f, 0x2e,
+0x34, 0x64, 0xfc, 0xe2, 0x7c, 0x12, 0x3b, 0xa1, 0x28, 0x84, 0xbd, 0x54, 0x06,
+0x40, 0xa8, 0x1b, 0xfa, 0xfb, 0xbe, 0x20, 0x80, 0x86, 0x08, 0xcb, 0x00, 0x42,
+0x14, 0xeb, 0xa4, 0xd9, 0x95, 0xc9, 0x32, 0x22, 0x44, 0x9f, 0x24, 0x71, 0xb8,
+0x79, 0x0a, 0xad, 0x52, 0x24, 0xa3, 0xd9, 0xd2, 0xfd, 0x03, 0xd8, 0x15, 0x0a,
+0x34, 0xe7, 0x2e, 0x29, 0xc2, 0xe7, 0x0f, 0xbe, 0xbf, 0x22, 0xc0, 0x9f, 0x95,
+0xcc, 0x57, 0xf7, 0xff, 0x49, 0xc0, 0xfc, 0x32, 0xa3, 0xde, 0xc2, 0xbd, 0x66,
+0xbc, 0x8c, 0xc4, 0xb1, 0x1b, 0x3e, 0xc2, 0xc9, 0x81, 0x94, 0x41, 0x71, 0x27,
+0x4f, 0xf8, 0x26, 0xc7, 0xba, 0x7d, 0x4b, 0x00, 0x85, 0x04, 0x63, 0x28, 0x2e,
+0x9a, 0x04, 0x49, 0x66, 0x94, 0x9e, 0x5d, 0x9a, 0x28, 0x65, 0x78, 0x3a, 0x9e,
+0x87, 0xba, 0xb6, 0xa0, 0x55, 0x8a, 0xf8, 0x76, 0x1a, 0xc2, 0x8e, 0x04, 0x29,
+0x5e, 0x00, 0xcd, 0xb9, 0x41, 0xb1, 0x4e, 0xb8, 0x26, 0x47, 0xb0, 0xf3, 0x50,
+0x28, 0x9e, 0x0d, 0xdc, 0x51, 0x0c, 0x9f, 0xb2, 0x1f, 0xa0, 0x1e, 0xf0, 0xd3,
+0x62, 0x16, 0xbb, 0xe1, 0x43, 0xec, 0x47, 0x04, 0x14, 0xde, 0x9c, 0x8b, 0x00,
+0x42, 0x00, 0xb6, 0x7a, 0x0d, 0xf8, 0x9e, 0x23, 0x80, 0x8e, 0x22, 0xac, 0xda,
+0x9d, 0x36, 0x1f, 0xcd, 0xb9, 0x31, 0xbb, 0x34, 0x81, 0x71, 0xaf, 0x03, 0x87,
+0x9b, 0xbf, 0x20, 0xfa, 0x24, 0x05, 0x8a, 0x75, 0xe2, 0xce, 0xda, 0x54, 0x69,
+0x43, 0x48, 0x36, 0x79, 0x56, 0x5a, 0x5c, 0x4a, 0x45, 0x73, 0xc5, 0xd3, 0xc1,
+0x6a, 0x28, 0x23, 0x5f, 0x33, 0xf0, 0xd3, 0x62, 0x16, 0x07, 0x5b, 0x22, 0x5e,
+0x46, 0x04, 0x35, 0xdb, 0xb7, 0x00, 0x44, 0x7a, 0xa1, 0xc6, 0xf7, 0x25, 0x01,
+0x34, 0x44, 0x98, 0x56, 0x54, 0x21, 0xa0, 0xde, 0x87, 0x58, 0xdd, 0x3e, 0x26,
+0x6c, 0x4b, 0xa0, 0x39, 0x37, 0x98, 0x45, 0xb2, 0xac, 0x64, 0x24, 0xa3, 0xd9,
+0xa2, 0x02, 0x98, 0x80, 0x9f, 0xcf, 0x9c, 0x41, 0xe0, 0x53, 0x88, 0xf3, 0x49,
+0x1c, 0x6c, 0x89, 0x90, 0x8e, 0x73, 0x19, 0x14, 0xf7, 0xea, 0x6f, 0xf5, 0x72,
+0xb6, 0xf7, 0x1d, 0x01, 0x74, 0x0c, 0x23, 0x87, 0xe2, 0x6d, 0x56, 0x39, 0x27,
+0x65, 0x47, 0x4e, 0x39, 0x6e, 0x46, 0x32, 0xa3, 0x98, 0x5d, 0x9a, 0x28, 0x8e,
+0x86, 0x85, 0xc2, 0x15, 0x01, 0x00, 0xbc, 0xf3, 0xf1, 0x2c, 0x7c, 0x01, 0x1a,
+0x27, 0x31, 0x09, 0x89, 0x98, 0x04, 0x81, 0x4f, 0x42, 0x3a, 0xce, 0x01, 0xc5,
+0x55, 0x01, 0x5e, 0x01, 0x7c, 0x0f, 0x7d, 0x1a, 0x7d, 0x43, 0x00, 0x1d, 0x42,
+0x2c, 0x28, 0x1d, 0xbe, 0x0f, 0x00, 0xad, 0x90, 0x03, 0x5a, 0x62, 0x68, 0x82,
+0x07, 0x20, 0x2a, 0xa0, 0xc7, 0xba, 0x1d, 0xf0, 0x7f, 0x1b, 0x1e, 0x26, 0xfe,
+0xeb, 0xe2, 0xa2, 0x25, 0xc0, 0x0d, 0xf7, 0x2b, 0xb3, 0x15, 0x10, 0xf7, 0x0c,
+0x88, 0xa1, 0x46, 0xac, 0x17, 0xe5, 0x5c, 0x96, 0xe5, 0x7f, 0x00, 0x70, 0x6e,
+0x11, 0xa0, 0x79, 0x62, 0xf4, 0xfa, 0xef, 0xf0, 0x8f, 0xad, 0x22, 0x40, 0xdf,
+0x96, 0x00, 0x2b, 0xea, 0x8b, 0xff, 0x1f, 0x00, 0xcc, 0x76, 0x1f, 0x47, 0xd4,
+0x27, 0x0e, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
+0x60, 0x82 };
+
+/** A PNG image stating that using Tor as HTTP Proxy is wrong! */
+const char proxytest_image[] = {
+0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00,
+0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
+0xc8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x88, 0x33, 0xf1, 0x42, 0x00, 0x00, 0x00,
+0x01, 0x73, 0x52, 0x47, 0x42, 0x03, 0x37, 0xc7, 0x4d, 0x53, 0x00, 0x00, 0x00,
+0xcb, 0x69, 0x43, 0x43, 0x50, 0x69, 0x63, 0x63, 0x00, 0x00, 0x78, 0xda, 0x63,
+0x60, 0x60, 0xd2, 0xca, 0x49, 0xce, 0x2d, 0x66, 0x32, 0x60, 0x60, 0xc8, 0xcd,
+0x2b, 0x29, 0x72, 0x0f, 0x72, 0x8c, 0x8c, 0x88, 0x8c, 0x52, 0x60, 0xbf, 0xc1,
+0xc0, 0xc9, 0xc0, 0xce, 0xc0, 0xc7, 0xc0, 0xcd, 0xa0, 0x90, 0x98, 0x5c, 0x5c,
+0xe0, 0x18, 0x10, 0xe0, 0xc3, 0x00, 0x04, 0x20, 0xb5, 0x0c, 0x18, 0xe0, 0xdb,
+0x35, 0x06, 0x46, 0x10, 0x7d, 0x59, 0x17, 0xbb, 0x3c, 0x5e, 0xc0, 0x9a, 0x92,
+0x9b, 0x97, 0x02, 0xa4, 0x0f, 0x00, 0x71, 0x56, 0x4a, 0x6a, 0x71, 0x32, 0x03,
+0x03, 0xa3, 0x0e, 0x90, 0x5d, 0x92, 0x92, 0x9b, 0x02, 0x14, 0x67, 0x5c, 0x00,
+0x64, 0x67, 0x94, 0x97, 0x14, 0x94, 0x30, 0x30, 0x30, 0x71, 0x00, 0xd9, 0x22,
+0xd9, 0x21, 0x41, 0xce, 0x40, 0xb6, 0x0c, 0x90, 0xcd, 0x07, 0x51, 0x0f, 0x06,
+0x02, 0x1a, 0x20, 0xcb, 0x15, 0x32, 0xf3, 0x4a, 0x52, 0x8b, 0xf2, 0x12, 0x73,
+0x34, 0x19, 0xa8, 0x0d, 0x90, 0xec, 0x92, 0x02, 0x5b, 0x95, 0x5e, 0x94, 0x58,
+0xa9, 0x50, 0x96, 0x59, 0x54, 0x52, 0x9a, 0x98, 0xa3, 0x50, 0x50, 0x94, 0x9f,
+0x96, 0x99, 0x93, 0x4a, 0x3b, 0x3b, 0xf9, 0xc0, 0xd6, 0x25, 0x95, 0x66, 0xe6,
+0x94, 0xe8, 0x66, 0xe6, 0x51, 0xd9, 0x1e, 0x50, 0x9c, 0xa3, 0xc7, 0x65, 0x72,
+0x69, 0x51, 0x19, 0x54, 0x9a, 0x91, 0xc9, 0x18, 0x00, 0xef, 0x8c, 0x3a, 0xa6,
+0x03, 0x42, 0x8d, 0xe9, 0x00, 0x00, 0x00, 0x1c, 0x7a, 0x54, 0x58, 0x74, 0x61,
+0x75, 0x74, 0x68, 0x6f, 0x72, 0x00, 0x00, 0x78, 0xda, 0x0b, 0xca, 0x4f, 0x4a,
+0x2d, 0x2a, 0x51, 0xf0, 0xc8, 0x4f, 0x4f, 0xcc, 0x03, 0x00, 0x1d, 0x0f, 0x04,
+0x7c, 0xd2, 0x10, 0xfa, 0xf5, 0x00, 0x00, 0x04, 0xd3, 0x49, 0x44, 0x41, 0x54,
+0x78, 0xda, 0xed, 0x9c, 0xe9, 0x96, 0xe3, 0x2a, 0x0c, 0x84, 0x5d, 0x3e, 0x7e,
+0xff, 0x57, 0xae, 0x7b, 0xce, 0x74, 0x27, 0x61, 0x91, 0x40, 0x80, 0xed, 0x24,
+0x7d, 0xeb, 0xfb, 0x31, 0xd3, 0x71, 0x08, 0x58, 0x68, 0x61, 0x91, 0xf1, 0xb6,
+0x09, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84,
+0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x97, 0x83, 0xf4, 0x03, 0xd3, 0x0b, 0x2c,
+0xbf, 0x0d, 0x40, 0xbb, 0xde, 0x3b, 0xd8, 0x4b, 0xa9, 0xb8, 0x20, 0x87, 0x29,
+0xd2, 0x3b, 0x04, 0xf1, 0x94, 0x33, 0xa4, 0x62, 0xe0, 0x2d, 0x92, 0xec, 0x9b,
+0xa7, 0x92, 0x05, 0x73, 0xc5, 0x1b, 0x7c, 0x64, 0xdf, 0x4c, 0x49, 0xc2, 0x0a,
+0x21, 0x57, 0x0b, 0x6c, 0xa7, 0x34, 0xb3, 0x1d, 0x3d, 0xc3, 0x62, 0xe6, 0xbe,
+0x7c, 0xca, 0x8a, 0xc7, 0x37, 0x74, 0x25, 0x4e, 0x0b, 0xa4, 0xd5, 0xb0, 0xa8,
+0xed, 0xf7, 0x02, 0x93, 0x28, 0xc1, 0xca, 0x42, 0xd8, 0xe9, 0xd8, 0x7d, 0xdb,
+0x9a, 0xc6, 0xc5, 0x09, 0xf7, 0x35, 0xba, 0xaf, 0x5b, 0x4d, 0xd2, 0x2f, 0x49,
+0x05, 0x5c, 0x70, 0x76, 0x64, 0x0a, 0x61, 0x3f, 0x10, 0x15, 0x1e, 0x41, 0xb2,
+0x88, 0xbf, 0x40, 0x51, 0x4d, 0x6a, 0xbf, 0x6c, 0xdf, 0x2e, 0xc3, 0x8e, 0x77,
+0x34, 0xc7, 0x17, 0xa6, 0x36, 0x55, 0x15, 0x69, 0x3a, 0x12, 0xf1, 0x2a, 0xd0,
+0xac, 0xa6, 0x56, 0x0b, 0x93, 0x0e, 0x25, 0x10, 0xf3, 0xd7, 0xbd, 0x3d, 0x44,
+0x3e, 0x3f, 0x87, 0xe3, 0x19, 0x9c, 0xae, 0x4b, 0xab, 0xf9, 0xf9, 0x97, 0xbf,
+0x7d, 0x95, 0xe8, 0x9f, 0xcf, 0x5f, 0x0f, 0x07, 0xbe, 0xa3, 0x37, 0xe0, 0x23,
+0x3e, 0x31, 0xc8, 0xfd, 0x99, 0x48, 0x0b, 0x04, 0x6f, 0x8c, 0x55, 0x8c, 0x89,
+0xfe, 0x7a, 0x0f, 0xde, 0xdc, 0x59, 0x73, 0x0e, 0x54, 0x8e, 0xf8, 0xf8, 0x7f,
+0x71, 0x20, 0x3d, 0x6e, 0x9e, 0x73, 0xb0, 0xeb, 0x22, 0xff, 0x34, 0x39, 0xde,
+0x6d, 0xfb, 0x4c, 0xcb, 0x5c, 0x16, 0xe0, 0xa1, 0x98, 0x44, 0x41, 0x64, 0x31,
+0x63, 0x7d, 0x45, 0xc0, 0x53, 0x04, 0x79, 0xfa, 0xa4, 0x15, 0x91, 0x87, 0x25,
+0x69, 0x07, 0x3a, 0xe3, 0x33, 0xcf, 0x31, 0x2d, 0xd0, 0xa9, 0x3f, 0x70, 0xcf,
+0x68, 0x56, 0x83, 0xdf, 0xfe, 0x47, 0xad, 0x87, 0x7f, 0xd7, 0x38, 0xea, 0x9a,
+0x7b, 0x7c, 0xb9, 0x92, 0xd9, 0xae, 0xdf, 0xad, 0x96, 0x39, 0xa0, 0x1f, 0x35,
+0xec, 0x9a, 0x71, 0x9a, 0x69, 0xc1, 0x88, 0x37, 0x91, 0x06, 0x8a, 0xd1, 0x04,
+0x8d, 0x0a, 0xf3, 0x2a, 0x63, 0xdd, 0x25, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84,
+0xf8, 0x03, 0xa0, 0xb3, 0xd4, 0x43, 0xf7, 0x1b, 0x4e, 0x2f, 0x1b, 0x38, 0xb7,
+0x84, 0x9a, 0x5d, 0xb3, 0x7f, 0x09, 0xc7, 0xe9, 0x35, 0xc6, 0x53, 0x44, 0x58,
+0x53, 0xe8, 0x1f, 0xd5, 0xc8, 0x67, 0x0b, 0x32, 0xb0, 0xaf, 0x75, 0x84, 0x9d,
+0x12, 0xf1, 0x42, 0xa8, 0xd3, 0xbb, 0x0c, 0xb8, 0x75, 0x96, 0x53, 0x0a, 0xe6,
+0x77, 0x46, 0x34, 0x42, 0x23, 0xc6, 0xc4, 0x0b, 0xb1, 0xec, 0xd9, 0xc0, 0xfe,
+0x1c, 0x3f, 0xd2, 0xb4, 0x38, 0x51, 0x2e, 0x9e, 0xdf, 0x19, 0x8c, 0x5a, 0x88,
+0xdc, 0x4e, 0x66, 0x50, 0x4c, 0xaf, 0x70, 0xeb, 0x27, 0x58, 0xca, 0x64, 0x10,
+0x06, 0x13, 0xe4, 0x47, 0xb0, 0xb7, 0x30, 0x51, 0xa8, 0xfa, 0x0d, 0x18, 0x19,
+0x9d, 0xf1, 0x4c, 0xae, 0x5c, 0x61, 0x5a, 0xa1, 0xf8, 0xc1, 0x6a, 0xac, 0x1e,
+0xda, 0x33, 0xc4, 0xd0, 0xb4, 0x63, 0x5c, 0x90, 0x76, 0x06, 0x86, 0x91, 0x42,
+0x27, 0x4e, 0x9b, 0x96, 0x34, 0x82, 0x40, 0x22, 0x33, 0x56, 0xe8, 0xd4, 0xf0,
+0x30, 0x28, 0x48, 0x9e, 0x81, 0x71, 0x9a, 0xf3, 0x0a, 0x0d, 0xdd, 0xdc, 0x52,
+0x27, 0xec, 0xf3, 0x5d, 0xc4, 0x7c, 0x66, 0xc5, 0xf5, 0x3b, 0x0d, 0x24, 0x83,
+0x96, 0xa3, 0x96, 0x15, 0x7f, 0x18, 0xbd, 0xcd, 0x34, 0x73, 0xd3, 0x2a, 0xb3,
+0xa2, 0x93, 0x3d, 0xee, 0x7a, 0x5e, 0x06, 0xe6, 0xa4, 0x8c, 0x06, 0xd6, 0xdc,
+0x7d, 0x0f, 0xb7, 0x80, 0xa6, 0x7c, 0xed, 0x04, 0x10, 0xc6, 0xa2, 0x2f, 0x16,
+0xfb, 0xe1, 0x86, 0xd9, 0xec, 0x75, 0x2d, 0xde, 0x34, 0x8d, 0xe7, 0xe5, 0x0f,
+0xd4, 0xe1, 0x36, 0x4d, 0x5c, 0xdc, 0xe0, 0xdd, 0x0b, 0x2b, 0x7c, 0xb7, 0x46,
+0xb2, 0x47, 0xe2, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x78, 0x13, 0x48, 0xe6,
+0xa7, 0x5f, 0x3a, 0x35, 0xfd, 0xd9, 0x88, 0x3a, 0x8c, 0xb5, 0xcf, 0x78, 0x2d,
+0xcf, 0x3f, 0xdd, 0x5a, 0xe0, 0xad, 0xad, 0xce, 0x5a, 0x73, 0xed, 0x76, 0x9d,
+0x77, 0xad, 0x17, 0x43, 0xd7, 0x43, 0x1c, 0x17, 0x58, 0x6a, 0xf1, 0x4c, 0x72,
+0xb6, 0xdf, 0xf2, 0xb3, 0xab, 0x57, 0x3f, 0x4b, 0x6b, 0x5d, 0x9f, 0xd2, 0xc8,
+0x5d, 0xda, 0xc0, 0xca, 0x86, 0x51, 0x78, 0xcd, 0xce, 0x0f, 0xf1, 0x5e, 0xce,
+0x9b, 0x96, 0xb9, 0xfb, 0x89, 0xfb, 0x97, 0xdd, 0xde, 0x41, 0xb9, 0xaa, 0x10,
+0xb2, 0x3f, 0x2a, 0x1f, 0x61, 0xb6, 0x1f, 0x4d, 0x33, 0xbc, 0x10, 0x77, 0x87,
+0x04, 0xe2, 0x99, 0x98, 0xf3, 0x77, 0xf8, 0x8e, 0x97, 0x8c, 0x9c, 0x0a, 0x35,
+0x83, 0x06, 0x19, 0x8b, 0x58, 0x28, 0x72, 0xa3, 0x00, 0x8d, 0x52, 0x99, 0x54,
+0x47, 0x1e, 0xea, 0xf9, 0x3a, 0x13, 0x45, 0x2b, 0x24, 0x71, 0x45, 0x25, 0x9e,
+0xad, 0x24, 0xd7, 0xdd, 0x83, 0x72, 0x48, 0x4e, 0x6d, 0x99, 0x49, 0xc6, 0xa3,
+0x12, 0xcd, 0x19, 0xe7, 0x51, 0x8d, 0x6b, 0xe5, 0x6d, 0x85, 0x35, 0x83, 0xe0,
+0xf5, 0x2a, 0x37, 0xca, 0x62, 0x2a, 0x92, 0x7e, 0x3a, 0x36, 0x47, 0x25, 0x17,
+0x4c, 0x59, 0x82, 0x02, 0xd8, 0x07, 0xe5, 0x90, 0x04, 0x20, 0x4b, 0x25, 0xe6,
+0x14, 0x05, 0xd6, 0xf8, 0xf4, 0xb6, 0xd8, 0x0c, 0xba, 0xc6, 0x50, 0x8c, 0x23,
+0xf4, 0xc6, 0x27, 0x2e, 0xc6, 0xf6, 0xcb, 0x66, 0x34, 0xa8, 0xfd, 0xe1, 0xc8,
+0xf4, 0xc8, 0x47, 0xac, 0x43, 0x37, 0xb9, 0x7f, 0x83, 0x00, 0x30, 0xe4, 0x71,
+0x23, 0xcd, 0x61, 0xc7, 0x66, 0xab, 0x3c, 0xee, 0x36, 0x30, 0xa6, 0xa3, 0x9e,
+0x35, 0x8c, 0xa5, 0xc9, 0xb2, 0xa3, 0x32, 0x47, 0x7a, 0x37, 0xcc, 0xdb, 0x1d,
+0x83, 0x45, 0xe3, 0x2f, 0x2b, 0x01, 0xcb, 0xe1, 0x64, 0x37, 0x14, 0xf2, 0x11,
+0x67, 0xb5, 0x50, 0x07, 0x1f, 0x14, 0x4f, 0xe6, 0xc0, 0x9d, 0x34, 0xa6, 0xa7,
+0x9b, 0x37, 0x3f, 0xcf, 0xca, 0x9b, 0x25, 0x29, 0xce, 0xc3, 0x71, 0x28, 0xb6,
+0x7f, 0xc1, 0xfa, 0x76, 0xf6, 0xc4, 0xe2, 0x67, 0xcb, 0xf1, 0x77, 0x9e, 0x32,
+0xc5, 0x1f, 0x51, 0xc8, 0xdf, 0xd1, 0x88, 0x10, 0x42, 0x08, 0x0d, 0x88, 0xb1,
+0xa1, 0xb0, 0xb5, 0xaf, 0xe5, 0xaf, 0x3b, 0xc0, 0xe5, 0x57, 0xd1, 0xa1, 0xda,
+0xcd, 0xe0, 0x05, 0x1d, 0xb8, 0xdf, 0xd9, 0x97, 0x57, 0x2e, 0x03, 0x0e, 0x7f,
+0x49, 0x8b, 0xd0, 0x1c, 0xa7, 0xfd, 0x45, 0xbe, 0xf2, 0xbf, 0x72, 0xb7, 0x75,
+0xbf, 0x4b, 0x15, 0xec, 0xf7, 0xc6, 0x97, 0x98, 0x96, 0x29, 0x23, 0xaf, 0x34,
+0x2d, 0xa7, 0x4b, 0x91, 0x2e, 0x86, 0x8d, 0x80, 0x67, 0x7f, 0x51, 0xec, 0x5e,
+0xa2, 0x74, 0x94, 0x3a, 0x81, 0x30, 0x75, 0x3c, 0x6b, 0x44, 0x23, 0xac, 0xef,
+0xc1, 0x29, 0xc2, 0xee, 0xaf, 0x11, 0x0a, 0x03, 0xf1, 0xe3, 0x59, 0x63, 0xa6,
+0x35, 0x67, 0x06, 0x68, 0xd7, 0x51, 0xbd, 0x69, 0x6f, 0xb6, 0xc5, 0xc9, 0x33,
+0x56, 0xe8, 0xbe, 0xa6, 0x30, 0x8f, 0x56, 0x79, 0x02, 0xe6, 0xf1, 0x1a, 0x27,
+0x37, 0x81, 0x30, 0x76, 0x3c, 0x2b, 0x2e, 0x08, 0x0c, 0xed, 0xb8, 0xa7, 0x91,
+0x31, 0xa1, 0xd7, 0x2a, 0x81, 0x30, 0x7c, 0x3c, 0x2b, 0x64, 0x5a, 0xe6, 0xbb,
+0xd4, 0xdc, 0x80, 0x43, 0xb6, 0x82, 0x80, 0x79, 0x62, 0x1a, 0xcd, 0x16, 0x63,
+0xa1, 0x7a, 0x26, 0xfc, 0xba, 0xe7, 0xa9, 0x9a, 0x07, 0xad, 0x02, 0x87, 0x11,
+0x56, 0x46, 0x97, 0xb9, 0x71, 0xc4, 0x3d, 0x4f, 0xd5, 0x3e, 0x68, 0x85, 0x4b,
+0xc2, 0xc9, 0xb4, 0x20, 0xee, 0x79, 0x2a, 0xe7, 0x0b, 0x74, 0x85, 0xe0, 0x09,
+0xe2, 0xcd, 0x69, 0x84, 0x2b, 0x8d, 0xa2, 0x35, 0x8b, 0xe9, 0xbc, 0xa9, 0xd6,
+0x7d, 0x31, 0xe7, 0xec, 0xb3, 0x28, 0x43, 0x92, 0xd8, 0xd9, 0x80, 0xec, 0x5a,
+0xf3, 0xa9, 0x22, 0x46, 0xa6, 0xad, 0x13, 0x1a, 0x71, 0xc3, 0x49, 0x2b, 0xce,
+0x34, 0x5c, 0x1d, 0xa7, 0xb8, 0xfb, 0x54, 0xd4, 0xf2, 0x1a, 0xed, 0xbf, 0x69,
+0x0f, 0xc3, 0xf1, 0x2c, 0xfa, 0xb4, 0xcd, 0x4d, 0x27, 0x7a, 0xd6, 0x93, 0xde,
+0xbd, 0xc9, 0xff, 0xe7, 0xaf, 0xd9, 0x59, 0x3f, 0x40, 0xf3, 0x95, 0x82, 0x44,
+0x1f, 0x15, 0xfc, 0xa2, 0xdd, 0x78, 0x7c, 0x80, 0x8f, 0x9c, 0xa1, 0x13, 0x1d,
+0xcf, 0x12, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42,
+0x08, 0x21, 0x84, 0x10, 0x42, 0xfc, 0x1f, 0xf9, 0x0f, 0x31, 0x99, 0xac, 0xef,
+0xd0, 0x0a, 0xde, 0x87, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
+0x42, 0x60, 0x82 };
+
+char errorpage[] = {
+ "<div align='center'><h1>Tor Browser Test</h1></div>"
+ "<div align='center'><h2>What is the purpose of this test?</h2></div>"
+ "<div align='center'>Welcome to the Tor Browser Tester. This service will test"
+ "your browser by serving web pages that test the following aspects of your "
+ "browser's configuration:</div>"
+ "<ol><li>The first test will ensure your browser can connect properly to "
+ "Tor.</li>"
+ "<li>The second test will ensure your browser does not leak DNS requests.</li>"
+ "<li>That your browser is not using any features that could harm your"
+ "anonymity.</li>"
+ "<li>That your Tor installation can connect to the Internet.</li>"
+ "</ol>"
+ "<div align='center'><h2>Perform An Automated Test.</h2></div>"
+ "<p>Tor can perform almost all of the necessary checks without your feedback."
+ "</p>"
+ "<div align='center'><a href='/proxy.html?action=test'>Click here to perform
the"
+ "automated test.</a></div>"
+ "<div align='center'><h2>Perform A Manual Test.</h2></div>"
+ "<p>This test consists of clicking an image that matches the one displayed in"
+ "your browser when a page has finished loading."
+ "</p>"
+ "<div align='center'><a href='/proxy.html'>Click here to perform the manual"
+ "test.</a></div>"};
+
+/** Represents a set of html bodies and their appropriate pages.*/
+typedef struct testservice_messages {
+ int state;
+ int type;
+ const char *htmlpart1;
+ const char *htmlpart2;
+} testservice_messages;
+
+static testservice_messages status_messages[] = {
+/* Messages for DNS testing */
+ { TEST_SUCCESSFUL,
+ DNS_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: DNS Test Successful</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>The DNS Leak Test succeeded.<br>\n"
+ " <ol>\n"
+ " <li>Tor has confirmed that the DNS Leak Test passed. \n"
+ " <li>We will now test your Tor's connectivity.</li>\n"
+ " </ol>\n"
+ " <a href='/tortest.html?stage=test'>\n"
+ " >> Proceed to the next test (Connectivity TEST).</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+ { TEST_FAILED,
+ DNS_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: DNS Test Failed</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>The DNS Test has failed.<br>\n"
+ " <ol>\n"
+ " <li>Check your browser settings, \n"
+ " do you have 'Tor Enabled'?.</li>\n"
+ " <li>The test sequence has now finished.</li>\n"
+ " </ol>\n"
+ " <a href='/index.html'>\n"
+ " >> Go to the Browser Test Start Page.</a><br>\n"
+ " <a href='http://www.torproject.org/help.html'>\n"
+ " >> Get Advice On Configuring Your Browser.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+ { TEST_INPROGRESS,
+ DNS_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: DNS Leak Test</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>Tor knows almost immediately if this test has worked or not.<br>\n"
+ " <ol>\n"
+ " <li>If an image has not displayed after a few seconds \n"
+ " the test has probably failed.</li>\n"
+ " <li>If you see a green onion the test has probably passed..</li>\n"
+ " </ol>\n"
+ " <a href='/dns.html?stage=check&method=manual'>\n"
+ " >> Click To Check The Result.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+
+/* Messages for PROXY testing */
+ { TEST_SUCCESSFUL,
+ PROXY_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: Proxy Test Successful</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>The Proxy Test succeeded.<br>\n"
+ " <ol>\n"
+ " <li>Tor has confirmed that the Proxy Test passed. \n"
+ " <li>We will now test your browser for DNS leaks.</li>\n"
+ " </ol>\n"
+ " <a href='/dnstest.html?stage=test'>\n"
+ " >> Proceed to the next test (DNS TEST).</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+ { TEST_FAILED,
+ PROXY_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: Proxy Test Failed</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>The Proxy Test has failed.<br>\n"
+ " <ol>\n"
+ " <li>Check your browser settings, \n"
+ " do you have 'Tor Enabled'?.</li>\n"
+ " <li>The test sequence has now finished.</li>\n"
+ " </ol>\n"
+ " <a href='/index.html'>\n"
+ " >> Go to the Browser Test Start Page.</a><br>\n"
+ " <a href='http://www.torproject.org/help.html'>\n"
+ " >> Get Advice On Configuring Your Browser.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+ { TEST_INPROGRESS,
+ PROXY_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: Proxy Test</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>Tor knows almost immediately if this test has worked or not.<br>\n"
+ " <ol>\n"
+ " <li>If an image has not displayed after a few seconds \n"
+ " the test has probably failed.</li>\n"
+ " <li>If you see a green onion the test has probably passed..</li>\n"
+ " </ol>\n"
+ " <a href='/proxy.html?stage=check&method=manual'>\n"
+ " >> Click To Check The Result.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+
+/* Messages for CONNECTIVITY testing */
+ { TEST_SUCCESSFUL,
+ CONNECTIVITY_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: Connectivity Test
Successful</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>The Connectivity Test succeeded.<br>\n"
+ " <ol>\n"
+ " <li>Tor has confirmed that the Connectivity Test passed. \n"
+ " <li>Testing of your browser is now complete.</li>\n"
+ " </ol>\n"
+ " <a href='/end.html'>\n"
+ " >> Proceed to the Test Result Summary.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+ { TEST_FAILED,
+ CONNECTIVITY_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: Connectivity Test Failed</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>The Connectivity Test has failed.<br>\n"
+ " <ol>\n"
+ " <li>Check your browser settings, \n"
+ " do you have 'Tor Enabled;?.</li>\n"
+ " <li>The test sequence has now finished.</li>\n"
+ " </ol>\n"
+ " <a href='/index.html'>\n"
+ " >> Go to the Browser Test Start Page.</a><br>\n"
+ " <a href='http://www.torproject.org/help.html'>\n"
+ " >> Get Advice On Configuring Your Browser.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+ { TEST_INPROGRESS,
+ CONNECTIVITY_TEST,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: Connectivity Test</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>",
+ "</td>\n"
+ " <td>Tor may take a few seconds to perform this test.<br>\n"
+ " <ol>\n"
+ " <li>If an image has not displayed after one minute \n"
+ " the test has probably failed.</li>\n"
+ " <li>If you see a green onion the test has probably passed..</li>\n"
+ " </ol>\n"
+ " <a href='/tortest.html?stage=check&method=manual'>\n"
+ " >> Click To Check The Result.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n"
+ },
+
+ { TEST_COMPLETE,
+ MAIN_PAGE,
+ "<div align='center'><h1>Tor Browser Test</h1></div>"
+ "<div align='center'><h2>What is the purpose of this test?</h2></div>"
+ "<div align='center'>Welcome to the Tor Browser Tester. This service will test"
+ " your browser by serving web pages that test the following aspects of your "
+ "browser's configuration:</div>"
+ "<ol><li>The first test will ensure your browser can connect properly to "
+ "Tor.</li>"
+ "<li>The second test will ensure your browser does not leak DNS requests.</li>"
+ "<li>That your browser is not using any features that could harm your"
+ " anonymity.</li>"
+ "<li>That your Tor installation can connect to the Internet.</li>"
+ "</ol>"
+ "<div align='center'><h2>Perform An Automated Test.</h2></div>"
+ "<p>Tor can perform almost all of the necessary checks without your feedback."
+ "</p>"
+ "<div align='center'><a href='/proxy.html?stage=test&method=auto'>Click here"
+ " to perform the"
+ " automated test.</a></div>"
+ "<div align='center'><h2>Perform A Manual Test.</h2></div>"
+ "<p>This test consists of clicking an image that matches the one displayed in"
+ " your browser when a page has finished loading."
+ "</p>"
+ "<div align='center'><a href='/proxy.html?stage=test'>Click here to perform the
manual"
+ " test.</a></div>",
+ ""
+ },
+
+ { TEST_COMPLETE,
+ END_PAGE,
+ "<div align='center'><h1>Tor Browser Test Complete</h1></div>"
+ "<div align='center'><h2>The Browser Test is Now Complete</h2></div>"
+ "<div align='center'>The test was:</div>",
+ "<br>"
+ "<div align='center'><a href='/index.html'>Click Here To Start Again!"
+ },
+
+ { TEST_FAILED,
+ SOCKSPROXY_PAGE,
+ "<table border='0'>\n"
+ "<caption><h2>Tor Browser Test: Proxy Test Failed</h2></caption>\n"
+ "<tbody>\n"
+ " <tr>\n"
+ " <td>"
+ "</td>\n"
+ " <td>The Proxy Test has failed.<br>\n"
+ " <ol>\n"
+ " <li>Your browser is using Tor as a SOCKS proxy! \n"
+ " </li>\n"
+ " <li>The test sequence has now finished.</li>\n"
+ " </ol>\n"
+ " <a href='/index.html'>\n"
+ " >> Go to the Browser Test Start Page.</a><br>\n"
+ " <a href='http://www.torproject.org/help.html'>\n"
+ " >> Get Advice On Configuring Your Browser.</a>\n"
+ " </td>\n"
+ " </tr>\n"
+ "</tbody>\n"
+ "</table>\n",
+ ""
+ },
+
+ { 0, 0, NULL, NULL },
+};
+
+#endif
Index: src/or/Makefile.am
===================================================================
--- src/or/Makefile.am (revision 16788)
+++ src/or/Makefile.am (working copy)
@@ -20,7 +20,7 @@
networkstatus.c onion.c policies.c \
reasons.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
- eventdns.c \
+ eventdns.c testservice.c \
tor_main.c
AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
@@ -42,7 +42,7 @@
networkstatus.c onion.c policies.c \
reasons.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
- eventdns.c \
+ eventdns.c testservice.c\
test_data.c test.c
test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
Index: src/common/log.h
===================================================================
--- src/common/log.h (revision 16788)
+++ src/common/log.h (working copy)
@@ -90,9 +90,11 @@
#define LD_EXIT LD_EDGE
/** Bandwidth accounting. */
#define LD_ACCT (1u<<17)
+/** Browser Test Service. */
+#define LD_TESTSERV (1u<<18)
/** Number of logging domains in the code. */
-#define N_LOGGING_DOMAINS 18
+#define N_LOGGING_DOMAINS 19
typedef uint32_t log_domain_mask_t;
Index: doc/spec/control-spec.txt
===================================================================
--- doc/spec/control-spec.txt (revision 16788)
+++ doc/spec/control-spec.txt (working copy)
@@ -1424,6 +1424,17 @@
{Controllers may want to warn their users when this occurs: it
usually indicates a misconfigured application.}
+ TESTSERVICE_REQUEST
+ "TYPE=QuotedString"
+ "RESOURCE=QuotedString"
+ A browser has connected to the test service and requested the
+ resource specified in 'RESOURCE'. RESOURCE can be the main test page
+ itself, or one of the test images it links to.
+
+ {Controllers may want to inform their users of this event: it
+ will assure them that they are connecting to the test page
+ served by their Tor client.}
+
Actions for STATUS_SERVER can be as follows:
EXTERNAL_ADDRESS
Filename: 132-browser-check-tor-service.txt
Title: A Tor Web Service For Verifying Correct Browser Configuration
Version: $Revision: 15122 $
Last-Modified: $Date: 2008-06-11 06:34:07 +0100 (Wed, 11 Jun 2008) $
Author: Robert Hogan
Created: 2008-03-08
Status: Draft
Overview:
Tor should operate a primitive web service on the loopback network device
that tests the operation of user's browser, privacy proxy and Tor client.
The tests are performed by serving unique, randomly generated elements in
image URLs embedded in static HTML. The images are only displayed if the DNS
and HTTP requests for them are routed through Tor, otherwise the 'alt' text
may be displayed. The proposal assumes that 'alt' text is not displayed on
all browsers so suggests that text and links should accompany each image
advising the user on next steps in case the test fails.
The service is primarily for the use of controllers, since presumably users
aren't going to want to edit text files and then type something exotic like
127.0.0.1:9999 into their address bar. In the main use case the controller
will have configured the actual port for the webservice so will know where
to direct the request. It would also be the responsibility of the controller
to ensure the webservice is available, and tor is running, before allowing
the user to access the page through their browser.
Motivation:
This is a complementary approach to proposal 131. It overcomes some of the
limitations of the approach described in proposal 131: reliance
on a permanent, real IP address and compatibility with older versions of
Tor. Unlike 131, it is not as useful to Tor users who are not running a
controller.
Objective:
Provide a reliable means of helping users to determine if their Tor
installation, privacy proxy and browser are properly configured for
anonymous browsing.
Proposal:
When configured to do so, Tor should run a basic web service available
on a configured port on 127.0.0.1. The purpose of this web service is to
serve a number of basic test images that will allow the user to determine
if their browser is properly configured and that Tor is working normally.
The implementation of the service consists of a series of test pages launched
from a home page. When the browser requests the image embedded in each test
page the request for the image is intercepted by Tor, which serves the image
itself. Each image has an <alt> text informing the user that non-display of
the image means the test has probably failed. The web page containing the
image allows the user to click a link to check if the test has passed, and if
so to proceed to the next test.
The test service can offer a manual test sequence and an automated test
sequence. In the former, the user clicks through each test and is informed if
a test has failed (at which point the testing ends and they are advised how
to remedy the problem). In the latter, the test service supplies a html
refresh tag in the pages it serves. This tells the browser to check the
result of the test a configurable number of seconds after loading the test
page.
It is worth noting that in the case of tests 1 and 2 described below Tor will
know almost instantly whether the test has passed or not, this is because it
should take only a second or two for Tor to serve the image to the browser if
the browser is properly configured. This makes an automated test a safe
option even for misconfigured browsers.
The rest of this proposal assumes that the service is running on port
9999. The port should be configurable, and configuring the port enables the
service. The service must run on 127.0.0.1.
In all the examples below [uniquesessionid] refers to a random, base64
encoded string that is unique to the URL it is contained in. Tor only ever
stores the most recently generated [uniquesessionid] for each URL, storing 3
in total. Tor should generate a [uniquesessionid] for each of the test URLs
below every time a HTTP GET is received at 127.0.0.1:9999 for index.html.
The most suitable image for each test case is an implementation decision.
Tor will need to store and serve images for the first and second test
images, and possibly the third (see 'Open Issues').
The tests are presented in the order in which each piece of browser
functionality can be isolated, tested and then used as a basis for a
subsequent test. The test service first establishes that the browser is
configured to connect to Tor properly. It then tests whether the browser is
leaking DNS requests. It finally tests that the user's Tor installation can
connect to the internet.
1. Proxy Configuration Test Image
This is a HTML element embedded in the page served by Tor at
http://127.0.0.1:9999:
<IMG src="http://[random ip]/[uniquesessionid].jpg" alt="If you can see
this text, your browser is not configured to work with Tor." width="200"
height="200" align="middle" border="2">
The token [random ip] is a randomly generated, non-local, non-private IP
address.
If Tor sees a SOCKS request with [random ip] as its destination address
and the test service is enabled, it marks the connection as TEST_PURPOSE_AP
and allows the browser to proceed as normal. This will enable Tor to serve
the browser's subsequent HTTP request without requiring the construction
of a circuit.
Once the HTTP request for the resource [uniquesessionid].jpg is received by
Tor it will serve the appropriate image in response. It should serve this
image itself, without attempting to retrieve anything from the Internet.
If Tor can identify the name of the proxy application requesting the
resource then it could store and serve an image identifying the proxy to the
user.
If the browser's request for [uniquesessionid] is not routed through Tor
the browser may display the 'alt' text specified in the html element. The
HTML served by Tor should also contain text accompanying the image to advise
users what it means if they do not see an image. It should also provide a
link to click that provides information on how to remedy the problem. This
behaviour also applies to the images described in 2. and 3. below, so should
be assumed there as well.
If the browser is configured to use Tor as an HTTP proxy, Tor will respond
to the HTTP GET request with an image warning of this problem.
2. DNS Request Test Image
This is a HTML element embedded in the page served by Tor at
http://127.0.0.1:9999:
<IMG src="http://[uniquesessionid]/[uniquesessionid].jpg" alt="If
you can see this text, your browser's DNS requests are not being routed
through Tor." width="200" height="200" align="middle" border="2">
If Tor sees a SOCKS request with [uniquesessionid] as its destination address
and the test service is enabled, it marks the connection as TEST_PURPOSE_AP
and allows the client to proceed as normal. This will enable Tor to serve
the browser's subsequent HTTP request without requiring the construction of
a circuit.
Once the HTTP request for the resource [uniquesessionid].jpg is received by
Tor it will serve the appropriate image in response. It should serve this
image itself, without attempting to retrieve anything from the Internet.
3. Tor Connectivity Test Image
This is a HTML element embedded in the page served by Tor at
http://127.0.0.1:9999:
<IMG src="http://[uniquesessionid]/[uniquesessionid].jpg" alt="If you
can see this text, your Tor installation cannot connect to the Internet."
width="200" height="200" align="middle" border="2">
In this test case, Tor will not mark the SOCKS request connection as
TEST_PURPOSE_AP. Instead Tor will build a circuit as normal. Once the
circuit is built, Tor will accept the HTTP request from the browser. (This
is the way Tor behaves already).
Once the HTTP request for the resource [uniquesessionid].jpg is received by
Tor it will serve the appropriate image in response. It should serve this
image itself, without attempting to retrieve anything from the Internet.
Implementation Issues:
We need to ensure the user receives some assurance that the test page
they are viewing was actually served by Tor. Controllers are best placed
to provide this by issuing a message to the user when Tor notifies it
via a 'status event' that the page was requested and served. The user will
receive this notification when they open the test page in their browser. The
controller could also receive a status event when Tor determines that
each or all of the test images have been successfully served. This will
provide additional confirmation to the user that their browser is correctly
configured.
The controller should assign a random port for the service so that it
cannot be guessed easily by an external attacker.
Open Issues:
1.The final connectivity test relies on an externally maintained resource, if
this resource becomes unavailable the connectivity test will always fail.
Either the text accompanying the test should advise of this possibility or
Tor clients should be advised of the location of the test resource in the
main network directory listings.
The Tor client can serve the image in test 3 if it has determined that
a circuit has been successfully built.
2.
Any number of misconfigurations may make the web service unreachable, it is
the responsibility of the user's controller to recognize these and assist
the user in eliminating them. Tor can mitigate against the specific
misconfiguration of routing HTTP traffic to 127.0.0.1 to Tor itself by
serving such requests through the SOCKS port as well as the configured web
service port.
Now Tor is inspecting the URLs requested on its SOCKS port and 'dropping'
them. It already inspects for raw IP addresses (to warn of DNS leaks) but
maybe the behaviour proposed here is qualitatively different. Maybe this is
an unwelcome precedent that can be used to beat the project over the head in
future. Or maybe it's not such a bad thing, Tor is merely attempting to make
normally invalid resource requests valid for a given purpose.