Initial import.
diff --git a/src/core/channel/call_op_string.c b/src/core/channel/call_op_string.c
new file mode 100644
index 0000000..4a98cbf
--- /dev/null
+++ b/src/core/channel/call_op_string.c
@@ -0,0 +1,155 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/channel_stack.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/string.h>
+#include <grpc/support/useful.h>
+
+#define MAX_APPEND 1024
+
+typedef struct {
+  size_t cap;
+  size_t len;
+  char *buffer;
+} buf;
+
+static void bprintf(buf *b, const char *fmt, ...) {
+  va_list arg;
+  if (b->len + MAX_APPEND > b->cap) {
+    b->cap = GPR_MAX(b->len + MAX_APPEND, b->cap * 3 / 2);
+    b->buffer = gpr_realloc(b->buffer, b->cap);
+  }
+  va_start(arg, fmt);
+  b->len += vsprintf(b->buffer + b->len, fmt, arg);
+  va_end(arg);
+}
+
+static void bputs(buf *b, const char *s) {
+  size_t slen = strlen(s);
+  if (b->len + slen + 1 > b->cap) {
+    b->cap = GPR_MAX(b->len + slen + 1, b->cap * 3 / 2);
+    b->buffer = gpr_realloc(b->buffer, b->cap);
+  }
+  strcat(b->buffer, s);
+  b->len += slen;
+}
+
+static void put_metadata(buf *b, grpc_mdelem *md) {
+  char *txt;
+
+  txt = gpr_hexdump((char *)GPR_SLICE_START_PTR(md->key->slice),
+                    GPR_SLICE_LENGTH(md->key->slice), GPR_HEXDUMP_PLAINTEXT);
+  bputs(b, " key=");
+  bputs(b, txt);
+  gpr_free(txt);
+
+  txt = gpr_hexdump((char *)GPR_SLICE_START_PTR(md->value->slice),
+                    GPR_SLICE_LENGTH(md->value->slice), GPR_HEXDUMP_PLAINTEXT);
+  bputs(b, " value=");
+  bputs(b, txt);
+  gpr_free(txt);
+}
+
+char *grpc_call_op_string(grpc_call_op *op) {
+  buf b = {0, 0, 0};
+
+  switch (op->dir) {
+    case GRPC_CALL_DOWN:
+      bprintf(&b, ">");
+      break;
+    case GRPC_CALL_UP:
+      bprintf(&b, "<");
+      break;
+  }
+  switch (op->type) {
+    case GRPC_SEND_METADATA:
+      bprintf(&b, "SEND_METADATA");
+      put_metadata(&b, op->data.metadata);
+      break;
+    case GRPC_SEND_DEADLINE:
+      bprintf(&b, "SEND_DEADLINE %d.%09d", op->data.deadline.tv_sec,
+              op->data.deadline.tv_nsec);
+      break;
+    case GRPC_SEND_START:
+      bprintf(&b, "SEND_START");
+      break;
+    case GRPC_SEND_MESSAGE:
+      bprintf(&b, "SEND_MESSAGE");
+      break;
+    case GRPC_SEND_FINISH:
+      bprintf(&b, "SEND_FINISH");
+      break;
+    case GRPC_REQUEST_DATA:
+      bprintf(&b, "REQUEST_DATA");
+      break;
+    case GRPC_RECV_METADATA:
+      bprintf(&b, "RECV_METADATA");
+      put_metadata(&b, op->data.metadata);
+      break;
+    case GRPC_RECV_DEADLINE:
+      bprintf(&b, "RECV_DEADLINE %d.%09d", op->data.deadline.tv_sec,
+              op->data.deadline.tv_nsec);
+      break;
+    case GRPC_RECV_END_OF_INITIAL_METADATA:
+      bprintf(&b, "RECV_END_OF_INITIAL_METADATA");
+      break;
+    case GRPC_RECV_MESSAGE:
+      bprintf(&b, "RECV_MESSAGE");
+      break;
+    case GRPC_RECV_HALF_CLOSE:
+      bprintf(&b, "RECV_HALF_CLOSE");
+      break;
+    case GRPC_RECV_FINISH:
+      bprintf(&b, "RECV_FINISH");
+      break;
+    case GRPC_CANCEL_OP:
+      bprintf(&b, "CANCEL_OP");
+      break;
+  }
+  bprintf(&b, " flags=0x%08x", op->flags);
+
+  return b.buffer;
+}
+
+void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
+                      grpc_call_element *elem, grpc_call_op *op) {
+  char *str = grpc_call_op_string(op);
+  gpr_log(file, line, severity, "OP[%s:%p]: %s", elem->filter->name, elem, str);
+  gpr_free(str);
+}
diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c
new file mode 100644
index 0000000..4285b28
--- /dev/null
+++ b/src/core/channel/census_filter.c
@@ -0,0 +1,189 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/census_filter.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "src/core/channel/channel_stack.h"
+#include "src/core/channel/noop_filter.h"
+#include "src/core/statistics/census_interface.h"
+#include "src/core/statistics/census_rpc_stats.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/time.h>
+
+typedef struct call_data {
+  census_op_id op_id;
+  census_rpc_stats stats;
+  gpr_timespec start_ts;
+} call_data;
+
+typedef struct channel_data {
+  grpc_mdstr* path_str; /* pointer to meta data str with key == ":path" */
+} channel_data;
+
+static void init_rpc_stats(census_rpc_stats* stats) {
+  memset(stats, 0, sizeof(census_rpc_stats));
+  stats->cnt = 1;
+}
+
+static double gpr_timespec_to_micros(gpr_timespec t) {
+  return t.tv_sec * GPR_US_PER_SEC + t.tv_nsec * 1e-3;
+}
+
+static void extract_and_annotate_method_tag(grpc_call_op* op, call_data* calld,
+                                            channel_data* chand) {
+  if (op->data.metadata->key == chand->path_str) {
+    census_add_method_tag(calld->op_id, (const char*)GPR_SLICE_START_PTR(
+                                            op->data.metadata->value->slice));
+  }
+}
+
+static void client_call_op(grpc_call_element* elem, grpc_call_op* op) {
+  call_data* calld = elem->call_data;
+  channel_data* chand = elem->channel_data;
+  GPR_ASSERT(calld != NULL);
+  GPR_ASSERT(chand != NULL);
+  GPR_ASSERT((calld->op_id.upper != 0) && (calld->op_id.lower != 0));
+  switch (op->type) {
+    case GRPC_SEND_METADATA:
+      extract_and_annotate_method_tag(op, calld, chand);
+      break;
+    case GRPC_RECV_FINISH:
+      /* Should we stop timing the rpc here? */
+      break;
+    default:
+      break;
+  }
+  /* Always pass control up or down the stack depending on op->dir */
+  grpc_call_next_op(elem, op);
+}
+
+static void server_call_op(grpc_call_element* elem, grpc_call_op* op) {
+  call_data* calld = elem->call_data;
+  channel_data* chand = elem->channel_data;
+  GPR_ASSERT(calld != NULL);
+  GPR_ASSERT(chand != NULL);
+  GPR_ASSERT((calld->op_id.upper != 0) && (calld->op_id.lower != 0));
+  switch (op->type) {
+    case GRPC_RECV_METADATA:
+      extract_and_annotate_method_tag(op, calld, chand);
+      break;
+    case GRPC_SEND_FINISH:
+      /* Should we stop timing the rpc here? */
+      break;
+    default:
+      break;
+  }
+  /* Always pass control up or down the stack depending on op->dir */
+  grpc_call_next_op(elem, op);
+}
+
+static void channel_op(grpc_channel_element* elem, grpc_channel_op* op) {
+  switch (op->type) {
+    case GRPC_TRANSPORT_CLOSED:
+      /* TODO(hongyu): Annotate trace information for all calls of the channel
+       */
+      break;
+    default:
+      break;
+  }
+  grpc_channel_next_op(elem, op);
+}
+
+static void client_init_call_elem(grpc_call_element* elem,
+                                  const void* server_transport_data) {
+  call_data* d = elem->call_data;
+  GPR_ASSERT(d != NULL);
+  init_rpc_stats(&d->stats);
+  d->start_ts = gpr_now();
+  d->op_id = census_tracing_start_op();
+}
+
+static void client_destroy_call_elem(grpc_call_element* elem) {
+  call_data* d = elem->call_data;
+  GPR_ASSERT(d != NULL);
+  census_record_rpc_client_stats(d->op_id, &d->stats);
+  census_tracing_end_op(d->op_id);
+}
+
+static void server_init_call_elem(grpc_call_element* elem,
+                                  const void* server_transport_data) {
+  call_data* d = elem->call_data;
+  GPR_ASSERT(d != NULL);
+  init_rpc_stats(&d->stats);
+  d->start_ts = gpr_now();
+  d->op_id = census_tracing_start_op();
+}
+
+static void server_destroy_call_elem(grpc_call_element* elem) {
+  call_data* d = elem->call_data;
+  GPR_ASSERT(d != NULL);
+  d->stats.elapsed_time_ms =
+      gpr_timespec_to_micros(gpr_time_sub(gpr_now(), d->start_ts));
+  census_record_rpc_server_stats(d->op_id, &d->stats);
+  census_tracing_end_op(d->op_id);
+}
+
+static void init_channel_elem(grpc_channel_element* elem,
+                              const grpc_channel_args* args, grpc_mdctx* mdctx,
+                              int is_first, int is_last) {
+  channel_data* chand = elem->channel_data;
+  GPR_ASSERT(chand != NULL);
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(!is_last);
+  chand->path_str = grpc_mdstr_from_string(mdctx, ":path");
+}
+
+static void destroy_channel_elem(grpc_channel_element* elem) {}
+
+const grpc_channel_filter grpc_client_census_filter = {
+    client_call_op, channel_op,
+
+    sizeof(call_data), client_init_call_elem, client_destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "census-client"};
+
+const grpc_channel_filter grpc_server_census_filter = {
+    server_call_op, channel_op,
+
+    sizeof(call_data), server_init_call_elem, server_destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "census-server"};
diff --git a/src/core/channel/census_filter.h b/src/core/channel/census_filter.h
new file mode 100644
index 0000000..5b2c01c
--- /dev/null
+++ b/src/core/channel/census_filter.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_CENSUS_FILTER_H__
+#define __GRPC_INTERNAL_CHANNEL_CENSUS_FILTER_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* Census filters: provides tracing and stats collection functionalities. It
+   needs to reside right below the surface filter in the channel stack. */
+extern const grpc_channel_filter grpc_client_census_filter;
+extern const grpc_channel_filter grpc_server_census_filter;
+
+#endif /* __GRPC_INTERNAL_CHANNEL_CENSUS_FILTER_H__ */
diff --git a/src/core/channel/channel_args.c b/src/core/channel/channel_args.c
new file mode 100644
index 0000000..36312e5
--- /dev/null
+++ b/src/core/channel/channel_args.c
@@ -0,0 +1,112 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include "src/core/channel/channel_args.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/string.h>
+
+#include <string.h>
+
+static grpc_arg copy_arg(const grpc_arg *src) {
+  grpc_arg dst;
+  dst.type = src->type;
+  dst.key = gpr_strdup(src->key);
+  switch (dst.type) {
+    case GRPC_ARG_STRING:
+      dst.value.string = gpr_strdup(src->value.string);
+      break;
+    case GRPC_ARG_INTEGER:
+      dst.value.integer = src->value.integer;
+      break;
+    case GRPC_ARG_POINTER:
+      dst.value.pointer = src->value.pointer;
+      dst.value.pointer.p = src->value.pointer.copy(src->value.pointer.p);
+      break;
+  }
+  return dst;
+}
+
+grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src,
+                                                  const grpc_arg *to_add) {
+  grpc_channel_args *dst = gpr_malloc(sizeof(grpc_channel_args));
+  size_t i;
+  size_t src_num_args = (src == NULL) ? 0 : src->num_args;
+  if (!src && !to_add) {
+    dst->num_args = 0;
+    dst->args = NULL;
+    return dst;
+  }
+  dst->num_args = src_num_args + ((to_add == NULL) ? 0 : 1);
+  dst->args = gpr_malloc(sizeof(grpc_arg) * dst->num_args);
+  for (i = 0; i < src_num_args; i++) {
+    dst->args[i] = copy_arg(&src->args[i]);
+  }
+  if (to_add != NULL) dst->args[src_num_args] = copy_arg(to_add);
+  return dst;
+}
+
+grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src) {
+  return grpc_channel_args_copy_and_add(src, NULL);
+}
+
+void grpc_channel_args_destroy(grpc_channel_args *a) {
+  size_t i;
+  for (i = 0; i < a->num_args; i++) {
+    switch (a->args[i].type) {
+      case GRPC_ARG_STRING:
+        gpr_free(a->args[i].value.string);
+        break;
+      case GRPC_ARG_INTEGER:
+        break;
+      case GRPC_ARG_POINTER:
+        a->args[i].value.pointer.destroy(a->args[i].value.pointer.p);
+        break;
+    }
+    gpr_free(a->args[i].key);
+  }
+  gpr_free(a->args);
+  gpr_free(a);
+}
+
+int grpc_channel_args_is_census_enabled(const grpc_channel_args *a) {
+  int i;
+  if (a == NULL) return 0;
+  for (i = 0; i < a->num_args; i++) {
+    if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_CENSUS)) {
+      return a->args[i].value.integer != 0;
+    }
+  }
+  return 0;
+}
diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h
new file mode 100644
index 0000000..cf38d5d
--- /dev/null
+++ b/src/core/channel/channel_args.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__
+#define __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__
+
+#include <grpc/grpc.h>
+
+/* Copy some arguments */
+grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src);
+
+/* Copy some arguments and add the to_add parameter in the end.
+   If to_add is NULL, it is equivalent to call grpc_channel_args_copy. */
+grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src,
+                                                  const grpc_arg *to_add);
+
+/* Destroy arguments created by grpc_channel_args_copy */
+void grpc_channel_args_destroy(grpc_channel_args *a);
+
+/* Reads census_enabled settings from channel args. Returns 1 if census_enabled
+   is specified in channel args, otherwise returns 0. */
+int grpc_channel_args_is_census_enabled(const grpc_channel_args *a);
+
+#endif  /* __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__ */
diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c
new file mode 100644
index 0000000..a403db3
--- /dev/null
+++ b/src/core/channel/channel_stack.c
@@ -0,0 +1,223 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/channel_stack.h"
+#include <grpc/support/log.h>
+
+#include <stdlib.h>
+
+/* Memory layouts.
+
+   Channel stack is laid out as: {
+     grpc_channel_stack stk;
+     padding to GPR_MAX_ALIGNMENT
+     grpc_channel_element[stk.count];
+     per-filter memory, aligned to GPR_MAX_ALIGNMENT
+   }
+
+   Call stack is laid out as: {
+     grpc_call_stack stk;
+     padding to GPR_MAX_ALIGNMENT
+     grpc_call_element[stk.count];
+     per-filter memory, aligned to GPR_MAX_ALIGNMENT
+   } */
+
+/* Given a size, round up to the next multiple of sizeof(void*) */
+#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
+  (((x)+GPR_MAX_ALIGNMENT - 1) & ~(GPR_MAX_ALIGNMENT - 1))
+
+size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
+                               size_t filter_count) {
+  /* always need the header, and size for the channel elements */
+  size_t size =
+      ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) +
+      ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
+  size_t i;
+
+  GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 &&
+             "GPR_MAX_ALIGNMENT must be a power of two");
+
+  /* add the size for each filter */
+  for (i = 0; i < filter_count; i++) {
+    size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
+  }
+
+  return size;
+}
+
+#define CHANNEL_ELEMS_FROM_STACK(stk)                                   \
+  ((grpc_channel_element *)((char *)(stk) + ROUND_UP_TO_ALIGNMENT_SIZE( \
+                                                sizeof(grpc_channel_stack))))
+
+#define CALL_ELEMS_FROM_STACK(stk)       \
+  ((grpc_call_element *)((char *)(stk) + \
+                         ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack))))
+
+grpc_channel_element *grpc_channel_stack_element(
+    grpc_channel_stack *channel_stack, size_t index) {
+  return CHANNEL_ELEMS_FROM_STACK(channel_stack) + index;
+}
+
+grpc_channel_element *grpc_channel_stack_last_element(
+    grpc_channel_stack *channel_stack) {
+  return grpc_channel_stack_element(channel_stack, channel_stack->count - 1);
+}
+
+grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack,
+                                           size_t index) {
+  return CALL_ELEMS_FROM_STACK(call_stack) + index;
+}
+
+void grpc_channel_stack_init(const grpc_channel_filter **filters,
+                             size_t filter_count, const grpc_channel_args *args,
+                             grpc_mdctx *metadata_context,
+                             grpc_channel_stack *stack) {
+  size_t call_size =
+      ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
+      ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
+  grpc_channel_element *elems;
+  char *user_data;
+  size_t i;
+
+  stack->count = filter_count;
+  elems = CHANNEL_ELEMS_FROM_STACK(stack);
+  user_data =
+      ((char *)elems) +
+      ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
+
+  /* init per-filter data */
+  for (i = 0; i < filter_count; i++) {
+    elems[i].filter = filters[i];
+    elems[i].channel_data = user_data;
+    elems[i].filter->init_channel_elem(&elems[i], args, metadata_context,
+                                       i == 0, i == (filter_count - 1));
+    user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
+    call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
+  }
+
+  GPR_ASSERT(user_data - (char *)stack ==
+             grpc_channel_stack_size(filters, filter_count));
+
+  stack->call_stack_size = call_size;
+}
+
+void grpc_channel_stack_destroy(grpc_channel_stack *stack) {
+  grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(stack);
+  size_t count = stack->count;
+  size_t i;
+
+  /* destroy per-filter data */
+  for (i = 0; i < count; i++) {
+    channel_elems[i].filter->destroy_channel_elem(&channel_elems[i]);
+  }
+}
+
+void grpc_call_stack_init(grpc_channel_stack *channel_stack,
+                          const void *transport_server_data,
+                          grpc_call_stack *call_stack) {
+  grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack);
+  size_t count = channel_stack->count;
+  grpc_call_element *call_elems;
+  char *user_data;
+  size_t i;
+
+  call_stack->count = count;
+  call_elems = CALL_ELEMS_FROM_STACK(call_stack);
+  user_data = ((char *)call_elems) +
+              ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
+
+  /* init per-filter data */
+  for (i = 0; i < count; i++) {
+    call_elems[i].filter = channel_elems[i].filter;
+    call_elems[i].channel_data = channel_elems[i].channel_data;
+    call_elems[i].call_data = user_data;
+    call_elems[i].filter->init_call_elem(&call_elems[i], transport_server_data);
+    user_data +=
+        ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
+  }
+}
+
+void grpc_call_stack_destroy(grpc_call_stack *stack) {
+  grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack);
+  size_t count = stack->count;
+  size_t i;
+
+  /* destroy per-filter data */
+  for (i = 0; i < count; i++) {
+    elems[i].filter->destroy_call_elem(&elems[i]);
+  }
+}
+
+void grpc_call_next_op(grpc_call_element *elem, grpc_call_op *op) {
+  grpc_call_element *next_elem = elem + op->dir;
+  next_elem->filter->call_op(next_elem, op);
+}
+
+void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  grpc_channel_element *next_elem = elem + op->dir;
+  next_elem->filter->channel_op(next_elem, op);
+}
+
+grpc_channel_stack *grpc_channel_stack_from_top_element(
+    grpc_channel_element *elem) {
+  return (grpc_channel_stack *)((char *)(elem) -
+                                ROUND_UP_TO_ALIGNMENT_SIZE(
+                                    sizeof(grpc_channel_stack)));
+}
+
+grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) {
+  return (grpc_call_stack *)((char *)(elem) - ROUND_UP_TO_ALIGNMENT_SIZE(
+                                                  sizeof(grpc_call_stack)));
+}
+
+static void do_nothing(void *user_data, grpc_op_error error) {}
+
+void grpc_call_element_send_metadata(grpc_call_element *cur_elem,
+                                     grpc_mdelem *mdelem) {
+  grpc_call_op metadata_op;
+  metadata_op.type = GRPC_SEND_METADATA;
+  metadata_op.dir = GRPC_CALL_DOWN;
+  metadata_op.done_cb = do_nothing;
+  metadata_op.user_data = NULL;
+  metadata_op.data.metadata = grpc_mdelem_ref(mdelem);
+  grpc_call_next_op(cur_elem, &metadata_op);
+}
+
+void grpc_call_element_send_cancel(grpc_call_element *cur_elem) {
+  grpc_call_op cancel_op;
+  cancel_op.type = GRPC_CANCEL_OP;
+  cancel_op.dir = GRPC_CALL_DOWN;
+  cancel_op.done_cb = do_nothing;
+  cancel_op.user_data = NULL;
+  grpc_call_next_op(cur_elem, &cancel_op);
+}
diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h
new file mode 100644
index 0000000..0ae1005
--- /dev/null
+++ b/src/core/channel/channel_stack.h
@@ -0,0 +1,288 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__
+#define __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__
+
+/* A channel filter defines how operations on a channel are implemented.
+   Channel filters are chained together to create full channels, and if those
+   chains are linear, then channel stacks provide a mechanism to minimize
+   allocations for that chain.
+   Call stacks are created by channel stacks and represent the per-call data
+   for that stack. */
+
+#include <stddef.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "src/core/transport/transport.h"
+
+/* #define GRPC_CHANNEL_STACK_TRACE 1 */
+
+typedef struct grpc_channel_element grpc_channel_element;
+typedef struct grpc_call_element grpc_call_element;
+
+/* Call operations - things that can be sent and received.
+
+   Threading:
+     SEND, RECV, and CANCEL ops can be active on a call at the same time, but
+     only one SEND, one RECV, and one CANCEL can be active at a time.
+
+   If state is shared between send/receive/cancel operations, it is up to
+   filters to provide their own protection around that. */
+typedef enum {
+  /* send metadata to the channels peer */
+  GRPC_SEND_METADATA,
+  /* send a deadline */
+  GRPC_SEND_DEADLINE,
+  /* start a connection (corresponds to start_invoke/accept) */
+  GRPC_SEND_START,
+  /* send a message to the channels peer */
+  GRPC_SEND_MESSAGE,
+  /* send half-close to the channels peer */
+  GRPC_SEND_FINISH,
+  /* request that more data be allowed through flow control */
+  GRPC_REQUEST_DATA,
+  /* metadata was received from the channels peer */
+  GRPC_RECV_METADATA,
+  /* receive a deadline */
+  GRPC_RECV_DEADLINE,
+  /* the end of the first batch of metadata was received */
+  GRPC_RECV_END_OF_INITIAL_METADATA,
+  /* a message was received from the channels peer */
+  GRPC_RECV_MESSAGE,
+  /* half-close was received from the channels peer */
+  GRPC_RECV_HALF_CLOSE,
+  /* full close was received from the channels peer */
+  GRPC_RECV_FINISH,
+  /* the call has been abnormally terminated */
+  GRPC_CANCEL_OP
+} grpc_call_op_type;
+
+/* The direction of the call.
+   The values of the enums (1, -1) matter here - they are used to increment
+   or decrement a pointer to find the next element to call */
+typedef enum { GRPC_CALL_DOWN = 1, GRPC_CALL_UP = -1 } grpc_call_dir;
+
+/* A single filterable operation to be performed on a call */
+typedef struct {
+  /* The type of operation we're performing */
+  grpc_call_op_type type;
+  /* The directionality of this call - does the operation begin at the bottom
+     of the stack and flow up, or does the operation start at the top of the
+     stack and flow down through the filters. */
+  grpc_call_dir dir;
+
+  /* Flags associated with this call: see GRPC_WRITE_* in grpc.h */
+  gpr_uint32 flags;
+
+  /* Argument data, matching up with grpc_call_op_type names */
+  union {
+    grpc_byte_buffer *message;
+    grpc_mdelem *metadata;
+    gpr_timespec deadline;
+  } data;
+
+  /* Must be called when processing of this call-op is complete.
+     Signature chosen to match transport flow control callbacks */
+  void (*done_cb)(void *user_data, grpc_op_error error);
+  /* User data to be passed into done_cb */
+  void *user_data;
+} grpc_call_op;
+
+/* returns a string representation of op, that can be destroyed with gpr_free */
+char *grpc_call_op_string(grpc_call_op *op);
+
+typedef enum {
+  GRPC_CHANNEL_SHUTDOWN,
+  GRPC_ACCEPT_CALL,
+  GRPC_TRANSPORT_CLOSED
+} grpc_channel_op_type;
+
+/* A single filterable operation to be performed on a channel */
+typedef struct {
+  /* The type of operation we're performing */
+  grpc_channel_op_type type;
+  /* The directionality of this call - is it bubbling up the stack, or down? */
+  grpc_call_dir dir;
+
+  /* Argument data, matching up with grpc_channel_op_type names */
+  union {
+    struct {
+      grpc_transport *transport;
+      const void *transport_server_data;
+    } accept_call;
+  } data;
+} grpc_channel_op;
+
+/* Channel filters specify:
+   1. the amount of memory needed in the channel & call (via the sizeof_XXX
+      members)
+   2. functions to initialize and destroy channel & call data
+      (init_XXX, destroy_XXX)
+   3. functions to implement call operations and channel operations (call_op,
+      channel_op)
+   4. a name, which is useful when debugging
+
+   Members are laid out in approximate frequency of use order. */
+typedef struct {
+  /* Called to eg. send/receive data on a call.
+     See grpc_call_next_op on how to call the next element in the stack */
+  void (*call_op)(grpc_call_element *elem, grpc_call_op *op);
+  /* Called to handle channel level operations - e.g. new calls, or transport
+     closure.
+     See grpc_channel_next_op on how to call the next element in the stack */
+  void (*channel_op)(grpc_channel_element *elem, grpc_channel_op *op);
+
+  /* sizeof(per call data) */
+  size_t sizeof_call_data;
+  /* Initialize per call data.
+     elem is initialized at the start of the call, and elem->call_data is what
+     needs initializing.
+     The filter does not need to do any chaining.
+     server_transport_data is an opaque pointer. If it is NULL, this call is
+     on a client; if it is non-NULL, then it points to memory owned by the
+     transport and is on the server. Most filters want to ignore this
+     argument.*/
+  void (*init_call_elem)(grpc_call_element *elem,
+                         const void *server_transport_data);
+  /* Destroy per call data.
+     The filter does not need to do any chaining */
+  void (*destroy_call_elem)(grpc_call_element *elem);
+
+  /* sizeof(per channel data) */
+  size_t sizeof_channel_data;
+  /* Initialize per-channel data.
+     elem is initialized at the start of the call, and elem->channel_data is
+     what needs initializing.
+     is_first, is_last designate this elements position in the stack, and are
+     useful for asserting correct configuration by upper layer code.
+     The filter does not need to do any chaining */
+  void (*init_channel_elem)(grpc_channel_element *elem,
+                            const grpc_channel_args *args,
+                            grpc_mdctx *metadata_context, int is_first,
+                            int is_last);
+  /* Destroy per channel data.
+     The filter does not need to do any chaining */
+  void (*destroy_channel_elem)(grpc_channel_element *elem);
+
+  /* The name of this filter */
+  const char *name;
+} grpc_channel_filter;
+
+/* A channel_element tracks its filter and the filter requested memory within
+   a channel allocation */
+struct grpc_channel_element {
+  const grpc_channel_filter *filter;
+  void *channel_data;
+};
+
+/* A call_element tracks its filter, the filter requested memory within
+   a channel allocation, and the filter requested memory within a call
+   allocation */
+struct grpc_call_element {
+  const grpc_channel_filter *filter;
+  void *channel_data;
+  void *call_data;
+};
+
+/* A channel stack tracks a set of related filters for one channel, and
+   guarantees they live within a single malloc() allocation */
+typedef struct {
+  size_t count;
+  /* Memory required for a call stack (computed at channel stack
+     initialization) */
+  size_t call_stack_size;
+} grpc_channel_stack;
+
+/* A call stack tracks a set of related filters for one call, and guarantees
+   they live within a single malloc() allocation */
+typedef struct { size_t count; } grpc_call_stack;
+
+/* Get a channel element given a channel stack and its index */
+grpc_channel_element *grpc_channel_stack_element(grpc_channel_stack *stack,
+                                                 size_t i);
+/* Get the last channel element in a channel stack */
+grpc_channel_element *grpc_channel_stack_last_element(
+    grpc_channel_stack *stack);
+/* Get a call stack element given a call stack and an index */
+grpc_call_element *grpc_call_stack_element(grpc_call_stack *stack, size_t i);
+
+/* Determine memory required for a channel stack containing a set of filters */
+size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
+                               size_t filter_count);
+/* Initialize a channel stack given some filters */
+void grpc_channel_stack_init(const grpc_channel_filter **filters,
+                             size_t filter_count, const grpc_channel_args *args,
+                             grpc_mdctx *metadata_context,
+                             grpc_channel_stack *stack);
+/* Destroy a channel stack */
+void grpc_channel_stack_destroy(grpc_channel_stack *stack);
+
+/* Initialize a call stack given a channel stack. transport_server_data is
+   expected to be NULL on a client, or an opaque transport owned pointer on the
+   server. */
+void grpc_call_stack_init(grpc_channel_stack *channel_stack,
+                          const void *transport_server_data,
+                          grpc_call_stack *call_stack);
+/* Destroy a call stack */
+void grpc_call_stack_destroy(grpc_call_stack *stack);
+
+/* Call the next operation (depending on call directionality) in a call stack */
+void grpc_call_next_op(grpc_call_element *elem, grpc_call_op *op);
+/* Call the next operation (depending on call directionality) in a channel
+   stack */
+void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op);
+
+/* Given the top element of a channel stack, get the channel stack itself */
+grpc_channel_stack *grpc_channel_stack_from_top_element(
+    grpc_channel_element *elem);
+/* Given the top element of a call stack, get the call stack itself */
+grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem);
+
+void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
+                      grpc_call_element *elem, grpc_call_op *op);
+
+void grpc_call_element_send_metadata(grpc_call_element *cur_elem,
+                                     grpc_mdelem *elem);
+void grpc_call_element_send_cancel(grpc_call_element *cur_elem);
+
+#ifdef GRPC_CHANNEL_STACK_TRACE
+#define GRPC_CALL_LOG_OP(sev, elem, op) grpc_call_log_op(sev, elem, op)
+#else
+#define GRPC_CALL_LOG_OP(sev, elem, op) \
+  do {                                  \
+  } while (0)
+#endif
+
+#endif  /* __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__ */
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
new file mode 100644
index 0000000..9056368
--- /dev/null
+++ b/src/core/channel/client_channel.c
@@ -0,0 +1,641 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/client_channel.h"
+
+#include <stdio.h>
+
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/metadata_buffer.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+
+/* Link back filter: passes up calls to the client channel, pushes down calls
+   down */
+
+typedef struct { grpc_channel_element *back; } lb_channel_data;
+
+typedef struct { grpc_call_element *back; } lb_call_data;
+
+static void lb_call_op(grpc_call_element *elem, grpc_call_op *op) {
+  lb_call_data *calld = elem->call_data;
+
+  switch (op->dir) {
+    case GRPC_CALL_UP:
+      calld->back->filter->call_op(calld->back, op);
+      break;
+    case GRPC_CALL_DOWN:
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+/* Currently we assume all channel operations should just be pushed up. */
+static void lb_channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  lb_channel_data *chand = elem->channel_data;
+
+  switch (op->dir) {
+    case GRPC_CALL_UP:
+      chand->back->filter->channel_op(chand->back, op);
+      break;
+    case GRPC_CALL_DOWN:
+      grpc_channel_next_op(elem, op);
+      break;
+  }
+}
+
+/* Constructor for call_data */
+static void lb_init_call_elem(grpc_call_element *elem,
+                              const void *server_transport_data) {}
+
+/* Destructor for call_data */
+static void lb_destroy_call_elem(grpc_call_element *elem) {}
+
+/* Constructor for channel_data */
+static void lb_init_channel_elem(grpc_channel_element *elem,
+                                 const grpc_channel_args *args,
+                                 grpc_mdctx *metadata_context, int is_first,
+                                 int is_last) {
+  GPR_ASSERT(is_first);
+  GPR_ASSERT(!is_last);
+}
+
+/* Destructor for channel_data */
+static void lb_destroy_channel_elem(grpc_channel_element *elem) {}
+
+static const grpc_channel_filter link_back_filter = {
+    lb_call_op,               lb_channel_op,
+
+    sizeof(lb_call_data),     lb_init_call_elem,    lb_destroy_call_elem,
+
+    sizeof(lb_channel_data),  lb_init_channel_elem, lb_destroy_channel_elem,
+
+    "clientchannel.linkback",
+};
+
+/* Client channel implementation */
+
+typedef struct {
+  size_t inflight_requests;
+  grpc_channel_stack *channel_stack;
+} child_entry;
+
+typedef struct call_data call_data;
+
+typedef struct {
+  /* protects children, child_count, child_capacity, active_child,
+     transport_setup_initiated
+     does not protect channel stacks held by children
+     transport_setup is assumed to be set once during construction */
+  gpr_mu mu;
+
+  /* the sending child (points somewhere in children, or NULL) */
+  child_entry *active_child;
+  /* vector of child channels  */
+  child_entry *children;
+  size_t child_count;
+  size_t child_capacity;
+
+  /* calls waiting for a channel to be ready */
+  call_data **waiting_children;
+  size_t waiting_child_count;
+  size_t waiting_child_capacity;
+
+  /* transport setup for this channel */
+  grpc_transport_setup *transport_setup;
+  int transport_setup_initiated;
+
+  grpc_channel_args *args;
+
+  /* metadata cache */
+  grpc_mdelem *cancel_status;
+} channel_data;
+
+typedef enum {
+  CALL_CREATED,
+  CALL_WAITING,
+  CALL_ACTIVE,
+  CALL_CANCELLED
+} call_state;
+
+struct call_data {
+  /* owning element */
+  grpc_call_element *elem;
+
+  call_state state;
+  grpc_metadata_buffer pending_metadata;
+  gpr_timespec deadline;
+  union {
+    struct {
+      /* our child call stack */
+      grpc_call_stack *child_stack;
+      /* ... and the channel stack associated with it */
+      grpc_channel_stack *using_stack;
+    } active;
+    struct {
+      void (*on_complete)(void *user_data, grpc_op_error error);
+      void *on_complete_user_data;
+      gpr_uint32 start_flags;
+    } waiting;
+  } s;
+};
+
+static int prepare_activate(call_data *calld, child_entry *on_child) {
+  grpc_call_element *child_elem;
+  grpc_channel_stack *use_stack = on_child->channel_stack;
+
+  if (calld->state == CALL_CANCELLED) return 0;
+
+  on_child->inflight_requests++;
+
+  /* no more access to calld->s.waiting allowed */
+  GPR_ASSERT(calld->state == CALL_WAITING);
+  calld->state = CALL_ACTIVE;
+
+  /* create a child stack, and record that we're using a particular channel
+     stack */
+  calld->s.active.child_stack = gpr_malloc(use_stack->call_stack_size);
+  calld->s.active.using_stack = use_stack;
+  grpc_call_stack_init(use_stack, NULL, calld->s.active.child_stack);
+  /* initialize the top level link back element */
+  child_elem = grpc_call_stack_element(calld->s.active.child_stack, 0);
+  GPR_ASSERT(child_elem->filter == &link_back_filter);
+  ((lb_call_data *)child_elem->call_data)->back = calld->elem;
+
+  return 1;
+}
+
+static void do_nothing(void *ignored, grpc_op_error error) {}
+
+static void complete_activate(call_data *calld, child_entry *on_child,
+                              grpc_call_op *op) {
+  grpc_call_element *child_elem =
+      grpc_call_stack_element(calld->s.active.child_stack, 0);
+
+  GPR_ASSERT(calld->state == CALL_ACTIVE);
+
+  /* sending buffered metadata down the stack before the start call */
+  grpc_metadata_buffer_flush(&calld->pending_metadata, child_elem);
+
+  if (gpr_time_cmp(calld->deadline, gpr_inf_future) != 0) {
+    grpc_call_op dop;
+    dop.type = GRPC_SEND_DEADLINE;
+    dop.dir = GRPC_CALL_DOWN;
+    dop.flags = 0;
+    dop.data.deadline = calld->deadline;
+    dop.done_cb = do_nothing;
+    dop.user_data = NULL;
+    child_elem->filter->call_op(child_elem, &dop);
+  }
+
+  /* continue the start call down the stack, this nees to happen after metadata
+     are flushed*/
+  child_elem->filter->call_op(child_elem, op);
+}
+
+static void start_rpc(call_data *calld, channel_data *chand, grpc_call_op *op) {
+  gpr_mu_lock(&chand->mu);
+  if (calld->state == CALL_CANCELLED) {
+    gpr_mu_unlock(&chand->mu);
+    op->done_cb(op->user_data, GRPC_OP_ERROR);
+    return;
+  }
+  GPR_ASSERT(calld->state == CALL_CREATED);
+  calld->state = CALL_WAITING;
+  if (chand->active_child) {
+    /* channel is connected - use the connected stack */
+    if (prepare_activate(calld, chand->active_child)) {
+      gpr_mu_unlock(&chand->mu);
+      /* activate the request (pass it down) outside the lock */
+      complete_activate(calld, chand->active_child, op);
+    } else {
+      gpr_mu_unlock(&chand->mu);
+    }
+  } else {
+    /* check to see if we should initiate a connection (if we're not already),
+       but don't do so until outside the lock to avoid re-entrancy problems if
+       the callback is immediate */
+    int initiate_transport_setup = 0;
+    if (!chand->transport_setup_initiated) {
+      chand->transport_setup_initiated = 1;
+      initiate_transport_setup = 1;
+    }
+    /* add this call to the waiting set to be resumed once we have a child
+       channel stack, growing the waiting set if needed */
+    if (chand->waiting_child_count == chand->waiting_child_capacity) {
+      chand->waiting_child_capacity =
+          GPR_MAX(chand->waiting_child_capacity * 2, 8);
+      chand->waiting_children =
+          gpr_realloc(chand->waiting_children,
+                      chand->waiting_child_capacity * sizeof(call_data *));
+    }
+    calld->s.waiting.on_complete = op->done_cb;
+    calld->s.waiting.on_complete_user_data = op->user_data;
+    calld->s.waiting.start_flags = op->flags;
+    chand->waiting_children[chand->waiting_child_count++] = calld;
+    gpr_mu_unlock(&chand->mu);
+
+    /* finally initiate transport setup if needed */
+    if (initiate_transport_setup) {
+      grpc_transport_setup_initiate(chand->transport_setup);
+    }
+  }
+}
+
+static void remove_waiting_child(channel_data *chand, call_data *calld) {
+  size_t new_count;
+  size_t i;
+  for (i = 0, new_count = 0; i < chand->waiting_child_count; i++) {
+    if (chand->waiting_children[i] == calld) continue;
+    chand->waiting_children[new_count++] = chand->waiting_children[i];
+  }
+  GPR_ASSERT(new_count == chand->waiting_child_count - 1 ||
+             new_count == chand->waiting_child_count);
+  chand->waiting_child_count = new_count;
+}
+
+static void cancel_rpc(grpc_call_element *elem, grpc_call_op *op) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  grpc_call_element *child_elem;
+  grpc_call_op finish_op;
+
+  gpr_mu_lock(&chand->mu);
+  switch (calld->state) {
+    case CALL_ACTIVE:
+      child_elem = grpc_call_stack_element(calld->s.active.child_stack, 0);
+      gpr_mu_unlock(&chand->mu);
+      child_elem->filter->call_op(child_elem, op);
+      return; /* early out */
+    case CALL_WAITING:
+      remove_waiting_child(chand, calld);
+      calld->s.waiting.on_complete(calld->s.waiting.on_complete_user_data,
+                                   GRPC_OP_ERROR);
+    /* fallthrough intended */
+    case CALL_CREATED:
+      calld->state = CALL_CANCELLED;
+      gpr_mu_unlock(&chand->mu);
+      /* send up a synthesized status */
+      finish_op.type = GRPC_RECV_METADATA;
+      finish_op.dir = GRPC_CALL_UP;
+      finish_op.flags = 0;
+      finish_op.data.metadata = grpc_mdelem_ref(chand->cancel_status);
+      finish_op.done_cb = do_nothing;
+      finish_op.user_data = NULL;
+      grpc_call_next_op(elem, &finish_op);
+      /* send up a finish */
+      finish_op.type = GRPC_RECV_FINISH;
+      finish_op.dir = GRPC_CALL_UP;
+      finish_op.flags = 0;
+      finish_op.done_cb = do_nothing;
+      finish_op.user_data = NULL;
+      grpc_call_next_op(elem, &finish_op);
+      return; /* early out */
+    case CALL_CANCELLED:
+      gpr_mu_unlock(&chand->mu);
+      return; /* early out */
+  }
+  gpr_log(GPR_ERROR, "should never reach here");
+  abort();
+}
+
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  grpc_call_element *child_elem;
+  GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+  switch (op->type) {
+    case GRPC_SEND_METADATA:
+      grpc_metadata_buffer_queue(&calld->pending_metadata, op);
+      break;
+    case GRPC_SEND_DEADLINE:
+      calld->deadline = op->data.deadline;
+      op->done_cb(op->user_data, GRPC_OP_OK);
+      break;
+    case GRPC_SEND_START:
+      /* filter out the start event to find which child to send on */
+      start_rpc(calld, chand, op);
+      break;
+    case GRPC_CANCEL_OP:
+      cancel_rpc(elem, op);
+      break;
+    default:
+      switch (op->dir) {
+        case GRPC_CALL_UP:
+          grpc_call_next_op(elem, op);
+          break;
+        case GRPC_CALL_DOWN:
+          child_elem = grpc_call_stack_element(calld->s.active.child_stack, 0);
+          GPR_ASSERT(calld->state == CALL_ACTIVE);
+          child_elem->filter->call_op(child_elem, op);
+          break;
+      }
+      break;
+  }
+}
+
+static void broadcast_channel_op_down(grpc_channel_element *elem,
+                                      grpc_channel_op *op) {
+  channel_data *chand = elem->channel_data;
+  grpc_channel_element *child_elem;
+  grpc_channel_stack **children;
+  size_t child_count;
+  size_t i;
+
+  /* copy the current set of children, and mark them all as having an inflight
+     request */
+  gpr_mu_lock(&chand->mu);
+  child_count = chand->child_count;
+  children = gpr_malloc(sizeof(grpc_channel_stack *) * child_count);
+  for (i = 0; i < child_count; i++) {
+    children[i] = chand->children[i].channel_stack;
+    chand->children[i].inflight_requests++;
+  }
+  gpr_mu_unlock(&chand->mu);
+
+  /* send the message down */
+  for (i = 0; i < child_count; i++) {
+    child_elem = grpc_channel_stack_element(children[i], 0);
+    child_elem->filter->channel_op(child_elem, op);
+  }
+
+  /* unmark the inflight requests */
+  gpr_mu_lock(&chand->mu);
+  for (i = 0; i < child_count; i++) {
+    chand->children[i].inflight_requests--;
+  }
+  gpr_mu_unlock(&chand->mu);
+
+  gpr_free(children);
+}
+
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
+
+  switch (op->type) {
+    default:
+      switch (op->dir) {
+        case GRPC_CALL_UP:
+          grpc_channel_next_op(elem, op);
+          break;
+        case GRPC_CALL_DOWN:
+          broadcast_channel_op_down(elem, op);
+          break;
+      }
+      break;
+  }
+}
+
+static void error_bad_on_complete(void *arg, grpc_op_error error) {
+  gpr_log(GPR_ERROR,
+          "Waiting finished but not started? Bad on_complete callback");
+  abort();
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  call_data *calld = elem->call_data;
+
+  GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
+  GPR_ASSERT(server_transport_data == NULL);
+  calld->elem = elem;
+  calld->state = CALL_CREATED;
+  calld->deadline = gpr_inf_future;
+  calld->s.waiting.on_complete = error_bad_on_complete;
+  calld->s.waiting.on_complete_user_data = NULL;
+  grpc_metadata_buffer_init(&calld->pending_metadata);
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_call_element *elem) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  size_t i;
+
+  /* if the metadata buffer is not flushed, destroy it here. */
+  grpc_metadata_buffer_destroy(&calld->pending_metadata, GRPC_OP_OK);
+  /* if the call got activated, we need to destroy the child stack also, and
+     remove it from the in-flight requests tracked by the child_entry we
+     picked */
+  if (calld->state == CALL_ACTIVE) {
+    grpc_call_stack_destroy(calld->s.active.child_stack);
+    gpr_free(calld->s.active.child_stack);
+
+    gpr_mu_lock(&chand->mu);
+    for (i = 0; i < chand->child_count; i++) {
+      if (chand->children[i].channel_stack == calld->s.active.using_stack) {
+        chand->children[i].inflight_requests--;
+        /* TODO(ctiller): garbage collect channels that are not active
+           and have no inflight requests */
+      }
+    }
+    gpr_mu_unlock(&chand->mu);
+  }
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args,
+                              grpc_mdctx *metadata_context, int is_first,
+                              int is_last) {
+  channel_data *chand = elem->channel_data;
+  char temp[16];
+
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(is_last);
+  GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
+
+  gpr_mu_init(&chand->mu);
+  chand->active_child = NULL;
+  chand->children = NULL;
+  chand->child_count = 0;
+  chand->child_capacity = 0;
+  chand->waiting_children = NULL;
+  chand->waiting_child_count = 0;
+  chand->waiting_child_capacity = 0;
+  chand->transport_setup = NULL;
+  chand->transport_setup_initiated = 0;
+  chand->args = grpc_channel_args_copy(args);
+
+  sprintf(temp, "%d", GRPC_STATUS_CANCELLED);
+  chand->cancel_status =
+      grpc_mdelem_from_strings(metadata_context, "grpc-status", temp);
+}
+
+/* Destructor for channel_data */
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  channel_data *chand = elem->channel_data;
+  size_t i;
+
+  grpc_transport_setup_cancel(chand->transport_setup);
+
+  for (i = 0; i < chand->child_count; i++) {
+    GPR_ASSERT(chand->children[i].inflight_requests == 0);
+    grpc_channel_stack_destroy(chand->children[i].channel_stack);
+    gpr_free(chand->children[i].channel_stack);
+  }
+
+  grpc_channel_args_destroy(chand->args);
+  grpc_mdelem_unref(chand->cancel_status);
+
+  gpr_mu_destroy(&chand->mu);
+  GPR_ASSERT(chand->waiting_child_count == 0);
+  gpr_free(chand->waiting_children);
+  gpr_free(chand->children);
+}
+
+const grpc_channel_filter grpc_client_channel_filter = {
+    call_op,              channel_op,
+
+    sizeof(call_data),    init_call_elem,    destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "clientchannel",
+};
+
+grpc_transport_setup_result grpc_client_channel_transport_setup_complete(
+    grpc_channel_stack *channel_stack, grpc_transport *transport,
+    grpc_channel_filter const **channel_filters, size_t num_channel_filters,
+    grpc_mdctx *mdctx) {
+  /* we just got a new transport: lets create a child channel stack for it */
+  grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
+  channel_data *chand = elem->channel_data;
+  grpc_channel_element *lb_elem;
+  grpc_channel_stack *child_stack;
+  size_t num_child_filters = 2 + num_channel_filters;
+  grpc_channel_filter const **child_filters;
+  grpc_transport_setup_result result;
+  child_entry *child_ent;
+  call_data **waiting_children;
+  size_t waiting_child_count;
+  size_t i;
+  grpc_call_op *call_ops;
+
+  /* build the child filter stack */
+  child_filters = gpr_malloc(sizeof(grpc_channel_filter *) * num_child_filters);
+  /* we always need a link back filter to get back to the connected channel */
+  child_filters[0] = &link_back_filter;
+  for (i = 0; i < num_channel_filters; i++) {
+    child_filters[i + 1] = channel_filters[i];
+  }
+  /* and we always need a connected channel to talk to the transport */
+  child_filters[num_child_filters - 1] = &grpc_connected_channel_filter;
+
+  GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
+
+  /* BEGIN LOCKING CHANNEL */
+  gpr_mu_lock(&chand->mu);
+  chand->transport_setup_initiated = 0;
+
+  if (chand->child_count == chand->child_capacity) {
+    /* realloc will invalidate chand->active_child, but it's reset in the next
+       stanza anyway */
+    chand->child_capacity =
+        GPR_MAX(2 * chand->child_capacity, chand->child_capacity + 2);
+    chand->children = gpr_realloc(chand->children,
+                                  sizeof(child_entry) * chand->child_capacity);
+  }
+
+  /* build up the child stack */
+  child_stack =
+      gpr_malloc(grpc_channel_stack_size(child_filters, num_child_filters));
+  grpc_channel_stack_init(child_filters, num_child_filters, chand->args, mdctx,
+                          child_stack);
+  lb_elem = grpc_channel_stack_element(child_stack, 0);
+  GPR_ASSERT(lb_elem->filter == &link_back_filter);
+  ((lb_channel_data *)lb_elem->channel_data)->back = elem;
+  result = grpc_connected_channel_bind_transport(child_stack, transport);
+  child_ent = &chand->children[chand->child_count++];
+  child_ent->channel_stack = child_stack;
+  child_ent->inflight_requests = 0;
+  chand->active_child = child_ent;
+
+  /* capture the waiting children - we'll activate them outside the lock
+     to avoid re-entrancy problems */
+  waiting_children = chand->waiting_children;
+  waiting_child_count = chand->waiting_child_count;
+  /* bumping up inflight_requests here avoids taking a lock per rpc below */
+
+  chand->waiting_children = NULL;
+  chand->waiting_child_count = 0;
+  chand->waiting_child_capacity = 0;
+
+  call_ops = gpr_malloc(sizeof(grpc_call_op) * waiting_child_count);
+
+  for (i = 0; i < waiting_child_count; i++) {
+    call_ops[i].type = GRPC_SEND_START;
+    call_ops[i].dir = GRPC_CALL_DOWN;
+    call_ops[i].flags = waiting_children[i]->s.waiting.start_flags;
+    call_ops[i].done_cb = waiting_children[i]->s.waiting.on_complete;
+    call_ops[i].user_data =
+        waiting_children[i]->s.waiting.on_complete_user_data;
+    if (!prepare_activate(waiting_children[i], child_ent)) {
+      waiting_children[i] = NULL;
+      call_ops[i].done_cb(call_ops[i].user_data, GRPC_OP_ERROR);
+    }
+  }
+
+  /* END LOCKING CHANNEL */
+  gpr_mu_unlock(&chand->mu);
+
+  /* activate any pending operations - this is safe to do as we guarantee one
+     and only one write operation per request at the surface api - if we lose
+     that guarantee we need to do some curly locking here */
+  for (i = 0; i < waiting_child_count; i++) {
+    if (waiting_children[i]) {
+      complete_activate(waiting_children[i], child_ent, &call_ops[i]);
+    }
+  }
+  gpr_free(waiting_children);
+  gpr_free(call_ops);
+  gpr_free(child_filters);
+
+  return result;
+}
+
+void grpc_client_channel_set_transport_setup(grpc_channel_stack *channel_stack,
+                                             grpc_transport_setup *setup) {
+  /* post construction initialization: set the transport setup pointer */
+  grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
+  channel_data *chand = elem->channel_data;
+  GPR_ASSERT(!chand->transport_setup);
+  chand->transport_setup = setup;
+}
diff --git a/src/core/channel/client_channel.h b/src/core/channel/client_channel.h
new file mode 100644
index 0000000..576af64
--- /dev/null
+++ b/src/core/channel/client_channel.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__
+#define __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* A client channel is a channel that begins disconnected, and can connect
+   to some endpoint on demand. If that endpoint disconnects, it will be
+   connected to again later.
+
+   Calls on a disconnected client channel are queued until a connection is
+   established. */
+
+extern const grpc_channel_filter grpc_client_channel_filter;
+
+/* post-construction initializer to let the client channel know which
+   transport setup it should cancel upon destruction, or initiate when it needs
+   a connection */
+void grpc_client_channel_set_transport_setup(grpc_channel_stack *channel_stack,
+                                             grpc_transport_setup *setup);
+
+/* grpc_transport_setup_callback for binding new transports into a client
+   channel - user_data should be the channel stack containing the client
+   channel */
+grpc_transport_setup_result grpc_client_channel_transport_setup_complete(
+    grpc_channel_stack *channel_stack, grpc_transport *transport,
+    grpc_channel_filter const **channel_filters, size_t num_channel_filters,
+    grpc_mdctx *mdctx);
+
+#endif  /* __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__ */
diff --git a/src/core/channel/client_setup.c b/src/core/channel/client_setup.c
new file mode 100644
index 0000000..c667e39
--- /dev/null
+++ b/src/core/channel/client_setup.c
@@ -0,0 +1,239 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/client_setup.h"
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/channel_stack.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
+struct grpc_client_setup {
+  grpc_transport_setup base; /* must be first */
+  void (*initiate)(void *user_data, grpc_client_setup_request *request);
+  void (*done)(void *user_data);
+  void *user_data;
+  grpc_channel_args *args;
+  grpc_mdctx *mdctx;
+  grpc_em *em;
+  grpc_em_alarm backoff_alarm;
+  gpr_timespec current_backoff_interval;
+  int in_alarm;
+
+  gpr_mu mu;
+  grpc_client_setup_request *active_request;
+  int refs;
+};
+
+struct grpc_client_setup_request {
+  /* pointer back to the setup object */
+  grpc_client_setup *setup;
+  gpr_timespec deadline;
+};
+
+gpr_timespec grpc_client_setup_request_deadline(grpc_client_setup_request *r) {
+  return r->deadline;
+}
+
+static void destroy_setup(grpc_client_setup *s) {
+  gpr_mu_destroy(&s->mu);
+  s->done(s->user_data);
+  grpc_channel_args_destroy(s->args);
+  gpr_free(s);
+}
+
+/* initiate handshaking */
+static void setup_initiate(grpc_transport_setup *sp) {
+  grpc_client_setup *s = (grpc_client_setup *)sp;
+  grpc_client_setup_request *r = gpr_malloc(sizeof(grpc_client_setup_request));
+  int in_alarm = 0;
+
+  r->setup = s;
+  /* TODO(klempner): Actually set a deadline */
+  r->deadline = gpr_inf_future;
+
+  gpr_mu_lock(&s->mu);
+  GPR_ASSERT(s->refs > 0);
+  /* there might be more than one request outstanding if the caller calls
+     initiate in some kind of rapid-fire way: we try to connect each time,
+     and keep track of the latest request (which is the only one that gets
+     to finish) */
+  if (!s->in_alarm) {
+    s->active_request = r;
+    s->refs++;
+  } else {
+    /* TODO(klempner): Maybe do something more clever here */
+    in_alarm = 1;
+  }
+  gpr_mu_unlock(&s->mu);
+
+  if (!in_alarm) {
+    s->initiate(s->user_data, r);
+  } else {
+    gpr_free(r);
+  }
+}
+
+/* cancel handshaking: cancel all requests, and shutdown (the caller promises
+   not to initiate again) */
+static void setup_cancel(grpc_transport_setup *sp) {
+  grpc_client_setup *s = (grpc_client_setup *)sp;
+  void *ignored;
+
+  gpr_mu_lock(&s->mu);
+
+  GPR_ASSERT(s->refs > 0);
+  /* effectively cancels the current request (if any) */
+  s->active_request = NULL;
+  if (s->in_alarm) {
+    grpc_em_alarm_cancel(&s->backoff_alarm, &ignored);
+  }
+  if (--s->refs == 0) {
+    gpr_mu_unlock(&s->mu);
+    destroy_setup(s);
+  } else {
+    gpr_mu_unlock(&s->mu);
+  }
+}
+
+/* vtable for transport setup */
+static const grpc_transport_setup_vtable setup_vtable = {setup_initiate,
+                                                         setup_cancel};
+
+void grpc_client_setup_create_and_attach(
+    grpc_channel_stack *newly_minted_channel, const grpc_channel_args *args,
+    grpc_mdctx *mdctx,
+    void (*initiate)(void *user_data, grpc_client_setup_request *request),
+    void (*done)(void *user_data), void *user_data, grpc_em *em) {
+  grpc_client_setup *s = gpr_malloc(sizeof(grpc_client_setup));
+
+  s->base.vtable = &setup_vtable;
+  gpr_mu_init(&s->mu);
+  s->refs = 1;
+  s->mdctx = mdctx;
+  s->initiate = initiate;
+  s->done = done;
+  s->user_data = user_data;
+  s->em = em;
+  s->active_request = NULL;
+  s->args = grpc_channel_args_copy(args);
+  s->current_backoff_interval = gpr_time_from_micros(1000000);
+  s->in_alarm = 0;
+
+  grpc_client_channel_set_transport_setup(newly_minted_channel, &s->base);
+}
+
+int grpc_client_setup_request_should_continue(grpc_client_setup_request *r) {
+  int result;
+  if (gpr_time_cmp(gpr_now(), r->deadline) > 0) {
+    return 0;
+  }
+  gpr_mu_lock(&r->setup->mu);
+  result = r->setup->active_request == r;
+  gpr_mu_unlock(&r->setup->mu);
+  return result;
+}
+
+static void backoff_alarm_done(void *arg /* grpc_client_setup */,
+                               grpc_em_cb_status status) {
+  grpc_client_setup *s = arg;
+  grpc_client_setup_request *r = gpr_malloc(sizeof(grpc_client_setup_request));
+  r->setup = s;
+  /* TODO(klempner): Set this to something useful */
+  r->deadline = gpr_inf_future;
+  /* Handle status cancelled? */
+  gpr_mu_lock(&s->mu);
+  s->active_request = r;
+  s->in_alarm = 0;
+  if (status != GRPC_CALLBACK_SUCCESS) {
+    if (0 == --s->refs) {
+      gpr_mu_unlock(&s->mu);
+      destroy_setup(s);
+      gpr_free(r);
+      return;
+    } else {
+      gpr_mu_unlock(&s->mu);
+      return;
+    }
+  }
+  gpr_mu_unlock(&s->mu);
+  s->initiate(s->user_data, r);
+}
+
+void grpc_client_setup_request_finish(grpc_client_setup_request *r,
+                                      int was_successful) {
+  int retry = !was_successful;
+  grpc_client_setup *s = r->setup;
+
+  gpr_mu_lock(&s->mu);
+  if (s->active_request == r) {
+    s->active_request = NULL;
+  } else {
+    retry = 0;
+  }
+  if (!retry && 0 == --s->refs) {
+    gpr_mu_unlock(&s->mu);
+    destroy_setup(s);
+    gpr_free(r);
+    return;
+  }
+
+  gpr_free(r);
+
+  if (retry) {
+    /* TODO(klempner): Replace these values with further consideration. 2x is
+       probably too aggressive of a backoff. */
+    gpr_timespec max_backoff = gpr_time_from_micros(120000000);
+    GPR_ASSERT(!s->in_alarm);
+    s->in_alarm = 1;
+    grpc_em_alarm_init(&s->backoff_alarm, s->em, backoff_alarm_done, s);
+    grpc_em_alarm_add(&s->backoff_alarm,
+                      gpr_time_add(s->current_backoff_interval, gpr_now()));
+    s->current_backoff_interval =
+        gpr_time_add(s->current_backoff_interval, s->current_backoff_interval);
+    if (gpr_time_cmp(s->current_backoff_interval, max_backoff) > 0) {
+      s->current_backoff_interval = max_backoff;
+    }
+  }
+
+  gpr_mu_unlock(&s->mu);
+}
+
+const grpc_channel_args *grpc_client_setup_get_channel_args(
+    grpc_client_setup_request *r) {
+  return r->setup->args;
+}
+
+grpc_mdctx *grpc_client_setup_get_mdctx(grpc_client_setup_request *r) {
+  return r->setup->mdctx;
+}
diff --git a/src/core/channel/client_setup.h b/src/core/channel/client_setup.h
new file mode 100644
index 0000000..862c132
--- /dev/null
+++ b/src/core/channel/client_setup.h
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__
+#define __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/eventmanager/em.h"
+#include "src/core/transport/metadata.h"
+#include <grpc/support/time.h>
+
+/* Convenience API's to simplify transport setup */
+
+typedef struct grpc_client_setup grpc_client_setup;
+typedef struct grpc_client_setup_request grpc_client_setup_request;
+
+void grpc_client_setup_create_and_attach(
+    grpc_channel_stack *newly_minted_channel, const grpc_channel_args *args,
+    grpc_mdctx *mdctx,
+    void (*initiate)(void *user_data, grpc_client_setup_request *request),
+    void (*done)(void *user_data), void *user_data, grpc_em *em);
+
+/* Check that r is the active request: needs to be performed at each callback.
+   If this races, we'll have two connection attempts running at once and the
+   old one will get cleaned up in due course, which is fine. */
+int grpc_client_setup_request_should_continue(grpc_client_setup_request *r);
+void grpc_client_setup_request_finish(grpc_client_setup_request *r,
+                                      int was_successful);
+const grpc_channel_args *grpc_client_setup_get_channel_args(
+    grpc_client_setup_request *r);
+
+/* Get the deadline for a request passed in to initiate. Implementations should
+   make a best effort to honor this deadline. */
+gpr_timespec grpc_client_setup_request_deadline(grpc_client_setup_request *r);
+
+grpc_mdctx *grpc_client_setup_get_mdctx(grpc_client_setup_request *r);
+
+#endif  /* __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__ */
diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c
new file mode 100644
index 0000000..336472e
--- /dev/null
+++ b/src/core/channel/connected_channel.c
@@ -0,0 +1,501 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/connected_channel.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "src/core/transport/transport.h"
+#include <grpc/byte_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice_buffer.h>
+#include <grpc/support/string.h>
+
+#define MAX_BUFFER_LENGTH 8192
+/* the protobuf library will (by default) start warning at 100megs */
+#define DEFAULT_MAX_MESSAGE_LENGTH (100 * 1024 * 1024)
+
+typedef struct {
+  grpc_transport *transport;
+  gpr_uint32 max_message_length;
+} channel_data;
+
+typedef struct {
+  grpc_call_element *elem;
+  grpc_stream_op_buffer outgoing_sopb;
+
+  gpr_uint32 max_message_length;
+  gpr_uint32 incoming_message_length;
+  gpr_uint8 reading_message;
+  gpr_uint8 got_metadata_boundary;
+  gpr_uint8 got_read_close;
+  gpr_slice_buffer incoming_message;
+  gpr_uint32 outgoing_buffer_length_estimate;
+} call_data;
+
+/* We perform a small hack to locate transport data alongside the connected
+   channel data in call allocations, to allow everything to be pulled in minimal
+   cache line requests */
+#define TRANSPORT_STREAM_FROM_CALL_DATA(calld) ((grpc_stream *)((calld)+1))
+#define CALL_DATA_FROM_TRANSPORT_STREAM(transport_stream) \
+  (((call_data *)(transport_stream)) - 1)
+
+/* Copy the contents of a byte buffer into stream ops */
+static void copy_byte_buffer_to_stream_ops(grpc_byte_buffer *byte_buffer,
+                                           grpc_stream_op_buffer *sopb) {
+  size_t i;
+
+  switch (byte_buffer->type) {
+    case GRPC_BB_SLICE_BUFFER:
+      for (i = 0; i < byte_buffer->data.slice_buffer.count; i++) {
+        gpr_slice slice = byte_buffer->data.slice_buffer.slices[i];
+        gpr_slice_ref(slice);
+        grpc_sopb_add_slice(sopb, slice);
+      }
+      break;
+  }
+}
+
+/* Flush queued stream operations onto the transport */
+static void end_bufferable_op(grpc_call_op *op, channel_data *chand,
+                              call_data *calld, int is_last) {
+  size_t nops;
+
+  if (op->flags & GRPC_WRITE_BUFFER_HINT) {
+    if (calld->outgoing_buffer_length_estimate < MAX_BUFFER_LENGTH) {
+      op->done_cb(op->user_data, GRPC_OP_OK);
+      return;
+    }
+  }
+
+  calld->outgoing_buffer_length_estimate = 0;
+  grpc_sopb_add_flow_ctl_cb(&calld->outgoing_sopb, op->done_cb, op->user_data);
+
+  nops = calld->outgoing_sopb.nops;
+  calld->outgoing_sopb.nops = 0;
+  grpc_transport_send_batch(chand->transport,
+                            TRANSPORT_STREAM_FROM_CALL_DATA(calld),
+                            calld->outgoing_sopb.ops, nops, is_last);
+}
+
+/* Intercept a call operation and either push it directly up or translate it
+   into transport stream operations */
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+  switch (op->type) {
+    case GRPC_SEND_METADATA:
+      grpc_sopb_add_metadata(&calld->outgoing_sopb, op->data.metadata);
+      grpc_sopb_add_flow_ctl_cb(&calld->outgoing_sopb, op->done_cb,
+                                op->user_data);
+      break;
+    case GRPC_SEND_DEADLINE:
+      grpc_sopb_add_deadline(&calld->outgoing_sopb, op->data.deadline);
+      grpc_sopb_add_flow_ctl_cb(&calld->outgoing_sopb, op->done_cb,
+                                op->user_data);
+      break;
+    case GRPC_SEND_START:
+      grpc_sopb_add_metadata_boundary(&calld->outgoing_sopb);
+      end_bufferable_op(op, chand, calld, 0);
+      break;
+    case GRPC_SEND_MESSAGE:
+      grpc_sopb_add_begin_message(&calld->outgoing_sopb,
+                                  grpc_byte_buffer_length(op->data.message),
+                                  op->flags);
+      copy_byte_buffer_to_stream_ops(op->data.message, &calld->outgoing_sopb);
+      calld->outgoing_buffer_length_estimate +=
+          (5 + grpc_byte_buffer_length(op->data.message));
+      end_bufferable_op(op, chand, calld, 0);
+      break;
+    case GRPC_SEND_FINISH:
+      end_bufferable_op(op, chand, calld, 1);
+      break;
+    case GRPC_REQUEST_DATA:
+      /* re-arm window updates if they were disarmed by finish_message */
+      grpc_transport_set_allow_window_updates(
+          chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), 1);
+      break;
+    case GRPC_CANCEL_OP:
+      grpc_transport_abort_stream(chand->transport,
+                                  TRANSPORT_STREAM_FROM_CALL_DATA(calld),
+                                  GRPC_STATUS_CANCELLED);
+      break;
+    default:
+      GPR_ASSERT(op->dir == GRPC_CALL_UP);
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+/* Currently we assume all channel operations should just be pushed up. */
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  channel_data *chand = elem->channel_data;
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+
+  switch (op->type) {
+    case GRPC_CHANNEL_SHUTDOWN:
+      grpc_transport_close(chand->transport);
+      break;
+    default:
+      GPR_ASSERT(op->dir == GRPC_CALL_UP);
+      grpc_channel_next_op(elem, op);
+      break;
+  }
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  int r;
+
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  calld->elem = elem;
+  grpc_sopb_init(&calld->outgoing_sopb);
+
+  calld->reading_message = 0;
+  calld->got_metadata_boundary = 0;
+  calld->got_read_close = 0;
+  calld->outgoing_buffer_length_estimate = 0;
+  calld->max_message_length = chand->max_message_length;
+  gpr_slice_buffer_init(&calld->incoming_message);
+  r = grpc_transport_init_stream(chand->transport,
+                                 TRANSPORT_STREAM_FROM_CALL_DATA(calld),
+                                 server_transport_data);
+  GPR_ASSERT(r == 0);
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_call_element *elem) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  grpc_sopb_destroy(&calld->outgoing_sopb);
+  gpr_slice_buffer_destroy(&calld->incoming_message);
+  grpc_transport_destroy_stream(chand->transport,
+                                TRANSPORT_STREAM_FROM_CALL_DATA(calld));
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args, grpc_mdctx *mdctx,
+                              int is_first, int is_last) {
+  channel_data *cd = (channel_data *)elem->channel_data;
+  size_t i;
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(is_last);
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  cd->transport = NULL;
+
+  cd->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH;
+  if (args) {
+    for (i = 0; i < args->num_args; i++) {
+      if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_MESSAGE_LENGTH)) {
+        if (args->args[i].type != GRPC_ARG_INTEGER) {
+          gpr_log(GPR_ERROR, "%s ignored: it must be an integer",
+                  GRPC_ARG_MAX_MESSAGE_LENGTH);
+        } else if (args->args[i].value.integer < 0) {
+          gpr_log(GPR_ERROR, "%s ignored: it must be >= 0",
+                  GRPC_ARG_MAX_MESSAGE_LENGTH);
+        } else {
+          cd->max_message_length = args->args[i].value.integer;
+        }
+      }
+    }
+  }
+}
+
+/* Destructor for channel_data */
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  channel_data *cd = (channel_data *)elem->channel_data;
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  grpc_transport_destroy(cd->transport);
+}
+
+const grpc_channel_filter grpc_connected_channel_filter = {
+    call_op,              channel_op,
+
+    sizeof(call_data),    init_call_elem,    destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "connected",
+};
+
+static gpr_slice alloc_recv_buffer(void *user_data, grpc_transport *transport,
+                                   grpc_stream *stream, size_t size_hint) {
+  return gpr_slice_malloc(size_hint);
+}
+
+/* Transport callback to accept a new stream... calls up to handle it */
+static void accept_stream(void *user_data, grpc_transport *transport,
+                          const void *transport_server_data) {
+  grpc_channel_element *elem = user_data;
+  channel_data *chand = elem->channel_data;
+  grpc_channel_op op;
+
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  GPR_ASSERT(chand->transport == transport);
+
+  op.type = GRPC_ACCEPT_CALL;
+  op.dir = GRPC_CALL_UP;
+  op.data.accept_call.transport = transport;
+  op.data.accept_call.transport_server_data = transport_server_data;
+  channel_op(elem, &op);
+}
+
+static void recv_error(channel_data *chand, call_data *calld, int line,
+                       const char *fmt, ...) {
+  char msg[512];
+  va_list a;
+
+  va_start(a, fmt);
+  vsprintf(msg, fmt, a);
+  va_end(a);
+
+  gpr_log(__FILE__, line, GPR_LOG_SEVERITY_ERROR, "%s", msg);
+
+  if (chand->transport) {
+    grpc_transport_abort_stream(chand->transport,
+                                TRANSPORT_STREAM_FROM_CALL_DATA(calld),
+                                GRPC_STATUS_INVALID_ARGUMENT);
+  }
+}
+
+static void do_nothing(void *calldata, grpc_op_error error) {}
+
+static void done_message(void *user_data, grpc_op_error error) {
+  grpc_byte_buffer_destroy(user_data);
+}
+
+static void finish_message(channel_data *chand, call_data *calld) {
+  grpc_call_element *elem = calld->elem;
+  grpc_call_op call_op;
+  call_op.dir = GRPC_CALL_UP;
+  call_op.flags = 0;
+  /* if we got all the bytes for this message, call up the stack */
+  call_op.type = GRPC_RECV_MESSAGE;
+  call_op.done_cb = done_message;
+  /* TODO(ctiller): this could be a lot faster if coded directly */
+  call_op.user_data = call_op.data.message = grpc_byte_buffer_create(
+      calld->incoming_message.slices, calld->incoming_message.count);
+  gpr_slice_buffer_reset_and_unref(&calld->incoming_message);
+
+  /* disable window updates until we get a request more from above */
+  grpc_transport_set_allow_window_updates(
+      chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), 0);
+
+  GPR_ASSERT(calld->incoming_message.count == 0);
+  calld->reading_message = 0;
+  grpc_call_next_op(elem, &call_op);
+}
+
+/* Handle incoming stream ops from the transport, translating them into
+   call_ops to pass up the call stack */
+static void recv_batch(void *user_data, grpc_transport *transport,
+                       grpc_stream *stream, grpc_stream_op *ops,
+                       size_t ops_count, grpc_stream_state final_state) {
+  call_data *calld = CALL_DATA_FROM_TRANSPORT_STREAM(stream);
+  grpc_call_element *elem = calld->elem;
+  channel_data *chand = elem->channel_data;
+  grpc_stream_op *stream_op;
+  grpc_call_op call_op;
+  size_t i;
+  gpr_uint32 length;
+
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+
+  for (i = 0; i < ops_count; i++) {
+    stream_op = ops + i;
+    switch (stream_op->type) {
+      case GRPC_OP_FLOW_CTL_CB:
+        gpr_log(GPR_ERROR,
+                "should not receive flow control ops from transport");
+        abort();
+        break;
+      case GRPC_NO_OP:
+        break;
+      case GRPC_OP_METADATA:
+        call_op.type = GRPC_RECV_METADATA;
+        call_op.dir = GRPC_CALL_UP;
+        call_op.flags = 0;
+        call_op.data.metadata = stream_op->data.metadata;
+        call_op.done_cb = do_nothing;
+        call_op.user_data = NULL;
+        grpc_call_next_op(elem, &call_op);
+        break;
+      case GRPC_OP_DEADLINE:
+        call_op.type = GRPC_RECV_DEADLINE;
+        call_op.dir = GRPC_CALL_UP;
+        call_op.flags = 0;
+        call_op.data.deadline = stream_op->data.deadline;
+        call_op.done_cb = do_nothing;
+        call_op.user_data = NULL;
+        grpc_call_next_op(elem, &call_op);
+        break;
+      case GRPC_OP_METADATA_BOUNDARY:
+        if (!calld->got_metadata_boundary) {
+          calld->got_metadata_boundary = 1;
+          call_op.type = GRPC_RECV_END_OF_INITIAL_METADATA;
+          call_op.dir = GRPC_CALL_UP;
+          call_op.flags = 0;
+          call_op.done_cb = do_nothing;
+          call_op.user_data = NULL;
+          grpc_call_next_op(elem, &call_op);
+        }
+        break;
+      case GRPC_OP_BEGIN_MESSAGE:
+        /* can't begin a message when we're still reading a message */
+        if (calld->reading_message) {
+          recv_error(chand, calld, __LINE__,
+                     "Message terminated early; read %d bytes, expected %d",
+                     calld->incoming_message.length,
+                     calld->incoming_message_length);
+          return;
+        }
+        /* stash away parameters, and prepare for incoming slices */
+        length = stream_op->data.begin_message.length;
+        if (length > calld->max_message_length) {
+          recv_error(
+              chand, calld, __LINE__,
+              "Maximum message length of %d exceeded by a message of length %d",
+              calld->max_message_length, length);
+        } else if (length > 0) {
+          calld->reading_message = 1;
+          calld->incoming_message_length = length;
+        } else {
+          finish_message(chand, calld);
+        }
+        break;
+      case GRPC_OP_SLICE:
+        if (GPR_SLICE_LENGTH(stream_op->data.slice) == 0) {
+          gpr_slice_unref(stream_op->data.slice);
+          break;
+        }
+        /* we have to be reading a message to know what to do here */
+        if (!calld->reading_message) {
+          recv_error(chand, calld, __LINE__,
+                     "Received payload data while not reading a message");
+          return;
+        }
+        /* append the slice to the incoming buffer */
+        gpr_slice_buffer_add(&calld->incoming_message, stream_op->data.slice);
+        if (calld->incoming_message.length > calld->incoming_message_length) {
+          /* if we got too many bytes, complain */
+          recv_error(chand, calld, __LINE__,
+                     "Receiving message overflow; read %d bytes, expected %d",
+                     calld->incoming_message.length,
+                     calld->incoming_message_length);
+          return;
+        } else if (calld->incoming_message.length ==
+                   calld->incoming_message_length) {
+          finish_message(chand, calld);
+        }
+    }
+  }
+  /* if the stream closed, then call up the stack to let it know */
+  if (!calld->got_read_close && (final_state == GRPC_STREAM_RECV_CLOSED ||
+                                 final_state == GRPC_STREAM_CLOSED)) {
+    calld->got_read_close = 1;
+    if (calld->reading_message) {
+      recv_error(chand, calld, __LINE__,
+                 "Last message truncated; read %d bytes, expected %d",
+                 calld->incoming_message.length,
+                 calld->incoming_message_length);
+      return;
+    }
+    call_op.type = GRPC_RECV_HALF_CLOSE;
+    call_op.dir = GRPC_CALL_UP;
+    call_op.flags = 0;
+    call_op.done_cb = do_nothing;
+    call_op.user_data = NULL;
+    grpc_call_next_op(elem, &call_op);
+  }
+  if (final_state == GRPC_STREAM_CLOSED) {
+    call_op.type = GRPC_RECV_FINISH;
+    call_op.dir = GRPC_CALL_UP;
+    call_op.flags = 0;
+    call_op.done_cb = do_nothing;
+    call_op.user_data = NULL;
+    grpc_call_next_op(elem, &call_op);
+  }
+}
+
+static void transport_closed(void *user_data, grpc_transport *transport) {
+  /* transport was closed ==> call up and handle it */
+  grpc_channel_element *elem = user_data;
+  channel_data *chand = elem->channel_data;
+  grpc_channel_op op;
+
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  GPR_ASSERT(chand->transport == transport);
+
+  op.type = GRPC_TRANSPORT_CLOSED;
+  op.dir = GRPC_CALL_UP;
+  channel_op(elem, &op);
+}
+
+const grpc_transport_callbacks connected_channel_transport_callbacks = {
+    alloc_recv_buffer, accept_stream, recv_batch, transport_closed,
+};
+
+grpc_transport_setup_result grpc_connected_channel_bind_transport(
+    grpc_channel_stack *channel_stack, grpc_transport *transport) {
+  /* Assumes that the connected channel filter is always the last filter
+     in a channel stack */
+  grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
+  channel_data *cd = (channel_data *)elem->channel_data;
+  grpc_transport_setup_result ret;
+  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  GPR_ASSERT(cd->transport == NULL);
+  cd->transport = transport;
+
+  /* HACK(ctiller): increase call stack size for the channel to make space
+     for channel data. We need a cleaner (but performant) way to do this,
+     and I'm not sure what that is yet.
+     This is only "safe" because call stacks place no additional data after
+     the last call element, and the last call element MUST be the connected
+     channel. */
+  channel_stack->call_stack_size += grpc_transport_stream_size(transport);
+
+  ret.user_data = elem;
+  ret.callbacks = &connected_channel_transport_callbacks;
+  return ret;
+}
diff --git a/src/core/channel/connected_channel.h b/src/core/channel/connected_channel.h
new file mode 100644
index 0000000..660ea7a
--- /dev/null
+++ b/src/core/channel/connected_channel.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__
+#define __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* A channel filter representing a channel that is on a connected transport.
+   This filter performs actual sending and receiving of messages. */
+
+extern const grpc_channel_filter grpc_connected_channel_filter;
+
+/* Post construction fixup: set the transport in the connected channel.
+   Must be called before any call stack using this filter is used. */
+grpc_transport_setup_result grpc_connected_channel_bind_transport(
+    grpc_channel_stack *channel_stack, grpc_transport *transport);
+
+#endif  /* __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__ */
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
new file mode 100644
index 0000000..b82c735
--- /dev/null
+++ b/src/core/channel/http_client_filter.c
@@ -0,0 +1,143 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/http_client_filter.h"
+#include <grpc/support/log.h>
+
+typedef struct call_data {
+  int unused; /* C89 requires at least one struct element */
+} call_data;
+
+typedef struct channel_data { grpc_mdelem *te_trailers; } channel_data;
+
+/* used to silence 'variable not used' warnings */
+static void ignore_unused(void *ignored) {}
+
+/* Called either:
+     - in response to an API call (or similar) from above, to send something
+     - a network event (or similar) from below, to receive something
+   op contains type and call direction information, in addition to the data
+   that is being sent or received. */
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+  ignore_unused(calld);
+
+  switch (op->type) {
+    case GRPC_SEND_START:
+      /* just prior to starting, add a te: trailers header */
+      grpc_call_element_send_metadata(elem, channeld->te_trailers);
+      grpc_call_next_op(elem, op);
+      break;
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+/* Called on special channel events, such as disconnection or new incoming
+   calls on the server */
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+
+  switch (op->type) {
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_channel_next_op(elem, op);
+      break;
+  }
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+
+  /* initialize members */
+  calld->unused = 0;
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_call_element *elem) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(calld);
+  ignore_unused(channeld);
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args, grpc_mdctx *mdctx,
+                              int is_first, int is_last) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  /* The first and the last filters tend to be implemented differently to
+     handle the case that there's no 'next' filter to call on the up or down
+     path */
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(!is_last);
+
+  /* initialize members */
+  channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers");
+}
+
+/* Destructor for channel data */
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  grpc_mdelem_unref(channeld->te_trailers);
+}
+
+const grpc_channel_filter grpc_http_client_filter = {
+    call_op, channel_op,
+
+    sizeof(call_data), init_call_elem, destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "http-client"};
diff --git a/src/core/channel/http_client_filter.h b/src/core/channel/http_client_filter.h
new file mode 100644
index 0000000..f939cbd
--- /dev/null
+++ b/src/core/channel/http_client_filter.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_HTTP_CLIENT_FILTER_H__
+#define __GRPC_INTERNAL_CHANNEL_HTTP_CLIENT_FILTER_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* Processes metadata on the client side for HTTP2 transports */
+extern const grpc_channel_filter grpc_http_client_filter;
+
+#endif /* __GRPC_INTERNAL_CHANNEL_HTTP_CLIENT_FILTER_H__ */
diff --git a/src/core/channel/http_filter.c b/src/core/channel/http_filter.c
new file mode 100644
index 0000000..b5c1541
--- /dev/null
+++ b/src/core/channel/http_filter.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/http_filter.h"
+#include <grpc/support/log.h>
+
+typedef struct call_data {
+  int unused; /* C89 requires at least one struct element */
+} call_data;
+
+typedef struct channel_data {
+  int unused; /* C89 requires at least one struct element */
+} channel_data;
+
+/* used to silence 'variable not used' warnings */
+static void ignore_unused(void *ignored) {}
+
+/* Called either:
+     - in response to an API call (or similar) from above, to send something
+     - a network event (or similar) from below, to receive something
+   op contains type and call direction information, in addition to the data
+   that is being sent or received. */
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+  ignore_unused(calld);
+  ignore_unused(channeld);
+
+  switch (op->type) {
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+/* Called on special channel events, such as disconnection or new incoming
+   calls on the server */
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+
+  switch (op->type) {
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_channel_next_op(elem, op);
+      break;
+  }
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  /* initialize members */
+  calld->unused = channeld->unused;
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_call_element *elem) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(calld);
+  ignore_unused(channeld);
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args, grpc_mdctx *mdctx,
+                              int is_first, int is_last) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  /* The first and the last filters tend to be implemented differently to
+     handle the case that there's no 'next' filter to call on the up or down
+     path */
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(!is_last);
+
+  /* initialize members */
+  channeld->unused = 0;
+}
+
+/* Destructor for channel data */
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+}
+
+const grpc_channel_filter grpc_http_filter = {
+    call_op, channel_op,
+
+    sizeof(call_data), init_call_elem, destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "http"};
diff --git a/src/core/channel/http_filter.h b/src/core/channel/http_filter.h
new file mode 100644
index 0000000..89ad482
--- /dev/null
+++ b/src/core/channel/http_filter.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_HTTP_FILTER_H__
+#define __GRPC_INTERNAL_CHANNEL_HTTP_FILTER_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* Processes metadata that is common to both client and server for HTTP2
+   transports. */
+extern const grpc_channel_filter grpc_http_filter;
+
+#endif /* __GRPC_INTERNAL_CHANNEL_HTTP_FILTER_H__ */
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
new file mode 100644
index 0000000..b176064
--- /dev/null
+++ b/src/core/channel/http_server_filter.c
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/http_server_filter.h"
+#include <grpc/support/log.h>
+
+typedef struct call_data {
+  int unused; /* C89 requires at least one struct element */
+} call_data;
+
+typedef struct channel_data { grpc_mdelem *te_trailers; } channel_data;
+
+/* used to silence 'variable not used' warnings */
+static void ignore_unused(void *ignored) {}
+
+/* Called either:
+     - in response to an API call (or similar) from above, to send something
+     - a network event (or similar) from below, to receive something
+   op contains type and call direction information, in addition to the data
+   that is being sent or received. */
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+  ignore_unused(calld);
+  ignore_unused(channeld);
+
+  switch (op->type) {
+    case GRPC_RECV_METADATA:
+      /* check if it's a te: trailers header */
+      if (op->data.metadata == channeld->te_trailers) {
+        /* swallow it */
+        grpc_mdelem_unref(op->data.metadata);
+        op->done_cb(op->user_data, GRPC_OP_OK);
+      } else {
+        /* pass the event up */
+        grpc_call_next_op(elem, op);
+      }
+      break;
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+/* Called on special channel events, such as disconnection or new incoming
+   calls on the server */
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+
+  switch (op->type) {
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_channel_next_op(elem, op);
+      break;
+  }
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+
+  /* initialize members */
+  calld->unused = 0;
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_call_element *elem) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(calld);
+  ignore_unused(channeld);
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args, grpc_mdctx *mdctx,
+                              int is_first, int is_last) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  /* The first and the last filters tend to be implemented differently to
+     handle the case that there's no 'next' filter to call on the up or down
+     path */
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(!is_last);
+
+  /* initialize members */
+  channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers");
+}
+
+/* Destructor for channel data */
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  grpc_mdelem_unref(channeld->te_trailers);
+}
+
+const grpc_channel_filter grpc_http_server_filter = {
+    call_op, channel_op,
+
+    sizeof(call_data), init_call_elem, destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "http-server"};
diff --git a/src/core/channel/http_server_filter.h b/src/core/channel/http_server_filter.h
new file mode 100644
index 0000000..5b47543
--- /dev/null
+++ b/src/core/channel/http_server_filter.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_HTTP_SERVER_FILTER_H__
+#define __GRPC_INTERNAL_CHANNEL_HTTP_SERVER_FILTER_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* Processes metadata on the client side for HTTP2 transports */
+extern const grpc_channel_filter grpc_http_server_filter;
+
+#endif /* __GRPC_INTERNAL_CHANNEL_HTTP_SERVER_FILTER_H__ */
diff --git a/src/core/channel/metadata_buffer.c b/src/core/channel/metadata_buffer.c
new file mode 100644
index 0000000..75fd90b
--- /dev/null
+++ b/src/core/channel/metadata_buffer.c
@@ -0,0 +1,198 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/metadata_buffer.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+#include <string.h>
+
+#define INITIAL_ELEM_CAP 8
+
+/* One queued call; we track offsets to string data in a shared buffer to
+   reduce allocations. See grpc_metadata_buffer_impl for the memory use
+   strategy */
+typedef struct {
+  grpc_mdelem *md;
+  void (*cb)(void *user_data, grpc_op_error error);
+  void *user_data;
+  gpr_uint32 flags;
+} qelem;
+
+/* Memory layout:
+
+  grpc_metadata_buffer_impl
+  followed by an array of qelem  */
+struct grpc_metadata_buffer_impl {
+  /* number of elements in q */
+  size_t elems;
+  /* capacity of q */
+  size_t elem_cap;
+};
+
+#define ELEMS(buffer) ((qelem *)((buffer)+1))
+
+void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer) {
+  /* start buffer as NULL, indicating no elements */
+  *buffer = NULL;
+}
+
+void grpc_metadata_buffer_destroy(grpc_metadata_buffer *buffer,
+                                  grpc_op_error error) {
+  size_t i;
+  qelem *qe;
+  if (*buffer) {
+    for (i = 0; i < (*buffer)->elems; i++) {
+      qe = &ELEMS(*buffer)[i];
+      grpc_mdelem_unref(qe->md);
+      qe->cb(qe->user_data, error);
+    }
+    gpr_free(*buffer);
+  }
+}
+
+void grpc_metadata_buffer_queue(grpc_metadata_buffer *buffer,
+                                grpc_call_op *op) {
+  grpc_metadata_buffer_impl *impl = *buffer;
+  qelem *qe;
+  size_t bytes;
+
+  GPR_ASSERT(op->type == GRPC_SEND_METADATA || op->type == GRPC_RECV_METADATA);
+
+  if (!impl) {
+    /* this is the first element: allocate enough space to hold the
+       header object and the initial element capacity of qelems */
+    bytes =
+        sizeof(grpc_metadata_buffer_impl) + INITIAL_ELEM_CAP * sizeof(qelem);
+    impl = gpr_malloc(bytes);
+    /* initialize the header object */
+    impl->elems = 0;
+    impl->elem_cap = INITIAL_ELEM_CAP;
+  } else if (impl->elems == impl->elem_cap) {
+    /* more qelems than what we can deal with: grow by doubling size */
+    impl->elem_cap *= 2;
+    bytes = sizeof(grpc_metadata_buffer_impl) + impl->elem_cap * sizeof(qelem);
+    impl = gpr_realloc(impl, bytes);
+  }
+
+  /* append an element to the queue */
+  qe = &ELEMS(impl)[impl->elems];
+  impl->elems++;
+
+  qe->md = op->data.metadata;
+  qe->cb = op->done_cb;
+  qe->user_data = op->user_data;
+  qe->flags = op->flags;
+
+  /* header object may have changed location: store it back */
+  *buffer = impl;
+}
+
+void grpc_metadata_buffer_flush(grpc_metadata_buffer *buffer,
+                                grpc_call_element *elem) {
+  grpc_metadata_buffer_impl *impl = *buffer;
+  grpc_call_op op;
+  qelem *qe;
+  size_t i;
+
+  if (!impl) {
+    /* nothing to send */
+    return;
+  }
+
+  /* construct call_op's, and push them down the stack */
+  op.type = GRPC_SEND_METADATA;
+  op.dir = GRPC_CALL_DOWN;
+  for (i = 0; i < impl->elems; i++) {
+    qe = &ELEMS(impl)[i];
+    op.done_cb = qe->cb;
+    op.user_data = qe->user_data;
+    op.flags = qe->flags;
+    op.data.metadata = qe->md;
+    grpc_call_next_op(elem, &op);
+  }
+
+  /* free data structures and reset to NULL: we can only flush once */
+  gpr_free(impl);
+  *buffer = NULL;
+}
+
+size_t grpc_metadata_buffer_count(const grpc_metadata_buffer *buffer) {
+  return *buffer ? (*buffer)->elems : 0;
+}
+
+typedef struct { grpc_metadata_buffer_impl *impl; } elems_hdr;
+
+grpc_metadata *grpc_metadata_buffer_extract_elements(
+    grpc_metadata_buffer *buffer) {
+  grpc_metadata_buffer_impl *impl;
+  elems_hdr *hdr;
+  qelem *src;
+  grpc_metadata *out;
+  size_t i;
+
+  impl = *buffer;
+
+  if (!impl) {
+    return NULL;
+  }
+
+  hdr = gpr_malloc(sizeof(elems_hdr) + impl->elems * sizeof(grpc_metadata));
+  src = ELEMS(impl);
+  out = (grpc_metadata *)(hdr + 1);
+
+  hdr->impl = impl;
+  for (i = 0; i < impl->elems; i++) {
+    out[i].key = (char *)grpc_mdstr_as_c_string(src[i].md->key);
+    out[i].value = (char *)grpc_mdstr_as_c_string(src[i].md->value);
+    out[i].value_length = GPR_SLICE_LENGTH(src[i].md->value->slice);
+  }
+
+  /* clear out buffer (it's not possible to extract elements twice */
+  *buffer = NULL;
+
+  return out;
+}
+
+void grpc_metadata_buffer_cleanup_elements(void *elements,
+                                           grpc_op_error error) {
+  elems_hdr *hdr = ((elems_hdr *)elements) - 1;
+
+  if (!elements) {
+    return;
+  }
+
+  grpc_metadata_buffer_destroy(&hdr->impl, error);
+  gpr_free(hdr);
+}
diff --git a/src/core/channel/metadata_buffer.h b/src/core/channel/metadata_buffer.h
new file mode 100644
index 0000000..818b290
--- /dev/null
+++ b/src/core/channel/metadata_buffer.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__
+#define __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* Utility code to buffer GRPC_SEND_METADATA calls and pass them down the stack
+   all at once at some otherwise-determined time. Useful for implementing
+   filters that want to queue metadata until a START event chooses some
+   underlying filter stack to send an rpc on. */
+
+/* Clients should declare a member of grpc_metadata_buffer. This may at some
+   point become a typedef for a struct, but for now a pointer suffices */
+typedef struct grpc_metadata_buffer_impl grpc_metadata_buffer_impl;
+typedef grpc_metadata_buffer_impl *grpc_metadata_buffer;
+
+/* Initializes the metadata buffer. Allocates no memory. */
+void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer);
+/* Destroy the metadata buffer. */
+void grpc_metadata_buffer_destroy(grpc_metadata_buffer *buffer,
+                                  grpc_op_error error);
+/* Append a call to the end of a metadata buffer: may allocate memory */
+void grpc_metadata_buffer_queue(grpc_metadata_buffer *buffer, grpc_call_op *op);
+/* Flush all queued operations from the metadata buffer to the element below
+   self */
+void grpc_metadata_buffer_flush(grpc_metadata_buffer *buffer,
+                                grpc_call_element *self);
+/* Count the number of queued elements in the buffer. */
+size_t grpc_metadata_buffer_count(const grpc_metadata_buffer *buffer);
+/* Extract elements as a grpc_metadata*, for presentation to applications.
+   The returned buffer must be freed with
+   grpc_metadata_buffer_cleanup_elements.
+   Clears the metadata buffer (this is a one-shot operation) */
+grpc_metadata *grpc_metadata_buffer_extract_elements(
+    grpc_metadata_buffer *buffer);
+void grpc_metadata_buffer_cleanup_elements(void *elements, grpc_op_error error);
+
+#endif  /* __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__ */
diff --git a/src/core/channel/noop_filter.c b/src/core/channel/noop_filter.c
new file mode 100644
index 0000000..705df4a
--- /dev/null
+++ b/src/core/channel/noop_filter.c
@@ -0,0 +1,138 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/noop_filter.h"
+#include <grpc/support/log.h>
+
+typedef struct call_data {
+  int unused; /* C89 requires at least one struct element */
+} call_data;
+
+typedef struct channel_data {
+  int unused; /* C89 requires at least one struct element */
+} channel_data;
+
+/* used to silence 'variable not used' warnings */
+static void ignore_unused(void *ignored) {}
+
+/* Called either:
+     - in response to an API call (or similar) from above, to send something
+     - a network event (or similar) from below, to receive something
+   op contains type and call direction information, in addition to the data
+   that is being sent or received. */
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(calld);
+  ignore_unused(channeld);
+
+  switch (op->type) {
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+/* Called on special channel events, such as disconnection or new incoming
+   calls on the server */
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+
+  switch (op->type) {
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_channel_next_op(elem, op);
+      break;
+  }
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  /* initialize members */
+  calld->unused = channeld->unused;
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_call_element *elem) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(calld);
+  ignore_unused(channeld);
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args, grpc_mdctx *mdctx,
+                              int is_first, int is_last) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  /* The first and the last filters tend to be implemented differently to
+     handle the case that there's no 'next' filter to call on the up or down
+     path */
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(!is_last);
+
+  /* initialize members */
+  channeld->unused = 0;
+}
+
+/* Destructor for channel data */
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  ignore_unused(channeld);
+}
+
+const grpc_channel_filter grpc_no_op_filter = {
+    call_op,              channel_op,
+
+    sizeof(call_data),    init_call_elem,    destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "no-op"};
diff --git a/src/core/channel/noop_filter.h b/src/core/channel/noop_filter.h
new file mode 100644
index 0000000..4057ff7
--- /dev/null
+++ b/src/core/channel/noop_filter.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__
+#define __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__
+
+#include "src/core/channel/channel_stack.h"
+
+/* No-op filter: simply takes everything it's given, and passes it on to the
+   next filter. Exists simply as a starting point that others can take and
+   customize for their own filters */
+extern const grpc_channel_filter grpc_no_op_filter;
+
+#endif  /* __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__ */
diff --git a/src/core/compression/algorithm.c b/src/core/compression/algorithm.c
new file mode 100644
index 0000000..0b5576f
--- /dev/null
+++ b/src/core/compression/algorithm.c
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/compression/algorithm.h"
+
+const char *grpc_compression_algorithm_name(
+    grpc_compression_algorithm algorithm) {
+  switch (algorithm) {
+    case GRPC_COMPRESS_NONE:
+      return "none";
+    case GRPC_COMPRESS_DEFLATE:
+      return "deflate";
+    case GRPC_COMPRESS_GZIP:
+      return "gzip";
+    case GRPC_COMPRESS_ALGORITHMS_COUNT:
+      return "error";
+  }
+  return "error";
+}
diff --git a/src/core/compression/algorithm.h b/src/core/compression/algorithm.h
new file mode 100644
index 0000000..05895a8
--- /dev/null
+++ b/src/core/compression/algorithm.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__
+#define __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__
+
+/* The various compression algorithms supported by GRPC */
+typedef enum {
+  GRPC_COMPRESS_NONE = 0,
+  GRPC_COMPRESS_DEFLATE,
+  GRPC_COMPRESS_GZIP,
+  /* TODO(ctiller): snappy */
+  GRPC_COMPRESS_ALGORITHMS_COUNT
+} grpc_compression_algorithm;
+
+const char *grpc_compression_algorithm_name(
+    grpc_compression_algorithm algorithm);
+
+#endif  /* __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__ */
diff --git a/src/core/compression/message_compress.c b/src/core/compression/message_compress.c
new file mode 100644
index 0000000..1787ccd
--- /dev/null
+++ b/src/core/compression/message_compress.c
@@ -0,0 +1,193 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/compression/message_compress.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include <zlib.h>
+
+#define OUTPUT_BLOCK_SIZE 1024
+
+static int zlib_body(z_stream *zs, gpr_slice_buffer *input,
+                     gpr_slice_buffer *output,
+                     int (*flate)(z_stream *zs, int flush)) {
+  int r;
+  int flush;
+  size_t i;
+  size_t output_bytes = 0;
+  gpr_slice outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE);
+
+  zs->avail_out = GPR_SLICE_LENGTH(outbuf);
+  zs->next_out = GPR_SLICE_START_PTR(outbuf);
+  flush = Z_NO_FLUSH;
+  for (i = 0; i < input->count; i++) {
+    if (i == input->count - 1) flush = Z_FINISH;
+    zs->avail_in = GPR_SLICE_LENGTH(input->slices[i]);
+    zs->next_in = GPR_SLICE_START_PTR(input->slices[i]);
+    do {
+      if (zs->avail_out == 0) {
+        output_bytes += GPR_SLICE_LENGTH(outbuf);
+        gpr_slice_buffer_add_indexed(output, outbuf);
+        outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE);
+        zs->avail_out = GPR_SLICE_LENGTH(outbuf);
+        zs->next_out = GPR_SLICE_START_PTR(outbuf);
+      }
+      r = flate(zs, flush);
+      if (r == Z_STREAM_ERROR) {
+        gpr_log(GPR_INFO, "zlib: stream error");
+        goto error;
+      }
+    } while (zs->avail_out == 0);
+    if (zs->avail_in) {
+      gpr_log(GPR_INFO, "zlib: not all input consumed");
+      goto error;
+    }
+  }
+
+  GPR_ASSERT(outbuf.refcount);
+  outbuf.data.refcounted.length -= zs->avail_out;
+  output_bytes += GPR_SLICE_LENGTH(outbuf);
+  gpr_slice_buffer_add_indexed(output, outbuf);
+
+  return 1;
+
+error:
+  gpr_slice_unref(outbuf);
+  return 0;
+}
+
+static int zlib_compress(gpr_slice_buffer *input, gpr_slice_buffer *output,
+                         int gzip) {
+  z_stream zs;
+  int r;
+  size_t i;
+  size_t count_before = output->count;
+  size_t length_before = output->length;
+  memset(&zs, 0, sizeof(zs));
+  r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0),
+                   8, Z_DEFAULT_STRATEGY);
+  if (r != Z_OK) {
+    gpr_log(GPR_ERROR, "deflateInit2 returns %d", r);
+    return 0;
+  }
+  r = zlib_body(&zs, input, output, deflate) && output->length < input->length;
+  if (!r) {
+    for (i = count_before; i < output->count; i++) {
+      gpr_slice_unref(output->slices[i]);
+    }
+    output->count = count_before;
+    output->length = length_before;
+  }
+  deflateEnd(&zs);
+  return r;
+}
+
+static int zlib_decompress(gpr_slice_buffer *input, gpr_slice_buffer *output,
+                           int gzip) {
+  z_stream zs;
+  int r;
+  size_t i;
+  size_t count_before = output->count;
+  size_t length_before = output->length;
+  memset(&zs, 0, sizeof(zs));
+  r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
+  if (r != Z_OK) {
+    gpr_log(GPR_ERROR, "inflateInit2 returns %d", r);
+    return 0;
+  }
+  r = zlib_body(&zs, input, output, inflate);
+  if (!r) {
+    for (i = count_before; i < output->count; i++) {
+      gpr_slice_unref(output->slices[i]);
+    }
+    output->count = count_before;
+    output->length = length_before;
+  }
+  inflateEnd(&zs);
+  return r;
+}
+
+static int copy(gpr_slice_buffer *input, gpr_slice_buffer *output) {
+  size_t i;
+  for (i = 0; i < input->count; i++) {
+    gpr_slice_buffer_add(output, gpr_slice_ref(input->slices[i]));
+  }
+  return 1;
+}
+
+int compress_inner(grpc_compression_algorithm algorithm,
+                   gpr_slice_buffer *input, gpr_slice_buffer *output) {
+  switch (algorithm) {
+    case GRPC_COMPRESS_NONE:
+      /* the fallback path always needs to be send uncompressed: we simply
+         rely on that here */
+      return 0;
+    case GRPC_COMPRESS_DEFLATE:
+      return zlib_compress(input, output, 0);
+    case GRPC_COMPRESS_GZIP:
+      return zlib_compress(input, output, 1);
+    case GRPC_COMPRESS_ALGORITHMS_COUNT:
+      break;
+  }
+  gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm);
+  return 0;
+}
+
+int grpc_msg_compress(grpc_compression_algorithm algorithm,
+                      gpr_slice_buffer *input, gpr_slice_buffer *output) {
+  if (!compress_inner(algorithm, input, output)) {
+    copy(input, output);
+    return 0;
+  }
+  return 1;
+}
+
+int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+                        gpr_slice_buffer *input, gpr_slice_buffer *output) {
+  switch (algorithm) {
+    case GRPC_COMPRESS_NONE:
+      return copy(input, output);
+    case GRPC_COMPRESS_DEFLATE:
+      return zlib_decompress(input, output, 0);
+    case GRPC_COMPRESS_GZIP:
+      return zlib_decompress(input, output, 1);
+    case GRPC_COMPRESS_ALGORITHMS_COUNT:
+      break;
+  }
+  gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm);
+  return 0;
+}
diff --git a/src/core/compression/message_compress.h b/src/core/compression/message_compress.h
new file mode 100644
index 0000000..af8a0a5
--- /dev/null
+++ b/src/core/compression/message_compress.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__
+#define __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__
+
+#include "src/core/compression/algorithm.h"
+#include <grpc/support/slice_buffer.h>
+
+/* compress 'input' to 'output' using 'algorithm'.
+   On success, appends compressed slices to output and returns 1.
+   On failure, appends uncompressed slices to output and returns 0. */
+int grpc_msg_compress(grpc_compression_algorithm algorithm,
+                      gpr_slice_buffer *input, gpr_slice_buffer *output);
+
+/* decompress 'input' to 'output' using 'algorithm'.
+   On success, appends slices to output and returns 1.
+   On failure, output is unchanged, and returns 0. */
+int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+                        gpr_slice_buffer *input, gpr_slice_buffer *output);
+
+#endif  /* __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__ */
diff --git a/src/core/endpoint/endpoint.c b/src/core/endpoint/endpoint.c
new file mode 100644
index 0000000..0735375
--- /dev/null
+++ b/src/core/endpoint/endpoint.c
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/endpoint/endpoint.h"
+
+void grpc_endpoint_notify_on_read(grpc_endpoint *ep, grpc_endpoint_read_cb cb,
+                                  void *user_data, gpr_timespec deadline) {
+  ep->vtable->notify_on_read(ep, cb, user_data, deadline);
+}
+
+grpc_endpoint_write_status grpc_endpoint_write(
+    grpc_endpoint *ep, gpr_slice *slices, size_t nslices,
+    grpc_endpoint_write_cb cb, void *user_data, gpr_timespec deadline) {
+  return ep->vtable->write(ep, slices, nslices, cb, user_data, deadline);
+}
+
+void grpc_endpoint_shutdown(grpc_endpoint *ep) { ep->vtable->shutdown(ep); }
+
+void grpc_endpoint_destroy(grpc_endpoint *ep) { ep->vtable->destroy(ep); }
diff --git a/src/core/endpoint/endpoint.h b/src/core/endpoint/endpoint.h
new file mode 100644
index 0000000..14d9a56
--- /dev/null
+++ b/src/core/endpoint/endpoint.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_ENDPOINT_ENDPOINT_H__
+#define __GRPC_INTERNAL_ENDPOINT_ENDPOINT_H__
+
+#include <grpc/support/slice.h>
+#include <grpc/support/time.h>
+
+/* An endpoint caps a streaming channel between two communicating processes.
+   Examples may be: a tcp socket, <stdin+stdout>, or some shared memory. */
+
+typedef struct grpc_endpoint grpc_endpoint;
+typedef struct grpc_endpoint_vtable grpc_endpoint_vtable;
+
+typedef enum grpc_endpoint_cb_status {
+  GRPC_ENDPOINT_CB_OK = 0, /* Call completed successfully */
+  GRPC_ENDPOINT_CB_EOF, /* Call completed successfully, end of file reached */
+  GRPC_ENDPOINT_CB_SHUTDOWN, /* Call interrupted by shutdown */
+  GRPC_ENDPOINT_CB_ERROR,    /* Call interrupted by socket error */
+  GRPC_ENDPOINT_CB_TIMED_OUT /* Call timed out */
+} grpc_endpoint_cb_status;
+
+typedef enum grpc_endpoint_write_status {
+  GRPC_ENDPOINT_WRITE_DONE,    /* completed immediately, cb won't be called */
+  GRPC_ENDPOINT_WRITE_PENDING, /* cb will be called when completed */
+  GRPC_ENDPOINT_WRITE_ERROR    /* write errored out, cb won't be called */
+} grpc_endpoint_write_status;
+
+typedef void (*grpc_endpoint_read_cb)(void *user_data, gpr_slice *slices,
+                                      size_t nslices,
+                                      grpc_endpoint_cb_status error);
+typedef void (*grpc_endpoint_write_cb)(void *user_data,
+                                       grpc_endpoint_cb_status error);
+
+struct grpc_endpoint_vtable {
+  void (*notify_on_read)(grpc_endpoint *ep, grpc_endpoint_read_cb cb,
+                         void *user_data, gpr_timespec deadline);
+  grpc_endpoint_write_status (*write)(grpc_endpoint *ep, gpr_slice *slices,
+                                      size_t nslices, grpc_endpoint_write_cb cb,
+                                      void *user_data, gpr_timespec deadline);
+  void (*shutdown)(grpc_endpoint *ep);
+  void (*destroy)(grpc_endpoint *ep);
+};
+
+/* When data is available on the connection, calls the callback with slices. */
+void grpc_endpoint_notify_on_read(grpc_endpoint *ep, grpc_endpoint_read_cb cb,
+                                  void *user_data, gpr_timespec deadline);
+
+/* Write slices out to the socket.
+
+   If the connection is ready for more data after the end of the call, it
+   returns GRPC_ENDPOINT_WRITE_DONE.
+   Otherwise it returns GRPC_ENDPOINT_WRITE_PENDING and calls cb when the
+   connection is ready for more data. */
+grpc_endpoint_write_status grpc_endpoint_write(
+    grpc_endpoint *ep, gpr_slice *slices, size_t nslices,
+    grpc_endpoint_write_cb cb, void *user_data, gpr_timespec deadline);
+
+/* Causes any pending read/write callbacks to run immediately with
+   GRPC_ENDPOINT_CB_SHUTDOWN status */
+void grpc_endpoint_shutdown(grpc_endpoint *ep);
+void grpc_endpoint_destroy(grpc_endpoint *ep);
+
+struct grpc_endpoint {
+  const grpc_endpoint_vtable *vtable;
+};
+
+#endif  /* __GRPC_INTERNAL_ENDPOINT_ENDPOINT_H__ */
diff --git a/src/core/endpoint/resolve_address.c b/src/core/endpoint/resolve_address.c
new file mode 100644
index 0000000..aa21954
--- /dev/null
+++ b/src/core/endpoint/resolve_address.c
@@ -0,0 +1,195 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define _POSIX_SOURCE
+
+#include "src/core/endpoint/resolve_address.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/string.h>
+#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+
+typedef struct {
+  char *name;
+  char *default_port;
+  grpc_resolve_cb cb;
+  void *arg;
+} request;
+
+static void split_host_port(const char *name, char **host, char **port) {
+  const char *host_start;
+  size_t host_len;
+  const char *port_start;
+
+  *host = NULL;
+  *port = NULL;
+
+  if (name[0] == '[') {
+    /* Parse a bracketed host, typically an IPv6 literal. */
+    const char *rbracket = strchr(name, ']');
+    if (rbracket == NULL) {
+      /* Unmatched [ */
+      return;
+    }
+    if (rbracket[1] == '\0') {
+      /* ]<end> */
+      port_start = NULL;
+    } else if (rbracket[1] == ':') {
+      /* ]:<port?> */
+      port_start = rbracket + 2;
+    } else {
+      /* ]<invalid> */
+      return;
+    }
+    host_start = name + 1;
+    host_len = rbracket - host_start;
+    if (memchr(host_start, ':', host_len) == NULL) {
+      /* Require all bracketed hosts to contain a colon, because a hostname or
+         IPv4 address should never use brackets. */
+      return;
+    }
+  } else {
+    const char *colon = strchr(name, ':');
+    if (colon != NULL && strchr(colon + 1, ':') == NULL) {
+      /* Exactly 1 colon.  Split into host:port. */
+      host_start = name;
+      host_len = colon - name;
+      port_start = colon + 1;
+    } else {
+      /* 0 or 2+ colons.  Bare hostname or IPv6 litearal. */
+      host_start = name;
+      host_len = strlen(name);
+      port_start = NULL;
+    }
+  }
+
+  /* Allocate return values. */
+  *host = gpr_malloc(host_len + 1);
+  memcpy(*host, host_start, host_len);
+  (*host)[host_len] = '\0';
+
+  if (port_start != NULL) {
+    *port = gpr_strdup(port_start);
+  }
+}
+
+grpc_resolved_addresses *grpc_blocking_resolve_address(
+    const char *name, const char *default_port) {
+  struct addrinfo hints;
+  struct addrinfo *result = NULL, *resp;
+  char *host;
+  char *port;
+  int s;
+  size_t i;
+  grpc_resolved_addresses *addrs = NULL;
+
+  /* parse name, splitting it into host and port parts */
+  split_host_port(name, &host, &port);
+  if (host == NULL) {
+    gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name);
+    goto done;
+  }
+  if (port == NULL) {
+    if (default_port == NULL) {
+      gpr_log(GPR_ERROR, "no port in name '%s'", name);
+      goto done;
+    }
+    port = gpr_strdup(default_port);
+  }
+
+  /* Call getaddrinfo */
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = AF_UNSPEC;     /* ipv4 or ipv6 */
+  hints.ai_socktype = SOCK_STREAM; /* stream socket */
+  hints.ai_flags = AI_PASSIVE;     /* for wildcard IP address */
+
+  s = getaddrinfo(host, port, &hints, &result);
+  if (s != 0) {
+    gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s));
+    goto done;
+  }
+
+  /* Success path: set addrs non-NULL, fill it in */
+  addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
+  addrs->naddrs = 0;
+  for (resp = result; resp != NULL; resp = resp->ai_next) {
+    addrs->naddrs++;
+  }
+  addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs);
+  i = 0;
+  for (resp = result; resp != NULL; resp = resp->ai_next) {
+    memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen);
+    addrs->addrs[i].len = resp->ai_addrlen;
+    i++;
+  }
+
+done:
+  gpr_free(host);
+  gpr_free(port);
+  if (result) {
+    freeaddrinfo(result);
+  }
+  return addrs;
+}
+
+/* Thread function to asynch-ify grpc_blocking_resolve_address */
+static void do_request(void *rp) {
+  request *r = rp;
+  r->cb(r->arg, grpc_blocking_resolve_address(r->name, r->default_port));
+  gpr_free(r->name);
+  gpr_free(r->default_port);
+  gpr_free(r);
+}
+
+void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
+  gpr_free(addrs->addrs);
+  gpr_free(addrs);
+}
+
+void grpc_resolve_address(const char *name, const char *default_port,
+                          grpc_resolve_cb cb, void *arg) {
+  request *r = gpr_malloc(sizeof(request));
+  gpr_thd_id id;
+  r->name = gpr_strdup(name);
+  r->default_port = gpr_strdup(default_port);
+  r->cb = cb;
+  r->arg = arg;
+  gpr_thd_new(&id, do_request, r, NULL);
+}
diff --git a/src/core/endpoint/resolve_address.h b/src/core/endpoint/resolve_address.h
new file mode 100644
index 0000000..cc32c47
--- /dev/null
+++ b/src/core/endpoint/resolve_address.h
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_ENDPOINT_RESOLVE_ADDRESS_H__
+#define __GRPC_INTERNAL_ENDPOINT_RESOLVE_ADDRESS_H__
+
+#include <sys/socket.h>
+
+typedef struct {
+  struct sockaddr_storage addr;
+  int len;
+} grpc_resolved_address;
+
+typedef struct {
+  size_t naddrs;
+  grpc_resolved_address *addrs;
+} grpc_resolved_addresses;
+
+/* Async result callback:
+   On success: addresses is the result, and the callee must call
+   grpc_resolved_addresses_destroy when it's done with them
+   On failure: addresses is NULL */
+typedef void (*grpc_resolve_cb)(void *arg, grpc_resolved_addresses *addresses);
+/* Asynchronously resolve addr. Use default_port if a port isn't designated
+   in addr, otherwise use the port in addr. */
+/* TODO(ctiller): add a timeout here */
+void grpc_resolve_address(const char *addr, const char *default_port,
+                          grpc_resolve_cb cb, void *arg);
+/* Destroy resolved addresses */
+void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addresses);
+
+/* Resolve addr in a blocking fashion. Returns NULL on failure. On success,
+   result must be freed with grpc_resolved_addresses_destroy. */
+grpc_resolved_addresses *grpc_blocking_resolve_address(
+    const char *addr, const char *default_port);
+
+#endif  /* __GRPC_INTERNAL_ENDPOINT_RESOLVE_ADDRESS_H__ */
diff --git a/src/core/endpoint/secure_endpoint.c b/src/core/endpoint/secure_endpoint.c
new file mode 100644
index 0000000..4fab0fa
--- /dev/null
+++ b/src/core/endpoint/secure_endpoint.c
@@ -0,0 +1,335 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/endpoint/secure_endpoint.h"
+#include "src/core/tsi/transport_security_interface.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+
+#define STAGING_BUFFER_SIZE 8192
+
+typedef struct {
+  grpc_endpoint base;
+  grpc_endpoint *wrapped_ep;
+  struct tsi_frame_protector *protector;
+  gpr_mu protector_mu;
+  /* saved upper level callbacks and user_data. */
+  grpc_endpoint_read_cb read_cb;
+  void *read_user_data;
+  /* saved handshaker leftover data to unprotect. */
+  gpr_slice_buffer leftover_bytes;
+  /* buffers for read and write */
+  gpr_slice read_staging_buffer;
+  gpr_slice_buffer input_buffer;
+
+  gpr_slice write_staging_buffer;
+  gpr_slice_buffer output_buffer;
+
+  gpr_refcount ref;
+} secure_endpoint;
+
+static void secure_endpoint_ref(secure_endpoint *ep) { gpr_ref(&ep->ref); }
+
+static void destroy(secure_endpoint *secure_ep) {
+  secure_endpoint *ep = (secure_endpoint *)secure_ep;
+  grpc_endpoint_destroy(ep->wrapped_ep);
+  tsi_frame_protector_destroy(ep->protector);
+  gpr_slice_buffer_destroy(&ep->leftover_bytes);
+  gpr_slice_unref(ep->read_staging_buffer);
+  gpr_slice_buffer_destroy(&ep->input_buffer);
+  gpr_slice_unref(ep->write_staging_buffer);
+  gpr_slice_buffer_destroy(&ep->output_buffer);
+  gpr_mu_destroy(&ep->protector_mu);
+  gpr_free(ep);
+}
+
+static void secure_endpoint_unref(secure_endpoint *ep) {
+  if (gpr_unref(&ep->ref)) {
+    destroy(ep);
+  }
+}
+
+static void flush_read_staging_buffer(secure_endpoint *ep, gpr_uint8 **cur,
+                                      gpr_uint8 **end) {
+  gpr_slice_buffer_add(&ep->input_buffer, ep->read_staging_buffer);
+  ep->read_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE);
+  *cur = GPR_SLICE_START_PTR(ep->read_staging_buffer);
+  *end = GPR_SLICE_END_PTR(ep->read_staging_buffer);
+}
+
+static void call_read_cb(secure_endpoint *ep, gpr_slice *slices, size_t nslices,
+                         grpc_endpoint_cb_status error) {
+#ifdef GRPC_TRACE_SECURE_TRANSPORT
+  size_t i;
+  for (i = 0; i < nslices; i++) {
+    char *data =
+        gpr_hexdump((char*)GPR_SLICE_START_PTR(slices[i]),
+            GPR_SLICE_LENGTH(slices[i]), GPR_HEXDUMP_PLAINTEXT);
+    gpr_log(GPR_DEBUG, "READ %p: %s", ep, data);
+    gpr_free(data);
+  }
+#endif
+  ep->read_cb(ep->read_user_data, slices, nslices, error);
+  secure_endpoint_unref(ep);
+}
+
+static void on_read(void *user_data, gpr_slice *slices, size_t nslices,
+                    grpc_endpoint_cb_status error) {
+  int i = 0;
+  gpr_uint8 keep_looping = 0;
+  int input_buffer_count = 0;
+  tsi_result result = TSI_OK;
+  secure_endpoint *ep = (secure_endpoint *)user_data;
+  gpr_uint8 *cur = GPR_SLICE_START_PTR(ep->read_staging_buffer);
+  gpr_uint8 *end = GPR_SLICE_END_PTR(ep->read_staging_buffer);
+
+  /* TODO(yangg) check error, maybe bail out early */
+  for (i = 0; i < nslices; i++) {
+    gpr_slice encrypted = slices[i];
+    gpr_uint8 *message_bytes = GPR_SLICE_START_PTR(encrypted);
+    size_t message_size = GPR_SLICE_LENGTH(encrypted);
+
+    while (message_size > 0 || keep_looping) {
+      gpr_uint32 unprotected_buffer_size_written = end - cur;
+      gpr_uint32 processed_message_size = message_size;
+      gpr_mu_lock(&ep->protector_mu);
+      result = tsi_frame_protector_unprotect(ep->protector, message_bytes,
+                                             &processed_message_size, cur,
+                                             &unprotected_buffer_size_written);
+      gpr_mu_unlock(&ep->protector_mu);
+      if (result != TSI_OK) {
+        gpr_log(GPR_ERROR, "Decryption error: %s",
+                tsi_result_to_string(result));
+        break;
+      }
+      message_bytes += processed_message_size;
+      message_size -= processed_message_size;
+      cur += unprotected_buffer_size_written;
+
+      if (cur == end) {
+        flush_read_staging_buffer(ep, &cur, &end);
+        /* Force to enter the loop again to extract buffered bytes in protector.
+           The bytes could be buffered because of running out of staging_buffer.
+           If this happens at the end of all slices, doing another unprotect
+           avoids leaving data in the protector. */
+        keep_looping = 1;
+      } else if (unprotected_buffer_size_written > 0) {
+        keep_looping = 1;
+      } else {
+        keep_looping = 0;
+      }
+    }
+    if (result != TSI_OK) break;
+  }
+
+  if (cur != GPR_SLICE_START_PTR(ep->read_staging_buffer)) {
+    gpr_slice_buffer_add(
+        &ep->input_buffer,
+        gpr_slice_split_head(
+            &ep->read_staging_buffer,
+            cur - GPR_SLICE_START_PTR(ep->read_staging_buffer)));
+  }
+
+  /* TODO(yangg) experiment with moving this block after read_cb to see if it
+     helps latency */
+  for (i = 0; i < nslices; i++) {
+    gpr_slice_unref(slices[i]);
+  }
+
+  if (result != TSI_OK) {
+    gpr_slice_buffer_reset_and_unref(&ep->input_buffer);
+    call_read_cb(ep, NULL, 0, GRPC_ENDPOINT_CB_ERROR);
+    return;
+  }
+  /* The upper level will unref the slices. */
+  input_buffer_count = ep->input_buffer.count;
+  ep->input_buffer.count = 0;
+  call_read_cb(ep, ep->input_buffer.slices, input_buffer_count, error);
+}
+
+static void notify_on_read(grpc_endpoint *secure_ep, grpc_endpoint_read_cb cb,
+                           void *user_data, gpr_timespec deadline) {
+  secure_endpoint *ep = (secure_endpoint *)secure_ep;
+  ep->read_cb = cb;
+  ep->read_user_data = user_data;
+
+  secure_endpoint_ref(ep);
+
+  if (ep->leftover_bytes.count) {
+    size_t leftover_nslices = ep->leftover_bytes.count;
+    ep->leftover_bytes.count = 0;
+    on_read(ep, ep->leftover_bytes.slices, leftover_nslices,
+            GRPC_ENDPOINT_CB_OK);
+    return;
+  }
+
+  grpc_endpoint_notify_on_read(ep->wrapped_ep, on_read, ep, deadline);
+}
+
+static void flush_write_staging_buffer(secure_endpoint *ep, gpr_uint8 **cur,
+                                       gpr_uint8 **end) {
+  gpr_slice_buffer_add(&ep->output_buffer, ep->write_staging_buffer);
+  ep->write_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE);
+  *cur = GPR_SLICE_START_PTR(ep->write_staging_buffer);
+  *end = GPR_SLICE_END_PTR(ep->write_staging_buffer);
+}
+
+static grpc_endpoint_write_status write(grpc_endpoint *secure_ep,
+                                        gpr_slice *slices, size_t nslices,
+                                        grpc_endpoint_write_cb cb,
+                                        void *user_data,
+                                        gpr_timespec deadline) {
+  int i = 0;
+  int output_buffer_count = 0;
+  tsi_result result = TSI_OK;
+  secure_endpoint *ep = (secure_endpoint *)secure_ep;
+  gpr_uint8 *cur = GPR_SLICE_START_PTR(ep->write_staging_buffer);
+  gpr_uint8 *end = GPR_SLICE_END_PTR(ep->write_staging_buffer);
+  GPR_ASSERT(ep->output_buffer.count == 0);
+
+#ifdef GRPC_TRACE_SECURE_TRANSPORT
+  for (i = 0; i < nslices; i++) {
+    char *data =
+        gpr_hexdump((char*)GPR_SLICE_START_PTR(slices[i]),
+            GPR_SLICE_LENGTH(slices[i]), GPR_HEXDUMP_PLAINTEXT);
+    gpr_log(GPR_DEBUG, "WRITE %p: %s", ep, data);
+    gpr_free(data);
+  }
+#endif
+
+  for (i = 0; i < nslices; i++) {
+    gpr_slice plain = slices[i];
+    gpr_uint8 *message_bytes = GPR_SLICE_START_PTR(plain);
+    size_t message_size = GPR_SLICE_LENGTH(plain);
+    while (message_size > 0) {
+      gpr_uint32 protected_buffer_size_to_send = end - cur;
+      gpr_uint32 processed_message_size = message_size;
+      gpr_mu_lock(&ep->protector_mu);
+      result = tsi_frame_protector_protect(ep->protector, message_bytes,
+                                           &processed_message_size, cur,
+                                           &protected_buffer_size_to_send);
+      gpr_mu_unlock(&ep->protector_mu);
+      if (result != TSI_OK) {
+        gpr_log(GPR_ERROR, "Encryption error: %s",
+                tsi_result_to_string(result));
+        break;
+      }
+      message_bytes += processed_message_size;
+      message_size -= processed_message_size;
+      cur += protected_buffer_size_to_send;
+
+      if (cur == end) {
+        flush_write_staging_buffer(ep, &cur, &end);
+      }
+    }
+    if (result != TSI_OK) break;
+  }
+  if (result == TSI_OK) {
+    gpr_uint32 still_pending_size;
+    do {
+      gpr_uint32 protected_buffer_size_to_send = end - cur;
+      gpr_mu_lock(&ep->protector_mu);
+      result = tsi_frame_protector_protect_flush(ep->protector, cur,
+                                                 &protected_buffer_size_to_send,
+                                                 &still_pending_size);
+      gpr_mu_unlock(&ep->protector_mu);
+      if (result != TSI_OK) break;
+      cur += protected_buffer_size_to_send;
+      if (cur == end) {
+        flush_write_staging_buffer(ep, &cur, &end);
+      }
+    } while (still_pending_size > 0);
+    if (cur != GPR_SLICE_START_PTR(ep->write_staging_buffer)) {
+      gpr_slice_buffer_add(
+          &ep->output_buffer,
+          gpr_slice_split_head(
+              &ep->write_staging_buffer,
+              cur - GPR_SLICE_START_PTR(ep->write_staging_buffer)));
+    }
+  }
+
+  for (i = 0; i < nslices; i++) {
+    gpr_slice_unref(slices[i]);
+  }
+
+  if (result != TSI_OK) {
+    /* TODO(yangg) do different things according to the error type? */
+    gpr_slice_buffer_reset_and_unref(&ep->output_buffer);
+    return GRPC_ENDPOINT_WRITE_ERROR;
+  }
+
+  /* clear output_buffer and let the lower level handle its slices. */
+  output_buffer_count = ep->output_buffer.count;
+  ep->output_buffer.count = 0;
+  return grpc_endpoint_write(ep->wrapped_ep, ep->output_buffer.slices,
+                             output_buffer_count, cb, user_data, deadline);
+}
+
+static void shutdown(grpc_endpoint *secure_ep) {
+  secure_endpoint *ep = (secure_endpoint *)secure_ep;
+  grpc_endpoint_shutdown(ep->wrapped_ep);
+}
+
+static void unref(grpc_endpoint *secure_ep) {
+  secure_endpoint *ep = (secure_endpoint *)secure_ep;
+  secure_endpoint_unref(ep);
+}
+
+static const grpc_endpoint_vtable vtable = {notify_on_read, write, shutdown,
+                                            unref};
+
+grpc_endpoint *grpc_secure_endpoint_create(
+    struct tsi_frame_protector *protector, grpc_endpoint *transport,
+    gpr_slice *leftover_slices, size_t leftover_nslices) {
+  size_t i;
+  secure_endpoint *ep = (secure_endpoint *)gpr_malloc(sizeof(secure_endpoint));
+  ep->base.vtable = &vtable;
+  ep->wrapped_ep = transport;
+  ep->protector = protector;
+  gpr_slice_buffer_init(&ep->leftover_bytes);
+  for (i = 0; i < leftover_nslices; i++) {
+    gpr_slice_buffer_add(&ep->leftover_bytes,
+                         gpr_slice_ref(leftover_slices[i]));
+  }
+  ep->write_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE);
+  ep->read_staging_buffer = gpr_slice_malloc(STAGING_BUFFER_SIZE);
+  gpr_slice_buffer_init(&ep->input_buffer);
+  gpr_slice_buffer_init(&ep->output_buffer);
+  gpr_mu_init(&ep->protector_mu);
+  gpr_ref_init(&ep->ref, 1);
+  return &ep->base;
+}
diff --git a/src/core/endpoint/secure_endpoint.h b/src/core/endpoint/secure_endpoint.h
new file mode 100644
index 0000000..971170a
--- /dev/null
+++ b/src/core/endpoint/secure_endpoint.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__
+#define __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__
+
+#include <grpc/support/slice.h>
+#include "src/core/endpoint/endpoint.h"
+
+struct tsi_frame_protector;
+
+/* Takes ownership of protector and to_wrap, and refs leftover_slices. */
+grpc_endpoint *grpc_secure_endpoint_create(
+    struct tsi_frame_protector *protector, grpc_endpoint *to_wrap,
+    gpr_slice *leftover_slices, size_t leftover_nslices);
+
+#endif  /* __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__ */
diff --git a/src/core/endpoint/socket_utils.c b/src/core/endpoint/socket_utils.c
new file mode 100644
index 0000000..9c2540b
--- /dev/null
+++ b/src/core/endpoint/socket_utils.c
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/endpoint/socket_utils.h"
+
+#include <limits.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+/* set a socket to non blocking mode */
+int grpc_set_socket_nonblocking(int fd, int non_blocking) {
+  int oldflags = fcntl(fd, F_GETFL, 0);
+  if (oldflags < 0) {
+    return 0;
+  }
+
+  if (non_blocking) {
+    oldflags |= O_NONBLOCK;
+  } else {
+    oldflags &= ~O_NONBLOCK;
+  }
+
+  if (fcntl(fd, F_SETFL, oldflags) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+
+/* set a socket to close on exec */
+int grpc_set_socket_cloexec(int fd, int close_on_exec) {
+  int oldflags = fcntl(fd, F_GETFD, 0);
+  if (oldflags < 0) {
+    return 0;
+  }
+
+  if (close_on_exec) {
+    oldflags |= FD_CLOEXEC;
+  } else {
+    oldflags &= ~FD_CLOEXEC;
+  }
+
+  if (fcntl(fd, F_SETFD, oldflags) != 0) {
+    return 0;
+  }
+
+  return 1;
+}
+
+/* set a socket to reuse old addresses */
+int grpc_set_socket_reuse_addr(int fd, int reuse) {
+  int val = (reuse != 0);
+  int newval;
+  socklen_t intlen = sizeof(newval);
+  return 0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) &&
+         0 == getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen) &&
+         newval == val;
+}
+
+/* disable nagle */
+int grpc_set_socket_low_latency(int fd, int low_latency) {
+  int val = (low_latency != 0);
+  int newval;
+  socklen_t intlen = sizeof(newval);
+  return 0 == setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) &&
+         0 == getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen) &&
+         newval == val;
+}
diff --git a/src/core/endpoint/socket_utils.h b/src/core/endpoint/socket_utils.h
new file mode 100644
index 0000000..545d678
--- /dev/null
+++ b/src/core/endpoint/socket_utils.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_ENDPOINT_SOCKET_UTILS_H__
+#define __GRPC_INTERNAL_ENDPOINT_SOCKET_UTILS_H__
+
+#include <unistd.h>
+#include <sys/socket.h>
+
+struct sockaddr;
+
+/* a wrapper for accept or accept4 */
+int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
+                 int nonblock, int cloexec);
+
+/* set a socket to non blocking mode */
+int grpc_set_socket_nonblocking(int fd, int non_blocking);
+
+/* set a socket to close on exec */
+int grpc_set_socket_cloexec(int fd, int close_on_exec);
+
+/* set a socket to reuse old addresses */
+int grpc_set_socket_reuse_addr(int fd, int reuse);
+
+/* disable nagle */
+int grpc_set_socket_low_latency(int fd, int low_latency);
+
+#endif  /* __GRPC_INTERNAL_ENDPOINT_SOCKET_UTILS_H__ */
diff --git a/src/core/endpoint/socket_utils_linux.c b/src/core/endpoint/socket_utils_linux.c
new file mode 100644
index 0000000..479675e
--- /dev/null
+++ b/src/core/endpoint/socket_utils_linux.c
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_LINUX
+
+#include "src/core/endpoint/socket_utils.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
+                 int nonblock, int cloexec) {
+  int flags = 0;
+  flags |= nonblock ? SOCK_NONBLOCK : 0;
+  flags |= cloexec ? SOCK_CLOEXEC : 0;
+  return accept4(sockfd, addr, addrlen, flags);
+}
+
+#endif
diff --git a/src/core/endpoint/socket_utils_posix.c b/src/core/endpoint/socket_utils_posix.c
new file mode 100644
index 0000000..262d606
--- /dev/null
+++ b/src/core/endpoint/socket_utils_posix.c
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_POSIX_SOCKETUTILS
+
+#define _BSD_SOURCE
+#include "src/core/endpoint/socket_utils.h"
+
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <grpc/support/log.h>
+
+int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
+                 int nonblock, int cloexec) {
+  int fd, flags;
+
+  fd = accept(sockfd, addr, addrlen);
+  if (fd >= 0) {
+    flags = fcntl(fd, F_GETFL, 0);
+    flags |= nonblock ? O_NONBLOCK : 0;
+    flags |= cloexec ? FD_CLOEXEC : 0;
+    GPR_ASSERT(fcntl(fd, F_SETFL, flags) == 0);
+  }
+  return fd;
+}
+
+#endif /* GPR_POSIX_SOCKETUTILS */
diff --git a/src/core/endpoint/tcp.c b/src/core/endpoint/tcp.c
new file mode 100644
index 0000000..39367e8
--- /dev/null
+++ b/src/core/endpoint/tcp.c
@@ -0,0 +1,570 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/endpoint/tcp.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "src/core/eventmanager/em.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+/* Holds a slice array and associated state. */
+typedef struct grpc_tcp_slice_state {
+  gpr_slice *slices;       /* Array of slices */
+  size_t nslices;          /* Size of slices array. */
+  ssize_t first_slice;     /* First valid slice in array */
+  ssize_t last_slice;      /* Last valid slice in array */
+  gpr_slice working_slice; /* pointer to original final slice */
+  int working_slice_valid; /* True if there is a working slice */
+  int memory_owned;        /* True if slices array is owned */
+} grpc_tcp_slice_state;
+
+static void slice_state_init(grpc_tcp_slice_state *state, gpr_slice *slices,
+                             size_t nslices, size_t valid_slices) {
+  state->slices = slices;
+  state->nslices = nslices;
+  if (valid_slices == 0) {
+    state->first_slice = -1;
+  } else {
+    state->first_slice = 0;
+  }
+  state->last_slice = valid_slices - 1;
+  state->working_slice_valid = 0;
+  state->memory_owned = 0;
+}
+
+/* Returns true if there is still available data */
+static int slice_state_has_available(grpc_tcp_slice_state *state) {
+  return state->first_slice != -1 && state->last_slice >= state->first_slice;
+}
+
+static ssize_t slice_state_slices_allocated(grpc_tcp_slice_state *state) {
+  if (state->first_slice == -1) {
+    return 0;
+  } else {
+    return state->last_slice - state->first_slice + 1;
+  }
+}
+
+static void slice_state_realloc(grpc_tcp_slice_state *state, size_t new_size) {
+  /* TODO(klempner): use realloc instead when first_slice is 0 */
+  /* TODO(klempner): Avoid a realloc in cases where it is unnecessary */
+  gpr_slice *slices = state->slices;
+  size_t original_size = slice_state_slices_allocated(state);
+  size_t i;
+  gpr_slice *new_slices = gpr_malloc(sizeof(gpr_slice) * new_size);
+
+  for (i = 0; i < original_size; ++i) {
+    new_slices[i] = slices[i + state->first_slice];
+  }
+
+  state->slices = new_slices;
+  state->last_slice = original_size - 1;
+  if (original_size > 0) {
+    state->first_slice = 0;
+  } else {
+    state->first_slice = -1;
+  }
+  state->nslices = new_size;
+
+  if (state->memory_owned) {
+    gpr_free(slices);
+  }
+  state->memory_owned = 1;
+}
+
+static void slice_state_remove_prefix(grpc_tcp_slice_state *state,
+                                      size_t prefix_bytes) {
+  gpr_slice *current_slice = &state->slices[state->first_slice];
+  size_t current_slice_size;
+
+  while (slice_state_has_available(state)) {
+    current_slice_size = GPR_SLICE_LENGTH(*current_slice);
+    if (current_slice_size > prefix_bytes) {
+      /* TODO(klempner): Get rid of the extra refcount created here by adding a
+         native "trim the first N bytes" operation to splice */
+      /* TODO(klempner): This really shouldn't be modifying the current slice
+         unless we own the slices array. */
+      *current_slice = gpr_slice_split_tail(current_slice, prefix_bytes);
+      gpr_slice_unref(*current_slice);
+      return;
+    } else {
+      gpr_slice_unref(*current_slice);
+      ++state->first_slice;
+      ++current_slice;
+      prefix_bytes -= current_slice_size;
+    }
+  }
+}
+
+static void slice_state_destroy(grpc_tcp_slice_state *state) {
+  while (slice_state_has_available(state)) {
+    gpr_slice_unref(state->slices[state->first_slice]);
+    ++state->first_slice;
+  }
+
+  if (state->memory_owned) {
+    gpr_free(state->slices);
+    state->memory_owned = 0;
+  }
+}
+
+void slice_state_transfer_ownership(grpc_tcp_slice_state *state,
+                                    gpr_slice **slices, size_t *nslices) {
+  *slices = state->slices + state->first_slice;
+  *nslices = state->last_slice - state->first_slice + 1;
+
+  state->first_slice = -1;
+  state->last_slice = -1;
+}
+
+/* Fills iov with the first min(iov_size, available) slices, returns number
+   filled */
+static size_t slice_state_to_iovec(grpc_tcp_slice_state *state,
+                                   struct iovec *iov, size_t iov_size) {
+  size_t nslices = state->last_slice - state->first_slice + 1;
+  gpr_slice *slices = state->slices + state->first_slice;
+  size_t i;
+  if (nslices < iov_size) {
+    iov_size = nslices;
+  }
+
+  for (i = 0; i < iov_size; ++i) {
+    iov[i].iov_base = GPR_SLICE_START_PTR(slices[i]);
+    iov[i].iov_len = GPR_SLICE_LENGTH(slices[i]);
+  }
+  return iov_size;
+}
+
+/* Makes n blocks available at the end of state, writes them into iov, and
+   returns the number of bytes allocated */
+static size_t slice_state_append_blocks_into_iovec(grpc_tcp_slice_state *state,
+                                                   struct iovec *iov, size_t n,
+                                                   size_t slice_size) {
+  size_t target_size;
+  size_t i;
+  size_t allocated_bytes;
+  ssize_t allocated_slices = slice_state_slices_allocated(state);
+
+  if (n - state->working_slice_valid >= state->nslices - state->last_slice) {
+    /* Need to grow the slice array */
+    target_size = state->nslices;
+    do {
+      target_size = target_size * 2;
+    } while (target_size < allocated_slices + n - state->working_slice_valid);
+    /* TODO(klempner): If this ever needs to support both prefix removal and
+       append, we should be smarter about the growth logic here */
+    slice_state_realloc(state, target_size);
+  }
+
+  i = 0;
+  allocated_bytes = 0;
+
+  if (state->working_slice_valid) {
+    iov[0].iov_base = GPR_SLICE_END_PTR(state->slices[state->last_slice]);
+    iov[0].iov_len = GPR_SLICE_LENGTH(state->working_slice) -
+                     GPR_SLICE_LENGTH(state->slices[state->last_slice]);
+    allocated_bytes += iov[0].iov_len;
+    ++i;
+    state->slices[state->last_slice] = state->working_slice;
+    state->working_slice_valid = 0;
+  }
+
+  for (; i < n; ++i) {
+    ++state->last_slice;
+    state->slices[state->last_slice] = gpr_slice_malloc(slice_size);
+    iov[i].iov_base = GPR_SLICE_START_PTR(state->slices[state->last_slice]);
+    iov[i].iov_len = slice_size;
+    allocated_bytes += slice_size;
+  }
+  if (state->first_slice == -1) {
+    state->first_slice = 0;
+  }
+  return allocated_bytes;
+}
+
+/* Remove the last n bytes from state */
+/* TODO(klempner): Consider having this defer actual deletion until later */
+static void slice_state_remove_last(grpc_tcp_slice_state *state, size_t bytes) {
+  while (bytes > 0 && slice_state_has_available(state)) {
+    if (GPR_SLICE_LENGTH(state->slices[state->last_slice]) > bytes) {
+      state->working_slice = state->slices[state->last_slice];
+      state->working_slice_valid = 1;
+      /* TODO(klempner): Combine these into a single operation that doesn't need
+         to refcount */
+      gpr_slice_unref(gpr_slice_split_tail(
+          &state->slices[state->last_slice],
+          GPR_SLICE_LENGTH(state->slices[state->last_slice]) - bytes));
+      bytes = 0;
+    } else {
+      bytes -= GPR_SLICE_LENGTH(state->slices[state->last_slice]);
+      gpr_slice_unref(state->slices[state->last_slice]);
+      --state->last_slice;
+      if (state->last_slice == -1) {
+        state->first_slice = -1;
+      }
+    }
+  }
+}
+
+typedef struct {
+  grpc_endpoint base;
+  grpc_em *em;
+  grpc_em_fd em_fd;
+  int fd;
+  size_t slice_size;
+  gpr_refcount refcount;
+
+  grpc_endpoint_read_cb read_cb;
+  void *read_user_data;
+  gpr_timespec read_deadline;
+  grpc_endpoint_write_cb write_cb;
+  void *write_user_data;
+  gpr_timespec write_deadline;
+
+  grpc_tcp_slice_state write_state;
+} grpc_tcp;
+
+static void grpc_tcp_handle_read(void *arg /* grpc_tcp */,
+                                 grpc_em_cb_status status);
+static void grpc_tcp_handle_write(void *arg /* grpc_tcp */,
+                                  grpc_em_cb_status status);
+
+#define DEFAULT_SLICE_SIZE 8192
+grpc_endpoint *grpc_tcp_create(int fd, grpc_em *em) {
+  return grpc_tcp_create_dbg(fd, em, DEFAULT_SLICE_SIZE);
+}
+
+static void grpc_tcp_shutdown(grpc_endpoint *ep) {
+  grpc_tcp *tcp = (grpc_tcp *)ep;
+  grpc_em_fd_shutdown(&tcp->em_fd);
+}
+
+static void grpc_tcp_unref(grpc_tcp *tcp) {
+  int refcount_zero = gpr_unref(&tcp->refcount);
+  if (refcount_zero) {
+    grpc_em_fd_destroy(&tcp->em_fd);
+    close(tcp->fd);
+    gpr_free(tcp);
+  }
+}
+
+static void grpc_tcp_destroy(grpc_endpoint *ep) {
+  grpc_tcp *tcp = (grpc_tcp *)ep;
+  grpc_tcp_unref(tcp);
+}
+
+static void call_read_cb(grpc_tcp *tcp, gpr_slice *slices, size_t nslices,
+                         grpc_endpoint_cb_status status) {
+  grpc_endpoint_read_cb cb = tcp->read_cb;
+
+#ifdef GRPC_TRACE_TCP
+  size_t i;
+  gpr_log(GPR_DEBUG, "read: status=%d", status);
+  for (i = 0; i < nslices; i++) {
+    char *dump =
+        gpr_hexdump((char *)GPR_SLICE_START_PTR(slices[i]),
+                    GPR_SLICE_LENGTH(slices[i]), GPR_HEXDUMP_PLAINTEXT);
+    gpr_log(GPR_DEBUG, "READ: %s", dump);
+    gpr_free(dump);
+  }
+#endif
+
+  tcp->read_cb = NULL;
+  cb(tcp->read_user_data, slices, nslices, status);
+}
+
+#define INLINE_SLICE_BUFFER_SIZE 8
+#define MAX_READ_IOVEC 4
+static void grpc_tcp_handle_read(void *arg /* grpc_tcp */,
+                                 grpc_em_cb_status status) {
+  grpc_tcp *tcp = (grpc_tcp *)arg;
+  int iov_size = 1;
+  gpr_slice static_read_slices[INLINE_SLICE_BUFFER_SIZE];
+  struct msghdr msg;
+  struct iovec iov[MAX_READ_IOVEC];
+  ssize_t read_bytes;
+  ssize_t allocated_bytes;
+  struct grpc_tcp_slice_state read_state;
+  gpr_slice *final_slices;
+  size_t final_nslices;
+
+  slice_state_init(&read_state, static_read_slices, INLINE_SLICE_BUFFER_SIZE,
+                   0);
+
+  if (status == GRPC_CALLBACK_CANCELLED) {
+    call_read_cb(tcp, NULL, 0, GRPC_ENDPOINT_CB_SHUTDOWN);
+    grpc_tcp_unref(tcp);
+    return;
+  }
+
+  if (status == GRPC_CALLBACK_TIMED_OUT) {
+    call_read_cb(tcp, NULL, 0, GRPC_ENDPOINT_CB_TIMED_OUT);
+    grpc_tcp_unref(tcp);
+    return;
+  }
+
+  /* TODO(klempner): Limit the amount we read at once. */
+  for (;;) {
+    allocated_bytes = slice_state_append_blocks_into_iovec(
+        &read_state, iov, iov_size, tcp->slice_size);
+
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = iov_size;
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_flags = 0;
+
+    do {
+      read_bytes = recvmsg(tcp->fd, &msg, 0);
+    } while (read_bytes < 0 && errno == EINTR);
+
+    if (read_bytes < allocated_bytes) {
+      /* TODO(klempner): Consider a second read first, in hopes of getting a
+       * quick EAGAIN and saving a bunch of allocations. */
+      slice_state_remove_last(&read_state, read_bytes < 0
+                                               ? allocated_bytes
+                                               : allocated_bytes - read_bytes);
+    }
+
+    if (read_bytes < 0) {
+      /* NB: After calling the user_cb a parallel call of the read handler may
+       * be running. */
+      if (errno == EAGAIN) {
+        if (slice_state_has_available(&read_state)) {
+          /* TODO(klempner): We should probably do the call into the application
+             without all this junk on the stack */
+          /* FIXME(klempner): Refcount properly */
+          slice_state_transfer_ownership(&read_state, &final_slices,
+                                         &final_nslices);
+          call_read_cb(tcp, final_slices, final_nslices, GRPC_ENDPOINT_CB_OK);
+          slice_state_destroy(&read_state);
+          grpc_tcp_unref(tcp);
+        } else {
+          /* Spurious read event, consume it here */
+          slice_state_destroy(&read_state);
+          grpc_em_fd_notify_on_read(&tcp->em_fd, grpc_tcp_handle_read, tcp,
+                                    tcp->read_deadline);
+        }
+      } else {
+        /* TODO(klempner): Log interesting errors */
+        call_read_cb(tcp, NULL, 0, GRPC_ENDPOINT_CB_ERROR);
+        slice_state_destroy(&read_state);
+        grpc_tcp_unref(tcp);
+      }
+      return;
+    } else if (read_bytes == 0) {
+      /* 0 read size ==> end of stream */
+      if (slice_state_has_available(&read_state)) {
+        /* there were bytes already read: pass them up to the application */
+        slice_state_transfer_ownership(&read_state, &final_slices,
+                                       &final_nslices);
+        call_read_cb(tcp, final_slices, final_nslices, GRPC_ENDPOINT_CB_EOF);
+      } else {
+        call_read_cb(tcp, NULL, 0, GRPC_ENDPOINT_CB_EOF);
+      }
+      slice_state_destroy(&read_state);
+      grpc_tcp_unref(tcp);
+      return;
+    } else if (iov_size < MAX_READ_IOVEC) {
+      ++iov_size;
+    }
+  }
+}
+
+static void grpc_tcp_notify_on_read(grpc_endpoint *ep, grpc_endpoint_read_cb cb,
+                                    void *user_data, gpr_timespec deadline) {
+  grpc_tcp *tcp = (grpc_tcp *)ep;
+  GPR_ASSERT(tcp->read_cb == NULL);
+  tcp->read_cb = cb;
+  tcp->read_user_data = user_data;
+  tcp->read_deadline = deadline;
+  gpr_ref(&tcp->refcount);
+  grpc_em_fd_notify_on_read(&tcp->em_fd, grpc_tcp_handle_read, tcp, deadline);
+}
+
+#define MAX_WRITE_IOVEC 16
+static grpc_endpoint_write_status grpc_tcp_flush(grpc_tcp *tcp) {
+  struct msghdr msg;
+  struct iovec iov[MAX_WRITE_IOVEC];
+  int iov_size;
+  ssize_t sent_length;
+  grpc_tcp_slice_state *state = &tcp->write_state;
+
+  for (;;) {
+    iov_size = slice_state_to_iovec(state, iov, MAX_WRITE_IOVEC);
+
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = iov_size;
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_flags = 0;
+
+    do {
+      /* TODO(klempner): Cork if this is a partial write */
+      sent_length = sendmsg(tcp->fd, &msg, 0);
+    } while (sent_length < 0 && errno == EINTR);
+
+    if (sent_length < 0) {
+      if (errno == EAGAIN) {
+        return GRPC_ENDPOINT_WRITE_PENDING;
+      } else {
+        /* TODO(klempner): Log some of these */
+        slice_state_destroy(state);
+        return GRPC_ENDPOINT_WRITE_ERROR;
+      }
+    }
+
+    /* TODO(klempner): Probably better to batch this after we finish flushing */
+    slice_state_remove_prefix(state, sent_length);
+
+    if (!slice_state_has_available(state)) {
+      return GRPC_ENDPOINT_WRITE_DONE;
+    }
+  };
+}
+
+static void grpc_tcp_handle_write(void *arg /* grpc_tcp */,
+                                  grpc_em_cb_status status) {
+  grpc_tcp *tcp = (grpc_tcp *)arg;
+  grpc_endpoint_write_status write_status;
+  grpc_endpoint_cb_status cb_status;
+  grpc_endpoint_write_cb cb;
+
+  cb_status = GRPC_ENDPOINT_CB_OK;
+
+  if (status == GRPC_CALLBACK_CANCELLED) {
+    cb_status = GRPC_ENDPOINT_CB_SHUTDOWN;
+  } else if (status == GRPC_CALLBACK_TIMED_OUT) {
+    cb_status = GRPC_ENDPOINT_CB_TIMED_OUT;
+  }
+
+  if (cb_status != GRPC_ENDPOINT_CB_OK) {
+    slice_state_destroy(&tcp->write_state);
+    cb = tcp->write_cb;
+    tcp->write_cb = NULL;
+    cb(tcp->write_user_data, cb_status);
+    grpc_tcp_unref(tcp);
+    return;
+  }
+
+  write_status = grpc_tcp_flush(tcp);
+  if (write_status == GRPC_ENDPOINT_WRITE_PENDING) {
+    grpc_em_fd_notify_on_write(&tcp->em_fd, grpc_tcp_handle_write, tcp,
+                               tcp->write_deadline);
+  } else {
+    slice_state_destroy(&tcp->write_state);
+    if (write_status == GRPC_ENDPOINT_WRITE_DONE) {
+      cb_status = GRPC_ENDPOINT_CB_OK;
+    } else {
+      cb_status = GRPC_ENDPOINT_CB_ERROR;
+    }
+    cb = tcp->write_cb;
+    tcp->write_cb = NULL;
+    cb(tcp->write_user_data, cb_status);
+    grpc_tcp_unref(tcp);
+  }
+}
+
+static grpc_endpoint_write_status grpc_tcp_write(
+    grpc_endpoint *ep, gpr_slice *slices, size_t nslices,
+    grpc_endpoint_write_cb cb, void *user_data, gpr_timespec deadline) {
+  grpc_tcp *tcp = (grpc_tcp *)ep;
+  grpc_endpoint_write_status status;
+
+#ifdef GRPC_TRACE_TCP
+  size_t i;
+
+  for (i = 0; i < nslices; i++) {
+    char *data =
+        gpr_hexdump((char *)GPR_SLICE_START_PTR(slices[i]),
+                    GPR_SLICE_LENGTH(slices[i]), GPR_HEXDUMP_PLAINTEXT);
+    gpr_log(GPR_DEBUG, "WRITE %p: %s", tcp, data);
+    gpr_free(data);
+  }
+#endif
+
+  GPR_ASSERT(tcp->write_cb == NULL);
+  slice_state_init(&tcp->write_state, slices, nslices, nslices);
+
+  status = grpc_tcp_flush(tcp);
+  if (status == GRPC_ENDPOINT_WRITE_PENDING) {
+    /* TODO(klempner): Consider inlining rather than malloc for small nslices */
+    slice_state_realloc(&tcp->write_state, nslices);
+    gpr_ref(&tcp->refcount);
+    tcp->write_cb = cb;
+    tcp->write_user_data = user_data;
+    tcp->write_deadline = deadline;
+    grpc_em_fd_notify_on_write(&tcp->em_fd, grpc_tcp_handle_write, tcp,
+                               tcp->write_deadline);
+  }
+
+  return status;
+}
+
+static const grpc_endpoint_vtable vtable = {grpc_tcp_notify_on_read,
+                                            grpc_tcp_write, grpc_tcp_shutdown,
+                                            grpc_tcp_destroy};
+
+grpc_endpoint *grpc_tcp_create_dbg(int fd, grpc_em *em, size_t slice_size) {
+  grpc_tcp *tcp = (grpc_tcp *)gpr_malloc(sizeof(grpc_tcp));
+  tcp->base.vtable = &vtable;
+  tcp->fd = fd;
+  tcp->em = em;
+  tcp->read_cb = NULL;
+  tcp->write_cb = NULL;
+  tcp->read_user_data = NULL;
+  tcp->write_user_data = NULL;
+  tcp->slice_size = slice_size;
+  tcp->read_deadline = gpr_inf_future;
+  tcp->write_deadline = gpr_inf_future;
+  slice_state_init(&tcp->write_state, NULL, 0, 0);
+  /* paired with unref in grpc_tcp_destroy */
+  gpr_ref_init(&tcp->refcount, 1);
+  grpc_em_fd_init(&tcp->em_fd, tcp->em, fd);
+  return &tcp->base;
+}
diff --git a/src/core/endpoint/tcp.h b/src/core/endpoint/tcp.h
new file mode 100644
index 0000000..6507b2f
--- /dev/null
+++ b/src/core/endpoint/tcp.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_ENDPOINT_TCP_H__
+#define __GRPC_INTERNAL_ENDPOINT_TCP_H__
+/*
+   Low level TCP "bottom half" implementation, for use by transports built on
+   top of a TCP connection.
+
+   Note that this file does not (yet) include APIs for creating the socket in
+   the first place.
+
+   All calls passing slice transfer ownership of a slice refcount unless
+   otherwise specified.
+*/
+
+#include "src/core/endpoint/endpoint.h"
+#include "src/core/eventmanager/em.h"
+
+/* Create a tcp from an already connected file descriptor. */
+grpc_endpoint *grpc_tcp_create(int fd, grpc_em *em);
+/* Special version for debugging slice changes */
+grpc_endpoint *grpc_tcp_create_dbg(int fd, grpc_em *em, size_t slice_size);
+
+#endif  /* __GRPC_INTERNAL_ENDPOINT_TCP_H__ */
diff --git a/src/core/endpoint/tcp_client.c b/src/core/endpoint/tcp_client.c
new file mode 100644
index 0000000..01a0c3f
--- /dev/null
+++ b/src/core/endpoint/tcp_client.c
@@ -0,0 +1,170 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/endpoint/tcp_client.h"
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "src/core/endpoint/socket_utils.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
+typedef struct {
+  void (*cb)(void *arg, grpc_endpoint *tcp);
+  void *cb_arg;
+  grpc_em_fd fd;
+  gpr_timespec deadline;
+} async_connect;
+
+static int create_fd(int address_family) {
+  int fd = socket(address_family, SOCK_STREAM, 0);
+  if (fd < 0) {
+    gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
+    goto error;
+  }
+
+  if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
+      !grpc_set_socket_low_latency(fd, 1)) {
+    gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
+            strerror(errno));
+    goto error;
+  }
+
+  return fd;
+
+error:
+  if (fd >= 0) {
+    close(fd);
+  }
+  return -1;
+}
+
+static void on_writable(void *acp, grpc_em_cb_status status) {
+  async_connect *ac = acp;
+  int so_error = 0;
+  socklen_t so_error_size;
+  int err;
+  int fd = grpc_em_fd_get(&ac->fd);
+  grpc_em *em = grpc_em_fd_get_em(&ac->fd);
+
+  if (status == GRPC_CALLBACK_SUCCESS) {
+    do {
+      so_error_size = sizeof(so_error);
+      err = getsockopt(fd, SOL_SOCKET, SO_ERROR, &so_error, &so_error_size);
+    } while (err < 0 && errno == EINTR);
+    if (err < 0) {
+      gpr_log(GPR_ERROR, "getsockopt(ERROR): %s", strerror(errno));
+      goto error;
+    } else if (so_error != 0) {
+      if (so_error == ENOBUFS) {
+        /* We will get one of these errors if we have run out of
+           memory in the kernel for the data structures allocated
+           when you connect a socket.  If this happens it is very
+           likely that if we wait a little bit then try again the
+           connection will work (since other programs or this
+           program will close their network connections and free up
+           memory).  This does _not_ indicate that there is anything
+           wrong with the server we are connecting to, this is a
+           local problem.
+
+           If you are looking at this code, then chances are that
+           your program or another program on the same computer
+           opened too many network connections.  The "easy" fix:
+           don't do that! */
+        gpr_log(GPR_ERROR, "kernel out of buffers");
+        grpc_em_fd_notify_on_write(&ac->fd, on_writable, ac, ac->deadline);
+        return;
+      } else {
+        goto error;
+      }
+    } else {
+      goto great_success;
+    }
+  } else {
+    gpr_log(GPR_ERROR, "on_writable failed during connect: status=%d", status);
+    goto error;
+  }
+
+  abort();
+
+error:
+  ac->cb(ac->cb_arg, NULL);
+  grpc_em_fd_destroy(&ac->fd);
+  gpr_free(ac);
+  close(fd);
+  return;
+
+great_success:
+  grpc_em_fd_destroy(&ac->fd);
+  ac->cb(ac->cb_arg, grpc_tcp_create(fd, em));
+  gpr_free(ac);
+}
+
+void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *ep),
+                             void *arg, grpc_em *em, struct sockaddr *addr,
+                             int len, gpr_timespec deadline) {
+  int fd = create_fd(addr->sa_family);
+  int err;
+  async_connect *ac;
+
+  if (fd < 0) {
+    cb(arg, NULL);
+    return;
+  }
+
+  do {
+    err = connect(fd, addr, len);
+  } while (err < 0 && errno == EINTR);
+
+  if (err >= 0) {
+    cb(arg, grpc_tcp_create(fd, em));
+    return;
+  }
+
+  if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
+    gpr_log(GPR_ERROR, "connect error: %s", strerror(errno));
+    close(fd);
+    cb(arg, NULL);
+    return;
+  }
+
+  ac = gpr_malloc(sizeof(async_connect));
+  ac->cb = cb;
+  ac->cb_arg = arg;
+  ac->deadline = deadline;
+  grpc_em_fd_init(&ac->fd, em, fd);
+  grpc_em_fd_notify_on_write(&ac->fd, on_writable, ac, deadline);
+}
diff --git a/src/core/endpoint/tcp_client.h b/src/core/endpoint/tcp_client.h
new file mode 100644
index 0000000..2a8b8ee
--- /dev/null
+++ b/src/core/endpoint/tcp_client.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_ENDPOINT_TCP_CLIENT_H__
+#define __GRPC_INTERNAL_ENDPOINT_TCP_CLIENT_H__
+
+#include "src/core/endpoint/tcp.h"
+#include <grpc/support/time.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* Asynchronously connect to an address (specified as (addr, len)), and call
+   cb with arg and the completed connection when done (or call cb with arg and
+   NULL on failure) */
+void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *tcp),
+                             void *arg, grpc_em *em, struct sockaddr *addr,
+                             int len, gpr_timespec deadline);
+
+#endif  /* __GRPC_INTERNAL_ENDPOINT_TCP_CLIENT_H__ */
diff --git a/src/core/endpoint/tcp_server.c b/src/core/endpoint/tcp_server.c
new file mode 100644
index 0000000..2f386ce
--- /dev/null
+++ b/src/core/endpoint/tcp_server.c
@@ -0,0 +1,282 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define _GNU_SOURCE
+#include "src/core/endpoint/tcp_server.h"
+
+#include <limits.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "src/core/endpoint/socket_utils.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+#define INIT_PORT_CAP 2
+#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
+
+static gpr_once s_init_max_accept_queue_size;
+static int s_max_accept_queue_size;
+
+/* one listening port */
+typedef struct {
+  int fd;
+  grpc_em_fd *emfd;
+  grpc_tcp_server *server;
+} server_port;
+
+/* the overall server */
+struct grpc_tcp_server {
+  grpc_em *em;
+  grpc_tcp_server_cb cb;
+  void *cb_arg;
+
+  gpr_mu mu;
+  gpr_cv cv;
+
+  /* active port count: how many ports are actually still listening */
+  int active_ports;
+
+  /* all listening ports */
+  server_port *ports;
+  size_t nports;
+  size_t port_capacity;
+};
+
+grpc_tcp_server *grpc_tcp_server_create(grpc_em *em) {
+  grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
+  gpr_mu_init(&s->mu);
+  gpr_cv_init(&s->cv);
+  s->active_ports = 0;
+  s->em = em;
+  s->cb = NULL;
+  s->cb_arg = NULL;
+  s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
+  s->nports = 0;
+  s->port_capacity = INIT_PORT_CAP;
+  return s;
+}
+
+void grpc_tcp_server_destroy(grpc_tcp_server *s) {
+  size_t i;
+  gpr_mu_lock(&s->mu);
+  /* shutdown all fd's */
+  for (i = 0; i < s->nports; i++) {
+    grpc_em_fd_shutdown(s->ports[i].emfd);
+  }
+  /* wait while that happens */
+  while (s->active_ports) {
+    gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future);
+  }
+  gpr_mu_unlock(&s->mu);
+
+  /* delete ALL the things */
+  for (i = 0; i < s->nports; i++) {
+    server_port *sp = &s->ports[i];
+    grpc_em_fd_destroy(sp->emfd);
+    gpr_free(sp->emfd);
+    close(sp->fd);
+  }
+  gpr_free(s->ports);
+  gpr_free(s);
+}
+
+/* get max listen queue size on linux */
+static void init_max_accept_queue_size() {
+  int n = SOMAXCONN;
+  char buf[64];
+  FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
+  if (fp == NULL) {
+    /* 2.4 kernel. */
+    s_max_accept_queue_size = SOMAXCONN;
+    return;
+  }
+  if (fgets(buf, sizeof buf, fp)) {
+    char *end;
+    long i = strtol(buf, &end, 10);
+    if (i > 0 && i <= INT_MAX && end && *end == 0) {
+      n = i;
+    }
+  }
+  fclose(fp);
+  s_max_accept_queue_size = n;
+
+  if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
+    gpr_log(GPR_INFO,
+            "Suspiciously small accept queue (%d) will probably lead to "
+            "connection drops",
+            s_max_accept_queue_size);
+  }
+}
+
+static int get_max_accept_queue_size() {
+  gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
+  return s_max_accept_queue_size;
+}
+
+/* create a socket to listen with */
+static int create_listening_socket(struct sockaddr *port, int len) {
+  int fd = socket(port->sa_family, SOCK_STREAM, 0);
+  if (fd < 0) {
+    gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
+    goto error;
+  }
+
+  if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
+      !grpc_set_socket_low_latency(fd, 1) ||
+      !grpc_set_socket_reuse_addr(fd, 1)) {
+    gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
+            strerror(errno));
+    goto error;
+  }
+
+  if (bind(fd, port, len) < 0) {
+    gpr_log(GPR_ERROR, "bind: %s", strerror(errno));
+    goto error;
+  }
+
+  if (listen(fd, get_max_accept_queue_size()) < 0) {
+    gpr_log(GPR_ERROR, "listen: %s", strerror(errno));
+    goto error;
+  }
+
+  return fd;
+
+error:
+  if (fd >= 0) {
+    close(fd);
+  }
+  return -1;
+}
+
+/* event manager callback when reads are ready */
+static void on_read(void *arg, grpc_em_cb_status status) {
+  server_port *sp = arg;
+
+  if (status != GRPC_CALLBACK_SUCCESS) {
+    goto error;
+  }
+
+  /* loop until accept4 returns EAGAIN, and then re-arm notification */
+  for (;;) {
+    struct sockaddr_storage addr;
+    socklen_t addrlen = sizeof(addr);
+    int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1);
+    if (fd < 0) {
+      switch (errno) {
+        case EINTR:
+          continue;
+        case EAGAIN:
+          if (GRPC_EM_OK != grpc_em_fd_notify_on_read(sp->emfd, on_read, sp,
+                                                      gpr_inf_future)) {
+            gpr_log(GPR_ERROR, "Failed to register read request with em");
+            goto error;
+          }
+          return;
+        default:
+          gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
+          goto error;
+      }
+    }
+
+    sp->server->cb(sp->server->cb_arg, grpc_tcp_create(fd, sp->server->em));
+  }
+
+  abort();
+
+error:
+  gpr_mu_lock(&sp->server->mu);
+  if (0 == --sp->server->active_ports) {
+    gpr_cv_broadcast(&sp->server->cv);
+  }
+  gpr_mu_unlock(&sp->server->mu);
+}
+
+int grpc_tcp_server_add_port(grpc_tcp_server *s, struct sockaddr *port,
+                             int len) {
+  server_port *sp;
+  /* create a socket */
+  int fd = create_listening_socket(port, len);
+  if (fd < 0) {
+    return -1;
+  }
+
+  gpr_mu_lock(&s->mu);
+  GPR_ASSERT(!s->cb && "must add ports before starting server");
+  /* append it to the list under a lock */
+  if (s->nports == s->port_capacity) {
+    s->port_capacity *= 2;
+    s->ports = gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
+  }
+  sp = &s->ports[s->nports++];
+  sp->emfd = gpr_malloc(sizeof(grpc_em_fd));
+  sp->fd = fd;
+  sp->server = s;
+  /* initialize the em desc */
+  if (GRPC_EM_OK != grpc_em_fd_init(sp->emfd, s->em, fd)) {
+    grpc_em_fd_destroy(sp->emfd);
+    gpr_free(sp->emfd);
+    s->nports--;
+    gpr_mu_unlock(&s->mu);
+    return -1;
+  }
+  gpr_mu_unlock(&s->mu);
+
+  return fd;
+}
+
+void grpc_tcp_server_start(grpc_tcp_server *s, grpc_tcp_server_cb cb,
+                           void *cb_arg) {
+  size_t i;
+  GPR_ASSERT(cb);
+  gpr_mu_lock(&s->mu);
+  GPR_ASSERT(!s->cb);
+  GPR_ASSERT(s->active_ports == 0);
+  s->cb = cb;
+  s->cb_arg = cb_arg;
+  for (i = 0; i < s->nports; i++) {
+    grpc_em_fd_notify_on_read(s->ports[i].emfd, on_read, &s->ports[i],
+                              gpr_inf_future);
+    s->active_ports++;
+  }
+  gpr_mu_unlock(&s->mu);
+}
diff --git a/src/core/endpoint/tcp_server.h b/src/core/endpoint/tcp_server.h
new file mode 100644
index 0000000..99cb83e
--- /dev/null
+++ b/src/core/endpoint/tcp_server.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_ENDPOINT_TCP_SERVER_H__
+#define __GRPC_INTERNAL_ENDPOINT_TCP_SERVER_H__
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "src/core/endpoint/tcp.h"
+#include "src/core/eventmanager/em.h"
+
+/* Forward decl of grpc_tcp_server */
+typedef struct grpc_tcp_server grpc_tcp_server;
+
+/* New server callback: tcp is the newly connected tcp connection */
+typedef void (*grpc_tcp_server_cb)(void *arg, grpc_endpoint *ep);
+
+/* Create a server, initially not bound to any ports */
+grpc_tcp_server *grpc_tcp_server_create(grpc_em *em);
+
+/* Start listening to bound ports */
+void grpc_tcp_server_start(grpc_tcp_server *server, grpc_tcp_server_cb cb,
+                           void *cb_arg);
+
+/* Add a port to the server, returns a file descriptor on success, or <0 on
+   failure; the file descriptor remains owned by the server and will be cleaned
+   up when grpc_tcp_server_destroy is called */
+int grpc_tcp_server_add_port(grpc_tcp_server *server, struct sockaddr *port,
+                             int len);
+
+void grpc_tcp_server_destroy(grpc_tcp_server *server);
+
+#endif  /* __GRPC_INTERNAL_ENDPOINT_TCP_SERVER_H__ */
diff --git a/src/core/eventmanager/em.c b/src/core/eventmanager/em.c
new file mode 100644
index 0000000..e02d56c
--- /dev/null
+++ b/src/core/eventmanager/em.c
@@ -0,0 +1,664 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/eventmanager/em.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <grpc/support/atm.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+#include <event2/event.h>
+#include <event2/thread.h>
+
+int evthread_use_threads(void);
+
+#define ALARM_TRIGGER_INIT ((gpr_atm)0)
+#define ALARM_TRIGGER_INCREMENT ((gpr_atm)1)
+#define DONE_SHUTDOWN ((void *)1)
+
+#define POLLER_ID_INVALID ((gpr_atm)-1)
+
+/* ================== grpc_em implementation ===================== */
+
+/* If anything is in the work queue, process one item and return 1.
+   Return 0 if there were no work items to complete.
+   Requires em->mu locked, may unlock and relock during the call. */
+static int maybe_do_queue_work(grpc_em *em) {
+  grpc_em_activation_data *work = em->q;
+
+  if (work == NULL) return 0;
+
+  if (work->next == work) {
+    em->q = NULL;
+  } else {
+    em->q = work->next;
+    em->q->prev = work->prev;
+    em->q->next->prev = em->q->prev->next = em->q;
+  }
+  work->next = work->prev = NULL;
+  gpr_mu_unlock(&em->mu);
+
+  work->cb(work->arg, work->status);
+
+  gpr_mu_lock(&em->mu);
+  return 1;
+}
+
+/* Break out of the event loop on timeout */
+static void timer_callback(int fd, short events, void *context) {
+  event_base_loopbreak((struct event_base *)context);
+}
+
+/* Spend some time polling if no other thread is.
+   Returns 1 if polling was performed, 0 otherwise.
+   Requires em->mu locked, may unlock and relock during the call. */
+static int maybe_do_polling_work(grpc_em *em, struct timeval delay) {
+  int status;
+
+  if (em->num_pollers) return 0;
+
+  em->num_pollers = 1;
+  gpr_mu_unlock(&em->mu);
+
+  event_add(em->timeout_ev, &delay);
+  status = event_base_loop(em->event_base, EVLOOP_ONCE);
+  if (status < 0) {
+    gpr_log(GPR_ERROR, "event polling loop stops with error status %d", status);
+  }
+  event_del(em->timeout_ev);
+
+  gpr_mu_lock(&em->mu);
+  em->num_pollers = 0;
+  gpr_cv_broadcast(&em->cv);
+  return 1;
+}
+
+int grpc_em_work(grpc_em *em, gpr_timespec deadline) {
+  gpr_timespec delay_timespec = gpr_time_sub(deadline, gpr_now());
+  /* poll for no longer than one second */
+  gpr_timespec max_delay = {1, 0};
+  struct timeval delay;
+
+  GPR_ASSERT(em);
+
+  if (gpr_time_cmp(delay_timespec, gpr_time_0) <= 0) {
+    return 0;
+  }
+
+  if (gpr_time_cmp(delay_timespec, max_delay) > 0) {
+    delay_timespec = max_delay;
+  }
+
+  delay = gpr_timeval_from_timespec(delay_timespec);
+
+  if (maybe_do_queue_work(em) || maybe_do_polling_work(em, delay)) {
+    em->last_poll_completed = gpr_now();
+    return 1;
+  }
+
+  return 0;
+}
+
+static void backup_poller_thread(void *p) {
+  grpc_em *em = p;
+  int backup_poller_engaged = 0;
+  /* allow no pollers for 100 milliseconds, then engage backup polling */
+  gpr_timespec allow_no_pollers = gpr_time_from_micros(100 * 1000);
+
+  gpr_mu_lock(&em->mu);
+  while (!em->shutdown_backup_poller) {
+    if (em->num_pollers == 0) {
+      gpr_timespec now = gpr_now();
+      gpr_timespec time_until_engage = gpr_time_sub(
+          allow_no_pollers, gpr_time_sub(now, em->last_poll_completed));
+      if (gpr_time_cmp(time_until_engage, gpr_time_0) <= 0) {
+        if (!backup_poller_engaged) {
+          gpr_log(GPR_DEBUG, "No pollers for a while - engaging backup poller");
+          backup_poller_engaged = 1;
+        }
+        if (!maybe_do_queue_work(em)) {
+          struct timeval tv = {1, 0};
+          maybe_do_polling_work(em, tv);
+        }
+      } else {
+        if (backup_poller_engaged) {
+          gpr_log(GPR_DEBUG, "Backup poller disengaged");
+          backup_poller_engaged = 0;
+        }
+        gpr_mu_unlock(&em->mu);
+        gpr_sleep_until(gpr_time_add(now, time_until_engage));
+        gpr_mu_lock(&em->mu);
+      }
+    } else {
+      if (backup_poller_engaged) {
+        gpr_log(GPR_DEBUG, "Backup poller disengaged");
+        backup_poller_engaged = 0;
+      }
+      gpr_cv_wait(&em->cv, &em->mu, gpr_inf_future);
+    }
+  }
+  gpr_mu_unlock(&em->mu);
+
+  gpr_event_set(&em->backup_poller_done, (void *)1);
+}
+
+grpc_em_error grpc_em_init(grpc_em *em) {
+  gpr_thd_id backup_poller_id;
+
+  if (evthread_use_threads() != 0) {
+    gpr_log(GPR_ERROR, "Failed to initialize libevent thread support!");
+    return GRPC_EM_ERROR;
+  }
+
+  gpr_mu_init(&em->mu);
+  gpr_cv_init(&em->cv);
+  em->q = NULL;
+  em->num_pollers = 0;
+  em->num_fds = 0;
+  em->last_poll_completed = gpr_now();
+  em->shutdown_backup_poller = 0;
+
+  gpr_event_init(&em->backup_poller_done);
+
+  em->event_base = NULL;
+  em->timeout_ev = NULL;
+
+  em->event_base = event_base_new();
+  if (!em->event_base) {
+    gpr_log(GPR_ERROR, "Failed to create the event base");
+    return GRPC_EM_ERROR;
+  }
+
+  if (evthread_make_base_notifiable(em->event_base) != 0) {
+    gpr_log(GPR_ERROR, "Couldn't make event base notifiable cross threads!");
+    return GRPC_EM_ERROR;
+  }
+
+  em->timeout_ev = evtimer_new(em->event_base, timer_callback, em->event_base);
+
+  gpr_thd_new(&backup_poller_id, backup_poller_thread, em, NULL);
+
+  return GRPC_EM_OK;
+}
+
+grpc_em_error grpc_em_destroy(grpc_em *em) {
+  gpr_timespec fd_shutdown_deadline =
+      gpr_time_add(gpr_now(), gpr_time_from_micros(10 * 1000 * 1000));
+
+  /* broadcast shutdown */
+  gpr_mu_lock(&em->mu);
+  while (em->num_fds) {
+    gpr_log(GPR_INFO,
+            "waiting for %d fds to be destroyed before closing event manager",
+            em->num_fds);
+    if (gpr_cv_wait(&em->cv, &em->mu, fd_shutdown_deadline)) {
+      gpr_log(GPR_ERROR,
+              "not all fds destroyed before shutdown deadline: memory leaks "
+              "are likely");
+      break;
+    } else if (em->num_fds == 0) {
+      gpr_log(GPR_INFO, "all fds closed");
+    }
+  }
+
+  em->shutdown_backup_poller = 1;
+  gpr_cv_broadcast(&em->cv);
+  gpr_mu_unlock(&em->mu);
+
+  gpr_event_wait(&em->backup_poller_done, gpr_inf_future);
+
+  /* drain pending work */
+  gpr_mu_lock(&em->mu);
+  while (maybe_do_queue_work(em))
+    ;
+  gpr_mu_unlock(&em->mu);
+
+  /* complete shutdown */
+  gpr_mu_destroy(&em->mu);
+  gpr_cv_destroy(&em->cv);
+
+  if (em->timeout_ev != NULL) {
+    event_free(em->timeout_ev);
+  }
+
+  if (em->event_base != NULL) {
+    event_base_free(em->event_base);
+    em->event_base = NULL;
+  }
+
+  return GRPC_EM_OK;
+}
+
+static void add_task(grpc_em *em, grpc_em_activation_data *adata) {
+  gpr_mu_lock(&em->mu);
+  if (em->q) {
+    adata->next = em->q;
+    adata->prev = adata->next->prev;
+    adata->next->prev = adata->prev->next = adata;
+  } else {
+    em->q = adata;
+    adata->next = adata->prev = adata;
+  }
+  gpr_cv_broadcast(&em->cv);
+  gpr_mu_unlock(&em->mu);
+}
+
+/* ===============grpc_em_alarm implementation==================== */
+
+/* The following function frees up the alarm's libevent structure and
+   should always be invoked just before calling the alarm's callback */
+static void alarm_ev_destroy(grpc_em_alarm *alarm) {
+  grpc_em_activation_data *adata = &alarm->task.activation[GRPC_EM_TA_ONLY];
+  if (adata->ev != NULL) {
+    event_free(adata->ev);
+    adata->ev = NULL;
+  }
+}
+/* Proxy callback triggered by alarm->ev to call alarm->cb */
+static void libevent_alarm_cb(int fd, short what, void *arg /*=alarm*/) {
+  grpc_em_alarm *alarm = arg;
+  grpc_em_activation_data *adata = &alarm->task.activation[GRPC_EM_TA_ONLY];
+  int trigger_old;
+
+  /* First check if this alarm has been canceled, atomically */
+  trigger_old =
+      gpr_atm_full_fetch_add(&alarm->triggered, ALARM_TRIGGER_INCREMENT);
+  if (trigger_old == ALARM_TRIGGER_INIT) {
+    /* Before invoking user callback, destroy the libevent structure */
+    alarm_ev_destroy(alarm);
+    adata->status = GRPC_CALLBACK_SUCCESS;
+    add_task(alarm->task.em, adata);
+  }
+}
+
+grpc_em_error grpc_em_alarm_init(grpc_em_alarm *alarm, grpc_em *em,
+                                 grpc_em_cb_func alarm_cb, void *alarm_cb_arg) {
+  grpc_em_activation_data *adata = &alarm->task.activation[GRPC_EM_TA_ONLY];
+  alarm->task.type = GRPC_EM_TASK_ALARM;
+  alarm->task.em = em;
+  gpr_atm_rel_store(&alarm->triggered, ALARM_TRIGGER_INIT);
+  adata->cb = alarm_cb;
+  adata->arg = alarm_cb_arg;
+  adata->prev = NULL;
+  adata->next = NULL;
+  adata->ev = NULL;
+  return GRPC_EM_OK;
+}
+
+grpc_em_error grpc_em_alarm_add(grpc_em_alarm *alarm, gpr_timespec deadline) {
+  grpc_em_activation_data *adata = &alarm->task.activation[GRPC_EM_TA_ONLY];
+  gpr_timespec delay_timespec = gpr_time_sub(deadline, gpr_now());
+  struct timeval delay = gpr_timeval_from_timespec(delay_timespec);
+  if (adata->ev) {
+    event_free(adata->ev);
+    gpr_log(GPR_INFO, "Adding an alarm that already has an event.");
+    adata->ev = NULL;
+  }
+  adata->ev = evtimer_new(alarm->task.em->event_base, libevent_alarm_cb, alarm);
+  /* Set the trigger field to untriggered. Do this as the last store since
+     it is a release of previous stores. */
+  gpr_atm_rel_store(&alarm->triggered, ALARM_TRIGGER_INIT);
+
+  if (adata->ev != NULL && evtimer_add(adata->ev, &delay) == 0) {
+    return GRPC_EM_OK;
+  } else {
+    return GRPC_EM_ERROR;
+  }
+}
+
+grpc_em_error grpc_em_alarm_cancel(grpc_em_alarm *alarm, void **arg) {
+  grpc_em_activation_data *adata = &alarm->task.activation[GRPC_EM_TA_ONLY];
+  int trigger_old;
+
+  *arg = adata->arg;
+
+  /* First check if this alarm has been triggered, atomically */
+  trigger_old =
+      gpr_atm_full_fetch_add(&alarm->triggered, ALARM_TRIGGER_INCREMENT);
+  if (trigger_old == ALARM_TRIGGER_INIT) {
+    /* We need to make sure that we only invoke the callback if it hasn't
+       already been invoked */
+    /* First remove this event from libevent. This returns success even if the
+       event has gone active or invoked its callback. */
+    if (evtimer_del(adata->ev) != 0) {
+      /* The delete was unsuccessful for some reason. */
+      gpr_log(GPR_ERROR, "Attempt to delete alarm event was unsuccessful");
+      return GRPC_EM_ERROR;
+    }
+    /* Free up the event structure before invoking callback */
+    alarm_ev_destroy(alarm);
+    adata->status = GRPC_CALLBACK_CANCELLED;
+    add_task(alarm->task.em, adata);
+  }
+  return GRPC_EM_OK;
+}
+
+/* ==================== grpc_em_fd implementation =================== */
+
+/* Proxy callback to call a gRPC read/write callback */
+static void em_fd_cb(int fd, short what, void *arg /*=em_fd*/) {
+  grpc_em_fd *em_fd = arg;
+  grpc_em_cb_status status = GRPC_CALLBACK_SUCCESS;
+  int run_read_cb = 0;
+  int run_write_cb = 0;
+  grpc_em_activation_data *rdata, *wdata;
+
+  gpr_mu_lock(&em_fd->mu);
+  /* TODO(klempner): We need to delete the event here too so we avoid spurious
+     shutdowns. */
+  if (em_fd->shutdown_started) {
+    status = GRPC_CALLBACK_CANCELLED;
+  } else if (status == GRPC_CALLBACK_SUCCESS && (what & EV_TIMEOUT)) {
+    status = GRPC_CALLBACK_TIMED_OUT;
+    /* TODO(klempner): This is broken if we are monitoring both read and write
+       events on the same fd -- generating a spurious event is okay, but
+       generating a spurious timeout is not. */
+    what |= (EV_READ | EV_WRITE);
+  }
+
+  if (what & EV_READ) {
+    switch (em_fd->read_state) {
+      case GRPC_EM_FD_WAITING:
+        run_read_cb = 1;
+        em_fd->read_state = GRPC_EM_FD_IDLE;
+        break;
+      case GRPC_EM_FD_IDLE:
+      case GRPC_EM_FD_CACHED:
+        em_fd->read_state = GRPC_EM_FD_CACHED;
+    }
+  }
+  if (what & EV_WRITE) {
+    switch (em_fd->write_state) {
+      case GRPC_EM_FD_WAITING:
+        run_write_cb = 1;
+        em_fd->write_state = GRPC_EM_FD_IDLE;
+        break;
+      case GRPC_EM_FD_IDLE:
+      case GRPC_EM_FD_CACHED:
+        em_fd->write_state = GRPC_EM_FD_CACHED;
+    }
+  }
+
+  if (run_read_cb) {
+    rdata = &(em_fd->task.activation[GRPC_EM_TA_READ]);
+    rdata->status = status;
+    add_task(em_fd->task.em, rdata);
+  } else if (run_write_cb) {
+    wdata = &(em_fd->task.activation[GRPC_EM_TA_WRITE]);
+    wdata->status = status;
+    add_task(em_fd->task.em, wdata);
+  }
+  gpr_mu_unlock(&em_fd->mu);
+}
+
+static void em_fd_shutdown_cb(int fd, short what, void *arg /*=em_fd*/) {
+  /* TODO(klempner): This could just run directly in the calling thread, except
+     that libevent's handling of event_active() on an event which is already in
+     flight on a different thread is racy and easily triggers TSAN.
+   */
+  grpc_em_fd *em_fd = arg;
+  gpr_mu_lock(&em_fd->mu);
+  em_fd->shutdown_started = 1;
+  if (em_fd->read_state == GRPC_EM_FD_WAITING) {
+    event_active(em_fd->task.activation[GRPC_EM_TA_READ].ev, EV_READ, 1);
+  }
+  if (em_fd->write_state == GRPC_EM_FD_WAITING) {
+    event_active(em_fd->task.activation[GRPC_EM_TA_WRITE].ev, EV_WRITE, 1);
+  }
+  gpr_mu_unlock(&em_fd->mu);
+}
+
+grpc_em_error grpc_em_fd_init(grpc_em_fd *em_fd, grpc_em *em, int fd) {
+  int flags;
+  grpc_em_activation_data *rdata, *wdata;
+
+  gpr_mu_lock(&em->mu);
+  em->num_fds++;
+  gpr_mu_unlock(&em->mu);
+
+  em_fd->shutdown_ev = NULL;
+  gpr_mu_init(&em_fd->mu);
+
+  flags = fcntl(fd, F_GETFL, 0);
+  if ((flags & O_NONBLOCK) == 0) {
+    gpr_log(GPR_ERROR, "File descriptor %d is blocking", fd);
+    return GRPC_EM_INVALID_ARGUMENTS;
+  }
+
+  em_fd->task.type = GRPC_EM_TASK_FD;
+  em_fd->task.em = em;
+  em_fd->fd = fd;
+
+  rdata = &(em_fd->task.activation[GRPC_EM_TA_READ]);
+  rdata->ev = NULL;
+  rdata->cb = NULL;
+  rdata->arg = NULL;
+  rdata->status = GRPC_CALLBACK_SUCCESS;
+  rdata->prev = NULL;
+  rdata->next = NULL;
+
+  wdata = &(em_fd->task.activation[GRPC_EM_TA_WRITE]);
+  wdata->ev = NULL;
+  wdata->cb = NULL;
+  wdata->arg = NULL;
+  wdata->status = GRPC_CALLBACK_SUCCESS;
+  wdata->prev = NULL;
+  wdata->next = NULL;
+
+  em_fd->read_state = GRPC_EM_FD_IDLE;
+  em_fd->write_state = GRPC_EM_FD_IDLE;
+
+  /* TODO(chenw): detect platforms where only level trigger is supported,
+     and set the event to non-persist. */
+  rdata->ev = event_new(em->event_base, em_fd->fd, EV_ET | EV_PERSIST | EV_READ,
+                        em_fd_cb, em_fd);
+  if (!rdata->ev) {
+    gpr_log(GPR_ERROR, "Failed to create read event");
+    return GRPC_EM_ERROR;
+  }
+
+  wdata->ev = event_new(em->event_base, em_fd->fd,
+                        EV_ET | EV_PERSIST | EV_WRITE, em_fd_cb, em_fd);
+  if (!wdata->ev) {
+    gpr_log(GPR_ERROR, "Failed to create write event");
+    return GRPC_EM_ERROR;
+  }
+
+  em_fd->shutdown_ev =
+      event_new(em->event_base, -1, EV_READ, em_fd_shutdown_cb, em_fd);
+
+  if (!em_fd->shutdown_ev) {
+    gpr_log(GPR_ERROR, "Failed to create shutdown event");
+    return GRPC_EM_ERROR;
+  }
+
+  em_fd->shutdown_started = 0;
+  return GRPC_EM_OK;
+}
+
+void grpc_em_fd_destroy(grpc_em_fd *em_fd) {
+  grpc_em_task_activity_type type;
+  grpc_em_activation_data *adata;
+  grpc_em *em = em_fd->task.em;
+
+  /* ensure anyone holding the lock has left - it's the callers responsibility
+     to ensure that no new users enter */
+  gpr_mu_lock(&em_fd->mu);
+  gpr_mu_unlock(&em_fd->mu);
+
+  for (type = GRPC_EM_TA_READ; type < GRPC_EM_TA_COUNT; type++) {
+    adata = &(em_fd->task.activation[type]);
+    GPR_ASSERT(adata->next == NULL);
+    if (adata->ev != NULL) {
+      event_free(adata->ev);
+      adata->ev = NULL;
+    }
+  }
+
+  if (em_fd->shutdown_ev != NULL) {
+    event_free(em_fd->shutdown_ev);
+    em_fd->shutdown_ev = NULL;
+  }
+  gpr_mu_destroy(&em_fd->mu);
+
+  gpr_mu_lock(&em->mu);
+  em->num_fds--;
+  gpr_cv_broadcast(&em->cv);
+  gpr_mu_unlock(&em->mu);
+}
+
+int grpc_em_fd_get(struct grpc_em_fd *em_fd) { return em_fd->fd; }
+
+/* Returns the event manager associated with *em_fd. */
+grpc_em *grpc_em_fd_get_em(grpc_em_fd *em_fd) { return em_fd->task.em; }
+
+/* TODO(chenw): should we enforce the contract that notify_on_read cannot be
+   called when the previously registered callback has not been called yet. */
+grpc_em_error grpc_em_fd_notify_on_read(grpc_em_fd *em_fd,
+                                        grpc_em_cb_func read_cb,
+                                        void *read_cb_arg,
+                                        gpr_timespec deadline) {
+  int force_event = 0;
+  grpc_em_activation_data *rdata;
+  grpc_em_error result = GRPC_EM_OK;
+  gpr_timespec delay_timespec = gpr_time_sub(deadline, gpr_now());
+  struct timeval delay = gpr_timeval_from_timespec(delay_timespec);
+  struct timeval *delayp =
+      gpr_time_cmp(deadline, gpr_inf_future) ? &delay : NULL;
+
+  rdata = &em_fd->task.activation[GRPC_EM_TA_READ];
+
+  gpr_mu_lock(&em_fd->mu);
+  rdata->cb = read_cb;
+  rdata->arg = read_cb_arg;
+
+  force_event =
+      (em_fd->shutdown_started || em_fd->read_state == GRPC_EM_FD_CACHED);
+  em_fd->read_state = GRPC_EM_FD_WAITING;
+
+  if (force_event) {
+    event_active(rdata->ev, EV_READ, 1);
+  } else if (event_add(rdata->ev, delayp) == -1) {
+    result = GRPC_EM_ERROR;
+  }
+  gpr_mu_unlock(&em_fd->mu);
+  return result;
+}
+
+grpc_em_error grpc_em_fd_notify_on_write(grpc_em_fd *em_fd,
+                                         grpc_em_cb_func write_cb,
+                                         void *write_cb_arg,
+                                         gpr_timespec deadline) {
+  int force_event = 0;
+  grpc_em_activation_data *wdata;
+  grpc_em_error result = GRPC_EM_OK;
+  gpr_timespec delay_timespec = gpr_time_sub(deadline, gpr_now());
+  struct timeval delay = gpr_timeval_from_timespec(delay_timespec);
+  struct timeval *delayp =
+      gpr_time_cmp(deadline, gpr_inf_future) ? &delay : NULL;
+
+  wdata = &em_fd->task.activation[GRPC_EM_TA_WRITE];
+
+  gpr_mu_lock(&em_fd->mu);
+  wdata->cb = write_cb;
+  wdata->arg = write_cb_arg;
+
+  force_event =
+      (em_fd->shutdown_started || em_fd->write_state == GRPC_EM_FD_CACHED);
+  em_fd->write_state = GRPC_EM_FD_WAITING;
+
+  if (force_event) {
+    event_active(wdata->ev, EV_WRITE, 1);
+  } else if (event_add(wdata->ev, delayp) == -1) {
+    result = GRPC_EM_ERROR;
+  }
+  gpr_mu_unlock(&em_fd->mu);
+  return result;
+}
+
+void grpc_em_fd_shutdown(grpc_em_fd *em_fd) {
+  event_active(em_fd->shutdown_ev, EV_READ, 1);
+}
+
+/*====================== Other callback functions ======================*/
+
+/* Sometimes we want a followup callback: something to be added from the
+   current callback for the EM to invoke once this callback is complete.
+   This is implemented by inserting an entry into an EM queue. */
+
+/* The following structure holds the field needed for adding the
+   followup callback. These are the argument for the followup callback,
+   the function to use for the followup callback, and the
+   activation data pointer used for the queues (to free in the CB) */
+struct followup_callback_arg {
+  grpc_em_cb_func func;
+  void *cb_arg;
+  grpc_em_activation_data adata;
+};
+
+static void followup_proxy_callback(void *cb_arg, grpc_em_cb_status status) {
+  struct followup_callback_arg *fcb_arg = cb_arg;
+  /* Invoke the function */
+  fcb_arg->func(fcb_arg->cb_arg, status);
+  gpr_free(fcb_arg);
+}
+
+grpc_em_error grpc_em_add_callback(grpc_em *em, grpc_em_cb_func cb,
+                                   void *cb_arg) {
+  grpc_em_activation_data *adptr;
+  struct followup_callback_arg *fcb_arg;
+
+  fcb_arg = gpr_malloc(sizeof(*fcb_arg));
+  if (fcb_arg == NULL) {
+    return GRPC_EM_ERROR;
+  }
+  /* Set up the activation data and followup callback argument structures */
+  adptr = &fcb_arg->adata;
+  adptr->ev = NULL;
+  adptr->cb = followup_proxy_callback;
+  adptr->arg = fcb_arg;
+  adptr->status = GRPC_CALLBACK_SUCCESS;
+  adptr->prev = NULL;
+  adptr->next = NULL;
+
+  fcb_arg->func = cb;
+  fcb_arg->cb_arg = cb_arg;
+
+  /* Insert an activation data for the specified em */
+  add_task(em, adptr);
+  return GRPC_EM_OK;
+}
diff --git a/src/core/eventmanager/em.h b/src/core/eventmanager/em.h
new file mode 100644
index 0000000..32d37a5
--- /dev/null
+++ b/src/core/eventmanager/em.h
@@ -0,0 +1,350 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_EVENTMANAGER_EM_H__
+#define __GRPC_INTERNAL_EVENTMANAGER_EM_H__
+/* grpc_em is an event manager wrapping event loop with multithread support.
+   It executes a callback function when a specific event occurs on a file
+   descriptor or after a timeout has passed.
+   All methods are threadsafe and can be called from any thread.
+
+   To use the event manager, a grpc_em instance needs to be initialized to
+   maintains the internal states. The grpc_em instance can be used to
+   initialize file descriptor instance of grpc_em_fd, or alarm instance of
+   grpc_em_alarm. The former is used to register a callback with a IO event.
+   The later is used to schedule an alarm.
+
+   Instantiating any of these data structures requires including em_internal.h
+   A typical usage example is shown in the end of that header file.  */
+
+#include <grpc/support/atm.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+
+/* =============== Enums used in GRPC event manager API ==================== */
+
+/* Result of a grpc_em operation */
+typedef enum grpc_em_error {
+  GRPC_EM_OK = 0,           /* everything went ok */
+  GRPC_EM_ERROR,            /* internal errors not caused by the caller */
+  GRPC_EM_INVALID_ARGUMENTS /* invalid arguments from the caller */
+} grpc_em_error;
+
+/* Status passed to callbacks for grpc_em_fd_notify_on_read and
+   grpc_em_fd_notify_on_write.  */
+typedef enum grpc_em_cb_status {
+  GRPC_CALLBACK_SUCCESS = 0,
+  GRPC_CALLBACK_TIMED_OUT,
+  GRPC_CALLBACK_CANCELLED,
+  GRPC_CALLBACK_DO_NOT_USE
+} grpc_em_cb_status;
+
+/* ======= Useful forward struct typedefs for GRPC event manager API ======= */
+
+struct grpc_em;
+struct grpc_em_alarm;
+struct grpc_fd;
+
+typedef struct grpc_em grpc_em;
+typedef struct grpc_em_alarm grpc_em_alarm;
+typedef struct grpc_em_fd grpc_em_fd;
+
+/* gRPC Callback definition */
+typedef void (*grpc_em_cb_func)(void *arg, grpc_em_cb_status status);
+
+/* ============================ grpc_em =============================== */
+/* Initialize *em and start polling, return GRPC_EM_OK on success, return
+   GRPC_EM_ERROR on failure. Upon failure, caller should call grpc_em_destroy()
+   to clean partially initialized *em.
+
+   Requires:  *em uninitialized.  */
+grpc_em_error grpc_em_init(grpc_em *em);
+
+/* Stop polling and cause *em no longer to be initialized.
+   Return GRPC_EM_OK if event polling is cleanly stopped.
+   Otherwise, return GRPC_EM_ERROR if polling is shutdown with errors.
+   Requires: *em initialized; no other concurrent operation on *em.  */
+grpc_em_error grpc_em_destroy(grpc_em *em);
+
+/* do some work; assumes em->mu locked; may unlock and relock em->mu */
+int grpc_em_work(grpc_em *em, gpr_timespec deadline);
+
+/* =========================== grpc_em_am ============================== */
+/* Initialize *alarm. When expired or canceled, alarm_cb will be called with
+   *alarm_cb_arg and status to indicate if it expired (SUCCESS) or was
+   canceled (CANCELLED). alarm_cb is guaranteed to be called exactly once,
+   and application code should check the status to determine how it was
+   invoked. The application callback is also responsible for maintaining
+   information about when to free up any user-level state.  */
+grpc_em_error grpc_em_alarm_init(grpc_em_alarm *alarm, grpc_em *em,
+                                 grpc_em_cb_func alarm_cb, void *alarm_cb_arg);
+
+/* Note that there is no alarm destroy function. This is because the
+   alarm is a one-time occurrence with a guarantee that the callback will
+   be called exactly once, either at expiration or cancellation. Thus, all
+   the internal alarm event management state is destroyed just before
+   that callback is invoked. If the user has additional state associated with
+   the alarm, the user is responsible for determining when it is safe to
+   destroy that state. */
+
+/* Schedule *alarm to expire at deadline. If *alarm is
+   re-added before expiration, the *delay is simply reset to the new value.
+   Return GRPC_EM_OK on success, or GRPC_EM_ERROR on failure.
+   Upon failure, caller should abort further operations on *alarm */
+grpc_em_error grpc_em_alarm_add(grpc_em_alarm *alarm, gpr_timespec deadline);
+
+/* Cancel an *alarm.
+   There are three cases:
+   1. We normally cancel the alarm
+   2. The alarm has already run
+   3. We can't cancel the alarm because it is "in flight".
+
+   In all of these cases, the cancellation is still considered successful.
+   They are essentially distinguished in that the alarm_cb will be run
+   exactly once from either the cancellation (with status CANCELLED)
+   or from the activation (with status SUCCESS)
+
+   Requires:  cancel() must happen after add() on a given alarm */
+grpc_em_error grpc_em_alarm_cancel(grpc_em_alarm *alarm, void **arg);
+
+/* ========================== grpc_em_fd ============================= */
+
+/* Initialize *em_fd, return GRPM_EM_OK on success, GRPC_EM_ERROR on internal
+   errors, or GRPC_EM_INVALID_ARGUMENTS if fd is a blocking file descriptor.
+   Upon failure, caller should call grpc_em_fd_destroy() to clean partially
+   initialized *em_fd.
+   fd is a non-blocking file descriptor.
+
+   Requires:  *em_fd uninitialized. fd is a non-blocking file descriptor.  */
+grpc_em_error grpc_em_fd_init(grpc_em_fd *em_fd, grpc_em *em, int fd);
+
+/* Cause *em_fd no longer to be initialized.
+   Requires: *em_fd initialized; no outstanding notify_on_read or
+   notify_on_write.  */
+void grpc_em_fd_destroy(grpc_em_fd *em_fd);
+
+/* Returns the file descriptor associated with *em_fd. */
+int grpc_em_fd_get(grpc_em_fd *em_fd);
+
+/* Returns the event manager associated with *em_fd. */
+grpc_em *grpc_em_fd_get_em(grpc_em_fd *em_fd);
+
+/* Register read interest, causing read_cb to be called once when em_fd becomes
+   readable, on deadline specified by deadline, or on shutdown triggered by
+   grpc_em_fd_shutdown.
+   Return GRPC_EM_OK on success, or GRPC_EM_ERROR on failure.
+   Upon Failure, caller should abort further operations on *em_fd except
+   grpc_em_fd_shutdown().
+   read_cb will be called with read_cb_arg when *em_fd becomes readable.
+   read_cb is Called with status of GRPC_CALLBACK_SUCCESS if readable,
+   GRPC_CALLBACK_TIMED_OUT if the call timed out,
+   and CANCELLED if the call was cancelled.
+
+   Requires:This method must not be called before the read_cb for any previous
+   call runs. Edge triggered events are used whenever they are supported by the
+   underlying platform. This means that users must drain em_fd in read_cb before
+   calling notify_on_read again. Users are also expected to handle spurious
+   events, i.e read_cb is called while nothing can be readable from em_fd  */
+grpc_em_error grpc_em_fd_notify_on_read(grpc_em_fd *em_fd,
+                                        grpc_em_cb_func read_cb,
+                                        void *read_cb_arg,
+                                        gpr_timespec deadline);
+
+/* Exactly the same semantics as above, except based on writable events.  */
+grpc_em_error grpc_em_fd_notify_on_write(grpc_em_fd *fd,
+                                         grpc_em_cb_func write_cb,
+                                         void *write_cb_arg,
+                                         gpr_timespec deadline);
+
+/* Cause any current and all future read/write callbacks to error out with
+   GRPC_CALLBACK_CANCELLED. */
+void grpc_em_fd_shutdown(grpc_em_fd *em_fd);
+
+/* ================== Other functions =================== */
+
+/* This function is called from within a callback or from anywhere else
+   and causes the invocation of a callback at some point in the future */
+grpc_em_error grpc_em_add_callback(grpc_em *em, grpc_em_cb_func cb,
+                                   void *cb_arg);
+
+/* ========== Declarations related to queue management (non-API) =========== */
+
+/* Forward declarations */
+struct grpc_em_activation_data;
+
+/* ================== Actual structure definitions ========================= */
+/* gRPC event manager handle.
+   The handle is used to initialize both grpc_em_alarm and grpc_em_fd. */
+struct em_thread_arg;
+
+struct grpc_em {
+  struct event_base *event_base;
+
+  gpr_mu mu;
+  gpr_cv cv;
+  struct grpc_em_activation_data *q;
+  int num_pollers;
+  int num_fds;
+  gpr_timespec last_poll_completed;
+
+  int shutdown_backup_poller;
+  gpr_event backup_poller_done;
+
+  struct event *timeout_ev; /* activated to break out of the event loop early */
+};
+
+/* gRPC event manager task "base class". This is pretend-inheritance in C89.
+   This should be the first member of any actual grpc_em task type.
+
+   Memory warning: expanding this will increase memory usage in any derived
+   class, so be careful.
+
+   For generality, this base can be on multiple task queues and can have
+   multiple event callbacks registered. Not all "derived classes" will use
+   this feature. */
+
+typedef enum grpc_em_task_type {
+  GRPC_EM_TASK_ALARM,
+  GRPC_EM_TASK_FD,
+  GRPC_EM_TASK_DO_NOT_USE
+} grpc_em_task_type;
+
+/* Different activity types to shape the callback and queueing arrays */
+typedef enum grpc_em_task_activity_type {
+  GRPC_EM_TA_READ, /* use this also for single-type events */
+  GRPC_EM_TA_WRITE,
+  GRPC_EM_TA_COUNT
+} grpc_em_task_activity_type;
+
+/* Include the following #define for convenience for tasks like alarms that
+   only have a single type */
+#define GRPC_EM_TA_ONLY GRPC_EM_TA_READ
+
+typedef struct grpc_em_activation_data {
+  struct event *ev;   /* event activated on this callback type */
+  grpc_em_cb_func cb; /* function pointer for callback */
+  void *arg;          /* argument passed to cb */
+
+  /* Hold the status associated with the callback when queued */
+  grpc_em_cb_status status;
+  /* Now set up to link activations into scheduler queues */
+  struct grpc_em_activation_data *prev;
+  struct grpc_em_activation_data *next;
+} grpc_em_activation_data;
+
+typedef struct grpc_em_task {
+  grpc_em_task_type type;
+  grpc_em *em;
+
+  /* Now have an array of activation data elements: one for each activity
+     type that could get activated */
+  grpc_em_activation_data activation[GRPC_EM_TA_COUNT];
+} grpc_em_task;
+
+/* gRPC alarm handle.
+   The handle is used to add an alarm which expires after specified timeout. */
+struct grpc_em_alarm {
+  grpc_em_task task; /* Include the base class */
+
+  gpr_atm triggered; /* To be used atomically if alarm triggered */
+};
+
+/* =================== Event caching ===================
+   In order to not miss or double-return edges in the context of edge triggering
+   and multithreading, we need a per-fd caching layer in the eventmanager itself
+   to cache relevant events.
+
+   There are two types of events we care about: calls to notify_on_[read|write]
+   and readable/writable events for the socket from eventfd. There are separate
+   event caches for read and write.
+
+   There are three states:
+   0. "waiting" -- There's been a call to notify_on_[read|write] which has not
+   had a corresponding event. In other words, we're waiting for an event so we
+   can run the callback.
+   1. "idle" -- We are neither waiting nor have a cached event.
+   2. "cached" -- There has been a read/write event without a waiting callback,
+   so we want to run the event next time the application calls
+   notify_on_[read|write].
+
+   The high level state diagram:
+
+   +--------------------------------------------------------------------+
+   | WAITING                  | IDLE                | CACHED            |
+   |                          |                     |                   |
+   |                     1. --*->              2. --+->           3.  --+\
+   |                          |                     |                <--+/
+   |                          |                     |                   |
+  x+-- 6.                5. <-+--              4. <-*--                 |
+   |                          |                     |                   |
+   +--------------------------------------------------------------------+
+
+   Transitions right occur on read|write events. Transitions left occur on
+   notify_on_[read|write] events.
+   State transitions:
+   1. Read|Write event while waiting -> run the callback and transition to idle.
+   2. Read|Write event while idle -> transition to cached.
+   3. Read|Write event with one already cached -> still cached.
+   4. notify_on_[read|write] with event cached: run callback and transition to
+      idle.
+   5. notify_on_[read|write] when idle: Store callback and transition to
+      waiting.
+   6. notify_on_[read|write] when waiting: invalid. */
+
+typedef enum grpc_em_fd_state {
+  GRPC_EM_FD_WAITING = 0,
+  GRPC_EM_FD_IDLE = 1,
+  GRPC_EM_FD_CACHED = 2
+} grpc_em_fd_state;
+
+/* gRPC file descriptor handle.
+   The handle is used to register read/write callbacks to a file descriptor */
+struct grpc_em_fd {
+  grpc_em_task task; /* Base class, callbacks, queues, etc */
+  int fd;            /* File descriptor */
+
+  /* Note that the shutdown event is only needed as a workaround for libevent
+     not properly handling event_active on an in flight event. */
+  struct event *shutdown_ev; /* activated to trigger shutdown */
+
+  /* protect shutdown_started|read_state|write_state and ensure barriers
+     between notify_on_[read|write] and read|write callbacks */
+  gpr_mu mu;
+  int shutdown_started; /* 0 -> shutdown not started, 1 -> started */
+  grpc_em_fd_state read_state;
+  grpc_em_fd_state write_state;
+  /* activated after some timeout to activate shutdown_ev */
+};
+
+#endif  /* __GRPC_INTERNAL_EVENTMANAGER_EM_H__ */
diff --git a/src/core/eventmanager/em_posix.c b/src/core/eventmanager/em_posix.c
new file mode 100644
index 0000000..af44934
--- /dev/null
+++ b/src/core/eventmanager/em_posix.c
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix grpc event manager support code. */
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <event2/thread.h>
+
+static int error_code = 0;
+static gpr_once threads_once = GPR_ONCE_INIT;
+static void evthread_threads_initialize(void) {
+  error_code = evthread_use_pthreads();
+  if (error_code) {
+    gpr_log(GPR_ERROR, "Failed to initialize libevent thread support!");
+  }
+}
+
+/* Notify LibEvent that Posix pthread is used. */
+int evthread_use_threads() {
+  gpr_once_init(&threads_once, &evthread_threads_initialize);
+  /* For Pthreads or Windows threads, Libevent provides simple APIs to set
+     mutexes and conditional variables to support cross thread operations.
+     For other platforms, LibEvent provide callback APIs to hook mutexes and
+     conditional variables. */
+  return error_code;
+}
diff --git a/src/core/eventmanager/em_win32.c b/src/core/eventmanager/em_win32.c
new file mode 100644
index 0000000..4d5c3b5
--- /dev/null
+++ b/src/core/eventmanager/em_win32.c
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Windows event manager support code. */
+#include <event2/thread.h>
+
+/* Notify LibEvent that Windows thread is used. */
+int evthread_use_threads() { return evthread_use_windows_threads(); }
diff --git a/src/core/httpcli/format_request.c b/src/core/httpcli/format_request.c
new file mode 100644
index 0000000..7a44f12
--- /dev/null
+++ b/src/core/httpcli/format_request.c
@@ -0,0 +1,121 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/httpcli/format_request.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/useful.h>
+
+typedef struct {
+  size_t length;
+  size_t capacity;
+  char *data;
+} sbuf;
+
+static void sbuf_append(sbuf *buf, const char *bytes, size_t len) {
+  if (buf->length + len > buf->capacity) {
+    buf->capacity = GPR_MAX(buf->length + len, buf->capacity * 3 / 2);
+    buf->data = gpr_realloc(buf->data, buf->capacity);
+  }
+  memcpy(buf->data + buf->length, bytes, len);
+  buf->length += len;
+}
+
+static void sbprintf(sbuf *buf, const char *fmt, ...) {
+  char temp[GRPC_HTTPCLI_MAX_HEADER_LENGTH];
+  size_t len;
+  va_list args;
+
+  va_start(args, fmt);
+  len = vsprintf(temp, fmt, args);
+  va_end(args);
+
+  sbuf_append(buf, temp, len);
+}
+
+static void fill_common_header(const grpc_httpcli_request *request, sbuf *buf) {
+  size_t i;
+  sbprintf(buf, "%s HTTP/1.0\r\n", request->path);
+  /* just in case some crazy server really expects HTTP/1.1 */
+  sbprintf(buf, "Host: %s\r\n", request->host);
+  sbprintf(buf, "Connection: close\r\n");
+  sbprintf(buf, "User-Agent: %s\r\n", GRPC_HTTPCLI_USER_AGENT);
+  /* user supplied headers */
+  for (i = 0; i < request->hdr_count; i++) {
+    sbprintf(buf, "%s: %s\r\n", request->hdrs[i].key, request->hdrs[i].value);
+  }
+}
+
+gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) {
+  sbuf out = {0, 0, NULL};
+
+  sbprintf(&out, "GET ");
+  fill_common_header(request, &out);
+  sbprintf(&out, "\r\n");
+
+  return gpr_slice_new(out.data, out.length, gpr_free);
+}
+
+gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
+                                           const char *body_bytes,
+                                           size_t body_size) {
+  sbuf out = {0, 0, NULL};
+  size_t i;
+
+  sbprintf(&out, "POST ");
+  fill_common_header(request, &out);
+  if (body_bytes) {
+    gpr_uint8 has_content_type = 0;
+    for (i = 0; i < request->hdr_count; i++) {
+      if (strcmp(request->hdrs[i].key, "Content-Type") == 0) {
+        has_content_type = 1;
+        break;
+      }
+    }
+    if (!has_content_type) {
+      sbprintf(&out, "Content-Type: text/plain\r\n");
+    }
+    sbprintf(&out, "Content-Length: %lu\r\n", (unsigned long)body_size);
+  }
+  sbprintf(&out, "\r\n");
+  if (body_bytes) {
+    sbuf_append(&out, body_bytes, body_size);
+  }
+
+  return gpr_slice_new(out.data, out.length, gpr_free);
+}
diff --git a/src/core/httpcli/format_request.h b/src/core/httpcli/format_request.h
new file mode 100644
index 0000000..988f872
--- /dev/null
+++ b/src/core/httpcli/format_request.h
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__
+#define __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__
+
+#include "src/core/httpcli/httpcli.h"
+#include <grpc/support/slice.h>
+
+gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request);
+gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
+                                           const char *body_bytes,
+                                           size_t body_size);
+
+#endif  /* __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__ */
diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c
new file mode 100644
index 0000000..6c0a688
--- /dev/null
+++ b/src/core/httpcli/httpcli.c
@@ -0,0 +1,259 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/httpcli/httpcli.h"
+
+#include <string.h>
+
+#include "src/core/endpoint/endpoint.h"
+#include "src/core/endpoint/resolve_address.h"
+#include "src/core/endpoint/tcp_client.h"
+#include "src/core/httpcli/format_request.h"
+#include "src/core/httpcli/httpcli_security_context.h"
+#include "src/core/httpcli/parser.h"
+#include "src/core/security/security_context.h"
+#include "src/core/security/google_root_certs.h"
+#include "src/core/security/secure_transport_setup.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+
+typedef struct {
+  gpr_slice request_text;
+  grpc_httpcli_parser parser;
+  grpc_resolved_addresses *addresses;
+  size_t next_address;
+  grpc_endpoint *ep;
+  grpc_em *em;
+  char *host;
+  gpr_timespec deadline;
+  int have_read_byte;
+  int use_ssl;
+  grpc_httpcli_response_cb on_response;
+  void *user_data;
+} internal_request;
+
+static void next_address(internal_request *req);
+
+static void finish(internal_request *req, int success) {
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  req->on_response(req->user_data, success ? &req->parser.r : NULL);
+  grpc_httpcli_parser_destroy(&req->parser);
+  if (req->addresses != NULL) {
+    grpc_resolved_addresses_destroy(req->addresses);
+  }
+  if (req->ep != NULL) {
+    grpc_endpoint_destroy(req->ep);
+  }
+  gpr_slice_unref(req->request_text);
+  gpr_free(req->host);
+  gpr_free(req);
+}
+
+static void on_read(void *user_data, gpr_slice *slices, size_t nslices,
+                    grpc_endpoint_cb_status status) {
+  internal_request *req = user_data;
+  size_t i;
+
+  gpr_log(GPR_DEBUG, "%s nslices=%d status=%d", __FUNCTION__, nslices, status);
+
+  for (i = 0; i < nslices; i++) {
+    if (GPR_SLICE_LENGTH(slices[i])) {
+      req->have_read_byte = 1;
+      if (!grpc_httpcli_parser_parse(&req->parser, slices[i])) {
+        finish(req, 0);
+        goto done;
+      }
+    }
+  }
+
+  switch (status) {
+    case GRPC_ENDPOINT_CB_OK:
+      grpc_endpoint_notify_on_read(req->ep, on_read, req, gpr_inf_future);
+      break;
+    case GRPC_ENDPOINT_CB_EOF:
+    case GRPC_ENDPOINT_CB_ERROR:
+    case GRPC_ENDPOINT_CB_SHUTDOWN:
+    case GRPC_ENDPOINT_CB_TIMED_OUT:
+      if (!req->have_read_byte) {
+        next_address(req);
+      } else {
+        finish(req, grpc_httpcli_parser_eof(&req->parser));
+      }
+      break;
+  }
+
+done:
+  for (i = 0; i < nslices; i++) {
+    gpr_slice_unref(slices[i]);
+  }
+}
+
+static void on_written(internal_request *req) {
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  grpc_endpoint_notify_on_read(req->ep, on_read, req, gpr_inf_future);
+}
+
+static void done_write(void *arg, grpc_endpoint_cb_status status) {
+  internal_request *req = arg;
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  switch (status) {
+    case GRPC_ENDPOINT_CB_OK:
+      on_written(req);
+      break;
+    case GRPC_ENDPOINT_CB_EOF:
+    case GRPC_ENDPOINT_CB_SHUTDOWN:
+    case GRPC_ENDPOINT_CB_ERROR:
+    case GRPC_ENDPOINT_CB_TIMED_OUT:
+      next_address(req);
+      break;
+  }
+}
+
+static void start_write(internal_request *req) {
+  gpr_slice_ref(req->request_text);
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  switch (grpc_endpoint_write(req->ep, &req->request_text, 1, done_write, req,
+                              gpr_inf_future)) {
+    case GRPC_ENDPOINT_WRITE_DONE:
+      on_written(req);
+      break;
+    case GRPC_ENDPOINT_WRITE_PENDING:
+      break;
+    case GRPC_ENDPOINT_WRITE_ERROR:
+      finish(req, 0);
+      break;
+  }
+}
+
+static void on_secure_transport_setup_done(void *rp,
+                                           grpc_security_status status,
+                                           grpc_endpoint *secure_endpoint) {
+  internal_request *req = rp;
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  if (status != GRPC_SECURITY_OK) {
+    gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
+    finish(req, 0);
+  } else {
+    req->ep = secure_endpoint;
+    start_write(req);
+  }
+}
+
+static void on_connected(void *arg, grpc_endpoint *tcp) {
+  internal_request *req = arg;
+
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  if (!tcp) {
+    next_address(req);
+    return;
+  }
+  req->ep = tcp;
+  if (req->use_ssl) {
+    grpc_channel_security_context *ctx = NULL;
+    GPR_ASSERT(grpc_httpcli_ssl_channel_security_context_create(
+                   grpc_google_root_certs, grpc_google_root_certs_size,
+                   req->host, &ctx) == GRPC_SECURITY_OK);
+    grpc_setup_secure_transport(&ctx->base, tcp, on_secure_transport_setup_done,
+                                req);
+    grpc_security_context_unref(&ctx->base);
+  } else {
+    start_write(req);
+  }
+}
+
+static void next_address(internal_request *req) {
+  grpc_resolved_address *addr;
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  if (req->next_address == req->addresses->naddrs) {
+    finish(req, 0);
+    return;
+  }
+  addr = &req->addresses->addrs[req->next_address++];
+  grpc_tcp_client_connect(on_connected, req, req->em,
+                          (struct sockaddr *)&addr->addr, addr->len,
+                          req->deadline);
+}
+
+static void on_resolved(void *arg, grpc_resolved_addresses *addresses) {
+  internal_request *req = arg;
+  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
+  if (!addresses) {
+    finish(req, 0);
+  }
+  req->addresses = addresses;
+  req->next_address = 0;
+  next_address(req);
+}
+
+void grpc_httpcli_get(const grpc_httpcli_request *request,
+                      gpr_timespec deadline, grpc_em *em,
+                      grpc_httpcli_response_cb on_response, void *user_data) {
+  internal_request *req = gpr_malloc(sizeof(internal_request));
+  memset(req, 0, sizeof(*req));
+  req->request_text = grpc_httpcli_format_get_request(request);
+  grpc_httpcli_parser_init(&req->parser);
+  req->on_response = on_response;
+  req->user_data = user_data;
+  req->em = em;
+  req->deadline = deadline;
+  req->use_ssl = request->use_ssl;
+  if (req->use_ssl) {
+    req->host = gpr_strdup(request->host);
+  }
+
+  grpc_resolve_address(request->host, req->use_ssl ? "https" : "http",
+                       on_resolved, req);
+}
+
+void grpc_httpcli_post(const grpc_httpcli_request *request,
+                       const char *body_bytes, size_t body_size,
+                       gpr_timespec deadline, grpc_em *em,
+                       grpc_httpcli_response_cb on_response, void *user_data) {
+  internal_request *req = gpr_malloc(sizeof(internal_request));
+  memset(req, 0, sizeof(*req));
+  req->request_text =
+      grpc_httpcli_format_post_request(request, body_bytes, body_size);
+  grpc_httpcli_parser_init(&req->parser);
+  req->on_response = on_response;
+  req->user_data = user_data;
+  req->em = em;
+  req->deadline = deadline;
+  req->use_ssl = request->use_ssl;
+  if (req->use_ssl) {
+    req->host = gpr_strdup(request->host);
+  }
+
+  grpc_resolve_address(request->host, req->use_ssl ? "https" : "http",
+                       on_resolved, req);
+}
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
new file mode 100644
index 0000000..aef0edf
--- /dev/null
+++ b/src/core/httpcli/httpcli.h
@@ -0,0 +1,104 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__
+#define __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__
+
+#include <stddef.h>
+
+#include "src/core/eventmanager/em.h"
+#include <grpc/support/time.h>
+
+/* User agent this library reports */
+#define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0"
+/* Maximum length of a header string of the form 'Key: Value\r\n' */
+#define GRPC_HTTPCLI_MAX_HEADER_LENGTH 4096
+
+/* A single header to be passed in a request */
+typedef struct grpc_httpcli_header {
+  char *key;
+  char *value;
+} grpc_httpcli_header;
+
+/* A request */
+typedef struct grpc_httpcli_request {
+  /* The host name to connect to */
+  char *host;
+  /* The path of the resource to fetch */
+  char *path;
+  /* Additional headers: count and key/values; the following are supplied
+     automatically and MUST NOT be set here:
+       Host, Connection, User-Agent */
+  size_t hdr_count;
+  grpc_httpcli_header *hdrs;
+  /* whether to use ssl for the request */
+  int use_ssl;
+} grpc_httpcli_request;
+
+/* A response */
+typedef struct grpc_httpcli_response {
+  /* HTTP status code */
+  int status;
+  /* Headers: count and key/values */
+  size_t hdr_count;
+  grpc_httpcli_header *hdrs;
+  /* Body: length and contents; contents are NOT null-terminated */
+  size_t body_length;
+  char *body;
+} grpc_httpcli_response;
+
+/* Callback for grpc_httpcli_get */
+typedef void (*grpc_httpcli_response_cb)(void *user_data,
+                                         const grpc_httpcli_response *response);
+
+/* Asynchronously perform a HTTP GET.
+   'request' contains request parameters - these are caller owned and can be
+     destroyed once the call returns
+   'deadline' contains a deadline for the request (or gpr_inf_future)
+   'em' points to a caller owned event manager that must be alive for the
+     lifetime of the request
+   'on_response' is a callback to report results to (and 'user_data' is a user
+     supplied pointer to pass to said call) */
+void grpc_httpcli_get(const grpc_httpcli_request *request,
+                      gpr_timespec deadline, grpc_em *em,
+                      grpc_httpcli_response_cb on_response, void *user_data);
+
+/* Asynchronously perform a HTTP POST.
+   When there is no body, pass in NULL as body_bytes.
+   Does not support ?var1=val1&var2=val2 in the path. */
+void grpc_httpcli_post(const grpc_httpcli_request *request,
+                       const char *body_bytes, size_t body_size,
+                       gpr_timespec deadline, grpc_em *em,
+                       grpc_httpcli_response_cb on_response, void *user_data);
+
+#endif  /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__ */
diff --git a/src/core/httpcli/httpcli_security_context.c b/src/core/httpcli/httpcli_security_context.c
new file mode 100644
index 0000000..c7b9b33
--- /dev/null
+++ b/src/core/httpcli/httpcli_security_context.c
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/httpcli/httpcli_security_context.h"
+
+#include <string.h>
+
+#include "src/core/security/secure_transport_setup.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include "src/core/tsi/ssl_transport_security.h"
+
+typedef struct {
+  grpc_channel_security_context base;
+  tsi_ssl_handshaker_factory *handshaker_factory;
+  char *secure_peer_name;
+} grpc_httpcli_ssl_channel_security_context;
+
+static void httpcli_ssl_destroy(grpc_security_context *ctx) {
+  grpc_httpcli_ssl_channel_security_context *c =
+      (grpc_httpcli_ssl_channel_security_context *)ctx;
+  if (c->handshaker_factory != NULL) {
+    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
+  }
+  if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
+  gpr_free(ctx);
+}
+
+static grpc_security_status httpcli_ssl_create_handshaker(
+    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+  grpc_httpcli_ssl_channel_security_context *c =
+      (grpc_httpcli_ssl_channel_security_context *)ctx;
+  tsi_result result = TSI_OK;
+  if (c->handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
+  result = tsi_ssl_handshaker_factory_create_handshaker(
+      c->handshaker_factory, c->secure_peer_name, handshaker);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
+            tsi_result_to_string(result));
+    return GRPC_SECURITY_ERROR;
+  }
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_status httpcli_ssl_check_peer(
+    grpc_security_context *ctx, const tsi_peer *peer,
+    grpc_security_check_peer_cb cb, void *user_data) {
+  grpc_httpcli_ssl_channel_security_context *c =
+      (grpc_httpcli_ssl_channel_security_context *)ctx;
+
+  /* Check the peer name. */
+  if (c->secure_peer_name != NULL &&
+      !tsi_ssl_peer_matches_name(peer, c->secure_peer_name)) {
+    gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate",
+            c->secure_peer_name);
+    return GRPC_SECURITY_ERROR;
+  }
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_context_vtable httpcli_ssl_vtable = {
+    httpcli_ssl_destroy, httpcli_ssl_create_handshaker, httpcli_ssl_check_peer};
+
+grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
+    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
+    const char *secure_peer_name, grpc_channel_security_context **ctx) {
+  tsi_result result = TSI_OK;
+  grpc_httpcli_ssl_channel_security_context *c;
+
+  if (secure_peer_name != NULL && pem_root_certs == NULL) {
+    gpr_log(GPR_ERROR,
+            "Cannot assert a secure peer name without a trust root.");
+    return GRPC_SECURITY_ERROR;
+  }
+
+  c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_context));
+  memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_context));
+
+  gpr_ref_init(&c->base.base.refcount, 1);
+  c->base.base.is_client_side = 1;
+  c->base.base.vtable = &httpcli_ssl_vtable;
+  if (secure_peer_name != NULL) {
+    c->secure_peer_name = gpr_strdup(secure_peer_name);
+  }
+  result = tsi_create_ssl_client_handshaker_factory(
+      NULL, 0, NULL, 0, pem_root_certs, pem_root_certs_size, NULL, NULL, NULL,
+      0, &c->handshaker_factory);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+            tsi_result_to_string(result));
+    httpcli_ssl_destroy(&c->base.base);
+    *ctx = NULL;
+    return GRPC_SECURITY_ERROR;
+  }
+  *ctx = &c->base;
+  return GRPC_SECURITY_OK;
+}
diff --git a/src/core/httpcli/httpcli_security_context.h b/src/core/httpcli/httpcli_security_context.h
new file mode 100644
index 0000000..c267622
--- /dev/null
+++ b/src/core/httpcli/httpcli_security_context.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__
+#define __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__
+
+#include "src/core/security/security_context.h"
+
+grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
+    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
+    const char *secure_peer_name, grpc_channel_security_context **ctx);
+
+#endif  /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__ */
diff --git a/src/core/httpcli/parser.c b/src/core/httpcli/parser.c
new file mode 100644
index 0000000..1f0c516
--- /dev/null
+++ b/src/core/httpcli/parser.c
@@ -0,0 +1,212 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/httpcli/parser.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+static int handle_response_line(grpc_httpcli_parser *parser) {
+  gpr_uint8 *beg = parser->cur_line;
+  gpr_uint8 *cur = beg;
+  gpr_uint8 *end = beg + parser->cur_line_length;
+
+  if (cur == end || *cur++ != 'H') goto error;
+  if (cur == end || *cur++ != 'T') goto error;
+  if (cur == end || *cur++ != 'T') goto error;
+  if (cur == end || *cur++ != 'P') goto error;
+  if (cur == end || *cur++ != '/') goto error;
+  if (cur == end || *cur++ != '1') goto error;
+  if (cur == end || *cur++ != '.') goto error;
+  if (cur == end || *cur < '0' || *cur++ > '1') goto error;
+  if (cur == end || *cur++ != ' ') goto error;
+  if (cur == end || *cur < '1' || *cur++ > '9') goto error;
+  if (cur == end || *cur < '0' || *cur++ > '9') goto error;
+  if (cur == end || *cur < '0' || *cur++ > '9') goto error;
+  parser->r.status =
+      (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0');
+  if (cur == end || *cur++ != ' ') goto error;
+
+  /* we don't really care about the status code message */
+
+  return 1;
+
+error:
+  gpr_log(GPR_ERROR, "Failed parsing response line");
+  return 0;
+}
+
+static char *buf2str(void *buffer, size_t length) {
+  char *out = gpr_malloc(length + 1);
+  memcpy(out, buffer, length);
+  out[length] = 0;
+  return out;
+}
+
+static int add_header(grpc_httpcli_parser *parser) {
+  gpr_uint8 *beg = parser->cur_line;
+  gpr_uint8 *cur = beg;
+  gpr_uint8 *end = beg + parser->cur_line_length;
+  grpc_httpcli_header hdr = {NULL, NULL};
+
+  GPR_ASSERT(cur != end);
+
+  if (*cur == ' ' || *cur == '\t') {
+    gpr_log(GPR_ERROR, "Continued header lines not supported yet");
+    goto error;
+  }
+
+  while (cur != end && *cur != ':') {
+    cur++;
+  }
+  if (cur == end) {
+    gpr_log(GPR_ERROR, "Didn't find ':' in header string");
+    goto error;
+  }
+  hdr.key = buf2str(beg, cur - beg);
+  cur++; /* skip : */
+
+  while (cur != end && (*cur == ' ' || *cur == '\t')) {
+    cur++;
+  }
+  hdr.value = buf2str(cur, end - cur - 2);
+
+  if (parser->r.hdr_count == parser->hdr_capacity) {
+    parser->hdr_capacity =
+        GPR_MAX(parser->hdr_capacity + 1, parser->hdr_capacity * 3 / 2);
+    parser->r.hdrs = gpr_realloc(
+        parser->r.hdrs, parser->hdr_capacity * sizeof(*parser->r.hdrs));
+  }
+  parser->r.hdrs[parser->r.hdr_count++] = hdr;
+  return 1;
+
+error:
+  gpr_free(hdr.key);
+  gpr_free(hdr.value);
+  return 0;
+}
+
+static int finish_line(grpc_httpcli_parser *parser) {
+  switch (parser->state) {
+    case GRPC_HTTPCLI_INITIAL_RESPONSE:
+      if (!handle_response_line(parser)) {
+        return 0;
+      }
+      parser->state = GRPC_HTTPCLI_HEADERS;
+      break;
+    case GRPC_HTTPCLI_HEADERS:
+      if (parser->cur_line_length == 2) {
+        parser->state = GRPC_HTTPCLI_BODY;
+        break;
+      }
+      if (!add_header(parser)) {
+        return 0;
+      }
+      break;
+    case GRPC_HTTPCLI_BODY:
+      gpr_log(GPR_ERROR, "should never reach here");
+      abort();
+  }
+
+  parser->cur_line_length = 0;
+  return 1;
+}
+
+static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) {
+  switch (parser->state) {
+    case GRPC_HTTPCLI_INITIAL_RESPONSE:
+    case GRPC_HTTPCLI_HEADERS:
+      if (parser->cur_line_length >= GRPC_HTTPCLI_MAX_HEADER_LENGTH) {
+        gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded",
+                GRPC_HTTPCLI_MAX_HEADER_LENGTH);
+        return 0;
+      }
+      parser->cur_line[parser->cur_line_length] = byte;
+      parser->cur_line_length++;
+      if (parser->cur_line_length >= 2 &&
+          parser->cur_line[parser->cur_line_length - 2] == '\r' &&
+          parser->cur_line[parser->cur_line_length - 1] == '\n') {
+        return finish_line(parser);
+      } else {
+        return 1;
+      }
+      gpr_log(GPR_ERROR, "should never reach here");
+      abort();
+    case GRPC_HTTPCLI_BODY:
+      if (parser->r.body_length == parser->body_capacity) {
+        parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2);
+        parser->r.body =
+            gpr_realloc((void *)parser->r.body, parser->body_capacity);
+      }
+      ((char *)parser->r.body)[parser->r.body_length] = byte;
+      parser->r.body_length++;
+      return 1;
+  }
+  gpr_log(GPR_ERROR, "should never reach here");
+  abort();
+}
+
+void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) {
+  memset(parser, 0, sizeof(*parser));
+  parser->state = GRPC_HTTPCLI_INITIAL_RESPONSE;
+  parser->r.status = 500;
+}
+
+void grpc_httpcli_parser_destroy(grpc_httpcli_parser *parser) {
+  size_t i;
+  gpr_free(parser->r.body);
+  for (i = 0; i < parser->r.hdr_count; i++) {
+    gpr_free(parser->r.hdrs[i].key);
+    gpr_free(parser->r.hdrs[i].value);
+  }
+  gpr_free(parser->r.hdrs);
+}
+
+int grpc_httpcli_parser_parse(grpc_httpcli_parser *parser, gpr_slice slice) {
+  size_t i;
+
+  for (i = 0; i < GPR_SLICE_LENGTH(slice); i++) {
+    if (!addbyte(parser, GPR_SLICE_START_PTR(slice)[i])) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+int grpc_httpcli_parser_eof(grpc_httpcli_parser *parser) {
+  return parser->state == GRPC_HTTPCLI_BODY;
+}
diff --git a/src/core/httpcli/parser.h b/src/core/httpcli/parser.h
new file mode 100644
index 0000000..e2c24a9
--- /dev/null
+++ b/src/core/httpcli/parser.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_HTTPCLI_PARSER_H__
+#define __GRPC_INTERNAL_HTTPCLI_PARSER_H__
+
+#include "src/core/httpcli/httpcli.h"
+#include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+
+typedef enum {
+  GRPC_HTTPCLI_INITIAL_RESPONSE,
+  GRPC_HTTPCLI_HEADERS,
+  GRPC_HTTPCLI_BODY
+} grpc_httpcli_parser_state;
+
+typedef struct {
+  grpc_httpcli_parser_state state;
+
+  grpc_httpcli_response r;
+  size_t body_capacity;
+  size_t hdr_capacity;
+
+  gpr_uint8 cur_line[GRPC_HTTPCLI_MAX_HEADER_LENGTH];
+  size_t cur_line_length;
+} grpc_httpcli_parser;
+
+void grpc_httpcli_parser_init(grpc_httpcli_parser *parser);
+void grpc_httpcli_parser_destroy(grpc_httpcli_parser *parser);
+
+int grpc_httpcli_parser_parse(grpc_httpcli_parser *parser, gpr_slice slice);
+int grpc_httpcli_parser_eof(grpc_httpcli_parser *parser);
+
+#endif  /* __GRPC_INTERNAL_HTTPCLI_PARSER_H__ */
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
new file mode 100644
index 0000000..6480dd2
--- /dev/null
+++ b/src/core/security/auth.c
@@ -0,0 +1,160 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/security/auth.h"
+
+#include <string.h>
+
+#include "src/core/security/security_context.h"
+#include "src/core/security/credentials.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+/* We can have a per-call credentials. */
+typedef struct {
+  grpc_credentials *creds;
+  grpc_call_op op;
+} call_data;
+
+/* We can have a per-channel credentials. */
+typedef struct {
+  grpc_channel_security_context *security_context;
+} channel_data;
+
+static void on_credentials_metadata(void *user_data, grpc_mdelem **md_elems,
+                                    size_t num_md,
+                                    grpc_credentials_status status) {
+  grpc_call_element *elem = (grpc_call_element *)user_data;
+  size_t i;
+  for (i = 0; i < num_md; i++) {
+    grpc_call_element_send_metadata(elem, md_elems[i]);
+  }
+  grpc_call_next_op(elem, &((call_data *)elem->call_data)->op);
+}
+
+/* Called either:
+     - in response to an API call (or similar) from above, to send something
+     - a network event (or similar) from below, to receive something
+   op contains type and call direction information, in addition to the data
+   that is being sent or received. */
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  switch (op->type) {
+    case GRPC_SEND_START: {
+      grpc_credentials *channel_creds =
+          channeld->security_context->request_metadata_only_creds;
+      /* TODO(jboeuf):
+         Decide on the policy in this case:
+         - populate both channel and call?
+         - the call takes precedence over the channel?
+         - leave this decision up to the channel credentials?  */
+      if (calld->creds != NULL) {
+        gpr_log(GPR_ERROR, "Ignoring per call credentials for now.");
+      }
+      if (channel_creds != NULL &&
+          grpc_credentials_has_request_metadata(channel_creds)) {
+        calld->op = *op; /* Copy op (originates from the caller's stack). */
+        grpc_credentials_get_request_metadata(channel_creds,
+                                              on_credentials_metadata, elem);
+        break;
+      }
+      /* FALLTHROUGH INTENDED. */
+    }
+
+    default:
+      /* pass control up or down the stack depending on op->dir */
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+/* Called on special channel events, such as disconnection or new incoming
+   calls on the server */
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  grpc_channel_next_op(elem, op);
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  /* TODO(jboeuf):
+     Find a way to pass-in the credentials from the caller here.  */
+  call_data *calld = elem->call_data;
+  calld->creds = NULL;
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_call_element *elem) {
+  call_data *calld = elem->call_data;
+  if (calld->creds != NULL) {
+    grpc_credentials_unref(calld->creds);
+  }
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args,
+                              grpc_mdctx *metadata_context, int is_first,
+                              int is_last) {
+  grpc_security_context *ctx = grpc_find_security_context_in_args(args);
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+
+  /* The first and the last filters tend to be implemented differently to
+     handle the case that there's no 'next' filter to call on the up or down
+     path */
+  GPR_ASSERT(!is_first);
+  GPR_ASSERT(!is_last);
+  GPR_ASSERT(ctx != NULL);
+
+  /* initialize members */
+  GPR_ASSERT(ctx->is_client_side);
+  channeld->security_context =
+      (grpc_channel_security_context *)grpc_security_context_ref(ctx);
+}
+
+/* Destructor for channel data */
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  /* grab pointers to our data from the channel element */
+  channel_data *channeld = elem->channel_data;
+  grpc_channel_security_context *ctx = channeld->security_context;
+  if (ctx != NULL) grpc_security_context_unref(&ctx->base);
+}
+
+const grpc_channel_filter grpc_client_auth_filter = {
+    call_op,           channel_op,           sizeof(call_data),
+    init_call_elem,    destroy_call_elem,    sizeof(channel_data),
+    init_channel_elem, destroy_channel_elem, "auth"};
diff --git a/src/core/security/auth.h b/src/core/security/auth.h
new file mode 100644
index 0000000..0b279f8
--- /dev/null
+++ b/src/core/security/auth.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SECURITY_AUTH_H__
+#define __GRPC_INTERNAL_SECURITY_AUTH_H__
+
+#include "src/core/channel/channel_stack.h"
+
+extern const grpc_channel_filter grpc_client_auth_filter;
+
+#endif  /* __GRPC_INTERNAL_SECURITY_AUTH_H__ */
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
new file mode 100644
index 0000000..969a973
--- /dev/null
+++ b/src/core/security/credentials.c
@@ -0,0 +1,534 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/security/credentials.h"
+
+#include "src/core/httpcli/httpcli.h"
+#include "src/core/surface/surface_em.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+#include "third_party/cJSON/cJSON.h"
+
+#include <string.h>
+#include <stdio.h>
+
+/* -- Constants. -- */
+
+#define GRPC_COMPUTE_ENGINE_TOKEN_REFRESH_THRESHOLD_SECS 60
+#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
+#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
+  "computeMetadata/v1/instance/service-accounts/default/token"
+#define GRPC_AUTHORIZATION_METADATA_KEY "Authorization"
+
+/* -- Common. -- */
+
+typedef struct {
+  grpc_credentials *creds;
+  grpc_credentials_metadata_cb cb;
+  void *user_data;
+} grpc_credentials_metadata_request;
+
+static grpc_credentials_metadata_request *
+grpc_credentials_metadata_request_create(grpc_credentials *creds,
+                                         grpc_credentials_metadata_cb cb,
+                                         void *user_data) {
+  grpc_credentials_metadata_request *r =
+      gpr_malloc(sizeof(grpc_credentials_metadata_request));
+  r->creds = grpc_credentials_ref(creds);
+  r->cb = cb;
+  r->user_data = user_data;
+  return r;
+}
+
+static void grpc_credentials_metadata_request_destroy(
+    grpc_credentials_metadata_request *r) {
+  grpc_credentials_unref(r->creds);
+  gpr_free(r);
+}
+
+grpc_credentials *grpc_credentials_ref(grpc_credentials *creds) {
+  if (creds == NULL) return NULL;
+  gpr_ref(&creds->refcount);
+  return creds;
+}
+
+void grpc_credentials_unref(grpc_credentials *creds) {
+  if (creds == NULL) return;
+  if (gpr_unref(&creds->refcount)) creds->vtable->destroy(creds);
+}
+
+void grpc_credentials_release(grpc_credentials *creds) {
+  grpc_credentials_unref(creds);
+}
+
+int grpc_credentials_has_request_metadata(grpc_credentials *creds) {
+  if (creds == NULL) return 0;
+  return creds->vtable->has_request_metadata(creds);
+}
+
+int grpc_credentials_has_request_metadata_only(grpc_credentials *creds) {
+  if (creds == NULL) return 0;
+  return creds->vtable->has_request_metadata_only(creds);
+}
+
+void grpc_credentials_get_request_metadata(grpc_credentials *creds,
+                                           grpc_credentials_metadata_cb cb,
+                                           void *user_data) {
+  if (creds == NULL || !grpc_credentials_has_request_metadata(creds)) return;
+  creds->vtable->get_request_metadata(creds, cb, user_data);
+}
+
+void grpc_server_credentials_release(grpc_server_credentials *creds) {
+  if (creds == NULL) return;
+  creds->vtable->destroy(creds);
+}
+
+/* -- Ssl credentials. -- */
+
+typedef struct {
+  grpc_credentials base;
+  grpc_ssl_config config;
+} grpc_ssl_credentials;
+
+typedef struct {
+  grpc_server_credentials base;
+  grpc_ssl_config config;
+} grpc_ssl_server_credentials;
+
+static void ssl_destroy(grpc_credentials *creds) {
+  grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
+  if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
+  if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
+  if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain);
+  gpr_free(creds);
+}
+
+static void ssl_server_destroy(grpc_server_credentials *creds) {
+  grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
+  if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
+  if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
+  if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain);
+  gpr_free(creds);
+}
+
+static int ssl_has_request_metadata(const grpc_credentials *creds) { return 0; }
+
+static int ssl_has_request_metadata_only(const grpc_credentials *creds) {
+  return 0;
+}
+
+static grpc_credentials_vtable ssl_vtable = {
+    ssl_destroy, ssl_has_request_metadata, ssl_has_request_metadata_only, NULL};
+
+static grpc_server_credentials_vtable ssl_server_vtable = {ssl_server_destroy};
+
+const grpc_ssl_config *grpc_ssl_credentials_get_config(
+    const grpc_credentials *creds) {
+  if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
+    return NULL;
+  } else {
+    grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
+    return &c->config;
+  }
+}
+
+const grpc_ssl_config *grpc_ssl_server_credentials_get_config(
+    const grpc_server_credentials *creds) {
+  if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
+    return NULL;
+  } else {
+    grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
+    return &c->config;
+  }
+}
+
+static void ssl_build_config(const unsigned char *pem_root_certs,
+                             size_t pem_root_certs_size,
+                             const unsigned char *pem_private_key,
+                             size_t pem_private_key_size,
+                             const unsigned char *pem_cert_chain,
+                             size_t pem_cert_chain_size,
+                             grpc_ssl_config *config) {
+  if (pem_root_certs != NULL) {
+    config->pem_root_certs = gpr_malloc(pem_root_certs_size);
+    memcpy(config->pem_root_certs, pem_root_certs, pem_root_certs_size);
+    config->pem_root_certs_size = pem_root_certs_size;
+  }
+  if (pem_private_key != NULL) {
+    config->pem_private_key = gpr_malloc(pem_private_key_size);
+    memcpy(config->pem_private_key, pem_private_key, pem_private_key_size);
+    config->pem_private_key_size = pem_private_key_size;
+  }
+  if (pem_cert_chain != NULL) {
+    config->pem_cert_chain = gpr_malloc(pem_cert_chain_size);
+    memcpy(config->pem_cert_chain, pem_cert_chain, pem_cert_chain_size);
+    config->pem_cert_chain_size = pem_cert_chain_size;
+  }
+}
+
+grpc_credentials *grpc_ssl_credentials_create(
+    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
+    const unsigned char *pem_private_key, size_t pem_private_key_size,
+    const unsigned char *pem_cert_chain, size_t pem_cert_chain_size) {
+  grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials));
+  memset(c, 0, sizeof(grpc_ssl_credentials));
+  c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
+  c->base.vtable = &ssl_vtable;
+  gpr_ref_init(&c->base.refcount, 1);
+  ssl_build_config(pem_root_certs, pem_root_certs_size, pem_private_key,
+                   pem_private_key_size, pem_cert_chain, pem_cert_chain_size,
+                   &c->config);
+  return &c->base;
+}
+
+grpc_server_credentials *grpc_ssl_server_credentials_create(
+    const unsigned char *pem_root_certs, size_t pem_root_certs_size,
+    const unsigned char *pem_private_key, size_t pem_private_key_size,
+    const unsigned char *pem_cert_chain, size_t pem_cert_chain_size) {
+  grpc_ssl_server_credentials *c =
+      gpr_malloc(sizeof(grpc_ssl_server_credentials));
+  memset(c, 0, sizeof(grpc_ssl_server_credentials));
+  c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
+  c->base.vtable = &ssl_server_vtable;
+  ssl_build_config(pem_root_certs, pem_root_certs_size, pem_private_key,
+                   pem_private_key_size, pem_cert_chain, pem_cert_chain_size,
+                   &c->config);
+  return &c->base;
+}
+
+/* -- ComputeEngine credentials. -- */
+
+typedef struct {
+  grpc_credentials base;
+  gpr_mu mu;
+  grpc_mdctx *md_ctx;
+  grpc_mdelem *access_token_md;
+  gpr_timespec token_expiration;
+} grpc_compute_engine_credentials;
+
+static void compute_engine_destroy(grpc_credentials *creds) {
+  grpc_compute_engine_credentials *c = (grpc_compute_engine_credentials *)creds;
+  if (c->access_token_md != NULL) {
+    grpc_mdelem_unref(c->access_token_md);
+  }
+  gpr_mu_destroy(&c->mu);
+  grpc_mdctx_orphan(c->md_ctx);
+  gpr_free(c);
+}
+
+static int compute_engine_has_request_metadata(const grpc_credentials *creds) {
+  return 1;
+}
+
+static int compute_engine_has_request_metadata_only(
+    const grpc_credentials *creds) {
+  return 1;
+}
+
+grpc_credentials_status grpc_compute_engine_credentials_parse_server_response(
+    const grpc_httpcli_response *response, grpc_mdctx *ctx,
+    grpc_mdelem **token_elem, gpr_timespec *token_lifetime) {
+  char *null_terminated_body = NULL;
+  char *new_access_token = NULL;
+  grpc_credentials_status status = GRPC_CREDENTIALS_OK;
+  cJSON *json = NULL;
+
+  if (response->status != 200) {
+    gpr_log(GPR_ERROR, "Call to metadata server ended with error %d",
+            response->status);
+    status = GRPC_CREDENTIALS_ERROR;
+    goto end;
+  } else {
+    cJSON *access_token = NULL;
+    cJSON *token_type = NULL;
+    cJSON *expires_in = NULL;
+    size_t new_access_token_size = 0;
+    null_terminated_body = gpr_malloc(response->body_length + 1);
+    null_terminated_body[response->body_length] = '\0';
+    memcpy(null_terminated_body, response->body, response->body_length);
+    json = cJSON_Parse(null_terminated_body);
+    if (json == NULL) {
+      gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body);
+      status = GRPC_CREDENTIALS_ERROR;
+      goto end;
+    }
+    if (json->type != cJSON_Object) {
+      gpr_log(GPR_ERROR, "Response should be a JSON object");
+      status = GRPC_CREDENTIALS_ERROR;
+      goto end;
+    }
+    access_token = cJSON_GetObjectItem(json, "access_token");
+    if (access_token == NULL || access_token->type != cJSON_String) {
+      gpr_log(GPR_ERROR, "Missing or invalid access_token in JSON.");
+      status = GRPC_CREDENTIALS_ERROR;
+      goto end;
+    }
+    token_type = cJSON_GetObjectItem(json, "token_type");
+    if (token_type == NULL || token_type->type != cJSON_String) {
+      gpr_log(GPR_ERROR, "Missing or invalid token_type in JSON.");
+      status = GRPC_CREDENTIALS_ERROR;
+      goto end;
+    }
+    expires_in = cJSON_GetObjectItem(json, "expires_in");
+    if (expires_in == NULL || expires_in->type != cJSON_Number) {
+      gpr_log(GPR_ERROR, "Missing or invalid expires_in in JSON.");
+      status = GRPC_CREDENTIALS_ERROR;
+      goto end;
+    }
+    new_access_token_size = strlen(token_type->valuestring) + 1 +
+                            strlen(access_token->valuestring) + 1;
+    new_access_token = gpr_malloc(new_access_token_size);
+    /* C89 does not have snprintf :(. */
+    sprintf(new_access_token, "%s %s", token_type->valuestring,
+            access_token->valuestring);
+    token_lifetime->tv_sec = expires_in->valueint;
+    token_lifetime->tv_nsec = 0;
+    if (*token_elem != NULL) grpc_mdelem_unref(*token_elem);
+    *token_elem = grpc_mdelem_from_strings(ctx, GRPC_AUTHORIZATION_METADATA_KEY,
+                                           new_access_token);
+    status = GRPC_CREDENTIALS_OK;
+  }
+
+end:
+  if (status != GRPC_CREDENTIALS_OK && (*token_elem != NULL)) {
+    grpc_mdelem_unref(*token_elem);
+    *token_elem = NULL;
+  }
+  if (null_terminated_body != NULL) gpr_free(null_terminated_body);
+  if (new_access_token != NULL) gpr_free(new_access_token);
+  if (json != NULL) cJSON_Delete(json);
+  return status;
+}
+
+static void on_compute_engine_token_response(
+    void *user_data, const grpc_httpcli_response *response) {
+  grpc_credentials_metadata_request *r =
+      (grpc_credentials_metadata_request *)user_data;
+  grpc_compute_engine_credentials *c =
+      (grpc_compute_engine_credentials *)r->creds;
+  gpr_timespec token_lifetime;
+  grpc_credentials_status status;
+
+  gpr_mu_lock(&c->mu);
+  status = grpc_compute_engine_credentials_parse_server_response(
+      response, c->md_ctx, &c->access_token_md, &token_lifetime);
+  if (status == GRPC_CREDENTIALS_OK) {
+    c->token_expiration = gpr_time_add(gpr_now(), token_lifetime);
+    r->cb(r->user_data, &c->access_token_md, 1, status);
+  } else {
+    c->token_expiration = gpr_inf_past;
+    r->cb(r->user_data, NULL, 0, status);
+  }
+  gpr_mu_unlock(&c->mu);
+  grpc_credentials_metadata_request_destroy(r);
+}
+
+static void compute_engine_get_request_metadata(grpc_credentials *creds,
+                                                grpc_credentials_metadata_cb cb,
+                                                void *user_data) {
+  grpc_compute_engine_credentials *c = (grpc_compute_engine_credentials *)creds;
+  gpr_timespec refresh_threshold = {
+      GRPC_COMPUTE_ENGINE_TOKEN_REFRESH_THRESHOLD_SECS, 0};
+
+  gpr_mu_lock(&c->mu);
+  if (c->access_token_md == NULL ||
+      (gpr_time_cmp(gpr_time_sub(gpr_now(), c->token_expiration),
+                    refresh_threshold) < 0)) {
+    grpc_httpcli_header header = {"Metadata-Flavor", "Google"};
+    grpc_httpcli_request request;
+    request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
+    request.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
+    request.hdr_count = 1;
+    request.hdrs = &header;
+    grpc_httpcli_get(
+        &request, gpr_time_add(gpr_now(), refresh_threshold), grpc_surface_em(),
+        on_compute_engine_token_response,
+        grpc_credentials_metadata_request_create(creds, cb, user_data));
+  } else {
+    cb(user_data, &c->access_token_md, 1, GRPC_CREDENTIALS_OK);
+  }
+  gpr_mu_unlock(&c->mu);
+}
+
+static grpc_credentials_vtable compute_engine_vtable = {
+    compute_engine_destroy, compute_engine_has_request_metadata,
+    compute_engine_has_request_metadata_only,
+    compute_engine_get_request_metadata};
+
+grpc_credentials *grpc_compute_engine_credentials_create(void) {
+  grpc_compute_engine_credentials *c =
+      gpr_malloc(sizeof(grpc_compute_engine_credentials));
+  memset(c, 0, sizeof(grpc_compute_engine_credentials));
+  c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
+  c->base.vtable = &compute_engine_vtable;
+  gpr_ref_init(&c->base.refcount, 1);
+  gpr_mu_init(&c->mu);
+  c->md_ctx = grpc_mdctx_create();
+  c->token_expiration = gpr_inf_past;
+  return &c->base;
+}
+
+/* -- Fake Oauth2 credentials. -- */
+
+typedef struct {
+  grpc_credentials base;
+  grpc_mdctx *md_ctx;
+  grpc_mdelem *access_token_md;
+  int is_async;
+} grpc_fake_oauth2_credentials;
+
+static void fake_oauth2_destroy(grpc_credentials *creds) {
+  grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)creds;
+  if (c->access_token_md != NULL) {
+    grpc_mdelem_unref(c->access_token_md);
+  }
+  grpc_mdctx_orphan(c->md_ctx);
+  gpr_free(c);
+}
+
+static int fake_oauth2_has_request_metadata(const grpc_credentials *creds) {
+  return 1;
+}
+
+static int fake_oauth2_has_request_metadata_only(
+    const grpc_credentials *creds) {
+  return 1;
+}
+
+void on_simulated_token_fetch_done(void *user_data, grpc_em_cb_status status) {
+  grpc_credentials_metadata_request *r =
+      (grpc_credentials_metadata_request *)user_data;
+  grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)r->creds;
+  GPR_ASSERT(status == GRPC_CALLBACK_SUCCESS);
+  r->cb(r->user_data, &c->access_token_md, 1, GRPC_CREDENTIALS_OK);
+  grpc_credentials_metadata_request_destroy(r);
+}
+
+static void fake_oauth2_get_request_metadata(grpc_credentials *creds,
+                                             grpc_credentials_metadata_cb cb,
+                                             void *user_data) {
+  grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)creds;
+
+  if (c->is_async) {
+    GPR_ASSERT(grpc_em_add_callback(grpc_surface_em(),
+                                    on_simulated_token_fetch_done,
+                                    grpc_credentials_metadata_request_create(
+                                        creds, cb, user_data)) == GRPC_EM_OK);
+  } else {
+    cb(user_data, &c->access_token_md, 1, GRPC_CREDENTIALS_OK);
+  }
+}
+
+static grpc_credentials_vtable fake_oauth2_vtable = {
+    fake_oauth2_destroy, fake_oauth2_has_request_metadata,
+    fake_oauth2_has_request_metadata_only, fake_oauth2_get_request_metadata};
+
+grpc_credentials *grpc_fake_oauth2_credentials_create(
+    const char *token_md_value, int is_async) {
+  grpc_fake_oauth2_credentials *c =
+      gpr_malloc(sizeof(grpc_fake_oauth2_credentials));
+  memset(c, 0, sizeof(grpc_fake_oauth2_credentials));
+  c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
+  c->base.vtable = &fake_oauth2_vtable;
+  gpr_ref_init(&c->base.refcount, 1);
+  c->md_ctx = grpc_mdctx_create();
+  c->access_token_md = grpc_mdelem_from_strings(
+      c->md_ctx, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value);
+  c->is_async = is_async;
+  return &c->base;
+}
+
+/* -- Fake transport security credentials. -- */
+
+static void fake_transport_security_credentials_destroy(
+    grpc_credentials *creds) {
+  gpr_free(creds);
+}
+
+static void fake_transport_security_server_credentials_destroy(
+    grpc_server_credentials *creds) {
+  gpr_free(creds);
+}
+
+static int fake_transport_security_has_request_metadata(
+    const grpc_credentials *creds) {
+  return 0;
+}
+
+static int fake_transport_security_has_request_metadata_only(
+    const grpc_credentials *creds) {
+  return 0;
+}
+
+static grpc_credentials_vtable fake_transport_security_credentials_vtable = {
+    fake_transport_security_credentials_destroy,
+    fake_transport_security_has_request_metadata,
+    fake_transport_security_has_request_metadata_only, NULL};
+
+static grpc_server_credentials_vtable
+    fake_transport_security_server_credentials_vtable = {
+        fake_transport_security_server_credentials_destroy};
+
+grpc_credentials *grpc_fake_transport_security_credentials_create(void) {
+  grpc_credentials *c = gpr_malloc(sizeof(grpc_credentials));
+  memset(c, 0, sizeof(grpc_credentials));
+  c->type = GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
+  c->vtable = &fake_transport_security_credentials_vtable;
+  gpr_ref_init(&c->refcount, 1);
+  return c;
+}
+
+grpc_server_credentials *
+grpc_fake_transport_security_server_credentials_create() {
+  grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials));
+  memset(c, 0, sizeof(grpc_server_credentials));
+  c->type = GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
+  c->vtable = &fake_transport_security_server_credentials_vtable;
+  return c;
+}
+
+
+/* -- Composite credentials TODO(jboeuf). -- */
+
+grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
+                                                    grpc_credentials *creds2) {
+  return NULL;
+}
+
+/* -- Default credentials TODO(jboeuf). -- */
+
+grpc_credentials *grpc_default_credentials_create(void) { return NULL; }
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
new file mode 100644
index 0000000..1432611
--- /dev/null
+++ b/src/core/security/credentials.h
@@ -0,0 +1,125 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__
+#define __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__
+
+#include "src/core/transport/stream_op.h"
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/sync.h>
+
+struct grpc_httpcli_response;
+
+/* --- Constants. --- */
+
+typedef enum {
+  GRPC_CREDENTIALS_OK = 0,
+  GRPC_CREDENTIALS_ERROR
+} grpc_credentials_status;
+
+#define GRPC_CREDENTIALS_TYPE_SSL "Ssl"
+#define GRPC_CREDENTIALS_TYPE_OAUTH2 "Oauth2"
+#define GRPC_CREDENTIALS_TYPE_COMPOSITE "Composite"
+#define GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY "FakeTransportSecurity"
+
+/* --- grpc_credentials. --- */
+
+typedef void (*grpc_credentials_metadata_cb)(void *user_data,
+                                             grpc_mdelem **md_elems,
+                                             size_t num_md,
+                                             grpc_credentials_status status);
+
+typedef struct {
+  void (*destroy)(grpc_credentials *c);
+  int (*has_request_metadata)(const grpc_credentials *c);
+  int (*has_request_metadata_only)(const grpc_credentials *c);
+  void (*get_request_metadata)(grpc_credentials *c,
+                               grpc_credentials_metadata_cb cb,
+                               void *user_data);
+} grpc_credentials_vtable;
+
+struct grpc_credentials {
+  const grpc_credentials_vtable *vtable;
+  const char *type;
+  gpr_refcount refcount;
+};
+
+grpc_credentials *grpc_credentials_ref(grpc_credentials *creds);
+void grpc_credentials_unref(grpc_credentials *creds);
+int grpc_credentials_has_request_metadata(grpc_credentials *creds);
+int grpc_credentials_has_request_metadata_only(grpc_credentials *creds);
+void grpc_credentials_get_request_metadata(grpc_credentials *creds,
+                                           grpc_credentials_metadata_cb cb,
+                                           void *user_data);
+typedef struct {
+  unsigned char *pem_private_key;
+  size_t pem_private_key_size;
+  unsigned char *pem_cert_chain;
+  size_t pem_cert_chain_size;
+  unsigned char *pem_root_certs;
+  size_t pem_root_certs_size;
+} grpc_ssl_config;
+
+const grpc_ssl_config *grpc_ssl_credentials_get_config(
+    const grpc_credentials *ssl_creds);
+
+/* Exposed for testing only. */
+grpc_credentials_status grpc_compute_engine_credentials_parse_server_response(
+    const struct grpc_httpcli_response *response, grpc_mdctx *ctx,
+    grpc_mdelem **token_elem, gpr_timespec *token_lifetime);
+
+/* Simulates an oauth2 token fetch with the specified value for testing. */
+grpc_credentials *grpc_fake_oauth2_credentials_create(
+    const char *token_md_value, int is_async);
+
+
+/* --- grpc_server_credentials. --- */
+
+typedef struct {
+  void (*destroy)(grpc_server_credentials *c);
+} grpc_server_credentials_vtable;
+
+struct grpc_server_credentials {
+  const grpc_server_credentials_vtable *vtable;
+  const char *type;
+};
+
+/* TODO(jboeuf): Have an ssl_server_config that can contain multiple key/cert
+   pairs. */
+
+const grpc_ssl_config *grpc_ssl_server_credentials_get_config(
+    const grpc_server_credentials *ssl_creds);
+
+
+#endif  /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */
diff --git a/src/core/security/google_root_certs.c b/src/core/security/google_root_certs.c
new file mode 100644
index 0000000..669d637
--- /dev/null
+++ b/src/core/security/google_root_certs.c
@@ -0,0 +1,11277 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* this file is created by
+   xxd -i security/cacerts/for_connecting_to_google/roots.pem */
+
+unsigned char grpc_google_root_certs[] = {
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52,
+    0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f,
+    0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x55,
+    0x3d, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+    0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x54,
+    0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x4f, 0x3d, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f,
+    0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x55, 0x3d, 0x47, 0x54,
+    0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+    0x3a, 0x20, 0x22, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72,
+    0x69, 0x61, 0x6c, 0x3a, 0x20, 0x34, 0x32, 0x31, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x63, 0x61, 0x3a, 0x33, 0x64, 0x3a, 0x64, 0x33,
+    0x3a, 0x36, 0x38, 0x3a, 0x66, 0x31, 0x3a, 0x30, 0x33, 0x3a, 0x35, 0x63,
+    0x3a, 0x64, 0x30, 0x3a, 0x33, 0x32, 0x3a, 0x66, 0x61, 0x3a, 0x62, 0x38,
+    0x3a, 0x32, 0x62, 0x3a, 0x35, 0x39, 0x3a, 0x65, 0x38, 0x3a, 0x35, 0x61,
+    0x3a, 0x64, 0x62, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x39, 0x37, 0x3a, 0x38, 0x31, 0x3a, 0x37, 0x39, 0x3a, 0x35, 0x30, 0x3a,
+    0x64, 0x38, 0x3a, 0x31, 0x63, 0x3a, 0x39, 0x36, 0x3a, 0x37, 0x30, 0x3a,
+    0x63, 0x63, 0x3a, 0x33, 0x34, 0x3a, 0x64, 0x38, 0x3a, 0x30, 0x39, 0x3a,
+    0x63, 0x66, 0x3a, 0x37, 0x39, 0x3a, 0x34, 0x34, 0x3a, 0x33, 0x31, 0x3a,
+    0x33, 0x36, 0x3a, 0x37, 0x65, 0x3a, 0x66, 0x34, 0x3a, 0x37, 0x34, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x35,
+    0x3a, 0x33, 0x31, 0x3a, 0x32, 0x35, 0x3a, 0x31, 0x38, 0x3a, 0x38, 0x64,
+    0x3a, 0x32, 0x31, 0x3a, 0x31, 0x30, 0x3a, 0x61, 0x61, 0x3a, 0x39, 0x36,
+    0x3a, 0x34, 0x62, 0x3a, 0x30, 0x32, 0x3a, 0x63, 0x37, 0x3a, 0x62, 0x37,
+    0x3a, 0x63, 0x36, 0x3a, 0x64, 0x61, 0x3a, 0x33, 0x32, 0x3a, 0x30, 0x33,
+    0x3a, 0x31, 0x37, 0x3a, 0x30, 0x38, 0x3a, 0x39, 0x34, 0x3a, 0x65, 0x35,
+    0x3a, 0x66, 0x62, 0x3a, 0x37, 0x31, 0x3a, 0x66, 0x66, 0x3a, 0x66, 0x62,
+    0x3a, 0x36, 0x36, 0x3a, 0x36, 0x37, 0x3a, 0x64, 0x35, 0x3a, 0x65, 0x36,
+    0x3a, 0x38, 0x31, 0x3a, 0x30, 0x61, 0x3a, 0x33, 0x36, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x57, 0x6a, 0x43, 0x43, 0x41, 0x63,
+    0x4d, 0x43, 0x41, 0x67, 0x47, 0x6c, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53,
+    0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x41,
+    0x55, 0x41, 0x4d, 0x48, 0x55, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52,
+    0x67, 0x77, 0x46, 0x67, 0x59, 0x44, 0x0a, 0x56, 0x51, 0x51, 0x4b, 0x45,
+    0x77, 0x39, 0x48, 0x56, 0x45, 0x55, 0x67, 0x51, 0x32, 0x39, 0x79, 0x63,
+    0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x4a,
+    0x7a, 0x41, 0x6c, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48,
+    0x6b, 0x64, 0x55, 0x52, 0x53, 0x42, 0x44, 0x65, 0x57, 0x4a, 0x6c, 0x63,
+    0x6c, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x46, 0x4e, 0x76, 0x0a,
+    0x62, 0x48, 0x56, 0x30, 0x61, 0x57, 0x39, 0x75, 0x63, 0x79, 0x77, 0x67,
+    0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x6a, 0x4d, 0x43, 0x45, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x61, 0x52, 0x31, 0x52, 0x46,
+    0x49, 0x45, 0x4e, 0x35, 0x59, 0x6d, 0x56, 0x79, 0x56, 0x48, 0x4a, 0x31,
+    0x63, 0x33, 0x51, 0x67, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d, 0x46, 0x73,
+    0x49, 0x46, 0x4a, 0x76, 0x0a, 0x62, 0x33, 0x51, 0x77, 0x48, 0x68, 0x63,
+    0x4e, 0x4f, 0x54, 0x67, 0x77, 0x4f, 0x44, 0x45, 0x7a, 0x4d, 0x44, 0x41,
+    0x79, 0x4f, 0x54, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x67,
+    0x77, 0x4f, 0x44, 0x45, 0x7a, 0x4d, 0x6a, 0x4d, 0x31, 0x4f, 0x54, 0x41,
+    0x77, 0x57, 0x6a, 0x42, 0x31, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x0a, 0x55, 0x7a,
+    0x45, 0x59, 0x4d, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x50, 0x52, 0x31, 0x52, 0x46, 0x49, 0x45, 0x4e, 0x76, 0x63, 0x6e,
+    0x42, 0x76, 0x63, 0x6d, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4d, 0x53,
+    0x63, 0x77, 0x4a, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78,
+    0x35, 0x48, 0x56, 0x45, 0x55, 0x67, 0x51, 0x33, 0x6c, 0x69, 0x5a, 0x58,
+    0x4a, 0x55, 0x0a, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x54, 0x62,
+    0x32, 0x78, 0x31, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x6e, 0x4d, 0x73, 0x49,
+    0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78, 0x49, 0x7a, 0x41, 0x68, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x47, 0x6b, 0x64, 0x55, 0x52,
+    0x53, 0x42, 0x44, 0x65, 0x57, 0x4a, 0x6c, 0x63, 0x6c, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x49, 0x45, 0x64, 0x73, 0x0a, 0x62, 0x32, 0x4a, 0x68,
+    0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4d, 0x49, 0x47, 0x66,
+    0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4e,
+    0x41, 0x44, 0x43, 0x42, 0x69, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x43, 0x56,
+    0x44, 0x36, 0x43, 0x32, 0x38, 0x46, 0x43, 0x63, 0x36, 0x48, 0x72, 0x48,
+    0x0a, 0x69, 0x4d, 0x33, 0x64, 0x46, 0x77, 0x34, 0x75, 0x73, 0x4a, 0x54,
+    0x51, 0x47, 0x7a, 0x30, 0x4f, 0x39, 0x70, 0x54, 0x41, 0x69, 0x70, 0x54,
+    0x48, 0x42, 0x73, 0x69, 0x51, 0x6c, 0x38, 0x69, 0x34, 0x5a, 0x42, 0x70,
+    0x36, 0x66, 0x6d, 0x77, 0x38, 0x55, 0x2b, 0x45, 0x33, 0x4b, 0x48, 0x4e,
+    0x67, 0x66, 0x37, 0x4b, 0x58, 0x55, 0x77, 0x65, 0x66, 0x55, 0x2f, 0x6c,
+    0x74, 0x57, 0x4a, 0x54, 0x53, 0x0a, 0x72, 0x34, 0x31, 0x74, 0x69, 0x47,
+    0x65, 0x41, 0x35, 0x75, 0x32, 0x79, 0x6c, 0x63, 0x39, 0x79, 0x4d, 0x63,
+    0x71, 0x6c, 0x48, 0x48, 0x4b, 0x36, 0x58, 0x41, 0x4c, 0x6e, 0x5a, 0x45,
+    0x4c, 0x6e, 0x2b, 0x61, 0x6b, 0x73, 0x31, 0x6a, 0x6f, 0x4e, 0x72, 0x49,
+    0x31, 0x43, 0x71, 0x69, 0x51, 0x42, 0x4f, 0x65, 0x61, 0x63, 0x50, 0x77,
+    0x47, 0x46, 0x56, 0x77, 0x31, 0x59, 0x68, 0x30, 0x58, 0x34, 0x0a, 0x30,
+    0x34, 0x57, 0x71, 0x6b, 0x32, 0x6b, 0x6d, 0x68, 0x58, 0x42, 0x49, 0x67,
+    0x44, 0x38, 0x53, 0x46, 0x63, 0x64, 0x35, 0x74, 0x42, 0x38, 0x46, 0x4c,
+    0x7a, 0x74, 0x69, 0x6d, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x4d,
+    0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44,
+    0x51, 0x45, 0x42, 0x42, 0x41, 0x55, 0x41, 0x41, 0x34, 0x47, 0x42, 0x41,
+    0x47, 0x33, 0x72, 0x0a, 0x47, 0x77, 0x6e, 0x70, 0x58, 0x74, 0x6c, 0x52,
+    0x32, 0x32, 0x63, 0x69, 0x59, 0x61, 0x51, 0x71, 0x50, 0x45, 0x68, 0x33,
+    0x34, 0x36, 0x42, 0x38, 0x70, 0x74, 0x35, 0x7a, 0x6f, 0x68, 0x51, 0x44,
+    0x68, 0x54, 0x33, 0x37, 0x71, 0x77, 0x34, 0x77, 0x78, 0x59, 0x4d, 0x57,
+    0x4d, 0x34, 0x45, 0x54, 0x43, 0x4a, 0x35, 0x37, 0x4e, 0x45, 0x37, 0x66,
+    0x51, 0x4d, 0x68, 0x30, 0x31, 0x37, 0x6c, 0x39, 0x0a, 0x33, 0x50, 0x52,
+    0x32, 0x56, 0x58, 0x32, 0x62, 0x59, 0x31, 0x51, 0x59, 0x36, 0x66, 0x44,
+    0x71, 0x38, 0x31, 0x79, 0x78, 0x32, 0x59, 0x74, 0x43, 0x48, 0x72, 0x6e,
+    0x41, 0x6c, 0x55, 0x36, 0x36, 0x2b, 0x74, 0x58, 0x69, 0x66, 0x50, 0x56,
+    0x6f, 0x59, 0x62, 0x2b, 0x4f, 0x37, 0x41, 0x57, 0x58, 0x58, 0x31, 0x75,
+    0x77, 0x31, 0x36, 0x4f, 0x46, 0x4e, 0x4d, 0x51, 0x6b, 0x70, 0x77, 0x30,
+    0x50, 0x0a, 0x6c, 0x5a, 0x50, 0x76, 0x79, 0x35, 0x54, 0x59, 0x6e, 0x68,
+    0x2b, 0x64, 0x58, 0x49, 0x56, 0x74, 0x78, 0x36, 0x71, 0x75, 0x54, 0x78,
+    0x38, 0x69, 0x74, 0x63, 0x32, 0x56, 0x72, 0x62, 0x71, 0x6e, 0x7a, 0x50,
+    0x6d, 0x72, 0x43, 0x33, 0x70, 0x2f, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43,
+    0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20,
+    0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x54,
+    0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+    0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65,
+    0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20,
+    0x63, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76,
+    0x69, 0x63, 0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f,
+    0x6e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,
+    0x20, 0x43, 0x4e, 0x3d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53,
+    0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d, 0x54,
+    0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
+    0x74, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, 0x69,
+    0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62,
+    0x65, 0x6c, 0x3a, 0x20, 0x22, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+    0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23,
+    0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23,
+    0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x35, 0x3a, 0x37, 0x30, 0x3a,
+    0x63, 0x34, 0x3a, 0x61, 0x32, 0x3a, 0x65, 0x64, 0x3a, 0x35, 0x33, 0x3a,
+    0x37, 0x38, 0x3a, 0x30, 0x63, 0x3a, 0x63, 0x38, 0x3a, 0x31, 0x30, 0x3a,
+    0x35, 0x33, 0x3a, 0x38, 0x31, 0x3a, 0x36, 0x34, 0x3a, 0x63, 0x62, 0x3a,
+    0x64, 0x30, 0x3a, 0x31, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x32, 0x33, 0x3a, 0x65, 0x35, 0x3a, 0x39, 0x34, 0x3a, 0x39,
+    0x34, 0x3a, 0x35, 0x31, 0x3a, 0x39, 0x35, 0x3a, 0x66, 0x32, 0x3a, 0x34,
+    0x31, 0x3a, 0x34, 0x38, 0x3a, 0x30, 0x33, 0x3a, 0x62, 0x34, 0x3a, 0x64,
+    0x35, 0x3a, 0x36, 0x34, 0x3a, 0x64, 0x32, 0x3a, 0x61, 0x33, 0x3a, 0x61,
+    0x33, 0x3a, 0x66, 0x35, 0x3a, 0x64, 0x38, 0x3a, 0x38, 0x62, 0x3a, 0x38,
+    0x63, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x62, 0x34, 0x3a, 0x34, 0x31, 0x3a, 0x30, 0x62, 0x3a, 0x37, 0x33, 0x3a,
+    0x65, 0x32, 0x3a, 0x65, 0x36, 0x3a, 0x65, 0x61, 0x3a, 0x63, 0x61, 0x3a,
+    0x34, 0x37, 0x3a, 0x66, 0x62, 0x3a, 0x63, 0x34, 0x3a, 0x32, 0x66, 0x3a,
+    0x38, 0x66, 0x3a, 0x61, 0x34, 0x3a, 0x30, 0x31, 0x3a, 0x38, 0x61, 0x3a,
+    0x66, 0x34, 0x3a, 0x33, 0x38, 0x3a, 0x31, 0x64, 0x3a, 0x63, 0x35, 0x3a,
+    0x34, 0x63, 0x3a, 0x66, 0x61, 0x3a, 0x61, 0x38, 0x3a, 0x34, 0x34, 0x3a,
+    0x35, 0x30, 0x3a, 0x34, 0x36, 0x3a, 0x31, 0x65, 0x3a, 0x65, 0x64, 0x3a,
+    0x30, 0x39, 0x3a, 0x34, 0x35, 0x3a, 0x34, 0x64, 0x3a, 0x65, 0x39, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x45, 0x7a, 0x43, 0x43,
+    0x41, 0x6e, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
+    0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x51, 0x46, 0x41, 0x44, 0x43, 0x42,
+    0x78, 0x44, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x42, 0x68, 0x4d, 0x43, 0x57, 0x6b, 0x45, 0x78, 0x0a, 0x46, 0x54, 0x41,
+    0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x54, 0x44, 0x46, 0x64,
+    0x6c, 0x63, 0x33, 0x52, 0x6c, 0x63, 0x6d, 0x34, 0x67, 0x51, 0x32, 0x46,
+    0x77, 0x5a, 0x54, 0x45, 0x53, 0x4d, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x42, 0x78, 0x4d, 0x4a, 0x51, 0x32, 0x46, 0x77, 0x5a, 0x53, 0x42,
+    0x55, 0x62, 0x33, 0x64, 0x75, 0x4d, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59,
+    0x44, 0x0a, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x52, 0x55, 0x61, 0x47,
+    0x46, 0x33, 0x64, 0x47, 0x55, 0x67, 0x51, 0x32, 0x39, 0x75, 0x63, 0x33,
+    0x56, 0x73, 0x64, 0x47, 0x6c, 0x75, 0x5a, 0x79, 0x42, 0x6a, 0x59, 0x7a,
+    0x45, 0x6f, 0x4d, 0x43, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78,
+    0x4d, 0x66, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57,
+    0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x0a, 0x62, 0x69, 0x42, 0x54, 0x5a,
+    0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x63, 0x79, 0x42, 0x45, 0x61,
+    0x58, 0x5a, 0x70, 0x63, 0x32, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x5a, 0x4d,
+    0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x51, 0x56,
+    0x47, 0x68, 0x68, 0x64, 0x33, 0x52, 0x6c, 0x49, 0x46, 0x4e, 0x6c, 0x63,
+    0x6e, 0x5a, 0x6c, 0x63, 0x69, 0x42, 0x44, 0x51, 0x54, 0x45, 0x6d, 0x0a,
+    0x4d, 0x43, 0x51, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x4a, 0x41, 0x52, 0x59, 0x58, 0x63, 0x32, 0x56, 0x79,
+    0x64, 0x6d, 0x56, 0x79, 0x4c, 0x57, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x7a,
+    0x51, 0x48, 0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x35, 0x6a,
+    0x62, 0x32, 0x30, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4f, 0x54, 0x59, 0x77,
+    0x4f, 0x44, 0x41, 0x78, 0x0a, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41,
+    0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x41, 0x78, 0x4d, 0x6a, 0x4d,
+    0x78, 0x4d, 0x6a, 0x4d, 0x31, 0x4f, 0x54, 0x55, 0x35, 0x57, 0x6a, 0x43,
+    0x42, 0x78, 0x44, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x42, 0x68, 0x4d, 0x43, 0x57, 0x6b, 0x45, 0x78, 0x46, 0x54, 0x41,
+    0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x54, 0x0a, 0x44, 0x46,
+    0x64, 0x6c, 0x63, 0x33, 0x52, 0x6c, 0x63, 0x6d, 0x34, 0x67, 0x51, 0x32,
+    0x46, 0x77, 0x5a, 0x54, 0x45, 0x53, 0x4d, 0x42, 0x41, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x42, 0x78, 0x4d, 0x4a, 0x51, 0x32, 0x46, 0x77, 0x5a, 0x53,
+    0x42, 0x55, 0x62, 0x33, 0x64, 0x75, 0x4d, 0x52, 0x30, 0x77, 0x47, 0x77,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x52, 0x55, 0x61, 0x47,
+    0x46, 0x33, 0x0a, 0x64, 0x47, 0x55, 0x67, 0x51, 0x32, 0x39, 0x75, 0x63,
+    0x33, 0x56, 0x73, 0x64, 0x47, 0x6c, 0x75, 0x5a, 0x79, 0x42, 0x6a, 0x59,
+    0x7a, 0x45, 0x6f, 0x4d, 0x43, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x78, 0x4d, 0x66, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61,
+    0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x54, 0x5a,
+    0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x0a, 0x63, 0x79, 0x42, 0x45,
+    0x61, 0x58, 0x5a, 0x70, 0x63, 0x32, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x5a,
+    0x4d, 0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x51,
+    0x56, 0x47, 0x68, 0x68, 0x64, 0x33, 0x52, 0x6c, 0x49, 0x46, 0x4e, 0x6c,
+    0x63, 0x6e, 0x5a, 0x6c, 0x63, 0x69, 0x42, 0x44, 0x51, 0x54, 0x45, 0x6d,
+    0x4d, 0x43, 0x51, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x0a, 0x44, 0x51, 0x45, 0x4a, 0x41, 0x52, 0x59, 0x58, 0x63, 0x32, 0x56,
+    0x79, 0x64, 0x6d, 0x56, 0x79, 0x4c, 0x57, 0x4e, 0x6c, 0x63, 0x6e, 0x52,
+    0x7a, 0x51, 0x48, 0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x35,
+    0x6a, 0x62, 0x32, 0x30, 0x77, 0x67, 0x5a, 0x38, 0x77, 0x44, 0x51, 0x59,
+    0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45,
+    0x42, 0x42, 0x51, 0x41, 0x44, 0x0a, 0x67, 0x59, 0x30, 0x41, 0x4d, 0x49,
+    0x47, 0x4a, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4e, 0x4f, 0x6b, 0x55, 0x47,
+    0x37, 0x49, 0x2f, 0x31, 0x5a, 0x72, 0x35, 0x73, 0x39, 0x64, 0x74, 0x75,
+    0x6f, 0x4d, 0x61, 0x48, 0x56, 0x48, 0x6f, 0x71, 0x72, 0x43, 0x32, 0x6f,
+    0x51, 0x6c, 0x2f, 0x4b, 0x6a, 0x30, 0x52, 0x31, 0x48, 0x61, 0x68, 0x62,
+    0x55, 0x67, 0x64, 0x4a, 0x53, 0x47, 0x48, 0x67, 0x39, 0x31, 0x0a, 0x79,
+    0x65, 0x6b, 0x49, 0x59, 0x66, 0x55, 0x47, 0x62, 0x54, 0x42, 0x75, 0x46,
+    0x52, 0x6b, 0x43, 0x36, 0x56, 0x4c, 0x41, 0x59, 0x74, 0x74, 0x4e, 0x6d,
+    0x5a, 0x37, 0x69, 0x61, 0x67, 0x78, 0x45, 0x4f, 0x4d, 0x33, 0x2b, 0x76,
+    0x75, 0x4e, 0x6b, 0x43, 0x58, 0x44, 0x46, 0x2f, 0x72, 0x46, 0x72, 0x4b,
+    0x62, 0x59, 0x76, 0x53, 0x63, 0x67, 0x37, 0x31, 0x43, 0x63, 0x45, 0x4a,
+    0x52, 0x43, 0x58, 0x0a, 0x4c, 0x2b, 0x65, 0x51, 0x62, 0x63, 0x41, 0x6f,
+    0x51, 0x70, 0x6e, 0x58, 0x54, 0x45, 0x50, 0x65, 0x77, 0x2f, 0x55, 0x68,
+    0x62, 0x56, 0x53, 0x66, 0x58, 0x63, 0x4e, 0x59, 0x34, 0x63, 0x44, 0x6b,
+    0x32, 0x56, 0x75, 0x77, 0x75, 0x4e, 0x79, 0x30, 0x65, 0x39, 0x38, 0x32,
+    0x4f, 0x73, 0x4b, 0x31, 0x5a, 0x69, 0x49, 0x53, 0x31, 0x6f, 0x63, 0x4e,
+    0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x0a, 0x45, 0x7a, 0x41,
+    0x52, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45,
+    0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38,
+    0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63,
+    0x4e, 0x41, 0x51, 0x45, 0x45, 0x42, 0x51, 0x41, 0x44, 0x67, 0x59, 0x45,
+    0x41, 0x42, 0x2f, 0x70, 0x4d, 0x61, 0x56, 0x7a, 0x37, 0x6c, 0x63, 0x78,
+    0x47, 0x0a, 0x37, 0x6f, 0x57, 0x44, 0x54, 0x53, 0x45, 0x77, 0x6a, 0x73,
+    0x72, 0x5a, 0x71, 0x47, 0x39, 0x4a, 0x47, 0x75, 0x62, 0x61, 0x55, 0x65,
+    0x4e, 0x67, 0x63, 0x47, 0x79, 0x45, 0x59, 0x52, 0x47, 0x68, 0x47, 0x73,
+    0x68, 0x49, 0x50, 0x6c, 0x6c, 0x44, 0x66, 0x55, 0x2b, 0x56, 0x50, 0x61,
+    0x47, 0x4c, 0x74, 0x77, 0x74, 0x69, 0x6d, 0x48, 0x70, 0x31, 0x69, 0x74,
+    0x32, 0x49, 0x54, 0x6b, 0x36, 0x65, 0x0a, 0x51, 0x4e, 0x75, 0x6f, 0x7a,
+    0x44, 0x4a, 0x30, 0x75, 0x57, 0x38, 0x4e, 0x78, 0x75, 0x4f, 0x7a, 0x52,
+    0x41, 0x76, 0x5a, 0x69, 0x6d, 0x2b, 0x61, 0x4b, 0x5a, 0x75, 0x5a, 0x47,
+    0x43, 0x67, 0x37, 0x30, 0x65, 0x4e, 0x41, 0x4b, 0x4a, 0x70, 0x61, 0x50,
+    0x4e, 0x57, 0x31, 0x35, 0x79, 0x41, 0x62, 0x69, 0x38, 0x71, 0x6b, 0x71,
+    0x34, 0x33, 0x70, 0x55, 0x64, 0x6e, 0x69, 0x54, 0x43, 0x78, 0x5a, 0x0a,
+    0x71, 0x64, 0x71, 0x35, 0x73, 0x6e, 0x55, 0x62, 0x39, 0x6b, 0x4c, 0x79,
+    0x37, 0x38, 0x66, 0x79, 0x47, 0x50, 0x6d, 0x4a, 0x76, 0x4b, 0x50, 0x2f,
+    0x69, 0x69, 0x4d, 0x75, 0x63, 0x45, 0x63, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65, 0x6d,
+    0x69, 0x75, 0x6d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43,
+    0x41, 0x20, 0x4f, 0x3d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43,
+    0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x63,
+    0x20, 0x4f, 0x55, 0x3d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+    0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x0a,
+    0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65,
+    0x6d, 0x69, 0x75, 0x6d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
+    0x43, 0x41, 0x20, 0x4f, 0x3d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+    0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x63,
+    0x63, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69,
+    0x63, 0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+    0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x54,
+    0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75,
+    0x6d, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x22,
+    0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31,
+    0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30, 0x36, 0x3a, 0x39,
+    0x66, 0x3a, 0x36, 0x39, 0x3a, 0x37, 0x39, 0x3a, 0x31, 0x36, 0x3a, 0x36,
+    0x36, 0x3a, 0x39, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x31, 0x62, 0x3a, 0x38,
+    0x63, 0x3a, 0x38, 0x63, 0x3a, 0x61, 0x32, 0x3a, 0x63, 0x33, 0x3a, 0x30,
+    0x37, 0x3a, 0x36, 0x66, 0x3a, 0x33, 0x61, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x36, 0x32, 0x3a, 0x37, 0x66, 0x3a, 0x38, 0x64,
+    0x3a, 0x37, 0x38, 0x3a, 0x32, 0x37, 0x3a, 0x36, 0x35, 0x3a, 0x36, 0x33,
+    0x3a, 0x39, 0x39, 0x3a, 0x64, 0x32, 0x3a, 0x37, 0x64, 0x3a, 0x37, 0x66,
+    0x3a, 0x39, 0x30, 0x3a, 0x34, 0x34, 0x3a, 0x63, 0x39, 0x3a, 0x66, 0x65,
+    0x3a, 0x62, 0x33, 0x3a, 0x66, 0x33, 0x3a, 0x33, 0x65, 0x3a, 0x66, 0x61,
+    0x3a, 0x39, 0x61, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x61, 0x62, 0x3a, 0x37, 0x30, 0x3a, 0x33, 0x36, 0x3a, 0x33,
+    0x36, 0x3a, 0x35, 0x63, 0x3a, 0x37, 0x31, 0x3a, 0x35, 0x34, 0x3a, 0x61,
+    0x61, 0x3a, 0x32, 0x39, 0x3a, 0x63, 0x32, 0x3a, 0x63, 0x32, 0x3a, 0x39,
+    0x66, 0x3a, 0x35, 0x64, 0x3a, 0x34, 0x31, 0x3a, 0x39, 0x31, 0x3a, 0x31,
+    0x36, 0x3a, 0x33, 0x62, 0x3a, 0x31, 0x36, 0x3a, 0x32, 0x61, 0x3a, 0x32,
+    0x32, 0x3a, 0x32, 0x35, 0x3a, 0x30, 0x31, 0x3a, 0x31, 0x33, 0x3a, 0x35,
+    0x37, 0x3a, 0x64, 0x35, 0x3a, 0x36, 0x64, 0x3a, 0x30, 0x37, 0x3a, 0x66,
+    0x66, 0x3a, 0x61, 0x37, 0x3a, 0x62, 0x63, 0x3a, 0x31, 0x66, 0x3a, 0x37,
+    0x32, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x4a, 0x7a,
+    0x43, 0x43, 0x41, 0x70, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67,
+    0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x51, 0x46, 0x41, 0x44,
+    0x43, 0x42, 0x7a, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x57, 0x6b, 0x45, 0x78, 0x0a, 0x46,
+    0x54, 0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x54, 0x44,
+    0x46, 0x64, 0x6c, 0x63, 0x33, 0x52, 0x6c, 0x63, 0x6d, 0x34, 0x67, 0x51,
+    0x32, 0x46, 0x77, 0x5a, 0x54, 0x45, 0x53, 0x4d, 0x42, 0x41, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x42, 0x78, 0x4d, 0x4a, 0x51, 0x32, 0x46, 0x77, 0x5a,
+    0x53, 0x42, 0x55, 0x62, 0x33, 0x64, 0x75, 0x4d, 0x52, 0x30, 0x77, 0x47,
+    0x77, 0x59, 0x44, 0x0a, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x52, 0x55,
+    0x61, 0x47, 0x46, 0x33, 0x64, 0x47, 0x55, 0x67, 0x51, 0x32, 0x39, 0x75,
+    0x63, 0x33, 0x56, 0x73, 0x64, 0x47, 0x6c, 0x75, 0x5a, 0x79, 0x42, 0x6a,
+    0x59, 0x7a, 0x45, 0x6f, 0x4d, 0x43, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x78, 0x4d, 0x66, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d,
+    0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x0a, 0x62, 0x69, 0x42,
+    0x54, 0x5a, 0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x63, 0x79, 0x42,
+    0x45, 0x61, 0x58, 0x5a, 0x70, 0x63, 0x32, 0x6c, 0x76, 0x62, 0x6a, 0x45,
+    0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x59, 0x56, 0x47, 0x68, 0x68, 0x64, 0x33, 0x52, 0x6c, 0x49, 0x46, 0x42,
+    0x79, 0x5a, 0x57, 0x31, 0x70, 0x64, 0x57, 0x30, 0x67, 0x55, 0x32, 0x56,
+    0x79, 0x0a, 0x64, 0x6d, 0x56, 0x79, 0x49, 0x45, 0x4e, 0x42, 0x4d, 0x53,
+    0x67, 0x77, 0x4a, 0x67, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x63, 0x4e, 0x41, 0x51, 0x6b, 0x42, 0x46, 0x68, 0x6c, 0x77, 0x63, 0x6d,
+    0x56, 0x74, 0x61, 0x58, 0x56, 0x74, 0x4c, 0x58, 0x4e, 0x6c, 0x63, 0x6e,
+    0x5a, 0x6c, 0x63, 0x6b, 0x42, 0x30, 0x61, 0x47, 0x46, 0x33, 0x64, 0x47,
+    0x55, 0x75, 0x59, 0x32, 0x39, 0x74, 0x0a, 0x4d, 0x42, 0x34, 0x58, 0x44,
+    0x54, 0x6b, 0x32, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x54, 0x41, 0x77, 0x4d,
+    0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x49, 0x77, 0x4d,
+    0x54, 0x49, 0x7a, 0x4d, 0x54, 0x49, 0x7a, 0x4e, 0x54, 0x6b, 0x31, 0x4f,
+    0x56, 0x6f, 0x77, 0x67, 0x63, 0x34, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x70, 0x42, 0x0a,
+    0x4d, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49,
+    0x45, 0x77, 0x78, 0x58, 0x5a, 0x58, 0x4e, 0x30, 0x5a, 0x58, 0x4a, 0x75,
+    0x49, 0x45, 0x4e, 0x68, 0x63, 0x47, 0x55, 0x78, 0x45, 0x6a, 0x41, 0x51,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x55, 0x4e, 0x68,
+    0x63, 0x47, 0x55, 0x67, 0x56, 0x47, 0x39, 0x33, 0x62, 0x6a, 0x45, 0x64,
+    0x4d, 0x42, 0x73, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d,
+    0x55, 0x56, 0x47, 0x68, 0x68, 0x64, 0x33, 0x52, 0x6c, 0x49, 0x45, 0x4e,
+    0x76, 0x62, 0x6e, 0x4e, 0x31, 0x62, 0x48, 0x52, 0x70, 0x62, 0x6d, 0x63,
+    0x67, 0x59, 0x32, 0x4d, 0x78, 0x4b, 0x44, 0x41, 0x6d, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x30, 0x4e, 0x6c, 0x63, 0x6e, 0x52,
+    0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x0a, 0x62, 0x32,
+    0x34, 0x67, 0x55, 0x32, 0x56, 0x79, 0x64, 0x6d, 0x6c, 0x6a, 0x5a, 0x58,
+    0x4d, 0x67, 0x52, 0x47, 0x6c, 0x32, 0x61, 0x58, 0x4e, 0x70, 0x62, 0x32,
+    0x34, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x4d, 0x54, 0x47, 0x46, 0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53,
+    0x42, 0x51, 0x63, 0x6d, 0x56, 0x74, 0x61, 0x58, 0x56, 0x74, 0x49, 0x46,
+    0x4e, 0x6c, 0x0a, 0x63, 0x6e, 0x5a, 0x6c, 0x63, 0x69, 0x42, 0x44, 0x51,
+    0x54, 0x45, 0x6f, 0x4d, 0x43, 0x59, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53,
+    0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x4a, 0x41, 0x52, 0x59, 0x5a, 0x63,
+    0x48, 0x4a, 0x6c, 0x62, 0x57, 0x6c, 0x31, 0x62, 0x53, 0x31, 0x7a, 0x5a,
+    0x58, 0x4a, 0x32, 0x5a, 0x58, 0x4a, 0x41, 0x64, 0x47, 0x68, 0x68, 0x64,
+    0x33, 0x52, 0x6c, 0x4c, 0x6d, 0x4e, 0x76, 0x0a, 0x62, 0x54, 0x43, 0x42,
+    0x6e, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x42,
+    0x6a, 0x51, 0x41, 0x77, 0x67, 0x59, 0x6b, 0x43, 0x67, 0x59, 0x45, 0x41,
+    0x30, 0x6a, 0x59, 0x32, 0x61, 0x6f, 0x76, 0x58, 0x77, 0x6c, 0x75, 0x65,
+    0x32, 0x6f, 0x46, 0x42, 0x59, 0x6f, 0x38, 0x34, 0x37, 0x6b, 0x6b, 0x45,
+    0x0a, 0x56, 0x64, 0x62, 0x51, 0x37, 0x78, 0x77, 0x62, 0x6c, 0x52, 0x5a,
+    0x48, 0x37, 0x78, 0x68, 0x49, 0x4e, 0x54, 0x70, 0x53, 0x39, 0x43, 0x74,
+    0x71, 0x42, 0x6f, 0x38, 0x37, 0x4c, 0x2b, 0x70, 0x57, 0x34, 0x36, 0x2b,
+    0x47, 0x6a, 0x5a, 0x34, 0x58, 0x39, 0x35, 0x36, 0x30, 0x5a, 0x58, 0x55,
+    0x43, 0x54, 0x65, 0x2f, 0x4c, 0x43, 0x61, 0x49, 0x68, 0x55, 0x64, 0x69,
+    0x62, 0x30, 0x47, 0x66, 0x51, 0x0a, 0x75, 0x67, 0x32, 0x53, 0x42, 0x68,
+    0x52, 0x7a, 0x31, 0x4a, 0x50, 0x4c, 0x6c, 0x79, 0x6f, 0x41, 0x6e, 0x46,
+    0x78, 0x4f, 0x44, 0x4c, 0x7a, 0x36, 0x46, 0x56, 0x4c, 0x38, 0x38, 0x6b,
+    0x52, 0x75, 0x32, 0x68, 0x46, 0x4b, 0x62, 0x67, 0x69, 0x66, 0x4c, 0x79,
+    0x33, 0x6a, 0x2b, 0x61, 0x6f, 0x36, 0x68, 0x6e, 0x4f, 0x32, 0x52, 0x6c,
+    0x4e, 0x59, 0x79, 0x49, 0x6b, 0x46, 0x76, 0x59, 0x4d, 0x52, 0x0a, 0x75,
+    0x48, 0x4d, 0x2f, 0x71, 0x67, 0x65, 0x4e, 0x39, 0x45, 0x4a, 0x4e, 0x35,
+    0x30, 0x43, 0x64, 0x48, 0x44, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41,
+    0x61, 0x4d, 0x54, 0x4d, 0x42, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41,
+    0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x0a, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x51, 0x46,
+    0x41, 0x41, 0x4f, 0x42, 0x67, 0x51, 0x41, 0x6d, 0x53, 0x43, 0x77, 0x57,
+    0x77, 0x6c, 0x6a, 0x36, 0x36, 0x42, 0x5a, 0x30, 0x44, 0x4b, 0x71, 0x71,
+    0x58, 0x31, 0x51, 0x2f, 0x38, 0x74, 0x66, 0x4a, 0x65, 0x47, 0x42, 0x65,
+    0x58, 0x6d, 0x34, 0x33, 0x59, 0x79, 0x4a, 0x33, 0x4e, 0x6e, 0x36, 0x79,
+    0x46, 0x38, 0x51, 0x30, 0x75, 0x66, 0x55, 0x49, 0x0a, 0x68, 0x66, 0x7a,
+    0x4a, 0x41, 0x54, 0x6a, 0x2f, 0x54, 0x62, 0x37, 0x79, 0x46, 0x6b, 0x4a,
+    0x44, 0x35, 0x37, 0x74, 0x61, 0x52, 0x76, 0x76, 0x42, 0x78, 0x68, 0x45,
+    0x66, 0x38, 0x55, 0x71, 0x77, 0x4b, 0x45, 0x62, 0x4a, 0x77, 0x38, 0x52,
+    0x43, 0x66, 0x62, 0x7a, 0x36, 0x71, 0x31, 0x6c, 0x75, 0x31, 0x62, 0x64,
+    0x52, 0x69, 0x42, 0x48, 0x6a, 0x70, 0x49, 0x55, 0x5a, 0x61, 0x34, 0x4a,
+    0x4d, 0x0a, 0x70, 0x41, 0x77, 0x53, 0x72, 0x65, 0x6d, 0x6b, 0x72, 0x6a,
+    0x2f, 0x78, 0x77, 0x30, 0x6c, 0x6c, 0x6d, 0x6f, 0x7a, 0x46, 0x79, 0x44,
+    0x34, 0x6c, 0x74, 0x35, 0x53, 0x5a, 0x75, 0x35, 0x49, 0x79, 0x63, 0x51,
+    0x66, 0x77, 0x68, 0x6c, 0x37, 0x74, 0x55, 0x43, 0x65, 0x6d, 0x44, 0x61,
+    0x59, 0x6a, 0x2b, 0x62, 0x76, 0x4c, 0x70, 0x67, 0x63, 0x55, 0x51, 0x67,
+    0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75,
+    0x65, 0x72, 0x3a, 0x20, 0x4f, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61,
+    0x78, 0x20, 0x4f, 0x55, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
+    0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a,
+    0x65, 0x63, 0x74, 0x3a, 0x20, 0x4f, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66,
+    0x61, 0x78, 0x20, 0x4f, 0x55, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61,
+    0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62,
+    0x65, 0x6c, 0x3a, 0x20, 0x22, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
+    0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x41, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x39, 0x30,
+    0x33, 0x38, 0x30, 0x34, 0x31, 0x31, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44,
+    0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x36, 0x37, 0x3a, 0x63, 0x62, 0x3a, 0x39, 0x64, 0x3a,
+    0x63, 0x30, 0x3a, 0x31, 0x33, 0x3a, 0x32, 0x34, 0x3a, 0x38, 0x61, 0x3a,
+    0x38, 0x32, 0x3a, 0x39, 0x62, 0x3a, 0x62, 0x32, 0x3a, 0x31, 0x37, 0x3a,
+    0x31, 0x65, 0x3a, 0x64, 0x31, 0x3a, 0x31, 0x62, 0x3a, 0x65, 0x63, 0x3a,
+    0x64, 0x34, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64,
+    0x32, 0x3a, 0x33, 0x32, 0x3a, 0x30, 0x39, 0x3a, 0x61, 0x64, 0x3a, 0x32,
+    0x33, 0x3a, 0x64, 0x33, 0x3a, 0x31, 0x34, 0x3a, 0x32, 0x33, 0x3a, 0x32,
+    0x31, 0x3a, 0x37, 0x34, 0x3a, 0x65, 0x34, 0x3a, 0x30, 0x64, 0x3a, 0x37,
+    0x66, 0x3a, 0x39, 0x64, 0x3a, 0x36, 0x32, 0x3a, 0x31, 0x33, 0x3a, 0x39,
+    0x37, 0x3a, 0x38, 0x36, 0x3a, 0x36, 0x33, 0x3a, 0x33, 0x61, 0x0a, 0x23,
+    0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30, 0x38, 0x3a,
+    0x32, 0x39, 0x3a, 0x37, 0x61, 0x3a, 0x34, 0x30, 0x3a, 0x34, 0x37, 0x3a,
+    0x64, 0x62, 0x3a, 0x61, 0x32, 0x3a, 0x33, 0x36, 0x3a, 0x38, 0x30, 0x3a,
+    0x63, 0x37, 0x3a, 0x33, 0x31, 0x3a, 0x64, 0x62, 0x3a, 0x36, 0x65, 0x3a,
+    0x33, 0x31, 0x3a, 0x37, 0x36, 0x3a, 0x35, 0x33, 0x3a, 0x63, 0x61, 0x3a,
+    0x37, 0x38, 0x3a, 0x34, 0x38, 0x3a, 0x65, 0x31, 0x3a, 0x62, 0x65, 0x3a,
+    0x62, 0x64, 0x3a, 0x33, 0x61, 0x3a, 0x30, 0x62, 0x3a, 0x30, 0x31, 0x3a,
+    0x37, 0x39, 0x3a, 0x61, 0x37, 0x3a, 0x30, 0x37, 0x3a, 0x66, 0x39, 0x3a,
+    0x32, 0x63, 0x3a, 0x66, 0x31, 0x3a, 0x37, 0x38, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x4d, 0x49, 0x49, 0x44, 0x49, 0x44, 0x43, 0x43, 0x41, 0x6f, 0x6d,
+    0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x45, 0x4e, 0x64, 0x37,
+    0x30, 0x7a, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42,
+    0x4f, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x47, 0x45, 0x77, 0x4a, 0x56, 0x0a, 0x55, 0x7a, 0x45, 0x51, 0x4d, 0x41,
+    0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x48, 0x52, 0x58,
+    0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x44, 0x45, 0x74, 0x4d, 0x43,
+    0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x6b, 0x52, 0x58,
+    0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x43, 0x42, 0x54, 0x5a, 0x57,
+    0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67, 0x51, 0x32, 0x56, 0x79, 0x0a, 0x64,
+    0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x55, 0x67, 0x51,
+    0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d,
+    0x42, 0x34, 0x58, 0x44, 0x54, 0x6b, 0x34, 0x4d, 0x44, 0x67, 0x79, 0x4d,
+    0x6a, 0x45, 0x32, 0x4e, 0x44, 0x45, 0x31, 0x4d, 0x56, 0x6f, 0x58, 0x44,
+    0x54, 0x45, 0x34, 0x4d, 0x44, 0x67, 0x79, 0x4d, 0x6a, 0x45, 0x32, 0x4e,
+    0x44, 0x45, 0x31, 0x0a, 0x4d, 0x56, 0x6f, 0x77, 0x54, 0x6a, 0x45, 0x4c,
+    0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43,
+    0x56, 0x56, 0x4d, 0x78, 0x45, 0x44, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x6f, 0x54, 0x42, 0x30, 0x56, 0x78, 0x64, 0x57, 0x6c, 0x6d,
+    0x59, 0x58, 0x67, 0x78, 0x4c, 0x54, 0x41, 0x72, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x73, 0x54, 0x4a, 0x45, 0x56, 0x78, 0x0a, 0x64, 0x57, 0x6c,
+    0x6d, 0x59, 0x58, 0x67, 0x67, 0x55, 0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a,
+    0x6c, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c,
+    0x6a, 0x59, 0x58, 0x52, 0x6c, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68,
+    0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x54, 0x43, 0x42, 0x6e, 0x7a, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x0a, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x42, 0x6a, 0x51,
+    0x41, 0x77, 0x67, 0x59, 0x6b, 0x43, 0x67, 0x59, 0x45, 0x41, 0x77, 0x56,
+    0x32, 0x78, 0x57, 0x47, 0x63, 0x49, 0x59, 0x75, 0x36, 0x67, 0x6d, 0x69,
+    0x30, 0x66, 0x43, 0x47, 0x32, 0x52, 0x46, 0x47, 0x69, 0x59, 0x43, 0x68,
+    0x37, 0x2b, 0x32, 0x67, 0x52, 0x76, 0x45, 0x34, 0x52, 0x69, 0x49, 0x63,
+    0x50, 0x52, 0x66, 0x4d, 0x36, 0x66, 0x0a, 0x42, 0x65, 0x43, 0x34, 0x41,
+    0x66, 0x42, 0x4f, 0x4e, 0x4f, 0x7a, 0x69, 0x69, 0x70, 0x55, 0x45, 0x5a,
+    0x4b, 0x7a, 0x78, 0x61, 0x31, 0x4e, 0x66, 0x42, 0x62, 0x50, 0x4c, 0x5a,
+    0x34, 0x43, 0x2f, 0x51, 0x67, 0x4b, 0x4f, 0x2f, 0x74, 0x30, 0x42, 0x43,
+    0x65, 0x7a, 0x68, 0x41, 0x42, 0x52, 0x50, 0x2f, 0x50, 0x76, 0x77, 0x44,
+    0x4e, 0x31, 0x44, 0x75, 0x6c, 0x73, 0x72, 0x34, 0x52, 0x2b, 0x41, 0x0a,
+    0x63, 0x4a, 0x6b, 0x56, 0x56, 0x35, 0x4d, 0x57, 0x38, 0x51, 0x2b, 0x58,
+    0x61, 0x72, 0x66, 0x43, 0x61, 0x43, 0x4d, 0x63, 0x7a, 0x45, 0x31, 0x5a,
+    0x4d, 0x4b, 0x78, 0x52, 0x48, 0x6a, 0x75, 0x76, 0x4b, 0x39, 0x62, 0x75,
+    0x59, 0x30, 0x56, 0x37, 0x78, 0x64, 0x6c, 0x66, 0x55, 0x4e, 0x4c, 0x6a,
+    0x55, 0x41, 0x38, 0x36, 0x69, 0x4f, 0x65, 0x2f, 0x46, 0x50, 0x33, 0x67,
+    0x78, 0x37, 0x6b, 0x43, 0x0a, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4f,
+    0x43, 0x41, 0x51, 0x6b, 0x77, 0x67, 0x67, 0x45, 0x46, 0x4d, 0x48, 0x41,
+    0x47, 0x41, 0x31, 0x55, 0x64, 0x48, 0x77, 0x52, 0x70, 0x4d, 0x47, 0x63,
+    0x77, 0x5a, 0x61, 0x42, 0x6a, 0x6f, 0x47, 0x47, 0x6b, 0x58, 0x7a, 0x42,
+    0x64, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x51, 0x0a, 0x4d, 0x41,
+    0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x48, 0x52, 0x58,
+    0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x44, 0x45, 0x74, 0x4d, 0x43,
+    0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x6b, 0x52, 0x58,
+    0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x43, 0x42, 0x54, 0x5a, 0x57,
+    0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47,
+    0x6c, 0x6d, 0x0a, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x55, 0x67, 0x51,
+    0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d,
+    0x51, 0x30, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45,
+    0x77, 0x52, 0x44, 0x55, 0x6b, 0x77, 0x78, 0x4d, 0x42, 0x6f, 0x47, 0x41,
+    0x31, 0x55, 0x64, 0x45, 0x41, 0x51, 0x54, 0x4d, 0x42, 0x47, 0x42, 0x44,
+    0x7a, 0x49, 0x77, 0x4d, 0x54, 0x67, 0x77, 0x0a, 0x4f, 0x44, 0x49, 0x79,
+    0x4d, 0x54, 0x59, 0x30, 0x4d, 0x54, 0x55, 0x78, 0x57, 0x6a, 0x41, 0x4c,
+    0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43,
+    0x41, 0x51, 0x59, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a,
+    0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, 0x41, 0x55, 0x53, 0x4f, 0x5a, 0x6f,
+    0x2b, 0x53, 0x76, 0x53, 0x73, 0x70, 0x58, 0x58, 0x52, 0x39, 0x67, 0x6a,
+    0x0a, 0x49, 0x42, 0x42, 0x50, 0x4d, 0x35, 0x69, 0x51, 0x6e, 0x39, 0x51,
+    0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59,
+    0x45, 0x46, 0x45, 0x6a, 0x6d, 0x61, 0x50, 0x6b, 0x72, 0x30, 0x72, 0x4b,
+    0x56, 0x31, 0x30, 0x66, 0x59, 0x49, 0x79, 0x41, 0x51, 0x54, 0x7a, 0x4f,
+    0x59, 0x6b, 0x4a, 0x2f, 0x55, 0x4d, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x45, 0x77, 0x51, 0x46, 0x0a, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66,
+    0x38, 0x77, 0x47, 0x67, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x5a, 0x39, 0x42, 0x30, 0x45, 0x41, 0x42, 0x41, 0x30, 0x77, 0x43, 0x78,
+    0x73, 0x46, 0x56, 0x6a, 0x4d, 0x75, 0x4d, 0x47, 0x4d, 0x44, 0x41, 0x67,
+    0x62, 0x41, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
+    0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x0a, 0x41,
+    0x34, 0x47, 0x42, 0x41, 0x46, 0x6a, 0x4f, 0x4b, 0x65, 0x72, 0x38, 0x39,
+    0x39, 0x36, 0x31, 0x7a, 0x67, 0x4b, 0x35, 0x46, 0x37, 0x57, 0x46, 0x30,
+    0x62, 0x6e, 0x6a, 0x34, 0x4a, 0x58, 0x4d, 0x4a, 0x54, 0x45, 0x4e, 0x41,
+    0x4b, 0x61, 0x53, 0x62, 0x6e, 0x2b, 0x32, 0x6b, 0x6d, 0x4f, 0x65, 0x55,
+    0x4a, 0x58, 0x52, 0x6d, 0x6d, 0x2f, 0x6b, 0x45, 0x64, 0x35, 0x6a, 0x68,
+    0x57, 0x36, 0x59, 0x0a, 0x37, 0x71, 0x6a, 0x2f, 0x57, 0x73, 0x6a, 0x54,
+    0x56, 0x62, 0x4a, 0x6d, 0x63, 0x56, 0x66, 0x65, 0x77, 0x43, 0x48, 0x72,
+    0x50, 0x53, 0x71, 0x6e, 0x49, 0x30, 0x6b, 0x42, 0x42, 0x49, 0x5a, 0x43,
+    0x65, 0x2f, 0x7a, 0x75, 0x66, 0x36, 0x49, 0x57, 0x55, 0x72, 0x56, 0x6e,
+    0x5a, 0x39, 0x4e, 0x41, 0x32, 0x7a, 0x73, 0x6d, 0x57, 0x4c, 0x49, 0x6f,
+    0x64, 0x7a, 0x32, 0x75, 0x46, 0x48, 0x64, 0x68, 0x0a, 0x31, 0x76, 0x6f,
+    0x71, 0x5a, 0x69, 0x65, 0x67, 0x44, 0x66, 0x71, 0x6e, 0x63, 0x31, 0x7a,
+    0x71, 0x63, 0x50, 0x47, 0x55, 0x49, 0x57, 0x56, 0x45, 0x58, 0x2f, 0x72,
+    0x38, 0x37, 0x79, 0x6c, 0x6f, 0x71, 0x61, 0x4b, 0x48, 0x65, 0x65, 0x39,
+    0x35, 0x37, 0x30, 0x2b, 0x73, 0x42, 0x33, 0x63, 0x34, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x4f,
+    0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x6c, 0x61, 0x73, 0x73,
+    0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72,
+    0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a,
+    0x65, 0x63, 0x74, 0x3a, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53,
+    0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55,
+    0x3d, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
+    0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x56, 0x65,
+    0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
+    0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72,
+    0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72,
+    0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x34, 0x39, 0x38, 0x34, 0x33, 0x39,
+    0x32, 0x39, 0x34, 0x33, 0x35, 0x38, 0x31, 0x38, 0x36, 0x39, 0x32, 0x38,
+    0x34, 0x38, 0x30, 0x34, 0x30, 0x33, 0x36, 0x35, 0x37, 0x31, 0x36, 0x38,
+    0x35, 0x31, 0x37, 0x30, 0x32, 0x34, 0x36, 0x33, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x31, 0x30, 0x3a, 0x66, 0x63, 0x3a, 0x36, 0x33,
+    0x3a, 0x35, 0x64, 0x3a, 0x66, 0x36, 0x3a, 0x32, 0x36, 0x3a, 0x33, 0x65,
+    0x3a, 0x30, 0x64, 0x3a, 0x66, 0x33, 0x3a, 0x32, 0x35, 0x3a, 0x62, 0x65,
+    0x3a, 0x35, 0x66, 0x3a, 0x37, 0x39, 0x3a, 0x63, 0x64, 0x3a, 0x36, 0x37,
+    0x3a, 0x36, 0x37, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x37, 0x34, 0x3a, 0x32, 0x63, 0x3a, 0x33, 0x31, 0x3a, 0x39, 0x32, 0x3a,
+    0x65, 0x36, 0x3a, 0x30, 0x37, 0x3a, 0x65, 0x34, 0x3a, 0x32, 0x34, 0x3a,
+    0x65, 0x62, 0x3a, 0x34, 0x35, 0x3a, 0x34, 0x39, 0x3a, 0x35, 0x34, 0x3a,
+    0x32, 0x62, 0x3a, 0x65, 0x31, 0x3a, 0x62, 0x62, 0x3a, 0x63, 0x35, 0x3a,
+    0x33, 0x65, 0x3a, 0x36, 0x31, 0x3a, 0x37, 0x34, 0x3a, 0x65, 0x32, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x65, 0x37,
+    0x3a, 0x36, 0x38, 0x3a, 0x35, 0x36, 0x3a, 0x33, 0x34, 0x3a, 0x65, 0x66,
+    0x3a, 0x61, 0x63, 0x3a, 0x66, 0x36, 0x3a, 0x39, 0x61, 0x3a, 0x63, 0x65,
+    0x3a, 0x39, 0x33, 0x3a, 0x39, 0x61, 0x3a, 0x36, 0x62, 0x3a, 0x32, 0x35,
+    0x3a, 0x35, 0x62, 0x3a, 0x37, 0x62, 0x3a, 0x34, 0x66, 0x3a, 0x61, 0x62,
+    0x3a, 0x65, 0x66, 0x3a, 0x34, 0x32, 0x3a, 0x39, 0x33, 0x3a, 0x35, 0x62,
+    0x3a, 0x35, 0x30, 0x3a, 0x61, 0x32, 0x3a, 0x36, 0x35, 0x3a, 0x61, 0x63,
+    0x3a, 0x62, 0x35, 0x3a, 0x63, 0x62, 0x3a, 0x36, 0x30, 0x3a, 0x32, 0x37,
+    0x3a, 0x65, 0x34, 0x3a, 0x34, 0x65, 0x3a, 0x37, 0x30, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x50, 0x44, 0x43, 0x43, 0x41, 0x61,
+    0x55, 0x43, 0x45, 0x48, 0x43, 0x36, 0x35, 0x42, 0x30, 0x51, 0x32, 0x53,
+    0x6b, 0x30, 0x74, 0x6a, 0x6a, 0x4b, 0x65, 0x77, 0x50, 0x4d, 0x75, 0x72,
+    0x38, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x63, 0x4e, 0x41, 0x51, 0x45, 0x43, 0x42, 0x51, 0x41, 0x77, 0x58, 0x7a,
+    0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x6c, 0x5a, 0x6c, 0x63,
+    0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62,
+    0x6d, 0x4d, 0x75, 0x4d, 0x54, 0x63, 0x77, 0x4e, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x4c, 0x45, 0x79, 0x35, 0x44, 0x62, 0x47, 0x46, 0x7a, 0x0a,
+    0x63, 0x79, 0x41, 0x7a, 0x49, 0x46, 0x42, 0x31, 0x59, 0x6d, 0x78, 0x70,
+    0x59, 0x79, 0x42, 0x51, 0x63, 0x6d, 0x6c, 0x74, 0x59, 0x58, 0x4a, 0x35,
+    0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a,
+    0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30,
+    0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x42, 0x34, 0x58,
+    0x44, 0x54, 0x6b, 0x32, 0x0a, 0x4d, 0x44, 0x45, 0x79, 0x4f, 0x54, 0x41,
+    0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x49,
+    0x34, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x54, 0x49, 0x7a, 0x4e, 0x54, 0x6b,
+    0x31, 0x4f, 0x56, 0x6f, 0x77, 0x58, 0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d,
+    0x78, 0x46, 0x7a, 0x41, 0x56, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41,
+    0x6f, 0x54, 0x44, 0x6c, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57,
+    0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x54,
+    0x63, 0x77, 0x4e, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x79,
+    0x35, 0x44, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x79, 0x41, 0x7a, 0x49, 0x46,
+    0x42, 0x31, 0x59, 0x6d, 0x78, 0x70, 0x59, 0x79, 0x42, 0x51, 0x63, 0x6d,
+    0x6c, 0x74, 0x0a, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x45, 0x4e, 0x6c, 0x63,
+    0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62,
+    0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61,
+    0x58, 0x52, 0x35, 0x4d, 0x49, 0x47, 0x66, 0x4d, 0x41, 0x30, 0x47, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41,
+    0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4e, 0x0a, 0x41, 0x44, 0x43, 0x42,
+    0x69, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x4a, 0x58, 0x46, 0x6d, 0x65,
+    0x38, 0x68, 0x75, 0x4b, 0x41, 0x52, 0x53, 0x30, 0x45, 0x4e, 0x38, 0x45,
+    0x51, 0x4e, 0x76, 0x6a, 0x56, 0x36, 0x39, 0x71, 0x52, 0x55, 0x43, 0x50,
+    0x68, 0x41, 0x77, 0x4c, 0x30, 0x54, 0x50, 0x5a, 0x32, 0x52, 0x48, 0x50,
+    0x37, 0x67, 0x4a, 0x59, 0x48, 0x79, 0x58, 0x33, 0x4b, 0x71, 0x68, 0x45,
+    0x0a, 0x42, 0x61, 0x72, 0x73, 0x41, 0x78, 0x39, 0x34, 0x66, 0x35, 0x36,
+    0x54, 0x75, 0x5a, 0x6f, 0x41, 0x71, 0x69, 0x4e, 0x39, 0x31, 0x71, 0x79,
+    0x46, 0x6f, 0x6d, 0x4e, 0x46, 0x78, 0x33, 0x49, 0x6e, 0x7a, 0x50, 0x52,
+    0x4d, 0x78, 0x6e, 0x56, 0x78, 0x30, 0x6a, 0x6e, 0x76, 0x54, 0x30, 0x4c,
+    0x77, 0x64, 0x64, 0x38, 0x4b, 0x6b, 0x4d, 0x61, 0x4f, 0x49, 0x47, 0x2b,
+    0x59, 0x44, 0x2f, 0x69, 0x73, 0x0a, 0x49, 0x31, 0x39, 0x77, 0x4b, 0x54,
+    0x61, 0x6b, 0x79, 0x59, 0x62, 0x6e, 0x73, 0x5a, 0x6f, 0x67, 0x79, 0x31,
+    0x4f, 0x6c, 0x68, 0x65, 0x63, 0x39, 0x76, 0x6e, 0x32, 0x61, 0x2f, 0x69,
+    0x52, 0x46, 0x4d, 0x39, 0x78, 0x32, 0x46, 0x65, 0x30, 0x50, 0x6f, 0x6e,
+    0x46, 0x6b, 0x54, 0x47, 0x55, 0x75, 0x67, 0x57, 0x68, 0x46, 0x70, 0x77,
+    0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x4d, 0x41, 0x30, 0x47, 0x0a, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41,
+    0x67, 0x55, 0x41, 0x41, 0x34, 0x47, 0x42, 0x41, 0x4c, 0x74, 0x4d, 0x45,
+    0x69, 0x76, 0x50, 0x4c, 0x43, 0x59, 0x41, 0x54, 0x78, 0x51, 0x54, 0x33,
+    0x61, 0x62, 0x37, 0x2f, 0x41, 0x6f, 0x52, 0x68, 0x49, 0x7a, 0x7a, 0x4b,
+    0x42, 0x78, 0x6e, 0x6b, 0x69, 0x39, 0x38, 0x74, 0x73, 0x58, 0x36, 0x33,
+    0x2f, 0x44, 0x6f, 0x0a, 0x6c, 0x62, 0x77, 0x64, 0x6a, 0x32, 0x77, 0x73,
+    0x71, 0x46, 0x48, 0x4d, 0x63, 0x39, 0x69, 0x6b, 0x77, 0x46, 0x50, 0x77,
+    0x54, 0x74, 0x59, 0x6d, 0x77, 0x48, 0x59, 0x42, 0x56, 0x34, 0x47, 0x53,
+    0x58, 0x69, 0x48, 0x78, 0x30, 0x62, 0x48, 0x2f, 0x35, 0x39, 0x41, 0x68,
+    0x57, 0x4d, 0x31, 0x70, 0x46, 0x2b, 0x4e, 0x45, 0x48, 0x4a, 0x77, 0x5a,
+    0x52, 0x44, 0x6d, 0x4a, 0x58, 0x4e, 0x79, 0x63, 0x0a, 0x41, 0x41, 0x39,
+    0x57, 0x6a, 0x51, 0x4b, 0x5a, 0x37, 0x61, 0x4b, 0x51, 0x52, 0x55, 0x7a,
+    0x6b, 0x75, 0x78, 0x43, 0x6b, 0x50, 0x66, 0x41, 0x79, 0x41, 0x77, 0x37,
+    0x78, 0x7a, 0x76, 0x6a, 0x6f, 0x79, 0x56, 0x47, 0x4d, 0x35, 0x6d, 0x4b,
+    0x66, 0x35, 0x70, 0x2f, 0x41, 0x66, 0x62, 0x64, 0x79, 0x6e, 0x4d, 0x6b,
+    0x32, 0x4f, 0x6d, 0x75, 0x66, 0x54, 0x71, 0x6a, 0x2f, 0x5a, 0x41, 0x31,
+    0x6b, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x43,
+    0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69,
+    0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+    0x47, 0x32, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20,
+    0x6f, 0x6e, 0x6c, 0x79, 0x2f, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x43,
+    0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69,
+    0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+    0x47, 0x32, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20,
+    0x6f, 0x6e, 0x6c, 0x79, 0x2f, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x56, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x43,
+    0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69,
+    0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+    0x47, 0x32, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c,
+    0x3a, 0x20, 0x31, 0x36, 0x37, 0x32, 0x38, 0x35, 0x33, 0x38, 0x30, 0x32,
+    0x34, 0x32, 0x33, 0x31, 0x39, 0x36, 0x34, 0x38, 0x34, 0x35, 0x31, 0x31,
+    0x35, 0x34, 0x34, 0x37, 0x38, 0x38, 0x30, 0x38, 0x30, 0x33, 0x36, 0x38,
+    0x38, 0x31, 0x36, 0x30, 0x36, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x61, 0x32, 0x3a, 0x33, 0x33, 0x3a, 0x39, 0x62, 0x3a, 0x34, 0x63,
+    0x3a, 0x37, 0x34, 0x3a, 0x37, 0x38, 0x3a, 0x37, 0x33, 0x3a, 0x64, 0x34,
+    0x3a, 0x36, 0x63, 0x3a, 0x65, 0x37, 0x3a, 0x63, 0x31, 0x3a, 0x66, 0x33,
+    0x3a, 0x38, 0x64, 0x3a, 0x63, 0x62, 0x3a, 0x35, 0x63, 0x3a, 0x65, 0x39,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x35, 0x3a,
+    0x33, 0x37, 0x3a, 0x31, 0x63, 0x3a, 0x61, 0x36, 0x3a, 0x65, 0x35, 0x3a,
+    0x35, 0x30, 0x3a, 0x31, 0x34, 0x3a, 0x33, 0x64, 0x3a, 0x63, 0x65, 0x3a,
+    0x32, 0x38, 0x3a, 0x30, 0x33, 0x3a, 0x34, 0x37, 0x3a, 0x31, 0x62, 0x3a,
+    0x64, 0x65, 0x3a, 0x33, 0x61, 0x3a, 0x30, 0x39, 0x3a, 0x65, 0x38, 0x3a,
+    0x66, 0x38, 0x3a, 0x37, 0x37, 0x3a, 0x30, 0x66, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x33, 0x3a, 0x63, 0x65,
+    0x3a, 0x33, 0x63, 0x3a, 0x31, 0x32, 0x3a, 0x32, 0x39, 0x3a, 0x36, 0x38,
+    0x3a, 0x38, 0x61, 0x3a, 0x35, 0x39, 0x3a, 0x33, 0x64, 0x3a, 0x34, 0x38,
+    0x3a, 0x35, 0x66, 0x3a, 0x38, 0x31, 0x3a, 0x39, 0x37, 0x3a, 0x33, 0x63,
+    0x3a, 0x30, 0x66, 0x3a, 0x39, 0x31, 0x3a, 0x39, 0x35, 0x3a, 0x34, 0x33,
+    0x3a, 0x31, 0x65, 0x3a, 0x64, 0x61, 0x3a, 0x33, 0x37, 0x3a, 0x63, 0x63,
+    0x3a, 0x35, 0x65, 0x3a, 0x33, 0x36, 0x3a, 0x34, 0x33, 0x3a, 0x30, 0x65,
+    0x3a, 0x37, 0x39, 0x3a, 0x63, 0x37, 0x3a, 0x61, 0x38, 0x3a, 0x38, 0x38,
+    0x3a, 0x36, 0x33, 0x3a, 0x38, 0x62, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
+    0x49, 0x49, 0x44, 0x41, 0x6a, 0x43, 0x43, 0x41, 0x6d, 0x73, 0x43, 0x45,
+    0x48, 0x33, 0x5a, 0x2f, 0x67, 0x66, 0x50, 0x71, 0x42, 0x36, 0x33, 0x45,
+    0x48, 0x6c, 0x6e, 0x2b, 0x36, 0x65, 0x4a, 0x4e, 0x4d, 0x59, 0x77, 0x44,
+    0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41,
+    0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x67, 0x63, 0x45, 0x78, 0x43,
+    0x7a, 0x41, 0x4a, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54,
+    0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x63, 0x77, 0x46, 0x51, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x4b, 0x45, 0x77, 0x35, 0x57, 0x5a, 0x58, 0x4a, 0x70,
+    0x55, 0x32, 0x6c, 0x6e, 0x62, 0x69, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a,
+    0x4c, 0x6a, 0x45, 0x38, 0x4d, 0x44, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x78, 0x4d, 0x7a, 0x51, 0x32, 0x78, 0x68, 0x0a, 0x63, 0x33, 0x4d,
+    0x67, 0x4d, 0x79, 0x42, 0x51, 0x64, 0x57, 0x4a, 0x73, 0x61, 0x57, 0x4d,
+    0x67, 0x55, 0x48, 0x4a, 0x70, 0x62, 0x57, 0x46, 0x79, 0x65, 0x53, 0x42,
+    0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46,
+    0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68,
+    0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63,
+    0x79, 0x0a, 0x4d, 0x54, 0x6f, 0x77, 0x4f, 0x41, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x4c, 0x45, 0x7a, 0x45, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x54,
+    0x6b, 0x35, 0x4f, 0x43, 0x42, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32,
+    0x6c, 0x6e, 0x62, 0x69, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x69,
+    0x41, 0x74, 0x49, 0x45, 0x5a, 0x76, 0x63, 0x69, 0x42, 0x68, 0x64, 0x58,
+    0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x0a, 0x65, 0x6d, 0x56, 0x6b, 0x49,
+    0x48, 0x56, 0x7a, 0x5a, 0x53, 0x42, 0x76, 0x62, 0x6d, 0x78, 0x35, 0x4d,
+    0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45,
+    0x78, 0x5a, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62,
+    0x69, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4f, 0x5a,
+    0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x4d, 0x42, 0x34, 0x58, 0x0a,
+    0x44, 0x54, 0x6b, 0x34, 0x4d, 0x44, 0x55, 0x78, 0x4f, 0x44, 0x41, 0x77,
+    0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x49, 0x34,
+    0x4d, 0x44, 0x67, 0x77, 0x4d, 0x54, 0x49, 0x7a, 0x4e, 0x54, 0x6b, 0x31,
+    0x4f, 0x56, 0x6f, 0x77, 0x67, 0x63, 0x45, 0x78, 0x43, 0x7a, 0x41, 0x4a,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54,
+    0x4d, 0x52, 0x63, 0x77, 0x0a, 0x46, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4b, 0x45, 0x77, 0x35, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c,
+    0x6e, 0x62, 0x69, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45,
+    0x38, 0x4d, 0x44, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d,
+    0x7a, 0x51, 0x32, 0x78, 0x68, 0x63, 0x33, 0x4d, 0x67, 0x4d, 0x79, 0x42,
+    0x51, 0x64, 0x57, 0x4a, 0x73, 0x61, 0x57, 0x4d, 0x67, 0x0a, 0x55, 0x48,
+    0x4a, 0x70, 0x62, 0x57, 0x46, 0x79, 0x65, 0x53, 0x42, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57,
+    0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d,
+    0x6c, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x79, 0x4d, 0x54,
+    0x6f, 0x77, 0x4f, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x7a,
+    0x45, 0x6f, 0x0a, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x54, 0x6b, 0x35, 0x4f,
+    0x43, 0x42, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62,
+    0x69, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x69, 0x41, 0x74, 0x49,
+    0x45, 0x5a, 0x76, 0x63, 0x69, 0x42, 0x68, 0x64, 0x58, 0x52, 0x6f, 0x62,
+    0x33, 0x4a, 0x70, 0x65, 0x6d, 0x56, 0x6b, 0x49, 0x48, 0x56, 0x7a, 0x5a,
+    0x53, 0x42, 0x76, 0x62, 0x6d, 0x78, 0x35, 0x0a, 0x4d, 0x52, 0x38, 0x77,
+    0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x5a, 0x57,
+    0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x69, 0x42, 0x55,
+    0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33,
+    0x62, 0x33, 0x4a, 0x72, 0x4d, 0x49, 0x47, 0x66, 0x4d, 0x41, 0x30, 0x47,
+    0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42,
+    0x0a, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4e, 0x41, 0x44, 0x43,
+    0x42, 0x69, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x4d, 0x58, 0x74, 0x45,
+    0x52, 0x58, 0x56, 0x78, 0x70, 0x30, 0x4b, 0x76, 0x54, 0x75, 0x57, 0x70,
+    0x4d, 0x6d, 0x52, 0x39, 0x5a, 0x6d, 0x44, 0x43, 0x4f, 0x46, 0x6f, 0x55,
+    0x67, 0x52, 0x6d, 0x31, 0x48, 0x50, 0x39, 0x53, 0x46, 0x49, 0x49, 0x54,
+    0x68, 0x62, 0x62, 0x50, 0x34, 0x0a, 0x70, 0x4f, 0x30, 0x4d, 0x38, 0x52,
+    0x63, 0x50, 0x4f, 0x2f, 0x6d, 0x6e, 0x2b, 0x53, 0x58, 0x58, 0x77, 0x63,
+    0x2b, 0x45, 0x59, 0x2f, 0x4a, 0x38, 0x59, 0x38, 0x2b, 0x69, 0x52, 0x2f,
+    0x4c, 0x47, 0x57, 0x7a, 0x4f, 0x4f, 0x5a, 0x45, 0x41, 0x45, 0x61, 0x4d,
+    0x47, 0x41, 0x75, 0x57, 0x51, 0x63, 0x52, 0x58, 0x66, 0x48, 0x32, 0x47,
+    0x37, 0x31, 0x6c, 0x53, 0x6b, 0x38, 0x55, 0x4f, 0x67, 0x30, 0x0a, 0x31,
+    0x33, 0x67, 0x66, 0x71, 0x4c, 0x70, 0x74, 0x51, 0x35, 0x47, 0x56, 0x6a,
+    0x30, 0x56, 0x58, 0x58, 0x6e, 0x37, 0x46, 0x2b, 0x38, 0x71, 0x6b, 0x42,
+    0x4f, 0x76, 0x71, 0x6c, 0x7a, 0x64, 0x55, 0x4d, 0x47, 0x2b, 0x37, 0x41,
+    0x55, 0x63, 0x79, 0x4d, 0x38, 0x33, 0x63, 0x56, 0x35, 0x74, 0x6b, 0x61,
+    0x57, 0x48, 0x34, 0x6d, 0x78, 0x30, 0x63, 0x69, 0x55, 0x39, 0x63, 0x5a,
+    0x77, 0x49, 0x44, 0x0a, 0x41, 0x51, 0x41, 0x42, 0x4d, 0x41, 0x30, 0x47,
+    0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42,
+    0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x42, 0x41, 0x46, 0x46, 0x4e,
+    0x7a, 0x62, 0x35, 0x63, 0x79, 0x35, 0x67, 0x5a, 0x6e, 0x42, 0x57, 0x79,
+    0x41, 0x54, 0x6c, 0x34, 0x4c, 0x6b, 0x30, 0x50, 0x5a, 0x33, 0x42, 0x77,
+    0x6d, 0x63, 0x59, 0x51, 0x57, 0x70, 0x53, 0x6b, 0x0a, 0x55, 0x30, 0x31,
+    0x55, 0x62, 0x53, 0x75, 0x76, 0x44, 0x56, 0x31, 0x41, 0x69, 0x32, 0x54,
+    0x54, 0x31, 0x2b, 0x37, 0x65, 0x56, 0x6d, 0x47, 0x53, 0x58, 0x36, 0x62,
+    0x45, 0x48, 0x52, 0x42, 0x68, 0x4e, 0x74, 0x4d, 0x73, 0x4a, 0x7a, 0x7a,
+    0x6f, 0x4b, 0x51, 0x6d, 0x35, 0x45, 0x57, 0x52, 0x30, 0x7a, 0x4c, 0x56,
+    0x7a, 0x6e, 0x78, 0x78, 0x49, 0x71, 0x62, 0x78, 0x68, 0x41, 0x65, 0x37,
+    0x69, 0x0a, 0x46, 0x36, 0x59, 0x4d, 0x34, 0x30, 0x41, 0x49, 0x4f, 0x77,
+    0x37, 0x6e, 0x36, 0x30, 0x52, 0x7a, 0x4b, 0x70, 0x72, 0x78, 0x61, 0x5a,
+    0x4c, 0x76, 0x63, 0x52, 0x54, 0x44, 0x4f, 0x61, 0x78, 0x78, 0x70, 0x35,
+    0x45, 0x4a, 0x62, 0x2b, 0x52, 0x78, 0x42, 0x72, 0x4f, 0x36, 0x57, 0x56,
+    0x63, 0x6d, 0x65, 0x51, 0x44, 0x32, 0x2b, 0x41, 0x32, 0x69, 0x4d, 0x7a,
+    0x41, 0x6f, 0x31, 0x4b, 0x70, 0x59, 0x0a, 0x6f, 0x4a, 0x32, 0x64, 0x61,
+    0x5a, 0x48, 0x39, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73,
+    0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x6c, 0x6f, 0x62,
+    0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x43, 0x41, 0x20, 0x4f, 0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53,
+    0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x20, 0x4f, 0x55,
+    0x3d, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47,
+    0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f,
+    0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d, 0x47, 0x6c, 0x6f, 0x62,
+    0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61,
+    0x20, 0x4f, 0x55, 0x3d, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x47, 0x6c,
+    0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f,
+    0x74, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69,
+    0x61, 0x6c, 0x3a, 0x20, 0x34, 0x38, 0x33, 0x35, 0x37, 0x30, 0x33, 0x32,
+    0x37, 0x38, 0x34, 0x35, 0x39, 0x37, 0x30, 0x37, 0x36, 0x36, 0x39, 0x30,
+    0x30, 0x35, 0x32, 0x30, 0x34, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x33, 0x65, 0x3a, 0x34, 0x35, 0x3a, 0x35, 0x32, 0x3a, 0x31, 0x35,
+    0x3a, 0x30, 0x39, 0x3a, 0x35, 0x31, 0x3a, 0x39, 0x32, 0x3a, 0x65, 0x31,
+    0x3a, 0x62, 0x37, 0x3a, 0x35, 0x64, 0x3a, 0x33, 0x37, 0x3a, 0x39, 0x66,
+    0x3a, 0x62, 0x31, 0x3a, 0x38, 0x37, 0x3a, 0x32, 0x39, 0x3a, 0x38, 0x61,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x62, 0x31, 0x3a,
+    0x62, 0x63, 0x3a, 0x39, 0x36, 0x3a, 0x38, 0x62, 0x3a, 0x64, 0x34, 0x3a,
+    0x66, 0x34, 0x3a, 0x39, 0x64, 0x3a, 0x36, 0x32, 0x3a, 0x32, 0x61, 0x3a,
+    0x61, 0x38, 0x3a, 0x39, 0x61, 0x3a, 0x38, 0x31, 0x3a, 0x66, 0x32, 0x3a,
+    0x31, 0x35, 0x3a, 0x30, 0x31, 0x3a, 0x35, 0x32, 0x3a, 0x61, 0x34, 0x3a,
+    0x31, 0x64, 0x3a, 0x38, 0x32, 0x3a, 0x39, 0x63, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x65, 0x62, 0x3a, 0x64, 0x34,
+    0x3a, 0x31, 0x30, 0x3a, 0x34, 0x30, 0x3a, 0x65, 0x34, 0x3a, 0x62, 0x62,
+    0x3a, 0x33, 0x65, 0x3a, 0x63, 0x37, 0x3a, 0x34, 0x32, 0x3a, 0x63, 0x39,
+    0x3a, 0x65, 0x33, 0x3a, 0x38, 0x31, 0x3a, 0x64, 0x33, 0x3a, 0x31, 0x65,
+    0x3a, 0x66, 0x32, 0x3a, 0x61, 0x34, 0x3a, 0x31, 0x61, 0x3a, 0x34, 0x38,
+    0x3a, 0x62, 0x36, 0x3a, 0x36, 0x38, 0x3a, 0x35, 0x63, 0x3a, 0x39, 0x36,
+    0x3a, 0x65, 0x37, 0x3a, 0x63, 0x65, 0x3a, 0x66, 0x33, 0x3a, 0x63, 0x31,
+    0x3a, 0x64, 0x66, 0x3a, 0x36, 0x63, 0x3a, 0x64, 0x34, 0x3a, 0x33, 0x33,
+    0x3a, 0x31, 0x63, 0x3a, 0x39, 0x39, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
+    0x49, 0x49, 0x44, 0x64, 0x54, 0x43, 0x43, 0x41, 0x6c, 0x32, 0x67, 0x41,
+    0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4c, 0x42, 0x41, 0x41, 0x41, 0x41,
+    0x41, 0x41, 0x42, 0x46, 0x55, 0x74, 0x61, 0x77, 0x35, 0x51, 0x77, 0x44,
+    0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41,
+    0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x56, 0x7a, 0x45, 0x4c, 0x4d,
+    0x41, 0x6b, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43,
+    0x51, 0x6b, 0x55, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x6f, 0x54, 0x45, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4a, 0x68,
+    0x62, 0x46, 0x4e, 0x70, 0x5a, 0x32, 0x34, 0x67, 0x62, 0x6e, 0x59, 0x74,
+    0x63, 0x32, 0x45, 0x78, 0x45, 0x44, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x73, 0x54, 0x42, 0x31, 0x4a, 0x76, 0x0a, 0x62, 0x33, 0x51,
+    0x67, 0x51, 0x30, 0x45, 0x78, 0x47, 0x7a, 0x41, 0x5a, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x4d, 0x54, 0x45, 0x6b, 0x64, 0x73, 0x62, 0x32, 0x4a,
+    0x68, 0x62, 0x46, 0x4e, 0x70, 0x5a, 0x32, 0x34, 0x67, 0x55, 0x6d, 0x39,
+    0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30,
+    0x35, 0x4f, 0x44, 0x41, 0x35, 0x4d, 0x44, 0x45, 0x78, 0x4d, 0x6a, 0x41,
+    0x77, 0x0a, 0x4d, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x79, 0x4f, 0x44,
+    0x41, 0x78, 0x4d, 0x6a, 0x67, 0x78, 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x44,
+    0x42, 0x61, 0x4d, 0x46, 0x63, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6b, 0x4a, 0x46, 0x4d, 0x52,
+    0x6b, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78,
+    0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x0a, 0x59, 0x57, 0x78, 0x54, 0x61,
+    0x57, 0x64, 0x75, 0x49, 0x47, 0x35, 0x32, 0x4c, 0x58, 0x4e, 0x68, 0x4d,
+    0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45,
+    0x77, 0x64, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4e, 0x42, 0x4d,
+    0x52, 0x73, 0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45,
+    0x78, 0x4a, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x54, 0x0a,
+    0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x67,
+    0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47,
+    0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42,
+    0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77,
+    0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x61,
+    0x44, 0x75, 0x61, 0x5a, 0x0a, 0x6a, 0x63, 0x36, 0x6a, 0x34, 0x30, 0x2b,
+    0x4b, 0x66, 0x76, 0x76, 0x78, 0x69, 0x34, 0x4d, 0x6c, 0x61, 0x2b, 0x70,
+    0x49, 0x48, 0x2f, 0x45, 0x71, 0x73, 0x4c, 0x6d, 0x56, 0x45, 0x51, 0x53,
+    0x39, 0x38, 0x47, 0x50, 0x52, 0x34, 0x6d, 0x64, 0x6d, 0x7a, 0x78, 0x7a,
+    0x64, 0x7a, 0x78, 0x74, 0x49, 0x4b, 0x2b, 0x36, 0x4e, 0x69, 0x59, 0x36,
+    0x61, 0x72, 0x79, 0x6d, 0x41, 0x5a, 0x61, 0x76, 0x70, 0x0a, 0x78, 0x79,
+    0x30, 0x53, 0x79, 0x36, 0x73, 0x63, 0x54, 0x48, 0x41, 0x48, 0x6f, 0x54,
+    0x30, 0x4b, 0x4d, 0x4d, 0x30, 0x56, 0x6a, 0x55, 0x2f, 0x34, 0x33, 0x64,
+    0x53, 0x4d, 0x55, 0x42, 0x55, 0x63, 0x37, 0x31, 0x44, 0x75, 0x78, 0x43,
+    0x37, 0x33, 0x2f, 0x4f, 0x6c, 0x53, 0x38, 0x70, 0x46, 0x39, 0x34, 0x47,
+    0x33, 0x56, 0x4e, 0x54, 0x43, 0x4f, 0x58, 0x6b, 0x4e, 0x7a, 0x38, 0x6b,
+    0x48, 0x70, 0x0a, 0x31, 0x57, 0x72, 0x6a, 0x73, 0x6f, 0x6b, 0x36, 0x56,
+    0x6a, 0x6b, 0x34, 0x62, 0x77, 0x59, 0x38, 0x69, 0x47, 0x6c, 0x62, 0x4b,
+    0x6b, 0x33, 0x46, 0x70, 0x31, 0x53, 0x34, 0x62, 0x49, 0x6e, 0x4d, 0x6d,
+    0x2f, 0x6b, 0x38, 0x79, 0x75, 0x58, 0x39, 0x69, 0x66, 0x55, 0x53, 0x50,
+    0x4a, 0x4a, 0x34, 0x6c, 0x74, 0x62, 0x63, 0x64, 0x47, 0x36, 0x54, 0x52,
+    0x47, 0x48, 0x52, 0x6a, 0x63, 0x64, 0x47, 0x0a, 0x73, 0x6e, 0x55, 0x4f,
+    0x68, 0x75, 0x67, 0x5a, 0x69, 0x74, 0x56, 0x74, 0x62, 0x4e, 0x56, 0x34,
+    0x46, 0x70, 0x57, 0x69, 0x36, 0x63, 0x67, 0x4b, 0x4f, 0x4f, 0x76, 0x79,
+    0x4a, 0x42, 0x4e, 0x50, 0x63, 0x31, 0x53, 0x54, 0x45, 0x34, 0x55, 0x36,
+    0x47, 0x37, 0x77, 0x65, 0x4e, 0x4c, 0x57, 0x4c, 0x42, 0x59, 0x79, 0x35,
+    0x64, 0x34, 0x75, 0x78, 0x32, 0x78, 0x38, 0x67, 0x6b, 0x61, 0x73, 0x4a,
+    0x0a, 0x55, 0x32, 0x36, 0x51, 0x7a, 0x6e, 0x73, 0x33, 0x64, 0x4c, 0x6c,
+    0x77, 0x52, 0x35, 0x45, 0x69, 0x55, 0x57, 0x4d, 0x57, 0x65, 0x61, 0x36,
+    0x78, 0x72, 0x6b, 0x45, 0x6d, 0x43, 0x4d, 0x67, 0x5a, 0x4b, 0x39, 0x46,
+    0x47, 0x71, 0x6b, 0x6a, 0x57, 0x5a, 0x43, 0x72, 0x58, 0x67, 0x7a, 0x54,
+    0x2f, 0x4c, 0x43, 0x72, 0x42, 0x62, 0x42, 0x6c, 0x44, 0x53, 0x67, 0x65,
+    0x46, 0x35, 0x39, 0x4e, 0x38, 0x0a, 0x39, 0x69, 0x46, 0x6f, 0x37, 0x2b,
+    0x72, 0x79, 0x55, 0x70, 0x39, 0x2f, 0x6b, 0x35, 0x44, 0x50, 0x41, 0x67,
+    0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x51, 0x6a, 0x42, 0x41, 0x4d, 0x41,
+    0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2f, 0x77,
+    0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, 0x50, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x0a, 0x42,
+    0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x42, 0x30, 0x47, 0x41,
+    0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x67, 0x65,
+    0x32, 0x59, 0x61, 0x52, 0x51, 0x32, 0x58, 0x79, 0x6f, 0x6c, 0x51, 0x4c,
+    0x33, 0x30, 0x45, 0x7a, 0x54, 0x53, 0x6f, 0x2f, 0x2f, 0x7a, 0x39, 0x53,
+    0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x0a, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43,
+    0x41, 0x51, 0x45, 0x41, 0x31, 0x6e, 0x50, 0x6e, 0x66, 0x45, 0x39, 0x32,
+    0x30, 0x49, 0x32, 0x2f, 0x37, 0x4c, 0x71, 0x69, 0x76, 0x6a, 0x54, 0x46,
+    0x4b, 0x44, 0x4b, 0x31, 0x66, 0x50, 0x78, 0x73, 0x6e, 0x43, 0x77, 0x72,
+    0x76, 0x51, 0x6d, 0x65, 0x55, 0x37, 0x39, 0x72, 0x58, 0x71, 0x6f, 0x52,
+    0x53, 0x4c, 0x62, 0x6c, 0x43, 0x4b, 0x4f, 0x7a, 0x0a, 0x79, 0x6a, 0x31,
+    0x68, 0x54, 0x64, 0x4e, 0x47, 0x43, 0x62, 0x4d, 0x2b, 0x77, 0x36, 0x44,
+    0x6a, 0x59, 0x31, 0x55, 0x62, 0x38, 0x72, 0x72, 0x76, 0x72, 0x54, 0x6e,
+    0x68, 0x51, 0x37, 0x6b, 0x34, 0x6f, 0x2b, 0x59, 0x76, 0x69, 0x69, 0x59,
+    0x37, 0x37, 0x36, 0x42, 0x51, 0x56, 0x76, 0x6e, 0x47, 0x43, 0x76, 0x30,
+    0x34, 0x7a, 0x63, 0x51, 0x4c, 0x63, 0x46, 0x47, 0x55, 0x6c, 0x35, 0x67,
+    0x45, 0x0a, 0x33, 0x38, 0x4e, 0x66, 0x6c, 0x4e, 0x55, 0x56, 0x79, 0x52,
+    0x52, 0x42, 0x6e, 0x4d, 0x52, 0x64, 0x64, 0x57, 0x51, 0x56, 0x44, 0x66,
+    0x39, 0x56, 0x4d, 0x4f, 0x79, 0x47, 0x6a, 0x2f, 0x38, 0x4e, 0x37, 0x79,
+    0x79, 0x35, 0x59, 0x30, 0x62, 0x32, 0x71, 0x76, 0x7a, 0x66, 0x76, 0x47,
+    0x6e, 0x39, 0x4c, 0x68, 0x4a, 0x49, 0x5a, 0x4a, 0x72, 0x67, 0x6c, 0x66,
+    0x43, 0x6d, 0x37, 0x79, 0x6d, 0x50, 0x0a, 0x41, 0x62, 0x45, 0x56, 0x74,
+    0x51, 0x77, 0x64, 0x70, 0x66, 0x35, 0x70, 0x4c, 0x47, 0x6b, 0x6b, 0x65,
+    0x42, 0x36, 0x7a, 0x70, 0x78, 0x78, 0x78, 0x59, 0x75, 0x37, 0x4b, 0x79,
+    0x4a, 0x65, 0x73, 0x46, 0x31, 0x32, 0x4b, 0x77, 0x76, 0x68, 0x48, 0x68,
+    0x6d, 0x34, 0x71, 0x78, 0x46, 0x59, 0x78, 0x6c, 0x64, 0x42, 0x6e, 0x69,
+    0x59, 0x55, 0x72, 0x2b, 0x57, 0x79, 0x6d, 0x58, 0x55, 0x61, 0x64, 0x0a,
+    0x44, 0x4b, 0x71, 0x43, 0x35, 0x4a, 0x6c, 0x52, 0x33, 0x58, 0x43, 0x33,
+    0x32, 0x31, 0x59, 0x39, 0x59, 0x65, 0x52, 0x71, 0x34, 0x56, 0x7a, 0x57,
+    0x39, 0x76, 0x34, 0x39, 0x33, 0x6b, 0x48, 0x4d, 0x42, 0x36, 0x35, 0x6a,
+    0x55, 0x72, 0x39, 0x54, 0x55, 0x2f, 0x51, 0x72, 0x36, 0x63, 0x66, 0x39,
+    0x74, 0x76, 0x65, 0x43, 0x58, 0x34, 0x58, 0x53, 0x51, 0x52, 0x6a, 0x62,
+    0x67, 0x62, 0x4d, 0x45, 0x0a, 0x48, 0x4d, 0x55, 0x66, 0x70, 0x49, 0x42,
+    0x76, 0x46, 0x53, 0x44, 0x4a, 0x33, 0x67, 0x79, 0x49, 0x43, 0x68, 0x33,
+    0x57, 0x5a, 0x6c, 0x58, 0x69, 0x2f, 0x45, 0x6a, 0x4a, 0x4b, 0x53, 0x5a,
+    0x70, 0x34, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49,
+    0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x6c,
+    0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x3d, 0x47,
+    0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x55,
+    0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x52, 0x32,
+    0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67,
+    0x6e, 0x20, 0x4f, 0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
+    0x67, 0x6e, 0x20, 0x4f, 0x55, 0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+    0x20, 0x2d, 0x20, 0x52, 0x32, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
+    0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d,
+    0x20, 0x52, 0x32, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61,
+    0x6c, 0x3a, 0x20, 0x34, 0x38, 0x33, 0x35, 0x37, 0x30, 0x33, 0x32, 0x37,
+    0x38, 0x34, 0x35, 0x39, 0x36, 0x38, 0x32, 0x38, 0x38, 0x35, 0x36, 0x35,
+    0x38, 0x31, 0x32, 0x35, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x39, 0x34, 0x3a, 0x31, 0x34, 0x3a, 0x37, 0x37, 0x3a, 0x37, 0x65, 0x3a,
+    0x33, 0x65, 0x3a, 0x35, 0x65, 0x3a, 0x66, 0x64, 0x3a, 0x38, 0x66, 0x3a,
+    0x33, 0x30, 0x3a, 0x62, 0x64, 0x3a, 0x34, 0x31, 0x3a, 0x62, 0x30, 0x3a,
+    0x63, 0x66, 0x3a, 0x65, 0x37, 0x3a, 0x64, 0x30, 0x3a, 0x33, 0x30, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x37, 0x35, 0x3a, 0x65,
+    0x30, 0x3a, 0x61, 0x62, 0x3a, 0x62, 0x36, 0x3a, 0x31, 0x33, 0x3a, 0x38,
+    0x35, 0x3a, 0x31, 0x32, 0x3a, 0x32, 0x37, 0x3a, 0x31, 0x63, 0x3a, 0x30,
+    0x34, 0x3a, 0x66, 0x38, 0x3a, 0x35, 0x66, 0x3a, 0x64, 0x64, 0x3a, 0x64,
+    0x65, 0x3a, 0x33, 0x38, 0x3a, 0x65, 0x34, 0x3a, 0x62, 0x37, 0x3a, 0x32,
+    0x34, 0x3a, 0x32, 0x65, 0x3a, 0x66, 0x65, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x61, 0x3a, 0x34, 0x32, 0x3a,
+    0x64, 0x64, 0x3a, 0x34, 0x31, 0x3a, 0x37, 0x34, 0x3a, 0x35, 0x66, 0x3a,
+    0x64, 0x30, 0x3a, 0x62, 0x38, 0x3a, 0x31, 0x65, 0x3a, 0x62, 0x39, 0x3a,
+    0x30, 0x32, 0x3a, 0x33, 0x36, 0x3a, 0x32, 0x63, 0x3a, 0x66, 0x39, 0x3a,
+    0x64, 0x38, 0x3a, 0x62, 0x66, 0x3a, 0x37, 0x31, 0x3a, 0x39, 0x64, 0x3a,
+    0x61, 0x31, 0x3a, 0x62, 0x64, 0x3a, 0x31, 0x62, 0x3a, 0x31, 0x65, 0x3a,
+    0x66, 0x63, 0x3a, 0x39, 0x34, 0x3a, 0x36, 0x66, 0x3a, 0x35, 0x62, 0x3a,
+    0x34, 0x63, 0x3a, 0x39, 0x39, 0x3a, 0x66, 0x34, 0x3a, 0x32, 0x63, 0x3a,
+    0x31, 0x62, 0x3a, 0x39, 0x65, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42,
+    0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49,
+    0x49, 0x44, 0x75, 0x6a, 0x43, 0x43, 0x41, 0x71, 0x4b, 0x67, 0x41, 0x77,
+    0x49, 0x42, 0x41, 0x67, 0x49, 0x4c, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41,
+    0x41, 0x42, 0x44, 0x34, 0x59, 0x6d, 0x35, 0x67, 0x30, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x54, 0x44, 0x45, 0x67, 0x4d, 0x42,
+    0x34, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x58, 0x52,
+    0x32, 0x78, 0x76, 0x59, 0x6d, 0x46, 0x73, 0x55, 0x32, 0x6c, 0x6e, 0x62,
+    0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4e, 0x42, 0x49,
+    0x43, 0x30, 0x67, 0x55, 0x6a, 0x49, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x43, 0x6b, 0x64, 0x73, 0x62,
+    0x32, 0x4a, 0x68, 0x62, 0x46, 0x4e, 0x70, 0x0a, 0x5a, 0x32, 0x34, 0x78,
+    0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54,
+    0x43, 0x6b, 0x64, 0x73, 0x62, 0x32, 0x4a, 0x68, 0x62, 0x46, 0x4e, 0x70,
+    0x5a, 0x32, 0x34, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x59, 0x78,
+    0x4d, 0x6a, 0x45, 0x31, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x44, 0x41, 0x77,
+    0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x45, 0x78, 0x4d, 0x6a, 0x45, 0x31,
+    0x0a, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x6a, 0x42,
+    0x4d, 0x4d, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4c, 0x45, 0x78, 0x64, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78,
+    0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51,
+    0x67, 0x51, 0x30, 0x45, 0x67, 0x4c, 0x53, 0x42, 0x53, 0x4d, 0x6a, 0x45,
+    0x54, 0x4d, 0x42, 0x45, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4b, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d, 0x46, 0x73, 0x55, 0x32,
+    0x6c, 0x6e, 0x62, 0x6a, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x41, 0x78, 0x4d, 0x4b, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d,
+    0x46, 0x73, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x6a, 0x43, 0x43, 0x41, 0x53,
+    0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x0a, 0x68,
+    0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67,
+    0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67,
+    0x67, 0x45, 0x42, 0x41, 0x4b, 0x62, 0x50, 0x4a, 0x41, 0x36, 0x2b, 0x4c,
+    0x6d, 0x38, 0x6f, 0x6d, 0x55, 0x56, 0x43, 0x78, 0x4b, 0x73, 0x2b, 0x49,
+    0x56, 0x53, 0x62, 0x43, 0x39, 0x4e, 0x2f, 0x68, 0x48, 0x44, 0x36, 0x45,
+    0x72, 0x50, 0x4c, 0x0a, 0x76, 0x34, 0x64, 0x66, 0x78, 0x6e, 0x2b, 0x47,
+    0x30, 0x37, 0x49, 0x77, 0x58, 0x4e, 0x62, 0x39, 0x72, 0x66, 0x46, 0x37,
+    0x33, 0x4f, 0x58, 0x34, 0x59, 0x4a, 0x59, 0x4a, 0x6b, 0x68, 0x44, 0x31,
+    0x30, 0x46, 0x50, 0x65, 0x2b, 0x33, 0x74, 0x2b, 0x63, 0x34, 0x69, 0x73,
+    0x55, 0x6f, 0x68, 0x37, 0x53, 0x71, 0x62, 0x4b, 0x53, 0x61, 0x5a, 0x65,
+    0x71, 0x4b, 0x65, 0x4d, 0x57, 0x68, 0x47, 0x38, 0x0a, 0x65, 0x6f, 0x4c,
+    0x72, 0x76, 0x6f, 0x7a, 0x70, 0x73, 0x36, 0x79, 0x57, 0x4a, 0x51, 0x65,
+    0x58, 0x53, 0x70, 0x6b, 0x71, 0x42, 0x79, 0x2b, 0x30, 0x48, 0x6e, 0x65,
+    0x2f, 0x69, 0x67, 0x2b, 0x31, 0x41, 0x6e, 0x77, 0x62, 0x6c, 0x72, 0x6a,
+    0x46, 0x75, 0x54, 0x6f, 0x73, 0x76, 0x4e, 0x59, 0x53, 0x75, 0x65, 0x74,
+    0x5a, 0x66, 0x65, 0x4c, 0x51, 0x42, 0x6f, 0x5a, 0x66, 0x58, 0x6b, 0x6c,
+    0x71, 0x0a, 0x74, 0x54, 0x6c, 0x65, 0x69, 0x44, 0x54, 0x73, 0x76, 0x48,
+    0x67, 0x4d, 0x43, 0x4a, 0x69, 0x45, 0x62, 0x4b, 0x6a, 0x4e, 0x53, 0x37,
+    0x53, 0x67, 0x66, 0x51, 0x78, 0x35, 0x54, 0x66, 0x43, 0x34, 0x4c, 0x63,
+    0x73, 0x68, 0x79, 0x74, 0x56, 0x73, 0x57, 0x33, 0x33, 0x68, 0x6f, 0x43,
+    0x6d, 0x45, 0x6f, 0x66, 0x6e, 0x54, 0x6c, 0x45, 0x6e, 0x4c, 0x4a, 0x47,
+    0x4b, 0x52, 0x49, 0x4c, 0x7a, 0x64, 0x0a, 0x43, 0x39, 0x58, 0x5a, 0x7a,
+    0x50, 0x6e, 0x71, 0x4a, 0x77, 0x6f, 0x72, 0x63, 0x35, 0x48, 0x47, 0x6e,
+    0x52, 0x75, 0x73, 0x79, 0x4d, 0x76, 0x6f, 0x34, 0x4b, 0x44, 0x30, 0x4c,
+    0x35, 0x43, 0x4c, 0x54, 0x66, 0x75, 0x77, 0x4e, 0x68, 0x76, 0x32, 0x47,
+    0x58, 0x71, 0x46, 0x34, 0x47, 0x33, 0x79, 0x59, 0x52, 0x4f, 0x49, 0x58,
+    0x4a, 0x2f, 0x67, 0x6b, 0x77, 0x70, 0x52, 0x6c, 0x34, 0x70, 0x61, 0x0a,
+    0x7a, 0x71, 0x2b, 0x72, 0x31, 0x66, 0x65, 0x71, 0x43, 0x61, 0x70, 0x67,
+    0x76, 0x64, 0x7a, 0x5a, 0x58, 0x39, 0x39, 0x79, 0x71, 0x57, 0x41, 0x54,
+    0x58, 0x67, 0x41, 0x42, 0x79, 0x55, 0x72, 0x36, 0x50, 0x36, 0x54, 0x71,
+    0x42, 0x77, 0x4d, 0x68, 0x41, 0x6f, 0x36, 0x43, 0x79, 0x67, 0x50, 0x43,
+    0x6d, 0x34, 0x38, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4f, 0x42,
+    0x6e, 0x44, 0x43, 0x42, 0x0a, 0x6d, 0x54, 0x41, 0x4f, 0x42, 0x67, 0x4e,
+    0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d,
+    0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45,
+    0x42, 0x2f, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34,
+    0x45, 0x46, 0x67, 0x51, 0x55, 0x6d, 0x2b, 0x49, 0x48, 0x0a, 0x56, 0x32,
+    0x63, 0x63, 0x48, 0x73, 0x42, 0x71, 0x42, 0x74, 0x35, 0x5a, 0x74, 0x4a,
+    0x6f, 0x74, 0x33, 0x39, 0x77, 0x5a, 0x68, 0x69, 0x34, 0x77, 0x4e, 0x67,
+    0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x43, 0x38, 0x77, 0x4c, 0x54,
+    0x41, 0x72, 0x6f, 0x43, 0x6d, 0x67, 0x4a, 0x34, 0x59, 0x6c, 0x61, 0x48,
+    0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32, 0x4e, 0x79, 0x62, 0x43,
+    0x35, 0x6e, 0x0a, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78, 0x7a, 0x61,
+    0x57, 0x64, 0x75, 0x4c, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x39, 0x79, 0x62,
+    0x32, 0x39, 0x30, 0x4c, 0x58, 0x49, 0x79, 0x4c, 0x6d, 0x4e, 0x79, 0x62,
+    0x44, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47,
+    0x44, 0x41, 0x57, 0x67, 0x42, 0x53, 0x62, 0x34, 0x67, 0x64, 0x58, 0x5a,
+    0x78, 0x77, 0x65, 0x77, 0x47, 0x6f, 0x47, 0x0a, 0x33, 0x6c, 0x6d, 0x30,
+    0x6d, 0x69, 0x33, 0x66, 0x33, 0x42, 0x6d, 0x47, 0x4c, 0x6a, 0x41, 0x4e,
+    0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
+    0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41,
+    0x6d, 0x59, 0x46, 0x54, 0x68, 0x78, 0x78, 0x6f, 0x6c, 0x34, 0x61, 0x52,
+    0x37, 0x4f, 0x42, 0x4b, 0x75, 0x45, 0x51, 0x4c, 0x71, 0x34, 0x47, 0x73,
+    0x0a, 0x4a, 0x30, 0x2f, 0x57, 0x77, 0x62, 0x67, 0x63, 0x51, 0x33, 0x69,
+    0x7a, 0x44, 0x4a, 0x72, 0x38, 0x36, 0x69, 0x77, 0x38, 0x62, 0x6d, 0x45,
+    0x62, 0x54, 0x55, 0x73, 0x70, 0x39, 0x5a, 0x38, 0x46, 0x48, 0x53, 0x62,
+    0x42, 0x75, 0x4f, 0x6d, 0x44, 0x41, 0x47, 0x4a, 0x46, 0x74, 0x71, 0x6b,
+    0x49, 0x6b, 0x37, 0x6d, 0x70, 0x4d, 0x30, 0x73, 0x59, 0x6d, 0x73, 0x4c,
+    0x34, 0x68, 0x34, 0x68, 0x4f, 0x0a, 0x32, 0x39, 0x31, 0x78, 0x4e, 0x42,
+    0x72, 0x42, 0x56, 0x4e, 0x70, 0x47, 0x50, 0x2b, 0x44, 0x54, 0x4b, 0x71,
+    0x74, 0x74, 0x56, 0x43, 0x4c, 0x31, 0x4f, 0x6d, 0x4c, 0x4e, 0x49, 0x47,
+    0x2b, 0x36, 0x4b, 0x59, 0x6e, 0x58, 0x33, 0x5a, 0x48, 0x75, 0x30, 0x31,
+    0x79, 0x69, 0x50, 0x71, 0x46, 0x62, 0x51, 0x66, 0x58, 0x66, 0x35, 0x57,
+    0x52, 0x44, 0x4c, 0x65, 0x6e, 0x56, 0x4f, 0x61, 0x76, 0x53, 0x0a, 0x6f,
+    0x74, 0x2b, 0x33, 0x69, 0x39, 0x44, 0x41, 0x67, 0x42, 0x6b, 0x63, 0x52,
+    0x63, 0x41, 0x74, 0x6a, 0x4f, 0x6a, 0x34, 0x4c, 0x61, 0x52, 0x30, 0x56,
+    0x6b, 0x6e, 0x46, 0x42, 0x62, 0x56, 0x50, 0x46, 0x64, 0x35, 0x75, 0x52,
+    0x48, 0x67, 0x35, 0x68, 0x36, 0x68, 0x2b, 0x75, 0x2f, 0x4e, 0x35, 0x47,
+    0x4a, 0x47, 0x37, 0x39, 0x47, 0x2b, 0x64, 0x77, 0x66, 0x43, 0x4d, 0x4e,
+    0x59, 0x78, 0x64, 0x0a, 0x41, 0x66, 0x76, 0x44, 0x62, 0x62, 0x6e, 0x76,
+    0x52, 0x47, 0x31, 0x35, 0x52, 0x6a, 0x46, 0x2b, 0x43, 0x76, 0x36, 0x70,
+    0x67, 0x73, 0x48, 0x2f, 0x37, 0x36, 0x74, 0x75, 0x49, 0x4d, 0x52, 0x51,
+    0x79, 0x56, 0x2b, 0x64, 0x54, 0x5a, 0x73, 0x58, 0x6a, 0x41, 0x7a, 0x6c,
+    0x41, 0x63, 0x6d, 0x67, 0x51, 0x57, 0x70, 0x7a, 0x55, 0x2f, 0x71, 0x6c,
+    0x55, 0x4c, 0x52, 0x75, 0x4a, 0x51, 0x2f, 0x37, 0x0a, 0x54, 0x42, 0x6a,
+    0x30, 0x2f, 0x56, 0x4c, 0x5a, 0x6a, 0x6d, 0x6d, 0x78, 0x36, 0x42, 0x45,
+    0x50, 0x33, 0x6f, 0x6a, 0x59, 0x2b, 0x78, 0x31, 0x4a, 0x39, 0x36, 0x72,
+    0x65, 0x6c, 0x63, 0x38, 0x67, 0x65, 0x4d, 0x4a, 0x67, 0x45, 0x74, 0x73,
+    0x6c, 0x51, 0x49, 0x78, 0x71, 0x2f, 0x48, 0x35, 0x43, 0x4f, 0x45, 0x42,
+    0x6b, 0x45, 0x76, 0x65, 0x65, 0x67, 0x65, 0x47, 0x54, 0x4c, 0x67, 0x3d,
+    0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+    0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x63, 0x65, 0x72,
+    0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x20, 0x4f, 0x3d, 0x56, 0x61, 0x6c,
+    0x69, 0x43, 0x65, 0x72, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
+    0x4f, 0x55, 0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20,
+    0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20, 0x50, 0x6f, 0x6c, 0x69,
+    0x63, 0x79, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a,
+    0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+    0x2e, 0x76, 0x61, 0x6c, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
+    0x6d, 0x2f, 0x20, 0x4f, 0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65, 0x72,
+    0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56,
+    0x61, 0x6c, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x43, 0x6c, 0x61, 0x73,
+    0x73, 0x20, 0x31, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x56,
+    0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61,
+    0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65,
+    0x72, 0x74, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20, 0x56,
+    0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a,
+    0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x36, 0x35,
+    0x3a, 0x35, 0x38, 0x3a, 0x61, 0x62, 0x3a, 0x31, 0x35, 0x3a, 0x61, 0x64,
+    0x3a, 0x35, 0x37, 0x3a, 0x36, 0x63, 0x3a, 0x31, 0x65, 0x3a, 0x61, 0x38,
+    0x3a, 0x61, 0x37, 0x3a, 0x62, 0x35, 0x3a, 0x36, 0x39, 0x3a, 0x61, 0x63,
+    0x3a, 0x62, 0x66, 0x3a, 0x66, 0x66, 0x3a, 0x65, 0x62, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x65, 0x35, 0x3a, 0x64, 0x66, 0x3a,
+    0x37, 0x34, 0x3a, 0x33, 0x63, 0x3a, 0x62, 0x36, 0x3a, 0x30, 0x31, 0x3a,
+    0x63, 0x34, 0x3a, 0x39, 0x62, 0x3a, 0x39, 0x38, 0x3a, 0x34, 0x33, 0x3a,
+    0x64, 0x63, 0x3a, 0x61, 0x62, 0x3a, 0x38, 0x63, 0x3a, 0x65, 0x38, 0x3a,
+    0x36, 0x61, 0x3a, 0x38, 0x31, 0x3a, 0x31, 0x30, 0x3a, 0x39, 0x66, 0x3a,
+    0x65, 0x34, 0x3a, 0x38, 0x65, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32,
+    0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x66, 0x34, 0x3a, 0x63, 0x31, 0x3a, 0x34, 0x39,
+    0x3a, 0x35, 0x35, 0x3a, 0x31, 0x61, 0x3a, 0x33, 0x30, 0x3a, 0x31, 0x33,
+    0x3a, 0x61, 0x33, 0x3a, 0x35, 0x62, 0x3a, 0x63, 0x37, 0x3a, 0x62, 0x66,
+    0x3a, 0x66, 0x65, 0x3a, 0x31, 0x37, 0x3a, 0x61, 0x37, 0x3a, 0x66, 0x33,
+    0x3a, 0x34, 0x34, 0x3a, 0x39, 0x62, 0x3a, 0x63, 0x31, 0x3a, 0x61, 0x62,
+    0x3a, 0x35, 0x62, 0x3a, 0x35, 0x61, 0x3a, 0x30, 0x61, 0x3a, 0x65, 0x37,
+    0x3a, 0x34, 0x62, 0x3a, 0x30, 0x36, 0x3a, 0x63, 0x32, 0x3a, 0x33, 0x62,
+    0x3a, 0x39, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x34, 0x63, 0x3a, 0x30, 0x31,
+    0x3a, 0x30, 0x34, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47,
+    0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
+    0x35, 0x7a, 0x43, 0x43, 0x41, 0x6c, 0x41, 0x43, 0x41, 0x51, 0x45, 0x77,
+    0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e,
+    0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x67, 0x62, 0x73, 0x78,
+    0x4a, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54,
+    0x47, 0x31, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30,
+    0x0a, 0x49, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52,
+    0x70, 0x62, 0x32, 0x34, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39,
+    0x79, 0x61, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x46, 0x73, 0x61, 0x55, 0x4e,
+    0x6c, 0x63, 0x6e, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34,
+    0x78, 0x4e, 0x54, 0x41, 0x7a, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x73, 0x54, 0x4c, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44,
+    0x45, 0x67, 0x55, 0x47, 0x39, 0x73, 0x61, 0x57, 0x4e, 0x35, 0x49, 0x46,
+    0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32,
+    0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x0a, 0x61,
+    0x58, 0x52, 0x35, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x44, 0x45, 0x78, 0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f,
+    0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x5a, 0x68, 0x62,
+    0x47, 0x6c, 0x6a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6d, 0x4e, 0x76, 0x62,
+    0x53, 0x38, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x0a, 0x39, 0x77, 0x30, 0x42, 0x43, 0x51, 0x45, 0x57,
+    0x45, 0x57, 0x6c, 0x75, 0x5a, 0x6d, 0x39, 0x41, 0x64, 0x6d, 0x46, 0x73,
+    0x61, 0x57, 0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74,
+    0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x6b, 0x35, 0x4d, 0x44, 0x59, 0x79,
+    0x4e, 0x54, 0x49, 0x79, 0x4d, 0x6a, 0x4d, 0x30, 0x4f, 0x46, 0x6f, 0x58,
+    0x44, 0x54, 0x45, 0x35, 0x4d, 0x44, 0x59, 0x79, 0x0a, 0x4e, 0x54, 0x49,
+    0x79, 0x4d, 0x6a, 0x4d, 0x30, 0x4f, 0x46, 0x6f, 0x77, 0x67, 0x62, 0x73,
+    0x78, 0x4a, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63,
+    0x54, 0x47, 0x31, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a,
+    0x30, 0x49, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52,
+    0x70, 0x62, 0x32, 0x34, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39,
+    0x79, 0x0a, 0x61, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x46, 0x73, 0x61, 0x55,
+    0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79,
+    0x34, 0x78, 0x4e, 0x54, 0x41, 0x7a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x73, 0x54, 0x4c, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x49, 0x45, 0x4e, 0x73, 0x0a, 0x59, 0x58, 0x4e, 0x7a, 0x49,
+    0x44, 0x45, 0x67, 0x55, 0x47, 0x39, 0x73, 0x61, 0x57, 0x4e, 0x35, 0x49,
+    0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62,
+    0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61,
+    0x58, 0x52, 0x35, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x44, 0x45, 0x78, 0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x0a,
+    0x4f, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x5a, 0x68,
+    0x62, 0x47, 0x6c, 0x6a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6d, 0x4e, 0x76,
+    0x62, 0x53, 0x38, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x6b, 0x71,
+    0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x43, 0x51, 0x45, 0x57,
+    0x45, 0x57, 0x6c, 0x75, 0x5a, 0x6d, 0x39, 0x41, 0x64, 0x6d, 0x46, 0x73,
+    0x61, 0x57, 0x4e, 0x6c, 0x0a, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39,
+    0x74, 0x4d, 0x49, 0x47, 0x66, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71,
+    0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55,
+    0x41, 0x41, 0x34, 0x47, 0x4e, 0x41, 0x44, 0x43, 0x42, 0x69, 0x51, 0x4b,
+    0x42, 0x67, 0x51, 0x44, 0x59, 0x57, 0x59, 0x4a, 0x36, 0x69, 0x62, 0x69,
+    0x57, 0x75, 0x71, 0x59, 0x76, 0x61, 0x47, 0x39, 0x59, 0x0a, 0x4c, 0x71,
+    0x64, 0x55, 0x48, 0x41, 0x5a, 0x75, 0x39, 0x4f, 0x71, 0x4e, 0x53, 0x4c,
+    0x77, 0x78, 0x6c, 0x42, 0x66, 0x77, 0x38, 0x30, 0x36, 0x38, 0x73, 0x72,
+    0x67, 0x31, 0x6b, 0x6e, 0x61, 0x77, 0x30, 0x4b, 0x57, 0x6c, 0x41, 0x64,
+    0x63, 0x41, 0x41, 0x78, 0x49, 0x69, 0x47, 0x51, 0x6a, 0x34, 0x2f, 0x78,
+    0x45, 0x6a, 0x6d, 0x38, 0x34, 0x48, 0x39, 0x62, 0x39, 0x70, 0x47, 0x69,
+    0x62, 0x2b, 0x0a, 0x54, 0x75, 0x6e, 0x52, 0x66, 0x35, 0x30, 0x73, 0x51,
+    0x42, 0x31, 0x5a, 0x61, 0x47, 0x36, 0x6d, 0x2b, 0x46, 0x69, 0x77, 0x6e,
+    0x52, 0x71, 0x50, 0x30, 0x7a, 0x2f, 0x78, 0x33, 0x42, 0x6b, 0x47, 0x67,
+    0x61, 0x67, 0x4f, 0x34, 0x44, 0x72, 0x64, 0x79, 0x46, 0x4e, 0x46, 0x43,
+    0x51, 0x62, 0x6d, 0x44, 0x33, 0x44, 0x44, 0x2b, 0x6b, 0x43, 0x6d, 0x44,
+    0x75, 0x4a, 0x57, 0x42, 0x51, 0x38, 0x59, 0x0a, 0x54, 0x66, 0x77, 0x67,
+    0x67, 0x74, 0x46, 0x7a, 0x56, 0x58, 0x53, 0x4e, 0x64, 0x6e, 0x4b, 0x67,
+    0x48, 0x5a, 0x30, 0x64, 0x77, 0x4e, 0x30, 0x2f, 0x63, 0x51, 0x49, 0x44,
+    0x41, 0x51, 0x41, 0x42, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47,
+    0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41,
+    0x41, 0x34, 0x47, 0x42, 0x41, 0x46, 0x42, 0x6f, 0x50, 0x55, 0x6e, 0x30,
+    0x0a, 0x4c, 0x42, 0x77, 0x47, 0x6c, 0x4e, 0x2b, 0x56, 0x59, 0x48, 0x2b,
+    0x57, 0x65, 0x78, 0x66, 0x2b, 0x54, 0x33, 0x47, 0x74, 0x5a, 0x4d, 0x6a,
+    0x64, 0x64, 0x39, 0x4c, 0x76, 0x57, 0x56, 0x58, 0x6f, 0x50, 0x2b, 0x69,
+    0x4f, 0x42, 0x53, 0x6f, 0x68, 0x38, 0x67, 0x66, 0x53, 0x74, 0x61, 0x64,
+    0x53, 0x2f, 0x70, 0x79, 0x78, 0x74, 0x75, 0x4a, 0x62, 0x64, 0x78, 0x64,
+    0x41, 0x36, 0x6e, 0x4c, 0x57, 0x0a, 0x49, 0x38, 0x73, 0x6f, 0x67, 0x54,
+    0x4c, 0x44, 0x41, 0x48, 0x6b, 0x59, 0x37, 0x46, 0x6b, 0x58, 0x69, 0x63,
+    0x6e, 0x47, 0x61, 0x68, 0x35, 0x78, 0x79, 0x66, 0x32, 0x33, 0x64, 0x4b,
+    0x55, 0x6c, 0x52, 0x57, 0x6e, 0x46, 0x53, 0x4b, 0x73, 0x5a, 0x34, 0x55,
+    0x57, 0x4b, 0x4a, 0x57, 0x73, 0x5a, 0x37, 0x75, 0x57, 0x37, 0x45, 0x76,
+    0x56, 0x2f, 0x39, 0x36, 0x61, 0x4e, 0x55, 0x63, 0x50, 0x77, 0x0a, 0x6e,
+    0x58, 0x53, 0x33, 0x71, 0x54, 0x36, 0x67, 0x70, 0x66, 0x2b, 0x32, 0x53,
+    0x51, 0x4d, 0x54, 0x32, 0x69, 0x4c, 0x4d, 0x37, 0x58, 0x47, 0x43, 0x4b,
+    0x35, 0x6e, 0x50, 0x4f, 0x72, 0x66, 0x31, 0x4c, 0x58, 0x4c, 0x49, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a,
+    0x20, 0x43, 0x4e, 0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+    0x77, 0x77, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+    0x63, 0x6f, 0x6d, 0x2f, 0x20, 0x4f, 0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43,
+    0x65, 0x72, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55,
+    0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x43, 0x6c,
+    0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79,
+    0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20,
+    0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76,
+    0x61, 0x6c, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x20, 0x4f, 0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x61, 0x6c,
+    0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x32, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x56, 0x61, 0x6c,
+    0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65, 0x72, 0x74,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x56, 0x41, 0x22,
+    0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31,
+    0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x39, 0x3a, 0x32,
+    0x33, 0x3a, 0x37, 0x35, 0x3a, 0x39, 0x62, 0x3a, 0x62, 0x61, 0x3a, 0x34,
+    0x39, 0x3a, 0x33, 0x36, 0x3a, 0x36, 0x65, 0x3a, 0x33, 0x31, 0x3a, 0x63,
+    0x32, 0x3a, 0x64, 0x62, 0x3a, 0x66, 0x32, 0x3a, 0x65, 0x37, 0x3a, 0x36,
+    0x36, 0x3a, 0x62, 0x61, 0x3a, 0x38, 0x37, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x33, 0x31, 0x3a, 0x37, 0x61, 0x3a, 0x32, 0x61,
+    0x3a, 0x64, 0x30, 0x3a, 0x37, 0x66, 0x3a, 0x32, 0x62, 0x3a, 0x33, 0x33,
+    0x3a, 0x35, 0x65, 0x3a, 0x66, 0x35, 0x3a, 0x61, 0x31, 0x3a, 0x63, 0x33,
+    0x3a, 0x34, 0x65, 0x3a, 0x34, 0x62, 0x3a, 0x35, 0x37, 0x3a, 0x65, 0x38,
+    0x3a, 0x62, 0x37, 0x3a, 0x64, 0x38, 0x3a, 0x66, 0x31, 0x3a, 0x66, 0x63,
+    0x3a, 0x61, 0x36, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x35, 0x38, 0x3a, 0x64, 0x30, 0x3a, 0x31, 0x37, 0x3a, 0x32,
+    0x37, 0x3a, 0x39, 0x63, 0x3a, 0x64, 0x34, 0x3a, 0x64, 0x63, 0x3a, 0x36,
+    0x33, 0x3a, 0x61, 0x62, 0x3a, 0x64, 0x64, 0x3a, 0x62, 0x31, 0x3a, 0x39,
+    0x36, 0x3a, 0x61, 0x36, 0x3a, 0x63, 0x39, 0x3a, 0x39, 0x30, 0x3a, 0x36,
+    0x63, 0x3a, 0x33, 0x30, 0x3a, 0x63, 0x34, 0x3a, 0x65, 0x30, 0x3a, 0x38,
+    0x37, 0x3a, 0x38, 0x33, 0x3a, 0x65, 0x61, 0x3a, 0x65, 0x38, 0x3a, 0x63,
+    0x31, 0x3a, 0x36, 0x30, 0x3a, 0x39, 0x39, 0x3a, 0x35, 0x34, 0x3a, 0x64,
+    0x36, 0x3a, 0x39, 0x33, 0x3a, 0x35, 0x35, 0x3a, 0x35, 0x39, 0x3a, 0x36,
+    0x62, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x35, 0x7a,
+    0x43, 0x43, 0x41, 0x6c, 0x41, 0x43, 0x41, 0x51, 0x45, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x67, 0x62, 0x73, 0x78, 0x4a, 0x44,
+    0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x47, 0x31,
+    0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x0a, 0x49,
+    0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62,
+    0x32, 0x34, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79, 0x61,
+    0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x46, 0x73, 0x61, 0x55, 0x4e, 0x6c, 0x63,
+    0x6e, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4e,
+    0x54, 0x41, 0x7a, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54,
+    0x4c, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30,
+    0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44, 0x49, 0x67,
+    0x55, 0x47, 0x39, 0x73, 0x61, 0x57, 0x4e, 0x35, 0x49, 0x46, 0x5a, 0x68,
+    0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67,
+    0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x0a, 0x61, 0x58, 0x52,
+    0x35, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x44, 0x45, 0x78, 0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38,
+    0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x5a, 0x68, 0x62, 0x47, 0x6c,
+    0x6a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x38,
+    0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x0a, 0x39, 0x77, 0x30, 0x42, 0x43, 0x51, 0x45, 0x57, 0x45, 0x57,
+    0x6c, 0x75, 0x5a, 0x6d, 0x39, 0x41, 0x64, 0x6d, 0x46, 0x73, 0x61, 0x57,
+    0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x42,
+    0x34, 0x58, 0x44, 0x54, 0x6b, 0x35, 0x4d, 0x44, 0x59, 0x79, 0x4e, 0x6a,
+    0x41, 0x77, 0x4d, 0x54, 0x6b, 0x31, 0x4e, 0x46, 0x6f, 0x58, 0x44, 0x54,
+    0x45, 0x35, 0x4d, 0x44, 0x59, 0x79, 0x0a, 0x4e, 0x6a, 0x41, 0x77, 0x4d,
+    0x54, 0x6b, 0x31, 0x4e, 0x46, 0x6f, 0x77, 0x67, 0x62, 0x73, 0x78, 0x4a,
+    0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x47,
+    0x31, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x49,
+    0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62,
+    0x32, 0x34, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79, 0x0a,
+    0x61, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x46, 0x73, 0x61, 0x55, 0x4e, 0x6c,
+    0x63, 0x6e, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78,
+    0x4e, 0x54, 0x41, 0x7a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54,
+    0x4c, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30,
+    0x49, 0x45, 0x4e, 0x73, 0x0a, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44, 0x49,
+    0x67, 0x55, 0x47, 0x39, 0x73, 0x61, 0x57, 0x4e, 0x35, 0x49, 0x46, 0x5a,
+    0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34,
+    0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52,
+    0x35, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x44, 0x45, 0x78, 0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x0a, 0x4f, 0x69,
+    0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x5a, 0x68, 0x62, 0x47,
+    0x6c, 0x6a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53,
+    0x38, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x43, 0x51, 0x45, 0x57, 0x45, 0x57,
+    0x6c, 0x75, 0x5a, 0x6d, 0x39, 0x41, 0x64, 0x6d, 0x46, 0x73, 0x61, 0x57,
+    0x4e, 0x6c, 0x0a, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d,
+    0x49, 0x47, 0x66, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53,
+    0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41,
+    0x34, 0x47, 0x4e, 0x41, 0x44, 0x43, 0x42, 0x69, 0x51, 0x4b, 0x42, 0x67,
+    0x51, 0x44, 0x4f, 0x4f, 0x6e, 0x48, 0x4b, 0x35, 0x61, 0x76, 0x49, 0x57,
+    0x5a, 0x4a, 0x56, 0x31, 0x36, 0x76, 0x59, 0x0a, 0x64, 0x41, 0x37, 0x35,
+    0x37, 0x74, 0x6e, 0x32, 0x56, 0x55, 0x64, 0x5a, 0x5a, 0x55, 0x63, 0x4f,
+    0x42, 0x56, 0x58, 0x63, 0x36, 0x35, 0x67, 0x32, 0x50, 0x46, 0x78, 0x54,
+    0x58, 0x64, 0x4d, 0x77, 0x7a, 0x7a, 0x6a, 0x73, 0x76, 0x55, 0x47, 0x4a,
+    0x37, 0x53, 0x56, 0x43, 0x43, 0x53, 0x52, 0x72, 0x43, 0x6c, 0x36, 0x7a,
+    0x66, 0x4e, 0x31, 0x53, 0x4c, 0x55, 0x7a, 0x6d, 0x31, 0x4e, 0x5a, 0x39,
+    0x0a, 0x57, 0x6c, 0x6d, 0x70, 0x5a, 0x64, 0x52, 0x4a, 0x45, 0x79, 0x30,
+    0x6b, 0x54, 0x52, 0x78, 0x51, 0x62, 0x37, 0x58, 0x42, 0x68, 0x56, 0x51,
+    0x37, 0x2f, 0x6e, 0x48, 0x6b, 0x30, 0x31, 0x78, 0x43, 0x2b, 0x59, 0x44,
+    0x67, 0x6b, 0x52, 0x6f, 0x4b, 0x57, 0x7a, 0x6b, 0x32, 0x5a, 0x2f, 0x4d,
+    0x2f, 0x56, 0x58, 0x77, 0x62, 0x50, 0x37, 0x52, 0x66, 0x5a, 0x48, 0x4d,
+    0x30, 0x34, 0x37, 0x51, 0x53, 0x0a, 0x76, 0x34, 0x64, 0x6b, 0x2b, 0x4e,
+    0x6f, 0x53, 0x2f, 0x7a, 0x63, 0x6e, 0x77, 0x62, 0x4e, 0x44, 0x75, 0x2b,
+    0x39, 0x37, 0x62, 0x69, 0x35, 0x70, 0x39, 0x77, 0x49, 0x44, 0x41, 0x51,
+    0x41, 0x42, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
+    0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34,
+    0x47, 0x42, 0x41, 0x44, 0x74, 0x2f, 0x55, 0x47, 0x39, 0x76, 0x0a, 0x55,
+    0x4a, 0x53, 0x5a, 0x53, 0x57, 0x49, 0x34, 0x4f, 0x42, 0x39, 0x4c, 0x2b,
+    0x4b, 0x58, 0x49, 0x50, 0x71, 0x65, 0x43, 0x67, 0x66, 0x59, 0x72, 0x78,
+    0x2b, 0x6a, 0x46, 0x7a, 0x75, 0x67, 0x36, 0x45, 0x49, 0x4c, 0x4c, 0x47,
+    0x41, 0x43, 0x4f, 0x54, 0x62, 0x32, 0x6f, 0x57, 0x48, 0x2b, 0x68, 0x65,
+    0x51, 0x43, 0x31, 0x75, 0x2b, 0x6d, 0x4e, 0x72, 0x30, 0x48, 0x5a, 0x44,
+    0x7a, 0x54, 0x75, 0x0a, 0x49, 0x59, 0x45, 0x5a, 0x6f, 0x44, 0x4a, 0x4a,
+    0x4b, 0x50, 0x54, 0x45, 0x6a, 0x6c, 0x62, 0x56, 0x55, 0x6a, 0x50, 0x39,
+    0x55, 0x4e, 0x56, 0x2b, 0x6d, 0x57, 0x77, 0x44, 0x35, 0x4d, 0x6c, 0x4d,
+    0x2f, 0x4d, 0x74, 0x73, 0x71, 0x32, 0x61, 0x7a, 0x53, 0x69, 0x47, 0x4d,
+    0x35, 0x62, 0x55, 0x4d, 0x4d, 0x6a, 0x34, 0x51, 0x73, 0x73, 0x78, 0x73,
+    0x6f, 0x64, 0x79, 0x61, 0x6d, 0x45, 0x77, 0x43, 0x0a, 0x57, 0x2f, 0x50,
+    0x4f, 0x75, 0x5a, 0x36, 0x6c, 0x63, 0x67, 0x35, 0x4b, 0x74, 0x7a, 0x38,
+    0x38, 0x35, 0x68, 0x5a, 0x6f, 0x2b, 0x4c, 0x37, 0x74, 0x64, 0x45, 0x79,
+    0x38, 0x57, 0x39, 0x56, 0x69, 0x48, 0x30, 0x50, 0x64, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+    0x2e, 0x76, 0x61, 0x6c, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f,
+    0x6d, 0x2f, 0x20, 0x4f, 0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65, 0x72,
+    0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56,
+    0x61, 0x6c, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x43, 0x6c, 0x61, 0x73,
+    0x73, 0x20, 0x33, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x56,
+    0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x68, 0x74,
+    0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x61, 0x6c,
+    0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x20, 0x4f,
+    0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x61, 0x6c, 0x69, 0x43,
+    0x65, 0x72, 0x74, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20,
+    0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x31,
+    0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20,
+    0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x32, 0x3a,
+    0x36, 0x66, 0x3a, 0x35, 0x33, 0x3a, 0x62, 0x37, 0x3a, 0x65, 0x65, 0x3a,
+    0x34, 0x30, 0x3a, 0x64, 0x62, 0x3a, 0x34, 0x61, 0x3a, 0x36, 0x38, 0x3a,
+    0x65, 0x37, 0x3a, 0x66, 0x61, 0x3a, 0x31, 0x38, 0x3a, 0x64, 0x39, 0x3a,
+    0x31, 0x30, 0x3a, 0x34, 0x62, 0x3a, 0x37, 0x32, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x36, 0x39, 0x3a, 0x62, 0x64, 0x3a, 0x38,
+    0x63, 0x3a, 0x66, 0x34, 0x3a, 0x39, 0x63, 0x3a, 0x64, 0x33, 0x3a, 0x30,
+    0x30, 0x3a, 0x66, 0x62, 0x3a, 0x35, 0x39, 0x3a, 0x32, 0x65, 0x3a, 0x31,
+    0x37, 0x3a, 0x39, 0x33, 0x3a, 0x63, 0x61, 0x3a, 0x35, 0x35, 0x3a, 0x36,
+    0x61, 0x3a, 0x66, 0x33, 0x3a, 0x65, 0x63, 0x3a, 0x61, 0x61, 0x3a, 0x33,
+    0x35, 0x3a, 0x66, 0x62, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35,
+    0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x62, 0x63, 0x3a, 0x32, 0x33, 0x3a, 0x66, 0x39, 0x3a,
+    0x38, 0x61, 0x3a, 0x33, 0x31, 0x3a, 0x33, 0x63, 0x3a, 0x62, 0x39, 0x3a,
+    0x32, 0x64, 0x3a, 0x65, 0x33, 0x3a, 0x62, 0x62, 0x3a, 0x66, 0x63, 0x3a,
+    0x33, 0x61, 0x3a, 0x35, 0x61, 0x3a, 0x39, 0x66, 0x3a, 0x34, 0x34, 0x3a,
+    0x36, 0x31, 0x3a, 0x61, 0x63, 0x3a, 0x33, 0x39, 0x3a, 0x34, 0x39, 0x3a,
+    0x34, 0x63, 0x3a, 0x34, 0x61, 0x3a, 0x65, 0x31, 0x3a, 0x35, 0x61, 0x3a,
+    0x39, 0x65, 0x3a, 0x39, 0x64, 0x3a, 0x66, 0x31, 0x3a, 0x33, 0x31, 0x3a,
+    0x65, 0x39, 0x3a, 0x39, 0x62, 0x3a, 0x37, 0x33, 0x3a, 0x30, 0x31, 0x3a,
+    0x39, 0x61, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49,
+    0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x35,
+    0x7a, 0x43, 0x43, 0x41, 0x6c, 0x41, 0x43, 0x41, 0x51, 0x45, 0x77, 0x44,
+    0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41,
+    0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x67, 0x62, 0x73, 0x78, 0x4a,
+    0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x47,
+    0x31, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x0a,
+    0x49, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70,
+    0x62, 0x32, 0x34, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79,
+    0x61, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x46, 0x73, 0x61, 0x55, 0x4e, 0x6c,
+    0x63, 0x6e, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78,
+    0x4e, 0x54, 0x41, 0x7a, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73,
+    0x54, 0x4c, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a,
+    0x30, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44, 0x4d,
+    0x67, 0x55, 0x47, 0x39, 0x73, 0x61, 0x57, 0x4e, 0x35, 0x49, 0x46, 0x5a,
+    0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34,
+    0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x0a, 0x61, 0x58,
+    0x52, 0x35, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x44, 0x45, 0x78, 0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69,
+    0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x5a, 0x68, 0x62, 0x47,
+    0x6c, 0x6a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53,
+    0x38, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x0a, 0x39, 0x77, 0x30, 0x42, 0x43, 0x51, 0x45, 0x57, 0x45,
+    0x57, 0x6c, 0x75, 0x5a, 0x6d, 0x39, 0x41, 0x64, 0x6d, 0x46, 0x73, 0x61,
+    0x57, 0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d,
+    0x42, 0x34, 0x58, 0x44, 0x54, 0x6b, 0x35, 0x4d, 0x44, 0x59, 0x79, 0x4e,
+    0x6a, 0x41, 0x77, 0x4d, 0x6a, 0x49, 0x7a, 0x4d, 0x31, 0x6f, 0x58, 0x44,
+    0x54, 0x45, 0x35, 0x4d, 0x44, 0x59, 0x79, 0x0a, 0x4e, 0x6a, 0x41, 0x77,
+    0x4d, 0x6a, 0x49, 0x7a, 0x4d, 0x31, 0x6f, 0x77, 0x67, 0x62, 0x73, 0x78,
+    0x4a, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54,
+    0x47, 0x31, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a, 0x30,
+    0x49, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70,
+    0x62, 0x32, 0x34, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79,
+    0x0a, 0x61, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x46, 0x73, 0x61, 0x55, 0x4e,
+    0x6c, 0x63, 0x6e, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34,
+    0x78, 0x4e, 0x54, 0x41, 0x7a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73,
+    0x54, 0x4c, 0x46, 0x5a, 0x68, 0x62, 0x47, 0x6c, 0x44, 0x5a, 0x58, 0x4a,
+    0x30, 0x49, 0x45, 0x4e, 0x73, 0x0a, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44,
+    0x4d, 0x67, 0x55, 0x47, 0x39, 0x73, 0x61, 0x57, 0x4e, 0x35, 0x49, 0x46,
+    0x5a, 0x68, 0x62, 0x47, 0x6c, 0x6b, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32,
+    0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58,
+    0x52, 0x35, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x44, 0x45, 0x78, 0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x0a, 0x4f,
+    0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x5a, 0x68, 0x62,
+    0x47, 0x6c, 0x6a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6d, 0x4e, 0x76, 0x62,
+    0x53, 0x38, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x43, 0x51, 0x45, 0x57, 0x45,
+    0x57, 0x6c, 0x75, 0x5a, 0x6d, 0x39, 0x41, 0x64, 0x6d, 0x46, 0x73, 0x61,
+    0x57, 0x4e, 0x6c, 0x0a, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74,
+    0x4d, 0x49, 0x47, 0x66, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47,
+    0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41,
+    0x41, 0x34, 0x47, 0x4e, 0x41, 0x44, 0x43, 0x42, 0x69, 0x51, 0x4b, 0x42,
+    0x67, 0x51, 0x44, 0x6a, 0x6d, 0x46, 0x47, 0x57, 0x48, 0x4f, 0x6a, 0x56,
+    0x73, 0x51, 0x61, 0x42, 0x61, 0x6c, 0x66, 0x44, 0x0a, 0x63, 0x6e, 0x57,
+    0x54, 0x71, 0x38, 0x2b, 0x65, 0x70, 0x76, 0x7a, 0x7a, 0x46, 0x6c, 0x4c,
+    0x57, 0x4c, 0x55, 0x32, 0x66, 0x4e, 0x55, 0x53, 0x6f, 0x4c, 0x67, 0x52,
+    0x4e, 0x42, 0x30, 0x6d, 0x4b, 0x4f, 0x43, 0x6e, 0x31, 0x64, 0x7a, 0x66,
+    0x6e, 0x74, 0x36, 0x74, 0x64, 0x33, 0x7a, 0x5a, 0x78, 0x46, 0x4a, 0x6d,
+    0x50, 0x33, 0x4d, 0x4b, 0x53, 0x38, 0x65, 0x64, 0x67, 0x6b, 0x70, 0x66,
+    0x73, 0x0a, 0x32, 0x45, 0x6a, 0x63, 0x76, 0x38, 0x45, 0x43, 0x49, 0x4d,
+    0x59, 0x6b, 0x70, 0x43, 0x68, 0x4d, 0x4d, 0x46, 0x70, 0x32, 0x62, 0x62,
+    0x46, 0x63, 0x38, 0x39, 0x33, 0x65, 0x6e, 0x68, 0x42, 0x78, 0x6f, 0x59,
+    0x6a, 0x48, 0x57, 0x35, 0x74, 0x42, 0x62, 0x63, 0x71, 0x77, 0x75, 0x49,
+    0x34, 0x56, 0x37, 0x71, 0x30, 0x7a, 0x4b, 0x38, 0x39, 0x48, 0x42, 0x46,
+    0x78, 0x31, 0x63, 0x51, 0x71, 0x59, 0x0a, 0x4a, 0x4a, 0x67, 0x70, 0x70,
+    0x30, 0x6c, 0x5a, 0x70, 0x64, 0x33, 0x34, 0x74, 0x30, 0x4e, 0x69, 0x59,
+    0x66, 0x50, 0x54, 0x34, 0x74, 0x42, 0x56, 0x50, 0x77, 0x49, 0x44, 0x41,
+    0x51, 0x41, 0x42, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53,
+    0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41,
+    0x34, 0x47, 0x42, 0x41, 0x46, 0x61, 0x37, 0x41, 0x6c, 0x69, 0x45, 0x0a,
+    0x5a, 0x77, 0x67, 0x73, 0x33, 0x78, 0x2f, 0x62, 0x65, 0x30, 0x6b, 0x7a,
+    0x39, 0x64, 0x4e, 0x6e, 0x6e, 0x66, 0x53, 0x30, 0x43, 0x68, 0x43, 0x7a,
+    0x79, 0x63, 0x55, 0x73, 0x34, 0x70, 0x4a, 0x71, 0x63, 0x58, 0x67, 0x6e,
+    0x38, 0x6e, 0x43, 0x44, 0x51, 0x74, 0x4d, 0x2b, 0x7a, 0x36, 0x6c, 0x55,
+    0x39, 0x50, 0x48, 0x59, 0x6b, 0x68, 0x61, 0x4d, 0x30, 0x51, 0x54, 0x4c,
+    0x53, 0x36, 0x76, 0x4a, 0x0a, 0x6e, 0x30, 0x57, 0x75, 0x50, 0x49, 0x71,
+    0x70, 0x73, 0x48, 0x45, 0x7a, 0x58, 0x63, 0x6a, 0x46, 0x56, 0x39, 0x2b,
+    0x76, 0x71, 0x44, 0x57, 0x7a, 0x66, 0x34, 0x6d, 0x48, 0x36, 0x65, 0x67,
+    0x6c, 0x6b, 0x72, 0x68, 0x2f, 0x68, 0x58, 0x71, 0x75, 0x31, 0x72, 0x77,
+    0x65, 0x4e, 0x31, 0x67, 0x71, 0x5a, 0x38, 0x6d, 0x52, 0x7a, 0x79, 0x71,
+    0x42, 0x50, 0x75, 0x33, 0x47, 0x4f, 0x64, 0x2f, 0x41, 0x0a, 0x50, 0x68,
+    0x6d, 0x63, 0x47, 0x63, 0x77, 0x54, 0x54, 0x59, 0x4a, 0x42, 0x74, 0x59,
+    0x7a, 0x65, 0x34, 0x44, 0x31, 0x67, 0x43, 0x43, 0x41, 0x50, 0x52, 0x58,
+    0x35, 0x72, 0x6f, 0x6e, 0x2b, 0x6a, 0x6a, 0x42, 0x58, 0x75, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c,
+    0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d,
+    0x20, 0x47, 0x33, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
+    0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28,
+    0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
+    0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c,
+    0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d,
+    0x20, 0x47, 0x33, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
+    0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28,
+    0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d,
+    0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x56,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73,
+    0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50,
+    0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x22,
+    0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x32,
+    0x30, 0x36, 0x36, 0x38, 0x34, 0x36, 0x39, 0x36, 0x32, 0x37, 0x39, 0x34,
+    0x37, 0x32, 0x33, 0x31, 0x30, 0x32, 0x35, 0x34, 0x32, 0x37, 0x37, 0x38,
+    0x37, 0x30, 0x31, 0x38, 0x30, 0x39, 0x36, 0x36, 0x37, 0x32, 0x33, 0x34,
+    0x31, 0x35, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x64,
+    0x3a, 0x36, 0x38, 0x3a, 0x62, 0x36, 0x3a, 0x61, 0x37, 0x3a, 0x63, 0x37,
+    0x3a, 0x63, 0x34, 0x3a, 0x63, 0x65, 0x3a, 0x37, 0x35, 0x3a, 0x65, 0x30,
+    0x3a, 0x31, 0x64, 0x3a, 0x34, 0x66, 0x3a, 0x35, 0x37, 0x3a, 0x34, 0x34,
+    0x3a, 0x36, 0x31, 0x3a, 0x39, 0x32, 0x3a, 0x30, 0x39, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x31, 0x33, 0x3a, 0x32, 0x64, 0x3a,
+    0x30, 0x64, 0x3a, 0x34, 0x35, 0x3a, 0x35, 0x33, 0x3a, 0x34, 0x62, 0x3a,
+    0x36, 0x39, 0x3a, 0x39, 0x37, 0x3a, 0x63, 0x64, 0x3a, 0x62, 0x32, 0x3a,
+    0x64, 0x35, 0x3a, 0x63, 0x33, 0x3a, 0x33, 0x39, 0x3a, 0x65, 0x32, 0x3a,
+    0x35, 0x35, 0x3a, 0x37, 0x36, 0x3a, 0x36, 0x30, 0x3a, 0x39, 0x62, 0x3a,
+    0x35, 0x63, 0x3a, 0x63, 0x36, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32,
+    0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x65, 0x62, 0x3a, 0x30, 0x34, 0x3a, 0x63, 0x66,
+    0x3a, 0x35, 0x65, 0x3a, 0x62, 0x31, 0x3a, 0x66, 0x33, 0x3a, 0x39, 0x61,
+    0x3a, 0x66, 0x61, 0x3a, 0x37, 0x36, 0x3a, 0x32, 0x66, 0x3a, 0x32, 0x62,
+    0x3a, 0x62, 0x31, 0x3a, 0x32, 0x30, 0x3a, 0x66, 0x32, 0x3a, 0x39, 0x36,
+    0x3a, 0x63, 0x62, 0x3a, 0x61, 0x35, 0x3a, 0x32, 0x30, 0x3a, 0x63, 0x31,
+    0x3a, 0x62, 0x39, 0x3a, 0x37, 0x64, 0x3a, 0x62, 0x31, 0x3a, 0x35, 0x38,
+    0x3a, 0x39, 0x35, 0x3a, 0x36, 0x35, 0x3a, 0x62, 0x38, 0x3a, 0x31, 0x63,
+    0x3a, 0x62, 0x39, 0x3a, 0x61, 0x31, 0x3a, 0x37, 0x62, 0x3a, 0x37, 0x32,
+    0x3a, 0x34, 0x34, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47,
+    0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45,
+    0x47, 0x6a, 0x43, 0x43, 0x41, 0x77, 0x49, 0x43, 0x45, 0x51, 0x43, 0x62,
+    0x66, 0x67, 0x5a, 0x4a, 0x6f, 0x7a, 0x35, 0x69, 0x75, 0x64, 0x58, 0x75,
+    0x6b, 0x45, 0x68, 0x78, 0x4b, 0x65, 0x39, 0x58, 0x4d, 0x41, 0x30, 0x47,
+    0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42,
+    0x42, 0x51, 0x55, 0x41, 0x4d, 0x49, 0x48, 0x4b, 0x4d, 0x51, 0x73, 0x77,
+    0x0a, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a,
+    0x56, 0x55, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x56, 0x79, 0x61, 0x56, 0x4e,
+    0x70, 0x5a, 0x32, 0x34, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34,
+    0x78, 0x48, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73,
+    0x54, 0x46, 0x6c, 0x5a, 0x6c, 0x0a, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57,
+    0x64, 0x75, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45,
+    0x35, 0x6c, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6d, 0x73, 0x78, 0x4f, 0x6a,
+    0x41, 0x34, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4d, 0x53,
+    0x68, 0x6a, 0x4b, 0x53, 0x41, 0x78, 0x4f, 0x54, 0x6b, 0x35, 0x49, 0x46,
+    0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x0a, 0x4c,
+    0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30, 0x67, 0x52,
+    0x6d, 0x39, 0x79, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63,
+    0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67, 0x64, 0x58, 0x4e, 0x6c, 0x49,
+    0x47, 0x39, 0x75, 0x62, 0x48, 0x6b, 0x78, 0x52, 0x54, 0x42, 0x44, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x50, 0x46, 0x5a, 0x6c, 0x63,
+    0x6d, 0x6c, 0x54, 0x0a, 0x61, 0x57, 0x64, 0x75, 0x49, 0x45, 0x4e, 0x73,
+    0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44, 0x4d, 0x67, 0x55, 0x48, 0x56, 0x69,
+    0x62, 0x47, 0x6c, 0x6a, 0x49, 0x46, 0x42, 0x79, 0x61, 0x57, 0x31, 0x68,
+    0x63, 0x6e, 0x6b, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d,
+    0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42,
+    0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x0a, 0x64, 0x48, 0x6b,
+    0x67, 0x4c, 0x53, 0x42, 0x48, 0x4d, 0x7a, 0x41, 0x65, 0x46, 0x77, 0x30,
+    0x35, 0x4f, 0x54, 0x45, 0x77, 0x4d, 0x44, 0x45, 0x77, 0x4d, 0x44, 0x41,
+    0x77, 0x4d, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7a, 0x4e, 0x6a, 0x41,
+    0x33, 0x4d, 0x54, 0x59, 0x79, 0x4d, 0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c,
+    0x61, 0x4d, 0x49, 0x48, 0x4b, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59,
+    0x44, 0x0a, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a,
+    0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4f, 0x56, 0x6d, 0x56, 0x79, 0x61, 0x56, 0x4e, 0x70, 0x5a, 0x32,
+    0x34, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78, 0x48, 0x7a,
+    0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x46, 0x6c,
+    0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x0a, 0x61, 0x57, 0x64, 0x75, 0x49,
+    0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x35, 0x6c, 0x64,
+    0x48, 0x64, 0x76, 0x63, 0x6d, 0x73, 0x78, 0x4f, 0x6a, 0x41, 0x34, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4d, 0x53, 0x68, 0x6a, 0x4b,
+    0x53, 0x41, 0x78, 0x4f, 0x54, 0x6b, 0x35, 0x49, 0x46, 0x5a, 0x6c, 0x63,
+    0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x0a,
+    0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30, 0x67, 0x52, 0x6d, 0x39, 0x79,
+    0x49, 0x47, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x36,
+    0x5a, 0x57, 0x51, 0x67, 0x64, 0x58, 0x4e, 0x6c, 0x49, 0x47, 0x39, 0x75,
+    0x62, 0x48, 0x6b, 0x78, 0x52, 0x54, 0x42, 0x44, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x4d, 0x54, 0x50, 0x46, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54,
+    0x61, 0x57, 0x64, 0x75, 0x0a, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e,
+    0x7a, 0x49, 0x44, 0x4d, 0x67, 0x55, 0x48, 0x56, 0x69, 0x62, 0x47, 0x6c,
+    0x6a, 0x49, 0x46, 0x42, 0x79, 0x61, 0x57, 0x31, 0x68, 0x63, 0x6e, 0x6b,
+    0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e,
+    0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52,
+    0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x0a, 0x4c, 0x53,
+    0x42, 0x48, 0x4d, 0x7a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44,
+    0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4d,
+    0x75, 0x36, 0x6e, 0x46, 0x4c, 0x38, 0x65, 0x42, 0x38, 0x61, 0x48, 0x6d,
+    0x38, 0x62, 0x0a, 0x4e, 0x33, 0x4f, 0x39, 0x2b, 0x4d, 0x6c, 0x72, 0x6c,
+    0x42, 0x49, 0x77, 0x54, 0x2f, 0x41, 0x32, 0x52, 0x2f, 0x58, 0x51, 0x6b,
+    0x51, 0x72, 0x31, 0x46, 0x38, 0x69, 0x6c, 0x59, 0x63, 0x45, 0x57, 0x51,
+    0x45, 0x33, 0x37, 0x69, 0x6d, 0x47, 0x51, 0x35, 0x58, 0x59, 0x67, 0x77,
+    0x52, 0x45, 0x47, 0x66, 0x61, 0x73, 0x73, 0x62, 0x71, 0x62, 0x31, 0x45,
+    0x55, 0x47, 0x4f, 0x2b, 0x69, 0x32, 0x74, 0x0a, 0x4b, 0x6d, 0x46, 0x5a,
+    0x70, 0x47, 0x63, 0x6d, 0x54, 0x4e, 0x44, 0x6f, 0x76, 0x46, 0x4a, 0x62,
+    0x63, 0x43, 0x41, 0x45, 0x57, 0x4e, 0x46, 0x36, 0x79, 0x61, 0x52, 0x70,
+    0x76, 0x49, 0x4d, 0x58, 0x5a, 0x4b, 0x30, 0x46, 0x69, 0x37, 0x7a, 0x51,
+    0x57, 0x4d, 0x36, 0x4e, 0x6a, 0x50, 0x58, 0x72, 0x38, 0x45, 0x4a, 0x4a,
+    0x43, 0x35, 0x32, 0x58, 0x4a, 0x32, 0x63, 0x79, 0x62, 0x75, 0x47, 0x75,
+    0x0a, 0x6b, 0x78, 0x55, 0x63, 0x63, 0x4c, 0x77, 0x67, 0x54, 0x53, 0x38,
+    0x59, 0x33, 0x70, 0x4b, 0x49, 0x36, 0x47, 0x79, 0x46, 0x56, 0x78, 0x45,
+    0x61, 0x36, 0x58, 0x37, 0x6a, 0x4a, 0x68, 0x46, 0x55, 0x6f, 0x6b, 0x57,
+    0x57, 0x56, 0x59, 0x50, 0x4b, 0x4d, 0x49, 0x6e, 0x6f, 0x33, 0x4e, 0x69,
+    0x6a, 0x37, 0x53, 0x71, 0x41, 0x50, 0x33, 0x39, 0x35, 0x5a, 0x56, 0x63,
+    0x2b, 0x46, 0x53, 0x42, 0x6d, 0x0a, 0x43, 0x43, 0x2b, 0x56, 0x6b, 0x37,
+    0x2b, 0x71, 0x52, 0x79, 0x2b, 0x6f, 0x52, 0x70, 0x66, 0x77, 0x45, 0x75,
+    0x4c, 0x2b, 0x77, 0x67, 0x6f, 0x72, 0x55, 0x65, 0x5a, 0x32, 0x35, 0x72,
+    0x64, 0x47, 0x74, 0x2b, 0x49, 0x4e, 0x70, 0x73, 0x79, 0x6f, 0x77, 0x30,
+    0x78, 0x5a, 0x56, 0x59, 0x6e, 0x6d, 0x36, 0x46, 0x4e, 0x63, 0x48, 0x4f,
+    0x71, 0x64, 0x38, 0x47, 0x49, 0x57, 0x43, 0x36, 0x66, 0x4a, 0x0a, 0x58,
+    0x77, 0x7a, 0x77, 0x33, 0x73, 0x4a, 0x32, 0x7a, 0x71, 0x2f, 0x33, 0x61,
+    0x76, 0x4c, 0x36, 0x51, 0x61, 0x61, 0x69, 0x4d, 0x78, 0x54, 0x4a, 0x35,
+    0x58, 0x70, 0x6a, 0x30, 0x35, 0x35, 0x69, 0x4e, 0x39, 0x57, 0x46, 0x5a,
+    0x5a, 0x34, 0x4f, 0x35, 0x6c, 0x4d, 0x6b, 0x64, 0x42, 0x74, 0x65, 0x48,
+    0x52, 0x4a, 0x54, 0x57, 0x38, 0x63, 0x73, 0x35, 0x34, 0x4e, 0x4a, 0x4f,
+    0x78, 0x57, 0x75, 0x0a, 0x69, 0x6d, 0x69, 0x35, 0x56, 0x35, 0x63, 0x43,
+    0x41, 0x77, 0x45, 0x41, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71,
+    0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46,
+    0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x45, 0x52, 0x53, 0x57,
+    0x77, 0x61, 0x75, 0x53, 0x43, 0x50, 0x63, 0x2f, 0x4c, 0x38, 0x6d, 0x79,
+    0x2f, 0x75, 0x52, 0x61, 0x6e, 0x32, 0x54, 0x65, 0x0a, 0x32, 0x79, 0x46,
+    0x50, 0x68, 0x70, 0x6b, 0x30, 0x64, 0x6a, 0x5a, 0x58, 0x33, 0x64, 0x41,
+    0x56, 0x4c, 0x38, 0x57, 0x74, 0x66, 0x78, 0x55, 0x66, 0x4e, 0x32, 0x4a,
+    0x7a, 0x50, 0x74, 0x54, 0x6e, 0x58, 0x38, 0x34, 0x58, 0x41, 0x39, 0x73,
+    0x31, 0x2b, 0x69, 0x76, 0x62, 0x72, 0x6d, 0x41, 0x4a, 0x58, 0x78, 0x35,
+    0x66, 0x6a, 0x32, 0x36, 0x37, 0x43, 0x7a, 0x33, 0x71, 0x57, 0x68, 0x4d,
+    0x65, 0x0a, 0x44, 0x47, 0x42, 0x76, 0x74, 0x63, 0x43, 0x31, 0x49, 0x79,
+    0x49, 0x75, 0x42, 0x77, 0x76, 0x4c, 0x71, 0x58, 0x54, 0x4c, 0x52, 0x37,
+    0x73, 0x64, 0x77, 0x64, 0x65, 0x6c, 0x61, 0x38, 0x77, 0x76, 0x30, 0x6b,
+    0x4c, 0x39, 0x53, 0x64, 0x32, 0x6e, 0x69, 0x63, 0x39, 0x54, 0x75, 0x74,
+    0x6f, 0x41, 0x57, 0x69, 0x69, 0x2f, 0x67, 0x74, 0x2f, 0x34, 0x75, 0x68,
+    0x4d, 0x64, 0x55, 0x49, 0x61, 0x43, 0x0a, 0x2f, 0x59, 0x34, 0x77, 0x6a,
+    0x79, 0x6c, 0x47, 0x73, 0x42, 0x34, 0x39, 0x4e, 0x64, 0x6f, 0x34, 0x59,
+    0x68, 0x59, 0x59, 0x53, 0x71, 0x33, 0x6d, 0x74, 0x6c, 0x46, 0x73, 0x33,
+    0x71, 0x39, 0x69, 0x36, 0x77, 0x48, 0x51, 0x48, 0x69, 0x54, 0x2b, 0x65,
+    0x6f, 0x38, 0x53, 0x47, 0x68, 0x4a, 0x6f, 0x75, 0x50, 0x74, 0x6d, 0x6d,
+    0x52, 0x51, 0x55, 0x52, 0x56, 0x79, 0x75, 0x35, 0x36, 0x35, 0x70, 0x0a,
+    0x46, 0x34, 0x45, 0x72, 0x57, 0x6a, 0x66, 0x4a, 0x58, 0x69, 0x72, 0x30,
+    0x78, 0x75, 0x4b, 0x68, 0x58, 0x46, 0x53, 0x62, 0x70, 0x6c, 0x51, 0x41,
+    0x7a, 0x2f, 0x44, 0x78, 0x77, 0x63, 0x65, 0x59, 0x4d, 0x42, 0x6f, 0x37,
+    0x4e, 0x68, 0x62, 0x62, 0x6f, 0x32, 0x37, 0x71, 0x2f, 0x61, 0x32, 0x79,
+    0x77, 0x74, 0x72, 0x76, 0x41, 0x6b, 0x63, 0x54, 0x69, 0x73, 0x44, 0x78,
+    0x73, 0x7a, 0x47, 0x74, 0x0a, 0x54, 0x78, 0x7a, 0x68, 0x54, 0x35, 0x79,
+    0x76, 0x44, 0x77, 0x79, 0x64, 0x39, 0x33, 0x67, 0x4e, 0x32, 0x50, 0x51,
+    0x31, 0x56, 0x6f, 0x44, 0x61, 0x74, 0x32, 0x30, 0x58, 0x6a, 0x35, 0x30,
+    0x65, 0x67, 0x57, 0x54, 0x68, 0x2f, 0x73, 0x56, 0x46, 0x75, 0x71, 0x31,
+    0x72, 0x75, 0x51, 0x70, 0x36, 0x54, 0x6b, 0x39, 0x4c, 0x68, 0x4f, 0x35,
+    0x4c, 0x38, 0x58, 0x33, 0x64, 0x45, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43,
+    0x6c, 0x61, 0x73, 0x73, 0x20, 0x34, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69,
+    0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+    0x47, 0x33, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63,
+    0x29, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53,
+    0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20,
+    0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
+    0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a,
+    0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43,
+    0x6c, 0x61, 0x73, 0x73, 0x20, 0x34, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69,
+    0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+    0x47, 0x33, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63,
+    0x29, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53,
+    0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20,
+    0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
+    0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x56, 0x65,
+    0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
+    0x20, 0x34, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72,
+    0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x33, 0x31,
+    0x34, 0x35, 0x33, 0x31, 0x39, 0x37, 0x32, 0x37, 0x31, 0x31, 0x39, 0x30,
+    0x39, 0x34, 0x31, 0x33, 0x37, 0x34, 0x33, 0x30, 0x37, 0x35, 0x30, 0x39,
+    0x36, 0x30, 0x33, 0x39, 0x33, 0x37, 0x38, 0x39, 0x33, 0x35, 0x35, 0x31,
+    0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x62, 0x3a,
+    0x63, 0x38, 0x3a, 0x66, 0x32, 0x3a, 0x32, 0x37, 0x3a, 0x32, 0x65, 0x3a,
+    0x62, 0x31, 0x3a, 0x65, 0x61, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x39, 0x3a,
+    0x32, 0x33, 0x3a, 0x35, 0x64, 0x3a, 0x66, 0x65, 0x3a, 0x35, 0x36, 0x3a,
+    0x33, 0x65, 0x3a, 0x33, 0x33, 0x3a, 0x64, 0x66, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x38, 0x3a, 0x65, 0x63, 0x3a, 0x38,
+    0x63, 0x3a, 0x38, 0x37, 0x3a, 0x39, 0x32, 0x3a, 0x36, 0x39, 0x3a, 0x63,
+    0x62, 0x3a, 0x34, 0x62, 0x3a, 0x61, 0x62, 0x3a, 0x33, 0x39, 0x3a, 0x65,
+    0x39, 0x3a, 0x38, 0x64, 0x3a, 0x37, 0x65, 0x3a, 0x35, 0x37, 0x3a, 0x36,
+    0x37, 0x3a, 0x66, 0x33, 0x3a, 0x31, 0x34, 0x3a, 0x39, 0x35, 0x3a, 0x37,
+    0x33, 0x3a, 0x39, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35,
+    0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x65, 0x33, 0x3a, 0x38, 0x39, 0x3a, 0x33, 0x36, 0x3a,
+    0x30, 0x64, 0x3a, 0x30, 0x66, 0x3a, 0x64, 0x62, 0x3a, 0x61, 0x65, 0x3a,
+    0x62, 0x33, 0x3a, 0x64, 0x32, 0x3a, 0x35, 0x30, 0x3a, 0x35, 0x38, 0x3a,
+    0x34, 0x62, 0x3a, 0x34, 0x37, 0x3a, 0x33, 0x30, 0x3a, 0x33, 0x31, 0x3a,
+    0x34, 0x65, 0x3a, 0x32, 0x32, 0x3a, 0x32, 0x66, 0x3a, 0x33, 0x39, 0x3a,
+    0x63, 0x31, 0x3a, 0x35, 0x36, 0x3a, 0x61, 0x30, 0x3a, 0x32, 0x30, 0x3a,
+    0x31, 0x34, 0x3a, 0x34, 0x65, 0x3a, 0x38, 0x64, 0x3a, 0x39, 0x36, 0x3a,
+    0x30, 0x35, 0x3a, 0x36, 0x31, 0x3a, 0x37, 0x39, 0x3a, 0x31, 0x35, 0x3a,
+    0x30, 0x36, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49,
+    0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x47,
+    0x6a, 0x43, 0x43, 0x41, 0x77, 0x49, 0x43, 0x45, 0x51, 0x44, 0x73, 0x6f,
+    0x4b, 0x65, 0x4c, 0x62, 0x6e, 0x56, 0x71, 0x41, 0x63, 0x2f, 0x45, 0x66,
+    0x4d, 0x77, 0x76, 0x6c, 0x46, 0x37, 0x58, 0x4d, 0x41, 0x30, 0x47, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42,
+    0x51, 0x55, 0x41, 0x4d, 0x49, 0x48, 0x4b, 0x4d, 0x51, 0x73, 0x77, 0x0a,
+    0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56,
+    0x55, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x56, 0x79, 0x61, 0x56, 0x4e, 0x70,
+    0x5a, 0x32, 0x34, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78,
+    0x48, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54,
+    0x46, 0x6c, 0x5a, 0x6c, 0x0a, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64,
+    0x75, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x35,
+    0x6c, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6d, 0x73, 0x78, 0x4f, 0x6a, 0x41,
+    0x34, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4d, 0x53, 0x68,
+    0x6a, 0x4b, 0x53, 0x41, 0x78, 0x4f, 0x54, 0x6b, 0x35, 0x49, 0x46, 0x5a,
+    0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x0a, 0x4c, 0x43,
+    0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30, 0x67, 0x52, 0x6d,
+    0x39, 0x79, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d,
+    0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67, 0x64, 0x58, 0x4e, 0x6c, 0x49, 0x47,
+    0x39, 0x75, 0x62, 0x48, 0x6b, 0x78, 0x52, 0x54, 0x42, 0x44, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x50, 0x46, 0x5a, 0x6c, 0x63, 0x6d,
+    0x6c, 0x54, 0x0a, 0x61, 0x57, 0x64, 0x75, 0x49, 0x45, 0x4e, 0x73, 0x59,
+    0x58, 0x4e, 0x7a, 0x49, 0x44, 0x51, 0x67, 0x55, 0x48, 0x56, 0x69, 0x62,
+    0x47, 0x6c, 0x6a, 0x49, 0x46, 0x42, 0x79, 0x61, 0x57, 0x31, 0x68, 0x63,
+    0x6e, 0x6b, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61,
+    0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64,
+    0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x0a, 0x64, 0x48, 0x6b, 0x67,
+    0x4c, 0x53, 0x42, 0x48, 0x4d, 0x7a, 0x41, 0x65, 0x46, 0x77, 0x30, 0x35,
+    0x4f, 0x54, 0x45, 0x77, 0x4d, 0x44, 0x45, 0x77, 0x4d, 0x44, 0x41, 0x77,
+    0x4d, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7a, 0x4e, 0x6a, 0x41, 0x33,
+    0x4d, 0x54, 0x59, 0x79, 0x4d, 0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c, 0x61,
+    0x4d, 0x49, 0x48, 0x4b, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44,
+    0x0a, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45,
+    0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d,
+    0x4f, 0x56, 0x6d, 0x56, 0x79, 0x61, 0x56, 0x4e, 0x70, 0x5a, 0x32, 0x34,
+    0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78, 0x48, 0x7a, 0x41,
+    0x64, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x46, 0x6c, 0x5a,
+    0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x0a, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46,
+    0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x35, 0x6c, 0x64, 0x48,
+    0x64, 0x76, 0x63, 0x6d, 0x73, 0x78, 0x4f, 0x6a, 0x41, 0x34, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4d, 0x53, 0x68, 0x6a, 0x4b, 0x53,
+    0x41, 0x78, 0x4f, 0x54, 0x6b, 0x35, 0x49, 0x46, 0x5a, 0x6c, 0x63, 0x6d,
+    0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x0a, 0x62,
+    0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30, 0x67, 0x52, 0x6d, 0x39, 0x79, 0x49,
+    0x47, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x36, 0x5a,
+    0x57, 0x51, 0x67, 0x64, 0x58, 0x4e, 0x6c, 0x49, 0x47, 0x39, 0x75, 0x62,
+    0x48, 0x6b, 0x78, 0x52, 0x54, 0x42, 0x44, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x4d, 0x54, 0x50, 0x46, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61,
+    0x57, 0x64, 0x75, 0x0a, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a,
+    0x49, 0x44, 0x51, 0x67, 0x55, 0x48, 0x56, 0x69, 0x62, 0x47, 0x6c, 0x6a,
+    0x49, 0x46, 0x42, 0x79, 0x61, 0x57, 0x31, 0x68, 0x63, 0x6e, 0x6b, 0x67,
+    0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68,
+    0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f,
+    0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x0a, 0x4c, 0x53, 0x42,
+    0x48, 0x4d, 0x7a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59,
+    0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45,
+    0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43,
+    0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4b, 0x33,
+    0x4c, 0x70, 0x52, 0x46, 0x70, 0x78, 0x6c, 0x6d, 0x72, 0x38, 0x59, 0x2b,
+    0x31, 0x0a, 0x47, 0x51, 0x39, 0x57, 0x7a, 0x73, 0x79, 0x31, 0x48, 0x79,
+    0x44, 0x6b, 0x6e, 0x69, 0x59, 0x6c, 0x53, 0x2b, 0x42, 0x7a, 0x5a, 0x59,
+    0x6c, 0x5a, 0x33, 0x74, 0x43, 0x44, 0x35, 0x50, 0x55, 0x50, 0x74, 0x62,
+    0x75, 0x74, 0x38, 0x58, 0x7a, 0x6f, 0x49, 0x66, 0x7a, 0x6b, 0x36, 0x41,
+    0x7a, 0x75, 0x66, 0x45, 0x55, 0x69, 0x47, 0x58, 0x61, 0x53, 0x74, 0x42,
+    0x4f, 0x33, 0x49, 0x46, 0x73, 0x4a, 0x0a, 0x2b, 0x6d, 0x47, 0x75, 0x71,
+    0x50, 0x4b, 0x6c, 0x6a, 0x59, 0x58, 0x43, 0x4b, 0x74, 0x62, 0x65, 0x5a,
+    0x6a, 0x62, 0x53, 0x6d, 0x77, 0x4c, 0x30, 0x71, 0x4a, 0x4a, 0x67, 0x66,
+    0x4a, 0x78, 0x70, 0x74, 0x49, 0x38, 0x6b, 0x48, 0x74, 0x43, 0x47, 0x55,
+    0x76, 0x59, 0x79, 0x6e, 0x45, 0x46, 0x59, 0x48, 0x69, 0x4b, 0x39, 0x7a,
+    0x55, 0x56, 0x69, 0x6c, 0x51, 0x68, 0x75, 0x30, 0x47, 0x62, 0x64, 0x0a,
+    0x55, 0x36, 0x4c, 0x4d, 0x38, 0x42, 0x44, 0x63, 0x56, 0x48, 0x4f, 0x4c,
+    0x42, 0x4b, 0x46, 0x47, 0x4d, 0x7a, 0x4e, 0x63, 0x46, 0x30, 0x43, 0x35,
+    0x6e, 0x6b, 0x33, 0x54, 0x38, 0x37, 0x35, 0x56, 0x67, 0x2b, 0x69, 0x78,
+    0x69, 0x59, 0x35, 0x61, 0x66, 0x4a, 0x71, 0x57, 0x49, 0x70, 0x41, 0x37,
+    0x69, 0x43, 0x58, 0x79, 0x30, 0x6c, 0x4f, 0x49, 0x41, 0x67, 0x77, 0x4c,
+    0x65, 0x50, 0x4c, 0x6d, 0x0a, 0x4e, 0x78, 0x64, 0x4c, 0x4d, 0x45, 0x59,
+    0x48, 0x35, 0x49, 0x42, 0x74, 0x70, 0x74, 0x69, 0x57, 0x4c, 0x75, 0x67,
+    0x73, 0x2b, 0x42, 0x47, 0x7a, 0x4f, 0x41, 0x31, 0x6d, 0x70, 0x70, 0x76,
+    0x71, 0x79, 0x53, 0x4e, 0x62, 0x32, 0x34, 0x37, 0x69, 0x38, 0x78, 0x4f,
+    0x4f, 0x47, 0x6c, 0x6b, 0x74, 0x71, 0x67, 0x4c, 0x77, 0x37, 0x4b, 0x53,
+    0x48, 0x5a, 0x74, 0x7a, 0x42, 0x50, 0x2f, 0x58, 0x59, 0x0a, 0x75, 0x66,
+    0x54, 0x73, 0x67, 0x73, 0x62, 0x53, 0x50, 0x5a, 0x55, 0x64, 0x35, 0x63,
+    0x42, 0x50, 0x68, 0x4d, 0x6e, 0x5a, 0x6f, 0x30, 0x51, 0x6f, 0x42, 0x6d,
+    0x72, 0x58, 0x52, 0x61, 0x7a, 0x77, 0x61, 0x32, 0x72, 0x76, 0x54, 0x6c,
+    0x2f, 0x34, 0x45, 0x59, 0x49, 0x65, 0x4f, 0x47, 0x4d, 0x30, 0x5a, 0x6c,
+    0x44, 0x55, 0x50, 0x70, 0x4e, 0x7a, 0x2b, 0x6a, 0x44, 0x44, 0x5a, 0x71,
+    0x33, 0x2f, 0x0a, 0x6b, 0x79, 0x32, 0x58, 0x37, 0x77, 0x4d, 0x43, 0x41,
+    0x77, 0x45, 0x41, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41,
+    0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x6a, 0x2f, 0x6f, 0x6c, 0x61,
+    0x30, 0x39, 0x62, 0x35, 0x4b, 0x52, 0x4f, 0x4a, 0x31, 0x57, 0x72, 0x49,
+    0x68, 0x56, 0x5a, 0x50, 0x4d, 0x71, 0x31, 0x0a, 0x43, 0x74, 0x52, 0x4b,
+    0x32, 0x36, 0x76, 0x64, 0x6f, 0x56, 0x39, 0x54, 0x78, 0x61, 0x42, 0x58,
+    0x4f, 0x63, 0x4c, 0x4f, 0x52, 0x79, 0x75, 0x2b, 0x4f, 0x73, 0x68, 0x57,
+    0x76, 0x38, 0x4c, 0x5a, 0x4a, 0x78, 0x41, 0x36, 0x73, 0x51, 0x55, 0x38,
+    0x77, 0x48, 0x63, 0x78, 0x75, 0x7a, 0x72, 0x54, 0x42, 0x58, 0x74, 0x74,
+    0x6d, 0x68, 0x77, 0x77, 0x6a, 0x49, 0x44, 0x4c, 0x6b, 0x35, 0x4d, 0x71,
+    0x0a, 0x67, 0x36, 0x73, 0x46, 0x55, 0x59, 0x49, 0x43, 0x41, 0x42, 0x46,
+    0x6e, 0x61, 0x2f, 0x4f, 0x49, 0x59, 0x55, 0x64, 0x66, 0x41, 0x35, 0x50,
+    0x56, 0x57, 0x77, 0x33, 0x67, 0x38, 0x64, 0x53, 0x68, 0x4d, 0x6a, 0x57,
+    0x46, 0x73, 0x6a, 0x72, 0x62, 0x73, 0x49, 0x4b, 0x72, 0x30, 0x63, 0x73,
+    0x4b, 0x76, 0x45, 0x2b, 0x4d, 0x57, 0x38, 0x56, 0x4c, 0x41, 0x44, 0x73,
+    0x66, 0x4b, 0x6f, 0x4b, 0x6d, 0x0a, 0x66, 0x6a, 0x61, 0x46, 0x33, 0x48,
+    0x34, 0x38, 0x5a, 0x77, 0x43, 0x31, 0x35, 0x44, 0x74, 0x53, 0x34, 0x4b,
+    0x6a, 0x72, 0x58, 0x52, 0x58, 0x35, 0x78, 0x6d, 0x33, 0x77, 0x72, 0x52,
+    0x30, 0x4f, 0x68, 0x62, 0x65, 0x70, 0x6d, 0x6e, 0x4d, 0x55, 0x57, 0x6c,
+    0x75, 0x50, 0x51, 0x53, 0x6a, 0x41, 0x31, 0x65, 0x67, 0x74, 0x54, 0x61,
+    0x52, 0x65, 0x7a, 0x61, 0x72, 0x5a, 0x37, 0x63, 0x37, 0x63, 0x0a, 0x32,
+    0x4e, 0x55, 0x38, 0x51, 0x68, 0x30, 0x58, 0x77, 0x52, 0x4a, 0x64, 0x52,
+    0x54, 0x6a, 0x44, 0x4f, 0x50, 0x50, 0x38, 0x68, 0x53, 0x36, 0x44, 0x52,
+    0x6b, 0x69, 0x79, 0x31, 0x79, 0x42, 0x66, 0x6b, 0x6a, 0x61, 0x50, 0x35,
+    0x33, 0x6b, 0x50, 0x6d, 0x46, 0x36, 0x5a, 0x36, 0x50, 0x44, 0x51, 0x70,
+    0x4c, 0x76, 0x31, 0x55, 0x37, 0x30, 0x71, 0x7a, 0x6c, 0x6d, 0x77, 0x72,
+    0x32, 0x35, 0x2f, 0x0a, 0x62, 0x4c, 0x76, 0x53, 0x48, 0x67, 0x43, 0x77,
+    0x49, 0x65, 0x33, 0x34, 0x51, 0x57, 0x4b, 0x43, 0x75, 0x64, 0x69, 0x79,
+    0x78, 0x4c, 0x74, 0x47, 0x55, 0x50, 0x4d, 0x78, 0x78, 0x59, 0x38, 0x42,
+    0x71, 0x48, 0x54, 0x72, 0x39, 0x58, 0x67, 0x6e, 0x32, 0x75, 0x66, 0x33,
+    0x5a, 0x6b, 0x50, 0x7a, 0x6e, 0x6f, 0x4d, 0x2b, 0x49, 0x4b, 0x72, 0x44,
+    0x4e, 0x57, 0x43, 0x52, 0x7a, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74,
+    0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76,
+    0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x4f, 0x3d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
+    0x2e, 0x6e, 0x65, 0x74, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e,
+    0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
+    0x43, 0x50, 0x53, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20,
+    0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d,
+    0x69, 0x74, 0x73, 0x20, 0x6c, 0x69, 0x61, 0x62, 0x2e, 0x29, 0x2f, 0x28,
+    0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72,
+    0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x4c, 0x69, 0x6d, 0x69,
+    0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73,
+    0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
+    0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x45, 0x6e,
+    0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x4f, 0x55,
+    0x3d, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
+    0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x69, 0x6e, 0x63,
+    0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x2e,
+    0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x20, 0x6c, 0x69, 0x61,
+    0x62, 0x2e, 0x29, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39,
+    0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74,
+    0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x4c,
+    0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x45, 0x6e, 0x74, 0x72, 0x75,
+    0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x22,
+    0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x39,
+    0x32, 0x37, 0x36, 0x35, 0x30, 0x33, 0x37, 0x31, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x64, 0x66, 0x3a, 0x66, 0x32, 0x3a, 0x38, 0x30,
+    0x3a, 0x37, 0x33, 0x3a, 0x63, 0x63, 0x3a, 0x66, 0x31, 0x3a, 0x65, 0x36,
+    0x3a, 0x36, 0x31, 0x3a, 0x37, 0x33, 0x3a, 0x66, 0x63, 0x3a, 0x66, 0x35,
+    0x3a, 0x34, 0x32, 0x3a, 0x65, 0x39, 0x3a, 0x63, 0x35, 0x3a, 0x37, 0x63,
+    0x3a, 0x65, 0x65, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x39, 0x39, 0x3a, 0x61, 0x36, 0x3a, 0x39, 0x62, 0x3a, 0x65, 0x36, 0x3a,
+    0x31, 0x61, 0x3a, 0x66, 0x65, 0x3a, 0x38, 0x38, 0x3a, 0x36, 0x62, 0x3a,
+    0x34, 0x64, 0x3a, 0x32, 0x62, 0x3a, 0x38, 0x32, 0x3a, 0x30, 0x30, 0x3a,
+    0x37, 0x63, 0x3a, 0x62, 0x38, 0x3a, 0x35, 0x34, 0x3a, 0x66, 0x63, 0x3a,
+    0x33, 0x31, 0x3a, 0x37, 0x65, 0x3a, 0x31, 0x35, 0x3a, 0x33, 0x39, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x36, 0x32,
+    0x3a, 0x66, 0x32, 0x3a, 0x34, 0x30, 0x3a, 0x32, 0x37, 0x3a, 0x38, 0x63,
+    0x3a, 0x35, 0x36, 0x3a, 0x34, 0x63, 0x3a, 0x34, 0x64, 0x3a, 0x64, 0x38,
+    0x3a, 0x62, 0x66, 0x3a, 0x37, 0x64, 0x3a, 0x39, 0x64, 0x3a, 0x34, 0x66,
+    0x3a, 0x36, 0x66, 0x3a, 0x33, 0x36, 0x3a, 0x36, 0x65, 0x3a, 0x61, 0x38,
+    0x3a, 0x39, 0x34, 0x3a, 0x64, 0x32, 0x3a, 0x32, 0x66, 0x3a, 0x35, 0x66,
+    0x3a, 0x33, 0x34, 0x3a, 0x64, 0x39, 0x3a, 0x38, 0x39, 0x3a, 0x61, 0x39,
+    0x3a, 0x38, 0x33, 0x3a, 0x61, 0x63, 0x3a, 0x65, 0x63, 0x3a, 0x32, 0x66,
+    0x3a, 0x66, 0x66, 0x3a, 0x65, 0x64, 0x3a, 0x35, 0x30, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x32, 0x44, 0x43, 0x43, 0x42, 0x45,
+    0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x45, 0x4e, 0x30,
+    0x72, 0x53, 0x51, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44,
+    0x43, 0x42, 0x77, 0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x0a, 0x56, 0x56, 0x4d, 0x78, 0x46,
+    0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x43,
+    0x30, 0x56, 0x75, 0x64, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x75, 0x62,
+    0x6d, 0x56, 0x30, 0x4d, 0x54, 0x73, 0x77, 0x4f, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x4c, 0x45, 0x7a, 0x4a, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5a,
+    0x57, 0x35, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x75, 0x0a,
+    0x5a, 0x58, 0x51, 0x76, 0x51, 0x31, 0x42, 0x54, 0x49, 0x47, 0x6c, 0x75,
+    0x59, 0x32, 0x39, 0x79, 0x63, 0x43, 0x34, 0x67, 0x59, 0x6e, 0x6b, 0x67,
+    0x63, 0x6d, 0x56, 0x6d, 0x4c, 0x69, 0x41, 0x6f, 0x62, 0x47, 0x6c, 0x74,
+    0x61, 0x58, 0x52, 0x7a, 0x49, 0x47, 0x78, 0x70, 0x59, 0x57, 0x49, 0x75,
+    0x4b, 0x54, 0x45, 0x6c, 0x4d, 0x43, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x78, 0x4d, 0x63, 0x0a, 0x4b, 0x47, 0x4d, 0x70, 0x49, 0x44, 0x45,
+    0x35, 0x4f, 0x54, 0x6b, 0x67, 0x52, 0x57, 0x35, 0x30, 0x63, 0x6e, 0x56,
+    0x7a, 0x64, 0x43, 0x35, 0x75, 0x5a, 0x58, 0x51, 0x67, 0x54, 0x47, 0x6c,
+    0x74, 0x61, 0x58, 0x52, 0x6c, 0x5a, 0x44, 0x45, 0x36, 0x4d, 0x44, 0x67,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x78, 0x52, 0x57, 0x35,
+    0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x75, 0x0a, 0x5a, 0x58,
+    0x51, 0x67, 0x55, 0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, 0x6c, 0x49, 0x46,
+    0x4e, 0x6c, 0x63, 0x6e, 0x5a, 0x6c, 0x63, 0x69, 0x42, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57,
+    0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d,
+    0x6c, 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x35, 0x4f, 0x54,
+    0x41, 0x31, 0x0a, 0x4d, 0x6a, 0x55, 0x78, 0x4e, 0x6a, 0x41, 0x35, 0x4e,
+    0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x78, 0x4f, 0x54, 0x41, 0x31, 0x4d,
+    0x6a, 0x55, 0x78, 0x4e, 0x6a, 0x4d, 0x35, 0x4e, 0x44, 0x42, 0x61, 0x4d,
+    0x49, 0x48, 0x44, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x55, 0x4d,
+    0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x43, 0x68, 0x4d, 0x4c,
+    0x52, 0x57, 0x35, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x75,
+    0x5a, 0x58, 0x51, 0x78, 0x4f, 0x7a, 0x41, 0x35, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x73, 0x54, 0x4d, 0x6e, 0x64, 0x33, 0x64, 0x79, 0x35, 0x6c,
+    0x62, 0x6e, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x35, 0x6c,
+    0x64, 0x43, 0x39, 0x44, 0x55, 0x46, 0x4d, 0x67, 0x61, 0x57, 0x35, 0x6a,
+    0x0a, 0x62, 0x33, 0x4a, 0x77, 0x4c, 0x69, 0x42, 0x69, 0x65, 0x53, 0x42,
+    0x79, 0x5a, 0x57, 0x59, 0x75, 0x49, 0x43, 0x68, 0x73, 0x61, 0x57, 0x31,
+    0x70, 0x64, 0x48, 0x4d, 0x67, 0x62, 0x47, 0x6c, 0x68, 0x59, 0x69, 0x34,
+    0x70, 0x4d, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4c, 0x45, 0x78, 0x77, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x54, 0x6b,
+    0x35, 0x4f, 0x53, 0x42, 0x46, 0x0a, 0x62, 0x6e, 0x52, 0x79, 0x64, 0x58,
+    0x4e, 0x30, 0x4c, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42, 0x4d, 0x61, 0x57,
+    0x31, 0x70, 0x64, 0x47, 0x56, 0x6b, 0x4d, 0x54, 0x6f, 0x77, 0x4f, 0x41,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x7a, 0x46, 0x46, 0x62, 0x6e,
+    0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x35, 0x6c, 0x64, 0x43,
+    0x42, 0x54, 0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67, 0x0a, 0x55,
+    0x32, 0x56, 0x79, 0x64, 0x6d, 0x56, 0x79, 0x49, 0x45, 0x4e, 0x6c, 0x63,
+    0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62,
+    0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61,
+    0x58, 0x52, 0x35, 0x4d, 0x49, 0x47, 0x64, 0x4d, 0x41, 0x30, 0x47, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41,
+    0x51, 0x55, 0x41, 0x0a, 0x41, 0x34, 0x47, 0x4c, 0x41, 0x44, 0x43, 0x42,
+    0x68, 0x77, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x4e, 0x4b, 0x49, 0x4d, 0x30,
+    0x56, 0x42, 0x75, 0x4a, 0x38, 0x77, 0x2b, 0x76, 0x4e, 0x35, 0x45, 0x78,
+    0x2f, 0x36, 0x38, 0x78, 0x59, 0x4d, 0x6d, 0x6f, 0x36, 0x4c, 0x49, 0x51,
+    0x61, 0x4f, 0x32, 0x66, 0x35, 0x35, 0x4d, 0x32, 0x38, 0x51, 0x70, 0x6b,
+    0x75, 0x30, 0x66, 0x31, 0x42, 0x42, 0x63, 0x2f, 0x0a, 0x49, 0x30, 0x64,
+    0x4e, 0x78, 0x53, 0x63, 0x5a, 0x67, 0x53, 0x59, 0x4d, 0x56, 0x48, 0x49,
+    0x4e, 0x69, 0x43, 0x33, 0x5a, 0x48, 0x35, 0x6f, 0x53, 0x6e, 0x37, 0x79,
+    0x7a, 0x63, 0x64, 0x4f, 0x41, 0x47, 0x54, 0x39, 0x48, 0x5a, 0x6e, 0x75,
+    0x4d, 0x4e, 0x53, 0x6a, 0x53, 0x75, 0x51, 0x72, 0x66, 0x4a, 0x4e, 0x71,
+    0x63, 0x31, 0x6c, 0x42, 0x35, 0x67, 0x58, 0x70, 0x61, 0x30, 0x7a, 0x66,
+    0x33, 0x0a, 0x77, 0x6b, 0x72, 0x59, 0x4b, 0x5a, 0x49, 0x6d, 0x5a, 0x4e,
+    0x48, 0x6b, 0x6d, 0x47, 0x77, 0x36, 0x41, 0x49, 0x72, 0x31, 0x4e, 0x4a,
+    0x74, 0x6c, 0x2b, 0x4f, 0x33, 0x6a, 0x45, 0x50, 0x2f, 0x39, 0x75, 0x45,
+    0x6c, 0x59, 0x33, 0x4b, 0x44, 0x65, 0x67, 0x6a, 0x6c, 0x72, 0x67, 0x62,
+    0x45, 0x57, 0x47, 0x57, 0x47, 0x35, 0x56, 0x4c, 0x62, 0x6d, 0x51, 0x77,
+    0x49, 0x42, 0x41, 0x36, 0x4f, 0x43, 0x0a, 0x41, 0x64, 0x63, 0x77, 0x67,
+    0x67, 0x48, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x43, 0x57, 0x43, 0x47, 0x53,
+    0x41, 0x47, 0x47, 0x2b, 0x45, 0x49, 0x42, 0x41, 0x51, 0x51, 0x45, 0x41,
+    0x77, 0x49, 0x41, 0x42, 0x7a, 0x43, 0x43, 0x41, 0x52, 0x6b, 0x47, 0x41,
+    0x31, 0x55, 0x64, 0x48, 0x77, 0x53, 0x43, 0x41, 0x52, 0x41, 0x77, 0x67,
+    0x67, 0x45, 0x4d, 0x4d, 0x49, 0x48, 0x65, 0x6f, 0x49, 0x48, 0x62, 0x0a,
+    0x6f, 0x49, 0x48, 0x59, 0x70, 0x49, 0x48, 0x56, 0x4d, 0x49, 0x48, 0x53,
+    0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
+    0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x55, 0x4d, 0x42, 0x49, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4c, 0x52, 0x57, 0x35, 0x30,
+    0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x75, 0x5a, 0x58, 0x51, 0x78,
+    0x4f, 0x7a, 0x41, 0x35, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73,
+    0x54, 0x4d, 0x6e, 0x64, 0x33, 0x64, 0x79, 0x35, 0x6c, 0x62, 0x6e, 0x52,
+    0x79, 0x64, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x39,
+    0x44, 0x55, 0x46, 0x4d, 0x67, 0x61, 0x57, 0x35, 0x6a, 0x62, 0x33, 0x4a,
+    0x77, 0x4c, 0x69, 0x42, 0x69, 0x65, 0x53, 0x42, 0x79, 0x5a, 0x57, 0x59,
+    0x75, 0x49, 0x43, 0x68, 0x73, 0x61, 0x57, 0x31, 0x70, 0x0a, 0x64, 0x48,
+    0x4d, 0x67, 0x62, 0x47, 0x6c, 0x68, 0x59, 0x69, 0x34, 0x70, 0x4d, 0x53,
+    0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78,
+    0x77, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x54, 0x6b, 0x35, 0x4f, 0x53,
+    0x42, 0x46, 0x62, 0x6e, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4c, 0x6d,
+    0x35, 0x6c, 0x64, 0x43, 0x42, 0x4d, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47,
+    0x56, 0x6b, 0x0a, 0x4d, 0x54, 0x6f, 0x77, 0x4f, 0x41, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x44, 0x45, 0x7a, 0x46, 0x46, 0x62, 0x6e, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42, 0x54, 0x5a,
+    0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67, 0x55, 0x32, 0x56, 0x79, 0x64,
+    0x6d, 0x56, 0x79, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a,
+    0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x0a, 0x62, 0x32, 0x34, 0x67,
+    0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35,
+    0x4d, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44,
+    0x45, 0x77, 0x52, 0x44, 0x55, 0x6b, 0x77, 0x78, 0x4d, 0x43, 0x6d, 0x67,
+    0x4a, 0x36, 0x41, 0x6c, 0x68, 0x69, 0x4e, 0x6f, 0x64, 0x48, 0x52, 0x77,
+    0x4f, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6d, 0x56, 0x75,
+    0x0a, 0x64, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x75, 0x62, 0x6d, 0x56,
+    0x30, 0x4c, 0x30, 0x4e, 0x53, 0x54, 0x43, 0x39, 0x75, 0x5a, 0x58, 0x51,
+    0x78, 0x4c, 0x6d, 0x4e, 0x79, 0x62, 0x44, 0x41, 0x72, 0x42, 0x67, 0x4e,
+    0x56, 0x48, 0x52, 0x41, 0x45, 0x4a, 0x44, 0x41, 0x69, 0x67, 0x41, 0x38,
+    0x78, 0x4f, 0x54, 0x6b, 0x35, 0x4d, 0x44, 0x55, 0x79, 0x4e, 0x54, 0x45,
+    0x32, 0x4d, 0x44, 0x6b, 0x30, 0x0a, 0x4d, 0x46, 0x71, 0x42, 0x44, 0x7a,
+    0x49, 0x77, 0x4d, 0x54, 0x6b, 0x77, 0x4e, 0x54, 0x49, 0x31, 0x4d, 0x54,
+    0x59, 0x77, 0x4f, 0x54, 0x51, 0x77, 0x57, 0x6a, 0x41, 0x4c, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x51, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51,
+    0x59, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42, 0x42,
+    0x67, 0x77, 0x46, 0x6f, 0x41, 0x55, 0x38, 0x42, 0x64, 0x69, 0x0a, 0x45,
+    0x31, 0x55, 0x39, 0x73, 0x2f, 0x38, 0x4b, 0x41, 0x47, 0x76, 0x37, 0x55,
+    0x49, 0x53, 0x58, 0x38, 0x2b, 0x31, 0x69, 0x30, 0x42, 0x6f, 0x77, 0x48,
+    0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46,
+    0x50, 0x41, 0x58, 0x59, 0x68, 0x4e, 0x56, 0x50, 0x62, 0x50, 0x2f, 0x43,
+    0x67, 0x42, 0x72, 0x2b, 0x31, 0x43, 0x45, 0x6c, 0x2f, 0x50, 0x74, 0x59,
+    0x74, 0x41, 0x61, 0x0a, 0x4d, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x64,
+    0x45, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77,
+    0x47, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x5a, 0x39,
+    0x42, 0x30, 0x45, 0x41, 0x42, 0x41, 0x77, 0x77, 0x43, 0x68, 0x73, 0x45,
+    0x56, 0x6a, 0x51, 0x75, 0x4d, 0x41, 0x4d, 0x43, 0x42, 0x4a, 0x41, 0x77,
+    0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x0a, 0x68, 0x76, 0x63,
+    0x4e, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x59, 0x45,
+    0x41, 0x6b, 0x4e, 0x77, 0x77, 0x41, 0x76, 0x70, 0x6b, 0x64, 0x4d, 0x4b,
+    0x6e, 0x43, 0x71, 0x56, 0x38, 0x49, 0x59, 0x30, 0x30, 0x46, 0x36, 0x6a,
+    0x37, 0x52, 0x77, 0x37, 0x2f, 0x4a, 0x58, 0x79, 0x4e, 0x45, 0x77, 0x72,
+    0x37, 0x35, 0x4a, 0x69, 0x31, 0x37, 0x34, 0x7a, 0x34, 0x78, 0x52, 0x41,
+    0x4e, 0x0a, 0x39, 0x35, 0x4b, 0x2b, 0x38, 0x63, 0x50, 0x56, 0x31, 0x5a,
+    0x56, 0x71, 0x42, 0x4c, 0x73, 0x73, 0x7a, 0x69, 0x59, 0x32, 0x5a, 0x63,
+    0x67, 0x78, 0x78, 0x75, 0x66, 0x75, 0x50, 0x2b, 0x4e, 0x58, 0x64, 0x59,
+    0x52, 0x36, 0x45, 0x65, 0x39, 0x47, 0x54, 0x78, 0x6a, 0x30, 0x30, 0x35,
+    0x69, 0x37, 0x71, 0x49, 0x63, 0x79, 0x75, 0x6e, 0x4c, 0x32, 0x50, 0x4f,
+    0x49, 0x39, 0x6e, 0x39, 0x63, 0x64, 0x0a, 0x32, 0x63, 0x4e, 0x67, 0x51,
+    0x34, 0x78, 0x59, 0x44, 0x69, 0x4b, 0x57, 0x4c, 0x32, 0x4b, 0x6a, 0x4c,
+    0x42, 0x2b, 0x36, 0x72, 0x51, 0x58, 0x76, 0x71, 0x7a, 0x4a, 0x34, 0x68,
+    0x36, 0x42, 0x55, 0x63, 0x78, 0x6d, 0x31, 0x58, 0x41, 0x58, 0x35, 0x55,
+    0x6a, 0x35, 0x74, 0x4c, 0x55, 0x55, 0x4c, 0x39, 0x77, 0x71, 0x54, 0x36,
+    0x75, 0x30, 0x47, 0x2b, 0x62, 0x49, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20,
+    0x28, 0x32, 0x30, 0x34, 0x38, 0x29, 0x20, 0x4f, 0x3d, 0x45, 0x6e, 0x74,
+    0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x4f, 0x55, 0x3d,
+    0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e,
+    0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38,
+    0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20,
+    0x72, 0x65, 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73,
+    0x20, 0x6c, 0x69, 0x61, 0x62, 0x2e, 0x29, 0x2f, 0x28, 0x63, 0x29, 0x20,
+    0x31, 0x39, 0x39, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
+    0x2e, 0x6e, 0x65, 0x74, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64,
+    0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e,
+    0x65, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x28, 0x32, 0x30, 0x34, 0x38, 0x29, 0x20, 0x4f, 0x3d,
+    0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20,
+    0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75,
+    0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32,
+    0x30, 0x34, 0x38, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20,
+    0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d,
+    0x69, 0x74, 0x73, 0x20, 0x6c, 0x69, 0x61, 0x62, 0x2e, 0x29, 0x2f, 0x28,
+    0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72,
+    0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x4c, 0x69, 0x6d, 0x69,
+    0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65,
+    0x74, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x32, 0x30,
+    0x34, 0x38, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x39, 0x34, 0x36, 0x30, 0x35,
+    0x39, 0x36, 0x32, 0x32, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x62, 0x61, 0x3a, 0x32, 0x31, 0x3a, 0x65, 0x61, 0x3a, 0x32, 0x30, 0x3a,
+    0x64, 0x36, 0x3a, 0x64, 0x64, 0x3a, 0x64, 0x62, 0x3a, 0x38, 0x66, 0x3a,
+    0x63, 0x31, 0x3a, 0x35, 0x37, 0x3a, 0x38, 0x62, 0x3a, 0x34, 0x30, 0x3a,
+    0x61, 0x64, 0x3a, 0x61, 0x31, 0x3a, 0x66, 0x63, 0x3a, 0x66, 0x63, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x30, 0x3a, 0x31,
+    0x64, 0x3a, 0x36, 0x32, 0x3a, 0x64, 0x30, 0x3a, 0x37, 0x62, 0x3a, 0x34,
+    0x34, 0x3a, 0x39, 0x64, 0x3a, 0x35, 0x63, 0x3a, 0x35, 0x63, 0x3a, 0x30,
+    0x33, 0x3a, 0x35, 0x63, 0x3a, 0x39, 0x38, 0x3a, 0x65, 0x61, 0x3a, 0x36,
+    0x31, 0x3a, 0x66, 0x61, 0x3a, 0x34, 0x34, 0x3a, 0x33, 0x63, 0x3a, 0x32,
+    0x61, 0x3a, 0x35, 0x38, 0x3a, 0x66, 0x65, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x31, 0x3a, 0x63, 0x33, 0x3a,
+    0x33, 0x39, 0x3a, 0x65, 0x61, 0x3a, 0x32, 0x37, 0x3a, 0x38, 0x34, 0x3a,
+    0x65, 0x62, 0x3a, 0x38, 0x37, 0x3a, 0x30, 0x66, 0x3a, 0x39, 0x33, 0x3a,
+    0x34, 0x66, 0x3a, 0x63, 0x35, 0x3a, 0x36, 0x33, 0x3a, 0x34, 0x65, 0x3a,
+    0x34, 0x61, 0x3a, 0x61, 0x39, 0x3a, 0x61, 0x64, 0x3a, 0x35, 0x35, 0x3a,
+    0x30, 0x35, 0x3a, 0x30, 0x31, 0x3a, 0x36, 0x34, 0x3a, 0x30, 0x31, 0x3a,
+    0x66, 0x32, 0x3a, 0x36, 0x34, 0x3a, 0x36, 0x35, 0x3a, 0x64, 0x33, 0x3a,
+    0x37, 0x61, 0x3a, 0x35, 0x37, 0x3a, 0x34, 0x36, 0x3a, 0x36, 0x33, 0x3a,
+    0x33, 0x35, 0x3a, 0x39, 0x66, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42,
+    0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49,
+    0x49, 0x45, 0x58, 0x44, 0x43, 0x43, 0x41, 0x30, 0x53, 0x67, 0x41, 0x77,
+    0x49, 0x42, 0x41, 0x67, 0x49, 0x45, 0x4f, 0x47, 0x4f, 0x35, 0x5a, 0x6a,
+    0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77,
+    0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x74, 0x44,
+    0x45, 0x55, 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4c, 0x0a, 0x52, 0x57, 0x35, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64,
+    0x43, 0x35, 0x75, 0x5a, 0x58, 0x51, 0x78, 0x51, 0x44, 0x41, 0x2b, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x55, 0x4e, 0x33, 0x64, 0x33, 0x64,
+    0x79, 0x35, 0x6c, 0x62, 0x6e, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4c,
+    0x6d, 0x35, 0x6c, 0x64, 0x43, 0x39, 0x44, 0x55, 0x46, 0x4e, 0x66, 0x4d,
+    0x6a, 0x41, 0x30, 0x4f, 0x43, 0x42, 0x70, 0x0a, 0x62, 0x6d, 0x4e, 0x76,
+    0x63, 0x6e, 0x41, 0x75, 0x49, 0x47, 0x4a, 0x35, 0x49, 0x48, 0x4a, 0x6c,
+    0x5a, 0x69, 0x34, 0x67, 0x4b, 0x47, 0x78, 0x70, 0x62, 0x57, 0x6c, 0x30,
+    0x63, 0x79, 0x42, 0x73, 0x61, 0x57, 0x46, 0x69, 0x4c, 0x69, 0x6b, 0x78,
+    0x4a, 0x54, 0x41, 0x6a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54,
+    0x48, 0x43, 0x68, 0x6a, 0x4b, 0x53, 0x41, 0x78, 0x4f, 0x54, 0x6b, 0x35,
+    0x0a, 0x49, 0x45, 0x56, 0x75, 0x64, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51,
+    0x75, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6c,
+    0x30, 0x5a, 0x57, 0x51, 0x78, 0x4d, 0x7a, 0x41, 0x78, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x4d, 0x54, 0x4b, 0x6b, 0x56, 0x75, 0x64, 0x48, 0x4a,
+    0x31, 0x63, 0x33, 0x51, 0x75, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x45, 0x4e,
+    0x6c, 0x63, 0x6e, 0x52, 0x70, 0x0a, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58,
+    0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47,
+    0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x43, 0x67, 0x79, 0x4d, 0x44,
+    0x51, 0x34, 0x4b, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x35, 0x4f, 0x54,
+    0x45, 0x79, 0x4d, 0x6a, 0x51, 0x78, 0x4e, 0x7a, 0x55, 0x77, 0x4e, 0x54,
+    0x46, 0x61, 0x46, 0x77, 0x30, 0x78, 0x4f, 0x54, 0x45, 0x79, 0x0a, 0x4d,
+    0x6a, 0x51, 0x78, 0x4f, 0x44, 0x49, 0x77, 0x4e, 0x54, 0x46, 0x61, 0x4d,
+    0x49, 0x47, 0x30, 0x4d, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x4b, 0x45, 0x77, 0x74, 0x46, 0x62, 0x6e, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x35, 0x6c, 0x64, 0x44, 0x46, 0x41, 0x4d,
+    0x44, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x51, 0x33, 0x64,
+    0x33, 0x64, 0x33, 0x0a, 0x4c, 0x6d, 0x56, 0x75, 0x64, 0x48, 0x4a, 0x31,
+    0x63, 0x33, 0x51, 0x75, 0x62, 0x6d, 0x56, 0x30, 0x4c, 0x30, 0x4e, 0x51,
+    0x55, 0x31, 0x38, 0x79, 0x4d, 0x44, 0x51, 0x34, 0x49, 0x47, 0x6c, 0x75,
+    0x59, 0x32, 0x39, 0x79, 0x63, 0x43, 0x34, 0x67, 0x59, 0x6e, 0x6b, 0x67,
+    0x63, 0x6d, 0x56, 0x6d, 0x4c, 0x69, 0x41, 0x6f, 0x62, 0x47, 0x6c, 0x74,
+    0x61, 0x58, 0x52, 0x7a, 0x49, 0x47, 0x78, 0x70, 0x0a, 0x59, 0x57, 0x49,
+    0x75, 0x4b, 0x54, 0x45, 0x6c, 0x4d, 0x43, 0x4d, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x78, 0x4d, 0x63, 0x4b, 0x47, 0x4d, 0x70, 0x49, 0x44, 0x45,
+    0x35, 0x4f, 0x54, 0x6b, 0x67, 0x52, 0x57, 0x35, 0x30, 0x63, 0x6e, 0x56,
+    0x7a, 0x64, 0x43, 0x35, 0x75, 0x5a, 0x58, 0x51, 0x67, 0x54, 0x47, 0x6c,
+    0x74, 0x61, 0x58, 0x52, 0x6c, 0x5a, 0x44, 0x45, 0x7a, 0x4d, 0x44, 0x45,
+    0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x71, 0x52, 0x57,
+    0x35, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x75, 0x5a, 0x58,
+    0x51, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57,
+    0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58,
+    0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x4b, 0x44,
+    0x49, 0x77, 0x4e, 0x44, 0x67, 0x70, 0x0a, 0x4d, 0x49, 0x49, 0x42, 0x49,
+    0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41,
+    0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41,
+    0x51, 0x45, 0x41, 0x72, 0x55, 0x31, 0x4c, 0x71, 0x52, 0x4b, 0x47, 0x73,
+    0x75, 0x71, 0x6a, 0x49, 0x41, 0x63, 0x56, 0x46, 0x6d, 0x51, 0x71, 0x0a,
+    0x4b, 0x30, 0x76, 0x52, 0x76, 0x77, 0x74, 0x4b, 0x54, 0x59, 0x37, 0x74,
+    0x67, 0x48, 0x61, 0x6c, 0x5a, 0x37, 0x64, 0x34, 0x51, 0x4d, 0x42, 0x7a,
+    0x51, 0x73, 0x68, 0x6f, 0x77, 0x4e, 0x74, 0x54, 0x4b, 0x39, 0x31, 0x65,
+    0x75, 0x48, 0x61, 0x59, 0x4e, 0x5a, 0x4f, 0x4c, 0x47, 0x70, 0x31, 0x38,
+    0x45, 0x7a, 0x6f, 0x4f, 0x48, 0x31, 0x75, 0x33, 0x48, 0x73, 0x2f, 0x6c,
+    0x4a, 0x42, 0x51, 0x65, 0x0a, 0x73, 0x59, 0x47, 0x70, 0x6a, 0x58, 0x32,
+    0x34, 0x7a, 0x47, 0x74, 0x4c, 0x41, 0x2f, 0x45, 0x43, 0x44, 0x4e, 0x79,
+    0x72, 0x70, 0x55, 0x41, 0x6b, 0x41, 0x48, 0x39, 0x30, 0x6c, 0x4b, 0x47,
+    0x64, 0x43, 0x43, 0x6d, 0x7a, 0x69, 0x41, 0x76, 0x31, 0x68, 0x33, 0x65,
+    0x64, 0x56, 0x63, 0x33, 0x6b, 0x77, 0x33, 0x37, 0x58, 0x61, 0x6d, 0x53,
+    0x72, 0x68, 0x52, 0x53, 0x47, 0x6c, 0x56, 0x75, 0x58, 0x0a, 0x4d, 0x6c,
+    0x42, 0x76, 0x50, 0x63, 0x69, 0x36, 0x5a, 0x67, 0x7a, 0x6a, 0x2f, 0x4c,
+    0x32, 0x34, 0x53, 0x63, 0x46, 0x32, 0x69, 0x55, 0x6b, 0x5a, 0x2f, 0x63,
+    0x43, 0x6f, 0x76, 0x59, 0x6d, 0x6a, 0x5a, 0x79, 0x2f, 0x47, 0x6e, 0x37,
+    0x78, 0x78, 0x47, 0x57, 0x43, 0x34, 0x4c, 0x65, 0x6b, 0x73, 0x79, 0x5a,
+    0x42, 0x32, 0x5a, 0x6e, 0x75, 0x55, 0x34, 0x71, 0x39, 0x34, 0x31, 0x6d,
+    0x56, 0x54, 0x0a, 0x58, 0x54, 0x7a, 0x57, 0x6e, 0x4c, 0x4c, 0x50, 0x4b,
+    0x51, 0x50, 0x35, 0x4c, 0x36, 0x52, 0x51, 0x73, 0x74, 0x52, 0x49, 0x7a,
+    0x67, 0x55, 0x79, 0x56, 0x59, 0x72, 0x39, 0x73, 0x6d, 0x52, 0x4d, 0x44,
+    0x75, 0x53, 0x59, 0x42, 0x33, 0x58, 0x62, 0x66, 0x39, 0x2b, 0x35, 0x43,
+    0x46, 0x56, 0x67, 0x68, 0x54, 0x41, 0x70, 0x2b, 0x58, 0x74, 0x49, 0x70,
+    0x47, 0x6d, 0x47, 0x34, 0x7a, 0x55, 0x2f, 0x0a, 0x48, 0x6f, 0x5a, 0x64,
+    0x65, 0x6e, 0x6f, 0x56, 0x76, 0x65, 0x38, 0x41, 0x6a, 0x68, 0x55, 0x69,
+    0x56, 0x42, 0x63, 0x41, 0x6b, 0x43, 0x61, 0x54, 0x76, 0x41, 0x35, 0x4a,
+    0x61, 0x4a, 0x47, 0x2f, 0x2b, 0x45, 0x66, 0x54, 0x6e, 0x5a, 0x56, 0x43,
+    0x77, 0x51, 0x35, 0x4e, 0x33, 0x32, 0x38, 0x6d, 0x7a, 0x38, 0x4d, 0x59,
+    0x49, 0x57, 0x4a, 0x6d, 0x51, 0x33, 0x44, 0x57, 0x31, 0x63, 0x41, 0x48,
+    0x0a, 0x34, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x33, 0x51,
+    0x77, 0x63, 0x6a, 0x41, 0x52, 0x42, 0x67, 0x6c, 0x67, 0x68, 0x6b, 0x67,
+    0x42, 0x68, 0x76, 0x68, 0x43, 0x41, 0x51, 0x45, 0x45, 0x42, 0x41, 0x4d,
+    0x43, 0x41, 0x41, 0x63, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, 0x41, 0x55, 0x56, 0x65, 0x53,
+    0x42, 0x30, 0x52, 0x47, 0x41, 0x0a, 0x76, 0x74, 0x69, 0x4a, 0x75, 0x51,
+    0x69, 0x6a, 0x4d, 0x66, 0x6d, 0x68, 0x4a, 0x41, 0x6b, 0x57, 0x75, 0x58,
+    0x41, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42,
+    0x59, 0x45, 0x46, 0x46, 0x58, 0x6b, 0x67, 0x64, 0x45, 0x52, 0x67, 0x4c,
+    0x37, 0x59, 0x69, 0x62, 0x6b, 0x49, 0x6f, 0x7a, 0x48, 0x35, 0x6f, 0x53,
+    0x51, 0x4a, 0x46, 0x72, 0x6c, 0x77, 0x4d, 0x42, 0x30, 0x47, 0x0a, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x32, 0x66, 0x51, 0x64, 0x42, 0x41,
+    0x41, 0x51, 0x51, 0x4d, 0x41, 0x34, 0x62, 0x43, 0x46, 0x59, 0x31, 0x4c,
+    0x6a, 0x41, 0x36, 0x4e, 0x43, 0x34, 0x77, 0x41, 0x77, 0x49, 0x45, 0x6b,
+    0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41,
+    0x51, 0x45, 0x41, 0x0a, 0x57, 0x55, 0x65, 0x73, 0x49, 0x59, 0x53, 0x4b,
+    0x46, 0x38, 0x6d, 0x63, 0x69, 0x56, 0x4d, 0x65, 0x75, 0x6f, 0x43, 0x46,
+    0x47, 0x73, 0x59, 0x38, 0x54, 0x6a, 0x36, 0x78, 0x6e, 0x4c, 0x5a, 0x38,
+    0x78, 0x70, 0x4a, 0x64, 0x47, 0x47, 0x51, 0x43, 0x34, 0x39, 0x4d, 0x47,
+    0x43, 0x42, 0x46, 0x68, 0x66, 0x47, 0x50, 0x6a, 0x4b, 0x35, 0x30, 0x78,
+    0x41, 0x33, 0x42, 0x32, 0x30, 0x71, 0x4d, 0x6f, 0x0a, 0x6f, 0x50, 0x53,
+    0x37, 0x6d, 0x6d, 0x4e, 0x7a, 0x37, 0x57, 0x33, 0x6c, 0x4b, 0x74, 0x76,
+    0x74, 0x46, 0x4b, 0x6b, 0x72, 0x78, 0x6a, 0x59, 0x52, 0x30, 0x43, 0x76,
+    0x72, 0x42, 0x34, 0x75, 0x6c, 0x32, 0x70, 0x35, 0x63, 0x47, 0x5a, 0x31,
+    0x57, 0x45, 0x76, 0x56, 0x55, 0x4b, 0x63, 0x67, 0x46, 0x37, 0x62, 0x49,
+    0x53, 0x4b, 0x6f, 0x33, 0x30, 0x41, 0x78, 0x76, 0x2f, 0x35, 0x35, 0x49,
+    0x51, 0x0a, 0x68, 0x37, 0x41, 0x36, 0x74, 0x63, 0x4f, 0x64, 0x42, 0x54,
+    0x63, 0x53, 0x6f, 0x38, 0x66, 0x30, 0x46, 0x62, 0x6e, 0x56, 0x70, 0x44,
+    0x6b, 0x57, 0x6d, 0x31, 0x4d, 0x36, 0x49, 0x35, 0x48, 0x78, 0x71, 0x49,
+    0x4b, 0x69, 0x61, 0x6f, 0x68, 0x6f, 0x77, 0x58, 0x6b, 0x43, 0x49, 0x72,
+    0x79, 0x71, 0x70, 0x74, 0x61, 0x75, 0x33, 0x37, 0x41, 0x55, 0x58, 0x37,
+    0x69, 0x48, 0x30, 0x4e, 0x31, 0x38, 0x0a, 0x66, 0x33, 0x76, 0x2f, 0x72,
+    0x78, 0x7a, 0x50, 0x35, 0x74, 0x73, 0x48, 0x72, 0x56, 0x37, 0x62, 0x68,
+    0x5a, 0x33, 0x51, 0x4b, 0x77, 0x30, 0x7a, 0x32, 0x77, 0x54, 0x52, 0x35,
+    0x6b, 0x6c, 0x41, 0x45, 0x79, 0x74, 0x32, 0x2b, 0x7a, 0x37, 0x70, 0x6e,
+    0x49, 0x6b, 0x50, 0x46, 0x63, 0x34, 0x59, 0x73, 0x49, 0x56, 0x34, 0x49,
+    0x55, 0x39, 0x72, 0x54, 0x77, 0x37, 0x36, 0x4e, 0x6d, 0x66, 0x4e, 0x0a,
+    0x42, 0x2f, 0x4c, 0x2f, 0x43, 0x4e, 0x44, 0x69, 0x33, 0x74, 0x6d, 0x2f,
+    0x4b, 0x71, 0x2b, 0x34, 0x68, 0x34, 0x59, 0x68, 0x50, 0x41, 0x54, 0x4b,
+    0x74, 0x35, 0x52, 0x6f, 0x66, 0x38, 0x38, 0x38, 0x36, 0x5a, 0x6a, 0x58,
+    0x4f, 0x50, 0x2f, 0x73, 0x77, 0x4e, 0x6c, 0x51, 0x38, 0x43, 0x35, 0x4c,
+    0x57, 0x4b, 0x35, 0x47, 0x62, 0x39, 0x41, 0x75, 0x77, 0x32, 0x44, 0x61,
+    0x63, 0x6c, 0x56, 0x79, 0x0a, 0x76, 0x55, 0x78, 0x46, 0x6e, 0x6d, 0x47,
+    0x36, 0x76, 0x34, 0x53, 0x42, 0x6b, 0x67, 0x50, 0x52, 0x30, 0x6d, 0x6c,
+    0x38, 0x78, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49,
+    0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x42, 0x61,
+    0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65,
+    0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x4f, 0x3d, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20,
+    0x4f, 0x55, 0x3d, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,
+    0x20, 0x43, 0x4e, 0x3d, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72,
+    0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d, 0x42, 0x61, 0x6c, 0x74,
+    0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x79, 0x62,
+    0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x0a, 0x23, 0x20, 0x4c, 0x61,
+    0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d,
+    0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x33, 0x33, 0x35, 0x35, 0x34,
+    0x36, 0x31, 0x37, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61,
+    0x63, 0x3a, 0x62, 0x36, 0x3a, 0x39, 0x34, 0x3a, 0x61, 0x35, 0x3a, 0x39,
+    0x63, 0x3a, 0x31, 0x37, 0x3a, 0x65, 0x30, 0x3a, 0x64, 0x37, 0x3a, 0x39,
+    0x31, 0x3a, 0x35, 0x32, 0x3a, 0x39, 0x62, 0x3a, 0x62, 0x31, 0x3a, 0x39,
+    0x37, 0x3a, 0x30, 0x36, 0x3a, 0x61, 0x36, 0x3a, 0x65, 0x34, 0x0a, 0x23,
+    0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x34, 0x3a, 0x64, 0x65,
+    0x3a, 0x32, 0x30, 0x3a, 0x64, 0x30, 0x3a, 0x35, 0x65, 0x3a, 0x36, 0x36,
+    0x3a, 0x66, 0x63, 0x3a, 0x35, 0x33, 0x3a, 0x66, 0x65, 0x3a, 0x31, 0x61,
+    0x3a, 0x35, 0x30, 0x3a, 0x38, 0x38, 0x3a, 0x32, 0x63, 0x3a, 0x37, 0x38,
+    0x3a, 0x64, 0x62, 0x3a, 0x32, 0x38, 0x3a, 0x35, 0x32, 0x3a, 0x63, 0x61,
+    0x3a, 0x65, 0x34, 0x3a, 0x37, 0x34, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x31, 0x36, 0x3a, 0x61, 0x66, 0x3a, 0x35,
+    0x37, 0x3a, 0x61, 0x39, 0x3a, 0x66, 0x36, 0x3a, 0x37, 0x36, 0x3a, 0x62,
+    0x30, 0x3a, 0x61, 0x62, 0x3a, 0x31, 0x32, 0x3a, 0x36, 0x30, 0x3a, 0x39,
+    0x35, 0x3a, 0x61, 0x61, 0x3a, 0x35, 0x65, 0x3a, 0x62, 0x61, 0x3a, 0x64,
+    0x65, 0x3a, 0x66, 0x32, 0x3a, 0x32, 0x61, 0x3a, 0x62, 0x33, 0x3a, 0x31,
+    0x31, 0x3a, 0x31, 0x39, 0x3a, 0x64, 0x36, 0x3a, 0x34, 0x34, 0x3a, 0x61,
+    0x63, 0x3a, 0x39, 0x35, 0x3a, 0x63, 0x64, 0x3a, 0x34, 0x62, 0x3a, 0x39,
+    0x33, 0x3a, 0x64, 0x62, 0x3a, 0x66, 0x33, 0x3a, 0x66, 0x32, 0x3a, 0x36,
+    0x61, 0x3a, 0x65, 0x62, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45,
+    0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43,
+    0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49,
+    0x44, 0x64, 0x7a, 0x43, 0x43, 0x41, 0x6c, 0x2b, 0x67, 0x41, 0x77, 0x49,
+    0x42, 0x41, 0x67, 0x49, 0x45, 0x41, 0x67, 0x41, 0x41, 0x75, 0x54, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x61, 0x4d, 0x51, 0x73,
+    0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a,
+    0x4a, 0x0a, 0x52, 0x54, 0x45, 0x53, 0x4d, 0x42, 0x41, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x43, 0x68, 0x4d, 0x4a, 0x51, 0x6d, 0x46, 0x73, 0x64, 0x47,
+    0x6c, 0x74, 0x62, 0x33, 0x4a, 0x6c, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x77, 0x70, 0x44, 0x65, 0x57,
+    0x4a, 0x6c, 0x63, 0x6c, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4d, 0x53,
+    0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x0a, 0x56, 0x51, 0x51, 0x44, 0x45,
+    0x78, 0x6c, 0x43, 0x59, 0x57, 0x78, 0x30, 0x61, 0x57, 0x31, 0x76, 0x63,
+    0x6d, 0x55, 0x67, 0x51, 0x33, 0x6c, 0x69, 0x5a, 0x58, 0x4a, 0x55, 0x63,
+    0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4d,
+    0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x55, 0x78, 0x4d,
+    0x6a, 0x45, 0x34, 0x4e, 0x44, 0x59, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x0a,
+    0x44, 0x54, 0x49, 0x31, 0x4d, 0x44, 0x55, 0x78, 0x4d, 0x6a, 0x49, 0x7a,
+    0x4e, 0x54, 0x6b, 0x77, 0x4d, 0x46, 0x6f, 0x77, 0x57, 0x6a, 0x45, 0x4c,
+    0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43,
+    0x53, 0x55, 0x55, 0x78, 0x45, 0x6a, 0x41, 0x51, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x6f, 0x54, 0x43, 0x55, 0x4a, 0x68, 0x62, 0x48, 0x52, 0x70,
+    0x62, 0x57, 0x39, 0x79, 0x0a, 0x5a, 0x54, 0x45, 0x54, 0x4d, 0x42, 0x45,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x4b, 0x51, 0x33, 0x6c,
+    0x69, 0x5a, 0x58, 0x4a, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x44, 0x45,
+    0x69, 0x4d, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x5a, 0x51, 0x6d, 0x46, 0x73, 0x64, 0x47, 0x6c, 0x74, 0x62, 0x33, 0x4a,
+    0x6c, 0x49, 0x45, 0x4e, 0x35, 0x59, 0x6d, 0x56, 0x79, 0x0a, 0x56, 0x48,
+    0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x44,
+    0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f,
+    0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51,
+    0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51,
+    0x6f, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4b, 0x4d, 0x45, 0x75, 0x79,
+    0x4b, 0x72, 0x0a, 0x6d, 0x44, 0x31, 0x58, 0x36, 0x43, 0x5a, 0x79, 0x6d,
+    0x72, 0x56, 0x35, 0x31, 0x43, 0x6e, 0x69, 0x34, 0x65, 0x69, 0x56, 0x67,
+    0x4c, 0x47, 0x77, 0x34, 0x31, 0x75, 0x4f, 0x4b, 0x79, 0x6d, 0x61, 0x5a,
+    0x4e, 0x2b, 0x68, 0x58, 0x65, 0x32, 0x77, 0x43, 0x51, 0x56, 0x74, 0x32,
+    0x79, 0x67, 0x75, 0x7a, 0x6d, 0x4b, 0x69, 0x59, 0x76, 0x36, 0x30, 0x69,
+    0x4e, 0x6f, 0x53, 0x36, 0x7a, 0x6a, 0x72, 0x0a, 0x49, 0x5a, 0x33, 0x41,
+    0x51, 0x53, 0x73, 0x42, 0x55, 0x6e, 0x75, 0x49, 0x64, 0x39, 0x4d, 0x63,
+    0x6a, 0x38, 0x65, 0x36, 0x75, 0x59, 0x69, 0x31, 0x61, 0x67, 0x6e, 0x6e,
+    0x63, 0x2b, 0x67, 0x52, 0x51, 0x4b, 0x66, 0x52, 0x7a, 0x4d, 0x70, 0x69,
+    0x6a, 0x53, 0x33, 0x6c, 0x6a, 0x77, 0x75, 0x6d, 0x55, 0x4e, 0x4b, 0x6f,
+    0x55, 0x4d, 0x4d, 0x6f, 0x36, 0x76, 0x57, 0x72, 0x4a, 0x59, 0x65, 0x4b,
+    0x0a, 0x6d, 0x70, 0x59, 0x63, 0x71, 0x57, 0x65, 0x34, 0x50, 0x77, 0x7a,
+    0x56, 0x39, 0x2f, 0x6c, 0x53, 0x45, 0x79, 0x2f, 0x43, 0x47, 0x39, 0x56,
+    0x77, 0x63, 0x50, 0x43, 0x50, 0x77, 0x42, 0x4c, 0x4b, 0x42, 0x73, 0x75,
+    0x61, 0x34, 0x64, 0x6e, 0x4b, 0x4d, 0x33, 0x70, 0x33, 0x31, 0x76, 0x6a,
+    0x73, 0x75, 0x66, 0x46, 0x6f, 0x52, 0x45, 0x4a, 0x49, 0x45, 0x39, 0x4c,
+    0x41, 0x77, 0x71, 0x53, 0x75, 0x0a, 0x58, 0x6d, 0x44, 0x2b, 0x74, 0x71,
+    0x59, 0x46, 0x2f, 0x4c, 0x54, 0x64, 0x42, 0x31, 0x6b, 0x43, 0x31, 0x46,
+    0x6b, 0x59, 0x6d, 0x47, 0x50, 0x31, 0x70, 0x57, 0x50, 0x67, 0x6b, 0x41,
+    0x78, 0x39, 0x58, 0x62, 0x49, 0x47, 0x65, 0x76, 0x4f, 0x46, 0x36, 0x75,
+    0x76, 0x55, 0x41, 0x36, 0x35, 0x65, 0x68, 0x44, 0x35, 0x66, 0x2f, 0x78,
+    0x58, 0x74, 0x61, 0x62, 0x7a, 0x35, 0x4f, 0x54, 0x5a, 0x79, 0x0a, 0x64,
+    0x63, 0x39, 0x33, 0x55, 0x6b, 0x33, 0x7a, 0x79, 0x5a, 0x41, 0x73, 0x75,
+    0x54, 0x33, 0x6c, 0x79, 0x53, 0x4e, 0x54, 0x50, 0x78, 0x38, 0x6b, 0x6d,
+    0x43, 0x46, 0x63, 0x42, 0x35, 0x6b, 0x70, 0x76, 0x63, 0x59, 0x36, 0x37,
+    0x4f, 0x64, 0x75, 0x68, 0x6a, 0x70, 0x72, 0x6c, 0x33, 0x52, 0x6a, 0x4d,
+    0x37, 0x31, 0x6f, 0x47, 0x44, 0x48, 0x77, 0x65, 0x49, 0x31, 0x32, 0x76,
+    0x2f, 0x79, 0x65, 0x0a, 0x6a, 0x6c, 0x30, 0x71, 0x68, 0x71, 0x64, 0x4e,
+    0x6b, 0x4e, 0x77, 0x6e, 0x47, 0x6a, 0x6b, 0x43, 0x41, 0x77, 0x45, 0x41,
+    0x41, 0x61, 0x4e, 0x46, 0x4d, 0x45, 0x4d, 0x77, 0x48, 0x51, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4f, 0x57, 0x64,
+    0x57, 0x54, 0x43, 0x43, 0x52, 0x31, 0x6a, 0x4d, 0x72, 0x50, 0x6f, 0x49,
+    0x56, 0x44, 0x61, 0x47, 0x65, 0x7a, 0x71, 0x31, 0x0a, 0x42, 0x45, 0x33,
+    0x77, 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45,
+    0x42, 0x2f, 0x77, 0x51, 0x49, 0x4d, 0x41, 0x59, 0x42, 0x41, 0x66, 0x38,
+    0x43, 0x41, 0x51, 0x4d, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x50, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45,
+    0x47, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62,
+    0x33, 0x0a, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34,
+    0x49, 0x42, 0x41, 0x51, 0x43, 0x46, 0x44, 0x46, 0x32, 0x4f, 0x35, 0x47,
+    0x39, 0x52, 0x61, 0x45, 0x49, 0x46, 0x6f, 0x4e, 0x32, 0x37, 0x54, 0x79,
+    0x63, 0x6c, 0x68, 0x41, 0x4f, 0x39, 0x39, 0x32, 0x54, 0x39, 0x4c, 0x64,
+    0x63, 0x77, 0x34, 0x36, 0x51, 0x51, 0x46, 0x2b, 0x76, 0x61, 0x4b, 0x53,
+    0x6d, 0x32, 0x65, 0x54, 0x39, 0x32, 0x0a, 0x39, 0x68, 0x6b, 0x54, 0x49,
+    0x37, 0x67, 0x51, 0x43, 0x76, 0x6c, 0x59, 0x70, 0x4e, 0x52, 0x68, 0x63,
+    0x4c, 0x30, 0x45, 0x59, 0x57, 0x6f, 0x53, 0x69, 0x68, 0x66, 0x56, 0x43,
+    0x72, 0x33, 0x46, 0x76, 0x44, 0x42, 0x38, 0x31, 0x75, 0x6b, 0x4d, 0x4a,
+    0x59, 0x32, 0x47, 0x51, 0x45, 0x2f, 0x73, 0x7a, 0x4b, 0x4e, 0x2b, 0x4f,
+    0x4d, 0x59, 0x33, 0x45, 0x55, 0x2f, 0x74, 0x33, 0x57, 0x67, 0x78, 0x0a,
+    0x6a, 0x6b, 0x7a, 0x53, 0x73, 0x77, 0x46, 0x30, 0x37, 0x72, 0x35, 0x31,
+    0x58, 0x67, 0x64, 0x49, 0x47, 0x6e, 0x39, 0x77, 0x2f, 0x78, 0x5a, 0x63,
+    0x68, 0x4d, 0x42, 0x35, 0x68, 0x62, 0x67, 0x46, 0x2f, 0x58, 0x2b, 0x2b,
+    0x5a, 0x52, 0x47, 0x6a, 0x44, 0x38, 0x41, 0x43, 0x74, 0x50, 0x68, 0x53,
+    0x4e, 0x7a, 0x6b, 0x45, 0x31, 0x61, 0x6b, 0x78, 0x65, 0x68, 0x69, 0x2f,
+    0x6f, 0x43, 0x72, 0x30, 0x0a, 0x45, 0x70, 0x6e, 0x33, 0x6f, 0x30, 0x57,
+    0x43, 0x34, 0x7a, 0x78, 0x65, 0x39, 0x5a, 0x32, 0x65, 0x74, 0x63, 0x69,
+    0x65, 0x66, 0x43, 0x37, 0x49, 0x70, 0x4a, 0x35, 0x4f, 0x43, 0x42, 0x52,
+    0x4c, 0x62, 0x66, 0x31, 0x77, 0x62, 0x57, 0x73, 0x61, 0x59, 0x37, 0x31,
+    0x6b, 0x35, 0x68, 0x2b, 0x33, 0x7a, 0x76, 0x44, 0x79, 0x6e, 0x79, 0x36,
+    0x37, 0x47, 0x37, 0x66, 0x79, 0x55, 0x49, 0x68, 0x7a, 0x0a, 0x6b, 0x73,
+    0x4c, 0x69, 0x34, 0x78, 0x61, 0x4e, 0x6d, 0x6a, 0x49, 0x43, 0x71, 0x34,
+    0x34, 0x59, 0x33, 0x65, 0x6b, 0x51, 0x45, 0x65, 0x35, 0x2b, 0x4e, 0x61,
+    0x75, 0x51, 0x72, 0x7a, 0x34, 0x77, 0x6c, 0x48, 0x72, 0x51, 0x4d, 0x7a,
+    0x32, 0x6e, 0x5a, 0x51, 0x2f, 0x31, 0x2f, 0x49, 0x36, 0x65, 0x59, 0x73,
+    0x39, 0x48, 0x52, 0x43, 0x77, 0x42, 0x58, 0x62, 0x73, 0x64, 0x74, 0x54,
+    0x4c, 0x53, 0x0a, 0x52, 0x39, 0x49, 0x34, 0x4c, 0x74, 0x44, 0x2b, 0x67,
+    0x64, 0x77, 0x79, 0x61, 0x68, 0x36, 0x31, 0x37, 0x6a, 0x7a, 0x56, 0x2f,
+    0x4f, 0x65, 0x42, 0x48, 0x52, 0x6e, 0x44, 0x4a, 0x45, 0x4c, 0x71, 0x59,
+    0x7a, 0x6d, 0x70, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73,
+    0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x45, 0x71, 0x75, 0x69,
+    0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47,
+    0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x65, 0x42, 0x75, 0x73, 0x69, 0x6e,
+    0x65, 0x73, 0x73, 0x20, 0x43, 0x41, 0x2d, 0x31, 0x20, 0x4f, 0x3d, 0x45,
+    0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62,
+    0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x45, 0x71, 0x75,
+    0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
+    0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x65, 0x42, 0x75, 0x73, 0x69,
+    0x6e, 0x65, 0x73, 0x73, 0x20, 0x43, 0x41, 0x2d, 0x31, 0x20, 0x4f, 0x3d,
+    0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75,
+    0x72, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61,
+    0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61,
+    0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6c, 0x6f,
+    0x62, 0x61, 0x6c, 0x20, 0x65, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73,
+    0x73, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69,
+    0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x38, 0x66, 0x3a, 0x35, 0x64, 0x3a, 0x37, 0x37, 0x3a, 0x30, 0x36,
+    0x3a, 0x32, 0x37, 0x3a, 0x63, 0x34, 0x3a, 0x39, 0x38, 0x3a, 0x33, 0x63,
+    0x3a, 0x35, 0x62, 0x3a, 0x39, 0x33, 0x3a, 0x37, 0x38, 0x3a, 0x65, 0x37,
+    0x3a, 0x64, 0x37, 0x3a, 0x37, 0x64, 0x3a, 0x39, 0x62, 0x3a, 0x63, 0x63,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x37, 0x65, 0x3a,
+    0x37, 0x38, 0x3a, 0x34, 0x61, 0x3a, 0x31, 0x30, 0x3a, 0x31, 0x63, 0x3a,
+    0x38, 0x32, 0x3a, 0x36, 0x35, 0x3a, 0x63, 0x63, 0x3a, 0x32, 0x64, 0x3a,
+    0x65, 0x31, 0x3a, 0x66, 0x31, 0x3a, 0x36, 0x64, 0x3a, 0x34, 0x37, 0x3a,
+    0x62, 0x34, 0x3a, 0x34, 0x30, 0x3a, 0x63, 0x61, 0x3a, 0x64, 0x39, 0x3a,
+    0x30, 0x61, 0x3a, 0x31, 0x39, 0x3a, 0x34, 0x35, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x35, 0x66, 0x3a, 0x30, 0x62,
+    0x3a, 0x36, 0x32, 0x3a, 0x65, 0x61, 0x3a, 0x62, 0x35, 0x3a, 0x65, 0x33,
+    0x3a, 0x35, 0x33, 0x3a, 0x65, 0x61, 0x3a, 0x36, 0x35, 0x3a, 0x32, 0x31,
+    0x3a, 0x36, 0x35, 0x3a, 0x31, 0x36, 0x3a, 0x35, 0x38, 0x3a, 0x66, 0x62,
+    0x3a, 0x62, 0x36, 0x3a, 0x35, 0x33, 0x3a, 0x35, 0x39, 0x3a, 0x66, 0x34,
+    0x3a, 0x34, 0x33, 0x3a, 0x32, 0x38, 0x3a, 0x30, 0x61, 0x3a, 0x34, 0x61,
+    0x3a, 0x66, 0x62, 0x3a, 0x64, 0x31, 0x3a, 0x30, 0x34, 0x3a, 0x64, 0x37,
+    0x3a, 0x37, 0x64, 0x3a, 0x31, 0x30, 0x3a, 0x66, 0x39, 0x3a, 0x66, 0x30,
+    0x3a, 0x34, 0x63, 0x3a, 0x30, 0x37, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
+    0x49, 0x49, 0x43, 0x6b, 0x44, 0x43, 0x43, 0x41, 0x66, 0x6d, 0x67, 0x41,
+    0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x51, 0x46, 0x41, 0x44, 0x42, 0x61, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55,
+    0x7a, 0x45, 0x63, 0x0a, 0x4d, 0x42, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x54, 0x52, 0x58, 0x46, 0x31, 0x61, 0x57, 0x5a, 0x68,
+    0x65, 0x43, 0x42, 0x54, 0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67,
+    0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x74, 0x4d, 0x43, 0x73, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x6b, 0x52, 0x58, 0x46, 0x31,
+    0x61, 0x57, 0x5a, 0x68, 0x65, 0x43, 0x42, 0x54, 0x0a, 0x5a, 0x57, 0x4e,
+    0x31, 0x63, 0x6d, 0x55, 0x67, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d, 0x46,
+    0x73, 0x49, 0x47, 0x56, 0x43, 0x64, 0x58, 0x4e, 0x70, 0x62, 0x6d, 0x56,
+    0x7a, 0x63, 0x79, 0x42, 0x44, 0x51, 0x53, 0x30, 0x78, 0x4d, 0x42, 0x34,
+    0x58, 0x44, 0x54, 0x6b, 0x35, 0x4d, 0x44, 0x59, 0x79, 0x4d, 0x54, 0x41,
+    0x30, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x49,
+    0x77, 0x0a, 0x4d, 0x44, 0x59, 0x79, 0x4d, 0x54, 0x41, 0x30, 0x4d, 0x44,
+    0x41, 0x77, 0x4d, 0x46, 0x6f, 0x77, 0x57, 0x6a, 0x45, 0x4c, 0x4d, 0x41,
+    0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56,
+    0x4d, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x6f, 0x54, 0x45, 0x30, 0x56, 0x78, 0x64, 0x57, 0x6c, 0x6d, 0x59, 0x58,
+    0x67, 0x67, 0x55, 0x32, 0x56, 0x6a, 0x0a, 0x64, 0x58, 0x4a, 0x6c, 0x49,
+    0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4c, 0x54, 0x41, 0x72, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x4a, 0x45, 0x56, 0x78, 0x64,
+    0x57, 0x6c, 0x6d, 0x59, 0x58, 0x67, 0x67, 0x55, 0x32, 0x56, 0x6a, 0x64,
+    0x58, 0x4a, 0x6c, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4a, 0x68, 0x62,
+    0x43, 0x42, 0x6c, 0x51, 0x6e, 0x56, 0x7a, 0x61, 0x57, 0x35, 0x6c, 0x0a,
+    0x63, 0x33, 0x4d, 0x67, 0x51, 0x30, 0x45, 0x74, 0x4d, 0x54, 0x43, 0x42,
+    0x6e, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x42,
+    0x6a, 0x51, 0x41, 0x77, 0x67, 0x59, 0x6b, 0x43, 0x67, 0x59, 0x45, 0x41,
+    0x75, 0x75, 0x63, 0x58, 0x6b, 0x41, 0x4a, 0x6c, 0x73, 0x54, 0x52, 0x56,
+    0x50, 0x45, 0x6e, 0x43, 0x0a, 0x55, 0x64, 0x58, 0x66, 0x70, 0x39, 0x45,
+    0x33, 0x6a, 0x39, 0x48, 0x6e, 0x67, 0x58, 0x4e, 0x42, 0x55, 0x6d, 0x43,
+    0x62, 0x6e, 0x61, 0x45, 0x58, 0x4a, 0x6e, 0x69, 0x74, 0x78, 0x37, 0x48,
+    0x6f, 0x4a, 0x70, 0x51, 0x79, 0x74, 0x64, 0x34, 0x7a, 0x6a, 0x54, 0x6f,
+    0x76, 0x32, 0x2f, 0x4b, 0x61, 0x65, 0x6c, 0x70, 0x7a, 0x6d, 0x4b, 0x4e,
+    0x63, 0x36, 0x66, 0x75, 0x4b, 0x63, 0x78, 0x74, 0x63, 0x0a, 0x35, 0x38,
+    0x4f, 0x2f, 0x67, 0x47, 0x7a, 0x4e, 0x71, 0x66, 0x54, 0x57, 0x4b, 0x38,
+    0x44, 0x33, 0x2b, 0x5a, 0x6d, 0x71, 0x59, 0x36, 0x4b, 0x78, 0x52, 0x77,
+    0x49, 0x50, 0x31, 0x4f, 0x52, 0x52, 0x4f, 0x68, 0x49, 0x38, 0x62, 0x49,
+    0x70, 0x61, 0x56, 0x49, 0x52, 0x77, 0x32, 0x38, 0x48, 0x46, 0x6b, 0x4d,
+    0x39, 0x79, 0x52, 0x63, 0x75, 0x6f, 0x57, 0x63, 0x44, 0x4e, 0x4d, 0x35,
+    0x30, 0x2f, 0x0a, 0x6f, 0x35, 0x62, 0x72, 0x68, 0x54, 0x4d, 0x68, 0x48,
+    0x44, 0x34, 0x65, 0x50, 0x6d, 0x42, 0x75, 0x64, 0x70, 0x78, 0x6e, 0x68,
+    0x63, 0x58, 0x49, 0x77, 0x32, 0x45, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41,
+    0x61, 0x4e, 0x6d, 0x4d, 0x47, 0x51, 0x77, 0x45, 0x51, 0x59, 0x4a, 0x59,
+    0x49, 0x5a, 0x49, 0x41, 0x59, 0x62, 0x34, 0x51, 0x67, 0x45, 0x42, 0x42,
+    0x41, 0x51, 0x44, 0x41, 0x67, 0x41, 0x48, 0x0a, 0x4d, 0x41, 0x38, 0x47,
+    0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46,
+    0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x77, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, 0x41, 0x55,
+    0x76, 0x71, 0x69, 0x67, 0x64, 0x48, 0x4a, 0x51, 0x61, 0x30, 0x53, 0x33,
+    0x79, 0x53, 0x50, 0x59, 0x2b, 0x36, 0x6a, 0x2f, 0x73, 0x31, 0x64, 0x72,
+    0x0a, 0x61, 0x47, 0x77, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4c, 0x36, 0x6f, 0x6f, 0x48, 0x52,
+    0x79, 0x55, 0x47, 0x74, 0x45, 0x74, 0x38, 0x6b, 0x6a, 0x32, 0x50, 0x75,
+    0x6f, 0x2f, 0x37, 0x4e, 0x58, 0x61, 0x32, 0x68, 0x73, 0x4d, 0x41, 0x30,
+    0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45,
+    0x42, 0x42, 0x41, 0x55, 0x41, 0x0a, 0x41, 0x34, 0x47, 0x42, 0x41, 0x44,
+    0x44, 0x69, 0x41, 0x56, 0x47, 0x71, 0x78, 0x2b, 0x70, 0x66, 0x32, 0x72,
+    0x6e, 0x51, 0x5a, 0x51, 0x38, 0x77, 0x31, 0x6a, 0x37, 0x61, 0x44, 0x52,
+    0x52, 0x4a, 0x62, 0x70, 0x47, 0x54, 0x4a, 0x78, 0x51, 0x78, 0x37, 0x38,
+    0x54, 0x33, 0x4c, 0x55, 0x58, 0x34, 0x37, 0x4d, 0x65, 0x2f, 0x6f, 0x6b,
+    0x45, 0x4e, 0x49, 0x37, 0x53, 0x53, 0x2b, 0x52, 0x6b, 0x41, 0x0a, 0x5a,
+    0x37, 0x30, 0x42, 0x72, 0x38, 0x33, 0x67, 0x63, 0x66, 0x78, 0x61, 0x7a,
+    0x32, 0x54, 0x45, 0x34, 0x4a, 0x61, 0x59, 0x30, 0x4b, 0x4e, 0x41, 0x34,
+    0x67, 0x47, 0x4b, 0x37, 0x79, 0x63, 0x48, 0x38, 0x57, 0x55, 0x42, 0x69,
+    0x6b, 0x51, 0x74, 0x42, 0x6d, 0x56, 0x31, 0x55, 0x73, 0x43, 0x47, 0x45,
+    0x43, 0x41, 0x68, 0x58, 0x32, 0x78, 0x72, 0x44, 0x32, 0x79, 0x75, 0x43,
+    0x52, 0x79, 0x76, 0x0a, 0x38, 0x71, 0x49, 0x59, 0x4e, 0x4d, 0x52, 0x31,
+    0x70, 0x48, 0x4d, 0x63, 0x38, 0x59, 0x33, 0x63, 0x37, 0x36, 0x33, 0x35,
+    0x73, 0x33, 0x61, 0x30, 0x6b, 0x72, 0x2f, 0x63, 0x6c, 0x52, 0x41, 0x65,
+    0x76, 0x73, 0x76, 0x49, 0x4f, 0x31, 0x71, 0x45, 0x59, 0x42, 0x6c, 0x57,
+    0x6c, 0x4b, 0x6c, 0x56, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e,
+    0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73,
+    0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x45, 0x71, 0x75,
+    0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
+    0x65, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x43, 0x41,
+    0x2d, 0x31, 0x20, 0x4f, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
+    0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x20, 0x53,
+    0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x65, 0x42, 0x75, 0x73, 0x69, 0x6e,
+    0x65, 0x73, 0x73, 0x20, 0x43, 0x41, 0x2d, 0x31, 0x20, 0x4f, 0x3d, 0x45,
+    0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62,
+    0x65, 0x6c, 0x3a, 0x20, 0x22, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
+    0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x65, 0x42, 0x75, 0x73,
+    0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x43, 0x41, 0x20, 0x31, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x34, 0x0a,
+    0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x36, 0x34, 0x3a, 0x39, 0x63,
+    0x3a, 0x65, 0x66, 0x3a, 0x32, 0x65, 0x3a, 0x34, 0x34, 0x3a, 0x66, 0x63,
+    0x3a, 0x63, 0x36, 0x3a, 0x38, 0x66, 0x3a, 0x35, 0x32, 0x3a, 0x30, 0x37,
+    0x3a, 0x64, 0x30, 0x3a, 0x35, 0x31, 0x3a, 0x37, 0x33, 0x3a, 0x38, 0x66,
+    0x3a, 0x63, 0x62, 0x3a, 0x33, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x64, 0x61, 0x3a, 0x34, 0x30, 0x3a, 0x31, 0x38, 0x3a,
+    0x38, 0x62, 0x3a, 0x39, 0x31, 0x3a, 0x38, 0x39, 0x3a, 0x61, 0x33, 0x3a,
+    0x65, 0x64, 0x3a, 0x65, 0x65, 0x3a, 0x61, 0x65, 0x3a, 0x64, 0x61, 0x3a,
+    0x39, 0x37, 0x3a, 0x66, 0x65, 0x3a, 0x32, 0x66, 0x3a, 0x39, 0x64, 0x3a,
+    0x66, 0x35, 0x3a, 0x62, 0x37, 0x3a, 0x64, 0x31, 0x3a, 0x38, 0x61, 0x3a,
+    0x34, 0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x63, 0x66, 0x3a, 0x35, 0x36, 0x3a, 0x66, 0x66, 0x3a, 0x34, 0x36,
+    0x3a, 0x61, 0x34, 0x3a, 0x61, 0x31, 0x3a, 0x38, 0x36, 0x3a, 0x31, 0x30,
+    0x3a, 0x39, 0x64, 0x3a, 0x64, 0x39, 0x3a, 0x36, 0x35, 0x3a, 0x38, 0x34,
+    0x3a, 0x62, 0x35, 0x3a, 0x65, 0x65, 0x3a, 0x62, 0x35, 0x3a, 0x38, 0x61,
+    0x3a, 0x35, 0x31, 0x3a, 0x30, 0x63, 0x3a, 0x34, 0x32, 0x3a, 0x37, 0x35,
+    0x3a, 0x62, 0x30, 0x3a, 0x65, 0x35, 0x3a, 0x66, 0x39, 0x3a, 0x34, 0x66,
+    0x3a, 0x34, 0x30, 0x3a, 0x62, 0x62, 0x3a, 0x61, 0x65, 0x3a, 0x38, 0x36,
+    0x3a, 0x35, 0x65, 0x3a, 0x31, 0x39, 0x3a, 0x66, 0x36, 0x3a, 0x37, 0x33,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x67, 0x6a, 0x43,
+    0x43, 0x41, 0x65, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
+    0x42, 0x42, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x51, 0x46, 0x41, 0x44, 0x42,
+    0x54, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x63, 0x0a, 0x4d, 0x42,
+    0x6f, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x54, 0x52, 0x58,
+    0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x43, 0x42, 0x54, 0x5a, 0x57,
+    0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a,
+    0x45, 0x6d, 0x4d, 0x43, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78,
+    0x4d, 0x64, 0x52, 0x58, 0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x43,
+    0x42, 0x54, 0x0a, 0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67, 0x5a,
+    0x55, 0x4a, 0x31, 0x63, 0x32, 0x6c, 0x75, 0x5a, 0x58, 0x4e, 0x7a, 0x49,
+    0x45, 0x4e, 0x42, 0x4c, 0x54, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4f,
+    0x54, 0x6b, 0x77, 0x4e, 0x6a, 0x49, 0x78, 0x4d, 0x44, 0x51, 0x77, 0x4d,
+    0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x41, 0x77, 0x4e,
+    0x6a, 0x49, 0x78, 0x4d, 0x44, 0x51, 0x77, 0x0a, 0x4d, 0x44, 0x41, 0x77,
+    0x57, 0x6a, 0x42, 0x54, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x63,
+    0x4d, 0x42, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x54,
+    0x52, 0x58, 0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x43, 0x42, 0x54,
+    0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55, 0x67, 0x53, 0x57, 0x35, 0x6a,
+    0x0a, 0x4c, 0x6a, 0x45, 0x6d, 0x4d, 0x43, 0x51, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x41, 0x78, 0x4d, 0x64, 0x52, 0x58, 0x46, 0x31, 0x61, 0x57, 0x5a,
+    0x68, 0x65, 0x43, 0x42, 0x54, 0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55,
+    0x67, 0x5a, 0x55, 0x4a, 0x31, 0x63, 0x32, 0x6c, 0x75, 0x5a, 0x58, 0x4e,
+    0x7a, 0x49, 0x45, 0x4e, 0x42, 0x4c, 0x54, 0x45, 0x77, 0x67, 0x5a, 0x38,
+    0x77, 0x44, 0x51, 0x59, 0x4a, 0x0a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x59,
+    0x30, 0x41, 0x4d, 0x49, 0x47, 0x4a, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4d,
+    0x34, 0x76, 0x47, 0x62, 0x77, 0x58, 0x74, 0x33, 0x66, 0x65, 0x6b, 0x36,
+    0x6c, 0x66, 0x57, 0x67, 0x30, 0x58, 0x54, 0x7a, 0x51, 0x61, 0x44, 0x4a,
+    0x6a, 0x30, 0x49, 0x74, 0x6c, 0x5a, 0x31, 0x4d, 0x52, 0x6f, 0x0a, 0x52,
+    0x76, 0x43, 0x30, 0x4e, 0x63, 0x57, 0x46, 0x41, 0x79, 0x44, 0x47, 0x72,
+    0x30, 0x57, 0x6c, 0x49, 0x56, 0x46, 0x46, 0x51, 0x65, 0x73, 0x57, 0x57,
+    0x44, 0x59, 0x79, 0x62, 0x2b, 0x4a, 0x51, 0x59, 0x6d, 0x54, 0x35, 0x2f,
+    0x56, 0x47, 0x63, 0x71, 0x69, 0x54, 0x5a, 0x39, 0x4a, 0x32, 0x44, 0x4b,
+    0x6f, 0x63, 0x4b, 0x49, 0x64, 0x4d, 0x53, 0x4f, 0x44, 0x52, 0x73, 0x6a,
+    0x51, 0x42, 0x75, 0x0a, 0x57, 0x71, 0x44, 0x5a, 0x51, 0x75, 0x34, 0x61,
+    0x49, 0x5a, 0x58, 0x35, 0x55, 0x6b, 0x78, 0x56, 0x57, 0x73, 0x55, 0x50,
+    0x4f, 0x45, 0x39, 0x47, 0x2b, 0x6d, 0x33, 0x34, 0x4c, 0x6a, 0x58, 0x57,
+    0x48, 0x58, 0x7a, 0x72, 0x34, 0x76, 0x43, 0x77, 0x64, 0x59, 0x44, 0x49,
+    0x71, 0x52, 0x4f, 0x73, 0x76, 0x6f, 0x6a, 0x76, 0x4f, 0x6d, 0x36, 0x72,
+    0x58, 0x79, 0x6f, 0x34, 0x59, 0x67, 0x4b, 0x77, 0x0a, 0x45, 0x6e, 0x76,
+    0x2b, 0x6a, 0x36, 0x59, 0x44, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47,
+    0x6a, 0x5a, 0x6a, 0x42, 0x6b, 0x4d, 0x42, 0x45, 0x47, 0x43, 0x57, 0x43,
+    0x47, 0x53, 0x41, 0x47, 0x47, 0x2b, 0x45, 0x49, 0x42, 0x41, 0x51, 0x51,
+    0x45, 0x41, 0x77, 0x49, 0x41, 0x42, 0x7a, 0x41, 0x50, 0x42, 0x67, 0x4e,
+    0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41,
+    0x44, 0x0a, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31,
+    0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x45,
+    0x70, 0x34, 0x4d, 0x6c, 0x49, 0x52, 0x32, 0x31, 0x6b, 0x57, 0x4e, 0x6c,
+    0x37, 0x66, 0x77, 0x52, 0x51, 0x32, 0x51, 0x47, 0x70, 0x48, 0x66, 0x45,
+    0x79, 0x68, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67,
+    0x51, 0x57, 0x42, 0x42, 0x52, 0x4b, 0x0a, 0x65, 0x44, 0x4a, 0x53, 0x45,
+    0x64, 0x74, 0x5a, 0x46, 0x6a, 0x5a, 0x65, 0x33, 0x38, 0x45, 0x55, 0x4e,
+    0x6b, 0x42, 0x71, 0x52, 0x33, 0x78, 0x4d, 0x6f, 0x54, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x51, 0x46, 0x41, 0x41, 0x4f, 0x42, 0x67, 0x51, 0x42, 0x31, 0x57,
+    0x36, 0x69, 0x62, 0x41, 0x78, 0x48, 0x6d, 0x36, 0x56, 0x5a, 0x4d, 0x0a,
+    0x7a, 0x66, 0x6d, 0x70, 0x54, 0x4d, 0x41, 0x4e, 0x6d, 0x76, 0x50, 0x4d,
+    0x5a, 0x57, 0x6e, 0x6d, 0x4a, 0x58, 0x62, 0x4d, 0x57, 0x62, 0x66, 0x57,
+    0x56, 0x4d, 0x4d, 0x64, 0x7a, 0x5a, 0x6d, 0x73, 0x47, 0x64, 0x32, 0x30,
+    0x68, 0x64, 0x58, 0x67, 0x50, 0x66, 0x78, 0x69, 0x49, 0x4b, 0x65, 0x45,
+    0x53, 0x31, 0x68, 0x6c, 0x38, 0x65, 0x4c, 0x35, 0x6c, 0x53, 0x45, 0x2f,
+    0x39, 0x64, 0x52, 0x2b, 0x0a, 0x57, 0x42, 0x35, 0x48, 0x68, 0x31, 0x51,
+    0x2b, 0x57, 0x4b, 0x47, 0x31, 0x74, 0x66, 0x67, 0x71, 0x37, 0x33, 0x48,
+    0x6e, 0x76, 0x4d, 0x50, 0x32, 0x73, 0x55, 0x6c, 0x47, 0x34, 0x74, 0x65,
+    0x67, 0x61, 0x2b, 0x56, 0x57, 0x65, 0x70, 0x6f, 0x6e, 0x6d, 0x48, 0x78,
+    0x47, 0x59, 0x68, 0x54, 0x6e, 0x79, 0x66, 0x78, 0x75, 0x41, 0x78, 0x4a,
+    0x35, 0x67, 0x44, 0x67, 0x64, 0x53, 0x49, 0x4b, 0x4e, 0x0a, 0x2f, 0x42,
+    0x66, 0x2b, 0x4b, 0x70, 0x59, 0x72, 0x74, 0x57, 0x4b, 0x6d, 0x70, 0x6a,
+    0x32, 0x39, 0x66, 0x35, 0x4a, 0x5a, 0x7a, 0x56, 0x6f, 0x71, 0x67, 0x72,
+    0x49, 0x33, 0x65, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43,
+    0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20,
+    0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x4f, 0x3d, 0x45, 0x71,
+    0x75, 0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
+    0x20, 0x4f, 0x55, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x20,
+    0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x65, 0x42, 0x75, 0x73, 0x69,
+    0x6e, 0x65, 0x73, 0x73, 0x20, 0x43, 0x41, 0x2d, 0x32, 0x0a, 0x23, 0x20,
+    0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x4f, 0x3d, 0x45,
+    0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x65, 0x20, 0x4f, 0x55, 0x3d, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78,
+    0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x65, 0x42, 0x75, 0x73,
+    0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x43, 0x41, 0x2d, 0x32, 0x0a, 0x23,
+    0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x45, 0x71, 0x75,
+    0x69, 0x66, 0x61, 0x78, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
+    0x65, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x43, 0x41,
+    0x20, 0x32, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c,
+    0x3a, 0x20, 0x39, 0x33, 0x30, 0x31, 0x34, 0x30, 0x30, 0x38, 0x35, 0x0a,
+    0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x61, 0x3a, 0x62, 0x66,
+    0x3a, 0x62, 0x66, 0x3a, 0x36, 0x34, 0x3a, 0x39, 0x37, 0x3a, 0x64, 0x61,
+    0x3a, 0x39, 0x38, 0x3a, 0x31, 0x64, 0x3a, 0x36, 0x66, 0x3a, 0x63, 0x36,
+    0x3a, 0x30, 0x38, 0x3a, 0x33, 0x61, 0x3a, 0x39, 0x35, 0x3a, 0x37, 0x30,
+    0x3a, 0x33, 0x33, 0x3a, 0x63, 0x61, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x33, 0x39, 0x3a, 0x34, 0x66, 0x3a, 0x66, 0x36, 0x3a,
+    0x38, 0x35, 0x3a, 0x30, 0x62, 0x3a, 0x30, 0x36, 0x3a, 0x62, 0x65, 0x3a,
+    0x35, 0x32, 0x3a, 0x65, 0x35, 0x3a, 0x31, 0x38, 0x3a, 0x35, 0x36, 0x3a,
+    0x63, 0x63, 0x3a, 0x31, 0x30, 0x3a, 0x65, 0x31, 0x3a, 0x38, 0x30, 0x3a,
+    0x65, 0x38, 0x3a, 0x38, 0x32, 0x3a, 0x62, 0x33, 0x3a, 0x38, 0x35, 0x3a,
+    0x63, 0x63, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x32, 0x66, 0x3a, 0x32, 0x37, 0x3a, 0x34, 0x65, 0x3a, 0x34, 0x38,
+    0x3a, 0x61, 0x62, 0x3a, 0x61, 0x34, 0x3a, 0x61, 0x63, 0x3a, 0x37, 0x62,
+    0x3a, 0x37, 0x36, 0x3a, 0x35, 0x39, 0x3a, 0x33, 0x33, 0x3a, 0x31, 0x30,
+    0x3a, 0x31, 0x37, 0x3a, 0x37, 0x35, 0x3a, 0x35, 0x30, 0x3a, 0x36, 0x64,
+    0x3a, 0x63, 0x33, 0x3a, 0x30, 0x65, 0x3a, 0x65, 0x33, 0x3a, 0x38, 0x65,
+    0x3a, 0x66, 0x36, 0x3a, 0x61, 0x63, 0x3a, 0x64, 0x35, 0x3a, 0x63, 0x30,
+    0x3a, 0x34, 0x39, 0x3a, 0x33, 0x32, 0x3a, 0x63, 0x66, 0x3a, 0x65, 0x30,
+    0x3a, 0x34, 0x31, 0x3a, 0x32, 0x33, 0x3a, 0x34, 0x32, 0x3a, 0x32, 0x30,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x49, 0x44, 0x43,
+    0x43, 0x41, 0x6f, 0x6d, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
+    0x45, 0x4e, 0x33, 0x44, 0x50, 0x74, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b,
+    0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55,
+    0x46, 0x41, 0x44, 0x42, 0x4f, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x0a, 0x55, 0x7a,
+    0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4f, 0x52, 0x58, 0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x43,
+    0x42, 0x54, 0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55, 0x78, 0x4a, 0x6a,
+    0x41, 0x6b, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x55,
+    0x56, 0x78, 0x64, 0x57, 0x6c, 0x6d, 0x59, 0x58, 0x67, 0x67, 0x55, 0x32,
+    0x56, 0x6a, 0x0a, 0x64, 0x58, 0x4a, 0x6c, 0x49, 0x47, 0x56, 0x43, 0x64,
+    0x58, 0x4e, 0x70, 0x62, 0x6d, 0x56, 0x7a, 0x63, 0x79, 0x42, 0x44, 0x51,
+    0x53, 0x30, 0x79, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x6b, 0x35, 0x4d,
+    0x44, 0x59, 0x79, 0x4d, 0x7a, 0x45, 0x79, 0x4d, 0x54, 0x51, 0x30, 0x4e,
+    0x56, 0x6f, 0x58, 0x44, 0x54, 0x45, 0x35, 0x4d, 0x44, 0x59, 0x79, 0x4d,
+    0x7a, 0x45, 0x79, 0x4d, 0x54, 0x51, 0x30, 0x0a, 0x4e, 0x56, 0x6f, 0x77,
+    0x54, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x7a, 0x41, 0x56,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x6b, 0x56, 0x78,
+    0x64, 0x57, 0x6c, 0x6d, 0x59, 0x58, 0x67, 0x67, 0x55, 0x32, 0x56, 0x6a,
+    0x64, 0x58, 0x4a, 0x6c, 0x4d, 0x53, 0x59, 0x77, 0x4a, 0x41, 0x59, 0x44,
+    0x0a, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x31, 0x46, 0x63, 0x58, 0x56,
+    0x70, 0x5a, 0x6d, 0x46, 0x34, 0x49, 0x46, 0x4e, 0x6c, 0x59, 0x33, 0x56,
+    0x79, 0x5a, 0x53, 0x42, 0x6c, 0x51, 0x6e, 0x56, 0x7a, 0x61, 0x57, 0x35,
+    0x6c, 0x63, 0x33, 0x4d, 0x67, 0x51, 0x30, 0x45, 0x74, 0x4d, 0x6a, 0x43,
+    0x42, 0x6e, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x0a, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41,
+    0x4f, 0x42, 0x6a, 0x51, 0x41, 0x77, 0x67, 0x59, 0x6b, 0x43, 0x67, 0x59,
+    0x45, 0x41, 0x35, 0x44, 0x6b, 0x35, 0x6b, 0x78, 0x35, 0x53, 0x42, 0x68,
+    0x73, 0x6f, 0x4e, 0x76, 0x69, 0x79, 0x6f, 0x79, 0x6e, 0x46, 0x37, 0x59,
+    0x36, 0x79, 0x45, 0x62, 0x33, 0x2b, 0x36, 0x2b, 0x65, 0x30, 0x64, 0x4d,
+    0x4b, 0x50, 0x2f, 0x77, 0x58, 0x6e, 0x32, 0x5a, 0x30, 0x47, 0x0a, 0x76,
+    0x78, 0x4c, 0x49, 0x50, 0x77, 0x37, 0x79, 0x31, 0x74, 0x45, 0x6b, 0x73,
+    0x68, 0x48, 0x65, 0x30, 0x58, 0x4d, 0x4a, 0x69, 0x74, 0x53, 0x78, 0x4c,
+    0x4a, 0x67, 0x4a, 0x44, 0x52, 0x35, 0x51, 0x52, 0x72, 0x4b, 0x44, 0x70,
+    0x6b, 0x57, 0x4e, 0x59, 0x6d, 0x69, 0x37, 0x68, 0x52, 0x73, 0x67, 0x63,
+    0x44, 0x4b, 0x71, 0x51, 0x4d, 0x32, 0x6d, 0x6c, 0x6c, 0x2f, 0x45, 0x63,
+    0x54, 0x63, 0x2f, 0x0a, 0x42, 0x50, 0x4f, 0x33, 0x51, 0x53, 0x51, 0x35,
+    0x42, 0x78, 0x6f, 0x65, 0x4c, 0x6d, 0x46, 0x59, 0x6f, 0x42, 0x49, 0x4c,
+    0x35, 0x61, 0x58, 0x66, 0x78, 0x61, 0x76, 0x71, 0x4e, 0x33, 0x48, 0x4d,
+    0x48, 0x4d, 0x67, 0x33, 0x4f, 0x72, 0x6d, 0x58, 0x55, 0x71, 0x65, 0x73,
+    0x78, 0x57, 0x6f, 0x6b, 0x6c, 0x45, 0x36, 0x63, 0x65, 0x38, 0x2f, 0x41,
+    0x61, 0x74, 0x62, 0x66, 0x49, 0x62, 0x30, 0x43, 0x0a, 0x41, 0x77, 0x45,
+    0x41, 0x41, 0x61, 0x4f, 0x43, 0x41, 0x51, 0x6b, 0x77, 0x67, 0x67, 0x45,
+    0x46, 0x4d, 0x48, 0x41, 0x47, 0x41, 0x31, 0x55, 0x64, 0x48, 0x77, 0x52,
+    0x70, 0x4d, 0x47, 0x63, 0x77, 0x5a, 0x61, 0x42, 0x6a, 0x6f, 0x47, 0x47,
+    0x6b, 0x58, 0x7a, 0x42, 0x64, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45,
+    0x58, 0x0a, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4f, 0x52, 0x58, 0x46, 0x31, 0x61, 0x57, 0x5a, 0x68, 0x65, 0x43,
+    0x42, 0x54, 0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d, 0x55, 0x78, 0x4a, 0x6a,
+    0x41, 0x6b, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x55,
+    0x56, 0x78, 0x64, 0x57, 0x6c, 0x6d, 0x59, 0x58, 0x67, 0x67, 0x55, 0x32,
+    0x56, 0x6a, 0x64, 0x58, 0x4a, 0x6c, 0x0a, 0x49, 0x47, 0x56, 0x43, 0x64,
+    0x58, 0x4e, 0x70, 0x62, 0x6d, 0x56, 0x7a, 0x63, 0x79, 0x42, 0x44, 0x51,
+    0x53, 0x30, 0x79, 0x4d, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x44, 0x45, 0x77, 0x52, 0x44, 0x55, 0x6b, 0x77, 0x78, 0x4d,
+    0x42, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x41, 0x51, 0x54, 0x4d,
+    0x42, 0x47, 0x42, 0x44, 0x7a, 0x49, 0x77, 0x4d, 0x54, 0x6b, 0x77, 0x0a,
+    0x4e, 0x6a, 0x49, 0x7a, 0x4d, 0x54, 0x49, 0x78, 0x4e, 0x44, 0x51, 0x31,
+    0x57, 0x6a, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x45,
+    0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, 0x77, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, 0x41, 0x55,
+    0x55, 0x4a, 0x34, 0x4c, 0x36, 0x71, 0x39, 0x65, 0x75, 0x53, 0x42, 0x49,
+    0x70, 0x6c, 0x42, 0x71, 0x0a, 0x79, 0x2f, 0x33, 0x59, 0x49, 0x48, 0x71,
+    0x6e, 0x67, 0x6e, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x46, 0x43, 0x65, 0x43, 0x2b, 0x71,
+    0x76, 0x58, 0x72, 0x6b, 0x67, 0x53, 0x4b, 0x5a, 0x51, 0x61, 0x73, 0x76,
+    0x39, 0x32, 0x43, 0x42, 0x36, 0x70, 0x34, 0x4a, 0x32, 0x4d, 0x41, 0x77,
+    0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x51, 0x46, 0x0a, 0x4d, 0x41,
+    0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x47, 0x67, 0x59, 0x4a, 0x4b, 0x6f,
+    0x5a, 0x49, 0x68, 0x76, 0x5a, 0x39, 0x42, 0x30, 0x45, 0x41, 0x42, 0x41,
+    0x30, 0x77, 0x43, 0x78, 0x73, 0x46, 0x56, 0x6a, 0x4d, 0x75, 0x4d, 0x47,
+    0x4d, 0x44, 0x41, 0x67, 0x62, 0x41, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53,
+    0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51,
+    0x55, 0x41, 0x0a, 0x41, 0x34, 0x47, 0x42, 0x41, 0x41, 0x79, 0x47, 0x67,
+    0x71, 0x33, 0x6f, 0x54, 0x68, 0x72, 0x31, 0x6a, 0x6f, 0x6b, 0x6e, 0x34,
+    0x6a, 0x56, 0x59, 0x50, 0x53, 0x6d, 0x30, 0x42, 0x34, 0x38, 0x32, 0x55,
+    0x4a, 0x57, 0x2f, 0x62, 0x73, 0x47, 0x65, 0x36, 0x38, 0x53, 0x51, 0x73,
+    0x6f, 0x57, 0x6f, 0x75, 0x37, 0x64, 0x43, 0x34, 0x41, 0x38, 0x48, 0x4f,
+    0x64, 0x2f, 0x37, 0x6e, 0x70, 0x43, 0x79, 0x0a, 0x30, 0x63, 0x45, 0x2b,
+    0x55, 0x35, 0x38, 0x44, 0x52, 0x4c, 0x42, 0x2b, 0x53, 0x2f, 0x52, 0x76,
+    0x35, 0x48, 0x77, 0x66, 0x35, 0x2b, 0x4b, 0x78, 0x35, 0x4c, 0x69, 0x61,
+    0x37, 0x38, 0x4f, 0x39, 0x7a, 0x74, 0x34, 0x4c, 0x4d, 0x6a, 0x54, 0x5a,
+    0x33, 0x69, 0x6a, 0x74, 0x4d, 0x32, 0x76, 0x45, 0x31, 0x4e, 0x63, 0x39,
+    0x45, 0x6c, 0x69, 0x72, 0x66, 0x51, 0x6b, 0x74, 0x79, 0x33, 0x44, 0x31,
+    0x0a, 0x45, 0x34, 0x71, 0x55, 0x6f, 0x53, 0x65, 0x6b, 0x31, 0x6e, 0x44,
+    0x46, 0x62, 0x5a, 0x53, 0x31, 0x79, 0x58, 0x32, 0x64, 0x6f, 0x4e, 0x4c,
+    0x47, 0x43, 0x45, 0x6e, 0x5a, 0x5a, 0x70, 0x75, 0x6d, 0x30, 0x2f, 0x51,
+    0x4c, 0x33, 0x4d, 0x55, 0x6d, 0x56, 0x2b, 0x47, 0x52, 0x4d, 0x4f, 0x72,
+    0x4e, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20, 0x43,
+    0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d, 0x41, 0x64, 0x64,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x20, 0x4f, 0x55, 0x3d,
+    0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x54, 0x54, 0x50,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41,
+    0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x61, 0x73,
+    0x73, 0x20, 0x31, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x4f, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41,
+    0x42, 0x20, 0x4f, 0x55, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+    0x6b, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22,
+    0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4c, 0x6f, 0x77,
+    0x2d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69,
+    0x63, 0x65, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20,
+    0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23, 0x20,
+    0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x31, 0x65, 0x3a, 0x34, 0x32, 0x3a, 0x39,
+    0x35, 0x3a, 0x30, 0x32, 0x3a, 0x33, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x36,
+    0x62, 0x3a, 0x62, 0x39, 0x3a, 0x35, 0x66, 0x3a, 0x63, 0x30, 0x3a, 0x37,
+    0x66, 0x3a, 0x64, 0x61, 0x3a, 0x64, 0x36, 0x3a, 0x62, 0x32, 0x3a, 0x34,
+    0x62, 0x3a, 0x66, 0x63, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x63, 0x63, 0x3a, 0x61, 0x62, 0x3a, 0x30, 0x65, 0x3a, 0x61, 0x30,
+    0x3a, 0x34, 0x63, 0x3a, 0x32, 0x33, 0x3a, 0x30, 0x31, 0x3a, 0x64, 0x36,
+    0x3a, 0x36, 0x39, 0x3a, 0x37, 0x62, 0x3a, 0x64, 0x64, 0x3a, 0x33, 0x37,
+    0x3a, 0x39, 0x66, 0x3a, 0x63, 0x64, 0x3a, 0x31, 0x32, 0x3a, 0x65, 0x62,
+    0x3a, 0x32, 0x34, 0x3a, 0x65, 0x33, 0x3a, 0x39, 0x34, 0x3a, 0x39, 0x64,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38,
+    0x63, 0x3a, 0x37, 0x32, 0x3a, 0x30, 0x39, 0x3a, 0x32, 0x37, 0x3a, 0x39,
+    0x61, 0x3a, 0x63, 0x30, 0x3a, 0x34, 0x65, 0x3a, 0x32, 0x37, 0x3a, 0x35,
+    0x65, 0x3a, 0x31, 0x36, 0x3a, 0x64, 0x30, 0x3a, 0x37, 0x66, 0x3a, 0x64,
+    0x33, 0x3a, 0x62, 0x37, 0x3a, 0x37, 0x35, 0x3a, 0x65, 0x38, 0x3a, 0x30,
+    0x31, 0x3a, 0x35, 0x34, 0x3a, 0x62, 0x35, 0x3a, 0x39, 0x36, 0x3a, 0x38,
+    0x30, 0x3a, 0x34, 0x36, 0x3a, 0x65, 0x33, 0x3a, 0x31, 0x66, 0x3a, 0x35,
+    0x32, 0x3a, 0x64, 0x64, 0x3a, 0x32, 0x35, 0x3a, 0x37, 0x36, 0x3a, 0x36,
+    0x33, 0x3a, 0x32, 0x34, 0x3a, 0x65, 0x39, 0x3a, 0x61, 0x37, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x47, 0x44, 0x43, 0x43, 0x41,
+    0x77, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41,
+    0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x6c, 0x4d,
+    0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x54, 0x52, 0x54, 0x45, 0x55, 0x0a, 0x4d, 0x42, 0x49, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4c, 0x51, 0x57, 0x52, 0x6b,
+    0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x55, 0x49, 0x78,
+    0x48, 0x54, 0x41, 0x62, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54,
+    0x46, 0x45, 0x46, 0x6b, 0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30,
+    0x49, 0x46, 0x52, 0x55, 0x55, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33,
+    0x0a, 0x62, 0x33, 0x4a, 0x72, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x68, 0x42, 0x5a, 0x47, 0x52,
+    0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x44, 0x62, 0x47, 0x46,
+    0x7a, 0x63, 0x79, 0x41, 0x78, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x46, 0x4a,
+    0x76, 0x62, 0x33, 0x51, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x41,
+    0x77, 0x4e, 0x54, 0x4d, 0x77, 0x0a, 0x4d, 0x54, 0x41, 0x7a, 0x4f, 0x44,
+    0x4d, 0x78, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x41, 0x77, 0x4e, 0x54,
+    0x4d, 0x77, 0x4d, 0x54, 0x41, 0x7a, 0x4f, 0x44, 0x4d, 0x78, 0x57, 0x6a,
+    0x42, 0x6c, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x47, 0x45, 0x77, 0x4a, 0x54, 0x52, 0x54, 0x45, 0x55, 0x4d, 0x42,
+    0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4c, 0x0a, 0x51,
+    0x57, 0x52, 0x6b, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51,
+    0x55, 0x49, 0x78, 0x48, 0x54, 0x41, 0x62, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x73, 0x54, 0x46, 0x45, 0x46, 0x6b, 0x5a, 0x46, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x49, 0x46, 0x52, 0x55, 0x55, 0x43, 0x42, 0x4f, 0x5a,
+    0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x4d, 0x53, 0x45, 0x77, 0x48,
+    0x77, 0x59, 0x44, 0x0a, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x68, 0x42,
+    0x5a, 0x47, 0x52, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x44,
+    0x62, 0x47, 0x46, 0x7a, 0x63, 0x79, 0x41, 0x78, 0x49, 0x45, 0x4e, 0x42,
+    0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x77, 0x67, 0x67, 0x45, 0x69,
+    0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x0a, 0x41, 0x34, 0x49,
+    0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49,
+    0x42, 0x41, 0x51, 0x43, 0x57, 0x6c, 0x74, 0x51, 0x68, 0x53, 0x57, 0x44,
+    0x69, 0x61, 0x2b, 0x68, 0x42, 0x42, 0x77, 0x7a, 0x65, 0x78, 0x4f, 0x44,
+    0x63, 0x45, 0x79, 0x50, 0x4e, 0x77, 0x54, 0x58, 0x48, 0x2b, 0x39, 0x5a,
+    0x4f, 0x45, 0x51, 0x70, 0x6e, 0x58, 0x76, 0x55, 0x47, 0x57, 0x32, 0x75,
+    0x6c, 0x0a, 0x43, 0x44, 0x74, 0x62, 0x4b, 0x52, 0x59, 0x36, 0x35, 0x34,
+    0x65, 0x79, 0x4e, 0x41, 0x62, 0x46, 0x76, 0x41, 0x57, 0x6c, 0x41, 0x33,
+    0x79, 0x43, 0x79, 0x79, 0x6b, 0x51, 0x72, 0x75, 0x47, 0x49, 0x67, 0x62,
+    0x33, 0x57, 0x6e, 0x74, 0x50, 0x2b, 0x4c, 0x56, 0x62, 0x42, 0x46, 0x63,
+    0x37, 0x6a, 0x4a, 0x70, 0x30, 0x56, 0x4c, 0x68, 0x44, 0x37, 0x42, 0x6f,
+    0x38, 0x77, 0x42, 0x4e, 0x36, 0x6e, 0x0a, 0x74, 0x47, 0x4f, 0x30, 0x2f,
+    0x37, 0x47, 0x63, 0x72, 0x6a, 0x79, 0x76, 0x64, 0x37, 0x5a, 0x57, 0x78,
+    0x62, 0x57, 0x72, 0x6f, 0x75, 0x6c, 0x70, 0x4f, 0x6a, 0x30, 0x4f, 0x4d,
+    0x33, 0x6b, 0x79, 0x50, 0x33, 0x43, 0x43, 0x6b, 0x70, 0x6c, 0x68, 0x62,
+    0x59, 0x30, 0x77, 0x43, 0x49, 0x39, 0x78, 0x50, 0x36, 0x5a, 0x49, 0x56,
+    0x78, 0x6e, 0x34, 0x4a, 0x64, 0x78, 0x4c, 0x5a, 0x6c, 0x79, 0x6c, 0x0a,
+    0x64, 0x49, 0x2b, 0x59, 0x72, 0x73, 0x6a, 0x35, 0x77, 0x41, 0x59, 0x69,
+    0x35, 0x36, 0x78, 0x7a, 0x33, 0x36, 0x55, 0x75, 0x2b, 0x31, 0x4c, 0x63,
+    0x73, 0x52, 0x56, 0x6c, 0x49, 0x50, 0x6f, 0x31, 0x5a, 0x6d, 0x6e, 0x65,
+    0x33, 0x79, 0x7a, 0x78, 0x62, 0x72, 0x77, 0x77, 0x32, 0x79, 0x77, 0x6b,
+    0x45, 0x74, 0x76, 0x72, 0x4e, 0x54, 0x56, 0x6f, 0x6b, 0x4d, 0x73, 0x41,
+    0x73, 0x4a, 0x63, 0x68, 0x0a, 0x50, 0x58, 0x51, 0x68, 0x49, 0x32, 0x55,
+    0x30, 0x4b, 0x37, 0x74, 0x34, 0x57, 0x61, 0x50, 0x57, 0x34, 0x58, 0x59,
+    0x35, 0x6d, 0x71, 0x52, 0x4a, 0x6a, 0x6f, 0x78, 0x30, 0x72, 0x32, 0x36,
+    0x6b, 0x6d, 0x71, 0x50, 0x5a, 0x6d, 0x39, 0x49, 0x34, 0x58, 0x4a, 0x75,
+    0x69, 0x47, 0x4d, 0x78, 0x31, 0x49, 0x34, 0x53, 0x2b, 0x36, 0x2b, 0x4a,
+    0x4e, 0x4d, 0x33, 0x47, 0x4f, 0x47, 0x76, 0x44, 0x43, 0x0a, 0x2b, 0x4d,
+    0x63, 0x64, 0x6f, 0x71, 0x30, 0x44, 0x6c, 0x79, 0x7a, 0x34, 0x7a, 0x79,
+    0x58, 0x47, 0x39, 0x72, 0x67, 0x6b, 0x4d, 0x62, 0x46, 0x6a, 0x58, 0x5a,
+    0x4a, 0x2f, 0x59, 0x2f, 0x41, 0x6c, 0x79, 0x56, 0x4d, 0x75, 0x48, 0x37,
+    0x39, 0x4e, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x67, 0x64,
+    0x49, 0x77, 0x67, 0x63, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52,
+    0x30, 0x4f, 0x0a, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4a, 0x57, 0x78, 0x74,
+    0x50, 0x43, 0x55, 0x74, 0x72, 0x33, 0x48, 0x32, 0x74, 0x45, 0x52, 0x43,
+    0x53, 0x47, 0x2b, 0x77, 0x61, 0x39, 0x4a, 0x2f, 0x52, 0x42, 0x37, 0x4d,
+    0x41, 0x73, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x51, 0x45, 0x41,
+    0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x48,
+    0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x0a, 0x42, 0x54, 0x41, 0x44,
+    0x41, 0x51, 0x48, 0x2f, 0x4d, 0x49, 0x47, 0x50, 0x42, 0x67, 0x4e, 0x56,
+    0x48, 0x53, 0x4d, 0x45, 0x67, 0x59, 0x63, 0x77, 0x67, 0x59, 0x53, 0x41,
+    0x46, 0x4a, 0x57, 0x78, 0x74, 0x50, 0x43, 0x55, 0x74, 0x72, 0x33, 0x48,
+    0x32, 0x74, 0x45, 0x52, 0x43, 0x53, 0x47, 0x2b, 0x77, 0x61, 0x39, 0x4a,
+    0x2f, 0x52, 0x42, 0x37, 0x6f, 0x57, 0x6d, 0x6b, 0x5a, 0x7a, 0x42, 0x6c,
+    0x0a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x47, 0x45, 0x77, 0x4a, 0x54, 0x52, 0x54, 0x45, 0x55, 0x4d, 0x42, 0x49,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4c, 0x51, 0x57, 0x52,
+    0x6b, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x55, 0x49,
+    0x78, 0x48, 0x54, 0x41, 0x62, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73,
+    0x54, 0x46, 0x45, 0x46, 0x6b, 0x0a, 0x5a, 0x46, 0x52, 0x79, 0x64, 0x58,
+    0x4e, 0x30, 0x49, 0x46, 0x52, 0x55, 0x55, 0x43, 0x42, 0x4f, 0x5a, 0x58,
+    0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x68, 0x42, 0x5a, 0x47,
+    0x52, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x44, 0x62, 0x47,
+    0x46, 0x7a, 0x63, 0x79, 0x41, 0x78, 0x49, 0x45, 0x4e, 0x42, 0x0a, 0x49,
+    0x46, 0x4a, 0x76, 0x62, 0x33, 0x53, 0x43, 0x41, 0x51, 0x45, 0x77, 0x44,
+    0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41,
+    0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41,
+    0x43, 0x78, 0x74, 0x5a, 0x42, 0x73, 0x66, 0x7a, 0x51, 0x33, 0x64, 0x75,
+    0x51, 0x48, 0x36, 0x6c, 0x6d, 0x4d, 0x30, 0x4d, 0x6b, 0x68, 0x48, 0x6d,
+    0x61, 0x36, 0x58, 0x0a, 0x37, 0x66, 0x31, 0x79, 0x46, 0x71, 0x5a, 0x7a,
+    0x52, 0x31, 0x72, 0x30, 0x36, 0x39, 0x33, 0x70, 0x39, 0x64, 0x62, 0x37,
+    0x52, 0x63, 0x77, 0x70, 0x69, 0x55, 0x52, 0x64, 0x76, 0x30, 0x59, 0x35,
+    0x50, 0x65, 0x6a, 0x75, 0x76, 0x45, 0x31, 0x55, 0x68, 0x68, 0x34, 0x64,
+    0x62, 0x4f, 0x4d, 0x58, 0x4a, 0x30, 0x50, 0x68, 0x69, 0x56, 0x59, 0x72,
+    0x71, 0x57, 0x39, 0x79, 0x54, 0x6b, 0x6b, 0x7a, 0x0a, 0x34, 0x33, 0x4a,
+    0x38, 0x4b, 0x69, 0x4f, 0x61, 0x76, 0x44, 0x37, 0x2f, 0x4b, 0x43, 0x72,
+    0x74, 0x6f, 0x2f, 0x38, 0x63, 0x49, 0x37, 0x70, 0x44, 0x56, 0x77, 0x6c,
+    0x6e, 0x54, 0x55, 0x74, 0x69, 0x42, 0x69, 0x33, 0x34, 0x2f, 0x32, 0x79,
+    0x64, 0x59, 0x42, 0x37, 0x59, 0x48, 0x45, 0x74, 0x39, 0x74, 0x54, 0x45,
+    0x76, 0x32, 0x64, 0x42, 0x38, 0x58, 0x66, 0x6a, 0x65, 0x61, 0x34, 0x4d,
+    0x59, 0x0a, 0x65, 0x44, 0x64, 0x58, 0x4c, 0x2b, 0x67, 0x7a, 0x42, 0x32,
+    0x66, 0x66, 0x48, 0x73, 0x64, 0x72, 0x4b, 0x70, 0x56, 0x32, 0x72, 0x6f,
+    0x39, 0x58, 0x6f, 0x2f, 0x44, 0x30, 0x55, 0x72, 0x53, 0x70, 0x55, 0x77,
+    0x6a, 0x50, 0x34, 0x45, 0x2f, 0x54, 0x65, 0x6c, 0x4f, 0x4c, 0x2f, 0x62,
+    0x73, 0x63, 0x56, 0x6a, 0x62, 0x79, 0x2f, 0x72, 0x4b, 0x32, 0x35, 0x58,
+    0x61, 0x37, 0x31, 0x53, 0x4a, 0x6c, 0x0a, 0x70, 0x7a, 0x2f, 0x2b, 0x30,
+    0x57, 0x61, 0x74, 0x43, 0x37, 0x78, 0x72, 0x6d, 0x59, 0x62, 0x76, 0x50,
+    0x33, 0x33, 0x7a, 0x47, 0x44, 0x4c, 0x4b, 0x65, 0x38, 0x62, 0x6a, 0x71,
+    0x32, 0x52, 0x47, 0x6c, 0x66, 0x67, 0x6d, 0x61, 0x64, 0x6c, 0x56, 0x67,
+    0x33, 0x73, 0x73, 0x6c, 0x67, 0x66, 0x2f, 0x57, 0x53, 0x78, 0x45, 0x6f,
+    0x38, 0x62, 0x6c, 0x36, 0x61, 0x6e, 0x63, 0x6f, 0x57, 0x4f, 0x41, 0x0a,
+    0x57, 0x69, 0x46, 0x65, 0x49, 0x63, 0x39, 0x54, 0x56, 0x50, 0x43, 0x36,
+    0x62, 0x34, 0x6e, 0x62, 0x71, 0x4b, 0x71, 0x56, 0x7a, 0x34, 0x76, 0x6a,
+    0x63, 0x63, 0x77, 0x65, 0x47, 0x79, 0x42, 0x45, 0x43, 0x4d, 0x42, 0x36,
+    0x74, 0x6b, 0x44, 0x39, 0x78, 0x4f, 0x51, 0x31, 0x34, 0x52, 0x30, 0x57,
+    0x48, 0x4e, 0x43, 0x38, 0x4b, 0x34, 0x37, 0x57, 0x63, 0x64, 0x6b, 0x3d,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72,
+    0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43,
+    0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d, 0x41, 0x64, 0x64,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x20, 0x4f, 0x55, 0x3d,
+    0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
+    0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65,
+    0x74, 0x77, 0x6f, 0x72, 0x6b, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a,
+    0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x64, 0x64, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
+    0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d,
+    0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x20,
+    0x4f, 0x55, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x0a, 0x23, 0x20, 0x4c,
+    0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x41, 0x64, 0x64, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72,
+    0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x31, 0x64, 0x3a, 0x33, 0x35, 0x3a, 0x35, 0x34, 0x3a, 0x30,
+    0x34, 0x3a, 0x38, 0x35, 0x3a, 0x37, 0x38, 0x3a, 0x62, 0x30, 0x3a, 0x33,
+    0x66, 0x3a, 0x34, 0x32, 0x3a, 0x34, 0x32, 0x3a, 0x34, 0x64, 0x3a, 0x62,
+    0x66, 0x3a, 0x32, 0x30, 0x3a, 0x37, 0x33, 0x3a, 0x30, 0x61, 0x3a, 0x33,
+    0x66, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30, 0x32,
+    0x3a, 0x66, 0x61, 0x3a, 0x66, 0x33, 0x3a, 0x65, 0x32, 0x3a, 0x39, 0x31,
+    0x3a, 0x34, 0x33, 0x3a, 0x35, 0x34, 0x3a, 0x36, 0x38, 0x3a, 0x36, 0x30,
+    0x3a, 0x37, 0x38, 0x3a, 0x35, 0x37, 0x3a, 0x36, 0x39, 0x3a, 0x34, 0x64,
+    0x3a, 0x66, 0x35, 0x3a, 0x65, 0x34, 0x3a, 0x35, 0x62, 0x3a, 0x36, 0x38,
+    0x3a, 0x38, 0x35, 0x3a, 0x31, 0x38, 0x3a, 0x36, 0x38, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x36, 0x38, 0x3a, 0x37,
+    0x66, 0x3a, 0x61, 0x34, 0x3a, 0x35, 0x31, 0x3a, 0x33, 0x38, 0x3a, 0x32,
+    0x32, 0x3a, 0x37, 0x38, 0x3a, 0x66, 0x66, 0x3a, 0x66, 0x30, 0x3a, 0x63,
+    0x38, 0x3a, 0x62, 0x31, 0x3a, 0x31, 0x66, 0x3a, 0x38, 0x64, 0x3a, 0x34,
+    0x33, 0x3a, 0x64, 0x35, 0x3a, 0x37, 0x36, 0x3a, 0x36, 0x37, 0x3a, 0x31,
+    0x63, 0x3a, 0x36, 0x65, 0x3a, 0x62, 0x32, 0x3a, 0x62, 0x63, 0x3a, 0x65,
+    0x61, 0x3a, 0x62, 0x34, 0x3a, 0x31, 0x33, 0x3a, 0x66, 0x62, 0x3a, 0x38,
+    0x33, 0x3a, 0x64, 0x39, 0x3a, 0x36, 0x35, 0x3a, 0x64, 0x30, 0x3a, 0x36,
+    0x64, 0x3a, 0x32, 0x66, 0x3a, 0x66, 0x32, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x4d, 0x49, 0x49, 0x45, 0x4e, 0x6a, 0x43, 0x43, 0x41, 0x78, 0x36, 0x67,
+    0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e,
+    0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
+    0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x76, 0x4d, 0x51, 0x73, 0x77,
+    0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x54,
+    0x52, 0x54, 0x45, 0x55, 0x0a, 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x4c, 0x51, 0x57, 0x52, 0x6b, 0x56, 0x48, 0x4a,
+    0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x55, 0x49, 0x78, 0x4a, 0x6a, 0x41,
+    0x6b, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x48, 0x55, 0x46,
+    0x6b, 0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x56,
+    0x34, 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, 0x46, 0x73, 0x0a, 0x49, 0x46,
+    0x52, 0x55, 0x55, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33,
+    0x4a, 0x72, 0x4d, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x44, 0x45, 0x78, 0x6c, 0x42, 0x5a, 0x47, 0x52, 0x55, 0x63, 0x6e,
+    0x56, 0x7a, 0x64, 0x43, 0x42, 0x46, 0x65, 0x48, 0x52, 0x6c, 0x63, 0x6d,
+    0x35, 0x68, 0x62, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x53, 0x62, 0x32,
+    0x39, 0x30, 0x0a, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x77, 0x4d,
+    0x44, 0x55, 0x7a, 0x4d, 0x44, 0x45, 0x77, 0x4e, 0x44, 0x67, 0x7a, 0x4f,
+    0x46, 0x6f, 0x58, 0x44, 0x54, 0x49, 0x77, 0x4d, 0x44, 0x55, 0x7a, 0x4d,
+    0x44, 0x45, 0x77, 0x4e, 0x44, 0x67, 0x7a, 0x4f, 0x46, 0x6f, 0x77, 0x62,
+    0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x68, 0x4d, 0x43, 0x55, 0x30, 0x55, 0x78, 0x0a, 0x46, 0x44, 0x41, 0x53,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x43, 0x30, 0x46, 0x6b,
+    0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x46, 0x43,
+    0x4d, 0x53, 0x59, 0x77, 0x4a, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c,
+    0x45, 0x78, 0x31, 0x42, 0x5a, 0x47, 0x52, 0x55, 0x63, 0x6e, 0x56, 0x7a,
+    0x64, 0x43, 0x42, 0x46, 0x65, 0x48, 0x52, 0x6c, 0x63, 0x6d, 0x35, 0x68,
+    0x0a, 0x62, 0x43, 0x42, 0x55, 0x56, 0x46, 0x41, 0x67, 0x54, 0x6d, 0x56,
+    0x30, 0x64, 0x32, 0x39, 0x79, 0x61, 0x7a, 0x45, 0x69, 0x4d, 0x43, 0x41,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x5a, 0x51, 0x57, 0x52,
+    0x6b, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x52, 0x58, 0x68,
+    0x30, 0x5a, 0x58, 0x4a, 0x75, 0x59, 0x57, 0x77, 0x67, 0x51, 0x30, 0x45,
+    0x67, 0x55, 0x6d, 0x39, 0x76, 0x0a, 0x64, 0x44, 0x43, 0x43, 0x41, 0x53,
+    0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67,
+    0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67,
+    0x45, 0x42, 0x41, 0x4c, 0x66, 0x33, 0x47, 0x6a, 0x50, 0x6d, 0x38, 0x67,
+    0x41, 0x45, 0x4c, 0x54, 0x6e, 0x67, 0x54, 0x6c, 0x76, 0x74, 0x0a, 0x48,
+    0x37, 0x78, 0x73, 0x44, 0x38, 0x32, 0x31, 0x2b, 0x69, 0x4f, 0x32, 0x7a,
+    0x74, 0x36, 0x62, 0x45, 0x54, 0x4f, 0x58, 0x70, 0x43, 0x6c, 0x4d, 0x66,
+    0x5a, 0x4f, 0x66, 0x76, 0x55, 0x71, 0x38, 0x6b, 0x2b, 0x30, 0x44, 0x47,
+    0x75, 0x4f, 0x50, 0x7a, 0x2b, 0x56, 0x74, 0x55, 0x46, 0x72, 0x57, 0x6c,
+    0x79, 0x6d, 0x55, 0x57, 0x6f, 0x43, 0x77, 0x53, 0x58, 0x72, 0x62, 0x4c,
+    0x70, 0x58, 0x39, 0x0a, 0x75, 0x4d, 0x71, 0x2f, 0x4e, 0x7a, 0x67, 0x74,
+    0x48, 0x6a, 0x36, 0x52, 0x51, 0x61, 0x31, 0x77, 0x56, 0x73, 0x66, 0x77,
+    0x54, 0x7a, 0x2f, 0x6f, 0x4d, 0x70, 0x35, 0x30, 0x79, 0x73, 0x69, 0x51,
+    0x56, 0x4f, 0x6e, 0x47, 0x58, 0x77, 0x39, 0x34, 0x6e, 0x5a, 0x70, 0x41,
+    0x50, 0x41, 0x36, 0x73, 0x59, 0x61, 0x70, 0x65, 0x46, 0x49, 0x2b, 0x65,
+    0x68, 0x36, 0x46, 0x71, 0x55, 0x4e, 0x7a, 0x58, 0x0a, 0x6d, 0x6b, 0x36,
+    0x76, 0x42, 0x62, 0x4f, 0x6d, 0x63, 0x5a, 0x53, 0x63, 0x63, 0x62, 0x4e,
+    0x51, 0x59, 0x41, 0x72, 0x48, 0x45, 0x35, 0x30, 0x34, 0x42, 0x34, 0x59,
+    0x43, 0x71, 0x4f, 0x6d, 0x6f, 0x61, 0x53, 0x59, 0x59, 0x6b, 0x4b, 0x74,
+    0x4d, 0x73, 0x45, 0x38, 0x6a, 0x71, 0x7a, 0x70, 0x50, 0x68, 0x4e, 0x6a,
+    0x66, 0x7a, 0x70, 0x2f, 0x68, 0x61, 0x57, 0x2b, 0x37, 0x31, 0x30, 0x4c,
+    0x58, 0x0a, 0x61, 0x30, 0x54, 0x6b, 0x78, 0x36, 0x33, 0x75, 0x62, 0x55,
+    0x46, 0x66, 0x63, 0x6c, 0x70, 0x78, 0x43, 0x44, 0x65, 0x7a, 0x65, 0x57,
+    0x57, 0x6b, 0x57, 0x61, 0x43, 0x55, 0x4e, 0x2f, 0x63, 0x41, 0x4c, 0x77,
+    0x33, 0x43, 0x6b, 0x6e, 0x4c, 0x61, 0x30, 0x44, 0x68, 0x79, 0x32, 0x78,
+    0x53, 0x6f, 0x52, 0x63, 0x52, 0x64, 0x4b, 0x6e, 0x32, 0x33, 0x74, 0x4e,
+    0x62, 0x45, 0x37, 0x71, 0x7a, 0x4e, 0x0a, 0x45, 0x30, 0x53, 0x33, 0x79,
+    0x53, 0x76, 0x64, 0x51, 0x77, 0x41, 0x6c, 0x2b, 0x6d, 0x47, 0x35, 0x61,
+    0x57, 0x70, 0x59, 0x49, 0x78, 0x47, 0x33, 0x70, 0x7a, 0x4f, 0x50, 0x56,
+    0x6e, 0x56, 0x5a, 0x39, 0x63, 0x30, 0x70, 0x31, 0x30, 0x61, 0x33, 0x43,
+    0x69, 0x74, 0x6c, 0x74, 0x74, 0x4e, 0x43, 0x62, 0x78, 0x57, 0x79, 0x75,
+    0x48, 0x76, 0x37, 0x37, 0x2b, 0x6c, 0x64, 0x55, 0x39, 0x55, 0x30, 0x0a,
+    0x57, 0x69, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4f, 0x42,
+    0x33, 0x44, 0x43, 0x42, 0x32, 0x54, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56,
+    0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x72, 0x62, 0x32, 0x59,
+    0x65, 0x6a, 0x53, 0x30, 0x4a, 0x76, 0x66, 0x36, 0x78, 0x43, 0x5a, 0x55,
+    0x37, 0x77, 0x4f, 0x39, 0x34, 0x43, 0x54, 0x4c, 0x56, 0x42, 0x6f, 0x77,
+    0x43, 0x77, 0x59, 0x44, 0x0a, 0x56, 0x52, 0x30, 0x50, 0x42, 0x41, 0x51,
+    0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d,
+    0x42, 0x41, 0x66, 0x38, 0x77, 0x67, 0x5a, 0x6b, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x49, 0x77, 0x53, 0x42, 0x6b, 0x54, 0x43, 0x42, 0x6a, 0x6f, 0x41,
+    0x55, 0x72, 0x62, 0x32, 0x59, 0x65, 0x6a, 0x53, 0x30, 0x0a, 0x4a, 0x76,
+    0x66, 0x36, 0x78, 0x43, 0x5a, 0x55, 0x37, 0x77, 0x4f, 0x39, 0x34, 0x43,
+    0x54, 0x4c, 0x56, 0x42, 0x71, 0x68, 0x63, 0x36, 0x52, 0x78, 0x4d, 0x47,
+    0x38, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x59, 0x54, 0x41, 0x6c, 0x4e, 0x46, 0x4d, 0x52, 0x51, 0x77, 0x45, 0x67,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x77, 0x74, 0x42, 0x5a, 0x47,
+    0x52, 0x55, 0x0a, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x42, 0x51,
+    0x6a, 0x45, 0x6d, 0x4d, 0x43, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x78, 0x4d, 0x64, 0x51, 0x57, 0x52, 0x6b, 0x56, 0x48, 0x4a, 0x31, 0x63,
+    0x33, 0x51, 0x67, 0x52, 0x58, 0x68, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x59,
+    0x57, 0x77, 0x67, 0x56, 0x46, 0x52, 0x51, 0x49, 0x45, 0x35, 0x6c, 0x64,
+    0x48, 0x64, 0x76, 0x63, 0x6d, 0x73, 0x78, 0x0a, 0x49, 0x6a, 0x41, 0x67,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x47, 0x55, 0x46, 0x6b,
+    0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x56, 0x34,
+    0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, 0x46, 0x73, 0x49, 0x45, 0x4e, 0x42,
+    0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x53, 0x43, 0x41, 0x51, 0x45, 0x77,
+    0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e,
+    0x0a, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45,
+    0x42, 0x41, 0x4c, 0x43, 0x62, 0x34, 0x49, 0x55, 0x6c, 0x77, 0x74, 0x59,
+    0x6a, 0x34, 0x67, 0x2b, 0x57, 0x42, 0x70, 0x4b, 0x64, 0x51, 0x5a, 0x69,
+    0x63, 0x32, 0x59, 0x52, 0x35, 0x67, 0x64, 0x6b, 0x65, 0x57, 0x78, 0x51,
+    0x48, 0x49, 0x7a, 0x5a, 0x6c, 0x6a, 0x37, 0x44, 0x59, 0x64, 0x37, 0x75,
+    0x73, 0x51, 0x57, 0x78, 0x48, 0x0a, 0x59, 0x49, 0x4e, 0x52, 0x73, 0x50,
+    0x6b, 0x79, 0x50, 0x65, 0x66, 0x38, 0x39, 0x69, 0x59, 0x54, 0x78, 0x34,
+    0x41, 0x57, 0x70, 0x62, 0x39, 0x61, 0x2f, 0x49, 0x66, 0x50, 0x65, 0x48,
+    0x6d, 0x4a, 0x49, 0x5a, 0x72, 0x69, 0x54, 0x41, 0x63, 0x4b, 0x68, 0x6a,
+    0x57, 0x38, 0x38, 0x74, 0x35, 0x52, 0x78, 0x4e, 0x4b, 0x57, 0x74, 0x39,
+    0x78, 0x2b, 0x54, 0x75, 0x35, 0x77, 0x2f, 0x52, 0x77, 0x35, 0x0a, 0x36,
+    0x77, 0x77, 0x43, 0x55, 0x52, 0x51, 0x74, 0x6a, 0x72, 0x30, 0x57, 0x34,
+    0x4d, 0x48, 0x66, 0x52, 0x6e, 0x58, 0x6e, 0x4a, 0x4b, 0x33, 0x73, 0x39,
+    0x45, 0x4b, 0x30, 0x68, 0x5a, 0x4e, 0x77, 0x45, 0x47, 0x65, 0x36, 0x6e,
+    0x51, 0x59, 0x31, 0x53, 0x68, 0x6a, 0x54, 0x4b, 0x33, 0x72, 0x4d, 0x55,
+    0x55, 0x4b, 0x68, 0x65, 0x6d, 0x50, 0x52, 0x35, 0x72, 0x75, 0x68, 0x78,
+    0x53, 0x76, 0x43, 0x0a, 0x4e, 0x72, 0x34, 0x54, 0x44, 0x65, 0x61, 0x39,
+    0x59, 0x33, 0x35, 0x35, 0x65, 0x36, 0x63, 0x4a, 0x44, 0x55, 0x43, 0x72,
+    0x61, 0x74, 0x32, 0x50, 0x69, 0x73, 0x50, 0x32, 0x39, 0x6f, 0x77, 0x61,
+    0x51, 0x67, 0x56, 0x52, 0x31, 0x45, 0x58, 0x31, 0x6e, 0x36, 0x64, 0x69,
+    0x49, 0x57, 0x67, 0x56, 0x49, 0x45, 0x4d, 0x38, 0x6d, 0x65, 0x64, 0x38,
+    0x76, 0x53, 0x54, 0x59, 0x71, 0x5a, 0x45, 0x58, 0x0a, 0x63, 0x34, 0x67,
+    0x2f, 0x56, 0x68, 0x73, 0x78, 0x4f, 0x42, 0x69, 0x30, 0x63, 0x51, 0x2b,
+    0x61, 0x7a, 0x63, 0x67, 0x4f, 0x6e, 0x6f, 0x34, 0x75, 0x47, 0x2b, 0x47,
+    0x4d, 0x6d, 0x49, 0x50, 0x4c, 0x48, 0x7a, 0x48, 0x78, 0x52, 0x45, 0x7a,
+    0x47, 0x42, 0x48, 0x4e, 0x4a, 0x64, 0x6d, 0x41, 0x50, 0x78, 0x2f, 0x69,
+    0x39, 0x46, 0x34, 0x42, 0x72, 0x4c, 0x75, 0x6e, 0x4d, 0x54, 0x41, 0x35,
+    0x61, 0x0a, 0x6d, 0x6e, 0x6b, 0x50, 0x49, 0x41, 0x6f, 0x75, 0x31, 0x5a,
+    0x35, 0x6a, 0x4a, 0x68, 0x35, 0x56, 0x6b, 0x70, 0x54, 0x59, 0x67, 0x68,
+    0x64, 0x61, 0x65, 0x39, 0x43, 0x38, 0x78, 0x34, 0x39, 0x4f, 0x68, 0x67,
+    0x51, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75,
+    0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x43,
+    0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d, 0x41, 0x64, 0x64,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x20, 0x4f, 0x55, 0x3d,
+    0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x54, 0x54, 0x50,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41,
+    0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6c,
+    0x69, 0x63, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f,
+    0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42,
+    0x20, 0x4f, 0x55, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+    0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x41,
+    0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6c,
+    0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20,
+    0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69,
+    0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x63, 0x31, 0x3a, 0x36, 0x32, 0x3a, 0x33, 0x65, 0x3a, 0x32, 0x33,
+    0x3a, 0x63, 0x35, 0x3a, 0x38, 0x32, 0x3a, 0x37, 0x33, 0x3a, 0x39, 0x63,
+    0x3a, 0x30, 0x33, 0x3a, 0x35, 0x39, 0x3a, 0x34, 0x62, 0x3a, 0x32, 0x62,
+    0x3a, 0x65, 0x39, 0x3a, 0x37, 0x37, 0x3a, 0x34, 0x39, 0x3a, 0x37, 0x66,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x32, 0x61, 0x3a,
+    0x62, 0x36, 0x3a, 0x32, 0x38, 0x3a, 0x34, 0x38, 0x3a, 0x35, 0x65, 0x3a,
+    0x37, 0x38, 0x3a, 0x66, 0x62, 0x3a, 0x66, 0x33, 0x3a, 0x61, 0x64, 0x3a,
+    0x39, 0x65, 0x3a, 0x37, 0x39, 0x3a, 0x31, 0x30, 0x3a, 0x64, 0x64, 0x3a,
+    0x36, 0x62, 0x3a, 0x64, 0x66, 0x3a, 0x39, 0x39, 0x3a, 0x37, 0x32, 0x3a,
+    0x32, 0x63, 0x3a, 0x39, 0x36, 0x3a, 0x65, 0x35, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30, 0x37, 0x3a, 0x39, 0x31,
+    0x3a, 0x63, 0x61, 0x3a, 0x30, 0x37, 0x3a, 0x34, 0x39, 0x3a, 0x62, 0x32,
+    0x3a, 0x30, 0x37, 0x3a, 0x38, 0x32, 0x3a, 0x61, 0x61, 0x3a, 0x64, 0x33,
+    0x3a, 0x63, 0x37, 0x3a, 0x64, 0x37, 0x3a, 0x62, 0x64, 0x3a, 0x30, 0x63,
+    0x3a, 0x64, 0x66, 0x3a, 0x63, 0x39, 0x3a, 0x34, 0x38, 0x3a, 0x35, 0x38,
+    0x3a, 0x33, 0x35, 0x3a, 0x38, 0x34, 0x3a, 0x33, 0x65, 0x3a, 0x62, 0x32,
+    0x3a, 0x64, 0x37, 0x3a, 0x39, 0x39, 0x3a, 0x36, 0x30, 0x3a, 0x30, 0x39,
+    0x3a, 0x63, 0x65, 0x3a, 0x34, 0x33, 0x3a, 0x61, 0x62, 0x3a, 0x36, 0x63,
+    0x3a, 0x36, 0x39, 0x3a, 0x32, 0x37, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
+    0x49, 0x49, 0x45, 0x46, 0x54, 0x43, 0x43, 0x41, 0x76, 0x32, 0x67, 0x41,
+    0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x6b, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x54, 0x52,
+    0x54, 0x45, 0x55, 0x0a, 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x4c, 0x51, 0x57, 0x52, 0x6b, 0x56, 0x48, 0x4a, 0x31,
+    0x63, 0x33, 0x51, 0x67, 0x51, 0x55, 0x49, 0x78, 0x48, 0x54, 0x41, 0x62,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x46, 0x45, 0x46, 0x6b,
+    0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x46, 0x52, 0x55,
+    0x55, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x0a, 0x62, 0x33, 0x4a,
+    0x72, 0x4d, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x44, 0x45, 0x78, 0x64, 0x42, 0x5a, 0x47, 0x52, 0x55, 0x63, 0x6e, 0x56,
+    0x7a, 0x64, 0x43, 0x42, 0x51, 0x64, 0x57, 0x4a, 0x73, 0x61, 0x57, 0x4d,
+    0x67, 0x51, 0x30, 0x45, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x44, 0x41,
+    0x65, 0x46, 0x77, 0x30, 0x77, 0x4d, 0x44, 0x41, 0x31, 0x4d, 0x7a, 0x41,
+    0x78, 0x0a, 0x4d, 0x44, 0x51, 0x78, 0x4e, 0x54, 0x42, 0x61, 0x46, 0x77,
+    0x30, 0x79, 0x4d, 0x44, 0x41, 0x31, 0x4d, 0x7a, 0x41, 0x78, 0x4d, 0x44,
+    0x51, 0x78, 0x4e, 0x54, 0x42, 0x61, 0x4d, 0x47, 0x51, 0x78, 0x43, 0x7a,
+    0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c,
+    0x4e, 0x46, 0x4d, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x4b, 0x45, 0x77, 0x74, 0x42, 0x0a, 0x5a, 0x47, 0x52, 0x55, 0x63,
+    0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x42, 0x51, 0x6a, 0x45, 0x64, 0x4d,
+    0x42, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x55, 0x51,
+    0x57, 0x52, 0x6b, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x56,
+    0x46, 0x52, 0x51, 0x49, 0x45, 0x35, 0x6c, 0x64, 0x48, 0x64, 0x76, 0x63,
+    0x6d, 0x73, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4e, 0x56, 0x0a,
+    0x42, 0x41, 0x4d, 0x54, 0x46, 0x30, 0x46, 0x6b, 0x5a, 0x46, 0x52, 0x79,
+    0x64, 0x58, 0x4e, 0x30, 0x49, 0x46, 0x42, 0x31, 0x59, 0x6d, 0x78, 0x70,
+    0x59, 0x79, 0x42, 0x44, 0x51, 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30,
+    0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71,
+    0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46,
+    0x41, 0x41, 0x4f, 0x43, 0x0a, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, 0x49,
+    0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x36, 0x52, 0x6f,
+    0x77, 0x6a, 0x34, 0x4f, 0x49, 0x46, 0x4d, 0x45, 0x67, 0x32, 0x44, 0x79,
+    0x62, 0x6a, 0x78, 0x74, 0x2b, 0x41, 0x33, 0x53, 0x37, 0x32, 0x6d, 0x6e,
+    0x54, 0x52, 0x71, 0x58, 0x34, 0x6a, 0x73, 0x49, 0x4d, 0x45, 0x5a, 0x42,
+    0x52, 0x70, 0x53, 0x39, 0x6d, 0x56, 0x45, 0x42, 0x56, 0x0a, 0x36, 0x74,
+    0x73, 0x66, 0x53, 0x6c, 0x62, 0x75, 0x6e, 0x79, 0x4e, 0x75, 0x39, 0x44,
+    0x6e, 0x4c, 0x6f, 0x62, 0x6c, 0x76, 0x38, 0x6e, 0x37, 0x35, 0x58, 0x59,
+    0x63, 0x6d, 0x59, 0x5a, 0x34, 0x63, 0x2b, 0x4f, 0x4c, 0x73, 0x70, 0x6f,
+    0x48, 0x34, 0x49, 0x63, 0x55, 0x6b, 0x7a, 0x42, 0x45, 0x4d, 0x50, 0x39,
+    0x73, 0x6d, 0x63, 0x6e, 0x72, 0x48, 0x41, 0x5a, 0x63, 0x48, 0x46, 0x2f,
+    0x6e, 0x58, 0x0a, 0x47, 0x43, 0x77, 0x77, 0x66, 0x51, 0x35, 0x36, 0x48,
+    0x6d, 0x49, 0x65, 0x78, 0x6b, 0x76, 0x41, 0x2f, 0x58, 0x31, 0x69, 0x64,
+    0x39, 0x4e, 0x45, 0x48, 0x69, 0x66, 0x32, 0x50, 0x30, 0x74, 0x45, 0x73,
+    0x37, 0x63, 0x34, 0x32, 0x54, 0x6b, 0x66, 0x59, 0x4e, 0x56, 0x52, 0x6b,
+    0x6e, 0x4d, 0x44, 0x74, 0x41, 0x42, 0x70, 0x34, 0x2f, 0x4d, 0x55, 0x54,
+    0x75, 0x37, 0x52, 0x33, 0x41, 0x6e, 0x50, 0x0a, 0x64, 0x7a, 0x52, 0x47,
+    0x55, 0x4c, 0x44, 0x34, 0x45, 0x66, 0x4c, 0x2b, 0x4f, 0x48, 0x6e, 0x33,
+    0x42, 0x7a, 0x6e, 0x2b, 0x55, 0x5a, 0x4b, 0x58, 0x43, 0x31, 0x73, 0x49,
+    0x58, 0x7a, 0x53, 0x47, 0x41, 0x61, 0x32, 0x49, 0x6c, 0x2b, 0x74, 0x6d,
+    0x7a, 0x56, 0x37, 0x52, 0x2f, 0x39, 0x78, 0x39, 0x38, 0x6f, 0x54, 0x61,
+    0x75, 0x6e, 0x65, 0x74, 0x33, 0x49, 0x41, 0x49, 0x78, 0x36, 0x65, 0x48,
+    0x0a, 0x31, 0x6c, 0x57, 0x66, 0x6c, 0x32, 0x72, 0x6f, 0x79, 0x42, 0x46,
+    0x6b, 0x75, 0x75, 0x63, 0x5a, 0x4b, 0x54, 0x38, 0x52, 0x73, 0x33, 0x69,
+    0x51, 0x68, 0x43, 0x42, 0x53, 0x57, 0x78, 0x48, 0x76, 0x65, 0x4e, 0x43,
+    0x44, 0x39, 0x74, 0x56, 0x49, 0x6b, 0x4e, 0x41, 0x77, 0x48, 0x4d, 0x2b,
+    0x41, 0x2b, 0x57, 0x44, 0x2b, 0x65, 0x65, 0x53, 0x49, 0x38, 0x74, 0x30,
+    0x41, 0x36, 0x35, 0x52, 0x46, 0x0a, 0x36, 0x32, 0x57, 0x55, 0x61, 0x55,
+    0x43, 0x36, 0x77, 0x4e, 0x57, 0x30, 0x75, 0x4c, 0x70, 0x39, 0x42, 0x42,
+    0x47, 0x6f, 0x36, 0x7a, 0x45, 0x46, 0x6c, 0x70, 0x52, 0x4f, 0x57, 0x43,
+    0x47, 0x4f, 0x6e, 0x39, 0x42, 0x67, 0x2f, 0x51, 0x49, 0x44, 0x41, 0x51,
+    0x41, 0x42, 0x6f, 0x34, 0x48, 0x52, 0x4d, 0x49, 0x48, 0x4f, 0x4d, 0x42,
+    0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x0a, 0x42,
+    0x42, 0x53, 0x42, 0x50, 0x6a, 0x66, 0x59, 0x6b, 0x72, 0x41, 0x66, 0x64,
+    0x35, 0x39, 0x63, 0x74, 0x4b, 0x74, 0x7a, 0x71, 0x75, 0x66, 0x32, 0x4e,
+    0x47, 0x41, 0x76, 0x2b, 0x6a, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x48,
+    0x51, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44,
+    0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42,
+    0x41, 0x55, 0x77, 0x0a, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x43, 0x42,
+    0x6a, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42, 0x49, 0x47, 0x47,
+    0x4d, 0x49, 0x47, 0x44, 0x67, 0x42, 0x53, 0x42, 0x50, 0x6a, 0x66, 0x59,
+    0x6b, 0x72, 0x41, 0x66, 0x64, 0x35, 0x39, 0x63, 0x74, 0x4b, 0x74, 0x7a,
+    0x71, 0x75, 0x66, 0x32, 0x4e, 0x47, 0x41, 0x76, 0x2b, 0x71, 0x46, 0x6f,
+    0x70, 0x47, 0x59, 0x77, 0x5a, 0x44, 0x45, 0x4c, 0x0a, 0x4d, 0x41, 0x6b,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x55, 0x30, 0x55,
+    0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f,
+    0x54, 0x43, 0x30, 0x46, 0x6b, 0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e,
+    0x30, 0x49, 0x45, 0x46, 0x43, 0x4d, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x52, 0x42, 0x5a, 0x47, 0x52,
+    0x55, 0x0a, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x55, 0x56, 0x46,
+    0x41, 0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79, 0x61, 0x7a,
+    0x45, 0x67, 0x4d, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78,
+    0x4d, 0x58, 0x51, 0x57, 0x52, 0x6b, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33,
+    0x51, 0x67, 0x55, 0x48, 0x56, 0x69, 0x62, 0x47, 0x6c, 0x6a, 0x49, 0x45,
+    0x4e, 0x42, 0x49, 0x46, 0x4a, 0x76, 0x0a, 0x62, 0x33, 0x53, 0x43, 0x41,
+    0x51, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68,
+    0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67,
+    0x67, 0x45, 0x42, 0x41, 0x41, 0x50, 0x33, 0x46, 0x55, 0x72, 0x34, 0x4a,
+    0x4e, 0x6f, 0x6a, 0x56, 0x68, 0x61, 0x54, 0x64, 0x74, 0x30, 0x32, 0x4b,
+    0x4c, 0x6d, 0x75, 0x47, 0x37, 0x6a, 0x44, 0x38, 0x57, 0x53, 0x36, 0x0a,
+    0x49, 0x42, 0x68, 0x34, 0x6c, 0x53, 0x6b, 0x6e, 0x56, 0x77, 0x57, 0x38,
+    0x66, 0x43, 0x72, 0x30, 0x75, 0x56, 0x46, 0x56, 0x32, 0x6f, 0x63, 0x43,
+    0x33, 0x67, 0x38, 0x57, 0x46, 0x7a, 0x48, 0x34, 0x71, 0x6e, 0x6b, 0x75,
+    0x43, 0x52, 0x4f, 0x37, 0x72, 0x37, 0x49, 0x67, 0x47, 0x52, 0x4c, 0x6c,
+    0x6b, 0x2f, 0x6c, 0x4c, 0x2b, 0x59, 0x50, 0x6f, 0x52, 0x4e, 0x57, 0x79,
+    0x51, 0x53, 0x57, 0x2f, 0x0a, 0x69, 0x48, 0x56, 0x76, 0x2f, 0x78, 0x44,
+    0x38, 0x53, 0x6c, 0x54, 0x51, 0x58, 0x2f, 0x44, 0x36, 0x37, 0x7a, 0x5a,
+    0x7a, 0x66, 0x52, 0x73, 0x32, 0x52, 0x63, 0x59, 0x68, 0x62, 0x62, 0x51,
+    0x56, 0x75, 0x45, 0x37, 0x50, 0x6e, 0x46, 0x79, 0x6c, 0x50, 0x56, 0x6f,
+    0x41, 0x6a, 0x67, 0x62, 0x6a, 0x50, 0x47, 0x73, 0x79, 0x65, 0x2f, 0x4b,
+    0x66, 0x38, 0x4c, 0x62, 0x39, 0x33, 0x2f, 0x41, 0x6f, 0x0a, 0x47, 0x45,
+    0x6a, 0x77, 0x78, 0x72, 0x7a, 0x51, 0x76, 0x7a, 0x53, 0x41, 0x6c, 0x73,
+    0x4a, 0x4b, 0x73, 0x57, 0x32, 0x4f, 0x78, 0x35, 0x42, 0x46, 0x33, 0x69,
+    0x39, 0x6e, 0x72, 0x45, 0x55, 0x45, 0x6f, 0x33, 0x72, 0x63, 0x56, 0x5a,
+    0x4c, 0x4a, 0x52, 0x32, 0x62, 0x59, 0x47, 0x6f, 0x7a, 0x48, 0x37, 0x5a,
+    0x78, 0x4f, 0x6d, 0x75, 0x41, 0x53, 0x75, 0x37, 0x56, 0x71, 0x54, 0x49,
+    0x54, 0x68, 0x0a, 0x34, 0x53, 0x49, 0x4e, 0x68, 0x77, 0x42, 0x6b, 0x2f,
+    0x6f, 0x78, 0x39, 0x59, 0x6a, 0x6c, 0x6c, 0x70, 0x75, 0x39, 0x43, 0x74,
+    0x6f, 0x41, 0x6c, 0x45, 0x6d, 0x45, 0x42, 0x71, 0x43, 0x51, 0x54, 0x63,
+    0x41, 0x41, 0x52, 0x4a, 0x6c, 0x2f, 0x36, 0x4e, 0x56, 0x44, 0x46, 0x53,
+    0x4d, 0x77, 0x47, 0x52, 0x2b, 0x67, 0x6e, 0x32, 0x48, 0x43, 0x4e, 0x58,
+    0x32, 0x54, 0x6d, 0x6f, 0x55, 0x51, 0x6d, 0x0a, 0x58, 0x69, 0x4c, 0x73,
+    0x6b, 0x73, 0x33, 0x2f, 0x51, 0x70, 0x70, 0x45, 0x49, 0x57, 0x31, 0x63,
+    0x78, 0x65, 0x4d, 0x69, 0x48, 0x56, 0x39, 0x48, 0x45, 0x75, 0x66, 0x4f,
+    0x58, 0x31, 0x33, 0x36, 0x32, 0x4b, 0x71, 0x78, 0x4d, 0x79, 0x33, 0x5a,
+    0x64, 0x76, 0x4a, 0x4f, 0x4f, 0x6a, 0x4d, 0x4d, 0x4b, 0x37, 0x4d, 0x74,
+    0x6b, 0x41, 0x59, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e,
+    0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73,
+    0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x64, 0x64,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66,
+    0x69, 0x65, 0x64, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x4f, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41,
+    0x42, 0x20, 0x4f, 0x55, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+    0x6b, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,
+    0x20, 0x43, 0x4e, 0x3d, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x43,
+    0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d, 0x41, 0x64, 0x64,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x20, 0x4f, 0x55, 0x3d,
+    0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x54, 0x54, 0x50,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x0a, 0x23, 0x20, 0x4c,
+    0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x41, 0x64, 0x64, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65,
+    0x64, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x65, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x32, 0x37, 0x3a, 0x65, 0x63, 0x3a, 0x33, 0x39,
+    0x3a, 0x34, 0x37, 0x3a, 0x63, 0x64, 0x3a, 0x64, 0x61, 0x3a, 0x35, 0x61,
+    0x3a, 0x61, 0x66, 0x3a, 0x65, 0x32, 0x3a, 0x39, 0x61, 0x3a, 0x30, 0x31,
+    0x3a, 0x36, 0x35, 0x3a, 0x32, 0x31, 0x3a, 0x61, 0x39, 0x3a, 0x34, 0x63,
+    0x3a, 0x62, 0x62, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x34, 0x64, 0x3a, 0x32, 0x33, 0x3a, 0x37, 0x38, 0x3a, 0x65, 0x63, 0x3a,
+    0x39, 0x31, 0x3a, 0x39, 0x35, 0x3a, 0x33, 0x39, 0x3a, 0x62, 0x35, 0x3a,
+    0x30, 0x30, 0x3a, 0x37, 0x66, 0x3a, 0x37, 0x35, 0x3a, 0x38, 0x66, 0x3a,
+    0x30, 0x33, 0x3a, 0x33, 0x62, 0x3a, 0x32, 0x31, 0x3a, 0x31, 0x65, 0x3a,
+    0x63, 0x35, 0x3a, 0x34, 0x64, 0x3a, 0x38, 0x62, 0x3a, 0x63, 0x66, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x30,
+    0x3a, 0x39, 0x35, 0x3a, 0x32, 0x31, 0x3a, 0x30, 0x38, 0x3a, 0x30, 0x35,
+    0x3a, 0x64, 0x62, 0x3a, 0x34, 0x62, 0x3a, 0x62, 0x63, 0x3a, 0x33, 0x35,
+    0x3a, 0x35, 0x65, 0x3a, 0x34, 0x34, 0x3a, 0x32, 0x38, 0x3a, 0x64, 0x38,
+    0x3a, 0x66, 0x64, 0x3a, 0x36, 0x65, 0x3a, 0x63, 0x32, 0x3a, 0x63, 0x64,
+    0x3a, 0x65, 0x33, 0x3a, 0x61, 0x62, 0x3a, 0x35, 0x66, 0x3a, 0x62, 0x39,
+    0x3a, 0x37, 0x61, 0x3a, 0x39, 0x39, 0x3a, 0x34, 0x32, 0x3a, 0x39, 0x38,
+    0x3a, 0x38, 0x65, 0x3a, 0x62, 0x38, 0x3a, 0x66, 0x34, 0x3a, 0x64, 0x63,
+    0x3a, 0x64, 0x30, 0x3a, 0x36, 0x30, 0x3a, 0x31, 0x36, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x48, 0x6a, 0x43, 0x43, 0x41, 0x77,
+    0x61, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54,
+    0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77,
+    0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x6e, 0x4d, 0x51,
+    0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77,
+    0x4a, 0x54, 0x52, 0x54, 0x45, 0x55, 0x0a, 0x4d, 0x42, 0x49, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4c, 0x51, 0x57, 0x52, 0x6b, 0x56,
+    0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x51, 0x55, 0x49, 0x78, 0x48,
+    0x54, 0x41, 0x62, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x46,
+    0x45, 0x46, 0x6b, 0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49,
+    0x46, 0x52, 0x55, 0x55, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x0a,
+    0x62, 0x33, 0x4a, 0x72, 0x4d, 0x53, 0x4d, 0x77, 0x49, 0x51, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x70, 0x42, 0x5a, 0x47, 0x52, 0x55,
+    0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x52, 0x64, 0x57, 0x46, 0x73,
+    0x61, 0x57, 0x5a, 0x70, 0x5a, 0x57, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67,
+    0x55, 0x6d, 0x39, 0x76, 0x64, 0x44, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77,
+    0x4d, 0x44, 0x41, 0x31, 0x0a, 0x4d, 0x7a, 0x41, 0x78, 0x4d, 0x44, 0x51,
+    0x30, 0x4e, 0x54, 0x42, 0x61, 0x46, 0x77, 0x30, 0x79, 0x4d, 0x44, 0x41,
+    0x31, 0x4d, 0x7a, 0x41, 0x78, 0x4d, 0x44, 0x51, 0x30, 0x4e, 0x54, 0x42,
+    0x61, 0x4d, 0x47, 0x63, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x4e, 0x46, 0x4d, 0x52, 0x51,
+    0x77, 0x45, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x0a, 0x45, 0x77,
+    0x74, 0x42, 0x5a, 0x47, 0x52, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43,
+    0x42, 0x42, 0x51, 0x6a, 0x45, 0x64, 0x4d, 0x42, 0x73, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x43, 0x78, 0x4d, 0x55, 0x51, 0x57, 0x52, 0x6b, 0x56, 0x48,
+    0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x56, 0x46, 0x52, 0x51, 0x49, 0x45,
+    0x35, 0x6c, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6d, 0x73, 0x78, 0x49, 0x7a,
+    0x41, 0x68, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x47,
+    0x6b, 0x46, 0x6b, 0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49,
+    0x46, 0x46, 0x31, 0x59, 0x57, 0x78, 0x70, 0x5a, 0x6d, 0x6c, 0x6c, 0x5a,
+    0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4d,
+    0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x0a, 0x41, 0x51, 0x45, 0x46,
+    0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42,
+    0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x35, 0x42, 0x36, 0x61,
+    0x2f, 0x74, 0x77, 0x4a, 0x57, 0x6f, 0x65, 0x6b, 0x6e, 0x30, 0x65, 0x2b,
+    0x45, 0x56, 0x2b, 0x76, 0x68, 0x44, 0x54, 0x62, 0x59, 0x6a, 0x78, 0x35,
+    0x65, 0x4c, 0x66, 0x70, 0x4d, 0x4c, 0x58, 0x73, 0x44, 0x42, 0x77, 0x71,
+    0x0a, 0x78, 0x42, 0x62, 0x2f, 0x34, 0x4f, 0x78, 0x78, 0x36, 0x34, 0x72,
+    0x31, 0x45, 0x57, 0x37, 0x74, 0x54, 0x77, 0x32, 0x52, 0x30, 0x68, 0x49,
+    0x59, 0x4c, 0x55, 0x6b, 0x56, 0x41, 0x63, 0x4b, 0x6b, 0x49, 0x68, 0x50,
+    0x48, 0x45, 0x57, 0x54, 0x2f, 0x49, 0x68, 0x4b, 0x61, 0x75, 0x59, 0x35,
+    0x63, 0x4c, 0x77, 0x6a, 0x50, 0x63, 0x57, 0x71, 0x7a, 0x5a, 0x77, 0x46,
+    0x5a, 0x38, 0x56, 0x31, 0x47, 0x0a, 0x38, 0x37, 0x42, 0x34, 0x70, 0x66,
+    0x59, 0x4f, 0x51, 0x6e, 0x72, 0x6a, 0x66, 0x78, 0x76, 0x4d, 0x30, 0x50,
+    0x43, 0x33, 0x4b, 0x50, 0x30, 0x71, 0x36, 0x70, 0x36, 0x7a, 0x73, 0x4c,
+    0x6b, 0x45, 0x71, 0x76, 0x33, 0x32, 0x78, 0x37, 0x53, 0x78, 0x75, 0x43,
+    0x71, 0x67, 0x2b, 0x31, 0x6a, 0x78, 0x47, 0x61, 0x42, 0x76, 0x63, 0x43,
+    0x56, 0x2b, 0x50, 0x6d, 0x6c, 0x4b, 0x66, 0x77, 0x38, 0x69, 0x0a, 0x32,
+    0x4f, 0x2b, 0x74, 0x43, 0x42, 0x47, 0x61, 0x4b, 0x5a, 0x6e, 0x68, 0x71,
+    0x6b, 0x52, 0x46, 0x6d, 0x68, 0x4a, 0x65, 0x50, 0x70, 0x31, 0x74, 0x55,
+    0x76, 0x7a, 0x6e, 0x6f, 0x44, 0x31, 0x6f, 0x4c, 0x2f, 0x42, 0x4c, 0x63,
+    0x48, 0x77, 0x54, 0x4f, 0x4b, 0x32, 0x38, 0x46, 0x53, 0x58, 0x78, 0x31,
+    0x73, 0x36, 0x72, 0x6f, 0x73, 0x41, 0x78, 0x31, 0x69, 0x2b, 0x66, 0x34,
+    0x50, 0x38, 0x55, 0x0a, 0x57, 0x66, 0x79, 0x45, 0x6b, 0x39, 0x6d, 0x48,
+    0x66, 0x45, 0x78, 0x55, 0x45, 0x2b, 0x75, 0x66, 0x30, 0x53, 0x30, 0x52,
+    0x2b, 0x42, 0x67, 0x36, 0x4f, 0x74, 0x34, 0x6c, 0x32, 0x66, 0x66, 0x54,
+    0x51, 0x4f, 0x32, 0x6b, 0x42, 0x68, 0x4c, 0x45, 0x4f, 0x2b, 0x47, 0x52,
+    0x77, 0x56, 0x59, 0x31, 0x38, 0x42, 0x54, 0x63, 0x5a, 0x54, 0x59, 0x4a,
+    0x62, 0x71, 0x75, 0x6b, 0x42, 0x38, 0x63, 0x31, 0x0a, 0x30, 0x63, 0x49,
+    0x44, 0x4d, 0x7a, 0x5a, 0x62, 0x64, 0x53, 0x5a, 0x74, 0x51, 0x76, 0x45,
+    0x53, 0x61, 0x30, 0x4e, 0x76, 0x53, 0x33, 0x47, 0x55, 0x2b, 0x6a, 0x51,
+    0x64, 0x37, 0x52, 0x4e, 0x75, 0x79, 0x6f, 0x42, 0x2f, 0x6d, 0x43, 0x39,
+    0x73, 0x75, 0x57, 0x58, 0x59, 0x36, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41,
+    0x42, 0x6f, 0x34, 0x48, 0x55, 0x4d, 0x49, 0x48, 0x52, 0x4d, 0x42, 0x30,
+    0x47, 0x0a, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42,
+    0x51, 0x35, 0x6c, 0x59, 0x74, 0x69, 0x69, 0x31, 0x7a, 0x4a, 0x31, 0x49,
+    0x43, 0x36, 0x57, 0x41, 0x2b, 0x58, 0x50, 0x78, 0x55, 0x49, 0x51, 0x38,
+    0x79, 0x59, 0x70, 0x7a, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51,
+    0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77,
+    0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x0a, 0x41, 0x51, 0x48, 0x2f, 0x42,
+    0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x43, 0x42, 0x6b,
+    0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42, 0x49, 0x47, 0x4a, 0x4d,
+    0x49, 0x47, 0x47, 0x67, 0x42, 0x51, 0x35, 0x6c, 0x59, 0x74, 0x69, 0x69,
+    0x31, 0x7a, 0x4a, 0x31, 0x49, 0x43, 0x36, 0x57, 0x41, 0x2b, 0x58, 0x50,
+    0x78, 0x55, 0x49, 0x51, 0x38, 0x79, 0x59, 0x70, 0x36, 0x46, 0x72, 0x0a,
+    0x70, 0x47, 0x6b, 0x77, 0x5a, 0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x55, 0x30, 0x55, 0x78,
+    0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54,
+    0x43, 0x30, 0x46, 0x6b, 0x5a, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30,
+    0x49, 0x45, 0x46, 0x43, 0x4d, 0x52, 0x30, 0x77, 0x47, 0x77, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x4c, 0x0a, 0x45, 0x78, 0x52, 0x42, 0x5a, 0x47, 0x52,
+    0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x55, 0x56, 0x46, 0x41,
+    0x67, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79, 0x61, 0x7a, 0x45,
+    0x6a, 0x4d, 0x43, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x61, 0x51, 0x57, 0x52, 0x6b, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51,
+    0x67, 0x55, 0x58, 0x56, 0x68, 0x62, 0x47, 0x6c, 0x6d, 0x0a, 0x61, 0x57,
+    0x56, 0x6b, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33,
+    0x53, 0x43, 0x41, 0x51, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f,
+    0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51,
+    0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x42, 0x6d, 0x72, 0x64, 0x65,
+    0x72, 0x34, 0x69, 0x32, 0x56, 0x68, 0x6c, 0x52, 0x4f, 0x36, 0x61, 0x51,
+    0x54, 0x76, 0x0a, 0x68, 0x73, 0x6f, 0x54, 0x6f, 0x4d, 0x65, 0x71, 0x54,
+    0x32, 0x51, 0x62, 0x50, 0x78, 0x6a, 0x32, 0x71, 0x43, 0x30, 0x73, 0x56,
+    0x59, 0x38, 0x46, 0x74, 0x7a, 0x44, 0x71, 0x51, 0x6d, 0x6f, 0x64, 0x77,
+    0x43, 0x56, 0x52, 0x4c, 0x61, 0x65, 0x2f, 0x44, 0x4c, 0x50, 0x74, 0x37,
+    0x77, 0x68, 0x2f, 0x62, 0x44, 0x78, 0x47, 0x47, 0x75, 0x6f, 0x59, 0x51,
+    0x39, 0x39, 0x32, 0x7a, 0x50, 0x6c, 0x6d, 0x0a, 0x68, 0x70, 0x77, 0x73,
+    0x61, 0x50, 0x58, 0x70, 0x46, 0x2f, 0x67, 0x78, 0x73, 0x78, 0x6a, 0x45,
+    0x31, 0x6b, 0x68, 0x39, 0x49, 0x30, 0x78, 0x6f, 0x77, 0x58, 0x36, 0x37,
+    0x41, 0x52, 0x52, 0x76, 0x78, 0x64, 0x6c, 0x75, 0x33, 0x72, 0x73, 0x45,
+    0x51, 0x6d, 0x72, 0x34, 0x39, 0x6c, 0x78, 0x39, 0x35, 0x64, 0x72, 0x36,
+    0x68, 0x2b, 0x73, 0x4e, 0x4e, 0x56, 0x4a, 0x6e, 0x30, 0x4a, 0x36, 0x58,
+    0x0a, 0x64, 0x67, 0x57, 0x54, 0x50, 0x35, 0x58, 0x48, 0x41, 0x65, 0x5a,
+    0x70, 0x56, 0x54, 0x68, 0x2f, 0x45, 0x47, 0x47, 0x5a, 0x79, 0x65, 0x4e,
+    0x66, 0x70, 0x73, 0x6f, 0x2b, 0x67, 0x6d, 0x4e, 0x49, 0x71, 0x75, 0x49,
+    0x49, 0x53, 0x44, 0x36, 0x71, 0x38, 0x72, 0x4b, 0x46, 0x59, 0x71, 0x61,
+    0x30, 0x70, 0x39, 0x6d, 0x39, 0x4e, 0x35, 0x78, 0x6f, 0x74, 0x53, 0x31,
+    0x57, 0x66, 0x62, 0x43, 0x33, 0x0a, 0x50, 0x36, 0x43, 0x78, 0x42, 0x39,
+    0x62, 0x70, 0x54, 0x39, 0x7a, 0x65, 0x52, 0x58, 0x45, 0x77, 0x4d, 0x6e,
+    0x38, 0x62, 0x4c, 0x67, 0x6e, 0x35, 0x76, 0x31, 0x4b, 0x68, 0x37, 0x73,
+    0x4b, 0x41, 0x50, 0x67, 0x5a, 0x63, 0x4c, 0x6c, 0x56, 0x41, 0x77, 0x52,
+    0x76, 0x31, 0x63, 0x45, 0x57, 0x77, 0x33, 0x46, 0x33, 0x36, 0x39, 0x6e,
+    0x4a, 0x61, 0x64, 0x39, 0x4a, 0x6a, 0x7a, 0x63, 0x39, 0x59, 0x0a, 0x69,
+    0x51, 0x42, 0x43, 0x59, 0x7a, 0x39, 0x35, 0x4f, 0x64, 0x42, 0x45, 0x73,
+    0x49, 0x4a, 0x75, 0x51, 0x52, 0x6e, 0x6f, 0x33, 0x65, 0x44, 0x42, 0x69,
+    0x46, 0x72, 0x52, 0x48, 0x6e, 0x47, 0x54, 0x48, 0x79, 0x51, 0x77, 0x64,
+    0x4f, 0x55, 0x65, 0x71, 0x4e, 0x34, 0x38, 0x4a, 0x7a, 0x64, 0x2f, 0x67,
+    0x36, 0x36, 0x65, 0x64, 0x38, 0x2f, 0x77, 0x4d, 0x4c, 0x48, 0x2f, 0x53,
+    0x35, 0x6e, 0x6f, 0x0a, 0x78, 0x71, 0x45, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f,
+    0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+    0x79, 0x20, 0x4f, 0x3d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77,
+    0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74,
+    0x2f, 0x43, 0x50, 0x53, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6f,
+    0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20,
+    0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2f, 0x28, 0x63,
+    0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75,
+    0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x45,
+    0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20,
+    0x4f, 0x3d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e, 0x65,
+    0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43,
+    0x50, 0x53, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70,
+    0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65,
+    0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2f, 0x28, 0x63, 0x29, 0x20,
+    0x32, 0x30, 0x30, 0x36, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62,
+    0x65, 0x6c, 0x3a, 0x20, 0x22, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72,
+    0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x31, 0x36, 0x34, 0x36, 0x36, 0x30,
+    0x38, 0x32, 0x30, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64,
+    0x36, 0x3a, 0x61, 0x35, 0x3a, 0x63, 0x33, 0x3a, 0x65, 0x64, 0x3a, 0x35,
+    0x64, 0x3a, 0x64, 0x64, 0x3a, 0x33, 0x65, 0x3a, 0x30, 0x30, 0x3a, 0x63,
+    0x31, 0x3a, 0x33, 0x64, 0x3a, 0x38, 0x37, 0x3a, 0x39, 0x32, 0x3a, 0x31,
+    0x66, 0x3a, 0x31, 0x64, 0x3a, 0x33, 0x66, 0x3a, 0x65, 0x34, 0x0a, 0x23,
+    0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x62, 0x33, 0x3a, 0x31, 0x65,
+    0x3a, 0x62, 0x31, 0x3a, 0x62, 0x37, 0x3a, 0x34, 0x30, 0x3a, 0x65, 0x33,
+    0x3a, 0x36, 0x63, 0x3a, 0x38, 0x34, 0x3a, 0x30, 0x32, 0x3a, 0x64, 0x61,
+    0x3a, 0x64, 0x63, 0x3a, 0x33, 0x37, 0x3a, 0x64, 0x34, 0x3a, 0x34, 0x64,
+    0x3a, 0x66, 0x35, 0x3a, 0x64, 0x34, 0x3a, 0x36, 0x37, 0x3a, 0x34, 0x39,
+    0x3a, 0x35, 0x32, 0x3a, 0x66, 0x39, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x37, 0x33, 0x3a, 0x63, 0x31, 0x3a, 0x37,
+    0x36, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x66, 0x3a, 0x31, 0x62, 0x3a, 0x63,
+    0x36, 0x3a, 0x64, 0x35, 0x3a, 0x61, 0x64, 0x3a, 0x66, 0x34, 0x3a, 0x35,
+    0x62, 0x3a, 0x30, 0x65, 0x3a, 0x37, 0x36, 0x3a, 0x65, 0x37, 0x3a, 0x32,
+    0x37, 0x3a, 0x32, 0x38, 0x3a, 0x37, 0x63, 0x3a, 0x38, 0x64, 0x3a, 0x65,
+    0x35, 0x3a, 0x37, 0x36, 0x3a, 0x31, 0x36, 0x3a, 0x63, 0x31, 0x3a, 0x65,
+    0x36, 0x3a, 0x65, 0x36, 0x3a, 0x31, 0x34, 0x3a, 0x31, 0x61, 0x3a, 0x32,
+    0x62, 0x3a, 0x32, 0x63, 0x3a, 0x62, 0x63, 0x3a, 0x37, 0x64, 0x3a, 0x38,
+    0x65, 0x3a, 0x34, 0x63, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45,
+    0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43,
+    0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49,
+    0x45, 0x6b, 0x54, 0x43, 0x43, 0x41, 0x33, 0x6d, 0x67, 0x41, 0x77, 0x49,
+    0x42, 0x41, 0x67, 0x49, 0x45, 0x52, 0x57, 0x74, 0x51, 0x56, 0x44, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x73, 0x44, 0x45,
+    0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d,
+    0x43, 0x0a, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x6a, 0x41, 0x55, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x55, 0x56, 0x75, 0x64, 0x48,
+    0x4a, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79,
+    0x34, 0x78, 0x4f, 0x54, 0x41, 0x33, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x73, 0x54, 0x4d, 0x48, 0x64, 0x33, 0x64, 0x79, 0x35, 0x6c, 0x62, 0x6e,
+    0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x0a, 0x4c, 0x6d, 0x35, 0x6c, 0x64,
+    0x43, 0x39, 0x44, 0x55, 0x46, 0x4d, 0x67, 0x61, 0x58, 0x4d, 0x67, 0x61,
+    0x57, 0x35, 0x6a, 0x62, 0x33, 0x4a, 0x77, 0x62, 0x33, 0x4a, 0x68, 0x64,
+    0x47, 0x56, 0x6b, 0x49, 0x47, 0x4a, 0x35, 0x49, 0x48, 0x4a, 0x6c, 0x5a,
+    0x6d, 0x56, 0x79, 0x5a, 0x57, 0x35, 0x6a, 0x5a, 0x54, 0x45, 0x66, 0x4d,
+    0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x57, 0x0a,
+    0x4b, 0x47, 0x4d, 0x70, 0x49, 0x44, 0x49, 0x77, 0x4d, 0x44, 0x59, 0x67,
+    0x52, 0x57, 0x35, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x77, 0x67,
+    0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x74, 0x4d, 0x43, 0x73, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x6b, 0x52, 0x57, 0x35, 0x30,
+    0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30,
+    0x49, 0x45, 0x4e, 0x6c, 0x0a, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c,
+    0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56,
+    0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x42, 0x34,
+    0x58, 0x44, 0x54, 0x41, 0x32, 0x4d, 0x54, 0x45, 0x79, 0x4e, 0x7a, 0x49,
+    0x77, 0x4d, 0x6a, 0x4d, 0x30, 0x4d, 0x6c, 0x6f, 0x58, 0x44, 0x54, 0x49,
+    0x32, 0x4d, 0x54, 0x45, 0x79, 0x4e, 0x7a, 0x49, 0x77, 0x0a, 0x4e, 0x54,
+    0x4d, 0x30, 0x4d, 0x6c, 0x6f, 0x77, 0x67, 0x62, 0x41, 0x78, 0x43, 0x7a,
+    0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c,
+    0x56, 0x54, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x4b, 0x45, 0x77, 0x31, 0x46, 0x62, 0x6e, 0x52, 0x79, 0x64, 0x58,
+    0x4e, 0x30, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x54,
+    0x6b, 0x77, 0x0a, 0x4e, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45,
+    0x7a, 0x42, 0x33, 0x64, 0x33, 0x63, 0x75, 0x5a, 0x57, 0x35, 0x30, 0x63,
+    0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x75, 0x5a, 0x58, 0x51, 0x76, 0x51,
+    0x31, 0x42, 0x54, 0x49, 0x47, 0x6c, 0x7a, 0x49, 0x47, 0x6c, 0x75, 0x59,
+    0x32, 0x39, 0x79, 0x63, 0x47, 0x39, 0x79, 0x59, 0x58, 0x52, 0x6c, 0x5a,
+    0x43, 0x42, 0x69, 0x65, 0x53, 0x42, 0x79, 0x0a, 0x5a, 0x57, 0x5a, 0x6c,
+    0x63, 0x6d, 0x56, 0x75, 0x59, 0x32, 0x55, 0x78, 0x48, 0x7a, 0x41, 0x64,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x46, 0x69, 0x68, 0x6a,
+    0x4b, 0x53, 0x41, 0x79, 0x4d, 0x44, 0x41, 0x32, 0x49, 0x45, 0x56, 0x75,
+    0x64, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x73, 0x49, 0x45, 0x6c, 0x75,
+    0x59, 0x79, 0x34, 0x78, 0x4c, 0x54, 0x41, 0x72, 0x42, 0x67, 0x4e, 0x56,
+    0x0a, 0x42, 0x41, 0x4d, 0x54, 0x4a, 0x45, 0x56, 0x75, 0x64, 0x48, 0x4a,
+    0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x43, 0x42,
+    0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46,
+    0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68,
+    0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49,
+    0x77, 0x44, 0x51, 0x59, 0x4a, 0x0a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67,
+    0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67,
+    0x45, 0x42, 0x41, 0x4c, 0x61, 0x56, 0x74, 0x6b, 0x4e, 0x43, 0x2b, 0x73,
+    0x5a, 0x74, 0x4b, 0x6d, 0x39, 0x49, 0x33, 0x35, 0x52, 0x4d, 0x4f, 0x56,
+    0x63, 0x46, 0x37, 0x73, 0x4e, 0x35, 0x45, 0x55, 0x46, 0x6f, 0x0a, 0x4e,
+    0x75, 0x33, 0x73, 0x2f, 0x70, 0x6f, 0x42, 0x6a, 0x36, 0x45, 0x34, 0x4b,
+    0x50, 0x7a, 0x33, 0x45, 0x45, 0x5a, 0x6d, 0x4c, 0x6b, 0x30, 0x65, 0x47,
+    0x72, 0x45, 0x61, 0x54, 0x73, 0x62, 0x52, 0x77, 0x4a, 0x57, 0x49, 0x73,
+    0x4d, 0x6e, 0x2f, 0x4d, 0x59, 0x73, 0x7a, 0x41, 0x39, 0x75, 0x33, 0x67,
+    0x33, 0x73, 0x2b, 0x49, 0x49, 0x52, 0x65, 0x37, 0x62, 0x4a, 0x57, 0x4b,
+    0x4b, 0x66, 0x34, 0x0a, 0x34, 0x4c, 0x6c, 0x41, 0x63, 0x54, 0x66, 0x46,
+    0x79, 0x30, 0x63, 0x4f, 0x6c, 0x79, 0x70, 0x6f, 0x77, 0x43, 0x4b, 0x56,
+    0x59, 0x68, 0x58, 0x62, 0x52, 0x39, 0x6e, 0x31, 0x30, 0x43, 0x76, 0x2f,
+    0x67, 0x6b, 0x76, 0x4a, 0x72, 0x54, 0x37, 0x65, 0x54, 0x4e, 0x75, 0x51,
+    0x67, 0x46, 0x41, 0x2f, 0x43, 0x59, 0x71, 0x45, 0x41, 0x4f, 0x77, 0x77,
+    0x43, 0x6a, 0x30, 0x59, 0x7a, 0x66, 0x76, 0x39, 0x0a, 0x4b, 0x6c, 0x6d,
+    0x61, 0x49, 0x35, 0x55, 0x58, 0x4c, 0x45, 0x57, 0x65, 0x48, 0x32, 0x35,
+    0x44, 0x65, 0x57, 0x30, 0x4d, 0x58, 0x4a, 0x6a, 0x2b, 0x53, 0x4b, 0x66,
+    0x46, 0x49, 0x30, 0x64, 0x63, 0x58, 0x76, 0x31, 0x75, 0x35, 0x78, 0x36,
+    0x30, 0x39, 0x6d, 0x68, 0x46, 0x30, 0x59, 0x61, 0x44, 0x57, 0x36, 0x4b,
+    0x4b, 0x6a, 0x62, 0x48, 0x6a, 0x4b, 0x59, 0x44, 0x2b, 0x4a, 0x58, 0x47,
+    0x49, 0x0a, 0x72, 0x62, 0x36, 0x38, 0x6a, 0x36, 0x78, 0x53, 0x6c, 0x6b,
+    0x75, 0x71, 0x55, 0x59, 0x33, 0x6b, 0x45, 0x7a, 0x45, 0x5a, 0x36, 0x45,
+    0x35, 0x4e, 0x6e, 0x39, 0x75, 0x73, 0x73, 0x32, 0x72, 0x56, 0x76, 0x44,
+    0x6c, 0x55, 0x63, 0x63, 0x70, 0x36, 0x65, 0x6e, 0x2b, 0x51, 0x33, 0x58,
+    0x30, 0x64, 0x67, 0x4e, 0x6d, 0x42, 0x75, 0x31, 0x6b, 0x6d, 0x77, 0x68,
+    0x48, 0x2b, 0x35, 0x70, 0x50, 0x69, 0x0a, 0x39, 0x34, 0x44, 0x6b, 0x5a,
+    0x66, 0x73, 0x30, 0x4e, 0x77, 0x34, 0x70, 0x67, 0x48, 0x42, 0x4e, 0x72,
+    0x7a, 0x69, 0x47, 0x4c, 0x70, 0x35, 0x2f, 0x56, 0x36, 0x2b, 0x65, 0x46,
+    0x36, 0x37, 0x72, 0x48, 0x4d, 0x73, 0x6f, 0x49, 0x56, 0x2b, 0x32, 0x48,
+    0x4e, 0x6a, 0x6e, 0x6f, 0x67, 0x51, 0x69, 0x2b, 0x64, 0x50, 0x61, 0x32,
+    0x4d, 0x73, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4f, 0x42, 0x0a,
+    0x73, 0x44, 0x43, 0x42, 0x72, 0x54, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56,
+    0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43,
+    0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54,
+    0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42,
+    0x2f, 0x7a, 0x41, 0x72, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x41, 0x45,
+    0x4a, 0x44, 0x41, 0x69, 0x0a, 0x67, 0x41, 0x38, 0x79, 0x4d, 0x44, 0x41,
+    0x32, 0x4d, 0x54, 0x45, 0x79, 0x4e, 0x7a, 0x49, 0x77, 0x4d, 0x6a, 0x4d,
+    0x30, 0x4d, 0x6c, 0x71, 0x42, 0x44, 0x7a, 0x49, 0x77, 0x4d, 0x6a, 0x59,
+    0x78, 0x4d, 0x54, 0x49, 0x33, 0x4d, 0x6a, 0x41, 0x31, 0x4d, 0x7a, 0x51,
+    0x79, 0x57, 0x6a, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d,
+    0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x52, 0x6f, 0x0a, 0x6b, 0x4f,
+    0x52, 0x6e, 0x70, 0x4b, 0x5a, 0x54, 0x67, 0x4d, 0x65, 0x47, 0x5a, 0x71,
+    0x54, 0x78, 0x39, 0x30, 0x74, 0x44, 0x2b, 0x34, 0x53, 0x39, 0x62, 0x54,
+    0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67,
+    0x51, 0x55, 0x61, 0x4a, 0x44, 0x6b, 0x5a, 0x36, 0x53, 0x6d, 0x55, 0x34,
+    0x44, 0x48, 0x68, 0x6d, 0x61, 0x6b, 0x38, 0x66, 0x64, 0x4c, 0x51, 0x2f,
+    0x75, 0x45, 0x0a, 0x76, 0x57, 0x30, 0x77, 0x48, 0x51, 0x59, 0x4a, 0x4b,
+    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x5a, 0x39, 0x42, 0x30, 0x45, 0x41, 0x42,
+    0x42, 0x41, 0x77, 0x44, 0x68, 0x73, 0x49, 0x56, 0x6a, 0x63, 0x75, 0x4d,
+    0x54, 0x6f, 0x30, 0x4c, 0x6a, 0x41, 0x44, 0x41, 0x67, 0x53, 0x51, 0x4d,
+    0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44,
+    0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x0a, 0x41, 0x34, 0x49, 0x42,
+    0x41, 0x51, 0x43, 0x54, 0x31, 0x44, 0x43, 0x77, 0x31, 0x77, 0x4d, 0x67,
+    0x4b, 0x74, 0x44, 0x35, 0x59, 0x2b, 0x69, 0x52, 0x44, 0x41, 0x55, 0x67,
+    0x71, 0x56, 0x38, 0x5a, 0x79, 0x6e, 0x74, 0x79, 0x54, 0x74, 0x53, 0x78,
+    0x32, 0x39, 0x43, 0x57, 0x2b, 0x31, 0x52, 0x61, 0x47, 0x53, 0x77, 0x4d,
+    0x43, 0x50, 0x65, 0x79, 0x76, 0x49, 0x57, 0x6f, 0x6e, 0x58, 0x39, 0x74,
+    0x0a, 0x4f, 0x31, 0x4b, 0x7a, 0x4b, 0x74, 0x76, 0x6e, 0x31, 0x49, 0x53,
+    0x4d, 0x59, 0x2f, 0x59, 0x50, 0x79, 0x79, 0x59, 0x42, 0x6b, 0x56, 0x42,
+    0x73, 0x39, 0x46, 0x38, 0x55, 0x34, 0x70, 0x4e, 0x30, 0x77, 0x42, 0x4f,
+    0x65, 0x4d, 0x44, 0x70, 0x51, 0x34, 0x37, 0x52, 0x67, 0x78, 0x52, 0x7a,
+    0x77, 0x49, 0x6b, 0x53, 0x4e, 0x63, 0x55, 0x65, 0x73, 0x79, 0x42, 0x72,
+    0x4a, 0x36, 0x5a, 0x75, 0x61, 0x0a, 0x41, 0x47, 0x41, 0x54, 0x2f, 0x33,
+    0x42, 0x2b, 0x58, 0x78, 0x46, 0x4e, 0x53, 0x52, 0x75, 0x7a, 0x46, 0x56,
+    0x4a, 0x37, 0x79, 0x56, 0x54, 0x61, 0x76, 0x35, 0x32, 0x56, 0x72, 0x32,
+    0x75, 0x61, 0x32, 0x4a, 0x37, 0x70, 0x38, 0x65, 0x52, 0x44, 0x6a, 0x65,
+    0x49, 0x52, 0x52, 0x44, 0x71, 0x2f, 0x72, 0x37, 0x32, 0x44, 0x51, 0x6e,
+    0x4e, 0x53, 0x69, 0x36, 0x71, 0x37, 0x70, 0x79, 0x6e, 0x50, 0x0a, 0x39,
+    0x57, 0x51, 0x63, 0x43, 0x6b, 0x33, 0x52, 0x76, 0x4b, 0x71, 0x73, 0x6e,
+    0x79, 0x72, 0x51, 0x2f, 0x33, 0x39, 0x2f, 0x32, 0x6e, 0x33, 0x71, 0x73,
+    0x65, 0x30, 0x77, 0x4a, 0x63, 0x47, 0x45, 0x32, 0x6a, 0x54, 0x53, 0x57,
+    0x33, 0x69, 0x44, 0x56, 0x75, 0x79, 0x63, 0x4e, 0x73, 0x4d, 0x6d, 0x34,
+    0x68, 0x48, 0x32, 0x5a, 0x30, 0x6b, 0x64, 0x6b, 0x71, 0x75, 0x4d, 0x2b,
+    0x2b, 0x76, 0x2f, 0x0a, 0x65, 0x75, 0x36, 0x46, 0x53, 0x71, 0x64, 0x51,
+    0x67, 0x50, 0x43, 0x6e, 0x58, 0x45, 0x71, 0x55, 0x4c, 0x6c, 0x38, 0x46,
+    0x6d, 0x54, 0x78, 0x53, 0x51, 0x65, 0x44, 0x4e, 0x74, 0x47, 0x50, 0x50,
+    0x41, 0x55, 0x4f, 0x36, 0x6e, 0x49, 0x50, 0x63, 0x6a, 0x32, 0x41, 0x37,
+    0x38, 0x31, 0x71, 0x30, 0x74, 0x48, 0x75, 0x75, 0x32, 0x67, 0x75, 0x51,
+    0x4f, 0x48, 0x58, 0x76, 0x67, 0x52, 0x31, 0x6d, 0x0a, 0x30, 0x76, 0x64,
+    0x58, 0x63, 0x44, 0x61, 0x7a, 0x76, 0x2f, 0x77, 0x6f, 0x72, 0x33, 0x45,
+    0x6c, 0x68, 0x56, 0x73, 0x54, 0x2f, 0x68, 0x35, 0x2f, 0x57, 0x72, 0x51,
+    0x38, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41,
+    0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65,
+    0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43,
+    0x41, 0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x34,
+    0x34, 0x34, 0x37, 0x30, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x66, 0x37, 0x3a, 0x37, 0x35, 0x3a, 0x61, 0x62, 0x3a, 0x32, 0x39, 0x3a,
+    0x66, 0x62, 0x3a, 0x35, 0x31, 0x3a, 0x34, 0x65, 0x3a, 0x62, 0x37, 0x3a,
+    0x37, 0x37, 0x3a, 0x35, 0x65, 0x3a, 0x66, 0x66, 0x3a, 0x30, 0x35, 0x3a,
+    0x33, 0x63, 0x3a, 0x39, 0x39, 0x3a, 0x38, 0x65, 0x3a, 0x66, 0x35, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x65, 0x3a, 0x32,
+    0x38, 0x3a, 0x66, 0x34, 0x3a, 0x61, 0x34, 0x3a, 0x66, 0x66, 0x3a, 0x65,
+    0x35, 0x3a, 0x62, 0x39, 0x3a, 0x32, 0x66, 0x3a, 0x61, 0x33, 0x3a, 0x63,
+    0x35, 0x3a, 0x30, 0x33, 0x3a, 0x64, 0x31, 0x3a, 0x61, 0x33, 0x3a, 0x34,
+    0x39, 0x3a, 0x61, 0x37, 0x3a, 0x66, 0x39, 0x3a, 0x39, 0x36, 0x3a, 0x32,
+    0x61, 0x3a, 0x38, 0x32, 0x3a, 0x31, 0x32, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x66, 0x66, 0x3a, 0x38, 0x35, 0x3a,
+    0x36, 0x61, 0x3a, 0x32, 0x64, 0x3a, 0x32, 0x35, 0x3a, 0x31, 0x64, 0x3a,
+    0x63, 0x64, 0x3a, 0x38, 0x38, 0x3a, 0x64, 0x33, 0x3a, 0x36, 0x36, 0x3a,
+    0x35, 0x36, 0x3a, 0x66, 0x34, 0x3a, 0x35, 0x30, 0x3a, 0x31, 0x32, 0x3a,
+    0x36, 0x37, 0x3a, 0x39, 0x38, 0x3a, 0x63, 0x66, 0x3a, 0x61, 0x62, 0x3a,
+    0x61, 0x61, 0x3a, 0x64, 0x65, 0x3a, 0x34, 0x30, 0x3a, 0x37, 0x39, 0x3a,
+    0x39, 0x63, 0x3a, 0x37, 0x32, 0x3a, 0x32, 0x64, 0x3a, 0x65, 0x34, 0x3a,
+    0x64, 0x32, 0x3a, 0x62, 0x35, 0x3a, 0x64, 0x62, 0x3a, 0x33, 0x36, 0x3a,
+    0x61, 0x37, 0x3a, 0x33, 0x61, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42,
+    0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49,
+    0x49, 0x44, 0x56, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x79, 0x67, 0x41, 0x77,
+    0x49, 0x42, 0x41, 0x67, 0x49, 0x44, 0x41, 0x6a, 0x52, 0x57, 0x4d, 0x41,
+    0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51,
+    0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4d, 0x45, 0x49, 0x78, 0x43, 0x7a,
+    0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c,
+    0x56, 0x54, 0x0a, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x4b, 0x45, 0x77, 0x31, 0x48, 0x5a, 0x57, 0x39, 0x55, 0x63,
+    0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d,
+    0x52, 0x73, 0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45,
+    0x78, 0x4a, 0x48, 0x5a, 0x57, 0x39, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64,
+    0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x0a, 0x59, 0x57, 0x77, 0x67,
+    0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x49, 0x77,
+    0x4e, 0x54, 0x49, 0x78, 0x4d, 0x44, 0x51, 0x77, 0x4d, 0x44, 0x41, 0x77,
+    0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x49, 0x77, 0x4e, 0x54, 0x49, 0x78,
+    0x4d, 0x44, 0x51, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x6a, 0x42, 0x43,
+    0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
+    0x0a, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x57, 0x4d, 0x42, 0x51,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x52, 0x32, 0x56,
+    0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x57, 0x35,
+    0x6a, 0x4c, 0x6a, 0x45, 0x62, 0x4d, 0x42, 0x6b, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x41, 0x78, 0x4d, 0x53, 0x52, 0x32, 0x56, 0x76, 0x56, 0x48, 0x4a,
+    0x31, 0x63, 0x33, 0x51, 0x67, 0x0a, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d,
+    0x46, 0x73, 0x49, 0x45, 0x4e, 0x42, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a,
+    0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77,
+    0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51,
+    0x38, 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51,
+    0x45, 0x41, 0x32, 0x73, 0x77, 0x59, 0x59, 0x7a, 0x44, 0x39, 0x0a, 0x39,
+    0x42, 0x63, 0x6a, 0x47, 0x6c, 0x5a, 0x2b, 0x57, 0x39, 0x38, 0x38, 0x62,
+    0x44, 0x6a, 0x6b, 0x63, 0x62, 0x64, 0x34, 0x6b, 0x64, 0x53, 0x38, 0x6f,
+    0x64, 0x68, 0x4d, 0x2b, 0x4b, 0x68, 0x44, 0x74, 0x67, 0x50, 0x70, 0x54,
+    0x53, 0x45, 0x48, 0x43, 0x49, 0x6a, 0x61, 0x57, 0x43, 0x39, 0x6d, 0x4f,
+    0x53, 0x6d, 0x39, 0x42, 0x58, 0x69, 0x4c, 0x6e, 0x54, 0x6a, 0x6f, 0x42,
+    0x62, 0x64, 0x71, 0x0a, 0x66, 0x6e, 0x47, 0x6b, 0x35, 0x73, 0x52, 0x67,
+    0x70, 0x72, 0x44, 0x76, 0x67, 0x4f, 0x53, 0x4a, 0x4b, 0x41, 0x2b, 0x65,
+    0x4a, 0x64, 0x62, 0x74, 0x67, 0x2f, 0x4f, 0x74, 0x70, 0x70, 0x48, 0x48,
+    0x6d, 0x4d, 0x6c, 0x43, 0x47, 0x44, 0x55, 0x55, 0x6e, 0x61, 0x32, 0x59,
+    0x52, 0x70, 0x49, 0x75, 0x54, 0x38, 0x72, 0x78, 0x68, 0x30, 0x50, 0x42,
+    0x46, 0x70, 0x56, 0x58, 0x4c, 0x56, 0x44, 0x76, 0x0a, 0x69, 0x53, 0x32,
+    0x41, 0x65, 0x6c, 0x65, 0x74, 0x38, 0x75, 0x35, 0x66, 0x61, 0x39, 0x49,
+    0x41, 0x6a, 0x62, 0x6b, 0x55, 0x2b, 0x42, 0x51, 0x56, 0x4e, 0x64, 0x6e,
+    0x41, 0x52, 0x71, 0x4e, 0x37, 0x63, 0x73, 0x69, 0x52, 0x76, 0x38, 0x6c,
+    0x56, 0x4b, 0x38, 0x33, 0x51, 0x6c, 0x7a, 0x36, 0x63, 0x4a, 0x6d, 0x54,
+    0x4d, 0x33, 0x38, 0x36, 0x44, 0x47, 0x58, 0x48, 0x4b, 0x54, 0x75, 0x62,
+    0x55, 0x0a, 0x31, 0x58, 0x75, 0x70, 0x47, 0x63, 0x31, 0x56, 0x33, 0x73,
+    0x6a, 0x73, 0x30, 0x6c, 0x34, 0x34, 0x55, 0x2b, 0x56, 0x63, 0x54, 0x34,
+    0x77, 0x74, 0x2f, 0x6c, 0x41, 0x6a, 0x4e, 0x76, 0x78, 0x6d, 0x35, 0x73,
+    0x75, 0x4f, 0x70, 0x44, 0x6b, 0x5a, 0x41, 0x4c, 0x65, 0x56, 0x41, 0x6a,
+    0x6d, 0x52, 0x43, 0x77, 0x37, 0x2b, 0x4f, 0x43, 0x37, 0x52, 0x48, 0x51,
+    0x57, 0x61, 0x39, 0x6b, 0x30, 0x2b, 0x0a, 0x62, 0x77, 0x38, 0x48, 0x48,
+    0x61, 0x38, 0x73, 0x48, 0x6f, 0x39, 0x67, 0x4f, 0x65, 0x4c, 0x36, 0x4e,
+    0x6c, 0x4d, 0x54, 0x4f, 0x64, 0x52, 0x65, 0x4a, 0x69, 0x76, 0x62, 0x50,
+    0x61, 0x67, 0x55, 0x76, 0x54, 0x4c, 0x72, 0x47, 0x41, 0x4d, 0x6f, 0x55,
+    0x67, 0x52, 0x78, 0x35, 0x61, 0x73, 0x7a, 0x50, 0x65, 0x45, 0x34, 0x75,
+    0x77, 0x63, 0x32, 0x68, 0x47, 0x4b, 0x63, 0x65, 0x65, 0x6f, 0x57, 0x0a,
+    0x4d, 0x50, 0x52, 0x66, 0x77, 0x43, 0x76, 0x6f, 0x63, 0x57, 0x76, 0x6b,
+    0x2b, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x31, 0x4d, 0x77,
+    0x55, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42,
+    0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f,
+    0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57,
+    0x42, 0x42, 0x54, 0x41, 0x0a, 0x65, 0x70, 0x68, 0x6f, 0x6a, 0x59, 0x6e,
+    0x37, 0x71, 0x77, 0x56, 0x6b, 0x44, 0x42, 0x46, 0x39, 0x71, 0x6e, 0x31,
+    0x6c, 0x75, 0x4d, 0x72, 0x4d, 0x54, 0x6a, 0x41, 0x66, 0x42, 0x67, 0x4e,
+    0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x54,
+    0x41, 0x65, 0x70, 0x68, 0x6f, 0x6a, 0x59, 0x6e, 0x37, 0x71, 0x77, 0x56,
+    0x6b, 0x44, 0x42, 0x46, 0x39, 0x71, 0x6e, 0x31, 0x6c, 0x0a, 0x75, 0x4d,
+    0x72, 0x4d, 0x54, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41,
+    0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x4e, 0x65, 0x4d, 0x70, 0x61, 0x75,
+    0x55, 0x76, 0x58, 0x56, 0x53, 0x4f, 0x4b, 0x56, 0x43, 0x55, 0x6e, 0x35,
+    0x6b, 0x61, 0x46, 0x4f, 0x53, 0x50, 0x65, 0x43, 0x70, 0x69, 0x6c, 0x4b,
+    0x49, 0x6e, 0x0a, 0x5a, 0x35, 0x37, 0x51, 0x7a, 0x78, 0x70, 0x65, 0x52,
+    0x2b, 0x6e, 0x42, 0x73, 0x71, 0x54, 0x50, 0x33, 0x55, 0x45, 0x61, 0x42,
+    0x55, 0x36, 0x62, 0x53, 0x2b, 0x35, 0x4b, 0x62, 0x31, 0x56, 0x53, 0x73,
+    0x79, 0x53, 0x68, 0x4e, 0x77, 0x72, 0x72, 0x5a, 0x48, 0x59, 0x71, 0x4c,
+    0x69, 0x7a, 0x7a, 0x2f, 0x54, 0x74, 0x31, 0x6b, 0x4c, 0x2f, 0x36, 0x63,
+    0x64, 0x6a, 0x48, 0x50, 0x54, 0x66, 0x53, 0x0a, 0x74, 0x51, 0x57, 0x56,
+    0x59, 0x72, 0x6d, 0x6d, 0x33, 0x6f, 0x6b, 0x39, 0x4e, 0x6e, 0x73, 0x34,
+    0x64, 0x30, 0x69, 0x58, 0x72, 0x4b, 0x59, 0x67, 0x6a, 0x79, 0x36, 0x6d,
+    0x79, 0x51, 0x7a, 0x43, 0x73, 0x70, 0x6c, 0x46, 0x41, 0x4d, 0x66, 0x4f,
+    0x45, 0x56, 0x45, 0x69, 0x49, 0x75, 0x43, 0x6c, 0x36, 0x72, 0x59, 0x56,
+    0x53, 0x41, 0x6c, 0x6b, 0x36, 0x6c, 0x35, 0x50, 0x64, 0x50, 0x63, 0x46,
+    0x0a, 0x50, 0x73, 0x65, 0x4b, 0x55, 0x67, 0x7a, 0x62, 0x46, 0x62, 0x53,
+    0x39, 0x62, 0x5a, 0x76, 0x6c, 0x78, 0x72, 0x46, 0x55, 0x61, 0x4b, 0x6e,
+    0x6a, 0x61, 0x5a, 0x43, 0x32, 0x6d, 0x71, 0x55, 0x50, 0x75, 0x4c, 0x6b,
+    0x2f, 0x49, 0x48, 0x32, 0x75, 0x53, 0x72, 0x57, 0x34, 0x6e, 0x4f, 0x51,
+    0x64, 0x74, 0x71, 0x76, 0x6d, 0x6c, 0x4b, 0x58, 0x42, 0x78, 0x34, 0x4f,
+    0x74, 0x32, 0x2f, 0x55, 0x6e, 0x0a, 0x68, 0x77, 0x34, 0x45, 0x62, 0x4e,
+    0x58, 0x2f, 0x33, 0x61, 0x42, 0x64, 0x37, 0x59, 0x64, 0x53, 0x74, 0x79,
+    0x73, 0x56, 0x41, 0x71, 0x34, 0x35, 0x70, 0x6d, 0x70, 0x30, 0x36, 0x64,
+    0x72, 0x45, 0x35, 0x37, 0x78, 0x4e, 0x4e, 0x42, 0x36, 0x70, 0x58, 0x45,
+    0x30, 0x7a, 0x58, 0x35, 0x49, 0x4a, 0x4c, 0x34, 0x68, 0x6d, 0x58, 0x58,
+    0x65, 0x58, 0x78, 0x78, 0x31, 0x32, 0x45, 0x36, 0x6e, 0x56, 0x0a, 0x35,
+    0x66, 0x45, 0x57, 0x43, 0x52, 0x45, 0x31, 0x31, 0x61, 0x7a, 0x62, 0x4a,
+    0x48, 0x46, 0x77, 0x4c, 0x4a, 0x68, 0x57, 0x43, 0x39, 0x6b, 0x58, 0x74,
+    0x4e, 0x48, 0x6a, 0x55, 0x53, 0x74, 0x65, 0x64, 0x65, 0x6a, 0x56, 0x30,
+    0x4e, 0x78, 0x50, 0x4e, 0x4f, 0x33, 0x43, 0x42, 0x57, 0x61, 0x41, 0x6f,
+    0x63, 0x76, 0x6d, 0x4d, 0x77, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f,
+    0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x4f, 0x3d, 0x47,
+    0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20,
+    0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47,
+    0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x32, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a,
+    0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30, 0x65, 0x3a, 0x34, 0x30,
+    0x3a, 0x61, 0x37, 0x3a, 0x36, 0x63, 0x3a, 0x64, 0x65, 0x3a, 0x30, 0x33,
+    0x3a, 0x35, 0x64, 0x3a, 0x38, 0x66, 0x3a, 0x64, 0x31, 0x3a, 0x30, 0x66,
+    0x3a, 0x65, 0x34, 0x3a, 0x64, 0x31, 0x3a, 0x38, 0x64, 0x3a, 0x66, 0x39,
+    0x3a, 0x36, 0x63, 0x3a, 0x61, 0x39, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x61, 0x39, 0x3a, 0x65, 0x39, 0x3a, 0x37, 0x38, 0x3a,
+    0x30, 0x38, 0x3a, 0x31, 0x34, 0x3a, 0x33, 0x37, 0x3a, 0x35, 0x38, 0x3a,
+    0x38, 0x38, 0x3a, 0x66, 0x32, 0x3a, 0x30, 0x35, 0x3a, 0x31, 0x39, 0x3a,
+    0x62, 0x30, 0x3a, 0x36, 0x64, 0x3a, 0x32, 0x62, 0x3a, 0x30, 0x64, 0x3a,
+    0x32, 0x62, 0x3a, 0x36, 0x30, 0x3a, 0x31, 0x36, 0x3a, 0x39, 0x30, 0x3a,
+    0x37, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x63, 0x61, 0x3a, 0x32, 0x64, 0x3a, 0x38, 0x32, 0x3a, 0x61, 0x30,
+    0x3a, 0x38, 0x36, 0x3a, 0x37, 0x37, 0x3a, 0x30, 0x37, 0x3a, 0x32, 0x66,
+    0x3a, 0x38, 0x61, 0x3a, 0x62, 0x36, 0x3a, 0x37, 0x36, 0x3a, 0x34, 0x66,
+    0x3a, 0x66, 0x30, 0x3a, 0x33, 0x35, 0x3a, 0x36, 0x37, 0x3a, 0x36, 0x63,
+    0x3a, 0x66, 0x65, 0x3a, 0x33, 0x65, 0x3a, 0x35, 0x65, 0x3a, 0x33, 0x32,
+    0x3a, 0x35, 0x65, 0x3a, 0x30, 0x31, 0x3a, 0x32, 0x31, 0x3a, 0x37, 0x32,
+    0x3a, 0x64, 0x66, 0x3a, 0x33, 0x66, 0x3a, 0x39, 0x32, 0x3a, 0x30, 0x39,
+    0x3a, 0x36, 0x64, 0x3a, 0x62, 0x37, 0x3a, 0x39, 0x62, 0x3a, 0x38, 0x35,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x5a, 0x6a, 0x43,
+    0x43, 0x41, 0x6b, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
+    0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42,
+    0x45, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x57, 0x0a, 0x4d, 0x42,
+    0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x52, 0x32,
+    0x56, 0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x57,
+    0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x64, 0x4d, 0x42, 0x73, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x41, 0x78, 0x4d, 0x55, 0x52, 0x32, 0x56, 0x76, 0x56, 0x48,
+    0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d,
+    0x46, 0x73, 0x0a, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x44, 0x49, 0x77, 0x48,
+    0x68, 0x63, 0x4e, 0x4d, 0x44, 0x51, 0x77, 0x4d, 0x7a, 0x41, 0x30, 0x4d,
+    0x44, 0x55, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d,
+    0x54, 0x6b, 0x77, 0x4d, 0x7a, 0x41, 0x30, 0x4d, 0x44, 0x55, 0x77, 0x4d,
+    0x44, 0x41, 0x77, 0x57, 0x6a, 0x42, 0x45, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0a, 0x45, 0x77, 0x4a, 0x56,
+    0x55, 0x7a, 0x45, 0x57, 0x4d, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x4e, 0x52, 0x32, 0x56, 0x76, 0x56, 0x48, 0x4a, 0x31,
+    0x63, 0x33, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x64,
+    0x4d, 0x42, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x55,
+    0x52, 0x32, 0x56, 0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67,
+    0x0a, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d, 0x46, 0x73, 0x49, 0x45, 0x4e,
+    0x42, 0x49, 0x44, 0x49, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30,
+    0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45,
+    0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41,
+    0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44,
+    0x76, 0x50, 0x45, 0x31, 0x41, 0x0a, 0x50, 0x52, 0x44, 0x66, 0x4f, 0x31,
+    0x4d, 0x41, 0x34, 0x57, 0x66, 0x2b, 0x6c, 0x47, 0x41, 0x56, 0x50, 0x6f,
+    0x57, 0x49, 0x38, 0x59, 0x6b, 0x4e, 0x6b, 0x4d, 0x67, 0x6f, 0x49, 0x35,
+    0x6b, 0x46, 0x36, 0x43, 0x73, 0x67, 0x6e, 0x63, 0x62, 0x7a, 0x59, 0x45,
+    0x62, 0x59, 0x77, 0x62, 0x4c, 0x56, 0x6a, 0x44, 0x48, 0x5a, 0x33, 0x43,
+    0x42, 0x35, 0x4a, 0x49, 0x47, 0x2f, 0x4e, 0x54, 0x4c, 0x38, 0x0a, 0x59,
+    0x32, 0x6e, 0x62, 0x73, 0x53, 0x70, 0x72, 0x37, 0x69, 0x46, 0x59, 0x38,
+    0x67, 0x6a, 0x70, 0x65, 0x4d, 0x74, 0x76, 0x79, 0x2f, 0x77, 0x57, 0x55,
+    0x73, 0x69, 0x52, 0x78, 0x50, 0x38, 0x39, 0x63, 0x39, 0x36, 0x78, 0x50,
+    0x71, 0x66, 0x43, 0x66, 0x57, 0x62, 0x42, 0x39, 0x58, 0x35, 0x53, 0x4a,
+    0x42, 0x72, 0x69, 0x31, 0x57, 0x65, 0x52, 0x30, 0x49, 0x49, 0x51, 0x31,
+    0x33, 0x68, 0x4c, 0x0a, 0x54, 0x79, 0x74, 0x43, 0x4f, 0x62, 0x31, 0x6b,
+    0x4c, 0x55, 0x43, 0x67, 0x73, 0x42, 0x44, 0x54, 0x4f, 0x45, 0x68, 0x47,
+    0x69, 0x4b, 0x45, 0x4d, 0x75, 0x7a, 0x6f, 0x7a, 0x4b, 0x6d, 0x4b, 0x59,
+    0x2b, 0x77, 0x43, 0x64, 0x45, 0x31, 0x6c, 0x2f, 0x62, 0x7a, 0x74, 0x79,
+    0x71, 0x75, 0x36, 0x6d, 0x44, 0x34, 0x62, 0x35, 0x42, 0x57, 0x48, 0x71,
+    0x5a, 0x33, 0x38, 0x4d, 0x4e, 0x35, 0x61, 0x4c, 0x0a, 0x35, 0x6d, 0x6b,
+    0x57, 0x52, 0x78, 0x48, 0x43, 0x4a, 0x31, 0x6b, 0x44, 0x73, 0x36, 0x5a,
+    0x67, 0x77, 0x69, 0x46, 0x41, 0x56, 0x76, 0x71, 0x67, 0x78, 0x33, 0x30,
+    0x36, 0x45, 0x2b, 0x50, 0x73, 0x56, 0x38, 0x65, 0x7a, 0x31, 0x71, 0x36,
+    0x64, 0x69, 0x59, 0x44, 0x33, 0x41, 0x65, 0x63, 0x73, 0x39, 0x70, 0x59,
+    0x72, 0x45, 0x77, 0x31, 0x35, 0x4c, 0x4e, 0x6e, 0x41, 0x35, 0x49, 0x5a,
+    0x37, 0x0a, 0x53, 0x34, 0x77, 0x4d, 0x63, 0x6f, 0x4b, 0x4b, 0x2b, 0x78,
+    0x66, 0x4e, 0x41, 0x47, 0x77, 0x36, 0x45, 0x7a, 0x79, 0x77, 0x68, 0x49,
+    0x64, 0x4c, 0x46, 0x6e, 0x6f, 0x70, 0x73, 0x6b, 0x2f, 0x62, 0x48, 0x64,
+    0x51, 0x4c, 0x38, 0x32, 0x59, 0x33, 0x76, 0x64, 0x6a, 0x32, 0x56, 0x37,
+    0x74, 0x65, 0x4a, 0x48, 0x71, 0x34, 0x50, 0x49, 0x75, 0x35, 0x2b, 0x70,
+    0x49, 0x61, 0x47, 0x6f, 0x53, 0x65, 0x0a, 0x32, 0x48, 0x53, 0x50, 0x71,
+    0x68, 0x74, 0x2f, 0x58, 0x76, 0x54, 0x2b, 0x52, 0x53, 0x49, 0x68, 0x41,
+    0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x59, 0x7a, 0x42, 0x68, 0x4d,
+    0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f,
+    0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48,
+    0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x0a,
+    0x46, 0x48, 0x45, 0x34, 0x4e, 0x76, 0x49, 0x43, 0x4d, 0x56, 0x4e, 0x48,
+    0x4b, 0x32, 0x36, 0x36, 0x5a, 0x55, 0x61, 0x70, 0x45, 0x42, 0x56, 0x59,
+    0x49, 0x41, 0x55, 0x4a, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64,
+    0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x48, 0x45, 0x34,
+    0x4e, 0x76, 0x49, 0x43, 0x4d, 0x56, 0x4e, 0x48, 0x4b, 0x32, 0x36, 0x36,
+    0x5a, 0x55, 0x61, 0x70, 0x0a, 0x45, 0x42, 0x56, 0x59, 0x49, 0x41, 0x55,
+    0x4a, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45,
+    0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6a, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45,
+    0x41, 0x41, 0x2f, 0x65, 0x31, 0x4b, 0x36, 0x74, 0x64, 0x0a, 0x45, 0x50,
+    0x78, 0x37, 0x73, 0x72, 0x4a, 0x65, 0x72, 0x4a, 0x73, 0x4f, 0x66, 0x6c,
+    0x4e, 0x34, 0x57, 0x54, 0x35, 0x43, 0x42, 0x50, 0x35, 0x31, 0x6f, 0x36,
+    0x32, 0x73, 0x67, 0x55, 0x37, 0x58, 0x41, 0x6f, 0x74, 0x65, 0x78, 0x43,
+    0x33, 0x49, 0x55, 0x6e, 0x62, 0x48, 0x4c, 0x42, 0x2f, 0x38, 0x67, 0x54,
+    0x4b, 0x59, 0x30, 0x55, 0x76, 0x47, 0x6b, 0x70, 0x4d, 0x7a, 0x4e, 0x54,
+    0x45, 0x76, 0x0a, 0x2f, 0x4e, 0x67, 0x64, 0x52, 0x4e, 0x33, 0x67, 0x67,
+    0x58, 0x2b, 0x64, 0x36, 0x59, 0x76, 0x68, 0x5a, 0x4a, 0x46, 0x69, 0x43,
+    0x7a, 0x6b, 0x49, 0x6a, 0x4b, 0x78, 0x30, 0x6e, 0x56, 0x6e, 0x5a, 0x65,
+    0x6c, 0x6c, 0x53, 0x6c, 0x78, 0x47, 0x35, 0x46, 0x6e, 0x74, 0x76, 0x52,
+    0x64, 0x4f, 0x57, 0x32, 0x54, 0x46, 0x39, 0x41, 0x6a, 0x59, 0x50, 0x6e,
+    0x44, 0x74, 0x75, 0x7a, 0x79, 0x77, 0x4e, 0x0a, 0x41, 0x30, 0x5a, 0x46,
+    0x36, 0x36, 0x44, 0x30, 0x66, 0x30, 0x68, 0x45, 0x78, 0x67, 0x68, 0x41,
+    0x7a, 0x4e, 0x34, 0x62, 0x63, 0x4c, 0x55, 0x70, 0x72, 0x62, 0x71, 0x4c,
+    0x4f, 0x7a, 0x52, 0x6c, 0x64, 0x52, 0x74, 0x78, 0x49, 0x52, 0x30, 0x73,
+    0x46, 0x41, 0x71, 0x77, 0x6c, 0x70, 0x57, 0x34, 0x31, 0x75, 0x72, 0x79,
+    0x5a, 0x66, 0x73, 0x70, 0x75, 0x6b, 0x2f, 0x71, 0x6b, 0x5a, 0x4e, 0x30,
+    0x0a, 0x61, 0x62, 0x62, 0x79, 0x2f, 0x2b, 0x45, 0x61, 0x30, 0x41, 0x7a,
+    0x52, 0x64, 0x6f, 0x58, 0x4c, 0x69, 0x69, 0x57, 0x39, 0x6c, 0x31, 0x34,
+    0x73, 0x62, 0x78, 0x57, 0x5a, 0x4a, 0x75, 0x65, 0x32, 0x4b, 0x66, 0x38,
+    0x69, 0x37, 0x4d, 0x6b, 0x43, 0x78, 0x31, 0x59, 0x41, 0x7a, 0x55, 0x6d,
+    0x35, 0x73, 0x32, 0x78, 0x37, 0x55, 0x77, 0x51, 0x61, 0x34, 0x71, 0x6a,
+    0x4a, 0x71, 0x68, 0x49, 0x46, 0x0a, 0x49, 0x38, 0x4c, 0x4f, 0x35, 0x37,
+    0x73, 0x45, 0x41, 0x73, 0x7a, 0x41, 0x52, 0x36, 0x4c, 0x6b, 0x78, 0x43,
+    0x6b, 0x76, 0x57, 0x30, 0x56, 0x58, 0x69, 0x56, 0x48, 0x75, 0x50, 0x4f,
+    0x74, 0x53, 0x43, 0x50, 0x38, 0x48, 0x4e, 0x52, 0x36, 0x66, 0x4e, 0x57,
+    0x70, 0x48, 0x53, 0x6c, 0x61, 0x59, 0x30, 0x56, 0x71, 0x46, 0x48, 0x34,
+    0x7a, 0x31, 0x49, 0x72, 0x2b, 0x72, 0x7a, 0x6f, 0x50, 0x7a, 0x0a, 0x34,
+    0x69, 0x49, 0x70, 0x72, 0x6e, 0x32, 0x44, 0x51, 0x4b, 0x69, 0x36, 0x62,
+    0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73,
+    0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x65, 0x6f, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73,
+    0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20,
+    0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x55, 0x6e, 0x69,
+    0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d,
+    0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22,
+    0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x55, 0x6e, 0x69,
+    0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23,
+    0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23,
+    0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x39, 0x32, 0x3a, 0x36, 0x35, 0x3a,
+    0x35, 0x38, 0x3a, 0x38, 0x62, 0x3a, 0x61, 0x32, 0x3a, 0x31, 0x61, 0x3a,
+    0x33, 0x31, 0x3a, 0x37, 0x32, 0x3a, 0x37, 0x33, 0x3a, 0x36, 0x38, 0x3a,
+    0x35, 0x63, 0x3a, 0x62, 0x34, 0x3a, 0x61, 0x35, 0x3a, 0x37, 0x61, 0x3a,
+    0x30, 0x37, 0x3a, 0x34, 0x38, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x65, 0x36, 0x3a, 0x32, 0x31, 0x3a, 0x66, 0x33, 0x3a, 0x33,
+    0x35, 0x3a, 0x34, 0x33, 0x3a, 0x37, 0x39, 0x3a, 0x30, 0x35, 0x3a, 0x39,
+    0x61, 0x3a, 0x34, 0x62, 0x3a, 0x36, 0x38, 0x3a, 0x33, 0x30, 0x3a, 0x39,
+    0x64, 0x3a, 0x38, 0x61, 0x3a, 0x32, 0x66, 0x3a, 0x37, 0x34, 0x3a, 0x32,
+    0x32, 0x3a, 0x31, 0x35, 0x3a, 0x38, 0x37, 0x3a, 0x65, 0x63, 0x3a, 0x37,
+    0x39, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x61, 0x30, 0x3a, 0x34, 0x35, 0x3a, 0x39, 0x62, 0x3a, 0x39, 0x66, 0x3a,
+    0x36, 0x33, 0x3a, 0x62, 0x32, 0x3a, 0x32, 0x35, 0x3a, 0x35, 0x39, 0x3a,
+    0x66, 0x35, 0x3a, 0x66, 0x61, 0x3a, 0x35, 0x64, 0x3a, 0x34, 0x63, 0x3a,
+    0x36, 0x64, 0x3a, 0x62, 0x33, 0x3a, 0x66, 0x39, 0x3a, 0x66, 0x37, 0x3a,
+    0x32, 0x66, 0x3a, 0x66, 0x31, 0x3a, 0x39, 0x33, 0x3a, 0x34, 0x32, 0x3a,
+    0x30, 0x33, 0x3a, 0x33, 0x35, 0x3a, 0x37, 0x38, 0x3a, 0x66, 0x30, 0x3a,
+    0x37, 0x33, 0x3a, 0x62, 0x66, 0x3a, 0x31, 0x64, 0x3a, 0x31, 0x62, 0x3a,
+    0x34, 0x36, 0x3a, 0x63, 0x62, 0x3a, 0x62, 0x39, 0x3a, 0x31, 0x32, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, 0x61, 0x44, 0x43, 0x43,
+    0x41, 0x31, 0x43, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
+    0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x46,
+    0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
+    0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x57, 0x0a, 0x4d, 0x42, 0x51,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x52, 0x32, 0x56,
+    0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x57, 0x35,
+    0x6a, 0x4c, 0x6a, 0x45, 0x65, 0x4d, 0x42, 0x77, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x41, 0x78, 0x4d, 0x56, 0x52, 0x32, 0x56, 0x76, 0x56, 0x48, 0x4a,
+    0x31, 0x63, 0x33, 0x51, 0x67, 0x56, 0x57, 0x35, 0x70, 0x64, 0x6d, 0x56,
+    0x79, 0x0a, 0x63, 0x32, 0x46, 0x73, 0x49, 0x45, 0x4e, 0x42, 0x4d, 0x42,
+    0x34, 0x58, 0x44, 0x54, 0x41, 0x30, 0x4d, 0x44, 0x4d, 0x77, 0x4e, 0x44,
+    0x41, 0x31, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54,
+    0x49, 0x35, 0x4d, 0x44, 0x4d, 0x77, 0x4e, 0x44, 0x41, 0x31, 0x4d, 0x44,
+    0x41, 0x77, 0x4d, 0x46, 0x6f, 0x77, 0x52, 0x54, 0x45, 0x4c, 0x4d, 0x41,
+    0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x46, 0x6a, 0x41, 0x55, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x44, 0x55, 0x64, 0x6c, 0x62, 0x31, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78, 0x48,
+    0x6a, 0x41, 0x63, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x46,
+    0x55, 0x64, 0x6c, 0x62, 0x31, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x0a,
+    0x49, 0x46, 0x56, 0x75, 0x61, 0x58, 0x5a, 0x6c, 0x63, 0x6e, 0x4e, 0x68,
+    0x62, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77,
+    0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e,
+    0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50,
+    0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6f, 0x43, 0x67, 0x67, 0x49, 0x42,
+    0x41, 0x4b, 0x59, 0x56, 0x0a, 0x56, 0x61, 0x43, 0x6a, 0x78, 0x75, 0x41,
+    0x66, 0x6a, 0x4a, 0x30, 0x68, 0x55, 0x4e, 0x66, 0x42, 0x76, 0x69, 0x74,
+    0x62, 0x74, 0x61, 0x53, 0x65, 0x6f, 0x64, 0x6c, 0x79, 0x57, 0x4c, 0x30,
+    0x41, 0x47, 0x30, 0x79, 0x2f, 0x59, 0x63, 0x6b, 0x55, 0x48, 0x55, 0x57,
+    0x43, 0x71, 0x38, 0x59, 0x64, 0x67, 0x4e, 0x59, 0x39, 0x36, 0x78, 0x43,
+    0x63, 0x4f, 0x71, 0x39, 0x74, 0x4a, 0x50, 0x69, 0x38, 0x0a, 0x63, 0x51,
+    0x47, 0x65, 0x42, 0x76, 0x56, 0x38, 0x58, 0x78, 0x37, 0x42, 0x44, 0x6c,
+    0x58, 0x4b, 0x67, 0x35, 0x70, 0x5a, 0x4d, 0x4b, 0x34, 0x5a, 0x79, 0x7a,
+    0x42, 0x49, 0x6c, 0x65, 0x30, 0x69, 0x4e, 0x34, 0x33, 0x30, 0x53, 0x70,
+    0x70, 0x79, 0x5a, 0x6a, 0x36, 0x74, 0x6c, 0x63, 0x44, 0x67, 0x46, 0x67,
+    0x44, 0x67, 0x45, 0x42, 0x38, 0x72, 0x4d, 0x51, 0x37, 0x58, 0x6c, 0x46,
+    0x54, 0x54, 0x0a, 0x51, 0x6a, 0x4f, 0x67, 0x4e, 0x42, 0x30, 0x65, 0x52,
+    0x58, 0x62, 0x64, 0x54, 0x38, 0x6f, 0x59, 0x4e, 0x2b, 0x79, 0x46, 0x46,
+    0x58, 0x6f, 0x5a, 0x43, 0x50, 0x7a, 0x56, 0x78, 0x35, 0x7a, 0x77, 0x38,
+    0x71, 0x6b, 0x75, 0x45, 0x4b, 0x6d, 0x53, 0x35, 0x6a, 0x31, 0x59, 0x50,
+    0x61, 0x6b, 0x57, 0x61, 0x44, 0x77, 0x76, 0x64, 0x53, 0x45, 0x59, 0x66,
+    0x79, 0x68, 0x33, 0x70, 0x65, 0x46, 0x68, 0x0a, 0x46, 0x37, 0x65, 0x6d,
+    0x36, 0x66, 0x67, 0x65, 0x6d, 0x64, 0x74, 0x7a, 0x62, 0x76, 0x51, 0x4b,
+    0x6f, 0x69, 0x46, 0x73, 0x37, 0x74, 0x71, 0x71, 0x68, 0x5a, 0x4a, 0x6d,
+    0x72, 0x2f, 0x5a, 0x36, 0x61, 0x34, 0x4c, 0x61, 0x75, 0x69, 0x49, 0x49,
+    0x4e, 0x51, 0x2f, 0x50, 0x51, 0x76, 0x45, 0x31, 0x2b, 0x6d, 0x72, 0x75,
+    0x66, 0x69, 0x73, 0x6c, 0x7a, 0x44, 0x6f, 0x52, 0x35, 0x47, 0x32, 0x76,
+    0x0a, 0x63, 0x37, 0x4a, 0x32, 0x48, 0x61, 0x33, 0x51, 0x73, 0x6e, 0x68,
+    0x6e, 0x47, 0x71, 0x51, 0x35, 0x48, 0x46, 0x45, 0x4c, 0x5a, 0x31, 0x61,
+    0x44, 0x2f, 0x54, 0x68, 0x64, 0x44, 0x63, 0x37, 0x64, 0x38, 0x4c, 0x73,
+    0x72, 0x6c, 0x68, 0x2f, 0x65, 0x65, 0x7a, 0x4a, 0x53, 0x2f, 0x52, 0x32,
+    0x37, 0x74, 0x51, 0x61, 0x68, 0x73, 0x69, 0x46, 0x65, 0x70, 0x64, 0x61,
+    0x56, 0x61, 0x48, 0x2f, 0x77, 0x0a, 0x6d, 0x5a, 0x37, 0x63, 0x52, 0x51,
+    0x67, 0x2b, 0x35, 0x39, 0x49, 0x4a, 0x44, 0x54, 0x57, 0x55, 0x33, 0x59,
+    0x42, 0x4f, 0x55, 0x35, 0x66, 0x58, 0x74, 0x51, 0x6c, 0x45, 0x49, 0x47,
+    0x51, 0x57, 0x46, 0x77, 0x4d, 0x43, 0x54, 0x46, 0x4d, 0x4e, 0x61, 0x4e,
+    0x37, 0x56, 0x71, 0x6e, 0x4a, 0x4e, 0x6b, 0x32, 0x32, 0x43, 0x44, 0x74,
+    0x75, 0x63, 0x76, 0x63, 0x2b, 0x30, 0x38, 0x31, 0x78, 0x64, 0x0a, 0x56,
+    0x48, 0x70, 0x70, 0x43, 0x5a, 0x62, 0x57, 0x32, 0x78, 0x48, 0x42, 0x6a,
+    0x58, 0x57, 0x6f, 0x74, 0x4d, 0x38, 0x35, 0x79, 0x4d, 0x34, 0x38, 0x76,
+    0x43, 0x52, 0x38, 0x35, 0x6d, 0x4c, 0x4b, 0x34, 0x62, 0x31, 0x39, 0x70,
+    0x37, 0x31, 0x58, 0x5a, 0x51, 0x76, 0x6b, 0x2f, 0x69, 0x58, 0x74, 0x74,
+    0x6d, 0x6b, 0x51, 0x33, 0x43, 0x67, 0x61, 0x52, 0x72, 0x30, 0x42, 0x48,
+    0x64, 0x43, 0x58, 0x0a, 0x74, 0x65, 0x47, 0x59, 0x4f, 0x38, 0x41, 0x33,
+    0x5a, 0x4e, 0x59, 0x39, 0x6c, 0x4f, 0x34, 0x4c, 0x34, 0x66, 0x55, 0x6f,
+    0x72, 0x67, 0x74, 0x57, 0x76, 0x33, 0x47, 0x4c, 0x49, 0x79, 0x6c, 0x42,
+    0x6a, 0x6f, 0x62, 0x46, 0x53, 0x31, 0x4a, 0x37, 0x32, 0x48, 0x47, 0x72,
+    0x48, 0x34, 0x6f, 0x56, 0x70, 0x6a, 0x75, 0x44, 0x57, 0x74, 0x64, 0x59,
+    0x41, 0x56, 0x48, 0x47, 0x54, 0x45, 0x48, 0x5a, 0x0a, 0x66, 0x39, 0x68,
+    0x42, 0x5a, 0x33, 0x4b, 0x69, 0x4b, 0x4e, 0x39, 0x67, 0x67, 0x36, 0x6d,
+    0x65, 0x79, 0x48, 0x76, 0x38, 0x55, 0x33, 0x4e, 0x79, 0x57, 0x66, 0x57,
+    0x54, 0x65, 0x68, 0x64, 0x32, 0x44, 0x73, 0x37, 0x33, 0x35, 0x56, 0x7a,
+    0x5a, 0x43, 0x31, 0x55, 0x30, 0x6f, 0x71, 0x70, 0x62, 0x74, 0x57, 0x70,
+    0x55, 0x35, 0x78, 0x50, 0x4b, 0x56, 0x2b, 0x79, 0x58, 0x62, 0x66, 0x52,
+    0x65, 0x0a, 0x42, 0x69, 0x39, 0x46, 0x69, 0x31, 0x6a, 0x55, 0x49, 0x78,
+    0x61, 0x53, 0x35, 0x42, 0x5a, 0x75, 0x4b, 0x47, 0x4e, 0x5a, 0x4d, 0x4e,
+    0x39, 0x51, 0x41, 0x5a, 0x78, 0x6a, 0x69, 0x52, 0x71, 0x66, 0x32, 0x78,
+    0x65, 0x55, 0x67, 0x6e, 0x41, 0x33, 0x77, 0x79, 0x53, 0x65, 0x6d, 0x6b,
+    0x66, 0x57, 0x57, 0x73, 0x70, 0x4f, 0x71, 0x47, 0x6d, 0x4a, 0x63, 0x68,
+    0x2b, 0x52, 0x62, 0x4e, 0x74, 0x2b, 0x0a, 0x6e, 0x68, 0x75, 0x74, 0x78,
+    0x78, 0x39, 0x7a, 0x33, 0x53, 0x78, 0x50, 0x47, 0x57, 0x58, 0x39, 0x66,
+    0x35, 0x4e, 0x41, 0x45, 0x43, 0x37, 0x53, 0x38, 0x4f, 0x30, 0x38, 0x6e,
+    0x69, 0x34, 0x6f, 0x50, 0x6d, 0x6b, 0x6d, 0x4d, 0x38, 0x56, 0x37, 0x41,
+    0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x59, 0x7a, 0x42, 0x68, 0x4d,
+    0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x0a,
+    0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77,
+    0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45,
+    0x46, 0x4e, 0x71, 0x37, 0x4c, 0x71, 0x71, 0x77, 0x44, 0x4c, 0x69, 0x49,
+    0x4a, 0x6c, 0x46, 0x30, 0x58, 0x47, 0x30, 0x44, 0x30, 0x38, 0x44, 0x59,
+    0x6a, 0x33, 0x72, 0x57, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64,
+    0x49, 0x77, 0x51, 0x59, 0x0a, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x4e, 0x71,
+    0x37, 0x4c, 0x71, 0x71, 0x77, 0x44, 0x4c, 0x69, 0x49, 0x4a, 0x6c, 0x46,
+    0x30, 0x58, 0x47, 0x30, 0x44, 0x30, 0x38, 0x44, 0x59, 0x6a, 0x33, 0x72,
+    0x57, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45,
+    0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6a, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x0a, 0x39, 0x77,
+    0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x67,
+    0x45, 0x41, 0x4d, 0x58, 0x6a, 0x6d, 0x78, 0x37, 0x58, 0x66, 0x75, 0x4a,
+    0x52, 0x41, 0x79, 0x58, 0x48, 0x45, 0x71, 0x44, 0x58, 0x73, 0x52, 0x68,
+    0x33, 0x43, 0x68, 0x66, 0x4d, 0x6f, 0x57, 0x49, 0x61, 0x77, 0x43, 0x2f,
+    0x79, 0x4f, 0x73, 0x6a, 0x6d, 0x50, 0x52, 0x46, 0x57, 0x72, 0x5a, 0x49,
+    0x52, 0x63, 0x0a, 0x61, 0x61, 0x6e, 0x51, 0x6d, 0x6a, 0x67, 0x38, 0x2b,
+    0x75, 0x55, 0x66, 0x4e, 0x65, 0x56, 0x45, 0x34, 0x34, 0x42, 0x35, 0x6c,
+    0x47, 0x69, 0x6b, 0x75, 0x38, 0x53, 0x66, 0x50, 0x65, 0x45, 0x30, 0x7a,
+    0x54, 0x42, 0x47, 0x69, 0x31, 0x51, 0x72, 0x6c, 0x61, 0x58, 0x76, 0x39,
+    0x7a, 0x2b, 0x5a, 0x68, 0x50, 0x30, 0x31, 0x35, 0x73, 0x38, 0x78, 0x78,
+    0x74, 0x78, 0x71, 0x76, 0x36, 0x66, 0x58, 0x0a, 0x49, 0x77, 0x6a, 0x68,
+    0x6d, 0x46, 0x37, 0x44, 0x57, 0x67, 0x68, 0x32, 0x71, 0x61, 0x61, 0x76,
+    0x64, 0x79, 0x2b, 0x33, 0x59, 0x4c, 0x31, 0x45, 0x52, 0x6d, 0x72, 0x76,
+    0x6c, 0x2f, 0x39, 0x7a, 0x6c, 0x63, 0x47, 0x4f, 0x36, 0x4a, 0x50, 0x37,
+    0x2f, 0x54, 0x47, 0x33, 0x37, 0x46, 0x63, 0x52, 0x45, 0x55, 0x57, 0x62,
+    0x4d, 0x50, 0x45, 0x61, 0x69, 0x44, 0x6e, 0x42, 0x54, 0x7a, 0x79, 0x6e,
+    0x0a, 0x41, 0x4e, 0x58, 0x48, 0x2f, 0x4b, 0x74, 0x74, 0x67, 0x43, 0x4a,
+    0x77, 0x70, 0x51, 0x7a, 0x67, 0x58, 0x51, 0x51, 0x70, 0x41, 0x76, 0x76,
+    0x4c, 0x6f, 0x4a, 0x48, 0x52, 0x66, 0x4e, 0x62, 0x44, 0x66, 0x6c, 0x44,
+    0x56, 0x6e, 0x56, 0x69, 0x2b, 0x51, 0x54, 0x6a, 0x72, 0x75, 0x58, 0x55,
+    0x38, 0x46, 0x64, 0x6d, 0x62, 0x79, 0x55, 0x71, 0x44, 0x57, 0x63, 0x44,
+    0x61, 0x55, 0x2f, 0x30, 0x7a, 0x0a, 0x75, 0x7a, 0x59, 0x59, 0x6d, 0x34,
+    0x55, 0x50, 0x46, 0x64, 0x33, 0x75, 0x4c, 0x61, 0x78, 0x32, 0x6b, 0x37,
+    0x6e, 0x5a, 0x41, 0x59, 0x31, 0x49, 0x45, 0x4b, 0x6a, 0x37, 0x39, 0x54,
+    0x69, 0x47, 0x38, 0x64, 0x73, 0x4b, 0x78, 0x72, 0x32, 0x45, 0x6f, 0x79,
+    0x4e, 0x42, 0x33, 0x74, 0x5a, 0x33, 0x62, 0x34, 0x58, 0x55, 0x68, 0x52,
+    0x78, 0x51, 0x34, 0x4b, 0x35, 0x52, 0x69, 0x72, 0x71, 0x4e, 0x0a, 0x50,
+    0x6e, 0x62, 0x69, 0x75, 0x63, 0x6f, 0x6e, 0x38, 0x6c, 0x2b, 0x66, 0x37,
+    0x32, 0x35, 0x5a, 0x44, 0x51, 0x62, 0x59, 0x4b, 0x78, 0x65, 0x6b, 0x30,
+    0x6e, 0x78, 0x72, 0x75, 0x31, 0x38, 0x55, 0x47, 0x6b, 0x69, 0x50, 0x47,
+    0x6b, 0x7a, 0x6e, 0x73, 0x30, 0x63, 0x63, 0x6a, 0x6b, 0x78, 0x46, 0x4b,
+    0x79, 0x44, 0x75, 0x53, 0x4e, 0x2f, 0x6e, 0x33, 0x51, 0x6d, 0x4f, 0x47,
+    0x4b, 0x6a, 0x61, 0x0a, 0x51, 0x49, 0x32, 0x53, 0x4a, 0x68, 0x46, 0x54,
+    0x59, 0x58, 0x4e, 0x64, 0x36, 0x37, 0x33, 0x6e, 0x78, 0x45, 0x30, 0x70,
+    0x4e, 0x32, 0x48, 0x72, 0x72, 0x44, 0x6b, 0x74, 0x5a, 0x79, 0x34, 0x57,
+    0x31, 0x76, 0x55, 0x41, 0x67, 0x34, 0x57, 0x68, 0x7a, 0x48, 0x39, 0x32,
+    0x78, 0x48, 0x33, 0x6b, 0x74, 0x30, 0x74, 0x6d, 0x37, 0x77, 0x4e, 0x46,
+    0x59, 0x47, 0x6d, 0x32, 0x44, 0x46, 0x4b, 0x57, 0x0a, 0x6b, 0x6f, 0x52,
+    0x65, 0x70, 0x71, 0x4f, 0x31, 0x70, 0x44, 0x34, 0x72, 0x32, 0x63, 0x7a,
+    0x59, 0x47, 0x30, 0x65, 0x71, 0x38, 0x6b, 0x54, 0x61, 0x54, 0x2f, 0x6b,
+    0x44, 0x36, 0x50, 0x41, 0x55, 0x79, 0x7a, 0x2f, 0x7a, 0x67, 0x39, 0x37,
+    0x51, 0x77, 0x56, 0x54, 0x6a, 0x74, 0x2b, 0x67, 0x4b, 0x4e, 0x30, 0x32,
+    0x4c, 0x49, 0x46, 0x6b, 0x44, 0x4d, 0x42, 0x6d, 0x68, 0x4c, 0x4d, 0x69,
+    0x39, 0x0a, 0x45, 0x52, 0x2f, 0x66, 0x72, 0x73, 0x6c, 0x4b, 0x78, 0x66,
+    0x4d, 0x6e, 0x5a, 0x6d, 0x61, 0x47, 0x72, 0x47, 0x69, 0x52, 0x2f, 0x39,
+    0x6e, 0x6d, 0x55, 0x78, 0x77, 0x50, 0x69, 0x31, 0x78, 0x70, 0x5a, 0x51,
+    0x6f, 0x6d, 0x79, 0x42, 0x34, 0x30, 0x77, 0x31, 0x31, 0x52, 0x65, 0x39,
+    0x65, 0x70, 0x6e, 0x41, 0x61, 0x68, 0x4e, 0x74, 0x33, 0x56, 0x69, 0x5a,
+    0x53, 0x38, 0x32, 0x65, 0x51, 0x74, 0x0a, 0x44, 0x46, 0x34, 0x4a, 0x62,
+    0x41, 0x69, 0x58, 0x66, 0x4b, 0x4d, 0x39, 0x66, 0x4a, 0x50, 0x2f, 0x50,
+    0x36, 0x45, 0x55, 0x70, 0x38, 0x2b, 0x31, 0x58, 0x65, 0x76, 0x62, 0x32,
+    0x78, 0x7a, 0x45, 0x64, 0x74, 0x2b, 0x49, 0x75, 0x62, 0x31, 0x46, 0x42,
+    0x5a, 0x55, 0x62, 0x72, 0x76, 0x78, 0x47, 0x61, 0x6b, 0x79, 0x76, 0x53,
+    0x4f, 0x50, 0x4f, 0x72, 0x67, 0x2f, 0x53, 0x66, 0x75, 0x76, 0x6d, 0x0a,
+    0x62, 0x4a, 0x78, 0x50, 0x67, 0x57, 0x70, 0x36, 0x5a, 0x4b, 0x79, 0x37,
+    0x50, 0x74, 0x58, 0x6e, 0x79, 0x33, 0x59, 0x75, 0x78, 0x61, 0x64, 0x49,
+    0x77, 0x56, 0x79, 0x51, 0x44, 0x38, 0x76, 0x49, 0x50, 0x2f, 0x72, 0x6d,
+    0x4d, 0x75, 0x47, 0x4e, 0x47, 0x32, 0x2b, 0x6b, 0x35, 0x6f, 0x37, 0x59,
+    0x2b, 0x53, 0x6c, 0x49, 0x69, 0x73, 0x35, 0x7a, 0x2f, 0x69, 0x77, 0x3d,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72,
+    0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20,
+    0x43, 0x41, 0x20, 0x32, 0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47,
+    0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x55, 0x6e, 0x69, 0x76,
+    0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x4f,
+    0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20,
+    0x22, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x55, 0x6e,
+    0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x32,
+    0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20,
+    0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x33, 0x34, 0x3a,
+    0x66, 0x63, 0x3a, 0x62, 0x38, 0x3a, 0x64, 0x30, 0x3a, 0x33, 0x36, 0x3a,
+    0x64, 0x62, 0x3a, 0x39, 0x65, 0x3a, 0x31, 0x34, 0x3a, 0x62, 0x33, 0x3a,
+    0x63, 0x32, 0x3a, 0x66, 0x32, 0x3a, 0x64, 0x62, 0x3a, 0x38, 0x66, 0x3a,
+    0x65, 0x34, 0x3a, 0x39, 0x34, 0x3a, 0x63, 0x37, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x33, 0x37, 0x3a, 0x39, 0x61, 0x3a, 0x31,
+    0x39, 0x3a, 0x37, 0x62, 0x3a, 0x34, 0x31, 0x3a, 0x38, 0x35, 0x3a, 0x34,
+    0x35, 0x3a, 0x33, 0x35, 0x3a, 0x30, 0x63, 0x3a, 0x61, 0x36, 0x3a, 0x30,
+    0x33, 0x3a, 0x36, 0x39, 0x3a, 0x66, 0x33, 0x3a, 0x33, 0x63, 0x3a, 0x32,
+    0x65, 0x3a, 0x61, 0x66, 0x3a, 0x34, 0x37, 0x3a, 0x34, 0x66, 0x3a, 0x32,
+    0x30, 0x3a, 0x37, 0x39, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35,
+    0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x61, 0x30, 0x3a, 0x32, 0x33, 0x3a, 0x34, 0x66, 0x3a,
+    0x33, 0x62, 0x3a, 0x63, 0x38, 0x3a, 0x35, 0x32, 0x3a, 0x37, 0x63, 0x3a,
+    0x61, 0x35, 0x3a, 0x36, 0x32, 0x3a, 0x38, 0x65, 0x3a, 0x65, 0x63, 0x3a,
+    0x38, 0x31, 0x3a, 0x61, 0x64, 0x3a, 0x35, 0x64, 0x3a, 0x36, 0x39, 0x3a,
+    0x38, 0x39, 0x3a, 0x35, 0x64, 0x3a, 0x61, 0x35, 0x3a, 0x36, 0x38, 0x3a,
+    0x30, 0x64, 0x3a, 0x63, 0x39, 0x3a, 0x31, 0x64, 0x3a, 0x31, 0x63, 0x3a,
+    0x62, 0x38, 0x3a, 0x34, 0x37, 0x3a, 0x37, 0x66, 0x3a, 0x33, 0x33, 0x3a,
+    0x66, 0x38, 0x3a, 0x37, 0x38, 0x3a, 0x62, 0x39, 0x3a, 0x35, 0x62, 0x3a,
+    0x30, 0x62, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49,
+    0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, 0x62,
+    0x44, 0x43, 0x43, 0x41, 0x31, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41,
+    0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41,
+    0x44, 0x42, 0x48, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x57, 0x0a,
+    0x4d, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e,
+    0x52, 0x32, 0x56, 0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67,
+    0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x67, 0x4d, 0x42, 0x34, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x58, 0x52, 0x32, 0x56, 0x76,
+    0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x56, 0x57, 0x35, 0x70,
+    0x64, 0x6d, 0x56, 0x79, 0x0a, 0x63, 0x32, 0x46, 0x73, 0x49, 0x45, 0x4e,
+    0x42, 0x49, 0x44, 0x49, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x51,
+    0x77, 0x4d, 0x7a, 0x41, 0x30, 0x4d, 0x44, 0x55, 0x77, 0x4d, 0x44, 0x41,
+    0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x6b, 0x77, 0x4d, 0x7a, 0x41,
+    0x30, 0x4d, 0x44, 0x55, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x6a, 0x42,
+    0x48, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x0a, 0x56, 0x51,
+    0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x57, 0x4d, 0x42,
+    0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x52, 0x32,
+    0x56, 0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x57,
+    0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x67, 0x4d, 0x42, 0x34, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x41, 0x78, 0x4d, 0x58, 0x52, 0x32, 0x56, 0x76, 0x56, 0x48,
+    0x4a, 0x31, 0x0a, 0x63, 0x33, 0x51, 0x67, 0x56, 0x57, 0x35, 0x70, 0x64,
+    0x6d, 0x56, 0x79, 0x63, 0x32, 0x46, 0x73, 0x49, 0x45, 0x4e, 0x42, 0x49,
+    0x44, 0x49, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41,
+    0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67,
+    0x67, 0x49, 0x4b, 0x41, 0x6f, 0x49, 0x43, 0x0a, 0x41, 0x51, 0x43, 0x7a,
+    0x56, 0x46, 0x4c, 0x42, 0x79, 0x54, 0x37, 0x79, 0x32, 0x64, 0x79, 0x78,
+    0x55, 0x78, 0x70, 0x5a, 0x4b, 0x65, 0x65, 0x78, 0x77, 0x30, 0x55, 0x6f,
+    0x35, 0x64, 0x66, 0x52, 0x37, 0x63, 0x58, 0x46, 0x53, 0x36, 0x47, 0x71,
+    0x64, 0x48, 0x74, 0x58, 0x72, 0x30, 0x6f, 0x6d, 0x2f, 0x4e, 0x6a, 0x31,
+    0x58, 0x71, 0x64, 0x75, 0x47, 0x64, 0x74, 0x30, 0x44, 0x45, 0x38, 0x31,
+    0x0a, 0x57, 0x7a, 0x49, 0x4c, 0x41, 0x65, 0x50, 0x62, 0x36, 0x33, 0x70,
+    0x33, 0x4e, 0x65, 0x71, 0x71, 0x57, 0x75, 0x44, 0x57, 0x36, 0x4b, 0x46,
+    0x58, 0x6c, 0x50, 0x43, 0x51, 0x6f, 0x33, 0x52, 0x57, 0x6c, 0x45, 0x51,
+    0x77, 0x41, 0x78, 0x35, 0x63, 0x54, 0x69, 0x75, 0x46, 0x4a, 0x6e, 0x53,
+    0x43, 0x65, 0x67, 0x78, 0x32, 0x6f, 0x47, 0x39, 0x4e, 0x7a, 0x6b, 0x45,
+    0x74, 0x6f, 0x42, 0x55, 0x47, 0x0a, 0x46, 0x46, 0x2b, 0x33, 0x51, 0x73,
+    0x31, 0x37, 0x6a, 0x31, 0x68, 0x68, 0x4e, 0x4e, 0x77, 0x71, 0x43, 0x50,
+    0x6b, 0x75, 0x77, 0x77, 0x47, 0x6d, 0x49, 0x6b, 0x51, 0x63, 0x54, 0x41,
+    0x65, 0x43, 0x35, 0x6c, 0x76, 0x4f, 0x30, 0x45, 0x70, 0x38, 0x42, 0x4e,
+    0x4d, 0x5a, 0x63, 0x79, 0x66, 0x77, 0x71, 0x70, 0x68, 0x2f, 0x4c, 0x71,
+    0x39, 0x4f, 0x36, 0x34, 0x63, 0x65, 0x4a, 0x48, 0x64, 0x71, 0x0a, 0x58,
+    0x62, 0x62, 0x6f, 0x57, 0x30, 0x57, 0x36, 0x33, 0x4d, 0x4f, 0x68, 0x42,
+    0x57, 0x39, 0x57, 0x6a, 0x6f, 0x38, 0x51, 0x4a, 0x71, 0x56, 0x4a, 0x77,
+    0x79, 0x37, 0x58, 0x51, 0x59, 0x63, 0x69, 0x34, 0x45, 0x2b, 0x47, 0x79,
+    0x6d, 0x43, 0x31, 0x36, 0x71, 0x46, 0x6a, 0x77, 0x41, 0x47, 0x58, 0x45,
+    0x48, 0x6d, 0x39, 0x41, 0x44, 0x77, 0x53, 0x62, 0x53, 0x73, 0x56, 0x73,
+    0x61, 0x78, 0x4c, 0x0a, 0x73, 0x65, 0x34, 0x59, 0x75, 0x55, 0x36, 0x57,
+    0x33, 0x4e, 0x78, 0x32, 0x2f, 0x7a, 0x75, 0x2b, 0x7a, 0x31, 0x38, 0x44,
+    0x77, 0x50, 0x77, 0x37, 0x36, 0x4c, 0x35, 0x47, 0x47, 0x2f, 0x2f, 0x61,
+    0x51, 0x4d, 0x4a, 0x53, 0x39, 0x2f, 0x37, 0x6a, 0x4f, 0x76, 0x64, 0x71,
+    0x64, 0x7a, 0x58, 0x51, 0x32, 0x6f, 0x33, 0x72, 0x58, 0x68, 0x68, 0x71,
+    0x4d, 0x63, 0x63, 0x65, 0x75, 0x6a, 0x77, 0x62, 0x0a, 0x4b, 0x4e, 0x5a,
+    0x72, 0x56, 0x4d, 0x61, 0x71, 0x57, 0x39, 0x65, 0x69, 0x4c, 0x42, 0x73,
+    0x5a, 0x7a, 0x4b, 0x49, 0x43, 0x39, 0x70, 0x74, 0x5a, 0x76, 0x54, 0x64,
+    0x72, 0x68, 0x72, 0x56, 0x74, 0x67, 0x72, 0x72, 0x59, 0x36, 0x73, 0x6c,
+    0x57, 0x76, 0x4b, 0x6b, 0x32, 0x57, 0x50, 0x30, 0x2b, 0x47, 0x66, 0x50,
+    0x74, 0x44, 0x43, 0x61, 0x70, 0x6b, 0x7a, 0x6a, 0x34, 0x54, 0x38, 0x46,
+    0x64, 0x0a, 0x49, 0x67, 0x62, 0x51, 0x6c, 0x2b, 0x72, 0x68, 0x72, 0x63,
+    0x5a, 0x56, 0x34, 0x49, 0x45, 0x72, 0x4b, 0x49, 0x4d, 0x36, 0x2b, 0x76,
+    0x52, 0x37, 0x49, 0x56, 0x45, 0x41, 0x76, 0x6c, 0x49, 0x34, 0x7a, 0x73,
+    0x31, 0x6d, 0x65, 0x61, 0x6a, 0x30, 0x67, 0x56, 0x62, 0x69, 0x30, 0x49,
+    0x4d, 0x4a, 0x52, 0x31, 0x46, 0x62, 0x55, 0x47, 0x72, 0x50, 0x32, 0x30,
+    0x67, 0x61, 0x58, 0x54, 0x37, 0x33, 0x0a, 0x79, 0x2f, 0x5a, 0x6c, 0x39,
+    0x32, 0x7a, 0x78, 0x6c, 0x66, 0x67, 0x43, 0x4f, 0x7a, 0x4a, 0x57, 0x67,
+    0x6a, 0x6c, 0x36, 0x57, 0x37, 0x30, 0x76, 0x69, 0x52, 0x75, 0x2f, 0x6f,
+    0x62, 0x54, 0x6f, 0x2f, 0x33, 0x2b, 0x4e, 0x6a, 0x4e, 0x38, 0x44, 0x38,
+    0x57, 0x42, 0x4f, 0x57, 0x42, 0x46, 0x4d, 0x36, 0x36, 0x4d, 0x2f, 0x45,
+    0x43, 0x75, 0x44, 0x6d, 0x67, 0x46, 0x7a, 0x32, 0x5a, 0x52, 0x74, 0x0a,
+    0x68, 0x41, 0x41, 0x6e, 0x5a, 0x71, 0x7a, 0x77, 0x63, 0x45, 0x41, 0x4a,
+    0x51, 0x70, 0x4b, 0x74, 0x54, 0x35, 0x4d, 0x4e, 0x59, 0x51, 0x6c, 0x52,
+    0x4a, 0x4e, 0x69, 0x53, 0x31, 0x51, 0x75, 0x55, 0x59, 0x62, 0x4b, 0x48,
+    0x73, 0x75, 0x33, 0x2f, 0x6d, 0x6a, 0x58, 0x2f, 0x68, 0x56, 0x54, 0x4b,
+    0x37, 0x55, 0x52, 0x44, 0x72, 0x42, 0x73, 0x38, 0x46, 0x6d, 0x74, 0x49,
+    0x53, 0x67, 0x6f, 0x63, 0x0a, 0x51, 0x49, 0x67, 0x66, 0x6b, 0x73, 0x49,
+    0x4c, 0x41, 0x41, 0x58, 0x2f, 0x38, 0x73, 0x67, 0x43, 0x53, 0x71, 0x53,
+    0x71, 0x71, 0x63, 0x79, 0x5a, 0x6c, 0x70, 0x77, 0x76, 0x57, 0x4f, 0x42,
+    0x39, 0x34, 0x62, 0x36, 0x37, 0x42, 0x39, 0x78, 0x66, 0x42, 0x48, 0x4a,
+    0x63, 0x4d, 0x54, 0x54, 0x44, 0x37, 0x46, 0x38, 0x74, 0x34, 0x44, 0x31,
+    0x6b, 0x6b, 0x43, 0x4c, 0x6d, 0x30, 0x65, 0x79, 0x34, 0x0a, 0x4c, 0x74,
+    0x31, 0x5a, 0x72, 0x74, 0x6d, 0x68, 0x4e, 0x37, 0x39, 0x55, 0x4e, 0x64,
+    0x78, 0x7a, 0x4d, 0x6b, 0x2b, 0x4d, 0x42, 0x42, 0x34, 0x7a, 0x73, 0x73,
+    0x6c, 0x47, 0x38, 0x64, 0x68, 0x63, 0x79, 0x46, 0x56, 0x51, 0x79, 0x57,
+    0x69, 0x39, 0x71, 0x4c, 0x6f, 0x32, 0x43, 0x51, 0x49, 0x44, 0x41, 0x51,
+    0x41, 0x42, 0x6f, 0x32, 0x4d, 0x77, 0x59, 0x54, 0x41, 0x50, 0x42, 0x67,
+    0x4e, 0x56, 0x0a, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42,
+    0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x42, 0x30, 0x47, 0x41,
+    0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x32, 0x38,
+    0x31, 0x58, 0x68, 0x2b, 0x71, 0x51, 0x32, 0x2b, 0x2f, 0x43, 0x66, 0x58,
+    0x47, 0x4a, 0x78, 0x37, 0x54, 0x7a, 0x30, 0x52, 0x7a, 0x67, 0x51, 0x4b,
+    0x7a, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x48, 0x53, 0x4d, 0x45,
+    0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x52, 0x32, 0x38, 0x31, 0x58, 0x68,
+    0x2b, 0x71, 0x51, 0x32, 0x2b, 0x2f, 0x43, 0x66, 0x58, 0x47, 0x4a, 0x78,
+    0x37, 0x54, 0x7a, 0x30, 0x52, 0x7a, 0x67, 0x51, 0x4b, 0x7a, 0x41, 0x4f,
+    0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45,
+    0x42, 0x41, 0x4d, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4a,
+    0x0a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45,
+    0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x47, 0x62,
+    0x42, 0x78, 0x69, 0x50, 0x7a, 0x32, 0x65, 0x41, 0x75, 0x62, 0x6c, 0x2f,
+    0x6f, 0x7a, 0x36, 0x36, 0x77, 0x73, 0x43, 0x56, 0x4e, 0x4b, 0x2f, 0x67,
+    0x37, 0x57, 0x4a, 0x74, 0x41, 0x4a, 0x44, 0x64, 0x61, 0x79, 0x36, 0x73,
+    0x57, 0x53, 0x66, 0x2b, 0x7a, 0x0a, 0x64, 0x58, 0x6b, 0x7a, 0x6f, 0x53,
+    0x39, 0x74, 0x63, 0x42, 0x63, 0x30, 0x6b, 0x66, 0x35, 0x6e, 0x66, 0x6f,
+    0x2f, 0x73, 0x6d, 0x2b, 0x56, 0x65, 0x67, 0x71, 0x6c, 0x56, 0x48, 0x79,
+    0x2f, 0x63, 0x31, 0x46, 0x45, 0x48, 0x45, 0x76, 0x36, 0x73, 0x46, 0x6a,
+    0x34, 0x73, 0x4e, 0x63, 0x5a, 0x6a, 0x2f, 0x4e, 0x77, 0x51, 0x36, 0x77,
+    0x32, 0x6a, 0x71, 0x74, 0x42, 0x38, 0x7a, 0x4e, 0x48, 0x51, 0x0a, 0x4c,
+    0x31, 0x45, 0x75, 0x78, 0x42, 0x52, 0x61, 0x33, 0x75, 0x67, 0x5a, 0x34,
+    0x54, 0x37, 0x47, 0x7a, 0x4b, 0x51, 0x70, 0x35, 0x79, 0x36, 0x45, 0x71,
+    0x67, 0x59, 0x77, 0x65, 0x48, 0x5a, 0x55, 0x63, 0x79, 0x69, 0x59, 0x57,
+    0x54, 0x6a, 0x67, 0x41, 0x41, 0x31, 0x69, 0x30, 0x30, 0x4a, 0x39, 0x49,
+    0x5a, 0x2b, 0x75, 0x50, 0x54, 0x71, 0x4d, 0x31, 0x66, 0x70, 0x33, 0x44,
+    0x52, 0x67, 0x72, 0x0a, 0x46, 0x67, 0x35, 0x66, 0x4e, 0x75, 0x48, 0x38,
+    0x4b, 0x72, 0x55, 0x77, 0x4a, 0x4d, 0x2f, 0x67, 0x59, 0x77, 0x78, 0x37,
+    0x57, 0x42, 0x72, 0x2b, 0x6d, 0x62, 0x70, 0x43, 0x45, 0x72, 0x47, 0x52,
+    0x39, 0x48, 0x78, 0x6f, 0x34, 0x73, 0x6a, 0x6f, 0x72, 0x79, 0x7a, 0x71,
+    0x79, 0x58, 0x36, 0x75, 0x75, 0x79, 0x6f, 0x39, 0x44, 0x52, 0x58, 0x63,
+    0x4e, 0x4a, 0x57, 0x32, 0x47, 0x48, 0x53, 0x6f, 0x0a, 0x61, 0x67, 0x2f,
+    0x48, 0x74, 0x50, 0x51, 0x54, 0x78, 0x4f, 0x52, 0x62, 0x37, 0x51, 0x72,
+    0x53, 0x70, 0x4a, 0x64, 0x4d, 0x4b, 0x75, 0x30, 0x76, 0x62, 0x42, 0x4b,
+    0x4a, 0x50, 0x66, 0x45, 0x6e, 0x63, 0x4b, 0x70, 0x71, 0x41, 0x31, 0x49,
+    0x68, 0x6e, 0x30, 0x43, 0x6f, 0x5a, 0x31, 0x44, 0x79, 0x38, 0x31, 0x6f,
+    0x66, 0x33, 0x39, 0x38, 0x6a, 0x39, 0x74, 0x78, 0x34, 0x54, 0x75, 0x61,
+    0x59, 0x0a, 0x54, 0x31, 0x55, 0x36, 0x55, 0x2b, 0x50, 0x76, 0x38, 0x76,
+    0x53, 0x66, 0x78, 0x33, 0x7a, 0x59, 0x57, 0x4b, 0x38, 0x70, 0x49, 0x70,
+    0x65, 0x34, 0x34, 0x4c, 0x32, 0x52, 0x4c, 0x72, 0x42, 0x32, 0x37, 0x46,
+    0x63, 0x52, 0x7a, 0x2b, 0x38, 0x70, 0x52, 0x50, 0x50, 0x70, 0x68, 0x58,
+    0x70, 0x67, 0x59, 0x2b, 0x52, 0x64, 0x4d, 0x34, 0x6b, 0x58, 0x32, 0x54,
+    0x47, 0x71, 0x32, 0x74, 0x62, 0x7a, 0x0a, 0x47, 0x44, 0x56, 0x79, 0x7a,
+    0x34, 0x63, 0x72, 0x4c, 0x32, 0x4d, 0x6a, 0x68, 0x46, 0x32, 0x45, 0x6a,
+    0x44, 0x39, 0x58, 0x6f, 0x49, 0x6a, 0x38, 0x6d, 0x5a, 0x45, 0x6f, 0x4a,
+    0x6d, 0x6d, 0x5a, 0x31, 0x49, 0x2b, 0x58, 0x52, 0x4c, 0x36, 0x4f, 0x31,
+    0x55, 0x69, 0x78, 0x70, 0x43, 0x67, 0x70, 0x38, 0x52, 0x57, 0x30, 0x34,
+    0x65, 0x57, 0x65, 0x33, 0x66, 0x69, 0x50, 0x70, 0x6d, 0x38, 0x6d, 0x0a,
+    0x31, 0x77, 0x6b, 0x38, 0x4f, 0x68, 0x77, 0x52, 0x44, 0x71, 0x5a, 0x73,
+    0x4e, 0x2f, 0x65, 0x74, 0x52, 0x49, 0x63, 0x73, 0x4b, 0x4d, 0x66, 0x59,
+    0x64, 0x49, 0x4b, 0x7a, 0x30, 0x47, 0x39, 0x4b, 0x56, 0x37, 0x73, 0x31,
+    0x4b, 0x53, 0x65, 0x67, 0x69, 0x2b, 0x67, 0x68, 0x70, 0x34, 0x64, 0x6b,
+    0x4e, 0x6c, 0x33, 0x4d, 0x32, 0x42, 0x61, 0x73, 0x78, 0x37, 0x49, 0x6e,
+    0x51, 0x4a, 0x4a, 0x56, 0x0a, 0x4f, 0x43, 0x69, 0x4e, 0x55, 0x57, 0x37,
+    0x64, 0x46, 0x47, 0x64, 0x54, 0x62, 0x48, 0x46, 0x63, 0x4a, 0x6f, 0x52,
+    0x4e, 0x64, 0x56, 0x71, 0x32, 0x66, 0x6d, 0x42, 0x57, 0x71, 0x55, 0x32,
+    0x74, 0x2b, 0x35, 0x73, 0x65, 0x6c, 0x2f, 0x4d, 0x4e, 0x32, 0x64, 0x4b,
+    0x58, 0x56, 0x48, 0x66, 0x61, 0x50, 0x52, 0x4b, 0x33, 0x34, 0x42, 0x37,
+    0x76, 0x43, 0x41, 0x61, 0x73, 0x2b, 0x59, 0x57, 0x48, 0x0a, 0x36, 0x61,
+    0x4c, 0x63, 0x72, 0x33, 0x34, 0x59, 0x45, 0x6f, 0x50, 0x39, 0x56, 0x68,
+    0x64, 0x42, 0x4c, 0x74, 0x55, 0x70, 0x67, 0x6e, 0x32, 0x5a, 0x39, 0x44,
+    0x48, 0x32, 0x63, 0x61, 0x6e, 0x50, 0x4c, 0x41, 0x45, 0x6e, 0x70, 0x51,
+    0x57, 0x35, 0x71, 0x72, 0x4a, 0x49, 0x54, 0x69, 0x72, 0x76, 0x6e, 0x35,
+    0x4e, 0x53, 0x55, 0x5a, 0x55, 0x38, 0x55, 0x6e, 0x4f, 0x4f, 0x56, 0x6b,
+    0x77, 0x58, 0x0a, 0x51, 0x4d, 0x41, 0x4a, 0x4b, 0x4f, 0x53, 0x4c, 0x61,
+    0x6b, 0x68, 0x54, 0x32, 0x2b, 0x7a, 0x4e, 0x56, 0x56, 0x58, 0x78, 0x78,
+    0x76, 0x6a, 0x70, 0x6f, 0x69, 0x78, 0x4d, 0x70, 0x74, 0x45, 0x6d, 0x58,
+    0x33, 0x36, 0x76, 0x57, 0x6b, 0x7a, 0x61, 0x48, 0x36, 0x62, 0x79, 0x48,
+    0x43, 0x78, 0x2b, 0x72, 0x67, 0x49, 0x57, 0x30, 0x6c, 0x62, 0x51, 0x4c,
+    0x31, 0x64, 0x54, 0x52, 0x2b, 0x69, 0x53, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69,
+    0x6e, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x31, 0x20, 0x4f, 0x3d,
+    0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69,
+    0x6e, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x6d,
+    0x65, 0x72, 0x69, 0x63, 0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x31, 0x20, 0x4f, 0x3d, 0x41, 0x6d,
+    0x65, 0x72, 0x69, 0x63, 0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x20,
+    0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20,
+    0x31, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a,
+    0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x31, 0x34,
+    0x3a, 0x66, 0x31, 0x3a, 0x30, 0x38, 0x3a, 0x61, 0x64, 0x3a, 0x39, 0x64,
+    0x3a, 0x66, 0x61, 0x3a, 0x36, 0x34, 0x3a, 0x65, 0x32, 0x3a, 0x38, 0x39,
+    0x3a, 0x65, 0x37, 0x3a, 0x31, 0x63, 0x3a, 0x63, 0x66, 0x3a, 0x61, 0x38,
+    0x3a, 0x61, 0x64, 0x3a, 0x37, 0x64, 0x3a, 0x35, 0x65, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x33, 0x39, 0x3a, 0x32, 0x31, 0x3a,
+    0x63, 0x31, 0x3a, 0x31, 0x35, 0x3a, 0x63, 0x31, 0x3a, 0x35, 0x64, 0x3a,
+    0x30, 0x65, 0x3a, 0x63, 0x61, 0x3a, 0x35, 0x63, 0x3a, 0x63, 0x62, 0x3a,
+    0x35, 0x62, 0x3a, 0x63, 0x34, 0x3a, 0x66, 0x30, 0x3a, 0x37, 0x64, 0x3a,
+    0x32, 0x31, 0x3a, 0x64, 0x38, 0x3a, 0x30, 0x35, 0x3a, 0x30, 0x62, 0x3a,
+    0x35, 0x36, 0x3a, 0x36, 0x61, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32,
+    0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x37, 0x37, 0x3a, 0x34, 0x30, 0x3a, 0x37, 0x33,
+    0x3a, 0x31, 0x32, 0x3a, 0x63, 0x36, 0x3a, 0x33, 0x61, 0x3a, 0x31, 0x35,
+    0x3a, 0x33, 0x64, 0x3a, 0x35, 0x62, 0x3a, 0x63, 0x30, 0x3a, 0x30, 0x62,
+    0x3a, 0x34, 0x65, 0x3a, 0x35, 0x31, 0x3a, 0x37, 0x35, 0x3a, 0x39, 0x63,
+    0x3a, 0x64, 0x66, 0x3a, 0x64, 0x61, 0x3a, 0x63, 0x32, 0x3a, 0x33, 0x37,
+    0x3a, 0x64, 0x63, 0x3a, 0x32, 0x61, 0x3a, 0x33, 0x33, 0x3a, 0x62, 0x36,
+    0x3a, 0x37, 0x39, 0x3a, 0x34, 0x36, 0x3a, 0x65, 0x39, 0x3a, 0x38, 0x65,
+    0x3a, 0x39, 0x62, 0x3a, 0x66, 0x61, 0x3a, 0x36, 0x38, 0x3a, 0x30, 0x61,
+    0x3a, 0x65, 0x33, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47,
+    0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44,
+    0x70, 0x44, 0x43, 0x43, 0x41, 0x6f, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42,
+    0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71,
+    0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46,
+    0x41, 0x44, 0x42, 0x6a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x63,
+    0x0a, 0x4d, 0x42, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d,
+    0x54, 0x51, 0x57, 0x31, 0x6c, 0x63, 0x6d, 0x6c, 0x6a, 0x59, 0x53, 0x42,
+    0x50, 0x62, 0x6d, 0x78, 0x70, 0x62, 0x6d, 0x55, 0x67, 0x53, 0x57, 0x35,
+    0x6a, 0x4c, 0x6a, 0x45, 0x32, 0x4d, 0x44, 0x51, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x41, 0x78, 0x4d, 0x74, 0x51, 0x57, 0x31, 0x6c, 0x63, 0x6d, 0x6c,
+    0x6a, 0x59, 0x53, 0x42, 0x50, 0x0a, 0x62, 0x6d, 0x78, 0x70, 0x62, 0x6d,
+    0x55, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57,
+    0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d,
+    0x6c, 0x30, 0x65, 0x53, 0x41, 0x78, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54,
+    0x41, 0x79, 0x4d, 0x44, 0x55, 0x79, 0x4f, 0x44, 0x41, 0x32, 0x0a, 0x4d,
+    0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x4d, 0x33, 0x4d,
+    0x54, 0x45, 0x78, 0x4f, 0x54, 0x49, 0x77, 0x4e, 0x44, 0x4d, 0x77, 0x4d,
+    0x46, 0x6f, 0x77, 0x59, 0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x48,
+    0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x45,
+    0x30, 0x46, 0x74, 0x0a, 0x5a, 0x58, 0x4a, 0x70, 0x59, 0x32, 0x45, 0x67,
+    0x54, 0x32, 0x35, 0x73, 0x61, 0x57, 0x35, 0x6c, 0x49, 0x45, 0x6c, 0x75,
+    0x59, 0x79, 0x34, 0x78, 0x4e, 0x6a, 0x41, 0x30, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x4d, 0x54, 0x4c, 0x55, 0x46, 0x74, 0x5a, 0x58, 0x4a, 0x70,
+    0x59, 0x32, 0x45, 0x67, 0x54, 0x32, 0x35, 0x73, 0x61, 0x57, 0x35, 0x6c,
+    0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x67, 0x0a, 0x51, 0x32, 0x56,
+    0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c,
+    0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a,
+    0x70, 0x64, 0x48, 0x6b, 0x67, 0x4d, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49,
+    0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63,
+    0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45,
+    0x50, 0x0a, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67,
+    0x45, 0x42, 0x41, 0x4b, 0x67, 0x76, 0x36, 0x4b, 0x52, 0x70, 0x42, 0x67,
+    0x4e, 0x48, 0x77, 0x2b, 0x6b, 0x71, 0x6d, 0x50, 0x38, 0x5a, 0x6f, 0x6e,
+    0x43, 0x61, 0x78, 0x6c, 0x43, 0x79, 0x66, 0x71, 0x58, 0x66, 0x61, 0x45,
+    0x30, 0x62, 0x66, 0x41, 0x2b, 0x32, 0x6c, 0x32, 0x68, 0x39, 0x4c, 0x61,
+    0x61, 0x4c, 0x6c, 0x2b, 0x6c, 0x6b, 0x0a, 0x68, 0x73, 0x6d, 0x6a, 0x37,
+    0x36, 0x43, 0x47, 0x76, 0x32, 0x42, 0x6c, 0x6e, 0x45, 0x74, 0x55, 0x69,
+    0x4d, 0x4a, 0x49, 0x78, 0x55, 0x6f, 0x35, 0x76, 0x78, 0x54, 0x6a, 0x57,
+    0x56, 0x58, 0x6c, 0x47, 0x62, 0x52, 0x30, 0x79, 0x4c, 0x51, 0x46, 0x4f,
+    0x56, 0x77, 0x57, 0x70, 0x65, 0x4b, 0x56, 0x42, 0x65, 0x41, 0x53, 0x72,
+    0x6c, 0x6d, 0x4c, 0x6f, 0x6a, 0x4e, 0x6f, 0x57, 0x42, 0x79, 0x6d, 0x0a,
+    0x31, 0x42, 0x57, 0x33, 0x32, 0x4a, 0x2f, 0x58, 0x33, 0x48, 0x47, 0x72,
+    0x66, 0x70, 0x71, 0x2f, 0x6d, 0x34, 0x34, 0x7a, 0x44, 0x79, 0x4c, 0x39,
+    0x48, 0x79, 0x37, 0x6e, 0x42, 0x7a, 0x62, 0x76, 0x59, 0x6a, 0x6e, 0x46,
+    0x33, 0x63, 0x75, 0x36, 0x4a, 0x52, 0x51, 0x6a, 0x33, 0x67, 0x7a, 0x47,
+    0x50, 0x54, 0x7a, 0x4f, 0x67, 0x67, 0x6a, 0x6d, 0x5a, 0x6a, 0x37, 0x61,
+    0x55, 0x54, 0x73, 0x57, 0x0a, 0x4f, 0x71, 0x4d, 0x46, 0x66, 0x36, 0x44,
+    0x63, 0x68, 0x39, 0x57, 0x63, 0x2f, 0x48, 0x4b, 0x70, 0x6f, 0x48, 0x31,
+    0x34, 0x35, 0x4c, 0x63, 0x78, 0x56, 0x52, 0x35, 0x6c, 0x75, 0x39, 0x52,
+    0x68, 0x73, 0x43, 0x46, 0x67, 0x37, 0x52, 0x41, 0x79, 0x63, 0x73, 0x57,
+    0x53, 0x4a, 0x52, 0x37, 0x34, 0x6b, 0x45, 0x6f, 0x59, 0x65, 0x45, 0x66,
+    0x66, 0x66, 0x6a, 0x41, 0x33, 0x50, 0x6c, 0x41, 0x62, 0x0a, 0x32, 0x78,
+    0x7a, 0x54, 0x61, 0x35, 0x71, 0x47, 0x55, 0x77, 0x65, 0x77, 0x37, 0x36,
+    0x77, 0x47, 0x65, 0x50, 0x69, 0x45, 0x6d, 0x66, 0x34, 0x68, 0x6a, 0x55,
+    0x79, 0x41, 0x74, 0x67, 0x79, 0x43, 0x39, 0x6d, 0x5a, 0x77, 0x65, 0x52,
+    0x72, 0x54, 0x54, 0x36, 0x50, 0x50, 0x38, 0x63, 0x39, 0x47, 0x73, 0x45,
+    0x73, 0x50, 0x50, 0x74, 0x32, 0x49, 0x59, 0x72, 0x69, 0x4d, 0x71, 0x51,
+    0x6b, 0x6f, 0x0a, 0x4f, 0x33, 0x72, 0x48, 0x6c, 0x2b, 0x45, 0x65, 0x35,
+    0x66, 0x53, 0x66, 0x77, 0x4d, 0x43, 0x75, 0x4a, 0x4b, 0x44, 0x49, 0x6f,
+    0x64, 0x6b, 0x50, 0x31, 0x6e, 0x73, 0x6d, 0x67, 0x6d, 0x6b, 0x79, 0x50,
+    0x61, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4e, 0x6a, 0x4d,
+    0x47, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41,
+    0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x0a, 0x41, 0x77, 0x45, 0x42,
+    0x2f, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45,
+    0x46, 0x67, 0x51, 0x55, 0x41, 0x4b, 0x33, 0x5a, 0x6f, 0x2f, 0x5a, 0x35,
+    0x39, 0x6d, 0x35, 0x30, 0x71, 0x58, 0x38, 0x7a, 0x50, 0x59, 0x45, 0x58,
+    0x31, 0x30, 0x7a, 0x50, 0x4d, 0x39, 0x34, 0x77, 0x48, 0x77, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, 0x41, 0x55,
+    0x0a, 0x41, 0x4b, 0x33, 0x5a, 0x6f, 0x2f, 0x5a, 0x35, 0x39, 0x6d, 0x35,
+    0x30, 0x71, 0x58, 0x38, 0x7a, 0x50, 0x59, 0x45, 0x58, 0x31, 0x30, 0x7a,
+    0x50, 0x4d, 0x39, 0x34, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x50, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47,
+    0x47, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62,
+    0x33, 0x44, 0x51, 0x45, 0x42, 0x0a, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34,
+    0x49, 0x42, 0x41, 0x51, 0x42, 0x38, 0x69, 0x74, 0x45, 0x66, 0x47, 0x44,
+    0x65, 0x43, 0x34, 0x4c, 0x69, 0x77, 0x6f, 0x2b, 0x31, 0x57, 0x6c, 0x63,
+    0x68, 0x69, 0x59, 0x5a, 0x77, 0x46, 0x6f, 0x73, 0x33, 0x43, 0x59, 0x69,
+    0x5a, 0x68, 0x7a, 0x52, 0x41, 0x57, 0x31, 0x38, 0x79, 0x30, 0x5a, 0x54,
+    0x54, 0x51, 0x45, 0x59, 0x71, 0x74, 0x71, 0x4b, 0x6b, 0x46, 0x0a, 0x5a,
+    0x75, 0x39, 0x30, 0x38, 0x32, 0x31, 0x66, 0x6e, 0x5a, 0x6d, 0x76, 0x39,
+    0x6f, 0x76, 0x37, 0x36, 0x31, 0x4b, 0x79, 0x42, 0x5a, 0x69, 0x69, 0x62,
+    0x79, 0x72, 0x46, 0x56, 0x4c, 0x30, 0x6c, 0x76, 0x56, 0x2b, 0x75, 0x79,
+    0x49, 0x62, 0x71, 0x52, 0x69, 0x7a, 0x42, 0x73, 0x37, 0x33, 0x42, 0x36,
+    0x55, 0x6c, 0x77, 0x47, 0x42, 0x61, 0x58, 0x43, 0x42, 0x4f, 0x4d, 0x49,
+    0x4f, 0x41, 0x62, 0x0a, 0x4c, 0x6a, 0x70, 0x48, 0x79, 0x78, 0x37, 0x6b,
+    0x41, 0x44, 0x43, 0x56, 0x57, 0x2f, 0x52, 0x46, 0x6f, 0x38, 0x41, 0x61,
+    0x73, 0x41, 0x46, 0x4f, 0x71, 0x37, 0x33, 0x41, 0x49, 0x32, 0x35, 0x6a,
+    0x50, 0x34, 0x42, 0x4b, 0x78, 0x51, 0x66, 0x74, 0x33, 0x4f, 0x4a, 0x76,
+    0x78, 0x38, 0x46, 0x69, 0x38, 0x65, 0x4e, 0x79, 0x31, 0x67, 0x54, 0x49,
+    0x64, 0x47, 0x63, 0x4c, 0x2b, 0x6f, 0x69, 0x72, 0x0a, 0x6f, 0x51, 0x48,
+    0x49, 0x62, 0x2f, 0x41, 0x55, 0x72, 0x39, 0x4b, 0x5a, 0x7a, 0x56, 0x47,
+    0x54, 0x66, 0x75, 0x30, 0x75, 0x4f, 0x4d, 0x65, 0x39, 0x7a, 0x6b, 0x5a,
+    0x51, 0x50, 0x58, 0x4c, 0x6a, 0x65, 0x53, 0x57, 0x64, 0x6d, 0x34, 0x67,
+    0x72, 0x45, 0x43, 0x44, 0x64, 0x70, 0x62, 0x67, 0x79, 0x6e, 0x34, 0x33,
+    0x67, 0x4b, 0x64, 0x38, 0x68, 0x64, 0x49, 0x61, 0x43, 0x32, 0x79, 0x2b,
+    0x43, 0x0a, 0x4d, 0x4d, 0x62, 0x48, 0x4e, 0x59, 0x61, 0x7a, 0x2b, 0x5a,
+    0x5a, 0x66, 0x52, 0x74, 0x73, 0x4d, 0x52, 0x66, 0x33, 0x7a, 0x55, 0x4d,
+    0x4e, 0x76, 0x78, 0x73, 0x4e, 0x49, 0x72, 0x55, 0x61, 0x6d, 0x34, 0x53,
+    0x64, 0x48, 0x43, 0x68, 0x30, 0x4f, 0x6d, 0x37, 0x62, 0x43, 0x64, 0x33,
+    0x39, 0x6a, 0x38, 0x75, 0x42, 0x39, 0x47, 0x72, 0x37, 0x38, 0x34, 0x4e,
+    0x2f, 0x58, 0x78, 0x36, 0x64, 0x73, 0x0a, 0x73, 0x50, 0x6d, 0x75, 0x75,
+    0x6a, 0x7a, 0x39, 0x64, 0x4c, 0x51, 0x52, 0x36, 0x46, 0x67, 0x4e, 0x67,
+    0x4c, 0x7a, 0x54, 0x71, 0x49, 0x41, 0x36, 0x6d, 0x65, 0x31, 0x31, 0x7a,
+    0x45, 0x5a, 0x37, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73,
+    0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x6d, 0x65, 0x72,
+    0x69, 0x63, 0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x52,
+    0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x32, 0x20, 0x4f, 0x3d, 0x41, 0x6d, 0x65, 0x72,
+    0x69, 0x63, 0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+    0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x52, 0x6f, 0x6f,
+    0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+    0x79, 0x20, 0x32, 0x20, 0x4f, 0x3d, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+    0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22,
+    0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x20, 0x4f, 0x6e, 0x6c, 0x69,
+    0x6e, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x22, 0x0a, 0x23,
+    0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23,
+    0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x36, 0x3a, 0x65, 0x64, 0x3a,
+    0x33, 0x63, 0x3a, 0x63, 0x61, 0x3a, 0x65, 0x32, 0x3a, 0x36, 0x36, 0x3a,
+    0x30, 0x66, 0x3a, 0x61, 0x66, 0x3a, 0x31, 0x30, 0x3a, 0x34, 0x33, 0x3a,
+    0x30, 0x64, 0x3a, 0x37, 0x37, 0x3a, 0x39, 0x62, 0x3a, 0x30, 0x34, 0x3a,
+    0x30, 0x39, 0x3a, 0x62, 0x66, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x38, 0x35, 0x3a, 0x62, 0x35, 0x3a, 0x66, 0x66, 0x3a, 0x36,
+    0x37, 0x3a, 0x39, 0x62, 0x3a, 0x30, 0x63, 0x3a, 0x37, 0x39, 0x3a, 0x39,
+    0x36, 0x3a, 0x31, 0x66, 0x3a, 0x63, 0x38, 0x3a, 0x36, 0x65, 0x3a, 0x34,
+    0x34, 0x3a, 0x32, 0x32, 0x3a, 0x30, 0x30, 0x3a, 0x34, 0x36, 0x3a, 0x31,
+    0x33, 0x3a, 0x64, 0x62, 0x3a, 0x31, 0x37, 0x3a, 0x39, 0x32, 0x3a, 0x38,
+    0x34, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x37, 0x64, 0x3a, 0x33, 0x62, 0x3a, 0x34, 0x36, 0x3a, 0x35, 0x61, 0x3a,
+    0x36, 0x30, 0x3a, 0x31, 0x34, 0x3a, 0x65, 0x35, 0x3a, 0x32, 0x36, 0x3a,
+    0x63, 0x30, 0x3a, 0x61, 0x66, 0x3a, 0x66, 0x63, 0x3a, 0x65, 0x65, 0x3a,
+    0x32, 0x31, 0x3a, 0x32, 0x37, 0x3a, 0x64, 0x32, 0x3a, 0x33, 0x31, 0x3a,
+    0x31, 0x37, 0x3a, 0x32, 0x37, 0x3a, 0x61, 0x64, 0x3a, 0x38, 0x31, 0x3a,
+    0x31, 0x63, 0x3a, 0x32, 0x36, 0x3a, 0x38, 0x34, 0x3a, 0x32, 0x64, 0x3a,
+    0x30, 0x30, 0x3a, 0x36, 0x61, 0x3a, 0x66, 0x33, 0x3a, 0x37, 0x33, 0x3a,
+    0x30, 0x36, 0x3a, 0x63, 0x63, 0x3a, 0x38, 0x30, 0x3a, 0x62, 0x64, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, 0x70, 0x44, 0x43, 0x43,
+    0x41, 0x34, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
+    0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x6a,
+    0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
+    0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x63, 0x0a, 0x4d, 0x42, 0x6f,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x54, 0x51, 0x57, 0x31,
+    0x6c, 0x63, 0x6d, 0x6c, 0x6a, 0x59, 0x53, 0x42, 0x50, 0x62, 0x6d, 0x78,
+    0x70, 0x62, 0x6d, 0x55, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45,
+    0x32, 0x4d, 0x44, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x74, 0x51, 0x57, 0x31, 0x6c, 0x63, 0x6d, 0x6c, 0x6a, 0x59, 0x53, 0x42,
+    0x50, 0x0a, 0x62, 0x6d, 0x78, 0x70, 0x62, 0x6d, 0x55, 0x67, 0x55, 0x6d,
+    0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57,
+    0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45,
+    0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x53,
+    0x41, 0x79, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x79, 0x4d, 0x44,
+    0x55, 0x79, 0x4f, 0x44, 0x41, 0x32, 0x0a, 0x4d, 0x44, 0x41, 0x77, 0x4d,
+    0x46, 0x6f, 0x58, 0x44, 0x54, 0x4d, 0x33, 0x4d, 0x44, 0x6b, 0x79, 0x4f,
+    0x54, 0x45, 0x30, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x46, 0x6f, 0x77, 0x59,
+    0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x45, 0x30, 0x46, 0x74, 0x0a,
+    0x5a, 0x58, 0x4a, 0x70, 0x59, 0x32, 0x45, 0x67, 0x54, 0x32, 0x35, 0x73,
+    0x61, 0x57, 0x35, 0x6c, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78,
+    0x4e, 0x6a, 0x41, 0x30, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54,
+    0x4c, 0x55, 0x46, 0x74, 0x5a, 0x58, 0x4a, 0x70, 0x59, 0x32, 0x45, 0x67,
+    0x54, 0x32, 0x35, 0x73, 0x61, 0x57, 0x35, 0x6c, 0x49, 0x46, 0x4a, 0x76,
+    0x62, 0x33, 0x51, 0x67, 0x0a, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c,
+    0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42,
+    0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b,
+    0x67, 0x4d, 0x6a, 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59,
+    0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45,
+    0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x0a, 0x41, 0x44,
+    0x43, 0x43, 0x41, 0x67, 0x6f, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4d,
+    0x78, 0x42, 0x52, 0x52, 0x33, 0x70, 0x50, 0x55, 0x30, 0x51, 0x39, 0x6f,
+    0x79, 0x78, 0x51, 0x63, 0x6e, 0x67, 0x58, 0x73, 0x73, 0x4e, 0x74, 0x37,
+    0x39, 0x48, 0x63, 0x39, 0x50, 0x77, 0x56, 0x55, 0x33, 0x64, 0x78, 0x67,
+    0x7a, 0x36, 0x73, 0x57, 0x59, 0x46, 0x61, 0x73, 0x31, 0x34, 0x74, 0x4e,
+    0x77, 0x43, 0x0a, 0x32, 0x30, 0x36, 0x42, 0x38, 0x39, 0x65, 0x6e, 0x66,
+    0x48, 0x47, 0x38, 0x64, 0x57, 0x4f, 0x67, 0x58, 0x65, 0x4d, 0x48, 0x44,
+    0x45, 0x6a, 0x73, 0x4a, 0x63, 0x51, 0x44, 0x49, 0x50, 0x54, 0x2f, 0x44,
+    0x6a, 0x73, 0x53, 0x2f, 0x35, 0x75, 0x4e, 0x34, 0x63, 0x62, 0x56, 0x47,
+    0x37, 0x52, 0x74, 0x49, 0x75, 0x4f, 0x78, 0x32, 0x33, 0x38, 0x68, 0x5a,
+    0x4b, 0x2b, 0x47, 0x76, 0x46, 0x63, 0x69, 0x0a, 0x4b, 0x74, 0x5a, 0x48,
+    0x67, 0x56, 0x64, 0x45, 0x67, 0x6c, 0x5a, 0x54, 0x76, 0x59, 0x59, 0x55,
+    0x41, 0x51, 0x76, 0x38, 0x66, 0x33, 0x53, 0x6b, 0x57, 0x71, 0x37, 0x78,
+    0x75, 0x68, 0x47, 0x31, 0x6d, 0x31, 0x68, 0x61, 0x67, 0x4c, 0x51, 0x33,
+    0x65, 0x41, 0x6b, 0x7a, 0x66, 0x44, 0x4a, 0x48, 0x41, 0x31, 0x7a, 0x45,
+    0x70, 0x59, 0x4e, 0x49, 0x39, 0x46, 0x64, 0x57, 0x62, 0x6f, 0x45, 0x32,
+    0x0a, 0x4a, 0x78, 0x68, 0x50, 0x37, 0x4a, 0x73, 0x6f, 0x77, 0x74, 0x53,
+    0x30, 0x31, 0x33, 0x77, 0x4d, 0x50, 0x67, 0x77, 0x72, 0x33, 0x38, 0x6f,
+    0x45, 0x31, 0x38, 0x61, 0x4f, 0x36, 0x6c, 0x68, 0x4f, 0x71, 0x4b, 0x53,
+    0x6c, 0x47, 0x42, 0x78, 0x73, 0x52, 0x5a, 0x69, 0x6a, 0x51, 0x64, 0x45,
+    0x74, 0x30, 0x73, 0x64, 0x74, 0x6a, 0x52, 0x6e, 0x78, 0x72, 0x58, 0x6d,
+    0x33, 0x67, 0x54, 0x2b, 0x39, 0x0a, 0x42, 0x6f, 0x49, 0x6e, 0x4c, 0x52,
+    0x42, 0x59, 0x42, 0x62, 0x56, 0x34, 0x42, 0x62, 0x6b, 0x76, 0x32, 0x77,
+    0x78, 0x72, 0x6b, 0x4a, 0x42, 0x2b, 0x46, 0x46, 0x6b, 0x34, 0x75, 0x35,
+    0x51, 0x6b, 0x45, 0x2b, 0x58, 0x52, 0x6e, 0x52, 0x54, 0x66, 0x30, 0x34,
+    0x4a, 0x4e, 0x52, 0x76, 0x43, 0x41, 0x4f, 0x56, 0x49, 0x79, 0x44, 0x2b,
+    0x4f, 0x45, 0x73, 0x6e, 0x70, 0x44, 0x38, 0x6c, 0x37, 0x65, 0x0a, 0x58,
+    0x7a, 0x38, 0x64, 0x33, 0x65, 0x4f, 0x79, 0x47, 0x36, 0x43, 0x68, 0x4b,
+    0x69, 0x4d, 0x44, 0x62, 0x69, 0x34, 0x42, 0x46, 0x59, 0x64, 0x63, 0x70,
+    0x6e, 0x56, 0x31, 0x78, 0x35, 0x64, 0x68, 0x76, 0x74, 0x36, 0x47, 0x33,
+    0x4e, 0x52, 0x49, 0x32, 0x37, 0x30, 0x71, 0x76, 0x30, 0x70, 0x56, 0x32,
+    0x75, 0x68, 0x39, 0x55, 0x50, 0x75, 0x30, 0x67, 0x42, 0x65, 0x34, 0x6c,
+    0x4c, 0x38, 0x42, 0x0a, 0x50, 0x65, 0x72, 0x61, 0x75, 0x6e, 0x7a, 0x67,
+    0x57, 0x47, 0x63, 0x58, 0x75, 0x56, 0x6a, 0x67, 0x69, 0x49, 0x5a, 0x47,
+    0x5a, 0x32, 0x79, 0x64, 0x45, 0x45, 0x64, 0x59, 0x4d, 0x74, 0x41, 0x31,
+    0x66, 0x48, 0x6b, 0x71, 0x6b, 0x4b, 0x4a, 0x61, 0x45, 0x42, 0x45, 0x6a,
+    0x4e, 0x61, 0x30, 0x76, 0x7a, 0x4f, 0x52, 0x4b, 0x57, 0x36, 0x66, 0x49,
+    0x4a, 0x2f, 0x4b, 0x44, 0x33, 0x6c, 0x36, 0x37, 0x0a, 0x58, 0x6e, 0x66,
+    0x6e, 0x36, 0x4b, 0x56, 0x75, 0x59, 0x38, 0x49, 0x4e, 0x58, 0x57, 0x48,
+    0x51, 0x6a, 0x4e, 0x4a, 0x73, 0x57, 0x69, 0x45, 0x4f, 0x79, 0x69, 0x69,
+    0x6a, 0x7a, 0x69, 0x72, 0x70, 0x6c, 0x63, 0x64, 0x49, 0x7a, 0x35, 0x5a,
+    0x76, 0x48, 0x5a, 0x49, 0x6c, 0x79, 0x4d, 0x62, 0x47, 0x77, 0x63, 0x45,
+    0x4d, 0x42, 0x61, 0x77, 0x6d, 0x78, 0x4e, 0x4a, 0x31, 0x30, 0x75, 0x45,
+    0x71, 0x0a, 0x5a, 0x38, 0x41, 0x39, 0x57, 0x36, 0x57, 0x61, 0x36, 0x38,
+    0x39, 0x37, 0x47, 0x71, 0x69, 0x64, 0x46, 0x45, 0x58, 0x6c, 0x44, 0x36,
+    0x43, 0x61, 0x5a, 0x64, 0x34, 0x76, 0x4b, 0x4c, 0x33, 0x4f, 0x62, 0x35,
+    0x52, 0x6d, 0x67, 0x30, 0x67, 0x70, 0x32, 0x4f, 0x70, 0x6c, 0x6a, 0x4b,
+    0x2b, 0x54, 0x32, 0x57, 0x53, 0x66, 0x56, 0x56, 0x63, 0x6d, 0x76, 0x32,
+    0x2f, 0x4c, 0x4e, 0x7a, 0x47, 0x5a, 0x0a, 0x6f, 0x32, 0x43, 0x37, 0x48,
+    0x4b, 0x32, 0x4a, 0x4e, 0x44, 0x4a, 0x69, 0x75, 0x45, 0x4d, 0x68, 0x42,
+    0x6e, 0x49, 0x4d, 0x6f, 0x56, 0x78, 0x74, 0x52, 0x73, 0x58, 0x36, 0x4b,
+    0x63, 0x38, 0x77, 0x33, 0x6f, 0x6e, 0x63, 0x63, 0x56, 0x76, 0x64, 0x74,
+    0x6a, 0x63, 0x2b, 0x33, 0x31, 0x44, 0x31, 0x75, 0x41, 0x63, 0x6c, 0x4a,
+    0x75, 0x57, 0x38, 0x74, 0x66, 0x34, 0x38, 0x41, 0x72, 0x4f, 0x33, 0x0a,
+    0x2b, 0x4c, 0x35, 0x44, 0x77, 0x59, 0x63, 0x52, 0x6c, 0x4a, 0x34, 0x6a,
+    0x62, 0x42, 0x65, 0x4b, 0x75, 0x49, 0x6f, 0x6e, 0x44, 0x46, 0x52, 0x48,
+    0x38, 0x4b, 0x6d, 0x7a, 0x77, 0x49, 0x43, 0x4d, 0x6f, 0x43, 0x66, 0x72,
+    0x48, 0x52, 0x6e, 0x6a, 0x42, 0x34, 0x35, 0x33, 0x63, 0x4d, 0x6f, 0x72,
+    0x39, 0x48, 0x31, 0x32, 0x34, 0x48, 0x68, 0x6e, 0x41, 0x67, 0x4d, 0x42,
+    0x41, 0x41, 0x47, 0x6a, 0x0a, 0x59, 0x7a, 0x42, 0x68, 0x4d, 0x41, 0x38,
+    0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51,
+    0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59,
+    0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x45, 0x31,
+    0x46, 0x77, 0x57, 0x67, 0x34, 0x75, 0x33, 0x4f, 0x70, 0x61, 0x61, 0x45,
+    0x67, 0x35, 0x2b, 0x33, 0x31, 0x49, 0x71, 0x45, 0x6a, 0x0a, 0x46, 0x4e,
+    0x65, 0x65, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77,
+    0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x45, 0x31, 0x46, 0x77, 0x57,
+    0x67, 0x34, 0x75, 0x33, 0x4f, 0x70, 0x61, 0x61, 0x45, 0x67, 0x35, 0x2b,
+    0x33, 0x31, 0x49, 0x71, 0x45, 0x6a, 0x46, 0x4e, 0x65, 0x65, 0x4d, 0x41,
+    0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2f, 0x77,
+    0x51, 0x45, 0x0a, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6a, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x67, 0x45, 0x41, 0x5a,
+    0x32, 0x73, 0x47, 0x75, 0x56, 0x39, 0x46, 0x4f, 0x79, 0x70, 0x4c, 0x4d,
+    0x37, 0x50, 0x6d, 0x47, 0x32, 0x74, 0x5a, 0x54, 0x69, 0x4c, 0x4d, 0x75,
+    0x62, 0x65, 0x6b, 0x4a, 0x63, 0x6d, 0x6e, 0x0a, 0x78, 0x50, 0x42, 0x55,
+    0x6c, 0x67, 0x74, 0x6b, 0x38, 0x37, 0x46, 0x59, 0x54, 0x31, 0x35, 0x52,
+    0x2f, 0x4c, 0x4b, 0x58, 0x65, 0x79, 0x64, 0x6c, 0x77, 0x75, 0x58, 0x4b,
+    0x35, 0x77, 0x30, 0x4d, 0x4a, 0x58, 0x74, 0x69, 0x34, 0x2f, 0x71, 0x66,
+    0x74, 0x49, 0x65, 0x33, 0x52, 0x55, 0x61, 0x76, 0x67, 0x36, 0x57, 0x58,
+    0x53, 0x49, 0x79, 0x6c, 0x76, 0x66, 0x45, 0x57, 0x4b, 0x35, 0x74, 0x32,
+    0x0a, 0x4c, 0x48, 0x6f, 0x31, 0x59, 0x47, 0x77, 0x52, 0x67, 0x4a, 0x66,
+    0x4d, 0x71, 0x5a, 0x4a, 0x53, 0x35, 0x69, 0x76, 0x6d, 0x61, 0x65, 0x32,
+    0x70, 0x2b, 0x44, 0x59, 0x74, 0x4c, 0x48, 0x65, 0x2f, 0x59, 0x55, 0x6a,
+    0x52, 0x59, 0x77, 0x75, 0x35, 0x57, 0x31, 0x4c, 0x74, 0x47, 0x4c, 0x42,
+    0x44, 0x51, 0x69, 0x4b, 0x6d, 0x73, 0x58, 0x65, 0x75, 0x33, 0x6d, 0x6e,
+    0x46, 0x7a, 0x63, 0x63, 0x63, 0x0a, 0x6f, 0x62, 0x47, 0x6c, 0x48, 0x42,
+    0x44, 0x37, 0x47, 0x4c, 0x34, 0x61, 0x63, 0x4e, 0x33, 0x42, 0x6b, 0x6b,
+    0x75, 0x2b, 0x4b, 0x56, 0x71, 0x64, 0x50, 0x7a, 0x57, 0x2b, 0x35, 0x58,
+    0x31, 0x52, 0x2b, 0x46, 0x58, 0x67, 0x4a, 0x58, 0x55, 0x6a, 0x68, 0x78,
+    0x35, 0x63, 0x33, 0x4c, 0x71, 0x64, 0x73, 0x4b, 0x79, 0x7a, 0x61, 0x64,
+    0x73, 0x58, 0x67, 0x38, 0x6e, 0x33, 0x33, 0x67, 0x79, 0x38, 0x0a, 0x43,
+    0x4e, 0x79, 0x52, 0x6e, 0x71, 0x6a, 0x51, 0x31, 0x78, 0x55, 0x33, 0x63,
+    0x36, 0x55, 0x31, 0x75, 0x50, 0x78, 0x2b, 0x78, 0x55, 0x52, 0x41, 0x42,
+    0x73, 0x50, 0x72, 0x2b, 0x43, 0x4b, 0x41, 0x58, 0x45, 0x66, 0x4f, 0x41,
+    0x75, 0x4d, 0x52, 0x6e, 0x30, 0x54, 0x2f, 0x2f, 0x5a, 0x6f, 0x79, 0x7a,
+    0x48, 0x31, 0x6b, 0x55, 0x51, 0x37, 0x72, 0x56, 0x79, 0x5a, 0x32, 0x4f,
+    0x75, 0x4d, 0x65, 0x0a, 0x49, 0x6a, 0x7a, 0x43, 0x70, 0x6a, 0x62, 0x64,
+    0x47, 0x65, 0x2b, 0x6e, 0x2f, 0x42, 0x4c, 0x7a, 0x4a, 0x73, 0x42, 0x5a,
+    0x4d, 0x59, 0x56, 0x4d, 0x6e, 0x4e, 0x6a, 0x50, 0x33, 0x36, 0x54, 0x4d,
+    0x7a, 0x43, 0x6d, 0x54, 0x2f, 0x35, 0x52, 0x74, 0x64, 0x6c, 0x77, 0x54,
+    0x43, 0x4a, 0x66, 0x79, 0x37, 0x61, 0x55, 0x4c, 0x54, 0x64, 0x33, 0x6f,
+    0x79, 0x57, 0x67, 0x4f, 0x5a, 0x74, 0x4d, 0x41, 0x0a, 0x44, 0x6a, 0x4d,
+    0x53, 0x57, 0x37, 0x79, 0x56, 0x35, 0x54, 0x4b, 0x51, 0x71, 0x4c, 0x50,
+    0x47, 0x62, 0x49, 0x4f, 0x74, 0x64, 0x2b, 0x36, 0x4c, 0x66, 0x6e, 0x36,
+    0x78, 0x71, 0x61, 0x76, 0x54, 0x34, 0x66, 0x47, 0x32, 0x77, 0x4c, 0x48,
+    0x71, 0x69, 0x4d, 0x44, 0x6e, 0x30, 0x35, 0x44, 0x70, 0x4b, 0x4a, 0x4b,
+    0x55, 0x65, 0x32, 0x68, 0x37, 0x6c, 0x79, 0x6f, 0x4b, 0x5a, 0x79, 0x32,
+    0x46, 0x0a, 0x41, 0x6a, 0x67, 0x51, 0x35, 0x41, 0x4e, 0x68, 0x31, 0x4e,
+    0x6f, 0x6c, 0x4e, 0x73, 0x63, 0x49, 0x57, 0x43, 0x32, 0x68, 0x70, 0x31,
+    0x47, 0x76, 0x4d, 0x41, 0x70, 0x4a, 0x39, 0x61, 0x5a, 0x70, 0x68, 0x77,
+    0x63, 0x74, 0x52, 0x45, 0x5a, 0x32, 0x6a, 0x69, 0x72, 0x6c, 0x6d, 0x6a,
+    0x76, 0x58, 0x47, 0x4b, 0x4c, 0x38, 0x6e, 0x44, 0x67, 0x51, 0x7a, 0x4d,
+    0x59, 0x37, 0x30, 0x72, 0x55, 0x58, 0x0a, 0x4f, 0x6d, 0x2f, 0x39, 0x72,
+    0x69, 0x57, 0x39, 0x39, 0x58, 0x4a, 0x5a, 0x5a, 0x4c, 0x46, 0x30, 0x4b,
+    0x6a, 0x68, 0x66, 0x47, 0x45, 0x7a, 0x66, 0x7a, 0x33, 0x45, 0x45, 0x57,
+    0x6a, 0x62, 0x55, 0x76, 0x79, 0x2b, 0x5a, 0x6e, 0x4f, 0x6a, 0x5a, 0x75,
+    0x72, 0x47, 0x56, 0x35, 0x67, 0x4a, 0x4c, 0x49, 0x61, 0x46, 0x62, 0x31,
+    0x63, 0x46, 0x50, 0x6a, 0x36, 0x35, 0x70, 0x62, 0x56, 0x50, 0x62, 0x0a,
+    0x41, 0x5a, 0x4f, 0x31, 0x58, 0x42, 0x34, 0x59, 0x33, 0x57, 0x52, 0x61,
+    0x79, 0x68, 0x67, 0x6f, 0x50, 0x6d, 0x4d, 0x45, 0x45, 0x66, 0x30, 0x63,
+    0x6a, 0x51, 0x41, 0x50, 0x75, 0x44, 0x66, 0x66, 0x5a, 0x34, 0x71, 0x64,
+    0x5a, 0x71, 0x6b, 0x43, 0x61, 0x70, 0x48, 0x2f, 0x45, 0x38, 0x6f, 0x76,
+    0x58, 0x59, 0x4f, 0x38, 0x68, 0x35, 0x4e, 0x73, 0x33, 0x43, 0x52, 0x52,
+    0x46, 0x67, 0x51, 0x6c, 0x0a, 0x5a, 0x76, 0x71, 0x7a, 0x32, 0x63, 0x4b,
+    0x36, 0x4b, 0x62, 0x36, 0x61, 0x53, 0x44, 0x69, 0x43, 0x6d, 0x66, 0x53,
+    0x2f, 0x4f, 0x30, 0x6f, 0x78, 0x47, 0x66, 0x6d, 0x2f, 0x6a, 0x69, 0x45,
+    0x7a, 0x46, 0x4d, 0x70, 0x50, 0x56, 0x46, 0x2f, 0x37, 0x7a, 0x76, 0x75,
+    0x50, 0x63, 0x58, 0x2f, 0x39, 0x58, 0x68, 0x6d, 0x67, 0x44, 0x30, 0x75,
+    0x52, 0x75, 0x4d, 0x52, 0x55, 0x76, 0x41, 0x61, 0x77, 0x0a, 0x52, 0x59,
+    0x38, 0x6d, 0x6b, 0x61, 0x4b, 0x4f, 0x2f, 0x71, 0x6b, 0x3d, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69,
+    0x63, 0x65, 0x73, 0x20, 0x4f, 0x3d, 0x43, 0x6f, 0x6d, 0x6f, 0x64, 0x6f,
+    0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x0a,
+    0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+    0x65, 0x73, 0x20, 0x4f, 0x3d, 0x43, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x20,
+    0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x0a, 0x23,
+    0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x43, 0x6f, 0x6d,
+    0x6f, 0x64, 0x6f, 0x20, 0x41, 0x41, 0x41, 0x20, 0x53, 0x65, 0x72, 0x76,
+    0x69, 0x63, 0x65, 0x73, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23,
+    0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23,
+    0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x34, 0x39, 0x3a, 0x37, 0x39, 0x3a,
+    0x30, 0x34, 0x3a, 0x62, 0x30, 0x3a, 0x65, 0x62, 0x3a, 0x38, 0x37, 0x3a,
+    0x31, 0x39, 0x3a, 0x61, 0x63, 0x3a, 0x34, 0x37, 0x3a, 0x62, 0x30, 0x3a,
+    0x62, 0x63, 0x3a, 0x31, 0x31, 0x3a, 0x35, 0x31, 0x3a, 0x39, 0x62, 0x3a,
+    0x37, 0x34, 0x3a, 0x64, 0x30, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x64, 0x31, 0x3a, 0x65, 0x62, 0x3a, 0x32, 0x33, 0x3a, 0x61,
+    0x34, 0x3a, 0x36, 0x64, 0x3a, 0x31, 0x37, 0x3a, 0x64, 0x36, 0x3a, 0x38,
+    0x66, 0x3a, 0x64, 0x39, 0x3a, 0x32, 0x35, 0x3a, 0x36, 0x34, 0x3a, 0x63,
+    0x32, 0x3a, 0x66, 0x31, 0x3a, 0x66, 0x31, 0x3a, 0x36, 0x30, 0x3a, 0x31,
+    0x37, 0x3a, 0x36, 0x34, 0x3a, 0x64, 0x38, 0x3a, 0x65, 0x33, 0x3a, 0x34,
+    0x39, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x64, 0x37, 0x3a, 0x61, 0x37, 0x3a, 0x61, 0x30, 0x3a, 0x66, 0x62, 0x3a,
+    0x35, 0x64, 0x3a, 0x37, 0x65, 0x3a, 0x32, 0x37, 0x3a, 0x33, 0x31, 0x3a,
+    0x64, 0x37, 0x3a, 0x37, 0x31, 0x3a, 0x65, 0x39, 0x3a, 0x34, 0x38, 0x3a,
+    0x34, 0x65, 0x3a, 0x62, 0x63, 0x3a, 0x64, 0x65, 0x3a, 0x66, 0x37, 0x3a,
+    0x31, 0x64, 0x3a, 0x35, 0x66, 0x3a, 0x30, 0x63, 0x3a, 0x33, 0x65, 0x3a,
+    0x30, 0x61, 0x3a, 0x32, 0x39, 0x3a, 0x34, 0x38, 0x3a, 0x37, 0x38, 0x3a,
+    0x32, 0x62, 0x3a, 0x63, 0x38, 0x3a, 0x33, 0x65, 0x3a, 0x65, 0x30, 0x3a,
+    0x65, 0x61, 0x3a, 0x36, 0x39, 0x3a, 0x39, 0x65, 0x3a, 0x66, 0x34, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x4d, 0x6a, 0x43, 0x43,
+    0x41, 0x78, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
+    0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x37,
+    0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
+    0x45, 0x77, 0x4a, 0x48, 0x51, 0x6a, 0x45, 0x62, 0x0a, 0x4d, 0x42, 0x6b,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x53, 0x52, 0x33, 0x4a,
+    0x6c, 0x59, 0x58, 0x52, 0x6c, 0x63, 0x69, 0x42, 0x4e, 0x59, 0x57, 0x35,
+    0x6a, 0x61, 0x47, 0x56, 0x7a, 0x64, 0x47, 0x56, 0x79, 0x4d, 0x52, 0x41,
+    0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x64,
+    0x54, 0x59, 0x57, 0x78, 0x6d, 0x62, 0x33, 0x4a, 0x6b, 0x4d, 0x52, 0x6f,
+    0x77, 0x0a, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42,
+    0x46, 0x44, 0x62, 0x32, 0x31, 0x76, 0x5a, 0x47, 0x38, 0x67, 0x51, 0x30,
+    0x45, 0x67, 0x54, 0x47, 0x6c, 0x74, 0x61, 0x58, 0x52, 0x6c, 0x5a, 0x44,
+    0x45, 0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77,
+    0x77, 0x59, 0x51, 0x55, 0x46, 0x42, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e,
+    0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x0a, 0x59, 0x58, 0x52, 0x6c, 0x49,
+    0x46, 0x4e, 0x6c, 0x63, 0x6e, 0x5a, 0x70, 0x59, 0x32, 0x56, 0x7a, 0x4d,
+    0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x30, 0x4d, 0x44, 0x45, 0x77, 0x4d,
+    0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44,
+    0x54, 0x49, 0x34, 0x4d, 0x54, 0x49, 0x7a, 0x4d, 0x54, 0x49, 0x7a, 0x4e,
+    0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x65, 0x7a, 0x45, 0x4c, 0x0a,
+    0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43,
+    0x52, 0x30, 0x49, 0x78, 0x47, 0x7a, 0x41, 0x5a, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x67, 0x4d, 0x45, 0x6b, 0x64, 0x79, 0x5a, 0x57, 0x46, 0x30,
+    0x5a, 0x58, 0x49, 0x67, 0x54, 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6c,
+    0x63, 0x33, 0x52, 0x6c, 0x63, 0x6a, 0x45, 0x51, 0x4d, 0x41, 0x34, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x0a, 0x42, 0x77, 0x77, 0x48, 0x55, 0x32, 0x46,
+    0x73, 0x5a, 0x6d, 0x39, 0x79, 0x5a, 0x44, 0x45, 0x61, 0x4d, 0x42, 0x67,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x52, 0x51, 0x32, 0x39,
+    0x74, 0x62, 0x32, 0x52, 0x76, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x45, 0x78,
+    0x70, 0x62, 0x57, 0x6c, 0x30, 0x5a, 0x57, 0x51, 0x78, 0x49, 0x54, 0x41,
+    0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x0a, 0x47, 0x45,
+    0x46, 0x42, 0x51, 0x53, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57,
+    0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5a, 0x53, 0x42, 0x54, 0x5a, 0x58,
+    0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x63, 0x7a, 0x43, 0x43, 0x41, 0x53,
+    0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67,
+    0x45, 0x50, 0x0a, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67,
+    0x67, 0x45, 0x42, 0x41, 0x4c, 0x35, 0x41, 0x6e, 0x66, 0x52, 0x75, 0x34,
+    0x65, 0x70, 0x32, 0x68, 0x78, 0x78, 0x4e, 0x52, 0x55, 0x53, 0x4f, 0x76,
+    0x6b, 0x62, 0x49, 0x67, 0x77, 0x61, 0x64, 0x77, 0x53, 0x72, 0x2b, 0x47,
+    0x42, 0x2b, 0x4f, 0x35, 0x41, 0x4c, 0x36, 0x38, 0x36, 0x74, 0x64, 0x55,
+    0x49, 0x6f, 0x57, 0x4d, 0x51, 0x75, 0x61, 0x0a, 0x42, 0x74, 0x44, 0x46,
+    0x63, 0x43, 0x4c, 0x4e, 0x53, 0x53, 0x31, 0x55, 0x59, 0x38, 0x79, 0x32,
+    0x62, 0x6d, 0x68, 0x47, 0x43, 0x31, 0x50, 0x71, 0x79, 0x30, 0x77, 0x6b,
+    0x77, 0x4c, 0x78, 0x79, 0x54, 0x75, 0x72, 0x78, 0x46, 0x61, 0x37, 0x30,
+    0x56, 0x4a, 0x6f, 0x53, 0x43, 0x73, 0x4e, 0x36, 0x73, 0x6a, 0x4e, 0x67,
+    0x34, 0x74, 0x71, 0x4a, 0x56, 0x66, 0x4d, 0x69, 0x57, 0x50, 0x50, 0x65,
+    0x0a, 0x33, 0x4d, 0x2f, 0x76, 0x67, 0x34, 0x61, 0x69, 0x6a, 0x4a, 0x52,
+    0x50, 0x6e, 0x32, 0x6a, 0x79, 0x6d, 0x4a, 0x42, 0x47, 0x68, 0x43, 0x66,
+    0x48, 0x64, 0x72, 0x2f, 0x6a, 0x7a, 0x44, 0x55, 0x73, 0x69, 0x31, 0x34,
+    0x48, 0x5a, 0x47, 0x57, 0x43, 0x77, 0x45, 0x69, 0x77, 0x71, 0x4a, 0x48,
+    0x35, 0x59, 0x5a, 0x39, 0x32, 0x49, 0x46, 0x43, 0x6f, 0x6b, 0x63, 0x64,
+    0x6d, 0x74, 0x65, 0x74, 0x34, 0x0a, 0x59, 0x67, 0x4e, 0x57, 0x38, 0x49,
+    0x6f, 0x61, 0x45, 0x2b, 0x6f, 0x78, 0x6f, 0x78, 0x36, 0x67, 0x6d, 0x66,
+    0x30, 0x34, 0x39, 0x76, 0x59, 0x6e, 0x4d, 0x6c, 0x68, 0x76, 0x42, 0x2f,
+    0x56, 0x72, 0x75, 0x50, 0x73, 0x55, 0x4b, 0x36, 0x2b, 0x33, 0x71, 0x73,
+    0x7a, 0x57, 0x59, 0x31, 0x39, 0x7a, 0x6a, 0x4e, 0x6f, 0x46, 0x6d, 0x61,
+    0x67, 0x34, 0x71, 0x4d, 0x73, 0x58, 0x65, 0x44, 0x5a, 0x52, 0x0a, 0x72,
+    0x4f, 0x6d, 0x65, 0x39, 0x48, 0x67, 0x36, 0x6a, 0x63, 0x38, 0x50, 0x32,
+    0x55, 0x4c, 0x69, 0x6d, 0x41, 0x79, 0x72, 0x4c, 0x35, 0x38, 0x4f, 0x41,
+    0x64, 0x37, 0x76, 0x6e, 0x35, 0x6c, 0x4a, 0x38, 0x53, 0x33, 0x66, 0x72,
+    0x48, 0x52, 0x4e, 0x47, 0x35, 0x69, 0x31, 0x52, 0x38, 0x58, 0x6c, 0x4b,
+    0x64, 0x48, 0x35, 0x6b, 0x42, 0x6a, 0x48, 0x59, 0x70, 0x79, 0x2b, 0x67,
+    0x38, 0x63, 0x6d, 0x0a, 0x65, 0x7a, 0x36, 0x4b, 0x4a, 0x63, 0x66, 0x41,
+    0x33, 0x5a, 0x33, 0x6d, 0x4e, 0x57, 0x67, 0x51, 0x49, 0x4a, 0x32, 0x50,
+    0x32, 0x4e, 0x37, 0x53, 0x77, 0x34, 0x53, 0x63, 0x44, 0x56, 0x37, 0x6f,
+    0x4c, 0x38, 0x6b, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4f, 0x42,
+    0x77, 0x44, 0x43, 0x42, 0x76, 0x54, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56,
+    0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x0a, 0x6f, 0x42, 0x45,
+    0x4b, 0x49, 0x7a, 0x36, 0x57, 0x38, 0x51, 0x66, 0x73, 0x34, 0x71, 0x38,
+    0x70, 0x37, 0x34, 0x4b, 0x6c, 0x66, 0x39, 0x41, 0x77, 0x70, 0x4c, 0x51,
+    0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48,
+    0x2f, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x41, 0x38,
+    0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51,
+    0x46, 0x0a, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x65, 0x77,
+    0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x48, 0x51, 0x77, 0x63, 0x6a,
+    0x41, 0x34, 0x6f, 0x44, 0x61, 0x67, 0x4e, 0x49, 0x59, 0x79, 0x61, 0x48,
+    0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32, 0x4e, 0x79, 0x62, 0x43,
+    0x35, 0x6a, 0x62, 0x32, 0x31, 0x76, 0x5a, 0x47, 0x39, 0x6a, 0x59, 0x53,
+    0x35, 0x6a, 0x62, 0x32, 0x30, 0x76, 0x0a, 0x51, 0x55, 0x46, 0x42, 0x51,
+    0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64,
+    0x47, 0x56, 0x54, 0x5a, 0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x63,
+    0x79, 0x35, 0x6a, 0x63, 0x6d, 0x77, 0x77, 0x4e, 0x71, 0x41, 0x30, 0x6f,
+    0x44, 0x4b, 0x47, 0x4d, 0x47, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4c,
+    0x79, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x0a,
+    0x62, 0x32, 0x52, 0x76, 0x4c, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x39, 0x42,
+    0x51, 0x55, 0x46, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70,
+    0x59, 0x32, 0x46, 0x30, 0x5a, 0x56, 0x4e, 0x6c, 0x63, 0x6e, 0x5a, 0x70,
+    0x59, 0x32, 0x56, 0x7a, 0x4c, 0x6d, 0x4e, 0x79, 0x62, 0x44, 0x41, 0x4e,
+    0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
+    0x41, 0x51, 0x55, 0x46, 0x0a, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45,
+    0x41, 0x43, 0x46, 0x62, 0x38, 0x41, 0x76, 0x43, 0x62, 0x36, 0x50, 0x2b,
+    0x6b, 0x2b, 0x74, 0x5a, 0x37, 0x78, 0x6b, 0x53, 0x41, 0x7a, 0x6b, 0x2f,
+    0x45, 0x78, 0x66, 0x59, 0x41, 0x57, 0x4d, 0x79, 0x6d, 0x74, 0x72, 0x77,
+    0x55, 0x53, 0x57, 0x67, 0x45, 0x64, 0x75, 0x6a, 0x6d, 0x37, 0x6c, 0x33,
+    0x73, 0x41, 0x67, 0x39, 0x67, 0x31, 0x6f, 0x31, 0x51, 0x0a, 0x47, 0x45,
+    0x38, 0x6d, 0x54, 0x67, 0x48, 0x6a, 0x35, 0x72, 0x43, 0x6c, 0x37, 0x72,
+    0x2b, 0x38, 0x64, 0x46, 0x52, 0x42, 0x76, 0x2f, 0x33, 0x38, 0x45, 0x72,
+    0x6a, 0x48, 0x54, 0x31, 0x72, 0x30, 0x69, 0x57, 0x41, 0x46, 0x66, 0x32,
+    0x43, 0x33, 0x42, 0x55, 0x72, 0x7a, 0x39, 0x76, 0x48, 0x43, 0x76, 0x38,
+    0x53, 0x35, 0x64, 0x49, 0x61, 0x32, 0x4c, 0x58, 0x31, 0x72, 0x7a, 0x4e,
+    0x4c, 0x7a, 0x0a, 0x52, 0x74, 0x30, 0x76, 0x78, 0x75, 0x42, 0x71, 0x77,
+    0x38, 0x4d, 0x30, 0x41, 0x79, 0x78, 0x39, 0x6c, 0x74, 0x31, 0x61, 0x77,
+    0x67, 0x36, 0x6e, 0x43, 0x70, 0x6e, 0x42, 0x42, 0x59, 0x75, 0x72, 0x44,
+    0x43, 0x2f, 0x7a, 0x58, 0x44, 0x72, 0x50, 0x62, 0x44, 0x64, 0x56, 0x43,
+    0x59, 0x66, 0x65, 0x55, 0x30, 0x42, 0x73, 0x57, 0x4f, 0x2f, 0x38, 0x74,
+    0x71, 0x74, 0x6c, 0x62, 0x67, 0x54, 0x32, 0x0a, 0x47, 0x39, 0x77, 0x38,
+    0x34, 0x46, 0x6f, 0x56, 0x78, 0x70, 0x37, 0x5a, 0x38, 0x56, 0x6c, 0x49,
+    0x4d, 0x43, 0x46, 0x6c, 0x41, 0x32, 0x7a, 0x73, 0x36, 0x53, 0x46, 0x7a,
+    0x37, 0x4a, 0x73, 0x44, 0x6f, 0x65, 0x41, 0x33, 0x72, 0x61, 0x41, 0x56,
+    0x47, 0x49, 0x2f, 0x36, 0x75, 0x67, 0x4c, 0x4f, 0x70, 0x79, 0x79, 0x70,
+    0x45, 0x42, 0x4d, 0x73, 0x31, 0x4f, 0x55, 0x49, 0x4a, 0x71, 0x73, 0x69,
+    0x0a, 0x6c, 0x32, 0x44, 0x34, 0x6b, 0x46, 0x35, 0x30, 0x31, 0x4b, 0x4b,
+    0x61, 0x55, 0x37, 0x33, 0x79, 0x71, 0x57, 0x6a, 0x67, 0x6f, 0x6d, 0x37,
+    0x43, 0x31, 0x32, 0x79, 0x78, 0x6f, 0x77, 0x2b, 0x65, 0x76, 0x2b, 0x74,
+    0x6f, 0x35, 0x31, 0x62, 0x79, 0x72, 0x76, 0x4c, 0x6a, 0x4b, 0x7a, 0x67,
+    0x36, 0x43, 0x59, 0x47, 0x31, 0x61, 0x34, 0x58, 0x58, 0x76, 0x69, 0x33,
+    0x74, 0x50, 0x78, 0x71, 0x33, 0x0a, 0x73, 0x6d, 0x50, 0x69, 0x39, 0x57,
+    0x49, 0x73, 0x67, 0x74, 0x52, 0x71, 0x41, 0x45, 0x46, 0x51, 0x38, 0x54,
+    0x6d, 0x44, 0x6e, 0x35, 0x58, 0x70, 0x4e, 0x70, 0x61, 0x59, 0x62, 0x67,
+    0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75,
+    0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x4f,
+    0x3d, 0x43, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x20, 0x43, 0x41, 0x20, 0x4c,
+    0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62,
+    0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x63,
+    0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+    0x20, 0x4f, 0x3d, 0x43, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x20, 0x43, 0x41,
+    0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x4c,
+    0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x43, 0x6f, 0x6d, 0x6f, 0x64,
+    0x6f, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a,
+    0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x33, 0x3a, 0x64, 0x39,
+    0x3a, 0x62, 0x64, 0x3a, 0x61, 0x65, 0x3a, 0x39, 0x66, 0x3a, 0x61, 0x63,
+    0x3a, 0x36, 0x37, 0x3a, 0x32, 0x34, 0x3a, 0x62, 0x33, 0x3a, 0x63, 0x38,
+    0x3a, 0x31, 0x62, 0x3a, 0x35, 0x32, 0x3a, 0x65, 0x31, 0x3a, 0x62, 0x39,
+    0x3a, 0x61, 0x39, 0x3a, 0x62, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x34, 0x61, 0x3a, 0x36, 0x35, 0x3a, 0x64, 0x35, 0x3a,
+    0x66, 0x34, 0x3a, 0x31, 0x64, 0x3a, 0x65, 0x66, 0x3a, 0x33, 0x39, 0x3a,
+    0x62, 0x38, 0x3a, 0x62, 0x38, 0x3a, 0x39, 0x30, 0x3a, 0x34, 0x61, 0x3a,
+    0x34, 0x61, 0x3a, 0x64, 0x33, 0x3a, 0x36, 0x34, 0x3a, 0x38, 0x31, 0x3a,
+    0x33, 0x33, 0x3a, 0x63, 0x66, 0x3a, 0x63, 0x37, 0x3a, 0x61, 0x31, 0x3a,
+    0x64, 0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x62, 0x64, 0x3a, 0x38, 0x31, 0x3a, 0x63, 0x65, 0x3a, 0x33, 0x62,
+    0x3a, 0x34, 0x66, 0x3a, 0x36, 0x35, 0x3a, 0x39, 0x31, 0x3a, 0x64, 0x31,
+    0x3a, 0x31, 0x61, 0x3a, 0x36, 0x37, 0x3a, 0x62, 0x35, 0x3a, 0x66, 0x63,
+    0x3a, 0x37, 0x61, 0x3a, 0x34, 0x37, 0x3a, 0x66, 0x64, 0x3a, 0x65, 0x66,
+    0x3a, 0x32, 0x35, 0x3a, 0x35, 0x32, 0x3a, 0x31, 0x62, 0x3a, 0x66, 0x39,
+    0x3a, 0x61, 0x61, 0x3a, 0x34, 0x65, 0x3a, 0x31, 0x38, 0x3a, 0x62, 0x39,
+    0x3a, 0x65, 0x33, 0x3a, 0x64, 0x66, 0x3a, 0x32, 0x65, 0x3a, 0x33, 0x34,
+    0x3a, 0x61, 0x37, 0x3a, 0x38, 0x30, 0x3a, 0x33, 0x62, 0x3a, 0x65, 0x38,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x50, 0x7a, 0x43,
+    0x43, 0x41, 0x79, 0x65, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
+    0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42,
+    0x2b, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x47, 0x45, 0x77, 0x4a, 0x48, 0x51, 0x6a, 0x45, 0x62, 0x0a, 0x4d, 0x42,
+    0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x53, 0x52, 0x33,
+    0x4a, 0x6c, 0x59, 0x58, 0x52, 0x6c, 0x63, 0x69, 0x42, 0x4e, 0x59, 0x57,
+    0x35, 0x6a, 0x61, 0x47, 0x56, 0x7a, 0x64, 0x47, 0x56, 0x79, 0x4d, 0x52,
+    0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41,
+    0x64, 0x54, 0x59, 0x57, 0x78, 0x6d, 0x62, 0x33, 0x4a, 0x6b, 0x4d, 0x52,
+    0x6f, 0x77, 0x0a, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44,
+    0x42, 0x46, 0x44, 0x62, 0x32, 0x31, 0x76, 0x5a, 0x47, 0x38, 0x67, 0x51,
+    0x30, 0x45, 0x67, 0x54, 0x47, 0x6c, 0x74, 0x61, 0x58, 0x52, 0x6c, 0x5a,
+    0x44, 0x45, 0x6b, 0x4d, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41,
+    0x77, 0x77, 0x62, 0x55, 0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, 0x6c, 0x49,
+    0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x0a, 0x5a, 0x6d, 0x6c, 0x6a,
+    0x59, 0x58, 0x52, 0x6c, 0x49, 0x46, 0x4e, 0x6c, 0x63, 0x6e, 0x5a, 0x70,
+    0x59, 0x32, 0x56, 0x7a, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x30,
+    0x4d, 0x44, 0x45, 0x77, 0x4d, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77,
+    0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x49, 0x34, 0x4d, 0x54, 0x49, 0x7a,
+    0x4d, 0x54, 0x49, 0x7a, 0x4e, 0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77,
+    0x0a, 0x66, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x42, 0x68, 0x4d, 0x43, 0x52, 0x30, 0x49, 0x78, 0x47, 0x7a, 0x41,
+    0x5a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, 0x45, 0x6b, 0x64,
+    0x79, 0x5a, 0x57, 0x46, 0x30, 0x5a, 0x58, 0x49, 0x67, 0x54, 0x57, 0x46,
+    0x75, 0x59, 0x32, 0x68, 0x6c, 0x63, 0x33, 0x52, 0x6c, 0x63, 0x6a, 0x45,
+    0x51, 0x4d, 0x41, 0x34, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77,
+    0x77, 0x48, 0x55, 0x32, 0x46, 0x73, 0x5a, 0x6d, 0x39, 0x79, 0x5a, 0x44,
+    0x45, 0x61, 0x4d, 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67,
+    0x77, 0x52, 0x51, 0x32, 0x39, 0x74, 0x62, 0x32, 0x52, 0x76, 0x49, 0x45,
+    0x4e, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62, 0x57, 0x6c, 0x30, 0x5a, 0x57,
+    0x51, 0x78, 0x4a, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42,
+    0x41, 0x4d, 0x4d, 0x47, 0x31, 0x4e, 0x6c, 0x59, 0x33, 0x56, 0x79, 0x5a,
+    0x53, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59,
+    0x32, 0x46, 0x30, 0x5a, 0x53, 0x42, 0x54, 0x5a, 0x58, 0x4a, 0x32, 0x61,
+    0x57, 0x4e, 0x6c, 0x63, 0x7a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44,
+    0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41,
+    0x51, 0x45, 0x42, 0x0a, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50,
+    0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42,
+    0x41, 0x4d, 0x42, 0x78, 0x4d, 0x34, 0x4b, 0x4b, 0x30, 0x48, 0x44, 0x72,
+    0x63, 0x34, 0x65, 0x43, 0x51, 0x4e, 0x55, 0x64, 0x35, 0x4d, 0x76, 0x4a,
+    0x44, 0x6b, 0x4b, 0x51, 0x2b, 0x64, 0x34, 0x30, 0x75, 0x61, 0x47, 0x36,
+    0x45, 0x66, 0x51, 0x6c, 0x68, 0x66, 0x50, 0x4d, 0x0a, 0x63, 0x6d, 0x33,
+    0x79, 0x65, 0x35, 0x64, 0x72, 0x73, 0x77, 0x66, 0x78, 0x64, 0x79, 0x53,
+    0x52, 0x58, 0x79, 0x57, 0x50, 0x39, 0x6e, 0x51, 0x39, 0x35, 0x49, 0x44,
+    0x43, 0x2b, 0x44, 0x77, 0x4e, 0x38, 0x37, 0x39, 0x41, 0x36, 0x76, 0x66,
+    0x49, 0x55, 0x74, 0x46, 0x79, 0x62, 0x2b, 0x2f, 0x49, 0x71, 0x30, 0x47,
+    0x34, 0x62, 0x69, 0x34, 0x58, 0x4b, 0x70, 0x56, 0x70, 0x44, 0x4d, 0x33,
+    0x53, 0x0a, 0x48, 0x70, 0x52, 0x37, 0x4c, 0x5a, 0x51, 0x64, 0x71, 0x6e,
+    0x58, 0x58, 0x73, 0x35, 0x6a, 0x4c, 0x72, 0x4c, 0x78, 0x6b, 0x55, 0x30,
+    0x43, 0x38, 0x6a, 0x36, 0x79, 0x73, 0x4e, 0x73, 0x74, 0x63, 0x72, 0x62,
+    0x76, 0x64, 0x34, 0x4a, 0x51, 0x58, 0x37, 0x4e, 0x46, 0x63, 0x30, 0x4c,
+    0x2f, 0x76, 0x70, 0x5a, 0x58, 0x4a, 0x6b, 0x4d, 0x57, 0x77, 0x72, 0x50,
+    0x73, 0x62, 0x51, 0x39, 0x39, 0x36, 0x0a, 0x43, 0x46, 0x32, 0x33, 0x75,
+    0x50, 0x4a, 0x41, 0x47, 0x79, 0x73, 0x6e, 0x6e, 0x6c, 0x44, 0x4f, 0x58,
+    0x6d, 0x57, 0x43, 0x69, 0x49, 0x78, 0x65, 0x30, 0x30, 0x34, 0x4d, 0x65,
+    0x75, 0x6f, 0x49, 0x6b, 0x62, 0x59, 0x32, 0x71, 0x69, 0x74, 0x43, 0x2b,
+    0x2b, 0x72, 0x43, 0x6f, 0x7a, 0x6e, 0x6c, 0x32, 0x79, 0x59, 0x34, 0x72,
+    0x59, 0x73, 0x4b, 0x37, 0x68, 0x6c, 0x6a, 0x78, 0x78, 0x77, 0x6b, 0x0a,
+    0x33, 0x77, 0x4e, 0x34, 0x32, 0x75, 0x62, 0x71, 0x77, 0x55, 0x63, 0x61,
+    0x43, 0x77, 0x74, 0x47, 0x43, 0x64, 0x30, 0x43, 0x2f, 0x4e, 0x37, 0x4c,
+    0x68, 0x31, 0x2f, 0x58, 0x4d, 0x47, 0x4e, 0x6f, 0x6f, 0x61, 0x37, 0x63,
+    0x4d, 0x71, 0x47, 0x36, 0x76, 0x76, 0x35, 0x45, 0x71, 0x32, 0x69, 0x32,
+    0x70, 0x52, 0x63, 0x56, 0x2f, 0x62, 0x33, 0x56, 0x70, 0x36, 0x65, 0x61,
+    0x35, 0x45, 0x51, 0x7a, 0x0a, 0x36, 0x59, 0x69, 0x4f, 0x2f, 0x4f, 0x31,
+    0x52, 0x36, 0x35, 0x4e, 0x78, 0x54, 0x71, 0x30, 0x42, 0x35, 0x30, 0x53,
+    0x4f, 0x71, 0x79, 0x33, 0x4c, 0x71, 0x50, 0x34, 0x42, 0x53, 0x55, 0x6a,
+    0x77, 0x77, 0x4e, 0x33, 0x48, 0x61, 0x4e, 0x69, 0x53, 0x2f, 0x6a, 0x30,
+    0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4f, 0x42, 0x78, 0x7a, 0x43,
+    0x42, 0x78, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x48, 0x51,
+    0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x50, 0x4e, 0x69, 0x54, 0x69, 0x4d,
+    0x4c, 0x41, 0x67, 0x67, 0x6e, 0x4d, 0x41, 0x5a, 0x6b, 0x47, 0x6b, 0x79,
+    0x44, 0x70, 0x6e, 0x6e, 0x41, 0x4a, 0x59, 0x30, 0x38, 0x77, 0x44, 0x67,
+    0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41,
+    0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31,
+    0x55, 0x64, 0x0a, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d,
+    0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x67, 0x59, 0x45, 0x47, 0x41,
+    0x31, 0x55, 0x64, 0x48, 0x77, 0x52, 0x36, 0x4d, 0x48, 0x67, 0x77, 0x4f,
+    0x36, 0x41, 0x35, 0x6f, 0x44, 0x65, 0x47, 0x4e, 0x57, 0x68, 0x30, 0x64,
+    0x48, 0x41, 0x36, 0x4c, 0x79, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x75, 0x59,
+    0x32, 0x39, 0x74, 0x62, 0x32, 0x52, 0x76, 0x0a, 0x59, 0x32, 0x45, 0x75,
+    0x59, 0x32, 0x39, 0x74, 0x4c, 0x31, 0x4e, 0x6c, 0x59, 0x33, 0x56, 0x79,
+    0x5a, 0x55, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a,
+    0x59, 0x58, 0x52, 0x6c, 0x55, 0x32, 0x56, 0x79, 0x64, 0x6d, 0x6c, 0x6a,
+    0x5a, 0x58, 0x4d, 0x75, 0x59, 0x33, 0x4a, 0x73, 0x4d, 0x44, 0x6d, 0x67,
+    0x4e, 0x36, 0x41, 0x31, 0x68, 0x6a, 0x4e, 0x6f, 0x64, 0x48, 0x52, 0x77,
+    0x0a, 0x4f, 0x69, 0x38, 0x76, 0x59, 0x33, 0x4a, 0x73, 0x4c, 0x6d, 0x4e,
+    0x76, 0x62, 0x57, 0x39, 0x6b, 0x62, 0x79, 0x35, 0x75, 0x5a, 0x58, 0x51,
+    0x76, 0x55, 0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, 0x6c, 0x51, 0x32, 0x56,
+    0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x56,
+    0x54, 0x5a, 0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x63, 0x79, 0x35,
+    0x6a, 0x63, 0x6d, 0x77, 0x77, 0x0a, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f,
+    0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51,
+    0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x49, 0x63, 0x42, 0x62, 0x53,
+    0x4d, 0x64, 0x66, 0x6c, 0x73, 0x58, 0x66, 0x63, 0x46, 0x68, 0x4d, 0x73,
+    0x2b, 0x50, 0x35, 0x2f, 0x4f, 0x4b, 0x6c, 0x46, 0x6c, 0x6d, 0x34, 0x4a,
+    0x34, 0x6f, 0x71, 0x46, 0x37, 0x54, 0x74, 0x2f, 0x51, 0x30, 0x0a, 0x35,
+    0x71, 0x6f, 0x35, 0x73, 0x70, 0x63, 0x57, 0x78, 0x59, 0x4a, 0x76, 0x4d,
+    0x71, 0x54, 0x70, 0x6a, 0x4f, 0x65, 0x76, 0x2f, 0x65, 0x2f, 0x43, 0x36,
+    0x4c, 0x6c, 0x4c, 0x71, 0x71, 0x50, 0x30, 0x35, 0x74, 0x71, 0x4e, 0x5a,
+    0x53, 0x48, 0x37, 0x75, 0x6f, 0x44, 0x72, 0x4a, 0x69, 0x69, 0x46, 0x47,
+    0x76, 0x34, 0x35, 0x6a, 0x4e, 0x35, 0x62, 0x42, 0x41, 0x53, 0x30, 0x56,
+    0x50, 0x6d, 0x6a, 0x0a, 0x5a, 0x35, 0x35, 0x42, 0x2b, 0x67, 0x6c, 0x53,
+    0x7a, 0x41, 0x56, 0x49, 0x71, 0x4d, 0x6b, 0x2f, 0x49, 0x51, 0x51, 0x65,
+    0x7a, 0x6b, 0x68, 0x72, 0x2f, 0x49, 0x58, 0x6f, 0x77, 0x6e, 0x75, 0x76,
+    0x66, 0x37, 0x66, 0x4d, 0x2b, 0x46, 0x38, 0x36, 0x2f, 0x54, 0x58, 0x47,
+    0x44, 0x65, 0x2b, 0x58, 0x33, 0x45, 0x79, 0x72, 0x45, 0x65, 0x46, 0x72,
+    0x79, 0x7a, 0x48, 0x52, 0x62, 0x50, 0x74, 0x49, 0x0a, 0x67, 0x4b, 0x76,
+    0x63, 0x6e, 0x44, 0x65, 0x34, 0x49, 0x52, 0x52, 0x4c, 0x44, 0x58, 0x45,
+    0x39, 0x37, 0x49, 0x4d, 0x7a, 0x62, 0x74, 0x46, 0x75, 0x4d, 0x68, 0x62,
+    0x73, 0x6d, 0x4d, 0x63, 0x57, 0x69, 0x31, 0x6d, 0x6d, 0x4e, 0x4b, 0x73,
+    0x46, 0x56, 0x79, 0x32, 0x54, 0x39, 0x36, 0x6f, 0x54, 0x79, 0x39, 0x49,
+    0x54, 0x34, 0x72, 0x63, 0x75, 0x4f, 0x38, 0x31, 0x72, 0x55, 0x42, 0x63,
+    0x4a, 0x0a, 0x61, 0x44, 0x36, 0x31, 0x4a, 0x6c, 0x66, 0x75, 0x74, 0x75,
+    0x43, 0x32, 0x33, 0x62, 0x6b, 0x70, 0x67, 0x48, 0x6c, 0x39, 0x6a, 0x36,
+    0x50, 0x77, 0x70, 0x43, 0x69, 0x6b, 0x46, 0x63, 0x53, 0x46, 0x39, 0x43,
+    0x66, 0x55, 0x61, 0x37, 0x2f, 0x6c, 0x58, 0x4f, 0x52, 0x6c, 0x41, 0x6e,
+    0x5a, 0x55, 0x74, 0x4f, 0x4d, 0x33, 0x5a, 0x69, 0x54, 0x54, 0x47, 0x57,
+    0x48, 0x49, 0x55, 0x68, 0x44, 0x6c, 0x0a, 0x69, 0x7a, 0x65, 0x61, 0x75,
+    0x61, 0x6e, 0x35, 0x48, 0x62, 0x2f, 0x71, 0x6d, 0x5a, 0x4a, 0x68, 0x6c,
+    0x76, 0x38, 0x42, 0x7a, 0x61, 0x46, 0x66, 0x44, 0x62, 0x78, 0x78, 0x76,
+    0x41, 0x36, 0x73, 0x43, 0x78, 0x31, 0x48, 0x52, 0x52, 0x33, 0x42, 0x37,
+    0x48, 0x7a, 0x73, 0x2f, 0x53, 0x6b, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76,
+    0x69, 0x63, 0x65, 0x73, 0x20, 0x4f, 0x3d, 0x43, 0x6f, 0x6d, 0x6f, 0x64,
+    0x6f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64,
+    0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53,
+    0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x4f, 0x3d, 0x43, 0x6f,
+    0x6d, 0x6f, 0x64, 0x6f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69,
+    0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x43, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x20, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+    0x73, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65,
+    0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44,
+    0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x39, 0x31, 0x3a, 0x31, 0x62, 0x3a, 0x33, 0x66, 0x3a,
+    0x36, 0x65, 0x3a, 0x63, 0x64, 0x3a, 0x39, 0x65, 0x3a, 0x61, 0x62, 0x3a,
+    0x65, 0x65, 0x3a, 0x30, 0x37, 0x3a, 0x66, 0x65, 0x3a, 0x31, 0x66, 0x3a,
+    0x37, 0x31, 0x3a, 0x64, 0x32, 0x3a, 0x62, 0x33, 0x3a, 0x36, 0x31, 0x3a,
+    0x32, 0x37, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x65,
+    0x31, 0x3a, 0x39, 0x66, 0x3a, 0x65, 0x33, 0x3a, 0x30, 0x65, 0x3a, 0x38,
+    0x62, 0x3a, 0x38, 0x34, 0x3a, 0x36, 0x30, 0x3a, 0x39, 0x65, 0x3a, 0x38,
+    0x30, 0x3a, 0x39, 0x62, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x64, 0x3a, 0x37,
+    0x32, 0x3a, 0x61, 0x38, 0x3a, 0x63, 0x35, 0x3a, 0x62, 0x61, 0x3a, 0x36,
+    0x65, 0x3a, 0x31, 0x34, 0x3a, 0x30, 0x39, 0x3a, 0x62, 0x64, 0x0a, 0x23,
+    0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x33, 0x66, 0x3a,
+    0x30, 0x36, 0x3a, 0x65, 0x35, 0x3a, 0x35, 0x36, 0x3a, 0x38, 0x31, 0x3a,
+    0x64, 0x34, 0x3a, 0x39, 0x36, 0x3a, 0x66, 0x35, 0x3a, 0x62, 0x65, 0x3a,
+    0x31, 0x36, 0x3a, 0x39, 0x65, 0x3a, 0x62, 0x35, 0x3a, 0x33, 0x38, 0x3a,
+    0x39, 0x66, 0x3a, 0x39, 0x66, 0x3a, 0x32, 0x62, 0x3a, 0x38, 0x66, 0x3a,
+    0x66, 0x36, 0x3a, 0x31, 0x65, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x38, 0x3a,
+    0x64, 0x66, 0x3a, 0x36, 0x38, 0x3a, 0x38, 0x31, 0x3a, 0x37, 0x32, 0x3a,
+    0x34, 0x38, 0x3a, 0x34, 0x39, 0x3a, 0x63, 0x64, 0x3a, 0x35, 0x64, 0x3a,
+    0x32, 0x37, 0x3a, 0x63, 0x62, 0x3a, 0x36, 0x39, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x4d, 0x49, 0x49, 0x45, 0x51, 0x7a, 0x43, 0x43, 0x41, 0x79, 0x75,
+    0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x2f, 0x4d, 0x51, 0x73,
+    0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a,
+    0x48, 0x51, 0x6a, 0x45, 0x62, 0x0a, 0x4d, 0x42, 0x6b, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x43, 0x41, 0x77, 0x53, 0x52, 0x33, 0x4a, 0x6c, 0x59, 0x58,
+    0x52, 0x6c, 0x63, 0x69, 0x42, 0x4e, 0x59, 0x57, 0x35, 0x6a, 0x61, 0x47,
+    0x56, 0x7a, 0x64, 0x47, 0x56, 0x79, 0x4d, 0x52, 0x41, 0x77, 0x44, 0x67,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x64, 0x54, 0x59, 0x57,
+    0x78, 0x6d, 0x62, 0x33, 0x4a, 0x6b, 0x4d, 0x52, 0x6f, 0x77, 0x0a, 0x47,
+    0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x46, 0x44, 0x62,
+    0x32, 0x31, 0x76, 0x5a, 0x47, 0x38, 0x67, 0x51, 0x30, 0x45, 0x67, 0x54,
+    0x47, 0x6c, 0x74, 0x61, 0x58, 0x52, 0x6c, 0x5a, 0x44, 0x45, 0x6c, 0x4d,
+    0x43, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x63, 0x56,
+    0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x6c, 0x5a, 0x43, 0x42, 0x44, 0x5a,
+    0x58, 0x4a, 0x30, 0x0a, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30,
+    0x5a, 0x53, 0x42, 0x54, 0x5a, 0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c,
+    0x63, 0x7a, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4e, 0x44, 0x41, 0x78,
+    0x4d, 0x44, 0x45, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x42, 0x61,
+    0x46, 0x77, 0x30, 0x79, 0x4f, 0x44, 0x45, 0x79, 0x4d, 0x7a, 0x45, 0x79,
+    0x4d, 0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c, 0x61, 0x0a, 0x4d, 0x48, 0x38,
+    0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59,
+    0x54, 0x41, 0x6b, 0x64, 0x43, 0x4d, 0x52, 0x73, 0x77, 0x47, 0x51, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x42, 0x4a, 0x48, 0x63, 0x6d, 0x56,
+    0x68, 0x64, 0x47, 0x56, 0x79, 0x49, 0x45, 0x31, 0x68, 0x62, 0x6d, 0x4e,
+    0x6f, 0x5a, 0x58, 0x4e, 0x30, 0x5a, 0x58, 0x49, 0x78, 0x45, 0x44, 0x41,
+    0x4f, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x4d, 0x42, 0x31,
+    0x4e, 0x68, 0x62, 0x47, 0x5a, 0x76, 0x63, 0x6d, 0x51, 0x78, 0x47, 0x6a,
+    0x41, 0x59, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x45, 0x55,
+    0x4e, 0x76, 0x62, 0x57, 0x39, 0x6b, 0x62, 0x79, 0x42, 0x44, 0x51, 0x53,
+    0x42, 0x4d, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6b, 0x4d, 0x53,
+    0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x0a, 0x56, 0x51, 0x51, 0x44, 0x44,
+    0x42, 0x78, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x47, 0x56, 0x6b, 0x49,
+    0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59,
+    0x58, 0x52, 0x6c, 0x49, 0x46, 0x4e, 0x6c, 0x63, 0x6e, 0x5a, 0x70, 0x59,
+    0x32, 0x56, 0x7a, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x0a,
+    0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41,
+    0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41,
+    0x33, 0x33, 0x46, 0x76, 0x4e, 0x6c, 0x68, 0x54, 0x57, 0x76, 0x49, 0x32,
+    0x56, 0x46, 0x65, 0x41, 0x78, 0x48, 0x51, 0x49, 0x49, 0x4f, 0x30, 0x59,
+    0x66, 0x79, 0x6f, 0x64, 0x35, 0x6a, 0x57, 0x61, 0x48, 0x69, 0x57, 0x73,
+    0x6e, 0x4f, 0x57, 0x57, 0x0a, 0x66, 0x6e, 0x4a, 0x53, 0x6f, 0x42, 0x56,
+    0x43, 0x32, 0x31, 0x6e, 0x64, 0x5a, 0x48, 0x6f, 0x61, 0x30, 0x4c, 0x68,
+    0x37, 0x33, 0x54, 0x6b, 0x56, 0x76, 0x46, 0x56, 0x49, 0x78, 0x4f, 0x30,
+    0x36, 0x41, 0x4f, 0x6f, 0x78, 0x45, 0x62, 0x72, 0x79, 0x63, 0x58, 0x51,
+    0x61, 0x5a, 0x37, 0x6a, 0x50, 0x4d, 0x38, 0x79, 0x6f, 0x4d, 0x61, 0x2b,
+    0x6a, 0x34, 0x39, 0x64, 0x2f, 0x76, 0x7a, 0x4d, 0x74, 0x0a, 0x54, 0x47,
+    0x6f, 0x38, 0x37, 0x49, 0x76, 0x44, 0x6b, 0x74, 0x4a, 0x54, 0x64, 0x79,
+    0x52, 0x30, 0x6e, 0x41, 0x64, 0x75, 0x63, 0x50, 0x79, 0x39, 0x43, 0x31,
+    0x74, 0x32, 0x75, 0x6c, 0x2f, 0x79, 0x2f, 0x39, 0x63, 0x33, 0x53, 0x30,
+    0x70, 0x67, 0x65, 0x50, 0x66, 0x77, 0x2b, 0x73, 0x70, 0x77, 0x74, 0x4f,
+    0x70, 0x5a, 0x71, 0x71, 0x50, 0x4f, 0x53, 0x43, 0x2b, 0x70, 0x77, 0x37,
+    0x49, 0x4c, 0x0a, 0x66, 0x68, 0x64, 0x79, 0x46, 0x67, 0x79, 0x6d, 0x42,
+    0x77, 0x77, 0x62, 0x4f, 0x4d, 0x2f, 0x4a, 0x59, 0x72, 0x63, 0x2f, 0x6f,
+    0x4a, 0x4f, 0x6c, 0x68, 0x30, 0x48, 0x79, 0x74, 0x33, 0x42, 0x41, 0x64,
+    0x39, 0x69, 0x2b, 0x46, 0x48, 0x7a, 0x6a, 0x71, 0x4d, 0x42, 0x36, 0x6a,
+    0x75, 0x6c, 0x6a, 0x61, 0x74, 0x45, 0x50, 0x6d, 0x73, 0x62, 0x53, 0x39,
+    0x49, 0x73, 0x36, 0x46, 0x41, 0x52, 0x57, 0x0a, 0x31, 0x4f, 0x32, 0x34,
+    0x7a, 0x47, 0x37, 0x31, 0x2b, 0x2b, 0x49, 0x73, 0x57, 0x4c, 0x31, 0x2f,
+    0x54, 0x32, 0x73, 0x72, 0x39, 0x32, 0x41, 0x6b, 0x57, 0x43, 0x54, 0x4f,
+    0x4a, 0x75, 0x38, 0x30, 0x6b, 0x54, 0x72, 0x56, 0x34, 0x34, 0x48, 0x51,
+    0x73, 0x76, 0x41, 0x45, 0x41, 0x74, 0x64, 0x62, 0x74, 0x7a, 0x36, 0x53,
+    0x72, 0x47, 0x73, 0x53, 0x69, 0x76, 0x6e, 0x6b, 0x42, 0x62, 0x41, 0x37,
+    0x0a, 0x6b, 0x55, 0x6c, 0x63, 0x73, 0x75, 0x74, 0x54, 0x36, 0x76, 0x69,
+    0x66, 0x52, 0x34, 0x62, 0x75, 0x76, 0x35, 0x58, 0x41, 0x77, 0x41, 0x61,
+    0x66, 0x30, 0x6c, 0x74, 0x65, 0x45, 0x52, 0x76, 0x30, 0x78, 0x77, 0x51,
+    0x31, 0x4b, 0x64, 0x4a, 0x56, 0x58, 0x4f, 0x54, 0x74, 0x36, 0x77, 0x49,
+    0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x34, 0x48, 0x4a, 0x4d, 0x49, 0x48,
+    0x47, 0x4d, 0x42, 0x30, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67,
+    0x51, 0x57, 0x42, 0x42, 0x54, 0x46, 0x65, 0x31, 0x69, 0x39, 0x37, 0x64,
+    0x6f, 0x6c, 0x61, 0x64, 0x4c, 0x33, 0x57, 0x52, 0x61, 0x6f, 0x73, 0x7a,
+    0x4c, 0x41, 0x65, 0x79, 0x64, 0x62, 0x39, 0x44, 0x41, 0x4f, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41,
+    0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x0a, 0x56,
+    0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41,
+    0x77, 0x45, 0x42, 0x2f, 0x7a, 0x43, 0x42, 0x67, 0x77, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x66, 0x42, 0x48, 0x77, 0x77, 0x65, 0x6a, 0x41, 0x38, 0x6f,
+    0x44, 0x71, 0x67, 0x4f, 0x49, 0x59, 0x32, 0x61, 0x48, 0x52, 0x30, 0x63,
+    0x44, 0x6f, 0x76, 0x4c, 0x32, 0x4e, 0x79, 0x62, 0x43, 0x35, 0x6a, 0x62,
+    0x32, 0x31, 0x76, 0x0a, 0x5a, 0x47, 0x39, 0x6a, 0x59, 0x53, 0x35, 0x6a,
+    0x62, 0x32, 0x30, 0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x6c,
+    0x5a, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a,
+    0x59, 0x58, 0x52, 0x6c, 0x55, 0x32, 0x56, 0x79, 0x64, 0x6d, 0x6c, 0x6a,
+    0x5a, 0x58, 0x4d, 0x75, 0x59, 0x33, 0x4a, 0x73, 0x4d, 0x44, 0x71, 0x67,
+    0x4f, 0x4b, 0x41, 0x32, 0x68, 0x6a, 0x52, 0x6f, 0x0a, 0x64, 0x48, 0x52,
+    0x77, 0x4f, 0x69, 0x38, 0x76, 0x59, 0x33, 0x4a, 0x73, 0x4c, 0x6d, 0x4e,
+    0x76, 0x62, 0x57, 0x39, 0x6b, 0x62, 0x79, 0x35, 0x75, 0x5a, 0x58, 0x51,
+    0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x6c, 0x5a, 0x45, 0x4e,
+    0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52,
+    0x6c, 0x55, 0x32, 0x56, 0x79, 0x64, 0x6d, 0x6c, 0x6a, 0x5a, 0x58, 0x4d,
+    0x75, 0x0a, 0x59, 0x33, 0x4a, 0x73, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53,
+    0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51,
+    0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x44, 0x49, 0x6b, 0x34,
+    0x45, 0x37, 0x69, 0x62, 0x53, 0x76, 0x75, 0x49, 0x51, 0x53, 0x54, 0x49,
+    0x33, 0x53, 0x38, 0x4e, 0x74, 0x77, 0x75, 0x6c, 0x65, 0x47, 0x46, 0x54,
+    0x51, 0x51, 0x75, 0x53, 0x39, 0x2f, 0x0a, 0x48, 0x72, 0x43, 0x6f, 0x69,
+    0x57, 0x43, 0x68, 0x69, 0x73, 0x4a, 0x33, 0x44, 0x46, 0x42, 0x4b, 0x6d,
+    0x77, 0x43, 0x4c, 0x32, 0x49, 0x76, 0x30, 0x51, 0x65, 0x4c, 0x51, 0x67,
+    0x34, 0x70, 0x4b, 0x48, 0x42, 0x51, 0x47, 0x73, 0x4b, 0x4e, 0x6f, 0x42,
+    0x58, 0x41, 0x78, 0x4d, 0x4b, 0x64, 0x54, 0x6d, 0x77, 0x37, 0x70, 0x53,
+    0x71, 0x42, 0x59, 0x61, 0x57, 0x63, 0x4f, 0x72, 0x70, 0x33, 0x32, 0x0a,
+    0x70, 0x53, 0x78, 0x42, 0x76, 0x7a, 0x77, 0x47, 0x61, 0x2b, 0x52, 0x5a,
+    0x7a, 0x47, 0x30, 0x51, 0x38, 0x5a, 0x5a, 0x76, 0x48, 0x39, 0x2f, 0x30,
+    0x42, 0x41, 0x4b, 0x6b, 0x6e, 0x30, 0x55, 0x2b, 0x79, 0x4e, 0x6a, 0x36,
+    0x4e, 0x6b, 0x5a, 0x45, 0x55, 0x44, 0x2b, 0x43, 0x6c, 0x35, 0x45, 0x66,
+    0x4b, 0x4e, 0x73, 0x59, 0x45, 0x59, 0x77, 0x71, 0x35, 0x47, 0x57, 0x44,
+    0x56, 0x78, 0x49, 0x53, 0x0a, 0x6a, 0x42, 0x63, 0x2f, 0x6c, 0x44, 0x62,
+    0x2b, 0x58, 0x62, 0x44, 0x41, 0x42, 0x48, 0x63, 0x54, 0x75, 0x50, 0x51,
+    0x56, 0x31, 0x54, 0x38, 0x34, 0x7a, 0x4a, 0x51, 0x36, 0x56, 0x64, 0x43,
+    0x73, 0x6d, 0x50, 0x57, 0x36, 0x41, 0x46, 0x2f, 0x67, 0x68, 0x68, 0x6d,
+    0x42, 0x65, 0x43, 0x38, 0x6f, 0x77, 0x48, 0x37, 0x54, 0x7a, 0x45, 0x49,
+    0x4b, 0x39, 0x61, 0x35, 0x51, 0x6f, 0x4e, 0x45, 0x2b, 0x0a, 0x78, 0x71,
+    0x46, 0x78, 0x37, 0x44, 0x2b, 0x67, 0x49, 0x49, 0x78, 0x6d, 0x4f, 0x6f,
+    0x6d, 0x30, 0x6a, 0x74, 0x54, 0x59, 0x73, 0x55, 0x30, 0x6c, 0x52, 0x2b,
+    0x34, 0x76, 0x69, 0x4d, 0x69, 0x31, 0x34, 0x51, 0x56, 0x46, 0x77, 0x4c,
+    0x34, 0x55, 0x63, 0x64, 0x35, 0x36, 0x2f, 0x59, 0x35, 0x37, 0x66, 0x55,
+    0x30, 0x49, 0x6c, 0x71, 0x55, 0x53, 0x63, 0x2f, 0x41, 0x74, 0x79, 0x6a,
+    0x63, 0x6e, 0x0a, 0x64, 0x42, 0x49, 0x6e, 0x54, 0x4d, 0x75, 0x32, 0x6c,
+    0x2b, 0x6e, 0x5a, 0x72, 0x67, 0x68, 0x74, 0x57, 0x6a, 0x6c, 0x41, 0x33,
+    0x51, 0x56, 0x48, 0x64, 0x57, 0x70, 0x61, 0x49, 0x62, 0x4f, 0x6a, 0x47,
+    0x4d, 0x39, 0x4f, 0x39, 0x79, 0x35, 0x58, 0x74, 0x35, 0x68, 0x77, 0x58,
+    0x73, 0x6a, 0x45, 0x65, 0x4c, 0x42, 0x69, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x55, 0x54, 0x4e, 0x20, 0x2d, 0x20, 0x44, 0x41, 0x54, 0x41, 0x43, 0x6f,
+    0x72, 0x70, 0x20, 0x53, 0x47, 0x43, 0x20, 0x4f, 0x3d, 0x54, 0x68, 0x65,
+    0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e,
+    0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4f, 0x55, 0x3d, 0x68, 0x74,
+    0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, 0x65,
+    0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x55, 0x54, 0x4e, 0x20, 0x2d, 0x20, 0x44, 0x41, 0x54, 0x41, 0x43,
+    0x6f, 0x72, 0x70, 0x20, 0x53, 0x47, 0x43, 0x20, 0x4f, 0x3d, 0x54, 0x68,
+    0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20,
+    0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4f, 0x55, 0x3d, 0x68,
+    0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73,
+    0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x55, 0x54,
+    0x4e, 0x20, 0x44, 0x41, 0x54, 0x41, 0x43, 0x6f, 0x72, 0x70, 0x20, 0x53,
+    0x47, 0x43, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x39, 0x31,
+    0x33, 0x37, 0x34, 0x32, 0x39, 0x34, 0x35, 0x34, 0x32, 0x38, 0x38, 0x34,
+    0x36, 0x38, 0x39, 0x38, 0x35, 0x35, 0x31, 0x36, 0x37, 0x35, 0x37, 0x37,
+    0x36, 0x38, 0x30, 0x32, 0x34, 0x31, 0x30, 0x37, 0x37, 0x36, 0x30, 0x39,
+    0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x62, 0x33, 0x3a, 0x61,
+    0x35, 0x3a, 0x33, 0x65, 0x3a, 0x37, 0x37, 0x3a, 0x32, 0x31, 0x3a, 0x36,
+    0x64, 0x3a, 0x61, 0x63, 0x3a, 0x34, 0x61, 0x3a, 0x63, 0x30, 0x3a, 0x63,
+    0x39, 0x3a, 0x66, 0x62, 0x3a, 0x64, 0x35, 0x3a, 0x34, 0x31, 0x3a, 0x33,
+    0x64, 0x3a, 0x63, 0x61, 0x3a, 0x30, 0x36, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x35, 0x38, 0x3a, 0x31, 0x31, 0x3a, 0x39, 0x66,
+    0x3a, 0x30, 0x65, 0x3a, 0x31, 0x32, 0x3a, 0x38, 0x32, 0x3a, 0x38, 0x37,
+    0x3a, 0x65, 0x61, 0x3a, 0x35, 0x30, 0x3a, 0x66, 0x64, 0x3a, 0x64, 0x39,
+    0x3a, 0x38, 0x37, 0x3a, 0x34, 0x35, 0x3a, 0x36, 0x66, 0x3a, 0x34, 0x66,
+    0x3a, 0x37, 0x38, 0x3a, 0x64, 0x63, 0x3a, 0x66, 0x61, 0x3a, 0x64, 0x36,
+    0x3a, 0x64, 0x34, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x38, 0x35, 0x3a, 0x66, 0x62, 0x3a, 0x32, 0x66, 0x3a, 0x39,
+    0x31, 0x3a, 0x64, 0x64, 0x3a, 0x31, 0x32, 0x3a, 0x32, 0x37, 0x3a, 0x35,
+    0x61, 0x3a, 0x30, 0x31, 0x3a, 0x34, 0x35, 0x3a, 0x62, 0x36, 0x3a, 0x33,
+    0x36, 0x3a, 0x35, 0x33, 0x3a, 0x34, 0x66, 0x3a, 0x38, 0x34, 0x3a, 0x30,
+    0x32, 0x3a, 0x34, 0x61, 0x3a, 0x64, 0x36, 0x3a, 0x38, 0x62, 0x3a, 0x36,
+    0x39, 0x3a, 0x62, 0x38, 0x3a, 0x65, 0x65, 0x3a, 0x38, 0x38, 0x3a, 0x36,
+    0x38, 0x3a, 0x34, 0x66, 0x3a, 0x66, 0x37, 0x3a, 0x31, 0x31, 0x3a, 0x33,
+    0x37, 0x3a, 0x35, 0x38, 0x3a, 0x30, 0x35, 0x3a, 0x62, 0x33, 0x3a, 0x34,
+    0x38, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x58, 0x6a,
+    0x43, 0x43, 0x41, 0x30, 0x61, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67,
+    0x49, 0x51, 0x52, 0x4c, 0x34, 0x4d, 0x69, 0x31, 0x41, 0x41, 0x49, 0x62,
+    0x51, 0x52, 0x30, 0x79, 0x70, 0x6f, 0x42, 0x71, 0x6d, 0x74, 0x61, 0x54,
+    0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77,
+    0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a, 0x6b,
+    0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x54, 0x41, 0x6c, 0x56, 0x55, 0x4d,
+    0x52, 0x63, 0x77, 0x46, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45,
+    0x77, 0x35, 0x54, 0x59, 0x57, 0x78, 0x30, 0x49, 0x45, 0x78, 0x68, 0x61,
+    0x32, 0x55, 0x67, 0x0a, 0x51, 0x32, 0x6c, 0x30, 0x65, 0x54, 0x45, 0x65,
+    0x4d, 0x42, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x56,
+    0x56, 0x47, 0x68, 0x6c, 0x49, 0x46, 0x56, 0x54, 0x52, 0x56, 0x4a, 0x55,
+    0x55, 0x6c, 0x56, 0x54, 0x56, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33,
+    0x62, 0x33, 0x4a, 0x72, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x68, 0x6f, 0x0a, 0x64, 0x48, 0x52,
+    0x77, 0x4f, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x56,
+    0x7a, 0x5a, 0x58, 0x4a, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35,
+    0x6a, 0x62, 0x32, 0x30, 0x78, 0x47, 0x7a, 0x41, 0x5a, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x4d, 0x54, 0x45, 0x6c, 0x56, 0x55, 0x54, 0x69, 0x41,
+    0x74, 0x49, 0x45, 0x52, 0x42, 0x56, 0x45, 0x46, 0x44, 0x62, 0x33, 0x4a,
+    0x77, 0x0a, 0x49, 0x46, 0x4e, 0x48, 0x51, 0x7a, 0x41, 0x65, 0x46, 0x77,
+    0x30, 0x35, 0x4f, 0x54, 0x41, 0x32, 0x4d, 0x6a, 0x51, 0x78, 0x4f, 0x44,
+    0x55, 0x33, 0x4d, 0x6a, 0x46, 0x61, 0x46, 0x77, 0x30, 0x78, 0x4f, 0x54,
+    0x41, 0x32, 0x4d, 0x6a, 0x51, 0x78, 0x4f, 0x54, 0x41, 0x32, 0x4d, 0x7a,
+    0x42, 0x61, 0x4d, 0x49, 0x47, 0x54, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0a, 0x45, 0x77, 0x4a, 0x56, 0x55,
+    0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x42, 0x4d, 0x43, 0x56, 0x56, 0x51, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x44, 0x6c, 0x4e, 0x68, 0x62,
+    0x48, 0x51, 0x67, 0x54, 0x47, 0x46, 0x72, 0x5a, 0x53, 0x42, 0x44, 0x61,
+    0x58, 0x52, 0x35, 0x4d, 0x52, 0x34, 0x77, 0x48, 0x41, 0x59, 0x44, 0x0a,
+    0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x56, 0x55, 0x61, 0x47, 0x55, 0x67,
+    0x56, 0x56, 0x4e, 0x46, 0x55, 0x6c, 0x52, 0x53, 0x56, 0x56, 0x4e, 0x55,
+    0x49, 0x45, 0x35, 0x6c, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6d, 0x73, 0x78,
+    0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54,
+    0x47, 0x47, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4c, 0x79, 0x39, 0x33,
+    0x64, 0x33, 0x63, 0x75, 0x0a, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6e, 0x52,
+    0x79, 0x64, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x54, 0x45,
+    0x62, 0x4d, 0x42, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x53, 0x56, 0x56, 0x52, 0x4f, 0x49, 0x43, 0x30, 0x67, 0x52, 0x45, 0x46,
+    0x55, 0x51, 0x55, 0x4e, 0x76, 0x63, 0x6e, 0x41, 0x67, 0x55, 0x30, 0x64,
+    0x44, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x0a, 0x42, 0x67,
+    0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51,
+    0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49,
+    0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x33, 0x2b,
+    0x35, 0x59, 0x45, 0x4b, 0x49, 0x72, 0x62, 0x6c, 0x58, 0x45, 0x6a, 0x72,
+    0x38, 0x75, 0x52, 0x67, 0x6e, 0x6e, 0x34, 0x41, 0x67, 0x50, 0x4c, 0x69,
+    0x74, 0x36, 0x0a, 0x45, 0x35, 0x51, 0x62, 0x76, 0x66, 0x61, 0x32, 0x67,
+    0x49, 0x35, 0x6c, 0x42, 0x5a, 0x4d, 0x41, 0x48, 0x72, 0x79, 0x76, 0x34,
+    0x67, 0x2b, 0x4f, 0x47, 0x51, 0x30, 0x53, 0x52, 0x2b, 0x79, 0x73, 0x72,
+    0x61, 0x50, 0x36, 0x4c, 0x6e, 0x44, 0x34, 0x33, 0x6d, 0x37, 0x37, 0x56,
+    0x6b, 0x49, 0x56, 0x6e, 0x69, 0x35, 0x63, 0x37, 0x79, 0x50, 0x65, 0x49,
+    0x62, 0x6b, 0x46, 0x64, 0x69, 0x63, 0x5a, 0x0a, 0x44, 0x30, 0x2f, 0x57,
+    0x77, 0x35, 0x79, 0x30, 0x76, 0x70, 0x51, 0x5a, 0x59, 0x2f, 0x4b, 0x6d,
+    0x45, 0x51, 0x72, 0x72, 0x55, 0x30, 0x69, 0x63, 0x76, 0x76, 0x49, 0x70,
+    0x4f, 0x78, 0x62, 0x6f, 0x47, 0x71, 0x42, 0x4d, 0x70, 0x73, 0x6e, 0x30,
+    0x47, 0x46, 0x6c, 0x6f, 0x77, 0x48, 0x44, 0x79, 0x55, 0x77, 0x44, 0x41,
+    0x58, 0x6c, 0x43, 0x43, 0x70, 0x56, 0x5a, 0x76, 0x4e, 0x76, 0x6c, 0x4b,
+    0x0a, 0x34, 0x45, 0x53, 0x47, 0x6f, 0x45, 0x31, 0x4f, 0x31, 0x6b, 0x64,
+    0x75, 0x53, 0x55, 0x72, 0x4c, 0x5a, 0x39, 0x65, 0x6d, 0x78, 0x41, 0x57,
+    0x35, 0x6a, 0x68, 0x37, 0x30, 0x2f, 0x50, 0x2f, 0x4e, 0x35, 0x7a, 0x62,
+    0x67, 0x6e, 0x41, 0x56, 0x73, 0x73, 0x6a, 0x4d, 0x69, 0x46, 0x64, 0x43,
+    0x30, 0x34, 0x4d, 0x77, 0x58, 0x77, 0x4c, 0x4c, 0x41, 0x39, 0x50, 0x34,
+    0x79, 0x50, 0x79, 0x6b, 0x71, 0x0a, 0x6c, 0x58, 0x76, 0x59, 0x38, 0x71,
+    0x64, 0x4f, 0x44, 0x31, 0x52, 0x38, 0x6f, 0x51, 0x32, 0x41, 0x73, 0x77,
+    0x6b, 0x44, 0x77, 0x66, 0x39, 0x63, 0x33, 0x56, 0x36, 0x61, 0x50, 0x72,
+    0x79, 0x75, 0x76, 0x45, 0x65, 0x4b, 0x61, 0x71, 0x35, 0x78, 0x79, 0x68,
+    0x2b, 0x78, 0x4b, 0x72, 0x68, 0x66, 0x51, 0x67, 0x55, 0x4c, 0x37, 0x45,
+    0x59, 0x77, 0x30, 0x58, 0x49, 0x4c, 0x79, 0x75, 0x6c, 0x57, 0x0a, 0x62,
+    0x66, 0x58, 0x76, 0x33, 0x33, 0x69, 0x2b, 0x59, 0x62, 0x71, 0x79, 0x70,
+    0x61, 0x34, 0x45, 0x54, 0x4c, 0x79, 0x6f, 0x72, 0x47, 0x6b, 0x56, 0x6c,
+    0x37, 0x33, 0x76, 0x36, 0x37, 0x53, 0x4d, 0x76, 0x7a, 0x58, 0x34, 0x31,
+    0x4d, 0x50, 0x52, 0x4b, 0x41, 0x35, 0x63, 0x4f, 0x70, 0x39, 0x77, 0x47,
+    0x44, 0x4d, 0x67, 0x64, 0x38, 0x53, 0x69, 0x72, 0x77, 0x49, 0x44, 0x41,
+    0x51, 0x41, 0x42, 0x0a, 0x6f, 0x34, 0x47, 0x72, 0x4d, 0x49, 0x47, 0x6f,
+    0x4d, 0x41, 0x73, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x51, 0x45,
+    0x41, 0x77, 0x49, 0x42, 0x78, 0x6a, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56,
+    0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44,
+    0x41, 0x51, 0x48, 0x2f, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64,
+    0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x54, 0x0a, 0x4d, 0x74, 0x47,
+    0x7a, 0x7a, 0x33, 0x2f, 0x36, 0x34, 0x50, 0x47, 0x67, 0x58, 0x59, 0x56,
+    0x4f, 0x6b, 0x74, 0x4b, 0x65, 0x52, 0x52, 0x32, 0x30, 0x54, 0x7a, 0x41,
+    0x39, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x38, 0x45, 0x4e, 0x6a, 0x41,
+    0x30, 0x4d, 0x44, 0x4b, 0x67, 0x4d, 0x4b, 0x41, 0x75, 0x68, 0x69, 0x78,
+    0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x59, 0x33, 0x4a,
+    0x73, 0x0a, 0x4c, 0x6e, 0x56, 0x7a, 0x5a, 0x58, 0x4a, 0x30, 0x63, 0x6e,
+    0x56, 0x7a, 0x64, 0x43, 0x35, 0x6a, 0x62, 0x32, 0x30, 0x76, 0x56, 0x56,
+    0x52, 0x4f, 0x4c, 0x55, 0x52, 0x42, 0x56, 0x45, 0x46, 0x44, 0x62, 0x33,
+    0x4a, 0x77, 0x55, 0x30, 0x64, 0x44, 0x4c, 0x6d, 0x4e, 0x79, 0x62, 0x44,
+    0x41, 0x71, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x55, 0x45, 0x49, 0x7a,
+    0x41, 0x68, 0x42, 0x67, 0x67, 0x72, 0x0a, 0x42, 0x67, 0x45, 0x46, 0x42,
+    0x51, 0x63, 0x44, 0x41, 0x51, 0x59, 0x4b, 0x4b, 0x77, 0x59, 0x42, 0x42,
+    0x41, 0x47, 0x43, 0x4e, 0x77, 0x6f, 0x44, 0x41, 0x77, 0x59, 0x4a, 0x59,
+    0x49, 0x5a, 0x49, 0x41, 0x59, 0x62, 0x34, 0x51, 0x67, 0x51, 0x42, 0x4d,
+    0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44,
+    0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x0a,
+    0x41, 0x51, 0x41, 0x6e, 0x4e, 0x5a, 0x63, 0x41, 0x69, 0x6f, 0x73, 0x6f,
+    0x76, 0x63, 0x59, 0x7a, 0x4d, 0x42, 0x34, 0x70, 0x2f, 0x4f, 0x4c, 0x33,
+    0x31, 0x5a, 0x6a, 0x55, 0x51, 0x4c, 0x74, 0x67, 0x79, 0x72, 0x2b, 0x72,
+    0x46, 0x79, 0x77, 0x4a, 0x4e, 0x6e, 0x39, 0x51, 0x2b, 0x6b, 0x48, 0x63,
+    0x72, 0x70, 0x59, 0x36, 0x43, 0x69, 0x4d, 0x2b, 0x69, 0x56, 0x6e, 0x4a,
+    0x6f, 0x77, 0x66, 0x74, 0x0a, 0x47, 0x7a, 0x65, 0x74, 0x2f, 0x48, 0x79,
+    0x2b, 0x55, 0x55, 0x6c, 0x61, 0x33, 0x6a, 0x6f, 0x4b, 0x56, 0x41, 0x67,
+    0x57, 0x52, 0x63, 0x4b, 0x5a, 0x73, 0x59, 0x66, 0x4e, 0x6a, 0x47, 0x6a,
+    0x67, 0x61, 0x51, 0x50, 0x70, 0x78, 0x45, 0x36, 0x59, 0x73, 0x6a, 0x75,
+    0x4d, 0x46, 0x72, 0x4d, 0x4f, 0x6f, 0x41, 0x79, 0x59, 0x55, 0x4a, 0x75,
+    0x54, 0x71, 0x58, 0x41, 0x4a, 0x79, 0x43, 0x79, 0x6a, 0x0a, 0x6a, 0x39,
+    0x38, 0x43, 0x35, 0x4f, 0x42, 0x78, 0x4f, 0x76, 0x47, 0x30, 0x49, 0x33,
+    0x4b, 0x67, 0x71, 0x67, 0x48, 0x66, 0x33, 0x35, 0x67, 0x2b, 0x46, 0x46,
+    0x43, 0x67, 0x4d, 0x53, 0x61, 0x39, 0x4b, 0x4f, 0x6c, 0x61, 0x4d, 0x43,
+    0x5a, 0x31, 0x2b, 0x58, 0x74, 0x67, 0x48, 0x49, 0x33, 0x7a, 0x7a, 0x56,
+    0x41, 0x6d, 0x62, 0x51, 0x51, 0x6e, 0x6d, 0x74, 0x2f, 0x56, 0x44, 0x55,
+    0x56, 0x48, 0x0a, 0x4b, 0x57, 0x73, 0x73, 0x35, 0x6e, 0x62, 0x5a, 0x71,
+    0x53, 0x6c, 0x39, 0x4d, 0x74, 0x33, 0x4a, 0x4e, 0x6a, 0x79, 0x39, 0x72,
+    0x6a, 0x58, 0x78, 0x45, 0x5a, 0x34, 0x64, 0x75, 0x35, 0x41, 0x2f, 0x45,
+    0x6b, 0x64, 0x4f, 0x6a, 0x74, 0x64, 0x2b, 0x44, 0x32, 0x4a, 0x7a, 0x48,
+    0x56, 0x49, 0x6d, 0x4f, 0x42, 0x77, 0x59, 0x53, 0x66, 0x30, 0x77, 0x64,
+    0x4a, 0x72, 0x45, 0x35, 0x53, 0x49, 0x76, 0x0a, 0x32, 0x4d, 0x43, 0x4e,
+    0x37, 0x5a, 0x46, 0x36, 0x54, 0x41, 0x43, 0x50, 0x63, 0x6e, 0x39, 0x64,
+    0x32, 0x74, 0x30, 0x62, 0x69, 0x30, 0x56, 0x72, 0x35, 0x39, 0x31, 0x70,
+    0x6c, 0x36, 0x6a, 0x46, 0x56, 0x6b, 0x77, 0x50, 0x44, 0x50, 0x61, 0x66,
+    0x65, 0x70, 0x45, 0x33, 0x39, 0x70, 0x65, 0x43, 0x34, 0x4e, 0x31, 0x78,
+    0x61, 0x66, 0x39, 0x32, 0x50, 0x32, 0x42, 0x4e, 0x50, 0x4d, 0x2f, 0x33,
+    0x0a, 0x6d, 0x66, 0x6e, 0x47, 0x56, 0x2f, 0x54, 0x4a, 0x56, 0x54, 0x6c,
+    0x34, 0x75, 0x69, 0x78, 0x35, 0x79, 0x61, 0x61, 0x49, 0x4b, 0x2f, 0x51,
+    0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53,
+    0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64,
+    0x77, 0x61, 0x72, 0x65, 0x20, 0x4f, 0x3d, 0x54, 0x68, 0x65, 0x20, 0x55,
+    0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74,
+    0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4f, 0x55, 0x3d, 0x68, 0x74, 0x74, 0x70,
+    0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74,
+    0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x55,
+    0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74,
+    0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x4f, 0x3d,
+    0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53,
+    0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4f, 0x55,
+    0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
+    0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f,
+    0x6d, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22,
+    0x55, 0x54, 0x4e, 0x20, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73,
+    0x74, 0x20, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x52,
+    0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65,
+    0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x39, 0x31, 0x33, 0x37, 0x34, 0x32,
+    0x39, 0x34, 0x35, 0x34, 0x32, 0x38, 0x38, 0x34, 0x37, 0x30, 0x34, 0x30,
+    0x32, 0x32, 0x32, 0x36, 0x37, 0x30, 0x33, 0x39, 0x32, 0x32, 0x31, 0x31,
+    0x38, 0x34, 0x35, 0x33, 0x31, 0x31, 0x39, 0x37, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x34, 0x63, 0x3a, 0x35, 0x36, 0x3a, 0x34, 0x31,
+    0x3a, 0x65, 0x35, 0x3a, 0x30, 0x64, 0x3a, 0x62, 0x62, 0x3a, 0x32, 0x62,
+    0x3a, 0x65, 0x38, 0x3a, 0x63, 0x61, 0x3a, 0x61, 0x33, 0x3a, 0x65, 0x64,
+    0x3a, 0x31, 0x38, 0x3a, 0x30, 0x38, 0x3a, 0x61, 0x64, 0x3a, 0x34, 0x33,
+    0x3a, 0x33, 0x39, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x30, 0x34, 0x3a, 0x38, 0x33, 0x3a, 0x65, 0x64, 0x3a, 0x33, 0x33, 0x3a,
+    0x39, 0x39, 0x3a, 0x61, 0x63, 0x3a, 0x33, 0x36, 0x3a, 0x30, 0x38, 0x3a,
+    0x30, 0x35, 0x3a, 0x38, 0x37, 0x3a, 0x32, 0x32, 0x3a, 0x65, 0x64, 0x3a,
+    0x62, 0x63, 0x3a, 0x35, 0x65, 0x3a, 0x34, 0x36, 0x3a, 0x30, 0x30, 0x3a,
+    0x65, 0x33, 0x3a, 0x62, 0x65, 0x3a, 0x66, 0x39, 0x3a, 0x64, 0x37, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x36, 0x65,
+    0x3a, 0x61, 0x35, 0x3a, 0x34, 0x37, 0x3a, 0x34, 0x31, 0x3a, 0x64, 0x30,
+    0x3a, 0x30, 0x34, 0x3a, 0x36, 0x36, 0x3a, 0x37, 0x65, 0x3a, 0x65, 0x64,
+    0x3a, 0x31, 0x62, 0x3a, 0x34, 0x38, 0x3a, 0x31, 0x36, 0x3a, 0x36, 0x33,
+    0x3a, 0x34, 0x61, 0x3a, 0x61, 0x33, 0x3a, 0x61, 0x37, 0x3a, 0x39, 0x65,
+    0x3a, 0x36, 0x65, 0x3a, 0x34, 0x62, 0x3a, 0x39, 0x36, 0x3a, 0x39, 0x35,
+    0x3a, 0x30, 0x66, 0x3a, 0x38, 0x32, 0x3a, 0x37, 0x39, 0x3a, 0x64, 0x61,
+    0x3a, 0x66, 0x63, 0x3a, 0x38, 0x64, 0x3a, 0x39, 0x62, 0x3a, 0x64, 0x38,
+    0x3a, 0x38, 0x31, 0x3a, 0x32, 0x31, 0x3a, 0x33, 0x37, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x64, 0x44, 0x43, 0x43, 0x41, 0x31,
+    0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x52, 0x4c,
+    0x34, 0x4d, 0x69, 0x31, 0x41, 0x41, 0x4a, 0x4c, 0x51, 0x52, 0x30, 0x7a,
+    0x59, 0x71, 0x2f, 0x6d, 0x55, 0x4b, 0x2f, 0x54, 0x41, 0x4e, 0x42, 0x67,
+    0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51,
+    0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a, 0x6c, 0x7a, 0x45, 0x4c, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x67, 0x54, 0x41, 0x6c, 0x56, 0x55, 0x4d, 0x52, 0x63, 0x77, 0x46,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x35, 0x54, 0x59,
+    0x57, 0x78, 0x30, 0x49, 0x45, 0x78, 0x68, 0x61, 0x32, 0x55, 0x67, 0x0a,
+    0x51, 0x32, 0x6c, 0x30, 0x65, 0x54, 0x45, 0x65, 0x4d, 0x42, 0x77, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x56, 0x56, 0x47, 0x68, 0x6c,
+    0x49, 0x46, 0x56, 0x54, 0x52, 0x56, 0x4a, 0x55, 0x55, 0x6c, 0x56, 0x54,
+    0x56, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72,
+    0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c,
+    0x45, 0x78, 0x68, 0x6f, 0x0a, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38,
+    0x76, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x56, 0x7a, 0x5a, 0x58, 0x4a,
+    0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x6a, 0x62, 0x32, 0x30,
+    0x78, 0x48, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d,
+    0x54, 0x46, 0x6c, 0x56, 0x55, 0x54, 0x69, 0x31, 0x56, 0x55, 0x30, 0x56,
+    0x53, 0x52, 0x6d, 0x6c, 0x79, 0x63, 0x33, 0x51, 0x74, 0x0a, 0x53, 0x47,
+    0x46, 0x79, 0x5a, 0x48, 0x64, 0x68, 0x63, 0x6d, 0x55, 0x77, 0x48, 0x68,
+    0x63, 0x4e, 0x4f, 0x54, 0x6b, 0x77, 0x4e, 0x7a, 0x41, 0x35, 0x4d, 0x54,
+    0x67, 0x78, 0x4d, 0x44, 0x51, 0x79, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x54,
+    0x6b, 0x77, 0x4e, 0x7a, 0x41, 0x35, 0x4d, 0x54, 0x67, 0x78, 0x4f, 0x54,
+    0x49, 0x79, 0x57, 0x6a, 0x43, 0x42, 0x6c, 0x7a, 0x45, 0x4c, 0x4d, 0x41,
+    0x6b, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x67, 0x54, 0x41, 0x6c, 0x56, 0x55, 0x4d, 0x52, 0x63, 0x77, 0x46,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x35, 0x54, 0x59,
+    0x57, 0x78, 0x30, 0x49, 0x45, 0x78, 0x68, 0x61, 0x32, 0x55, 0x67, 0x51,
+    0x32, 0x6c, 0x30, 0x65, 0x54, 0x45, 0x65, 0x0a, 0x4d, 0x42, 0x77, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x56, 0x56, 0x47, 0x68, 0x6c,
+    0x49, 0x46, 0x56, 0x54, 0x52, 0x56, 0x4a, 0x55, 0x55, 0x6c, 0x56, 0x54,
+    0x56, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72,
+    0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c,
+    0x45, 0x78, 0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76,
+    0x0a, 0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x56, 0x7a, 0x5a, 0x58, 0x4a,
+    0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x6a, 0x62, 0x32, 0x30,
+    0x78, 0x48, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d,
+    0x54, 0x46, 0x6c, 0x56, 0x55, 0x54, 0x69, 0x31, 0x56, 0x55, 0x30, 0x56,
+    0x53, 0x52, 0x6d, 0x6c, 0x79, 0x63, 0x33, 0x51, 0x74, 0x53, 0x47, 0x46,
+    0x79, 0x5a, 0x48, 0x64, 0x68, 0x0a, 0x63, 0x6d, 0x55, 0x77, 0x67, 0x67,
+    0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
+    0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34,
+    0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f,
+    0x49, 0x42, 0x41, 0x51, 0x43, 0x78, 0x39, 0x38, 0x4d, 0x34, 0x50, 0x37,
+    0x53, 0x6f, 0x66, 0x38, 0x38, 0x35, 0x67, 0x6c, 0x46, 0x6e, 0x0a, 0x30,
+    0x47, 0x32, 0x66, 0x30, 0x76, 0x39, 0x59, 0x38, 0x2b, 0x65, 0x66, 0x4b,
+    0x2b, 0x77, 0x4e, 0x69, 0x56, 0x53, 0x5a, 0x75, 0x54, 0x69, 0x5a, 0x46,
+    0x76, 0x66, 0x67, 0x49, 0x58, 0x6c, 0x49, 0x77, 0x72, 0x74, 0x68, 0x64,
+    0x42, 0x4b, 0x57, 0x48, 0x54, 0x78, 0x71, 0x63, 0x74, 0x55, 0x38, 0x45,
+    0x47, 0x63, 0x36, 0x4f, 0x65, 0x30, 0x72, 0x45, 0x38, 0x31, 0x6d, 0x36,
+    0x35, 0x55, 0x4a, 0x0a, 0x4d, 0x36, 0x52, 0x73, 0x6c, 0x37, 0x48, 0x6f,
+    0x78, 0x75, 0x7a, 0x42, 0x64, 0x58, 0x6d, 0x63, 0x52, 0x6c, 0x36, 0x4e,
+    0x71, 0x39, 0x42, 0x71, 0x2f, 0x62, 0x6b, 0x71, 0x56, 0x52, 0x63, 0x51,
+    0x56, 0x4c, 0x4d, 0x5a, 0x38, 0x4a, 0x72, 0x32, 0x38, 0x62, 0x46, 0x64,
+    0x74, 0x71, 0x64, 0x74, 0x2b, 0x2b, 0x42, 0x78, 0x46, 0x32, 0x75, 0x69,
+    0x69, 0x50, 0x73, 0x41, 0x33, 0x2f, 0x34, 0x61, 0x0a, 0x4d, 0x58, 0x63,
+    0x4d, 0x6d, 0x67, 0x46, 0x36, 0x73, 0x54, 0x4c, 0x6a, 0x4b, 0x77, 0x45,
+    0x48, 0x4f, 0x47, 0x37, 0x44, 0x70, 0x56, 0x34, 0x6a, 0x76, 0x45, 0x57,
+    0x62, 0x65, 0x31, 0x44, 0x42, 0x79, 0x54, 0x43, 0x50, 0x32, 0x2b, 0x55,
+    0x72, 0x65, 0x74, 0x4e, 0x62, 0x2b, 0x7a, 0x4e, 0x41, 0x48, 0x71, 0x44,
+    0x56, 0x6d, 0x42, 0x65, 0x38, 0x69, 0x34, 0x66, 0x44, 0x69, 0x64, 0x4e,
+    0x64, 0x0a, 0x6f, 0x49, 0x36, 0x79, 0x71, 0x71, 0x72, 0x32, 0x6a, 0x6d,
+    0x6d, 0x49, 0x42, 0x73, 0x58, 0x36, 0x69, 0x53, 0x48, 0x7a, 0x43, 0x4a,
+    0x31, 0x70, 0x4c, 0x67, 0x6b, 0x7a, 0x6d, 0x79, 0x6b, 0x4e, 0x52, 0x67,
+    0x2b, 0x4d, 0x7a, 0x45, 0x6b, 0x30, 0x73, 0x47, 0x6c, 0x52, 0x76, 0x66,
+    0x6b, 0x47, 0x7a, 0x57, 0x69, 0x74, 0x5a, 0x6b, 0x79, 0x38, 0x50, 0x71,
+    0x78, 0x68, 0x76, 0x51, 0x71, 0x49, 0x0a, 0x44, 0x73, 0x6a, 0x66, 0x50,
+    0x65, 0x35, 0x38, 0x42, 0x45, 0x79, 0x64, 0x43, 0x6c, 0x35, 0x72, 0x6b,
+    0x64, 0x62, 0x75, 0x78, 0x2b, 0x30, 0x6f, 0x6a, 0x61, 0x74, 0x4e, 0x68,
+    0x34, 0x6c, 0x7a, 0x30, 0x47, 0x36, 0x6b, 0x30, 0x42, 0x34, 0x57, 0x69,
+    0x78, 0x54, 0x68, 0x64, 0x6b, 0x51, 0x44, 0x66, 0x32, 0x4f, 0x73, 0x35,
+    0x4d, 0x31, 0x4a, 0x6e, 0x4d, 0x57, 0x53, 0x39, 0x4b, 0x73, 0x79, 0x0a,
+    0x6f, 0x55, 0x68, 0x62, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a,
+    0x67, 0x62, 0x6b, 0x77, 0x67, 0x62, 0x59, 0x77, 0x43, 0x77, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x50, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x48, 0x47,
+    0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42,
+    0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77,
+    0x48, 0x51, 0x59, 0x44, 0x0a, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59,
+    0x45, 0x46, 0x4b, 0x46, 0x79, 0x58, 0x79, 0x59, 0x62, 0x4b, 0x4a, 0x68,
+    0x44, 0x6c, 0x56, 0x30, 0x48, 0x4e, 0x39, 0x57, 0x46, 0x6c, 0x70, 0x31,
+    0x4c, 0x30, 0x73, 0x4e, 0x46, 0x4d, 0x45, 0x51, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x48, 0x77, 0x51, 0x39, 0x4d, 0x44, 0x73, 0x77, 0x4f, 0x61, 0x41,
+    0x33, 0x6f, 0x44, 0x57, 0x47, 0x4d, 0x32, 0x68, 0x30, 0x0a, 0x64, 0x48,
+    0x41, 0x36, 0x4c, 0x79, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x75, 0x64, 0x58,
+    0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4c, 0x6d,
+    0x4e, 0x76, 0x62, 0x53, 0x39, 0x56, 0x56, 0x45, 0x34, 0x74, 0x56, 0x56,
+    0x4e, 0x46, 0x55, 0x6b, 0x5a, 0x70, 0x63, 0x6e, 0x4e, 0x30, 0x4c, 0x55,
+    0x68, 0x68, 0x63, 0x6d, 0x52, 0x33, 0x59, 0x58, 0x4a, 0x6c, 0x4c, 0x6d,
+    0x4e, 0x79, 0x0a, 0x62, 0x44, 0x41, 0x78, 0x42, 0x67, 0x4e, 0x56, 0x48,
+    0x53, 0x55, 0x45, 0x4b, 0x6a, 0x41, 0x6f, 0x42, 0x67, 0x67, 0x72, 0x42,
+    0x67, 0x45, 0x46, 0x42, 0x51, 0x63, 0x44, 0x41, 0x51, 0x59, 0x49, 0x4b,
+    0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48, 0x41, 0x77, 0x55, 0x47, 0x43,
+    0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x4d, 0x47, 0x42,
+    0x67, 0x67, 0x72, 0x42, 0x67, 0x45, 0x46, 0x0a, 0x42, 0x51, 0x63, 0x44,
+    0x42, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43,
+    0x41, 0x51, 0x45, 0x41, 0x52, 0x78, 0x6b, 0x50, 0x33, 0x6e, 0x54, 0x47,
+    0x6d, 0x5a, 0x65, 0x76, 0x2f, 0x4b, 0x30, 0x6f, 0x58, 0x6e, 0x57, 0x4f,
+    0x36, 0x79, 0x31, 0x6e, 0x37, 0x6b, 0x35, 0x37, 0x4b, 0x39, 0x63, 0x4d,
+    0x0a, 0x2f, 0x2f, 0x62, 0x65, 0x79, 0x31, 0x57, 0x69, 0x43, 0x75, 0x46,
+    0x4d, 0x56, 0x47, 0x57, 0x54, 0x59, 0x47, 0x75, 0x66, 0x45, 0x70, 0x79,
+    0x74, 0x58, 0x6f, 0x4d, 0x73, 0x36, 0x31, 0x71, 0x75, 0x77, 0x4f, 0x51,
+    0x74, 0x39, 0x41, 0x42, 0x6a, 0x48, 0x62, 0x6a, 0x41, 0x62, 0x50, 0x4c,
+    0x50, 0x53, 0x62, 0x74, 0x4e, 0x6b, 0x32, 0x38, 0x47, 0x70, 0x67, 0x6f,
+    0x69, 0x73, 0x6b, 0x6c, 0x69, 0x0a, 0x43, 0x45, 0x37, 0x2f, 0x79, 0x4d,
+    0x67, 0x55, 0x73, 0x6f, 0x67, 0x57, 0x58, 0x65, 0x63, 0x42, 0x35, 0x42,
+    0x4b, 0x56, 0x35, 0x55, 0x55, 0x30, 0x73, 0x34, 0x74, 0x70, 0x76, 0x63,
+    0x2b, 0x30, 0x68, 0x59, 0x39, 0x31, 0x55, 0x5a, 0x35, 0x39, 0x4f, 0x6a,
+    0x67, 0x36, 0x46, 0x45, 0x67, 0x53, 0x78, 0x76, 0x75, 0x6e, 0x4f, 0x78,
+    0x71, 0x4e, 0x44, 0x59, 0x4a, 0x41, 0x42, 0x2b, 0x67, 0x45, 0x0a, 0x43,
+    0x4a, 0x43, 0x68, 0x69, 0x63, 0x73, 0x5a, 0x55, 0x4e, 0x2f, 0x4b, 0x48,
+    0x41, 0x47, 0x38, 0x48, 0x51, 0x51, 0x5a, 0x65, 0x78, 0x42, 0x32, 0x6c,
+    0x7a, 0x76, 0x75, 0x6b, 0x4a, 0x44, 0x4b, 0x78, 0x41, 0x34, 0x66, 0x46,
+    0x6d, 0x35, 0x31, 0x37, 0x7a, 0x50, 0x34, 0x30, 0x32, 0x39, 0x62, 0x48,
+    0x70, 0x62, 0x6a, 0x34, 0x48, 0x52, 0x33, 0x64, 0x48, 0x75, 0x4b, 0x6f,
+    0x6d, 0x34, 0x74, 0x0a, 0x33, 0x58, 0x62, 0x57, 0x4f, 0x54, 0x43, 0x43,
+    0x38, 0x4b, 0x75, 0x63, 0x55, 0x76, 0x49, 0x71, 0x78, 0x36, 0x39, 0x4a,
+    0x58, 0x6e, 0x37, 0x48, 0x61, 0x4f, 0x57, 0x43, 0x67, 0x63, 0x68, 0x71,
+    0x4a, 0x2f, 0x6b, 0x6e, 0x69, 0x43, 0x72, 0x56, 0x57, 0x46, 0x43, 0x56,
+    0x48, 0x2f, 0x41, 0x37, 0x48, 0x46, 0x65, 0x37, 0x66, 0x52, 0x51, 0x35,
+    0x59, 0x69, 0x75, 0x61, 0x79, 0x5a, 0x53, 0x53, 0x0a, 0x4b, 0x71, 0x4d,
+    0x69, 0x44, 0x50, 0x2b, 0x4a, 0x4a, 0x6e, 0x31, 0x66, 0x49, 0x79, 0x74,
+    0x48, 0x31, 0x78, 0x55, 0x64, 0x71, 0x57, 0x71, 0x65, 0x55, 0x51, 0x30,
+    0x71, 0x55, 0x5a, 0x36, 0x42, 0x2b, 0x64, 0x51, 0x37, 0x58, 0x6e, 0x41,
+    0x53, 0x66, 0x78, 0x41, 0x79, 0x6e, 0x42, 0x36, 0x37, 0x6e, 0x66, 0x68,
+    0x6d, 0x71, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49,
+    0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x58, 0x52,
+    0x61, 0x6d, 0x70, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f,
+    0x3d, 0x58, 0x52, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+    0x20, 0x49, 0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e,
+    0x78, 0x72, 0x61, 0x6d, 0x70, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
+    0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a,
+    0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x58, 0x52, 0x61, 0x6d,
+    0x70, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x58,
+    0x52, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
+    0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49,
+    0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e, 0x78, 0x72,
+    0x61, 0x6d, 0x70, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2e,
+    0x63, 0x6f, 0x6d, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x58, 0x52, 0x61, 0x6d, 0x70, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+    0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x30,
+    0x37, 0x31, 0x30, 0x38, 0x39, 0x30, 0x38, 0x38, 0x30, 0x33, 0x36, 0x35,
+    0x31, 0x35, 0x30, 0x39, 0x36, 0x39, 0x32, 0x39, 0x38, 0x30, 0x31, 0x32,
+    0x34, 0x32, 0x33, 0x33, 0x37, 0x34, 0x35, 0x30, 0x31, 0x34, 0x39, 0x35,
+    0x37, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x31, 0x3a,
+    0x30, 0x62, 0x3a, 0x34, 0x34, 0x3a, 0x62, 0x33, 0x3a, 0x63, 0x61, 0x3a,
+    0x31, 0x30, 0x3a, 0x64, 0x38, 0x3a, 0x30, 0x30, 0x3a, 0x36, 0x65, 0x3a,
+    0x39, 0x64, 0x3a, 0x30, 0x66, 0x3a, 0x64, 0x38, 0x3a, 0x30, 0x66, 0x3a,
+    0x39, 0x32, 0x3a, 0x30, 0x61, 0x3a, 0x64, 0x31, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x62, 0x38, 0x3a, 0x30, 0x31, 0x3a, 0x38,
+    0x36, 0x3a, 0x64, 0x31, 0x3a, 0x65, 0x62, 0x3a, 0x39, 0x63, 0x3a, 0x38,
+    0x36, 0x3a, 0x61, 0x35, 0x3a, 0x34, 0x31, 0x3a, 0x30, 0x34, 0x3a, 0x63,
+    0x66, 0x3a, 0x33, 0x30, 0x3a, 0x35, 0x34, 0x3a, 0x66, 0x33, 0x3a, 0x34,
+    0x63, 0x3a, 0x35, 0x32, 0x3a, 0x62, 0x37, 0x3a, 0x65, 0x35, 0x3a, 0x35,
+    0x38, 0x3a, 0x63, 0x36, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35,
+    0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x63, 0x65, 0x3a, 0x63, 0x64, 0x3a, 0x64, 0x63, 0x3a,
+    0x39, 0x30, 0x3a, 0x35, 0x30, 0x3a, 0x39, 0x39, 0x3a, 0x64, 0x38, 0x3a,
+    0x64, 0x61, 0x3a, 0x64, 0x66, 0x3a, 0x63, 0x35, 0x3a, 0x62, 0x31, 0x3a,
+    0x64, 0x32, 0x3a, 0x30, 0x39, 0x3a, 0x62, 0x37, 0x3a, 0x33, 0x37, 0x3a,
+    0x63, 0x62, 0x3a, 0x65, 0x32, 0x3a, 0x63, 0x31, 0x3a, 0x38, 0x63, 0x3a,
+    0x66, 0x62, 0x3a, 0x32, 0x63, 0x3a, 0x31, 0x30, 0x3a, 0x63, 0x30, 0x3a,
+    0x66, 0x66, 0x3a, 0x30, 0x62, 0x3a, 0x63, 0x66, 0x3a, 0x30, 0x64, 0x3a,
+    0x33, 0x32, 0x3a, 0x38, 0x36, 0x3a, 0x66, 0x63, 0x3a, 0x31, 0x61, 0x3a,
+    0x61, 0x32, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49,
+    0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x4d,
+    0x44, 0x43, 0x43, 0x41, 0x78, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41,
+    0x67, 0x49, 0x51, 0x55, 0x4a, 0x52, 0x73, 0x37, 0x42, 0x6a, 0x71, 0x31,
+    0x5a, 0x78, 0x4e, 0x31, 0x5a, 0x66, 0x76, 0x64, 0x59, 0x2b, 0x67, 0x72,
+    0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a,
+    0x67, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x48, 0x6a, 0x41, 0x63,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x46, 0x58, 0x64, 0x33,
+    0x64, 0x79, 0x35, 0x34, 0x63, 0x6d, 0x46, 0x74, 0x63, 0x48, 0x4e, 0x6c,
+    0x59, 0x33, 0x56, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4c, 0x6d, 0x4e, 0x76,
+    0x62, 0x54, 0x45, 0x6b, 0x0a, 0x4d, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x62, 0x57, 0x46, 0x4a, 0x68, 0x62, 0x58, 0x41,
+    0x67, 0x55, 0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, 0x70, 0x64, 0x48, 0x6b,
+    0x67, 0x55, 0x32, 0x56, 0x79, 0x64, 0x6d, 0x6c, 0x6a, 0x5a, 0x58, 0x4d,
+    0x67, 0x53, 0x57, 0x35, 0x6a, 0x4d, 0x53, 0x30, 0x77, 0x4b, 0x77, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x52, 0x59, 0x0a, 0x55, 0x6d,
+    0x46, 0x74, 0x63, 0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57,
+    0x77, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57,
+    0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58,
+    0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x48, 0x68,
+    0x63, 0x4e, 0x4d, 0x44, 0x51, 0x78, 0x4d, 0x54, 0x41, 0x78, 0x4d, 0x54,
+    0x63, 0x78, 0x0a, 0x4e, 0x44, 0x41, 0x30, 0x57, 0x68, 0x63, 0x4e, 0x4d,
+    0x7a, 0x55, 0x77, 0x4d, 0x54, 0x41, 0x78, 0x4d, 0x44, 0x55, 0x7a, 0x4e,
+    0x7a, 0x45, 0x35, 0x57, 0x6a, 0x43, 0x42, 0x67, 0x6a, 0x45, 0x4c, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x48, 0x6a, 0x41, 0x63, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x73, 0x54, 0x46, 0x58, 0x64, 0x33, 0x0a, 0x64, 0x79, 0x35, 0x34,
+    0x63, 0x6d, 0x46, 0x74, 0x63, 0x48, 0x4e, 0x6c, 0x59, 0x33, 0x56, 0x79,
+    0x61, 0x58, 0x52, 0x35, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x54, 0x45, 0x6b,
+    0x4d, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x62,
+    0x57, 0x46, 0x4a, 0x68, 0x62, 0x58, 0x41, 0x67, 0x55, 0x32, 0x56, 0x6a,
+    0x64, 0x58, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x55, 0x32, 0x56, 0x79,
+    0x0a, 0x64, 0x6d, 0x6c, 0x6a, 0x5a, 0x58, 0x4d, 0x67, 0x53, 0x57, 0x35,
+    0x6a, 0x4d, 0x53, 0x30, 0x77, 0x4b, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x44, 0x45, 0x79, 0x52, 0x59, 0x55, 0x6d, 0x46, 0x74, 0x63, 0x43, 0x42,
+    0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x67, 0x51, 0x32, 0x56,
+    0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c,
+    0x76, 0x62, 0x69, 0x42, 0x42, 0x0a, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33,
+    0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41,
+    0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51,
+    0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77,
+    0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51,
+    0x43, 0x59, 0x4a, 0x42, 0x36, 0x39, 0x46, 0x62, 0x53, 0x36, 0x0a, 0x33,
+    0x38, 0x65, 0x4d, 0x70, 0x53, 0x65, 0x32, 0x4f, 0x41, 0x74, 0x70, 0x38,
+    0x37, 0x5a, 0x4f, 0x71, 0x43, 0x77, 0x75, 0x49, 0x52, 0x31, 0x63, 0x52,
+    0x4e, 0x38, 0x68, 0x58, 0x58, 0x34, 0x6a, 0x64, 0x50, 0x35, 0x65, 0x66,
+    0x72, 0x52, 0x4b, 0x74, 0x36, 0x61, 0x74, 0x48, 0x36, 0x37, 0x67, 0x42,
+    0x68, 0x62, 0x69, 0x6d, 0x31, 0x76, 0x5a, 0x5a, 0x33, 0x52, 0x72, 0x58,
+    0x59, 0x43, 0x50, 0x0a, 0x4b, 0x5a, 0x32, 0x47, 0x47, 0x39, 0x6d, 0x63,
+    0x44, 0x5a, 0x68, 0x74, 0x64, 0x68, 0x41, 0x6f, 0x57, 0x4f, 0x52, 0x6c,
+    0x73, 0x48, 0x39, 0x4b, 0x6d, 0x48, 0x6d, 0x66, 0x34, 0x4d, 0x4d, 0x78,
+    0x66, 0x6f, 0x41, 0x72, 0x74, 0x59, 0x7a, 0x41, 0x51, 0x44, 0x73, 0x52,
+    0x68, 0x74, 0x44, 0x4c, 0x6f, 0x6f, 0x59, 0x32, 0x59, 0x4b, 0x54, 0x56,
+    0x4d, 0x49, 0x4a, 0x74, 0x32, 0x57, 0x37, 0x51, 0x0a, 0x44, 0x78, 0x49,
+    0x45, 0x4d, 0x35, 0x64, 0x66, 0x54, 0x32, 0x46, 0x61, 0x38, 0x4f, 0x54,
+    0x35, 0x6b, 0x61, 0x76, 0x6e, 0x48, 0x54, 0x75, 0x38, 0x36, 0x4d, 0x2f,
+    0x30, 0x61, 0x79, 0x30, 0x30, 0x66, 0x4f, 0x4a, 0x49, 0x59, 0x52, 0x79,
+    0x4f, 0x38, 0x32, 0x46, 0x45, 0x7a, 0x47, 0x2b, 0x67, 0x53, 0x71, 0x6d,
+    0x55, 0x73, 0x45, 0x33, 0x61, 0x35, 0x36, 0x6b, 0x30, 0x65, 0x6e, 0x49,
+    0x34, 0x0a, 0x71, 0x45, 0x48, 0x4d, 0x50, 0x4a, 0x51, 0x52, 0x66, 0x65,
+    0x76, 0x49, 0x70, 0x6f, 0x79, 0x33, 0x68, 0x73, 0x76, 0x4b, 0x4d, 0x7a,
+    0x76, 0x5a, 0x50, 0x54, 0x65, 0x4c, 0x2b, 0x33, 0x6f, 0x2b, 0x68, 0x69,
+    0x7a, 0x6e, 0x63, 0x39, 0x63, 0x4b, 0x56, 0x36, 0x78, 0x6b, 0x6d, 0x78,
+    0x6e, 0x72, 0x39, 0x41, 0x38, 0x45, 0x43, 0x49, 0x71, 0x73, 0x41, 0x78,
+    0x63, 0x5a, 0x5a, 0x50, 0x52, 0x61, 0x0a, 0x4a, 0x53, 0x4b, 0x4e, 0x4e,
+    0x43, 0x79, 0x79, 0x39, 0x6d, 0x67, 0x64, 0x45, 0x6d, 0x33, 0x54, 0x69,
+    0x68, 0x34, 0x55, 0x32, 0x73, 0x53, 0x50, 0x70, 0x75, 0x49, 0x6a, 0x68,
+    0x64, 0x56, 0x36, 0x44, 0x62, 0x31, 0x71, 0x34, 0x4f, 0x6e, 0x73, 0x37,
+    0x42, 0x65, 0x37, 0x51, 0x68, 0x74, 0x6e, 0x71, 0x69, 0x58, 0x74, 0x52,
+    0x59, 0x4d, 0x68, 0x2f, 0x4d, 0x48, 0x4a, 0x66, 0x4e, 0x56, 0x69, 0x0a,
+    0x50, 0x76, 0x72, 0x79, 0x78, 0x53, 0x33, 0x54, 0x2f, 0x64, 0x52, 0x6c,
+    0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x67, 0x5a, 0x38, 0x77,
+    0x67, 0x5a, 0x77, 0x77, 0x45, 0x77, 0x59, 0x4a, 0x4b, 0x77, 0x59, 0x42,
+    0x42, 0x41, 0x47, 0x43, 0x4e, 0x78, 0x51, 0x43, 0x42, 0x41, 0x59, 0x65,
+    0x42, 0x41, 0x42, 0x44, 0x41, 0x45, 0x45, 0x77, 0x43, 0x77, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x50, 0x0a, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x47,
+    0x47, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45,
+    0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38,
+    0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59,
+    0x45, 0x46, 0x4d, 0x5a, 0x50, 0x6f, 0x6a, 0x30, 0x47, 0x59, 0x34, 0x51,
+    0x4a, 0x6e, 0x4d, 0x35, 0x69, 0x35, 0x41, 0x53, 0x73, 0x0a, 0x6a, 0x56,
+    0x79, 0x31, 0x36, 0x62, 0x59, 0x62, 0x4d, 0x44, 0x59, 0x47, 0x41, 0x31,
+    0x55, 0x64, 0x48, 0x77, 0x51, 0x76, 0x4d, 0x43, 0x30, 0x77, 0x4b, 0x36,
+    0x41, 0x70, 0x6f, 0x43, 0x65, 0x47, 0x4a, 0x57, 0x68, 0x30, 0x64, 0x48,
+    0x41, 0x36, 0x4c, 0x79, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x75, 0x65, 0x48,
+    0x4a, 0x68, 0x62, 0x58, 0x42, 0x7a, 0x5a, 0x57, 0x4e, 0x31, 0x63, 0x6d,
+    0x6c, 0x30, 0x0a, 0x65, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x30, 0x76, 0x57,
+    0x45, 0x64, 0x44, 0x51, 0x53, 0x35, 0x6a, 0x63, 0x6d, 0x77, 0x77, 0x45,
+    0x41, 0x59, 0x4a, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x41, 0x47, 0x43, 0x4e,
+    0x78, 0x55, 0x42, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x45, 0x77, 0x44,
+    0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41,
+    0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x0a, 0x67, 0x67, 0x45, 0x42,
+    0x41, 0x4a, 0x45, 0x56, 0x4f, 0x51, 0x4d, 0x42, 0x47, 0x32, 0x66, 0x37,
+    0x53, 0x68, 0x7a, 0x35, 0x43, 0x6d, 0x42, 0x62, 0x6f, 0x64, 0x70, 0x4e,
+    0x6c, 0x32, 0x4c, 0x35, 0x4a, 0x46, 0x4d, 0x6e, 0x31, 0x34, 0x4a, 0x6b,
+    0x54, 0x70, 0x41, 0x75, 0x77, 0x30, 0x6b, 0x62, 0x4b, 0x35, 0x72, 0x63,
+    0x2f, 0x4b, 0x68, 0x34, 0x5a, 0x7a, 0x58, 0x78, 0x48, 0x66, 0x41, 0x52,
+    0x0a, 0x76, 0x62, 0x64, 0x49, 0x34, 0x78, 0x44, 0x32, 0x44, 0x64, 0x38,
+    0x2f, 0x30, 0x73, 0x6d, 0x32, 0x71, 0x6c, 0x57, 0x6b, 0x53, 0x4c, 0x6f,
+    0x43, 0x32, 0x39, 0x35, 0x5a, 0x4c, 0x68, 0x56, 0x62, 0x4f, 0x35, 0x30,
+    0x57, 0x66, 0x55, 0x66, 0x58, 0x4e, 0x2b, 0x70, 0x66, 0x54, 0x58, 0x59,
+    0x53, 0x4e, 0x72, 0x73, 0x66, 0x31, 0x36, 0x47, 0x42, 0x42, 0x45, 0x59,
+    0x67, 0x6f, 0x79, 0x78, 0x74, 0x0a, 0x71, 0x5a, 0x34, 0x42, 0x66, 0x6a,
+    0x38, 0x70, 0x7a, 0x67, 0x43, 0x54, 0x33, 0x2f, 0x33, 0x4a, 0x6b, 0x6e,
+    0x4f, 0x4a, 0x69, 0x57, 0x53, 0x65, 0x35, 0x79, 0x76, 0x6b, 0x48, 0x4a,
+    0x45, 0x73, 0x30, 0x72, 0x6e, 0x4f, 0x66, 0x63, 0x35, 0x76, 0x4d, 0x5a,
+    0x6e, 0x54, 0x35, 0x72, 0x37, 0x53, 0x48, 0x70, 0x44, 0x77, 0x43, 0x52,
+    0x52, 0x35, 0x58, 0x43, 0x4f, 0x72, 0x54, 0x64, 0x4c, 0x61, 0x0a, 0x49,
+    0x52, 0x39, 0x4e, 0x6d, 0x58, 0x6d, 0x64, 0x34, 0x63, 0x38, 0x6e, 0x6e,
+    0x78, 0x43, 0x62, 0x48, 0x49, 0x67, 0x4e, 0x73, 0x49, 0x70, 0x6b, 0x51,
+    0x54, 0x47, 0x34, 0x44, 0x6d, 0x79, 0x51, 0x4a, 0x4b, 0x53, 0x62, 0x58,
+    0x48, 0x47, 0x50, 0x75, 0x72, 0x74, 0x2b, 0x48, 0x42, 0x76, 0x62, 0x61,
+    0x6f, 0x41, 0x50, 0x49, 0x62, 0x7a, 0x70, 0x32, 0x36, 0x61, 0x33, 0x51,
+    0x50, 0x53, 0x79, 0x0a, 0x69, 0x36, 0x6d, 0x78, 0x35, 0x4f, 0x2b, 0x61,
+    0x47, 0x74, 0x41, 0x39, 0x61, 0x5a, 0x6e, 0x75, 0x71, 0x43, 0x69, 0x6a,
+    0x34, 0x54, 0x79, 0x7a, 0x38, 0x4c, 0x49, 0x52, 0x6e, 0x4d, 0x39, 0x38,
+    0x51, 0x4f, 0x62, 0x64, 0x35, 0x30, 0x4e, 0x39, 0x6f, 0x74, 0x67, 0x36,
+    0x74, 0x61, 0x6d, 0x4e, 0x38, 0x6a, 0x53, 0x5a, 0x78, 0x4e, 0x51, 0x51,
+    0x34, 0x51, 0x62, 0x39, 0x43, 0x59, 0x51, 0x51, 0x0a, 0x4f, 0x2b, 0x37,
+    0x45, 0x54, 0x50, 0x54, 0x73, 0x4a, 0x33, 0x78, 0x43, 0x77, 0x6e, 0x52,
+    0x38, 0x67, 0x6f, 0x6f, 0x4a, 0x79, 0x62, 0x51, 0x44, 0x4a, 0x62, 0x77,
+    0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x4f, 0x3d, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20,
+    0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x47, 0x6f, 0x20,
+    0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+    0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,
+    0x20, 0x4f, 0x3d, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61,
+    0x64, 0x64, 0x79, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x47, 0x6f, 0x20, 0x44, 0x61,
+    0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x47, 0x6f,
+    0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73,
+    0x20, 0x32, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72,
+    0x69, 0x61, 0x6c, 0x3a, 0x20, 0x30, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x39, 0x31, 0x3a, 0x64, 0x65, 0x3a, 0x30, 0x36, 0x3a, 0x32,
+    0x35, 0x3a, 0x61, 0x62, 0x3a, 0x64, 0x61, 0x3a, 0x66, 0x64, 0x3a, 0x33,
+    0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x63, 0x3a, 0x62, 0x62, 0x3a, 0x32,
+    0x35, 0x3a, 0x31, 0x37, 0x3a, 0x32, 0x61, 0x3a, 0x38, 0x34, 0x3a, 0x36,
+    0x37, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x32, 0x37,
+    0x3a, 0x39, 0x36, 0x3a, 0x62, 0x61, 0x3a, 0x65, 0x36, 0x3a, 0x33, 0x66,
+    0x3a, 0x31, 0x38, 0x3a, 0x30, 0x31, 0x3a, 0x65, 0x32, 0x3a, 0x37, 0x37,
+    0x3a, 0x32, 0x36, 0x3a, 0x31, 0x62, 0x3a, 0x61, 0x30, 0x3a, 0x64, 0x37,
+    0x3a, 0x37, 0x37, 0x3a, 0x37, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x66,
+    0x3a, 0x32, 0x30, 0x3a, 0x65, 0x65, 0x3a, 0x65, 0x34, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x33, 0x3a, 0x38,
+    0x34, 0x3a, 0x36, 0x62, 0x3a, 0x66, 0x32, 0x3a, 0x34, 0x62, 0x3a, 0x39,
+    0x65, 0x3a, 0x39, 0x33, 0x3a, 0x63, 0x61, 0x3a, 0x36, 0x34, 0x3a, 0x32,
+    0x37, 0x3a, 0x34, 0x63, 0x3a, 0x30, 0x65, 0x3a, 0x63, 0x36, 0x3a, 0x37,
+    0x63, 0x3a, 0x31, 0x65, 0x3a, 0x63, 0x63, 0x3a, 0x35, 0x65, 0x3a, 0x30,
+    0x32, 0x3a, 0x34, 0x66, 0x3a, 0x66, 0x63, 0x3a, 0x61, 0x63, 0x3a, 0x64,
+    0x32, 0x3a, 0x64, 0x37, 0x3a, 0x34, 0x30, 0x3a, 0x31, 0x39, 0x3a, 0x33,
+    0x35, 0x3a, 0x30, 0x65, 0x3a, 0x38, 0x31, 0x3a, 0x66, 0x65, 0x3a, 0x35,
+    0x34, 0x3a, 0x36, 0x61, 0x3a, 0x65, 0x34, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x4d, 0x49, 0x49, 0x45, 0x41, 0x44, 0x43, 0x43, 0x41, 0x75, 0x69, 0x67,
+    0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4e,
+    0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
+    0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x6a, 0x4d, 0x51, 0x73, 0x77,
+    0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56,
+    0x55, 0x7a, 0x45, 0x68, 0x0a, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x59, 0x56, 0x47, 0x68, 0x6c, 0x49, 0x45, 0x64,
+    0x76, 0x49, 0x45, 0x52, 0x68, 0x5a, 0x47, 0x52, 0x35, 0x49, 0x45, 0x64,
+    0x79, 0x62, 0x33, 0x56, 0x77, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d,
+    0x75, 0x4d, 0x54, 0x45, 0x77, 0x4c, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4c, 0x45, 0x79, 0x68, 0x48, 0x62, 0x79, 0x42, 0x45, 0x0a, 0x59, 0x57,
+    0x52, 0x6b, 0x65, 0x53, 0x42, 0x44, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x79,
+    0x41, 0x79, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d,
+    0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58,
+    0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x42,
+    0x34, 0x58, 0x44, 0x54, 0x41, 0x30, 0x4d, 0x44, 0x59, 0x79, 0x4f, 0x54,
+    0x45, 0x33, 0x0a, 0x4d, 0x44, 0x59, 0x79, 0x4d, 0x46, 0x6f, 0x58, 0x44,
+    0x54, 0x4d, 0x30, 0x4d, 0x44, 0x59, 0x79, 0x4f, 0x54, 0x45, 0x33, 0x4d,
+    0x44, 0x59, 0x79, 0x4d, 0x46, 0x6f, 0x77, 0x59, 0x7a, 0x45, 0x4c, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x47, 0x46, 0x52, 0x6f, 0x0a, 0x5a, 0x53, 0x42, 0x48,
+    0x62, 0x79, 0x42, 0x45, 0x59, 0x57, 0x52, 0x6b, 0x65, 0x53, 0x42, 0x48,
+    0x63, 0x6d, 0x39, 0x31, 0x63, 0x43, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a,
+    0x4c, 0x6a, 0x45, 0x78, 0x4d, 0x43, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x78, 0x4d, 0x6f, 0x52, 0x32, 0x38, 0x67, 0x52, 0x47, 0x46, 0x6b,
+    0x5a, 0x48, 0x6b, 0x67, 0x51, 0x32, 0x78, 0x68, 0x63, 0x33, 0x4d, 0x67,
+    0x0a, 0x4d, 0x69, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a,
+    0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46,
+    0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x54, 0x43,
+    0x43, 0x41, 0x53, 0x41, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a,
+    0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41,
+    0x44, 0x67, 0x67, 0x45, 0x4e, 0x0a, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51,
+    0x67, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4e, 0x36, 0x64, 0x31, 0x2b,
+    0x70, 0x58, 0x47, 0x45, 0x6d, 0x68, 0x57, 0x2b, 0x76, 0x58, 0x58, 0x30,
+    0x69, 0x47, 0x36, 0x72, 0x37, 0x64, 0x2f, 0x2b, 0x54, 0x76, 0x5a, 0x78,
+    0x7a, 0x30, 0x5a, 0x57, 0x69, 0x7a, 0x56, 0x33, 0x47, 0x67, 0x58, 0x6e,
+    0x65, 0x37, 0x37, 0x5a, 0x74, 0x4a, 0x36, 0x58, 0x43, 0x41, 0x0a, 0x50,
+    0x56, 0x59, 0x59, 0x59, 0x77, 0x68, 0x76, 0x32, 0x76, 0x4c, 0x4d, 0x30,
+    0x44, 0x39, 0x2f, 0x41, 0x6c, 0x51, 0x69, 0x56, 0x42, 0x44, 0x59, 0x73,
+    0x6f, 0x48, 0x55, 0x77, 0x48, 0x55, 0x39, 0x53, 0x33, 0x2f, 0x48, 0x64,
+    0x38, 0x4d, 0x2b, 0x65, 0x4b, 0x73, 0x61, 0x41, 0x37, 0x55, 0x67, 0x61,
+    0x79, 0x39, 0x71, 0x4b, 0x37, 0x48, 0x46, 0x69, 0x48, 0x37, 0x45, 0x75,
+    0x78, 0x36, 0x77, 0x0a, 0x77, 0x64, 0x68, 0x46, 0x4a, 0x32, 0x2b, 0x71,
+    0x4e, 0x31, 0x6a, 0x33, 0x68, 0x79, 0x62, 0x58, 0x32, 0x43, 0x33, 0x32,
+    0x71, 0x52, 0x65, 0x33, 0x48, 0x33, 0x49, 0x32, 0x54, 0x71, 0x59, 0x58,
+    0x50, 0x32, 0x57, 0x59, 0x6b, 0x74, 0x73, 0x71, 0x62, 0x6c, 0x32, 0x69,
+    0x2f, 0x6f, 0x6a, 0x67, 0x43, 0x39, 0x35, 0x2f, 0x35, 0x59, 0x30, 0x56,
+    0x34, 0x65, 0x76, 0x4c, 0x4f, 0x74, 0x58, 0x69, 0x0a, 0x45, 0x71, 0x49,
+    0x54, 0x4c, 0x64, 0x69, 0x4f, 0x72, 0x31, 0x38, 0x53, 0x50, 0x61, 0x41,
+    0x49, 0x42, 0x51, 0x69, 0x32, 0x58, 0x4b, 0x56, 0x6c, 0x4f, 0x41, 0x52,
+    0x46, 0x6d, 0x52, 0x36, 0x6a, 0x59, 0x47, 0x42, 0x30, 0x78, 0x55, 0x47,
+    0x6c, 0x63, 0x6d, 0x49, 0x62, 0x59, 0x73, 0x55, 0x66, 0x62, 0x31, 0x38,
+    0x61, 0x51, 0x72, 0x34, 0x43, 0x55, 0x57, 0x57, 0x6f, 0x72, 0x69, 0x4d,
+    0x59, 0x0a, 0x61, 0x76, 0x78, 0x34, 0x41, 0x36, 0x6c, 0x4e, 0x66, 0x34,
+    0x44, 0x44, 0x2b, 0x71, 0x74, 0x61, 0x2f, 0x4b, 0x46, 0x41, 0x70, 0x4d,
+    0x6f, 0x5a, 0x46, 0x76, 0x36, 0x79, 0x79, 0x4f, 0x39, 0x65, 0x63, 0x77,
+    0x33, 0x75, 0x64, 0x37, 0x32, 0x61, 0x39, 0x6e, 0x6d, 0x59, 0x76, 0x4c,
+    0x45, 0x48, 0x5a, 0x36, 0x49, 0x56, 0x44, 0x64, 0x32, 0x67, 0x57, 0x4d,
+    0x5a, 0x45, 0x65, 0x77, 0x6f, 0x2b, 0x0a, 0x59, 0x69, 0x68, 0x66, 0x75,
+    0x6b, 0x45, 0x48, 0x55, 0x31, 0x6a, 0x50, 0x45, 0x58, 0x34, 0x34, 0x64,
+    0x4d, 0x58, 0x34, 0x2f, 0x37, 0x56, 0x70, 0x6b, 0x49, 0x2b, 0x45, 0x64,
+    0x4f, 0x71, 0x58, 0x47, 0x36, 0x38, 0x43, 0x41, 0x51, 0x4f, 0x6a, 0x67,
+    0x63, 0x41, 0x77, 0x67, 0x62, 0x30, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4e, 0x4c, 0x45, 0x0a,
+    0x73, 0x4e, 0x4b, 0x52, 0x31, 0x45, 0x77, 0x52, 0x63, 0x62, 0x4e, 0x68,
+    0x79, 0x7a, 0x32, 0x68, 0x2f, 0x74, 0x32, 0x6f, 0x61, 0x74, 0x54, 0x6a,
+    0x4d, 0x49, 0x47, 0x4e, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45,
+    0x67, 0x59, 0x55, 0x77, 0x67, 0x59, 0x4b, 0x41, 0x46, 0x4e, 0x4c, 0x45,
+    0x73, 0x4e, 0x4b, 0x52, 0x31, 0x45, 0x77, 0x52, 0x63, 0x62, 0x4e, 0x68,
+    0x79, 0x7a, 0x32, 0x68, 0x0a, 0x2f, 0x74, 0x32, 0x6f, 0x61, 0x74, 0x54,
+    0x6a, 0x6f, 0x57, 0x65, 0x6b, 0x5a, 0x54, 0x42, 0x6a, 0x4d, 0x51, 0x73,
+    0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a,
+    0x56, 0x55, 0x7a, 0x45, 0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x59, 0x56, 0x47, 0x68, 0x6c, 0x49, 0x45, 0x64,
+    0x76, 0x49, 0x45, 0x52, 0x68, 0x5a, 0x47, 0x52, 0x35, 0x0a, 0x49, 0x45,
+    0x64, 0x79, 0x62, 0x33, 0x56, 0x77, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d,
+    0x4d, 0x75, 0x4d, 0x54, 0x45, 0x77, 0x4c, 0x77, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x4c, 0x45, 0x79, 0x68, 0x48, 0x62, 0x79, 0x42, 0x45, 0x59, 0x57,
+    0x52, 0x6b, 0x65, 0x53, 0x42, 0x44, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x79,
+    0x41, 0x79, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d,
+    0x6c, 0x6a, 0x0a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51,
+    0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x67,
+    0x67, 0x45, 0x41, 0x4d, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45,
+    0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44,
+    0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41,
+    0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x0a, 0x67, 0x67, 0x45, 0x42,
+    0x41, 0x44, 0x4a, 0x4c, 0x38, 0x37, 0x4c, 0x4b, 0x50, 0x70, 0x48, 0x38,
+    0x45, 0x73, 0x61, 0x68, 0x42, 0x34, 0x79, 0x4f, 0x64, 0x36, 0x41, 0x7a,
+    0x42, 0x68, 0x52, 0x63, 0x6b, 0x42, 0x34, 0x59, 0x39, 0x77, 0x69, 0x6d,
+    0x50, 0x51, 0x6f, 0x5a, 0x2b, 0x59, 0x65, 0x41, 0x45, 0x57, 0x35, 0x70,
+    0x35, 0x4a, 0x59, 0x58, 0x4d, 0x50, 0x38, 0x30, 0x6b, 0x57, 0x4e, 0x79,
+    0x0a, 0x4f, 0x4f, 0x37, 0x4d, 0x48, 0x41, 0x47, 0x6a, 0x48, 0x5a, 0x51,
+    0x6f, 0x70, 0x44, 0x48, 0x32, 0x65, 0x73, 0x52, 0x55, 0x31, 0x2f, 0x62,
+    0x6c, 0x4d, 0x56, 0x67, 0x44, 0x6f, 0x73, 0x7a, 0x4f, 0x59, 0x74, 0x75,
+    0x55, 0x52, 0x58, 0x4f, 0x31, 0x76, 0x30, 0x58, 0x4a, 0x4a, 0x4c, 0x58,
+    0x56, 0x67, 0x67, 0x4b, 0x74, 0x49, 0x33, 0x6c, 0x70, 0x6a, 0x62, 0x69,
+    0x32, 0x54, 0x63, 0x37, 0x50, 0x0a, 0x54, 0x4d, 0x6f, 0x7a, 0x49, 0x2b,
+    0x67, 0x63, 0x69, 0x4b, 0x71, 0x64, 0x69, 0x30, 0x46, 0x75, 0x46, 0x73,
+    0x6b, 0x67, 0x35, 0x59, 0x6d, 0x65, 0x7a, 0x54, 0x76, 0x61, 0x63, 0x50,
+    0x64, 0x2b, 0x6d, 0x53, 0x59, 0x67, 0x46, 0x46, 0x51, 0x6c, 0x71, 0x32,
+    0x35, 0x7a, 0x68, 0x65, 0x61, 0x62, 0x49, 0x5a, 0x30, 0x4b, 0x62, 0x49,
+    0x49, 0x4f, 0x71, 0x50, 0x6a, 0x43, 0x44, 0x50, 0x6f, 0x51, 0x0a, 0x48,
+    0x6d, 0x79, 0x57, 0x37, 0x34, 0x63, 0x4e, 0x78, 0x41, 0x39, 0x68, 0x69,
+    0x36, 0x33, 0x75, 0x67, 0x79, 0x75, 0x56, 0x2b, 0x49, 0x36, 0x53, 0x68,
+    0x48, 0x49, 0x35, 0x36, 0x79, 0x44, 0x71, 0x67, 0x2b, 0x32, 0x44, 0x7a,
+    0x5a, 0x64, 0x75, 0x43, 0x4c, 0x7a, 0x72, 0x54, 0x69, 0x61, 0x32, 0x63,
+    0x79, 0x76, 0x6b, 0x30, 0x2f, 0x5a, 0x4d, 0x2f, 0x69, 0x5a, 0x78, 0x34,
+    0x6d, 0x45, 0x52, 0x0a, 0x64, 0x45, 0x72, 0x2f, 0x56, 0x78, 0x71, 0x48,
+    0x44, 0x33, 0x56, 0x49, 0x4c, 0x73, 0x39, 0x52, 0x61, 0x52, 0x65, 0x67,
+    0x41, 0x68, 0x4a, 0x68, 0x6c, 0x64, 0x58, 0x52, 0x51, 0x4c, 0x49, 0x51,
+    0x54, 0x4f, 0x37, 0x45, 0x72, 0x42, 0x42, 0x44, 0x70, 0x71, 0x57, 0x65,
+    0x43, 0x74, 0x57, 0x56, 0x59, 0x70, 0x6f, 0x4e, 0x7a, 0x34, 0x69, 0x43,
+    0x78, 0x54, 0x49, 0x4d, 0x35, 0x43, 0x75, 0x66, 0x0a, 0x52, 0x65, 0x59,
+    0x4e, 0x6e, 0x79, 0x69, 0x63, 0x73, 0x62, 0x6b, 0x71, 0x57, 0x6c, 0x65,
+    0x74, 0x4e, 0x77, 0x2b, 0x76, 0x48, 0x58, 0x2f, 0x62, 0x76, 0x5a, 0x38,
+    0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x4f, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65,
+    0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67,
+    0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55,
+    0x3d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x43,
+    0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62,
+    0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x4f, 0x3d, 0x53, 0x74, 0x61, 0x72,
+    0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f,
+    0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x20, 0x4f, 0x55, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c,
+    0x64, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20,
+    0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x53, 0x74, 0x61, 0x72,
+    0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x32, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69,
+    0x61, 0x6c, 0x3a, 0x20, 0x30, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x33, 0x32, 0x3a, 0x34, 0x61, 0x3a, 0x34, 0x62, 0x3a, 0x62, 0x62,
+    0x3a, 0x63, 0x38, 0x3a, 0x36, 0x33, 0x3a, 0x36, 0x39, 0x3a, 0x39, 0x62,
+    0x3a, 0x62, 0x65, 0x3a, 0x37, 0x34, 0x3a, 0x39, 0x61, 0x3a, 0x63, 0x36,
+    0x3a, 0x64, 0x64, 0x3a, 0x31, 0x64, 0x3a, 0x34, 0x36, 0x3a, 0x32, 0x34,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x64, 0x3a,
+    0x37, 0x65, 0x3a, 0x31, 0x63, 0x3a, 0x32, 0x38, 0x3a, 0x62, 0x30, 0x3a,
+    0x36, 0x34, 0x3a, 0x65, 0x66, 0x3a, 0x38, 0x66, 0x3a, 0x36, 0x30, 0x3a,
+    0x30, 0x33, 0x3a, 0x34, 0x30, 0x3a, 0x32, 0x30, 0x3a, 0x31, 0x34, 0x3a,
+    0x63, 0x33, 0x3a, 0x64, 0x30, 0x3a, 0x65, 0x33, 0x3a, 0x33, 0x37, 0x3a,
+    0x30, 0x65, 0x3a, 0x62, 0x35, 0x3a, 0x38, 0x61, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x31, 0x34, 0x3a, 0x36, 0x35,
+    0x3a, 0x66, 0x61, 0x3a, 0x32, 0x30, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x37,
+    0x3a, 0x62, 0x38, 0x3a, 0x37, 0x36, 0x3a, 0x66, 0x61, 0x3a, 0x61, 0x36,
+    0x3a, 0x66, 0x30, 0x3a, 0x61, 0x39, 0x3a, 0x39, 0x35, 0x3a, 0x38, 0x65,
+    0x3a, 0x35, 0x35, 0x3a, 0x39, 0x30, 0x3a, 0x65, 0x34, 0x3a, 0x30, 0x66,
+    0x3a, 0x63, 0x63, 0x3a, 0x37, 0x66, 0x3a, 0x61, 0x61, 0x3a, 0x34, 0x66,
+    0x3a, 0x62, 0x37, 0x3a, 0x63, 0x32, 0x3a, 0x63, 0x38, 0x3a, 0x36, 0x37,
+    0x3a, 0x37, 0x35, 0x3a, 0x32, 0x31, 0x3a, 0x66, 0x62, 0x3a, 0x35, 0x66,
+    0x3a, 0x62, 0x36, 0x3a, 0x35, 0x38, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
+    0x49, 0x49, 0x45, 0x44, 0x7a, 0x43, 0x43, 0x41, 0x76, 0x65, 0x67, 0x41,
+    0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x6f, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55,
+    0x7a, 0x45, 0x6c, 0x0a, 0x4d, 0x43, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x63, 0x55, 0x33, 0x52, 0x68, 0x63, 0x6d, 0x5a, 0x70,
+    0x5a, 0x57, 0x78, 0x6b, 0x49, 0x46, 0x52, 0x6c, 0x59, 0x32, 0x68, 0x75,
+    0x62, 0x32, 0x78, 0x76, 0x5a, 0x32, 0x6c, 0x6c, 0x63, 0x79, 0x77, 0x67,
+    0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x79, 0x4d, 0x44, 0x41, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x70, 0x0a, 0x55, 0x33, 0x52,
+    0x68, 0x63, 0x6d, 0x5a, 0x70, 0x5a, 0x57, 0x78, 0x6b, 0x49, 0x45, 0x4e,
+    0x73, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44, 0x49, 0x67, 0x51, 0x32, 0x56,
+    0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c,
+    0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a,
+    0x70, 0x64, 0x48, 0x6b, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x51,
+    0x77, 0x0a, 0x4e, 0x6a, 0x49, 0x35, 0x4d, 0x54, 0x63, 0x7a, 0x4f, 0x54,
+    0x45, 0x32, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x51, 0x77, 0x4e, 0x6a,
+    0x49, 0x35, 0x4d, 0x54, 0x63, 0x7a, 0x4f, 0x54, 0x45, 0x32, 0x57, 0x6a,
+    0x42, 0x6f, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x6c, 0x4d, 0x43,
+    0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x43, 0x68, 0x4d, 0x63, 0x55,
+    0x33, 0x52, 0x68, 0x63, 0x6d, 0x5a, 0x70, 0x5a, 0x57, 0x78, 0x6b, 0x49,
+    0x46, 0x52, 0x6c, 0x59, 0x32, 0x68, 0x75, 0x62, 0x32, 0x78, 0x76, 0x5a,
+    0x32, 0x6c, 0x6c, 0x63, 0x79, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c,
+    0x6a, 0x45, 0x79, 0x4d, 0x44, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x78, 0x4d, 0x70, 0x55, 0x33, 0x52, 0x68, 0x63, 0x6d, 0x5a, 0x70, 0x0a,
+    0x5a, 0x57, 0x78, 0x6b, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a,
+    0x49, 0x44, 0x49, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d,
+    0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42,
+    0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77,
+    0x67, 0x67, 0x45, 0x67, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47,
+    0x53, 0x49, 0x62, 0x33, 0x0a, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55,
+    0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x51, 0x41, 0x77, 0x67, 0x67, 0x45,
+    0x49, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x43, 0x33, 0x4d, 0x73, 0x6a,
+    0x2b, 0x36, 0x58, 0x47, 0x6d, 0x42, 0x49, 0x57, 0x74, 0x44, 0x42, 0x46,
+    0x6b, 0x33, 0x38, 0x35, 0x4e, 0x37, 0x38, 0x67, 0x44, 0x47, 0x49, 0x63,
+    0x2f, 0x6f, 0x61, 0x76, 0x37, 0x50, 0x4b, 0x61, 0x66, 0x0a, 0x38, 0x4d,
+    0x4f, 0x68, 0x32, 0x74, 0x54, 0x59, 0x62, 0x69, 0x74, 0x54, 0x6b, 0x50,
+    0x73, 0x6b, 0x70, 0x44, 0x36, 0x45, 0x38, 0x4a, 0x37, 0x6f, 0x58, 0x2b,
+    0x7a, 0x6c, 0x4a, 0x30, 0x54, 0x31, 0x4b, 0x4b, 0x59, 0x2f, 0x65, 0x39,
+    0x37, 0x67, 0x4b, 0x76, 0x44, 0x49, 0x72, 0x31, 0x4d, 0x76, 0x6e, 0x73,
+    0x6f, 0x46, 0x41, 0x5a, 0x4d, 0x65, 0x6a, 0x32, 0x59, 0x63, 0x4f, 0x61,
+    0x64, 0x4e, 0x0a, 0x2b, 0x6c, 0x71, 0x32, 0x63, 0x77, 0x51, 0x6c, 0x5a,
+    0x75, 0x74, 0x33, 0x66, 0x2b, 0x64, 0x5a, 0x78, 0x6b, 0x71, 0x5a, 0x4a,
+    0x52, 0x52, 0x55, 0x36, 0x79, 0x62, 0x48, 0x38, 0x33, 0x38, 0x5a, 0x31,
+    0x54, 0x42, 0x77, 0x6a, 0x36, 0x2b, 0x77, 0x52, 0x69, 0x72, 0x2f, 0x72,
+    0x65, 0x73, 0x70, 0x37, 0x64, 0x65, 0x66, 0x71, 0x67, 0x53, 0x48, 0x6f,
+    0x39, 0x54, 0x35, 0x69, 0x61, 0x55, 0x30, 0x0a, 0x58, 0x39, 0x74, 0x44,
+    0x6b, 0x59, 0x49, 0x32, 0x32, 0x57, 0x59, 0x38, 0x73, 0x62, 0x69, 0x35,
+    0x67, 0x76, 0x32, 0x63, 0x4f, 0x6a, 0x34, 0x51, 0x79, 0x44, 0x76, 0x76,
+    0x42, 0x6d, 0x56, 0x6d, 0x65, 0x70, 0x73, 0x5a, 0x47, 0x44, 0x33, 0x2f,
+    0x63, 0x56, 0x45, 0x38, 0x4d, 0x43, 0x35, 0x66, 0x76, 0x6a, 0x31, 0x33,
+    0x63, 0x37, 0x4a, 0x64, 0x42, 0x6d, 0x7a, 0x44, 0x49, 0x31, 0x61, 0x61,
+    0x0a, 0x4b, 0x34, 0x55, 0x6d, 0x6b, 0x68, 0x79, 0x6e, 0x41, 0x72, 0x50,
+    0x6b, 0x50, 0x77, 0x32, 0x76, 0x43, 0x48, 0x6d, 0x43, 0x75, 0x44, 0x59,
+    0x39, 0x36, 0x70, 0x7a, 0x54, 0x4e, 0x62, 0x4f, 0x38, 0x61, 0x63, 0x72,
+    0x31, 0x7a, 0x4a, 0x33, 0x6f, 0x2f, 0x57, 0x53, 0x4e, 0x46, 0x34, 0x41,
+    0x7a, 0x62, 0x6c, 0x35, 0x4b, 0x58, 0x5a, 0x6e, 0x4a, 0x48, 0x6f, 0x65,
+    0x30, 0x6e, 0x52, 0x72, 0x41, 0x0a, 0x31, 0x57, 0x34, 0x54, 0x4e, 0x53,
+    0x4e, 0x65, 0x33, 0x35, 0x74, 0x66, 0x50, 0x65, 0x2f, 0x57, 0x39, 0x33,
+    0x62, 0x43, 0x36, 0x6a, 0x36, 0x37, 0x65, 0x41, 0x30, 0x63, 0x51, 0x6d,
+    0x64, 0x72, 0x42, 0x4e, 0x6a, 0x34, 0x31, 0x74, 0x70, 0x76, 0x69, 0x2f,
+    0x4a, 0x45, 0x6f, 0x41, 0x47, 0x72, 0x41, 0x67, 0x45, 0x44, 0x6f, 0x34,
+    0x48, 0x46, 0x4d, 0x49, 0x48, 0x43, 0x4d, 0x42, 0x30, 0x47, 0x0a, 0x41,
+    0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x2f, 0x58,
+    0x37, 0x66, 0x52, 0x7a, 0x74, 0x30, 0x66, 0x68, 0x76, 0x52, 0x62, 0x56,
+    0x61, 0x7a, 0x63, 0x31, 0x78, 0x44, 0x43, 0x44, 0x71, 0x6d, 0x49, 0x35,
+    0x7a, 0x43, 0x42, 0x6b, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42,
+    0x49, 0x47, 0x4b, 0x4d, 0x49, 0x47, 0x48, 0x67, 0x42, 0x53, 0x2f, 0x58,
+    0x37, 0x66, 0x52, 0x0a, 0x7a, 0x74, 0x30, 0x66, 0x68, 0x76, 0x52, 0x62,
+    0x56, 0x61, 0x7a, 0x63, 0x31, 0x78, 0x44, 0x43, 0x44, 0x71, 0x6d, 0x49,
+    0x35, 0x36, 0x46, 0x73, 0x70, 0x47, 0x6f, 0x77, 0x61, 0x44, 0x45, 0x4c,
+    0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43,
+    0x56, 0x56, 0x4d, 0x78, 0x4a, 0x54, 0x41, 0x6a, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x6f, 0x54, 0x48, 0x46, 0x4e, 0x30, 0x0a, 0x59, 0x58, 0x4a,
+    0x6d, 0x61, 0x57, 0x56, 0x73, 0x5a, 0x43, 0x42, 0x55, 0x5a, 0x57, 0x4e,
+    0x6f, 0x62, 0x6d, 0x39, 0x73, 0x62, 0x32, 0x64, 0x70, 0x5a, 0x58, 0x4d,
+    0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78, 0x4d, 0x6a, 0x41,
+    0x77, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x4b, 0x56, 0x4e,
+    0x30, 0x59, 0x58, 0x4a, 0x6d, 0x61, 0x57, 0x56, 0x73, 0x5a, 0x43, 0x42,
+    0x44, 0x0a, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x79, 0x41, 0x79, 0x49, 0x45,
+    0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58,
+    0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47,
+    0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x67, 0x67, 0x45, 0x41, 0x4d, 0x41,
+    0x77, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x51, 0x46, 0x4d, 0x41,
+    0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x0a, 0x44, 0x51, 0x59, 0x4a, 0x4b,
+    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42,
+    0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x41, 0x57, 0x64, 0x50,
+    0x34, 0x69, 0x64, 0x30, 0x63, 0x6b, 0x61, 0x56, 0x61, 0x47, 0x73, 0x61,
+    0x66, 0x50, 0x7a, 0x57, 0x64, 0x71, 0x62, 0x41, 0x59, 0x63, 0x61, 0x54,
+    0x31, 0x65, 0x70, 0x6f, 0x58, 0x6b, 0x4a, 0x4b, 0x74, 0x76, 0x33, 0x0a,
+    0x4c, 0x37, 0x49, 0x65, 0x7a, 0x4d, 0x64, 0x65, 0x61, 0x74, 0x69, 0x44,
+    0x68, 0x36, 0x47, 0x58, 0x37, 0x30, 0x6b, 0x31, 0x50, 0x6e, 0x63, 0x47,
+    0x51, 0x56, 0x68, 0x69, 0x76, 0x34, 0x35, 0x59, 0x75, 0x41, 0x70, 0x6e,
+    0x50, 0x2b, 0x79, 0x7a, 0x33, 0x53, 0x46, 0x6d, 0x48, 0x38, 0x6c, 0x55,
+    0x2b, 0x6e, 0x4c, 0x4d, 0x50, 0x55, 0x78, 0x41, 0x32, 0x49, 0x47, 0x76,
+    0x64, 0x35, 0x36, 0x44, 0x0a, 0x65, 0x72, 0x75, 0x69, 0x78, 0x2f, 0x55,
+    0x30, 0x46, 0x34, 0x37, 0x5a, 0x45, 0x55, 0x44, 0x30, 0x2f, 0x43, 0x77,
+    0x71, 0x54, 0x52, 0x56, 0x2f, 0x70, 0x32, 0x4a, 0x64, 0x4c, 0x69, 0x58,
+    0x54, 0x41, 0x41, 0x73, 0x67, 0x47, 0x68, 0x31, 0x6f, 0x2b, 0x52, 0x65,
+    0x34, 0x39, 0x4c, 0x32, 0x4c, 0x37, 0x53, 0x68, 0x5a, 0x33, 0x55, 0x30,
+    0x57, 0x69, 0x78, 0x65, 0x44, 0x79, 0x4c, 0x4a, 0x6c, 0x0a, 0x78, 0x79,
+    0x31, 0x36, 0x70, 0x61, 0x71, 0x38, 0x55, 0x34, 0x5a, 0x74, 0x33, 0x56,
+    0x65, 0x6b, 0x79, 0x76, 0x67, 0x67, 0x51, 0x51, 0x74, 0x6f, 0x38, 0x50,
+    0x54, 0x37, 0x64, 0x4c, 0x35, 0x57, 0x58, 0x58, 0x70, 0x35, 0x39, 0x66,
+    0x6b, 0x64, 0x68, 0x65, 0x4d, 0x74, 0x6c, 0x62, 0x37, 0x31, 0x63, 0x5a,
+    0x42, 0x44, 0x7a, 0x49, 0x30, 0x66, 0x6d, 0x67, 0x41, 0x4b, 0x68, 0x79,
+    0x6e, 0x70, 0x0a, 0x56, 0x53, 0x4a, 0x59, 0x41, 0x43, 0x50, 0x71, 0x34,
+    0x78, 0x4a, 0x44, 0x4b, 0x56, 0x74, 0x48, 0x43, 0x4e, 0x32, 0x4d, 0x51,
+    0x57, 0x70, 0x6c, 0x42, 0x71, 0x6a, 0x6c, 0x49, 0x61, 0x70, 0x42, 0x74,
+    0x4a, 0x55, 0x68, 0x6c, 0x62, 0x6c, 0x39, 0x30, 0x54, 0x53, 0x72, 0x45,
+    0x39, 0x61, 0x74, 0x76, 0x4e, 0x7a, 0x69, 0x50, 0x54, 0x6e, 0x4e, 0x76,
+    0x54, 0x35, 0x31, 0x63, 0x4b, 0x45, 0x59, 0x0a, 0x57, 0x51, 0x50, 0x4a,
+    0x49, 0x72, 0x53, 0x50, 0x6e, 0x4e, 0x56, 0x65, 0x4b, 0x74, 0x65, 0x6c,
+    0x74, 0x74, 0x51, 0x4b, 0x62, 0x66, 0x69, 0x33, 0x51, 0x42, 0x46, 0x47,
+    0x6d, 0x68, 0x39, 0x35, 0x44, 0x6d, 0x4b, 0x2f, 0x44, 0x35, 0x66, 0x73,
+    0x34, 0x43, 0x38, 0x66, 0x46, 0x35, 0x51, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d,
+    0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64,
+    0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
+    0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e,
+    0x69, 0x6e, 0x67, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43,
+    0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x4f, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f,
+    0x6d, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x53, 0x65,
+    0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c,
+    0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+    0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x0a, 0x23, 0x20, 0x4c,
+    0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x53, 0x74, 0x61, 0x72, 0x74,
+    0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61,
+    0x6c, 0x3a, 0x20, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x32, 0x32, 0x3a, 0x34, 0x64, 0x3a, 0x38, 0x66, 0x3a, 0x38, 0x61, 0x3a,
+    0x66, 0x63, 0x3a, 0x66, 0x37, 0x3a, 0x33, 0x35, 0x3a, 0x63, 0x32, 0x3a,
+    0x62, 0x62, 0x3a, 0x35, 0x37, 0x3a, 0x33, 0x34, 0x3a, 0x39, 0x30, 0x3a,
+    0x37, 0x62, 0x3a, 0x38, 0x62, 0x3a, 0x32, 0x32, 0x3a, 0x31, 0x36, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x33, 0x65, 0x3a, 0x32,
+    0x62, 0x3a, 0x66, 0x37, 0x3a, 0x66, 0x32, 0x3a, 0x30, 0x33, 0x3a, 0x31,
+    0x62, 0x3a, 0x39, 0x36, 0x3a, 0x66, 0x33, 0x3a, 0x38, 0x63, 0x3a, 0x65,
+    0x36, 0x3a, 0x63, 0x34, 0x3a, 0x64, 0x38, 0x3a, 0x61, 0x38, 0x3a, 0x35,
+    0x64, 0x3a, 0x33, 0x65, 0x3a, 0x32, 0x64, 0x3a, 0x35, 0x38, 0x3a, 0x34,
+    0x37, 0x3a, 0x36, 0x61, 0x3a, 0x30, 0x66, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x37, 0x3a, 0x36, 0x36, 0x3a,
+    0x61, 0x39, 0x3a, 0x62, 0x65, 0x3a, 0x66, 0x32, 0x3a, 0x64, 0x34, 0x3a,
+    0x30, 0x37, 0x3a, 0x31, 0x63, 0x3a, 0x38, 0x36, 0x3a, 0x33, 0x61, 0x3a,
+    0x33, 0x31, 0x3a, 0x61, 0x61, 0x3a, 0x34, 0x39, 0x3a, 0x32, 0x30, 0x3a,
+    0x65, 0x38, 0x3a, 0x31, 0x33, 0x3a, 0x62, 0x32, 0x3a, 0x64, 0x31, 0x3a,
+    0x39, 0x38, 0x3a, 0x36, 0x30, 0x3a, 0x38, 0x63, 0x3a, 0x62, 0x37, 0x3a,
+    0x62, 0x37, 0x3a, 0x63, 0x66, 0x3a, 0x65, 0x32, 0x3a, 0x31, 0x31, 0x3a,
+    0x34, 0x33, 0x3a, 0x62, 0x38, 0x3a, 0x33, 0x36, 0x3a, 0x64, 0x66, 0x3a,
+    0x30, 0x39, 0x3a, 0x65, 0x61, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42,
+    0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49,
+    0x49, 0x48, 0x79, 0x54, 0x43, 0x43, 0x42, 0x62, 0x47, 0x67, 0x41, 0x77,
+    0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67,
+    0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51,
+    0x55, 0x46, 0x41, 0x44, 0x42, 0x39, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x4a, 0x54, 0x44,
+    0x45, 0x57, 0x0a, 0x4d, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x68, 0x4d, 0x4e, 0x55, 0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x44, 0x62,
+    0x32, 0x30, 0x67, 0x54, 0x48, 0x52, 0x6b, 0x4c, 0x6a, 0x45, 0x72, 0x4d,
+    0x43, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x69, 0x55,
+    0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, 0x6c, 0x49, 0x45, 0x52, 0x70, 0x5a,
+    0x32, 0x6c, 0x30, 0x59, 0x57, 0x77, 0x67, 0x0a, 0x51, 0x32, 0x56, 0x79,
+    0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x55, 0x67,
+    0x55, 0x32, 0x6c, 0x6e, 0x62, 0x6d, 0x6c, 0x75, 0x5a, 0x7a, 0x45, 0x70,
+    0x4d, 0x43, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x67,
+    0x55, 0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67,
+    0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68,
+    0x0a, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52,
+    0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x48, 0x68, 0x63,
+    0x4e, 0x4d, 0x44, 0x59, 0x77, 0x4f, 0x54, 0x45, 0x33, 0x4d, 0x54, 0x6b,
+    0x30, 0x4e, 0x6a, 0x4d, 0x32, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x59,
+    0x77, 0x4f, 0x54, 0x45, 0x33, 0x4d, 0x54, 0x6b, 0x30, 0x4e, 0x6a, 0x4d,
+    0x32, 0x57, 0x6a, 0x42, 0x39, 0x0a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x4a, 0x54, 0x44,
+    0x45, 0x57, 0x4d, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4e, 0x55, 0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32,
+    0x30, 0x67, 0x54, 0x48, 0x52, 0x6b, 0x4c, 0x6a, 0x45, 0x72, 0x4d, 0x43,
+    0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x69, 0x0a, 0x55,
+    0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, 0x6c, 0x49, 0x45, 0x52, 0x70, 0x5a,
+    0x32, 0x6c, 0x30, 0x59, 0x57, 0x77, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64,
+    0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x55, 0x67, 0x55,
+    0x32, 0x6c, 0x6e, 0x62, 0x6d, 0x6c, 0x75, 0x5a, 0x7a, 0x45, 0x70, 0x4d,
+    0x43, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x67, 0x55,
+    0x33, 0x52, 0x68, 0x0a, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67,
+    0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68,
+    0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f,
+    0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x67, 0x67, 0x49, 0x69,
+    0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x0a, 0x41, 0x34, 0x49,
+    0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4b, 0x41, 0x6f, 0x49,
+    0x43, 0x41, 0x51, 0x44, 0x42, 0x69, 0x4e, 0x73, 0x4a, 0x76, 0x47, 0x78,
+    0x47, 0x66, 0x48, 0x69, 0x66, 0x6c, 0x58, 0x75, 0x31, 0x4d, 0x35, 0x44,
+    0x79, 0x63, 0x6d, 0x4c, 0x57, 0x77, 0x54, 0x59, 0x67, 0x49, 0x69, 0x52,
+    0x65, 0x7a, 0x75, 0x6c, 0x33, 0x38, 0x6b, 0x4d, 0x4b, 0x6f, 0x67, 0x5a,
+    0x6b, 0x0a, 0x70, 0x4d, 0x79, 0x4f, 0x4e, 0x76, 0x67, 0x34, 0x35, 0x69,
+    0x50, 0x77, 0x62, 0x6d, 0x32, 0x78, 0x50, 0x4e, 0x31, 0x79, 0x6f, 0x34,
+    0x55, 0x63, 0x6f, 0x64, 0x4d, 0x39, 0x74, 0x44, 0x4d, 0x72, 0x30, 0x79,
+    0x2b, 0x76, 0x2f, 0x75, 0x71, 0x77, 0x51, 0x56, 0x6c, 0x6e, 0x74, 0x73,
+    0x51, 0x47, 0x66, 0x51, 0x71, 0x65, 0x64, 0x49, 0x58, 0x57, 0x65, 0x55,
+    0x79, 0x41, 0x4e, 0x33, 0x72, 0x66, 0x0a, 0x4f, 0x51, 0x56, 0x53, 0x57,
+    0x66, 0x66, 0x30, 0x47, 0x30, 0x5a, 0x44, 0x70, 0x4e, 0x4b, 0x46, 0x68,
+    0x64, 0x4c, 0x44, 0x63, 0x66, 0x4e, 0x31, 0x59, 0x6a, 0x53, 0x36, 0x4c,
+    0x49, 0x70, 0x2f, 0x48, 0x6f, 0x2f, 0x75, 0x37, 0x54, 0x54, 0x51, 0x45,
+    0x63, 0x65, 0x57, 0x7a, 0x56, 0x49, 0x39, 0x75, 0x6a, 0x50, 0x57, 0x33,
+    0x55, 0x33, 0x65, 0x43, 0x7a, 0x74, 0x4b, 0x53, 0x35, 0x2f, 0x43, 0x0a,
+    0x4a, 0x69, 0x2f, 0x36, 0x74, 0x52, 0x59, 0x63, 0x63, 0x6a, 0x56, 0x33,
+    0x79, 0x6a, 0x78, 0x64, 0x35, 0x73, 0x72, 0x68, 0x4a, 0x6f, 0x73, 0x61,
+    0x4e, 0x6e, 0x5a, 0x63, 0x41, 0x64, 0x74, 0x30, 0x46, 0x43, 0x58, 0x2b,
+    0x37, 0x62, 0x57, 0x67, 0x69, 0x41, 0x2f, 0x64, 0x65, 0x4d, 0x6f, 0x74,
+    0x48, 0x77, 0x65, 0x58, 0x4d, 0x41, 0x45, 0x74, 0x63, 0x6e, 0x6e, 0x36,
+    0x52, 0x74, 0x59, 0x54, 0x0a, 0x4b, 0x71, 0x69, 0x35, 0x70, 0x71, 0x75,
+    0x44, 0x53, 0x52, 0x33, 0x6c, 0x38, 0x75, 0x2f, 0x64, 0x35, 0x41, 0x47,
+    0x4f, 0x47, 0x41, 0x71, 0x50, 0x59, 0x31, 0x4d, 0x57, 0x68, 0x57, 0x4b,
+    0x70, 0x44, 0x68, 0x6b, 0x36, 0x7a, 0x4c, 0x56, 0x6d, 0x70, 0x73, 0x4a,
+    0x72, 0x64, 0x41, 0x66, 0x6b, 0x4b, 0x2b, 0x46, 0x32, 0x50, 0x72, 0x52,
+    0x74, 0x32, 0x50, 0x5a, 0x45, 0x34, 0x58, 0x4e, 0x69, 0x0a, 0x48, 0x7a,
+    0x76, 0x45, 0x76, 0x71, 0x42, 0x54, 0x56, 0x69, 0x56, 0x73, 0x55, 0x51,
+    0x6e, 0x33, 0x71, 0x71, 0x76, 0x4b, 0x76, 0x33, 0x62, 0x39, 0x62, 0x5a,
+    0x76, 0x7a, 0x6e, 0x64, 0x75, 0x2f, 0x50, 0x57, 0x61, 0x38, 0x44, 0x46,
+    0x61, 0x71, 0x72, 0x35, 0x68, 0x49, 0x6c, 0x54, 0x70, 0x4c, 0x33, 0x36,
+    0x64, 0x59, 0x55, 0x4e, 0x6b, 0x34, 0x64, 0x61, 0x6c, 0x62, 0x36, 0x6b,
+    0x4d, 0x4d, 0x0a, 0x41, 0x76, 0x2b, 0x5a, 0x36, 0x2b, 0x68, 0x73, 0x54,
+    0x58, 0x42, 0x62, 0x4b, 0x57, 0x57, 0x63, 0x33, 0x61, 0x70, 0x64, 0x7a,
+    0x4b, 0x38, 0x42, 0x4d, 0x65, 0x77, 0x4d, 0x36, 0x39, 0x4b, 0x4e, 0x36,
+    0x4f, 0x71, 0x63, 0x65, 0x2b, 0x5a, 0x75, 0x39, 0x79, 0x64, 0x6d, 0x44,
+    0x42, 0x70, 0x49, 0x31, 0x32, 0x35, 0x43, 0x34, 0x7a, 0x2f, 0x65, 0x49,
+    0x54, 0x35, 0x37, 0x34, 0x51, 0x31, 0x77, 0x0a, 0x2b, 0x32, 0x4f, 0x71,
+    0x71, 0x47, 0x77, 0x61, 0x56, 0x4c, 0x52, 0x63, 0x4a, 0x58, 0x72, 0x4a,
+    0x6f, 0x73, 0x6d, 0x4c, 0x46, 0x71, 0x61, 0x37, 0x4c, 0x48, 0x34, 0x58,
+    0x58, 0x67, 0x56, 0x4e, 0x57, 0x47, 0x34, 0x53, 0x48, 0x51, 0x48, 0x75,
+    0x45, 0x68, 0x41, 0x4e, 0x78, 0x6a, 0x4a, 0x2f, 0x47, 0x50, 0x2f, 0x38,
+    0x39, 0x50, 0x72, 0x4e, 0x62, 0x70, 0x48, 0x6f, 0x4e, 0x6b, 0x6d, 0x2b,
+    0x0a, 0x47, 0x6b, 0x68, 0x70, 0x69, 0x38, 0x4b, 0x57, 0x54, 0x52, 0x6f,
+    0x53, 0x73, 0x6d, 0x6b, 0x58, 0x77, 0x51, 0x71, 0x51, 0x31, 0x76, 0x70,
+    0x35, 0x49, 0x6b, 0x69, 0x2f, 0x75, 0x6e, 0x74, 0x70, 0x2b, 0x48, 0x44,
+    0x48, 0x2b, 0x6e, 0x6f, 0x33, 0x32, 0x4e, 0x67, 0x4e, 0x30, 0x6e, 0x5a,
+    0x50, 0x56, 0x2f, 0x2b, 0x51, 0x74, 0x2b, 0x4f, 0x52, 0x30, 0x74, 0x33,
+    0x76, 0x77, 0x6d, 0x43, 0x33, 0x0a, 0x5a, 0x7a, 0x72, 0x64, 0x2f, 0x71,
+    0x71, 0x63, 0x38, 0x4e, 0x53, 0x4c, 0x66, 0x33, 0x49, 0x69, 0x7a, 0x73,
+    0x61, 0x66, 0x6c, 0x37, 0x62, 0x34, 0x72, 0x34, 0x71, 0x67, 0x45, 0x4b,
+    0x6a, 0x5a, 0x2b, 0x78, 0x6a, 0x47, 0x74, 0x72, 0x56, 0x63, 0x55, 0x6a,
+    0x79, 0x4a, 0x74, 0x68, 0x6b, 0x71, 0x63, 0x77, 0x45, 0x4b, 0x44, 0x77,
+    0x4f, 0x7a, 0x45, 0x6d, 0x44, 0x79, 0x65, 0x69, 0x2b, 0x42, 0x0a, 0x32,
+    0x36, 0x4e, 0x75, 0x2f, 0x79, 0x59, 0x77, 0x6c, 0x2f, 0x57, 0x4c, 0x33,
+    0x59, 0x6c, 0x58, 0x74, 0x71, 0x30, 0x39, 0x73, 0x36, 0x38, 0x72, 0x78,
+    0x62, 0x64, 0x32, 0x41, 0x76, 0x43, 0x6c, 0x31, 0x69, 0x75, 0x61, 0x68,
+    0x68, 0x51, 0x71, 0x63, 0x76, 0x62, 0x6a, 0x4d, 0x34, 0x78, 0x64, 0x43,
+    0x55, 0x73, 0x54, 0x33, 0x37, 0x75, 0x4d, 0x64, 0x42, 0x4e, 0x53, 0x53,
+    0x77, 0x49, 0x44, 0x0a, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x34, 0x49, 0x43,
+    0x55, 0x6a, 0x43, 0x43, 0x41, 0x6b, 0x34, 0x77, 0x44, 0x41, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x54, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42,
+    0x2f, 0x7a, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x45,
+    0x42, 0x41, 0x4d, 0x43, 0x41, 0x61, 0x34, 0x77, 0x48, 0x51, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x0a, 0x46, 0x45, 0x34,
+    0x4c, 0x37, 0x78, 0x71, 0x6b, 0x51, 0x46, 0x75, 0x6c, 0x46, 0x32, 0x6d,
+    0x48, 0x4d, 0x4d, 0x6f, 0x30, 0x61, 0x45, 0x50, 0x51, 0x51, 0x61, 0x37,
+    0x79, 0x4d, 0x47, 0x51, 0x47, 0x41, 0x31, 0x55, 0x64, 0x48, 0x77, 0x52,
+    0x64, 0x4d, 0x46, 0x73, 0x77, 0x4c, 0x4b, 0x41, 0x71, 0x6f, 0x43, 0x69,
+    0x47, 0x4a, 0x6d, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4c, 0x79, 0x39,
+    0x6a, 0x0a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6e, 0x4e, 0x30, 0x59, 0x58,
+    0x4a, 0x30, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x6d, 0x39, 0x79, 0x5a, 0x79,
+    0x39, 0x7a, 0x5a, 0x6e, 0x4e, 0x6a, 0x59, 0x53, 0x31, 0x6a, 0x63, 0x6d,
+    0x77, 0x75, 0x59, 0x33, 0x4a, 0x73, 0x4d, 0x43, 0x75, 0x67, 0x4b, 0x61,
+    0x41, 0x6e, 0x68, 0x69, 0x56, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69,
+    0x38, 0x76, 0x59, 0x33, 0x4a, 0x73, 0x0a, 0x4c, 0x6e, 0x4e, 0x30, 0x59,
+    0x58, 0x4a, 0x30, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x6d, 0x39, 0x79, 0x5a,
+    0x79, 0x39, 0x7a, 0x5a, 0x6e, 0x4e, 0x6a, 0x59, 0x53, 0x31, 0x6a, 0x63,
+    0x6d, 0x77, 0x75, 0x59, 0x33, 0x4a, 0x73, 0x4d, 0x49, 0x49, 0x42, 0x58,
+    0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x67, 0x42, 0x49, 0x49, 0x42, 0x56,
+    0x44, 0x43, 0x43, 0x41, 0x56, 0x41, 0x77, 0x67, 0x67, 0x46, 0x4d, 0x0a,
+    0x42, 0x67, 0x73, 0x72, 0x42, 0x67, 0x45, 0x45, 0x41, 0x59, 0x47, 0x31,
+    0x4e, 0x77, 0x45, 0x42, 0x41, 0x54, 0x43, 0x43, 0x41, 0x54, 0x73, 0x77,
+    0x4c, 0x77, 0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48,
+    0x41, 0x67, 0x45, 0x57, 0x49, 0x32, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36,
+    0x4c, 0x79, 0x39, 0x6a, 0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6e, 0x4e, 0x30,
+    0x59, 0x58, 0x4a, 0x30, 0x0a, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x6d, 0x39,
+    0x79, 0x5a, 0x79, 0x39, 0x77, 0x62, 0x32, 0x78, 0x70, 0x59, 0x33, 0x6b,
+    0x75, 0x63, 0x47, 0x52, 0x6d, 0x4d, 0x44, 0x55, 0x47, 0x43, 0x43, 0x73,
+    0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x49, 0x42, 0x46, 0x69, 0x6c,
+    0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x59, 0x32, 0x56,
+    0x79, 0x64, 0x43, 0x35, 0x7a, 0x64, 0x47, 0x46, 0x79, 0x0a, 0x64, 0x47,
+    0x4e, 0x76, 0x62, 0x53, 0x35, 0x76, 0x63, 0x6d, 0x63, 0x76, 0x61, 0x57,
+    0x35, 0x30, 0x5a, 0x58, 0x4a, 0x74, 0x5a, 0x57, 0x52, 0x70, 0x59, 0x58,
+    0x52, 0x6c, 0x4c, 0x6e, 0x42, 0x6b, 0x5a, 0x6a, 0x43, 0x42, 0x30, 0x41,
+    0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48, 0x41, 0x67,
+    0x49, 0x77, 0x67, 0x63, 0x4d, 0x77, 0x4a, 0x78, 0x59, 0x67, 0x55, 0x33,
+    0x52, 0x68, 0x0a, 0x63, 0x6e, 0x51, 0x67, 0x51, 0x32, 0x39, 0x74, 0x62,
+    0x57, 0x56, 0x79, 0x59, 0x32, 0x6c, 0x68, 0x62, 0x43, 0x41, 0x6f, 0x55,
+    0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x70, 0x49,
+    0x45, 0x78, 0x30, 0x5a, 0x43, 0x34, 0x77, 0x41, 0x77, 0x49, 0x42, 0x41,
+    0x52, 0x71, 0x42, 0x6c, 0x30, 0x78, 0x70, 0x62, 0x57, 0x6c, 0x30, 0x5a,
+    0x57, 0x51, 0x67, 0x54, 0x47, 0x6c, 0x68, 0x0a, 0x59, 0x6d, 0x6c, 0x73,
+    0x61, 0x58, 0x52, 0x35, 0x4c, 0x43, 0x42, 0x79, 0x5a, 0x57, 0x46, 0x6b,
+    0x49, 0x48, 0x52, 0x6f, 0x5a, 0x53, 0x42, 0x7a, 0x5a, 0x57, 0x4e, 0x30,
+    0x61, 0x57, 0x39, 0x75, 0x49, 0x43, 0x70, 0x4d, 0x5a, 0x57, 0x64, 0x68,
+    0x62, 0x43, 0x42, 0x4d, 0x61, 0x57, 0x31, 0x70, 0x64, 0x47, 0x46, 0x30,
+    0x61, 0x57, 0x39, 0x75, 0x63, 0x79, 0x6f, 0x67, 0x62, 0x32, 0x59, 0x67,
+    0x0a, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x46, 0x4e, 0x30, 0x59, 0x58, 0x4a,
+    0x30, 0x51, 0x32, 0x39, 0x74, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52,
+    0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34,
+    0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52,
+    0x35, 0x49, 0x46, 0x42, 0x76, 0x62, 0x47, 0x6c, 0x6a, 0x65, 0x53, 0x42,
+    0x68, 0x64, 0x6d, 0x46, 0x70, 0x0a, 0x62, 0x47, 0x46, 0x69, 0x62, 0x47,
+    0x55, 0x67, 0x59, 0x58, 0x51, 0x67, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44,
+    0x6f, 0x76, 0x4c, 0x32, 0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x75, 0x63, 0x33,
+    0x52, 0x68, 0x63, 0x6e, 0x52, 0x6a, 0x62, 0x32, 0x30, 0x75, 0x62, 0x33,
+    0x4a, 0x6e, 0x4c, 0x33, 0x42, 0x76, 0x62, 0x47, 0x6c, 0x6a, 0x65, 0x53,
+    0x35, 0x77, 0x5a, 0x47, 0x59, 0x77, 0x45, 0x51, 0x59, 0x4a, 0x0a, 0x59,
+    0x49, 0x5a, 0x49, 0x41, 0x59, 0x62, 0x34, 0x51, 0x67, 0x45, 0x42, 0x42,
+    0x41, 0x51, 0x44, 0x41, 0x67, 0x41, 0x48, 0x4d, 0x44, 0x67, 0x47, 0x43,
+    0x57, 0x43, 0x47, 0x53, 0x41, 0x47, 0x47, 0x2b, 0x45, 0x49, 0x42, 0x44,
+    0x51, 0x51, 0x72, 0x46, 0x69, 0x6c, 0x54, 0x64, 0x47, 0x46, 0x79, 0x64,
+    0x45, 0x4e, 0x76, 0x62, 0x53, 0x42, 0x47, 0x63, 0x6d, 0x56, 0x6c, 0x49,
+    0x46, 0x4e, 0x54, 0x0a, 0x54, 0x43, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30,
+    0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75,
+    0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30,
+    0x65, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43,
+    0x41, 0x67, 0x45, 0x41, 0x46, 0x6d, 0x79, 0x5a, 0x0a, 0x39, 0x47, 0x59,
+    0x4d, 0x4e, 0x50, 0x58, 0x51, 0x68, 0x56, 0x35, 0x39, 0x43, 0x75, 0x7a,
+    0x61, 0x45, 0x45, 0x34, 0x34, 0x48, 0x46, 0x37, 0x66, 0x70, 0x69, 0x55,
+    0x46, 0x53, 0x35, 0x45, 0x79, 0x77, 0x65, 0x67, 0x37, 0x38, 0x54, 0x33,
+    0x64, 0x52, 0x41, 0x6c, 0x62, 0x42, 0x30, 0x6d, 0x4b, 0x4b, 0x63, 0x74,
+    0x6d, 0x41, 0x72, 0x65, 0x78, 0x6d, 0x76, 0x63, 0x6c, 0x6d, 0x41, 0x6b,
+    0x38, 0x0a, 0x6a, 0x68, 0x76, 0x68, 0x33, 0x54, 0x61, 0x48, 0x4b, 0x30,
+    0x75, 0x37, 0x61, 0x4e, 0x4d, 0x35, 0x5a, 0x6a, 0x32, 0x67, 0x4a, 0x73,
+    0x66, 0x79, 0x4f, 0x5a, 0x45, 0x64, 0x55, 0x61, 0x75, 0x43, 0x65, 0x33,
+    0x37, 0x56, 0x7a, 0x6c, 0x72, 0x6b, 0x34, 0x67, 0x4e, 0x58, 0x63, 0x47,
+    0x6d, 0x58, 0x43, 0x50, 0x6c, 0x65, 0x57, 0x4b, 0x59, 0x4b, 0x33, 0x34,
+    0x77, 0x47, 0x6d, 0x6b, 0x55, 0x57, 0x0a, 0x46, 0x6a, 0x67, 0x4b, 0x58,
+    0x6c, 0x66, 0x32, 0x59, 0x73, 0x64, 0x36, 0x41, 0x67, 0x58, 0x6d, 0x76,
+    0x42, 0x36, 0x31, 0x38, 0x70, 0x37, 0x30, 0x71, 0x53, 0x6d, 0x44, 0x2b,
+    0x4c, 0x49, 0x55, 0x34, 0x32, 0x34, 0x6f, 0x68, 0x30, 0x54, 0x44, 0x6b,
+    0x42, 0x72, 0x65, 0x4f, 0x4b, 0x6b, 0x38, 0x72, 0x45, 0x4e, 0x4e, 0x5a,
+    0x45, 0x58, 0x4f, 0x33, 0x53, 0x69, 0x70, 0x58, 0x50, 0x4a, 0x7a, 0x0a,
+    0x65, 0x77, 0x54, 0x34, 0x46, 0x2b, 0x69, 0x72, 0x73, 0x66, 0x4d, 0x75,
+    0x58, 0x47, 0x52, 0x75, 0x63, 0x7a, 0x45, 0x36, 0x45, 0x72, 0x69, 0x38,
+    0x73, 0x78, 0x48, 0x6b, 0x66, 0x59, 0x2b, 0x42, 0x55, 0x5a, 0x6f, 0x37,
+    0x6a, 0x59, 0x6e, 0x30, 0x54, 0x5a, 0x4e, 0x6d, 0x65, 0x7a, 0x77, 0x44,
+    0x37, 0x64, 0x4f, 0x61, 0x48, 0x5a, 0x72, 0x7a, 0x5a, 0x56, 0x44, 0x31,
+    0x6f, 0x4e, 0x42, 0x31, 0x0a, 0x6e, 0x79, 0x2b, 0x76, 0x38, 0x4f, 0x71,
+    0x43, 0x51, 0x35, 0x6a, 0x34, 0x61, 0x5a, 0x79, 0x4a, 0x65, 0x63, 0x52,
+    0x44, 0x6a, 0x6b, 0x5a, 0x79, 0x34, 0x32, 0x51, 0x32, 0x45, 0x71, 0x2f,
+    0x33, 0x4a, 0x52, 0x34, 0x34, 0x69, 0x5a, 0x42, 0x33, 0x66, 0x73, 0x4e,
+    0x72, 0x61, 0x72, 0x6e, 0x44, 0x79, 0x30, 0x52, 0x4c, 0x72, 0x48, 0x69,
+    0x51, 0x69, 0x2b, 0x66, 0x48, 0x4c, 0x42, 0x35, 0x4c, 0x0a, 0x45, 0x55,
+    0x54, 0x49, 0x4e, 0x46, 0x49, 0x6e, 0x7a, 0x51, 0x70, 0x64, 0x6e, 0x34,
+    0x58, 0x42, 0x69, 0x64, 0x55, 0x61, 0x65, 0x50, 0x4b, 0x56, 0x45, 0x46,
+    0x4d, 0x79, 0x33, 0x59, 0x43, 0x45, 0x5a, 0x6e, 0x58, 0x5a, 0x74, 0x57,
+    0x67, 0x6f, 0x2b, 0x32, 0x45, 0x75, 0x76, 0x6f, 0x53, 0x6f, 0x4f, 0x4d,
+    0x43, 0x5a, 0x45, 0x6f, 0x61, 0x6c, 0x48, 0x6d, 0x64, 0x6b, 0x72, 0x51,
+    0x59, 0x75, 0x0a, 0x4c, 0x36, 0x6c, 0x77, 0x68, 0x63, 0x65, 0x57, 0x44,
+    0x33, 0x79, 0x4a, 0x5a, 0x66, 0x57, 0x4f, 0x51, 0x31, 0x51, 0x4f, 0x71,
+    0x39, 0x32, 0x6c, 0x67, 0x44, 0x6d, 0x55, 0x59, 0x4d, 0x41, 0x30, 0x79,
+    0x5a, 0x5a, 0x77, 0x4c, 0x4b, 0x4d, 0x53, 0x39, 0x52, 0x39, 0x49, 0x65,
+    0x37, 0x30, 0x63, 0x66, 0x6d, 0x75, 0x33, 0x6e, 0x5a, 0x44, 0x30, 0x49,
+    0x6a, 0x75, 0x75, 0x2b, 0x50, 0x77, 0x71, 0x0a, 0x79, 0x76, 0x71, 0x43,
+    0x55, 0x71, 0x44, 0x76, 0x72, 0x30, 0x74, 0x56, 0x6b, 0x2b, 0x76, 0x42,
+    0x74, 0x66, 0x41, 0x69, 0x69, 0x36, 0x77, 0x30, 0x54, 0x69, 0x59, 0x69,
+    0x42, 0x4b, 0x47, 0x48, 0x4c, 0x48, 0x56, 0x4b, 0x74, 0x2b, 0x56, 0x39,
+    0x45, 0x39, 0x65, 0x34, 0x44, 0x47, 0x54, 0x41, 0x4e, 0x74, 0x4c, 0x4a,
+    0x4c, 0x34, 0x59, 0x53, 0x6a, 0x43, 0x4d, 0x4a, 0x77, 0x52, 0x75, 0x43,
+    0x0a, 0x4f, 0x33, 0x4e, 0x4a, 0x6f, 0x32, 0x70, 0x58, 0x68, 0x35, 0x54,
+    0x6c, 0x31, 0x6e, 0x6a, 0x46, 0x6d, 0x55, 0x4e, 0x6a, 0x34, 0x30, 0x33,
+    0x67, 0x64, 0x79, 0x33, 0x68, 0x5a, 0x5a, 0x6c, 0x79, 0x61, 0x51, 0x51,
+    0x61, 0x52, 0x77, 0x6e, 0x6d, 0x44, 0x77, 0x46, 0x57, 0x4a, 0x50, 0x73,
+    0x66, 0x76, 0x77, 0x35, 0x35, 0x71, 0x56, 0x67, 0x75, 0x75, 0x63, 0x51,
+    0x4a, 0x41, 0x58, 0x36, 0x56, 0x0a, 0x75, 0x6d, 0x30, 0x41, 0x42, 0x6a,
+    0x36, 0x79, 0x36, 0x6b, 0x6f, 0x51, 0x4f, 0x64, 0x6a, 0x51, 0x4b, 0x2f,
+    0x57, 0x2f, 0x37, 0x48, 0x57, 0x2f, 0x6c, 0x77, 0x4c, 0x46, 0x43, 0x52,
+    0x73, 0x49, 0x33, 0x46, 0x55, 0x33, 0x34, 0x6f, 0x48, 0x37, 0x4e, 0x34,
+    0x52, 0x44, 0x59, 0x69, 0x44, 0x4b, 0x35, 0x31, 0x5a, 0x4c, 0x5a, 0x65,
+    0x72, 0x2b, 0x62, 0x4d, 0x45, 0x6b, 0x6b, 0x79, 0x53, 0x68, 0x0a, 0x4e,
+    0x4f, 0x73, 0x46, 0x2f, 0x35, 0x6f, 0x69, 0x72, 0x70, 0x74, 0x39, 0x50,
+    0x2f, 0x46, 0x6c, 0x55, 0x51, 0x71, 0x6d, 0x4d, 0x47, 0x71, 0x7a, 0x39,
+    0x49, 0x67, 0x63, 0x67, 0x41, 0x33, 0x38, 0x63, 0x6f, 0x72, 0x6f, 0x67,
+    0x31, 0x34, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73,
+    0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x44, 0x69, 0x67, 0x69,
+    0x43, 0x65, 0x72, 0x74, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64,
+    0x20, 0x49, 0x44, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20,
+    0x4f, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49,
+    0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69,
+    0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x41, 0x73,
+    0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, 0x52, 0x6f, 0x6f,
+    0x74, 0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43,
+    0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x77,
+    0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+    0x63, 0x6f, 0x6d, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x41,
+    0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, 0x52, 0x6f,
+    0x6f, 0x74, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72,
+    0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x37, 0x31, 0x35, 0x34, 0x37, 0x31,
+    0x37, 0x39, 0x33, 0x34, 0x31, 0x32, 0x30, 0x35, 0x38, 0x37, 0x38, 0x36,
+    0x32, 0x31, 0x36, 0x37, 0x37, 0x39, 0x34, 0x39, 0x31, 0x34, 0x30, 0x37,
+    0x31, 0x34, 0x32, 0x35, 0x30, 0x38, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44,
+    0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x38, 0x37, 0x3a, 0x63, 0x65, 0x3a, 0x30, 0x62, 0x3a,
+    0x37, 0x62, 0x3a, 0x32, 0x61, 0x3a, 0x30, 0x65, 0x3a, 0x34, 0x39, 0x3a,
+    0x30, 0x30, 0x3a, 0x65, 0x31, 0x3a, 0x35, 0x38, 0x3a, 0x37, 0x31, 0x3a,
+    0x39, 0x62, 0x3a, 0x33, 0x37, 0x3a, 0x61, 0x38, 0x3a, 0x39, 0x33, 0x3a,
+    0x37, 0x32, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30,
+    0x35, 0x3a, 0x36, 0x33, 0x3a, 0x62, 0x38, 0x3a, 0x36, 0x33, 0x3a, 0x30,
+    0x64, 0x3a, 0x36, 0x32, 0x3a, 0x64, 0x37, 0x3a, 0x35, 0x61, 0x3a, 0x62,
+    0x62, 0x3a, 0x63, 0x38, 0x3a, 0x61, 0x62, 0x3a, 0x31, 0x65, 0x3a, 0x34,
+    0x62, 0x3a, 0x64, 0x66, 0x3a, 0x62, 0x35, 0x3a, 0x61, 0x38, 0x3a, 0x39,
+    0x39, 0x3a, 0x62, 0x32, 0x3a, 0x34, 0x64, 0x3a, 0x34, 0x33, 0x0a, 0x23,
+    0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x33, 0x65, 0x3a,
+    0x39, 0x30, 0x3a, 0x39, 0x39, 0x3a, 0x62, 0x35, 0x3a, 0x30, 0x31, 0x3a,
+    0x35, 0x65, 0x3a, 0x38, 0x66, 0x3a, 0x34, 0x38, 0x3a, 0x36, 0x63, 0x3a,
+    0x30, 0x30, 0x3a, 0x62, 0x63, 0x3a, 0x65, 0x61, 0x3a, 0x39, 0x64, 0x3a,
+    0x31, 0x31, 0x3a, 0x31, 0x65, 0x3a, 0x65, 0x37, 0x3a, 0x32, 0x31, 0x3a,
+    0x66, 0x61, 0x3a, 0x62, 0x61, 0x3a, 0x33, 0x35, 0x3a, 0x35, 0x61, 0x3a,
+    0x38, 0x39, 0x3a, 0x62, 0x63, 0x3a, 0x66, 0x31, 0x3a, 0x64, 0x66, 0x3a,
+    0x36, 0x39, 0x3a, 0x35, 0x36, 0x3a, 0x31, 0x65, 0x3a, 0x33, 0x64, 0x3a,
+    0x63, 0x36, 0x3a, 0x33, 0x32, 0x3a, 0x35, 0x63, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x4d, 0x49, 0x49, 0x44, 0x74, 0x7a, 0x43, 0x43, 0x41, 0x70, 0x2b,
+    0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x44, 0x4f, 0x66,
+    0x67, 0x35, 0x52, 0x66, 0x59, 0x52, 0x76, 0x36, 0x50, 0x35, 0x57, 0x44,
+    0x38, 0x47, 0x2f, 0x41, 0x77, 0x4f, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b,
+    0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55,
+    0x46, 0x41, 0x44, 0x42, 0x6c, 0x0a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a,
+    0x45, 0x56, 0x4d, 0x42, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4d, 0x52, 0x47, 0x6c, 0x6e, 0x61, 0x55, 0x4e, 0x6c, 0x63, 0x6e,
+    0x51, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4d, 0x52, 0x6b, 0x77, 0x46, 0x77,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x42, 0x33, 0x0a, 0x64,
+    0x33, 0x63, 0x75, 0x5a, 0x47, 0x6c, 0x6e, 0x61, 0x57, 0x4e, 0x6c, 0x63,
+    0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x53, 0x51, 0x77, 0x49,
+    0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x74, 0x45, 0x61,
+    0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x42, 0x63,
+    0x33, 0x4e, 0x31, 0x63, 0x6d, 0x56, 0x6b, 0x49, 0x45, 0x6c, 0x45, 0x49,
+    0x46, 0x4a, 0x76, 0x0a, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x77,
+    0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x59, 0x78, 0x4d, 0x54, 0x45, 0x77,
+    0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e,
+    0x4d, 0x7a, 0x45, 0x78, 0x4d, 0x54, 0x45, 0x77, 0x4d, 0x44, 0x41, 0x77,
+    0x4d, 0x44, 0x41, 0x77, 0x57, 0x6a, 0x42, 0x6c, 0x4d, 0x51, 0x73, 0x77,
+    0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0a, 0x45, 0x77, 0x4a,
+    0x56, 0x55, 0x7a, 0x45, 0x56, 0x4d, 0x42, 0x4d, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x4d, 0x52, 0x47, 0x6c, 0x6e, 0x61, 0x55, 0x4e,
+    0x6c, 0x63, 0x6e, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4d, 0x52, 0x6b,
+    0x77, 0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x42,
+    0x33, 0x64, 0x33, 0x63, 0x75, 0x5a, 0x47, 0x6c, 0x6e, 0x61, 0x57, 0x4e,
+    0x6c, 0x0a, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x53,
+    0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78,
+    0x74, 0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43,
+    0x42, 0x42, 0x63, 0x33, 0x4e, 0x31, 0x63, 0x6d, 0x56, 0x6b, 0x49, 0x45,
+    0x6c, 0x45, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30,
+    0x45, 0x77, 0x67, 0x67, 0x45, 0x69, 0x0a, 0x4d, 0x41, 0x30, 0x47, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41,
+    0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67,
+    0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x43, 0x74, 0x44,
+    0x68, 0x58, 0x4f, 0x35, 0x45, 0x4f, 0x41, 0x58, 0x4c, 0x47, 0x48, 0x38,
+    0x37, 0x64, 0x67, 0x2b, 0x58, 0x45, 0x53, 0x70, 0x61, 0x37, 0x63, 0x0a,
+    0x4a, 0x70, 0x53, 0x49, 0x71, 0x76, 0x54, 0x4f, 0x39, 0x53, 0x41, 0x35,
+    0x4b, 0x46, 0x68, 0x67, 0x44, 0x50, 0x69, 0x41, 0x32, 0x71, 0x6b, 0x56,
+    0x6c, 0x54, 0x4a, 0x68, 0x50, 0x4c, 0x57, 0x78, 0x4b, 0x49, 0x53, 0x4b,
+    0x69, 0x74, 0x79, 0x66, 0x43, 0x67, 0x79, 0x44, 0x46, 0x33, 0x71, 0x50,
+    0x6b, 0x4b, 0x79, 0x4b, 0x35, 0x33, 0x6c, 0x54, 0x58, 0x44, 0x47, 0x45,
+    0x4b, 0x76, 0x59, 0x50, 0x0a, 0x6d, 0x44, 0x49, 0x32, 0x64, 0x73, 0x7a,
+    0x65, 0x33, 0x54, 0x79, 0x6f, 0x6f, 0x75, 0x39, 0x71, 0x2b, 0x79, 0x48,
+    0x79, 0x55, 0x6d, 0x48, 0x66, 0x6e, 0x79, 0x44, 0x58, 0x48, 0x2b, 0x4b,
+    0x78, 0x32, 0x66, 0x34, 0x59, 0x5a, 0x4e, 0x49, 0x53, 0x57, 0x31, 0x2f,
+    0x35, 0x57, 0x42, 0x67, 0x31, 0x76, 0x45, 0x66, 0x4e, 0x6f, 0x54, 0x62,
+    0x35, 0x61, 0x33, 0x2f, 0x55, 0x73, 0x44, 0x67, 0x2b, 0x0a, 0x77, 0x52,
+    0x76, 0x44, 0x6a, 0x44, 0x50, 0x5a, 0x32, 0x43, 0x38, 0x59, 0x2f, 0x69,
+    0x67, 0x50, 0x73, 0x36, 0x65, 0x44, 0x31, 0x73, 0x4e, 0x75, 0x52, 0x4d,
+    0x42, 0x68, 0x4e, 0x5a, 0x59, 0x57, 0x2f, 0x6c, 0x6d, 0x63, 0x69, 0x33,
+    0x5a, 0x74, 0x31, 0x2f, 0x47, 0x69, 0x53, 0x77, 0x30, 0x72, 0x2f, 0x77,
+    0x74, 0x79, 0x32, 0x70, 0x35, 0x67, 0x30, 0x49, 0x36, 0x51, 0x4e, 0x63,
+    0x5a, 0x34, 0x0a, 0x56, 0x59, 0x63, 0x67, 0x6f, 0x63, 0x2f, 0x6c, 0x62,
+    0x51, 0x72, 0x49, 0x53, 0x58, 0x77, 0x78, 0x6d, 0x44, 0x4e, 0x73, 0x49,
+    0x75, 0x6d, 0x48, 0x30, 0x44, 0x4a, 0x61, 0x6f, 0x72, 0x6f, 0x54, 0x67,
+    0x68, 0x48, 0x74, 0x4f, 0x52, 0x65, 0x64, 0x6d, 0x54, 0x70, 0x79, 0x6f,
+    0x65, 0x62, 0x36, 0x70, 0x4e, 0x6e, 0x56, 0x46, 0x7a, 0x46, 0x31, 0x72,
+    0x6f, 0x56, 0x39, 0x49, 0x71, 0x34, 0x2f, 0x0a, 0x41, 0x55, 0x61, 0x47,
+    0x39, 0x69, 0x68, 0x35, 0x79, 0x4c, 0x48, 0x61, 0x35, 0x46, 0x63, 0x58,
+    0x78, 0x48, 0x34, 0x63, 0x44, 0x72, 0x43, 0x30, 0x6b, 0x71, 0x5a, 0x57,
+    0x73, 0x37, 0x32, 0x79, 0x6c, 0x2b, 0x32, 0x71, 0x70, 0x2f, 0x43, 0x33,
+    0x78, 0x61, 0x67, 0x2f, 0x6c, 0x52, 0x62, 0x51, 0x2f, 0x36, 0x47, 0x57,
+    0x36, 0x77, 0x68, 0x66, 0x47, 0x48, 0x64, 0x50, 0x41, 0x67, 0x4d, 0x42,
+    0x0a, 0x41, 0x41, 0x47, 0x6a, 0x59, 0x7a, 0x42, 0x68, 0x4d, 0x41, 0x34,
+    0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51,
+    0x45, 0x41, 0x77, 0x49, 0x42, 0x68, 0x6a, 0x41, 0x50, 0x42, 0x67, 0x4e,
+    0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41,
+    0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x44, 0x67, 0x51, 0x57, 0x0a, 0x42, 0x42, 0x52, 0x46, 0x36, 0x36,
+    0x4b, 0x76, 0x39, 0x4a, 0x4c, 0x4c, 0x67, 0x6a, 0x45, 0x74, 0x55, 0x59,
+    0x75, 0x6e, 0x70, 0x79, 0x47, 0x64, 0x38, 0x32, 0x33, 0x49, 0x44, 0x7a,
+    0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44,
+    0x41, 0x57, 0x67, 0x42, 0x52, 0x46, 0x36, 0x36, 0x4b, 0x76, 0x39, 0x4a,
+    0x4c, 0x4c, 0x67, 0x6a, 0x45, 0x74, 0x55, 0x59, 0x75, 0x6e, 0x0a, 0x70,
+    0x79, 0x47, 0x64, 0x38, 0x32, 0x33, 0x49, 0x44, 0x7a, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x6f,
+    0x67, 0x36, 0x38, 0x33, 0x2b, 0x4c, 0x74, 0x38, 0x4f, 0x4e, 0x79, 0x63,
+    0x33, 0x70, 0x6b, 0x6c, 0x4c, 0x2f, 0x33, 0x63, 0x6d, 0x62, 0x59, 0x4d,
+    0x75, 0x52, 0x43, 0x0a, 0x64, 0x57, 0x4b, 0x75, 0x68, 0x2b, 0x76, 0x79,
+    0x31, 0x64, 0x6e, 0x65, 0x56, 0x72, 0x4f, 0x66, 0x7a, 0x4d, 0x34, 0x55,
+    0x4b, 0x4c, 0x6b, 0x4e, 0x6c, 0x32, 0x42, 0x63, 0x45, 0x6b, 0x78, 0x59,
+    0x35, 0x4e, 0x4d, 0x39, 0x67, 0x30, 0x6c, 0x46, 0x57, 0x4a, 0x63, 0x31,
+    0x61, 0x52, 0x71, 0x6f, 0x52, 0x2b, 0x70, 0x57, 0x78, 0x6e, 0x6d, 0x72,
+    0x45, 0x74, 0x68, 0x6e, 0x67, 0x59, 0x54, 0x66, 0x0a, 0x66, 0x77, 0x6b,
+    0x38, 0x6c, 0x4f, 0x61, 0x34, 0x4a, 0x69, 0x77, 0x67, 0x76, 0x54, 0x32,
+    0x7a, 0x4b, 0x49, 0x6e, 0x33, 0x58, 0x2f, 0x38, 0x69, 0x34, 0x70, 0x65,
+    0x45, 0x48, 0x2b, 0x6c, 0x6c, 0x37, 0x34, 0x66, 0x67, 0x33, 0x38, 0x46,
+    0x6e, 0x53, 0x62, 0x4e, 0x64, 0x36, 0x37, 0x49, 0x4a, 0x4b, 0x75, 0x73,
+    0x6d, 0x37, 0x58, 0x69, 0x2b, 0x66, 0x54, 0x38, 0x72, 0x38, 0x37, 0x63,
+    0x6d, 0x0a, 0x4e, 0x57, 0x31, 0x66, 0x69, 0x51, 0x47, 0x32, 0x53, 0x56,
+    0x75, 0x66, 0x41, 0x51, 0x57, 0x62, 0x71, 0x7a, 0x30, 0x6c, 0x77, 0x63,
+    0x79, 0x32, 0x66, 0x38, 0x4c, 0x78, 0x62, 0x34, 0x62, 0x47, 0x2b, 0x6d,
+    0x52, 0x6f, 0x36, 0x34, 0x45, 0x74, 0x6c, 0x4f, 0x74, 0x43, 0x74, 0x2f,
+    0x71, 0x4d, 0x48, 0x74, 0x31, 0x69, 0x38, 0x62, 0x35, 0x51, 0x5a, 0x37,
+    0x64, 0x73, 0x76, 0x66, 0x50, 0x78, 0x0a, 0x48, 0x32, 0x73, 0x4d, 0x4e,
+    0x67, 0x63, 0x57, 0x66, 0x7a, 0x64, 0x38, 0x71, 0x56, 0x74, 0x74, 0x65,
+    0x76, 0x45, 0x53, 0x52, 0x6d, 0x43, 0x44, 0x31, 0x79, 0x63, 0x45, 0x76,
+    0x6b, 0x76, 0x4f, 0x6c, 0x37, 0x37, 0x44, 0x5a, 0x79, 0x70, 0x6f, 0x45,
+    0x64, 0x2b, 0x41, 0x35, 0x77, 0x77, 0x7a, 0x5a, 0x72, 0x38, 0x54, 0x44,
+    0x52, 0x52, 0x75, 0x38, 0x33, 0x38, 0x66, 0x59, 0x78, 0x41, 0x65, 0x0a,
+    0x2b, 0x6f, 0x30, 0x62, 0x4a, 0x57, 0x31, 0x73, 0x6a, 0x36, 0x57, 0x33,
+    0x59, 0x51, 0x47, 0x78, 0x30, 0x71, 0x4d, 0x6d, 0x6f, 0x52, 0x42, 0x78,
+    0x6e, 0x61, 0x33, 0x69, 0x77, 0x2f, 0x6e, 0x44, 0x6d, 0x56, 0x47, 0x33,
+    0x4b, 0x77, 0x63, 0x49, 0x7a, 0x69, 0x37, 0x6d, 0x55, 0x4c, 0x4b, 0x6e,
+    0x2b, 0x67, 0x70, 0x46, 0x4c, 0x36, 0x4c, 0x77, 0x38, 0x67, 0x3d, 0x3d,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72,
+    0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72,
+    0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f,
+    0x74, 0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43,
+    0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x77,
+    0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e,
+    0x63, 0x6f, 0x6d, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65,
+    0x72, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f,
+    0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x4f, 0x3d, 0x44, 0x69, 0x67, 0x69,
+    0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d,
+    0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74,
+    0x2e, 0x63, 0x6f, 0x6d, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+    0x3a, 0x20, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20,
+    0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x43, 0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c,
+    0x3a, 0x20, 0x31, 0x30, 0x39, 0x34, 0x34, 0x37, 0x31, 0x39, 0x35, 0x39,
+    0x38, 0x39, 0x35, 0x32, 0x30, 0x34, 0x30, 0x33, 0x37, 0x34, 0x39, 0x35,
+    0x31, 0x38, 0x33, 0x32, 0x39, 0x36, 0x33, 0x37, 0x39, 0x34, 0x34, 0x35,
+    0x34, 0x33, 0x34, 0x36, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x37, 0x39, 0x3a, 0x65, 0x34, 0x3a, 0x61, 0x39, 0x3a, 0x38, 0x34, 0x3a,
+    0x30, 0x64, 0x3a, 0x37, 0x64, 0x3a, 0x33, 0x61, 0x3a, 0x39, 0x36, 0x3a,
+    0x64, 0x37, 0x3a, 0x63, 0x30, 0x3a, 0x34, 0x66, 0x3a, 0x65, 0x32, 0x3a,
+    0x34, 0x33, 0x3a, 0x34, 0x63, 0x3a, 0x38, 0x39, 0x3a, 0x32, 0x65, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x38, 0x3a, 0x39,
+    0x38, 0x3a, 0x35, 0x64, 0x3a, 0x33, 0x61, 0x3a, 0x36, 0x35, 0x3a, 0x65,
+    0x35, 0x3a, 0x65, 0x35, 0x3a, 0x63, 0x34, 0x3a, 0x62, 0x32, 0x3a, 0x64,
+    0x37, 0x3a, 0x64, 0x36, 0x3a, 0x36, 0x64, 0x3a, 0x34, 0x30, 0x3a, 0x63,
+    0x36, 0x3a, 0x64, 0x64, 0x3a, 0x32, 0x66, 0x3a, 0x62, 0x31, 0x3a, 0x39,
+    0x63, 0x3a, 0x35, 0x34, 0x3a, 0x33, 0x36, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x34, 0x33, 0x3a, 0x34, 0x38, 0x3a,
+    0x61, 0x30, 0x3a, 0x65, 0x39, 0x3a, 0x34, 0x34, 0x3a, 0x34, 0x63, 0x3a,
+    0x37, 0x38, 0x3a, 0x63, 0x62, 0x3a, 0x32, 0x36, 0x3a, 0x35, 0x65, 0x3a,
+    0x30, 0x35, 0x3a, 0x38, 0x64, 0x3a, 0x35, 0x65, 0x3a, 0x38, 0x39, 0x3a,
+    0x34, 0x34, 0x3a, 0x62, 0x34, 0x3a, 0x64, 0x38, 0x3a, 0x34, 0x66, 0x3a,
+    0x39, 0x36, 0x3a, 0x36, 0x32, 0x3a, 0x62, 0x64, 0x3a, 0x32, 0x36, 0x3a,
+    0x64, 0x62, 0x3a, 0x32, 0x35, 0x3a, 0x37, 0x66, 0x3a, 0x38, 0x39, 0x3a,
+    0x33, 0x34, 0x3a, 0x61, 0x34, 0x3a, 0x34, 0x33, 0x3a, 0x63, 0x37, 0x3a,
+    0x30, 0x31, 0x3a, 0x36, 0x31, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42,
+    0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49,
+    0x49, 0x44, 0x72, 0x7a, 0x43, 0x43, 0x41, 0x70, 0x65, 0x67, 0x41, 0x77,
+    0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x43, 0x44, 0x76, 0x67, 0x56, 0x70,
+    0x42, 0x43, 0x52, 0x72, 0x47, 0x68, 0x64, 0x57, 0x72, 0x4a, 0x57, 0x5a,
+    0x48, 0x48, 0x53, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44,
+    0x42, 0x68, 0x0a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x56, 0x4d,
+    0x42, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4d, 0x52,
+    0x47, 0x6c, 0x6e, 0x61, 0x55, 0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x67, 0x53,
+    0x57, 0x35, 0x6a, 0x4d, 0x52, 0x6b, 0x77, 0x46, 0x77, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x4c, 0x45, 0x78, 0x42, 0x33, 0x0a, 0x64, 0x33, 0x63, 0x75,
+    0x5a, 0x47, 0x6c, 0x6e, 0x61, 0x57, 0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x75,
+    0x59, 0x32, 0x39, 0x74, 0x4d, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x64, 0x45, 0x61, 0x57, 0x64, 0x70,
+    0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69,
+    0x59, 0x57, 0x77, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44,
+    0x0a, 0x51, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4e, 0x6a, 0x45,
+    0x78, 0x4d, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x42,
+    0x61, 0x46, 0x77, 0x30, 0x7a, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x54, 0x41,
+    0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x42, 0x61, 0x4d, 0x47, 0x45,
+    0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59,
+    0x54, 0x41, 0x6c, 0x56, 0x54, 0x0a, 0x4d, 0x52, 0x55, 0x77, 0x45, 0x77,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x77, 0x78, 0x45, 0x61, 0x57,
+    0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d,
+    0x4d, 0x78, 0x47, 0x54, 0x41, 0x58, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x73, 0x54, 0x45, 0x48, 0x64, 0x33, 0x64, 0x79, 0x35, 0x6b, 0x61, 0x57,
+    0x64, 0x70, 0x59, 0x32, 0x56, 0x79, 0x64, 0x43, 0x35, 0x6a, 0x0a, 0x62,
+    0x32, 0x30, 0x78, 0x49, 0x44, 0x41, 0x65, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x4d, 0x54, 0x46, 0x30, 0x52, 0x70, 0x5a, 0x32, 0x6c, 0x44, 0x5a,
+    0x58, 0x4a, 0x30, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4a, 0x68, 0x62,
+    0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4e, 0x42, 0x4d,
+    0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x0a, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46,
+    0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42,
+    0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x34, 0x6a, 0x76, 0x68,
+    0x45, 0x58, 0x4c, 0x65, 0x71, 0x4b, 0x54, 0x54, 0x6f, 0x31, 0x65, 0x71,
+    0x55, 0x4b, 0x4b, 0x50, 0x43, 0x33, 0x65, 0x51, 0x79, 0x61, 0x4b, 0x6c,
+    0x37, 0x68, 0x4c, 0x4f, 0x6c, 0x6c, 0x73, 0x42, 0x0a, 0x43, 0x53, 0x44,
+    0x4d, 0x41, 0x5a, 0x4f, 0x6e, 0x54, 0x6a, 0x43, 0x33, 0x55, 0x2f, 0x64,
+    0x44, 0x78, 0x47, 0x6b, 0x41, 0x56, 0x35, 0x33, 0x69, 0x6a, 0x53, 0x4c,
+    0x64, 0x68, 0x77, 0x5a, 0x41, 0x41, 0x49, 0x45, 0x4a, 0x7a, 0x73, 0x34,
+    0x62, 0x67, 0x37, 0x2f, 0x66, 0x7a, 0x54, 0x74, 0x78, 0x52, 0x75, 0x4c,
+    0x57, 0x5a, 0x73, 0x63, 0x46, 0x73, 0x33, 0x59, 0x6e, 0x46, 0x6f, 0x39,
+    0x37, 0x0a, 0x6e, 0x68, 0x36, 0x56, 0x66, 0x65, 0x36, 0x33, 0x53, 0x4b,
+    0x4d, 0x49, 0x32, 0x74, 0x61, 0x76, 0x65, 0x67, 0x77, 0x35, 0x42, 0x6d,
+    0x56, 0x2f, 0x53, 0x6c, 0x30, 0x66, 0x76, 0x42, 0x66, 0x34, 0x71, 0x37,
+    0x37, 0x75, 0x4b, 0x4e, 0x64, 0x30, 0x66, 0x33, 0x70, 0x34, 0x6d, 0x56,
+    0x6d, 0x46, 0x61, 0x47, 0x35, 0x63, 0x49, 0x7a, 0x4a, 0x4c, 0x76, 0x30,
+    0x37, 0x41, 0x36, 0x46, 0x70, 0x74, 0x0a, 0x34, 0x33, 0x43, 0x2f, 0x64,
+    0x78, 0x43, 0x2f, 0x2f, 0x41, 0x48, 0x32, 0x68, 0x64, 0x6d, 0x6f, 0x52,
+    0x42, 0x42, 0x59, 0x4d, 0x71, 0x6c, 0x31, 0x47, 0x4e, 0x58, 0x52, 0x6f,
+    0x72, 0x35, 0x48, 0x34, 0x69, 0x64, 0x71, 0x39, 0x4a, 0x6f, 0x7a, 0x2b,
+    0x45, 0x6b, 0x49, 0x59, 0x49, 0x76, 0x55, 0x58, 0x37, 0x51, 0x36, 0x68,
+    0x4c, 0x2b, 0x68, 0x71, 0x6b, 0x70, 0x4d, 0x66, 0x54, 0x37, 0x50, 0x0a,
+    0x54, 0x31, 0x39, 0x73, 0x64, 0x6c, 0x36, 0x67, 0x53, 0x7a, 0x65, 0x52,
+    0x6e, 0x74, 0x77, 0x69, 0x35, 0x6d, 0x33, 0x4f, 0x46, 0x42, 0x71, 0x4f,
+    0x61, 0x73, 0x76, 0x2b, 0x7a, 0x62, 0x4d, 0x55, 0x5a, 0x42, 0x66, 0x48,
+    0x57, 0x79, 0x6d, 0x65, 0x4d, 0x72, 0x2f, 0x79, 0x37, 0x76, 0x72, 0x54,
+    0x43, 0x30, 0x4c, 0x55, 0x71, 0x37, 0x64, 0x42, 0x4d, 0x74, 0x6f, 0x4d,
+    0x31, 0x4f, 0x2f, 0x34, 0x0a, 0x67, 0x64, 0x57, 0x37, 0x6a, 0x56, 0x67,
+    0x2f, 0x74, 0x52, 0x76, 0x6f, 0x53, 0x53, 0x69, 0x69, 0x63, 0x4e, 0x6f,
+    0x78, 0x42, 0x4e, 0x33, 0x33, 0x73, 0x68, 0x62, 0x79, 0x54, 0x41, 0x70,
+    0x4f, 0x42, 0x36, 0x6a, 0x74, 0x53, 0x6a, 0x31, 0x65, 0x74, 0x58, 0x2b,
+    0x6a, 0x6b, 0x4d, 0x4f, 0x76, 0x4a, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41,
+    0x42, 0x6f, 0x32, 0x4d, 0x77, 0x59, 0x54, 0x41, 0x4f, 0x0a, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41,
+    0x4d, 0x43, 0x41, 0x59, 0x59, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52,
+    0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77,
+    0x45, 0x42, 0x2f, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51,
+    0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x41, 0x39, 0x35, 0x51, 0x4e, 0x56,
+    0x62, 0x52, 0x0a, 0x54, 0x4c, 0x74, 0x6d, 0x38, 0x4b, 0x50, 0x69, 0x47,
+    0x78, 0x76, 0x44, 0x6c, 0x37, 0x49, 0x39, 0x30, 0x56, 0x55, 0x77, 0x48,
+    0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46,
+    0x6f, 0x41, 0x55, 0x41, 0x39, 0x35, 0x51, 0x4e, 0x56, 0x62, 0x52, 0x54,
+    0x4c, 0x74, 0x6d, 0x38, 0x4b, 0x50, 0x69, 0x47, 0x78, 0x76, 0x44, 0x6c,
+    0x37, 0x49, 0x39, 0x30, 0x56, 0x55, 0x77, 0x0a, 0x44, 0x51, 0x59, 0x4a,
+    0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46,
+    0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4d, 0x75, 0x63,
+    0x4e, 0x36, 0x70, 0x49, 0x45, 0x78, 0x49, 0x4b, 0x2b, 0x74, 0x31, 0x45,
+    0x6e, 0x45, 0x39, 0x53, 0x73, 0x50, 0x54, 0x66, 0x72, 0x67, 0x54, 0x31,
+    0x65, 0x58, 0x6b, 0x49, 0x6f, 0x79, 0x51, 0x59, 0x2f, 0x45, 0x73, 0x72,
+    0x0a, 0x68, 0x4d, 0x41, 0x74, 0x75, 0x64, 0x58, 0x48, 0x2f, 0x76, 0x54,
+    0x42, 0x48, 0x31, 0x6a, 0x4c, 0x75, 0x47, 0x32, 0x63, 0x65, 0x6e, 0x54,
+    0x6e, 0x6d, 0x43, 0x6d, 0x72, 0x45, 0x62, 0x58, 0x6a, 0x63, 0x4b, 0x43,
+    0x68, 0x7a, 0x55, 0x79, 0x49, 0x6d, 0x5a, 0x4f, 0x4d, 0x6b, 0x58, 0x44,
+    0x69, 0x71, 0x77, 0x38, 0x63, 0x76, 0x70, 0x4f, 0x70, 0x2f, 0x32, 0x50,
+    0x56, 0x35, 0x41, 0x64, 0x67, 0x0a, 0x30, 0x36, 0x4f, 0x2f, 0x6e, 0x56,
+    0x73, 0x4a, 0x38, 0x64, 0x57, 0x4f, 0x34, 0x31, 0x50, 0x30, 0x6a, 0x6d,
+    0x50, 0x36, 0x50, 0x36, 0x66, 0x62, 0x74, 0x47, 0x62, 0x66, 0x59, 0x6d,
+    0x62, 0x57, 0x30, 0x57, 0x35, 0x42, 0x6a, 0x66, 0x49, 0x74, 0x74, 0x65,
+    0x70, 0x33, 0x53, 0x70, 0x2b, 0x64, 0x57, 0x4f, 0x49, 0x72, 0x57, 0x63,
+    0x42, 0x41, 0x49, 0x2b, 0x30, 0x74, 0x4b, 0x49, 0x4a, 0x46, 0x0a, 0x50,
+    0x6e, 0x6c, 0x55, 0x6b, 0x69, 0x61, 0x59, 0x34, 0x49, 0x42, 0x49, 0x71,
+    0x44, 0x66, 0x76, 0x38, 0x4e, 0x5a, 0x35, 0x59, 0x42, 0x62, 0x65, 0x72,
+    0x4f, 0x67, 0x4f, 0x7a, 0x57, 0x36, 0x73, 0x52, 0x42, 0x63, 0x34, 0x4c,
+    0x30, 0x6e, 0x61, 0x34, 0x55, 0x55, 0x2b, 0x4b, 0x72, 0x6b, 0x32, 0x55,
+    0x38, 0x38, 0x36, 0x55, 0x41, 0x62, 0x33, 0x4c, 0x75, 0x6a, 0x45, 0x56,
+    0x30, 0x6c, 0x73, 0x0a, 0x59, 0x53, 0x45, 0x59, 0x31, 0x51, 0x53, 0x74,
+    0x65, 0x44, 0x77, 0x73, 0x4f, 0x6f, 0x42, 0x72, 0x70, 0x2b, 0x75, 0x76,
+    0x46, 0x52, 0x54, 0x70, 0x32, 0x49, 0x6e, 0x42, 0x75, 0x54, 0x68, 0x73,
+    0x34, 0x70, 0x46, 0x73, 0x69, 0x76, 0x39, 0x6b, 0x75, 0x58, 0x63, 0x6c,
+    0x56, 0x7a, 0x44, 0x41, 0x47, 0x79, 0x53, 0x6a, 0x34, 0x64, 0x7a, 0x70,
+    0x33, 0x30, 0x64, 0x38, 0x74, 0x62, 0x51, 0x6b, 0x0a, 0x43, 0x41, 0x55,
+    0x77, 0x37, 0x43, 0x32, 0x39, 0x43, 0x37, 0x39, 0x46, 0x76, 0x31, 0x43,
+    0x35, 0x71, 0x66, 0x50, 0x72, 0x6d, 0x41, 0x45, 0x53, 0x72, 0x63, 0x69,
+    0x49, 0x78, 0x70, 0x67, 0x30, 0x58, 0x34, 0x30, 0x4b, 0x50, 0x4d, 0x62,
+    0x70, 0x31, 0x5a, 0x57, 0x56, 0x62, 0x64, 0x34, 0x3d, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
+    0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
+    0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+    0x20, 0x4f, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20,
+    0x49, 0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e, 0x64,
+    0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0a,
+    0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48,
+    0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63,
+    0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+    0x20, 0x4f, 0x3d, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20,
+    0x49, 0x6e, 0x63, 0x20, 0x4f, 0x55, 0x3d, 0x77, 0x77, 0x77, 0x2e, 0x64,
+    0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x44, 0x69,
+    0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20,
+    0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x45, 0x56,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x22, 0x0a, 0x23, 0x20,
+    0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x33, 0x35, 0x35, 0x33,
+    0x34, 0x30, 0x30, 0x30, 0x37, 0x36, 0x34, 0x31, 0x30, 0x35, 0x34, 0x37,
+    0x39, 0x31, 0x39, 0x37, 0x32, 0x34, 0x37, 0x33, 0x30, 0x37, 0x33, 0x34,
+    0x33, 0x37, 0x38, 0x31, 0x30, 0x30, 0x30, 0x38, 0x37, 0x0a, 0x23, 0x20,
+    0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x34, 0x3a, 0x37, 0x34, 0x3a, 0x64,
+    0x65, 0x3a, 0x35, 0x37, 0x3a, 0x35, 0x63, 0x3a, 0x33, 0x39, 0x3a, 0x62,
+    0x32, 0x3a, 0x64, 0x33, 0x3a, 0x39, 0x63, 0x3a, 0x38, 0x35, 0x3a, 0x38,
+    0x33, 0x3a, 0x63, 0x35, 0x3a, 0x63, 0x30, 0x3a, 0x36, 0x35, 0x3a, 0x34,
+    0x39, 0x3a, 0x38, 0x61, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x35, 0x66, 0x3a, 0x62, 0x37, 0x3a, 0x65, 0x65, 0x3a, 0x30, 0x36,
+    0x3a, 0x33, 0x33, 0x3a, 0x65, 0x32, 0x3a, 0x35, 0x39, 0x3a, 0x64, 0x62,
+    0x3a, 0x61, 0x64, 0x3a, 0x30, 0x63, 0x3a, 0x34, 0x63, 0x3a, 0x39, 0x61,
+    0x3a, 0x65, 0x36, 0x3a, 0x64, 0x33, 0x3a, 0x38, 0x66, 0x3a, 0x31, 0x61,
+    0x3a, 0x36, 0x31, 0x3a, 0x63, 0x37, 0x3a, 0x64, 0x63, 0x3a, 0x32, 0x35,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x37,
+    0x34, 0x3a, 0x33, 0x31, 0x3a, 0x65, 0x35, 0x3a, 0x66, 0x34, 0x3a, 0x63,
+    0x33, 0x3a, 0x63, 0x31, 0x3a, 0x63, 0x65, 0x3a, 0x34, 0x36, 0x3a, 0x39,
+    0x30, 0x3a, 0x37, 0x37, 0x3a, 0x34, 0x66, 0x3a, 0x30, 0x62, 0x3a, 0x36,
+    0x31, 0x3a, 0x65, 0x30, 0x3a, 0x35, 0x34, 0x3a, 0x34, 0x30, 0x3a, 0x38,
+    0x38, 0x3a, 0x33, 0x62, 0x3a, 0x61, 0x39, 0x3a, 0x61, 0x30, 0x3a, 0x31,
+    0x65, 0x3a, 0x64, 0x30, 0x3a, 0x30, 0x62, 0x3a, 0x61, 0x36, 0x3a, 0x61,
+    0x62, 0x3a, 0x64, 0x37, 0x3a, 0x38, 0x30, 0x3a, 0x36, 0x65, 0x3a, 0x64,
+    0x33, 0x3a, 0x62, 0x31, 0x3a, 0x31, 0x38, 0x3a, 0x63, 0x66, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x78, 0x54, 0x43, 0x43, 0x41,
+    0x71, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x41,
+    0x71, 0x78, 0x63, 0x4a, 0x6d, 0x6f, 0x4c, 0x51, 0x4a, 0x75, 0x50, 0x43,
+    0x33, 0x6e, 0x79, 0x72, 0x6b, 0x59, 0x6c, 0x64, 0x7a, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x73, 0x0a, 0x4d, 0x51, 0x73, 0x77,
+    0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56,
+    0x55, 0x7a, 0x45, 0x56, 0x4d, 0x42, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x4d, 0x52, 0x47, 0x6c, 0x6e, 0x61, 0x55, 0x4e, 0x6c,
+    0x63, 0x6e, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4d, 0x52, 0x6b, 0x77,
+    0x46, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x42, 0x33,
+    0x0a, 0x64, 0x33, 0x63, 0x75, 0x5a, 0x47, 0x6c, 0x6e, 0x61, 0x57, 0x4e,
+    0x6c, 0x63, 0x6e, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x53, 0x73,
+    0x77, 0x4b, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x4a,
+    0x45, 0x61, 0x57, 0x64, 0x70, 0x51, 0x32, 0x56, 0x79, 0x64, 0x43, 0x42,
+    0x49, 0x61, 0x57, 0x64, 0x6f, 0x49, 0x45, 0x46, 0x7a, 0x63, 0x33, 0x56,
+    0x79, 0x59, 0x57, 0x35, 0x6a, 0x0a, 0x5a, 0x53, 0x42, 0x46, 0x56, 0x69,
+    0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4e, 0x42, 0x4d, 0x42,
+    0x34, 0x58, 0x44, 0x54, 0x41, 0x32, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x44,
+    0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54,
+    0x4d, 0x78, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44,
+    0x41, 0x77, 0x4d, 0x46, 0x6f, 0x77, 0x62, 0x44, 0x45, 0x4c, 0x0a, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x44, 0x45, 0x52, 0x70, 0x5a, 0x32, 0x6c, 0x44, 0x5a,
+    0x58, 0x4a, 0x30, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x7a, 0x45, 0x5a, 0x4d,
+    0x42, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x51, 0x64,
+    0x33, 0x64, 0x33, 0x0a, 0x4c, 0x6d, 0x52, 0x70, 0x5a, 0x32, 0x6c, 0x6a,
+    0x5a, 0x58, 0x4a, 0x30, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x54, 0x45, 0x72,
+    0x4d, 0x43, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x69,
+    0x52, 0x47, 0x6c, 0x6e, 0x61, 0x55, 0x4e, 0x6c, 0x63, 0x6e, 0x51, 0x67,
+    0x53, 0x47, 0x6c, 0x6e, 0x61, 0x43, 0x42, 0x42, 0x63, 0x33, 0x4e, 0x31,
+    0x63, 0x6d, 0x46, 0x75, 0x59, 0x32, 0x55, 0x67, 0x0a, 0x52, 0x56, 0x59,
+    0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x51, 0x54, 0x43,
+    0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a,
+    0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41,
+    0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f,
+    0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4d, 0x62, 0x4d, 0x35, 0x58, 0x50,
+    0x6d, 0x0a, 0x2b, 0x39, 0x53, 0x37, 0x35, 0x53, 0x30, 0x74, 0x4d, 0x71,
+    0x62, 0x66, 0x35, 0x59, 0x45, 0x2f, 0x79, 0x63, 0x30, 0x6c, 0x53, 0x62,
+    0x5a, 0x78, 0x4b, 0x73, 0x50, 0x56, 0x6c, 0x44, 0x52, 0x6e, 0x6f, 0x67,
+    0x6f, 0x63, 0x73, 0x46, 0x39, 0x70, 0x70, 0x6b, 0x43, 0x78, 0x78, 0x4c,
+    0x65, 0x79, 0x6a, 0x39, 0x43, 0x59, 0x70, 0x4b, 0x6c, 0x42, 0x57, 0x54,
+    0x72, 0x54, 0x33, 0x4a, 0x54, 0x57, 0x0a, 0x50, 0x4e, 0x74, 0x30, 0x4f,
+    0x4b, 0x52, 0x4b, 0x7a, 0x45, 0x30, 0x6c, 0x67, 0x76, 0x64, 0x4b, 0x70,
+    0x56, 0x4d, 0x53, 0x4f, 0x4f, 0x37, 0x7a, 0x53, 0x57, 0x31, 0x78, 0x6b,
+    0x58, 0x35, 0x6a, 0x74, 0x71, 0x75, 0x6d, 0x58, 0x38, 0x4f, 0x6b, 0x68,
+    0x50, 0x68, 0x50, 0x59, 0x6c, 0x47, 0x2b, 0x2b, 0x4d, 0x58, 0x73, 0x32,
+    0x7a, 0x69, 0x53, 0x34, 0x77, 0x62, 0x6c, 0x43, 0x4a, 0x45, 0x4d, 0x0a,
+    0x78, 0x43, 0x68, 0x42, 0x56, 0x66, 0x76, 0x4c, 0x57, 0x6f, 0x6b, 0x56,
+    0x66, 0x6e, 0x48, 0x6f, 0x4e, 0x62, 0x39, 0x4e, 0x63, 0x67, 0x6b, 0x39,
+    0x76, 0x6a, 0x6f, 0x34, 0x55, 0x46, 0x74, 0x33, 0x4d, 0x52, 0x75, 0x4e,
+    0x73, 0x38, 0x63, 0x6b, 0x52, 0x5a, 0x71, 0x6e, 0x72, 0x47, 0x30, 0x41,
+    0x46, 0x46, 0x6f, 0x45, 0x74, 0x37, 0x6f, 0x54, 0x36, 0x31, 0x45, 0x4b,
+    0x6d, 0x45, 0x46, 0x42, 0x0a, 0x49, 0x6b, 0x35, 0x6c, 0x59, 0x59, 0x65,
+    0x42, 0x51, 0x56, 0x43, 0x6d, 0x65, 0x56, 0x79, 0x4a, 0x33, 0x68, 0x6c,
+    0x4b, 0x56, 0x39, 0x55, 0x75, 0x35, 0x6c, 0x30, 0x63, 0x55, 0x79, 0x78,
+    0x2b, 0x6d, 0x4d, 0x30, 0x61, 0x42, 0x68, 0x61, 0x6b, 0x61, 0x48, 0x50,
+    0x51, 0x4e, 0x41, 0x51, 0x54, 0x58, 0x4b, 0x46, 0x78, 0x30, 0x31, 0x70,
+    0x38, 0x56, 0x64, 0x74, 0x65, 0x5a, 0x4f, 0x45, 0x33, 0x0a, 0x68, 0x7a,
+    0x42, 0x57, 0x42, 0x4f, 0x55, 0x52, 0x74, 0x43, 0x6d, 0x41, 0x45, 0x76,
+    0x46, 0x35, 0x4f, 0x59, 0x69, 0x69, 0x41, 0x68, 0x46, 0x38, 0x4a, 0x32,
+    0x61, 0x33, 0x69, 0x4c, 0x64, 0x34, 0x38, 0x73, 0x6f, 0x4b, 0x71, 0x44,
+    0x69, 0x72, 0x43, 0x6d, 0x54, 0x43, 0x76, 0x32, 0x5a, 0x64, 0x6c, 0x59,
+    0x54, 0x42, 0x6f, 0x53, 0x55, 0x65, 0x68, 0x31, 0x30, 0x61, 0x55, 0x41,
+    0x73, 0x67, 0x0a, 0x45, 0x73, 0x78, 0x42, 0x75, 0x32, 0x34, 0x4c, 0x55,
+    0x54, 0x69, 0x34, 0x53, 0x38, 0x73, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41,
+    0x61, 0x4e, 0x6a, 0x4d, 0x47, 0x45, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x51, 0x44, 0x41,
+    0x67, 0x47, 0x47, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45,
+    0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x0a, 0x4d, 0x41, 0x4d, 0x42,
+    0x41, 0x66, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f,
+    0x42, 0x42, 0x59, 0x45, 0x46, 0x4c, 0x45, 0x2b, 0x77, 0x32, 0x6b, 0x44,
+    0x2b, 0x4c, 0x39, 0x48, 0x41, 0x64, 0x53, 0x59, 0x4a, 0x68, 0x6f, 0x49,
+    0x41, 0x75, 0x39, 0x6a, 0x5a, 0x43, 0x76, 0x44, 0x4d, 0x42, 0x38, 0x47,
+    0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41,
+    0x0a, 0x46, 0x4c, 0x45, 0x2b, 0x77, 0x32, 0x6b, 0x44, 0x2b, 0x4c, 0x39,
+    0x48, 0x41, 0x64, 0x53, 0x59, 0x4a, 0x68, 0x6f, 0x49, 0x41, 0x75, 0x39,
+    0x6a, 0x5a, 0x43, 0x76, 0x44, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71,
+    0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55,
+    0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x41, 0x63, 0x47, 0x67, 0x61,
+    0x58, 0x33, 0x4e, 0x65, 0x63, 0x0a, 0x6e, 0x7a, 0x79, 0x49, 0x5a, 0x67,
+    0x59, 0x49, 0x56, 0x79, 0x48, 0x62, 0x49, 0x55, 0x66, 0x34, 0x4b, 0x6d,
+    0x65, 0x71, 0x76, 0x78, 0x67, 0x79, 0x64, 0x6b, 0x41, 0x51, 0x56, 0x38,
+    0x47, 0x4b, 0x38, 0x33, 0x72, 0x5a, 0x45, 0x57, 0x57, 0x4f, 0x4e, 0x66,
+    0x71, 0x65, 0x2f, 0x45, 0x57, 0x31, 0x6e, 0x74, 0x6c, 0x4d, 0x4d, 0x55,
+    0x75, 0x34, 0x6b, 0x65, 0x68, 0x44, 0x4c, 0x49, 0x36, 0x7a, 0x0a, 0x65,
+    0x4d, 0x37, 0x62, 0x34, 0x31, 0x4e, 0x35, 0x63, 0x64, 0x62, 0x6c, 0x49,
+    0x5a, 0x51, 0x42, 0x32, 0x6c, 0x57, 0x48, 0x6d, 0x69, 0x52, 0x6b, 0x39,
+    0x6f, 0x70, 0x6d, 0x7a, 0x4e, 0x36, 0x63, 0x4e, 0x38, 0x32, 0x6f, 0x4e,
+    0x4c, 0x46, 0x70, 0x6d, 0x79, 0x50, 0x49, 0x6e, 0x6e, 0x67, 0x69, 0x4b,
+    0x33, 0x42, 0x44, 0x34, 0x31, 0x56, 0x48, 0x4d, 0x57, 0x45, 0x5a, 0x37,
+    0x31, 0x6a, 0x46, 0x0a, 0x68, 0x53, 0x39, 0x4f, 0x4d, 0x50, 0x61, 0x67,
+    0x4d, 0x52, 0x59, 0x6a, 0x79, 0x4f, 0x66, 0x69, 0x5a, 0x52, 0x59, 0x7a,
+    0x79, 0x37, 0x38, 0x61, 0x47, 0x36, 0x41, 0x39, 0x2b, 0x4d, 0x70, 0x65,
+    0x69, 0x7a, 0x47, 0x4c, 0x59, 0x41, 0x69, 0x4a, 0x4c, 0x51, 0x77, 0x47,
+    0x58, 0x46, 0x4b, 0x33, 0x78, 0x50, 0x6b, 0x4b, 0x6d, 0x4e, 0x45, 0x56,
+    0x58, 0x35, 0x38, 0x53, 0x76, 0x6e, 0x77, 0x32, 0x0a, 0x59, 0x7a, 0x69,
+    0x39, 0x52, 0x4b, 0x52, 0x2f, 0x35, 0x43, 0x59, 0x72, 0x43, 0x73, 0x53,
+    0x58, 0x61, 0x51, 0x33, 0x70, 0x6a, 0x4f, 0x4c, 0x41, 0x45, 0x46, 0x65,
+    0x34, 0x79, 0x48, 0x59, 0x53, 0x6b, 0x56, 0x58, 0x79, 0x53, 0x47, 0x6e,
+    0x59, 0x76, 0x43, 0x6f, 0x43, 0x57, 0x77, 0x39, 0x45, 0x31, 0x43, 0x41,
+    0x78, 0x32, 0x2f, 0x53, 0x36, 0x63, 0x43, 0x5a, 0x64, 0x6b, 0x47, 0x43,
+    0x65, 0x0a, 0x76, 0x45, 0x73, 0x58, 0x43, 0x53, 0x2b, 0x30, 0x79, 0x78,
+    0x35, 0x44, 0x61, 0x4d, 0x6b, 0x48, 0x4a, 0x38, 0x48, 0x53, 0x58, 0x50,
+    0x66, 0x71, 0x49, 0x62, 0x6c, 0x6f, 0x45, 0x70, 0x77, 0x38, 0x6e, 0x4c,
+    0x2b, 0x65, 0x2f, 0x49, 0x42, 0x63, 0x6d, 0x32, 0x50, 0x4e, 0x37, 0x45,
+    0x65, 0x71, 0x4a, 0x53, 0x64, 0x6e, 0x6f, 0x44, 0x66, 0x7a, 0x41, 0x49,
+    0x4a, 0x39, 0x56, 0x4e, 0x65, 0x70, 0x0a, 0x2b, 0x4f, 0x6b, 0x75, 0x45,
+    0x36, 0x4e, 0x33, 0x36, 0x42, 0x39, 0x4b, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69,
+    0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47,
+    0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, 0x6d,
+    0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61,
+    0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x33, 0x32,
+    0x37, 0x39, 0x38, 0x32, 0x32, 0x36, 0x35, 0x35, 0x31, 0x32, 0x35, 0x36,
+    0x39, 0x36, 0x33, 0x33, 0x32, 0x34, 0x33, 0x31, 0x33, 0x38, 0x30, 0x36,
+    0x34, 0x33, 0x36, 0x39, 0x38, 0x31, 0x39, 0x38, 0x32, 0x33, 0x36, 0x39,
+    0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30, 0x32, 0x3a, 0x32,
+    0x36, 0x3a, 0x63, 0x33, 0x3a, 0x30, 0x31, 0x3a, 0x35, 0x65, 0x3a, 0x30,
+    0x38, 0x3a, 0x33, 0x30, 0x3a, 0x33, 0x37, 0x3a, 0x34, 0x33, 0x3a, 0x61,
+    0x39, 0x3a, 0x64, 0x30, 0x3a, 0x37, 0x64, 0x3a, 0x63, 0x66, 0x3a, 0x33,
+    0x37, 0x3a, 0x65, 0x36, 0x3a, 0x62, 0x66, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x33, 0x32, 0x3a, 0x33, 0x63, 0x3a, 0x31, 0x31,
+    0x3a, 0x38, 0x65, 0x3a, 0x31, 0x62, 0x3a, 0x66, 0x37, 0x3a, 0x62, 0x38,
+    0x3a, 0x62, 0x36, 0x3a, 0x35, 0x32, 0x3a, 0x35, 0x34, 0x3a, 0x65, 0x32,
+    0x3a, 0x65, 0x32, 0x3a, 0x31, 0x30, 0x3a, 0x30, 0x64, 0x3a, 0x64, 0x36,
+    0x3a, 0x30, 0x32, 0x3a, 0x39, 0x30, 0x3a, 0x33, 0x37, 0x3a, 0x66, 0x30,
+    0x3a, 0x39, 0x36, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x33, 0x37, 0x3a, 0x64, 0x35, 0x3a, 0x31, 0x30, 0x3a, 0x30,
+    0x36, 0x3a, 0x63, 0x35, 0x3a, 0x31, 0x32, 0x3a, 0x65, 0x61, 0x3a, 0x61,
+    0x62, 0x3a, 0x36, 0x32, 0x3a, 0x36, 0x34, 0x3a, 0x32, 0x31, 0x3a, 0x66,
+    0x31, 0x3a, 0x65, 0x63, 0x3a, 0x38, 0x63, 0x3a, 0x39, 0x32, 0x3a, 0x30,
+    0x31, 0x3a, 0x33, 0x66, 0x3a, 0x63, 0x35, 0x3a, 0x66, 0x38, 0x3a, 0x32,
+    0x61, 0x3a, 0x65, 0x39, 0x3a, 0x38, 0x65, 0x3a, 0x65, 0x35, 0x3a, 0x33,
+    0x33, 0x3a, 0x65, 0x62, 0x3a, 0x34, 0x36, 0x3a, 0x31, 0x39, 0x3a, 0x62,
+    0x38, 0x3a, 0x64, 0x65, 0x3a, 0x62, 0x34, 0x3a, 0x64, 0x30, 0x3a, 0x36,
+    0x63, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x66, 0x44,
+    0x43, 0x43, 0x41, 0x6d, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67,
+    0x49, 0x51, 0x47, 0x4b, 0x79, 0x31, 0x61, 0x76, 0x31, 0x70, 0x74, 0x68,
+    0x55, 0x36, 0x59, 0x32, 0x79, 0x76, 0x32, 0x76, 0x72, 0x45, 0x6f, 0x54,
+    0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77,
+    0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x59, 0x0a, 0x4d,
+    0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x57, 0x4d, 0x42, 0x51, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x52, 0x32, 0x56, 0x76, 0x56,
+    0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c,
+    0x6a, 0x45, 0x78, 0x4d, 0x43, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41,
+    0x78, 0x4d, 0x6f, 0x0a, 0x52, 0x32, 0x56, 0x76, 0x56, 0x48, 0x4a, 0x31,
+    0x63, 0x33, 0x51, 0x67, 0x55, 0x48, 0x4a, 0x70, 0x62, 0x57, 0x46, 0x79,
+    0x65, 0x53, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70,
+    0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31,
+    0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x54, 0x41, 0x65,
+    0x46, 0x77, 0x30, 0x77, 0x4e, 0x6a, 0x45, 0x78, 0x0a, 0x4d, 0x6a, 0x63,
+    0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30,
+    0x7a, 0x4e, 0x6a, 0x41, 0x33, 0x4d, 0x54, 0x59, 0x79, 0x4d, 0x7a, 0x55,
+    0x35, 0x4e, 0x54, 0x6c, 0x61, 0x4d, 0x46, 0x67, 0x78, 0x43, 0x7a, 0x41,
+    0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56,
+    0x54, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4b, 0x0a, 0x45, 0x77, 0x31, 0x48, 0x5a, 0x57, 0x39, 0x55, 0x63, 0x6e,
+    0x56, 0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x54,
+    0x45, 0x77, 0x4c, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79,
+    0x68, 0x48, 0x5a, 0x57, 0x39, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43,
+    0x42, 0x51, 0x63, 0x6d, 0x6c, 0x74, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x45,
+    0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x0a, 0x5a, 0x6d, 0x6c, 0x6a, 0x59,
+    0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61,
+    0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x49, 0x49, 0x42, 0x49,
+    0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41,
+    0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x0a,
+    0x41, 0x51, 0x45, 0x41, 0x76, 0x72, 0x67, 0x56, 0x65, 0x2f, 0x2f, 0x55,
+    0x66, 0x48, 0x31, 0x6e, 0x72, 0x59, 0x4e, 0x6b, 0x65, 0x38, 0x68, 0x43,
+    0x55, 0x79, 0x33, 0x66, 0x39, 0x6f, 0x51, 0x49, 0x49, 0x47, 0x48, 0x57,
+    0x41, 0x56, 0x6c, 0x71, 0x6e, 0x45, 0x51, 0x52, 0x72, 0x2b, 0x39, 0x32,
+    0x2f, 0x5a, 0x56, 0x2b, 0x7a, 0x6d, 0x45, 0x77, 0x75, 0x33, 0x71, 0x44,
+    0x58, 0x77, 0x4b, 0x39, 0x0a, 0x41, 0x57, 0x62, 0x4b, 0x37, 0x68, 0x57,
+    0x4e, 0x62, 0x36, 0x45, 0x77, 0x6e, 0x4c, 0x32, 0x68, 0x68, 0x5a, 0x36,
+    0x55, 0x4f, 0x76, 0x4e, 0x57, 0x69, 0x41, 0x41, 0x78, 0x7a, 0x39, 0x6a,
+    0x75, 0x61, 0x70, 0x59, 0x43, 0x32, 0x65, 0x30, 0x44, 0x6a, 0x50, 0x74,
+    0x31, 0x62, 0x65, 0x66, 0x71, 0x75, 0x46, 0x55, 0x57, 0x42, 0x52, 0x61,
+    0x61, 0x39, 0x4f, 0x42, 0x65, 0x73, 0x59, 0x6a, 0x41, 0x0a, 0x5a, 0x49,
+    0x56, 0x63, 0x46, 0x55, 0x32, 0x49, 0x78, 0x37, 0x65, 0x36, 0x34, 0x48,
+    0x58, 0x70, 0x72, 0x51, 0x55, 0x39, 0x6e, 0x63, 0x65, 0x4a, 0x53, 0x4f,
+    0x43, 0x37, 0x4b, 0x4d, 0x67, 0x44, 0x34, 0x54, 0x43, 0x54, 0x5a, 0x46,
+    0x35, 0x53, 0x77, 0x46, 0x6c, 0x77, 0x49, 0x6a, 0x56, 0x58, 0x69, 0x49,
+    0x72, 0x78, 0x6c, 0x51, 0x71, 0x44, 0x31, 0x37, 0x77, 0x78, 0x63, 0x77,
+    0x45, 0x30, 0x0a, 0x37, 0x65, 0x39, 0x47, 0x63, 0x65, 0x42, 0x72, 0x41,
+    0x71, 0x67, 0x31, 0x63, 0x6d, 0x75, 0x58, 0x6d, 0x32, 0x62, 0x67, 0x79,
+    0x78, 0x78, 0x35, 0x58, 0x39, 0x67, 0x61, 0x42, 0x47, 0x67, 0x65, 0x52,
+    0x77, 0x4c, 0x6d, 0x6e, 0x57, 0x44, 0x69, 0x4e, 0x70, 0x63, 0x42, 0x33,
+    0x38, 0x34, 0x31, 0x6b, 0x74, 0x2b, 0x2b, 0x5a, 0x38, 0x64, 0x74, 0x64,
+    0x31, 0x6b, 0x37, 0x6a, 0x35, 0x33, 0x57, 0x0a, 0x6b, 0x42, 0x57, 0x55,
+    0x76, 0x45, 0x49, 0x30, 0x45, 0x4d, 0x45, 0x35, 0x2b, 0x62, 0x45, 0x6e,
+    0x50, 0x6e, 0x37, 0x57, 0x69, 0x6e, 0x58, 0x46, 0x73, 0x71, 0x2b, 0x57,
+    0x30, 0x36, 0x4c, 0x65, 0x6d, 0x2b, 0x53, 0x59, 0x76, 0x6e, 0x33, 0x68,
+    0x36, 0x59, 0x47, 0x74, 0x74, 0x6d, 0x2f, 0x38, 0x31, 0x77, 0x37, 0x61,
+    0x34, 0x44, 0x53, 0x77, 0x44, 0x52, 0x70, 0x33, 0x35, 0x2b, 0x4d, 0x49,
+    0x0a, 0x6d, 0x4f, 0x39, 0x59, 0x2b, 0x70, 0x79, 0x45, 0x74, 0x7a, 0x61,
+    0x76, 0x77, 0x74, 0x2b, 0x73, 0x30, 0x76, 0x51, 0x51, 0x42, 0x6e, 0x42,
+    0x78, 0x4e, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x30, 0x49,
+    0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48,
+    0x2f, 0x4d, 0x41, 0x34, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77,
+    0x45, 0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a,
+    0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67,
+    0x51, 0x55, 0x4c, 0x4e, 0x56, 0x51, 0x51, 0x5a, 0x63, 0x56, 0x69, 0x2f,
+    0x43, 0x50, 0x4e, 0x6d, 0x46, 0x62, 0x53, 0x76, 0x74, 0x72, 0x32, 0x5a,
+    0x6e, 0x4a, 0x4d, 0x35, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x0a, 0x4b,
+    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42,
+    0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x46, 0x70, 0x77, 0x66,
+    0x79, 0x7a, 0x64, 0x74, 0x7a, 0x52, 0x50, 0x39, 0x59, 0x5a, 0x52, 0x71,
+    0x53, 0x61, 0x2b, 0x53, 0x37, 0x69, 0x71, 0x38, 0x58, 0x45, 0x4e, 0x33,
+    0x47, 0x48, 0x48, 0x6f, 0x4f, 0x6f, 0x30, 0x48, 0x6e, 0x70, 0x33, 0x44,
+    0x77, 0x51, 0x31, 0x0a, 0x36, 0x43, 0x65, 0x50, 0x62, 0x4a, 0x43, 0x2f,
+    0x6b, 0x52, 0x59, 0x6b, 0x52, 0x6a, 0x35, 0x4b, 0x54, 0x73, 0x34, 0x72,
+    0x46, 0x74, 0x55, 0x4c, 0x55, 0x68, 0x33, 0x38, 0x48, 0x32, 0x65, 0x69,
+    0x41, 0x6b, 0x55, 0x78, 0x54, 0x38, 0x37, 0x7a, 0x2b, 0x67, 0x4f, 0x6e,
+    0x65, 0x5a, 0x31, 0x54, 0x61, 0x74, 0x6e, 0x61, 0x59, 0x7a, 0x72, 0x34,
+    0x67, 0x4e, 0x66, 0x54, 0x6d, 0x65, 0x47, 0x6c, 0x0a, 0x34, 0x62, 0x37,
+    0x55, 0x56, 0x58, 0x47, 0x59, 0x4e, 0x54, 0x71, 0x2b, 0x6b, 0x2b, 0x71,
+    0x75, 0x72, 0x55, 0x4b, 0x79, 0x6b, 0x47, 0x2f, 0x67, 0x2f, 0x43, 0x46,
+    0x4e, 0x4e, 0x57, 0x4d, 0x7a, 0x69, 0x55, 0x6e, 0x57, 0x6d, 0x30, 0x37,
+    0x4b, 0x78, 0x2b, 0x64, 0x4f, 0x43, 0x51, 0x44, 0x33, 0x32, 0x73, 0x66,
+    0x76, 0x6d, 0x57, 0x4b, 0x5a, 0x64, 0x37, 0x61, 0x56, 0x49, 0x6c, 0x36,
+    0x4b, 0x0a, 0x6f, 0x4b, 0x76, 0x30, 0x75, 0x48, 0x69, 0x59, 0x79, 0x6a,
+    0x67, 0x5a, 0x6d, 0x63, 0x6c, 0x79, 0x6e, 0x6e, 0x6a, 0x4e, 0x53, 0x36,
+    0x79, 0x76, 0x47, 0x61, 0x42, 0x7a, 0x45, 0x69, 0x33, 0x38, 0x77, 0x6b,
+    0x47, 0x36, 0x67, 0x5a, 0x48, 0x61, 0x46, 0x6c, 0x6f, 0x78, 0x74, 0x2f,
+    0x6d, 0x30, 0x63, 0x59, 0x41, 0x53, 0x53, 0x4a, 0x6c, 0x79, 0x63, 0x31,
+    0x70, 0x5a, 0x55, 0x38, 0x46, 0x6a, 0x0a, 0x55, 0x6a, 0x50, 0x74, 0x70,
+    0x38, 0x6e, 0x53, 0x4f, 0x51, 0x4a, 0x77, 0x2b, 0x75, 0x43, 0x78, 0x51,
+    0x6d, 0x59, 0x70, 0x71, 0x70, 0x74, 0x52, 0x37, 0x54, 0x42, 0x55, 0x49,
+    0x68, 0x52, 0x66, 0x32, 0x61, 0x73, 0x64, 0x77, 0x65, 0x53, 0x55, 0x38,
+    0x50, 0x6a, 0x31, 0x4b, 0x2f, 0x66, 0x71, 0x79, 0x6e, 0x68, 0x47, 0x31,
+    0x72, 0x69, 0x52, 0x2f, 0x61, 0x59, 0x4e, 0x4b, 0x78, 0x6f, 0x55, 0x0a,
+    0x41, 0x54, 0x36, 0x41, 0x38, 0x45, 0x4b, 0x67, 0x6c, 0x51, 0x64, 0x65,
+    0x62, 0x63, 0x33, 0x4d, 0x53, 0x36, 0x52, 0x46, 0x6a, 0x61, 0x73, 0x53,
+    0x36, 0x4c, 0x50, 0x65, 0x57, 0x75, 0x57, 0x67, 0x66, 0x4f, 0x67, 0x50,
+    0x49, 0x68, 0x31, 0x61, 0x36, 0x56, 0x6b, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6d,
+    0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20,
+    0x4f, 0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76,
+    0x69, 0x63, 0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f,
+    0x6e, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x74,
+    0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
+    0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c,
+    0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,
+    0x20, 0x43, 0x4e, 0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50,
+    0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x43, 0x41, 0x20, 0x4f, 0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53,
+    0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69,
+    0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30,
+    0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20,
+    0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+    0x3a, 0x20, 0x22, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72,
+    0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
+    0x41, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a,
+    0x20, 0x36, 0x39, 0x35, 0x32, 0x39, 0x31, 0x38, 0x31, 0x39, 0x39, 0x32,
+    0x30, 0x33, 0x39, 0x32, 0x30, 0x33, 0x35, 0x36, 0x36, 0x32, 0x39, 0x38,
+    0x39, 0x35, 0x33, 0x37, 0x38, 0x37, 0x37, 0x31, 0x32, 0x39, 0x34, 0x30,
+    0x39, 0x30, 0x39, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38,
+    0x63, 0x3a, 0x63, 0x61, 0x3a, 0x64, 0x63, 0x3a, 0x30, 0x62, 0x3a, 0x32,
+    0x32, 0x3a, 0x63, 0x65, 0x3a, 0x66, 0x35, 0x3a, 0x62, 0x65, 0x3a, 0x37,
+    0x32, 0x3a, 0x61, 0x63, 0x3a, 0x34, 0x31, 0x3a, 0x31, 0x61, 0x3a, 0x31,
+    0x31, 0x3a, 0x61, 0x38, 0x3a, 0x64, 0x38, 0x3a, 0x31, 0x32, 0x0a, 0x23,
+    0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x39, 0x31, 0x3a, 0x63, 0x36,
+    0x3a, 0x64, 0x36, 0x3a, 0x65, 0x65, 0x3a, 0x33, 0x65, 0x3a, 0x38, 0x61,
+    0x3a, 0x63, 0x38, 0x3a, 0x36, 0x33, 0x3a, 0x38, 0x34, 0x3a, 0x65, 0x35,
+    0x3a, 0x34, 0x38, 0x3a, 0x63, 0x32, 0x3a, 0x39, 0x39, 0x3a, 0x32, 0x39,
+    0x3a, 0x35, 0x63, 0x3a, 0x37, 0x35, 0x3a, 0x36, 0x63, 0x3a, 0x38, 0x31,
+    0x3a, 0x37, 0x62, 0x3a, 0x38, 0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x64, 0x3a, 0x37, 0x32, 0x3a, 0x32,
+    0x66, 0x3a, 0x38, 0x31, 0x3a, 0x61, 0x39, 0x3a, 0x63, 0x31, 0x3a, 0x31,
+    0x33, 0x3a, 0x63, 0x30, 0x3a, 0x37, 0x39, 0x3a, 0x31, 0x64, 0x3a, 0x66,
+    0x31, 0x3a, 0x33, 0x36, 0x3a, 0x61, 0x32, 0x3a, 0x39, 0x36, 0x3a, 0x36,
+    0x64, 0x3a, 0x62, 0x32, 0x3a, 0x36, 0x63, 0x3a, 0x39, 0x35, 0x3a, 0x30,
+    0x61, 0x3a, 0x39, 0x37, 0x3a, 0x31, 0x64, 0x3a, 0x62, 0x34, 0x3a, 0x36,
+    0x62, 0x3a, 0x34, 0x31, 0x3a, 0x39, 0x39, 0x3a, 0x66, 0x34, 0x3a, 0x65,
+    0x61, 0x3a, 0x35, 0x34, 0x3a, 0x62, 0x37, 0x3a, 0x38, 0x62, 0x3a, 0x66,
+    0x62, 0x3a, 0x39, 0x66, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45,
+    0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43,
+    0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49,
+    0x45, 0x49, 0x44, 0x43, 0x43, 0x41, 0x77, 0x69, 0x67, 0x41, 0x77, 0x49,
+    0x42, 0x41, 0x67, 0x49, 0x51, 0x4e, 0x45, 0x37, 0x56, 0x56, 0x79, 0x44,
+    0x56, 0x37, 0x65, 0x78, 0x4a, 0x39, 0x43, 0x2f, 0x4f, 0x4e, 0x39, 0x73,
+    0x72, 0x62, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x43,
+    0x42, 0x0a, 0x71, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x54,
+    0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x48,
+    0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x77, 0x67, 0x53, 0x57,
+    0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x6f, 0x4d, 0x43, 0x59, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x43, 0x78, 0x4d, 0x66, 0x0a, 0x51, 0x32, 0x56, 0x79, 0x64,
+    0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62,
+    0x69, 0x42, 0x54, 0x5a, 0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x63,
+    0x79, 0x42, 0x45, 0x61, 0x58, 0x5a, 0x70, 0x63, 0x32, 0x6c, 0x76, 0x62,
+    0x6a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x78, 0x4d, 0x76, 0x4b, 0x47, 0x4d, 0x70, 0x49, 0x44, 0x49, 0x77, 0x0a,
+    0x4d, 0x44, 0x59, 0x67, 0x64, 0x47, 0x68, 0x68, 0x64, 0x33, 0x52, 0x6c,
+    0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30, 0x67,
+    0x52, 0x6d, 0x39, 0x79, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76,
+    0x63, 0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67, 0x64, 0x58, 0x4e, 0x6c,
+    0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6b, 0x78, 0x48, 0x7a, 0x41, 0x64,
+    0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x4d, 0x54, 0x46, 0x6e, 0x52,
+    0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x42, 0x51, 0x63, 0x6d, 0x6c,
+    0x74, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51,
+    0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x59,
+    0x78, 0x4d, 0x54, 0x45, 0x33, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41,
+    0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x59, 0x77, 0x0a, 0x4e, 0x7a,
+    0x45, 0x32, 0x4d, 0x6a, 0x4d, 0x31, 0x4f, 0x54, 0x55, 0x35, 0x57, 0x6a,
+    0x43, 0x42, 0x71, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x54,
+    0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x48,
+    0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x77, 0x67, 0x53, 0x57,
+    0x35, 0x6a, 0x0a, 0x4c, 0x6a, 0x45, 0x6f, 0x4d, 0x43, 0x59, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x66, 0x51, 0x32, 0x56, 0x79, 0x64,
+    0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62,
+    0x69, 0x42, 0x54, 0x5a, 0x58, 0x4a, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x63,
+    0x79, 0x42, 0x45, 0x61, 0x58, 0x5a, 0x70, 0x63, 0x32, 0x6c, 0x76, 0x62,
+    0x6a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x78, 0x4d, 0x76, 0x4b, 0x47, 0x4d, 0x70, 0x49, 0x44, 0x49, 0x77,
+    0x4d, 0x44, 0x59, 0x67, 0x64, 0x47, 0x68, 0x68, 0x64, 0x33, 0x52, 0x6c,
+    0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30, 0x67,
+    0x52, 0x6d, 0x39, 0x79, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76,
+    0x63, 0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67, 0x64, 0x58, 0x4e, 0x6c,
+    0x0a, 0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6b, 0x78, 0x48, 0x7a, 0x41,
+    0x64, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x46, 0x6e, 0x52,
+    0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x42, 0x51, 0x63, 0x6d, 0x6c,
+    0x74, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51,
+    0x67, 0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30,
+    0x47, 0x43, 0x53, 0x71, 0x47, 0x0a, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51,
+    0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77,
+    0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51,
+    0x43, 0x73, 0x6f, 0x50, 0x44, 0x37, 0x67, 0x46, 0x6e, 0x55, 0x6e, 0x4d,
+    0x65, 0x6b, 0x7a, 0x35, 0x32, 0x68, 0x57, 0x58, 0x4d, 0x4a, 0x45, 0x45,
+    0x55, 0x4d, 0x44, 0x53, 0x78, 0x75, 0x61, 0x50, 0x46, 0x73, 0x0a, 0x57,
+    0x30, 0x68, 0x6f, 0x53, 0x56, 0x6b, 0x33, 0x2f, 0x41, 0x73, 0x7a, 0x47,
+    0x63, 0x4a, 0x33, 0x66, 0x38, 0x77, 0x51, 0x4c, 0x5a, 0x55, 0x30, 0x48,
+    0x4f, 0x62, 0x72, 0x54, 0x51, 0x6d, 0x6e, 0x48, 0x4e, 0x4b, 0x34, 0x79,
+    0x5a, 0x63, 0x32, 0x41, 0x72, 0x65, 0x4a, 0x31, 0x43, 0x52, 0x66, 0x42,
+    0x73, 0x44, 0x4d, 0x52, 0x4a, 0x53, 0x55, 0x6a, 0x51, 0x4a, 0x69, 0x62,
+    0x2b, 0x74, 0x61, 0x0a, 0x33, 0x52, 0x47, 0x4e, 0x4b, 0x4a, 0x70, 0x63,
+    0x68, 0x4a, 0x41, 0x51, 0x65, 0x67, 0x32, 0x39, 0x64, 0x47, 0x59, 0x76,
+    0x61, 0x6a, 0x69, 0x67, 0x34, 0x74, 0x56, 0x55, 0x52, 0x4f, 0x73, 0x64,
+    0x42, 0x35, 0x38, 0x48, 0x75, 0x6d, 0x2f, 0x75, 0x36, 0x66, 0x31, 0x4f,
+    0x43, 0x79, 0x6e, 0x31, 0x50, 0x6f, 0x53, 0x67, 0x41, 0x66, 0x47, 0x63,
+    0x71, 0x2f, 0x67, 0x63, 0x66, 0x6f, 0x6d, 0x6b, 0x0a, 0x36, 0x4b, 0x48,
+    0x59, 0x63, 0x57, 0x55, 0x4e, 0x6f, 0x31, 0x46, 0x37, 0x37, 0x72, 0x7a,
+    0x53, 0x49, 0x6d, 0x41, 0x4e, 0x75, 0x56, 0x75, 0x64, 0x33, 0x37, 0x72,
+    0x38, 0x55, 0x56, 0x73, 0x4c, 0x72, 0x35, 0x69, 0x79, 0x36, 0x53, 0x37,
+    0x70, 0x42, 0x4f, 0x68, 0x69, 0x68, 0x39, 0x34, 0x72, 0x79, 0x4e, 0x64,
+    0x4f, 0x77, 0x55, 0x78, 0x6b, 0x48, 0x74, 0x33, 0x50, 0x68, 0x31, 0x69,
+    0x36, 0x0a, 0x53, 0x6b, 0x2f, 0x4b, 0x61, 0x41, 0x63, 0x64, 0x48, 0x4a,
+    0x31, 0x4b, 0x78, 0x74, 0x55, 0x76, 0x6b, 0x63, 0x78, 0x38, 0x63, 0x58,
+    0x49, 0x63, 0x78, 0x63, 0x42, 0x6e, 0x36, 0x7a, 0x4c, 0x39, 0x79, 0x5a,
+    0x4a, 0x63, 0x6c, 0x4e, 0x71, 0x46, 0x77, 0x4a, 0x75, 0x2f, 0x55, 0x33,
+    0x30, 0x72, 0x43, 0x66, 0x53, 0x4d, 0x6e, 0x5a, 0x45, 0x66, 0x6c, 0x32,
+    0x70, 0x53, 0x79, 0x39, 0x34, 0x4a, 0x0a, 0x4e, 0x71, 0x52, 0x33, 0x32,
+    0x48, 0x75, 0x48, 0x55, 0x45, 0x54, 0x56, 0x50, 0x6d, 0x34, 0x70, 0x61,
+    0x66, 0x73, 0x35, 0x53, 0x53, 0x59, 0x65, 0x43, 0x61, 0x57, 0x41, 0x65,
+    0x30, 0x41, 0x74, 0x36, 0x2b, 0x67, 0x6e, 0x68, 0x63, 0x6e, 0x2b, 0x59,
+    0x66, 0x31, 0x2b, 0x35, 0x6e, 0x79, 0x58, 0x48, 0x64, 0x57, 0x64, 0x41,
+    0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x51, 0x6a, 0x42, 0x41, 0x0a,
+    0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42,
+    0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77,
+    0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f,
+    0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x42, 0x30, 0x47,
+    0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x37,
+    0x57, 0x30, 0x58, 0x50, 0x0a, 0x72, 0x38, 0x37, 0x4c, 0x65, 0x76, 0x30,
+    0x78, 0x6b, 0x68, 0x70, 0x71, 0x74, 0x76, 0x4e, 0x47, 0x36, 0x31, 0x64,
+    0x49, 0x55, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f,
+    0x43, 0x41, 0x51, 0x45, 0x41, 0x65, 0x52, 0x48, 0x41, 0x53, 0x37, 0x4f,
+    0x52, 0x74, 0x76, 0x7a, 0x77, 0x36, 0x57, 0x66, 0x55, 0x0a, 0x44, 0x57,
+    0x35, 0x46, 0x76, 0x6c, 0x58, 0x6f, 0x6b, 0x39, 0x4c, 0x4f, 0x41, 0x7a,
+    0x2f, 0x74, 0x32, 0x69, 0x57, 0x77, 0x48, 0x56, 0x66, 0x4c, 0x48, 0x6a,
+    0x70, 0x32, 0x6f, 0x45, 0x7a, 0x73, 0x55, 0x48, 0x62, 0x6f, 0x5a, 0x48,
+    0x49, 0x4d, 0x70, 0x4b, 0x6e, 0x78, 0x75, 0x49, 0x76, 0x57, 0x31, 0x6f,
+    0x65, 0x45, 0x75, 0x7a, 0x4c, 0x6c, 0x51, 0x52, 0x48, 0x41, 0x64, 0x39,
+    0x6d, 0x7a, 0x0a, 0x59, 0x4a, 0x33, 0x72, 0x47, 0x39, 0x58, 0x52, 0x62,
+    0x6b, 0x52, 0x45, 0x71, 0x61, 0x59, 0x42, 0x37, 0x46, 0x56, 0x69, 0x48,
+    0x58, 0x65, 0x34, 0x58, 0x49, 0x35, 0x49, 0x53, 0x58, 0x79, 0x63, 0x4f,
+    0x31, 0x63, 0x52, 0x72, 0x4b, 0x31, 0x7a, 0x4e, 0x34, 0x34, 0x76, 0x65,
+    0x46, 0x79, 0x51, 0x61, 0x45, 0x66, 0x5a, 0x59, 0x47, 0x44, 0x6d, 0x2f,
+    0x41, 0x63, 0x39, 0x49, 0x69, 0x41, 0x58, 0x0a, 0x78, 0x50, 0x63, 0x57,
+    0x36, 0x63, 0x54, 0x59, 0x63, 0x76, 0x6e, 0x49, 0x63, 0x33, 0x7a, 0x66,
+    0x46, 0x69, 0x38, 0x56, 0x71, 0x54, 0x37, 0x39, 0x61, 0x69, 0x65, 0x32,
+    0x6f, 0x65, 0x74, 0x61, 0x75, 0x70, 0x67, 0x66, 0x31, 0x65, 0x4e, 0x4e,
+    0x5a, 0x41, 0x71, 0x64, 0x45, 0x38, 0x68, 0x68, 0x75, 0x76, 0x55, 0x35,
+    0x48, 0x49, 0x65, 0x36, 0x75, 0x4c, 0x31, 0x37, 0x49, 0x6e, 0x2f, 0x32,
+    0x0a, 0x2f, 0x71, 0x78, 0x41, 0x65, 0x65, 0x57, 0x73, 0x45, 0x47, 0x38,
+    0x39, 0x6a, 0x78, 0x74, 0x35, 0x64, 0x6f, 0x76, 0x45, 0x4e, 0x37, 0x4d,
+    0x68, 0x47, 0x49, 0x54, 0x6c, 0x4e, 0x67, 0x44, 0x72, 0x59, 0x79, 0x43,
+    0x5a, 0x75, 0x65, 0x6e, 0x2b, 0x4d, 0x77, 0x53, 0x37, 0x51, 0x63, 0x6a,
+    0x42, 0x41, 0x76, 0x6c, 0x45, 0x59, 0x79, 0x43, 0x65, 0x67, 0x63, 0x35,
+    0x43, 0x30, 0x39, 0x59, 0x2f, 0x0a, 0x4c, 0x48, 0x62, 0x54, 0x59, 0x35,
+    0x78, 0x5a, 0x33, 0x59, 0x2b, 0x6d, 0x34, 0x51, 0x36, 0x67, 0x4c, 0x6b,
+    0x48, 0x33, 0x4c, 0x70, 0x56, 0x48, 0x7a, 0x37, 0x7a, 0x39, 0x4d, 0x2f,
+    0x50, 0x32, 0x43, 0x32, 0x46, 0x2b, 0x66, 0x70, 0x45, 0x72, 0x67, 0x55,
+    0x66, 0x43, 0x4a, 0x7a, 0x44, 0x75, 0x70, 0x78, 0x42, 0x64, 0x4e, 0x34,
+    0x39, 0x63, 0x4f, 0x53, 0x76, 0x6b, 0x42, 0x50, 0x42, 0x37, 0x0a, 0x6a,
+    0x56, 0x61, 0x4d, 0x61, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61,
+    0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35,
+    0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63, 0x29, 0x20,
+    0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
+    0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20,
+    0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61,
+    0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35,
+    0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63, 0x29, 0x20,
+    0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
+    0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20,
+    0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+    0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x22, 0x0a, 0x23, 0x20,
+    0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x33, 0x33, 0x30, 0x33,
+    0x37, 0x36, 0x34, 0x34, 0x31, 0x36, 0x37, 0x35, 0x36, 0x38, 0x30, 0x35,
+    0x38, 0x39, 0x37, 0x30, 0x31, 0x36, 0x34, 0x37, 0x31, 0x39, 0x34, 0x37,
+    0x35, 0x36, 0x37, 0x36, 0x31, 0x30, 0x31, 0x34, 0x35, 0x30, 0x0a, 0x23,
+    0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x62, 0x3a, 0x31, 0x37, 0x3a,
+    0x65, 0x34, 0x3a, 0x33, 0x31, 0x3a, 0x36, 0x37, 0x3a, 0x33, 0x65, 0x3a,
+    0x65, 0x32, 0x3a, 0x30, 0x39, 0x3a, 0x66, 0x65, 0x3a, 0x34, 0x35, 0x3a,
+    0x35, 0x37, 0x3a, 0x39, 0x33, 0x3a, 0x66, 0x33, 0x3a, 0x30, 0x61, 0x3a,
+    0x66, 0x61, 0x3a, 0x31, 0x63, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x34, 0x65, 0x3a, 0x62, 0x36, 0x3a, 0x64, 0x35, 0x3a, 0x37,
+    0x38, 0x3a, 0x34, 0x39, 0x3a, 0x39, 0x62, 0x3a, 0x31, 0x63, 0x3a, 0x63,
+    0x66, 0x3a, 0x35, 0x66, 0x3a, 0x35, 0x38, 0x3a, 0x31, 0x65, 0x3a, 0x61,
+    0x64, 0x3a, 0x35, 0x36, 0x3a, 0x62, 0x65, 0x3a, 0x33, 0x64, 0x3a, 0x39,
+    0x62, 0x3a, 0x36, 0x37, 0x3a, 0x34, 0x34, 0x3a, 0x61, 0x35, 0x3a, 0x65,
+    0x35, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x39, 0x61, 0x3a, 0x63, 0x66, 0x3a, 0x61, 0x62, 0x3a, 0x37, 0x65, 0x3a,
+    0x34, 0x33, 0x3a, 0x63, 0x38, 0x3a, 0x64, 0x38, 0x3a, 0x38, 0x30, 0x3a,
+    0x64, 0x30, 0x3a, 0x36, 0x62, 0x3a, 0x32, 0x36, 0x3a, 0x32, 0x61, 0x3a,
+    0x39, 0x34, 0x3a, 0x64, 0x65, 0x3a, 0x65, 0x65, 0x3a, 0x65, 0x34, 0x3a,
+    0x62, 0x34, 0x3a, 0x36, 0x35, 0x3a, 0x39, 0x39, 0x3a, 0x38, 0x39, 0x3a,
+    0x63, 0x33, 0x3a, 0x64, 0x30, 0x3a, 0x63, 0x61, 0x3a, 0x66, 0x31, 0x3a,
+    0x39, 0x62, 0x3a, 0x61, 0x66, 0x3a, 0x36, 0x34, 0x3a, 0x30, 0x35, 0x3a,
+    0x65, 0x34, 0x3a, 0x31, 0x61, 0x3a, 0x62, 0x37, 0x3a, 0x64, 0x66, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x30, 0x7a, 0x43, 0x43,
+    0x41, 0x37, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51,
+    0x47, 0x4e, 0x72, 0x52, 0x6e, 0x69, 0x5a, 0x39, 0x36, 0x4c, 0x74, 0x4b,
+    0x49, 0x56, 0x6a, 0x4e, 0x7a, 0x47, 0x73, 0x37, 0x53, 0x6a, 0x41, 0x4e,
+    0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
+    0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a, 0x79, 0x6a, 0x45,
+    0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d,
+    0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x6c, 0x5a, 0x6c, 0x63, 0x6d, 0x6c,
+    0x54, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d,
+    0x75, 0x4d, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4c, 0x0a, 0x45, 0x78, 0x5a, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32,
+    0x6c, 0x6e, 0x62, 0x69, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43,
+    0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x4d, 0x54,
+    0x6f, 0x77, 0x4f, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x7a,
+    0x45, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x6a, 0x41, 0x77, 0x4e, 0x69,
+    0x42, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x0a, 0x55, 0x32, 0x6c, 0x6e, 0x62,
+    0x69, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x69, 0x41, 0x74, 0x49,
+    0x45, 0x5a, 0x76, 0x63, 0x69, 0x42, 0x68, 0x64, 0x58, 0x52, 0x6f, 0x62,
+    0x33, 0x4a, 0x70, 0x65, 0x6d, 0x56, 0x6b, 0x49, 0x48, 0x56, 0x7a, 0x5a,
+    0x53, 0x42, 0x76, 0x62, 0x6d, 0x78, 0x35, 0x4d, 0x55, 0x55, 0x77, 0x51,
+    0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x7a, 0x78, 0x57, 0x0a,
+    0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x69, 0x42, 0x44,
+    0x62, 0x47, 0x46, 0x7a, 0x63, 0x79, 0x41, 0x7a, 0x49, 0x46, 0x42, 0x31,
+    0x59, 0x6d, 0x78, 0x70, 0x59, 0x79, 0x42, 0x51, 0x63, 0x6d, 0x6c, 0x74,
+    0x59, 0x58, 0x4a, 0x35, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70,
+    0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67,
+    0x51, 0x58, 0x56, 0x30, 0x0a, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52,
+    0x35, 0x49, 0x43, 0x30, 0x67, 0x52, 0x7a, 0x55, 0x77, 0x48, 0x68, 0x63,
+    0x4e, 0x4d, 0x44, 0x59, 0x78, 0x4d, 0x54, 0x41, 0x34, 0x4d, 0x44, 0x41,
+    0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x59,
+    0x77, 0x4e, 0x7a, 0x45, 0x32, 0x4d, 0x6a, 0x4d, 0x31, 0x4f, 0x54, 0x55,
+    0x35, 0x57, 0x6a, 0x43, 0x42, 0x79, 0x6a, 0x45, 0x4c, 0x0a, 0x4d, 0x41,
+    0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56,
+    0x4d, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x6f, 0x54, 0x44, 0x6c, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57,
+    0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x52,
+    0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78,
+    0x5a, 0x57, 0x0a, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62,
+    0x69, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4f, 0x5a,
+    0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x4d, 0x54, 0x6f, 0x77, 0x4f,
+    0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x7a, 0x45, 0x6f, 0x59,
+    0x79, 0x6b, 0x67, 0x4d, 0x6a, 0x41, 0x77, 0x4e, 0x69, 0x42, 0x57, 0x5a,
+    0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x0a, 0x62, 0x69, 0x77, 0x67,
+    0x53, 0x57, 0x35, 0x6a, 0x4c, 0x69, 0x41, 0x74, 0x49, 0x45, 0x5a, 0x76,
+    0x63, 0x69, 0x42, 0x68, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70,
+    0x65, 0x6d, 0x56, 0x6b, 0x49, 0x48, 0x56, 0x7a, 0x5a, 0x53, 0x42, 0x76,
+    0x62, 0x6d, 0x78, 0x35, 0x4d, 0x55, 0x55, 0x77, 0x51, 0x77, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x44, 0x45, 0x7a, 0x78, 0x57, 0x5a, 0x58, 0x4a, 0x70,
+    0x0a, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x69, 0x42, 0x44, 0x62, 0x47, 0x46,
+    0x7a, 0x63, 0x79, 0x41, 0x7a, 0x49, 0x46, 0x42, 0x31, 0x59, 0x6d, 0x78,
+    0x70, 0x59, 0x79, 0x42, 0x51, 0x63, 0x6d, 0x6c, 0x74, 0x59, 0x58, 0x4a,
+    0x35, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c,
+    0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56,
+    0x30, 0x61, 0x47, 0x39, 0x79, 0x0a, 0x61, 0x58, 0x52, 0x35, 0x49, 0x43,
+    0x30, 0x67, 0x52, 0x7a, 0x55, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41,
+    0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51,
+    0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77,
+    0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51,
+    0x43, 0x76, 0x4a, 0x41, 0x67, 0x49, 0x4b, 0x58, 0x6f, 0x31, 0x0a, 0x6e,
+    0x6d, 0x41, 0x4d, 0x71, 0x75, 0x64, 0x4c, 0x4f, 0x30, 0x37, 0x63, 0x66,
+    0x4c, 0x77, 0x38, 0x52, 0x52, 0x79, 0x37, 0x4b, 0x2b, 0x44, 0x2b, 0x4b,
+    0x51, 0x4c, 0x35, 0x56, 0x77, 0x69, 0x6a, 0x5a, 0x49, 0x55, 0x56, 0x4a,
+    0x2f, 0x58, 0x78, 0x72, 0x63, 0x67, 0x78, 0x69, 0x56, 0x30, 0x69, 0x36,
+    0x43, 0x71, 0x71, 0x70, 0x6b, 0x4b, 0x7a, 0x6a, 0x2f, 0x69, 0x35, 0x56,
+    0x62, 0x65, 0x78, 0x0a, 0x74, 0x30, 0x75, 0x7a, 0x2f, 0x6f, 0x39, 0x2b,
+    0x42, 0x31, 0x66, 0x73, 0x37, 0x30, 0x50, 0x62, 0x5a, 0x6d, 0x49, 0x56,
+    0x59, 0x63, 0x39, 0x67, 0x44, 0x61, 0x54, 0x59, 0x33, 0x76, 0x6a, 0x67,
+    0x77, 0x32, 0x49, 0x49, 0x50, 0x56, 0x51, 0x54, 0x36, 0x30, 0x6e, 0x4b,
+    0x57, 0x56, 0x53, 0x46, 0x4a, 0x75, 0x55, 0x72, 0x6a, 0x78, 0x75, 0x66,
+    0x36, 0x2f, 0x57, 0x68, 0x6b, 0x63, 0x49, 0x7a, 0x0a, 0x53, 0x64, 0x68,
+    0x44, 0x59, 0x32, 0x70, 0x53, 0x53, 0x39, 0x4b, 0x50, 0x36, 0x48, 0x42,
+    0x52, 0x54, 0x64, 0x47, 0x4a, 0x61, 0x58, 0x76, 0x48, 0x63, 0x50, 0x61,
+    0x7a, 0x33, 0x42, 0x4a, 0x30, 0x32, 0x33, 0x74, 0x64, 0x53, 0x31, 0x62,
+    0x54, 0x6c, 0x72, 0x38, 0x56, 0x64, 0x36, 0x47, 0x77, 0x39, 0x4b, 0x49,
+    0x6c, 0x38, 0x71, 0x38, 0x63, 0x6b, 0x6d, 0x63, 0x59, 0x35, 0x66, 0x51,
+    0x47, 0x0a, 0x42, 0x4f, 0x2b, 0x51, 0x75, 0x65, 0x51, 0x41, 0x35, 0x4e,
+    0x30, 0x36, 0x74, 0x52, 0x6e, 0x2f, 0x41, 0x72, 0x72, 0x30, 0x50, 0x4f,
+    0x37, 0x67, 0x69, 0x2b, 0x73, 0x33, 0x69, 0x2b, 0x7a, 0x30, 0x31, 0x36,
+    0x7a, 0x79, 0x39, 0x76, 0x41, 0x39, 0x72, 0x39, 0x31, 0x31, 0x6b, 0x54,
+    0x4d, 0x5a, 0x48, 0x52, 0x78, 0x41, 0x79, 0x33, 0x51, 0x6b, 0x47, 0x53,
+    0x47, 0x54, 0x32, 0x52, 0x54, 0x2b, 0x0a, 0x72, 0x43, 0x70, 0x53, 0x78,
+    0x34, 0x2f, 0x56, 0x42, 0x45, 0x6e, 0x6b, 0x6a, 0x57, 0x4e, 0x48, 0x69,
+    0x44, 0x78, 0x70, 0x67, 0x38, 0x76, 0x2b, 0x52, 0x37, 0x30, 0x72, 0x66,
+    0x6b, 0x2f, 0x46, 0x6c, 0x61, 0x34, 0x4f, 0x6e, 0x64, 0x54, 0x52, 0x51,
+    0x38, 0x42, 0x6e, 0x63, 0x2b, 0x4d, 0x55, 0x43, 0x48, 0x37, 0x6c, 0x50,
+    0x35, 0x39, 0x7a, 0x75, 0x44, 0x4d, 0x4b, 0x7a, 0x31, 0x30, 0x2f, 0x0a,
+    0x4e, 0x49, 0x65, 0x57, 0x69, 0x75, 0x35, 0x54, 0x36, 0x43, 0x55, 0x56,
+    0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x67, 0x62, 0x49, 0x77,
+    0x67, 0x61, 0x38, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54,
+    0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42,
+    0x2f, 0x7a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x42,
+    0x41, 0x66, 0x38, 0x45, 0x0a, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59,
+    0x77, 0x62, 0x51, 0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55,
+    0x48, 0x41, 0x51, 0x77, 0x45, 0x59, 0x54, 0x42, 0x66, 0x6f, 0x56, 0x32,
+    0x67, 0x57, 0x7a, 0x42, 0x5a, 0x4d, 0x46, 0x63, 0x77, 0x56, 0x52, 0x59,
+    0x4a, 0x61, 0x57, 0x31, 0x68, 0x5a, 0x32, 0x55, 0x76, 0x5a, 0x32, 0x6c,
+    0x6d, 0x4d, 0x43, 0x45, 0x77, 0x48, 0x7a, 0x41, 0x48, 0x0a, 0x42, 0x67,
+    0x55, 0x72, 0x44, 0x67, 0x4d, 0x43, 0x47, 0x67, 0x51, 0x55, 0x6a, 0x2b,
+    0x58, 0x54, 0x47, 0x6f, 0x61, 0x73, 0x6a, 0x59, 0x35, 0x72, 0x77, 0x38,
+    0x2b, 0x41, 0x61, 0x74, 0x52, 0x49, 0x47, 0x43, 0x78, 0x37, 0x47, 0x53,
+    0x34, 0x77, 0x4a, 0x52, 0x59, 0x6a, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44,
+    0x6f, 0x76, 0x4c, 0x32, 0x78, 0x76, 0x5a, 0x32, 0x38, 0x75, 0x64, 0x6d,
+    0x56, 0x79, 0x0a, 0x61, 0x58, 0x4e, 0x70, 0x5a, 0x32, 0x34, 0x75, 0x59,
+    0x32, 0x39, 0x74, 0x4c, 0x33, 0x5a, 0x7a, 0x62, 0x47, 0x39, 0x6e, 0x62,
+    0x79, 0x35, 0x6e, 0x61, 0x57, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x48, 0x2f, 0x54, 0x5a,
+    0x61, 0x66, 0x43, 0x33, 0x65, 0x79, 0x37, 0x38, 0x44, 0x41, 0x4a, 0x38,
+    0x30, 0x4d, 0x35, 0x2b, 0x67, 0x4b, 0x76, 0x0a, 0x4d, 0x7a, 0x45, 0x7a,
+    0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42,
+    0x41, 0x51, 0x43, 0x54, 0x4a, 0x45, 0x6f, 0x77, 0x58, 0x32, 0x4c, 0x50,
+    0x32, 0x42, 0x71, 0x59, 0x4c, 0x7a, 0x33, 0x71, 0x33, 0x4a, 0x6b, 0x74,
+    0x76, 0x58, 0x66, 0x32, 0x70, 0x58, 0x6b, 0x69, 0x4f, 0x4f, 0x7a, 0x45,
+    0x0a, 0x70, 0x36, 0x42, 0x34, 0x45, 0x71, 0x31, 0x69, 0x44, 0x6b, 0x56,
+    0x77, 0x5a, 0x4d, 0x58, 0x6e, 0x6c, 0x32, 0x59, 0x74, 0x6d, 0x41, 0x6c,
+    0x2b, 0x58, 0x36, 0x2f, 0x57, 0x7a, 0x43, 0x68, 0x6c, 0x38, 0x67, 0x47,
+    0x71, 0x43, 0x42, 0x70, 0x48, 0x33, 0x76, 0x6e, 0x35, 0x66, 0x4a, 0x4a,
+    0x61, 0x43, 0x47, 0x6b, 0x67, 0x44, 0x64, 0x6b, 0x2b, 0x62, 0x57, 0x34,
+    0x38, 0x44, 0x57, 0x37, 0x59, 0x0a, 0x35, 0x67, 0x61, 0x52, 0x51, 0x42,
+    0x69, 0x35, 0x2b, 0x4d, 0x48, 0x74, 0x33, 0x39, 0x74, 0x42, 0x71, 0x75,
+    0x43, 0x57, 0x49, 0x4d, 0x6e, 0x4e, 0x5a, 0x42, 0x55, 0x34, 0x67, 0x63,
+    0x6d, 0x55, 0x37, 0x71, 0x4b, 0x45, 0x4b, 0x51, 0x73, 0x54, 0x62, 0x34,
+    0x37, 0x62, 0x44, 0x4e, 0x30, 0x6c, 0x41, 0x74, 0x75, 0x6b, 0x69, 0x78,
+    0x6c, 0x45, 0x30, 0x6b, 0x46, 0x36, 0x42, 0x57, 0x6c, 0x4b, 0x0a, 0x57,
+    0x45, 0x39, 0x67, 0x79, 0x6e, 0x36, 0x43, 0x61, 0x67, 0x73, 0x43, 0x71,
+    0x69, 0x55, 0x58, 0x4f, 0x62, 0x58, 0x62, 0x66, 0x2b, 0x65, 0x45, 0x5a,
+    0x53, 0x71, 0x56, 0x69, 0x72, 0x32, 0x47, 0x33, 0x6c, 0x36, 0x42, 0x46,
+    0x6f, 0x4d, 0x74, 0x45, 0x4d, 0x7a, 0x65, 0x2f, 0x61, 0x69, 0x43, 0x4b,
+    0x6d, 0x30, 0x6f, 0x48, 0x77, 0x30, 0x4c, 0x78, 0x4f, 0x58, 0x6e, 0x47,
+    0x69, 0x59, 0x5a, 0x0a, 0x34, 0x66, 0x51, 0x52, 0x62, 0x78, 0x43, 0x31,
+    0x6c, 0x66, 0x7a, 0x6e, 0x51, 0x67, 0x55, 0x79, 0x32, 0x38, 0x36, 0x64,
+    0x55, 0x56, 0x34, 0x6f, 0x74, 0x70, 0x36, 0x46, 0x30, 0x31, 0x76, 0x76,
+    0x70, 0x58, 0x31, 0x46, 0x51, 0x48, 0x4b, 0x4f, 0x74, 0x77, 0x35, 0x72,
+    0x44, 0x67, 0x62, 0x37, 0x4d, 0x7a, 0x56, 0x49, 0x63, 0x62, 0x69, 0x64,
+    0x4a, 0x34, 0x76, 0x45, 0x5a, 0x56, 0x38, 0x4e, 0x0a, 0x68, 0x6e, 0x61,
+    0x63, 0x52, 0x48, 0x72, 0x32, 0x6c, 0x56, 0x7a, 0x32, 0x58, 0x54, 0x49,
+    0x49, 0x4d, 0x36, 0x52, 0x55, 0x74, 0x68, 0x67, 0x2f, 0x61, 0x46, 0x7a,
+    0x79, 0x51, 0x6b, 0x71, 0x46, 0x4f, 0x46, 0x53, 0x44, 0x58, 0x39, 0x48,
+    0x6f, 0x4c, 0x50, 0x4b, 0x73, 0x45, 0x64, 0x61, 0x6f, 0x37, 0x57, 0x4e,
+    0x71, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65,
+    0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f,
+    0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+    0x20, 0x4f, 0x3d, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41,
+    0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x43,
+    0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x43, 0x4f, 0x4d, 0x4f,
+    0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65,
+    0x64, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22,
+    0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65,
+    0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x30, 0x34, 0x33, 0x35, 0x30,
+    0x35, 0x31, 0x33, 0x36, 0x34, 0x38, 0x32, 0x34, 0x39, 0x32, 0x33, 0x32,
+    0x39, 0x34, 0x31, 0x39, 0x39, 0x38, 0x35, 0x30, 0x38, 0x39, 0x38, 0x35,
+    0x38, 0x33, 0x34, 0x34, 0x36, 0x34, 0x35, 0x37, 0x33, 0x0a, 0x23, 0x20,
+    0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x35, 0x63, 0x3a, 0x34, 0x38, 0x3a, 0x64,
+    0x63, 0x3a, 0x66, 0x37, 0x3a, 0x34, 0x32, 0x3a, 0x37, 0x32, 0x3a, 0x65,
+    0x63, 0x3a, 0x35, 0x36, 0x3a, 0x39, 0x34, 0x3a, 0x36, 0x64, 0x3a, 0x31,
+    0x63, 0x3a, 0x63, 0x63, 0x3a, 0x37, 0x31, 0x3a, 0x33, 0x35, 0x3a, 0x38,
+    0x30, 0x3a, 0x37, 0x35, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x36, 0x36, 0x3a, 0x33, 0x31, 0x3a, 0x62, 0x66, 0x3a, 0x39, 0x65,
+    0x3a, 0x66, 0x37, 0x3a, 0x34, 0x66, 0x3a, 0x39, 0x65, 0x3a, 0x62, 0x36,
+    0x3a, 0x63, 0x39, 0x3a, 0x64, 0x35, 0x3a, 0x61, 0x36, 0x3a, 0x30, 0x63,
+    0x3a, 0x62, 0x61, 0x3a, 0x36, 0x61, 0x3a, 0x62, 0x65, 0x3a, 0x64, 0x31,
+    0x3a, 0x66, 0x37, 0x3a, 0x62, 0x64, 0x3a, 0x65, 0x66, 0x3a, 0x37, 0x62,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30,
+    0x63, 0x3a, 0x32, 0x63, 0x3a, 0x64, 0x36, 0x3a, 0x33, 0x64, 0x3a, 0x66,
+    0x37, 0x3a, 0x38, 0x30, 0x3a, 0x36, 0x66, 0x3a, 0x61, 0x33, 0x3a, 0x39,
+    0x39, 0x3a, 0x65, 0x64, 0x3a, 0x65, 0x38, 0x3a, 0x30, 0x39, 0x3a, 0x31,
+    0x31, 0x3a, 0x36, 0x62, 0x3a, 0x35, 0x37, 0x3a, 0x35, 0x62, 0x3a, 0x66,
+    0x38, 0x3a, 0x37, 0x39, 0x3a, 0x38, 0x39, 0x3a, 0x66, 0x30, 0x3a, 0x36,
+    0x35, 0x3a, 0x31, 0x38, 0x3a, 0x66, 0x39, 0x3a, 0x38, 0x30, 0x3a, 0x38,
+    0x63, 0x3a, 0x38, 0x36, 0x3a, 0x30, 0x35, 0x3a, 0x30, 0x33, 0x3a, 0x31,
+    0x37, 0x3a, 0x38, 0x62, 0x3a, 0x61, 0x66, 0x3a, 0x36, 0x36, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x48, 0x54, 0x43, 0x43, 0x41,
+    0x77, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x54,
+    0x6f, 0x45, 0x74, 0x69, 0x6f, 0x4a, 0x6c, 0x34, 0x41, 0x73, 0x43, 0x37,
+    0x6a, 0x34, 0x31, 0x41, 0x6b, 0x62, 0x6c, 0x50, 0x54, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x55, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a, 0x67, 0x54, 0x45, 0x4c,
+    0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43,
+    0x52, 0x30, 0x49, 0x78, 0x47, 0x7a, 0x41, 0x5a, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x67, 0x54, 0x45, 0x6b, 0x64, 0x79, 0x5a, 0x57, 0x46, 0x30,
+    0x5a, 0x58, 0x49, 0x67, 0x54, 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6c,
+    0x63, 0x33, 0x52, 0x6c, 0x63, 0x6a, 0x45, 0x51, 0x4d, 0x41, 0x34, 0x47,
+    0x0a, 0x41, 0x31, 0x55, 0x45, 0x42, 0x78, 0x4d, 0x48, 0x55, 0x32, 0x46,
+    0x73, 0x5a, 0x6d, 0x39, 0x79, 0x5a, 0x44, 0x45, 0x61, 0x4d, 0x42, 0x67,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x52, 0x51, 0x30, 0x39,
+    0x4e, 0x54, 0x30, 0x52, 0x50, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x45, 0x78,
+    0x70, 0x62, 0x57, 0x6c, 0x30, 0x5a, 0x57, 0x51, 0x78, 0x4a, 0x7a, 0x41,
+    0x6c, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x4d, 0x54, 0x48, 0x6b,
+    0x4e, 0x50, 0x54, 0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57,
+    0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d,
+    0x6c, 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4e, 0x6a,
+    0x45, 0x79, 0x4d, 0x44, 0x45, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x0a, 0x4d,
+    0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x79, 0x4f, 0x54, 0x45, 0x79, 0x4d,
+    0x7a, 0x45, 0x79, 0x4d, 0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c, 0x61, 0x4d,
+    0x49, 0x47, 0x42, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x48, 0x51, 0x6a, 0x45, 0x62, 0x4d,
+    0x42, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, 0x4d, 0x53, 0x52,
+    0x33, 0x4a, 0x6c, 0x0a, 0x59, 0x58, 0x52, 0x6c, 0x63, 0x69, 0x42, 0x4e,
+    0x59, 0x57, 0x35, 0x6a, 0x61, 0x47, 0x56, 0x7a, 0x64, 0x47, 0x56, 0x79,
+    0x4d, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48,
+    0x45, 0x77, 0x64, 0x54, 0x59, 0x57, 0x78, 0x6d, 0x62, 0x33, 0x4a, 0x6b,
+    0x4d, 0x52, 0x6f, 0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b,
+    0x45, 0x78, 0x46, 0x44, 0x54, 0x30, 0x31, 0x50, 0x0a, 0x52, 0x45, 0x38,
+    0x67, 0x51, 0x30, 0x45, 0x67, 0x54, 0x47, 0x6c, 0x74, 0x61, 0x58, 0x52,
+    0x6c, 0x5a, 0x44, 0x45, 0x6e, 0x4d, 0x43, 0x55, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x41, 0x78, 0x4d, 0x65, 0x51, 0x30, 0x39, 0x4e, 0x54, 0x30, 0x52,
+    0x50, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c,
+    0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56,
+    0x30, 0x0a, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x49,
+    0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41,
+    0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43, 0x67,
+    0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x30, 0x45, 0x43, 0x4c, 0x69, 0x33,
+    0x4c, 0x6a, 0x6b, 0x52, 0x76, 0x33, 0x0a, 0x55, 0x63, 0x45, 0x62, 0x56,
+    0x41, 0x53, 0x59, 0x30, 0x36, 0x6d, 0x2f, 0x77, 0x65, 0x61, 0x4b, 0x58,
+    0x54, 0x75, 0x48, 0x2b, 0x37, 0x75, 0x49, 0x7a, 0x67, 0x33, 0x6a, 0x4c,
+    0x7a, 0x38, 0x47, 0x6c, 0x76, 0x43, 0x69, 0x4b, 0x56, 0x43, 0x5a, 0x72,
+    0x74, 0x73, 0x37, 0x6f, 0x56, 0x65, 0x77, 0x64, 0x46, 0x46, 0x78, 0x7a,
+    0x65, 0x31, 0x43, 0x6b, 0x55, 0x31, 0x42, 0x2f, 0x71, 0x6e, 0x49, 0x0a,
+    0x32, 0x47, 0x71, 0x47, 0x64, 0x30, 0x53, 0x37, 0x57, 0x57, 0x61, 0x58,
+    0x55, 0x46, 0x36, 0x30, 0x31, 0x43, 0x78, 0x77, 0x52, 0x4d, 0x2f, 0x61,
+    0x4e, 0x35, 0x56, 0x43, 0x61, 0x54, 0x77, 0x77, 0x78, 0x48, 0x47, 0x7a,
+    0x55, 0x76, 0x41, 0x68, 0x54, 0x61, 0x48, 0x59, 0x75, 0x6a, 0x6c, 0x38,
+    0x48, 0x4a, 0x36, 0x6a, 0x4a, 0x4a, 0x33, 0x79, 0x67, 0x78, 0x61, 0x59,
+    0x71, 0x68, 0x5a, 0x38, 0x0a, 0x51, 0x35, 0x73, 0x56, 0x57, 0x37, 0x65,
+    0x75, 0x4e, 0x4a, 0x48, 0x2b, 0x31, 0x47, 0x49, 0x6d, 0x47, 0x45, 0x61,
+    0x61, 0x50, 0x2b, 0x76, 0x42, 0x2b, 0x66, 0x47, 0x51, 0x56, 0x2b, 0x75,
+    0x73, 0x65, 0x67, 0x32, 0x4c, 0x32, 0x33, 0x49, 0x77, 0x61, 0x6d, 0x62,
+    0x56, 0x34, 0x45, 0x61, 0x6a, 0x63, 0x4e, 0x78, 0x6f, 0x32, 0x66, 0x38,
+    0x45, 0x53, 0x49, 0x6c, 0x33, 0x33, 0x72, 0x58, 0x70, 0x0a, 0x2b, 0x32,
+    0x64, 0x74, 0x51, 0x65, 0x6d, 0x38, 0x4f, 0x62, 0x30, 0x79, 0x32, 0x57,
+    0x49, 0x43, 0x38, 0x62, 0x47, 0x6f, 0x50, 0x57, 0x34, 0x33, 0x6e, 0x4f,
+    0x49, 0x76, 0x34, 0x74, 0x4f, 0x69, 0x4a, 0x6f, 0x76, 0x47, 0x75, 0x46,
+    0x56, 0x44, 0x69, 0x4f, 0x45, 0x6a, 0x50, 0x71, 0x58, 0x53, 0x4a, 0x44,
+    0x6c, 0x71, 0x52, 0x36, 0x73, 0x41, 0x31, 0x4b, 0x47, 0x7a, 0x71, 0x53,
+    0x58, 0x2b, 0x0a, 0x44, 0x54, 0x2b, 0x6e, 0x48, 0x62, 0x72, 0x54, 0x55,
+    0x63, 0x45, 0x4c, 0x70, 0x4e, 0x71, 0x73, 0x4f, 0x4f, 0x39, 0x56, 0x55,
+    0x43, 0x51, 0x46, 0x5a, 0x55, 0x61, 0x54, 0x4e, 0x45, 0x38, 0x74, 0x6a,
+    0x61, 0x33, 0x47, 0x31, 0x43, 0x45, 0x5a, 0x30, 0x6f, 0x37, 0x4b, 0x42,
+    0x57, 0x46, 0x78, 0x42, 0x33, 0x4e, 0x48, 0x35, 0x59, 0x6f, 0x5a, 0x45,
+    0x72, 0x30, 0x45, 0x54, 0x63, 0x35, 0x4f, 0x0a, 0x6e, 0x4b, 0x56, 0x49,
+    0x72, 0x4c, 0x73, 0x6d, 0x39, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42,
+    0x6f, 0x34, 0x47, 0x4f, 0x4d, 0x49, 0x47, 0x4c, 0x4d, 0x42, 0x30, 0x47,
+    0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x51, 0x4c,
+    0x57, 0x4f, 0x57, 0x4c, 0x78, 0x6b, 0x77, 0x56, 0x4e, 0x36, 0x52, 0x41,
+    0x71, 0x54, 0x43, 0x70, 0x49, 0x62, 0x35, 0x48, 0x4e, 0x6c, 0x70, 0x57,
+    0x0a, 0x2f, 0x7a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59,
+    0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48,
+    0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x42,
+    0x4a, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x38, 0x45, 0x51, 0x6a, 0x42,
+    0x41, 0x4d, 0x44, 0x36, 0x67, 0x0a, 0x50, 0x4b, 0x41, 0x36, 0x68, 0x6a,
+    0x68, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x59, 0x33,
+    0x4a, 0x73, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x57, 0x39, 0x6b, 0x62, 0x32,
+    0x4e, 0x68, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x44, 0x54, 0x30,
+    0x31, 0x50, 0x52, 0x45, 0x39, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57,
+    0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x0a, 0x51,
+    0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4c,
+    0x6d, 0x4e, 0x79, 0x62, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41,
+    0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x50, 0x70, 0x69, 0x65, 0x6d,
+    0x2f, 0x59, 0x62, 0x36, 0x64, 0x63, 0x35, 0x74, 0x33, 0x69, 0x75, 0x48,
+    0x58, 0x49, 0x59, 0x0a, 0x53, 0x64, 0x4f, 0x48, 0x35, 0x45, 0x4f, 0x43,
+    0x36, 0x7a, 0x2f, 0x4a, 0x71, 0x76, 0x57, 0x6f, 0x74, 0x65, 0x39, 0x56,
+    0x66, 0x43, 0x46, 0x53, 0x5a, 0x66, 0x6e, 0x56, 0x44, 0x65, 0x46, 0x73,
+    0x39, 0x44, 0x36, 0x4d, 0x6b, 0x33, 0x4f, 0x52, 0x4c, 0x67, 0x4c, 0x45,
+    0x54, 0x67, 0x64, 0x78, 0x62, 0x38, 0x43, 0x50, 0x4f, 0x47, 0x45, 0x49,
+    0x71, 0x42, 0x36, 0x42, 0x43, 0x73, 0x41, 0x76, 0x0a, 0x49, 0x43, 0x39,
+    0x42, 0x69, 0x35, 0x48, 0x63, 0x53, 0x45, 0x57, 0x38, 0x38, 0x63, 0x62,
+    0x65, 0x75, 0x6e, 0x5a, 0x72, 0x4d, 0x38, 0x67, 0x41, 0x4c, 0x54, 0x46,
+    0x47, 0x54, 0x4f, 0x33, 0x6e, 0x6e, 0x63, 0x2b, 0x49, 0x6c, 0x50, 0x38,
+    0x7a, 0x77, 0x46, 0x62, 0x6f, 0x4a, 0x49, 0x59, 0x6d, 0x75, 0x4e, 0x67,
+    0x34, 0x4f, 0x4e, 0x38, 0x71, 0x61, 0x39, 0x30, 0x53, 0x7a, 0x4d, 0x63,
+    0x2f, 0x0a, 0x52, 0x78, 0x64, 0x4d, 0x6f, 0x73, 0x49, 0x47, 0x6c, 0x67,
+    0x6e, 0x57, 0x32, 0x2f, 0x34, 0x2f, 0x50, 0x45, 0x5a, 0x42, 0x33, 0x31,
+    0x6a, 0x69, 0x56, 0x67, 0x38, 0x38, 0x4f, 0x38, 0x45, 0x63, 0x6b, 0x7a,
+    0x58, 0x5a, 0x4f, 0x46, 0x4b, 0x73, 0x37, 0x73, 0x6a, 0x73, 0x4c, 0x6a,
+    0x42, 0x4f, 0x6c, 0x44, 0x57, 0x30, 0x4a, 0x42, 0x39, 0x4c, 0x65, 0x47,
+    0x6e, 0x61, 0x38, 0x67, 0x49, 0x34, 0x0a, 0x7a, 0x4a, 0x56, 0x53, 0x6b,
+    0x2f, 0x42, 0x77, 0x4a, 0x56, 0x6d, 0x63, 0x49, 0x47, 0x66, 0x45, 0x37,
+    0x76, 0x6d, 0x4c, 0x56, 0x32, 0x48, 0x30, 0x6b, 0x6e, 0x5a, 0x39, 0x50,
+    0x34, 0x53, 0x4e, 0x56, 0x62, 0x66, 0x6f, 0x35, 0x61, 0x7a, 0x56, 0x38,
+    0x66, 0x55, 0x5a, 0x56, 0x71, 0x5a, 0x61, 0x2b, 0x35, 0x41, 0x63, 0x72,
+    0x35, 0x50, 0x72, 0x35, 0x52, 0x7a, 0x55, 0x5a, 0x35, 0x64, 0x64, 0x0a,
+    0x42, 0x41, 0x36, 0x2b, 0x43, 0x34, 0x4f, 0x6d, 0x46, 0x34, 0x4f, 0x35,
+    0x4d, 0x42, 0x4b, 0x67, 0x78, 0x54, 0x4d, 0x56, 0x42, 0x62, 0x6b, 0x4e,
+    0x2b, 0x38, 0x63, 0x46, 0x64, 0x75, 0x50, 0x59, 0x53, 0x6f, 0x33, 0x38,
+    0x4e, 0x42, 0x65, 0x6a, 0x78, 0x69, 0x45, 0x6f, 0x76, 0x6a, 0x42, 0x46,
+    0x4d, 0x52, 0x37, 0x48, 0x65, 0x4c, 0x35, 0x59, 0x59, 0x54, 0x69, 0x73,
+    0x4f, 0x2b, 0x49, 0x42, 0x0a, 0x5a, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x53, 0x6f,
+    0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+    0x73, 0x20, 0x4c, 0x2e, 0x4c, 0x2e, 0x43, 0x2e, 0x0a, 0x23, 0x20, 0x53,
+    0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x4e,
+    0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74,
+    0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x4f, 0x3d, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+    0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x4c,
+    0x2e, 0x4c, 0x2e, 0x43, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20,
+    0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x31, 0x36, 0x36, 0x39,
+    0x37, 0x39, 0x31, 0x35, 0x31, 0x35, 0x32, 0x39, 0x33, 0x37, 0x34, 0x39,
+    0x37, 0x34, 0x39, 0x30, 0x34, 0x33, 0x37, 0x35, 0x35, 0x36, 0x33, 0x38,
+    0x36, 0x38, 0x31, 0x32, 0x34, 0x38, 0x37, 0x39, 0x30, 0x34, 0x0a, 0x23,
+    0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x33, 0x3a, 0x66, 0x33, 0x3a,
+    0x61, 0x36, 0x3a, 0x31, 0x36, 0x3a, 0x63, 0x30, 0x3a, 0x66, 0x61, 0x3a,
+    0x36, 0x62, 0x3a, 0x31, 0x64, 0x3a, 0x35, 0x39, 0x3a, 0x62, 0x31, 0x3a,
+    0x32, 0x64, 0x3a, 0x39, 0x36, 0x3a, 0x34, 0x64, 0x3a, 0x30, 0x65, 0x3a,
+    0x31, 0x31, 0x3a, 0x32, 0x65, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x37, 0x34, 0x3a, 0x66, 0x38, 0x3a, 0x61, 0x33, 0x3a, 0x63,
+    0x33, 0x3a, 0x65, 0x66, 0x3a, 0x65, 0x37, 0x3a, 0x62, 0x33, 0x3a, 0x39,
+    0x30, 0x3a, 0x30, 0x36, 0x3a, 0x34, 0x62, 0x3a, 0x38, 0x33, 0x3a, 0x39,
+    0x30, 0x3a, 0x33, 0x63, 0x3a, 0x32, 0x31, 0x3a, 0x36, 0x34, 0x3a, 0x36,
+    0x30, 0x3a, 0x32, 0x30, 0x3a, 0x65, 0x35, 0x3a, 0x64, 0x66, 0x3a, 0x63,
+    0x65, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x31, 0x35, 0x3a, 0x66, 0x30, 0x3a, 0x62, 0x61, 0x3a, 0x30, 0x30, 0x3a,
+    0x61, 0x33, 0x3a, 0x61, 0x63, 0x3a, 0x37, 0x61, 0x3a, 0x66, 0x33, 0x3a,
+    0x61, 0x63, 0x3a, 0x38, 0x38, 0x3a, 0x34, 0x63, 0x3a, 0x30, 0x37, 0x3a,
+    0x32, 0x62, 0x3a, 0x31, 0x30, 0x3a, 0x31, 0x31, 0x3a, 0x61, 0x30, 0x3a,
+    0x37, 0x37, 0x3a, 0x62, 0x64, 0x3a, 0x37, 0x37, 0x3a, 0x63, 0x30, 0x3a,
+    0x39, 0x37, 0x3a, 0x66, 0x34, 0x3a, 0x30, 0x31, 0x3a, 0x36, 0x34, 0x3a,
+    0x62, 0x32, 0x3a, 0x66, 0x38, 0x3a, 0x35, 0x39, 0x3a, 0x38, 0x61, 0x3a,
+    0x62, 0x64, 0x3a, 0x38, 0x33, 0x3a, 0x38, 0x36, 0x3a, 0x30, 0x63, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x35, 0x6a, 0x43, 0x43,
+    0x41, 0x73, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51,
+    0x56, 0x38, 0x73, 0x7a, 0x62, 0x38, 0x4a, 0x63, 0x46, 0x75, 0x5a, 0x48,
+    0x46, 0x68, 0x66, 0x6a, 0x6b, 0x44, 0x46, 0x6f, 0x34, 0x44, 0x41, 0x4e,
+    0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
+    0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x69, 0x0a, 0x4d, 0x51, 0x73,
+    0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a,
+    0x56, 0x55, 0x7a, 0x45, 0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x68, 0x4d, 0x59, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39,
+    0x79, 0x61, 0x79, 0x42, 0x54, 0x62, 0x32, 0x78, 0x31, 0x64, 0x47, 0x6c,
+    0x76, 0x62, 0x6e, 0x4d, 0x67, 0x54, 0x43, 0x35, 0x4d, 0x4c, 0x6b, 0x4d,
+    0x75, 0x0a, 0x4d, 0x54, 0x41, 0x77, 0x4c, 0x67, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x44, 0x45, 0x79, 0x64, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33,
+    0x4a, 0x72, 0x49, 0x46, 0x4e, 0x76, 0x62, 0x48, 0x56, 0x30, 0x61, 0x57,
+    0x39, 0x75, 0x63, 0x79, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57,
+    0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5a, 0x53, 0x42, 0x42, 0x64, 0x58,
+    0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x0a, 0x64, 0x48, 0x6b, 0x77, 0x48,
+    0x68, 0x63, 0x4e, 0x4d, 0x44, 0x59, 0x78, 0x4d, 0x6a, 0x41, 0x78, 0x4d,
+    0x44, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d,
+    0x6a, 0x6b, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x6a, 0x4d, 0x31, 0x4f,
+    0x54, 0x55, 0x35, 0x57, 0x6a, 0x42, 0x69, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x0a,
+    0x55, 0x7a, 0x45, 0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x68, 0x4d, 0x59, 0x54, 0x6d, 0x56, 0x30, 0x64, 0x32, 0x39, 0x79,
+    0x61, 0x79, 0x42, 0x54, 0x62, 0x32, 0x78, 0x31, 0x64, 0x47, 0x6c, 0x76,
+    0x62, 0x6e, 0x4d, 0x67, 0x54, 0x43, 0x35, 0x4d, 0x4c, 0x6b, 0x4d, 0x75,
+    0x4d, 0x54, 0x41, 0x77, 0x4c, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44,
+    0x45, 0x79, 0x64, 0x4f, 0x0a, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4a,
+    0x72, 0x49, 0x46, 0x4e, 0x76, 0x62, 0x48, 0x56, 0x30, 0x61, 0x57, 0x39,
+    0x75, 0x63, 0x79, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a,
+    0x70, 0x59, 0x32, 0x46, 0x30, 0x5a, 0x53, 0x42, 0x42, 0x64, 0x58, 0x52,
+    0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x67, 0x67, 0x45,
+    0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x0a, 0x53, 0x49,
+    0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34,
+    0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f,
+    0x49, 0x42, 0x41, 0x51, 0x44, 0x6b, 0x76, 0x48, 0x36, 0x53, 0x4d, 0x47,
+    0x33, 0x47, 0x32, 0x49, 0x34, 0x72, 0x43, 0x37, 0x78, 0x47, 0x7a, 0x75,
+    0x41, 0x6e, 0x6c, 0x74, 0x37, 0x65, 0x2b, 0x66, 0x6f, 0x53, 0x30, 0x7a,
+    0x77, 0x7a, 0x0a, 0x63, 0x37, 0x4d, 0x45, 0x4c, 0x37, 0x78, 0x78, 0x6a,
+    0x4f, 0x57, 0x66, 0x74, 0x69, 0x4a, 0x67, 0x50, 0x6c, 0x39, 0x64, 0x7a,
+    0x67, 0x6e, 0x2f, 0x67, 0x67, 0x77, 0x62, 0x6d, 0x6c, 0x46, 0x51, 0x47,
+    0x69, 0x61, 0x4a, 0x33, 0x64, 0x56, 0x68, 0x58, 0x52, 0x6e, 0x63, 0x45,
+    0x67, 0x38, 0x74, 0x43, 0x71, 0x4a, 0x44, 0x58, 0x52, 0x66, 0x51, 0x4e,
+    0x4a, 0x49, 0x67, 0x36, 0x6e, 0x50, 0x50, 0x0a, 0x4f, 0x43, 0x77, 0x47,
+    0x4a, 0x67, 0x6c, 0x36, 0x63, 0x76, 0x66, 0x36, 0x55, 0x44, 0x4c, 0x34,
+    0x77, 0x70, 0x50, 0x54, 0x61, 0x61, 0x49, 0x6a, 0x7a, 0x6b, 0x47, 0x78,
+    0x7a, 0x4f, 0x54, 0x56, 0x48, 0x7a, 0x62, 0x52, 0x69, 0x6a, 0x72, 0x34,
+    0x6a, 0x47, 0x50, 0x69, 0x46, 0x46, 0x6c, 0x70, 0x37, 0x51, 0x33, 0x54,
+    0x66, 0x32, 0x76, 0x6f, 0x75, 0x41, 0x50, 0x6c, 0x54, 0x32, 0x72, 0x6c,
+    0x0a, 0x6d, 0x47, 0x4e, 0x70, 0x53, 0x41, 0x57, 0x2b, 0x4c, 0x76, 0x38,
+    0x7a, 0x74, 0x75, 0x6d, 0x58, 0x57, 0x57, 0x6e, 0x34, 0x5a, 0x78, 0x6d,
+    0x75, 0x6b, 0x32, 0x47, 0x57, 0x52, 0x42, 0x58, 0x54, 0x63, 0x72, 0x41,
+    0x2f, 0x76, 0x47, 0x70, 0x39, 0x37, 0x45, 0x68, 0x2f, 0x6a, 0x63, 0x4f,
+    0x72, 0x71, 0x6e, 0x45, 0x72, 0x55, 0x32, 0x6c, 0x42, 0x55, 0x7a, 0x53,
+    0x31, 0x73, 0x4c, 0x6e, 0x46, 0x0a, 0x42, 0x67, 0x72, 0x45, 0x73, 0x45,
+    0x58, 0x31, 0x51, 0x56, 0x31, 0x75, 0x69, 0x55, 0x56, 0x37, 0x50, 0x54,
+    0x73, 0x6d, 0x6a, 0x48, 0x54, 0x43, 0x35, 0x64, 0x4c, 0x52, 0x66, 0x62,
+    0x49, 0x52, 0x31, 0x50, 0x74, 0x59, 0x4d, 0x69, 0x4b, 0x61, 0x67, 0x4d,
+    0x6e, 0x63, 0x2f, 0x51, 0x7a, 0x70, 0x66, 0x31, 0x34, 0x44, 0x6c, 0x38,
+    0x34, 0x37, 0x41, 0x42, 0x53, 0x48, 0x4a, 0x33, 0x41, 0x34, 0x0a, 0x71,
+    0x59, 0x35, 0x75, 0x73, 0x79, 0x64, 0x32, 0x6d, 0x46, 0x48, 0x67, 0x42,
+    0x65, 0x4d, 0x68, 0x71, 0x78, 0x72, 0x56, 0x68, 0x53, 0x49, 0x38, 0x4b,
+    0x62, 0x57, 0x61, 0x46, 0x73, 0x57, 0x41, 0x71, 0x50, 0x53, 0x37, 0x61,
+    0x7a, 0x43, 0x50, 0x4c, 0x30, 0x59, 0x43, 0x6f, 0x72, 0x45, 0x4d, 0x49,
+    0x75, 0x44, 0x54, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x67,
+    0x5a, 0x63, 0x77, 0x0a, 0x67, 0x5a, 0x51, 0x77, 0x48, 0x51, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x43, 0x45, 0x77,
+    0x79, 0x66, 0x73, 0x41, 0x31, 0x30, 0x36, 0x59, 0x32, 0x6f, 0x65, 0x71,
+    0x4b, 0x74, 0x43, 0x6e, 0x4c, 0x72, 0x46, 0x41, 0x4d, 0x61, 0x64, 0x4d,
+    0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42,
+    0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x0a, 0x42, 0x6a, 0x41,
+    0x50, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38,
+    0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x46, 0x49,
+    0x47, 0x41, 0x31, 0x55, 0x64, 0x48, 0x77, 0x52, 0x4c, 0x4d, 0x45, 0x6b,
+    0x77, 0x52, 0x36, 0x42, 0x46, 0x6f, 0x45, 0x4f, 0x47, 0x51, 0x57, 0x68,
+    0x30, 0x64, 0x48, 0x41, 0x36, 0x4c, 0x79, 0x39, 0x6a, 0x63, 0x6d, 0x77,
+    0x75, 0x0a, 0x62, 0x6d, 0x56, 0x30, 0x63, 0x32, 0x39, 0x73, 0x63, 0x33,
+    0x4e, 0x73, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x4f, 0x5a, 0x58,
+    0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x55, 0x32, 0x39, 0x73, 0x64, 0x58,
+    0x52, 0x70, 0x62, 0x32, 0x35, 0x7a, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47,
+    0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x56, 0x42, 0x64, 0x58,
+    0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x0a, 0x64, 0x48, 0x6b, 0x75, 0x59,
+    0x33, 0x4a, 0x73, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53,
+    0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41,
+    0x34, 0x49, 0x42, 0x41, 0x51, 0x43, 0x37, 0x72, 0x6b, 0x76, 0x6e, 0x74,
+    0x31, 0x66, 0x72, 0x66, 0x36, 0x6f, 0x74, 0x74, 0x33, 0x4e, 0x48, 0x68,
+    0x57, 0x72, 0x42, 0x35, 0x4b, 0x55, 0x64, 0x35, 0x4f, 0x63, 0x38, 0x0a,
+    0x36, 0x66, 0x52, 0x5a, 0x5a, 0x58, 0x65, 0x31, 0x65, 0x6c, 0x74, 0x61,
+    0x6a, 0x53, 0x55, 0x32, 0x34, 0x48, 0x71, 0x58, 0x4c, 0x6a, 0x6a, 0x41,
+    0x56, 0x32, 0x43, 0x44, 0x6d, 0x41, 0x61, 0x44, 0x6e, 0x37, 0x6c, 0x32,
+    0x65, 0x6d, 0x35, 0x51, 0x34, 0x4c, 0x71, 0x49, 0x4c, 0x50, 0x78, 0x46,
+    0x7a, 0x42, 0x69, 0x77, 0x6d, 0x5a, 0x56, 0x52, 0x44, 0x75, 0x77, 0x64,
+    0x75, 0x49, 0x6a, 0x2f, 0x0a, 0x68, 0x31, 0x41, 0x63, 0x67, 0x73, 0x4c,
+    0x6a, 0x34, 0x44, 0x4b, 0x41, 0x76, 0x36, 0x41, 0x4c, 0x52, 0x38, 0x6a,
+    0x44, 0x4d, 0x65, 0x2b, 0x5a, 0x5a, 0x7a, 0x4b, 0x41, 0x54, 0x78, 0x63,
+    0x68, 0x65, 0x51, 0x78, 0x70, 0x58, 0x4e, 0x35, 0x65, 0x4e, 0x4b, 0x34,
+    0x43, 0x74, 0x53, 0x62, 0x71, 0x55, 0x4e, 0x39, 0x2f, 0x47, 0x47, 0x55,
+    0x73, 0x79, 0x66, 0x4a, 0x6a, 0x34, 0x61, 0x6b, 0x48, 0x0a, 0x2f, 0x6e,
+    0x78, 0x78, 0x48, 0x32, 0x73, 0x7a, 0x4a, 0x47, 0x6f, 0x65, 0x42, 0x66,
+    0x63, 0x46, 0x61, 0x4d, 0x42, 0x71, 0x45, 0x73, 0x73, 0x75, 0x58, 0x6d,
+    0x48, 0x4c, 0x72, 0x69, 0x6a, 0x54, 0x66, 0x73, 0x4b, 0x30, 0x5a, 0x70,
+    0x45, 0x6d, 0x58, 0x7a, 0x77, 0x75, 0x4a, 0x46, 0x2f, 0x4c, 0x57, 0x41,
+    0x2f, 0x72, 0x4b, 0x4f, 0x79, 0x76, 0x45, 0x5a, 0x62, 0x7a, 0x33, 0x48,
+    0x74, 0x76, 0x0a, 0x77, 0x4b, 0x65, 0x49, 0x38, 0x6c, 0x4e, 0x33, 0x73,
+    0x32, 0x42, 0x65, 0x72, 0x71, 0x34, 0x6f, 0x32, 0x6a, 0x55, 0x73, 0x62,
+    0x7a, 0x52, 0x46, 0x30, 0x79, 0x62, 0x68, 0x33, 0x75, 0x78, 0x62, 0x54,
+    0x79, 0x64, 0x72, 0x46, 0x6e, 0x79, 0x39, 0x52, 0x41, 0x51, 0x59, 0x67,
+    0x72, 0x4f, 0x4a, 0x65, 0x52, 0x63, 0x51, 0x63, 0x54, 0x31, 0x36, 0x6f,
+    0x68, 0x5a, 0x4f, 0x39, 0x51, 0x48, 0x4e, 0x0a, 0x70, 0x47, 0x78, 0x6c,
+    0x61, 0x4b, 0x46, 0x4a, 0x64, 0x6c, 0x78, 0x44, 0x79, 0x64, 0x69, 0x38,
+    0x4e, 0x6d, 0x64, 0x73, 0x70, 0x5a, 0x53, 0x31, 0x31, 0x4d, 0x79, 0x35,
+    0x76, 0x57, 0x6f, 0x31, 0x56, 0x69, 0x48, 0x65, 0x32, 0x4d, 0x50, 0x72,
+    0x2b, 0x38, 0x75, 0x6b, 0x59, 0x45, 0x79, 0x77, 0x56, 0x61, 0x43, 0x67,
+    0x65, 0x31, 0x65, 0x79, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e,
+    0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73,
+    0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x43, 0x4f, 0x4d,
+    0x4f, 0x44, 0x4f, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x43, 0x4f,
+    0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69,
+    0x74, 0x65, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f,
+    0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x43, 0x4f, 0x4d, 0x4f, 0x44,
+    0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64,
+    0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x43,
+    0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a, 0x23,
+    0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x34, 0x31, 0x35,
+    0x37, 0x38, 0x32, 0x38, 0x33, 0x38, 0x36, 0x37, 0x30, 0x38, 0x36, 0x36,
+    0x39, 0x32, 0x36, 0x33, 0x38, 0x32, 0x35, 0x36, 0x39, 0x32, 0x31, 0x35,
+    0x38, 0x39, 0x37, 0x30, 0x37, 0x39, 0x33, 0x38, 0x30, 0x39, 0x30, 0x0a,
+    0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x37, 0x63, 0x3a, 0x36, 0x32,
+    0x3a, 0x66, 0x66, 0x3a, 0x37, 0x34, 0x3a, 0x39, 0x64, 0x3a, 0x33, 0x31,
+    0x3a, 0x35, 0x33, 0x3a, 0x35, 0x65, 0x3a, 0x36, 0x38, 0x3a, 0x34, 0x61,
+    0x3a, 0x64, 0x35, 0x3a, 0x37, 0x38, 0x3a, 0x61, 0x61, 0x3a, 0x31, 0x65,
+    0x3a, 0x62, 0x66, 0x3a, 0x32, 0x33, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x39, 0x66, 0x3a, 0x37, 0x34, 0x3a, 0x34, 0x65, 0x3a,
+    0x39, 0x66, 0x3a, 0x32, 0x62, 0x3a, 0x34, 0x64, 0x3a, 0x62, 0x61, 0x3a,
+    0x65, 0x63, 0x3a, 0x30, 0x66, 0x3a, 0x33, 0x31, 0x3a, 0x32, 0x63, 0x3a,
+    0x35, 0x30, 0x3a, 0x62, 0x36, 0x3a, 0x35, 0x36, 0x3a, 0x33, 0x62, 0x3a,
+    0x38, 0x65, 0x3a, 0x32, 0x64, 0x3a, 0x39, 0x33, 0x3a, 0x63, 0x33, 0x3a,
+    0x31, 0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x31, 0x37, 0x3a, 0x39, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x37, 0x61,
+    0x3a, 0x30, 0x36, 0x3a, 0x31, 0x34, 0x3a, 0x35, 0x34, 0x3a, 0x39, 0x37,
+    0x3a, 0x38, 0x39, 0x3a, 0x61, 0x64, 0x3a, 0x63, 0x65, 0x3a, 0x32, 0x66,
+    0x3a, 0x38, 0x66, 0x3a, 0x33, 0x34, 0x3a, 0x66, 0x37, 0x3a, 0x66, 0x30,
+    0x3a, 0x62, 0x36, 0x3a, 0x36, 0x64, 0x3a, 0x30, 0x66, 0x3a, 0x33, 0x61,
+    0x3a, 0x65, 0x33, 0x3a, 0x61, 0x33, 0x3a, 0x62, 0x38, 0x3a, 0x34, 0x64,
+    0x3a, 0x32, 0x31, 0x3a, 0x65, 0x63, 0x3a, 0x31, 0x35, 0x3a, 0x64, 0x62,
+    0x3a, 0x62, 0x61, 0x3a, 0x34, 0x66, 0x3a, 0x61, 0x64, 0x3a, 0x63, 0x37,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x69, 0x54, 0x43,
+    0x43, 0x41, 0x67, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
+    0x51, 0x48, 0x30, 0x65, 0x76, 0x71, 0x6d, 0x49, 0x41, 0x63, 0x46, 0x42,
+    0x55, 0x54, 0x41, 0x47, 0x65, 0x6d, 0x32, 0x4f, 0x5a, 0x4b, 0x6a, 0x41,
+    0x4b, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51,
+    0x44, 0x41, 0x7a, 0x43, 0x42, 0x68, 0x54, 0x45, 0x4c, 0x0a, 0x4d, 0x41,
+    0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x52, 0x30,
+    0x49, 0x78, 0x47, 0x7a, 0x41, 0x5a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x67, 0x54, 0x45, 0x6b, 0x64, 0x79, 0x5a, 0x57, 0x46, 0x30, 0x5a, 0x58,
+    0x49, 0x67, 0x54, 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6c, 0x63, 0x33,
+    0x52, 0x6c, 0x63, 0x6a, 0x45, 0x51, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x0a, 0x42, 0x78, 0x4d, 0x48, 0x55, 0x32, 0x46, 0x73, 0x5a,
+    0x6d, 0x39, 0x79, 0x5a, 0x44, 0x45, 0x61, 0x4d, 0x42, 0x67, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x52, 0x51, 0x30, 0x39, 0x4e, 0x54,
+    0x30, 0x52, 0x50, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62,
+    0x57, 0x6c, 0x30, 0x5a, 0x57, 0x51, 0x78, 0x4b, 0x7a, 0x41, 0x70, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x0a, 0x49, 0x6b, 0x4e, 0x50,
+    0x54, 0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4d, 0x67,
+    0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68,
+    0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f,
+    0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x48, 0x68, 0x63, 0x4e,
+    0x4d, 0x44, 0x67, 0x77, 0x4d, 0x7a, 0x41, 0x32, 0x4d, 0x44, 0x41, 0x77,
+    0x0a, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x67,
+    0x77, 0x4d, 0x54, 0x45, 0x34, 0x4d, 0x6a, 0x4d, 0x31, 0x4f, 0x54, 0x55,
+    0x35, 0x57, 0x6a, 0x43, 0x42, 0x68, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x52, 0x30, 0x49,
+    0x78, 0x47, 0x7a, 0x41, 0x5a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67,
+    0x54, 0x45, 0x6b, 0x64, 0x79, 0x0a, 0x5a, 0x57, 0x46, 0x30, 0x5a, 0x58,
+    0x49, 0x67, 0x54, 0x57, 0x46, 0x75, 0x59, 0x32, 0x68, 0x6c, 0x63, 0x33,
+    0x52, 0x6c, 0x63, 0x6a, 0x45, 0x51, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x42, 0x78, 0x4d, 0x48, 0x55, 0x32, 0x46, 0x73, 0x5a, 0x6d,
+    0x39, 0x79, 0x5a, 0x44, 0x45, 0x61, 0x4d, 0x42, 0x67, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x43, 0x68, 0x4d, 0x52, 0x51, 0x30, 0x39, 0x4e, 0x0a, 0x54,
+    0x30, 0x52, 0x50, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x45, 0x78, 0x70, 0x62,
+    0x57, 0x6c, 0x30, 0x5a, 0x57, 0x51, 0x78, 0x4b, 0x7a, 0x41, 0x70, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x49, 0x6b, 0x4e, 0x50, 0x54,
+    0x55, 0x39, 0x45, 0x54, 0x79, 0x42, 0x46, 0x51, 0x30, 0x4d, 0x67, 0x51,
+    0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64,
+    0x47, 0x6c, 0x76, 0x0a, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f,
+    0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x64, 0x6a, 0x41, 0x51,
+    0x42, 0x67, 0x63, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x49, 0x42,
+    0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67, 0x4e, 0x69,
+    0x41, 0x41, 0x51, 0x44, 0x52, 0x33, 0x73, 0x76, 0x64, 0x63, 0x6d, 0x43,
+    0x46, 0x59, 0x58, 0x37, 0x64, 0x65, 0x53, 0x52, 0x0a, 0x46, 0x74, 0x53,
+    0x72, 0x59, 0x70, 0x6e, 0x31, 0x50, 0x6c, 0x49, 0x4c, 0x42, 0x73, 0x35,
+    0x42, 0x41, 0x48, 0x2b, 0x58, 0x34, 0x51, 0x6f, 0x6b, 0x50, 0x42, 0x30,
+    0x42, 0x42, 0x4f, 0x34, 0x39, 0x30, 0x6f, 0x30, 0x4a, 0x6c, 0x77, 0x7a,
+    0x67, 0x64, 0x65, 0x54, 0x36, 0x2b, 0x33, 0x65, 0x4b, 0x4b, 0x76, 0x55,
+    0x44, 0x59, 0x45, 0x73, 0x32, 0x69, 0x78, 0x59, 0x6a, 0x46, 0x71, 0x30,
+    0x4a, 0x0a, 0x63, 0x66, 0x52, 0x4b, 0x39, 0x43, 0x68, 0x51, 0x74, 0x50,
+    0x36, 0x49, 0x48, 0x47, 0x34, 0x2f, 0x62, 0x43, 0x38, 0x76, 0x43, 0x56,
+    0x6c, 0x62, 0x70, 0x56, 0x73, 0x4c, 0x4d, 0x35, 0x6e, 0x69, 0x77, 0x7a,
+    0x32, 0x4a, 0x2b, 0x57, 0x6f, 0x73, 0x37, 0x37, 0x4c, 0x54, 0x42, 0x75,
+    0x6d, 0x6a, 0x51, 0x6a, 0x42, 0x41, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31,
+    0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x0a, 0x42, 0x42, 0x52, 0x31, 0x63,
+    0x61, 0x63, 0x5a, 0x53, 0x42, 0x6d, 0x38, 0x6e, 0x5a, 0x33, 0x71, 0x51,
+    0x55, 0x66, 0x66, 0x6c, 0x4d, 0x52, 0x49, 0x64, 0x35, 0x6e, 0x54, 0x65,
+    0x54, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41,
+    0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44,
+    0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x0a,
+    0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41, 0x4b,
+    0x42, 0x67, 0x67, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44,
+    0x41, 0x77, 0x4e, 0x6f, 0x41, 0x44, 0x42, 0x6c, 0x41, 0x6a, 0x45, 0x41,
+    0x37, 0x77, 0x4e, 0x62, 0x65, 0x71, 0x79, 0x33, 0x65, 0x41, 0x70, 0x79,
+    0x74, 0x34, 0x6a, 0x66, 0x2f, 0x37, 0x56, 0x47, 0x46, 0x41, 0x6b, 0x4b,
+    0x2b, 0x71, 0x44, 0x6d, 0x0a, 0x66, 0x51, 0x6a, 0x47, 0x47, 0x6f, 0x65,
+    0x39, 0x47, 0x4b, 0x68, 0x7a, 0x76, 0x53, 0x62, 0x4b, 0x59, 0x41, 0x79,
+    0x64, 0x7a, 0x70, 0x6d, 0x66, 0x7a, 0x31, 0x77, 0x50, 0x4d, 0x4f, 0x47,
+    0x2b, 0x46, 0x44, 0x48, 0x71, 0x41, 0x6a, 0x41, 0x55, 0x39, 0x4a, 0x4d,
+    0x38, 0x53, 0x61, 0x63, 0x7a, 0x65, 0x70, 0x42, 0x47, 0x52, 0x37, 0x4e,
+    0x6a, 0x66, 0x52, 0x4f, 0x62, 0x54, 0x72, 0x64, 0x76, 0x0a, 0x47, 0x44,
+    0x65, 0x41, 0x55, 0x2f, 0x37, 0x64, 0x49, 0x4f, 0x41, 0x31, 0x6d, 0x6a,
+    0x62, 0x52, 0x78, 0x77, 0x47, 0x35, 0x35, 0x74, 0x7a, 0x64, 0x38, 0x2f,
+    0x38, 0x64, 0x4c, 0x44, 0x6f, 0x57, 0x56, 0x39, 0x6d, 0x53, 0x4f, 0x64,
+    0x59, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75,
+    0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x43, 0x6c,
+    0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x41, 0x20, 0x49, 0x49, 0x20,
+    0x4f, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65,
+    0x6e, 0x74, 0x65, 0x72, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55,
+    0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e,
+    0x74, 0x65, 0x72, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20,
+    0x43, 0x41, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,
+    0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x43, 0x6c, 0x61, 0x73,
+    0x73, 0x20, 0x32, 0x20, 0x43, 0x41, 0x20, 0x49, 0x49, 0x20, 0x4f, 0x3d,
+    0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74,
+    0x65, 0x72, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55, 0x3d, 0x54,
+    0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65,
+    0x72, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x41,
+    0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x54,
+    0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65,
+    0x72, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x41,
+    0x20, 0x49, 0x49, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61,
+    0x6c, 0x3a, 0x20, 0x39, 0x34, 0x31, 0x33, 0x38, 0x39, 0x30, 0x32, 0x38,
+    0x32, 0x30, 0x33, 0x34, 0x35, 0x33, 0x38, 0x36, 0x36, 0x37, 0x38, 0x32,
+    0x31, 0x30, 0x33, 0x34, 0x30, 0x36, 0x39, 0x39, 0x32, 0x34, 0x34, 0x33,
+    0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x65, 0x3a, 0x37,
+    0x38, 0x3a, 0x33, 0x33, 0x3a, 0x35, 0x63, 0x3a, 0x35, 0x39, 0x3a, 0x37,
+    0x38, 0x3a, 0x30, 0x31, 0x3a, 0x36, 0x65, 0x3a, 0x31, 0x38, 0x3a, 0x65,
+    0x61, 0x3a, 0x62, 0x39, 0x3a, 0x33, 0x36, 0x3a, 0x61, 0x30, 0x3a, 0x62,
+    0x39, 0x3a, 0x32, 0x65, 0x3a, 0x32, 0x33, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x61, 0x65, 0x3a, 0x35, 0x30, 0x3a, 0x38, 0x33,
+    0x3a, 0x65, 0x64, 0x3a, 0x37, 0x63, 0x3a, 0x66, 0x34, 0x3a, 0x35, 0x63,
+    0x3a, 0x62, 0x63, 0x3a, 0x38, 0x66, 0x3a, 0x36, 0x31, 0x3a, 0x63, 0x36,
+    0x3a, 0x32, 0x31, 0x3a, 0x66, 0x65, 0x3a, 0x36, 0x38, 0x3a, 0x35, 0x64,
+    0x3a, 0x37, 0x39, 0x3a, 0x34, 0x32, 0x3a, 0x32, 0x31, 0x3a, 0x31, 0x35,
+    0x3a, 0x36, 0x65, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x65, 0x36, 0x3a, 0x62, 0x38, 0x3a, 0x66, 0x38, 0x3a, 0x37,
+    0x36, 0x3a, 0x36, 0x34, 0x3a, 0x38, 0x35, 0x3a, 0x66, 0x38, 0x3a, 0x30,
+    0x37, 0x3a, 0x61, 0x65, 0x3a, 0x37, 0x66, 0x3a, 0x38, 0x64, 0x3a, 0x61,
+    0x63, 0x3a, 0x31, 0x36, 0x3a, 0x37, 0x30, 0x3a, 0x34, 0x36, 0x3a, 0x31,
+    0x66, 0x3a, 0x30, 0x37, 0x3a, 0x63, 0x30, 0x3a, 0x61, 0x31, 0x3a, 0x33,
+    0x65, 0x3a, 0x65, 0x66, 0x3a, 0x33, 0x61, 0x3a, 0x31, 0x66, 0x3a, 0x66,
+    0x37, 0x3a, 0x31, 0x37, 0x3a, 0x35, 0x33, 0x3a, 0x38, 0x64, 0x3a, 0x37,
+    0x61, 0x3a, 0x62, 0x61, 0x3a, 0x64, 0x33, 0x3a, 0x39, 0x31, 0x3a, 0x62,
+    0x34, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x71, 0x6a,
+    0x43, 0x43, 0x41, 0x35, 0x4b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67,
+    0x49, 0x4f, 0x4c, 0x6d, 0x6f, 0x41, 0x41, 0x51, 0x41, 0x43, 0x48, 0x39,
+    0x64, 0x53, 0x49, 0x53, 0x77, 0x52, 0x58, 0x44, 0x73, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x64, 0x6a, 0x45, 0x4c, 0x0a, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x52,
+    0x45, 0x55, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x45, 0x31, 0x52, 0x44, 0x49, 0x46, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79, 0x49,
+    0x45, 0x64, 0x74, 0x59, 0x6b, 0x67, 0x78, 0x49, 0x6a, 0x41, 0x67, 0x42,
+    0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x73, 0x54, 0x47, 0x56, 0x52, 0x44,
+    0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75,
+    0x64, 0x47, 0x56, 0x79, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a,
+    0x49, 0x44, 0x49, 0x67, 0x51, 0x30, 0x45, 0x78, 0x4a, 0x54, 0x41, 0x6a,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x48, 0x46, 0x52, 0x44,
+    0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x0a, 0x51, 0x32, 0x56,
+    0x75, 0x64, 0x47, 0x56, 0x79, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e,
+    0x7a, 0x49, 0x44, 0x49, 0x67, 0x51, 0x30, 0x45, 0x67, 0x53, 0x55, 0x6b,
+    0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x59, 0x77, 0x4d, 0x54, 0x45,
+    0x79, 0x4d, 0x54, 0x51, 0x7a, 0x4f, 0x44, 0x51, 0x7a, 0x57, 0x68, 0x63,
+    0x4e, 0x4d, 0x6a, 0x55, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x6a, 0x49,
+    0x31, 0x0a, 0x4f, 0x54, 0x55, 0x35, 0x57, 0x6a, 0x42, 0x32, 0x4d, 0x51,
+    0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77,
+    0x4a, 0x45, 0x52, 0x54, 0x45, 0x63, 0x4d, 0x42, 0x6f, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x43, 0x68, 0x4d, 0x54, 0x56, 0x45, 0x4d, 0x67, 0x56, 0x48,
+    0x4a, 0x31, 0x63, 0x33, 0x52, 0x44, 0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58,
+    0x49, 0x67, 0x52, 0x32, 0x31, 0x69, 0x0a, 0x53, 0x44, 0x45, 0x69, 0x4d,
+    0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x5a, 0x56,
+    0x45, 0x4d, 0x67, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x44, 0x5a,
+    0x57, 0x35, 0x30, 0x5a, 0x58, 0x49, 0x67, 0x51, 0x32, 0x78, 0x68, 0x63,
+    0x33, 0x4d, 0x67, 0x4d, 0x69, 0x42, 0x44, 0x51, 0x54, 0x45, 0x6c, 0x4d,
+    0x43, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x63, 0x0a,
+    0x56, 0x45, 0x4d, 0x67, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x44,
+    0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x49, 0x67, 0x51, 0x32, 0x78, 0x68,
+    0x63, 0x33, 0x4d, 0x67, 0x4d, 0x69, 0x42, 0x44, 0x51, 0x53, 0x42, 0x4a,
+    0x53, 0x54, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a,
+    0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42,
+    0x42, 0x51, 0x41, 0x44, 0x0a, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43,
+    0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4b, 0x75,
+    0x41, 0x68, 0x35, 0x75, 0x4f, 0x38, 0x4d, 0x4e, 0x38, 0x68, 0x39, 0x66,
+    0x6f, 0x4a, 0x49, 0x49, 0x52, 0x73, 0x7a, 0x7a, 0x64, 0x51, 0x32, 0x4c,
+    0x75, 0x2b, 0x4d, 0x4e, 0x46, 0x32, 0x75, 0x6a, 0x68, 0x6f, 0x46, 0x2f,
+    0x52, 0x4b, 0x72, 0x4c, 0x71, 0x6b, 0x32, 0x6a, 0x66, 0x0a, 0x74, 0x4d,
+    0x6a, 0x57, 0x51, 0x2b, 0x6e, 0x45, 0x64, 0x56, 0x6c, 0x2f, 0x2f, 0x4f,
+    0x45, 0x64, 0x2b, 0x44, 0x46, 0x77, 0x49, 0x78, 0x75, 0x49, 0x6e, 0x69,
+    0x65, 0x35, 0x65, 0x2f, 0x30, 0x36, 0x30, 0x73, 0x6d, 0x70, 0x36, 0x52,
+    0x51, 0x76, 0x6b, 0x4c, 0x34, 0x44, 0x55, 0x73, 0x46, 0x4a, 0x7a, 0x66,
+    0x62, 0x39, 0x35, 0x41, 0x68, 0x6d, 0x43, 0x31, 0x65, 0x4b, 0x6f, 0x6b,
+    0x4b, 0x67, 0x0a, 0x75, 0x4e, 0x56, 0x2f, 0x61, 0x56, 0x79, 0x51, 0x4d,
+    0x72, 0x4b, 0x58, 0x44, 0x63, 0x70, 0x4b, 0x33, 0x45, 0x59, 0x2b, 0x41,
+    0x6c, 0x57, 0x4a, 0x55, 0x2b, 0x4d, 0x61, 0x57, 0x73, 0x73, 0x32, 0x78,
+    0x67, 0x64, 0x57, 0x39, 0x34, 0x7a, 0x50, 0x45, 0x66, 0x52, 0x4d, 0x75,
+    0x7a, 0x42, 0x77, 0x42, 0x4a, 0x57, 0x6c, 0x39, 0x6a, 0x6d, 0x4d, 0x2f,
+    0x58, 0x4f, 0x42, 0x43, 0x48, 0x32, 0x4a, 0x0a, 0x58, 0x6a, 0x49, 0x65,
+    0x49, 0x71, 0x6b, 0x69, 0x52, 0x55, 0x75, 0x77, 0x5a, 0x69, 0x34, 0x77,
+    0x7a, 0x4a, 0x39, 0x6c, 0x2f, 0x66, 0x7a, 0x4c, 0x67, 0x61, 0x6e, 0x78,
+    0x34, 0x44, 0x75, 0x76, 0x6f, 0x34, 0x62, 0x52, 0x69, 0x65, 0x72, 0x45,
+    0x52, 0x58, 0x6c, 0x51, 0x58, 0x61, 0x37, 0x70, 0x49, 0x58, 0x53, 0x53,
+    0x54, 0x59, 0x74, 0x5a, 0x67, 0x6f, 0x2b, 0x55, 0x34, 0x2b, 0x6c, 0x4b,
+    0x0a, 0x38, 0x65, 0x64, 0x4a, 0x73, 0x42, 0x54, 0x6a, 0x39, 0x57, 0x4c,
+    0x4c, 0x31, 0x58, 0x4b, 0x39, 0x48, 0x37, 0x6e, 0x53, 0x6e, 0x36, 0x44,
+    0x4e, 0x71, 0x50, 0x6f, 0x42, 0x79, 0x4e, 0x6b, 0x4e, 0x33, 0x39, 0x72,
+    0x38, 0x52, 0x35, 0x32, 0x7a, 0x79, 0x46, 0x54, 0x66, 0x53, 0x55, 0x72,
+    0x78, 0x49, 0x61, 0x6e, 0x2b, 0x47, 0x45, 0x37, 0x75, 0x53, 0x4e, 0x51,
+    0x5a, 0x75, 0x2b, 0x39, 0x39, 0x0a, 0x35, 0x4f, 0x4b, 0x64, 0x79, 0x31,
+    0x75, 0x32, 0x62, 0x76, 0x2f, 0x6a, 0x7a, 0x56, 0x72, 0x6e, 0x64, 0x49,
+    0x49, 0x46, 0x75, 0x6f, 0x41, 0x6c, 0x4f, 0x4d, 0x76, 0x6b, 0x61, 0x5a,
+    0x36, 0x76, 0x51, 0x61, 0x6f, 0x61, 0x68, 0x50, 0x55, 0x43, 0x41, 0x77,
+    0x45, 0x41, 0x41, 0x61, 0x4f, 0x43, 0x41, 0x54, 0x51, 0x77, 0x67, 0x67,
+    0x45, 0x77, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0a, 0x45,
+    0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41,
+    0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41,
+    0x51, 0x48, 0x2f, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d,
+    0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42,
+    0x42, 0x54, 0x6a, 0x71, 0x31, 0x52, 0x4d, 0x67, 0x4b, 0x48, 0x62, 0x56,
+    0x6b, 0x4f, 0x33, 0x0a, 0x6b, 0x55, 0x72, 0x4c, 0x38, 0x34, 0x4a, 0x36,
+    0x45, 0x31, 0x77, 0x49, 0x71, 0x7a, 0x43, 0x42, 0x37, 0x51, 0x59, 0x44,
+    0x56, 0x52, 0x30, 0x66, 0x42, 0x49, 0x48, 0x6c, 0x4d, 0x49, 0x48, 0x69,
+    0x4d, 0x49, 0x48, 0x66, 0x6f, 0x49, 0x48, 0x63, 0x6f, 0x49, 0x48, 0x5a,
+    0x68, 0x6a, 0x56, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76,
+    0x64, 0x33, 0x64, 0x33, 0x4c, 0x6e, 0x52, 0x79, 0x0a, 0x64, 0x58, 0x4e,
+    0x30, 0x59, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79, 0x4c, 0x6d, 0x52,
+    0x6c, 0x4c, 0x32, 0x4e, 0x79, 0x62, 0x43, 0x39, 0x32, 0x4d, 0x69, 0x39,
+    0x30, 0x59, 0x31, 0x39, 0x6a, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x31, 0x38,
+    0x79, 0x58, 0x32, 0x4e, 0x68, 0x58, 0x30, 0x6c, 0x4a, 0x4c, 0x6d, 0x4e,
+    0x79, 0x62, 0x49, 0x61, 0x42, 0x6e, 0x32, 0x78, 0x6b, 0x59, 0x58, 0x41,
+    0x36, 0x0a, 0x4c, 0x79, 0x39, 0x33, 0x64, 0x33, 0x63, 0x75, 0x64, 0x48,
+    0x4a, 0x31, 0x63, 0x33, 0x52, 0x6a, 0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58,
+    0x49, 0x75, 0x5a, 0x47, 0x55, 0x76, 0x51, 0x30, 0x34, 0x39, 0x56, 0x45,
+    0x4d, 0x6c, 0x4d, 0x6a, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x45,
+    0x4e, 0x6c, 0x62, 0x6e, 0x52, 0x6c, 0x63, 0x69, 0x55, 0x79, 0x4d, 0x45,
+    0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a, 0x0a, 0x4a, 0x54, 0x49, 0x77, 0x4d,
+    0x69, 0x55, 0x79, 0x4d, 0x45, 0x4e, 0x42, 0x4a, 0x54, 0x49, 0x77, 0x53,
+    0x55, 0x6b, 0x73, 0x54, 0x7a, 0x31, 0x55, 0x51, 0x79, 0x55, 0x79, 0x4d,
+    0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75, 0x64,
+    0x47, 0x56, 0x79, 0x4a, 0x54, 0x49, 0x77, 0x52, 0x32, 0x31, 0x69, 0x53,
+    0x43, 0x78, 0x50, 0x56, 0x54, 0x31, 0x79, 0x62, 0x32, 0x39, 0x30, 0x0a,
+    0x59, 0x32, 0x56, 0x79, 0x64, 0x48, 0x4d, 0x73, 0x52, 0x45, 0x4d, 0x39,
+    0x64, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x6a, 0x5a, 0x57, 0x35, 0x30,
+    0x5a, 0x58, 0x49, 0x73, 0x52, 0x45, 0x4d, 0x39, 0x5a, 0x47, 0x55, 0x2f,
+    0x59, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68,
+    0x64, 0x47, 0x56, 0x53, 0x5a, 0x58, 0x5a, 0x76, 0x59, 0x32, 0x46, 0x30,
+    0x61, 0x57, 0x39, 0x75, 0x0a, 0x54, 0x47, 0x6c, 0x7a, 0x64, 0x44, 0x39,
+    0x69, 0x59, 0x58, 0x4e, 0x6c, 0x50, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b,
+    0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55,
+    0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x6a, 0x4e, 0x66,
+    0x66, 0x66, 0x75, 0x34, 0x62, 0x67, 0x42, 0x43, 0x7a, 0x67, 0x2f, 0x58,
+    0x62, 0x45, 0x65, 0x70, 0x72, 0x53, 0x36, 0x69, 0x53, 0x0a, 0x47, 0x4e,
+    0x6e, 0x33, 0x42, 0x7a, 0x6e, 0x31, 0x4c, 0x4c, 0x34, 0x47, 0x64, 0x58,
+    0x70, 0x6f, 0x55, 0x78, 0x55, 0x63, 0x36, 0x6b, 0x72, 0x74, 0x58, 0x76,
+    0x77, 0x6a, 0x73, 0x68, 0x4f, 0x67, 0x30, 0x77, 0x6e, 0x2f, 0x39, 0x76,
+    0x59, 0x75, 0x61, 0x30, 0x46, 0x78, 0x65, 0x63, 0x33, 0x69, 0x62, 0x66,
+    0x32, 0x75, 0x57, 0x57, 0x75, 0x46, 0x48, 0x62, 0x68, 0x4f, 0x49, 0x70,
+    0x72, 0x74, 0x0a, 0x5a, 0x6a, 0x6c, 0x75, 0x53, 0x35, 0x54, 0x6d, 0x56,
+    0x66, 0x77, 0x4c, 0x47, 0x34, 0x74, 0x33, 0x77, 0x56, 0x4d, 0x54, 0x5a,
+    0x6f, 0x6e, 0x5a, 0x4b, 0x4e, 0x61, 0x4c, 0x38, 0x30, 0x56, 0x4b, 0x59,
+    0x37, 0x66, 0x39, 0x65, 0x77, 0x74, 0x68, 0x58, 0x62, 0x68, 0x74, 0x76,
+    0x73, 0x50, 0x63, 0x57, 0x33, 0x6e, 0x53, 0x37, 0x59, 0x62, 0x6c, 0x6f,
+    0x6b, 0x32, 0x2b, 0x58, 0x6e, 0x52, 0x38, 0x0a, 0x61, 0x75, 0x30, 0x57,
+    0x4f, 0x42, 0x39, 0x2f, 0x57, 0x49, 0x46, 0x61, 0x47, 0x75, 0x73, 0x79,
+    0x69, 0x43, 0x32, 0x79, 0x38, 0x7a, 0x6c, 0x33, 0x67, 0x4b, 0x39, 0x65,
+    0x74, 0x6d, 0x46, 0x31, 0x4b, 0x64, 0x73, 0x6a, 0x54, 0x59, 0x6a, 0x4b,
+    0x55, 0x43, 0x6a, 0x4c, 0x68, 0x64, 0x4c, 0x54, 0x45, 0x4b, 0x4a, 0x5a,
+    0x62, 0x74, 0x4f, 0x54, 0x56, 0x41, 0x42, 0x36, 0x6f, 0x6b, 0x61, 0x56,
+    0x0a, 0x68, 0x67, 0x57, 0x63, 0x71, 0x52, 0x6d, 0x59, 0x35, 0x54, 0x46,
+    0x79, 0x44, 0x41, 0x44, 0x69, 0x5a, 0x39, 0x6c, 0x41, 0x34, 0x43, 0x51,
+    0x7a, 0x65, 0x32, 0x38, 0x73, 0x75, 0x56, 0x79, 0x72, 0x5a, 0x5a, 0x30,
+    0x73, 0x72, 0x48, 0x62, 0x71, 0x4e, 0x5a, 0x6e, 0x31, 0x6c, 0x37, 0x6b,
+    0x50, 0x4a, 0x4f, 0x7a, 0x48, 0x64, 0x69, 0x45, 0x6f, 0x5a, 0x61, 0x35,
+    0x58, 0x36, 0x41, 0x65, 0x49, 0x0a, 0x64, 0x55, 0x70, 0x57, 0x6f, 0x4e,
+    0x49, 0x46, 0x4f, 0x71, 0x54, 0x6d, 0x6a, 0x5a, 0x4b, 0x49, 0x4c, 0x50,
+    0x50, 0x79, 0x34, 0x63, 0x48, 0x47, 0x59, 0x64, 0x74, 0x42, 0x78, 0x63,
+    0x65, 0x62, 0x39, 0x77, 0x34, 0x61, 0x55, 0x55, 0x58, 0x43, 0x59, 0x57,
+    0x76, 0x63, 0x5a, 0x43, 0x63, 0x58, 0x6a, 0x46, 0x71, 0x33, 0x32, 0x6e,
+    0x51, 0x6f, 0x7a, 0x5a, 0x66, 0x6b, 0x76, 0x51, 0x3d, 0x3d, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43,
+    0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x33, 0x20, 0x43, 0x41, 0x20, 0x49, 0x49, 0x20, 0x4f, 0x3d, 0x54, 0x43,
+    0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72,
+    0x20, 0x47, 0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55, 0x3d, 0x54, 0x43, 0x20,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20,
+    0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e,
+    0x74, 0x65, 0x72, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20,
+    0x43, 0x41, 0x20, 0x49, 0x49, 0x20, 0x4f, 0x3d, 0x54, 0x43, 0x20, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x47,
+    0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x43, 0x6c,
+    0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, 0x0a, 0x23, 0x20, 0x4c,
+    0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x54, 0x43, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x43, 0x6c,
+    0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, 0x20, 0x49, 0x49, 0x22,
+    0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31,
+    0x35, 0x30, 0x36, 0x35, 0x32, 0x33, 0x35, 0x31, 0x31, 0x34, 0x31, 0x37,
+    0x37, 0x31, 0x35, 0x36, 0x33, 0x38, 0x37, 0x37, 0x32, 0x32, 0x32, 0x30,
+    0x35, 0x33, 0x30, 0x30, 0x32, 0x30, 0x37, 0x39, 0x39, 0x0a, 0x23, 0x20,
+    0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x35, 0x36, 0x3a, 0x35, 0x66, 0x3a, 0x61,
+    0x61, 0x3a, 0x38, 0x30, 0x3a, 0x36, 0x31, 0x3a, 0x31, 0x32, 0x3a, 0x31,
+    0x37, 0x3a, 0x66, 0x36, 0x3a, 0x36, 0x37, 0x3a, 0x32, 0x31, 0x3a, 0x65,
+    0x36, 0x3a, 0x32, 0x62, 0x3a, 0x36, 0x64, 0x3a, 0x36, 0x31, 0x3a, 0x35,
+    0x36, 0x3a, 0x38, 0x65, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x38, 0x30, 0x3a, 0x32, 0x35, 0x3a, 0x65, 0x66, 0x3a, 0x66, 0x34,
+    0x3a, 0x36, 0x65, 0x3a, 0x37, 0x30, 0x3a, 0x63, 0x38, 0x3a, 0x64, 0x34,
+    0x3a, 0x37, 0x32, 0x3a, 0x32, 0x34, 0x3a, 0x36, 0x35, 0x3a, 0x38, 0x34,
+    0x3a, 0x66, 0x65, 0x3a, 0x34, 0x30, 0x3a, 0x33, 0x62, 0x3a, 0x38, 0x61,
+    0x3a, 0x38, 0x64, 0x3a, 0x36, 0x61, 0x3a, 0x64, 0x62, 0x3a, 0x66, 0x35,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38,
+    0x64, 0x3a, 0x61, 0x30, 0x3a, 0x38, 0x34, 0x3a, 0x66, 0x63, 0x3a, 0x66,
+    0x39, 0x3a, 0x39, 0x63, 0x3a, 0x65, 0x30, 0x3a, 0x37, 0x37, 0x3a, 0x32,
+    0x32, 0x3a, 0x66, 0x38, 0x3a, 0x39, 0x62, 0x3a, 0x33, 0x32, 0x3a, 0x30,
+    0x35, 0x3a, 0x39, 0x33, 0x3a, 0x39, 0x38, 0x3a, 0x30, 0x36, 0x3a, 0x66,
+    0x61, 0x3a, 0x35, 0x63, 0x3a, 0x62, 0x38, 0x3a, 0x31, 0x31, 0x3a, 0x65,
+    0x31, 0x3a, 0x63, 0x38, 0x3a, 0x31, 0x33, 0x3a, 0x66, 0x36, 0x3a, 0x61,
+    0x31, 0x3a, 0x30, 0x38, 0x3a, 0x63, 0x37, 0x3a, 0x64, 0x33, 0x3a, 0x33,
+    0x36, 0x3a, 0x62, 0x33, 0x3a, 0x34, 0x30, 0x3a, 0x38, 0x65, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x71, 0x6a, 0x43, 0x43, 0x41,
+    0x35, 0x4b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4f, 0x53,
+    0x6b, 0x63, 0x41, 0x41, 0x51, 0x41, 0x43, 0x35, 0x61, 0x42, 0x64, 0x31,
+    0x6a, 0x38, 0x41, 0x55, 0x62, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b,
+    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42,
+    0x51, 0x41, 0x77, 0x64, 0x6a, 0x45, 0x4c, 0x0a, 0x4d, 0x41, 0x6b, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x52, 0x45, 0x55, 0x78,
+    0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54,
+    0x45, 0x31, 0x52, 0x44, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30,
+    0x51, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79, 0x49, 0x45, 0x64, 0x74,
+    0x59, 0x6b, 0x67, 0x78, 0x49, 0x6a, 0x41, 0x67, 0x42, 0x67, 0x4e, 0x56,
+    0x0a, 0x42, 0x41, 0x73, 0x54, 0x47, 0x56, 0x52, 0x44, 0x49, 0x46, 0x52,
+    0x79, 0x64, 0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56,
+    0x79, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44, 0x4d,
+    0x67, 0x51, 0x30, 0x45, 0x78, 0x4a, 0x54, 0x41, 0x6a, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x4d, 0x54, 0x48, 0x46, 0x52, 0x44, 0x49, 0x46, 0x52,
+    0x79, 0x64, 0x58, 0x4e, 0x30, 0x0a, 0x51, 0x32, 0x56, 0x75, 0x64, 0x47,
+    0x56, 0x79, 0x49, 0x45, 0x4e, 0x73, 0x59, 0x58, 0x4e, 0x7a, 0x49, 0x44,
+    0x4d, 0x67, 0x51, 0x30, 0x45, 0x67, 0x53, 0x55, 0x6b, 0x77, 0x48, 0x68,
+    0x63, 0x4e, 0x4d, 0x44, 0x59, 0x77, 0x4d, 0x54, 0x45, 0x79, 0x4d, 0x54,
+    0x51, 0x30, 0x4d, 0x54, 0x55, 0x33, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a,
+    0x55, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x6a, 0x49, 0x31, 0x0a, 0x4f,
+    0x54, 0x55, 0x35, 0x57, 0x6a, 0x42, 0x32, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x45, 0x52,
+    0x54, 0x45, 0x63, 0x4d, 0x42, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x68, 0x4d, 0x54, 0x56, 0x45, 0x4d, 0x67, 0x56, 0x48, 0x4a, 0x31, 0x63,
+    0x33, 0x52, 0x44, 0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x49, 0x67, 0x52,
+    0x32, 0x31, 0x69, 0x0a, 0x53, 0x44, 0x45, 0x69, 0x4d, 0x43, 0x41, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x5a, 0x56, 0x45, 0x4d, 0x67,
+    0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x44, 0x5a, 0x57, 0x35, 0x30,
+    0x5a, 0x58, 0x49, 0x67, 0x51, 0x32, 0x78, 0x68, 0x63, 0x33, 0x4d, 0x67,
+    0x4d, 0x79, 0x42, 0x44, 0x51, 0x54, 0x45, 0x6c, 0x4d, 0x43, 0x4d, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x63, 0x0a, 0x56, 0x45, 0x4d,
+    0x67, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x44, 0x5a, 0x57, 0x35,
+    0x30, 0x5a, 0x58, 0x49, 0x67, 0x51, 0x32, 0x78, 0x68, 0x63, 0x33, 0x4d,
+    0x67, 0x4d, 0x79, 0x42, 0x44, 0x51, 0x53, 0x42, 0x4a, 0x53, 0x54, 0x43,
+    0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a,
+    0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41,
+    0x44, 0x0a, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51,
+    0x6f, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4c, 0x54, 0x67, 0x75, 0x31,
+    0x47, 0x37, 0x4f, 0x56, 0x79, 0x4c, 0x42, 0x4d, 0x56, 0x4d, 0x65, 0x52,
+    0x77, 0x6a, 0x68, 0x6a, 0x45, 0x51, 0x59, 0x30, 0x4e, 0x56, 0x4a, 0x7a,
+    0x2f, 0x47, 0x52, 0x63, 0x65, 0x6b, 0x50, 0x65, 0x77, 0x4a, 0x44, 0x52,
+    0x6f, 0x65, 0x49, 0x4d, 0x4a, 0x57, 0x0a, 0x48, 0x74, 0x34, 0x62, 0x4e,
+    0x77, 0x63, 0x77, 0x49, 0x69, 0x39, 0x76, 0x38, 0x51, 0x62, 0x78, 0x71,
+    0x36, 0x33, 0x57, 0x79, 0x4b, 0x74, 0x68, 0x6f, 0x79, 0x39, 0x44, 0x78,
+    0x4c, 0x43, 0x79, 0x4c, 0x66, 0x7a, 0x44, 0x6c, 0x6d, 0x6c, 0x37, 0x66,
+    0x6f, 0x72, 0x6b, 0x7a, 0x4d, 0x41, 0x35, 0x45, 0x70, 0x42, 0x43, 0x59,
+    0x4d, 0x6e, 0x4d, 0x4e, 0x57, 0x6a, 0x75, 0x32, 0x6c, 0x2b, 0x51, 0x0a,
+    0x56, 0x6c, 0x2f, 0x4e, 0x48, 0x45, 0x31, 0x62, 0x57, 0x45, 0x6e, 0x72,
+    0x44, 0x67, 0x46, 0x50, 0x5a, 0x50, 0x6f, 0x73, 0x50, 0x49, 0x6c, 0x59,
+    0x32, 0x43, 0x38, 0x75, 0x34, 0x72, 0x42, 0x6f, 0x36, 0x53, 0x49, 0x37,
+    0x64, 0x59, 0x6e, 0x57, 0x52, 0x42, 0x70, 0x6c, 0x38, 0x68, 0x75, 0x58,
+    0x4a, 0x68, 0x30, 0x6f, 0x62, 0x61, 0x7a, 0x6f, 0x76, 0x56, 0x6b, 0x64,
+    0x4b, 0x79, 0x54, 0x32, 0x0a, 0x31, 0x6f, 0x51, 0x44, 0x5a, 0x6f, 0x67,
+    0x6b, 0x41, 0x48, 0x68, 0x67, 0x38, 0x66, 0x69, 0x72, 0x2f, 0x67, 0x4b,
+    0x79, 0x61, 0x2f, 0x73, 0x69, 0x2b, 0x7a, 0x58, 0x6d, 0x46, 0x74, 0x47,
+    0x74, 0x39, 0x69, 0x34, 0x53, 0x35, 0x50, 0x6f, 0x31, 0x61, 0x75, 0x55,
+    0x5a, 0x75, 0x56, 0x33, 0x62, 0x4f, 0x78, 0x34, 0x61, 0x2b, 0x39, 0x50,
+    0x2f, 0x46, 0x52, 0x51, 0x49, 0x32, 0x41, 0x6c, 0x71, 0x0a, 0x75, 0x6b,
+    0x57, 0x64, 0x46, 0x48, 0x6c, 0x67, 0x66, 0x61, 0x39, 0x41, 0x69, 0x67,
+    0x64, 0x7a, 0x73, 0x35, 0x4f, 0x57, 0x30, 0x33, 0x51, 0x30, 0x6a, 0x54,
+    0x6f, 0x33, 0x4b, 0x64, 0x35, 0x63, 0x37, 0x50, 0x58, 0x75, 0x4c, 0x6a,
+    0x48, 0x43, 0x49, 0x4e, 0x79, 0x2b, 0x38, 0x55, 0x39, 0x2f, 0x49, 0x31,
+    0x4c, 0x5a, 0x57, 0x2b, 0x4a, 0x6b, 0x32, 0x5a, 0x79, 0x71, 0x42, 0x77,
+    0x69, 0x31, 0x0a, 0x52, 0x62, 0x33, 0x52, 0x30, 0x44, 0x48, 0x42, 0x71,
+    0x31, 0x53, 0x66, 0x71, 0x64, 0x4c, 0x44, 0x59, 0x6d, 0x41, 0x44, 0x38,
+    0x62, 0x73, 0x35, 0x53, 0x70, 0x4a, 0x4b, 0x50, 0x51, 0x71, 0x35, 0x6e,
+    0x63, 0x57, 0x67, 0x2f, 0x6a, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41,
+    0x61, 0x4f, 0x43, 0x41, 0x54, 0x51, 0x77, 0x67, 0x67, 0x45, 0x77, 0x4d,
+    0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0a, 0x45, 0x77, 0x45, 0x42,
+    0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77,
+    0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f,
+    0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x42, 0x30, 0x47,
+    0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x55,
+    0x6f, 0x76, 0x79, 0x66, 0x73, 0x38, 0x50, 0x59, 0x41, 0x39, 0x4e, 0x58,
+    0x0a, 0x58, 0x41, 0x65, 0x6b, 0x30, 0x43, 0x53, 0x6e, 0x77, 0x50, 0x49,
+    0x41, 0x31, 0x44, 0x43, 0x42, 0x37, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x66, 0x42, 0x49, 0x48, 0x6c, 0x4d, 0x49, 0x48, 0x69, 0x4d, 0x49, 0x48,
+    0x66, 0x6f, 0x49, 0x48, 0x63, 0x6f, 0x49, 0x48, 0x5a, 0x68, 0x6a, 0x56,
+    0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x64, 0x33, 0x64,
+    0x33, 0x4c, 0x6e, 0x52, 0x79, 0x0a, 0x64, 0x58, 0x4e, 0x30, 0x59, 0x32,
+    0x56, 0x75, 0x64, 0x47, 0x56, 0x79, 0x4c, 0x6d, 0x52, 0x6c, 0x4c, 0x32,
+    0x4e, 0x79, 0x62, 0x43, 0x39, 0x32, 0x4d, 0x69, 0x39, 0x30, 0x59, 0x31,
+    0x39, 0x6a, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x31, 0x38, 0x7a, 0x58, 0x32,
+    0x4e, 0x68, 0x58, 0x30, 0x6c, 0x4a, 0x4c, 0x6d, 0x4e, 0x79, 0x62, 0x49,
+    0x61, 0x42, 0x6e, 0x32, 0x78, 0x6b, 0x59, 0x58, 0x41, 0x36, 0x0a, 0x4c,
+    0x79, 0x39, 0x33, 0x64, 0x33, 0x63, 0x75, 0x64, 0x48, 0x4a, 0x31, 0x63,
+    0x33, 0x52, 0x6a, 0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x49, 0x75, 0x5a,
+    0x47, 0x55, 0x76, 0x51, 0x30, 0x34, 0x39, 0x56, 0x45, 0x4d, 0x6c, 0x4d,
+    0x6a, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x45, 0x4e, 0x6c, 0x62,
+    0x6e, 0x52, 0x6c, 0x63, 0x69, 0x55, 0x79, 0x4d, 0x45, 0x4e, 0x73, 0x59,
+    0x58, 0x4e, 0x7a, 0x0a, 0x4a, 0x54, 0x49, 0x77, 0x4d, 0x79, 0x55, 0x79,
+    0x4d, 0x45, 0x4e, 0x42, 0x4a, 0x54, 0x49, 0x77, 0x53, 0x55, 0x6b, 0x73,
+    0x54, 0x7a, 0x31, 0x55, 0x51, 0x79, 0x55, 0x79, 0x4d, 0x46, 0x52, 0x79,
+    0x64, 0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79,
+    0x4a, 0x54, 0x49, 0x77, 0x52, 0x32, 0x31, 0x69, 0x53, 0x43, 0x78, 0x50,
+    0x56, 0x54, 0x31, 0x79, 0x62, 0x32, 0x39, 0x30, 0x0a, 0x59, 0x32, 0x56,
+    0x79, 0x64, 0x48, 0x4d, 0x73, 0x52, 0x45, 0x4d, 0x39, 0x64, 0x48, 0x4a,
+    0x31, 0x63, 0x33, 0x52, 0x6a, 0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x49,
+    0x73, 0x52, 0x45, 0x4d, 0x39, 0x5a, 0x47, 0x55, 0x2f, 0x59, 0x32, 0x56,
+    0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x56,
+    0x53, 0x5a, 0x58, 0x5a, 0x76, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39,
+    0x75, 0x0a, 0x54, 0x47, 0x6c, 0x7a, 0x64, 0x44, 0x39, 0x69, 0x59, 0x58,
+    0x4e, 0x6c, 0x50, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b,
+    0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41,
+    0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x4e, 0x6d, 0x44, 0x6b, 0x63, 0x50,
+    0x63, 0x47, 0x49, 0x45, 0x50, 0x5a, 0x49, 0x78, 0x70, 0x43, 0x38, 0x76,
+    0x69, 0x6a, 0x73, 0x72, 0x6c, 0x4e, 0x0a, 0x69, 0x72, 0x54, 0x7a, 0x77,
+    0x70, 0x70, 0x56, 0x4d, 0x58, 0x7a, 0x45, 0x4f, 0x32, 0x65, 0x61, 0x74,
+    0x4e, 0x39, 0x4e, 0x44, 0x6f, 0x71, 0x54, 0x53, 0x68, 0x65, 0x4c, 0x47,
+    0x34, 0x33, 0x4b, 0x69, 0x65, 0x48, 0x50, 0x4f, 0x68, 0x36, 0x73, 0x48,
+    0x66, 0x47, 0x63, 0x4d, 0x72, 0x53, 0x4f, 0x57, 0x58, 0x61, 0x69, 0x51,
+    0x59, 0x55, 0x6c, 0x4e, 0x36, 0x41, 0x54, 0x30, 0x50, 0x56, 0x38, 0x0a,
+    0x54, 0x74, 0x58, 0x71, 0x6c, 0x75, 0x4a, 0x75, 0x63, 0x73, 0x47, 0x37,
+    0x4b, 0x76, 0x35, 0x73, 0x62, 0x76, 0x69, 0x52, 0x6d, 0x45, 0x62, 0x38,
+    0x79, 0x52, 0x74, 0x58, 0x57, 0x2b, 0x72, 0x49, 0x47, 0x6a, 0x73, 0x2f,
+    0x73, 0x46, 0x47, 0x59, 0x50, 0x41, 0x66, 0x61, 0x4c, 0x46, 0x6b, 0x42,
+    0x32, 0x6f, 0x74, 0x45, 0x36, 0x4f, 0x46, 0x30, 0x2f, 0x61, 0x64, 0x6f,
+    0x33, 0x56, 0x53, 0x36, 0x0a, 0x67, 0x30, 0x62, 0x73, 0x79, 0x45, 0x61,
+    0x31, 0x2b, 0x4b, 0x2b, 0x58, 0x77, 0x44, 0x73, 0x4a, 0x48, 0x49, 0x2f,
+    0x4f, 0x63, 0x70, 0x59, 0x39, 0x4d, 0x31, 0x5a, 0x77, 0x76, 0x4a, 0x62,
+    0x4c, 0x32, 0x4e, 0x56, 0x39, 0x49, 0x4a, 0x71, 0x44, 0x6e, 0x78, 0x72,
+    0x63, 0x4f, 0x66, 0x48, 0x46, 0x63, 0x71, 0x4d, 0x52, 0x41, 0x2f, 0x30,
+    0x37, 0x51, 0x6c, 0x49, 0x70, 0x32, 0x2b, 0x67, 0x42, 0x0a, 0x39, 0x35,
+    0x74, 0x65, 0x6a, 0x4e, 0x61, 0x4e, 0x68, 0x6b, 0x34, 0x5a, 0x2b, 0x72,
+    0x77, 0x63, 0x76, 0x73, 0x55, 0x68, 0x70, 0x59, 0x65, 0x65, 0x65, 0x43,
+    0x34, 0x32, 0x32, 0x77, 0x6c, 0x78, 0x6f, 0x33, 0x49, 0x30, 0x2b, 0x47,
+    0x7a, 0x6a, 0x42, 0x67, 0x6e, 0x79, 0x58, 0x6c, 0x61, 0x6c, 0x30, 0x39,
+    0x32, 0x59, 0x2b, 0x74, 0x54, 0x6d, 0x42, 0x76, 0x54, 0x77, 0x74, 0x69,
+    0x42, 0x6a, 0x0a, 0x53, 0x2b, 0x6f, 0x70, 0x76, 0x61, 0x71, 0x43, 0x5a,
+    0x68, 0x37, 0x37, 0x67, 0x61, 0x71, 0x6e, 0x4e, 0x36, 0x30, 0x54, 0x47,
+    0x4f, 0x61, 0x53, 0x77, 0x34, 0x48, 0x42, 0x4d, 0x37, 0x75, 0x49, 0x48,
+    0x71, 0x48, 0x6e, 0x34, 0x72, 0x53, 0x39, 0x4d, 0x57, 0x77, 0x4f, 0x55,
+    0x54, 0x31, 0x76, 0x2b, 0x35, 0x5a, 0x57, 0x67, 0x4f, 0x49, 0x32, 0x46,
+    0x39, 0x48, 0x63, 0x35, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74,
+    0x65, 0x72, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c,
+    0x20, 0x43, 0x41, 0x20, 0x49, 0x20, 0x4f, 0x3d, 0x54, 0x43, 0x20, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x47,
+    0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x55, 0x6e,
+    0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e,
+    0x74, 0x65, 0x72, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61,
+    0x6c, 0x20, 0x43, 0x41, 0x20, 0x49, 0x20, 0x4f, 0x3d, 0x54, 0x43, 0x20,
+    0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20,
+    0x47, 0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55, 0x3d, 0x54, 0x43, 0x20, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x55,
+    0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x54, 0x43,
+    0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72,
+    0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43,
+    0x41, 0x20, 0x49, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61,
+    0x6c, 0x3a, 0x20, 0x36, 0x30, 0x31, 0x30, 0x32, 0x34, 0x38, 0x34, 0x32,
+    0x30, 0x34, 0x32, 0x31, 0x38, 0x39, 0x30, 0x33, 0x35, 0x32, 0x39, 0x35,
+    0x36, 0x31, 0x39, 0x35, 0x38, 0x34, 0x37, 0x33, 0x34, 0x37, 0x32, 0x36,
+    0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x34, 0x35, 0x3a, 0x65,
+    0x31, 0x3a, 0x61, 0x35, 0x3a, 0x37, 0x32, 0x3a, 0x63, 0x35, 0x3a, 0x61,
+    0x39, 0x3a, 0x33, 0x36, 0x3a, 0x36, 0x34, 0x3a, 0x34, 0x30, 0x3a, 0x39,
+    0x65, 0x3a, 0x66, 0x35, 0x3a, 0x65, 0x34, 0x3a, 0x35, 0x38, 0x3a, 0x38,
+    0x34, 0x3a, 0x36, 0x37, 0x3a, 0x38, 0x63, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x36, 0x62, 0x3a, 0x32, 0x66, 0x3a, 0x33, 0x34,
+    0x3a, 0x61, 0x64, 0x3a, 0x38, 0x39, 0x3a, 0x35, 0x38, 0x3a, 0x62, 0x65,
+    0x3a, 0x36, 0x32, 0x3a, 0x66, 0x64, 0x3a, 0x62, 0x30, 0x3a, 0x36, 0x62,
+    0x3a, 0x35, 0x63, 0x3a, 0x63, 0x65, 0x3a, 0x62, 0x62, 0x3a, 0x39, 0x64,
+    0x3a, 0x64, 0x39, 0x3a, 0x34, 0x66, 0x3a, 0x34, 0x65, 0x3a, 0x33, 0x39,
+    0x3a, 0x66, 0x33, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x65, 0x62, 0x3a, 0x66, 0x33, 0x3a, 0x63, 0x30, 0x3a, 0x32,
+    0x61, 0x3a, 0x38, 0x37, 0x3a, 0x38, 0x39, 0x3a, 0x62, 0x31, 0x3a, 0x66,
+    0x62, 0x3a, 0x37, 0x64, 0x3a, 0x35, 0x31, 0x3a, 0x31, 0x39, 0x3a, 0x39,
+    0x35, 0x3a, 0x64, 0x36, 0x3a, 0x36, 0x33, 0x3a, 0x62, 0x37, 0x3a, 0x32,
+    0x39, 0x3a, 0x30, 0x36, 0x3a, 0x64, 0x39, 0x3a, 0x31, 0x33, 0x3a, 0x63,
+    0x65, 0x3a, 0x30, 0x64, 0x3a, 0x35, 0x65, 0x3a, 0x31, 0x30, 0x3a, 0x35,
+    0x36, 0x3a, 0x38, 0x61, 0x3a, 0x38, 0x61, 0x3a, 0x37, 0x37, 0x3a, 0x65,
+    0x32, 0x3a, 0x35, 0x38, 0x3a, 0x36, 0x31, 0x3a, 0x36, 0x37, 0x3a, 0x65,
+    0x37, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x33, 0x54,
+    0x43, 0x43, 0x41, 0x73, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67,
+    0x49, 0x4f, 0x48, 0x61, 0x49, 0x41, 0x41, 0x51, 0x41, 0x43, 0x37, 0x4c,
+    0x64, 0x67, 0x67, 0x48, 0x69, 0x4e, 0x74, 0x67, 0x59, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x65, 0x54, 0x45, 0x4c, 0x0a, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x52,
+    0x45, 0x55, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x45, 0x31, 0x52, 0x44, 0x49, 0x46, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79, 0x49,
+    0x45, 0x64, 0x74, 0x59, 0x6b, 0x67, 0x78, 0x4a, 0x44, 0x41, 0x69, 0x42,
+    0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x73, 0x54, 0x47, 0x31, 0x52, 0x44,
+    0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75,
+    0x64, 0x47, 0x56, 0x79, 0x49, 0x46, 0x56, 0x75, 0x61, 0x58, 0x5a, 0x6c,
+    0x63, 0x6e, 0x4e, 0x68, 0x62, 0x43, 0x42, 0x44, 0x51, 0x54, 0x45, 0x6d,
+    0x4d, 0x43, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x64,
+    0x56, 0x45, 0x4d, 0x67, 0x56, 0x48, 0x4a, 0x31, 0x0a, 0x63, 0x33, 0x52,
+    0x44, 0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x49, 0x67, 0x56, 0x57, 0x35,
+    0x70, 0x64, 0x6d, 0x56, 0x79, 0x63, 0x32, 0x46, 0x73, 0x49, 0x45, 0x4e,
+    0x42, 0x49, 0x45, 0x6b, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x59,
+    0x77, 0x4d, 0x7a, 0x49, 0x79, 0x4d, 0x54, 0x55, 0x31, 0x4e, 0x44, 0x49,
+    0x34, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x55, 0x78, 0x4d, 0x6a, 0x4d,
+    0x78, 0x0a, 0x4d, 0x6a, 0x49, 0x31, 0x4f, 0x54, 0x55, 0x35, 0x57, 0x6a,
+    0x42, 0x35, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x47, 0x45, 0x77, 0x4a, 0x45, 0x52, 0x54, 0x45, 0x63, 0x4d, 0x42,
+    0x6f, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x54, 0x56, 0x45,
+    0x4d, 0x67, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x52, 0x44, 0x5a, 0x57,
+    0x35, 0x30, 0x5a, 0x58, 0x49, 0x67, 0x0a, 0x52, 0x32, 0x31, 0x69, 0x53,
+    0x44, 0x45, 0x6b, 0x4d, 0x43, 0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x78, 0x4d, 0x62, 0x56, 0x45, 0x4d, 0x67, 0x56, 0x48, 0x4a, 0x31, 0x63,
+    0x33, 0x52, 0x44, 0x5a, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x49, 0x67, 0x56,
+    0x57, 0x35, 0x70, 0x64, 0x6d, 0x56, 0x79, 0x63, 0x32, 0x46, 0x73, 0x49,
+    0x45, 0x4e, 0x42, 0x4d, 0x53, 0x59, 0x77, 0x4a, 0x41, 0x59, 0x44, 0x0a,
+    0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x31, 0x55, 0x51, 0x79, 0x42, 0x55,
+    0x63, 0x6e, 0x56, 0x7a, 0x64, 0x45, 0x4e, 0x6c, 0x62, 0x6e, 0x52, 0x6c,
+    0x63, 0x69, 0x42, 0x56, 0x62, 0x6d, 0x6c, 0x32, 0x5a, 0x58, 0x4a, 0x7a,
+    0x59, 0x57, 0x77, 0x67, 0x51, 0x30, 0x45, 0x67, 0x53, 0x54, 0x43, 0x43,
+    0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49,
+    0x68, 0x76, 0x63, 0x4e, 0x0a, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41,
+    0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f,
+    0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4b, 0x52, 0x33, 0x49, 0x35, 0x5a,
+    0x45, 0x72, 0x35, 0x44, 0x30, 0x4d, 0x61, 0x63, 0x51, 0x39, 0x43, 0x61,
+    0x48, 0x6e, 0x50, 0x4d, 0x34, 0x32, 0x51, 0x39, 0x65, 0x33, 0x73, 0x39,
+    0x42, 0x36, 0x44, 0x47, 0x74, 0x78, 0x6e, 0x53, 0x52, 0x0a, 0x4a, 0x4a,
+    0x5a, 0x34, 0x48, 0x67, 0x6d, 0x67, 0x6d, 0x35, 0x71, 0x56, 0x53, 0x6b,
+    0x72, 0x31, 0x59, 0x6e, 0x77, 0x43, 0x71, 0x4d, 0x71, 0x73, 0x2b, 0x31,
+    0x6f, 0x45, 0x64, 0x6a, 0x6e, 0x65, 0x58, 0x2f, 0x48, 0x35, 0x73, 0x37,
+    0x2f, 0x7a, 0x41, 0x31, 0x68, 0x56, 0x30, 0x71, 0x71, 0x33, 0x34, 0x77,
+    0x51, 0x69, 0x30, 0x66, 0x69, 0x55, 0x32, 0x69, 0x49, 0x49, 0x41, 0x49,
+    0x33, 0x54, 0x0a, 0x66, 0x43, 0x5a, 0x64, 0x7a, 0x48, 0x64, 0x35, 0x35,
+    0x79, 0x78, 0x34, 0x4f, 0x61, 0x67, 0x6d, 0x63, 0x77, 0x36, 0x69, 0x58,
+    0x53, 0x56, 0x70, 0x68, 0x55, 0x39, 0x56, 0x44, 0x70, 0x72, 0x76, 0x78,
+    0x72, 0x6c, 0x45, 0x34, 0x56, 0x63, 0x39, 0x33, 0x78, 0x39, 0x55, 0x49,
+    0x75, 0x56, 0x76, 0x5a, 0x61, 0x6f, 0x7a, 0x68, 0x44, 0x72, 0x7a, 0x7a,
+    0x6e, 0x71, 0x2b, 0x56, 0x5a, 0x65, 0x75, 0x0a, 0x6a, 0x52, 0x49, 0x50,
+    0x46, 0x44, 0x50, 0x69, 0x55, 0x48, 0x44, 0x44, 0x53, 0x59, 0x63, 0x54,
+    0x76, 0x46, 0x48, 0x65, 0x31, 0x35, 0x67, 0x53, 0x57, 0x75, 0x38, 0x36,
+    0x67, 0x7a, 0x4f, 0x53, 0x42, 0x6e, 0x57, 0x4c, 0x6b, 0x6e, 0x77, 0x53,
+    0x61, 0x48, 0x74, 0x77, 0x61, 0x67, 0x2b, 0x31, 0x6d, 0x37, 0x5a, 0x33,
+    0x57, 0x30, 0x68, 0x5a, 0x6e, 0x65, 0x54, 0x76, 0x57, 0x71, 0x33, 0x7a,
+    0x0a, 0x77, 0x5a, 0x37, 0x55, 0x31, 0x30, 0x56, 0x4f, 0x79, 0x6c, 0x59,
+    0x30, 0x49, 0x62, 0x77, 0x2b, 0x46, 0x31, 0x74, 0x76, 0x64, 0x77, 0x78,
+    0x49, 0x41, 0x55, 0x4d, 0x70, 0x73, 0x4e, 0x30, 0x2f, 0x6c, 0x6d, 0x37,
+    0x6d, 0x6c, 0x61, 0x6f, 0x4d, 0x77, 0x43, 0x43, 0x32, 0x2f, 0x54, 0x34,
+    0x32, 0x4a, 0x35, 0x7a, 0x6a, 0x58, 0x4d, 0x39, 0x4f, 0x67, 0x64, 0x77,
+    0x5a, 0x75, 0x35, 0x47, 0x51, 0x0a, 0x66, 0x65, 0x7a, 0x6d, 0x6c, 0x77,
+    0x51, 0x65, 0x6b, 0x38, 0x77, 0x69, 0x53, 0x64, 0x65, 0x58, 0x68, 0x72,
+    0x59, 0x54, 0x43, 0x6a, 0x78, 0x44, 0x49, 0x33, 0x64, 0x2b, 0x38, 0x4e,
+    0x7a, 0x6d, 0x7a, 0x53, 0x51, 0x66, 0x4f, 0x34, 0x4f, 0x62, 0x4e, 0x44,
+    0x71, 0x44, 0x4e, 0x4f, 0x4d, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61,
+    0x4e, 0x6a, 0x4d, 0x47, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x0a, 0x56,
+    0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, 0x41, 0x55, 0x6b,
+    0x71, 0x52, 0x31, 0x4c, 0x4b, 0x53, 0x65, 0x76, 0x6f, 0x46, 0x45, 0x36,
+    0x33, 0x6e, 0x38, 0x69, 0x73, 0x57, 0x56, 0x70, 0x65, 0x73, 0x51, 0x64,
+    0x58, 0x4d, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41,
+    0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f,
+    0x7a, 0x41, 0x4f, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x42,
+    0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x59, 0x59, 0x77,
+    0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45,
+    0x46, 0x4a, 0x4b, 0x6b, 0x64, 0x53, 0x79, 0x6b, 0x6e, 0x72, 0x36, 0x42,
+    0x52, 0x4f, 0x74, 0x35, 0x2f, 0x49, 0x72, 0x46, 0x6c, 0x61, 0x58, 0x72,
+    0x45, 0x48, 0x56, 0x7a, 0x4d, 0x41, 0x30, 0x47, 0x0a, 0x43, 0x53, 0x71,
+    0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55,
+    0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x41, 0x6f, 0x30, 0x75, 0x43,
+    0x47, 0x31, 0x65, 0x62, 0x34, 0x65, 0x2f, 0x43, 0x58, 0x33, 0x43, 0x4a,
+    0x72, 0x4f, 0x35, 0x55, 0x55, 0x56, 0x67, 0x38, 0x52, 0x4d, 0x4b, 0x57,
+    0x61, 0x54, 0x7a, 0x71, 0x77, 0x4f, 0x75, 0x41, 0x47, 0x79, 0x32, 0x58,
+    0x31, 0x0a, 0x37, 0x63, 0x61, 0x58, 0x4a, 0x2f, 0x34, 0x6c, 0x38, 0x6c,
+    0x66, 0x6d, 0x58, 0x70, 0x57, 0x4d, 0x50, 0x6d, 0x52, 0x67, 0x46, 0x56,
+    0x70, 0x2f, 0x4c, 0x77, 0x30, 0x42, 0x78, 0x62, 0x46, 0x67, 0x2f, 0x55,
+    0x55, 0x31, 0x7a, 0x2f, 0x43, 0x79, 0x76, 0x77, 0x62, 0x5a, 0x37, 0x31,
+    0x71, 0x2b, 0x73, 0x32, 0x49, 0x68, 0x74, 0x4e, 0x65, 0x72, 0x4e, 0x58,
+    0x78, 0x54, 0x50, 0x71, 0x59, 0x6e, 0x0a, 0x38, 0x61, 0x45, 0x74, 0x32,
+    0x68, 0x6f, 0x6a, 0x6e, 0x63, 0x7a, 0x64, 0x37, 0x44, 0x77, 0x74, 0x6e,
+    0x69, 0x63, 0x30, 0x58, 0x51, 0x2f, 0x43, 0x4e, 0x6e, 0x6d, 0x38, 0x79,
+    0x55, 0x70, 0x69, 0x4c, 0x65, 0x31, 0x72, 0x32, 0x58, 0x31, 0x42, 0x51,
+    0x33, 0x79, 0x32, 0x71, 0x73, 0x72, 0x74, 0x59, 0x62, 0x45, 0x33, 0x67,
+    0x68, 0x55, 0x4a, 0x47, 0x6f, 0x6f, 0x57, 0x4d, 0x4e, 0x6a, 0x73, 0x0a,
+    0x79, 0x64, 0x5a, 0x48, 0x63, 0x6e, 0x68, 0x4c, 0x45, 0x45, 0x59, 0x55,
+    0x6a, 0x6c, 0x38, 0x4f, 0x72, 0x2b, 0x7a, 0x48, 0x4c, 0x36, 0x73, 0x51,
+    0x31, 0x37, 0x62, 0x78, 0x62, 0x75, 0x79, 0x47, 0x73, 0x73, 0x4c, 0x6f,
+    0x44, 0x5a, 0x4a, 0x7a, 0x33, 0x4b, 0x4c, 0x30, 0x44, 0x7a, 0x71, 0x2f,
+    0x59, 0x53, 0x4d, 0x51, 0x69, 0x5a, 0x78, 0x49, 0x51, 0x47, 0x35, 0x77,
+    0x41, 0x4c, 0x50, 0x54, 0x0a, 0x75, 0x6a, 0x64, 0x45, 0x57, 0x42, 0x46,
+    0x36, 0x41, 0x6d, 0x71, 0x49, 0x38, 0x44, 0x63, 0x30, 0x38, 0x42, 0x6e,
+    0x70, 0x72, 0x4e, 0x52, 0x6c, 0x63, 0x2f, 0x5a, 0x70, 0x6a, 0x47, 0x53,
+    0x55, 0x4f, 0x6e, 0x6d, 0x46, 0x4b, 0x62, 0x41, 0x57, 0x4b, 0x77, 0x79,
+    0x43, 0x50, 0x77, 0x61, 0x63, 0x78, 0x2f, 0x30, 0x51, 0x4b, 0x35, 0x34,
+    0x50, 0x4c, 0x4c, 0x61, 0x65, 0x34, 0x78, 0x57, 0x2f, 0x0a, 0x32, 0x54,
+    0x59, 0x63, 0x75, 0x69, 0x55, 0x61, 0x55, 0x6a, 0x30, 0x61, 0x37, 0x43,
+    0x49, 0x4d, 0x48, 0x4f, 0x43, 0x6b, 0x6f, 0x6a, 0x33, 0x77, 0x36, 0x44,
+    0x6e, 0x50, 0x67, 0x63, 0x42, 0x37, 0x37, 0x56, 0x30, 0x66, 0x62, 0x38,
+    0x58, 0x51, 0x43, 0x39, 0x65, 0x59, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43,
+    0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20,
+    0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x43,
+    0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c,
+    0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d,
+    0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74,
+    0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20,
+    0x52, 0x6f, 0x6f, 0x74, 0x20, 0x4f, 0x3d, 0x43, 0x79, 0x62, 0x65, 0x72,
+    0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x0a, 0x23,
+    0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x43, 0x79, 0x62,
+    0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
+    0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x34, 0x38, 0x33, 0x35, 0x37,
+    0x30, 0x33, 0x32, 0x37, 0x38, 0x34, 0x35, 0x39, 0x36, 0x38, 0x32, 0x38,
+    0x37, 0x37, 0x34, 0x38, 0x34, 0x33, 0x36, 0x30, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x37, 0x32, 0x3a, 0x65, 0x34, 0x3a, 0x34, 0x61,
+    0x3a, 0x38, 0x37, 0x3a, 0x65, 0x33, 0x3a, 0x36, 0x39, 0x3a, 0x34, 0x30,
+    0x3a, 0x38, 0x30, 0x3a, 0x37, 0x37, 0x3a, 0x65, 0x61, 0x3a, 0x62, 0x63,
+    0x3a, 0x65, 0x33, 0x3a, 0x66, 0x34, 0x3a, 0x66, 0x66, 0x3a, 0x66, 0x30,
+    0x3a, 0x65, 0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x35, 0x66, 0x3a, 0x34, 0x33, 0x3a, 0x65, 0x35, 0x3a, 0x62, 0x31, 0x3a,
+    0x62, 0x66, 0x3a, 0x66, 0x38, 0x3a, 0x37, 0x38, 0x3a, 0x38, 0x63, 0x3a,
+    0x61, 0x63, 0x3a, 0x31, 0x63, 0x3a, 0x63, 0x37, 0x3a, 0x63, 0x61, 0x3a,
+    0x34, 0x61, 0x3a, 0x39, 0x61, 0x3a, 0x63, 0x36, 0x3a, 0x32, 0x32, 0x3a,
+    0x32, 0x62, 0x3a, 0x63, 0x63, 0x3a, 0x33, 0x34, 0x3a, 0x63, 0x36, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x39, 0x36,
+    0x3a, 0x30, 0x61, 0x3a, 0x64, 0x66, 0x3a, 0x30, 0x30, 0x3a, 0x36, 0x33,
+    0x3a, 0x65, 0x39, 0x3a, 0x36, 0x33, 0x3a, 0x35, 0x36, 0x3a, 0x37, 0x35,
+    0x3a, 0x30, 0x63, 0x3a, 0x32, 0x39, 0x3a, 0x36, 0x35, 0x3a, 0x64, 0x64,
+    0x3a, 0x30, 0x61, 0x3a, 0x30, 0x38, 0x3a, 0x36, 0x37, 0x3a, 0x64, 0x61,
+    0x3a, 0x30, 0x62, 0x3a, 0x39, 0x63, 0x3a, 0x62, 0x64, 0x3a, 0x36, 0x65,
+    0x3a, 0x37, 0x37, 0x3a, 0x37, 0x31, 0x3a, 0x34, 0x61, 0x3a, 0x65, 0x61,
+    0x3a, 0x66, 0x62, 0x3a, 0x32, 0x33, 0x3a, 0x34, 0x39, 0x3a, 0x61, 0x62,
+    0x3a, 0x33, 0x39, 0x3a, 0x33, 0x64, 0x3a, 0x61, 0x33, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x6f, 0x54, 0x43, 0x43, 0x41, 0x6f,
+    0x6d, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4c, 0x42, 0x41,
+    0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x44, 0x34, 0x57, 0x71, 0x4c, 0x55,
+    0x67, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76,
+    0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x77, 0x4f, 0x7a,
+    0x45, 0x59, 0x4d, 0x42, 0x59, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x68, 0x4d, 0x50, 0x51, 0x33, 0x6c, 0x69, 0x5a, 0x58, 0x4a, 0x30, 0x63,
+    0x6e, 0x56, 0x7a, 0x64, 0x43, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4d,
+    0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45,
+    0x78, 0x5a, 0x44, 0x65, 0x57, 0x4a, 0x6c, 0x63, 0x6e, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x49, 0x45, 0x64, 0x73, 0x62, 0x32, 0x4a, 0x68, 0x0a,
+    0x62, 0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x4d, 0x42, 0x34, 0x58,
+    0x44, 0x54, 0x41, 0x32, 0x4d, 0x54, 0x49, 0x78, 0x4e, 0x54, 0x41, 0x34,
+    0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44, 0x54, 0x49, 0x78,
+    0x4d, 0x54, 0x49, 0x78, 0x4e, 0x54, 0x41, 0x34, 0x4d, 0x44, 0x41, 0x77,
+    0x4d, 0x46, 0x6f, 0x77, 0x4f, 0x7a, 0x45, 0x59, 0x4d, 0x42, 0x59, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x0a, 0x43, 0x68, 0x4d, 0x50, 0x51, 0x33, 0x6c,
+    0x69, 0x5a, 0x58, 0x4a, 0x30, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x77,
+    0x67, 0x53, 0x57, 0x35, 0x6a, 0x4d, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x5a, 0x44, 0x65, 0x57, 0x4a,
+    0x6c, 0x63, 0x6e, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x64,
+    0x73, 0x62, 0x32, 0x4a, 0x68, 0x62, 0x43, 0x42, 0x53, 0x0a, 0x62, 0x32,
+    0x39, 0x30, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67,
+    0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51,
+    0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49,
+    0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x2b, 0x4d,
+    0x69, 0x38, 0x76, 0x52, 0x52, 0x51, 0x5a, 0x68, 0x50, 0x2f, 0x38, 0x4e,
+    0x4e, 0x35, 0x0a, 0x37, 0x43, 0x50, 0x79, 0x74, 0x78, 0x72, 0x48, 0x6a,
+    0x6f, 0x58, 0x78, 0x45, 0x6e, 0x4f, 0x6d, 0x47, 0x61, 0x6f, 0x51, 0x32,
+    0x35, 0x79, 0x69, 0x5a, 0x58, 0x52, 0x61, 0x64, 0x7a, 0x35, 0x52, 0x66,
+    0x56, 0x62, 0x32, 0x33, 0x43, 0x4f, 0x32, 0x31, 0x4f, 0x31, 0x66, 0x57,
+    0x4c, 0x45, 0x33, 0x54, 0x64, 0x56, 0x4a, 0x44, 0x6d, 0x37, 0x31, 0x61,
+    0x6f, 0x66, 0x57, 0x30, 0x6f, 0x7a, 0x53, 0x0a, 0x4a, 0x38, 0x62, 0x69,
+    0x2f, 0x7a, 0x61, 0x66, 0x6d, 0x47, 0x57, 0x67, 0x45, 0x30, 0x37, 0x47,
+    0x4b, 0x6d, 0x53, 0x62, 0x31, 0x5a, 0x41, 0x53, 0x7a, 0x78, 0x51, 0x47,
+    0x39, 0x44, 0x76, 0x6a, 0x31, 0x43, 0x69, 0x2b, 0x36, 0x41, 0x37, 0x34,
+    0x71, 0x30, 0x35, 0x49, 0x6c, 0x47, 0x32, 0x4f, 0x6c, 0x54, 0x45, 0x51,
+    0x58, 0x4f, 0x32, 0x69, 0x4c, 0x62, 0x33, 0x56, 0x4f, 0x6d, 0x32, 0x79,
+    0x0a, 0x48, 0x4c, 0x74, 0x67, 0x77, 0x45, 0x5a, 0x4c, 0x41, 0x66, 0x56,
+    0x4a, 0x72, 0x6e, 0x35, 0x47, 0x69, 0x74, 0x42, 0x30, 0x6a, 0x61, 0x45,
+    0x4d, 0x41, 0x73, 0x37, 0x75, 0x2f, 0x4f, 0x65, 0x50, 0x75, 0x47, 0x74,
+    0x6d, 0x38, 0x33, 0x39, 0x45, 0x41, 0x4c, 0x39, 0x6d, 0x4a, 0x52, 0x51,
+    0x72, 0x33, 0x52, 0x41, 0x77, 0x48, 0x51, 0x65, 0x57, 0x50, 0x30, 0x33,
+    0x32, 0x61, 0x37, 0x69, 0x50, 0x0a, 0x74, 0x33, 0x73, 0x4d, 0x70, 0x54,
+    0x6a, 0x72, 0x33, 0x6b, 0x66, 0x62, 0x31, 0x56, 0x30, 0x35, 0x2f, 0x49,
+    0x69, 0x6e, 0x38, 0x39, 0x63, 0x71, 0x64, 0x50, 0x48, 0x6f, 0x57, 0x71,
+    0x49, 0x37, 0x6e, 0x31, 0x43, 0x36, 0x70, 0x6f, 0x78, 0x46, 0x4e, 0x63,
+    0x4a, 0x51, 0x5a, 0x5a, 0x58, 0x63, 0x59, 0x34, 0x4c, 0x76, 0x33, 0x62,
+    0x39, 0x33, 0x54, 0x5a, 0x78, 0x69, 0x79, 0x57, 0x4e, 0x7a, 0x0a, 0x46,
+    0x74, 0x41, 0x70, 0x44, 0x30, 0x6d, 0x70, 0x53, 0x50, 0x43, 0x7a, 0x71,
+    0x72, 0x64, 0x73, 0x78, 0x61, 0x63, 0x77, 0x4f, 0x55, 0x42, 0x64, 0x72,
+    0x73, 0x54, 0x69, 0x58, 0x53, 0x5a, 0x54, 0x38, 0x4d, 0x34, 0x63, 0x49,
+    0x77, 0x68, 0x68, 0x71, 0x4a, 0x51, 0x5a, 0x75, 0x67, 0x52, 0x69, 0x51,
+    0x4f, 0x77, 0x66, 0x4f, 0x48, 0x42, 0x33, 0x45, 0x67, 0x5a, 0x78, 0x70,
+    0x7a, 0x41, 0x59, 0x0a, 0x58, 0x53, 0x55, 0x6e, 0x70, 0x51, 0x49, 0x44,
+    0x41, 0x51, 0x41, 0x42, 0x6f, 0x34, 0x47, 0x6c, 0x4d, 0x49, 0x47, 0x69,
+    0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42,
+    0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, 0x50,
+    0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45,
+    0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x0a, 0x4d, 0x42, 0x30,
+    0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53,
+    0x32, 0x43, 0x48, 0x73, 0x4e, 0x65, 0x73, 0x79, 0x73, 0x49, 0x45, 0x79,
+    0x47, 0x56, 0x6a, 0x4a, 0x65, 0x7a, 0x36, 0x74, 0x75, 0x68, 0x53, 0x31,
+    0x77, 0x56, 0x7a, 0x41, 0x2f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x38,
+    0x45, 0x4f, 0x44, 0x41, 0x32, 0x4d, 0x44, 0x53, 0x67, 0x4d, 0x71, 0x41,
+    0x77, 0x0a, 0x68, 0x69, 0x35, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69,
+    0x38, 0x76, 0x64, 0x33, 0x64, 0x33, 0x4d, 0x69, 0x35, 0x77, 0x64, 0x57,
+    0x4a, 0x73, 0x61, 0x57, 0x4d, 0x74, 0x64, 0x48, 0x4a, 0x31, 0x63, 0x33,
+    0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x32, 0x4e, 0x79, 0x62, 0x43,
+    0x39, 0x6a, 0x64, 0x43, 0x39, 0x6a, 0x64, 0x48, 0x4a, 0x76, 0x62, 0x33,
+    0x51, 0x75, 0x59, 0x33, 0x4a, 0x73, 0x0a, 0x4d, 0x42, 0x38, 0x47, 0x41,
+    0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46,
+    0x4c, 0x59, 0x49, 0x65, 0x77, 0x31, 0x36, 0x7a, 0x4b, 0x77, 0x67, 0x54,
+    0x49, 0x5a, 0x57, 0x4d, 0x6c, 0x37, 0x50, 0x71, 0x32, 0x36, 0x46, 0x4c,
+    0x58, 0x42, 0x58, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53,
+    0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x0a,
+    0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x42, 0x57, 0x37, 0x77, 0x6f, 0x6a,
+    0x6f, 0x46, 0x52, 0x4f, 0x6c, 0x5a, 0x66, 0x4a, 0x2b, 0x49, 0x6e, 0x61,
+    0x52, 0x63, 0x48, 0x55, 0x6f, 0x77, 0x41, 0x6c, 0x39, 0x42, 0x38, 0x54,
+    0x71, 0x37, 0x65, 0x6a, 0x68, 0x56, 0x68, 0x70, 0x77, 0x6a, 0x43, 0x74,
+    0x32, 0x42, 0x57, 0x4b, 0x4c, 0x65, 0x50, 0x4a, 0x7a, 0x59, 0x46, 0x61,
+    0x2b, 0x48, 0x4d, 0x6a, 0x0a, 0x57, 0x71, 0x64, 0x38, 0x42, 0x66, 0x50,
+    0x39, 0x49, 0x6a, 0x73, 0x4f, 0x30, 0x51, 0x62, 0x45, 0x32, 0x7a, 0x5a,
+    0x4d, 0x63, 0x77, 0x53, 0x4f, 0x35, 0x62, 0x41, 0x69, 0x35, 0x4d, 0x58,
+    0x7a, 0x4c, 0x71, 0x58, 0x5a, 0x49, 0x2b, 0x4f, 0x34, 0x54, 0x6b, 0x6f,
+    0x67, 0x70, 0x32, 0x34, 0x43, 0x4a, 0x4a, 0x38, 0x69, 0x59, 0x47, 0x64,
+    0x37, 0x69, 0x78, 0x31, 0x79, 0x43, 0x63, 0x55, 0x78, 0x0a, 0x58, 0x4f,
+    0x6c, 0x35, 0x6e, 0x34, 0x42, 0x48, 0x50, 0x61, 0x32, 0x68, 0x43, 0x77,
+    0x63, 0x55, 0x50, 0x55, 0x66, 0x2f, 0x41, 0x32, 0x6b, 0x61, 0x44, 0x41,
+    0x74, 0x45, 0x35, 0x32, 0x4d, 0x6c, 0x70, 0x33, 0x2b, 0x79, 0x79, 0x62,
+    0x68, 0x32, 0x68, 0x4f, 0x30, 0x6a, 0x39, 0x6e, 0x30, 0x48, 0x71, 0x30,
+    0x56, 0x2b, 0x30, 0x39, 0x2b, 0x7a, 0x76, 0x2b, 0x6d, 0x4b, 0x74, 0x73,
+    0x32, 0x6f, 0x0a, 0x6f, 0x6d, 0x63, 0x72, 0x55, 0x74, 0x57, 0x33, 0x5a,
+    0x66, 0x41, 0x35, 0x54, 0x47, 0x4f, 0x67, 0x6b, 0x58, 0x6d, 0x54, 0x55,
+    0x67, 0x39, 0x55, 0x33, 0x59, 0x4f, 0x37, 0x6e, 0x39, 0x47, 0x50, 0x70,
+    0x31, 0x4e, 0x7a, 0x77, 0x38, 0x76, 0x2f, 0x4d, 0x4f, 0x78, 0x38, 0x42,
+    0x4c, 0x6a, 0x59, 0x52, 0x42, 0x2b, 0x54, 0x58, 0x33, 0x45, 0x4a, 0x49,
+    0x72, 0x64, 0x75, 0x50, 0x75, 0x6f, 0x63, 0x0a, 0x41, 0x30, 0x36, 0x64,
+    0x47, 0x69, 0x42, 0x68, 0x2b, 0x34, 0x45, 0x33, 0x37, 0x46, 0x37, 0x38,
+    0x43, 0x6b, 0x57, 0x72, 0x31, 0x2b, 0x63, 0x58, 0x56, 0x64, 0x43, 0x67,
+    0x36, 0x6d, 0x43, 0x62, 0x70, 0x76, 0x62, 0x6a, 0x6a, 0x46, 0x73, 0x70,
+    0x77, 0x67, 0x5a, 0x67, 0x46, 0x4a, 0x30, 0x74, 0x6c, 0x30, 0x79, 0x70,
+    0x6b, 0x78, 0x57, 0x64, 0x59, 0x63, 0x51, 0x42, 0x58, 0x30, 0x6a, 0x57,
+    0x0a, 0x57, 0x4c, 0x31, 0x57, 0x4d, 0x52, 0x4a, 0x4f, 0x45, 0x63, 0x67,
+    0x68, 0x34, 0x4c, 0x4d, 0x52, 0x6b, 0x57, 0x58, 0x62, 0x74, 0x4b, 0x61,
+    0x49, 0x4f, 0x4d, 0x35, 0x56, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49,
+    0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x65,
+    0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61,
+    0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x20, 0x4f, 0x3d, 0x47, 0x65,
+    0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
+    0x4f, 0x55, 0x3d, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20,
+    0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f,
+    0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d,
+    0x20, 0x47, 0x33, 0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75,
+    0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x28,
+    0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65, 0x6f, 0x54,
+    0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20,
+    0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
+    0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a,
+    0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x47, 0x65,
+    0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61,
+    0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x32, 0x38, 0x38, 0x30, 0x39,
+    0x31, 0x30, 0x35, 0x37, 0x36, 0x39, 0x39, 0x32, 0x38, 0x35, 0x36, 0x34,
+    0x33, 0x31, 0x33, 0x39, 0x38, 0x34, 0x30, 0x38, 0x35, 0x32, 0x30, 0x39,
+    0x39, 0x37, 0x35, 0x38, 0x38, 0x35, 0x35, 0x39, 0x39, 0x0a, 0x23, 0x20,
+    0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x62, 0x35, 0x3a, 0x65, 0x38, 0x3a, 0x33,
+    0x34, 0x3a, 0x33, 0x36, 0x3a, 0x63, 0x39, 0x3a, 0x31, 0x30, 0x3a, 0x34,
+    0x34, 0x3a, 0x35, 0x38, 0x3a, 0x34, 0x38, 0x3a, 0x37, 0x30, 0x3a, 0x36,
+    0x64, 0x3a, 0x32, 0x65, 0x3a, 0x38, 0x33, 0x3a, 0x64, 0x34, 0x3a, 0x62,
+    0x38, 0x3a, 0x30, 0x35, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x30, 0x33, 0x3a, 0x39, 0x65, 0x3a, 0x65, 0x64, 0x3a, 0x62, 0x38,
+    0x3a, 0x30, 0x62, 0x3a, 0x65, 0x37, 0x3a, 0x61, 0x30, 0x3a, 0x33, 0x63,
+    0x3a, 0x36, 0x39, 0x3a, 0x35, 0x33, 0x3a, 0x38, 0x39, 0x3a, 0x33, 0x62,
+    0x3a, 0x32, 0x30, 0x3a, 0x64, 0x32, 0x3a, 0x64, 0x39, 0x3a, 0x33, 0x32,
+    0x3a, 0x33, 0x61, 0x3a, 0x34, 0x63, 0x3a, 0x32, 0x61, 0x3a, 0x66, 0x64,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x62,
+    0x34, 0x3a, 0x37, 0x38, 0x3a, 0x62, 0x38, 0x3a, 0x31, 0x32, 0x3a, 0x32,
+    0x35, 0x3a, 0x30, 0x64, 0x3a, 0x66, 0x38, 0x3a, 0x37, 0x38, 0x3a, 0x36,
+    0x33, 0x3a, 0x35, 0x63, 0x3a, 0x32, 0x61, 0x3a, 0x61, 0x37, 0x3a, 0x65,
+    0x63, 0x3a, 0x37, 0x64, 0x3a, 0x31, 0x35, 0x3a, 0x35, 0x65, 0x3a, 0x61,
+    0x61, 0x3a, 0x36, 0x32, 0x3a, 0x35, 0x65, 0x3a, 0x65, 0x38, 0x3a, 0x32,
+    0x39, 0x3a, 0x31, 0x36, 0x3a, 0x65, 0x32, 0x3a, 0x63, 0x64, 0x3a, 0x32,
+    0x39, 0x3a, 0x34, 0x33, 0x3a, 0x36, 0x31, 0x3a, 0x38, 0x38, 0x3a, 0x36,
+    0x63, 0x3a, 0x64, 0x31, 0x3a, 0x66, 0x62, 0x3a, 0x64, 0x34, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x2f, 0x6a, 0x43, 0x43, 0x41,
+    0x75, 0x61, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x46,
+    0x61, 0x78, 0x75, 0x6c, 0x42, 0x6d, 0x79, 0x65, 0x55, 0x74, 0x42, 0x39,
+    0x69, 0x65, 0x70, 0x77, 0x78, 0x67, 0x50, 0x48, 0x7a, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a, 0x6d, 0x44, 0x45, 0x4c,
+    0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43,
+    0x56, 0x56, 0x4d, 0x78, 0x46, 0x6a, 0x41, 0x55, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x6f, 0x54, 0x44, 0x55, 0x64, 0x6c, 0x62, 0x31, 0x52, 0x79,
+    0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x78,
+    0x4f, 0x54, 0x41, 0x33, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54,
+    0x0a, 0x4d, 0x43, 0x68, 0x6a, 0x4b, 0x53, 0x41, 0x79, 0x4d, 0x44, 0x41,
+    0x34, 0x49, 0x45, 0x64, 0x6c, 0x62, 0x31, 0x52, 0x79, 0x64, 0x58, 0x4e,
+    0x30, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x67, 0x4c, 0x53, 0x42,
+    0x47, 0x62, 0x33, 0x49, 0x67, 0x59, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39,
+    0x79, 0x61, 0x58, 0x70, 0x6c, 0x5a, 0x43, 0x42, 0x31, 0x63, 0x32, 0x55,
+    0x67, 0x62, 0x32, 0x35, 0x73, 0x0a, 0x65, 0x54, 0x45, 0x32, 0x4d, 0x44,
+    0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x74, 0x52, 0x32,
+    0x56, 0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x48,
+    0x4a, 0x70, 0x62, 0x57, 0x46, 0x79, 0x65, 0x53, 0x42, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57,
+    0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x0a, 0x63,
+    0x6d, 0x6c, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x7a, 0x4d,
+    0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x34, 0x4d, 0x44, 0x51, 0x77, 0x4d,
+    0x6a, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44,
+    0x54, 0x4d, 0x33, 0x4d, 0x54, 0x49, 0x77, 0x4d, 0x54, 0x49, 0x7a, 0x4e,
+    0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x67, 0x5a, 0x67, 0x78, 0x43,
+    0x7a, 0x41, 0x4a, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54,
+    0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x4b, 0x45, 0x77, 0x31, 0x48, 0x5a, 0x57, 0x39, 0x55,
+    0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75,
+    0x4d, 0x54, 0x6b, 0x77, 0x4e, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c,
+    0x45, 0x7a, 0x41, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x0a, 0x4d, 0x6a, 0x41,
+    0x77, 0x4f, 0x43, 0x42, 0x48, 0x5a, 0x57, 0x39, 0x55, 0x63, 0x6e, 0x56,
+    0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30,
+    0x67, 0x52, 0x6d, 0x39, 0x79, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47, 0x68,
+    0x76, 0x63, 0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67, 0x64, 0x58, 0x4e,
+    0x6c, 0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6b, 0x78, 0x4e, 0x6a, 0x41,
+    0x30, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x4c, 0x55,
+    0x64, 0x6c, 0x62, 0x31, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x46,
+    0x42, 0x79, 0x61, 0x57, 0x31, 0x68, 0x63, 0x6e, 0x6b, 0x67, 0x51, 0x32,
+    0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47,
+    0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33,
+    0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x0a, 0x4c, 0x53, 0x42, 0x48, 0x4d,
+    0x7a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b,
+    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42,
+    0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41,
+    0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4e, 0x7a, 0x69, 0x58,
+    0x6d, 0x4a, 0x59, 0x48, 0x54, 0x4e, 0x58, 0x4f, 0x54, 0x49, 0x7a, 0x0a,
+    0x2b, 0x75, 0x76, 0x4c, 0x68, 0x34, 0x79, 0x6e, 0x31, 0x45, 0x72, 0x64,
+    0x42, 0x6f, 0x6a, 0x71, 0x5a, 0x49, 0x34, 0x78, 0x6d, 0x4b, 0x55, 0x34,
+    0x6b, 0x42, 0x36, 0x59, 0x7a, 0x79, 0x35, 0x6a, 0x4b, 0x2f, 0x42, 0x47,
+    0x76, 0x45, 0x53, 0x79, 0x69, 0x61, 0x48, 0x41, 0x4b, 0x41, 0x78, 0x4a,
+    0x63, 0x43, 0x47, 0x56, 0x6e, 0x32, 0x54, 0x41, 0x70, 0x70, 0x4d, 0x53,
+    0x41, 0x6d, 0x55, 0x6d, 0x0a, 0x68, 0x73, 0x61, 0x6c, 0x69, 0x66, 0x44,
+    0x36, 0x31, 0x34, 0x53, 0x67, 0x63, 0x4b, 0x39, 0x50, 0x47, 0x70, 0x63,
+    0x2f, 0x42, 0x6b, 0x54, 0x56, 0x79, 0x65, 0x74, 0x79, 0x45, 0x48, 0x33,
+    0x6b, 0x4d, 0x53, 0x6a, 0x37, 0x48, 0x47, 0x48, 0x6d, 0x4b, 0x41, 0x64,
+    0x45, 0x63, 0x35, 0x49, 0x69, 0x61, 0x61, 0x63, 0x44, 0x69, 0x47, 0x79,
+    0x64, 0x59, 0x38, 0x68, 0x53, 0x32, 0x70, 0x67, 0x6e, 0x0a, 0x35, 0x77,
+    0x68, 0x4d, 0x63, 0x44, 0x36, 0x30, 0x79, 0x52, 0x4c, 0x42, 0x78, 0x57,
+    0x65, 0x44, 0x58, 0x54, 0x50, 0x7a, 0x41, 0x78, 0x48, 0x73, 0x61, 0x74,
+    0x42, 0x54, 0x34, 0x74, 0x47, 0x36, 0x4e, 0x6d, 0x43, 0x55, 0x67, 0x4c,
+    0x74, 0x68, 0x59, 0x32, 0x78, 0x62, 0x46, 0x33, 0x37, 0x66, 0x51, 0x4a,
+    0x51, 0x65, 0x71, 0x77, 0x33, 0x43, 0x49, 0x53, 0x68, 0x77, 0x69, 0x50,
+    0x2f, 0x57, 0x0a, 0x4a, 0x6d, 0x78, 0x73, 0x59, 0x41, 0x51, 0x6c, 0x54,
+    0x6c, 0x56, 0x2b, 0x66, 0x65, 0x2b, 0x2f, 0x6c, 0x45, 0x6a, 0x65, 0x74,
+    0x78, 0x33, 0x64, 0x63, 0x49, 0x30, 0x46, 0x58, 0x34, 0x69, 0x6c, 0x6d,
+    0x2f, 0x4c, 0x43, 0x37, 0x75, 0x72, 0x52, 0x51, 0x45, 0x46, 0x74, 0x59,
+    0x6a, 0x67, 0x64, 0x56, 0x67, 0x62, 0x46, 0x41, 0x30, 0x64, 0x52, 0x49,
+    0x42, 0x6e, 0x38, 0x65, 0x78, 0x41, 0x4c, 0x0a, 0x44, 0x6d, 0x4b, 0x75,
+    0x64, 0x6c, 0x57, 0x2f, 0x58, 0x33, 0x65, 0x2b, 0x50, 0x6b, 0x6b, 0x42,
+    0x55, 0x7a, 0x32, 0x59, 0x4a, 0x51, 0x4e, 0x32, 0x4a, 0x46, 0x6f, 0x64,
+    0x74, 0x4e, 0x75, 0x4a, 0x36, 0x6e, 0x6e, 0x6c, 0x74, 0x72, 0x4d, 0x37,
+    0x50, 0x37, 0x70, 0x4d, 0x4b, 0x45, 0x46, 0x2f, 0x42, 0x71, 0x78, 0x71,
+    0x6a, 0x73, 0x48, 0x51, 0x39, 0x67, 0x55, 0x64, 0x66, 0x65, 0x5a, 0x43,
+    0x0a, 0x68, 0x75, 0x4f, 0x6c, 0x31, 0x55, 0x63, 0x43, 0x41, 0x77, 0x45,
+    0x41, 0x41, 0x61, 0x4e, 0x43, 0x4d, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59,
+    0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55,
+    0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41, 0x4f, 0x42, 0x67, 0x4e,
+    0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d,
+    0x43, 0x41, 0x51, 0x59, 0x77, 0x0a, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52,
+    0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4d, 0x52, 0x35, 0x79, 0x6f,
+    0x36, 0x68, 0x54, 0x67, 0x4d, 0x64, 0x48, 0x4e, 0x78, 0x72, 0x32, 0x7a,
+    0x46, 0x62, 0x6c, 0x44, 0x34, 0x2f, 0x4d, 0x48, 0x38, 0x74, 0x4d, 0x41,
+    0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51,
+    0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x0a, 0x41,
+    0x51, 0x41, 0x74, 0x78, 0x52, 0x50, 0x50, 0x56, 0x6f, 0x42, 0x37, 0x65,
+    0x6e, 0x69, 0x39, 0x6e, 0x36, 0x34, 0x73, 0x6d, 0x65, 0x66, 0x76, 0x32,
+    0x74, 0x2b, 0x55, 0x58, 0x67, 0x6c, 0x70, 0x70, 0x2b, 0x64, 0x75, 0x61,
+    0x49, 0x79, 0x39, 0x63, 0x72, 0x35, 0x48, 0x71, 0x51, 0x36, 0x58, 0x45,
+    0x72, 0x68, 0x4b, 0x38, 0x57, 0x54, 0x54, 0x4f, 0x64, 0x38, 0x6c, 0x4e,
+    0x4e, 0x54, 0x42, 0x0a, 0x7a, 0x55, 0x36, 0x42, 0x38, 0x41, 0x38, 0x45,
+    0x78, 0x43, 0x53, 0x7a, 0x4e, 0x4a, 0x62, 0x47, 0x70, 0x71, 0x6f, 0x77,
+    0x33, 0x32, 0x68, 0x68, 0x63, 0x39, 0x66, 0x35, 0x6a, 0x6f, 0x57, 0x4a,
+    0x37, 0x77, 0x35, 0x65, 0x6c, 0x53, 0x68, 0x4b, 0x4b, 0x69, 0x65, 0x50,
+    0x45, 0x49, 0x34, 0x75, 0x66, 0x49, 0x62, 0x45, 0x41, 0x70, 0x37, 0x61,
+    0x44, 0x48, 0x64, 0x6c, 0x44, 0x6b, 0x51, 0x4e, 0x0a, 0x6b, 0x76, 0x33,
+    0x39, 0x73, 0x78, 0x59, 0x32, 0x2b, 0x68, 0x45, 0x4e, 0x48, 0x59, 0x77,
+    0x4f, 0x42, 0x34, 0x6c, 0x71, 0x4b, 0x56, 0x62, 0x33, 0x63, 0x76, 0x54,
+    0x64, 0x46, 0x5a, 0x78, 0x33, 0x4e, 0x57, 0x5a, 0x58, 0x71, 0x78, 0x4e,
+    0x54, 0x32, 0x49, 0x37, 0x42, 0x51, 0x4d, 0x58, 0x58, 0x45, 0x78, 0x5a,
+    0x61, 0x63, 0x73, 0x65, 0x33, 0x61, 0x51, 0x48, 0x45, 0x65, 0x72, 0x47,
+    0x44, 0x0a, 0x41, 0x57, 0x68, 0x39, 0x6a, 0x55, 0x47, 0x68, 0x6c, 0x42,
+    0x6a, 0x42, 0x4a, 0x56, 0x7a, 0x38, 0x38, 0x50, 0x36, 0x44, 0x41, 0x6f,
+    0x64, 0x38, 0x44, 0x51, 0x33, 0x50, 0x4c, 0x67, 0x68, 0x63, 0x53, 0x6b,
+    0x41, 0x4e, 0x50, 0x75, 0x79, 0x42, 0x59, 0x65, 0x59, 0x6b, 0x32, 0x38,
+    0x72, 0x67, 0x44, 0x69, 0x30, 0x48, 0x73, 0x6a, 0x35, 0x57, 0x33, 0x49,
+    0x33, 0x31, 0x51, 0x59, 0x55, 0x48, 0x0a, 0x53, 0x4a, 0x73, 0x4d, 0x43,
+    0x38, 0x74, 0x4a, 0x50, 0x33, 0x33, 0x73, 0x74, 0x2f, 0x33, 0x4c, 0x6a,
+    0x57, 0x65, 0x4a, 0x47, 0x71, 0x76, 0x74, 0x75, 0x78, 0x36, 0x6a, 0x41,
+    0x41, 0x67, 0x49, 0x46, 0x79, 0x71, 0x43, 0x58, 0x44, 0x46, 0x64, 0x52,
+    0x6f, 0x6f, 0x74, 0x44, 0x34, 0x61, 0x62, 0x64, 0x4e, 0x6c, 0x46, 0x2b,
+    0x39, 0x52, 0x41, 0x73, 0x58, 0x71, 0x71, 0x61, 0x43, 0x32, 0x47, 0x0a,
+    0x73, 0x70, 0x6b, 0x69, 0x34, 0x63, 0x45, 0x72, 0x78, 0x35, 0x7a, 0x34,
+    0x38, 0x31, 0x2b, 0x6f, 0x67, 0x68, 0x4c, 0x72, 0x47, 0x52, 0x45, 0x74,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72,
+    0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f, 0x3d, 0x74,
+    0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
+    0x4f, 0x55, 0x3d, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x37, 0x20,
+    0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e,
+    0x6c, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,
+    0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
+    0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f, 0x3d, 0x74,
+    0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20,
+    0x4f, 0x55, 0x3d, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x37, 0x20,
+    0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e,
+    0x6c, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20,
+    0x22, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6d,
+    0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20,
+    0x2d, 0x20, 0x47, 0x32, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69,
+    0x61, 0x6c, 0x3a, 0x20, 0x37, 0x31, 0x37, 0x35, 0x38, 0x33, 0x32, 0x30,
+    0x36, 0x37, 0x32, 0x38, 0x32, 0x35, 0x34, 0x31, 0x30, 0x30, 0x32, 0x30,
+    0x36, 0x36, 0x31, 0x36, 0x32, 0x31, 0x30, 0x38, 0x35, 0x32, 0x35, 0x36,
+    0x34, 0x37, 0x32, 0x34, 0x30, 0x36, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x37, 0x34, 0x3a, 0x39, 0x64, 0x3a, 0x65, 0x61, 0x3a, 0x36,
+    0x30, 0x3a, 0x32, 0x34, 0x3a, 0x63, 0x34, 0x3a, 0x66, 0x64, 0x3a, 0x32,
+    0x32, 0x3a, 0x35, 0x33, 0x3a, 0x33, 0x65, 0x3a, 0x63, 0x63, 0x3a, 0x33,
+    0x61, 0x3a, 0x37, 0x32, 0x3a, 0x64, 0x39, 0x3a, 0x32, 0x39, 0x3a, 0x34,
+    0x66, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x61,
+    0x3a, 0x64, 0x62, 0x3a, 0x62, 0x63, 0x3a, 0x32, 0x32, 0x3a, 0x32, 0x33,
+    0x3a, 0x38, 0x66, 0x3a, 0x63, 0x34, 0x3a, 0x30, 0x31, 0x3a, 0x61, 0x31,
+    0x3a, 0x32, 0x37, 0x3a, 0x62, 0x62, 0x3a, 0x33, 0x38, 0x3a, 0x64, 0x64,
+    0x3a, 0x66, 0x34, 0x3a, 0x31, 0x64, 0x3a, 0x64, 0x62, 0x3a, 0x30, 0x38,
+    0x3a, 0x39, 0x65, 0x3a, 0x66, 0x30, 0x3a, 0x31, 0x32, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x34, 0x3a, 0x33,
+    0x31, 0x3a, 0x30, 0x64, 0x3a, 0x35, 0x30, 0x3a, 0x61, 0x66, 0x3a, 0x31,
+    0x38, 0x3a, 0x61, 0x36, 0x3a, 0x34, 0x34, 0x3a, 0x37, 0x31, 0x3a, 0x39,
+    0x30, 0x3a, 0x33, 0x37, 0x3a, 0x32, 0x61, 0x3a, 0x38, 0x36, 0x3a, 0x61,
+    0x66, 0x3a, 0x61, 0x66, 0x3a, 0x38, 0x62, 0x3a, 0x39, 0x35, 0x3a, 0x31,
+    0x66, 0x3a, 0x66, 0x62, 0x3a, 0x34, 0x33, 0x3a, 0x31, 0x64, 0x3a, 0x38,
+    0x33, 0x3a, 0x37, 0x66, 0x3a, 0x31, 0x65, 0x3a, 0x35, 0x36, 0x3a, 0x38,
+    0x38, 0x3a, 0x62, 0x34, 0x3a, 0x35, 0x39, 0x3a, 0x37, 0x31, 0x3a, 0x65,
+    0x64, 0x3a, 0x31, 0x35, 0x3a, 0x35, 0x37, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x4d, 0x49, 0x49, 0x43, 0x69, 0x44, 0x43, 0x43, 0x41, 0x67, 0x32, 0x67,
+    0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x4e, 0x66, 0x77, 0x6d,
+    0x58, 0x4e, 0x6d, 0x45, 0x54, 0x38, 0x6b, 0x39, 0x4a, 0x6a, 0x31, 0x58,
+    0x6d, 0x36, 0x37, 0x58, 0x56, 0x6a, 0x41, 0x4b, 0x42, 0x67, 0x67, 0x71,
+    0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7a, 0x43, 0x42,
+    0x68, 0x44, 0x45, 0x4c, 0x0a, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x54, 0x41,
+    0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x48, 0x52,
+    0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x77, 0x67, 0x53, 0x57, 0x35,
+    0x6a, 0x4c, 0x6a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x78, 0x4d, 0x76, 0x4b, 0x47, 0x4d, 0x70, 0x0a, 0x49, 0x44,
+    0x49, 0x77, 0x4d, 0x44, 0x63, 0x67, 0x64, 0x47, 0x68, 0x68, 0x64, 0x33,
+    0x52, 0x6c, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43,
+    0x30, 0x67, 0x52, 0x6d, 0x39, 0x79, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47,
+    0x68, 0x76, 0x63, 0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67, 0x64, 0x58,
+    0x4e, 0x6c, 0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6b, 0x78, 0x4a, 0x44,
+    0x41, 0x69, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x47,
+    0x33, 0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53, 0x42, 0x51, 0x63,
+    0x6d, 0x6c, 0x74, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x46, 0x4a, 0x76, 0x62,
+    0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4c, 0x53, 0x42, 0x48, 0x4d,
+    0x6a, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4e, 0x7a, 0x45, 0x78, 0x4d,
+    0x44, 0x55, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x0a, 0x4d, 0x44, 0x42, 0x61,
+    0x46, 0x77, 0x30, 0x7a, 0x4f, 0x44, 0x41, 0x78, 0x4d, 0x54, 0x67, 0x79,
+    0x4d, 0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c, 0x61, 0x4d, 0x49, 0x47, 0x45,
+    0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
+    0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x56, 0x4d, 0x42, 0x4d, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4d, 0x64, 0x47, 0x68, 0x68,
+    0x0a, 0x64, 0x33, 0x52, 0x6c, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d,
+    0x75, 0x4d, 0x54, 0x67, 0x77, 0x4e, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4c, 0x45, 0x79, 0x38, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x6a, 0x41,
+    0x77, 0x4e, 0x79, 0x42, 0x30, 0x61, 0x47, 0x46, 0x33, 0x64, 0x47, 0x55,
+    0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x67, 0x4c, 0x53, 0x42,
+    0x47, 0x62, 0x33, 0x49, 0x67, 0x0a, 0x59, 0x58, 0x56, 0x30, 0x61, 0x47,
+    0x39, 0x79, 0x61, 0x58, 0x70, 0x6c, 0x5a, 0x43, 0x42, 0x31, 0x63, 0x32,
+    0x55, 0x67, 0x62, 0x32, 0x35, 0x73, 0x65, 0x54, 0x45, 0x6b, 0x4d, 0x43,
+    0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x62, 0x64, 0x47,
+    0x68, 0x68, 0x64, 0x33, 0x52, 0x6c, 0x49, 0x46, 0x42, 0x79, 0x61, 0x57,
+    0x31, 0x68, 0x63, 0x6e, 0x6b, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x0a, 0x64,
+    0x43, 0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x79, 0x4d,
+    0x48, 0x59, 0x77, 0x45, 0x41, 0x59, 0x48, 0x4b, 0x6f, 0x5a, 0x49, 0x7a,
+    0x6a, 0x30, 0x43, 0x41, 0x51, 0x59, 0x46, 0x4b, 0x34, 0x45, 0x45, 0x41,
+    0x43, 0x49, 0x44, 0x59, 0x67, 0x41, 0x45, 0x6f, 0x74, 0x57, 0x63, 0x67,
+    0x6e, 0x75, 0x56, 0x6e, 0x66, 0x46, 0x53, 0x65, 0x49, 0x66, 0x2b, 0x69,
+    0x68, 0x61, 0x2f, 0x0a, 0x42, 0x65, 0x62, 0x66, 0x6f, 0x77, 0x4a, 0x50,
+    0x44, 0x51, 0x66, 0x47, 0x41, 0x46, 0x47, 0x36, 0x44, 0x41, 0x4a, 0x53,
+    0x4c, 0x53, 0x4b, 0x6b, 0x51, 0x6a, 0x6e, 0x45, 0x2f, 0x6f, 0x2f, 0x71,
+    0x79, 0x63, 0x47, 0x2b, 0x31, 0x45, 0x33, 0x2f, 0x6e, 0x33, 0x71, 0x65,
+    0x34, 0x72, 0x46, 0x38, 0x6d, 0x71, 0x32, 0x6e, 0x68, 0x67, 0x6c, 0x7a,
+    0x68, 0x39, 0x48, 0x6e, 0x6d, 0x75, 0x4e, 0x36, 0x0a, 0x70, 0x61, 0x70,
+    0x75, 0x2b, 0x37, 0x71, 0x7a, 0x63, 0x4d, 0x42, 0x6e, 0x69, 0x4b, 0x49,
+    0x31, 0x31, 0x4b, 0x4f, 0x61, 0x73, 0x66, 0x32, 0x74, 0x77, 0x75, 0x38,
+    0x78, 0x2b, 0x71, 0x69, 0x35, 0x38, 0x2f, 0x73, 0x49, 0x78, 0x70, 0x48,
+    0x52, 0x2b, 0x79, 0x6d, 0x56, 0x6f, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41,
+    0x50, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38,
+    0x45, 0x0a, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x41,
+    0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2f, 0x77,
+    0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, 0x64, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x6d, 0x74,
+    0x67, 0x41, 0x4d, 0x41, 0x44, 0x6e, 0x61, 0x33, 0x2b, 0x46, 0x47, 0x4f,
+    0x36, 0x4c, 0x74, 0x73, 0x36, 0x4b, 0x0a, 0x44, 0x50, 0x67, 0x52, 0x34,
+    0x62, 0x73, 0x77, 0x43, 0x67, 0x59, 0x49, 0x4b, 0x6f, 0x5a, 0x49, 0x7a,
+    0x6a, 0x30, 0x45, 0x41, 0x77, 0x4d, 0x44, 0x61, 0x51, 0x41, 0x77, 0x5a,
+    0x67, 0x49, 0x78, 0x41, 0x4e, 0x33, 0x34, 0x34, 0x46, 0x64, 0x48, 0x57,
+    0x36, 0x66, 0x6d, 0x43, 0x73, 0x4f, 0x39, 0x39, 0x59, 0x43, 0x4b, 0x6c,
+    0x7a, 0x55, 0x4e, 0x47, 0x34, 0x6b, 0x38, 0x56, 0x49, 0x5a, 0x33, 0x0a,
+    0x4b, 0x4d, 0x71, 0x68, 0x39, 0x48, 0x6e, 0x65, 0x74, 0x65, 0x59, 0x34,
+    0x73, 0x50, 0x42, 0x6c, 0x63, 0x49, 0x78, 0x2f, 0x41, 0x6c, 0x54, 0x43,
+    0x76, 0x2f, 0x2f, 0x59, 0x6f, 0x54, 0x37, 0x5a, 0x7a, 0x77, 0x49, 0x78,
+    0x41, 0x4d, 0x53, 0x4e, 0x6c, 0x50, 0x7a, 0x63, 0x55, 0x39, 0x4c, 0x63,
+    0x6e, 0x58, 0x67, 0x57, 0x48, 0x78, 0x55, 0x7a, 0x49, 0x31, 0x4e, 0x53,
+    0x34, 0x31, 0x6f, 0x78, 0x0a, 0x58, 0x5a, 0x33, 0x4b, 0x72, 0x72, 0x30,
+    0x54, 0x4b, 0x55, 0x51, 0x4e, 0x4a, 0x31, 0x75, 0x6f, 0x35, 0x32, 0x69,
+    0x63, 0x45, 0x76, 0x64, 0x59, 0x50, 0x79, 0x35, 0x79, 0x41, 0x6c, 0x65,
+    0x6a, 0x6a, 0x36, 0x45, 0x55, 0x4c, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69,
+    0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+    0x20, 0x2d, 0x20, 0x47, 0x33, 0x20, 0x4f, 0x3d, 0x74, 0x68, 0x61, 0x77,
+    0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44,
+    0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x28, 0x63, 0x29, 0x20,
+    0x32, 0x30, 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20,
+    0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75,
+    0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x74, 0x68,
+    0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47,
+    0x33, 0x20, 0x4f, 0x3d, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73,
+    0x69, 0x6f, 0x6e, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38,
+    0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f,
+    0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x69,
+    0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+    0x20, 0x2d, 0x20, 0x47, 0x33, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72,
+    0x69, 0x61, 0x6c, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x36, 0x31, 0x34, 0x31,
+    0x35, 0x37, 0x30, 0x35, 0x36, 0x36, 0x38, 0x31, 0x32, 0x39, 0x39, 0x38,
+    0x30, 0x35, 0x35, 0x35, 0x36, 0x34, 0x37, 0x36, 0x32, 0x37, 0x35, 0x39,
+    0x39, 0x35, 0x34, 0x31, 0x34, 0x37, 0x37, 0x39, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x66, 0x62, 0x3a, 0x31, 0x62, 0x3a, 0x35, 0x64,
+    0x3a, 0x34, 0x33, 0x3a, 0x38, 0x61, 0x3a, 0x39, 0x34, 0x3a, 0x63, 0x64,
+    0x3a, 0x34, 0x34, 0x3a, 0x63, 0x36, 0x3a, 0x37, 0x36, 0x3a, 0x66, 0x32,
+    0x3a, 0x34, 0x33, 0x3a, 0x34, 0x62, 0x3a, 0x34, 0x37, 0x3a, 0x65, 0x37,
+    0x3a, 0x33, 0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x66, 0x31, 0x3a, 0x38, 0x62, 0x3a, 0x35, 0x33, 0x3a, 0x38, 0x64, 0x3a,
+    0x31, 0x62, 0x3a, 0x65, 0x39, 0x3a, 0x30, 0x33, 0x3a, 0x62, 0x36, 0x3a,
+    0x61, 0x36, 0x3a, 0x66, 0x30, 0x3a, 0x35, 0x36, 0x3a, 0x34, 0x33, 0x3a,
+    0x35, 0x62, 0x3a, 0x31, 0x37, 0x3a, 0x31, 0x35, 0x3a, 0x38, 0x39, 0x3a,
+    0x63, 0x61, 0x3a, 0x66, 0x33, 0x3a, 0x36, 0x62, 0x3a, 0x66, 0x32, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x34, 0x62,
+    0x3a, 0x30, 0x33, 0x3a, 0x66, 0x34, 0x3a, 0x35, 0x38, 0x3a, 0x30, 0x37,
+    0x3a, 0x61, 0x64, 0x3a, 0x37, 0x30, 0x3a, 0x66, 0x32, 0x3a, 0x31, 0x62,
+    0x3a, 0x66, 0x63, 0x3a, 0x32, 0x63, 0x3a, 0x61, 0x65, 0x3a, 0x37, 0x31,
+    0x3a, 0x63, 0x39, 0x3a, 0x66, 0x64, 0x3a, 0x65, 0x34, 0x3a, 0x36, 0x30,
+    0x3a, 0x34, 0x63, 0x3a, 0x30, 0x36, 0x3a, 0x34, 0x63, 0x3a, 0x66, 0x35,
+    0x3a, 0x66, 0x66, 0x3a, 0x62, 0x36, 0x3a, 0x38, 0x36, 0x3a, 0x62, 0x61,
+    0x3a, 0x65, 0x35, 0x3a, 0x64, 0x62, 0x3a, 0x61, 0x61, 0x3a, 0x64, 0x37,
+    0x3a, 0x66, 0x64, 0x3a, 0x64, 0x33, 0x3a, 0x34, 0x63, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x4b, 0x6a, 0x43, 0x43, 0x41, 0x78,
+    0x4b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x59, 0x41,
+    0x47, 0x58, 0x74, 0x30, 0x61, 0x6e, 0x36, 0x72, 0x53, 0x30, 0x6d, 0x74,
+    0x5a, 0x4c, 0x4c, 0x2f, 0x65, 0x51, 0x2b, 0x7a, 0x41, 0x4e, 0x42, 0x67,
+    0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51,
+    0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a, 0x72, 0x6a, 0x45, 0x4c, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x44, 0x48, 0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a,
+    0x53, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45, 0x6f, 0x4d,
+    0x43, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x66, 0x0a,
+    0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68,
+    0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x54, 0x5a, 0x58, 0x4a, 0x32,
+    0x61, 0x57, 0x4e, 0x6c, 0x63, 0x79, 0x42, 0x45, 0x61, 0x58, 0x5a, 0x70,
+    0x63, 0x32, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x76, 0x4b, 0x47, 0x4d, 0x70,
+    0x49, 0x44, 0x49, 0x77, 0x0a, 0x4d, 0x44, 0x67, 0x67, 0x64, 0x47, 0x68,
+    0x68, 0x64, 0x33, 0x52, 0x6c, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d,
+    0x75, 0x49, 0x43, 0x30, 0x67, 0x52, 0x6d, 0x39, 0x79, 0x49, 0x47, 0x46,
+    0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51,
+    0x67, 0x64, 0x58, 0x4e, 0x6c, 0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6b,
+    0x78, 0x4a, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41,
+    0x4d, 0x54, 0x47, 0x33, 0x52, 0x6f, 0x59, 0x58, 0x64, 0x30, 0x5a, 0x53,
+    0x42, 0x51, 0x63, 0x6d, 0x6c, 0x74, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x46,
+    0x4a, 0x76, 0x62, 0x33, 0x51, 0x67, 0x51, 0x30, 0x45, 0x67, 0x4c, 0x53,
+    0x42, 0x48, 0x4d, 0x7a, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4f, 0x44,
+    0x41, 0x30, 0x4d, 0x44, 0x49, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44,
+    0x42, 0x61, 0x0a, 0x46, 0x77, 0x30, 0x7a, 0x4e, 0x7a, 0x45, 0x79, 0x4d,
+    0x44, 0x45, 0x79, 0x4d, 0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c, 0x61, 0x4d,
+    0x49, 0x47, 0x75, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x56, 0x4d,
+    0x42, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4d, 0x64,
+    0x47, 0x68, 0x68, 0x64, 0x33, 0x52, 0x6c, 0x0a, 0x4c, 0x43, 0x42, 0x4a,
+    0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x53, 0x67, 0x77, 0x4a, 0x67, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x39, 0x44, 0x5a, 0x58, 0x4a, 0x30,
+    0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75,
+    0x49, 0x46, 0x4e, 0x6c, 0x63, 0x6e, 0x5a, 0x70, 0x59, 0x32, 0x56, 0x7a,
+    0x49, 0x45, 0x52, 0x70, 0x64, 0x6d, 0x6c, 0x7a, 0x61, 0x57, 0x39, 0x75,
+    0x0a, 0x4d, 0x54, 0x67, 0x77, 0x4e, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4c, 0x45, 0x79, 0x38, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x6a, 0x41,
+    0x77, 0x4f, 0x43, 0x42, 0x30, 0x61, 0x47, 0x46, 0x33, 0x64, 0x47, 0x55,
+    0x73, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x67, 0x4c, 0x53, 0x42,
+    0x47, 0x62, 0x33, 0x49, 0x67, 0x59, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39,
+    0x79, 0x61, 0x58, 0x70, 0x6c, 0x0a, 0x5a, 0x43, 0x42, 0x31, 0x63, 0x32,
+    0x55, 0x67, 0x62, 0x32, 0x35, 0x73, 0x65, 0x54, 0x45, 0x6b, 0x4d, 0x43,
+    0x49, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x62, 0x64, 0x47,
+    0x68, 0x68, 0x64, 0x33, 0x52, 0x6c, 0x49, 0x46, 0x42, 0x79, 0x61, 0x57,
+    0x31, 0x68, 0x63, 0x6e, 0x6b, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x43,
+    0x42, 0x44, 0x51, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x7a, 0x0a, 0x4d,
+    0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41,
+    0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43,
+    0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x73, 0x72, 0x38, 0x6e, 0x4c,
+    0x50, 0x76, 0x62, 0x32, 0x46, 0x76, 0x64, 0x65, 0x48, 0x73, 0x62, 0x6e,
+    0x6e, 0x64, 0x6d, 0x0a, 0x67, 0x63, 0x73, 0x2b, 0x76, 0x48, 0x79, 0x75,
+    0x38, 0x36, 0x59, 0x6e, 0x6d, 0x6a, 0x53, 0x6a, 0x61, 0x44, 0x46, 0x78,
+    0x4f, 0x44, 0x4e, 0x69, 0x35, 0x50, 0x4e, 0x78, 0x5a, 0x6e, 0x6d, 0x78,
+    0x71, 0x57, 0x57, 0x6a, 0x70, 0x59, 0x76, 0x56, 0x6a, 0x32, 0x41, 0x74,
+    0x50, 0x30, 0x4c, 0x4d, 0x71, 0x6d, 0x73, 0x79, 0x77, 0x43, 0x50, 0x4c,
+    0x4c, 0x45, 0x48, 0x64, 0x35, 0x4e, 0x2f, 0x38, 0x0a, 0x59, 0x5a, 0x7a,
+    0x69, 0x63, 0x37, 0x49, 0x69, 0x6c, 0x52, 0x46, 0x44, 0x47, 0x46, 0x2f,
+    0x45, 0x74, 0x68, 0x39, 0x58, 0x62, 0x41, 0x6f, 0x46, 0x57, 0x43, 0x4c,
+    0x49, 0x4e, 0x6b, 0x77, 0x36, 0x66, 0x4b, 0x58, 0x52, 0x7a, 0x34, 0x61,
+    0x76, 0x69, 0x4b, 0x64, 0x45, 0x41, 0x68, 0x4e, 0x30, 0x63, 0x58, 0x4d,
+    0x4b, 0x51, 0x6c, 0x6b, 0x43, 0x2b, 0x42, 0x73, 0x55, 0x61, 0x30, 0x4c,
+    0x66, 0x0a, 0x62, 0x31, 0x2b, 0x36, 0x61, 0x34, 0x4b, 0x69, 0x6e, 0x56,
+    0x76, 0x6e, 0x53, 0x72, 0x30, 0x65, 0x41, 0x58, 0x4c, 0x62, 0x53, 0x33,
+    0x54, 0x6f, 0x4f, 0x33, 0x39, 0x2f, 0x66, 0x52, 0x38, 0x45, 0x74, 0x43,
+    0x61, 0x62, 0x34, 0x4c, 0x52, 0x61, 0x72, 0x45, 0x63, 0x39, 0x56, 0x62,
+    0x6a, 0x58, 0x73, 0x43, 0x5a, 0x53, 0x4b, 0x41, 0x45, 0x78, 0x51, 0x47,
+    0x62, 0x59, 0x32, 0x53, 0x53, 0x39, 0x0a, 0x39, 0x69, 0x72, 0x59, 0x37,
+    0x43, 0x46, 0x4a, 0x58, 0x4a, 0x76, 0x32, 0x65, 0x75, 0x6c, 0x2f, 0x56,
+    0x54, 0x56, 0x2b, 0x6c, 0x6d, 0x75, 0x4e, 0x6b, 0x35, 0x4d, 0x6e, 0x79,
+    0x35, 0x4b, 0x37, 0x36, 0x71, 0x78, 0x41, 0x77, 0x4a, 0x2f, 0x43, 0x2b,
+    0x49, 0x44, 0x50, 0x58, 0x66, 0x52, 0x61, 0x33, 0x4d, 0x35, 0x30, 0x68,
+    0x71, 0x59, 0x2b, 0x62, 0x41, 0x74, 0x54, 0x79, 0x72, 0x32, 0x53, 0x0a,
+    0x7a, 0x68, 0x6b, 0x47, 0x63, 0x75, 0x59, 0x4d, 0x58, 0x44, 0x68, 0x70,
+    0x78, 0x77, 0x54, 0x57, 0x76, 0x47, 0x7a, 0x4f, 0x57, 0x2f, 0x62, 0x33,
+    0x61, 0x4a, 0x7a, 0x63, 0x4a, 0x52, 0x56, 0x49, 0x69, 0x4b, 0x48, 0x70,
+    0x71, 0x66, 0x69, 0x59, 0x6e, 0x4f, 0x44, 0x7a, 0x31, 0x54, 0x45, 0x6f,
+    0x59, 0x52, 0x46, 0x73, 0x5a, 0x35, 0x61, 0x4e, 0x4f, 0x5a, 0x6e, 0x4c,
+    0x77, 0x6b, 0x55, 0x6b, 0x0a, 0x4f, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41,
+    0x42, 0x6f, 0x30, 0x49, 0x77, 0x51, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4e,
+    0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41,
+    0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x44, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49,
+    0x42, 0x42, 0x6a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x48, 0x51,
+    0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x72, 0x57, 0x79, 0x71, 0x6c, 0x47,
+    0x43, 0x63, 0x37, 0x65, 0x54, 0x2f, 0x2b, 0x6a, 0x34, 0x4b, 0x64, 0x43,
+    0x74, 0x6a, 0x41, 0x2f, 0x65, 0x32, 0x57, 0x62, 0x38, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x4c, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x42,
+    0x70, 0x41, 0x0a, 0x32, 0x4a, 0x56, 0x6c, 0x72, 0x41, 0x6d, 0x53, 0x69,
+    0x63, 0x59, 0x35, 0x39, 0x42, 0x44, 0x6c, 0x71, 0x51, 0x35, 0x6d, 0x55,
+    0x31, 0x31, 0x34, 0x33, 0x76, 0x6f, 0x6b, 0x6b, 0x62, 0x76, 0x6e, 0x52,
+    0x46, 0x48, 0x66, 0x78, 0x68, 0x59, 0x30, 0x43, 0x75, 0x39, 0x71, 0x52,
+    0x46, 0x48, 0x71, 0x4b, 0x77, 0x65, 0x4b, 0x41, 0x33, 0x72, 0x44, 0x36,
+    0x7a, 0x38, 0x4b, 0x4c, 0x46, 0x49, 0x57, 0x0a, 0x6f, 0x43, 0x74, 0x44,
+    0x75, 0x53, 0x57, 0x51, 0x50, 0x33, 0x43, 0x70, 0x4d, 0x79, 0x56, 0x74,
+    0x52, 0x52, 0x6f, 0x6f, 0x4f, 0x79, 0x66, 0x50, 0x71, 0x73, 0x4d, 0x70,
+    0x51, 0x68, 0x76, 0x66, 0x4f, 0x30, 0x7a, 0x41, 0x4d, 0x7a, 0x52, 0x62,
+    0x51, 0x59, 0x69, 0x2f, 0x61, 0x79, 0x74, 0x6c, 0x72, 0x79, 0x6a, 0x76,
+    0x73, 0x76, 0x58, 0x44, 0x71, 0x6d, 0x62, 0x4f, 0x65, 0x31, 0x62, 0x75,
+    0x0a, 0x74, 0x38, 0x6a, 0x4c, 0x5a, 0x38, 0x48, 0x4a, 0x6e, 0x42, 0x6f,
+    0x59, 0x75, 0x4d, 0x54, 0x44, 0x53, 0x51, 0x50, 0x78, 0x59, 0x41, 0x35,
+    0x51, 0x7a, 0x55, 0x62, 0x46, 0x38, 0x33, 0x64, 0x35, 0x39, 0x37, 0x59,
+    0x56, 0x34, 0x44, 0x6a, 0x62, 0x78, 0x79, 0x38, 0x6f, 0x6f, 0x41, 0x77,
+    0x2f, 0x64, 0x79, 0x5a, 0x30, 0x32, 0x53, 0x55, 0x53, 0x32, 0x6a, 0x48,
+    0x61, 0x47, 0x68, 0x37, 0x63, 0x0a, 0x4b, 0x55, 0x47, 0x52, 0x49, 0x6a,
+    0x78, 0x70, 0x70, 0x37, 0x73, 0x43, 0x38, 0x72, 0x5a, 0x63, 0x4a, 0x77,
+    0x4f, 0x4a, 0x39, 0x41, 0x62, 0x71, 0x6d, 0x2b, 0x52, 0x79, 0x67, 0x75,
+    0x4f, 0x68, 0x43, 0x63, 0x48, 0x70, 0x41, 0x42, 0x6e, 0x54, 0x50, 0x74,
+    0x52, 0x77, 0x61, 0x37, 0x70, 0x78, 0x70, 0x71, 0x70, 0x59, 0x72, 0x76,
+    0x53, 0x37, 0x36, 0x57, 0x79, 0x32, 0x37, 0x34, 0x66, 0x4d, 0x0a, 0x6d,
+    0x37, 0x76, 0x2f, 0x4f, 0x65, 0x5a, 0x57, 0x59, 0x64, 0x4d, 0x4b, 0x70,
+    0x38, 0x52, 0x63, 0x54, 0x47, 0x42, 0x37, 0x42, 0x58, 0x63, 0x6d, 0x65,
+    0x72, 0x2f, 0x59, 0x42, 0x31, 0x49, 0x73, 0x59, 0x76, 0x64, 0x77, 0x59,
+    0x39, 0x6b, 0x35, 0x76, 0x47, 0x38, 0x63, 0x77, 0x6e, 0x6e, 0x63, 0x64,
+    0x69, 0x6d, 0x76, 0x7a, 0x73, 0x55, 0x73, 0x5a, 0x41, 0x52, 0x65, 0x69,
+    0x44, 0x5a, 0x75, 0x0a, 0x4d, 0x64, 0x52, 0x41, 0x47, 0x6d, 0x49, 0x30,
+    0x4e, 0x6a, 0x38, 0x31, 0x41, 0x61, 0x36, 0x73, 0x59, 0x36, 0x41, 0x3d,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72,
+    0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+    0x47, 0x32, 0x20, 0x4f, 0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x28, 0x63,
+    0x29, 0x20, 0x32, 0x30, 0x30, 0x37, 0x20, 0x47, 0x65, 0x6f, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46,
+    0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65,
+    0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72,
+    0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f,
+    0x3d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+    0x30, 0x37, 0x20, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73,
+    0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62,
+    0x65, 0x6c, 0x3a, 0x20, 0x22, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+    0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20,
+    0x47, 0x32, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c,
+    0x3a, 0x20, 0x38, 0x30, 0x36, 0x38, 0x32, 0x38, 0x36, 0x33, 0x32, 0x30,
+    0x33, 0x33, 0x38, 0x31, 0x30, 0x36, 0x35, 0x37, 0x38, 0x32, 0x31, 0x37,
+    0x37, 0x39, 0x30, 0x38, 0x37, 0x35, 0x31, 0x37, 0x39, 0x34, 0x36, 0x31,
+    0x39, 0x32, 0x34, 0x33, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x30, 0x31, 0x3a, 0x35, 0x65, 0x3a, 0x64, 0x38, 0x3a, 0x36, 0x62, 0x3a,
+    0x62, 0x64, 0x3a, 0x36, 0x66, 0x3a, 0x33, 0x64, 0x3a, 0x38, 0x65, 0x3a,
+    0x61, 0x31, 0x3a, 0x33, 0x31, 0x3a, 0x66, 0x38, 0x3a, 0x31, 0x32, 0x3a,
+    0x65, 0x30, 0x3a, 0x39, 0x38, 0x3a, 0x37, 0x33, 0x3a, 0x36, 0x61, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x64, 0x3a, 0x31,
+    0x37, 0x3a, 0x38, 0x34, 0x3a, 0x64, 0x35, 0x3a, 0x33, 0x37, 0x3a, 0x66,
+    0x33, 0x3a, 0x30, 0x33, 0x3a, 0x37, 0x64, 0x3a, 0x65, 0x63, 0x3a, 0x37,
+    0x30, 0x3a, 0x66, 0x65, 0x3a, 0x35, 0x37, 0x3a, 0x38, 0x62, 0x3a, 0x35,
+    0x31, 0x3a, 0x39, 0x61, 0x3a, 0x39, 0x39, 0x3a, 0x65, 0x36, 0x3a, 0x31,
+    0x30, 0x3a, 0x64, 0x37, 0x3a, 0x62, 0x30, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x35, 0x65, 0x3a, 0x64, 0x62, 0x3a,
+    0x37, 0x61, 0x3a, 0x63, 0x34, 0x3a, 0x33, 0x62, 0x3a, 0x38, 0x32, 0x3a,
+    0x61, 0x30, 0x3a, 0x36, 0x61, 0x3a, 0x38, 0x37, 0x3a, 0x36, 0x31, 0x3a,
+    0x65, 0x38, 0x3a, 0x64, 0x37, 0x3a, 0x62, 0x65, 0x3a, 0x34, 0x39, 0x3a,
+    0x37, 0x39, 0x3a, 0x65, 0x62, 0x3a, 0x66, 0x32, 0x3a, 0x36, 0x31, 0x3a,
+    0x31, 0x66, 0x3a, 0x37, 0x64, 0x3a, 0x64, 0x37, 0x3a, 0x39, 0x62, 0x3a,
+    0x66, 0x39, 0x3a, 0x31, 0x63, 0x3a, 0x31, 0x63, 0x3a, 0x36, 0x62, 0x3a,
+    0x35, 0x36, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x31, 0x3a, 0x39, 0x65, 0x3a,
+    0x64, 0x37, 0x3a, 0x36, 0x36, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42,
+    0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49,
+    0x49, 0x43, 0x72, 0x6a, 0x43, 0x43, 0x41, 0x6a, 0x57, 0x67, 0x41, 0x77,
+    0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x50, 0x4c, 0x4c, 0x30, 0x53, 0x41,
+    0x6f, 0x41, 0x34, 0x76, 0x37, 0x72, 0x4a, 0x44, 0x74, 0x65, 0x59, 0x44,
+    0x37, 0x44, 0x61, 0x7a, 0x41, 0x4b, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6b,
+    0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7a, 0x43, 0x42, 0x6d, 0x44,
+    0x45, 0x4c, 0x0a, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x6a, 0x41, 0x55, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x55, 0x64, 0x6c, 0x62,
+    0x31, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x6c, 0x75, 0x59,
+    0x79, 0x34, 0x78, 0x4f, 0x54, 0x41, 0x33, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x73, 0x54, 0x4d, 0x43, 0x68, 0x6a, 0x0a, 0x4b, 0x53, 0x41, 0x79,
+    0x4d, 0x44, 0x41, 0x33, 0x49, 0x45, 0x64, 0x6c, 0x62, 0x31, 0x52, 0x79,
+    0x64, 0x58, 0x4e, 0x30, 0x49, 0x45, 0x6c, 0x75, 0x59, 0x79, 0x34, 0x67,
+    0x4c, 0x53, 0x42, 0x47, 0x62, 0x33, 0x49, 0x67, 0x59, 0x58, 0x56, 0x30,
+    0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x70, 0x6c, 0x5a, 0x43, 0x42, 0x31,
+    0x63, 0x32, 0x55, 0x67, 0x62, 0x32, 0x35, 0x73, 0x65, 0x54, 0x45, 0x32,
+    0x0a, 0x4d, 0x44, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x74, 0x52, 0x32, 0x56, 0x76, 0x56, 0x48, 0x4a, 0x31, 0x63, 0x33, 0x51,
+    0x67, 0x55, 0x48, 0x4a, 0x70, 0x62, 0x57, 0x46, 0x79, 0x65, 0x53, 0x42,
+    0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46,
+    0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68,
+    0x76, 0x63, 0x6d, 0x6c, 0x30, 0x0a, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45,
+    0x63, 0x79, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x33, 0x4d, 0x54,
+    0x45, 0x77, 0x4e, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46,
+    0x6f, 0x58, 0x44, 0x54, 0x4d, 0x34, 0x4d, 0x44, 0x45, 0x78, 0x4f, 0x44,
+    0x49, 0x7a, 0x4e, 0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x67, 0x5a,
+    0x67, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42,
+    0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x59, 0x77, 0x46,
+    0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x77, 0x31, 0x48, 0x5a,
+    0x57, 0x39, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62,
+    0x6d, 0x4d, 0x75, 0x4d, 0x54, 0x6b, 0x77, 0x4e, 0x77, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x4c, 0x45, 0x7a, 0x41, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d,
+    0x6a, 0x41, 0x77, 0x0a, 0x4e, 0x79, 0x42, 0x48, 0x5a, 0x57, 0x39, 0x55,
+    0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75,
+    0x49, 0x43, 0x30, 0x67, 0x52, 0x6d, 0x39, 0x79, 0x49, 0x47, 0x46, 0x31,
+    0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67,
+    0x64, 0x58, 0x4e, 0x6c, 0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6b, 0x78,
+    0x4e, 0x6a, 0x41, 0x30, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x4d,
+    0x54, 0x4c, 0x55, 0x64, 0x6c, 0x62, 0x31, 0x52, 0x79, 0x64, 0x58, 0x4e,
+    0x30, 0x49, 0x46, 0x42, 0x79, 0x61, 0x57, 0x31, 0x68, 0x63, 0x6e, 0x6b,
+    0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e,
+    0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52,
+    0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x4c, 0x53, 0x42,
+    0x48, 0x0a, 0x4d, 0x6a, 0x42, 0x32, 0x4d, 0x42, 0x41, 0x47, 0x42, 0x79,
+    0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, 0x53,
+    0x75, 0x42, 0x42, 0x41, 0x41, 0x69, 0x41, 0x32, 0x49, 0x41, 0x42, 0x42,
+    0x57, 0x78, 0x36, 0x50, 0x30, 0x44, 0x46, 0x55, 0x50, 0x6c, 0x72, 0x4f,
+    0x75, 0x48, 0x4e, 0x78, 0x46, 0x69, 0x37, 0x39, 0x4b, 0x44, 0x4e, 0x6c,
+    0x4a, 0x39, 0x52, 0x56, 0x63, 0x4c, 0x0a, 0x53, 0x6f, 0x31, 0x37, 0x56,
+    0x44, 0x73, 0x36, 0x62, 0x6c, 0x38, 0x56, 0x41, 0x73, 0x42, 0x51, 0x70,
+    0x73, 0x38, 0x6c, 0x4c, 0x33, 0x33, 0x4b, 0x53, 0x4c, 0x6a, 0x48, 0x55,
+    0x47, 0x4d, 0x63, 0x4b, 0x69, 0x45, 0x49, 0x66, 0x4a, 0x6f, 0x32, 0x32,
+    0x41, 0x76, 0x2b, 0x30, 0x53, 0x62, 0x46, 0x57, 0x44, 0x45, 0x77, 0x4b,
+    0x43, 0x58, 0x7a, 0x58, 0x56, 0x32, 0x6a, 0x75, 0x4c, 0x61, 0x6c, 0x0a,
+    0x74, 0x4a, 0x4c, 0x74, 0x62, 0x43, 0x79, 0x66, 0x36, 0x39, 0x31, 0x44,
+    0x69, 0x61, 0x49, 0x38, 0x53, 0x30, 0x69, 0x52, 0x48, 0x56, 0x44, 0x73,
+    0x4a, 0x74, 0x2f, 0x57, 0x59, 0x43, 0x36, 0x39, 0x49, 0x61, 0x4e, 0x43,
+    0x4d, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54,
+    0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42,
+    0x2f, 0x7a, 0x41, 0x4f, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59,
+    0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59,
+    0x45, 0x46, 0x42, 0x56, 0x66, 0x4e, 0x56, 0x64, 0x52, 0x56, 0x66, 0x73,
+    0x6c, 0x73, 0x71, 0x30, 0x44, 0x61, 0x66, 0x77, 0x42, 0x6f, 0x2f, 0x71,
+    0x2b, 0x45, 0x56, 0x58, 0x56, 0x4d, 0x41, 0x6f, 0x47, 0x0a, 0x43, 0x43,
+    0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x42, 0x41, 0x4d, 0x44, 0x41, 0x32,
+    0x63, 0x41, 0x4d, 0x47, 0x51, 0x43, 0x4d, 0x47, 0x53, 0x57, 0x57, 0x61,
+    0x62, 0x6f, 0x43, 0x64, 0x36, 0x4c, 0x75, 0x76, 0x70, 0x61, 0x69, 0x49,
+    0x6a, 0x77, 0x48, 0x35, 0x48, 0x54, 0x52, 0x71, 0x6a, 0x79, 0x53, 0x6b,
+    0x77, 0x43, 0x59, 0x2f, 0x74, 0x73, 0x58, 0x7a, 0x6a, 0x62, 0x4c, 0x6b,
+    0x47, 0x54, 0x0a, 0x71, 0x51, 0x37, 0x6d, 0x6e, 0x64, 0x77, 0x78, 0x48,
+    0x4c, 0x4b, 0x67, 0x70, 0x78, 0x67, 0x63, 0x65, 0x65, 0x48, 0x48, 0x4e,
+    0x67, 0x49, 0x77, 0x4f, 0x6c, 0x61, 0x76, 0x6d, 0x6e, 0x52, 0x73, 0x39,
+    0x76, 0x75, 0x44, 0x34, 0x44, 0x50, 0x54, 0x43, 0x46, 0x2b, 0x68, 0x6e,
+    0x4d, 0x4a, 0x62, 0x6e, 0x30, 0x62, 0x57, 0x74, 0x73, 0x75, 0x52, 0x42,
+    0x6d, 0x4f, 0x69, 0x42, 0x75, 0x63, 0x7a, 0x0a, 0x72, 0x44, 0x36, 0x6f,
+    0x67, 0x52, 0x4c, 0x51, 0x79, 0x37, 0x72, 0x51, 0x6b, 0x67, 0x75, 0x32,
+    0x6e, 0x70, 0x61, 0x71, 0x42, 0x41, 0x2b, 0x4b, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x55, 0x6e,
+    0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+    0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63, 0x29, 0x20,
+    0x32, 0x30, 0x30, 0x38, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f,
+    0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
+    0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20,
+    0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x55, 0x6e, 0x69,
+    0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20,
+    0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e,
+    0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32,
+    0x30, 0x30, 0x38, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72,
+    0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20,
+    0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x4c,
+    0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x56, 0x65, 0x72, 0x69, 0x53,
+    0x69, 0x67, 0x6e, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61,
+    0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65,
+    0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x38, 0x35, 0x32, 0x30, 0x39, 0x35,
+    0x37, 0x34, 0x37, 0x33, 0x34, 0x30, 0x38, 0x34, 0x35, 0x38, 0x31, 0x39,
+    0x31, 0x37, 0x37, 0x36, 0x33, 0x37, 0x35, 0x32, 0x36, 0x34, 0x34, 0x30,
+    0x33, 0x31, 0x37, 0x32, 0x36, 0x38, 0x37, 0x37, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x38, 0x65, 0x3a, 0x61, 0x64, 0x3a, 0x62, 0x35,
+    0x3a, 0x30, 0x31, 0x3a, 0x61, 0x61, 0x3a, 0x34, 0x64, 0x3a, 0x38, 0x31,
+    0x3a, 0x65, 0x34, 0x3a, 0x38, 0x63, 0x3a, 0x31, 0x64, 0x3a, 0x64, 0x31,
+    0x3a, 0x65, 0x31, 0x3a, 0x31, 0x34, 0x3a, 0x30, 0x30, 0x3a, 0x39, 0x35,
+    0x3a, 0x31, 0x39, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x33, 0x36, 0x3a, 0x37, 0x39, 0x3a, 0x63, 0x61, 0x3a, 0x33, 0x35, 0x3a,
+    0x36, 0x36, 0x3a, 0x38, 0x37, 0x3a, 0x37, 0x32, 0x3a, 0x33, 0x30, 0x3a,
+    0x34, 0x64, 0x3a, 0x33, 0x30, 0x3a, 0x61, 0x35, 0x3a, 0x66, 0x62, 0x3a,
+    0x38, 0x37, 0x3a, 0x33, 0x62, 0x3a, 0x30, 0x66, 0x3a, 0x61, 0x37, 0x3a,
+    0x37, 0x62, 0x3a, 0x62, 0x37, 0x3a, 0x30, 0x64, 0x3a, 0x35, 0x34, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x32, 0x33,
+    0x3a, 0x39, 0x39, 0x3a, 0x35, 0x36, 0x3a, 0x31, 0x31, 0x3a, 0x32, 0x37,
+    0x3a, 0x61, 0x35, 0x3a, 0x37, 0x31, 0x3a, 0x32, 0x35, 0x3a, 0x64, 0x65,
+    0x3a, 0x38, 0x63, 0x3a, 0x65, 0x66, 0x3a, 0x65, 0x61, 0x3a, 0x36, 0x31,
+    0x3a, 0x30, 0x64, 0x3a, 0x64, 0x66, 0x3a, 0x32, 0x66, 0x3a, 0x61, 0x30,
+    0x3a, 0x37, 0x38, 0x3a, 0x62, 0x35, 0x3a, 0x63, 0x38, 0x3a, 0x30, 0x36,
+    0x3a, 0x37, 0x66, 0x3a, 0x34, 0x65, 0x3a, 0x38, 0x32, 0x3a, 0x38, 0x32,
+    0x3a, 0x39, 0x30, 0x3a, 0x62, 0x66, 0x3a, 0x62, 0x38, 0x3a, 0x36, 0x30,
+    0x3a, 0x65, 0x38, 0x3a, 0x34, 0x62, 0x3a, 0x33, 0x63, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x75, 0x54, 0x43, 0x43, 0x41, 0x36,
+    0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x51, 0x42,
+    0x72, 0x45, 0x5a, 0x43, 0x47, 0x7a, 0x45, 0x79, 0x45, 0x44, 0x44, 0x72,
+    0x76, 0x6b, 0x45, 0x68, 0x72, 0x46, 0x48, 0x54, 0x41, 0x4e, 0x42, 0x67,
+    0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51,
+    0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x0a, 0x76, 0x54, 0x45, 0x4c, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x44, 0x6c, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61,
+    0x57, 0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d,
+    0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x0a,
+    0x45, 0x78, 0x5a, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e,
+    0x62, 0x69, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4f,
+    0x5a, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x4d, 0x54, 0x6f, 0x77,
+    0x4f, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x7a, 0x45, 0x6f,
+    0x59, 0x79, 0x6b, 0x67, 0x4d, 0x6a, 0x41, 0x77, 0x4f, 0x43, 0x42, 0x57,
+    0x5a, 0x58, 0x4a, 0x70, 0x0a, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x69, 0x77,
+    0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x69, 0x41, 0x74, 0x49, 0x45, 0x5a,
+    0x76, 0x63, 0x69, 0x42, 0x68, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a,
+    0x70, 0x65, 0x6d, 0x56, 0x6b, 0x49, 0x48, 0x56, 0x7a, 0x5a, 0x53, 0x42,
+    0x76, 0x62, 0x6d, 0x78, 0x35, 0x4d, 0x54, 0x67, 0x77, 0x4e, 0x67, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x39, 0x57, 0x0a, 0x5a, 0x58,
+    0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x69, 0x42, 0x56, 0x62, 0x6d,
+    0x6c, 0x32, 0x5a, 0x58, 0x4a, 0x7a, 0x59, 0x57, 0x77, 0x67, 0x55, 0x6d,
+    0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57,
+    0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45,
+    0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x54,
+    0x41, 0x65, 0x0a, 0x46, 0x77, 0x30, 0x77, 0x4f, 0x44, 0x41, 0x30, 0x4d,
+    0x44, 0x49, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x42, 0x61, 0x46,
+    0x77, 0x30, 0x7a, 0x4e, 0x7a, 0x45, 0x79, 0x4d, 0x44, 0x45, 0x79, 0x4d,
+    0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c, 0x61, 0x4d, 0x49, 0x47, 0x39, 0x4d,
+    0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x58, 0x0a, 0x4d, 0x42, 0x55, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4f, 0x56, 0x6d, 0x56, 0x79,
+    0x61, 0x56, 0x4e, 0x70, 0x5a, 0x32, 0x34, 0x73, 0x49, 0x45, 0x6c, 0x75,
+    0x59, 0x79, 0x34, 0x78, 0x48, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x73, 0x54, 0x46, 0x6c, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54,
+    0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30,
+    0x0a, 0x49, 0x45, 0x35, 0x6c, 0x64, 0x48, 0x64, 0x76, 0x63, 0x6d, 0x73,
+    0x78, 0x4f, 0x6a, 0x41, 0x34, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73,
+    0x54, 0x4d, 0x53, 0x68, 0x6a, 0x4b, 0x53, 0x41, 0x79, 0x4d, 0x44, 0x41,
+    0x34, 0x49, 0x46, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64,
+    0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x49, 0x43, 0x30,
+    0x67, 0x52, 0x6d, 0x39, 0x79, 0x0a, 0x49, 0x47, 0x46, 0x31, 0x64, 0x47,
+    0x68, 0x76, 0x63, 0x6d, 0x6c, 0x36, 0x5a, 0x57, 0x51, 0x67, 0x64, 0x58,
+    0x4e, 0x6c, 0x49, 0x47, 0x39, 0x75, 0x62, 0x48, 0x6b, 0x78, 0x4f, 0x44,
+    0x41, 0x32, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x4c, 0x31,
+    0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46,
+    0x56, 0x75, 0x61, 0x58, 0x5a, 0x6c, 0x63, 0x6e, 0x4e, 0x68, 0x0a, 0x62,
+    0x43, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4e, 0x6c, 0x63,
+    0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62,
+    0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61,
+    0x58, 0x52, 0x35, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42,
+    0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x45, 0x46, 0x0a, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41,
+    0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41,
+    0x78, 0x32, 0x45, 0x33, 0x58, 0x72, 0x45, 0x42, 0x4e, 0x4e, 0x74, 0x69,
+    0x31, 0x78, 0x57, 0x62, 0x2f, 0x31, 0x68, 0x61, 0x6a, 0x43, 0x4d, 0x6a,
+    0x31, 0x6d, 0x43, 0x4f, 0x6b, 0x64, 0x65, 0x51, 0x6d, 0x49, 0x4e, 0x36,
+    0x35, 0x6c, 0x67, 0x5a, 0x4f, 0x49, 0x7a, 0x46, 0x0a, 0x39, 0x75, 0x56,
+    0x6b, 0x68, 0x62, 0x53, 0x69, 0x63, 0x66, 0x76, 0x74, 0x76, 0x62, 0x6e,
+    0x61, 0x7a, 0x55, 0x30, 0x41, 0x74, 0x4d, 0x67, 0x74, 0x63, 0x36, 0x58,
+    0x48, 0x61, 0x58, 0x47, 0x56, 0x48, 0x7a, 0x6b, 0x38, 0x73, 0x6b, 0x51,
+    0x48, 0x6e, 0x4f, 0x67, 0x4f, 0x2b, 0x6b, 0x31, 0x4b, 0x78, 0x43, 0x48,
+    0x66, 0x4b, 0x57, 0x47, 0x50, 0x4d, 0x69, 0x4a, 0x68, 0x67, 0x73, 0x57,
+    0x48, 0x0a, 0x48, 0x32, 0x36, 0x4d, 0x66, 0x46, 0x38, 0x57, 0x49, 0x46,
+    0x46, 0x45, 0x30, 0x58, 0x42, 0x50, 0x56, 0x2b, 0x72, 0x6a, 0x48, 0x4f,
+    0x50, 0x4d, 0x65, 0x65, 0x35, 0x59, 0x32, 0x41, 0x37, 0x43, 0x73, 0x30,
+    0x57, 0x54, 0x77, 0x43, 0x7a, 0x6e, 0x6d, 0x68, 0x63, 0x72, 0x65, 0x77,
+    0x41, 0x33, 0x65, 0x6b, 0x45, 0x7a, 0x65, 0x4f, 0x45, 0x7a, 0x34, 0x76,
+    0x4d, 0x51, 0x47, 0x6e, 0x2b, 0x48, 0x0a, 0x4c, 0x4c, 0x37, 0x32, 0x39,
+    0x66, 0x64, 0x43, 0x34, 0x75, 0x57, 0x2f, 0x68, 0x32, 0x4b, 0x4a, 0x58,
+    0x77, 0x42, 0x4c, 0x33, 0x38, 0x58, 0x64, 0x35, 0x48, 0x56, 0x45, 0x4d,
+    0x6b, 0x45, 0x36, 0x48, 0x6e, 0x46, 0x75, 0x61, 0x63, 0x73, 0x4c, 0x64,
+    0x55, 0x59, 0x49, 0x30, 0x63, 0x72, 0x53, 0x4b, 0x35, 0x58, 0x51, 0x7a,
+    0x2f, 0x75, 0x35, 0x51, 0x47, 0x74, 0x6b, 0x6a, 0x46, 0x64, 0x4e, 0x0a,
+    0x2f, 0x42, 0x4d, 0x52, 0x65, 0x59, 0x54, 0x74, 0x58, 0x6c, 0x54, 0x32,
+    0x4e, 0x4a, 0x38, 0x49, 0x41, 0x66, 0x4d, 0x51, 0x4a, 0x51, 0x59, 0x58,
+    0x53, 0x74, 0x72, 0x78, 0x48, 0x58, 0x70, 0x6d, 0x61, 0x35, 0x68, 0x67,
+    0x5a, 0x71, 0x54, 0x5a, 0x37, 0x39, 0x49, 0x75, 0x67, 0x76, 0x48, 0x77,
+    0x37, 0x77, 0x6e, 0x71, 0x52, 0x4d, 0x6b, 0x56, 0x61, 0x75, 0x49, 0x44,
+    0x62, 0x6a, 0x50, 0x54, 0x0a, 0x72, 0x4a, 0x39, 0x56, 0x41, 0x4d, 0x66,
+    0x32, 0x43, 0x47, 0x71, 0x55, 0x75, 0x56, 0x2f, 0x63, 0x34, 0x44, 0x50,
+    0x78, 0x68, 0x47, 0x44, 0x35, 0x57, 0x79, 0x63, 0x52, 0x74, 0x50, 0x77,
+    0x57, 0x38, 0x72, 0x74, 0x57, 0x61, 0x6f, 0x41, 0x6c, 0x6a, 0x51, 0x49,
+    0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x34, 0x47, 0x79, 0x4d, 0x49, 0x47,
+    0x76, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0a, 0x45, 0x77,
+    0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66,
+    0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51,
+    0x48, 0x2f, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x47,
+    0x30, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77,
+    0x45, 0x4d, 0x42, 0x47, 0x45, 0x77, 0x58, 0x36, 0x46, 0x64, 0x6f, 0x46,
+    0x73, 0x77, 0x0a, 0x57, 0x54, 0x42, 0x58, 0x4d, 0x46, 0x55, 0x57, 0x43,
+    0x57, 0x6c, 0x74, 0x59, 0x57, 0x64, 0x6c, 0x4c, 0x32, 0x64, 0x70, 0x5a,
+    0x6a, 0x41, 0x68, 0x4d, 0x42, 0x38, 0x77, 0x42, 0x77, 0x59, 0x46, 0x4b,
+    0x77, 0x34, 0x44, 0x41, 0x68, 0x6f, 0x45, 0x46, 0x49, 0x2f, 0x6c, 0x30,
+    0x78, 0x71, 0x47, 0x72, 0x49, 0x32, 0x4f, 0x61, 0x38, 0x50, 0x50, 0x67,
+    0x47, 0x72, 0x55, 0x53, 0x42, 0x67, 0x73, 0x0a, 0x65, 0x78, 0x6b, 0x75,
+    0x4d, 0x43, 0x55, 0x57, 0x49, 0x32, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36,
+    0x4c, 0x79, 0x39, 0x73, 0x62, 0x32, 0x64, 0x76, 0x4c, 0x6e, 0x5a, 0x6c,
+    0x63, 0x6d, 0x6c, 0x7a, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x6d, 0x4e, 0x76,
+    0x62, 0x53, 0x39, 0x32, 0x63, 0x32, 0x78, 0x76, 0x5a, 0x32, 0x38, 0x75,
+    0x5a, 0x32, 0x6c, 0x6d, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64,
+    0x0a, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x32, 0x64, 0x2f, 0x70,
+    0x70, 0x53, 0x45, 0x65, 0x66, 0x55, 0x78, 0x4c, 0x56, 0x77, 0x75, 0x6f,
+    0x48, 0x4d, 0x6e, 0x59, 0x48, 0x30, 0x5a, 0x63, 0x48, 0x47, 0x54, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45,
+    0x41, 0x53, 0x76, 0x6a, 0x34, 0x0a, 0x73, 0x41, 0x50, 0x6d, 0x4c, 0x47,
+    0x64, 0x37, 0x35, 0x4a, 0x52, 0x33, 0x59, 0x38, 0x78, 0x75, 0x54, 0x50,
+    0x6c, 0x39, 0x44, 0x67, 0x33, 0x63, 0x79, 0x4c, 0x6b, 0x31, 0x75, 0x58,
+    0x42, 0x50, 0x59, 0x2f, 0x6f, 0x6b, 0x2b, 0x6d, 0x79, 0x44, 0x6a, 0x45,
+    0x65, 0x64, 0x4f, 0x32, 0x50, 0x7a, 0x6d, 0x76, 0x6c, 0x32, 0x4d, 0x70,
+    0x57, 0x52, 0x73, 0x58, 0x65, 0x38, 0x72, 0x4a, 0x71, 0x2b, 0x0a, 0x73,
+    0x65, 0x51, 0x78, 0x49, 0x63, 0x61, 0x42, 0x6c, 0x56, 0x5a, 0x61, 0x44,
+    0x72, 0x48, 0x43, 0x31, 0x4c, 0x47, 0x6d, 0x57, 0x61, 0x7a, 0x78, 0x59,
+    0x38, 0x75, 0x34, 0x54, 0x42, 0x31, 0x5a, 0x6b, 0x45, 0x72, 0x76, 0x6b,
+    0x42, 0x59, 0x6f, 0x48, 0x31, 0x71, 0x75, 0x45, 0x50, 0x75, 0x42, 0x55,
+    0x44, 0x67, 0x4d, 0x62, 0x4d, 0x7a, 0x78, 0x50, 0x63, 0x50, 0x31, 0x59,
+    0x2b, 0x4f, 0x7a, 0x0a, 0x34, 0x79, 0x48, 0x4a, 0x4a, 0x44, 0x6e, 0x70,
+    0x2f, 0x52, 0x56, 0x6d, 0x52, 0x76, 0x51, 0x62, 0x45, 0x64, 0x42, 0x4e,
+    0x63, 0x36, 0x4e, 0x39, 0x52, 0x76, 0x6b, 0x39, 0x37, 0x61, 0x68, 0x66,
+    0x59, 0x74, 0x54, 0x78, 0x50, 0x2f, 0x6a, 0x67, 0x64, 0x46, 0x63, 0x72,
+    0x47, 0x4a, 0x32, 0x42, 0x74, 0x4d, 0x51, 0x6f, 0x32, 0x70, 0x53, 0x58,
+    0x70, 0x58, 0x44, 0x72, 0x72, 0x42, 0x32, 0x2b, 0x0a, 0x42, 0x78, 0x48,
+    0x77, 0x31, 0x64, 0x76, 0x64, 0x35, 0x59, 0x7a, 0x77, 0x31, 0x54, 0x4b,
+    0x77, 0x67, 0x2b, 0x5a, 0x58, 0x34, 0x6f, 0x2b, 0x2f, 0x76, 0x71, 0x47,
+    0x71, 0x76, 0x7a, 0x30, 0x64, 0x74, 0x64, 0x51, 0x34, 0x36, 0x74, 0x65,
+    0x77, 0x58, 0x44, 0x70, 0x50, 0x61, 0x6a, 0x2b, 0x50, 0x77, 0x47, 0x5a,
+    0x73, 0x59, 0x36, 0x72, 0x70, 0x32, 0x61, 0x51, 0x57, 0x39, 0x49, 0x48,
+    0x52, 0x0a, 0x6c, 0x52, 0x51, 0x4f, 0x66, 0x63, 0x32, 0x56, 0x4e, 0x4e,
+    0x6e, 0x53, 0x6a, 0x33, 0x42, 0x7a, 0x67, 0x58, 0x75, 0x63, 0x66, 0x72,
+    0x32, 0x59, 0x59, 0x64, 0x68, 0x46, 0x68, 0x35, 0x69, 0x51, 0x78, 0x65,
+    0x75, 0x47, 0x4d, 0x4d, 0x59, 0x31, 0x76, 0x2f, 0x44, 0x2f, 0x77, 0x31,
+    0x57, 0x49, 0x67, 0x30, 0x76, 0x76, 0x42, 0x5a, 0x49, 0x47, 0x63, 0x66,
+    0x4b, 0x34, 0x6d, 0x4a, 0x4f, 0x33, 0x0a, 0x37, 0x4d, 0x32, 0x43, 0x59,
+    0x66, 0x45, 0x34, 0x35, 0x6b, 0x2b, 0x58, 0x6d, 0x43, 0x70, 0x61, 0x6a,
+    0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73,
+    0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+    0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x20, 0x4f, 0x3d, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x37,
+    0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+    0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a,
+    0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x56, 0x65, 0x72, 0x69,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
+    0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+    0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x34, 0x20, 0x4f, 0x3d, 0x56,
+    0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+    0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
+    0x6f, 0x72, 0x6b, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x37,
+    0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75,
+    0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65,
+    0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
+    0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20,
+    0x2d, 0x20, 0x47, 0x34, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69,
+    0x61, 0x6c, 0x3a, 0x20, 0x36, 0x33, 0x31, 0x34, 0x33, 0x34, 0x38, 0x34,
+    0x33, 0x34, 0x38, 0x31, 0x35, 0x33, 0x35, 0x30, 0x36, 0x36, 0x36, 0x35,
+    0x33, 0x31, 0x31, 0x39, 0x38, 0x35, 0x35, 0x30, 0x31, 0x34, 0x35, 0x38,
+    0x36, 0x34, 0x30, 0x30, 0x35, 0x31, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x33, 0x61, 0x3a, 0x35, 0x32, 0x3a, 0x65, 0x31, 0x3a, 0x65,
+    0x37, 0x3a, 0x66, 0x64, 0x3a, 0x36, 0x66, 0x3a, 0x33, 0x61, 0x3a, 0x65,
+    0x33, 0x3a, 0x36, 0x66, 0x3a, 0x66, 0x33, 0x3a, 0x36, 0x66, 0x3a, 0x39,
+    0x39, 0x3a, 0x31, 0x62, 0x3a, 0x66, 0x39, 0x3a, 0x32, 0x32, 0x3a, 0x34,
+    0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x32, 0x32,
+    0x3a, 0x64, 0x35, 0x3a, 0x64, 0x38, 0x3a, 0x64, 0x66, 0x3a, 0x38, 0x66,
+    0x3a, 0x30, 0x32, 0x3a, 0x33, 0x31, 0x3a, 0x64, 0x31, 0x3a, 0x38, 0x64,
+    0x3a, 0x66, 0x37, 0x3a, 0x39, 0x64, 0x3a, 0x62, 0x37, 0x3a, 0x63, 0x66,
+    0x3a, 0x38, 0x61, 0x3a, 0x32, 0x64, 0x3a, 0x36, 0x34, 0x3a, 0x63, 0x39,
+    0x3a, 0x33, 0x66, 0x3a, 0x36, 0x63, 0x3a, 0x33, 0x61, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x36, 0x39, 0x3a, 0x64,
+    0x64, 0x3a, 0x64, 0x37, 0x3a, 0x65, 0x61, 0x3a, 0x39, 0x30, 0x3a, 0x62,
+    0x62, 0x3a, 0x35, 0x37, 0x3a, 0x63, 0x39, 0x3a, 0x33, 0x65, 0x3a, 0x31,
+    0x33, 0x3a, 0x35, 0x64, 0x3a, 0x63, 0x38, 0x3a, 0x35, 0x65, 0x3a, 0x61,
+    0x36, 0x3a, 0x66, 0x63, 0x3a, 0x64, 0x35, 0x3a, 0x34, 0x38, 0x3a, 0x30,
+    0x62, 0x3a, 0x36, 0x30, 0x3a, 0x33, 0x32, 0x3a, 0x33, 0x39, 0x3a, 0x62,
+    0x64, 0x3a, 0x63, 0x34, 0x3a, 0x35, 0x34, 0x3a, 0x66, 0x63, 0x3a, 0x37,
+    0x35, 0x3a, 0x38, 0x62, 0x3a, 0x32, 0x61, 0x3a, 0x32, 0x36, 0x3a, 0x63,
+    0x66, 0x3a, 0x37, 0x66, 0x3a, 0x37, 0x39, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
+    0x4d, 0x49, 0x49, 0x44, 0x68, 0x44, 0x43, 0x43, 0x41, 0x77, 0x71, 0x67,
+    0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x51, 0x4c, 0x34, 0x44, 0x2b,
+    0x49, 0x34, 0x77, 0x4f, 0x49, 0x67, 0x39, 0x49, 0x5a, 0x78, 0x49, 0x6f,
+    0x6b, 0x59, 0x65, 0x73, 0x73, 0x7a, 0x41, 0x4b, 0x42, 0x67, 0x67, 0x71,
+    0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44, 0x41, 0x7a, 0x43, 0x42,
+    0x79, 0x6a, 0x45, 0x4c, 0x0a, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x7a, 0x41,
+    0x56, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x6c, 0x5a,
+    0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x43, 0x42,
+    0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x78, 0x5a, 0x57, 0x0a, 0x5a, 0x58,
+    0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x69, 0x42, 0x55, 0x63, 0x6e,
+    0x56, 0x7a, 0x64, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33,
+    0x4a, 0x72, 0x4d, 0x54, 0x6f, 0x77, 0x4f, 0x41, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x4c, 0x45, 0x7a, 0x45, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x6a,
+    0x41, 0x77, 0x4e, 0x79, 0x42, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32,
+    0x6c, 0x6e, 0x0a, 0x62, 0x69, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c,
+    0x69, 0x41, 0x74, 0x49, 0x45, 0x5a, 0x76, 0x63, 0x69, 0x42, 0x68, 0x64,
+    0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x65, 0x6d, 0x56, 0x6b, 0x49,
+    0x48, 0x56, 0x7a, 0x5a, 0x53, 0x42, 0x76, 0x62, 0x6d, 0x78, 0x35, 0x4d,
+    0x55, 0x55, 0x77, 0x51, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45,
+    0x7a, 0x78, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x0a, 0x55, 0x32, 0x6c, 0x6e,
+    0x62, 0x69, 0x42, 0x44, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x79, 0x41, 0x7a,
+    0x49, 0x46, 0x42, 0x31, 0x59, 0x6d, 0x78, 0x70, 0x59, 0x79, 0x42, 0x51,
+    0x63, 0x6d, 0x6c, 0x74, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x45, 0x4e, 0x6c,
+    0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70,
+    0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79,
+    0x0a, 0x61, 0x58, 0x52, 0x35, 0x49, 0x43, 0x30, 0x67, 0x52, 0x7a, 0x51,
+    0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x63, 0x78, 0x4d, 0x54, 0x41,
+    0x31, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63,
+    0x4e, 0x4d, 0x7a, 0x67, 0x77, 0x4d, 0x54, 0x45, 0x34, 0x4d, 0x6a, 0x4d,
+    0x31, 0x4f, 0x54, 0x55, 0x35, 0x57, 0x6a, 0x43, 0x42, 0x79, 0x6a, 0x45,
+    0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68,
+    0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x6c, 0x5a, 0x6c, 0x63, 0x6d,
+    0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d,
+    0x4d, 0x75, 0x4d, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x4c, 0x45, 0x78, 0x5a, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x0a, 0x55,
+    0x32, 0x6c, 0x6e, 0x62, 0x69, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64,
+    0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x4d,
+    0x54, 0x6f, 0x77, 0x4f, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45,
+    0x7a, 0x45, 0x6f, 0x59, 0x79, 0x6b, 0x67, 0x4d, 0x6a, 0x41, 0x77, 0x4e,
+    0x79, 0x42, 0x57, 0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x62,
+    0x69, 0x77, 0x67, 0x0a, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x69, 0x41, 0x74,
+    0x49, 0x45, 0x5a, 0x76, 0x63, 0x69, 0x42, 0x68, 0x64, 0x58, 0x52, 0x6f,
+    0x62, 0x33, 0x4a, 0x70, 0x65, 0x6d, 0x56, 0x6b, 0x49, 0x48, 0x56, 0x7a,
+    0x5a, 0x53, 0x42, 0x76, 0x62, 0x6d, 0x78, 0x35, 0x4d, 0x55, 0x55, 0x77,
+    0x51, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x7a, 0x78, 0x57,
+    0x5a, 0x58, 0x4a, 0x70, 0x55, 0x32, 0x6c, 0x6e, 0x0a, 0x62, 0x69, 0x42,
+    0x44, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x79, 0x41, 0x7a, 0x49, 0x46, 0x42,
+    0x31, 0x59, 0x6d, 0x78, 0x70, 0x59, 0x79, 0x42, 0x51, 0x63, 0x6d, 0x6c,
+    0x74, 0x59, 0x58, 0x4a, 0x35, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52,
+    0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34,
+    0x67, 0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52,
+    0x35, 0x0a, 0x49, 0x43, 0x30, 0x67, 0x52, 0x7a, 0x51, 0x77, 0x64, 0x6a,
+    0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51,
+    0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67,
+    0x4e, 0x69, 0x41, 0x41, 0x53, 0x6e, 0x56, 0x6e, 0x70, 0x38, 0x55, 0x74,
+    0x70, 0x6b, 0x6d, 0x77, 0x34, 0x74, 0x58, 0x4e, 0x68, 0x65, 0x72, 0x4a,
+    0x49, 0x39, 0x2f, 0x67, 0x48, 0x6d, 0x0a, 0x47, 0x55, 0x6f, 0x39, 0x46,
+    0x41, 0x4e, 0x4c, 0x2b, 0x6d, 0x41, 0x6e, 0x49, 0x4e, 0x6d, 0x44, 0x69,
+    0x57, 0x6e, 0x36, 0x56, 0x4d, 0x61, 0x61, 0x47, 0x46, 0x35, 0x56, 0x4b,
+    0x6d, 0x54, 0x65, 0x42, 0x76, 0x61, 0x4e, 0x53, 0x6a, 0x75, 0x74, 0x45,
+    0x44, 0x78, 0x6c, 0x50, 0x5a, 0x43, 0x49, 0x42, 0x49, 0x6e, 0x67, 0x4d,
+    0x47, 0x47, 0x7a, 0x72, 0x6c, 0x30, 0x42, 0x70, 0x33, 0x76, 0x65, 0x0a,
+    0x66, 0x4c, 0x4b, 0x2b, 0x79, 0x6d, 0x56, 0x68, 0x41, 0x49, 0x61, 0x75,
+    0x32, 0x6f, 0x39, 0x37, 0x30, 0x49, 0x6d, 0x74, 0x54, 0x52, 0x31, 0x5a,
+    0x6d, 0x6b, 0x47, 0x78, 0x76, 0x45, 0x65, 0x41, 0x33, 0x4a, 0x35, 0x69,
+    0x77, 0x2f, 0x6d, 0x6a, 0x67, 0x62, 0x49, 0x77, 0x67, 0x61, 0x38, 0x77,
+    0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f,
+    0x42, 0x41, 0x55, 0x77, 0x0a, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41,
+    0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38,
+    0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x62, 0x51, 0x59,
+    0x49, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48, 0x41, 0x51, 0x77,
+    0x45, 0x59, 0x54, 0x42, 0x66, 0x6f, 0x56, 0x32, 0x67, 0x57, 0x7a, 0x42,
+    0x5a, 0x4d, 0x46, 0x63, 0x77, 0x56, 0x52, 0x59, 0x4a, 0x0a, 0x61, 0x57,
+    0x31, 0x68, 0x5a, 0x32, 0x55, 0x76, 0x5a, 0x32, 0x6c, 0x6d, 0x4d, 0x43,
+    0x45, 0x77, 0x48, 0x7a, 0x41, 0x48, 0x42, 0x67, 0x55, 0x72, 0x44, 0x67,
+    0x4d, 0x43, 0x47, 0x67, 0x51, 0x55, 0x6a, 0x2b, 0x58, 0x54, 0x47, 0x6f,
+    0x61, 0x73, 0x6a, 0x59, 0x35, 0x72, 0x77, 0x38, 0x2b, 0x41, 0x61, 0x74,
+    0x52, 0x49, 0x47, 0x43, 0x78, 0x37, 0x47, 0x53, 0x34, 0x77, 0x4a, 0x52,
+    0x59, 0x6a, 0x0a, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c,
+    0x32, 0x78, 0x76, 0x5a, 0x32, 0x38, 0x75, 0x64, 0x6d, 0x56, 0x79, 0x61,
+    0x58, 0x4e, 0x70, 0x5a, 0x32, 0x34, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c,
+    0x33, 0x5a, 0x7a, 0x62, 0x47, 0x39, 0x6e, 0x62, 0x79, 0x35, 0x6e, 0x61,
+    0x57, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42,
+    0x42, 0x59, 0x45, 0x46, 0x4c, 0x4d, 0x57, 0x0a, 0x6b, 0x66, 0x33, 0x75,
+    0x70, 0x6d, 0x37, 0x6b, 0x74, 0x53, 0x35, 0x4a, 0x6a, 0x34, 0x64, 0x34,
+    0x67, 0x59, 0x44, 0x73, 0x35, 0x62, 0x47, 0x31, 0x4d, 0x41, 0x6f, 0x47,
+    0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x42, 0x41, 0x4d, 0x44,
+    0x41, 0x32, 0x67, 0x41, 0x4d, 0x47, 0x55, 0x43, 0x4d, 0x47, 0x59, 0x68,
+    0x44, 0x42, 0x67, 0x6d, 0x59, 0x46, 0x6f, 0x34, 0x65, 0x31, 0x5a, 0x43,
+    0x0a, 0x34, 0x4b, 0x66, 0x38, 0x4e, 0x6f, 0x52, 0x52, 0x6b, 0x53, 0x41,
+    0x73, 0x64, 0x6b, 0x31, 0x44, 0x50, 0x63, 0x51, 0x64, 0x68, 0x43, 0x50,
+    0x51, 0x72, 0x4e, 0x5a, 0x38, 0x4e, 0x51, 0x62, 0x4f, 0x7a, 0x57, 0x6d,
+    0x39, 0x6b, 0x41, 0x33, 0x62, 0x62, 0x45, 0x68, 0x43, 0x48, 0x51, 0x36,
+    0x71, 0x51, 0x67, 0x49, 0x78, 0x41, 0x4a, 0x77, 0x39, 0x53, 0x44, 0x6b,
+    0x6a, 0x4f, 0x56, 0x67, 0x61, 0x0a, 0x46, 0x52, 0x4a, 0x5a, 0x61, 0x70,
+    0x37, 0x76, 0x31, 0x56, 0x6d, 0x79, 0x48, 0x56, 0x49, 0x73, 0x6d, 0x58,
+    0x48, 0x4e, 0x78, 0x79, 0x6e, 0x66, 0x47, 0x79, 0x70, 0x68, 0x65, 0x33,
+    0x48, 0x52, 0x33, 0x76, 0x50, 0x41, 0x35, 0x51, 0x30, 0x36, 0x53, 0x71,
+    0x6f, 0x74, 0x70, 0x39, 0x69, 0x47, 0x4b, 0x74, 0x30, 0x75, 0x45, 0x41,
+    0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75,
+    0x65, 0x72, 0x3a, 0x20, 0x4f, 0x3d, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
+    0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d,
+    0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c,
+    0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x4f, 0x3d,
+    0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
+    0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69,
+    0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+    0x3a, 0x20, 0x22, 0x56, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x20,
+    0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c,
+    0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x38, 0x30,
+    0x35, 0x30, 0x37, 0x35, 0x37, 0x32, 0x37, 0x32, 0x32, 0x38, 0x36, 0x32,
+    0x34, 0x38, 0x35, 0x35, 0x31, 0x35, 0x33, 0x30, 0x36, 0x34, 0x32, 0x39,
+    0x39, 0x34, 0x30, 0x36, 0x39, 0x31, 0x33, 0x30, 0x39, 0x32, 0x34, 0x36,
+    0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x65, 0x66, 0x3a, 0x35,
+    0x61, 0x3a, 0x66, 0x31, 0x3a, 0x33, 0x33, 0x3a, 0x65, 0x66, 0x3a, 0x66,
+    0x31, 0x3a, 0x63, 0x64, 0x3a, 0x62, 0x62, 0x3a, 0x35, 0x31, 0x3a, 0x30,
+    0x32, 0x3a, 0x65, 0x65, 0x3a, 0x31, 0x32, 0x3a, 0x31, 0x34, 0x3a, 0x34,
+    0x62, 0x3a, 0x39, 0x36, 0x3a, 0x63, 0x34, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x61, 0x31, 0x3a, 0x64, 0x62, 0x3a, 0x36, 0x33,
+    0x3a, 0x39, 0x33, 0x3a, 0x39, 0x31, 0x3a, 0x36, 0x66, 0x3a, 0x31, 0x37,
+    0x3a, 0x65, 0x34, 0x3a, 0x31, 0x38, 0x3a, 0x35, 0x35, 0x3a, 0x30, 0x39,
+    0x3a, 0x34, 0x30, 0x3a, 0x30, 0x34, 0x3a, 0x31, 0x35, 0x3a, 0x63, 0x37,
+    0x3a, 0x30, 0x32, 0x3a, 0x34, 0x30, 0x3a, 0x62, 0x30, 0x3a, 0x61, 0x65,
+    0x3a, 0x36, 0x62, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x61, 0x34, 0x3a, 0x62, 0x36, 0x3a, 0x62, 0x33, 0x3a, 0x39,
+    0x39, 0x3a, 0x36, 0x66, 0x3a, 0x63, 0x32, 0x3a, 0x66, 0x33, 0x3a, 0x30,
+    0x36, 0x3a, 0x62, 0x33, 0x3a, 0x66, 0x64, 0x3a, 0x38, 0x36, 0x3a, 0x38,
+    0x31, 0x3a, 0x62, 0x64, 0x3a, 0x36, 0x33, 0x3a, 0x34, 0x31, 0x3a, 0x33,
+    0x64, 0x3a, 0x38, 0x63, 0x3a, 0x35, 0x30, 0x3a, 0x30, 0x39, 0x3a, 0x63,
+    0x63, 0x3a, 0x34, 0x66, 0x3a, 0x61, 0x33, 0x3a, 0x32, 0x39, 0x3a, 0x63,
+    0x32, 0x3a, 0x63, 0x63, 0x3a, 0x66, 0x30, 0x3a, 0x65, 0x32, 0x3a, 0x66,
+    0x61, 0x3a, 0x31, 0x62, 0x3a, 0x31, 0x34, 0x3a, 0x30, 0x33, 0x3a, 0x30,
+    0x35, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x50, 0x44,
+    0x43, 0x43, 0x41, 0x61, 0x55, 0x43, 0x45, 0x44, 0x79, 0x52, 0x4d, 0x63,
+    0x73, 0x66, 0x39, 0x74, 0x41, 0x62, 0x44, 0x70, 0x71, 0x34, 0x30, 0x45,
+    0x53, 0x2f, 0x45, 0x72, 0x34, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f,
+    0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51,
+    0x41, 0x77, 0x58, 0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x0a, 0x41,
+    0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46,
+    0x7a, 0x41, 0x56, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x44,
+    0x6c, 0x5a, 0x6c, 0x63, 0x6d, 0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4c,
+    0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x54, 0x63, 0x77, 0x4e,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x79, 0x35, 0x44, 0x62,
+    0x47, 0x46, 0x7a, 0x0a, 0x63, 0x79, 0x41, 0x7a, 0x49, 0x46, 0x42, 0x31,
+    0x59, 0x6d, 0x78, 0x70, 0x59, 0x79, 0x42, 0x51, 0x63, 0x6d, 0x6c, 0x74,
+    0x59, 0x58, 0x4a, 0x35, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70,
+    0x5a, 0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67,
+    0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35,
+    0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x6b, 0x32, 0x0a, 0x4d, 0x44, 0x45,
+    0x79, 0x4f, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f,
+    0x58, 0x44, 0x54, 0x49, 0x34, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x6a, 0x49,
+    0x7a, 0x4e, 0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x58, 0x7a, 0x45,
+    0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d,
+    0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42, 0x67, 0x4e,
+    0x56, 0x0a, 0x42, 0x41, 0x6f, 0x54, 0x44, 0x6c, 0x5a, 0x6c, 0x63, 0x6d,
+    0x6c, 0x54, 0x61, 0x57, 0x64, 0x75, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d,
+    0x4d, 0x75, 0x4d, 0x54, 0x63, 0x77, 0x4e, 0x51, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x4c, 0x45, 0x79, 0x35, 0x44, 0x62, 0x47, 0x46, 0x7a, 0x63, 0x79,
+    0x41, 0x7a, 0x49, 0x46, 0x42, 0x31, 0x59, 0x6d, 0x78, 0x70, 0x59, 0x79,
+    0x42, 0x51, 0x63, 0x6d, 0x6c, 0x74, 0x0a, 0x59, 0x58, 0x4a, 0x35, 0x49,
+    0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a, 0x59,
+    0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x58, 0x56, 0x30, 0x61,
+    0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x49, 0x47, 0x66, 0x4d,
+    0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44,
+    0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4e, 0x0a,
+    0x41, 0x44, 0x43, 0x42, 0x69, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x4a,
+    0x58, 0x46, 0x6d, 0x65, 0x38, 0x68, 0x75, 0x4b, 0x41, 0x52, 0x53, 0x30,
+    0x45, 0x4e, 0x38, 0x45, 0x51, 0x4e, 0x76, 0x6a, 0x56, 0x36, 0x39, 0x71,
+    0x52, 0x55, 0x43, 0x50, 0x68, 0x41, 0x77, 0x4c, 0x30, 0x54, 0x50, 0x5a,
+    0x32, 0x52, 0x48, 0x50, 0x37, 0x67, 0x4a, 0x59, 0x48, 0x79, 0x58, 0x33,
+    0x4b, 0x71, 0x68, 0x45, 0x0a, 0x42, 0x61, 0x72, 0x73, 0x41, 0x78, 0x39,
+    0x34, 0x66, 0x35, 0x36, 0x54, 0x75, 0x5a, 0x6f, 0x41, 0x71, 0x69, 0x4e,
+    0x39, 0x31, 0x71, 0x79, 0x46, 0x6f, 0x6d, 0x4e, 0x46, 0x78, 0x33, 0x49,
+    0x6e, 0x7a, 0x50, 0x52, 0x4d, 0x78, 0x6e, 0x56, 0x78, 0x30, 0x6a, 0x6e,
+    0x76, 0x54, 0x30, 0x4c, 0x77, 0x64, 0x64, 0x38, 0x4b, 0x6b, 0x4d, 0x61,
+    0x4f, 0x49, 0x47, 0x2b, 0x59, 0x44, 0x2f, 0x69, 0x73, 0x0a, 0x49, 0x31,
+    0x39, 0x77, 0x4b, 0x54, 0x61, 0x6b, 0x79, 0x59, 0x62, 0x6e, 0x73, 0x5a,
+    0x6f, 0x67, 0x79, 0x31, 0x4f, 0x6c, 0x68, 0x65, 0x63, 0x39, 0x76, 0x6e,
+    0x32, 0x61, 0x2f, 0x69, 0x52, 0x46, 0x4d, 0x39, 0x78, 0x32, 0x46, 0x65,
+    0x30, 0x50, 0x6f, 0x6e, 0x46, 0x6b, 0x54, 0x47, 0x55, 0x75, 0x67, 0x57,
+    0x68, 0x46, 0x70, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x4d, 0x41,
+    0x30, 0x47, 0x0a, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44,
+    0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x42, 0x41,
+    0x42, 0x42, 0x79, 0x55, 0x71, 0x6b, 0x46, 0x46, 0x42, 0x6b, 0x79, 0x43,
+    0x45, 0x48, 0x77, 0x78, 0x57, 0x73, 0x4b, 0x7a, 0x48, 0x34, 0x50, 0x49,
+    0x52, 0x6e, 0x4e, 0x35, 0x47, 0x66, 0x63, 0x58, 0x36, 0x6b, 0x62, 0x35,
+    0x73, 0x72, 0x6f, 0x63, 0x35, 0x30, 0x69, 0x0a, 0x32, 0x4a, 0x68, 0x75,
+    0x63, 0x77, 0x4e, 0x68, 0x6b, 0x63, 0x56, 0x38, 0x73, 0x45, 0x56, 0x41,
+    0x62, 0x6b, 0x53, 0x64, 0x6a, 0x62, 0x43, 0x78, 0x6c, 0x6e, 0x52, 0x68,
+    0x4c, 0x51, 0x32, 0x70, 0x52, 0x64, 0x4b, 0x6b, 0x6b, 0x69, 0x72, 0x57,
+    0x6d, 0x6e, 0x57, 0x58, 0x62, 0x6a, 0x39, 0x54, 0x2f, 0x55, 0x57, 0x5a,
+    0x59, 0x42, 0x32, 0x6f, 0x4b, 0x30, 0x7a, 0x35, 0x58, 0x71, 0x63, 0x4a,
+    0x0a, 0x32, 0x48, 0x55, 0x77, 0x31, 0x39, 0x4a, 0x6c, 0x59, 0x44, 0x31,
+    0x6e, 0x31, 0x6b, 0x68, 0x56, 0x64, 0x57, 0x6b, 0x2f, 0x6b, 0x66, 0x56,
+    0x49, 0x43, 0x30, 0x64, 0x70, 0x49, 0x6d, 0x6d, 0x43, 0x6c, 0x72, 0x37,
+    0x4a, 0x79, 0x44, 0x69, 0x47, 0x53, 0x6e, 0x6f, 0x73, 0x63, 0x78, 0x6c,
+    0x49, 0x61, 0x55, 0x35, 0x72, 0x66, 0x47, 0x57, 0x2f, 0x44, 0x2f, 0x78,
+    0x77, 0x7a, 0x6f, 0x69, 0x51, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49,
+    0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x6c,
+    0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x3d, 0x47,
+    0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x55,
+    0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20,
+    0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x52, 0x33,
+    0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67,
+    0x6e, 0x20, 0x4f, 0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
+    0x67, 0x6e, 0x20, 0x4f, 0x55, 0x3d, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
+    0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41,
+    0x20, 0x2d, 0x20, 0x52, 0x33, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69,
+    0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d,
+    0x20, 0x52, 0x33, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61,
+    0x6c, 0x3a, 0x20, 0x34, 0x38, 0x33, 0x35, 0x37, 0x30, 0x33, 0x32, 0x37,
+    0x38, 0x34, 0x35, 0x39, 0x37, 0x35, 0x39, 0x34, 0x32, 0x36, 0x32, 0x30,
+    0x39, 0x39, 0x35, 0x34, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x63, 0x35, 0x3a, 0x64, 0x66, 0x3a, 0x62, 0x38, 0x3a, 0x34, 0x39, 0x3a,
+    0x63, 0x61, 0x3a, 0x30, 0x35, 0x3a, 0x31, 0x33, 0x3a, 0x35, 0x35, 0x3a,
+    0x65, 0x65, 0x3a, 0x32, 0x64, 0x3a, 0x62, 0x61, 0x3a, 0x31, 0x61, 0x3a,
+    0x63, 0x33, 0x3a, 0x33, 0x65, 0x3a, 0x62, 0x30, 0x3a, 0x32, 0x38, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65,
+    0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x36, 0x3a, 0x39,
+    0x62, 0x3a, 0x35, 0x36, 0x3a, 0x31, 0x31, 0x3a, 0x34, 0x38, 0x3a, 0x66,
+    0x30, 0x3a, 0x31, 0x63, 0x3a, 0x37, 0x37, 0x3a, 0x63, 0x35, 0x3a, 0x34,
+    0x35, 0x3a, 0x37, 0x38, 0x3a, 0x63, 0x31, 0x3a, 0x30, 0x39, 0x3a, 0x32,
+    0x36, 0x3a, 0x64, 0x66, 0x3a, 0x35, 0x62, 0x3a, 0x38, 0x35, 0x3a, 0x36,
+    0x39, 0x3a, 0x37, 0x36, 0x3a, 0x61, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x48,
+    0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x62, 0x3a, 0x62, 0x35, 0x3a,
+    0x32, 0x32, 0x3a, 0x64, 0x37, 0x3a, 0x62, 0x37, 0x3a, 0x66, 0x31, 0x3a,
+    0x32, 0x37, 0x3a, 0x61, 0x64, 0x3a, 0x36, 0x61, 0x3a, 0x30, 0x31, 0x3a,
+    0x31, 0x33, 0x3a, 0x38, 0x36, 0x3a, 0x35, 0x62, 0x3a, 0x64, 0x66, 0x3a,
+    0x31, 0x63, 0x3a, 0x64, 0x34, 0x3a, 0x31, 0x30, 0x3a, 0x32, 0x65, 0x3a,
+    0x37, 0x64, 0x3a, 0x30, 0x37, 0x3a, 0x35, 0x39, 0x3a, 0x61, 0x66, 0x3a,
+    0x36, 0x33, 0x3a, 0x35, 0x61, 0x3a, 0x37, 0x63, 0x3a, 0x66, 0x34, 0x3a,
+    0x37, 0x32, 0x3a, 0x30, 0x64, 0x3a, 0x63, 0x39, 0x3a, 0x36, 0x33, 0x3a,
+    0x63, 0x35, 0x3a, 0x33, 0x62, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42,
+    0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49,
+    0x49, 0x44, 0x58, 0x7a, 0x43, 0x43, 0x41, 0x6b, 0x65, 0x67, 0x41, 0x77,
+    0x49, 0x42, 0x41, 0x67, 0x49, 0x4c, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41,
+    0x41, 0x42, 0x49, 0x56, 0x68, 0x54, 0x43, 0x4b, 0x49, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x4c, 0x42, 0x51, 0x41, 0x77, 0x54, 0x44, 0x45, 0x67, 0x4d, 0x42,
+    0x34, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x58, 0x52,
+    0x32, 0x78, 0x76, 0x59, 0x6d, 0x46, 0x73, 0x55, 0x32, 0x6c, 0x6e, 0x62,
+    0x69, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45, 0x4e, 0x42, 0x49,
+    0x43, 0x30, 0x67, 0x55, 0x6a, 0x4d, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x43, 0x6b, 0x64, 0x73, 0x62,
+    0x32, 0x4a, 0x68, 0x62, 0x46, 0x4e, 0x70, 0x0a, 0x5a, 0x32, 0x34, 0x78,
+    0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54,
+    0x43, 0x6b, 0x64, 0x73, 0x62, 0x32, 0x4a, 0x68, 0x62, 0x46, 0x4e, 0x70,
+    0x5a, 0x32, 0x34, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44, 0x6b, 0x77,
+    0x4d, 0x7a, 0x45, 0x34, 0x4d, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77,
+    0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, 0x6b, 0x77, 0x4d, 0x7a, 0x45, 0x34,
+    0x0a, 0x4d, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x6a, 0x42,
+    0x4d, 0x4d, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x4c, 0x45, 0x78, 0x64, 0x48, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x78,
+    0x54, 0x61, 0x57, 0x64, 0x75, 0x49, 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51,
+    0x67, 0x51, 0x30, 0x45, 0x67, 0x4c, 0x53, 0x42, 0x53, 0x4d, 0x7a, 0x45,
+    0x54, 0x4d, 0x42, 0x45, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68,
+    0x4d, 0x4b, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d, 0x46, 0x73, 0x55, 0x32,
+    0x6c, 0x6e, 0x62, 0x6a, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x41, 0x78, 0x4d, 0x4b, 0x52, 0x32, 0x78, 0x76, 0x59, 0x6d,
+    0x46, 0x73, 0x55, 0x32, 0x6c, 0x6e, 0x62, 0x6a, 0x43, 0x43, 0x41, 0x53,
+    0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x0a, 0x68,
+    0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67,
+    0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67,
+    0x67, 0x45, 0x42, 0x41, 0x4d, 0x77, 0x6c, 0x64, 0x70, 0x42, 0x35, 0x42,
+    0x6e, 0x67, 0x69, 0x46, 0x76, 0x58, 0x41, 0x67, 0x37, 0x61, 0x45, 0x79,
+    0x69, 0x69, 0x65, 0x2f, 0x51, 0x56, 0x32, 0x45, 0x63, 0x57, 0x74, 0x69,
+    0x48, 0x4c, 0x38, 0x0a, 0x52, 0x67, 0x4a, 0x44, 0x78, 0x37, 0x4b, 0x4b,
+    0x6e, 0x51, 0x52, 0x66, 0x4a, 0x4d, 0x73, 0x75, 0x53, 0x2b, 0x46, 0x67,
+    0x67, 0x6b, 0x62, 0x68, 0x55, 0x71, 0x73, 0x4d, 0x67, 0x55, 0x64, 0x77,
+    0x62, 0x4e, 0x31, 0x6b, 0x30, 0x65, 0x76, 0x31, 0x4c, 0x4b, 0x4d, 0x50,
+    0x67, 0x6a, 0x30, 0x4d, 0x4b, 0x36, 0x36, 0x58, 0x31, 0x37, 0x59, 0x55,
+    0x68, 0x68, 0x42, 0x35, 0x75, 0x7a, 0x73, 0x54, 0x0a, 0x67, 0x48, 0x65,
+    0x4d, 0x43, 0x4f, 0x46, 0x4a, 0x30, 0x6d, 0x70, 0x69, 0x4c, 0x78, 0x39,
+    0x65, 0x2b, 0x70, 0x5a, 0x6f, 0x33, 0x34, 0x6b, 0x6e, 0x6c, 0x54, 0x69,
+    0x66, 0x42, 0x74, 0x63, 0x2b, 0x79, 0x63, 0x73, 0x6d, 0x57, 0x51, 0x31,
+    0x7a, 0x33, 0x72, 0x44, 0x49, 0x36, 0x53, 0x59, 0x4f, 0x67, 0x78, 0x58,
+    0x47, 0x37, 0x31, 0x75, 0x4c, 0x30, 0x67, 0x52, 0x67, 0x79, 0x6b, 0x6d,
+    0x6d, 0x0a, 0x4b, 0x50, 0x5a, 0x70, 0x4f, 0x2f, 0x62, 0x4c, 0x79, 0x43,
+    0x69, 0x52, 0x35, 0x5a, 0x32, 0x4b, 0x59, 0x56, 0x63, 0x33, 0x72, 0x48,
+    0x51, 0x55, 0x33, 0x48, 0x54, 0x67, 0x4f, 0x75, 0x35, 0x79, 0x4c, 0x79,
+    0x36, 0x63, 0x2b, 0x39, 0x43, 0x37, 0x76, 0x2f, 0x55, 0x39, 0x41, 0x4f,
+    0x45, 0x47, 0x4d, 0x2b, 0x69, 0x43, 0x4b, 0x36, 0x35, 0x54, 0x70, 0x6a,
+    0x6f, 0x57, 0x63, 0x34, 0x7a, 0x64, 0x0a, 0x51, 0x51, 0x34, 0x67, 0x4f,
+    0x73, 0x43, 0x30, 0x70, 0x36, 0x48, 0x70, 0x73, 0x6b, 0x2b, 0x51, 0x4c,
+    0x6a, 0x4a, 0x67, 0x36, 0x56, 0x66, 0x4c, 0x75, 0x51, 0x53, 0x53, 0x61,
+    0x47, 0x6a, 0x6c, 0x4f, 0x43, 0x5a, 0x67, 0x64, 0x62, 0x4b, 0x66, 0x64,
+    0x2f, 0x2b, 0x52, 0x46, 0x4f, 0x2b, 0x75, 0x49, 0x45, 0x6e, 0x38, 0x72,
+    0x55, 0x41, 0x56, 0x53, 0x4e, 0x45, 0x43, 0x4d, 0x57, 0x45, 0x5a, 0x0a,
+    0x58, 0x72, 0x69, 0x58, 0x37, 0x36, 0x31, 0x33, 0x74, 0x32, 0x53, 0x61,
+    0x65, 0x72, 0x39, 0x66, 0x77, 0x52, 0x50, 0x76, 0x6d, 0x32, 0x4c, 0x37,
+    0x44, 0x57, 0x7a, 0x67, 0x56, 0x47, 0x6b, 0x57, 0x71, 0x51, 0x50, 0x61,
+    0x62, 0x75, 0x6d, 0x44, 0x6b, 0x33, 0x46, 0x32, 0x78, 0x6d, 0x6d, 0x46,
+    0x67, 0x68, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4e, 0x43,
+    0x4d, 0x45, 0x41, 0x77, 0x0a, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x50, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45,
+    0x47, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45,
+    0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38,
+    0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59,
+    0x45, 0x46, 0x49, 0x2f, 0x77, 0x53, 0x33, 0x2b, 0x6f, 0x0a, 0x4c, 0x6b,
+    0x55, 0x6b, 0x72, 0x6b, 0x31, 0x51, 0x2b, 0x6d, 0x4f, 0x61, 0x69, 0x39,
+    0x37, 0x69, 0x33, 0x52, 0x75, 0x38, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53,
+    0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77,
+    0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x42, 0x4c, 0x51, 0x4e,
+    0x76, 0x41, 0x55, 0x4b, 0x72, 0x2b, 0x79, 0x41, 0x7a, 0x76, 0x39, 0x35,
+    0x5a, 0x55, 0x0a, 0x52, 0x55, 0x6d, 0x37, 0x6c, 0x67, 0x41, 0x4a, 0x51,
+    0x61, 0x79, 0x7a, 0x45, 0x34, 0x61, 0x47, 0x4b, 0x41, 0x63, 0x7a, 0x79,
+    0x6d, 0x76, 0x6d, 0x64, 0x4c, 0x6d, 0x36, 0x41, 0x43, 0x32, 0x75, 0x70,
+    0x41, 0x72, 0x54, 0x39, 0x66, 0x48, 0x78, 0x44, 0x34, 0x71, 0x2f, 0x63,
+    0x32, 0x64, 0x4b, 0x67, 0x38, 0x64, 0x45, 0x65, 0x33, 0x6a, 0x67, 0x72,
+    0x32, 0x35, 0x73, 0x62, 0x77, 0x4d, 0x70, 0x0a, 0x6a, 0x6a, 0x4d, 0x35,
+    0x52, 0x63, 0x4f, 0x4f, 0x35, 0x4c, 0x6c, 0x58, 0x62, 0x4b, 0x72, 0x38,
+    0x45, 0x70, 0x62, 0x73, 0x55, 0x38, 0x59, 0x74, 0x35, 0x43, 0x52, 0x73,
+    0x75, 0x5a, 0x52, 0x6a, 0x2b, 0x39, 0x78, 0x54, 0x61, 0x47, 0x64, 0x57,
+    0x50, 0x6f, 0x4f, 0x34, 0x7a, 0x7a, 0x55, 0x68, 0x77, 0x38, 0x6c, 0x6f,
+    0x2f, 0x73, 0x37, 0x61, 0x77, 0x6c, 0x4f, 0x71, 0x7a, 0x4a, 0x43, 0x4b,
+    0x0a, 0x36, 0x66, 0x42, 0x64, 0x52, 0x6f, 0x79, 0x56, 0x33, 0x58, 0x70,
+    0x59, 0x4b, 0x42, 0x6f, 0x76, 0x48, 0x64, 0x37, 0x4e, 0x41, 0x44, 0x64,
+    0x42, 0x6a, 0x2b, 0x31, 0x45, 0x62, 0x64, 0x64, 0x54, 0x4b, 0x4a, 0x64,
+    0x2b, 0x38, 0x32, 0x63, 0x45, 0x48, 0x68, 0x58, 0x58, 0x69, 0x70, 0x61,
+    0x30, 0x30, 0x39, 0x35, 0x4d, 0x4a, 0x36, 0x52, 0x4d, 0x47, 0x33, 0x4e,
+    0x7a, 0x64, 0x76, 0x51, 0x58, 0x0a, 0x6d, 0x63, 0x49, 0x66, 0x65, 0x67,
+    0x37, 0x6a, 0x4c, 0x51, 0x69, 0x74, 0x43, 0x68, 0x77, 0x73, 0x2f, 0x7a,
+    0x79, 0x72, 0x56, 0x51, 0x34, 0x50, 0x6b, 0x58, 0x34, 0x32, 0x36, 0x38,
+    0x4e, 0x58, 0x53, 0x62, 0x37, 0x68, 0x4c, 0x69, 0x31, 0x38, 0x59, 0x49,
+    0x76, 0x44, 0x51, 0x56, 0x45, 0x54, 0x49, 0x35, 0x33, 0x4f, 0x39, 0x7a,
+    0x4a, 0x72, 0x6c, 0x41, 0x47, 0x6f, 0x6d, 0x65, 0x63, 0x73, 0x0a, 0x4d,
+    0x78, 0x38, 0x36, 0x4f, 0x79, 0x58, 0x53, 0x68, 0x6b, 0x44, 0x4f, 0x4f,
+    0x79, 0x79, 0x47, 0x65, 0x4d, 0x6c, 0x68, 0x4c, 0x78, 0x53, 0x36, 0x37,
+    0x74, 0x74, 0x56, 0x62, 0x39, 0x2b, 0x45, 0x37, 0x67, 0x55, 0x4a, 0x54,
+    0x62, 0x30, 0x6f, 0x32, 0x48, 0x4c, 0x4f, 0x30, 0x32, 0x4a, 0x51, 0x5a,
+    0x52, 0x37, 0x72, 0x6b, 0x70, 0x65, 0x44, 0x4d, 0x64, 0x6d, 0x7a, 0x74,
+    0x63, 0x70, 0x48, 0x0a, 0x57, 0x44, 0x39, 0x66, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e,
+    0x74, 0x65, 0x72, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61,
+    0x6c, 0x20, 0x43, 0x41, 0x20, 0x49, 0x49, 0x49, 0x20, 0x4f, 0x3d, 0x54,
+    0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65,
+    0x72, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55, 0x3d, 0x54, 0x43,
+    0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72,
+    0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x43,
+    0x41, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,
+    0x20, 0x43, 0x4e, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65,
+    0x72, 0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x49, 0x49, 0x49, 0x20,
+    0x4f, 0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65,
+    0x6e, 0x74, 0x65, 0x72, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x20, 0x4f, 0x55,
+    0x3d, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x65, 0x6e,
+    0x74, 0x65, 0x72, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61,
+    0x6c, 0x20, 0x43, 0x41, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+    0x3a, 0x20, 0x22, 0x54, 0x43, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43,
+    0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72,
+    0x73, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x49, 0x49, 0x49, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x32, 0x30,
+    0x31, 0x30, 0x38, 0x38, 0x39, 0x39, 0x39, 0x33, 0x39, 0x38, 0x33, 0x35,
+    0x30, 0x37, 0x33, 0x34, 0x36, 0x34, 0x36, 0x30, 0x35, 0x33, 0x33, 0x34,
+    0x30, 0x37, 0x39, 0x30, 0x32, 0x39, 0x36, 0x34, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x39, 0x66, 0x3a, 0x64, 0x64, 0x3a, 0x64, 0x62,
+    0x3a, 0x61, 0x62, 0x3a, 0x66, 0x66, 0x3a, 0x38, 0x65, 0x3a, 0x66, 0x66,
+    0x3a, 0x34, 0x35, 0x3a, 0x32, 0x31, 0x3a, 0x35, 0x66, 0x3a, 0x66, 0x30,
+    0x3a, 0x36, 0x63, 0x3a, 0x39, 0x64, 0x3a, 0x38, 0x66, 0x3a, 0x66, 0x65,
+    0x3a, 0x32, 0x62, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x39, 0x36, 0x3a, 0x35, 0x36, 0x3a, 0x63, 0x64, 0x3a, 0x37, 0x62, 0x3a,
+    0x35, 0x37, 0x3a, 0x39, 0x36, 0x3a, 0x39, 0x38, 0x3a, 0x39, 0x35, 0x3a,
+    0x64, 0x30, 0x3a, 0x65, 0x31, 0x3a, 0x34, 0x31, 0x3a, 0x34, 0x36, 0x3a,
+    0x36, 0x38, 0x3a, 0x30, 0x36, 0x3a, 0x66, 0x62, 0x3a, 0x62, 0x38, 0x3a,
+    0x63, 0x36, 0x3a, 0x31, 0x31, 0x3a, 0x30, 0x36, 0x3a, 0x38, 0x37, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x33, 0x30,
+    0x3a, 0x39, 0x62, 0x3a, 0x34, 0x61, 0x3a, 0x38, 0x37, 0x3a, 0x66, 0x36,
+    0x3a, 0x63, 0x61, 0x3a, 0x35, 0x36, 0x3a, 0x63, 0x39, 0x3a, 0x33, 0x31,
+    0x3a, 0x36, 0x39, 0x3a, 0x61, 0x61, 0x3a, 0x61, 0x39, 0x3a, 0x39, 0x63,
+    0x3a, 0x36, 0x64, 0x3a, 0x39, 0x38, 0x3a, 0x38, 0x38, 0x3a, 0x35, 0x34,
+    0x3a, 0x64, 0x37, 0x3a, 0x38, 0x39, 0x3a, 0x32, 0x62, 0x3a, 0x64, 0x35,
+    0x3a, 0x34, 0x33, 0x3a, 0x37, 0x65, 0x3a, 0x32, 0x64, 0x3a, 0x30, 0x37,
+    0x3a, 0x62, 0x32, 0x3a, 0x39, 0x63, 0x3a, 0x62, 0x65, 0x3a, 0x64, 0x61,
+    0x3a, 0x35, 0x35, 0x3a, 0x64, 0x33, 0x3a, 0x35, 0x64, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x34, 0x54, 0x43, 0x43, 0x41, 0x73,
+    0x6d, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4f, 0x59, 0x79,
+    0x55, 0x41, 0x41, 0x51, 0x41, 0x43, 0x46, 0x49, 0x30, 0x7a, 0x46, 0x51,
+    0x4c, 0x6b, 0x62, 0x50, 0x51, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f,
+    0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42, 0x51,
+    0x41, 0x77, 0x65, 0x7a, 0x45, 0x4c, 0x0a, 0x4d, 0x41, 0x6b, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x52, 0x45, 0x55, 0x78, 0x48,
+    0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x45,
+    0x31, 0x52, 0x44, 0x49, 0x46, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x51,
+    0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79, 0x49, 0x45, 0x64, 0x74, 0x59,
+    0x6b, 0x67, 0x78, 0x4a, 0x44, 0x41, 0x69, 0x42, 0x67, 0x4e, 0x56, 0x0a,
+    0x42, 0x41, 0x73, 0x54, 0x47, 0x31, 0x52, 0x44, 0x49, 0x46, 0x52, 0x79,
+    0x64, 0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79,
+    0x49, 0x46, 0x56, 0x75, 0x61, 0x58, 0x5a, 0x6c, 0x63, 0x6e, 0x4e, 0x68,
+    0x62, 0x43, 0x42, 0x44, 0x51, 0x54, 0x45, 0x6f, 0x4d, 0x43, 0x59, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x66, 0x56, 0x45, 0x4d, 0x67,
+    0x56, 0x48, 0x4a, 0x31, 0x0a, 0x63, 0x33, 0x52, 0x44, 0x5a, 0x57, 0x35,
+    0x30, 0x5a, 0x58, 0x49, 0x67, 0x56, 0x57, 0x35, 0x70, 0x64, 0x6d, 0x56,
+    0x79, 0x63, 0x32, 0x46, 0x73, 0x49, 0x45, 0x4e, 0x42, 0x49, 0x45, 0x6c,
+    0x4a, 0x53, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x77, 0x4f, 0x54, 0x41,
+    0x35, 0x4d, 0x44, 0x6b, 0x77, 0x4f, 0x44, 0x45, 0x31, 0x4d, 0x6a, 0x64,
+    0x61, 0x46, 0x77, 0x30, 0x79, 0x4f, 0x54, 0x45, 0x79, 0x0a, 0x4d, 0x7a,
+    0x45, 0x79, 0x4d, 0x7a, 0x55, 0x35, 0x4e, 0x54, 0x6c, 0x61, 0x4d, 0x48,
+    0x73, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41,
+    0x59, 0x54, 0x41, 0x6b, 0x52, 0x46, 0x4d, 0x52, 0x77, 0x77, 0x47, 0x67,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x4e, 0x55, 0x51, 0x79,
+    0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x45, 0x4e, 0x6c, 0x62, 0x6e,
+    0x52, 0x6c, 0x0a, 0x63, 0x69, 0x42, 0x48, 0x62, 0x57, 0x4a, 0x49, 0x4d,
+    0x53, 0x51, 0x77, 0x49, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45,
+    0x78, 0x74, 0x55, 0x51, 0x79, 0x42, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64,
+    0x45, 0x4e, 0x6c, 0x62, 0x6e, 0x52, 0x6c, 0x63, 0x69, 0x42, 0x56, 0x62,
+    0x6d, 0x6c, 0x32, 0x5a, 0x58, 0x4a, 0x7a, 0x59, 0x57, 0x77, 0x67, 0x51,
+    0x30, 0x45, 0x78, 0x4b, 0x44, 0x41, 0x6d, 0x0a, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x4d, 0x54, 0x48, 0x31, 0x52, 0x44, 0x49, 0x46, 0x52, 0x79,
+    0x64, 0x58, 0x4e, 0x30, 0x51, 0x32, 0x56, 0x75, 0x64, 0x47, 0x56, 0x79,
+    0x49, 0x46, 0x56, 0x75, 0x61, 0x58, 0x5a, 0x6c, 0x63, 0x6e, 0x4e, 0x68,
+    0x62, 0x43, 0x42, 0x44, 0x51, 0x53, 0x42, 0x4a, 0x53, 0x55, 0x6b, 0x77,
+    0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47,
+    0x0a, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55,
+    0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45,
+    0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x43, 0x32, 0x70, 0x78,
+    0x69, 0x73, 0x4c, 0x6c, 0x78, 0x45, 0x72, 0x41, 0x4c, 0x79, 0x42, 0x70,
+    0x58, 0x73, 0x71, 0x36, 0x44, 0x46, 0x4a, 0x6d, 0x7a, 0x4e, 0x45, 0x75,
+    0x62, 0x6b, 0x4b, 0x4c, 0x46, 0x0a, 0x35, 0x2b, 0x63, 0x76, 0x41, 0x71,
+    0x42, 0x4e, 0x4c, 0x61, 0x54, 0x36, 0x68, 0x64, 0x71, 0x62, 0x4a, 0x59,
+    0x55, 0x74, 0x51, 0x43, 0x67, 0x67, 0x62, 0x65, 0x72, 0x67, 0x76, 0x62,
+    0x46, 0x49, 0x67, 0x79, 0x49, 0x70, 0x52, 0x4a, 0x39, 0x4f, 0x67, 0x2b,
+    0x34, 0x31, 0x55, 0x52, 0x4e, 0x7a, 0x64, 0x4e, 0x57, 0x38, 0x38, 0x6a,
+    0x42, 0x6d, 0x6c, 0x46, 0x50, 0x41, 0x51, 0x44, 0x59, 0x76, 0x0a, 0x44,
+    0x49, 0x52, 0x6c, 0x7a, 0x67, 0x39, 0x75, 0x77, 0x6c, 0x69, 0x54, 0x36,
+    0x43, 0x77, 0x4c, 0x4f, 0x75, 0x6e, 0x42, 0x6a, 0x76, 0x76, 0x79, 0x61,
+    0x38, 0x6f, 0x38, 0x34, 0x70, 0x78, 0x4f, 0x6a, 0x75, 0x54, 0x35, 0x66,
+    0x64, 0x4d, 0x6e, 0x6e, 0x78, 0x76, 0x56, 0x5a, 0x33, 0x69, 0x48, 0x4c,
+    0x58, 0x38, 0x4c, 0x52, 0x37, 0x50, 0x48, 0x36, 0x4d, 0x6c, 0x49, 0x66,
+    0x4b, 0x38, 0x76, 0x0a, 0x7a, 0x41, 0x72, 0x5a, 0x51, 0x65, 0x2b, 0x66,
+    0x2f, 0x70, 0x72, 0x68, 0x73, 0x71, 0x37, 0x35, 0x55, 0x37, 0x58, 0x6c,
+    0x36, 0x55, 0x61, 0x66, 0x59, 0x4f, 0x50, 0x66, 0x6a, 0x64, 0x4e, 0x2f,
+    0x2b, 0x35, 0x5a, 0x2b, 0x73, 0x37, 0x56, 0x79, 0x2b, 0x45, 0x75, 0x74,
+    0x43, 0x48, 0x6e, 0x4e, 0x61, 0x59, 0x6c, 0x41, 0x4a, 0x2f, 0x55, 0x71,
+    0x77, 0x61, 0x31, 0x44, 0x37, 0x4b, 0x52, 0x54, 0x0a, 0x79, 0x47, 0x47,
+    0x32, 0x39, 0x39, 0x4a, 0x35, 0x4b, 0x6d, 0x63, 0x59, 0x64, 0x6b, 0x68,
+    0x74, 0x57, 0x79, 0x55, 0x42, 0x30, 0x53, 0x62, 0x46, 0x74, 0x31, 0x64,
+    0x70, 0x49, 0x78, 0x56, 0x62, 0x59, 0x59, 0x71, 0x74, 0x38, 0x42, 0x73,
+    0x74, 0x32, 0x61, 0x39, 0x63, 0x38, 0x53, 0x61, 0x51, 0x61, 0x61, 0x6e,
+    0x56, 0x44, 0x45, 0x44, 0x31, 0x4d, 0x34, 0x42, 0x44, 0x6a, 0x35, 0x79,
+    0x6a, 0x0a, 0x64, 0x69, 0x70, 0x46, 0x74, 0x4b, 0x2b, 0x2f, 0x66, 0x7a,
+    0x36, 0x48, 0x50, 0x33, 0x62, 0x46, 0x7a, 0x53, 0x72, 0x65, 0x49, 0x4d,
+    0x55, 0x57, 0x57, 0x4d, 0x76, 0x35, 0x47, 0x2f, 0x55, 0x50, 0x79, 0x77,
+    0x30, 0x52, 0x55, 0x6d, 0x53, 0x34, 0x30, 0x6e, 0x5a, 0x69, 0x64, 0x34,
+    0x50, 0x78, 0x57, 0x4a, 0x2f, 0x2f, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41,
+    0x47, 0x6a, 0x59, 0x7a, 0x42, 0x68, 0x0a, 0x4d, 0x42, 0x38, 0x47, 0x41,
+    0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46,
+    0x46, 0x62, 0x6e, 0x34, 0x56, 0x73, 0x6c, 0x51, 0x34, 0x44, 0x67, 0x39,
+    0x6f, 0x7a, 0x68, 0x63, 0x62, 0x79, 0x4f, 0x35, 0x59, 0x41, 0x76, 0x78,
+    0x45, 0x6a, 0x69, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45,
+    0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x0a,
+    0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50,
+    0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47,
+    0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57,
+    0x42, 0x42, 0x52, 0x57, 0x35, 0x2b, 0x46, 0x62, 0x4a, 0x55, 0x4f, 0x41,
+    0x34, 0x50, 0x61, 0x4d, 0x34, 0x58, 0x47, 0x38, 0x6a, 0x75, 0x57, 0x41,
+    0x4c, 0x38, 0x52, 0x49, 0x0a, 0x34, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b,
+    0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55,
+    0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x67, 0x38, 0x65,
+    0x76, 0x36, 0x6e, 0x39, 0x4e, 0x43, 0x6a, 0x77, 0x35, 0x73, 0x57, 0x69,
+    0x2b, 0x65, 0x32, 0x32, 0x4a, 0x4c, 0x75, 0x6d, 0x7a, 0x43, 0x65, 0x63,
+    0x59, 0x56, 0x34, 0x32, 0x46, 0x6d, 0x68, 0x66, 0x7a, 0x0a, 0x64, 0x6b,
+    0x4a, 0x51, 0x45, 0x77, 0x2f, 0x48, 0x6b, 0x47, 0x38, 0x7a, 0x72, 0x63,
+    0x56, 0x4a, 0x59, 0x43, 0x74, 0x73, 0x53, 0x56, 0x67, 0x5a, 0x31, 0x4f,
+    0x4b, 0x2b, 0x74, 0x37, 0x2b, 0x72, 0x53, 0x62, 0x79, 0x55, 0x79, 0x4b,
+    0x75, 0x2b, 0x4b, 0x47, 0x77, 0x57, 0x61, 0x4f, 0x44, 0x49, 0x6c, 0x30,
+    0x59, 0x67, 0x6f, 0x47, 0x68, 0x6e, 0x59, 0x49, 0x67, 0x35, 0x49, 0x46,
+    0x48, 0x59, 0x0a, 0x61, 0x41, 0x45, 0x52, 0x7a, 0x71, 0x66, 0x32, 0x45,
+    0x51, 0x66, 0x32, 0x37, 0x4f, 0x79, 0x73, 0x47, 0x68, 0x2b, 0x79, 0x5a,
+    0x6d, 0x35, 0x57, 0x5a, 0x32, 0x42, 0x36, 0x64, 0x46, 0x37, 0x41, 0x62,
+    0x5a, 0x63, 0x32, 0x72, 0x72, 0x55, 0x4e, 0x58, 0x57, 0x5a, 0x7a, 0x77,
+    0x43, 0x55, 0x79, 0x52, 0x64, 0x68, 0x4b, 0x42, 0x67, 0x65, 0x50, 0x78,
+    0x4c, 0x63, 0x48, 0x73, 0x55, 0x30, 0x47, 0x0a, 0x44, 0x65, 0x47, 0x6c,
+    0x36, 0x2f, 0x52, 0x31, 0x79, 0x72, 0x71, 0x63, 0x30, 0x4c, 0x32, 0x7a,
+    0x30, 0x7a, 0x49, 0x6b, 0x54, 0x4f, 0x35, 0x2b, 0x34, 0x6e, 0x59, 0x45,
+    0x53, 0x30, 0x6c, 0x54, 0x32, 0x50, 0x4c, 0x70, 0x56, 0x44, 0x50, 0x38,
+    0x35, 0x58, 0x45, 0x66, 0x50, 0x52, 0x52, 0x63, 0x6c, 0x6b, 0x76, 0x78,
+    0x4f, 0x76, 0x49, 0x41, 0x75, 0x32, 0x79, 0x30, 0x2b, 0x70, 0x5a, 0x56,
+    0x0a, 0x43, 0x49, 0x67, 0x4a, 0x77, 0x63, 0x79, 0x52, 0x47, 0x53, 0x6d,
+    0x77, 0x49, 0x43, 0x33, 0x2f, 0x79, 0x7a, 0x69, 0x6b, 0x51, 0x4f, 0x45,
+    0x58, 0x76, 0x6e, 0x6c, 0x68, 0x67, 0x50, 0x38, 0x48, 0x41, 0x34, 0x5a,
+    0x4d, 0x54, 0x6e, 0x73, 0x47, 0x6e, 0x78, 0x47, 0x47, 0x6a, 0x59, 0x6e,
+    0x75, 0x4a, 0x38, 0x54, 0x62, 0x34, 0x72, 0x77, 0x5a, 0x6a, 0x67, 0x76,
+    0x44, 0x77, 0x78, 0x50, 0x48, 0x0a, 0x4c, 0x51, 0x4e, 0x6a, 0x4f, 0x39,
+    0x50, 0x6f, 0x35, 0x4b, 0x49, 0x71, 0x77, 0x6f, 0x49, 0x49, 0x6c, 0x42,
+    0x5a, 0x55, 0x38, 0x4f, 0x38, 0x66, 0x4a, 0x35, 0x41, 0x6c, 0x75, 0x41,
+    0x30, 0x4f, 0x4b, 0x42, 0x74, 0x48, 0x64, 0x30, 0x65, 0x39, 0x48, 0x4b,
+    0x67, 0x6c, 0x38, 0x5a, 0x53, 0x30, 0x5a, 0x67, 0x3d, 0x3d, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20,
+    0x43, 0x4e, 0x3d, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20,
+    0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f, 0x3d, 0x47, 0x6f,
+    0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64,
+    0x64, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f,
+    0x3d, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62,
+    0x65, 0x6c, 0x3a, 0x20, 0x22, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64,
+    0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x22, 0x0a, 0x23,
+    0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x30, 0x0a, 0x23,
+    0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x30, 0x3a, 0x33, 0x61, 0x3a,
+    0x62, 0x63, 0x3a, 0x32, 0x32, 0x3a, 0x63, 0x31, 0x3a, 0x65, 0x36, 0x3a,
+    0x66, 0x62, 0x3a, 0x38, 0x64, 0x3a, 0x39, 0x62, 0x3a, 0x33, 0x62, 0x3a,
+    0x32, 0x37, 0x3a, 0x34, 0x61, 0x3a, 0x33, 0x32, 0x3a, 0x31, 0x62, 0x3a,
+    0x39, 0x61, 0x3a, 0x30, 0x31, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31,
+    0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
+    0x3a, 0x20, 0x34, 0x37, 0x3a, 0x62, 0x65, 0x3a, 0x61, 0x62, 0x3a, 0x63,
+    0x39, 0x3a, 0x32, 0x32, 0x3a, 0x65, 0x61, 0x3a, 0x65, 0x38, 0x3a, 0x30,
+    0x65, 0x3a, 0x37, 0x38, 0x3a, 0x37, 0x38, 0x3a, 0x33, 0x34, 0x3a, 0x36,
+    0x32, 0x3a, 0x61, 0x37, 0x3a, 0x39, 0x66, 0x3a, 0x34, 0x35, 0x3a, 0x63,
+    0x32, 0x3a, 0x35, 0x34, 0x3a, 0x66, 0x64, 0x3a, 0x65, 0x36, 0x3a, 0x38,
+    0x62, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x34, 0x35, 0x3a, 0x31, 0x34, 0x3a, 0x30, 0x62, 0x3a, 0x33, 0x32, 0x3a,
+    0x34, 0x37, 0x3a, 0x65, 0x62, 0x3a, 0x39, 0x63, 0x3a, 0x63, 0x38, 0x3a,
+    0x63, 0x35, 0x3a, 0x62, 0x34, 0x3a, 0x66, 0x30, 0x3a, 0x64, 0x37, 0x3a,
+    0x62, 0x35, 0x3a, 0x33, 0x30, 0x3a, 0x39, 0x31, 0x3a, 0x66, 0x37, 0x3a,
+    0x33, 0x32, 0x3a, 0x39, 0x32, 0x3a, 0x30, 0x38, 0x3a, 0x39, 0x65, 0x3a,
+    0x36, 0x65, 0x3a, 0x35, 0x61, 0x3a, 0x36, 0x33, 0x3a, 0x65, 0x32, 0x3a,
+    0x37, 0x34, 0x3a, 0x39, 0x64, 0x3a, 0x64, 0x33, 0x3a, 0x61, 0x63, 0x3a,
+    0x61, 0x39, 0x3a, 0x31, 0x39, 0x3a, 0x38, 0x65, 0x3a, 0x64, 0x61, 0x0a,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x78, 0x54, 0x43, 0x43,
+    0x41, 0x71, 0x32, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
+    0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42,
+    0x67, 0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x0a, 0x45, 0x44, 0x41,
+    0x4f, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x54, 0x42, 0x30, 0x46,
+    0x79, 0x61, 0x58, 0x70, 0x76, 0x62, 0x6d, 0x45, 0x78, 0x45, 0x7a, 0x41,
+    0x52, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x6c, 0x4e,
+    0x6a, 0x62, 0x33, 0x52, 0x30, 0x63, 0x32, 0x52, 0x68, 0x62, 0x47, 0x55,
+    0x78, 0x47, 0x6a, 0x41, 0x59, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f,
+    0x54, 0x0a, 0x45, 0x55, 0x64, 0x76, 0x52, 0x47, 0x46, 0x6b, 0x5a, 0x48,
+    0x6b, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x43, 0x42, 0x4a, 0x62, 0x6d,
+    0x4d, 0x75, 0x4d, 0x54, 0x45, 0x77, 0x4c, 0x77, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x44, 0x45, 0x79, 0x68, 0x48, 0x62, 0x79, 0x42, 0x45, 0x59, 0x57,
+    0x52, 0x6b, 0x65, 0x53, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30, 0x49, 0x45,
+    0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x0a, 0x5a, 0x6d, 0x6c, 0x6a, 0x59,
+    0x58, 0x52, 0x6c, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63,
+    0x6d, 0x6c, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x79, 0x4d,
+    0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x35, 0x4d, 0x44, 0x6b, 0x77, 0x4d,
+    0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f, 0x58, 0x44,
+    0x54, 0x4d, 0x33, 0x4d, 0x54, 0x49, 0x7a, 0x4d, 0x54, 0x49, 0x7a, 0x0a,
+    0x4e, 0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x67, 0x59, 0x4d, 0x78,
+    0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54,
+    0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x49, 0x45, 0x77, 0x64, 0x42, 0x63, 0x6d, 0x6c, 0x36,
+    0x62, 0x32, 0x35, 0x68, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x48, 0x0a, 0x45, 0x77, 0x70, 0x54, 0x59, 0x32, 0x39,
+    0x30, 0x64, 0x48, 0x4e, 0x6b, 0x59, 0x57, 0x78, 0x6c, 0x4d, 0x52, 0x6f,
+    0x77, 0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x46,
+    0x48, 0x62, 0x30, 0x52, 0x68, 0x5a, 0x47, 0x52, 0x35, 0x4c, 0x6d, 0x4e,
+    0x76, 0x62, 0x53, 0x77, 0x67, 0x53, 0x57, 0x35, 0x6a, 0x4c, 0x6a, 0x45,
+    0x78, 0x4d, 0x43, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x41, 0x78,
+    0x4d, 0x6f, 0x52, 0x32, 0x38, 0x67, 0x52, 0x47, 0x46, 0x6b, 0x5a, 0x48,
+    0x6b, 0x67, 0x55, 0x6d, 0x39, 0x76, 0x64, 0x43, 0x42, 0x44, 0x5a, 0x58,
+    0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x5a, 0x53,
+    0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48,
+    0x6b, 0x67, 0x4c, 0x53, 0x42, 0x48, 0x4d, 0x6a, 0x43, 0x43, 0x41, 0x53,
+    0x49, 0x77, 0x0a, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68,
+    0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67,
+    0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67,
+    0x67, 0x45, 0x42, 0x41, 0x4c, 0x39, 0x78, 0x59, 0x67, 0x6a, 0x78, 0x2b,
+    0x6c, 0x6b, 0x30, 0x39, 0x78, 0x76, 0x4a, 0x47, 0x4b, 0x50, 0x33, 0x67,
+    0x45, 0x6c, 0x59, 0x36, 0x53, 0x4b, 0x44, 0x0a, 0x45, 0x36, 0x62, 0x46,
+    0x49, 0x45, 0x4d, 0x42, 0x4f, 0x34, 0x54, 0x78, 0x35, 0x6f, 0x56, 0x4a,
+    0x6e, 0x79, 0x66, 0x71, 0x39, 0x6f, 0x51, 0x62, 0x54, 0x71, 0x43, 0x30,
+    0x32, 0x33, 0x43, 0x59, 0x78, 0x7a, 0x49, 0x42, 0x73, 0x51, 0x55, 0x2b,
+    0x42, 0x30, 0x37, 0x75, 0x39, 0x50, 0x70, 0x50, 0x4c, 0x31, 0x6b, 0x77,
+    0x49, 0x75, 0x65, 0x72, 0x47, 0x56, 0x5a, 0x72, 0x34, 0x6f, 0x41, 0x48,
+    0x0a, 0x2f, 0x50, 0x4d, 0x57, 0x64, 0x59, 0x41, 0x35, 0x55, 0x58, 0x76,
+    0x6c, 0x2b, 0x54, 0x57, 0x32, 0x64, 0x45, 0x36, 0x70, 0x6a, 0x59, 0x49,
+    0x54, 0x35, 0x4c, 0x59, 0x2f, 0x71, 0x51, 0x4f, 0x44, 0x2b, 0x71, 0x4b,
+    0x2b, 0x69, 0x68, 0x56, 0x71, 0x66, 0x39, 0x34, 0x4c, 0x77, 0x37, 0x59,
+    0x5a, 0x46, 0x41, 0x58, 0x4b, 0x36, 0x73, 0x4f, 0x6f, 0x42, 0x4a, 0x51,
+    0x37, 0x52, 0x6e, 0x77, 0x79, 0x0a, 0x44, 0x66, 0x4d, 0x41, 0x5a, 0x69,
+    0x4c, 0x49, 0x6a, 0x57, 0x6c, 0x74, 0x4e, 0x6f, 0x77, 0x52, 0x47, 0x4c,
+    0x66, 0x54, 0x73, 0x68, 0x78, 0x67, 0x74, 0x44, 0x6a, 0x36, 0x41, 0x6f,
+    0x7a, 0x4f, 0x30, 0x39, 0x31, 0x47, 0x42, 0x39, 0x34, 0x4b, 0x50, 0x75,
+    0x74, 0x64, 0x66, 0x4d, 0x68, 0x38, 0x2b, 0x37, 0x41, 0x72, 0x55, 0x36,
+    0x53, 0x53, 0x59, 0x6d, 0x6c, 0x52, 0x4a, 0x51, 0x56, 0x68, 0x0a, 0x47,
+    0x6b, 0x53, 0x42, 0x6a, 0x43, 0x79, 0x70, 0x51, 0x35, 0x59, 0x6a, 0x33,
+    0x36, 0x77, 0x36, 0x67, 0x5a, 0x6f, 0x4f, 0x4b, 0x63, 0x55, 0x63, 0x71,
+    0x65, 0x6c, 0x64, 0x48, 0x72, 0x61, 0x65, 0x6e, 0x6a, 0x41, 0x4b, 0x4f,
+    0x63, 0x37, 0x78, 0x69, 0x49, 0x44, 0x37, 0x53, 0x31, 0x33, 0x4d, 0x4d,
+    0x75, 0x79, 0x46, 0x59, 0x6b, 0x4d, 0x6c, 0x4e, 0x41, 0x4a, 0x57, 0x4a,
+    0x77, 0x47, 0x52, 0x0a, 0x74, 0x44, 0x74, 0x77, 0x4b, 0x6a, 0x39, 0x75,
+    0x73, 0x65, 0x69, 0x63, 0x69, 0x41, 0x46, 0x39, 0x6e, 0x39, 0x54, 0x35,
+    0x32, 0x31, 0x4e, 0x74, 0x59, 0x4a, 0x32, 0x2f, 0x4c, 0x4f, 0x64, 0x59,
+    0x71, 0x37, 0x68, 0x66, 0x52, 0x76, 0x7a, 0x4f, 0x78, 0x42, 0x73, 0x44,
+    0x50, 0x41, 0x6e, 0x72, 0x53, 0x54, 0x46, 0x63, 0x61, 0x55, 0x61, 0x7a,
+    0x34, 0x45, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, 0x0a, 0x41, 0x61, 0x4e,
+    0x43, 0x4d, 0x45, 0x41, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45,
+    0x42, 0x2f, 0x7a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59,
+    0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59,
+    0x45, 0x0a, 0x46, 0x44, 0x71, 0x61, 0x68, 0x51, 0x63, 0x51, 0x5a, 0x79,
+    0x69, 0x32, 0x37, 0x2f, 0x61, 0x39, 0x42, 0x55, 0x46, 0x75, 0x49, 0x4d,
+    0x47, 0x55, 0x32, 0x67, 0x2f, 0x65, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53,
+    0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77,
+    0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x43, 0x5a, 0x32, 0x31,
+    0x31, 0x35, 0x31, 0x66, 0x6d, 0x58, 0x0a, 0x57, 0x57, 0x63, 0x44, 0x59,
+    0x66, 0x46, 0x2b, 0x4f, 0x77, 0x59, 0x78, 0x64, 0x53, 0x32, 0x68, 0x49,
+    0x49, 0x35, 0x50, 0x5a, 0x59, 0x65, 0x30, 0x39, 0x36, 0x61, 0x63, 0x76,
+    0x4e, 0x6a, 0x70, 0x4c, 0x39, 0x44, 0x62, 0x57, 0x75, 0x37, 0x50, 0x64,
+    0x49, 0x78, 0x7a, 0x74, 0x44, 0x68, 0x43, 0x32, 0x67, 0x56, 0x37, 0x2b,
+    0x41, 0x4a, 0x31, 0x75, 0x50, 0x32, 0x6c, 0x73, 0x64, 0x65, 0x75, 0x0a,
+    0x39, 0x74, 0x66, 0x65, 0x45, 0x38, 0x74, 0x54, 0x45, 0x48, 0x36, 0x4b,
+    0x52, 0x74, 0x47, 0x58, 0x2b, 0x72, 0x63, 0x75, 0x4b, 0x78, 0x47, 0x72,
+    0x6b, 0x4c, 0x41, 0x6e, 0x67, 0x50, 0x6e, 0x6f, 0x6e, 0x31, 0x72, 0x70,
+    0x4e, 0x35, 0x2b, 0x72, 0x35, 0x4e, 0x39, 0x73, 0x73, 0x34, 0x55, 0x58,
+    0x6e, 0x54, 0x33, 0x5a, 0x4a, 0x45, 0x39, 0x35, 0x6b, 0x54, 0x58, 0x57,
+    0x58, 0x77, 0x54, 0x72, 0x0a, 0x67, 0x49, 0x4f, 0x72, 0x6d, 0x67, 0x49,
+    0x74, 0x74, 0x52, 0x44, 0x30, 0x32, 0x4a, 0x44, 0x48, 0x42, 0x48, 0x4e,
+    0x41, 0x37, 0x58, 0x49, 0x6c, 0x6f, 0x4b, 0x6d, 0x66, 0x37, 0x4a, 0x36,
+    0x72, 0x61, 0x42, 0x4b, 0x5a, 0x56, 0x38, 0x61, 0x50, 0x45, 0x6a, 0x6f,
+    0x4a, 0x70, 0x4c, 0x31, 0x45, 0x2f, 0x51, 0x59, 0x56, 0x4e, 0x38, 0x47,
+    0x62, 0x35, 0x44, 0x4b, 0x6a, 0x37, 0x54, 0x6a, 0x6f, 0x0a, 0x32, 0x47,
+    0x54, 0x7a, 0x4c, 0x48, 0x34, 0x55, 0x2f, 0x41, 0x4c, 0x71, 0x6e, 0x38,
+    0x33, 0x2f, 0x42, 0x32, 0x67, 0x58, 0x32, 0x79, 0x4b, 0x51, 0x4f, 0x43,
+    0x31, 0x36, 0x6a, 0x64, 0x46, 0x55, 0x38, 0x57, 0x6e, 0x6a, 0x58, 0x7a,
+    0x50, 0x4b, 0x65, 0x6a, 0x31, 0x37, 0x43, 0x75, 0x50, 0x4b, 0x66, 0x31,
+    0x38, 0x35, 0x35, 0x65, 0x4a, 0x31, 0x75, 0x73, 0x56, 0x32, 0x47, 0x44,
+    0x50, 0x4f, 0x0a, 0x4c, 0x50, 0x41, 0x76, 0x54, 0x4b, 0x33, 0x33, 0x73,
+    0x65, 0x66, 0x4f, 0x54, 0x36, 0x6a, 0x45, 0x6d, 0x30, 0x70, 0x55, 0x42,
+    0x73, 0x56, 0x2f, 0x66, 0x64, 0x55, 0x49, 0x44, 0x2b, 0x49, 0x63, 0x2f,
+    0x6e, 0x34, 0x58, 0x75, 0x4b, 0x78, 0x65, 0x39, 0x74, 0x51, 0x57, 0x73,
+    0x6b, 0x4d, 0x4a, 0x44, 0x45, 0x33, 0x32, 0x70, 0x32, 0x75, 0x30, 0x6d,
+    0x59, 0x52, 0x6c, 0x79, 0x6e, 0x71, 0x49, 0x0a, 0x34, 0x75, 0x4a, 0x45,
+    0x76, 0x6c, 0x7a, 0x33, 0x36, 0x68, 0x7a, 0x31, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x52,
+    0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+    0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f, 0x3d, 0x53, 0x74, 0x61,
+    0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e,
+    0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,
+    0x20, 0x43, 0x4e, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c,
+    0x64, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f, 0x3d,
+    0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65,
+    0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+    0x3a, 0x20, 0x22, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x22, 0x0a, 0x23, 0x20,
+    0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x30, 0x0a, 0x23, 0x20,
+    0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x36, 0x3a, 0x33, 0x39, 0x3a, 0x38,
+    0x31, 0x3a, 0x63, 0x36, 0x3a, 0x35, 0x32, 0x3a, 0x37, 0x65, 0x3a, 0x39,
+    0x36, 0x3a, 0x36, 0x39, 0x3a, 0x66, 0x63, 0x3a, 0x66, 0x63, 0x3a, 0x63,
+    0x61, 0x3a, 0x36, 0x36, 0x3a, 0x65, 0x64, 0x3a, 0x30, 0x35, 0x3a, 0x66,
+    0x32, 0x3a, 0x39, 0x36, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x62, 0x35, 0x3a, 0x31, 0x63, 0x3a, 0x30, 0x36, 0x3a, 0x37, 0x63,
+    0x3a, 0x65, 0x65, 0x3a, 0x32, 0x62, 0x3a, 0x30, 0x63, 0x3a, 0x33, 0x64,
+    0x3a, 0x66, 0x38, 0x3a, 0x35, 0x35, 0x3a, 0x61, 0x62, 0x3a, 0x32, 0x64,
+    0x3a, 0x39, 0x32, 0x3a, 0x66, 0x34, 0x3a, 0x66, 0x65, 0x3a, 0x33, 0x39,
+    0x3a, 0x64, 0x34, 0x3a, 0x65, 0x37, 0x3a, 0x30, 0x66, 0x3a, 0x30, 0x65,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x32,
+    0x63, 0x3a, 0x65, 0x31, 0x3a, 0x63, 0x62, 0x3a, 0x30, 0x62, 0x3a, 0x66,
+    0x39, 0x3a, 0x64, 0x32, 0x3a, 0x66, 0x39, 0x3a, 0x65, 0x31, 0x3a, 0x30,
+    0x32, 0x3a, 0x39, 0x39, 0x3a, 0x33, 0x66, 0x3a, 0x62, 0x65, 0x3a, 0x32,
+    0x31, 0x3a, 0x35, 0x31, 0x3a, 0x35, 0x32, 0x3a, 0x63, 0x33, 0x3a, 0x62,
+    0x32, 0x3a, 0x64, 0x64, 0x3a, 0x30, 0x63, 0x3a, 0x61, 0x62, 0x3a, 0x64,
+    0x65, 0x3a, 0x31, 0x63, 0x3a, 0x36, 0x38, 0x3a, 0x65, 0x35, 0x3a, 0x33,
+    0x31, 0x3a, 0x39, 0x62, 0x3a, 0x38, 0x33, 0x3a, 0x39, 0x31, 0x3a, 0x35,
+    0x34, 0x3a, 0x64, 0x62, 0x3a, 0x62, 0x37, 0x3a, 0x66, 0x35, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x33, 0x54, 0x43, 0x43, 0x41,
+    0x73, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41,
+    0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x6a,
+    0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x0a, 0x45, 0x44, 0x41, 0x4f,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x54, 0x42, 0x30, 0x46, 0x79,
+    0x61, 0x58, 0x70, 0x76, 0x62, 0x6d, 0x45, 0x78, 0x45, 0x7a, 0x41, 0x52,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x6c, 0x4e, 0x6a,
+    0x62, 0x33, 0x52, 0x30, 0x63, 0x32, 0x52, 0x68, 0x62, 0x47, 0x55, 0x78,
+    0x4a, 0x54, 0x41, 0x6a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54,
+    0x0a, 0x48, 0x46, 0x4e, 0x30, 0x59, 0x58, 0x4a, 0x6d, 0x61, 0x57, 0x56,
+    0x73, 0x5a, 0x43, 0x42, 0x55, 0x5a, 0x57, 0x4e, 0x6f, 0x62, 0x6d, 0x39,
+    0x73, 0x62, 0x32, 0x64, 0x70, 0x5a, 0x58, 0x4d, 0x73, 0x49, 0x45, 0x6c,
+    0x75, 0x59, 0x79, 0x34, 0x78, 0x4d, 0x6a, 0x41, 0x77, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x4d, 0x54, 0x4b, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x4a,
+    0x6d, 0x61, 0x57, 0x56, 0x73, 0x0a, 0x5a, 0x43, 0x42, 0x53, 0x62, 0x32,
+    0x39, 0x30, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d,
+    0x6c, 0x6a, 0x59, 0x58, 0x52, 0x6c, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47,
+    0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45,
+    0x63, 0x79, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x35, 0x4d, 0x44,
+    0x6b, 0x77, 0x4d, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x0a, 0x4d,
+    0x46, 0x6f, 0x58, 0x44, 0x54, 0x4d, 0x33, 0x4d, 0x54, 0x49, 0x7a, 0x4d,
+    0x54, 0x49, 0x7a, 0x4e, 0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x67,
+    0x59, 0x38, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x41, 0x77, 0x44,
+    0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x45, 0x77, 0x64, 0x42, 0x63,
+    0x6d, 0x6c, 0x36, 0x0a, 0x62, 0x32, 0x35, 0x68, 0x4d, 0x52, 0x4d, 0x77,
+    0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x70, 0x54,
+    0x59, 0x32, 0x39, 0x30, 0x64, 0x48, 0x4e, 0x6b, 0x59, 0x57, 0x78, 0x6c,
+    0x4d, 0x53, 0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b,
+    0x45, 0x78, 0x78, 0x54, 0x64, 0x47, 0x46, 0x79, 0x5a, 0x6d, 0x6c, 0x6c,
+    0x62, 0x47, 0x51, 0x67, 0x56, 0x47, 0x56, 0x6a, 0x0a, 0x61, 0x47, 0x35,
+    0x76, 0x62, 0x47, 0x39, 0x6e, 0x61, 0x57, 0x56, 0x7a, 0x4c, 0x43, 0x42,
+    0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x54, 0x49, 0x77, 0x4d, 0x41, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x79, 0x6c, 0x54, 0x64, 0x47, 0x46,
+    0x79, 0x5a, 0x6d, 0x6c, 0x6c, 0x62, 0x47, 0x51, 0x67, 0x55, 0x6d, 0x39,
+    0x76, 0x64, 0x43, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a,
+    0x70, 0x0a, 0x59, 0x32, 0x46, 0x30, 0x5a, 0x53, 0x42, 0x42, 0x64, 0x58,
+    0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x4c, 0x53,
+    0x42, 0x48, 0x4d, 0x6a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51,
+    0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51,
+    0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44,
+    0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x0a, 0x67, 0x67, 0x45, 0x42, 0x41,
+    0x4c, 0x33, 0x74, 0x77, 0x51, 0x50, 0x38, 0x39, 0x6f, 0x2f, 0x38, 0x41,
+    0x72, 0x46, 0x76, 0x57, 0x35, 0x39, 0x49, 0x32, 0x5a, 0x31, 0x35, 0x34,
+    0x71, 0x4b, 0x33, 0x41, 0x32, 0x46, 0x57, 0x47, 0x4d, 0x4e, 0x48, 0x74,
+    0x74, 0x66, 0x4b, 0x50, 0x54, 0x55, 0x75, 0x69, 0x55, 0x50, 0x33, 0x6f,
+    0x57, 0x6d, 0x62, 0x33, 0x6f, 0x6f, 0x61, 0x2f, 0x52, 0x4d, 0x67, 0x0a,
+    0x6e, 0x4c, 0x52, 0x4a, 0x64, 0x7a, 0x49, 0x70, 0x56, 0x76, 0x32, 0x35,
+    0x37, 0x49, 0x7a, 0x64, 0x49, 0x76, 0x70, 0x79, 0x33, 0x43, 0x64, 0x68,
+    0x6c, 0x2b, 0x37, 0x32, 0x57, 0x6f, 0x54, 0x73, 0x62, 0x68, 0x6d, 0x35,
+    0x69, 0x53, 0x7a, 0x63, 0x68, 0x46, 0x76, 0x56, 0x64, 0x50, 0x74, 0x72,
+    0x58, 0x38, 0x57, 0x4a, 0x70, 0x52, 0x42, 0x53, 0x69, 0x55, 0x5a, 0x56,
+    0x39, 0x4c, 0x68, 0x31, 0x0a, 0x48, 0x4f, 0x5a, 0x2f, 0x35, 0x46, 0x53,
+    0x75, 0x53, 0x2f, 0x68, 0x56, 0x63, 0x6c, 0x63, 0x43, 0x47, 0x66, 0x67,
+    0x58, 0x63, 0x56, 0x6e, 0x72, 0x48, 0x69, 0x67, 0x48, 0x64, 0x4d, 0x57,
+    0x64, 0x53, 0x4c, 0x35, 0x73, 0x74, 0x50, 0x53, 0x6b, 0x73, 0x50, 0x4e,
+    0x6b, 0x4e, 0x33, 0x6d, 0x53, 0x77, 0x4f, 0x78, 0x47, 0x58, 0x6e, 0x2f,
+    0x68, 0x62, 0x56, 0x4e, 0x4d, 0x59, 0x71, 0x2f, 0x4e, 0x0a, 0x48, 0x77,
+    0x74, 0x6a, 0x75, 0x7a, 0x71, 0x64, 0x2b, 0x2f, 0x78, 0x35, 0x41, 0x4a,
+    0x68, 0x68, 0x64, 0x4d, 0x38, 0x6d, 0x67, 0x6b, 0x42, 0x6a, 0x38, 0x37,
+    0x4a, 0x79, 0x61, 0x68, 0x6b, 0x4e, 0x6d, 0x63, 0x72, 0x55, 0x44, 0x6e,
+    0x58, 0x4d, 0x4e, 0x2f, 0x75, 0x4c, 0x69, 0x63, 0x46, 0x5a, 0x38, 0x57,
+    0x4a, 0x2f, 0x58, 0x37, 0x4e, 0x66, 0x5a, 0x54, 0x44, 0x34, 0x70, 0x37,
+    0x64, 0x4e, 0x0a, 0x64, 0x6c, 0x6f, 0x65, 0x64, 0x6c, 0x34, 0x30, 0x77,
+    0x4f, 0x69, 0x57, 0x56, 0x70, 0x6d, 0x4b, 0x73, 0x2f, 0x42, 0x2f, 0x70,
+    0x4d, 0x32, 0x39, 0x33, 0x44, 0x49, 0x78, 0x66, 0x4a, 0x48, 0x50, 0x34,
+    0x46, 0x38, 0x52, 0x2b, 0x47, 0x75, 0x71, 0x53, 0x56, 0x7a, 0x52, 0x6d,
+    0x5a, 0x54, 0x52, 0x6f, 0x75, 0x4e, 0x6a, 0x57, 0x77, 0x6c, 0x32, 0x74,
+    0x56, 0x5a, 0x69, 0x34, 0x55, 0x74, 0x30, 0x0a, 0x48, 0x5a, 0x62, 0x55,
+    0x4a, 0x74, 0x51, 0x49, 0x42, 0x46, 0x6e, 0x51, 0x6d, 0x41, 0x34, 0x4f,
+    0x35, 0x74, 0x37, 0x38, 0x77, 0x2b, 0x77, 0x66, 0x6b, 0x50, 0x45, 0x43,
+    0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4e, 0x43, 0x4d, 0x45, 0x41, 0x77,
+    0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f,
+    0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41, 0x4f,
+    0x0a, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38,
+    0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, 0x51, 0x59,
+    0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x48, 0x77,
+    0x4d, 0x4d, 0x68, 0x2b, 0x6e, 0x32, 0x54, 0x42, 0x2f, 0x78, 0x48, 0x31,
+    0x6f, 0x6f, 0x32, 0x4b, 0x6f, 0x6f, 0x63, 0x36, 0x72, 0x42, 0x31, 0x73,
+    0x6e, 0x4d, 0x41, 0x30, 0x47, 0x0a, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
+    0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34,
+    0x49, 0x42, 0x41, 0x51, 0x41, 0x52, 0x57, 0x66, 0x6f, 0x6c, 0x54, 0x77,
+    0x4e, 0x76, 0x6c, 0x4a, 0x6b, 0x37, 0x6d, 0x68, 0x2b, 0x43, 0x68, 0x54,
+    0x6e, 0x55, 0x64, 0x67, 0x57, 0x55, 0x58, 0x75, 0x45, 0x6f, 0x6b, 0x32,
+    0x31, 0x69, 0x58, 0x51, 0x6e, 0x43, 0x6f, 0x4b, 0x6a, 0x55, 0x0a, 0x73,
+    0x48, 0x55, 0x34, 0x38, 0x54, 0x52, 0x71, 0x6e, 0x65, 0x53, 0x66, 0x69,
+    0x6f, 0x59, 0x6d, 0x55, 0x65, 0x59, 0x73, 0x30, 0x63, 0x59, 0x74, 0x62,
+    0x70, 0x55, 0x67, 0x53, 0x70, 0x49, 0x42, 0x37, 0x4c, 0x69, 0x4b, 0x5a,
+    0x33, 0x73, 0x78, 0x34, 0x6d, 0x63, 0x75, 0x6a, 0x4a, 0x55, 0x44, 0x4a,
+    0x69, 0x35, 0x44, 0x6e, 0x55, 0x6f, 0x78, 0x39, 0x67, 0x36, 0x31, 0x44,
+    0x4c, 0x75, 0x33, 0x0a, 0x34, 0x6a, 0x64, 0x2f, 0x49, 0x72, 0x6f, 0x41,
+    0x6f, 0x77, 0x35, 0x37, 0x55, 0x76, 0x74, 0x72, 0x75, 0x7a, 0x76, 0x45,
+    0x30, 0x33, 0x6c, 0x52, 0x54, 0x73, 0x32, 0x51, 0x39, 0x47, 0x63, 0x48,
+    0x47, 0x63, 0x67, 0x38, 0x52, 0x6e, 0x6f, 0x4e, 0x41, 0x58, 0x33, 0x46,
+    0x57, 0x4f, 0x64, 0x74, 0x35, 0x6f, 0x55, 0x77, 0x46, 0x35, 0x6f, 0x6b,
+    0x78, 0x42, 0x44, 0x67, 0x42, 0x50, 0x66, 0x67, 0x0a, 0x38, 0x6e, 0x2f,
+    0x55, 0x71, 0x67, 0x72, 0x2f, 0x51, 0x68, 0x30, 0x33, 0x37, 0x5a, 0x54,
+    0x6c, 0x5a, 0x46, 0x6b, 0x53, 0x49, 0x48, 0x63, 0x34, 0x30, 0x7a, 0x49,
+    0x2b, 0x4f, 0x49, 0x46, 0x31, 0x6c, 0x6e, 0x50, 0x36, 0x61, 0x49, 0x2b,
+    0x78, 0x79, 0x38, 0x34, 0x66, 0x78, 0x65, 0x7a, 0x36, 0x6e, 0x48, 0x37,
+    0x50, 0x66, 0x72, 0x48, 0x78, 0x42, 0x79, 0x32, 0x32, 0x2f, 0x4c, 0x2f,
+    0x4b, 0x0a, 0x70, 0x4c, 0x2f, 0x51, 0x6c, 0x77, 0x56, 0x4b, 0x76, 0x4f,
+    0x6f, 0x59, 0x4b, 0x41, 0x4b, 0x51, 0x76, 0x56, 0x52, 0x34, 0x43, 0x53,
+    0x46, 0x78, 0x30, 0x39, 0x46, 0x39, 0x48, 0x64, 0x6b, 0x57, 0x73, 0x4b,
+    0x6c, 0x68, 0x50, 0x64, 0x41, 0x4b, 0x41, 0x43, 0x4c, 0x38, 0x78, 0x33,
+    0x76, 0x4c, 0x43, 0x57, 0x52, 0x46, 0x43, 0x7a, 0x74, 0x41, 0x67, 0x66,
+    0x64, 0x39, 0x66, 0x44, 0x4c, 0x31, 0x0a, 0x6d, 0x4d, 0x70, 0x59, 0x6a,
+    0x6e, 0x30, 0x71, 0x37, 0x70, 0x42, 0x5a, 0x63, 0x32, 0x54, 0x35, 0x4e,
+    0x6e, 0x52, 0x65, 0x4a, 0x61, 0x48, 0x31, 0x5a, 0x67, 0x55, 0x75, 0x66,
+    0x7a, 0x6b, 0x56, 0x71, 0x53, 0x72, 0x37, 0x55, 0x49, 0x75, 0x4f, 0x68,
+    0x57, 0x6e, 0x30, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73,
+    0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x53, 0x74, 0x61, 0x72,
+    0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+    0x65, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f,
+    0x3d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54,
+    0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a,
+    0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x53, 0x74, 0x61, 0x72,
+    0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+    0x65, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x20, 0x4f,
+    0x3d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54,
+    0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65,
+    0x6c, 0x3a, 0x20, 0x22, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c,
+    0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52,
+    0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+    0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65,
+    0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x30, 0x0a, 0x23, 0x20, 0x4d, 0x44,
+    0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x31, 0x37, 0x3a, 0x33, 0x35, 0x3a, 0x37, 0x34, 0x3a,
+    0x61, 0x66, 0x3a, 0x37, 0x62, 0x3a, 0x36, 0x31, 0x3a, 0x31, 0x63, 0x3a,
+    0x65, 0x62, 0x3a, 0x66, 0x34, 0x3a, 0x66, 0x39, 0x3a, 0x33, 0x63, 0x3a,
+    0x65, 0x32, 0x3a, 0x65, 0x65, 0x3a, 0x34, 0x30, 0x3a, 0x66, 0x39, 0x3a,
+    0x61, 0x32, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x39,
+    0x32, 0x3a, 0x35, 0x61, 0x3a, 0x38, 0x66, 0x3a, 0x38, 0x64, 0x3a, 0x32,
+    0x63, 0x3a, 0x36, 0x64, 0x3a, 0x30, 0x34, 0x3a, 0x65, 0x30, 0x3a, 0x36,
+    0x36, 0x3a, 0x35, 0x66, 0x3a, 0x35, 0x39, 0x3a, 0x36, 0x61, 0x3a, 0x66,
+    0x66, 0x3a, 0x32, 0x32, 0x3a, 0x64, 0x38, 0x3a, 0x36, 0x33, 0x3a, 0x65,
+    0x38, 0x3a, 0x32, 0x35, 0x3a, 0x36, 0x66, 0x3a, 0x33, 0x66, 0x0a, 0x23,
+    0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x35, 0x36, 0x3a,
+    0x38, 0x64, 0x3a, 0x36, 0x39, 0x3a, 0x30, 0x35, 0x3a, 0x61, 0x32, 0x3a,
+    0x63, 0x38, 0x3a, 0x38, 0x37, 0x3a, 0x30, 0x38, 0x3a, 0x61, 0x34, 0x3a,
+    0x62, 0x33, 0x3a, 0x30, 0x32, 0x3a, 0x35, 0x31, 0x3a, 0x39, 0x30, 0x3a,
+    0x65, 0x64, 0x3a, 0x63, 0x66, 0x3a, 0x65, 0x64, 0x3a, 0x62, 0x31, 0x3a,
+    0x39, 0x37, 0x3a, 0x34, 0x61, 0x3a, 0x36, 0x30, 0x3a, 0x36, 0x61, 0x3a,
+    0x31, 0x33, 0x3a, 0x63, 0x36, 0x3a, 0x65, 0x35, 0x3a, 0x32, 0x39, 0x3a,
+    0x30, 0x66, 0x3a, 0x63, 0x62, 0x3a, 0x32, 0x61, 0x3a, 0x65, 0x36, 0x3a,
+    0x33, 0x65, 0x3a, 0x64, 0x61, 0x3a, 0x62, 0x35, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x4d, 0x49, 0x49, 0x44, 0x37, 0x7a, 0x43, 0x43, 0x41, 0x74, 0x65,
+    0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x43, 0x42, 0x6d, 0x44, 0x45,
+    0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d,
+    0x43, 0x56, 0x56, 0x4d, 0x78, 0x0a, 0x45, 0x44, 0x41, 0x4f, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x67, 0x54, 0x42, 0x30, 0x46, 0x79, 0x61, 0x58,
+    0x70, 0x76, 0x62, 0x6d, 0x45, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x63, 0x54, 0x43, 0x6c, 0x4e, 0x6a, 0x62, 0x33,
+    0x52, 0x30, 0x63, 0x32, 0x52, 0x68, 0x62, 0x47, 0x55, 0x78, 0x4a, 0x54,
+    0x41, 0x6a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x0a, 0x48,
+    0x46, 0x4e, 0x30, 0x59, 0x58, 0x4a, 0x6d, 0x61, 0x57, 0x56, 0x73, 0x5a,
+    0x43, 0x42, 0x55, 0x5a, 0x57, 0x4e, 0x6f, 0x62, 0x6d, 0x39, 0x73, 0x62,
+    0x32, 0x64, 0x70, 0x5a, 0x58, 0x4d, 0x73, 0x49, 0x45, 0x6c, 0x75, 0x59,
+    0x79, 0x34, 0x78, 0x4f, 0x7a, 0x41, 0x35, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x4d, 0x54, 0x4d, 0x6c, 0x4e, 0x30, 0x59, 0x58, 0x4a, 0x6d, 0x61,
+    0x57, 0x56, 0x73, 0x0a, 0x5a, 0x43, 0x42, 0x54, 0x5a, 0x58, 0x4a, 0x32,
+    0x61, 0x57, 0x4e, 0x6c, 0x63, 0x79, 0x42, 0x53, 0x62, 0x32, 0x39, 0x30,
+    0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a, 0x6d, 0x6c, 0x6a,
+    0x59, 0x58, 0x52, 0x6c, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76,
+    0x63, 0x6d, 0x6c, 0x30, 0x65, 0x53, 0x41, 0x74, 0x49, 0x45, 0x63, 0x79,
+    0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x41, 0x35, 0x0a, 0x4d, 0x44, 0x6b,
+    0x77, 0x4d, 0x54, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x46, 0x6f,
+    0x58, 0x44, 0x54, 0x4d, 0x33, 0x4d, 0x54, 0x49, 0x7a, 0x4d, 0x54, 0x49,
+    0x7a, 0x4e, 0x54, 0x6b, 0x31, 0x4f, 0x56, 0x6f, 0x77, 0x67, 0x5a, 0x67,
+    0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59,
+    0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59,
+    0x44, 0x0a, 0x56, 0x51, 0x51, 0x49, 0x45, 0x77, 0x64, 0x42, 0x63, 0x6d,
+    0x6c, 0x36, 0x62, 0x32, 0x35, 0x68, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x45, 0x77, 0x70, 0x54, 0x59, 0x32,
+    0x39, 0x30, 0x64, 0x48, 0x4e, 0x6b, 0x59, 0x57, 0x78, 0x6c, 0x4d, 0x53,
+    0x55, 0x77, 0x49, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78,
+    0x78, 0x54, 0x64, 0x47, 0x46, 0x79, 0x0a, 0x5a, 0x6d, 0x6c, 0x6c, 0x62,
+    0x47, 0x51, 0x67, 0x56, 0x47, 0x56, 0x6a, 0x61, 0x47, 0x35, 0x76, 0x62,
+    0x47, 0x39, 0x6e, 0x61, 0x57, 0x56, 0x7a, 0x4c, 0x43, 0x42, 0x4a, 0x62,
+    0x6d, 0x4d, 0x75, 0x4d, 0x54, 0x73, 0x77, 0x4f, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x44, 0x45, 0x7a, 0x4a, 0x54, 0x64, 0x47, 0x46, 0x79, 0x5a,
+    0x6d, 0x6c, 0x6c, 0x62, 0x47, 0x51, 0x67, 0x55, 0x32, 0x56, 0x79, 0x0a,
+    0x64, 0x6d, 0x6c, 0x6a, 0x5a, 0x58, 0x4d, 0x67, 0x55, 0x6d, 0x39, 0x76,
+    0x64, 0x43, 0x42, 0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70,
+    0x59, 0x32, 0x46, 0x30, 0x5a, 0x53, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f,
+    0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b, 0x67, 0x4c, 0x53, 0x42, 0x48,
+    0x4d, 0x6a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a,
+    0x4b, 0x6f, 0x5a, 0x49, 0x0a, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45,
+    0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43,
+    0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4e, 0x55,
+    0x4d, 0x4f, 0x73, 0x51, 0x71, 0x2b, 0x55, 0x37, 0x69, 0x39, 0x62, 0x34,
+    0x5a, 0x6c, 0x31, 0x2b, 0x4f, 0x69, 0x46, 0x4f, 0x78, 0x48, 0x7a, 0x2f,
+    0x4c, 0x7a, 0x35, 0x38, 0x67, 0x45, 0x32, 0x30, 0x70, 0x0a, 0x4f, 0x73,
+    0x67, 0x50, 0x66, 0x54, 0x7a, 0x33, 0x61, 0x33, 0x59, 0x34, 0x59, 0x39,
+    0x6b, 0x32, 0x59, 0x4b, 0x69, 0x62, 0x58, 0x6c, 0x77, 0x41, 0x67, 0x4c,
+    0x49, 0x76, 0x57, 0x58, 0x2f, 0x32, 0x68, 0x2f, 0x6b, 0x6c, 0x51, 0x34,
+    0x62, 0x6e, 0x61, 0x52, 0x74, 0x53, 0x6d, 0x70, 0x44, 0x68, 0x63, 0x65,
+    0x50, 0x59, 0x4c, 0x51, 0x31, 0x4f, 0x62, 0x2f, 0x62, 0x49, 0x53, 0x64,
+    0x6d, 0x32, 0x0a, 0x38, 0x78, 0x70, 0x57, 0x72, 0x69, 0x75, 0x32, 0x64,
+    0x42, 0x54, 0x72, 0x7a, 0x2f, 0x73, 0x6d, 0x34, 0x78, 0x71, 0x36, 0x48,
+    0x5a, 0x59, 0x75, 0x61, 0x6a, 0x74, 0x59, 0x6c, 0x49, 0x6c, 0x48, 0x56,
+    0x76, 0x38, 0x6c, 0x6f, 0x4a, 0x4e, 0x77, 0x55, 0x34, 0x50, 0x61, 0x68,
+    0x48, 0x51, 0x55, 0x77, 0x32, 0x65, 0x65, 0x42, 0x47, 0x67, 0x36, 0x33,
+    0x34, 0x35, 0x41, 0x57, 0x68, 0x31, 0x4b, 0x0a, 0x54, 0x73, 0x39, 0x44,
+    0x6b, 0x54, 0x76, 0x6e, 0x56, 0x74, 0x59, 0x41, 0x63, 0x4d, 0x74, 0x53,
+    0x37, 0x6e, 0x74, 0x39, 0x72, 0x6a, 0x72, 0x6e, 0x76, 0x44, 0x48, 0x35,
+    0x52, 0x66, 0x62, 0x43, 0x59, 0x4d, 0x38, 0x54, 0x57, 0x51, 0x49, 0x72,
+    0x67, 0x4d, 0x77, 0x30, 0x52, 0x39, 0x2b, 0x35, 0x33, 0x70, 0x42, 0x6c,
+    0x62, 0x51, 0x4c, 0x50, 0x4c, 0x4a, 0x47, 0x6d, 0x70, 0x75, 0x66, 0x65,
+    0x0a, 0x68, 0x52, 0x68, 0x4a, 0x66, 0x47, 0x5a, 0x4f, 0x6f, 0x7a, 0x70,
+    0x74, 0x71, 0x62, 0x58, 0x75, 0x4e, 0x43, 0x36, 0x36, 0x44, 0x51, 0x4f,
+    0x34, 0x4d, 0x39, 0x39, 0x48, 0x36, 0x37, 0x46, 0x72, 0x6a, 0x53, 0x58,
+    0x5a, 0x6d, 0x38, 0x36, 0x42, 0x30, 0x55, 0x56, 0x47, 0x4d, 0x70, 0x5a,
+    0x77, 0x68, 0x39, 0x34, 0x43, 0x44, 0x6b, 0x6c, 0x44, 0x68, 0x62, 0x5a,
+    0x73, 0x63, 0x37, 0x74, 0x6b, 0x0a, 0x36, 0x6d, 0x46, 0x42, 0x72, 0x4d,
+    0x6e, 0x55, 0x56, 0x4e, 0x2b, 0x48, 0x4c, 0x38, 0x63, 0x69, 0x73, 0x69,
+    0x62, 0x4d, 0x6e, 0x31, 0x6c, 0x55, 0x61, 0x4a, 0x2f, 0x38, 0x76, 0x69,
+    0x6f, 0x76, 0x78, 0x46, 0x55, 0x63, 0x64, 0x55, 0x42, 0x67, 0x46, 0x34,
+    0x55, 0x43, 0x56, 0x54, 0x6d, 0x4c, 0x66, 0x77, 0x55, 0x43, 0x41, 0x77,
+    0x45, 0x41, 0x41, 0x61, 0x4e, 0x43, 0x4d, 0x45, 0x41, 0x77, 0x0a, 0x44,
+    0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42,
+    0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41, 0x4f, 0x42,
+    0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42,
+    0x41, 0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x4a, 0x78, 0x66, 0x41,
+    0x4e, 0x2b, 0x71, 0x0a, 0x41, 0x64, 0x63, 0x77, 0x4b, 0x7a, 0x69, 0x49,
+    0x6f, 0x72, 0x68, 0x74, 0x53, 0x70, 0x7a, 0x79, 0x45, 0x5a, 0x47, 0x44,
+    0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42,
+    0x41, 0x51, 0x42, 0x4c, 0x4e, 0x71, 0x61, 0x45, 0x64, 0x32, 0x6e, 0x64,
+    0x4f, 0x78, 0x6d, 0x66, 0x5a, 0x79, 0x4d, 0x49, 0x0a, 0x62, 0x77, 0x35,
+    0x68, 0x79, 0x66, 0x32, 0x45, 0x33, 0x46, 0x2f, 0x59, 0x4e, 0x6f, 0x48,
+    0x4e, 0x32, 0x42, 0x74, 0x42, 0x4c, 0x5a, 0x39, 0x67, 0x33, 0x63, 0x63,
+    0x61, 0x61, 0x4e, 0x6e, 0x52, 0x62, 0x6f, 0x62, 0x68, 0x69, 0x43, 0x50,
+    0x50, 0x45, 0x39, 0x35, 0x44, 0x7a, 0x2b, 0x49, 0x30, 0x73, 0x77, 0x53,
+    0x64, 0x48, 0x79, 0x6e, 0x56, 0x76, 0x2f, 0x68, 0x65, 0x79, 0x4e, 0x58,
+    0x42, 0x0a, 0x76, 0x65, 0x36, 0x53, 0x62, 0x7a, 0x4a, 0x30, 0x38, 0x70,
+    0x47, 0x43, 0x4c, 0x37, 0x32, 0x43, 0x51, 0x6e, 0x71, 0x74, 0x4b, 0x72,
+    0x63, 0x67, 0x66, 0x55, 0x32, 0x38, 0x65, 0x6c, 0x55, 0x53, 0x77, 0x68,
+    0x58, 0x71, 0x76, 0x66, 0x64, 0x71, 0x6c, 0x53, 0x35, 0x73, 0x64, 0x4a,
+    0x2f, 0x50, 0x48, 0x4c, 0x54, 0x79, 0x78, 0x51, 0x47, 0x6a, 0x68, 0x64,
+    0x42, 0x79, 0x50, 0x71, 0x31, 0x7a, 0x0a, 0x71, 0x77, 0x75, 0x62, 0x64,
+    0x51, 0x78, 0x74, 0x52, 0x62, 0x65, 0x4f, 0x6c, 0x4b, 0x79, 0x57, 0x4e,
+    0x37, 0x57, 0x67, 0x30, 0x49, 0x38, 0x56, 0x52, 0x77, 0x37, 0x6a, 0x36,
+    0x49, 0x50, 0x64, 0x6a, 0x2f, 0x33, 0x76, 0x51, 0x51, 0x46, 0x33, 0x7a,
+    0x43, 0x65, 0x70, 0x59, 0x6f, 0x55, 0x7a, 0x38, 0x6a, 0x63, 0x49, 0x37,
+    0x33, 0x48, 0x50, 0x64, 0x77, 0x62, 0x65, 0x79, 0x42, 0x6b, 0x64, 0x0a,
+    0x69, 0x45, 0x44, 0x50, 0x66, 0x55, 0x59, 0x64, 0x2f, 0x78, 0x37, 0x48,
+    0x34, 0x63, 0x37, 0x2f, 0x49, 0x39, 0x76, 0x47, 0x2b, 0x6f, 0x31, 0x56,
+    0x54, 0x71, 0x6b, 0x43, 0x35, 0x30, 0x63, 0x52, 0x52, 0x6a, 0x37, 0x30,
+    0x2f, 0x62, 0x31, 0x37, 0x4b, 0x53, 0x61, 0x37, 0x71, 0x57, 0x46, 0x69,
+    0x4e, 0x79, 0x69, 0x32, 0x4c, 0x53, 0x72, 0x32, 0x45, 0x49, 0x5a, 0x6b,
+    0x79, 0x58, 0x43, 0x6e, 0x0a, 0x30, 0x71, 0x32, 0x33, 0x4b, 0x58, 0x42,
+    0x35, 0x36, 0x6a, 0x7a, 0x61, 0x59, 0x79, 0x57, 0x66, 0x2f, 0x57, 0x69,
+    0x33, 0x4d, 0x4f, 0x78, 0x77, 0x2b, 0x33, 0x57, 0x4b, 0x74, 0x32, 0x31,
+    0x67, 0x5a, 0x37, 0x49, 0x65, 0x79, 0x4c, 0x6e, 0x70, 0x32, 0x4b, 0x68,
+    0x76, 0x41, 0x6f, 0x74, 0x6e, 0x44, 0x55, 0x30, 0x6d, 0x56, 0x33, 0x48,
+    0x61, 0x49, 0x50, 0x7a, 0x42, 0x53, 0x6c, 0x43, 0x4e, 0x0a, 0x73, 0x53,
+    0x69, 0x36, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73, 0x73, 0x75,
+    0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x66, 0x66, 0x69, 0x72,
+    0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65,
+    0x72, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x4f, 0x3d, 0x41, 0x66, 0x66, 0x69,
+    0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x0a, 0x23, 0x20, 0x53, 0x75,
+    0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x66,
+    0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6f,
+    0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x4f, 0x3d, 0x41,
+    0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x0a, 0x23,
+    0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x41, 0x66, 0x66,
+    0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6f, 0x6d,
+    0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x38, 0x36, 0x30, 0x38, 0x33,
+    0x35, 0x35, 0x39, 0x37, 0x37, 0x39, 0x36, 0x34, 0x31, 0x33, 0x38, 0x38,
+    0x37, 0x36, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x38, 0x32,
+    0x3a, 0x39, 0x32, 0x3a, 0x62, 0x61, 0x3a, 0x35, 0x62, 0x3a, 0x65, 0x66,
+    0x3a, 0x63, 0x64, 0x3a, 0x38, 0x61, 0x3a, 0x36, 0x66, 0x3a, 0x61, 0x36,
+    0x3a, 0x33, 0x64, 0x3a, 0x35, 0x35, 0x3a, 0x66, 0x39, 0x3a, 0x38, 0x34,
+    0x3a, 0x66, 0x36, 0x3a, 0x64, 0x36, 0x3a, 0x62, 0x37, 0x0a, 0x23, 0x20,
+    0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
+    0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x66, 0x39, 0x3a, 0x62, 0x35, 0x3a,
+    0x62, 0x36, 0x3a, 0x33, 0x32, 0x3a, 0x34, 0x35, 0x3a, 0x35, 0x66, 0x3a,
+    0x39, 0x63, 0x3a, 0x62, 0x65, 0x3a, 0x65, 0x63, 0x3a, 0x35, 0x37, 0x3a,
+    0x35, 0x66, 0x3a, 0x38, 0x30, 0x3a, 0x64, 0x63, 0x3a, 0x65, 0x39, 0x3a,
+    0x36, 0x65, 0x3a, 0x32, 0x63, 0x3a, 0x63, 0x37, 0x3a, 0x62, 0x32, 0x3a,
+    0x37, 0x38, 0x3a, 0x62, 0x37, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32,
+    0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x30, 0x33, 0x3a, 0x37, 0x36, 0x3a, 0x61, 0x62,
+    0x3a, 0x31, 0x64, 0x3a, 0x35, 0x34, 0x3a, 0x63, 0x35, 0x3a, 0x66, 0x39,
+    0x3a, 0x38, 0x30, 0x3a, 0x33, 0x63, 0x3a, 0x65, 0x34, 0x3a, 0x62, 0x32,
+    0x3a, 0x65, 0x32, 0x3a, 0x30, 0x31, 0x3a, 0x61, 0x30, 0x3a, 0x65, 0x65,
+    0x3a, 0x37, 0x65, 0x3a, 0x65, 0x66, 0x3a, 0x37, 0x62, 0x3a, 0x35, 0x37,
+    0x3a, 0x62, 0x36, 0x3a, 0x33, 0x36, 0x3a, 0x65, 0x38, 0x3a, 0x61, 0x39,
+    0x3a, 0x33, 0x63, 0x3a, 0x39, 0x62, 0x3a, 0x38, 0x64, 0x3a, 0x34, 0x38,
+    0x3a, 0x36, 0x30, 0x3a, 0x63, 0x39, 0x3a, 0x36, 0x66, 0x3a, 0x35, 0x66,
+    0x3a, 0x61, 0x37, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47,
+    0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44,
+    0x54, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42,
+    0x41, 0x67, 0x49, 0x49, 0x64, 0x33, 0x63, 0x47, 0x4a, 0x79, 0x61, 0x70,
+    0x73, 0x58, 0x77, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49,
+    0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41, 0x77,
+    0x52, 0x44, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x0a, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x44, 0x41,
+    0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x43, 0x30, 0x46,
+    0x6d, 0x5a, 0x6d, 0x6c, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4e,
+    0x30, 0x4d, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51,
+    0x44, 0x44, 0x42, 0x5a, 0x42, 0x5a, 0x6d, 0x5a, 0x70, 0x63, 0x6d, 0x31,
+    0x55, 0x63, 0x6e, 0x56, 0x7a, 0x0a, 0x64, 0x43, 0x42, 0x44, 0x62, 0x32,
+    0x31, 0x74, 0x5a, 0x58, 0x4a, 0x6a, 0x61, 0x57, 0x46, 0x73, 0x4d, 0x42,
+    0x34, 0x58, 0x44, 0x54, 0x45, 0x77, 0x4d, 0x44, 0x45, 0x79, 0x4f, 0x54,
+    0x45, 0x30, 0x4d, 0x44, 0x59, 0x77, 0x4e, 0x6c, 0x6f, 0x58, 0x44, 0x54,
+    0x4d, 0x77, 0x4d, 0x54, 0x49, 0x7a, 0x4d, 0x54, 0x45, 0x30, 0x4d, 0x44,
+    0x59, 0x77, 0x4e, 0x6c, 0x6f, 0x77, 0x52, 0x44, 0x45, 0x4c, 0x0a, 0x4d,
+    0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56,
+    0x56, 0x4d, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x4d, 0x43, 0x30, 0x46, 0x6d, 0x5a, 0x6d, 0x6c, 0x79, 0x62,
+    0x56, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4d, 0x52, 0x38, 0x77, 0x48,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x5a, 0x42, 0x5a,
+    0x6d, 0x5a, 0x70, 0x0a, 0x63, 0x6d, 0x31, 0x55, 0x63, 0x6e, 0x56, 0x7a,
+    0x64, 0x43, 0x42, 0x44, 0x62, 0x32, 0x31, 0x74, 0x5a, 0x58, 0x4a, 0x6a,
+    0x61, 0x57, 0x46, 0x73, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e,
+    0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42,
+    0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41,
+    0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x0a, 0x41, 0x51, 0x45,
+    0x41, 0x39, 0x68, 0x74, 0x50, 0x5a, 0x77, 0x63, 0x72, 0x6f, 0x52, 0x58,
+    0x31, 0x42, 0x69, 0x4c, 0x4c, 0x48, 0x77, 0x47, 0x79, 0x34, 0x33, 0x4e,
+    0x46, 0x42, 0x6b, 0x52, 0x4a, 0x4c, 0x4c, 0x74, 0x4a, 0x4a, 0x52, 0x54,
+    0x57, 0x7a, 0x73, 0x4f, 0x33, 0x71, 0x79, 0x78, 0x50, 0x78, 0x6b, 0x45,
+    0x79, 0x6c, 0x46, 0x66, 0x36, 0x45, 0x71, 0x64, 0x62, 0x44, 0x75, 0x4b,
+    0x50, 0x0a, 0x48, 0x78, 0x36, 0x47, 0x47, 0x61, 0x65, 0x71, 0x74, 0x53,
+    0x32, 0x35, 0x58, 0x77, 0x32, 0x4b, 0x77, 0x71, 0x2b, 0x46, 0x4e, 0x58,
+    0x6b, 0x79, 0x4c, 0x62, 0x73, 0x63, 0x59, 0x6a, 0x66, 0x79, 0x73, 0x56,
+    0x74, 0x4b, 0x50, 0x63, 0x72, 0x4e, 0x63, 0x56, 0x2f, 0x70, 0x51, 0x72,
+    0x36, 0x55, 0x36, 0x4d, 0x6a, 0x65, 0x2b, 0x53, 0x4a, 0x49, 0x5a, 0x4d,
+    0x62, 0x6c, 0x71, 0x38, 0x59, 0x72, 0x0a, 0x62, 0x61, 0x30, 0x46, 0x38,
+    0x50, 0x72, 0x56, 0x43, 0x38, 0x2b, 0x61, 0x35, 0x66, 0x42, 0x51, 0x70,
+    0x49, 0x73, 0x37, 0x52, 0x36, 0x55, 0x6a, 0x57, 0x33, 0x70, 0x36, 0x2b,
+    0x44, 0x4d, 0x2f, 0x75, 0x4f, 0x2b, 0x5a, 0x6c, 0x2b, 0x4d, 0x67, 0x77,
+    0x64, 0x59, 0x6f, 0x69, 0x63, 0x2b, 0x55, 0x2b, 0x37, 0x6c, 0x46, 0x37,
+    0x65, 0x4e, 0x41, 0x46, 0x78, 0x48, 0x55, 0x64, 0x50, 0x41, 0x4c, 0x0a,
+    0x4d, 0x65, 0x49, 0x72, 0x4a, 0x6d, 0x71, 0x62, 0x54, 0x46, 0x65, 0x75,
+    0x72, 0x43, 0x41, 0x2b, 0x75, 0x6b, 0x56, 0x36, 0x42, 0x66, 0x4f, 0x39,
+    0x6d, 0x32, 0x6b, 0x56, 0x72, 0x6e, 0x31, 0x4f, 0x49, 0x47, 0x50, 0x45,
+    0x4e, 0x58, 0x59, 0x36, 0x42, 0x77, 0x4c, 0x4a, 0x4e, 0x2f, 0x33, 0x48,
+    0x52, 0x2b, 0x37, 0x6f, 0x38, 0x58, 0x59, 0x64, 0x63, 0x78, 0x58, 0x79,
+    0x6c, 0x36, 0x53, 0x31, 0x0a, 0x79, 0x48, 0x70, 0x35, 0x32, 0x55, 0x4b,
+    0x71, 0x4b, 0x33, 0x39, 0x63, 0x2f, 0x73, 0x34, 0x6d, 0x54, 0x36, 0x4e,
+    0x6d, 0x67, 0x54, 0x57, 0x76, 0x52, 0x4c, 0x70, 0x55, 0x48, 0x68, 0x77,
+    0x77, 0x4d, 0x6d, 0x57, 0x64, 0x35, 0x6a, 0x79, 0x54, 0x58, 0x6c, 0x42,
+    0x4f, 0x65, 0x75, 0x4d, 0x36, 0x31, 0x47, 0x37, 0x4d, 0x47, 0x76, 0x76,
+    0x35, 0x30, 0x6a, 0x65, 0x75, 0x4a, 0x43, 0x71, 0x72, 0x0a, 0x56, 0x77,
+    0x4d, 0x69, 0x4b, 0x41, 0x31, 0x4a, 0x64, 0x58, 0x2b, 0x33, 0x4b, 0x4e,
+    0x70, 0x31, 0x76, 0x34, 0x37, 0x6a, 0x33, 0x41, 0x35, 0x35, 0x4d, 0x51,
+    0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x30, 0x49, 0x77, 0x51, 0x44,
+    0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67,
+    0x51, 0x55, 0x6e, 0x5a, 0x50, 0x47, 0x55, 0x34, 0x74, 0x65, 0x79, 0x71,
+    0x38, 0x2f, 0x0a, 0x6e, 0x78, 0x34, 0x50, 0x35, 0x5a, 0x6d, 0x56, 0x76,
+    0x43, 0x54, 0x32, 0x6c, 0x49, 0x38, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41,
+    0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48,
+    0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41,
+    0x51, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x0a, 0x4b, 0x6f, 0x5a, 0x49,
+    0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41, 0x44,
+    0x67, 0x67, 0x45, 0x42, 0x41, 0x46, 0x69, 0x73, 0x39, 0x41, 0x51, 0x4f,
+    0x7a, 0x63, 0x41, 0x4e, 0x2f, 0x77, 0x72, 0x39, 0x31, 0x4c, 0x6f, 0x57,
+    0x58, 0x79, 0x6d, 0x39, 0x65, 0x32, 0x69, 0x5a, 0x57, 0x45, 0x6e, 0x53,
+    0x74, 0x42, 0x30, 0x33, 0x54, 0x58, 0x38, 0x6e, 0x66, 0x55, 0x59, 0x47,
+    0x0a, 0x58, 0x55, 0x50, 0x47, 0x68, 0x69, 0x34, 0x2b, 0x63, 0x37, 0x49,
+    0x6d, 0x66, 0x55, 0x2b, 0x54, 0x71, 0x62, 0x62, 0x45, 0x4b, 0x70, 0x71,
+    0x72, 0x49, 0x5a, 0x63, 0x55, 0x73, 0x64, 0x36, 0x4d, 0x30, 0x36, 0x75,
+    0x4a, 0x46, 0x64, 0x68, 0x72, 0x4a, 0x4e, 0x54, 0x78, 0x46, 0x71, 0x37,
+    0x59, 0x70, 0x46, 0x7a, 0x55, 0x66, 0x31, 0x47, 0x4f, 0x37, 0x52, 0x67,
+    0x42, 0x73, 0x5a, 0x4e, 0x6a, 0x0a, 0x76, 0x62, 0x7a, 0x34, 0x59, 0x59,
+    0x43, 0x61, 0x6e, 0x72, 0x48, 0x4f, 0x51, 0x6e, 0x44, 0x69, 0x71, 0x58,
+    0x30, 0x47, 0x4a, 0x58, 0x30, 0x6e, 0x6f, 0x66, 0x35, 0x76, 0x37, 0x4c,
+    0x4d, 0x65, 0x4a, 0x4e, 0x72, 0x6a, 0x53, 0x31, 0x55, 0x61, 0x41, 0x44,
+    0x73, 0x31, 0x74, 0x44, 0x76, 0x5a, 0x31, 0x31, 0x30, 0x77, 0x2f, 0x59,
+    0x45, 0x54, 0x69, 0x66, 0x4c, 0x43, 0x42, 0x69, 0x76, 0x74, 0x0a, 0x5a,
+    0x38, 0x53, 0x4f, 0x79, 0x55, 0x4f, 0x79, 0x58, 0x47, 0x73, 0x56, 0x69,
+    0x51, 0x4b, 0x38, 0x59, 0x76, 0x78, 0x4f, 0x38, 0x72, 0x55, 0x7a, 0x71,
+    0x72, 0x4a, 0x76, 0x30, 0x77, 0x71, 0x69, 0x55, 0x4f, 0x50, 0x32, 0x4f,
+    0x2b, 0x67, 0x75, 0x52, 0x4d, 0x4c, 0x62, 0x5a, 0x6a, 0x69, 0x70, 0x4d,
+    0x31, 0x5a, 0x49, 0x38, 0x57, 0x30, 0x62, 0x4d, 0x34, 0x30, 0x4e, 0x6a,
+    0x44, 0x39, 0x67, 0x0a, 0x4e, 0x35, 0x33, 0x54, 0x79, 0x6d, 0x31, 0x2b,
+    0x4e, 0x48, 0x34, 0x4e, 0x6e, 0x33, 0x4a, 0x32, 0x69, 0x78, 0x75, 0x66,
+    0x63, 0x76, 0x31, 0x53, 0x4e, 0x55, 0x46, 0x46, 0x41, 0x70, 0x59, 0x76,
+    0x48, 0x4c, 0x4b, 0x61, 0x63, 0x30, 0x6b, 0x68, 0x73, 0x55, 0x6c, 0x48,
+    0x52, 0x55, 0x65, 0x30, 0x37, 0x32, 0x6f, 0x30, 0x45, 0x63, 0x6c, 0x4e,
+    0x6d, 0x73, 0x78, 0x5a, 0x74, 0x39, 0x59, 0x43, 0x0a, 0x6e, 0x6c, 0x70,
+    0x4f, 0x5a, 0x62, 0x57, 0x55, 0x72, 0x68, 0x76, 0x66, 0x4b, 0x62, 0x41,
+    0x57, 0x38, 0x62, 0x38, 0x41, 0x6e, 0x67, 0x63, 0x36, 0x46, 0x32, 0x53,
+    0x31, 0x42, 0x4c, 0x55, 0x6a, 0x49, 0x5a, 0x6b, 0x4b, 0x6c, 0x54, 0x75,
+    0x58, 0x66, 0x4f, 0x38, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49,
+    0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x66,
+    0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65,
+    0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x4f, 0x3d, 0x41,
+    0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x20,
+    0x4f, 0x3d, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22,
+    0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+    0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x22, 0x0a,
+    0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x38, 0x39,
+    0x35, 0x37, 0x33, 0x38, 0x32, 0x38, 0x32, 0x37, 0x32, 0x30, 0x36, 0x35,
+    0x34, 0x37, 0x37, 0x35, 0x37, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x34, 0x32, 0x3a, 0x36, 0x35, 0x3a, 0x63, 0x61, 0x3a, 0x62, 0x65,
+    0x3a, 0x30, 0x31, 0x3a, 0x39, 0x61, 0x3a, 0x39, 0x61, 0x3a, 0x34, 0x63,
+    0x3a, 0x61, 0x39, 0x3a, 0x38, 0x63, 0x3a, 0x34, 0x31, 0x3a, 0x34, 0x39,
+    0x3a, 0x63, 0x64, 0x3a, 0x63, 0x30, 0x3a, 0x64, 0x35, 0x3a, 0x37, 0x66,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x32, 0x39, 0x3a,
+    0x33, 0x36, 0x3a, 0x32, 0x31, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x62, 0x3a,
+    0x32, 0x30, 0x3a, 0x65, 0x64, 0x3a, 0x30, 0x32, 0x3a, 0x66, 0x35, 0x3a,
+    0x36, 0x36, 0x3a, 0x63, 0x35, 0x3a, 0x33, 0x32, 0x3a, 0x64, 0x31, 0x3a,
+    0x64, 0x36, 0x3a, 0x65, 0x64, 0x3a, 0x39, 0x30, 0x3a, 0x39, 0x66, 0x3a,
+    0x34, 0x35, 0x3a, 0x30, 0x30, 0x3a, 0x32, 0x66, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x30, 0x61, 0x3a, 0x38, 0x31,
+    0x3a, 0x65, 0x63, 0x3a, 0x35, 0x61, 0x3a, 0x39, 0x32, 0x3a, 0x39, 0x37,
+    0x3a, 0x37, 0x37, 0x3a, 0x66, 0x31, 0x3a, 0x34, 0x35, 0x3a, 0x39, 0x30,
+    0x3a, 0x34, 0x61, 0x3a, 0x66, 0x33, 0x3a, 0x38, 0x64, 0x3a, 0x35, 0x64,
+    0x3a, 0x35, 0x30, 0x3a, 0x39, 0x66, 0x3a, 0x36, 0x36, 0x3a, 0x62, 0x35,
+    0x3a, 0x65, 0x32, 0x3a, 0x63, 0x35, 0x3a, 0x38, 0x66, 0x3a, 0x63, 0x64,
+    0x3a, 0x62, 0x35, 0x3a, 0x33, 0x31, 0x3a, 0x30, 0x35, 0x3a, 0x38, 0x62,
+    0x3a, 0x30, 0x65, 0x3a, 0x31, 0x37, 0x3a, 0x66, 0x33, 0x3a, 0x66, 0x30,
+    0x3a, 0x62, 0x34, 0x3a, 0x31, 0x62, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
+    0x49, 0x49, 0x44, 0x54, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x53, 0x67, 0x41,
+    0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x66, 0x45, 0x38, 0x45, 0x4f,
+    0x52, 0x7a, 0x55, 0x6d, 0x53, 0x30, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b,
+    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42,
+    0x51, 0x41, 0x77, 0x52, 0x44, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x0a, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78,
+    0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d,
+    0x43, 0x30, 0x46, 0x6d, 0x5a, 0x6d, 0x6c, 0x79, 0x62, 0x56, 0x52, 0x79,
+    0x64, 0x58, 0x4e, 0x30, 0x4d, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44,
+    0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x5a, 0x42, 0x5a, 0x6d, 0x5a, 0x70,
+    0x63, 0x6d, 0x31, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x0a, 0x64, 0x43, 0x42,
+    0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62, 0x33, 0x4a, 0x72, 0x61, 0x57, 0x35,
+    0x6e, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x77, 0x4d, 0x44, 0x45,
+    0x79, 0x4f, 0x54, 0x45, 0x30, 0x4d, 0x44, 0x67, 0x79, 0x4e, 0x46, 0x6f,
+    0x58, 0x44, 0x54, 0x4d, 0x77, 0x4d, 0x54, 0x49, 0x7a, 0x4d, 0x54, 0x45,
+    0x30, 0x4d, 0x44, 0x67, 0x79, 0x4e, 0x46, 0x6f, 0x77, 0x52, 0x44, 0x45,
+    0x4c, 0x0a, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68,
+    0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x43, 0x30, 0x46, 0x6d, 0x5a, 0x6d,
+    0x6c, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4d, 0x52,
+    0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42,
+    0x5a, 0x42, 0x5a, 0x6d, 0x5a, 0x70, 0x0a, 0x63, 0x6d, 0x31, 0x55, 0x63,
+    0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4f, 0x5a, 0x58, 0x52, 0x33, 0x62,
+    0x33, 0x4a, 0x72, 0x61, 0x57, 0x35, 0x6e, 0x4d, 0x49, 0x49, 0x42, 0x49,
+    0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41,
+    0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x0a,
+    0x41, 0x51, 0x45, 0x41, 0x74, 0x49, 0x54, 0x4d, 0x4d, 0x78, 0x63, 0x75,
+    0x61, 0x35, 0x52, 0x73, 0x61, 0x32, 0x46, 0x53, 0x6f, 0x4f, 0x75, 0x6a,
+    0x7a, 0x33, 0x6d, 0x55, 0x54, 0x4f, 0x57, 0x55, 0x67, 0x4a, 0x6e, 0x4c,
+    0x56, 0x57, 0x52, 0x45, 0x5a, 0x59, 0x39, 0x6e, 0x5a, 0x4f, 0x49, 0x47,
+    0x34, 0x31, 0x77, 0x33, 0x53, 0x66, 0x59, 0x76, 0x6d, 0x34, 0x53, 0x45,
+    0x48, 0x69, 0x33, 0x79, 0x0a, 0x59, 0x4a, 0x30, 0x77, 0x54, 0x73, 0x79,
+    0x45, 0x68, 0x65, 0x49, 0x73, 0x7a, 0x78, 0x36, 0x65, 0x2f, 0x6a, 0x61,
+    0x72, 0x4d, 0x33, 0x63, 0x31, 0x52, 0x4e, 0x67, 0x31, 0x6c, 0x68, 0x6f,
+    0x39, 0x4e, 0x75, 0x68, 0x36, 0x44, 0x74, 0x6a, 0x56, 0x52, 0x36, 0x46,
+    0x71, 0x61, 0x59, 0x76, 0x5a, 0x2f, 0x4c, 0x73, 0x36, 0x72, 0x6e, 0x6c,
+    0x61, 0x31, 0x66, 0x54, 0x57, 0x63, 0x62, 0x75, 0x61, 0x0a, 0x6b, 0x43,
+    0x4e, 0x72, 0x6d, 0x72, 0x65, 0x49, 0x64, 0x49, 0x63, 0x4d, 0x48, 0x6c,
+    0x2b, 0x35, 0x6e, 0x69, 0x33, 0x36, 0x71, 0x31, 0x4d, 0x72, 0x33, 0x4c,
+    0x74, 0x32, 0x50, 0x70, 0x4e, 0x4d, 0x43, 0x41, 0x69, 0x4d, 0x48, 0x71,
+    0x49, 0x6a, 0x48, 0x4e, 0x52, 0x71, 0x72, 0x53, 0x4b, 0x36, 0x6d, 0x51,
+    0x45, 0x75, 0x62, 0x57, 0x58, 0x4c, 0x76, 0x69, 0x52, 0x6d, 0x56, 0x53,
+    0x52, 0x4c, 0x0a, 0x51, 0x45, 0x53, 0x78, 0x47, 0x39, 0x66, 0x68, 0x77,
+    0x6f, 0x58, 0x41, 0x33, 0x68, 0x41, 0x2f, 0x50, 0x65, 0x32, 0x34, 0x2f,
+    0x50, 0x48, 0x78, 0x49, 0x31, 0x50, 0x63, 0x76, 0x32, 0x57, 0x58, 0x62,
+    0x39, 0x6e, 0x35, 0x51, 0x48, 0x47, 0x4e, 0x66, 0x62, 0x32, 0x56, 0x31,
+    0x4d, 0x36, 0x2b, 0x6f, 0x46, 0x34, 0x6e, 0x49, 0x39, 0x37, 0x39, 0x70,
+    0x74, 0x41, 0x6d, 0x44, 0x67, 0x41, 0x70, 0x0a, 0x36, 0x7a, 0x78, 0x47,
+    0x38, 0x44, 0x31, 0x67, 0x76, 0x7a, 0x39, 0x51, 0x30, 0x74, 0x77, 0x6d,
+    0x51, 0x56, 0x47, 0x65, 0x46, 0x44, 0x64, 0x43, 0x42, 0x4b, 0x4e, 0x77,
+    0x56, 0x36, 0x67, 0x62, 0x68, 0x2b, 0x30, 0x74, 0x2b, 0x6e, 0x76, 0x75,
+    0x6a, 0x41, 0x72, 0x6a, 0x71, 0x57, 0x61, 0x4a, 0x47, 0x63, 0x74, 0x42,
+    0x2b, 0x64, 0x31, 0x45, 0x4e, 0x6d, 0x48, 0x50, 0x34, 0x6e, 0x64, 0x47,
+    0x0a, 0x79, 0x48, 0x33, 0x32, 0x39, 0x4a, 0x4b, 0x42, 0x4e, 0x76, 0x33,
+    0x62, 0x4e, 0x50, 0x46, 0x79, 0x66, 0x76, 0x4d, 0x4d, 0x46, 0x72, 0x32,
+    0x30, 0x46, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x30, 0x49,
+    0x77, 0x51, 0x44, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34,
+    0x45, 0x46, 0x67, 0x51, 0x55, 0x42, 0x78, 0x2f, 0x53, 0x35, 0x35, 0x7a,
+    0x61, 0x77, 0x6d, 0x36, 0x69, 0x0a, 0x51, 0x4c, 0x53, 0x77, 0x65, 0x6c,
+    0x41, 0x51, 0x55, 0x48, 0x54, 0x45, 0x79, 0x4c, 0x30, 0x77, 0x44, 0x77,
+    0x59, 0x44, 0x56, 0x52, 0x30, 0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41,
+    0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, 0x41, 0x4f, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x51, 0x38, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41,
+    0x4d, 0x43, 0x41, 0x51, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x0a, 0x4b,
+    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42,
+    0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x49, 0x6c, 0x58, 0x73,
+    0x68, 0x5a, 0x36, 0x71, 0x4d, 0x4c, 0x39, 0x31, 0x74, 0x6d, 0x62, 0x6d,
+    0x7a, 0x54, 0x43, 0x6e, 0x4c, 0x51, 0x79, 0x46, 0x45, 0x32, 0x6e, 0x70,
+    0x4e, 0x2f, 0x73, 0x76, 0x71, 0x65, 0x2b, 0x2b, 0x45, 0x50, 0x62, 0x6b,
+    0x54, 0x66, 0x4f, 0x0a, 0x74, 0x44, 0x49, 0x75, 0x55, 0x46, 0x55, 0x61,
+    0x4e, 0x55, 0x35, 0x32, 0x51, 0x33, 0x45, 0x67, 0x37, 0x35, 0x4e, 0x33,
+    0x54, 0x68, 0x56, 0x77, 0x4c, 0x6f, 0x66, 0x44, 0x77, 0x52, 0x31, 0x74,
+    0x33, 0x4d, 0x75, 0x31, 0x4a, 0x39, 0x51, 0x73, 0x56, 0x74, 0x46, 0x53,
+    0x55, 0x7a, 0x70, 0x45, 0x30, 0x6e, 0x50, 0x49, 0x78, 0x42, 0x73, 0x46,
+    0x5a, 0x56, 0x70, 0x69, 0x6b, 0x70, 0x7a, 0x75, 0x0a, 0x51, 0x59, 0x30,
+    0x78, 0x32, 0x2b, 0x63, 0x30, 0x36, 0x6c, 0x6b, 0x68, 0x31, 0x51, 0x46,
+    0x36, 0x31, 0x32, 0x53, 0x34, 0x5a, 0x44, 0x6e, 0x4e, 0x79, 0x65, 0x32,
+    0x76, 0x37, 0x55, 0x73, 0x44, 0x53, 0x4b, 0x65, 0x67, 0x6d, 0x51, 0x47,
+    0x41, 0x33, 0x47, 0x57, 0x6a, 0x4e, 0x71, 0x35, 0x6c, 0x57, 0x55, 0x68,
+    0x50, 0x67, 0x6b, 0x76, 0x49, 0x5a, 0x66, 0x46, 0x58, 0x48, 0x65, 0x56,
+    0x5a, 0x0a, 0x4c, 0x67, 0x6f, 0x2f, 0x62, 0x4e, 0x6a, 0x52, 0x39, 0x65,
+    0x55, 0x4a, 0x74, 0x47, 0x78, 0x55, 0x41, 0x41, 0x72, 0x67, 0x46, 0x55,
+    0x32, 0x48, 0x64, 0x57, 0x32, 0x33, 0x57, 0x4a, 0x5a, 0x61, 0x33, 0x57,
+    0x33, 0x53, 0x41, 0x4b, 0x44, 0x30, 0x6d, 0x30, 0x69, 0x2b, 0x77, 0x7a,
+    0x65, 0x6b, 0x75, 0x6a, 0x62, 0x67, 0x66, 0x49, 0x65, 0x46, 0x6c, 0x78,
+    0x6f, 0x56, 0x6f, 0x74, 0x34, 0x75, 0x0a, 0x6f, 0x6c, 0x75, 0x39, 0x72,
+    0x78, 0x6a, 0x35, 0x6b, 0x46, 0x44, 0x4e, 0x63, 0x46, 0x6e, 0x34, 0x4a,
+    0x32, 0x64, 0x48, 0x79, 0x38, 0x65, 0x67, 0x42, 0x7a, 0x70, 0x39, 0x30,
+    0x53, 0x78, 0x64, 0x62, 0x42, 0x6b, 0x36, 0x5a, 0x72, 0x56, 0x39, 0x2f,
+    0x5a, 0x46, 0x76, 0x67, 0x72, 0x47, 0x2b, 0x43, 0x4a, 0x50, 0x62, 0x46,
+    0x45, 0x66, 0x78, 0x6f, 0x6a, 0x66, 0x48, 0x52, 0x5a, 0x34, 0x38, 0x0a,
+    0x78, 0x33, 0x65, 0x76, 0x5a, 0x4b, 0x69, 0x54, 0x33, 0x2f, 0x5a, 0x70,
+    0x67, 0x34, 0x4a, 0x67, 0x38, 0x6b, 0x6c, 0x43, 0x4e, 0x4f, 0x31, 0x61,
+    0x41, 0x46, 0x53, 0x46, 0x48, 0x42, 0x59, 0x32, 0x6b, 0x67, 0x78, 0x63,
+    0x2b, 0x71, 0x61, 0x74, 0x76, 0x39, 0x73, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46,
+    0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a,
+    0x23, 0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x4f, 0x3d, 0x41,
+    0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x0a, 0x23,
+    0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43, 0x4e,
+    0x3d, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x4f, 0x3d, 0x41,
+    0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x0a, 0x23,
+    0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x41, 0x66, 0x66,
+    0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x65,
+    0x6d, 0x69, 0x75, 0x6d, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69,
+    0x61, 0x6c, 0x3a, 0x20, 0x37, 0x38, 0x39, 0x33, 0x37, 0x30, 0x36, 0x35,
+    0x34, 0x30, 0x37, 0x33, 0x34, 0x33, 0x35, 0x32, 0x31, 0x31, 0x30, 0x0a,
+    0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72,
+    0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x34, 0x3a, 0x35, 0x64,
+    0x3a, 0x30, 0x65, 0x3a, 0x34, 0x38, 0x3a, 0x62, 0x36, 0x3a, 0x61, 0x63,
+    0x3a, 0x32, 0x38, 0x3a, 0x33, 0x30, 0x3a, 0x34, 0x65, 0x3a, 0x30, 0x61,
+    0x3a, 0x62, 0x63, 0x3a, 0x66, 0x39, 0x3a, 0x33, 0x38, 0x3a, 0x31, 0x36,
+    0x3a, 0x38, 0x37, 0x3a, 0x35, 0x37, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41,
+    0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x64, 0x38, 0x3a, 0x61, 0x36, 0x3a, 0x33, 0x33, 0x3a,
+    0x32, 0x63, 0x3a, 0x65, 0x30, 0x3a, 0x30, 0x33, 0x3a, 0x36, 0x66, 0x3a,
+    0x62, 0x31, 0x3a, 0x38, 0x35, 0x3a, 0x66, 0x36, 0x3a, 0x36, 0x33, 0x3a,
+    0x34, 0x66, 0x3a, 0x37, 0x64, 0x3a, 0x36, 0x61, 0x3a, 0x30, 0x36, 0x3a,
+    0x36, 0x35, 0x3a, 0x32, 0x36, 0x3a, 0x33, 0x32, 0x3a, 0x32, 0x38, 0x3a,
+    0x32, 0x37, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x37, 0x30, 0x3a, 0x61, 0x37, 0x3a, 0x33, 0x66, 0x3a, 0x37, 0x66,
+    0x3a, 0x33, 0x37, 0x3a, 0x36, 0x62, 0x3a, 0x36, 0x30, 0x3a, 0x30, 0x37,
+    0x3a, 0x34, 0x32, 0x3a, 0x34, 0x38, 0x3a, 0x39, 0x30, 0x3a, 0x34, 0x35,
+    0x3a, 0x33, 0x34, 0x3a, 0x62, 0x31, 0x3a, 0x31, 0x34, 0x3a, 0x38, 0x32,
+    0x3a, 0x64, 0x35, 0x3a, 0x62, 0x66, 0x3a, 0x30, 0x65, 0x3a, 0x36, 0x39,
+    0x3a, 0x38, 0x65, 0x3a, 0x63, 0x63, 0x3a, 0x34, 0x39, 0x3a, 0x38, 0x64,
+    0x3a, 0x66, 0x35, 0x3a, 0x32, 0x35, 0x3a, 0x37, 0x37, 0x3a, 0x65, 0x62,
+    0x3a, 0x66, 0x32, 0x3a, 0x65, 0x39, 0x3a, 0x33, 0x62, 0x3a, 0x39, 0x61,
+    0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, 0x52, 0x6a, 0x43,
+    0x43, 0x41, 0x79, 0x36, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
+    0x49, 0x62, 0x59, 0x77, 0x55, 0x52, 0x72, 0x47, 0x6d, 0x43, 0x75, 0x34,
+    0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63,
+    0x4e, 0x41, 0x51, 0x45, 0x4d, 0x42, 0x51, 0x41, 0x77, 0x51, 0x54, 0x45,
+    0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x42, 0x68,
+    0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67,
+    0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x43, 0x30, 0x46, 0x6d, 0x5a, 0x6d,
+    0x6c, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30, 0x4d, 0x52,
+    0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42,
+    0x4e, 0x42, 0x5a, 0x6d, 0x5a, 0x70, 0x63, 0x6d, 0x31, 0x55, 0x63, 0x6e,
+    0x56, 0x7a, 0x0a, 0x64, 0x43, 0x42, 0x51, 0x63, 0x6d, 0x56, 0x74, 0x61,
+    0x58, 0x56, 0x74, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x77, 0x4d,
+    0x44, 0x45, 0x79, 0x4f, 0x54, 0x45, 0x30, 0x4d, 0x54, 0x41, 0x7a, 0x4e,
+    0x6c, 0x6f, 0x58, 0x44, 0x54, 0x51, 0x77, 0x4d, 0x54, 0x49, 0x7a, 0x4d,
+    0x54, 0x45, 0x30, 0x4d, 0x54, 0x41, 0x7a, 0x4e, 0x6c, 0x6f, 0x77, 0x51,
+    0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x45,
+    0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x46, 0x44, 0x41, 0x53,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x43, 0x30, 0x46, 0x6d,
+    0x5a, 0x6d, 0x6c, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64, 0x58, 0x4e, 0x30,
+    0x4d, 0x52, 0x77, 0x77, 0x47, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44,
+    0x44, 0x42, 0x4e, 0x42, 0x5a, 0x6d, 0x5a, 0x70, 0x63, 0x6d, 0x31, 0x55,
+    0x0a, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x51, 0x63, 0x6d, 0x56,
+    0x74, 0x61, 0x58, 0x56, 0x74, 0x4d, 0x49, 0x49, 0x43, 0x49, 0x6a, 0x41,
+    0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30,
+    0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x67, 0x38,
+    0x41, 0x4d, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x67, 0x45,
+    0x41, 0x78, 0x42, 0x4c, 0x66, 0x0a, 0x71, 0x56, 0x2f, 0x2b, 0x51, 0x64,
+    0x33, 0x64, 0x39, 0x5a, 0x2b, 0x4b, 0x34, 0x2f, 0x61, 0x73, 0x34, 0x54,
+    0x78, 0x34, 0x6d, 0x72, 0x7a, 0x59, 0x38, 0x48, 0x39, 0x36, 0x6f, 0x44,
+    0x4d, 0x71, 0x33, 0x49, 0x30, 0x67, 0x57, 0x36, 0x34, 0x74, 0x62, 0x2b,
+    0x65, 0x54, 0x32, 0x54, 0x5a, 0x77, 0x61, 0x6d, 0x6a, 0x50, 0x6a, 0x6c,
+    0x47, 0x6a, 0x68, 0x56, 0x74, 0x6e, 0x42, 0x4b, 0x41, 0x51, 0x0a, 0x4a,
+    0x47, 0x39, 0x64, 0x4b, 0x49, 0x4c, 0x42, 0x6c, 0x31, 0x66, 0x59, 0x53,
+    0x43, 0x6b, 0x54, 0x74, 0x75, 0x47, 0x2b, 0x6b, 0x55, 0x33, 0x66, 0x68,
+    0x51, 0x78, 0x54, 0x47, 0x4a, 0x6f, 0x65, 0x4a, 0x4b, 0x4a, 0x50, 0x6a,
+    0x2f, 0x43, 0x69, 0x68, 0x51, 0x76, 0x4c, 0x39, 0x43, 0x6c, 0x2f, 0x30,
+    0x71, 0x52, 0x59, 0x37, 0x69, 0x5a, 0x4e, 0x79, 0x61, 0x71, 0x6f, 0x65,
+    0x35, 0x72, 0x5a, 0x0a, 0x2b, 0x6a, 0x6a, 0x65, 0x52, 0x46, 0x63, 0x56,
+    0x35, 0x66, 0x69, 0x4d, 0x79, 0x4e, 0x6c, 0x49, 0x34, 0x67, 0x30, 0x57,
+    0x4a, 0x78, 0x30, 0x65, 0x79, 0x49, 0x4f, 0x46, 0x4a, 0x62, 0x65, 0x36,
+    0x71, 0x6c, 0x56, 0x42, 0x7a, 0x41, 0x4d, 0x69, 0x53, 0x79, 0x32, 0x52,
+    0x6a, 0x59, 0x76, 0x6d, 0x69, 0x61, 0x39, 0x6d, 0x78, 0x2b, 0x6e, 0x2f,
+    0x4b, 0x2b, 0x6b, 0x38, 0x72, 0x4e, 0x72, 0x53, 0x0a, 0x73, 0x38, 0x50,
+    0x68, 0x61, 0x4a, 0x79, 0x4a, 0x2b, 0x48, 0x6f, 0x41, 0x56, 0x74, 0x37,
+    0x30, 0x56, 0x5a, 0x56, 0x73, 0x2b, 0x37, 0x70, 0x6b, 0x33, 0x57, 0x4b,
+    0x4c, 0x33, 0x77, 0x74, 0x33, 0x4d, 0x75, 0x74, 0x69, 0x7a, 0x43, 0x61,
+    0x61, 0x6d, 0x37, 0x75, 0x71, 0x59, 0x6f, 0x4e, 0x4d, 0x74, 0x41, 0x5a,
+    0x36, 0x4d, 0x4d, 0x67, 0x70, 0x76, 0x2b, 0x30, 0x47, 0x54, 0x5a, 0x65,
+    0x35, 0x0a, 0x48, 0x4d, 0x51, 0x78, 0x4b, 0x39, 0x56, 0x66, 0x76, 0x46,
+    0x4d, 0x53, 0x46, 0x35, 0x79, 0x5a, 0x56, 0x79, 0x6c, 0x6d, 0x64, 0x32,
+    0x45, 0x68, 0x4d, 0x51, 0x63, 0x75, 0x4a, 0x55, 0x6d, 0x64, 0x47, 0x50,
+    0x4c, 0x75, 0x38, 0x79, 0x74, 0x78, 0x6a, 0x4c, 0x57, 0x36, 0x4f, 0x51,
+    0x64, 0x4a, 0x64, 0x2f, 0x7a, 0x76, 0x4c, 0x70, 0x4b, 0x51, 0x42, 0x59,
+    0x30, 0x74, 0x4c, 0x33, 0x64, 0x37, 0x0a, 0x37, 0x30, 0x4f, 0x2f, 0x4e,
+    0x62, 0x75, 0x61, 0x32, 0x50, 0x6c, 0x7a, 0x70, 0x79, 0x7a, 0x79, 0x30,
+    0x46, 0x66, 0x75, 0x4b, 0x45, 0x34, 0x6d, 0x58, 0x34, 0x2b, 0x51, 0x61,
+    0x41, 0x6b, 0x76, 0x75, 0x50, 0x6a, 0x63, 0x42, 0x75, 0x6b, 0x75, 0x6d,
+    0x6a, 0x35, 0x52, 0x70, 0x39, 0x45, 0x69, 0x78, 0x41, 0x71, 0x6e, 0x4f,
+    0x45, 0x68, 0x73, 0x73, 0x2f, 0x6e, 0x2f, 0x66, 0x61, 0x75, 0x47, 0x0a,
+    0x56, 0x2b, 0x4f, 0x36, 0x31, 0x6f, 0x56, 0x34, 0x64, 0x37, 0x70, 0x44,
+    0x36, 0x6b, 0x68, 0x2f, 0x39, 0x74, 0x69, 0x2b, 0x49, 0x32, 0x30, 0x65,
+    0x76, 0x39, 0x45, 0x32, 0x62, 0x46, 0x68, 0x63, 0x38, 0x65, 0x36, 0x6b,
+    0x47, 0x56, 0x51, 0x61, 0x39, 0x51, 0x50, 0x53, 0x64, 0x75, 0x62, 0x68,
+    0x6a, 0x4c, 0x30, 0x38, 0x73, 0x39, 0x4e, 0x49, 0x53, 0x2b, 0x4c, 0x49,
+    0x2b, 0x48, 0x2b, 0x53, 0x0a, 0x71, 0x48, 0x5a, 0x47, 0x6e, 0x45, 0x4a,
+    0x6c, 0x50, 0x71, 0x51, 0x65, 0x77, 0x51, 0x63, 0x44, 0x57, 0x6b, 0x59,
+    0x74, 0x75, 0x4a, 0x66, 0x7a, 0x74, 0x39, 0x57, 0x79, 0x56, 0x53, 0x48,
+    0x76, 0x75, 0x74, 0x78, 0x4d, 0x41, 0x4a, 0x66, 0x37, 0x46, 0x4a, 0x55,
+    0x6e, 0x4d, 0x37, 0x2f, 0x6f, 0x51, 0x30, 0x64, 0x47, 0x30, 0x67, 0x69,
+    0x5a, 0x46, 0x6d, 0x41, 0x37, 0x6d, 0x6e, 0x37, 0x53, 0x0a, 0x35, 0x75,
+    0x30, 0x34, 0x36, 0x75, 0x77, 0x42, 0x48, 0x6a, 0x78, 0x49, 0x56, 0x6b,
+    0x6b, 0x4a, 0x78, 0x30, 0x77, 0x33, 0x41, 0x4a, 0x36, 0x49, 0x44, 0x73,
+    0x42, 0x7a, 0x34, 0x57, 0x39, 0x6d, 0x36, 0x58, 0x4a, 0x48, 0x4d, 0x44,
+    0x34, 0x51, 0x35, 0x51, 0x73, 0x44, 0x79, 0x5a, 0x70, 0x43, 0x41, 0x47,
+    0x7a, 0x46, 0x6c, 0x48, 0x35, 0x68, 0x78, 0x49, 0x72, 0x66, 0x66, 0x34,
+    0x49, 0x61, 0x0a, 0x43, 0x31, 0x6e, 0x45, 0x57, 0x54, 0x4a, 0x33, 0x73,
+    0x37, 0x78, 0x67, 0x61, 0x56, 0x59, 0x35, 0x2f, 0x62, 0x51, 0x47, 0x65,
+    0x79, 0x7a, 0x57, 0x5a, 0x44, 0x62, 0x5a, 0x76, 0x55, 0x6a, 0x74, 0x68,
+    0x42, 0x39, 0x2b, 0x70, 0x53, 0x4b, 0x50, 0x4b, 0x72, 0x68, 0x43, 0x39,
+    0x49, 0x4b, 0x33, 0x31, 0x46, 0x4f, 0x51, 0x65, 0x45, 0x34, 0x74, 0x47,
+    0x76, 0x32, 0x42, 0x62, 0x30, 0x54, 0x58, 0x0a, 0x4f, 0x77, 0x46, 0x30,
+    0x6c, 0x6b, 0x4c, 0x67, 0x41, 0x4f, 0x49, 0x75, 0x61, 0x2b, 0x72, 0x46,
+    0x37, 0x6e, 0x4b, 0x73, 0x75, 0x37, 0x2f, 0x2b, 0x36, 0x71, 0x71, 0x6f,
+    0x2b, 0x4e, 0x7a, 0x32, 0x73, 0x6e, 0x6d, 0x4b, 0x74, 0x6d, 0x63, 0x43,
+    0x41, 0x77, 0x45, 0x41, 0x41, 0x61, 0x4e, 0x43, 0x4d, 0x45, 0x41, 0x77,
+    0x48, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45,
+    0x0a, 0x46, 0x4a, 0x33, 0x41, 0x5a, 0x36, 0x59, 0x4d, 0x49, 0x74, 0x6b,
+    0x6d, 0x39, 0x55, 0x57, 0x72, 0x70, 0x6d, 0x56, 0x53, 0x45, 0x53, 0x66,
+    0x59, 0x52, 0x61, 0x78, 0x6a, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d,
+    0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x50, 0x41, 0x51, 0x48, 0x2f, 0x0a, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67,
+    0x45, 0x47, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
+    0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x44, 0x41, 0x55, 0x41, 0x41, 0x34,
+    0x49, 0x43, 0x41, 0x51, 0x43, 0x7a, 0x56, 0x30, 0x30, 0x51, 0x59, 0x6b,
+    0x34, 0x36, 0x35, 0x4b, 0x7a, 0x71, 0x75, 0x42, 0x79, 0x76, 0x4d, 0x69,
+    0x50, 0x49, 0x73, 0x30, 0x6c, 0x61, 0x55, 0x5a, 0x78, 0x32, 0x0a, 0x4b,
+    0x49, 0x31, 0x35, 0x71, 0x6c, 0x64, 0x47, 0x46, 0x39, 0x58, 0x31, 0x55,
+    0x76, 0x61, 0x33, 0x52, 0x4f, 0x67, 0x49, 0x52, 0x4c, 0x38, 0x59, 0x68,
+    0x4e, 0x49, 0x4c, 0x67, 0x4d, 0x33, 0x46, 0x45, 0x76, 0x30, 0x41, 0x56,
+    0x51, 0x56, 0x68, 0x68, 0x30, 0x48, 0x63, 0x74, 0x53, 0x53, 0x65, 0x50,
+    0x4d, 0x54, 0x59, 0x79, 0x50, 0x74, 0x77, 0x6e, 0x69, 0x39, 0x34, 0x6c,
+    0x6f, 0x4d, 0x67, 0x0a, 0x4e, 0x74, 0x35, 0x38, 0x44, 0x32, 0x6b, 0x54,
+    0x69, 0x4b, 0x56, 0x31, 0x4e, 0x70, 0x67, 0x49, 0x70, 0x73, 0x62, 0x66,
+    0x72, 0x4d, 0x37, 0x6a, 0x57, 0x4e, 0x61, 0x33, 0x50, 0x74, 0x36, 0x36,
+    0x38, 0x2b, 0x73, 0x30, 0x51, 0x4e, 0x69, 0x69, 0x67, 0x66, 0x56, 0x34,
+    0x50, 0x79, 0x2f, 0x56, 0x70, 0x66, 0x7a, 0x5a, 0x6f, 0x74, 0x52, 0x65,
+    0x42, 0x41, 0x34, 0x58, 0x72, 0x66, 0x35, 0x42, 0x0a, 0x38, 0x4f, 0x57,
+    0x79, 0x63, 0x76, 0x70, 0x45, 0x67, 0x6a, 0x4e, 0x43, 0x36, 0x43, 0x31,
+    0x59, 0x39, 0x31, 0x61, 0x4d, 0x59, 0x6a, 0x2b, 0x36, 0x51, 0x72, 0x43,
+    0x63, 0x44, 0x46, 0x78, 0x2b, 0x4c, 0x6d, 0x55, 0x6d, 0x58, 0x46, 0x4e,
+    0x50, 0x41, 0x4c, 0x4a, 0x34, 0x66, 0x71, 0x45, 0x4e, 0x6d, 0x53, 0x32,
+    0x4e, 0x75, 0x42, 0x32, 0x4f, 0x6f, 0x73, 0x53, 0x77, 0x2f, 0x57, 0x44,
+    0x51, 0x0a, 0x4d, 0x4b, 0x53, 0x4f, 0x79, 0x41, 0x52, 0x69, 0x71, 0x63,
+    0x54, 0x74, 0x4e, 0x64, 0x35, 0x36, 0x6c, 0x2b, 0x30, 0x4f, 0x4f, 0x46,
+    0x36, 0x53, 0x4c, 0x35, 0x4e, 0x77, 0x70, 0x61, 0x6d, 0x63, 0x62, 0x36,
+    0x64, 0x39, 0x45, 0x78, 0x31, 0x2b, 0x78, 0x67, 0x68, 0x49, 0x73, 0x56,
+    0x35, 0x6e, 0x36, 0x31, 0x45, 0x49, 0x4a, 0x65, 0x6e, 0x6d, 0x4a, 0x57,
+    0x74, 0x53, 0x4b, 0x5a, 0x47, 0x63, 0x0a, 0x30, 0x6a, 0x6c, 0x7a, 0x43,
+    0x46, 0x66, 0x65, 0x6d, 0x51, 0x61, 0x30, 0x57, 0x35, 0x30, 0x51, 0x42,
+    0x75, 0x48, 0x43, 0x41, 0x4b, 0x69, 0x34, 0x48, 0x45, 0x6f, 0x43, 0x43,
+    0x68, 0x54, 0x51, 0x77, 0x55, 0x48, 0x4b, 0x2b, 0x34, 0x77, 0x31, 0x49,
+    0x58, 0x32, 0x43, 0x4f, 0x50, 0x4b, 0x70, 0x56, 0x4a, 0x45, 0x5a, 0x4e,
+    0x5a, 0x4f, 0x55, 0x62, 0x57, 0x6f, 0x36, 0x78, 0x62, 0x4c, 0x51, 0x0a,
+    0x75, 0x34, 0x6d, 0x47, 0x6b, 0x2b, 0x69, 0x62, 0x79, 0x51, 0x38, 0x36,
+    0x70, 0x33, 0x71, 0x34, 0x6f, 0x66, 0x42, 0x34, 0x52, 0x76, 0x72, 0x38,
+    0x4e, 0x79, 0x2f, 0x6c, 0x69, 0x6f, 0x54, 0x7a, 0x33, 0x2f, 0x34, 0x45,
+    0x32, 0x61, 0x46, 0x6f, 0x6f, 0x43, 0x38, 0x6b, 0x34, 0x67, 0x6d, 0x56,
+    0x42, 0x74, 0x57, 0x56, 0x79, 0x75, 0x45, 0x6b, 0x6c, 0x75, 0x74, 0x38,
+    0x39, 0x70, 0x4d, 0x46, 0x0a, 0x75, 0x2b, 0x31, 0x7a, 0x36, 0x53, 0x33,
+    0x52, 0x64, 0x54, 0x6e, 0x58, 0x35, 0x79, 0x54, 0x62, 0x32, 0x45, 0x35,
+    0x66, 0x51, 0x34, 0x2b, 0x65, 0x30, 0x42, 0x51, 0x35, 0x76, 0x31, 0x56,
+    0x77, 0x53, 0x4a, 0x6c, 0x58, 0x4d, 0x62, 0x53, 0x63, 0x37, 0x6b, 0x71,
+    0x59, 0x41, 0x35, 0x59, 0x77, 0x48, 0x32, 0x41, 0x47, 0x37, 0x68, 0x73,
+    0x6a, 0x2f, 0x6f, 0x46, 0x67, 0x49, 0x78, 0x70, 0x48, 0x0a, 0x59, 0x6f,
+    0x57, 0x6c, 0x7a, 0x42, 0x6b, 0x30, 0x67, 0x47, 0x2b, 0x7a, 0x72, 0x42,
+    0x72, 0x6a, 0x6e, 0x2f, 0x42, 0x37, 0x53, 0x4b, 0x33, 0x56, 0x41, 0x64,
+    0x6c, 0x6e, 0x74, 0x71, 0x6c, 0x79, 0x6b, 0x2b, 0x6f, 0x74, 0x5a, 0x72,
+    0x57, 0x79, 0x75, 0x4f, 0x51, 0x39, 0x50, 0x4c, 0x4c, 0x76, 0x54, 0x49,
+    0x7a, 0x71, 0x36, 0x77, 0x65, 0x2f, 0x71, 0x7a, 0x57, 0x61, 0x56, 0x59,
+    0x61, 0x38, 0x0a, 0x47, 0x4b, 0x61, 0x31, 0x71, 0x46, 0x36, 0x30, 0x67,
+    0x32, 0x78, 0x72, 0x61, 0x55, 0x44, 0x54, 0x6e, 0x39, 0x7a, 0x78, 0x77,
+    0x32, 0x6c, 0x72, 0x75, 0x65, 0x46, 0x74, 0x43, 0x66, 0x54, 0x78, 0x71,
+    0x6c, 0x42, 0x32, 0x43, 0x6e, 0x70, 0x39, 0x65, 0x68, 0x65, 0x68, 0x56,
+    0x5a, 0x5a, 0x43, 0x6d, 0x54, 0x45, 0x4a, 0x33, 0x57, 0x41, 0x52, 0x6a,
+    0x51, 0x55, 0x77, 0x66, 0x75, 0x61, 0x4f, 0x0a, 0x52, 0x74, 0x47, 0x64,
+    0x46, 0x4e, 0x72, 0x48, 0x46, 0x2b, 0x51, 0x46, 0x6c, 0x6f, 0x7a, 0x45,
+    0x4a, 0x4c, 0x55, 0x62, 0x7a, 0x78, 0x51, 0x48, 0x73, 0x6b, 0x44, 0x34,
+    0x6f, 0x35, 0x35, 0x42, 0x68, 0x72, 0x77, 0x45, 0x30, 0x47, 0x75, 0x57,
+    0x79, 0x43, 0x71, 0x41, 0x4e, 0x50, 0x32, 0x2f, 0x37, 0x77, 0x61, 0x6a,
+    0x33, 0x56, 0x6a, 0x46, 0x68, 0x54, 0x30, 0x2b, 0x6a, 0x2f, 0x36, 0x65,
+    0x0a, 0x4b, 0x65, 0x43, 0x32, 0x75, 0x41, 0x6c, 0x6f, 0x47, 0x52, 0x77,
+    0x59, 0x51, 0x77, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41,
+    0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49,
+    0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x41, 0x66,
+    0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72,
+    0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x45, 0x43, 0x43, 0x20, 0x4f, 0x3d,
+    0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x0a,
+    0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x45, 0x43,
+    0x43, 0x20, 0x4f, 0x3d, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72,
+    0x75, 0x73, 0x74, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a,
+    0x20, 0x22, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6d, 0x54, 0x72, 0x75, 0x73,
+    0x74, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x45, 0x43,
+    0x43, 0x22, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a,
+    0x20, 0x38, 0x34, 0x30, 0x31, 0x32, 0x32, 0x34, 0x39, 0x30, 0x37, 0x38,
+    0x36, 0x31, 0x34, 0x39, 0x30, 0x32, 0x36, 0x30, 0x0a, 0x23, 0x20, 0x4d,
+    0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69,
+    0x6e, 0x74, 0x3a, 0x20, 0x36, 0x34, 0x3a, 0x62, 0x30, 0x3a, 0x30, 0x39,
+    0x3a, 0x35, 0x35, 0x3a, 0x63, 0x66, 0x3a, 0x62, 0x31, 0x3a, 0x64, 0x35,
+    0x3a, 0x39, 0x39, 0x3a, 0x65, 0x32, 0x3a, 0x62, 0x65, 0x3a, 0x31, 0x33,
+    0x3a, 0x61, 0x62, 0x3a, 0x61, 0x36, 0x3a, 0x35, 0x64, 0x3a, 0x65, 0x61,
+    0x3a, 0x34, 0x64, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20, 0x46,
+    0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20,
+    0x62, 0x38, 0x3a, 0x32, 0x33, 0x3a, 0x36, 0x62, 0x3a, 0x30, 0x30, 0x3a,
+    0x32, 0x66, 0x3a, 0x31, 0x64, 0x3a, 0x31, 0x36, 0x3a, 0x38, 0x36, 0x3a,
+    0x35, 0x33, 0x3a, 0x30, 0x31, 0x3a, 0x35, 0x35, 0x3a, 0x36, 0x63, 0x3a,
+    0x31, 0x31, 0x3a, 0x61, 0x34, 0x3a, 0x33, 0x37, 0x3a, 0x63, 0x61, 0x3a,
+    0x65, 0x62, 0x3a, 0x66, 0x66, 0x3a, 0x63, 0x33, 0x3a, 0x62, 0x62, 0x0a,
+    0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69, 0x6e,
+    0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x62, 0x64,
+    0x3a, 0x37, 0x31, 0x3a, 0x66, 0x64, 0x3a, 0x66, 0x36, 0x3a, 0x64, 0x61,
+    0x3a, 0x39, 0x37, 0x3a, 0x65, 0x34, 0x3a, 0x63, 0x66, 0x3a, 0x36, 0x32,
+    0x3a, 0x64, 0x31, 0x3a, 0x36, 0x34, 0x3a, 0x37, 0x61, 0x3a, 0x64, 0x64,
+    0x3a, 0x32, 0x35, 0x3a, 0x38, 0x31, 0x3a, 0x62, 0x30, 0x3a, 0x37, 0x64,
+    0x3a, 0x37, 0x39, 0x3a, 0x61, 0x64, 0x3a, 0x66, 0x38, 0x3a, 0x33, 0x39,
+    0x3a, 0x37, 0x65, 0x3a, 0x62, 0x34, 0x3a, 0x65, 0x63, 0x3a, 0x62, 0x61,
+    0x3a, 0x39, 0x63, 0x3a, 0x35, 0x65, 0x3a, 0x38, 0x34, 0x3a, 0x38, 0x38,
+    0x3a, 0x38, 0x32, 0x3a, 0x31, 0x34, 0x3a, 0x32, 0x33, 0x0a, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+    0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, 0x2f, 0x6a, 0x43, 0x43, 0x41, 0x59,
+    0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x49, 0x64, 0x4a,
+    0x63, 0x6c, 0x69, 0x73, 0x63, 0x2f, 0x65, 0x6c, 0x51, 0x77, 0x43, 0x67,
+    0x59, 0x49, 0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x45, 0x41, 0x77,
+    0x4d, 0x77, 0x52, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x0a, 0x56, 0x56, 0x4d, 0x78, 0x46,
+    0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x43,
+    0x30, 0x46, 0x6d, 0x5a, 0x6d, 0x6c, 0x79, 0x62, 0x56, 0x52, 0x79, 0x64,
+    0x58, 0x4e, 0x30, 0x4d, 0x53, 0x41, 0x77, 0x48, 0x67, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x44, 0x44, 0x42, 0x64, 0x42, 0x5a, 0x6d, 0x5a, 0x70, 0x63,
+    0x6d, 0x31, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x51, 0x0a,
+    0x63, 0x6d, 0x56, 0x74, 0x61, 0x58, 0x56, 0x74, 0x49, 0x45, 0x56, 0x44,
+    0x51, 0x7a, 0x41, 0x65, 0x46, 0x77, 0x30, 0x78, 0x4d, 0x44, 0x41, 0x78,
+    0x4d, 0x6a, 0x6b, 0x78, 0x4e, 0x44, 0x49, 0x77, 0x4d, 0x6a, 0x52, 0x61,
+    0x46, 0x77, 0x30, 0x30, 0x4d, 0x44, 0x45, 0x79, 0x4d, 0x7a, 0x45, 0x78,
+    0x4e, 0x44, 0x49, 0x77, 0x4d, 0x6a, 0x52, 0x61, 0x4d, 0x45, 0x55, 0x78,
+    0x43, 0x7a, 0x41, 0x4a, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59,
+    0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x41, 0x74, 0x42, 0x5a, 0x6d, 0x5a,
+    0x70, 0x63, 0x6d, 0x31, 0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x44, 0x45,
+    0x67, 0x4d, 0x42, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77,
+    0x58, 0x51, 0x57, 0x5a, 0x6d, 0x61, 0x58, 0x4a, 0x74, 0x0a, 0x56, 0x48,
+    0x4a, 0x31, 0x63, 0x33, 0x51, 0x67, 0x55, 0x48, 0x4a, 0x6c, 0x62, 0x57,
+    0x6c, 0x31, 0x62, 0x53, 0x42, 0x46, 0x51, 0x30, 0x4d, 0x77, 0x64, 0x6a,
+    0x41, 0x51, 0x42, 0x67, 0x63, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51,
+    0x49, 0x42, 0x42, 0x67, 0x55, 0x72, 0x67, 0x51, 0x51, 0x41, 0x49, 0x67,
+    0x4e, 0x69, 0x41, 0x41, 0x51, 0x4e, 0x4d, 0x46, 0x34, 0x62, 0x46, 0x5a,
+    0x30, 0x44, 0x0a, 0x30, 0x4b, 0x46, 0x35, 0x4e, 0x62, 0x63, 0x36, 0x50,
+    0x4a, 0x4a, 0x36, 0x79, 0x68, 0x55, 0x63, 0x7a, 0x57, 0x4c, 0x7a, 0x6e,
+    0x43, 0x5a, 0x63, 0x42, 0x7a, 0x33, 0x6c, 0x56, 0x50, 0x71, 0x6a, 0x31,
+    0x73, 0x77, 0x53, 0x36, 0x76, 0x51, 0x55, 0x58, 0x2b, 0x69, 0x4f, 0x47,
+    0x61, 0x73, 0x76, 0x4c, 0x6b, 0x6a, 0x6d, 0x72, 0x42, 0x68, 0x44, 0x65,
+    0x4b, 0x7a, 0x51, 0x4e, 0x38, 0x4f, 0x39, 0x0a, 0x73, 0x73, 0x30, 0x73,
+    0x35, 0x6b, 0x66, 0x69, 0x47, 0x75, 0x5a, 0x6a, 0x75, 0x44, 0x30, 0x75,
+    0x4c, 0x33, 0x6a, 0x45, 0x54, 0x39, 0x76, 0x30, 0x44, 0x36, 0x52, 0x6f,
+    0x54, 0x46, 0x56, 0x79, 0x61, 0x35, 0x55, 0x64, 0x54, 0x68, 0x68, 0x43,
+    0x6c, 0x58, 0x6a, 0x4d, 0x4e, 0x7a, 0x79, 0x52, 0x34, 0x70, 0x74, 0x6c,
+    0x4b, 0x79, 0x6d, 0x6a, 0x51, 0x6a, 0x42, 0x41, 0x4d, 0x42, 0x30, 0x47,
+    0x0a, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53,
+    0x61, 0x72, 0x79, 0x6c, 0x36, 0x77, 0x42, 0x45, 0x31, 0x4e, 0x53, 0x5a,
+    0x52, 0x4d, 0x41, 0x44, 0x44, 0x61, 0x76, 0x35, 0x41, 0x31, 0x61, 0x37,
+    0x57, 0x50, 0x44, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48,
+    0x2f, 0x4d, 0x41, 0x34, 0x47, 0x0a, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77,
+    0x45, 0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a,
+    0x41, 0x4b, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51,
+    0x51, 0x44, 0x41, 0x77, 0x4e, 0x6e, 0x41, 0x44, 0x42, 0x6b, 0x41, 0x6a,
+    0x41, 0x58, 0x43, 0x66, 0x4f, 0x48, 0x69, 0x46, 0x42, 0x61, 0x72, 0x38,
+    0x6a, 0x41, 0x51, 0x72, 0x39, 0x48, 0x58, 0x2f, 0x56, 0x73, 0x0a, 0x61,
+    0x6f, 0x62, 0x67, 0x78, 0x43, 0x64, 0x30, 0x35, 0x44, 0x68, 0x54, 0x31,
+    0x77, 0x56, 0x2f, 0x47, 0x7a, 0x54, 0x6a, 0x78, 0x69, 0x2b, 0x7a, 0x79,
+    0x67, 0x6b, 0x38, 0x4e, 0x35, 0x33, 0x58, 0x35, 0x37, 0x68, 0x47, 0x38,
+    0x66, 0x32, 0x68, 0x34, 0x6e, 0x45, 0x43, 0x4d, 0x45, 0x4a, 0x5a, 0x68,
+    0x30, 0x50, 0x55, 0x55, 0x64, 0x2b, 0x36, 0x30, 0x77, 0x6b, 0x79, 0x57,
+    0x73, 0x36, 0x49, 0x0a, 0x66, 0x6c, 0x63, 0x39, 0x6e, 0x46, 0x39, 0x43,
+    0x61, 0x2f, 0x55, 0x48, 0x4c, 0x62, 0x58, 0x77, 0x67, 0x70, 0x50, 0x35,
+    0x57, 0x57, 0x2b, 0x75, 0x5a, 0x50, 0x70, 0x59, 0x35, 0x59, 0x73, 0x65,
+    0x34, 0x32, 0x4f, 0x2b, 0x74, 0x59, 0x48, 0x4e, 0x62, 0x77, 0x4b, 0x4d,
+    0x65, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e,
+    0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x73,
+    0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x53, 0x74, 0x61,
+    0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f, 0x3d, 0x53, 0x74, 0x61, 0x72,
+    0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x20, 0x4f, 0x55,
+    0x3d, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69,
+    0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x0a,
+    0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x43,
+    0x4e, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x4f,
+    0x3d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74,
+    0x64, 0x2e, 0x20, 0x4f, 0x55, 0x3d, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
+    0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67,
+    0x6e, 0x69, 0x6e, 0x67, 0x0a, 0x23, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+    0x3a, 0x20, 0x22, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22,
+    0x0a, 0x23, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x34,
+    0x35, 0x0a, 0x23, 0x20, 0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67,
+    0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x39, 0x3a,
+    0x33, 0x62, 0x3a, 0x30, 0x64, 0x3a, 0x38, 0x34, 0x3a, 0x34, 0x31, 0x3a,
+    0x66, 0x63, 0x3a, 0x61, 0x34, 0x3a, 0x37, 0x36, 0x3a, 0x37, 0x39, 0x3a,
+    0x32, 0x33, 0x3a, 0x30, 0x38, 0x3a, 0x35, 0x37, 0x3a, 0x64, 0x65, 0x3a,
+    0x31, 0x30, 0x3a, 0x31, 0x39, 0x3a, 0x31, 0x36, 0x0a, 0x23, 0x20, 0x53,
+    0x48, 0x41, 0x31, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x61, 0x33, 0x3a, 0x66, 0x31, 0x3a, 0x33,
+    0x33, 0x3a, 0x33, 0x66, 0x3a, 0x65, 0x32, 0x3a, 0x34, 0x32, 0x3a, 0x62,
+    0x66, 0x3a, 0x63, 0x66, 0x3a, 0x63, 0x35, 0x3a, 0x64, 0x31, 0x3a, 0x34,
+    0x65, 0x3a, 0x38, 0x66, 0x3a, 0x33, 0x39, 0x3a, 0x34, 0x32, 0x3a, 0x39,
+    0x38, 0x3a, 0x34, 0x30, 0x3a, 0x36, 0x38, 0x3a, 0x31, 0x30, 0x3a, 0x64,
+    0x31, 0x3a, 0x61, 0x30, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35,
+    0x36, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
+    0x74, 0x3a, 0x20, 0x65, 0x31, 0x3a, 0x37, 0x38, 0x3a, 0x39, 0x30, 0x3a,
+    0x65, 0x65, 0x3a, 0x30, 0x39, 0x3a, 0x61, 0x33, 0x3a, 0x66, 0x62, 0x3a,
+    0x66, 0x34, 0x3a, 0x66, 0x34, 0x3a, 0x38, 0x62, 0x3a, 0x39, 0x63, 0x3a,
+    0x34, 0x31, 0x3a, 0x34, 0x61, 0x3a, 0x31, 0x37, 0x3a, 0x64, 0x36, 0x3a,
+    0x33, 0x37, 0x3a, 0x62, 0x37, 0x3a, 0x61, 0x35, 0x3a, 0x30, 0x36, 0x3a,
+    0x34, 0x37, 0x3a, 0x65, 0x39, 0x3a, 0x62, 0x63, 0x3a, 0x37, 0x35, 0x3a,
+    0x32, 0x33, 0x3a, 0x32, 0x32, 0x3a, 0x37, 0x32, 0x3a, 0x37, 0x66, 0x3a,
+    0x63, 0x63, 0x3a, 0x31, 0x37, 0x3a, 0x34, 0x32, 0x3a, 0x61, 0x39, 0x3a,
+    0x31, 0x31, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49,
+    0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54,
+    0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x48, 0x68,
+    0x7a, 0x43, 0x43, 0x42, 0x57, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41,
+    0x67, 0x49, 0x42, 0x4c, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68,
+    0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41,
+    0x44, 0x42, 0x39, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x4a, 0x54, 0x44, 0x45, 0x57, 0x0a,
+    0x4d, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e,
+    0x55, 0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67,
+    0x54, 0x48, 0x52, 0x6b, 0x4c, 0x6a, 0x45, 0x72, 0x4d, 0x43, 0x6b, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x69, 0x55, 0x32, 0x56, 0x6a,
+    0x64, 0x58, 0x4a, 0x6c, 0x49, 0x45, 0x52, 0x70, 0x5a, 0x32, 0x6c, 0x30,
+    0x59, 0x57, 0x77, 0x67, 0x0a, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c,
+    0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x55, 0x67, 0x55, 0x32, 0x6c,
+    0x6e, 0x62, 0x6d, 0x6c, 0x75, 0x5a, 0x7a, 0x45, 0x70, 0x4d, 0x43, 0x63,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x67, 0x55, 0x33, 0x52,
+    0x68, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67, 0x51, 0x32, 0x56,
+    0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x0a, 0x64, 0x47,
+    0x6c, 0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33,
+    0x4a, 0x70, 0x64, 0x48, 0x6b, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x44,
+    0x59, 0x77, 0x4f, 0x54, 0x45, 0x33, 0x4d, 0x54, 0x6b, 0x30, 0x4e, 0x6a,
+    0x4d, 0x33, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x59, 0x77, 0x4f, 0x54,
+    0x45, 0x33, 0x4d, 0x54, 0x6b, 0x30, 0x4e, 0x6a, 0x4d, 0x32, 0x57, 0x6a,
+    0x42, 0x39, 0x0a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x4a, 0x54, 0x44, 0x45, 0x57, 0x4d,
+    0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x55,
+    0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67, 0x54,
+    0x48, 0x52, 0x6b, 0x4c, 0x6a, 0x45, 0x72, 0x4d, 0x43, 0x6b, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x43, 0x78, 0x4d, 0x69, 0x0a, 0x55, 0x32, 0x56, 0x6a,
+    0x64, 0x58, 0x4a, 0x6c, 0x49, 0x45, 0x52, 0x70, 0x5a, 0x32, 0x6c, 0x30,
+    0x59, 0x57, 0x77, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d,
+    0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x55, 0x67, 0x55, 0x32, 0x6c, 0x6e,
+    0x62, 0x6d, 0x6c, 0x75, 0x5a, 0x7a, 0x45, 0x70, 0x4d, 0x43, 0x63, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x67, 0x55, 0x33, 0x52, 0x68,
+    0x0a, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67, 0x51, 0x32, 0x56,
+    0x79, 0x64, 0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c,
+    0x76, 0x62, 0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a,
+    0x70, 0x64, 0x48, 0x6b, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4d, 0x41, 0x30,
+    0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45,
+    0x42, 0x41, 0x51, 0x55, 0x41, 0x0a, 0x41, 0x34, 0x49, 0x43, 0x44, 0x77,
+    0x41, 0x77, 0x67, 0x67, 0x49, 0x4b, 0x41, 0x6f, 0x49, 0x43, 0x41, 0x51,
+    0x44, 0x42, 0x69, 0x4e, 0x73, 0x4a, 0x76, 0x47, 0x78, 0x47, 0x66, 0x48,
+    0x69, 0x66, 0x6c, 0x58, 0x75, 0x31, 0x4d, 0x35, 0x44, 0x79, 0x63, 0x6d,
+    0x4c, 0x57, 0x77, 0x54, 0x59, 0x67, 0x49, 0x69, 0x52, 0x65, 0x7a, 0x75,
+    0x6c, 0x33, 0x38, 0x6b, 0x4d, 0x4b, 0x6f, 0x67, 0x5a, 0x6b, 0x0a, 0x70,
+    0x4d, 0x79, 0x4f, 0x4e, 0x76, 0x67, 0x34, 0x35, 0x69, 0x50, 0x77, 0x62,
+    0x6d, 0x32, 0x78, 0x50, 0x4e, 0x31, 0x79, 0x6f, 0x34, 0x55, 0x63, 0x6f,
+    0x64, 0x4d, 0x39, 0x74, 0x44, 0x4d, 0x72, 0x30, 0x79, 0x2b, 0x76, 0x2f,
+    0x75, 0x71, 0x77, 0x51, 0x56, 0x6c, 0x6e, 0x74, 0x73, 0x51, 0x47, 0x66,
+    0x51, 0x71, 0x65, 0x64, 0x49, 0x58, 0x57, 0x65, 0x55, 0x79, 0x41, 0x4e,
+    0x33, 0x72, 0x66, 0x0a, 0x4f, 0x51, 0x56, 0x53, 0x57, 0x66, 0x66, 0x30,
+    0x47, 0x30, 0x5a, 0x44, 0x70, 0x4e, 0x4b, 0x46, 0x68, 0x64, 0x4c, 0x44,
+    0x63, 0x66, 0x4e, 0x31, 0x59, 0x6a, 0x53, 0x36, 0x4c, 0x49, 0x70, 0x2f,
+    0x48, 0x6f, 0x2f, 0x75, 0x37, 0x54, 0x54, 0x51, 0x45, 0x63, 0x65, 0x57,
+    0x7a, 0x56, 0x49, 0x39, 0x75, 0x6a, 0x50, 0x57, 0x33, 0x55, 0x33, 0x65,
+    0x43, 0x7a, 0x74, 0x4b, 0x53, 0x35, 0x2f, 0x43, 0x0a, 0x4a, 0x69, 0x2f,
+    0x36, 0x74, 0x52, 0x59, 0x63, 0x63, 0x6a, 0x56, 0x33, 0x79, 0x6a, 0x78,
+    0x64, 0x35, 0x73, 0x72, 0x68, 0x4a, 0x6f, 0x73, 0x61, 0x4e, 0x6e, 0x5a,
+    0x63, 0x41, 0x64, 0x74, 0x30, 0x46, 0x43, 0x58, 0x2b, 0x37, 0x62, 0x57,
+    0x67, 0x69, 0x41, 0x2f, 0x64, 0x65, 0x4d, 0x6f, 0x74, 0x48, 0x77, 0x65,
+    0x58, 0x4d, 0x41, 0x45, 0x74, 0x63, 0x6e, 0x6e, 0x36, 0x52, 0x74, 0x59,
+    0x54, 0x0a, 0x4b, 0x71, 0x69, 0x35, 0x70, 0x71, 0x75, 0x44, 0x53, 0x52,
+    0x33, 0x6c, 0x38, 0x75, 0x2f, 0x64, 0x35, 0x41, 0x47, 0x4f, 0x47, 0x41,
+    0x71, 0x50, 0x59, 0x31, 0x4d, 0x57, 0x68, 0x57, 0x4b, 0x70, 0x44, 0x68,
+    0x6b, 0x36, 0x7a, 0x4c, 0x56, 0x6d, 0x70, 0x73, 0x4a, 0x72, 0x64, 0x41,
+    0x66, 0x6b, 0x4b, 0x2b, 0x46, 0x32, 0x50, 0x72, 0x52, 0x74, 0x32, 0x50,
+    0x5a, 0x45, 0x34, 0x58, 0x4e, 0x69, 0x0a, 0x48, 0x7a, 0x76, 0x45, 0x76,
+    0x71, 0x42, 0x54, 0x56, 0x69, 0x56, 0x73, 0x55, 0x51, 0x6e, 0x33, 0x71,
+    0x71, 0x76, 0x4b, 0x76, 0x33, 0x62, 0x39, 0x62, 0x5a, 0x76, 0x7a, 0x6e,
+    0x64, 0x75, 0x2f, 0x50, 0x57, 0x61, 0x38, 0x44, 0x46, 0x61, 0x71, 0x72,
+    0x35, 0x68, 0x49, 0x6c, 0x54, 0x70, 0x4c, 0x33, 0x36, 0x64, 0x59, 0x55,
+    0x4e, 0x6b, 0x34, 0x64, 0x61, 0x6c, 0x62, 0x36, 0x6b, 0x4d, 0x4d, 0x0a,
+    0x41, 0x76, 0x2b, 0x5a, 0x36, 0x2b, 0x68, 0x73, 0x54, 0x58, 0x42, 0x62,
+    0x4b, 0x57, 0x57, 0x63, 0x33, 0x61, 0x70, 0x64, 0x7a, 0x4b, 0x38, 0x42,
+    0x4d, 0x65, 0x77, 0x4d, 0x36, 0x39, 0x4b, 0x4e, 0x36, 0x4f, 0x71, 0x63,
+    0x65, 0x2b, 0x5a, 0x75, 0x39, 0x79, 0x64, 0x6d, 0x44, 0x42, 0x70, 0x49,
+    0x31, 0x32, 0x35, 0x43, 0x34, 0x7a, 0x2f, 0x65, 0x49, 0x54, 0x35, 0x37,
+    0x34, 0x51, 0x31, 0x77, 0x0a, 0x2b, 0x32, 0x4f, 0x71, 0x71, 0x47, 0x77,
+    0x61, 0x56, 0x4c, 0x52, 0x63, 0x4a, 0x58, 0x72, 0x4a, 0x6f, 0x73, 0x6d,
+    0x4c, 0x46, 0x71, 0x61, 0x37, 0x4c, 0x48, 0x34, 0x58, 0x58, 0x67, 0x56,
+    0x4e, 0x57, 0x47, 0x34, 0x53, 0x48, 0x51, 0x48, 0x75, 0x45, 0x68, 0x41,
+    0x4e, 0x78, 0x6a, 0x4a, 0x2f, 0x47, 0x50, 0x2f, 0x38, 0x39, 0x50, 0x72,
+    0x4e, 0x62, 0x70, 0x48, 0x6f, 0x4e, 0x6b, 0x6d, 0x2b, 0x0a, 0x47, 0x6b,
+    0x68, 0x70, 0x69, 0x38, 0x4b, 0x57, 0x54, 0x52, 0x6f, 0x53, 0x73, 0x6d,
+    0x6b, 0x58, 0x77, 0x51, 0x71, 0x51, 0x31, 0x76, 0x70, 0x35, 0x49, 0x6b,
+    0x69, 0x2f, 0x75, 0x6e, 0x74, 0x70, 0x2b, 0x48, 0x44, 0x48, 0x2b, 0x6e,
+    0x6f, 0x33, 0x32, 0x4e, 0x67, 0x4e, 0x30, 0x6e, 0x5a, 0x50, 0x56, 0x2f,
+    0x2b, 0x51, 0x74, 0x2b, 0x4f, 0x52, 0x30, 0x74, 0x33, 0x76, 0x77, 0x6d,
+    0x43, 0x33, 0x0a, 0x5a, 0x7a, 0x72, 0x64, 0x2f, 0x71, 0x71, 0x63, 0x38,
+    0x4e, 0x53, 0x4c, 0x66, 0x33, 0x49, 0x69, 0x7a, 0x73, 0x61, 0x66, 0x6c,
+    0x37, 0x62, 0x34, 0x72, 0x34, 0x71, 0x67, 0x45, 0x4b, 0x6a, 0x5a, 0x2b,
+    0x78, 0x6a, 0x47, 0x74, 0x72, 0x56, 0x63, 0x55, 0x6a, 0x79, 0x4a, 0x74,
+    0x68, 0x6b, 0x71, 0x63, 0x77, 0x45, 0x4b, 0x44, 0x77, 0x4f, 0x7a, 0x45,
+    0x6d, 0x44, 0x79, 0x65, 0x69, 0x2b, 0x42, 0x0a, 0x32, 0x36, 0x4e, 0x75,
+    0x2f, 0x79, 0x59, 0x77, 0x6c, 0x2f, 0x57, 0x4c, 0x33, 0x59, 0x6c, 0x58,
+    0x74, 0x71, 0x30, 0x39, 0x73, 0x36, 0x38, 0x72, 0x78, 0x62, 0x64, 0x32,
+    0x41, 0x76, 0x43, 0x6c, 0x31, 0x69, 0x75, 0x61, 0x68, 0x68, 0x51, 0x71,
+    0x63, 0x76, 0x62, 0x6a, 0x4d, 0x34, 0x78, 0x64, 0x43, 0x55, 0x73, 0x54,
+    0x33, 0x37, 0x75, 0x4d, 0x64, 0x42, 0x4e, 0x53, 0x53, 0x77, 0x49, 0x44,
+    0x0a, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x34, 0x49, 0x43, 0x45, 0x44, 0x43,
+    0x43, 0x41, 0x67, 0x77, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30,
+    0x54, 0x41, 0x51, 0x48, 0x2f, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45,
+    0x42, 0x2f, 0x7a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x51, 0x59,
+    0x77, 0x48, 0x51, 0x59, 0x44, 0x0a, 0x56, 0x52, 0x30, 0x4f, 0x42, 0x42,
+    0x59, 0x45, 0x46, 0x45, 0x34, 0x4c, 0x37, 0x78, 0x71, 0x6b, 0x51, 0x46,
+    0x75, 0x6c, 0x46, 0x32, 0x6d, 0x48, 0x4d, 0x4d, 0x6f, 0x30, 0x61, 0x45,
+    0x50, 0x51, 0x51, 0x61, 0x37, 0x79, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31,
+    0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x45,
+    0x34, 0x4c, 0x37, 0x78, 0x71, 0x6b, 0x51, 0x46, 0x75, 0x6c, 0x0a, 0x46,
+    0x32, 0x6d, 0x48, 0x4d, 0x4d, 0x6f, 0x30, 0x61, 0x45, 0x50, 0x51, 0x51,
+    0x61, 0x37, 0x79, 0x4d, 0x49, 0x49, 0x42, 0x57, 0x67, 0x59, 0x44, 0x56,
+    0x52, 0x30, 0x67, 0x42, 0x49, 0x49, 0x42, 0x55, 0x54, 0x43, 0x43, 0x41,
+    0x55, 0x30, 0x77, 0x67, 0x67, 0x46, 0x4a, 0x42, 0x67, 0x73, 0x72, 0x42,
+    0x67, 0x45, 0x45, 0x41, 0x59, 0x47, 0x31, 0x4e, 0x77, 0x45, 0x42, 0x41,
+    0x54, 0x43, 0x43, 0x0a, 0x41, 0x54, 0x67, 0x77, 0x4c, 0x67, 0x59, 0x49,
+    0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48, 0x41, 0x67, 0x45, 0x57,
+    0x49, 0x6d, 0x68, 0x30, 0x64, 0x48, 0x41, 0x36, 0x4c, 0x79, 0x39, 0x33,
+    0x64, 0x33, 0x63, 0x75, 0x63, 0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x7a,
+    0x63, 0x32, 0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x33, 0x42, 0x76,
+    0x62, 0x47, 0x6c, 0x6a, 0x65, 0x53, 0x35, 0x77, 0x0a, 0x5a, 0x47, 0x59,
+    0x77, 0x4e, 0x41, 0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55,
+    0x48, 0x41, 0x67, 0x45, 0x57, 0x4b, 0x47, 0x68, 0x30, 0x64, 0x48, 0x41,
+    0x36, 0x4c, 0x79, 0x39, 0x33, 0x64, 0x33, 0x63, 0x75, 0x63, 0x33, 0x52,
+    0x68, 0x63, 0x6e, 0x52, 0x7a, 0x63, 0x32, 0x77, 0x75, 0x59, 0x32, 0x39,
+    0x74, 0x4c, 0x32, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x57, 0x56,
+    0x6b, 0x0a, 0x61, 0x57, 0x46, 0x30, 0x5a, 0x53, 0x35, 0x77, 0x5a, 0x47,
+    0x59, 0x77, 0x67, 0x63, 0x38, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51,
+    0x55, 0x46, 0x42, 0x77, 0x49, 0x43, 0x4d, 0x49, 0x48, 0x43, 0x4d, 0x43,
+    0x63, 0x57, 0x49, 0x46, 0x4e, 0x30, 0x59, 0x58, 0x4a, 0x30, 0x49, 0x45,
+    0x4e, 0x76, 0x62, 0x57, 0x31, 0x6c, 0x63, 0x6d, 0x4e, 0x70, 0x59, 0x57,
+    0x77, 0x67, 0x4b, 0x46, 0x4e, 0x30, 0x0a, 0x59, 0x58, 0x4a, 0x30, 0x51,
+    0x32, 0x39, 0x74, 0x4b, 0x53, 0x42, 0x4d, 0x64, 0x47, 0x51, 0x75, 0x4d,
+    0x41, 0x4d, 0x43, 0x41, 0x51, 0x45, 0x61, 0x67, 0x5a, 0x5a, 0x4d, 0x61,
+    0x57, 0x31, 0x70, 0x64, 0x47, 0x56, 0x6b, 0x49, 0x45, 0x78, 0x70, 0x59,
+    0x57, 0x4a, 0x70, 0x62, 0x47, 0x6c, 0x30, 0x65, 0x53, 0x77, 0x67, 0x63,
+    0x6d, 0x56, 0x68, 0x5a, 0x43, 0x42, 0x30, 0x61, 0x47, 0x55, 0x67, 0x0a,
+    0x63, 0x32, 0x56, 0x6a, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x41, 0x71,
+    0x54, 0x47, 0x56, 0x6e, 0x59, 0x57, 0x77, 0x67, 0x54, 0x47, 0x6c, 0x74,
+    0x61, 0x58, 0x52, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x6e, 0x4d, 0x71,
+    0x49, 0x47, 0x39, 0x6d, 0x49, 0x48, 0x52, 0x6f, 0x5a, 0x53, 0x42, 0x54,
+    0x64, 0x47, 0x46, 0x79, 0x64, 0x45, 0x4e, 0x76, 0x62, 0x53, 0x42, 0x44,
+    0x5a, 0x58, 0x4a, 0x30, 0x0a, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46,
+    0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68,
+    0x76, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x53, 0x42, 0x51, 0x62, 0x32, 0x78,
+    0x70, 0x59, 0x33, 0x6b, 0x67, 0x59, 0x58, 0x5a, 0x68, 0x61, 0x57, 0x78,
+    0x68, 0x59, 0x6d, 0x78, 0x6c, 0x49, 0x47, 0x46, 0x30, 0x49, 0x47, 0x68,
+    0x30, 0x64, 0x48, 0x41, 0x36, 0x4c, 0x79, 0x39, 0x33, 0x0a, 0x64, 0x33,
+    0x63, 0x75, 0x63, 0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x7a, 0x63, 0x32,
+    0x77, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x33, 0x42, 0x76, 0x62, 0x47,
+    0x6c, 0x6a, 0x65, 0x53, 0x35, 0x77, 0x5a, 0x47, 0x59, 0x77, 0x45, 0x51,
+    0x59, 0x4a, 0x59, 0x49, 0x5a, 0x49, 0x41, 0x59, 0x62, 0x34, 0x51, 0x67,
+    0x45, 0x42, 0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x41, 0x48, 0x4d, 0x44,
+    0x67, 0x47, 0x0a, 0x43, 0x57, 0x43, 0x47, 0x53, 0x41, 0x47, 0x47, 0x2b,
+    0x45, 0x49, 0x42, 0x44, 0x51, 0x51, 0x72, 0x46, 0x69, 0x6c, 0x54, 0x64,
+    0x47, 0x46, 0x79, 0x64, 0x45, 0x4e, 0x76, 0x62, 0x53, 0x42, 0x47, 0x63,
+    0x6d, 0x56, 0x6c, 0x49, 0x46, 0x4e, 0x54, 0x54, 0x43, 0x42, 0x44, 0x5a,
+    0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61,
+    0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x0a, 0x64, 0x47, 0x68, 0x76,
+    0x63, 0x6d, 0x6c, 0x30, 0x65, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71,
+    0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46,
+    0x41, 0x41, 0x4f, 0x43, 0x41, 0x67, 0x45, 0x41, 0x6a, 0x6f, 0x2f, 0x6e,
+    0x33, 0x4a, 0x52, 0x35, 0x66, 0x50, 0x47, 0x46, 0x66, 0x35, 0x39, 0x4a,
+    0x62, 0x32, 0x76, 0x4b, 0x58, 0x66, 0x75, 0x4d, 0x2f, 0x67, 0x54, 0x46,
+    0x0a, 0x77, 0x57, 0x4c, 0x52, 0x66, 0x55, 0x4b, 0x4b, 0x76, 0x46, 0x4f,
+    0x33, 0x6c, 0x41, 0x4e, 0x6d, 0x4d, 0x44, 0x2b, 0x78, 0x35, 0x77, 0x71,
+    0x6e, 0x55, 0x43, 0x42, 0x56, 0x4a, 0x58, 0x39, 0x32, 0x65, 0x68, 0x51,
+    0x4e, 0x36, 0x77, 0x51, 0x4f, 0x51, 0x4f, 0x59, 0x2b, 0x32, 0x49, 0x69,
+    0x72, 0x42, 0x79, 0x65, 0x44, 0x71, 0x58, 0x57, 0x6d, 0x4e, 0x33, 0x50,
+    0x48, 0x2f, 0x55, 0x76, 0x53, 0x0a, 0x54, 0x61, 0x30, 0x58, 0x51, 0x4d,
+    0x68, 0x47, 0x76, 0x6a, 0x74, 0x2f, 0x55, 0x66, 0x7a, 0x44, 0x74, 0x67,
+    0x55, 0x78, 0x33, 0x4d, 0x32, 0x46, 0x49, 0x6b, 0x35, 0x78, 0x74, 0x2f,
+    0x4a, 0x78, 0x58, 0x72, 0x41, 0x61, 0x78, 0x72, 0x71, 0x54, 0x69, 0x33,
+    0x69, 0x53, 0x53, 0x6f, 0x58, 0x34, 0x65, 0x41, 0x2b, 0x44, 0x2f, 0x69,
+    0x2b, 0x74, 0x4c, 0x50, 0x66, 0x6b, 0x70, 0x4c, 0x73, 0x74, 0x0a, 0x30,
+    0x4f, 0x63, 0x4e, 0x4f, 0x72, 0x67, 0x2b, 0x7a, 0x76, 0x5a, 0x34, 0x39,
+    0x71, 0x35, 0x48, 0x4a, 0x4d, 0x71, 0x6a, 0x4e, 0x54, 0x62, 0x4f, 0x78,
+    0x38, 0x61, 0x48, 0x6d, 0x4e, 0x72, 0x73, 0x2b, 0x2b, 0x6d, 0x79, 0x7a,
+    0x69, 0x65, 0x62, 0x69, 0x4d, 0x4d, 0x45, 0x6f, 0x66, 0x59, 0x4c, 0x57,
+    0x57, 0x69, 0x76, 0x79, 0x64, 0x73, 0x51, 0x44, 0x30, 0x33, 0x32, 0x5a,
+    0x47, 0x4e, 0x63, 0x0a, 0x70, 0x52, 0x4a, 0x76, 0x6b, 0x72, 0x4b, 0x54,
+    0x6c, 0x4d, 0x65, 0x49, 0x46, 0x77, 0x36, 0x54, 0x74, 0x6e, 0x35, 0x69,
+    0x69, 0x35, 0x42, 0x2f, 0x71, 0x30, 0x36, 0x66, 0x2f, 0x4f, 0x4e, 0x31,
+    0x46, 0x45, 0x38, 0x71, 0x4d, 0x74, 0x39, 0x62, 0x44, 0x65, 0x44, 0x31,
+    0x65, 0x35, 0x4d, 0x4e, 0x71, 0x36, 0x48, 0x50, 0x68, 0x2b, 0x47, 0x6c,
+    0x42, 0x45, 0x58, 0x6f, 0x50, 0x42, 0x4b, 0x6c, 0x0a, 0x43, 0x63, 0x57,
+    0x77, 0x30, 0x62, 0x64, 0x54, 0x38, 0x32, 0x41, 0x55, 0x75, 0x6f, 0x56,
+    0x70, 0x61, 0x69, 0x46, 0x38, 0x48, 0x33, 0x56, 0x68, 0x46, 0x79, 0x41,
+    0x58, 0x65, 0x32, 0x77, 0x37, 0x51, 0x53, 0x6c, 0x63, 0x34, 0x61, 0x78,
+    0x61, 0x30, 0x63, 0x32, 0x4d, 0x6d, 0x2b, 0x74, 0x67, 0x48, 0x52, 0x6e,
+    0x73, 0x39, 0x2b, 0x57, 0x77, 0x32, 0x76, 0x6c, 0x35, 0x47, 0x4b, 0x56,
+    0x46, 0x0a, 0x50, 0x30, 0x6c, 0x44, 0x56, 0x39, 0x4c, 0x64, 0x4a, 0x4e,
+    0x55, 0x73, 0x6f, 0x2f, 0x32, 0x52, 0x6a, 0x53, 0x65, 0x31, 0x35, 0x65,
+    0x73, 0x55, 0x42, 0x70, 0x70, 0x4d, 0x65, 0x79, 0x47, 0x37, 0x4f, 0x71,
+    0x30, 0x77, 0x42, 0x68, 0x6a, 0x41, 0x32, 0x4d, 0x46, 0x72, 0x4c, 0x48,
+    0x39, 0x5a, 0x58, 0x46, 0x32, 0x52, 0x73, 0x58, 0x41, 0x69, 0x56, 0x2b,
+    0x75, 0x4b, 0x61, 0x30, 0x68, 0x4b, 0x0a, 0x31, 0x51, 0x38, 0x70, 0x37,
+    0x4d, 0x5a, 0x41, 0x77, 0x43, 0x2b, 0x49, 0x54, 0x47, 0x67, 0x42, 0x46,
+    0x33, 0x66, 0x30, 0x4a, 0x42, 0x6c, 0x50, 0x76, 0x66, 0x72, 0x68, 0x73,
+    0x69, 0x41, 0x68, 0x53, 0x39, 0x30, 0x61, 0x32, 0x43, 0x6c, 0x39, 0x71,
+    0x72, 0x6a, 0x65, 0x56, 0x4f, 0x77, 0x68, 0x56, 0x59, 0x42, 0x73, 0x48,
+    0x76, 0x55, 0x77, 0x79, 0x4b, 0x4d, 0x51, 0x35, 0x62, 0x4c, 0x6d, 0x0a,
+    0x4b, 0x68, 0x51, 0x78, 0x77, 0x34, 0x55, 0x74, 0x6a, 0x4a, 0x69, 0x78,
+    0x68, 0x6c, 0x70, 0x50, 0x69, 0x56, 0x6b, 0x74, 0x75, 0x63, 0x66, 0x33,
+    0x48, 0x4d, 0x69, 0x4b, 0x66, 0x38, 0x43, 0x64, 0x42, 0x55, 0x72, 0x6d,
+    0x51, 0x6b, 0x39, 0x69, 0x6f, 0x32, 0x30, 0x70, 0x70, 0x42, 0x2b, 0x46,
+    0x71, 0x39, 0x76, 0x6c, 0x67, 0x63, 0x69, 0x74, 0x4b, 0x6a, 0x31, 0x4d,
+    0x58, 0x56, 0x75, 0x45, 0x0a, 0x4a, 0x6e, 0x48, 0x45, 0x68, 0x56, 0x35,
+    0x78, 0x4a, 0x4d, 0x71, 0x6c, 0x47, 0x32, 0x7a, 0x59, 0x59, 0x64, 0x4d,
+    0x61, 0x34, 0x46, 0x54, 0x62, 0x7a, 0x72, 0x71, 0x70, 0x4d, 0x72, 0x55,
+    0x69, 0x39, 0x6e, 0x4e, 0x42, 0x43, 0x56, 0x32, 0x34, 0x46, 0x31, 0x30,
+    0x4f, 0x44, 0x35, 0x6d, 0x51, 0x31, 0x6b, 0x66, 0x61, 0x62, 0x77, 0x6f,
+    0x36, 0x59, 0x69, 0x67, 0x55, 0x5a, 0x34, 0x4c, 0x5a, 0x0a, 0x38, 0x64,
+    0x43, 0x41, 0x57, 0x5a, 0x76, 0x4c, 0x4d, 0x64, 0x69, 0x62, 0x44, 0x34,
+    0x78, 0x33, 0x54, 0x72, 0x56, 0x6f, 0x69, 0x76, 0x4a, 0x73, 0x39, 0x69,
+    0x51, 0x4f, 0x4c, 0x57, 0x78, 0x77, 0x78, 0x58, 0x50, 0x52, 0x33, 0x68,
+    0x54, 0x51, 0x63, 0x59, 0x2b, 0x32, 0x30, 0x33, 0x73, 0x43, 0x39, 0x75,
+    0x4f, 0x34, 0x31, 0x41, 0x6c, 0x75, 0x61, 0x35, 0x35, 0x31, 0x68, 0x44,
+    0x6e, 0x6d, 0x0a, 0x66, 0x79, 0x57, 0x6c, 0x38, 0x6b, 0x67, 0x41, 0x77,
+    0x4b, 0x51, 0x42, 0x32, 0x6a, 0x38, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49,
+    0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x23,
+    0x20, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x4e, 0x3d,
+    0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
+    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32, 0x20,
+    0x4f, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c,
+    0x74, 0x64, 0x2e, 0x0a, 0x23, 0x20, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x3a, 0x20, 0x43, 0x4e, 0x3d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43,
+    0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x47, 0x32, 0x20, 0x4f, 0x3d, 0x53, 0x74, 0x61, 0x72,
+    0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x0a, 0x23, 0x20,
+    0x4c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 0x22, 0x53, 0x74, 0x61, 0x72,
+    0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
+    0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32, 0x22, 0x0a, 0x23, 0x20, 0x53,
+    0x65, 0x72, 0x69, 0x61, 0x6c, 0x3a, 0x20, 0x35, 0x39, 0x0a, 0x23, 0x20,
+    0x4d, 0x44, 0x35, 0x20, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+    0x69, 0x6e, 0x74, 0x3a, 0x20, 0x37, 0x38, 0x3a, 0x34, 0x62, 0x3a, 0x66,
+    0x62, 0x3a, 0x39, 0x65, 0x3a, 0x36, 0x34, 0x3a, 0x38, 0x32, 0x3a, 0x30,
+    0x61, 0x3a, 0x64, 0x33, 0x3a, 0x62, 0x38, 0x3a, 0x34, 0x63, 0x3a, 0x36,
+    0x32, 0x3a, 0x66, 0x33, 0x3a, 0x36, 0x34, 0x3a, 0x66, 0x32, 0x3a, 0x39,
+    0x30, 0x3a, 0x36, 0x34, 0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x31, 0x20,
+    0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a,
+    0x20, 0x33, 0x31, 0x3a, 0x66, 0x31, 0x3a, 0x66, 0x64, 0x3a, 0x36, 0x38,
+    0x3a, 0x32, 0x32, 0x3a, 0x36, 0x33, 0x3a, 0x32, 0x30, 0x3a, 0x65, 0x65,
+    0x3a, 0x63, 0x36, 0x3a, 0x33, 0x62, 0x3a, 0x33, 0x66, 0x3a, 0x39, 0x64,
+    0x3a, 0x65, 0x61, 0x3a, 0x34, 0x61, 0x3a, 0x33, 0x65, 0x3a, 0x35, 0x33,
+    0x3a, 0x37, 0x63, 0x3a, 0x37, 0x63, 0x3a, 0x33, 0x39, 0x3a, 0x31, 0x37,
+    0x0a, 0x23, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x46, 0x69,
+    0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x3a, 0x20, 0x63,
+    0x37, 0x3a, 0x62, 0x61, 0x3a, 0x36, 0x35, 0x3a, 0x36, 0x37, 0x3a, 0x64,
+    0x65, 0x3a, 0x39, 0x33, 0x3a, 0x61, 0x37, 0x3a, 0x39, 0x38, 0x3a, 0x61,
+    0x65, 0x3a, 0x31, 0x66, 0x3a, 0x61, 0x61, 0x3a, 0x37, 0x39, 0x3a, 0x31,
+    0x65, 0x3a, 0x37, 0x31, 0x3a, 0x32, 0x64, 0x3a, 0x33, 0x37, 0x3a, 0x38,
+    0x66, 0x3a, 0x61, 0x65, 0x3a, 0x31, 0x66, 0x3a, 0x39, 0x33, 0x3a, 0x63,
+    0x34, 0x3a, 0x33, 0x39, 0x3a, 0x37, 0x66, 0x3a, 0x65, 0x61, 0x3a, 0x34,
+    0x34, 0x3a, 0x31, 0x62, 0x3a, 0x62, 0x37, 0x3a, 0x63, 0x62, 0x3a, 0x65,
+    0x36, 0x3a, 0x66, 0x64, 0x3a, 0x35, 0x39, 0x3a, 0x39, 0x35, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45,
+    0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, 0x59, 0x7a, 0x43, 0x43, 0x41,
+    0x30, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x4f,
+    0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x54, 0x4d,
+    0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x4a, 0x54, 0x44, 0x45, 0x57, 0x0a, 0x4d, 0x42, 0x51, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x55, 0x33, 0x52, 0x68,
+    0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67, 0x54, 0x48, 0x52, 0x6b,
+    0x4c, 0x6a, 0x45, 0x73, 0x4d, 0x43, 0x6f, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x41, 0x78, 0x4d, 0x6a, 0x55, 0x33, 0x52, 0x68, 0x63, 0x6e, 0x52, 0x44,
+    0x62, 0x32, 0x30, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64, 0x47, 0x6c, 0x6d,
+    0x0a, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x69, 0x42,
+    0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64, 0x48, 0x6b,
+    0x67, 0x52, 0x7a, 0x49, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x41,
+    0x77, 0x4d, 0x54, 0x41, 0x78, 0x4d, 0x44, 0x45, 0x77, 0x4d, 0x44, 0x41,
+    0x78, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x7a, 0x6b, 0x78, 0x4d, 0x6a, 0x4d,
+    0x78, 0x4d, 0x6a, 0x4d, 0x31, 0x0a, 0x4f, 0x54, 0x41, 0x78, 0x57, 0x6a,
+    0x42, 0x54, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51,
+    0x51, 0x47, 0x45, 0x77, 0x4a, 0x4a, 0x54, 0x44, 0x45, 0x57, 0x4d, 0x42,
+    0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, 0x4e, 0x55, 0x33,
+    0x52, 0x68, 0x63, 0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67, 0x54, 0x48,
+    0x52, 0x6b, 0x4c, 0x6a, 0x45, 0x73, 0x4d, 0x43, 0x6f, 0x47, 0x0a, 0x41,
+    0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x6a, 0x55, 0x33, 0x52, 0x68, 0x63,
+    0x6e, 0x52, 0x44, 0x62, 0x32, 0x30, 0x67, 0x51, 0x32, 0x56, 0x79, 0x64,
+    0x47, 0x6c, 0x6d, 0x61, 0x57, 0x4e, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62,
+    0x69, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a, 0x70, 0x64,
+    0x48, 0x6b, 0x67, 0x52, 0x7a, 0x49, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4d,
+    0x41, 0x30, 0x47, 0x0a, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43,
+    0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4b, 0x41, 0x6f, 0x49, 0x43,
+    0x41, 0x51, 0x43, 0x32, 0x69, 0x54, 0x5a, 0x62, 0x42, 0x37, 0x63, 0x67,
+    0x4e, 0x72, 0x32, 0x43, 0x75, 0x2b, 0x45, 0x57, 0x49, 0x41, 0x4f, 0x56,
+    0x65, 0x71, 0x38, 0x4f, 0x6f, 0x31, 0x58, 0x4a, 0x0a, 0x4a, 0x5a, 0x6c,
+    0x4b, 0x78, 0x64, 0x42, 0x57, 0x51, 0x59, 0x65, 0x51, 0x54, 0x53, 0x46,
+    0x67, 0x70, 0x42, 0x53, 0x48, 0x4f, 0x38, 0x33, 0x39, 0x73, 0x6a, 0x36,
+    0x30, 0x5a, 0x77, 0x4e, 0x71, 0x37, 0x65, 0x45, 0x50, 0x53, 0x38, 0x43,
+    0x52, 0x68, 0x58, 0x42, 0x46, 0x34, 0x45, 0x4b, 0x65, 0x33, 0x69, 0x6b,
+    0x6a, 0x31, 0x41, 0x45, 0x4e, 0x6f, 0x42, 0x42, 0x35, 0x75, 0x4e, 0x73,
+    0x44, 0x0a, 0x76, 0x66, 0x4f, 0x70, 0x4c, 0x39, 0x48, 0x47, 0x34, 0x41,
+    0x2f, 0x4c, 0x6e, 0x6f, 0x6f, 0x55, 0x43, 0x72, 0x69, 0x39, 0x39, 0x6c,
+    0x5a, 0x69, 0x38, 0x63, 0x56, 0x79, 0x74, 0x6a, 0x49, 0x6c, 0x32, 0x62,
+    0x4c, 0x7a, 0x76, 0x57, 0x58, 0x46, 0x44, 0x53, 0x78, 0x75, 0x31, 0x5a,
+    0x4a, 0x76, 0x47, 0x49, 0x73, 0x41, 0x51, 0x52, 0x53, 0x43, 0x62, 0x30,
+    0x41, 0x67, 0x4a, 0x6e, 0x6f, 0x6f, 0x0a, 0x44, 0x2f, 0x55, 0x65, 0x66,
+    0x79, 0x66, 0x33, 0x6c, 0x4c, 0x45, 0x33, 0x50, 0x62, 0x66, 0x48, 0x6b,
+    0x66, 0x66, 0x69, 0x41, 0x65, 0x7a, 0x39, 0x6c, 0x49, 0x6e, 0x68, 0x7a,
+    0x47, 0x37, 0x54, 0x4e, 0x74, 0x59, 0x4b, 0x47, 0x58, 0x6d, 0x75, 0x31,
+    0x7a, 0x53, 0x43, 0x5a, 0x66, 0x39, 0x38, 0x51, 0x72, 0x75, 0x32, 0x33,
+    0x51, 0x75, 0x6d, 0x4e, 0x4b, 0x39, 0x4c, 0x59, 0x50, 0x35, 0x2f, 0x0a,
+    0x51, 0x30, 0x6b, 0x47, 0x69, 0x34, 0x78, 0x44, 0x75, 0x46, 0x62, 0x79,
+    0x32, 0x58, 0x38, 0x68, 0x51, 0x78, 0x66, 0x71, 0x70, 0x30, 0x69, 0x56,
+    0x41, 0x58, 0x56, 0x31, 0x36, 0x69, 0x75, 0x6c, 0x51, 0x35, 0x58, 0x71,
+    0x46, 0x59, 0x53, 0x64, 0x43, 0x49, 0x30, 0x6d, 0x62, 0x6c, 0x57, 0x62,
+    0x71, 0x39, 0x7a, 0x53, 0x4f, 0x64, 0x49, 0x78, 0x48, 0x57, 0x44, 0x69,
+    0x72, 0x4d, 0x78, 0x57, 0x0a, 0x52, 0x53, 0x54, 0x31, 0x48, 0x46, 0x53,
+    0x72, 0x37, 0x6f, 0x62, 0x64, 0x6c, 0x6a, 0x4b, 0x46, 0x2b, 0x45, 0x78,
+    0x50, 0x36, 0x4a, 0x56, 0x32, 0x74, 0x67, 0x58, 0x64, 0x4e, 0x69, 0x4e,
+    0x6e, 0x76, 0x50, 0x38, 0x56, 0x34, 0x73, 0x6f, 0x37, 0x35, 0x71, 0x62,
+    0x73, 0x4f, 0x2b, 0x77, 0x6d, 0x45, 0x54, 0x52, 0x49, 0x6a, 0x66, 0x61,
+    0x41, 0x4b, 0x78, 0x6f, 0x6a, 0x41, 0x75, 0x75, 0x4b, 0x0a, 0x48, 0x44,
+    0x70, 0x32, 0x4b, 0x6e, 0x74, 0x57, 0x46, 0x68, 0x78, 0x79, 0x4b, 0x72,
+    0x4f, 0x71, 0x34, 0x32, 0x43, 0x6c, 0x41, 0x4a, 0x38, 0x45, 0x6d, 0x2b,
+    0x4a, 0x76, 0x48, 0x68, 0x52, 0x59, 0x57, 0x36, 0x56, 0x73, 0x69, 0x31,
+    0x67, 0x38, 0x77, 0x37, 0x70, 0x4f, 0x4f, 0x6c, 0x7a, 0x33, 0x34, 0x5a,
+    0x59, 0x72, 0x50, 0x75, 0x38, 0x48, 0x76, 0x4b, 0x54, 0x6c, 0x58, 0x63,
+    0x78, 0x4e, 0x0a, 0x6e, 0x77, 0x33, 0x68, 0x33, 0x4b, 0x71, 0x37, 0x34,
+    0x57, 0x34, 0x61, 0x37, 0x49, 0x2f, 0x68, 0x74, 0x6b, 0x78, 0x4e, 0x65,
+    0x58, 0x4a, 0x64, 0x46, 0x7a, 0x55, 0x4c, 0x48, 0x64, 0x66, 0x42, 0x52,
+    0x39, 0x71, 0x57, 0x4a, 0x4f, 0x44, 0x51, 0x63, 0x71, 0x68, 0x61, 0x58,
+    0x32, 0x59, 0x74, 0x45, 0x4e, 0x77, 0x76, 0x4b, 0x68, 0x4f, 0x75, 0x4a,
+    0x76, 0x34, 0x4b, 0x48, 0x42, 0x6e, 0x4d, 0x0a, 0x30, 0x44, 0x34, 0x4c,
+    0x6e, 0x4d, 0x67, 0x4a, 0x4c, 0x76, 0x6c, 0x62, 0x6c, 0x6e, 0x70, 0x48,
+    0x6e, 0x4f, 0x6c, 0x36, 0x38, 0x77, 0x56, 0x51, 0x64, 0x4a, 0x56, 0x7a,
+    0x6e, 0x6a, 0x41, 0x4a, 0x38, 0x35, 0x65, 0x43, 0x58, 0x75, 0x61, 0x50,
+    0x4f, 0x51, 0x67, 0x65, 0x57, 0x65, 0x55, 0x31, 0x46, 0x45, 0x49, 0x54,
+    0x2f, 0x77, 0x43, 0x63, 0x39, 0x37, 0x36, 0x71, 0x55, 0x4d, 0x2f, 0x69,
+    0x0a, 0x55, 0x55, 0x6a, 0x58, 0x75, 0x47, 0x2b, 0x76, 0x2b, 0x45, 0x35,
+    0x2b, 0x4d, 0x35, 0x69, 0x53, 0x46, 0x47, 0x49, 0x36, 0x64, 0x57, 0x50,
+    0x50, 0x65, 0x2f, 0x72, 0x65, 0x67, 0x6a, 0x75, 0x70, 0x75, 0x7a, 0x6e,
+    0x69, 0x78, 0x4c, 0x30, 0x73, 0x41, 0x41, 0x37, 0x49, 0x46, 0x36, 0x77,
+    0x54, 0x37, 0x30, 0x30, 0x6c, 0x6a, 0x74, 0x69, 0x7a, 0x6b, 0x43, 0x2b,
+    0x70, 0x32, 0x69, 0x6c, 0x39, 0x0a, 0x48, 0x61, 0x39, 0x30, 0x4f, 0x72,
+    0x49, 0x6e, 0x77, 0x4d, 0x45, 0x65, 0x50, 0x6e, 0x57, 0x6a, 0x46, 0x71,
+    0x6d, 0x76, 0x65, 0x69, 0x4a, 0x64, 0x6e, 0x78, 0x4d, 0x61, 0x7a, 0x36,
+    0x65, 0x67, 0x36, 0x2b, 0x4f, 0x47, 0x43, 0x74, 0x50, 0x39, 0x35, 0x70,
+    0x61, 0x56, 0x31, 0x79, 0x50, 0x49, 0x4e, 0x39, 0x33, 0x45, 0x66, 0x4b,
+    0x6f, 0x32, 0x72, 0x4a, 0x67, 0x61, 0x45, 0x72, 0x48, 0x67, 0x0a, 0x54,
+    0x75, 0x69, 0x78, 0x4f, 0x2f, 0x58, 0x57, 0x62, 0x2f, 0x45, 0x77, 0x31,
+    0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x30, 0x49, 0x77, 0x51,
+    0x44, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41,
+    0x66, 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d,
+    0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, 0x42, 0x2f,
+    0x77, 0x51, 0x45, 0x0a, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, 0x64,
+    0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55,
+    0x53, 0x38, 0x57, 0x30, 0x51, 0x47, 0x75, 0x74, 0x48, 0x4c, 0x4f, 0x6c,
+    0x48, 0x47, 0x56, 0x75, 0x52, 0x6a, 0x61, 0x4a, 0x68, 0x77, 0x55, 0x4d,
+    0x44, 0x72, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49,
+    0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41,
+    0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x48, 0x4e, 0x58, 0x50, 0x79, 0x7a,
+    0x56, 0x6c, 0x54, 0x4a, 0x2b, 0x4e, 0x39, 0x75, 0x57, 0x6b, 0x75, 0x73,
+    0x5a, 0x58, 0x6e, 0x35, 0x54, 0x35, 0x30, 0x48, 0x73, 0x45, 0x62, 0x5a,
+    0x48, 0x37, 0x37, 0x58, 0x65, 0x37, 0x58, 0x52, 0x63, 0x78, 0x66, 0x47,
+    0x4f, 0x53, 0x65, 0x44, 0x38, 0x62, 0x70, 0x6b, 0x54, 0x7a, 0x5a, 0x2b,
+    0x4b, 0x0a, 0x32, 0x73, 0x30, 0x36, 0x43, 0x74, 0x67, 0x36, 0x57, 0x67,
+    0x6b, 0x2f, 0x58, 0x7a, 0x54, 0x51, 0x4c, 0x77, 0x50, 0x53, 0x5a, 0x68,
+    0x30, 0x61, 0x76, 0x5a, 0x79, 0x51, 0x4e, 0x38, 0x67, 0x4d, 0x6a, 0x67,
+    0x64, 0x61, 0x6c, 0x45, 0x56, 0x47, 0x4b, 0x75, 0x61, 0x2b, 0x65, 0x74,
+    0x71, 0x68, 0x71, 0x61, 0x52, 0x70, 0x45, 0x70, 0x4b, 0x77, 0x66, 0x54,
+    0x62, 0x55, 0x52, 0x49, 0x66, 0x58, 0x0a, 0x55, 0x66, 0x45, 0x70, 0x59,
+    0x39, 0x5a, 0x31, 0x7a, 0x52, 0x62, 0x6b, 0x4a, 0x34, 0x6b, 0x64, 0x2b,
+    0x4d, 0x49, 0x79, 0x53, 0x50, 0x33, 0x62, 0x6d, 0x64, 0x43, 0x50, 0x58,
+    0x31, 0x52, 0x30, 0x7a, 0x4b, 0x78, 0x6e, 0x4e, 0x42, 0x46, 0x69, 0x32,
+    0x51, 0x77, 0x4b, 0x4e, 0x34, 0x66, 0x52, 0x6f, 0x78, 0x64, 0x49, 0x6a,
+    0x74, 0x49, 0x58, 0x48, 0x66, 0x62, 0x58, 0x2f, 0x64, 0x74, 0x6c, 0x0a,
+    0x36, 0x2f, 0x32, 0x6f, 0x31, 0x50, 0x58, 0x57, 0x54, 0x36, 0x52, 0x62,
+    0x64, 0x65, 0x6a, 0x46, 0x30, 0x6d, 0x43, 0x79, 0x32, 0x77, 0x6c, 0x2b,
+    0x4a, 0x59, 0x74, 0x37, 0x75, 0x6c, 0x4b, 0x53, 0x6e, 0x6a, 0x37, 0x6f,
+    0x78, 0x58, 0x65, 0x68, 0x50, 0x4f, 0x42, 0x4b, 0x63, 0x32, 0x74, 0x68,
+    0x7a, 0x34, 0x62, 0x63, 0x51, 0x2f, 0x2f, 0x2f, 0x49, 0x66, 0x34, 0x6a,
+    0x58, 0x53, 0x52, 0x4b, 0x0a, 0x39, 0x64, 0x4e, 0x74, 0x44, 0x32, 0x49,
+    0x45, 0x42, 0x56, 0x65, 0x43, 0x32, 0x6d, 0x36, 0x6b, 0x4d, 0x79, 0x56,
+    0x35, 0x53, 0x79, 0x35, 0x55, 0x47, 0x59, 0x76, 0x4d, 0x4c, 0x44, 0x30,
+    0x77, 0x36, 0x64, 0x45, 0x47, 0x2f, 0x2b, 0x67, 0x79, 0x52, 0x72, 0x36,
+    0x31, 0x4d, 0x33, 0x5a, 0x33, 0x71, 0x41, 0x46, 0x64, 0x6c, 0x73, 0x48,
+    0x42, 0x31, 0x62, 0x36, 0x75, 0x4a, 0x63, 0x44, 0x4a, 0x0a, 0x48, 0x67,
+    0x6f, 0x4a, 0x49, 0x49, 0x69, 0x68, 0x44, 0x73, 0x6e, 0x7a, 0x62, 0x30,
+    0x32, 0x43, 0x56, 0x41, 0x41, 0x67, 0x70, 0x39, 0x4b, 0x50, 0x35, 0x44,
+    0x6c, 0x55, 0x46, 0x79, 0x36, 0x4e, 0x48, 0x72, 0x67, 0x62, 0x75, 0x78,
+    0x75, 0x39, 0x6d, 0x6b, 0x34, 0x37, 0x45, 0x44, 0x54, 0x63, 0x6e, 0x49,
+    0x68, 0x54, 0x37, 0x36, 0x49, 0x78, 0x57, 0x31, 0x68, 0x50, 0x6b, 0x57,
+    0x4c, 0x49, 0x0a, 0x77, 0x70, 0x71, 0x61, 0x7a, 0x52, 0x56, 0x64, 0x4f,
+    0x4b, 0x6e, 0x57, 0x76, 0x76, 0x67, 0x54, 0x74, 0x5a, 0x38, 0x53, 0x61,
+    0x66, 0x4a, 0x51, 0x59, 0x71, 0x7a, 0x37, 0x46, 0x7a, 0x66, 0x30, 0x37,
+    0x72, 0x68, 0x31, 0x5a, 0x32, 0x41, 0x51, 0x2b, 0x34, 0x4e, 0x51, 0x2b,
+    0x55, 0x53, 0x31, 0x64, 0x5a, 0x78, 0x41, 0x46, 0x37, 0x4c, 0x2b, 0x2f,
+    0x58, 0x6c, 0x64, 0x62, 0x6c, 0x68, 0x59, 0x0a, 0x58, 0x7a, 0x44, 0x38,
+    0x41, 0x4b, 0x36, 0x76, 0x4d, 0x38, 0x45, 0x4f, 0x54, 0x6d, 0x79, 0x36,
+    0x70, 0x36, 0x61, 0x68, 0x66, 0x7a, 0x4c, 0x62, 0x4f, 0x4f, 0x43, 0x78,
+    0x63, 0x68, 0x63, 0x4b, 0x4b, 0x35, 0x48, 0x73, 0x61, 0x6d, 0x4d, 0x6d,
+    0x37, 0x59, 0x6e, 0x55, 0x65, 0x4d, 0x78, 0x30, 0x48, 0x67, 0x58, 0x34,
+    0x61, 0x2f, 0x36, 0x4d, 0x61, 0x6e, 0x59, 0x35, 0x4b, 0x61, 0x35, 0x6c,
+    0x0a, 0x49, 0x78, 0x4b, 0x56, 0x43, 0x43, 0x49, 0x63, 0x6c, 0x38, 0x35,
+    0x62, 0x42, 0x75, 0x34, 0x4d, 0x34, 0x72, 0x75, 0x38, 0x48, 0x30, 0x53,
+    0x54, 0x39, 0x74, 0x67, 0x34, 0x52, 0x51, 0x55, 0x68, 0x37, 0x65, 0x53,
+    0x74, 0x71, 0x78, 0x4b, 0x32, 0x41, 0x36, 0x52, 0x43, 0x4c, 0x69, 0x33,
+    0x45, 0x43, 0x54, 0x6f, 0x44, 0x5a, 0x32, 0x6d, 0x45, 0x6d, 0x75, 0x46,
+    0x5a, 0x6b, 0x49, 0x6f, 0x6f, 0x0a, 0x68, 0x64, 0x56, 0x64, 0x64, 0x4c,
+    0x48, 0x52, 0x44, 0x69, 0x42, 0x59, 0x6d, 0x78, 0x4f, 0x6c, 0x73, 0x47,
+    0x4f, 0x6d, 0x37, 0x58, 0x74, 0x48, 0x2f, 0x55, 0x56, 0x56, 0x4d, 0x4b,
+    0x54, 0x75, 0x6d, 0x74, 0x54, 0x6d, 0x34, 0x6f, 0x66, 0x76, 0x6d, 0x4d,
+    0x6b, 0x79, 0x67, 0x68, 0x45, 0x70, 0x49, 0x72, 0x77, 0x41, 0x43, 0x6a,
+    0x46, 0x65, 0x4c, 0x51, 0x2f, 0x41, 0x6a, 0x75, 0x6c, 0x72, 0x0a, 0x73,
+    0x6f, 0x38, 0x75, 0x42, 0x74, 0x6a, 0x52, 0x6b, 0x63, 0x66, 0x47, 0x45,
+    0x76, 0x52, 0x4d, 0x2f, 0x54, 0x41, 0x58, 0x77, 0x38, 0x48, 0x61, 0x4f,
+    0x46, 0x76, 0x6a, 0x71, 0x65, 0x72, 0x6d, 0x6f, 0x62, 0x70, 0x35, 0x37,
+    0x33, 0x50, 0x59, 0x74, 0x6c, 0x4e, 0x58, 0x4c, 0x66, 0x62, 0x51, 0x34,
+    0x64, 0x64, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a};
+unsigned int grpc_google_root_certs_size = 134862;
diff --git a/src/core/security/google_root_certs.h b/src/core/security/google_root_certs.h
new file mode 100644
index 0000000..4bcfadd
--- /dev/null
+++ b/src/core/security/google_root_certs.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SECURITY_GOOGLE_ROOT_CERTS_H__
+#define __GRPC_INTERNAL_SECURITY_GOOGLE_ROOT_CERTS_H__
+
+extern unsigned char grpc_google_root_certs[];
+extern unsigned int grpc_google_root_certs_size;
+
+#endif  /* __GRPC_INTERNAL_SECURITY_GOOGLE_ROOT_CERTS_H__ */
diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c
new file mode 100644
index 0000000..bc2e469
--- /dev/null
+++ b/src/core/security/secure_transport_setup.c
@@ -0,0 +1,289 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/security/secure_transport_setup.h"
+
+#include <string.h>
+
+#include "src/core/endpoint/secure_endpoint.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice_buffer.h>
+
+#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
+
+typedef struct {
+  grpc_security_context *ctx;
+  tsi_handshaker *handshaker;
+  unsigned char *handshake_buffer;
+  size_t handshake_buffer_size;
+  grpc_endpoint *endpoint;
+  gpr_slice_buffer left_overs;
+  grpc_secure_transport_setup_done_cb cb;
+  void *user_data;
+} grpc_secure_transport_setup;
+
+static void on_handshake_data_received_from_peer(void *setup, gpr_slice *slices,
+                                                 size_t nslices,
+                                                 grpc_endpoint_cb_status error);
+
+static void on_handshake_data_sent_to_peer(void *setup,
+                                           grpc_endpoint_cb_status error);
+
+static void secure_transport_setup_done(grpc_secure_transport_setup *s,
+                                        int is_success) {
+  if (is_success) {
+    s->cb(s->user_data, GRPC_SECURITY_OK, s->endpoint);
+  } else {
+    if (s->endpoint != NULL) {
+      grpc_endpoint_shutdown(s->endpoint);
+      grpc_endpoint_destroy(s->endpoint);
+    }
+    s->cb(s->user_data, GRPC_SECURITY_ERROR, NULL);
+  }
+  if (s->handshaker != NULL) tsi_handshaker_destroy(s->handshaker);
+  if (s->handshake_buffer != NULL) gpr_free(s->handshake_buffer);
+  gpr_slice_buffer_destroy(&s->left_overs);
+  grpc_security_context_unref(s->ctx);
+  gpr_free(s);
+}
+
+static void on_peer_checked(void *user_data, grpc_security_status status) {
+  grpc_secure_transport_setup *s = user_data;
+  tsi_frame_protector *protector;
+  tsi_result result;
+  if (status != GRPC_SECURITY_OK) {
+    gpr_log(GPR_ERROR, "Error checking peer.");
+    secure_transport_setup_done(s, 0);
+    return;
+  }
+  result =
+      tsi_handshaker_create_frame_protector(s->handshaker, NULL, &protector);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Frame protector creation failed with error %s.",
+            tsi_result_to_string(result));
+    secure_transport_setup_done(s, 0);
+    return;
+  }
+  s->endpoint = grpc_secure_endpoint_create(
+      protector, s->endpoint, s->left_overs.slices, s->left_overs.count);
+  secure_transport_setup_done(s, 1);
+  return;
+}
+
+static void check_peer(grpc_secure_transport_setup *s) {
+  grpc_security_status peer_status;
+  tsi_peer peer;
+  tsi_result result = tsi_handshaker_extract_peer(s->handshaker, &peer);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Peer extraction failed with error %s",
+            tsi_result_to_string(result));
+    secure_transport_setup_done(s, 0);
+    return;
+  }
+  peer_status =
+      grpc_security_context_check_peer(s->ctx, &peer, on_peer_checked, s);
+  tsi_peer_destruct(&peer);
+  if (peer_status == GRPC_SECURITY_ERROR) {
+    gpr_log(GPR_ERROR, "Peer check failed.");
+    secure_transport_setup_done(s, 0);
+    return;
+  } else if (peer_status == GRPC_SECURITY_OK) {
+    on_peer_checked(s, peer_status);
+  }
+}
+
+static void send_handshake_bytes_to_peer(grpc_secure_transport_setup *s) {
+  size_t offset = 0;
+  tsi_result result = TSI_OK;
+  gpr_slice to_send;
+  grpc_endpoint_write_status write_status;
+
+  do {
+    uint32_t to_send_size = s->handshake_buffer_size - offset;
+    result = tsi_handshaker_get_bytes_to_send_to_peer(
+        s->handshaker, s->handshake_buffer + offset, &to_send_size);
+    offset += to_send_size;
+    if (result == TSI_INCOMPLETE_DATA) {
+      s->handshake_buffer_size *= 2;
+      s->handshake_buffer =
+          gpr_realloc(s->handshake_buffer, s->handshake_buffer_size);
+    }
+  } while (result == TSI_INCOMPLETE_DATA);
+
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshake failed with error %s",
+            tsi_result_to_string(result));
+    secure_transport_setup_done(s, 0);
+    return;
+  }
+
+  to_send =
+      gpr_slice_from_copied_buffer((const char *)s->handshake_buffer, offset);
+  /* TODO(klempner,jboeuf): This should probably use the client setup
+         deadline */
+  write_status =
+      grpc_endpoint_write(s->endpoint, &to_send, 1,
+                          on_handshake_data_sent_to_peer, s, gpr_inf_future);
+  if (write_status == GRPC_ENDPOINT_WRITE_ERROR) {
+    gpr_log(GPR_ERROR, "Could not send handshake data to peer.");
+    secure_transport_setup_done(s, 0);
+  } else if (write_status == GRPC_ENDPOINT_WRITE_DONE) {
+    on_handshake_data_sent_to_peer(s, GRPC_ENDPOINT_CB_OK);
+  }
+}
+
+static void cleanup_slices(gpr_slice *slices, size_t num_slices) {
+  size_t i;
+  for (i = 0; i < num_slices; i++) {
+    gpr_slice_unref(slices[i]);
+  }
+}
+
+static void on_handshake_data_received_from_peer(
+    void *setup, gpr_slice *slices, size_t nslices,
+    grpc_endpoint_cb_status error) {
+  grpc_secure_transport_setup *s = setup;
+  uint32_t consumed_slice_size = 0;
+  tsi_result result = TSI_OK;
+  size_t i;
+  size_t num_left_overs;
+  int has_left_overs_in_current_slice = 0;
+
+  if (error != GRPC_ENDPOINT_CB_OK) {
+    gpr_log(GPR_ERROR, "Read failed.");
+    cleanup_slices(slices, nslices);
+    secure_transport_setup_done(s, 0);
+    return;
+  }
+
+  for (i = 0; i < nslices; i++) {
+    consumed_slice_size = GPR_SLICE_LENGTH(slices[i]);
+    result = tsi_handshaker_process_bytes_from_peer(
+        s->handshaker, GPR_SLICE_START_PTR(slices[i]), &consumed_slice_size);
+    if (!tsi_handshaker_is_in_progress(s->handshaker)) break;
+  }
+
+  if (tsi_handshaker_is_in_progress(s->handshaker)) {
+    /* We may need more data. */
+    if (result == TSI_INCOMPLETE_DATA) {
+      /* TODO(klempner,jboeuf): This should probably use the client setup
+         deadline */
+      grpc_endpoint_notify_on_read(s->endpoint,
+                                   on_handshake_data_received_from_peer, setup,
+                                   gpr_inf_future);
+      cleanup_slices(slices, nslices);
+      return;
+    } else {
+      send_handshake_bytes_to_peer(s);
+      cleanup_slices(slices, nslices);
+      return;
+    }
+  }
+
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshake failed with error %s",
+            tsi_result_to_string(result));
+    cleanup_slices(slices, nslices);
+    secure_transport_setup_done(s, 0);
+    return;
+  }
+
+  /* Handshake is done and successful this point. */
+  has_left_overs_in_current_slice =
+      (consumed_slice_size < GPR_SLICE_LENGTH(slices[i]));
+  num_left_overs = (has_left_overs_in_current_slice ? 1 : 0) + nslices - i - 1;
+  if (num_left_overs == 0) {
+    cleanup_slices(slices, nslices);
+    check_peer(s);
+    return;
+  }
+  cleanup_slices(slices, nslices - num_left_overs);
+
+  /* Put the leftovers in our buffer (ownership transfered). */
+  if (has_left_overs_in_current_slice) {
+    gpr_slice_buffer_add(&s->left_overs,
+                         gpr_slice_split_tail(&slices[i], consumed_slice_size));
+    gpr_slice_unref(slices[i]); /* split_tail above increments refcount. */
+  }
+  gpr_slice_buffer_addn(&s->left_overs, &slices[i + 1],
+                        num_left_overs - has_left_overs_in_current_slice);
+  check_peer(s);
+}
+
+/* If setup is NULL, the setup is done. */
+static void on_handshake_data_sent_to_peer(void *setup,
+                                           grpc_endpoint_cb_status error) {
+  grpc_secure_transport_setup *s = setup;
+
+  /* Make sure that write is OK. */
+  if (error != GRPC_ENDPOINT_CB_OK) {
+    gpr_log(GPR_ERROR, "Write failed with error %d.", error);
+    if (setup != NULL) secure_transport_setup_done(s, 0);
+    return;
+  }
+
+  /* We may be done. */
+  if (tsi_handshaker_is_in_progress(s->handshaker)) {
+    /* TODO(klempner,jboeuf): This should probably use the client setup
+       deadline */
+    grpc_endpoint_notify_on_read(s->endpoint,
+                                 on_handshake_data_received_from_peer, setup,
+                                 gpr_inf_future);
+  } else {
+    check_peer(s);
+  }
+}
+
+void grpc_setup_secure_transport(grpc_security_context *ctx,
+                                 grpc_endpoint *nonsecure_endpoint,
+                                 grpc_secure_transport_setup_done_cb cb,
+                                 void *user_data) {
+  grpc_security_status result = GRPC_SECURITY_OK;
+  grpc_secure_transport_setup *s =
+      gpr_malloc(sizeof(grpc_secure_transport_setup));
+  memset(s, 0, sizeof(grpc_secure_transport_setup));
+  result = grpc_security_context_create_handshaker(ctx, &s->handshaker);
+  if (result != GRPC_SECURITY_OK) {
+    secure_transport_setup_done(s, 0);
+    return;
+  }
+  s->ctx = grpc_security_context_ref(ctx);
+  s->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
+  s->handshake_buffer = gpr_malloc(s->handshake_buffer_size);
+  s->endpoint = nonsecure_endpoint;
+  s->user_data = user_data;
+  s->cb = cb;
+  gpr_slice_buffer_init(&s->left_overs);
+  send_handshake_bytes_to_peer(s);
+}
diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/secure_transport_setup.h
new file mode 100644
index 0000000..1a20fa9
--- /dev/null
+++ b/src/core/security/secure_transport_setup.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__
+#define __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__
+
+#include "src/core/endpoint/endpoint.h"
+#include "src/core/security/security_context.h"
+
+/* --- Secure transport setup --- */
+
+/* Ownership of the secure_endpoint is transfered. */
+typedef void (*grpc_secure_transport_setup_done_cb)(
+    void *user_data, grpc_security_status status,
+    grpc_endpoint *secure_endpoint);
+
+/* Calls the callback upon completion. */
+void grpc_setup_secure_transport(grpc_security_context *ctx,
+                                 grpc_endpoint *nonsecure_endpoint,
+                                 grpc_secure_transport_setup_done_cb cb,
+                                 void *user_data);
+
+#endif  /* __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__ */
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
new file mode 100644
index 0000000..beda64c
--- /dev/null
+++ b/src/core/security/security_context.c
@@ -0,0 +1,497 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/security/security_context.h"
+
+#include <string.h>
+
+#include "src/core/endpoint/secure_endpoint.h"
+#include "src/core/security/credentials.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice_buffer.h>
+#include <grpc/support/string.h>
+
+#include "src/core/tsi/fake_transport_security.h"
+#include "src/core/tsi/ssl_transport_security.h"
+
+/* -- Constants. -- */
+
+#define GRPC_ALPN_PROTOCOL_STRING "h2-15"
+/* Defines the cipher suites that we accept. All these cipher suites are
+   compliant with TLS 1.2 and use an RSA public key. We prefer GCM over CBC
+   and ECDHE-RSA over just RSA. */
+#define GRPC_SSL_CIPHER_SUITES                                                 \
+  "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:" \
+  "AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-"  \
+  "SHA256:AES256-SHA256"
+
+/* -- Common methods. -- */
+
+grpc_security_status grpc_security_context_create_handshaker(
+    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+  if (ctx == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR;
+  return ctx->vtable->create_handshaker(ctx, handshaker);
+}
+
+grpc_security_status grpc_security_context_check_peer(
+    grpc_security_context *ctx, const tsi_peer *peer,
+    grpc_security_check_peer_cb cb, void *user_data) {
+  if (ctx == NULL) return GRPC_SECURITY_ERROR;
+  return ctx->vtable->check_peer(ctx, peer, cb, user_data);
+}
+
+void grpc_security_context_unref(grpc_security_context *ctx) {
+  if (ctx == NULL) return;
+  if (gpr_unref(&ctx->refcount)) ctx->vtable->destroy(ctx);
+}
+
+grpc_security_context *grpc_security_context_ref(grpc_security_context *ctx) {
+  if (ctx == NULL) return NULL;
+  gpr_ref(&ctx->refcount);
+  return ctx;
+}
+
+static void context_pointer_arg_destroy(void *p) {
+  grpc_security_context_unref(p);
+}
+
+static void *context_pointer_arg_copy(void *p) {
+  return grpc_security_context_ref(p);
+}
+
+grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx) {
+  grpc_arg result;
+  result.type = GRPC_ARG_POINTER;
+  result.key = GRPC_SECURITY_CONTEXT_ARG;
+  result.value.pointer.destroy = context_pointer_arg_destroy;
+  result.value.pointer.copy = context_pointer_arg_copy;
+  result.value.pointer.p = ctx;
+  return result;
+}
+
+grpc_security_context *grpc_security_context_from_arg(
+    const grpc_arg *arg) {
+  if (strcmp(arg->key, GRPC_SECURITY_CONTEXT_ARG)) return NULL;
+  if (arg->type != GRPC_ARG_POINTER) {
+    gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
+            GRPC_SECURITY_CONTEXT_ARG);
+    return NULL;
+  }
+  return arg->value.pointer.p;
+}
+
+grpc_security_context *grpc_find_security_context_in_args(
+    const grpc_channel_args *args) {
+  size_t i;
+  if (args == NULL) return NULL;
+  for (i = 0; i < args->num_args; i++) {
+    grpc_security_context *ctx = grpc_security_context_from_arg(&args->args[i]);
+    if (ctx != NULL) return ctx;
+  }
+  return NULL;
+}
+
+static int check_request_metadata_only_creds(grpc_credentials *creds) {
+  if (creds != NULL && !grpc_credentials_has_request_metadata_only(creds)) {
+    gpr_log(GPR_ERROR,
+            "Incompatible credentials for channel security context: needs to "
+            "only set request metadata.");
+    return 0;
+  }
+  return 1;
+}
+
+/* -- Fake implementation. -- */
+
+static void fake_channel_destroy(grpc_security_context *ctx) {
+  grpc_channel_security_context *c = (grpc_channel_security_context *)ctx;
+  grpc_credentials_unref(c->request_metadata_only_creds);
+  gpr_free(ctx);
+}
+
+static void fake_server_destroy(grpc_security_context *ctx) {
+  gpr_free(ctx);
+}
+
+static grpc_security_status fake_channel_create_handshaker(
+    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+  *handshaker = tsi_create_fake_handshaker(1);
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_status fake_server_create_handshaker(
+    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+  *handshaker = tsi_create_fake_handshaker(0);
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_status fake_check_peer(grpc_security_context *ctx,
+                                            const tsi_peer *peer,
+                                            grpc_security_check_peer_cb cb,
+                                            void *user_data) {
+  const char *prop_name;
+  if (peer->property_count != 1) {
+    gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
+    return GRPC_SECURITY_ERROR;
+  }
+  prop_name = peer->properties[0].name;
+  if (prop_name == NULL ||
+      strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
+    gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
+            prop_name == NULL ? "<EMPTY>" : prop_name);
+    return GRPC_SECURITY_ERROR;
+  }
+  if (peer->properties[0].type != TSI_PEER_PROPERTY_TYPE_STRING) {
+    gpr_log(GPR_ERROR, "Invalid type of cert type property.");
+    return GRPC_SECURITY_ERROR;
+  }
+  if (strncmp(peer->properties[0].value.string.data, TSI_FAKE_CERTIFICATE_TYPE,
+              peer->properties[0].value.string.length)) {
+    gpr_log(GPR_ERROR, "Invalid value for cert type property.");
+    return GRPC_SECURITY_ERROR;
+  }
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_context_vtable fake_channel_vtable = {
+    fake_channel_destroy, fake_channel_create_handshaker, fake_check_peer};
+
+static grpc_security_context_vtable fake_server_vtable = {
+    fake_server_destroy, fake_server_create_handshaker, fake_check_peer};
+
+grpc_channel_security_context *grpc_fake_channel_security_context_create(
+    grpc_credentials *request_metadata_only_creds) {
+  grpc_channel_security_context *c =
+      gpr_malloc(sizeof(grpc_channel_security_context));
+  gpr_ref_init(&c->base.refcount, 1);
+  c->base.is_client_side = 1;
+  c->base.vtable = &fake_channel_vtable;
+  GPR_ASSERT(check_request_metadata_only_creds(request_metadata_only_creds));
+  c->request_metadata_only_creds =
+      grpc_credentials_ref(request_metadata_only_creds);
+  return c;
+}
+
+grpc_security_context *grpc_fake_server_security_context_create(void) {
+  grpc_security_context *c = gpr_malloc(sizeof(grpc_security_context));
+  gpr_ref_init(&c->refcount, 1);
+  c->vtable = &fake_server_vtable;
+  return c;
+}
+
+/* --- Ssl implementation. --- */
+
+typedef struct {
+  grpc_channel_security_context base;
+  tsi_ssl_handshaker_factory *handshaker_factory;
+  char *secure_peer_name;
+} grpc_ssl_channel_security_context;
+
+typedef struct {
+  grpc_security_context base;
+  tsi_ssl_handshaker_factory *handshaker_factory;
+} grpc_ssl_server_security_context;
+
+static void ssl_channel_destroy(grpc_security_context *ctx) {
+  grpc_ssl_channel_security_context *c =
+      (grpc_ssl_channel_security_context *)ctx;
+  grpc_credentials_unref(c->base.request_metadata_only_creds);
+  if (c->handshaker_factory != NULL) {
+    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
+  }
+  if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
+  gpr_free(ctx);
+}
+
+static void ssl_server_destroy(grpc_security_context *ctx) {
+  grpc_ssl_server_security_context *c =
+      (grpc_ssl_server_security_context *)ctx;
+  if (c->handshaker_factory != NULL) {
+    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
+  }
+  gpr_free(ctx);
+}
+
+static grpc_security_status ssl_create_handshaker(
+    tsi_ssl_handshaker_factory *handshaker_factory, int is_client,
+    const char *secure_peer_name, tsi_handshaker **handshaker) {
+  tsi_result result = TSI_OK;
+  if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
+  result = tsi_ssl_handshaker_factory_create_handshaker(
+      handshaker_factory, is_client ? secure_peer_name : NULL, handshaker);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
+            tsi_result_to_string(result));
+    return GRPC_SECURITY_ERROR;
+  }
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_status ssl_channel_create_handshaker(
+    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+  grpc_ssl_channel_security_context *c =
+      (grpc_ssl_channel_security_context *)ctx;
+  return ssl_create_handshaker(c->handshaker_factory, 1, c->secure_peer_name,
+                               handshaker);
+}
+
+static grpc_security_status ssl_server_create_handshaker(
+    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+  grpc_ssl_server_security_context *c =
+      (grpc_ssl_server_security_context *)ctx;
+  return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
+}
+
+static grpc_security_status ssl_check_peer(const char *secure_peer_name,
+                                           const tsi_peer *peer) {
+  /* Check the ALPN. */
+  const tsi_peer_property *p =
+      tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
+  if (p == NULL || p->type != TSI_PEER_PROPERTY_TYPE_STRING) {
+    gpr_log(GPR_ERROR, "Invalid or missing selected ALPN property.");
+    return GRPC_SECURITY_ERROR;
+  }
+  if (strncmp(GRPC_ALPN_PROTOCOL_STRING, p->value.string.data,
+              p->value.string.length)) {
+    gpr_log(GPR_ERROR, "Invalid ALPN value.");
+    return GRPC_SECURITY_ERROR;
+  }
+
+  /* Check the peer name if specified. */
+  if (secure_peer_name != NULL &&
+      !tsi_ssl_peer_matches_name(peer, secure_peer_name)) {
+    gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate",
+            secure_peer_name);
+    return GRPC_SECURITY_ERROR;
+  }
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_status ssl_channel_check_peer(
+    grpc_security_context *ctx, const tsi_peer *peer,
+    grpc_security_check_peer_cb cb, void *user_data) {
+  grpc_ssl_channel_security_context *c =
+      (grpc_ssl_channel_security_context *)ctx;
+  return ssl_check_peer(c->secure_peer_name, peer);
+}
+
+static grpc_security_status ssl_server_check_peer(
+    grpc_security_context *ctx, const tsi_peer *peer,
+    grpc_security_check_peer_cb cb, void *user_data) {
+  /* TODO(jboeuf): Find a way to expose the peer to the authorization layer. */
+  return ssl_check_peer(NULL, peer);
+}
+
+static grpc_security_context_vtable ssl_channel_vtable = {
+    ssl_channel_destroy, ssl_channel_create_handshaker, ssl_channel_check_peer};
+
+static grpc_security_context_vtable ssl_server_vtable = {
+    ssl_server_destroy, ssl_server_create_handshaker, ssl_server_check_peer};
+
+grpc_security_status grpc_ssl_channel_security_context_create(
+    grpc_credentials *request_metadata_only_creds,
+    const grpc_ssl_config *config, const char *secure_peer_name,
+    grpc_channel_security_context **ctx) {
+  const char *alpn_protocol_string = GRPC_ALPN_PROTOCOL_STRING;
+  unsigned char alpn_protocol_string_len =
+      (unsigned char)strlen(alpn_protocol_string);
+  tsi_result result = TSI_OK;
+  grpc_ssl_channel_security_context *c;
+
+  if (config == NULL || secure_peer_name == NULL ||
+      config->pem_root_certs == NULL) {
+    gpr_log(GPR_ERROR, "An ssl channel needs a secure name and root certs.");
+    return GRPC_SECURITY_ERROR;
+  }
+  if (!check_request_metadata_only_creds(request_metadata_only_creds)) {
+    return GRPC_SECURITY_ERROR;
+  }
+
+  c = gpr_malloc(sizeof(grpc_ssl_channel_security_context));
+  memset(c, 0, sizeof(grpc_ssl_channel_security_context));
+
+  gpr_ref_init(&c->base.base.refcount, 1);
+  c->base.base.vtable = &ssl_channel_vtable;
+  c->base.base.is_client_side = 1;
+  c->base.request_metadata_only_creds =
+      grpc_credentials_ref(request_metadata_only_creds);
+  if (secure_peer_name != NULL) {
+    c->secure_peer_name = gpr_strdup(secure_peer_name);
+  }
+  result = tsi_create_ssl_client_handshaker_factory(
+      config->pem_private_key, config->pem_private_key_size,
+      config->pem_cert_chain, config->pem_cert_chain_size,
+      config->pem_root_certs, config->pem_root_certs_size,
+      GRPC_SSL_CIPHER_SUITES, (const unsigned char **)&alpn_protocol_string,
+      &alpn_protocol_string_len, 1, &c->handshaker_factory);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+            tsi_result_to_string(result));
+    ssl_channel_destroy(&c->base.base);
+    *ctx = NULL;
+    return GRPC_SECURITY_ERROR;
+  }
+  *ctx = &c->base;
+  return GRPC_SECURITY_OK;
+}
+
+grpc_security_status grpc_ssl_server_security_context_create(
+    const grpc_ssl_config *config, grpc_security_context **ctx) {
+  const char *alpn_protocol_string = GRPC_ALPN_PROTOCOL_STRING;
+  unsigned char alpn_protocol_string_len =
+      (unsigned char)strlen(alpn_protocol_string);
+  tsi_result result = TSI_OK;
+  grpc_ssl_server_security_context *c;
+
+  if (config == NULL || config->pem_private_key == NULL ||
+      config->pem_cert_chain == NULL) {
+    gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
+    return GRPC_SECURITY_ERROR;
+  }
+  c = gpr_malloc(sizeof(grpc_ssl_server_security_context));
+  memset(c, 0, sizeof(grpc_ssl_server_security_context));
+
+  gpr_ref_init(&c->base.refcount, 1);
+  c->base.vtable = &ssl_server_vtable;
+  result = tsi_create_ssl_server_handshaker_factory(
+      (const unsigned char **)&config->pem_private_key,
+      (const gpr_uint32 *)&config->pem_private_key_size,
+      (const unsigned char **)&config->pem_cert_chain,
+      (const gpr_uint32 *)&config->pem_cert_chain_size, 1,
+      config->pem_root_certs, config->pem_root_certs_size,
+      GRPC_SSL_CIPHER_SUITES, (const unsigned char **)&alpn_protocol_string,
+      &alpn_protocol_string_len, 1, &c->handshaker_factory);
+  if (result != TSI_OK) {
+    gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+            tsi_result_to_string(result));
+    ssl_server_destroy(&c->base);
+    *ctx = NULL;
+    return GRPC_SECURITY_ERROR;
+  }
+  *ctx = &c->base;
+  return GRPC_SECURITY_OK;
+}
+
+
+
+/* -- High level objects. -- */
+
+static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
+                                             const grpc_ssl_config *config,
+                                             const char *target,
+                                             const grpc_channel_args *args) {
+  grpc_channel_security_context *ctx = NULL;
+  grpc_channel *channel = NULL;
+  grpc_security_status status = GRPC_SECURITY_OK;
+  size_t i = 0;
+  const char *secure_peer_name = target;
+  for (i = 0; i < args->num_args; i++) {
+    grpc_arg *arg = &args->args[i];
+    if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) &&
+        arg->type == GRPC_ARG_STRING) {
+      secure_peer_name = arg->value.string;
+      break;
+    }
+  }
+  status = grpc_ssl_channel_security_context_create(creds, config,
+                                                    secure_peer_name, &ctx);
+  if (status != GRPC_SECURITY_OK) {
+    return NULL; /* TODO(ctiller): return lame channel. */
+  }
+  channel = grpc_secure_channel_create_internal(target, args, ctx);
+  grpc_security_context_unref(&ctx->base);
+  return channel;
+}
+
+
+grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
+                                         const char *target,
+                                         const grpc_channel_args *args) {
+  if (grpc_credentials_has_request_metadata_only(creds)) {
+    gpr_log(GPR_ERROR,
+            "Credentials is insufficient to create a secure channel.");
+    return NULL; /* TODO(ctiller): return lame channel. */
+  }
+  if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
+    return grpc_ssl_channel_create(NULL, grpc_ssl_credentials_get_config(creds),
+                                   target, args);
+  } else if (!strcmp(creds->type,
+                     GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
+    grpc_channel_security_context *ctx =
+        grpc_fake_channel_security_context_create(NULL);
+    grpc_channel *channel =
+        grpc_secure_channel_create_internal(target, args, ctx);
+    grpc_security_context_unref(&ctx->base);
+    return channel;
+  } else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
+    return NULL; /* TODO(jboeuf) Implement. */
+  } else {
+    gpr_log(GPR_ERROR,
+            "Unknown credentials type %s for creating a secure channel.");
+    return NULL; /* TODO(ctiller): return lame channel. */
+  }
+}
+
+grpc_channel *grpc_default_secure_channel_create(
+    const char *target, const grpc_channel_args *args) {
+  return grpc_secure_channel_create(grpc_default_credentials_create(), target,
+                                    args);
+}
+
+grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
+                                       grpc_completion_queue *cq,
+                                       const grpc_channel_args *args) {
+  grpc_security_status status = GRPC_SECURITY_ERROR;
+  grpc_security_context *ctx = NULL;
+  grpc_server *server = NULL;
+  if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */
+  if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
+    status = grpc_ssl_server_security_context_create(
+        grpc_ssl_server_credentials_get_config(creds), &ctx);
+  } else if (!strcmp(creds->type,
+                     GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
+    ctx = grpc_fake_server_security_context_create();
+    status = GRPC_SECURITY_OK;
+  } else {
+    gpr_log(GPR_ERROR,
+            "Unable to create secure server with credentials of type %s.",
+            creds->type);
+  }
+  if (status != GRPC_SECURITY_OK) {
+    return NULL; /* TODO(ctiller): Return lame server. */
+  }
+  server = grpc_secure_server_create_internal(cq, args, ctx);
+  grpc_security_context_unref(ctx);
+  return server;
+}
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
new file mode 100644
index 0000000..59c9bbd
--- /dev/null
+++ b/src/core/security/security_context.h
@@ -0,0 +1,176 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__
+#define __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__
+
+#include <grpc/grpc_security.h>
+#include "src/core/endpoint/endpoint.h"
+#include "src/core/security/credentials.h"
+#include "src/core/tsi/transport_security_interface.h"
+
+/* --- status enum. --- */
+
+typedef enum {
+  GRPC_SECURITY_OK = 0,
+  GRPC_SECURITY_PENDING,
+  GRPC_SECURITY_ERROR
+} grpc_security_status;
+
+/* --- security_context object. ---
+
+    A security context object represents away to configure the underlying
+    transport security mechanism and check the resulting trusted peer.  */
+
+typedef struct grpc_security_context grpc_security_context;
+
+#define GRPC_SECURITY_CONTEXT_ARG "grpc.security_context"
+
+typedef void (*grpc_security_check_peer_cb)(void *user_data,
+                                            grpc_security_status status);
+
+typedef struct {
+  void (*destroy)(grpc_security_context *ctx);
+  grpc_security_status (*create_handshaker)(grpc_security_context *ctx,
+                                            tsi_handshaker **handshaker);
+  grpc_security_status (*check_peer)(grpc_security_context *ctx,
+                                     const tsi_peer *peer,
+                                     grpc_security_check_peer_cb,
+                                     void *user_data);
+} grpc_security_context_vtable;
+
+struct grpc_security_context {
+  const grpc_security_context_vtable *vtable;
+  gpr_refcount refcount;
+  int is_client_side;
+};
+
+/* Increments the refcount. */
+grpc_security_context *grpc_security_context_ref(grpc_security_context *ctx);
+
+/* Decrements the refcount and destroys the object if it reaches 0. */
+void grpc_security_context_unref(grpc_security_context *ctx);
+
+/* Handshake creation. */
+grpc_security_status grpc_security_context_create_handshaker(
+    grpc_security_context *ctx, tsi_handshaker **handshaker);
+
+/* Check the peer.
+   Implementations can choose to check the peer either synchronously or
+   asynchronously. In the first case, a successful will return
+   GRPC_SECURITY_OK. In the asynchronous case, the call will return
+   GRPC_SECURITY_PENDING unless an error is detected early on.
+
+   Note:
+   Asynchronous implementations of this interface should make a copy of the
+   fields of the peer they want to check as there is no guarantee on the
+   lifetime of the peer object beyond this call.
+*/
+grpc_security_status grpc_security_context_check_peer(
+    grpc_security_context *ctx, const tsi_peer *peer,
+    grpc_security_check_peer_cb cb, void *user_data);
+
+/* Util to encapsulate the context in a channel arg. */
+grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx);
+
+/* Util to get the context from a channel arg. */
+grpc_security_context *grpc_security_context_from_arg(const grpc_arg *arg);
+
+/* Util to find the context from channel args. */
+grpc_security_context *grpc_find_security_context_in_args(
+    const grpc_channel_args *args);
+
+/* --- channel_security_context object. ---
+
+    A channel security context object represents away to configure the
+    underlying transport security mechanism on the client side.  */
+
+typedef struct grpc_channel_security_context grpc_channel_security_context;
+
+struct grpc_channel_security_context {
+  grpc_security_context base;  /* requires is_client_side to be non 0. */
+  grpc_credentials *request_metadata_only_creds;
+};
+
+/* --- Creation security contexts. --- */
+
+/* For TESTING ONLY!
+   Creates a fake context that emulates real channel security.  */
+grpc_channel_security_context *grpc_fake_channel_security_context_create(
+    grpc_credentials *request_metadata_only_creds);
+
+/* For TESTING ONLY!
+   Creates a fake context that emulates real server security.  */
+grpc_security_context *grpc_fake_server_security_context_create(void);
+
+/* Creates an SSL channel_security_context.
+   - request_metadata_only_creds is the credentials object which metadata
+     will be sent with each request. This parameter can be NULL.
+   - config is the SSL config to be used for the SSL channel establishment.
+   - is_client should be 0 for a server or a non-0 value for a client.
+   - secure_peer_name is the secure peer name that should be checked in
+     grpc_channel_security_context_check_peer. This parameter may be NULL in
+     which case the peer name will not be checked. Note that if this parameter
+     is not NULL, then, pem_root_certs should not be NULL either.
+   - ctx is a pointer on the context to be created.
+  This function returns GRPC_SECURITY_OK in case of success or a
+  specific error code otherwise.
+*/
+grpc_security_status grpc_ssl_channel_security_context_create(
+    grpc_credentials *request_metadata_only_creds,
+    const grpc_ssl_config *config, const char *secure_peer_name,
+    grpc_channel_security_context **ctx);
+
+/* Creates an SSL server_security_context.
+   - config is the SSL config to be used for the SSL channel establishment.
+   - ctx is a pointer on the context to be created.
+  This function returns GRPC_SECURITY_OK in case of success or a
+  specific error code otherwise.
+*/
+grpc_security_status grpc_ssl_server_security_context_create(
+    const grpc_ssl_config *config, grpc_security_context **ctx);
+
+
+/* --- Creation of high level objects. --- */
+
+/* Secure client channel creation. */
+grpc_channel *grpc_secure_channel_create_internal(
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_context *ctx);
+
+/* Secure server creation. */
+grpc_server *grpc_secure_server_create_internal(
+    grpc_completion_queue *cq, const grpc_channel_args *args,
+    grpc_security_context *ctx);
+
+#endif  /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
new file mode 100644
index 0000000..bce27ec
--- /dev/null
+++ b/src/core/security/server_secure_chttp2.c
@@ -0,0 +1,141 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+
+#include "src/core/channel/http_filter.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/endpoint/resolve_address.h"
+#include "src/core/endpoint/tcp_server.h"
+#include "src/core/security/security_context.h"
+#include "src/core/security/secure_transport_setup.h"
+#include "src/core/surface/server.h"
+#include "src/core/surface/surface_em.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+static grpc_transport_setup_result setup_transport(void *server,
+                                                   grpc_transport *transport,
+                                                   grpc_mdctx *mdctx) {
+  static grpc_channel_filter const *extra_filters[] = {&grpc_http_server_filter,
+                                                       &grpc_http_filter};
+  return grpc_server_setup_transport(server, transport, extra_filters,
+                                     GPR_ARRAY_SIZE(extra_filters), mdctx);
+}
+
+static void on_secure_transport_setup_done(void *server,
+                                           grpc_security_status status,
+                                           grpc_endpoint *secure_endpoint) {
+  if (status == GRPC_SECURITY_OK) {
+    grpc_create_chttp2_transport(
+        setup_transport, server, grpc_server_get_channel_args(server),
+        secure_endpoint, NULL, 0, grpc_mdctx_create(), 0);
+  } else {
+    gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
+  }
+}
+
+static void on_accept(void *server, grpc_endpoint *tcp) {
+  const grpc_channel_args *args = grpc_server_get_channel_args(server);
+  grpc_security_context *ctx = grpc_find_security_context_in_args(args);
+  GPR_ASSERT(ctx);
+  grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done,
+                              server);
+}
+
+/* Note: the following code is the same with server_chttp2.c */
+
+/* Server callback: start listening on our ports */
+static void start(grpc_server *server, void *tcpp) {
+  grpc_tcp_server *tcp = tcpp;
+  grpc_tcp_server_start(tcp, on_accept, server);
+}
+
+/* Server callback: destroy the tcp listener (so we don't generate further
+   callbacks) */
+static void destroy(grpc_server *server, void *tcpp) {
+  grpc_tcp_server *tcp = tcpp;
+  grpc_tcp_server_destroy(tcp);
+}
+
+int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
+  grpc_resolved_addresses *resolved = NULL;
+  grpc_tcp_server *tcp = NULL;
+  size_t i;
+  int count = 0;
+
+  resolved = grpc_blocking_resolve_address(addr, "https");
+  if (!resolved) {
+    goto error;
+  }
+
+  tcp = grpc_tcp_server_create(grpc_surface_em());
+  if (!tcp) {
+    goto error;
+  }
+
+  for (i = 0; i < resolved->naddrs; i++) {
+    if (grpc_tcp_server_add_port(tcp,
+                                 (struct sockaddr *)&resolved->addrs[i].addr,
+                                 resolved->addrs[i].len) >= 0) {
+      count++;
+    }
+  }
+  if (count == 0) {
+    gpr_log(GPR_ERROR, "No address added out of total %d resolved",
+            resolved->naddrs);
+    goto error;
+  }
+  if (count != resolved->naddrs) {
+    gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
+            count, resolved->naddrs);
+  }
+  grpc_resolved_addresses_destroy(resolved);
+
+  /* Register with the server only upon success */
+  grpc_server_add_listener(server, tcp, start, destroy);
+
+  return 1;
+
+/* Error path: cleanup and return */
+error:
+  if (resolved) {
+    grpc_resolved_addresses_destroy(resolved);
+  }
+  if (tcp) {
+    grpc_tcp_server_destroy(tcp);
+  }
+  return 0;
+}
diff --git a/src/core/statistics/census_init.c b/src/core/statistics/census_init.c
new file mode 100644
index 0000000..340214f
--- /dev/null
+++ b/src/core/statistics/census_init.c
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/statistics/census_interface.h"
+
+void census_init() {}
+void census_shutdown() {}
diff --git a/src/core/statistics/census_interface.h b/src/core/statistics/census_interface.h
new file mode 100644
index 0000000..7618387
--- /dev/null
+++ b/src/core/statistics/census_interface.h
@@ -0,0 +1,76 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__
+#define __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__
+
+#include <grpc/support/port_platform.h>
+
+/* Maximum length of an individual census trace annotation. */
+#define CENSUS_MAX_ANNOTATION_LENGTH 200
+
+/* Structure of a census op id. Define as structure because 64bit integer is not
+   available on every platform for C89. */
+typedef struct census_op_id {
+  gpr_uint32 upper;
+  gpr_uint32 lower;
+} census_op_id;
+
+typedef struct census_rpc_stats census_rpc_stats;
+
+/* Initializes Census library. No-op if Census is already initialized. */
+void census_init();
+
+/* Shutdown Census Library. */
+void census_shutdown();
+
+/* Annotates grpc method name on a census_op_id. The method name has the format
+   of <full quantified rpc service name>/<rpc function name>. Returns 0 iff
+   op_id and method_name are all valid. op_id is valid after its creation and
+   before calling census_tracing_end_op().
+
+   TODO(hongyu): Figure out valid characters set for service name and command
+   name and document requirements here.*/
+int census_add_method_tag(census_op_id op_id, const char* method_name);
+
+/* Annotates tracing information to a specific op_id.
+   Up to CENSUS_MAX_ANNOTATION_LENGTH bytes are recorded. */
+void census_tracing_print(census_op_id op_id, const char* annotation);
+
+/* Starts tracing for an RPC. Returns a locally unique census_op_id */
+census_op_id census_tracing_start_op();
+
+/* Ends tracing. Calling this function will invalidate the input op_id. */
+void census_tracing_end_op(census_op_id op_id);
+
+#endif  /* __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__ */
diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c
new file mode 100644
index 0000000..28101ac
--- /dev/null
+++ b/src/core/statistics/census_rpc_stats.c
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+
+#include "src/core/statistics/census_interface.h"
+#include "src/core/statistics/census_rpc_stats.h"
+#include <grpc/support/alloc.h>
+
+census_rpc_stats* census_rpc_stats_create_empty() {
+  census_rpc_stats* ret =
+      (census_rpc_stats*)gpr_malloc(sizeof(census_rpc_stats));
+  memset(ret, 0, sizeof(census_rpc_stats));
+  return ret;
+}
+
+void census_aggregated_rpc_stats_destroy(census_aggregated_rpc_stats* data) {}
+
+void census_record_rpc_client_stats(census_op_id op_id,
+                                    const census_rpc_stats* stats) {}
+
+void census_record_rpc_server_stats(census_op_id op_id,
+                                    const census_rpc_stats* stats) {}
+
+void census_get_server_stats(census_aggregated_rpc_stats* data) {}
+
+void census_get_client_stats(census_aggregated_rpc_stats* data) {}
diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h
new file mode 100644
index 0000000..6ab7614
--- /dev/null
+++ b/src/core/statistics/census_rpc_stats.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__
+#define __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__
+
+#include "src/core/statistics/census_interface.h"
+#include <grpc/support/port_platform.h>
+
+struct census_rpc_stats {
+  gpr_uint64 cnt;
+  gpr_uint64 rpc_error_cnt;
+  gpr_uint64 app_error_cnt;
+  double elapsed_time_ms;
+  double api_request_bytes;
+  double wire_request_bytes;
+  double api_response_bytes;
+  double wire_response_bytes;
+};
+
+/* Creates an empty rpc stats object on heap. */
+census_rpc_stats* census_rpc_stats_create_empty();
+
+typedef struct census_per_service_per_method_rpc_stats {
+  const char* service;
+  const char* method;
+  census_rpc_stats data;
+} census_per_service_per_method_rpc_stats;
+
+typedef struct census_aggregated_rpc_stats {
+  int num_entries;
+  census_per_service_per_method_rpc_stats* stats;
+} census_aggregated_rpc_stats;
+
+/* Deletes aggregated data. */
+void census_aggregated_rpc_stats_destroy(census_aggregated_rpc_stats* data);
+
+/* Records client side stats of a rpc. */
+void census_record_rpc_client_stats(census_op_id op_id,
+                                    const census_rpc_stats* stats);
+
+/* Records server side stats of a rpc. */
+void census_record_rpc_server_stats(census_op_id op_id,
+                                    const census_rpc_stats* stats);
+
+/* The following two functions are intended for inprocess query of
+   per-service per-method stats from grpc implementations. */
+
+/* Populates *data_map with server side aggregated per-service per-method
+   stats.
+   DO NOT CALL from outside of grpc code. */
+void census_get_server_stats(census_aggregated_rpc_stats* data_map);
+
+/* Populates *data_map with client side aggregated per-service per-method
+   stats.
+   DO NOT CALL from outside of grpc code. */
+void census_get_client_stats(census_aggregated_rpc_stats* data_map);
+
+#endif  /* __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__ */
diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c
new file mode 100644
index 0000000..d0c9032
--- /dev/null
+++ b/src/core/statistics/census_tracing.c
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/statistics/census_interface.h"
+
+census_op_id census_tracing_start_op() {
+  census_op_id empty_op_id = {0, 0};
+  return empty_op_id;
+}
+
+int census_add_method_tag(census_op_id op_id, const char* method_name) {
+  return 0;
+}
+
+void census_tracing_print(census_op_id op_id, const char* annotation) {}
+
+void census_tracing_end_op(census_op_id op_id) {}
diff --git a/src/core/statistics/hash_table.c b/src/core/statistics/hash_table.c
new file mode 100644
index 0000000..f0105ee
--- /dev/null
+++ b/src/core/statistics/hash_table.c
@@ -0,0 +1,303 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/statistics/hash_table.h"
+
+#include <stdio.h>
+#include <stddef.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/port_platform.h>
+
+#define CENSUS_HT_NUM_BUCKETS 1999
+
+/* A single hash table data entry */
+typedef struct ht_entry {
+  census_ht_key key;
+  void* data;
+  struct ht_entry* next;
+} ht_entry;
+
+/* hash table bucket */
+typedef struct bucket {
+  /* NULL if bucket is empty */
+  ht_entry* next;
+  /* -1 if all buckets are empty. */
+  gpr_int32 prev_non_empty_bucket;
+  /* -1 if all buckets are empty. */
+  gpr_int32 next_non_empty_bucket;
+} bucket;
+
+struct unresizable_hash_table {
+  /* Number of entries in the table */
+  size_t size;
+  /* Number of buckets */
+  gpr_uint32 num_buckets;
+  /* Array of buckets initialized at creation time. Memory consumption is
+     16 bytes per bucket on a 64-bit platform. */
+  bucket* buckets;
+  /* Index of the first non-empty bucket. -1 iff size == 0. */
+  gpr_int32 first_non_empty_bucket;
+  /* Index of the last non_empty bucket. -1 iff size == 0. */
+  gpr_int32 last_non_empty_bucket;
+  /* Immutable options of this hash table, initialized at creation time. */
+  census_ht_option options;
+};
+
+typedef struct entry_locator {
+  gpr_int32 bucket_idx;
+  int is_first_in_chain;
+  int found;
+  ht_entry* prev_entry;
+} entry_locator;
+
+/* Asserts if option is not valid. */
+void check_options(const census_ht_option* option) {
+  GPR_ASSERT(option != NULL);
+  GPR_ASSERT(option->num_buckets > 0);
+  GPR_ASSERT(option->key_type == CENSUS_HT_UINT64 ||
+             option->key_type == CENSUS_HT_POINTER);
+  if (option->key_type == CENSUS_HT_UINT64) {
+    GPR_ASSERT(option->hash == NULL);
+  } else if (option->key_type == CENSUS_HT_POINTER) {
+    GPR_ASSERT(option->hash != NULL);
+    GPR_ASSERT(option->compare_keys != NULL);
+  }
+}
+
+#define REMOVE_NEXT(options, ptr) \
+  do {                            \
+    ht_entry* tmp = (ptr)->next;  \
+    (ptr)->next = tmp->next;      \
+    delete_entry(options, tmp);   \
+  } while (0)
+
+static void delete_entry(const census_ht_option* opt, ht_entry* p) {
+  if (opt->delete_data != NULL) {
+    opt->delete_data(p->data);
+  }
+  if (opt->delete_key != NULL) {
+    opt->delete_key(p->key.ptr);
+  }
+  gpr_free(p);
+}
+
+static gpr_uint64 hash(const census_ht_option* opt, census_ht_key key) {
+  return opt->key_type == CENSUS_HT_UINT64 ? key.val : opt->hash(key.ptr);
+}
+
+census_ht* census_ht_create(const census_ht_option* option) {
+  int i;
+  census_ht* ret = NULL;
+  check_options(option);
+  ret = (census_ht*)gpr_malloc(sizeof(census_ht));
+  ret->size = 0;
+  ret->num_buckets = option->num_buckets;
+  ret->buckets = (bucket*)gpr_malloc(sizeof(bucket) * ret->num_buckets);
+  ret->options = *option;
+  /* initialize each bucket */
+  for (i = 0; i < ret->options.num_buckets; i++) {
+    ret->buckets[i].prev_non_empty_bucket = -1;
+    ret->buckets[i].next_non_empty_bucket = -1;
+    ret->buckets[i].next = NULL;
+  }
+  return ret;
+}
+
+static gpr_int32 find_bucket_idx(const census_ht* ht, census_ht_key key) {
+  return hash(&ht->options, key) % ht->num_buckets;
+}
+
+static int keys_match(const census_ht_option* opt, const ht_entry* p,
+                      const census_ht_key key) {
+  if (opt->key_type == CENSUS_HT_UINT64) return p->key.val == key.val;
+  if (opt->key_type == CENSUS_HT_POINTER)
+    return !opt->compare_keys((p->key).ptr, key.ptr);
+  return 0;
+}
+
+static entry_locator ht_find(const census_ht* ht, census_ht_key key) {
+  entry_locator loc = {0, 0, 0, NULL};
+  gpr_int32 idx = 0;
+  ht_entry* ptr = NULL;
+  GPR_ASSERT(ht != NULL);
+  idx = find_bucket_idx(ht, key);
+  ptr = ht->buckets[idx].next;
+  if (ptr == NULL) {
+    /* bucket is empty */
+    return loc;
+  }
+  if (keys_match(&ht->options, ptr, key)) {
+    loc.bucket_idx = idx;
+    loc.is_first_in_chain = 1;
+    loc.found = 1;
+    return loc;
+  } else {
+    for (; ptr->next != NULL; ptr = ptr->next) {
+      if (keys_match(&ht->options, ptr->next, key)) {
+        loc.bucket_idx = idx;
+        loc.is_first_in_chain = 0;
+        loc.found = 1;
+        loc.prev_entry = ptr;
+        return loc;
+      }
+    }
+  }
+  /* Could not find the key */
+  return loc;
+}
+
+void* census_ht_find(const census_ht* ht, census_ht_key key) {
+  entry_locator loc = ht_find(ht, key);
+  if (loc.found == 0) {
+    return NULL;
+  }
+  return loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next->data
+                               : loc.prev_entry->next->data;
+}
+
+void census_ht_insert(census_ht* ht, census_ht_key key, void* data) {
+  gpr_int32 idx = find_bucket_idx(ht, key);
+  ht_entry* ptr = NULL;
+  entry_locator loc = ht_find(ht, key);
+  if (loc.found) {
+    /* Replace old value with new value. */
+    ptr = loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next
+                                : loc.prev_entry->next;
+    if (ht->options.delete_data != NULL) {
+      ht->options.delete_data(ptr->data);
+    }
+    ptr->data = data;
+    return;
+  }
+
+  /* first entry in the table. */
+  if (ht->size == 0) {
+    ht->buckets[idx].next_non_empty_bucket = -1;
+    ht->buckets[idx].prev_non_empty_bucket = -1;
+    ht->first_non_empty_bucket = idx;
+    ht->last_non_empty_bucket = idx;
+  } else if (ht->buckets[idx].next == NULL) {
+    /* first entry in the bucket. */
+    ht->buckets[ht->last_non_empty_bucket].next_non_empty_bucket = idx;
+    ht->buckets[idx].prev_non_empty_bucket = ht->last_non_empty_bucket;
+    ht->buckets[idx].next_non_empty_bucket = -1;
+    ht->last_non_empty_bucket = idx;
+  }
+  ptr = (ht_entry*)gpr_malloc(sizeof(ht_entry));
+  ptr->key = key;
+  ptr->data = data;
+  ptr->next = ht->buckets[idx].next;
+  ht->buckets[idx].next = ptr;
+  ht->size++;
+}
+
+void census_ht_erase(census_ht* ht, census_ht_key key) {
+  entry_locator loc = ht_find(ht, key);
+  if (loc.found == 0) {
+    /* noop if not found */
+    return;
+  }
+  ht->size--;
+  if (loc.is_first_in_chain) {
+    bucket* b = &ht->buckets[loc.bucket_idx];
+    GPR_ASSERT(b->next != NULL);
+    /* The only entry in the bucket */
+    if (b->next->next == NULL) {
+      int prev = b->prev_non_empty_bucket;
+      int next = b->next_non_empty_bucket;
+      if (prev != -1) {
+        ht->buckets[prev].next_non_empty_bucket = next;
+      } else {
+        ht->first_non_empty_bucket = next;
+      }
+      if (next != -1) {
+        ht->buckets[next].prev_non_empty_bucket = prev;
+      } else {
+        ht->last_non_empty_bucket = prev;
+      }
+    }
+    REMOVE_NEXT(&ht->options, b);
+  } else {
+    GPR_ASSERT(loc.prev_entry->next != NULL);
+    REMOVE_NEXT(&ht->options, loc.prev_entry);
+  }
+}
+
+/* Returns NULL if input table is empty. */
+census_ht_kv* census_ht_get_all_elements(const census_ht* ht, size_t* num) {
+  census_ht_kv* ret = NULL;
+  int i = 0;
+  gpr_int32 idx = -1;
+  GPR_ASSERT(ht != NULL && num != NULL);
+  *num = ht->size;
+  if (*num == 0) {
+    return NULL;
+  }
+
+  ret = (census_ht_kv*)gpr_malloc(sizeof(census_ht_kv) * ht->size);
+  idx = ht->first_non_empty_bucket;
+  while (idx >= 0) {
+    ht_entry* ptr = ht->buckets[idx].next;
+    for (; ptr != NULL; ptr = ptr->next) {
+      ret[i].k = ptr->key;
+      ret[i].v = ptr->data;
+      i++;
+    }
+    idx = ht->buckets[idx].next_non_empty_bucket;
+  }
+  return ret;
+}
+
+static void ht_delete_entry_chain(const census_ht_option* options,
+                                  ht_entry* first) {
+  if (first == NULL) {
+    return;
+  }
+  if (first->next != NULL) {
+    ht_delete_entry_chain(options, first->next);
+  }
+  delete_entry(options, first);
+}
+
+void census_ht_destroy(census_ht* ht) {
+  int i;
+  for (i = 0; i < ht->num_buckets; ++i) {
+    ht_delete_entry_chain(&ht->options, ht->buckets[i].next);
+  }
+  gpr_free(ht->buckets);
+  gpr_free(ht);
+}
+
+size_t census_ht_get_size(const census_ht* ht) { return ht->size; }
diff --git a/src/core/statistics/hash_table.h b/src/core/statistics/hash_table.h
new file mode 100644
index 0000000..5c9a3fa
--- /dev/null
+++ b/src/core/statistics/hash_table.h
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_STATISTICS_HASH_TABLE_H_
+#define __GRPC_INTERNAL_STATISTICS_HASH_TABLE_H_
+
+#include <stddef.h>
+
+#include <grpc/support/port_platform.h>
+
+/* A chain based hash table with fixed number of buckets.
+   Your probably shouldn't use this code directly. It is implemented for the
+   use case in census trace store and stats store, where number of entries in
+   the table is in the scale of upto several thousands, entries are added and
+   removed from the table very frequently (~100k/s), the frequency of find()
+   operations is roughly several times of the frequency of insert() and erase()
+   Comparing to find(), the insert(), erase() and get_all_entries() operations
+   are much less freqent (<1/s).
+
+   Per bucket memory overhead is about (8 + sizeof(intptr_t) bytes.
+   Per entry memory overhead is about (8 + 2 * sizeof(intptr_t) bytes.
+
+   All functions are not thread-safe. Synchronization will be provided in the
+   upper layer (in trace store and stats store).
+*/
+
+/* Opaque hash table struct */
+typedef struct unresizable_hash_table census_ht;
+
+/* Currently, the hash_table can take two types of keys. (uint64 for trace
+   store and const char* for stats store). */
+typedef union {
+  gpr_uint64 val;
+  void* ptr;
+} census_ht_key;
+
+typedef enum census_ht_key_type {
+  CENSUS_HT_UINT64 = 0,
+  CENSUS_HT_POINTER = 1
+} census_ht_key_type;
+
+typedef struct census_ht_option {
+  /* Type of hash key */
+  census_ht_key_type key_type;
+  /* Desired number of buckets, preferably a prime number */
+  gpr_int32 num_buckets;
+  /* Fucntion to calculate uint64 hash value of the key. Only takes effect if
+     key_type is POINTER. */
+  gpr_uint64 (*hash)(const void*);
+  /* Function to compare two keys, returns 0 iff equal. Only takes effect if
+     key_type is POINTER */
+  int (*compare_keys)(const void* k1, const void* k2);
+  /* Value deleter. NULL if no specialized delete function is needed. */
+  void (*delete_data)(void*);
+  /* Key deleter. NULL if table does not own the key. (e.g. key is part of the
+     value or key is not owned by the table.) */
+  void (*delete_key)(void*);
+} census_ht_option;
+
+/* Creates a hashtable with fixed number of buckets according to the settings
+   specified in 'options' arg. Function pointers "hash" and "compare_keys" must
+   be provided if key_type is POINTER. Asserts if fail to create. */
+census_ht* census_ht_create(const census_ht_option* options);
+
+/* Deletes hash table instance. Frees all dynamic memory owned by ht.*/
+void census_ht_destroy(census_ht* ht);
+
+/* Inserts the input key-val pair into hash_table. If an entry with the same key
+   exists in the table, the corresponding value will be overwritten by the input
+   val. */
+void census_ht_insert(census_ht* ht, census_ht_key key, void* val);
+
+/* Returns pointer to data, returns NULL if not found. */
+void* census_ht_find(const census_ht* ht, census_ht_key key);
+
+/* Erase hash table entry with input key. Noop if key is not found. */
+void census_ht_erase(census_ht* ht, census_ht_key key);
+
+typedef struct census_ht_kv {
+  census_ht_key k;
+  void* v;
+} census_ht_kv;
+
+/* Returns an array of pointers to all values in the hash table. Order of the
+   elements can be arbitrary. Sets 'num' to the size of returned array. Caller
+   owns returned array. */
+census_ht_kv* census_ht_get_all_elements(const census_ht* ht, size_t* num);
+
+/* Returns number of elements kept. */
+size_t census_ht_get_size(const census_ht* ht);
+
+/* Functor applied on each key-value pair while iterating through entries in the
+   table. The functor should not mutate data. */
+typedef void (*census_ht_itr_cb)(census_ht_key key, const void* val_ptr,
+                                 void* state);
+
+/* Iterates through all key-value pairs in the hash_table. The callback function
+   should not invalidate data entries. */
+gpr_uint64 census_ht_for_all(const census_ht* ht, census_ht_itr_cb);
+
+#endif /* __GRPC_INTERNAL_STATISTICS_HASH_TABLE_H_ */
diff --git a/src/core/statistics/log.c b/src/core/statistics/log.c
new file mode 100644
index 0000000..43a8653
--- /dev/null
+++ b/src/core/statistics/log.c
@@ -0,0 +1,617 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Available log space is divided up in blocks of
+   CENSUS_LOG_2_MAX_RECORD_SIZE bytes. A block can be in one of the
+   following three data structures:
+   - Free blocks (free_block_list)
+   - Blocks with unread data (dirty_block_list)
+   - Blocks currently attached to cores (core_local_blocks[])
+
+   census_log_start_write() moves a block from core_local_blocks[] to the
+   end of dirty_block_list when block:
+   - is out-of-space OR
+   - has an incomplete record (an incomplete record occurs when a thread calls
+     census_log_start_write() and is context-switched before calling
+     census_log_end_write()
+   So, blocks in dirty_block_list are ordered, from oldest to newest, by time
+   when block is detached from the core.
+
+   census_log_read_next() first iterates over dirty_block_list and then
+   core_local_blocks[]. It moves completely read blocks from dirty_block_list
+   to free_block_list. Blocks in core_local_blocks[] are not freed, even when
+   completely read.
+
+   If log is configured to discard old records and free_block_list is empty,
+   census_log_start_write() iterates over dirty_block_list to allocate a
+   new block. It moves the oldest available block (no pending read/write) to
+   core_local_blocks[].
+
+   core_local_block_struct is used to implement a map from core id to the block
+   associated with that core. This mapping is advisory. It is possible that the
+   block returned by this mapping is no longer associated with that core. This
+   mapping is updated, lazily, by census_log_start_write().
+
+   Locking in block struct:
+
+   Exclusive g_log.lock must be held before calling any functions operatong on
+   block structs except census_log_start_write() and
+   census_log_end_write().
+
+   Writes to a block are serialized via writer_lock.
+   census_log_start_write() acquires this lock and
+   census_log_end_write() releases it. On failure to acquire the lock,
+   writer allocates a new block for the current core and updates
+   core_local_block accordingly.
+
+   Simultaneous read and write access is allowed. Reader can safely read up to
+   committed bytes (bytes_committed).
+
+   reader_lock protects the block, currently being read, from getting recycled.
+   start_read() acquires reader_lock and end_read() releases the lock.
+
+   Read/write access to a block is disabled via try_disable_access(). It returns
+   with both writer_lock and reader_lock held. These locks are subsequently
+   released by enable_access() to enable access to the block.
+
+   A note on naming: Most function/struct names are prepended by cl_
+   (shorthand for census_log). Further, functions that manipulate structures
+   include the name of the structure, which will be passed as the first
+   argument. E.g. cl_block_initialize() will initialize a cl_block.
+*/
+#include "src/core/statistics/log.h"
+#include <string.h>
+#include "src/core/support/cpu.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
+#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/sync.h>
+
+/* End of platform specific code */
+
+typedef struct census_log_block_list_struct {
+  struct census_log_block_list_struct* next;
+  struct census_log_block_list_struct* prev;
+  struct census_log_block* block;
+} cl_block_list_struct;
+
+typedef struct census_log_block {
+  /* Pointer to underlying buffer */
+  char* buffer;
+  gpr_atm writer_lock;
+  gpr_atm reader_lock;
+  /* Keeps completely written bytes. Declared atomic because accessed
+     simultaneously by reader and writer. */
+  gpr_atm bytes_committed;
+  /* Bytes already read */
+  gpr_int32 bytes_read;
+  /* Links for list */
+  cl_block_list_struct link;
+  /* We want this structure to be cacheline aligned. We assume the following
+     sizes for the various parts on 32/64bit systems:
+     type                 32b size    64b size
+     char*                   4           8
+     3x gpr_atm             12          24
+     gpr_int32               4           8 (assumes padding)
+     cl_block_list_struct   12          24
+     TOTAL                  32          64
+
+     Depending on the size of our cacheline and the architecture, we
+     selectively add char buffering to this structure. The size is checked
+     via assert in census_log_initialize(). */
+#if defined(GPR_ARCH_64)
+#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 64)
+#else
+#if defined(GPR_ARCH_32)
+#define CL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 32)
+#else
+#error "Unknown architecture"
+#endif
+#endif
+#if CL_BLOCK_PAD_SIZE > 0
+  char padding[CL_BLOCK_PAD_SIZE];
+#endif
+} cl_block;
+
+/* A list of cl_blocks, doubly-linked through cl_block::link. */
+typedef struct census_log_block_list {
+  gpr_int32 count;  /* Number of items in list. */
+  cl_block_list_struct ht;  /* head/tail of linked list. */
+} cl_block_list;
+
+/* Cacheline aligned block pointers to avoid false sharing. Block pointer must
+   be initialized via set_block(), before calling other functions */
+typedef struct census_log_core_local_block {
+  gpr_atm block;
+  /* Ensure cachline alignment: we assume sizeof(gpr_atm) == 4 or 8 */
+#if defined(GPR_ARCH_64)
+#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 8)
+#else
+#if defined(GPR_ARCH_32)
+#define CL_CORE_LOCAL_BLOCK_PAD_SIZE (GPR_CACHELINE_SIZE - 4)
+#else
+#error "Unknown architecture"
+#endif
+#endif
+#if CL_CORE_LOCAL_BLOCK_PAD_SIZE > 0
+  char padding[CL_CORE_LOCAL_BLOCK_PAD_SIZE];
+#endif
+} cl_core_local_block;
+
+struct census_log {
+  int discard_old_records;
+  /* Number of cores (aka hardware-contexts) */
+  int num_cores;
+  /* number of CENSUS_LOG_2_MAX_RECORD_SIZE blocks in log */
+  gpr_int32 num_blocks;
+  cl_block* blocks;  /* Block metadata. */
+  cl_core_local_block* core_local_blocks;  /* Keeps core to block mappings. */
+  gpr_mu lock;
+  int initialized;  /* has log been initialized? */
+  /* Keeps the state of the reader iterator. A value of 0 indicates that
+     iterator has reached the end. census_log_init_reader() resets the
+     value to num_core to restart iteration. */
+  gpr_int32 read_iterator_state;
+  /* Points to the block being read. If non-NULL, the block is locked for
+     reading (block_being_read_->reader_lock is held). */
+  cl_block* block_being_read;
+  /* A non-zero value indicates that log is full. */
+  gpr_atm is_full;
+  char* buffer;
+  cl_block_list free_block_list;
+  cl_block_list dirty_block_list;
+  gpr_atm out_of_space_count;
+};
+
+/* Single internal log */
+static struct census_log g_log;
+
+/* Functions that operate on an atomic memory location used as a lock */
+
+/* Returns non-zero if lock is acquired */
+static int cl_try_lock(gpr_atm* lock) {
+  return gpr_atm_acq_cas(lock, 0, 1);
+}
+
+static void cl_unlock(gpr_atm* lock) {
+  gpr_atm_rel_store(lock, 0);
+}
+
+
+/* Functions that operate on cl_core_local_block's */
+
+static void cl_core_local_block_set_block(cl_core_local_block* clb,
+                                          cl_block* block) {
+  gpr_atm_rel_store(&clb->block, (gpr_atm)block);
+}
+
+static cl_block* cl_core_local_block_get_block(cl_core_local_block* clb) {
+  return (cl_block*)gpr_atm_acq_load(&clb->block);
+}
+
+
+/* Functions that operate on cl_block_list_struct's */
+
+static void cl_block_list_struct_initialize(cl_block_list_struct* bls,
+                                            cl_block* block) {
+  bls->next = bls->prev = bls;
+  bls->block = block;
+}
+
+
+/* Functions that operate on cl_block_list's */
+
+static void cl_block_list_initialize(cl_block_list* list) {
+  list->count = 0;
+  cl_block_list_struct_initialize(&list->ht, NULL);
+}
+
+/* Returns head of *this, or NULL if empty. */
+static cl_block* cl_block_list_head(cl_block_list* list) {
+  return list->ht.next->block;
+}
+
+/* Insert element *e after *pos. */
+static void cl_block_list_insert(cl_block_list* list,
+                                 cl_block_list_struct* pos,
+                                 cl_block_list_struct* e) {
+  list->count++;
+  e->next = pos->next;
+  e->prev = pos;
+  e->next->prev = e;
+  e->prev->next = e;
+}
+
+/* Insert block at the head of the list */
+static void cl_block_list_insert_at_head(cl_block_list* list,
+                                         cl_block* block) {
+  cl_block_list_insert(list, &list->ht, &block->link);
+}
+
+/* Insert block at the tail of the list */
+static void cl_block_list_insert_at_tail(cl_block_list* list,
+                                         cl_block* block) {
+  cl_block_list_insert(list, list->ht.prev, &block->link);
+}
+
+/* Removes block *b. Requires *b be in the list. */
+static void cl_block_list_remove(cl_block_list* list, cl_block* b) {
+  list->count--;
+  b->link.next->prev = b->link.prev;
+  b->link.prev->next = b->link.next;
+}
+
+
+/* Functions that operate on cl_block's */
+
+static void cl_block_initialize(cl_block* block, char* buffer) {
+  block->buffer = buffer;
+  gpr_atm_rel_store(&block->writer_lock, 0);
+  gpr_atm_rel_store(&block->reader_lock, 0);
+  gpr_atm_rel_store(&block->bytes_committed, 0);
+  block->bytes_read = 0;
+  cl_block_list_struct_initialize(&block->link, block);
+}
+
+/* Guards against exposing partially written buffer to the reader. */
+static void cl_block_set_bytes_committed(cl_block* block,
+                                         gpr_int32 bytes_committed) {
+  gpr_atm_rel_store(&block->bytes_committed, bytes_committed);
+}
+
+static gpr_int32 cl_block_get_bytes_committed(cl_block* block) {
+  return gpr_atm_acq_load(&block->bytes_committed);
+}
+
+/* Tries to disable future read/write access to this block. Succeeds if:
+   - no in-progress write AND
+   - no in-progress read AND
+   - 'discard_data' set to true OR no unread data
+   On success, clears the block state and returns with writer_lock_ and
+   reader_lock_ held. These locks are released by a subsequent
+   cl_block_access_enable() call. */
+static int cl_block_try_disable_access(cl_block* block, int discard_data) {
+  if (!cl_try_lock(&block->writer_lock)) {
+    return 0;
+  }
+  if (!cl_try_lock(&block->reader_lock)) {
+    cl_unlock(&block->writer_lock);
+    return 0;
+  }
+  if (!discard_data &&
+      (block->bytes_read != cl_block_get_bytes_committed(block))) {
+    cl_unlock(&block->reader_lock);
+    cl_unlock(&block->writer_lock);
+    return 0;
+  }
+  cl_block_set_bytes_committed(block, 0);
+  block->bytes_read = 0;
+  return 1;
+}
+
+static void cl_block_enable_access(cl_block* block) {
+  cl_unlock(&block->reader_lock);
+  cl_unlock(&block->writer_lock);
+}
+
+/* Returns with writer_lock held. */
+static void* cl_block_start_write(cl_block* block, size_t size) {
+  gpr_int32 bytes_committed;
+  if (!cl_try_lock(&block->writer_lock)) {
+    return NULL;
+  }
+  bytes_committed = cl_block_get_bytes_committed(block);
+  if (bytes_committed + size > CENSUS_LOG_MAX_RECORD_SIZE) {
+    cl_unlock(&block->writer_lock);
+    return NULL;
+  }
+  return block->buffer + bytes_committed;
+}
+
+/* Releases writer_lock and increments committed bytes by 'bytes_written'.
+  'bytes_written' must be <= 'size' specified in the corresponding
+  StartWrite() call. This function is thread-safe. */
+static void cl_block_end_write(cl_block* block, size_t bytes_written) {
+  cl_block_set_bytes_committed(
+      block, cl_block_get_bytes_committed(block) + bytes_written);
+  cl_unlock(&block->writer_lock);
+}
+
+/* Returns a pointer to the first unread byte in buffer. The number of bytes
+   available are returned in 'bytes_available'. Acquires reader lock that is
+   released by a subsequent cl_block_end_read() call. Returns NULL if:
+   - read in progress
+   - no data available */
+static void* cl_block_start_read(cl_block* block, size_t* bytes_available) {
+  void* record;
+  if (!cl_try_lock(&block->reader_lock)) {
+    return NULL;
+  }
+  /* bytes_committed may change from under us. Use bytes_available to update
+     bytes_read below. */
+  *bytes_available = cl_block_get_bytes_committed(block) - block->bytes_read;
+  if (*bytes_available == 0) {
+    cl_unlock(&block->reader_lock);
+    return NULL;
+  }
+  record = block->buffer + block->bytes_read;
+  block->bytes_read += *bytes_available;
+  return record;
+}
+
+static void cl_block_end_read(cl_block* block) {
+  cl_unlock(&block->reader_lock);
+}
+
+
+/* Internal functions operating on g_log */
+
+/* Allocates a new free block (or recycles an available dirty block if log is
+   configured to discard old records). Returns NULL if out-of-space. */
+static cl_block* cl_allocate_block() {
+  cl_block* block = cl_block_list_head(&g_log.free_block_list);
+  if (block != NULL) {
+    cl_block_list_remove(&g_log.free_block_list, block);
+    return block;
+  }
+  if (!g_log.discard_old_records) {
+    /* No free block and log is configured to keep old records. */
+    return NULL;
+  }
+  /* Recycle dirty block. Start from the oldest. */
+  for (block = cl_block_list_head(&g_log.dirty_block_list); block != NULL;
+       block = block->link.next->block) {
+    if (cl_block_try_disable_access(block, 1 /* discard data */)) {
+      cl_block_list_remove(&g_log.dirty_block_list, block);
+      return block;
+    }
+  }
+  return NULL;
+}
+
+/* Allocates a new block and updates core id => block mapping. 'old_block'
+   points to the block that the caller thinks is attached to
+   'core_id'. 'old_block' may be NULL. Returns non-zero if:
+   - allocated a new block OR
+   - 'core_id' => 'old_block' mapping changed (another thread allocated a
+     block before lock was acquired). */
+static int cl_allocate_core_local_block(gpr_int32 core_id,
+                                        cl_block* old_block) {
+  /* Now that we have the lock, check if core-local mapping has changed. */
+  cl_core_local_block* core_local_block = &g_log.core_local_blocks[core_id];
+  cl_block* block = cl_core_local_block_get_block(core_local_block);
+  if ((block != NULL) && (block != old_block)) {
+    return 1;
+  }
+  if (block != NULL) {
+    cl_core_local_block_set_block(core_local_block, NULL);
+    cl_block_list_insert_at_tail(&g_log.dirty_block_list, block);
+  }
+  block = cl_allocate_block();
+  if (block == NULL) {
+    gpr_atm_rel_store(&g_log.is_full, 1);
+    return 0;
+  }
+  cl_core_local_block_set_block(core_local_block, block);
+  cl_block_enable_access(block);
+  return 1;
+}
+
+static cl_block* cl_get_block(void* record) {
+  gpr_uintptr p = (gpr_uintptr)((char*)record - g_log.buffer);
+  gpr_uintptr index = p >> CENSUS_LOG_2_MAX_RECORD_SIZE;
+  return &g_log.blocks[index];
+}
+
+/* Gets the next block to read and tries to free 'prev' block (if not NULL).
+   Returns NULL if reached the end. */
+static cl_block* cl_next_block_to_read(cl_block* prev) {
+  cl_block* block = NULL;
+  if (g_log.read_iterator_state == g_log.num_cores) {
+    /* We are traversing dirty list; find the next dirty block. */
+    if (prev != NULL) {
+      /* Try to free the previous block if there is no unread data. This block
+         may have unread data if previously incomplete record completed between
+         read_next() calls. */
+      block = prev->link.next->block;
+      if (cl_block_try_disable_access(prev, 0 /* do not discard data */)) {
+        cl_block_list_remove(&g_log.dirty_block_list, prev);
+        cl_block_list_insert_at_head(&g_log.free_block_list, prev);
+        gpr_atm_rel_store(&g_log.is_full, 0);
+      }
+    } else {
+      block = cl_block_list_head(&g_log.dirty_block_list);
+    }
+    if (block != NULL) {
+      return block;
+    }
+    /* We are done with the dirty list; moving on to core-local blocks. */
+  }
+  while (g_log.read_iterator_state > 0) {
+    g_log.read_iterator_state--;
+    block = cl_core_local_block_get_block(
+        &g_log.core_local_blocks[g_log.read_iterator_state]);
+    if (block != NULL) {
+      return block;
+    }
+  }
+  return NULL;
+}
+
+/* External functions: primary stats_log interface */
+void census_log_initialize(size_t size_in_mb, int discard_old_records) {
+  gpr_int32 ix;
+  /* check cacheline alignment */
+  GPR_ASSERT(sizeof(cl_block) % GPR_CACHELINE_SIZE == 0);
+  GPR_ASSERT(sizeof(cl_core_local_block) % GPR_CACHELINE_SIZE == 0);
+  GPR_ASSERT(!g_log.initialized);
+  g_log.discard_old_records = discard_old_records;
+  g_log.num_cores = gpr_cpu_num_cores();
+  if (size_in_mb < 1 || size_in_mb > 1000) {
+    gpr_log(GPR_ERROR, "Invalid size for stats_log: using 1MB default");
+    size_in_mb = 1;
+  }
+  g_log.num_blocks = (size_in_mb << 20) >> CENSUS_LOG_2_MAX_RECORD_SIZE;
+  gpr_mu_init(&g_log.lock);
+  g_log.read_iterator_state = 0;
+  g_log.block_being_read = NULL;
+  gpr_atm_rel_store(&g_log.is_full, 0);
+  g_log.core_local_blocks = (cl_core_local_block*)gpr_malloc_aligned(
+      g_log.num_cores * sizeof(cl_core_local_block), GPR_CACHELINE_SIZE);
+  memset(g_log.core_local_blocks, 0,
+         g_log.num_cores * sizeof(cl_core_local_block));
+  g_log.blocks = (cl_block*)gpr_malloc_aligned(
+      g_log.num_blocks * sizeof(cl_block), GPR_CACHELINE_SIZE);
+  memset(g_log.blocks, 0, g_log.num_blocks * sizeof(cl_block));
+  g_log.buffer = gpr_malloc(g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE);
+  memset(g_log.buffer, 0, g_log.num_blocks * CENSUS_LOG_MAX_RECORD_SIZE);
+  cl_block_list_initialize(&g_log.free_block_list);
+  cl_block_list_initialize(&g_log.dirty_block_list);
+  for (ix = 0; ix < g_log.num_blocks; ++ix) {
+    cl_block* block = g_log.blocks + ix;
+    cl_block_initialize(block,
+                         g_log.buffer + (CENSUS_LOG_MAX_RECORD_SIZE * ix));
+    cl_block_try_disable_access(block, 1 /* discard data */);
+    cl_block_list_insert_at_tail(&g_log.free_block_list, block);
+  }
+  gpr_atm_rel_store(&g_log.out_of_space_count, 0);
+  g_log.initialized = 1;
+}
+
+void census_log_shutdown() {
+  GPR_ASSERT(g_log.initialized);
+  gpr_mu_destroy(&g_log.lock);
+  gpr_free_aligned(g_log.core_local_blocks);
+  g_log.core_local_blocks = NULL;
+  gpr_free_aligned(g_log.blocks);
+  g_log.blocks = NULL;
+  gpr_free(g_log.buffer);
+  g_log.buffer = NULL;
+  g_log.initialized = 0;
+}
+
+void* census_log_start_write(size_t size) {
+  /* Used to bound number of times block allocation is attempted. */
+  gpr_int32 attempts_remaining = g_log.num_blocks;
+  /* TODO(aveitch): move this inside the do loop when current_cpu is fixed */
+  gpr_int32 core_id = gpr_cpu_current_cpu();
+  GPR_ASSERT(g_log.initialized);
+  if (size > CENSUS_LOG_MAX_RECORD_SIZE) {
+    return NULL;
+  }
+  do {
+    int allocated;
+    void* record = NULL;
+    cl_block* block =
+        cl_core_local_block_get_block(&g_log.core_local_blocks[core_id]);
+    if (block && (record = cl_block_start_write(block, size))) {
+      return record;
+    }
+    /* Need to allocate a new block. We are here if:
+       - No block associated with the core OR
+       - Write in-progress on the block OR
+       - block is out of space */
+    if (gpr_atm_acq_load(&g_log.is_full)) {
+      gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
+      return NULL;
+    }
+    gpr_mu_lock(&g_log.lock);
+    allocated = cl_allocate_core_local_block(core_id, block);
+    gpr_mu_unlock(&g_log.lock);
+    if (!allocated) {
+      gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
+      return NULL;
+    }
+  } while (attempts_remaining--);
+  /* Give up. */
+  gpr_atm_no_barrier_fetch_add(&g_log.out_of_space_count, 1);
+  return NULL;
+}
+
+void census_log_end_write(void* record, size_t bytes_written) {
+  GPR_ASSERT(g_log.initialized);
+  cl_block_end_write(cl_get_block(record), bytes_written);
+}
+
+void census_log_init_reader() {
+  GPR_ASSERT(g_log.initialized);
+  gpr_mu_lock(&g_log.lock);
+  /* If a block is locked for reading unlock it. */
+  if (g_log.block_being_read != NULL) {
+    cl_block_end_read(g_log.block_being_read);
+    g_log.block_being_read = NULL;
+  }
+  g_log.read_iterator_state = g_log.num_cores;
+  gpr_mu_unlock(&g_log.lock);
+}
+
+const void* census_log_read_next(size_t* bytes_available) {
+  GPR_ASSERT(g_log.initialized);
+  gpr_mu_lock(&g_log.lock);
+  if (g_log.block_being_read != NULL) {
+    cl_block_end_read(g_log.block_being_read);
+  }
+  do {
+    g_log.block_being_read = cl_next_block_to_read(g_log.block_being_read);
+    if (g_log.block_being_read != NULL) {
+      void* record = cl_block_start_read(g_log.block_being_read,
+                                          bytes_available);
+      if (record != NULL) {
+        gpr_mu_unlock(&g_log.lock);
+        return record;
+      }
+    }
+  } while (g_log.block_being_read != NULL);
+  gpr_mu_unlock(&g_log.lock);
+  return NULL;
+}
+
+size_t census_log_remaining_space() {
+  size_t space;
+  GPR_ASSERT(g_log.initialized);
+  gpr_mu_lock(&g_log.lock);
+  if (g_log.discard_old_records) {
+    /* Remaining space is not meaningful; just return the entire log space. */
+    space = g_log.num_blocks << CENSUS_LOG_2_MAX_RECORD_SIZE;
+  } else {
+    space = g_log.free_block_list.count * CENSUS_LOG_MAX_RECORD_SIZE;
+  }
+  gpr_mu_unlock(&g_log.lock);
+  return space;
+}
+
+int census_log_out_of_space_count() {
+  GPR_ASSERT(g_log.initialized);
+  return gpr_atm_acq_load(&g_log.out_of_space_count);
+}
diff --git a/src/core/statistics/log.h b/src/core/statistics/log.h
new file mode 100644
index 0000000..e9c745c
--- /dev/null
+++ b/src/core/statistics/log.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_STATISTICS_LOG_H__
+#define __GRPC_INTERNAL_STATISTICS_LOG_H__
+
+#include <stddef.h>
+
+/* Maximum record size, in bytes. */
+#define CENSUS_LOG_2_MAX_RECORD_SIZE 14 /* 2^14 = 16KB */
+#define CENSUS_LOG_MAX_RECORD_SIZE (1 << CENSUS_LOG_2_MAX_RECORD_SIZE)
+
+/* Initialize the statistics logging subsystem with the given log size. If
+   discard_old_records is non-zero, then new records will displace older
+   ones when the log is full. This function must be called before any other
+   census_log functions.
+*/
+void census_log_initialize(size_t size_in_mb, int discard_old_records);
+
+/* Shutdown the logging subsystem. Caller must ensure that:
+   - no in progress or future call to any census_log functions
+   - no incomplete records
+*/
+void census_log_shutdown();
+
+/* Allocates and returns a 'size' bytes record and marks it in use. A
+   subsequent census_log_end_write() marks the record complete. The
+   'bytes_written' census_log_end_write() argument must be <=
+   'size'. Returns NULL if out-of-space AND:
+       - log is configured to keep old records OR
+       - all blocks are pinned by incomplete records.
+*/
+void* census_log_start_write(size_t size);
+
+void census_log_end_write(void* record, size_t bytes_written);
+
+/* census_log_read_next() iterates over blocks with data and for each block
+   returns a pointer to the first unread byte. The number of bytes that can be
+   read are returned in 'bytes_available'. Reader is expected to read all
+   available data. Reading the data consumes it i.e. it cannot be read again.
+   census_log_read_next() returns NULL if the end is reached i.e last block
+   is read. census_log_init_reader() starts the iteration or aborts the
+   current iteration.
+*/
+void census_log_init_reader();
+const void* census_log_read_next(size_t* bytes_available);
+
+/* Returns estimated remaining space across all blocks, in bytes. If log is
+   configured to discard old records, returns total log space. Otherwise,
+   returns space available in empty blocks (partially filled blocks are
+   treated as full).
+*/
+size_t census_log_remaining_space();
+
+/* Returns the number of times gprc_stats_log_start_write() failed due to
+   out-of-space. */
+int census_log_out_of_space_count();
+
+#endif  /* __GRPC_INTERNAL_STATISTICS_LOG_H__ */
diff --git a/src/core/statistics/window_stats.c b/src/core/statistics/window_stats.c
new file mode 100644
index 0000000..be53d81
--- /dev/null
+++ b/src/core/statistics/window_stats.c
@@ -0,0 +1,317 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/statistics/window_stats.h"
+#include <math.h>
+#include <stddef.h>
+#include <string.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+/* typedefs make typing long names easier. Use cws (for census_window_stats) */
+typedef census_window_stats_stat_info cws_stat_info;
+typedef struct census_window_stats_sum cws_sum;
+
+/* Each interval is composed of a number of buckets, which hold a count of
+   entries and a single statistic */
+typedef struct census_window_stats_bucket {
+  gpr_int64 count;
+  void* statistic;
+} cws_bucket;
+
+/* Each interval has a set of buckets, and the variables needed to keep
+   track of their current state */
+typedef struct census_window_stats_interval_stats {
+  /* The buckets. There will be 'granularity' + 1 of these. */
+  cws_bucket* buckets;
+  /* Index of the bucket containing the smallest time interval. */
+  int bottom_bucket;
+  /* The smallest time storable in the current window. */
+  gpr_int64 bottom;
+  /* The largest time storable in the current window + 1ns */
+  gpr_int64 top;
+  /* The width of each bucket in ns. */
+  gpr_int64 width;
+} cws_interval_stats;
+
+typedef struct census_window_stats {
+  /* Number of intervals. */
+  int nintervals;
+  /* Number of buckets in each interval. 'granularity' + 1. */
+  int nbuckets;
+  /* Record of stat_info. */
+  cws_stat_info stat_info;
+  /* Stats for each interval. */
+  cws_interval_stats* interval_stats;
+  /* The time the newset stat was recorded. */
+  gpr_int64 newest_time;
+} window_stats;
+
+/* Calculate an actual bucket index from a logical index 'IDX'. Other
+   parameters supply information on the interval struct and overall stats. */
+#define BUCKET_IDX(IS, IDX, WSTATS) \
+  ((IS->bottom_bucket + (IDX)) % WSTATS->nbuckets)
+
+/* The maximum seconds value we can have in a valid timespec. More than this
+   will result in overflow in timespec_to_ns(). This works out to ~292 years.
+   TODO: consider using doubles instead of int64. */
+static gpr_int64 max_seconds =
+    (GPR_INT64_MAX - GPR_NS_PER_SEC) / GPR_NS_PER_SEC;
+
+static gpr_int64 timespec_to_ns(const gpr_timespec ts) {
+  if (ts.tv_sec > max_seconds) {
+    return GPR_INT64_MAX - 1;
+  }
+  return (gpr_int64)ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec;
+}
+
+static void cws_initialize_statistic(void* statistic,
+                                     const cws_stat_info* stat_info) {
+  if (stat_info->stat_initialize == NULL) {
+    memset(statistic, 0, stat_info->stat_size);
+  } else {
+    stat_info->stat_initialize(statistic);
+  }
+}
+
+/* Create and initialize a statistic */
+static void* cws_create_statistic(const cws_stat_info* stat_info) {
+  void* stat = gpr_malloc(stat_info->stat_size);
+  cws_initialize_statistic(stat, stat_info);
+  return stat;
+}
+
+window_stats* census_window_stats_create(int nintervals,
+                                         const gpr_timespec intervals[],
+                                         int granularity,
+                                         const cws_stat_info* stat_info) {
+  window_stats* ret;
+  int i;
+  /* validate inputs */
+  GPR_ASSERT(nintervals > 0 && granularity > 2 && intervals != NULL &&
+             stat_info != NULL);
+  for (i = 0; i < nintervals; i++) {
+    gpr_int64 ns = timespec_to_ns(intervals[i]);
+    GPR_ASSERT(intervals[i].tv_sec >= 0 && intervals[i].tv_nsec >= 0 &&
+               intervals[i].tv_nsec < GPR_NS_PER_SEC && ns >= 100 &&
+               granularity * 10 <= ns);
+  }
+  /* Allocate and initialize relevant data structures */
+  ret = (window_stats*)gpr_malloc(sizeof(window_stats));
+  ret->nintervals = nintervals;
+  ret->nbuckets = granularity + 1;
+  ret->stat_info = *stat_info;
+  ret->interval_stats =
+      (cws_interval_stats*)gpr_malloc(nintervals * sizeof(cws_interval_stats));
+  for (i = 0; i < nintervals; i++) {
+    gpr_int64 size_ns = timespec_to_ns(intervals[i]);
+    cws_interval_stats* is = ret->interval_stats + i;
+    cws_bucket* buckets = is->buckets =
+        (cws_bucket*)gpr_malloc(ret->nbuckets * sizeof(cws_bucket));
+    int b;
+    for (b = 0; b < ret->nbuckets; b++) {
+      buckets[b].statistic = cws_create_statistic(stat_info);
+      buckets[b].count = 0;
+    }
+    is->bottom_bucket = 0;
+    is->bottom = 0;
+    is->width = size_ns / granularity;
+    /* Check for possible overflow issues, and maximize interval size if the
+       user requested something large enough. */
+    if (GPR_INT64_MAX - is->width > size_ns) {
+      is->top = size_ns + is->width;
+    } else {
+      is->top = GPR_INT64_MAX;
+      is->width = GPR_INT64_MAX / (granularity + 1);
+    }
+    /* If size doesn't divide evenly, we can have a width slightly too small;
+       better to have it slightly large. */
+    if ((size_ns - (granularity + 1) * is->width) > 0) {
+      is->width += 1;
+    }
+  }
+  ret->newest_time = 0;
+  return ret;
+}
+
+/* When we try adding a measurement above the current interval range, we
+   need to "shift" the buckets sufficiently to cover the new range. */
+static void cws_shift_buckets(const window_stats* wstats,
+                              cws_interval_stats* is, gpr_int64 when_ns) {
+  int i;
+  /* number of bucket time widths to "shift" */
+  int shift;
+  /* number of buckets to clear */
+  int nclear;
+  GPR_ASSERT(when_ns >= is->top);
+  /* number of bucket time widths to "shift" */
+  shift = ((when_ns - is->top) / is->width) + 1;
+  /* number of buckets to clear - limited by actual number of buckets */
+  nclear = GPR_MIN(shift, wstats->nbuckets);
+  for (i = 0; i < nclear; i++) {
+    int b = BUCKET_IDX(is, i, wstats);
+    is->buckets[b].count = 0;
+    cws_initialize_statistic(is->buckets[b].statistic, &wstats->stat_info);
+  }
+  /* adjust top/bottom times and current bottom bucket */
+  is->bottom_bucket = BUCKET_IDX(is, shift, wstats);
+  is->top += shift * is->width;
+  is->bottom += shift * is->width;
+}
+
+void census_window_stats_add(window_stats* wstats, const gpr_timespec when,
+                             const void* stat_value) {
+  int i;
+  gpr_int64 when_ns = timespec_to_ns(when);
+  GPR_ASSERT(wstats->interval_stats != NULL);
+  for (i = 0; i < wstats->nintervals; i++) {
+    cws_interval_stats* is = wstats->interval_stats + i;
+    cws_bucket* bucket;
+    if (when_ns < is->bottom) { /* Below smallest time in interval: drop */
+      continue;
+    }
+    if (when_ns >= is->top) { /* above limit: shift buckets */
+      cws_shift_buckets(wstats, is, when_ns);
+    }
+    /* Add the stat. */
+    GPR_ASSERT(is->bottom <= when_ns && when_ns < is->top);
+    bucket = is->buckets +
+             BUCKET_IDX(is, (when_ns - is->bottom) / is->width, wstats);
+    bucket->count++;
+    wstats->stat_info.stat_add(bucket->statistic, stat_value);
+  }
+  if (when_ns > wstats->newest_time) {
+    wstats->newest_time = when_ns;
+  }
+}
+
+/* Add a specific bucket contents to an accumulating total. */
+static void cws_add_bucket_to_sum(cws_sum* sum, const cws_bucket* bucket,
+                                  const cws_stat_info* stat_info) {
+  sum->count += bucket->count;
+  stat_info->stat_add(sum->statistic, bucket->statistic);
+}
+
+/* Add a proportion to an accumulating sum. */
+static void cws_add_proportion_to_sum(double p, cws_sum* sum,
+                                      const cws_bucket* bucket,
+                                      const cws_stat_info* stat_info) {
+  sum->count += p * bucket->count;
+  stat_info->stat_add_proportion(p, sum->statistic, bucket->statistic);
+}
+
+void census_window_stats_get_sums(const window_stats* wstats,
+                                  const gpr_timespec when, cws_sum sums[]) {
+  int i;
+  gpr_int64 when_ns = timespec_to_ns(when);
+  GPR_ASSERT(wstats->interval_stats != NULL);
+  for (i = 0; i < wstats->nintervals; i++) {
+    int when_bucket;
+    int new_bucket;
+    double last_proportion = 1.0;
+    double bottom_proportion;
+    cws_interval_stats* is = wstats->interval_stats + i;
+    cws_sum* sum = sums + i;
+    sum->count = 0;
+    cws_initialize_statistic(sum->statistic, &wstats->stat_info);
+    if (when_ns < is->bottom) {
+      continue;
+    }
+    if (when_ns >= is->top) {
+      cws_shift_buckets(wstats, is, when_ns);
+    }
+    /* Calculating the appropriate amount of which buckets to use can get
+       complicated. Essentially there are two cases:
+       1) if the "top" bucket (new_bucket, where the newest additions to the
+          stats recorded are entered) corresponds to 'when', then we need
+          to take a proportion of it - (if when < newest_time) or the full
+          thing. We also (possibly) need to take a corresponding
+          proportion of the bottom bucket.
+       2) Other cases, we just take a straight proportion.
+    */
+    when_bucket = (when_ns - is->bottom) / is->width;
+    new_bucket = (wstats->newest_time - is->bottom) / is->width;
+    if (new_bucket == when_bucket) {
+      gpr_int64 bottom_bucket_time = is->bottom + when_bucket * is->width;
+      if (when_ns < wstats->newest_time) {
+        last_proportion = (double)(when_ns - bottom_bucket_time) /
+                          (double)(wstats->newest_time - bottom_bucket_time);
+        bottom_proportion =
+            (double)(is->width - (when_ns - bottom_bucket_time)) / is->width;
+      } else {
+        bottom_proportion =
+            (double)(is->width - (wstats->newest_time - bottom_bucket_time)) /
+            is->width;
+      }
+    } else {
+      last_proportion =
+          (double)(when_ns + 1 - is->bottom - when_bucket * is->width) /
+          is->width;
+      bottom_proportion = 1.0 - last_proportion;
+    }
+    cws_add_proportion_to_sum(last_proportion, sum,
+                              is->buckets + BUCKET_IDX(is, when_bucket, wstats),
+                              &wstats->stat_info);
+    if (when_bucket != 0) { /* last bucket isn't also bottom bucket */
+      int b;
+      /* Add all of "bottom" bucket if we are looking at a subset of the
+         full interval, or a proportion if we are adding full interval. */
+      cws_add_proportion_to_sum(
+          (when_bucket == wstats->nbuckets - 1 ? bottom_proportion : 1.0), sum,
+          is->buckets + is->bottom_bucket, &wstats->stat_info);
+      /* Add all the remaining buckets (everything but top and bottom). */
+      for (b = 1; b < when_bucket; b++) {
+        cws_add_bucket_to_sum(sum, is->buckets + BUCKET_IDX(is, b, wstats),
+                              &wstats->stat_info);
+      }
+    }
+  }
+}
+
+void census_window_stats_destroy(window_stats* wstats) {
+  int i;
+  GPR_ASSERT(wstats->interval_stats != NULL);
+  for (i = 0; i < wstats->nintervals; i++) {
+    int b;
+    for (b = 0; b < wstats->nbuckets; b++) {
+      gpr_free(wstats->interval_stats[i].buckets[b].statistic);
+    }
+    gpr_free(wstats->interval_stats[i].buckets);
+  }
+  gpr_free(wstats->interval_stats);
+  /* Ensure any use-after free triggers assert. */
+  wstats->interval_stats = NULL;
+  gpr_free(wstats);
+}
diff --git a/src/core/statistics/window_stats.h b/src/core/statistics/window_stats.h
new file mode 100644
index 0000000..677f400
--- /dev/null
+++ b/src/core/statistics/window_stats.h
@@ -0,0 +1,173 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_STATISTICS_WINDOW_STATS_H_
+#define __GRPC_INTERNAL_STATISTICS_WINDOW_STATS_H_
+
+#include <grpc/support/time.h>
+
+/* Keep rolling sums of a user-defined statistic (containing a number of
+   measurements) over a a number of time intervals ("windows"). For example,
+   you can use a window_stats object to answer questions such as
+   "Approximately how many RPCs/s did I receive over the past minute, and
+   approximately how many bytes did I send out over that period?".
+
+   The type of data to record, and the time intervals to keep are specified
+   when creating the object via a call to census_window_stats_create().
+
+   A window's interval is divided into one or more "buckets"; the interval
+   must be divisible by the number of buckets. Internally, these buckets
+   control the granularity of window_stats' measurements. Increasing the
+   number of buckets lets the object respond more quickly to changes in the
+   overall rate of data added into the object, at the cost of additional
+   memory usage.
+
+   Here's some code which keeps one minute/hour measurements for two values
+   (latency in seconds and bytes transferred), with each interval divided into
+   4 buckets.
+
+    typedef struct my_stat {
+      double latency;
+      int bytes;
+    } my_stat;
+
+    void add_my_stat(void* base, const void* addme) {
+      my_stat* b = (my_stat*)base;
+      const my_stat* a = (const my_stat*)addme;
+      b->latency += a->latency;
+      b->bytes += a->bytes;
+    }
+
+    void add_proportion_my_stat(double p, void* base, const void* addme) {
+      (my_stat*)result->latency += p * (const my_stat*)base->latency;
+      (my_stat*)result->bytes += p * (const my_stat*)base->bytes;
+    }
+
+    #define kNumIntervals 2
+    #define kMinInterval 0
+    #define kHourInterval 1
+    #define kNumBuckets 4
+
+    const struct census_window_stats_stat_info kMyStatInfo
+        = { sizeof(my_stat), NULL, add_my_stat, add_proportion_my_stat };
+    gpr_timespec intervals[kNumIntervals] = {{60, 0}, {3600, 0}};
+    my_stat stat;
+    my_stat sums[kNumIntervals];
+    census_window_stats_sums result[kNumIntervals];
+    struct census_window_stats* stats
+        = census_window_stats_create(kNumIntervals, intervals, kNumBuckets,
+                                     &kMyStatInfo);
+    // Record a new event, taking 15.3ms, transferring 1784 bytes.
+    stat.latency = 0.153;
+    stat.bytes = 1784;
+    census_window_stats_add(stats, gpr_now(), &stat);
+    // Get sums and print them out
+    result[kMinInterval].statistic = &sums[kMinInterval];
+    result[kHourInterval].statistic = &sums[kHourInterval];
+    census_window_stats_get_sums(stats, gpr_now(), result);
+    printf("%d events/min, average time %gs, average bytes %g\n",
+           result[kMinInterval].count,
+           (my_stat*)result[kMinInterval].statistic->latency /
+             result[kMinInterval].count,
+           (my_stat*)result[kMinInterval].statistic->bytes /
+             result[kMinInterval].count
+          );
+    printf("%d events/hr, average time %gs, average bytes %g\n",
+           result[kHourInterval].count,
+           (my_stat*)result[kHourInterval].statistic->latency /
+             result[kHourInterval].count,
+           (my_stat*)result[kHourInterval].statistic->bytes /
+             result[kHourInterval].count
+          );
+*/
+
+/* Opaque structure for representing window_stats object */
+struct census_window_stats;
+
+/* Information provided by API user on the information they want to record */
+typedef struct census_window_stats_stat_info {
+  /* Number of bytes in user-defined object. */
+  size_t stat_size;
+  /* Function to initialize a user-defined statistics object. If this is set
+   * to NULL, then the object will be zero-initialized. */
+  void (*stat_initialize)(void* stat);
+  /* Function to add one user-defined statistics object ('addme') to 'base' */
+  void (*stat_add)(void* base, const void* addme);
+  /* As for previous function, but only add a proportion 'p'. This API will
+     currently only use 'p' values in the range [0,1], but other values are
+     possible in the future, and should be supported. */
+  void (*stat_add_proportion)(double p, void* base, const void* addme);
+} census_window_stats_stat_info;
+
+/* Create a new window_stats object. 'nintervals' is the number of
+   'intervals', and must be >=1. 'granularity' is the number of buckets, with
+   a larger number using more memory, but providing greater accuracy of
+   results. 'granularity should be > 2. We also require that each interval be
+   at least 10 * 'granularity' nanoseconds in size. 'stat_info' contains
+   information about the statistic to be gathered. Intervals greater than ~192
+   years will be treated as essentially infinite in size. This function will
+   GPR_ASSERT() if the object cannot be created or any of the parameters have
+   invalid values. This function is thread-safe. */
+struct census_window_stats* census_window_stats_create(
+    int nintervals, const gpr_timespec intervals[], int granularity,
+    const census_window_stats_stat_info* stat_info);
+
+/* Add a new measurement (in 'stat_value'), as of a given time ('when').
+   This function is thread-compatible. */
+void census_window_stats_add(struct census_window_stats* wstats,
+                             const gpr_timespec when, const void* stat_value);
+
+/* Structure used to record a single intervals sum for a given statistic */
+typedef struct census_window_stats_sum {
+  /* Total count of samples. Note that because some internal interpolation
+   is performed, the count of samples returned for each interval may not be an
+   integral value. */
+  double count;
+  /* Sum for statistic */
+  void* statistic;
+} census_window_stats_sums;
+
+/* Retrieve a set of all values stored in a window_stats object 'wstats'. The
+   number of 'sums' MUST be the same as the number 'nintervals' used in
+   census_window_stats_create(). This function is thread-compatible. */
+void census_window_stats_get_sums(const struct census_window_stats* wstats,
+                                  const gpr_timespec when,
+                                  struct census_window_stats_sum sums[]);
+
+/* Destroy a window_stats object. Once this function has been called, the
+   object will no longer be usable from any of the above functions (and
+   calling them will most likely result in a NULL-pointer dereference or
+   assertion failure). This function is thread-compatible. */
+void census_window_stats_destroy(struct census_window_stats* wstats);
+
+#endif /* __GRPC_INTERNAL_STATISTICS_WINDOW_STATS_H_ */
diff --git a/src/core/support/alloc.c b/src/core/support/alloc.c
new file mode 100644
index 0000000..658408f
--- /dev/null
+++ b/src/core/support/alloc.c
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/alloc.h>
+
+#include <stdlib.h>
+#include <grpc/support/port_platform.h>
+
+void *gpr_malloc(size_t size) {
+  void *p = malloc(size);
+  if (!p) {
+    abort();
+  }
+  return p;
+}
+
+void gpr_free(void *p) { free(p); }
+
+void *gpr_realloc(void *p, size_t size) {
+  p = realloc(p, size);
+  if (!p) {
+    abort();
+  }
+  return p;
+}
+
+void *gpr_malloc_aligned(size_t size, size_t alignment) {
+  size_t extra = alignment - 1 + sizeof(void *);
+  void *p = gpr_malloc(size + extra);
+  void **ret = (void **)(((gpr_uintptr)p + extra) & ~(alignment - 1));
+  ret[-1] = p;
+  return (void *)ret;
+}
+
+void gpr_free_aligned(void *ptr) {
+  free(((void **)ptr)[-1]);
+}
diff --git a/src/core/support/cancellable.c b/src/core/support/cancellable.c
new file mode 100644
index 0000000..5596413
--- /dev/null
+++ b/src/core/support/cancellable.c
@@ -0,0 +1,156 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Implementation for gpr_cancellable */
+
+#include <grpc/support/atm.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+void gpr_cancellable_init(gpr_cancellable *c) {
+  gpr_mu_init(&c->mu);
+  c->cancelled = 0;
+  c->waiters.next = &c->waiters;
+  c->waiters.prev = &c->waiters;
+  c->waiters.mu = NULL;
+  c->waiters.cv = NULL;
+}
+
+void gpr_cancellable_destroy(gpr_cancellable *c) { gpr_mu_destroy(&c->mu); }
+
+int gpr_cancellable_is_cancelled(gpr_cancellable *c) {
+  return gpr_atm_acq_load(&c->cancelled) != 0;
+}
+
+/* Threads in gpr_cv_cancellable_wait(cv, mu, ..., c) place themselves on a
+   linked list c->waiters of gpr_cancellable_list_ before waiting on their
+   condition variables.  They check for cancellation while holding *mu.  Thus,
+   to wake a thread from gpr_cv_cancellable_wait(), it suffices to:
+      - set c->cancelled
+      - acquire and release *mu
+      - gpr_cv_broadcast(cv)
+
+   However, gpr_cancellable_cancel() may not use gpr_mu_lock(mu), since the
+   caller may already hold *mu---a possible deadlock.  (If we knew the caller
+   did not hold *mu, care would still be needed, because c->mu follows *mu in
+   the locking order, so *mu could not be acquired while holding c->mu---which
+   is needed to iterate over c->waiters.)
+
+   Therefore, gpr_cancellable_cancel() uses gpr_mu_trylock() rather than
+   gpr_mu_lock(), and retries until either gpr_mu_trylock() succeeds or the
+   thread leaves gpr_cv_cancellable_wait() for other reasons.  In the first
+   case, gpr_cancellable_cancel() removes the entry from the waiters list; in
+   the second, the waiting thread removes itself from the list.
+
+   A one-entry cache of mutexes and condition variables processed is kept to
+   avoid doing the same work again and again if many threads are blocked in the
+   same place.  However, it's important to broadcast on a condition variable if
+   the corresponding mutex has been locked successfully, even if the condition
+   variable has been signalled before.  */
+
+void gpr_cancellable_cancel(gpr_cancellable *c) {
+  if (!gpr_cancellable_is_cancelled(c)) {
+    int failures;
+    int backoff = 1;
+    do {
+      struct gpr_cancellable_list_ *l;
+      struct gpr_cancellable_list_ *nl;
+      gpr_mu *omu = 0; /* one-element cache of a processed gpr_mu */
+      gpr_cv *ocv = 0; /* one-element cache of a processd gpr_cv */
+      gpr_mu_lock(&c->mu);
+      gpr_atm_rel_store(&c->cancelled, 1);
+      failures = 0;
+      for (l = c->waiters.next; l != &c->waiters; l = nl) {
+        nl = l->next;
+        if (omu != l->mu) {
+          omu = l->mu;
+          if (gpr_mu_trylock(l->mu)) {
+            gpr_mu_unlock(l->mu);
+            l->next->prev = l->prev; /* remove *l from list */
+            l->prev->next = l->next;
+            /* allow unconditional dequeue in gpr_cv_cancellable_wait() */
+            l->next = l;
+            l->prev = l;
+            ocv = 0; /* force broadcast */
+          } else {
+            failures++;
+          }
+        }
+        if (ocv != l->cv) {
+          ocv = l->cv;
+          gpr_cv_broadcast(l->cv);
+        }
+      }
+      gpr_mu_unlock(&c->mu);
+      if (failures != 0) {
+        if (backoff < 10) {
+          volatile int i;
+          for (i = 0; i != (1 << backoff); i++) {
+          }
+          backoff++;
+        } else {
+          gpr_event ev;
+          gpr_event_init(&ev);
+          gpr_event_wait(&ev,
+                         gpr_time_add(gpr_now(), gpr_time_from_micros(1000)));
+        }
+      }
+    } while (failures != 0);
+  }
+}
+
+int gpr_cv_cancellable_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline,
+                            gpr_cancellable *c) {
+  gpr_int32 timeout;
+  gpr_mu_lock(&c->mu);
+  timeout = gpr_cancellable_is_cancelled(c);
+  if (!timeout) {
+    struct gpr_cancellable_list_ le;
+    le.mu = mu;
+    le.cv = cv;
+    le.next = c->waiters.next;
+    le.prev = &c->waiters;
+    le.next->prev = &le;
+    le.prev->next = &le;
+    gpr_mu_unlock(&c->mu);
+    timeout = gpr_cv_wait(cv, mu, abs_deadline);
+    gpr_mu_lock(&c->mu);
+    le.next->prev = le.prev;
+    le.prev->next = le.next;
+    if (!timeout) {
+      timeout = gpr_cancellable_is_cancelled(c);
+    }
+  }
+  gpr_mu_unlock(&c->mu);
+  return timeout;
+}
diff --git a/src/core/support/cmdline.c b/src/core/support/cmdline.c
new file mode 100644
index 0000000..ff163a1
--- /dev/null
+++ b/src/core/support/cmdline.c
@@ -0,0 +1,292 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/cmdline.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+
+typedef enum { ARGTYPE_INT, ARGTYPE_BOOL, ARGTYPE_STRING } argtype;
+
+typedef struct arg {
+  const char *name;
+  const char *help;
+  argtype type;
+  void *value;
+  struct arg *next;
+} arg;
+
+struct gpr_cmdline {
+  const char *description;
+  arg *args;
+  const char *argv0;
+
+  const char *extra_arg_name;
+  const char *extra_arg_help;
+  void (*extra_arg)(void *user_data, const char *arg);
+  void *extra_arg_user_data;
+
+  void (*state)(gpr_cmdline *cl, char *arg);
+  arg *cur_arg;
+};
+
+static void normal_state(gpr_cmdline *cl, char *arg);
+
+gpr_cmdline *gpr_cmdline_create(const char *description) {
+  gpr_cmdline *cl = gpr_malloc(sizeof(gpr_cmdline));
+  memset(cl, 0, sizeof(gpr_cmdline));
+
+  cl->description = description;
+  cl->state = normal_state;
+
+  return cl;
+}
+
+void gpr_cmdline_destroy(gpr_cmdline *cl) {
+  while (cl->args) {
+    arg *a = cl->args;
+    cl->args = a->next;
+    gpr_free(a);
+  }
+  gpr_free(cl);
+}
+
+static void add_arg(gpr_cmdline *cl, const char *name, const char *help,
+                    argtype type, void *value) {
+  arg *a;
+
+  for (a = cl->args; a; a = a->next) {
+    GPR_ASSERT(0 != strcmp(a->name, name));
+  }
+
+  a = gpr_malloc(sizeof(arg));
+  memset(a, 0, sizeof(arg));
+  a->name = name;
+  a->help = help;
+  a->type = type;
+  a->value = value;
+  a->next = cl->args;
+  cl->args = a;
+}
+
+void gpr_cmdline_add_int(gpr_cmdline *cl, const char *name, const char *help,
+                         int *value) {
+  add_arg(cl, name, help, ARGTYPE_INT, value);
+}
+
+void gpr_cmdline_add_flag(gpr_cmdline *cl, const char *name, const char *help,
+                          int *value) {
+  add_arg(cl, name, help, ARGTYPE_BOOL, value);
+}
+
+void gpr_cmdline_add_string(gpr_cmdline *cl, const char *name, const char *help,
+                            char **value) {
+  add_arg(cl, name, help, ARGTYPE_STRING, value);
+}
+
+void gpr_cmdline_on_extra_arg(
+    gpr_cmdline *cl, const char *name, const char *help,
+    void (*on_extra_arg)(void *user_data, const char *arg), void *user_data) {
+  GPR_ASSERT(!cl->extra_arg);
+  GPR_ASSERT(on_extra_arg);
+
+  cl->extra_arg = on_extra_arg;
+  cl->extra_arg_user_data = user_data;
+  cl->extra_arg_name = name;
+  cl->extra_arg_help = help;
+}
+
+static void print_usage_and_die(gpr_cmdline *cl) {
+  /* TODO(ctiller): make this prettier */
+  arg *a;
+  const char *name = strrchr(cl->argv0, '/');
+  if (name) {
+    name++;
+  } else {
+    name = cl->argv0;
+  }
+  fprintf(stderr, "Usage: %s", name);
+  for (a = cl->args; a; a = a->next) {
+    switch (a->type) {
+      case ARGTYPE_BOOL:
+        fprintf(stderr, " [--%s|--no-%s]", a->name, a->name);
+        break;
+      case ARGTYPE_STRING:
+        fprintf(stderr, " [--%s=string]", a->name);
+        break;
+      case ARGTYPE_INT:
+        fprintf(stderr, " [--%s=int]", a->name);
+        break;
+    }
+  }
+  if (cl->extra_arg) {
+    fprintf(stderr, " [%s...]", cl->extra_arg_name);
+  }
+  fprintf(stderr, "\n");
+  exit(1);
+}
+
+static void extra_state(gpr_cmdline *cl, char *arg) {
+  if (!cl->extra_arg) print_usage_and_die(cl);
+  cl->extra_arg(cl->extra_arg_user_data, arg);
+}
+
+static arg *find_arg(gpr_cmdline *cl, char *name) {
+  arg *a;
+
+  for (a = cl->args; a; a = a->next) {
+    if (0 == strcmp(a->name, name)) {
+      break;
+    }
+  }
+
+  if (!a) {
+    fprintf(stderr, "Unknown argument: %s\n", name);
+    print_usage_and_die(cl);
+  }
+
+  return a;
+}
+
+static void value_state(gpr_cmdline *cl, char *arg) {
+  long intval;
+  char *end;
+
+  GPR_ASSERT(cl->cur_arg);
+
+  switch (cl->cur_arg->type) {
+    case ARGTYPE_INT:
+      intval = strtol(arg, &end, 0);
+      if (*end || intval < INT_MIN || intval > INT_MAX) {
+        fprintf(stderr, "expected integer, got '%s' for %s\n", arg,
+                cl->cur_arg->name);
+        print_usage_and_die(cl);
+      }
+      *(int *)cl->cur_arg->value = intval;
+      break;
+    case ARGTYPE_BOOL:
+      if (0 == strcmp(arg, "1") || 0 == strcmp(arg, "true")) {
+        *(int *)cl->cur_arg->value = 1;
+      } else if (0 == strcmp(arg, "0") || 0 == strcmp(arg, "false")) {
+        *(int *)cl->cur_arg->value = 0;
+      } else {
+        fprintf(stderr, "expected boolean, got '%s' for %s\n", arg,
+                cl->cur_arg->name);
+        print_usage_and_die(cl);
+      }
+      break;
+    case ARGTYPE_STRING:
+      *(char **)cl->cur_arg->value = arg;
+      break;
+  }
+
+  cl->state = normal_state;
+}
+
+static void normal_state(gpr_cmdline *cl, char *arg) {
+  char *eq = NULL;
+  char *tmp = NULL;
+  char *arg_name = NULL;
+
+  if (0 == strcmp(arg, "-help") || 0 == strcmp(arg, "--help") ||
+      0 == strcmp(arg, "-h")) {
+    print_usage_and_die(cl);
+  }
+
+  cl->cur_arg = NULL;
+
+  if (arg[0] == '-') {
+    if (arg[1] == '-') {
+      if (arg[2] == 0) {
+        /* handle '--' to move to just extra args */
+        cl->state = extra_state;
+        return;
+      }
+      arg += 2;
+    } else {
+      arg += 1;
+    }
+    /* first byte of arg is now past the leading '-' or '--' */
+    if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-') {
+      /* arg is of the form '--no-foo' - it's a flag disable */
+      arg += 3;
+      cl->cur_arg = find_arg(cl, arg);
+      if (cl->cur_arg->type != ARGTYPE_BOOL) {
+        fprintf(stderr, "%s is not a flag argument\n", arg);
+        print_usage_and_die(cl);
+      }
+      *(int *)cl->cur_arg->value = 0;
+      return; /* early out */
+    }
+    eq = strchr(arg, '=');
+    if (eq != NULL) {
+      /* copy the string into a temp buffer and extract the name */
+      tmp = arg_name = gpr_malloc(eq - arg + 1);
+      memcpy(arg_name, arg, eq - arg);
+      arg_name[eq - arg] = 0;
+    } else {
+      arg_name = arg;
+    }
+    cl->cur_arg = find_arg(cl, arg_name);
+    if (eq != NULL) {
+      /* arg was of the type --foo=value, parse the value */
+      value_state(cl, eq + 1);
+    } else if (cl->cur_arg->type != ARGTYPE_BOOL) {
+      /* flag types don't have a '--foo value' variant, other types do */
+      cl->state = value_state;
+    } else {
+      /* flag parameter: just set the value */
+      *(int *)cl->cur_arg->value = 1;
+    }
+  } else {
+    extra_state(cl, arg);
+  }
+
+  gpr_free(tmp);
+}
+
+void gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv) {
+  int i;
+
+  GPR_ASSERT(argc >= 1);
+  cl->argv0 = argv[0];
+
+  for (i = 1; i < argc; i++) {
+    cl->state(cl, argv[i]);
+  }
+}
diff --git a/src/core/support/cpu.h b/src/core/support/cpu.h
new file mode 100644
index 0000000..6ac0db3
--- /dev/null
+++ b/src/core/support/cpu.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SUPPORT_CPU_H__
+#define __GRPC_INTERNAL_SUPPORT_CPU_H__
+
+/* Interface providing CPU information for currently running system */
+
+/* Return the number of CPU cores on the current system. Will return 0 if
+   if information is not available. */
+int gpr_cpu_num_cores();
+
+/* Return the CPU on which the current thread is executing; N.B. This should
+   be considered advisory only - it is possible that the thread is switched
+   to a different CPU at any time. Returns a value in range
+   [0, gpr_cpu_num_cores() - 1] */
+int gpr_cpu_current_cpu();
+
+#endif  /* __GRPC_INTERNAL_SUPPORT_CPU_H__ */
diff --git a/src/core/support/cpu_posix.c b/src/core/support/cpu_posix.c
new file mode 100644
index 0000000..82d58de
--- /dev/null
+++ b/src/core/support/cpu_posix.c
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/support/cpu.h"
+
+#ifdef __linux__
+#include <errno.h>
+#include <unistd.h>
+#define _GNU_SOURCE
+#define __USE_GNU
+#define __USE_MISC
+#include <sched.h>
+#undef _GNU_SOURCE
+#undef __USE_GNU
+#undef __USE_MISC
+#include <string.h>
+
+#include <grpc/support/log.h>
+
+int gpr_cpu_num_cores() {
+  static int ncpus = 0;
+  if (ncpus == 0) {
+    ncpus = sysconf(_SC_NPROCESSORS_ONLN);
+    if (ncpus < 1) {
+      gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1");
+      ncpus = 1;
+    }
+  }
+  return ncpus;
+}
+
+int gpr_cpu_current_cpu() {
+  int cpu = sched_getcpu();
+  if (cpu < 0) {
+    gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno));
+    return 0;
+  }
+  return cpu;
+}
+
+#endif /* __linux__ */
diff --git a/src/core/support/histogram.c b/src/core/support/histogram.c
new file mode 100644
index 0000000..a3ecd3e
--- /dev/null
+++ b/src/core/support/histogram.c
@@ -0,0 +1,226 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/histogram.h>
+
+#include <math.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+/* Histograms are stored with exponentially increasing bucket sizes.
+   The first bucket is [0, m) where m = 1 + resolution
+   Bucket n (n>=1) contains [m**n, m**(n+1))
+   There are sufficient buckets to reach max_bucket_start */
+
+struct gpr_histogram {
+  /* Sum of all values seen so far */
+  double sum;
+  /* Sum of squares of all values seen so far */
+  double sum_of_squares;
+  /* number of values seen so far */
+  double count;
+  /* m in the description */
+  double multiplier;
+  double one_on_log_multiplier;
+  /* minimum value seen */
+  double min_seen;
+  /* maximum value seen */
+  double max_seen;
+  /* maximum representable value */
+  double max_possible;
+  /* number of buckets */
+  size_t num_buckets;
+  /* the buckets themselves */
+  gpr_uint32 *buckets;
+};
+
+/* determine a bucket index given a value - does no bounds checking */
+static size_t bucket_for_unchecked(gpr_histogram *h, double x) {
+  return (size_t)(log(x) * h->one_on_log_multiplier);
+}
+
+/* bounds checked version of the above */
+static size_t bucket_for(gpr_histogram *h, double x) {
+  size_t bucket = bucket_for_unchecked(h, GPR_CLAMP(x, 0, h->max_possible));
+  GPR_ASSERT(bucket >= 0);
+  GPR_ASSERT(bucket < h->num_buckets);
+  return bucket;
+}
+
+/* at what value does a bucket start? */
+static double bucket_start(gpr_histogram *h, double x) {
+  return pow(h->multiplier, x);
+}
+
+gpr_histogram *gpr_histogram_create(double resolution,
+                                    double max_bucket_start) {
+  gpr_histogram *h = gpr_malloc(sizeof(gpr_histogram));
+  GPR_ASSERT(resolution > 0.0);
+  GPR_ASSERT(max_bucket_start > resolution);
+  h->sum = 0.0;
+  h->sum_of_squares = 0.0;
+  h->multiplier = 1.0 + resolution;
+  h->one_on_log_multiplier = 1.0 / log(1.0 + resolution);
+  h->max_possible = max_bucket_start;
+  h->count = 0.0;
+  h->min_seen = max_bucket_start;
+  h->max_seen = 0.0;
+  h->num_buckets = bucket_for_unchecked(h, max_bucket_start) + 1;
+  GPR_ASSERT(h->num_buckets > 1);
+  GPR_ASSERT(h->num_buckets < 100000000);
+  h->buckets = gpr_malloc(sizeof(gpr_uint32) * h->num_buckets);
+  memset(h->buckets, 0, sizeof(gpr_uint32) * h->num_buckets);
+  return h;
+}
+
+void gpr_histogram_destroy(gpr_histogram *h) {
+  gpr_free(h->buckets);
+  gpr_free(h);
+}
+
+void gpr_histogram_add(gpr_histogram *h, double x) {
+  h->sum += x;
+  h->sum_of_squares += x * x;
+  h->count++;
+  if (x < h->min_seen) {
+    h->min_seen = x;
+  }
+  if (x > h->max_seen) {
+    h->max_seen = x;
+  }
+  h->buckets[bucket_for(h, x)]++;
+}
+
+int gpr_histogram_merge(gpr_histogram *dst, gpr_histogram *src) {
+  int i;
+  if ((dst->num_buckets != src->num_buckets) ||
+      (dst->multiplier != src->multiplier)) {
+    /* Fail because these histograms don't match */
+    return 0;
+  }
+  dst->sum += src->sum;
+  dst->sum_of_squares += src->sum_of_squares;
+  dst->count += src->count;
+  if (src->min_seen < dst->min_seen) {
+    dst->min_seen = src->min_seen;
+  }
+  if (src->max_seen > dst->max_seen) {
+    dst->max_seen = src->max_seen;
+  }
+  for (i = 0; i < dst->num_buckets; i++) {
+    dst->buckets[i] += src->buckets[i];
+  }
+  return 1;
+}
+
+static double threshold_for_count_below(gpr_histogram *h, double count_below) {
+  double count_so_far;
+  double lower_bound;
+  double upper_bound;
+  int lower_idx;
+  int upper_idx;
+
+  GPR_ASSERT(h->count >= 1);
+
+  if (count_below <= 0) {
+    return h->min_seen;
+  }
+  if (count_below >= h->count) {
+    return h->max_seen;
+  }
+
+  /* find the lowest bucket that gets us above count_below */
+  count_so_far = 0.0;
+  for (lower_idx = 0; lower_idx < h->num_buckets; lower_idx++) {
+    count_so_far += h->buckets[lower_idx];
+    if (count_so_far >= count_below) {
+      break;
+    }
+  }
+  if (count_so_far == count_below) {
+    /* this bucket hits the threshold exactly... we should be midway through
+       any run of zero values following the bucket */
+    for (upper_idx = lower_idx + 1; upper_idx < h->num_buckets; upper_idx++) {
+      if (h->buckets[upper_idx]) {
+        break;
+      }
+    }
+    return (bucket_start(h, lower_idx) + bucket_start(h, upper_idx)) / 2.0;
+  } else {
+    /* treat values as uniform throughout the bucket, and find where this value
+       should lie */
+    lower_bound = bucket_start(h, lower_idx);
+    upper_bound = bucket_start(h, lower_idx + 1);
+    return GPR_CLAMP(upper_bound -
+                         (upper_bound - lower_bound) *
+                             (count_so_far - count_below) /
+                             h->buckets[lower_idx],
+                     h->min_seen, h->max_seen);
+  }
+}
+
+double gpr_histogram_percentile(gpr_histogram *h, double percentile) {
+  return threshold_for_count_below(h, h->count * percentile / 100.0);
+}
+
+double gpr_histogram_mean(gpr_histogram *h) {
+  GPR_ASSERT(h->count);
+  return h->sum / h->count;
+}
+
+double gpr_histogram_stddev(gpr_histogram *h) {
+  return sqrt(gpr_histogram_variance(h));
+}
+
+double gpr_histogram_variance(gpr_histogram *h) {
+  if (h->count == 0) return 0.0;
+  return (h->sum_of_squares * h->count - h->sum * h->sum) /
+         (h->count * h->count);
+}
+
+double gpr_histogram_maximum(gpr_histogram *h) { return h->max_seen; }
+
+double gpr_histogram_minimum(gpr_histogram *h) { return h->min_seen; }
+
+double gpr_histogram_count(gpr_histogram *h) { return h->count; }
+
+double gpr_histogram_sum(gpr_histogram *h) { return h->sum; }
+
+double gpr_histogram_sum_of_squares(gpr_histogram *h) {
+  return h->sum_of_squares;
+}
diff --git a/src/core/support/host_port.c b/src/core/support/host_port.c
new file mode 100644
index 0000000..0250055
--- /dev/null
+++ b/src/core/support/host_port.c
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/host_port.h>
+
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+
+int gpr_join_host_port(char **out, const char *host, int port) {
+  if (host[0] != '[' && strchr(host, ':') != NULL) {
+    /* IPv6 literals must be enclosed in brackets. */
+    return gpr_asprintf(out, "[%s]:%d", host, port);
+  } else {
+    /* Ordinary non-bracketed host:port. */
+    return gpr_asprintf(out, "%s:%d", host, port);
+  }
+}
diff --git a/src/core/support/log.c b/src/core/support/log.c
new file mode 100644
index 0000000..79321f7
--- /dev/null
+++ b/src/core/support/log.c
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/log.h>
+
+#include <stdio.h>
+
+const char *gpr_log_severity_string(gpr_log_severity severity) {
+  switch (severity) {
+    case GPR_LOG_SEVERITY_DEBUG:
+      return "D";
+    case GPR_LOG_SEVERITY_INFO:
+      return "I";
+    case GPR_LOG_SEVERITY_ERROR:
+      return "E";
+  }
+  return "UNKNOWN";
+}
diff --git a/src/core/support/log_android.c b/src/core/support/log_android.c
new file mode 100644
index 0000000..9e2b034
--- /dev/null
+++ b/src/core/support/log_android.c
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_ANDROID
+
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <android/log.h>
+
+static android_LogPriority severity_to_log_priority(gpr_log_severity severity) {
+  switch (severity) {
+    case GPR_LOG_SEVERITY_DEBUG:
+      return ANDROID_LOG_DEBUG;
+    case GPR_LOG_SEVERITY_INFO:
+      return ANDROID_LOG_INFO;
+    case GPR_LOG_SEVERITY_ERROR:
+      return ANDROID_LOG_ERROR;
+  }
+  return ANDROID_LOG_DEFAULT;
+}
+
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *format, ...) {
+  char *final_slash;
+  const char *display_file;
+  char *prefix = NULL;
+  char *suffix = NULL;
+  char *output = NULL;
+  va_list args;
+  va_start(args, format);
+
+  final_slash = strrchr(file, '/');
+  if (final_slash == NULL)
+    display_file = file;
+  else
+    display_file = final_slash + 1;
+
+  asprintf(&prefix, "%s:%d] ", display_file, line);
+  vasprintf(&suffix, format, args);
+  asprintf(&output, "%s%s", prefix, suffix);
+  va_end(args);
+
+  __android_log_write(severity_to_log_priority(severity), "GRPC", output);
+
+  /* allocated by asprintf => use free, not gpr_free */
+  free(prefix);
+  free(suffix);
+  free(output);
+}
+
+#endif /* GPR_ANDROID */
diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c
new file mode 100644
index 0000000..e39e2cc
--- /dev/null
+++ b/src/core/support/log_linux.c
@@ -0,0 +1,85 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define _POSIX_SOURCE
+#define _GNU_SOURCE
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_LINUX
+
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <linux/unistd.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static long gettid() { return syscall(__NR_gettid); }
+
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *format, ...) {
+  char *final_slash;
+  const char *display_file;
+  char time_buffer[64];
+  gpr_timespec now = gpr_now();
+  struct tm tm;
+  va_list args;
+  va_start(args, format);
+
+  final_slash = strrchr(file, '/');
+  if (final_slash == NULL)
+    display_file = file;
+  else
+    display_file = final_slash + 1;
+
+  if (!localtime_r(&now.tv_sec, &tm)) {
+    strcpy(time_buffer, "error:localtime");
+  } else if (0 ==
+             strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {
+    strcpy(time_buffer, "error:strftime");
+  }
+
+  flockfile(stderr);
+  fprintf(stderr, "%s%s.%09d %7ld %s:%d] ", gpr_log_severity_string(severity),
+          time_buffer, (int)(now.tv_nsec), gettid(), display_file, line);
+  vfprintf(stderr, format, args);
+  fputc('\n', stderr);
+  funlockfile(stderr);
+
+  va_end(args);
+}
+
+#endif
diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c
new file mode 100644
index 0000000..68882f7
--- /dev/null
+++ b/src/core/support/log_posix.c
@@ -0,0 +1,83 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define _POSIX_SOURCE
+#define _GNU_SOURCE
+#include <grpc/support/port_platform.h>
+
+#if defined(GPR_POSIX_LOG)
+
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+
+static long gettid() { return pthread_self(); }
+
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *format, ...) {
+  char *final_slash;
+  const char *display_file;
+  char time_buffer[64];
+  gpr_timespec now = gpr_now();
+  struct tm tm;
+  va_list args;
+  va_start(args, format);
+
+  final_slash = strrchr(file, '/');
+  if (final_slash == NULL)
+    display_file = file;
+  else
+    display_file = final_slash + 1;
+
+  if (!localtime_r(&now.tv_sec, &tm)) {
+    strcpy(time_buffer, "error:localtime");
+  } else if (0 ==
+             strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {
+    strcpy(time_buffer, "error:strftime");
+  }
+
+  flockfile(stderr);
+  fprintf(stderr, "%s%s.%09d %7ld %s:%d] ", gpr_log_severity_string(severity),
+          time_buffer, (int)(now.tv_nsec), gettid(), display_file, line);
+  vfprintf(stderr, format, args);
+  fputc('\n', stderr);
+  funlockfile(stderr);
+
+  va_end(args);
+}
+
+#endif /* defined(GPR_POSIX_LOG) */
diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c
new file mode 100644
index 0000000..f5710fa
--- /dev/null
+++ b/src/core/support/log_win32.c
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_WIN32
+
+#include <grpc/support/log.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+/* Simple starter implementation */
+void gpr_log(char *file, int line, gpr_log_severity severity, char *format,
+             ...) {
+  va_list args;
+  va_start(args, format);
+
+  fprintf(stderr, "%s %s:%d: ", gpr_log_severity_string(severity), file, line);
+  vfprintf(stderr, format, args);
+  fputc('\n', stderr);
+
+  va_end(args);
+}
+
+#endif
diff --git a/src/core/support/murmur_hash.c b/src/core/support/murmur_hash.c
new file mode 100644
index 0000000..5d30263
--- /dev/null
+++ b/src/core/support/murmur_hash.c
@@ -0,0 +1,94 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/support/murmur_hash.h"
+
+#define ROTL32(x, r) ((x) << (r)) | ((x) >> (32 - (r)))
+
+#define FMIX32(h)    \
+  (h) ^= (h) >> 16;  \
+  (h) *= 0x85ebca6b; \
+  (h) ^= (h) >> 13;  \
+  (h) *= 0xc2b2ae35; \
+  (h) ^= (h) >> 16;
+
+/* Block read - if your platform needs to do endian-swapping or can only
+   handle aligned reads, do the conversion here */
+#define GETBLOCK32(p, i) (p)[(i)]
+
+gpr_uint32 gpr_murmur_hash3(const void* key, size_t len, gpr_uint32 seed) {
+  const gpr_uint8* data = (const gpr_uint8*)key;
+  const int nblocks = len / 4;
+  int i;
+
+  gpr_uint32 h1 = seed;
+  gpr_uint32 k1 = 0;
+
+  const gpr_uint32 c1 = 0xcc9e2d51;
+  const gpr_uint32 c2 = 0x1b873593;
+
+  const gpr_uint32* blocks = (const uint32_t*)(data + nblocks * 4);
+  const uint8_t* tail = (const uint8_t*)(data + nblocks * 4);
+
+  /* body */
+  for (i = -nblocks; i; i++) {
+    gpr_uint32 k1 = GETBLOCK32(blocks, i);
+
+    k1 *= c1;
+    k1 = ROTL32(k1, 15);
+    k1 *= c2;
+
+    h1 ^= k1;
+    h1 = ROTL32(h1, 13);
+    h1 = h1 * 5 + 0xe6546b64;
+  }
+
+  /* tail */
+  switch (len & 3) {
+    case 3:
+      k1 ^= tail[2] << 16;
+    case 2:
+      k1 ^= tail[1] << 8;
+    case 1:
+      k1 ^= tail[0];
+      k1 *= c1;
+      k1 = ROTL32(k1, 15);
+      k1 *= c2;
+      h1 ^= k1;
+  };
+
+  /* finalization */
+  h1 ^= len;
+  FMIX32(h1);
+  return h1;
+}
diff --git a/src/core/support/murmur_hash.h b/src/core/support/murmur_hash.h
new file mode 100644
index 0000000..5643717
--- /dev/null
+++ b/src/core/support/murmur_hash.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__
+#define __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__
+
+#include <grpc/support/port_platform.h>
+
+#include <stddef.h>
+
+/* compute the hash of key (length len) */
+gpr_uint32 gpr_murmur_hash3(const void *key, size_t len, gpr_uint32 seed);
+
+#endif  /* __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__ */
diff --git a/src/core/support/slice.c b/src/core/support/slice.c
new file mode 100644
index 0000000..fcdeb47
--- /dev/null
+++ b/src/core/support/slice.c
@@ -0,0 +1,325 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+
+#include <string.h>
+
+gpr_slice gpr_empty_slice() {
+  gpr_slice out;
+  out.refcount = 0;
+  out.data.inlined.length = 0;
+  return out;
+}
+
+gpr_slice gpr_slice_ref(gpr_slice slice) {
+  if (slice.refcount) {
+    slice.refcount->ref(slice.refcount);
+  }
+  return slice;
+}
+
+void gpr_slice_unref(gpr_slice slice) {
+  if (slice.refcount) {
+    slice.refcount->unref(slice.refcount);
+  }
+}
+
+/* gpr_slice_new support structures - we create a refcount object extended
+   with the user provided data pointer & destroy function */
+typedef struct new_slice_refcount {
+  gpr_slice_refcount rc;
+  gpr_refcount refs;
+  void (*user_destroy)(void *);
+  void *user_data;
+} new_slice_refcount;
+
+static void new_slice_ref(void *p) {
+  new_slice_refcount *r = p;
+  gpr_ref(&r->refs);
+}
+
+static void new_slice_unref(void *p) {
+  new_slice_refcount *r = p;
+  if (gpr_unref(&r->refs)) {
+    r->user_destroy(r->user_data);
+    gpr_free(r);
+  }
+}
+
+gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) {
+  gpr_slice slice;
+  new_slice_refcount *rc = gpr_malloc(sizeof(new_slice_refcount));
+  gpr_ref_init(&rc->refs, 1);
+  rc->rc.ref = new_slice_ref;
+  rc->rc.unref = new_slice_unref;
+  rc->user_destroy = destroy;
+  rc->user_data = p;
+
+  slice.refcount = &rc->rc;
+  slice.data.refcounted.bytes = p;
+  slice.data.refcounted.length = len;
+  return slice;
+}
+
+/* gpr_slice_new_with_len support structures - we create a refcount object
+   extended with the user provided data pointer & destroy function */
+typedef struct new_with_len_slice_refcount {
+  gpr_slice_refcount rc;
+  gpr_refcount refs;
+  void *user_data;
+  size_t user_length;
+  void (*user_destroy)(void *, size_t);
+} new_with_len_slice_refcount;
+
+static void new_with_len_ref(void *p) {
+  new_with_len_slice_refcount *r = p;
+  gpr_ref(&r->refs);
+}
+
+static void new_with_len_unref(void *p) {
+  new_with_len_slice_refcount *r = p;
+  if (gpr_unref(&r->refs)) {
+    r->user_destroy(r->user_data, r->user_length);
+    gpr_free(r);
+  }
+}
+
+gpr_slice gpr_slice_new_with_len(void *p, size_t len,
+                                 void (*destroy)(void *, size_t)) {
+  gpr_slice slice;
+  new_with_len_slice_refcount *rc =
+      gpr_malloc(sizeof(new_with_len_slice_refcount));
+  gpr_ref_init(&rc->refs, 1);
+  rc->rc.ref = new_with_len_ref;
+  rc->rc.unref = new_with_len_unref;
+  rc->user_destroy = destroy;
+  rc->user_data = p;
+  rc->user_length = len;
+
+  slice.refcount = &rc->rc;
+  slice.data.refcounted.bytes = p;
+  slice.data.refcounted.length = len;
+  return slice;
+}
+
+gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t length) {
+  gpr_slice slice = gpr_slice_malloc(length);
+  memcpy(GPR_SLICE_START_PTR(slice), source, length);
+  return slice;
+}
+
+gpr_slice gpr_slice_from_copied_string(const char *source) {
+  return gpr_slice_from_copied_buffer(source, strlen(source));
+}
+
+typedef struct {
+  gpr_slice_refcount base;
+  gpr_refcount refs;
+} malloc_refcount;
+
+static void malloc_ref(void *p) {
+  malloc_refcount *r = p;
+  gpr_ref(&r->refs);
+}
+
+static void malloc_unref(void *p) {
+  malloc_refcount *r = p;
+  if (gpr_unref(&r->refs)) {
+    gpr_free(r);
+  }
+}
+
+gpr_slice gpr_slice_malloc(size_t length) {
+  gpr_slice slice;
+
+  if (length > sizeof(slice.data.inlined.bytes)) {
+    /* Memory layout used by the slice created here:
+
+       +-----------+----------------------------------------------------------+
+       | refcount  | bytes                                                    |
+       +-----------+----------------------------------------------------------+
+
+       refcount is a malloc_refcount
+       bytes is an array of bytes of the requested length
+       Both parts are placed in the same allocation returned from gpr_malloc */
+    malloc_refcount *rc = gpr_malloc(sizeof(malloc_refcount) + length);
+
+    /* Initial refcount on rc is 1 - and it's up to the caller to release
+       this reference. */
+    gpr_ref_init(&rc->refs, 1);
+
+    rc->base.ref = malloc_ref;
+    rc->base.unref = malloc_unref;
+
+    /* Build up the slice to be returned. */
+    /* The slices refcount points back to the allocated block. */
+    slice.refcount = &rc->base;
+    /* The data bytes are placed immediately after the refcount struct */
+    slice.data.refcounted.bytes = (gpr_uint8 *)(rc + 1);
+    /* And the length of the block is set to the requested length */
+    slice.data.refcounted.length = length;
+  } else {
+    /* small slice: just inline the data */
+    slice.refcount = NULL;
+    slice.data.inlined.length = length;
+  }
+  return slice;
+}
+
+gpr_slice gpr_slice_sub_no_ref(gpr_slice source, size_t begin, size_t end) {
+  gpr_slice subset;
+
+  if (source.refcount) {
+    /* Enforce preconditions */
+    GPR_ASSERT(source.data.refcounted.length >= begin);
+    GPR_ASSERT(source.data.refcounted.length >= end);
+    GPR_ASSERT(end >= begin);
+
+    /* Build the result */
+    subset.refcount = source.refcount;
+    /* Point into the source array */
+    subset.data.refcounted.bytes = source.data.refcounted.bytes + begin;
+    subset.data.refcounted.length = end - begin;
+  } else {
+    subset.refcount = NULL;
+    subset.data.inlined.length = end - begin;
+    memcpy(subset.data.inlined.bytes, source.data.inlined.bytes + begin,
+           end - begin);
+  }
+  return subset;
+}
+
+gpr_slice gpr_slice_sub(gpr_slice source, size_t begin, size_t end) {
+  gpr_slice subset;
+
+  if (end - begin <= sizeof(subset.data.inlined.bytes)) {
+    subset.refcount = NULL;
+    subset.data.inlined.length = end - begin;
+    memcpy(subset.data.inlined.bytes, GPR_SLICE_START_PTR(source) + begin,
+           end - begin);
+  } else {
+    subset = gpr_slice_sub_no_ref(source, begin, end);
+    /* Bump the refcount */
+    subset.refcount->ref(subset.refcount);
+  }
+  return subset;
+}
+
+gpr_slice gpr_slice_split_tail(gpr_slice *source, size_t split) {
+  gpr_slice tail;
+
+  if (source->refcount == NULL) {
+    /* inlined data, copy it out */
+    GPR_ASSERT(source->data.inlined.length >= split);
+    tail.refcount = NULL;
+    tail.data.inlined.length = source->data.inlined.length - split;
+    memcpy(tail.data.inlined.bytes, source->data.inlined.bytes + split,
+           tail.data.inlined.length);
+    source->data.inlined.length = split;
+  } else {
+    size_t tail_length = source->data.refcounted.length - split;
+    GPR_ASSERT(source->data.refcounted.length >= split);
+    if (tail_length < sizeof(tail.data.inlined.bytes)) {
+      /* Copy out the bytes - it'll be cheaper than refcounting */
+      tail.refcount = NULL;
+      tail.data.inlined.length = tail_length;
+      memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split,
+             tail_length);
+    } else {
+      /* Build the result */
+      tail.refcount = source->refcount;
+      /* Bump the refcount */
+      tail.refcount->ref(tail.refcount);
+      /* Point into the source array */
+      tail.data.refcounted.bytes = source->data.refcounted.bytes + split;
+      tail.data.refcounted.length = tail_length;
+    }
+    source->data.refcounted.length = split;
+  }
+
+  return tail;
+}
+
+gpr_slice gpr_slice_split_head(gpr_slice *source, size_t split) {
+  gpr_slice head;
+
+  if (source->refcount == NULL) {
+    GPR_ASSERT(source->data.inlined.length >= split);
+
+    head.refcount = NULL;
+    head.data.inlined.length = split;
+    memcpy(head.data.inlined.bytes, source->data.inlined.bytes, split);
+    source->data.inlined.length -= split;
+    memmove(source->data.inlined.bytes, source->data.inlined.bytes + split,
+            source->data.inlined.length);
+  } else if (split < sizeof(head.data.inlined.bytes)) {
+    GPR_ASSERT(source->data.refcounted.length >= split);
+
+    head.refcount = NULL;
+    head.data.inlined.length = split;
+    memcpy(head.data.inlined.bytes, source->data.refcounted.bytes, split);
+    source->data.refcounted.bytes += split;
+    source->data.refcounted.length -= split;
+  } else {
+    GPR_ASSERT(source->data.refcounted.length >= split);
+
+    /* Build the result */
+    head.refcount = source->refcount;
+    /* Bump the refcount */
+    head.refcount->ref(head.refcount);
+    /* Point into the source array */
+    head.data.refcounted.bytes = source->data.refcounted.bytes;
+    head.data.refcounted.length = split;
+    source->data.refcounted.bytes += split;
+    source->data.refcounted.length -= split;
+  }
+
+  return head;
+}
+
+int gpr_slice_cmp(gpr_slice a, gpr_slice b) {
+  int d = GPR_SLICE_LENGTH(a) - GPR_SLICE_LENGTH(b);
+  if (d != 0) return d;
+  return memcmp(GPR_SLICE_START_PTR(a), GPR_SLICE_START_PTR(b),
+                GPR_SLICE_LENGTH(a));
+}
+
+int gpr_slice_str_cmp(gpr_slice a, const char *b) {
+  size_t b_length = strlen(b);
+  int d = GPR_SLICE_LENGTH(a) - b_length;
+  if (d != 0) return d;
+  return memcmp(GPR_SLICE_START_PTR(a), b, b_length);
+}
diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c
new file mode 100644
index 0000000..2ade049
--- /dev/null
+++ b/src/core/support/slice_buffer.c
@@ -0,0 +1,155 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/slice_buffer.h>
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+/* initial allocation size (# of slices) */
+#define INITIAL_CAPACITY 4
+/* grow a buffer; requires INITIAL_CAPACITY > 1 */
+#define GROW(x) (3 * (x) / 2)
+
+void gpr_slice_buffer_init(gpr_slice_buffer *sb) {
+  sb->count = 0;
+  sb->length = 0;
+  sb->capacity = INITIAL_CAPACITY;
+  sb->slices = gpr_malloc(sizeof(gpr_slice) * INITIAL_CAPACITY);
+}
+
+void gpr_slice_buffer_destroy(gpr_slice_buffer *sb) {
+  gpr_slice_buffer_reset_and_unref(sb);
+  gpr_free(sb->slices);
+}
+
+gpr_uint8 *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, int n) {
+  gpr_slice *back;
+  gpr_uint8 *out;
+
+  sb->length += n;
+
+  if (sb->count == 0) goto add_new;
+  back = &sb->slices[sb->count - 1];
+  if (back->refcount) goto add_new;
+  if (back->data.inlined.length + n > sizeof(back->data.inlined.bytes))
+    goto add_new;
+  out = back->data.inlined.bytes + back->data.inlined.length;
+  back->data.inlined.length += n;
+  return out;
+
+add_new:
+  if (sb->count == sb->capacity) {
+    sb->capacity = GROW(sb->capacity);
+    GPR_ASSERT(sb->capacity > sb->count);
+    sb->slices = gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice));
+  }
+  back = &sb->slices[sb->count];
+  sb->count++;
+  back->refcount = NULL;
+  back->data.inlined.length = n;
+  return back->data.inlined.bytes;
+}
+
+size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice s) {
+  size_t out = sb->count;
+  if (out == sb->capacity) {
+    sb->capacity = GROW(sb->capacity);
+    GPR_ASSERT(sb->capacity > sb->count);
+    sb->slices = gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice));
+  }
+  sb->slices[out] = s;
+  sb->length += GPR_SLICE_LENGTH(s);
+  sb->count = out + 1;
+  return out;
+}
+
+void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice s) {
+  size_t n = sb->count;
+  /* if both the last slice in the slice buffer and the slice being added
+     are inlined (that is, that they carry their data inside the slice data
+     structure), and the back slice is not full, then concatenate directly
+     into the back slice, preventing many small slices being passed into
+     writes */
+  if (!s.refcount && n) {
+    gpr_slice *back = &sb->slices[n - 1];
+    if (!back->refcount && back->data.inlined.length < GPR_SLICE_INLINED_SIZE) {
+      if (s.data.inlined.length + back->data.inlined.length <=
+          GPR_SLICE_INLINED_SIZE) {
+        memcpy(back->data.inlined.bytes + back->data.inlined.length,
+               s.data.inlined.bytes, s.data.inlined.length);
+        back->data.inlined.length += s.data.inlined.length;
+      } else {
+        size_t cp1 = GPR_SLICE_INLINED_SIZE - back->data.inlined.length;
+        memcpy(back->data.inlined.bytes + back->data.inlined.length,
+               s.data.inlined.bytes, cp1);
+        back->data.inlined.length = GPR_SLICE_INLINED_SIZE;
+        if (n == sb->capacity) {
+          sb->capacity = GROW(sb->capacity);
+          GPR_ASSERT(sb->capacity > sb->count);
+          sb->slices =
+              gpr_realloc(sb->slices, sb->capacity * sizeof(gpr_slice));
+        }
+        back = &sb->slices[n];
+        sb->count = n + 1;
+        back->refcount = NULL;
+        back->data.inlined.length = s.data.inlined.length - cp1;
+        memcpy(back->data.inlined.bytes, s.data.inlined.bytes + cp1,
+               s.data.inlined.length - cp1);
+      }
+      sb->length += s.data.inlined.length;
+      return; /* early out */
+    }
+  }
+  gpr_slice_buffer_add_indexed(sb, s);
+}
+
+void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *s, size_t n) {
+  size_t i;
+  for (i = 0; i < n; i++) {
+    gpr_slice_buffer_add(sb, s[i]);
+  }
+}
+
+void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb) {
+  size_t i;
+
+  for (i = 0; i < sb->count; i++) {
+    gpr_slice_unref(sb->slices[i]);
+  }
+
+  sb->count = 0;
+  sb->length = 0;
+}
diff --git a/src/core/support/string.c b/src/core/support/string.c
new file mode 100644
index 0000000..b1f0795
--- /dev/null
+++ b/src/core/support/string.c
@@ -0,0 +1,124 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/string.h>
+
+#include <ctype.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/useful.h>
+
+char *gpr_strdup(const char *src) {
+  char *dst;
+  size_t len;
+
+  if (!src) {
+    return NULL;
+  }
+
+  len = strlen(src) + 1;
+  dst = gpr_malloc(len);
+
+  memcpy(dst, src, len);
+
+  return dst;
+}
+
+typedef struct {
+  size_t capacity;
+  size_t length;
+  char *data;
+} hexout;
+
+static hexout hexout_create() {
+  hexout r = {0, 0, NULL};
+  return r;
+}
+
+static void hexout_append(hexout *out, char c) {
+  if (out->length == out->capacity) {
+    out->capacity = GPR_MAX(8, 2 * out->capacity);
+    out->data = gpr_realloc(out->data, out->capacity);
+  }
+  out->data[out->length++] = c;
+}
+
+char *gpr_hexdump(const char *buf, size_t len, gpr_uint32 flags) {
+  static const char hex[16] = "0123456789abcdef";
+  hexout out = hexout_create();
+
+  const gpr_uint8 *const beg = (const gpr_uint8 *)buf;
+  const gpr_uint8 *const end = beg + len;
+  const gpr_uint8 *cur;
+
+  for (cur = beg; cur != end; ++cur) {
+    if (cur != beg) hexout_append(&out, ' ');
+    hexout_append(&out, hex[*cur >> 4]);
+    hexout_append(&out, hex[*cur & 0xf]);
+  }
+
+  if (flags & GPR_HEXDUMP_PLAINTEXT) {
+    cur = beg;
+    if (len) hexout_append(&out, ' ');
+    hexout_append(&out, '\'');
+    for (cur = beg; cur != end; ++cur) {
+      hexout_append(&out, isprint(*cur) ? *cur : '.');
+    }
+    hexout_append(&out, '\'');
+  }
+
+  hexout_append(&out, 0);
+
+  return out.data;
+}
+
+int gpr_parse_bytes_to_uint32(const char *buf, size_t len, gpr_uint32 *result) {
+  gpr_uint32 out = 0;
+  gpr_uint32 new;
+  size_t i;
+
+  if (len == 0) return 0; /* must have some bytes */
+
+  for (i = 0; i < len; i++) {
+    if (buf[i] < '0' || buf[i] > '9') return 0; /* bad char */
+    new = 10 * out + (buf[i] - '0');
+    if (new < out) return 0; /* overflow */
+    out = new;
+  }
+
+  *result = out;
+  return 1;
+}
diff --git a/src/core/support/string_posix.c b/src/core/support/string_posix.c
new file mode 100644
index 0000000..d1da379
--- /dev/null
+++ b/src/core/support/string_posix.c
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix code for gpr snprintf support. */
+
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+
+int gpr_asprintf(char **strp, const char *format, ...) {
+  va_list args;
+  int ret;
+  char buf[64];
+  size_t strp_buflen;
+
+  /* Use a constant-sized buffer to determine the length. */
+  va_start(args, format);
+  ret = vsnprintf(buf, sizeof(buf), format, args);
+  va_end(args);
+  if (!(0 <= ret && ret < ~(size_t)0)) {
+    *strp = NULL;
+    return -1;
+  }
+
+  /* Allocate a new buffer, with space for the NUL terminator. */
+  strp_buflen = (size_t)ret + 1;
+  if ((*strp = gpr_malloc(strp_buflen)) == NULL) {
+    /* This shouldn't happen, because gpr_malloc() calls abort(). */
+    return -1;
+  }
+
+  /* Return early if we have all the bytes. */
+  if (strp_buflen <= sizeof(buf)) {
+    memcpy(*strp, buf, strp_buflen);
+    return ret;
+  }
+
+  /* Try again using the larger buffer. */
+  va_start(args, format);
+  ret = vsnprintf(*strp, strp_buflen, format, args);
+  va_end(args);
+  if (ret == strp_buflen - 1) {
+    return ret;
+  }
+
+  /* This should never happen. */
+  gpr_free(*strp);
+  *strp = NULL;
+  return -1;
+}
diff --git a/src/core/support/sync.c b/src/core/support/sync.c
new file mode 100644
index 0000000..40e5465
--- /dev/null
+++ b/src/core/support/sync.c
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Generic implementation of synchronization primitives. */
+
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/atm.h>
+
+/* Number of mutexes to allocate for events, to avoid lock contention.
+   Should be a prime. */
+enum { event_sync_partitions = 31 };
+
+/* Event are partitioned by address to avoid lock contention. */
+static struct sync_array_s {
+  gpr_mu mu;
+  gpr_cv cv;
+} sync_array[event_sync_partitions];
+
+/* This routine is executed once on first use, via event_once */
+static gpr_once event_once = GPR_ONCE_INIT;
+static void event_initialize(void) {
+  int i;
+  for (i = 0; i != event_sync_partitions; i++) {
+    gpr_mu_init(&sync_array[i].mu);
+    gpr_cv_init(&sync_array[i].cv);
+  }
+}
+
+/* Hash ev into an element of sync_array[]. */
+static struct sync_array_s *hash(gpr_event *ev) {
+  return &sync_array[((gpr_uintptr)ev) % event_sync_partitions];
+}
+
+void gpr_event_init(gpr_event *ev) {
+  gpr_once_init(&event_once, &event_initialize);
+  ev->state = 0;
+}
+
+void gpr_event_set(gpr_event *ev, void *value) {
+  struct sync_array_s *s = hash(ev);
+  gpr_mu_lock(&s->mu);
+  GPR_ASSERT(gpr_atm_acq_load(&ev->state) == 0);
+  GPR_ASSERT(value != NULL);
+  gpr_atm_rel_store(&ev->state, (gpr_atm)value);
+  gpr_cv_broadcast(&s->cv);
+  gpr_mu_unlock(&s->mu);
+}
+
+void *gpr_event_get(gpr_event *ev) {
+  return (void *)gpr_atm_acq_load(&ev->state);
+}
+
+void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline) {
+  void *result = (void *)gpr_atm_acq_load(&ev->state);
+  if (result == NULL) {
+    struct sync_array_s *s = hash(ev);
+    gpr_mu_lock(&s->mu);
+    do {
+      result = (void *)gpr_atm_acq_load(&ev->state);
+    } while (result == NULL && !gpr_cv_wait(&s->cv, &s->mu, abs_deadline));
+    gpr_mu_unlock(&s->mu);
+  }
+  return result;
+}
+
+void *gpr_event_cancellable_wait(gpr_event *ev, gpr_timespec abs_deadline,
+                                 gpr_cancellable *c) {
+  void *result = (void *)gpr_atm_acq_load(&ev->state);
+  if (result == NULL) {
+    struct sync_array_s *s = hash(ev);
+    gpr_mu_lock(&s->mu);
+    do {
+      result = (void *)gpr_atm_acq_load(&ev->state);
+    } while (result == NULL &&
+             !gpr_cv_cancellable_wait(&s->cv, &s->mu, abs_deadline, c));
+    gpr_mu_unlock(&s->mu);
+  }
+  return result;
+}
+
+void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); }
+
+void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); }
+
+void gpr_refn(gpr_refcount *r, int n) {
+  gpr_atm_no_barrier_fetch_add(&r->count, n);
+}
+
+int gpr_unref(gpr_refcount *r) {
+  return gpr_atm_full_fetch_add(&r->count, -1) == 1;
+}
+
+void gpr_stats_init(gpr_stats_counter *c, gpr_intptr n) {
+  gpr_atm_rel_store(&c->value, n);
+}
+
+void gpr_stats_inc(gpr_stats_counter *c, gpr_intptr inc) {
+  gpr_atm_no_barrier_fetch_add(&c->value, inc);
+}
+
+gpr_intptr gpr_stats_read(const gpr_stats_counter *c) {
+  /* don't need acquire-load, but we have no no-barrier load yet */
+  return gpr_atm_acq_load(&c->value);
+}
diff --git a/src/core/support/sync_posix.c b/src/core/support/sync_posix.c
new file mode 100644
index 0000000..257a7fb
--- /dev/null
+++ b/src/core/support/sync_posix.c
@@ -0,0 +1,82 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix gpr synchroization support code. */
+
+#include <errno.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+void gpr_mu_init(gpr_mu *mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); }
+
+void gpr_mu_destroy(gpr_mu *mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); }
+
+void gpr_mu_lock(gpr_mu *mu) { GPR_ASSERT(pthread_mutex_lock(mu) == 0); }
+
+void gpr_mu_unlock(gpr_mu *mu) { GPR_ASSERT(pthread_mutex_unlock(mu) == 0); }
+
+int gpr_mu_trylock(gpr_mu *mu) {
+  int err = pthread_mutex_trylock(mu);
+  GPR_ASSERT(err == 0 || err == EBUSY);
+  return err == 0;
+}
+
+/*----------------------------------------*/
+
+void gpr_cv_init(gpr_cv *cv) { GPR_ASSERT(pthread_cond_init(cv, NULL) == 0); }
+
+void gpr_cv_destroy(gpr_cv *cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); }
+
+int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline) {
+  int err = 0;
+  if (gpr_time_cmp(abs_deadline, gpr_inf_future) == 0) {
+    err = pthread_cond_wait(cv, mu);
+  } else {
+    err = pthread_cond_timedwait(cv, mu, &abs_deadline);
+  }
+  GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN);
+  return err == ETIMEDOUT;
+}
+
+void gpr_cv_signal(gpr_cv *cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); }
+
+void gpr_cv_broadcast(gpr_cv *cv) {
+  GPR_ASSERT(pthread_cond_broadcast(cv) == 0);
+}
+
+/*----------------------------------------*/
+
+void gpr_once_init(gpr_once *once, void (*init_function)(void)) {
+  GPR_ASSERT(pthread_once(once, init_function) == 0);
+}
diff --git a/src/core/support/sync_win32.c b/src/core/support/sync_win32.c
new file mode 100644
index 0000000..63dd4eb
--- /dev/null
+++ b/src/core/support/sync_win32.c
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Win32 code for gpr synchronization support. */
+
+#define _WIN32_WINNT 0x0600
+#include <windows.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+void gpr_mu_init(gpr_mu *mu) {
+  InitializeCriticalSection(&mu->cs);
+  mu->locked = 0;
+}
+
+void gpr_mu_destroy(gpr_mu *mu) { DeleteCriticalSection(&mu->cs); }
+
+void gpr_mu_lock(gpr_mu *mu) {
+  EnterCriticalSection(&mu->cs);
+  GPR_ASSERT(!mu->locked);
+  mu->locked = 1;
+}
+
+void gpr_mu_unlock(gpr_mu *mu) {
+  mu->locked = 0;
+  LeaveCriticalSection(&mu->cs);
+}
+
+int gpr_mu_trylock(gpr_mu *mu) {
+  int result = TryEnterCriticalSection(&mu->cs);
+  if (result) {
+    if (mu->locked) {                /* This thread already holds the lock. */
+      LeaveCriticalSection(&mu->cs); /* Decrement lock count. */
+      result = 0;                    /* Indicate failure */
+    }
+    mu->locked = 1;
+  }
+  return result;
+}
+
+/*----------------------------------------*/
+
+void gpr_cv_init(gpr_cv *cv) { InitializeConditionVariable(cv); }
+
+void gpr_cv_destroy(gpr_cv *cv) {
+  /* Condition variables don't need destruction in Win32. */
+}
+
+int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline) {
+  int timeout = 0;
+  if (gpr_time_cmp(abs_deadline, gpr_inf_future) == 0) {
+    SleepConditionVariableCS(cv, &mu->cs, INFINITE);
+  } else {
+    gpr_timespec now = gpr_now();
+    gpr_int64 now_ms = now.tv_sec * 1000 + now.tv_nsec / 1000000;
+    gpr_int64 deadline_ms =
+        abs_deadline.tv_sec * 1000 + abs_deadline.tv_nsec / 1000000;
+    if (now_ms >= deadline_ms) {
+      timeout = 1;
+    } else {
+      timeout =
+          (SleepConditionVariableCS(cv, &mu->cs, deadline_ms - now_ms) == 0 &&
+           GetLastError() == ERROR_TIMEOUT);
+    }
+  }
+  return timeout;
+}
+
+void gpr_cv_signal(gpr_cv *cv) { WakeConditionVariable(cv); }
+
+void gpr_cv_broadcast(gpr_cv *cv) { WakeAllConditionVariable(cv); }
+
+/*----------------------------------------*/
+
+static void *dummy;
+struct run_once_func_arg {
+  void (*init_function)(void);
+};
+static int run_once_func(gpr_once *once, void *v, void **pv) {
+  struct run_once_func_arg *arg = v;
+  (*arg->init_function)();
+  return 1;
+}
+
+void gpr_once_init(gpr_once *once, void (*init_function)(void)) {
+  struct run_once_func_arg arg;
+  arg.init_function = init_function;
+  InitOnceExecuteOnce(once, &run_once_func, &arg, &dummy);
+}
diff --git a/src/core/support/thd_internal.h b/src/core/support/thd_internal.h
new file mode 100644
index 0000000..519177a
--- /dev/null
+++ b/src/core/support/thd_internal.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__
+#define __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__
+
+/* Internal interfaces between modules within the gpr support library.  */
+
+#endif  /* __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__ */
diff --git a/src/core/support/thd_posix.c b/src/core/support/thd_posix.c
new file mode 100644
index 0000000..c86eea4
--- /dev/null
+++ b/src/core/support/thd_posix.c
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix implementation for gpr threads. */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+
+struct thd_arg {
+  void (*body)(void *arg); /* body of a thread */
+  void *arg;               /* argument to a thread */
+};
+
+/* Body of every thread started via gpr_thd_new. */
+static void *thread_body(void *v) {
+  struct thd_arg a = *(struct thd_arg *)v;
+  gpr_free(v);
+  (*a.body)(a.arg);
+  return NULL;
+}
+
+int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg,
+                const gpr_thd_options *options) {
+  int thread_started;
+  pthread_attr_t attr;
+  struct thd_arg *a = gpr_malloc(sizeof(*a));
+  a->body = thd_body;
+  a->arg = arg;
+
+  GPR_ASSERT(pthread_attr_init(&attr) == 0);
+  GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
+  thread_started = (pthread_create(t, &attr, &thread_body, a) == 0);
+  GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
+  if (!thread_started) {
+    gpr_free(a);
+  }
+  return thread_started;
+}
+
+gpr_thd_options gpr_thd_options_default(void) {
+  gpr_thd_options options;
+  memset(&options, 0, sizeof(options));
+  return options;
+}
diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c
new file mode 100644
index 0000000..8440479
--- /dev/null
+++ b/src/core/support/thd_win32.c
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix implementation for gpr threads. */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_WIN32
+
+#include <windows.h>
+#include <string.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/thd.h>
+
+struct thd_arg {
+  void (*body)(void *arg); /* body of a thread */
+  void *arg;               /* argument to a thread */
+};
+
+/* Body of every thread started via gpr_thd_new. */
+static DWORD thread_body(void *v) {
+  struct thd_arg a = *(struct thd_arg *)v;
+  gpr_free(v);
+  (*a.body)(a.arg);
+  return 0;
+}
+
+int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg,
+                const gpr_thd_options *options) {
+  HANDLE handle;
+  struct thd_arg *a = gpr_malloc(sizeof(*a));
+  a->body = thd_body;
+  a->arg = arg;
+  *t = 0;
+  handle = CreateThread(NULL, 64 * 1024, &thread_body, a, 0, NULL);
+  if (handle == NULL) {
+    gpr_free(a);
+  } else {
+    CloseHandle(handle); /* threads are "detached" */
+  }
+  return handle != NULL;
+}
+
+gpr_thd_options gpr_thd_options_default(void) {
+  gpr_thd_options options;
+  memset(&options, 0, sizeof(options));
+  return options;
+}
+
+#endif /* GPR_WIN32 */
diff --git a/src/core/support/time.c b/src/core/support/time.c
new file mode 100644
index 0000000..1d8765f
--- /dev/null
+++ b/src/core/support/time.c
@@ -0,0 +1,243 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Generic implementation of time calls. */
+
+#include <grpc/support/time.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <grpc/support/log.h>
+
+int gpr_time_cmp(gpr_timespec a, gpr_timespec b) {
+  int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
+  if (cmp == 0) {
+    cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
+  }
+  return cmp;
+}
+
+/* There's no standard TIME_T_MIN and TIME_T_MAX, so we construct them.  The
+   following assumes that signed types are two's-complement and that bytes are
+   8 bits.  */
+
+/* The top bit of integral type t. */
+#define TOP_BIT_OF_TYPE(t) (((gpr_uintmax)1) << ((8 * sizeof(t)) - 1))
+
+/* Return whether integral type t is signed. */
+#define TYPE_IS_SIGNED(t) (((t)1) > (t) ~(t)0)
+
+/* The minimum and maximum value of integral type t. */
+#define TYPE_MIN(t) ((t)(TYPE_IS_SIGNED(t) ? TOP_BIT_OF_TYPE(t) : 0))
+#define TYPE_MAX(t)                                 \
+  ((t)(TYPE_IS_SIGNED(t) ? (TOP_BIT_OF_TYPE(t) - 1) \
+                         : ((TOP_BIT_OF_TYPE(t) - 1) << 1) + 1))
+
+const gpr_timespec gpr_time_0 = {0, 0};
+const gpr_timespec gpr_inf_future = {TYPE_MAX(time_t), 0};
+const gpr_timespec gpr_inf_past = {TYPE_MIN(time_t), 0};
+
+/* TODO(ctiller): consider merging _nanos, _micros, _millis into a single
+   function for maintainability. Similarly for _seconds, _minutes, and _hours */
+
+gpr_timespec gpr_time_from_nanos(long ns) {
+  gpr_timespec result;
+  if (ns == LONG_MAX) {
+    result = gpr_inf_future;
+  } else if (ns == LONG_MIN) {
+    result = gpr_inf_past;
+  } else if (ns >= 0) {
+    result.tv_sec = ns / 1000000000;
+    result.tv_nsec = ns - result.tv_sec * 1000000000;
+  } else {
+    /* Calculation carefully formulated to avoid any possible under/overflow. */
+    result.tv_sec = (-(999999999 - (ns + 1000000000)) / 1000000000) - 1;
+    result.tv_nsec = ns - result.tv_sec * 1000000000;
+  }
+  return result;
+}
+
+gpr_timespec gpr_time_from_micros(long us) {
+  gpr_timespec result;
+  if (us == LONG_MAX) {
+    result = gpr_inf_future;
+  } else if (us == LONG_MIN) {
+    result = gpr_inf_past;
+  } else if (us >= 0) {
+    result.tv_sec = us / 1000000;
+    result.tv_nsec = (us - result.tv_sec * 1000000) * 1000;
+  } else {
+    /* Calculation carefully formulated to avoid any possible under/overflow. */
+    result.tv_sec = (-(999999 - (us + 1000000)) / 1000000) - 1;
+    result.tv_nsec = (us - result.tv_sec * 1000000) * 1000;
+  }
+  return result;
+}
+
+gpr_timespec gpr_time_from_millis(long ms) {
+  gpr_timespec result;
+  if (ms == LONG_MAX) {
+    result = gpr_inf_future;
+  } else if (ms == LONG_MIN) {
+    result = gpr_inf_past;
+  } else if (ms >= 0) {
+    result.tv_sec = ms / 1000;
+    result.tv_nsec = (ms - result.tv_sec * 1000) * 1000000;
+  } else {
+    /* Calculation carefully formulated to avoid any possible under/overflow. */
+    result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1;
+    result.tv_nsec = (ms - result.tv_sec * 1000) * 1000000;
+  }
+  return result;
+}
+
+gpr_timespec gpr_time_from_seconds(long s) {
+  gpr_timespec result;
+  if (s == LONG_MAX) {
+    result = gpr_inf_future;
+  } else if (s == LONG_MIN) {
+    result = gpr_inf_past;
+  } else {
+    result.tv_sec = s;
+    result.tv_nsec = 0;
+  }
+  return result;
+}
+
+gpr_timespec gpr_time_from_minutes(long m) {
+  gpr_timespec result;
+  if (m >= LONG_MAX / 60) {
+    result = gpr_inf_future;
+  } else if (m <= LONG_MIN / 60) {
+    result = gpr_inf_past;
+  } else {
+    result.tv_sec = m * 60;
+    result.tv_nsec = 0;
+  }
+  return result;
+}
+
+gpr_timespec gpr_time_from_hours(long h) {
+  gpr_timespec result;
+  if (h >= LONG_MAX / 3600) {
+    result = gpr_inf_future;
+  } else if (h <= LONG_MIN / 3600) {
+    result = gpr_inf_past;
+  } else {
+    result.tv_sec = h * 3600;
+    result.tv_nsec = 0;
+  }
+  return result;
+}
+
+gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
+  gpr_timespec sum;
+  int inc = 0;
+  sum.tv_nsec = a.tv_nsec + b.tv_nsec;
+  if (sum.tv_nsec >= 1000000000) {
+    sum.tv_nsec -= 1000000000;
+    inc++;
+  }
+  if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
+    sum = a;
+  } else if (b.tv_sec == TYPE_MAX(time_t) ||
+             (b.tv_sec >= 0 && a.tv_sec >= TYPE_MAX(time_t) - b.tv_sec)) {
+    sum = gpr_inf_future;
+  } else if (b.tv_sec == TYPE_MIN(time_t) ||
+             (b.tv_sec <= 0 && a.tv_sec <= TYPE_MIN(time_t) - b.tv_sec)) {
+    sum = gpr_inf_past;
+  } else {
+    sum.tv_sec = a.tv_sec + b.tv_sec;
+    if (inc != 0 && sum.tv_sec == TYPE_MAX(time_t) - 1) {
+      sum = gpr_inf_future;
+    } else {
+      sum.tv_sec += inc;
+    }
+  }
+  return sum;
+}
+
+gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) {
+  gpr_timespec diff;
+  int dec = 0;
+  diff.tv_nsec = a.tv_nsec - b.tv_nsec;
+  if (diff.tv_nsec < 0) {
+    diff.tv_nsec += 1000000000;
+    dec++;
+  }
+  if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
+    diff = a;
+  } else if (b.tv_sec == TYPE_MIN(time_t) ||
+             (b.tv_sec <= 0 && a.tv_sec >= TYPE_MAX(time_t) + b.tv_sec)) {
+    diff = gpr_inf_future;
+  } else if (b.tv_sec == TYPE_MAX(time_t) ||
+             (b.tv_sec >= 0 && a.tv_sec <= TYPE_MIN(time_t) + b.tv_sec)) {
+    diff = gpr_inf_past;
+  } else {
+    diff.tv_sec = a.tv_sec - b.tv_sec;
+    if (dec != 0 && diff.tv_sec == TYPE_MIN(time_t) + 1) {
+      diff = gpr_inf_past;
+    } else {
+      diff.tv_sec -= dec;
+    }
+  }
+  return diff;
+}
+
+int gpr_time_similar(gpr_timespec a, gpr_timespec b, gpr_timespec threshold) {
+  int cmp_ab;
+
+  cmp_ab = gpr_time_cmp(a, b);
+  if (cmp_ab == 0) return 1;
+  if (cmp_ab < 0) {
+    return gpr_time_cmp(gpr_time_sub(b, a), threshold) <= 0;
+  } else {
+    return gpr_time_cmp(gpr_time_sub(a, b), threshold) <= 0;
+  }
+}
+
+struct timeval gpr_timeval_from_timespec(gpr_timespec t) {
+  /* TODO(klempner): Consider whether this should round up, since it is likely
+     to be used for delays */
+  struct timeval tv;
+  tv.tv_sec = t.tv_sec;
+  tv.tv_usec = t.tv_nsec / 1000;
+  return tv;
+}
+
+gpr_timespec gpr_timespec_from_timeval(struct timeval t) {
+  gpr_timespec ts;
+  ts.tv_sec = t.tv_sec;
+  ts.tv_nsec = t.tv_usec * 1000;
+  return ts;
+}
diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c
new file mode 100644
index 0000000..e7b79d1
--- /dev/null
+++ b/src/core/support/time_posix.c
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix code for gpr time support. */
+
+/* So we get nanosleep and clock_* */
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 199309L
+#endif
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <grpc/support/time.h>
+
+#if _POSIX_TIMERS > 0
+gpr_timespec gpr_now(void) {
+  gpr_timespec now;
+  clock_gettime(CLOCK_REALTIME, &now);
+  return now;
+}
+#else
+/* For some reason Apple's OSes haven't implemented clock_gettime. */
+/* TODO(klempner): Add special handling for Apple. */
+gpr_timespec gpr_now(void) {
+  gpr_timespec now;
+  struct timeval now_tv;
+  gettimeofday(&now_tv, NULL);
+  now.tv_sec = now_tv.tv_sec;
+  now.tv_nsec = now_tv.tv_usec / 1000;
+  return now;
+}
+#endif
+
+void gpr_sleep_until(gpr_timespec until) {
+  gpr_timespec now;
+  gpr_timespec delta;
+
+  for (;;) {
+    /* We could simplify by using clock_nanosleep instead, but it might be
+     * slightly less portable. */
+    now = gpr_now();
+    if (gpr_time_cmp(until, now) <= 0) {
+      return;
+    }
+
+    delta = gpr_time_sub(until, now);
+    if (nanosleep(&delta, NULL) == 0) {
+      break;
+    }
+  }
+}
diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c
new file mode 100644
index 0000000..4258091
--- /dev/null
+++ b/src/core/support/time_win32.c
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Win32 code for gpr time support. */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_WIN32
+
+#include <grpc/support/time.h>
+#include <windows.h>
+
+gpr_timespec gpr_now(void) {
+  gpr_timespec now_tv;
+  struct _timeb64 now_tb;
+  _ftime64(&now_tb);
+  now_tv.tv_sec = now_tb.time;
+  now_tv.tv_nsec = now_tb.millitm * 1000000;
+  return now_tv;
+}
+
+#endif /* GPR_WIN32 */
diff --git a/src/core/surface/byte_buffer.c b/src/core/surface/byte_buffer.c
new file mode 100644
index 0000000..27a6c6e
--- /dev/null
+++ b/src/core/surface/byte_buffer.c
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/byte_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+grpc_byte_buffer *grpc_byte_buffer_create(gpr_slice *slices, size_t nslices) {
+  size_t i;
+  grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer));
+
+  bb->type = GRPC_BB_SLICE_BUFFER;
+  gpr_slice_buffer_init(&bb->data.slice_buffer);
+  for (i = 0; i < nslices; i++) {
+    gpr_slice_ref(slices[i]);
+    gpr_slice_buffer_add(&bb->data.slice_buffer, slices[i]);
+  }
+
+  return bb;
+}
+
+void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) {
+  switch (bb->type) {
+    case GRPC_BB_SLICE_BUFFER:
+      gpr_slice_buffer_destroy(&bb->data.slice_buffer);
+      break;
+  }
+  free(bb);
+}
+
+size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) {
+  switch (bb->type) {
+    case GRPC_BB_SLICE_BUFFER:
+      return bb->data.slice_buffer.length;
+  }
+  gpr_log(GPR_ERROR, "should never reach here");
+  abort();
+}
diff --git a/src/core/surface/byte_buffer_reader.c b/src/core/surface/byte_buffer_reader.c
new file mode 100644
index 0000000..18500b8
--- /dev/null
+++ b/src/core/surface/byte_buffer_reader.c
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/byte_buffer_reader.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice_buffer.h>
+#include <grpc/byte_buffer.h>
+
+grpc_byte_buffer_reader *grpc_byte_buffer_reader_create(
+    grpc_byte_buffer *buffer) {
+  grpc_byte_buffer_reader *reader = malloc(sizeof(grpc_byte_buffer_reader));
+  reader->buffer = buffer;
+  switch (buffer->type) {
+    case GRPC_BB_SLICE_BUFFER:
+      reader->current.index = 0;
+  }
+  return reader;
+}
+
+int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
+                                 gpr_slice *slice) {
+  grpc_byte_buffer *buffer = reader->buffer;
+  gpr_slice_buffer *slice_buffer;
+  switch (buffer->type) {
+    case GRPC_BB_SLICE_BUFFER:
+      slice_buffer = &buffer->data.slice_buffer;
+      if (reader->current.index < slice_buffer->count) {
+        *slice = gpr_slice_ref(slice_buffer->slices[reader->current.index]);
+        reader->current.index += 1;
+        return 1;
+      } else {
+        return 0;
+      }
+      break;
+  }
+  return 0;
+}
+
+void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) {
+  free(reader);
+}
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
new file mode 100644
index 0000000..63d408d
--- /dev/null
+++ b/src/core/surface/call.c
@@ -0,0 +1,835 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/call.h"
+#include "src/core/channel/channel_stack.h"
+#include "src/core/channel/metadata_buffer.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include "src/core/surface/channel.h"
+#include "src/core/surface/completion_queue.h"
+#include "src/core/surface/surface_em.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define INVALID_TAG ((void *)0xdeadbeef)
+
+/* Pending read queue
+
+   This data structure tracks reads that need to be presented to the completion
+   queue but are waiting for the application to ask for them. */
+
+#define INITIAL_PENDING_READ_COUNT 4
+
+typedef struct {
+  grpc_byte_buffer *byte_buffer;
+  void *user_data;
+  void (*on_finish)(void *user_data, grpc_op_error error);
+} pending_read;
+
+/* TODO(ctiller): inline an element or two into this struct to avoid per-call
+                  allocations */
+typedef struct {
+  pending_read *data;
+  size_t count;
+  size_t capacity;
+} pending_read_array;
+
+typedef struct {
+  size_t drain_pos;
+  pending_read_array filling;
+  pending_read_array draining;
+} pending_read_queue;
+
+static void pra_init(pending_read_array *array) {
+  array->data = gpr_malloc(sizeof(pending_read) * INITIAL_PENDING_READ_COUNT);
+  array->count = 0;
+  array->capacity = INITIAL_PENDING_READ_COUNT;
+}
+
+static void pra_destroy(pending_read_array *array,
+                        size_t finish_starting_from) {
+  size_t i;
+  for (i = finish_starting_from; i < array->count; i++) {
+    array->data[i].on_finish(array->data[i].user_data, GRPC_OP_ERROR);
+  }
+  gpr_free(array->data);
+}
+
+/* Append an operation to an array, expanding as needed */
+static void pra_push(pending_read_array *a, grpc_byte_buffer *buffer,
+                     void (*on_finish)(void *user_data, grpc_op_error error),
+                     void *user_data) {
+  if (a->count == a->capacity) {
+    a->capacity *= 2;
+    a->data = gpr_realloc(a->data, sizeof(pending_read) * a->capacity);
+  }
+  a->data[a->count].byte_buffer = buffer;
+  a->data[a->count].user_data = user_data;
+  a->data[a->count].on_finish = on_finish;
+  a->count++;
+}
+
+static void prq_init(pending_read_queue *q) {
+  q->drain_pos = 0;
+  pra_init(&q->filling);
+  pra_init(&q->draining);
+}
+
+static void prq_destroy(pending_read_queue *q) {
+  pra_destroy(&q->filling, 0);
+  pra_destroy(&q->draining, q->drain_pos);
+}
+
+static int prq_is_empty(pending_read_queue *q) {
+  return (q->drain_pos == q->draining.count && q->filling.count == 0);
+}
+
+static void prq_push(pending_read_queue *q, grpc_byte_buffer *buffer,
+                     void (*on_finish)(void *user_data, grpc_op_error error),
+                     void *user_data) {
+  pra_push(&q->filling, buffer, on_finish, user_data);
+}
+
+/* Take the first queue element and move it to the completion queue. Do nothing
+   if q is empty */
+static int prq_pop_to_cq(pending_read_queue *q, void *tag, grpc_call *call,
+                         grpc_completion_queue *cq) {
+  pending_read_array temp_array;
+  pending_read *pr;
+
+  if (q->drain_pos == q->draining.count) {
+    if (q->filling.count == 0) {
+      return 0;
+    }
+    q->draining.count = 0;
+    q->drain_pos = 0;
+    /* swap arrays */
+    temp_array = q->filling;
+    q->filling = q->draining;
+    q->draining = temp_array;
+  }
+
+  pr = q->draining.data + q->drain_pos;
+  q->drain_pos++;
+  grpc_cq_end_read(cq, tag, call, pr->on_finish, pr->user_data,
+                   pr->byte_buffer);
+  return 1;
+}
+
+/* grpc_call proper */
+
+/* the state of a call, based upon which functions have been called against
+   said call */
+typedef enum { CALL_CREATED, CALL_STARTED, CALL_FINISHED } call_state;
+
+struct grpc_call {
+  grpc_completion_queue *cq;
+  grpc_channel *channel;
+  grpc_mdctx *metadata_context;
+
+  call_state state;
+  gpr_uint8 is_client;
+  gpr_uint8 have_write;
+  grpc_metadata_buffer incoming_metadata;
+
+  /* protects variables in this section */
+  gpr_mu read_mu;
+  gpr_uint8 reads_done;
+  gpr_uint8 received_finish;
+  gpr_uint8 received_metadata;
+  gpr_uint8 have_read;
+  gpr_uint8 have_alarm;
+  /* The current outstanding read message tag (only valid if have_read == 1) */
+  void *read_tag;
+  void *metadata_tag;
+  void *finished_tag;
+  pending_read_queue prq;
+
+  grpc_em_alarm alarm;
+
+  /* The current outstanding send message/context/invoke/end tag (only valid if
+     have_write == 1) */
+  void *write_tag;
+
+  /* The final status of the call */
+  grpc_status_code status_code;
+  grpc_mdstr *status_details;
+
+  gpr_refcount internal_refcount;
+};
+
+#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call)+1))
+#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
+#define CALL_ELEM_FROM_CALL(call, idx) \
+  grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
+#define CALL_FROM_TOP_ELEM(top_elem) \
+  CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem))
+
+static void do_nothing(void *ignored, grpc_op_error also_ignored) {}
+
+grpc_call *grpc_call_create(grpc_channel *channel,
+                            const void *server_transport_data) {
+  grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
+  grpc_call *call =
+      gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
+  call->cq = NULL;
+  call->channel = channel;
+  grpc_channel_internal_ref(channel);
+  call->metadata_context = grpc_channel_get_metadata_context(channel);
+  call->state = CALL_CREATED;
+  call->is_client = (server_transport_data == NULL);
+  call->write_tag = INVALID_TAG;
+  call->read_tag = INVALID_TAG;
+  call->metadata_tag = INVALID_TAG;
+  call->finished_tag = INVALID_TAG;
+  call->have_read = 0;
+  call->have_write = 0;
+  call->have_alarm = 0;
+  call->received_metadata = 0;
+  call->status_code =
+      server_transport_data != NULL ? GRPC_STATUS_OK : GRPC_STATUS_UNKNOWN;
+  call->status_details = NULL;
+  call->received_finish = 0;
+  call->reads_done = 0;
+  grpc_metadata_buffer_init(&call->incoming_metadata);
+  gpr_ref_init(&call->internal_refcount, 1);
+  grpc_call_stack_init(channel_stack, server_transport_data,
+                       CALL_STACK_FROM_CALL(call));
+  prq_init(&call->prq);
+  gpr_mu_init(&call->read_mu);
+  return call;
+}
+
+void grpc_call_internal_ref(grpc_call *c) { gpr_ref(&c->internal_refcount); }
+
+void grpc_call_internal_unref(grpc_call *c) {
+  if (gpr_unref(&c->internal_refcount)) {
+    grpc_call_stack_destroy(CALL_STACK_FROM_CALL(c));
+    grpc_metadata_buffer_destroy(&c->incoming_metadata, GRPC_OP_OK);
+    if (c->status_details) {
+      grpc_mdstr_unref(c->status_details);
+    }
+    prq_destroy(&c->prq);
+    gpr_mu_destroy(&c->read_mu);
+    grpc_channel_internal_unref(c->channel);
+    gpr_free(c);
+  }
+}
+
+void grpc_call_destroy(grpc_call *c) {
+  gpr_mu_lock(&c->read_mu);
+  if (c->have_alarm) {
+    void *arg_was;
+    grpc_em_alarm_cancel(&c->alarm, &arg_was);
+    c->have_alarm = 0;
+  }
+  gpr_mu_unlock(&c->read_mu);
+  grpc_call_internal_unref(c);
+}
+
+grpc_call_error grpc_call_cancel(grpc_call *c) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  op.type = GRPC_CANCEL_OP;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = 0;
+  op.done_cb = do_nothing;
+  op.user_data = NULL;
+
+  elem = CALL_ELEM_FROM_CALL(c, 0);
+  elem->filter->call_op(elem, &op);
+
+  return GRPC_CALL_OK;
+}
+
+void grpc_call_execute_op(grpc_call *call, grpc_call_op *op) {
+  grpc_call_element *elem;
+  GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+  elem->filter->call_op(elem, op);
+}
+
+grpc_call_error grpc_call_add_metadata(grpc_call *call, grpc_metadata *metadata,
+                                       gpr_uint32 flags) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  if (call->state >= CALL_STARTED) {
+    return GRPC_CALL_ERROR_ALREADY_INVOKED;
+  }
+
+  op.type = GRPC_SEND_METADATA;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = flags;
+  op.done_cb = do_nothing;
+  op.user_data = NULL;
+  op.data.metadata = grpc_mdelem_from_string_and_buffer(
+      call->metadata_context, metadata->key, (gpr_uint8 *)metadata->value,
+      metadata->value_length);
+
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+  elem->filter->call_op(elem, &op);
+
+  return GRPC_CALL_OK;
+}
+
+static void done_invoke(void *user_data, grpc_op_error error) {
+  grpc_call *call = user_data;
+  void *tag = call->write_tag;
+
+  GPR_ASSERT(call->have_write);
+  call->have_write = 0;
+  call->write_tag = INVALID_TAG;
+  grpc_cq_end_invoke_accepted(call->cq, tag, call, NULL, NULL, error);
+}
+
+static void finish_call(grpc_call *call) {
+  grpc_status status;
+  status.code = call->status_code;
+  status.details = call->status_details
+                       ? (char *)grpc_mdstr_as_c_string(call->status_details)
+                       : NULL;
+  grpc_cq_end_finished(call->cq, call->finished_tag, call, NULL, NULL, status);
+}
+
+grpc_call_error grpc_call_start_invoke(grpc_call *call,
+                                       grpc_completion_queue *cq,
+                                       void *invoke_accepted_tag,
+                                       void *metadata_read_tag,
+                                       void *finished_tag, gpr_uint32 flags) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  /* validate preconditions */
+  if (!call->is_client) {
+    gpr_log(GPR_ERROR, "can only call %s on clients", __FUNCTION__);
+    return GRPC_CALL_ERROR_NOT_ON_SERVER;
+  }
+
+  if (call->state >= CALL_STARTED || call->cq) {
+    gpr_log(GPR_ERROR, "call is already invoked");
+    return GRPC_CALL_ERROR_ALREADY_INVOKED;
+  }
+
+  if (call->have_write) {
+    gpr_log(GPR_ERROR, "can only have one pending write operation at a time");
+    return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
+  }
+
+  if (call->have_read) {
+    gpr_log(GPR_ERROR, "can only have one pending read operation at a time");
+    return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
+  }
+
+  if (flags & GRPC_WRITE_NO_COMPRESS) {
+    return GRPC_CALL_ERROR_INVALID_FLAGS;
+  }
+
+  /* inform the completion queue of an incoming operation */
+  grpc_cq_begin_op(cq, call, GRPC_FINISHED);
+  grpc_cq_begin_op(cq, call, GRPC_CLIENT_METADATA_READ);
+  grpc_cq_begin_op(cq, call, GRPC_INVOKE_ACCEPTED);
+
+  gpr_mu_lock(&call->read_mu);
+
+  /* update state */
+  call->cq = cq;
+  call->state = CALL_STARTED;
+  call->finished_tag = finished_tag;
+
+  if (call->received_finish) {
+    /* handle early cancellation */
+    grpc_cq_end_invoke_accepted(call->cq, invoke_accepted_tag, call, NULL, NULL,
+                                GRPC_OP_ERROR);
+    grpc_cq_end_client_metadata_read(call->cq, metadata_read_tag, call, NULL,
+                                     NULL, 0, NULL);
+    finish_call(call);
+
+    /* early out.. unlock & return */
+    gpr_mu_unlock(&call->read_mu);
+    return GRPC_CALL_OK;
+  }
+
+  call->write_tag = invoke_accepted_tag;
+  call->metadata_tag = metadata_read_tag;
+
+  call->have_write = 1;
+
+  gpr_mu_unlock(&call->read_mu);
+
+  /* call down the filter stack */
+  op.type = GRPC_SEND_START;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = flags;
+  op.done_cb = done_invoke;
+  op.user_data = call;
+
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+  elem->filter->call_op(elem, &op);
+
+  return GRPC_CALL_OK;
+}
+
+grpc_call_error grpc_call_accept(grpc_call *call, grpc_completion_queue *cq,
+                                 void *finished_tag, gpr_uint32 flags) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  /* validate preconditions */
+  if (call->is_client) {
+    gpr_log(GPR_ERROR, "can only call %s on servers", __FUNCTION__);
+    return GRPC_CALL_ERROR_NOT_ON_CLIENT;
+  }
+
+  if (call->state >= CALL_STARTED) {
+    gpr_log(GPR_ERROR, "call is already invoked");
+    return GRPC_CALL_ERROR_ALREADY_INVOKED;
+  }
+
+  if (flags & GRPC_WRITE_NO_COMPRESS) {
+    return GRPC_CALL_ERROR_INVALID_FLAGS;
+  }
+
+  /* inform the completion queue of an incoming operation (corresponding to
+     finished_tag) */
+  grpc_cq_begin_op(cq, call, GRPC_FINISHED);
+
+  /* update state */
+  gpr_mu_lock(&call->read_mu);
+  call->state = CALL_STARTED;
+  call->cq = cq;
+  call->finished_tag = finished_tag;
+  if (prq_is_empty(&call->prq) && call->received_finish) {
+    finish_call(call);
+
+    /* early out.. unlock & return */
+    gpr_mu_unlock(&call->read_mu);
+    return GRPC_CALL_OK;
+  }
+  gpr_mu_unlock(&call->read_mu);
+
+  /* call down */
+  op.type = GRPC_SEND_START;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = flags;
+  op.done_cb = do_nothing;
+  op.user_data = NULL;
+
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+  elem->filter->call_op(elem, &op);
+
+  return GRPC_CALL_OK;
+}
+
+static void done_writes_done(void *user_data, grpc_op_error error) {
+  grpc_call *call = user_data;
+  void *tag = call->write_tag;
+
+  GPR_ASSERT(call->have_write);
+  call->have_write = 0;
+  call->write_tag = INVALID_TAG;
+  grpc_cq_end_finish_accepted(call->cq, tag, call, NULL, NULL, error);
+}
+
+static void done_write(void *user_data, grpc_op_error error) {
+  grpc_call *call = user_data;
+  void *tag = call->write_tag;
+
+  GPR_ASSERT(call->have_write);
+  call->have_write = 0;
+  call->write_tag = INVALID_TAG;
+  grpc_cq_end_write_accepted(call->cq, tag, call, NULL, NULL, error);
+}
+
+void grpc_call_client_initial_metadata_complete(
+    grpc_call_element *surface_element) {
+  grpc_call *call = grpc_call_from_top_element(surface_element);
+  size_t count;
+  grpc_metadata *elements;
+
+  gpr_mu_lock(&call->read_mu);
+  count = grpc_metadata_buffer_count(&call->incoming_metadata);
+  elements = grpc_metadata_buffer_extract_elements(&call->incoming_metadata);
+
+  GPR_ASSERT(!call->received_metadata);
+  grpc_cq_end_client_metadata_read(call->cq, call->metadata_tag, call,
+                                   grpc_metadata_buffer_cleanup_elements,
+                                   elements, count, elements);
+  call->received_metadata = 1;
+  call->metadata_tag = INVALID_TAG;
+  gpr_mu_unlock(&call->read_mu);
+}
+
+static void request_more_data(grpc_call *call) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  /* call down */
+  op.type = GRPC_REQUEST_DATA;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = 0;
+  op.done_cb = do_nothing;
+  op.user_data = NULL;
+
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+  elem->filter->call_op(elem, &op);
+}
+
+grpc_call_error grpc_call_start_read(grpc_call *call, void *tag) {
+  gpr_uint8 request_more = 0;
+
+  switch (call->state) {
+    case CALL_CREATED:
+      return GRPC_CALL_ERROR_NOT_INVOKED;
+    case CALL_STARTED:
+      break;
+    case CALL_FINISHED:
+      return GRPC_CALL_ERROR_ALREADY_FINISHED;
+  }
+
+  gpr_mu_lock(&call->read_mu);
+
+  if (call->have_read) {
+    gpr_mu_unlock(&call->read_mu);
+    return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
+  }
+
+  grpc_cq_begin_op(call->cq, call, GRPC_READ);
+
+  if (!prq_pop_to_cq(&call->prq, tag, call, call->cq)) {
+    if (call->reads_done) {
+      grpc_cq_end_read(call->cq, tag, call, do_nothing, NULL, NULL);
+    } else {
+      call->read_tag = tag;
+      call->have_read = 1;
+      request_more = 1;
+    }
+  } else if (prq_is_empty(&call->prq) && call->received_finish) {
+    finish_call(call);
+  }
+
+  gpr_mu_unlock(&call->read_mu);
+
+  if (request_more) {
+    request_more_data(call);
+  }
+
+  return GRPC_CALL_OK;
+}
+
+grpc_call_error grpc_call_start_write(grpc_call *call,
+                                      grpc_byte_buffer *byte_buffer, void *tag,
+                                      gpr_uint32 flags) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  switch (call->state) {
+    case CALL_CREATED:
+      return GRPC_CALL_ERROR_NOT_INVOKED;
+    case CALL_STARTED:
+      break;
+    case CALL_FINISHED:
+      return GRPC_CALL_ERROR_ALREADY_FINISHED;
+  }
+
+  if (call->have_write) {
+    return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
+  }
+
+  grpc_cq_begin_op(call->cq, call, GRPC_WRITE_ACCEPTED);
+
+  /* for now we do no buffering, so a NULL byte_buffer can have no impact
+     on our behavior -- succeed immediately */
+  /* TODO(ctiller): if flags & GRPC_WRITE_BUFFER_HINT == 0, this indicates a
+     flush, and that flush should be propogated down from here */
+  if (byte_buffer == NULL) {
+    grpc_cq_end_write_accepted(call->cq, tag, call, NULL, NULL, GRPC_OP_OK);
+    return GRPC_CALL_OK;
+  }
+
+  call->write_tag = tag;
+  call->have_write = 1;
+
+  op.type = GRPC_SEND_MESSAGE;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = flags;
+  op.done_cb = done_write;
+  op.user_data = call;
+  op.data.message = byte_buffer;
+
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+  elem->filter->call_op(elem, &op);
+
+  return GRPC_CALL_OK;
+}
+
+grpc_call_error grpc_call_writes_done(grpc_call *call, void *tag) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  if (!call->is_client) {
+    return GRPC_CALL_ERROR_NOT_ON_SERVER;
+  }
+
+  switch (call->state) {
+    case CALL_CREATED:
+      return GRPC_CALL_ERROR_NOT_INVOKED;
+    case CALL_FINISHED:
+      return GRPC_CALL_ERROR_ALREADY_FINISHED;
+    case CALL_STARTED:
+      break;
+  }
+
+  if (call->have_write) {
+    return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
+  }
+
+  grpc_cq_begin_op(call->cq, call, GRPC_FINISH_ACCEPTED);
+
+  call->write_tag = tag;
+  call->have_write = 1;
+
+  op.type = GRPC_SEND_FINISH;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = 0;
+  op.done_cb = done_writes_done;
+  op.user_data = call;
+
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+  elem->filter->call_op(elem, &op);
+
+  return GRPC_CALL_OK;
+}
+
+grpc_call_error grpc_call_start_write_status(grpc_call *call,
+                                             grpc_status status, void *tag) {
+  grpc_call_element *elem;
+  grpc_call_op op;
+
+  if (call->is_client) {
+    return GRPC_CALL_ERROR_NOT_ON_CLIENT;
+  }
+
+  switch (call->state) {
+    case CALL_CREATED:
+      return GRPC_CALL_ERROR_NOT_INVOKED;
+    case CALL_FINISHED:
+      return GRPC_CALL_ERROR_ALREADY_FINISHED;
+    case CALL_STARTED:
+      break;
+  }
+
+  if (call->have_write) {
+    return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
+  }
+
+  elem = CALL_ELEM_FROM_CALL(call, 0);
+
+  if (status.details && status.details[0]) {
+    grpc_mdelem *md = grpc_mdelem_from_strings(call->metadata_context,
+                                               "grpc-message", status.details);
+
+    op.type = GRPC_SEND_METADATA;
+    op.dir = GRPC_CALL_DOWN;
+    op.flags = 0;
+    op.done_cb = do_nothing;
+    op.user_data = NULL;
+    op.data.metadata = md;
+    elem->filter->call_op(elem, &op);
+  }
+
+  /* always send status */
+  {
+    grpc_mdelem *md;
+    char buffer[32];
+    sprintf(buffer, "%d", status.code);
+    md =
+        grpc_mdelem_from_strings(call->metadata_context, "grpc-status", buffer);
+
+    op.type = GRPC_SEND_METADATA;
+    op.dir = GRPC_CALL_DOWN;
+    op.flags = 0;
+    op.done_cb = do_nothing;
+    op.user_data = NULL;
+    op.data.metadata = md;
+    elem->filter->call_op(elem, &op);
+  }
+
+  grpc_cq_begin_op(call->cq, call, GRPC_FINISH_ACCEPTED);
+
+  call->state = CALL_FINISHED;
+  call->write_tag = tag;
+  call->have_write = 1;
+
+  op.type = GRPC_SEND_FINISH;
+  op.dir = GRPC_CALL_DOWN;
+  op.flags = 0;
+  op.done_cb = done_writes_done;
+  op.user_data = call;
+
+  elem->filter->call_op(elem, &op);
+
+  return GRPC_CALL_OK;
+}
+
+/* we offset status by a small amount when storing it into transport metadata
+   as metadata cannot store a 0 value (which is used as OK for grpc_status_codes
+   */
+#define STATUS_OFFSET 1
+static void destroy_status(void *ignored) {}
+
+static gpr_uint32 decode_status(grpc_mdelem *md) {
+  gpr_uint32 status;
+  void *user_data = grpc_mdelem_get_user_data(md, destroy_status);
+  if (user_data) {
+    status = ((gpr_uint32)(gpr_intptr)user_data) - STATUS_OFFSET;
+  } else {
+    if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
+                                   GPR_SLICE_LENGTH(md->value->slice),
+                                   &status)) {
+      status = GRPC_STATUS_UNKNOWN; /* could not parse status code */
+    }
+    grpc_mdelem_set_user_data(md, destroy_status,
+                              (void *)(gpr_intptr)(status + STATUS_OFFSET));
+  }
+  return status;
+}
+
+void grpc_call_recv_metadata(grpc_call_element *elem, grpc_call_op *op) {
+  grpc_call *call = CALL_FROM_TOP_ELEM(elem);
+  grpc_mdelem *md = op->data.metadata;
+  grpc_mdstr *key = md->key;
+  if (key == grpc_channel_get_status_string(call->channel)) {
+    call->status_code = decode_status(md);
+    grpc_mdelem_unref(md);
+    op->done_cb(op->user_data, GRPC_OP_OK);
+  } else if (key == grpc_channel_get_message_string(call->channel)) {
+    if (call->status_details) {
+      grpc_mdstr_unref(call->status_details);
+    }
+    call->status_details = grpc_mdstr_ref(md->value);
+    grpc_mdelem_unref(md);
+    op->done_cb(op->user_data, GRPC_OP_OK);
+  } else {
+    grpc_metadata_buffer_queue(&call->incoming_metadata, op);
+  }
+}
+
+void grpc_call_recv_finish(grpc_call_element *elem, int is_full_close) {
+  grpc_call *call = CALL_FROM_TOP_ELEM(elem);
+
+  gpr_mu_lock(&call->read_mu);
+
+  if (call->have_read) {
+    grpc_cq_end_read(call->cq, call->read_tag, call, do_nothing, NULL, NULL);
+    call->read_tag = INVALID_TAG;
+    call->have_read = 0;
+  }
+  if (call->is_client && !call->received_metadata && call->cq) {
+    size_t count;
+    grpc_metadata *elements;
+
+    call->received_metadata = 1;
+
+    count = grpc_metadata_buffer_count(&call->incoming_metadata);
+    elements = grpc_metadata_buffer_extract_elements(&call->incoming_metadata);
+    grpc_cq_end_client_metadata_read(call->cq, call->metadata_tag, call,
+                                     grpc_metadata_buffer_cleanup_elements,
+                                     elements, count, elements);
+  }
+  if (is_full_close) {
+    if (call->have_alarm) {
+      void *arg_was;
+      grpc_em_alarm_cancel(&call->alarm, &arg_was);
+      call->have_alarm = 0;
+    }
+    call->received_finish = 1;
+    if (prq_is_empty(&call->prq) && call->cq != NULL) {
+      finish_call(call);
+    }
+  } else {
+    call->reads_done = 1;
+  }
+  gpr_mu_unlock(&call->read_mu);
+}
+
+void grpc_call_recv_message(grpc_call_element *elem, grpc_byte_buffer *message,
+                            void (*on_finish)(void *user_data,
+                                              grpc_op_error error),
+                            void *user_data) {
+  grpc_call *call = CALL_FROM_TOP_ELEM(elem);
+
+  gpr_mu_lock(&call->read_mu);
+  if (call->have_read) {
+    grpc_cq_end_read(call->cq, call->read_tag, call, on_finish, user_data,
+                     message);
+    call->read_tag = INVALID_TAG;
+    call->have_read = 0;
+  } else {
+    prq_push(&call->prq, message, on_finish, user_data);
+  }
+  gpr_mu_unlock(&call->read_mu);
+}
+
+grpc_call *grpc_call_from_top_element(grpc_call_element *elem) {
+  return CALL_FROM_TOP_ELEM(elem);
+}
+
+grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call) {
+  return &call->incoming_metadata;
+}
+
+static void call_alarm(void *arg, grpc_em_cb_status status) {
+  grpc_call *call = arg;
+  if (status == GRPC_CALLBACK_SUCCESS) {
+    grpc_call_cancel(call);
+  }
+  grpc_call_internal_unref(call);
+}
+
+void grpc_call_set_deadline(grpc_call_element *elem, gpr_timespec deadline) {
+  grpc_call *call = CALL_FROM_TOP_ELEM(elem);
+
+  if (call->have_alarm) {
+    gpr_log(GPR_ERROR, "Attempt to set deadline alarm twice");
+  }
+  grpc_call_internal_ref(call);
+  call->have_alarm = 1;
+  grpc_em_alarm_init(&call->alarm, grpc_surface_em(), call_alarm, call);
+  grpc_em_alarm_add(&call->alarm, deadline);
+}
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
new file mode 100644
index 0000000..2c785a5
--- /dev/null
+++ b/src/core/surface/call.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_CALL_H__
+#define __GRPC_INTERNAL_SURFACE_CALL_H__
+
+#include "src/core/channel/channel_stack.h"
+#include "src/core/channel/metadata_buffer.h"
+#include <grpc/grpc.h>
+
+grpc_call *grpc_call_create(grpc_channel *channel,
+                            const void *server_transport_data);
+
+void grpc_call_internal_ref(grpc_call *call);
+void grpc_call_internal_unref(grpc_call *call);
+
+/* Helpers for grpc_client, grpc_server filters to publish received data to
+   the completion queue/surface layer */
+void grpc_call_recv_metadata(grpc_call_element *surface_element,
+                             grpc_call_op *op);
+void grpc_call_recv_message(
+    grpc_call_element *surface_element, grpc_byte_buffer *message,
+    void (*on_finish)(void *user_data, grpc_op_error error), void *user_data);
+void grpc_call_recv_finish(grpc_call_element *surface_element,
+                           int is_full_close);
+
+void grpc_call_execute_op(grpc_call *call, grpc_call_op *op);
+
+/* Called when it's known that the initial batch of metadata is complete on the
+   client side (must not be called on the server) */
+void grpc_call_client_initial_metadata_complete(
+    grpc_call_element *surface_element);
+
+void grpc_call_set_deadline(grpc_call_element *surface_element,
+                            gpr_timespec deadline);
+
+/* Given the top call_element, get the call object. */
+grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element);
+
+/* Get the metadata buffer. */
+grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call);
+
+#endif  /* __GRPC_INTERNAL_SURFACE_CALL_H__ */
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
new file mode 100644
index 0000000..ff99425
--- /dev/null
+++ b/src/core/surface/channel.c
@@ -0,0 +1,152 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/channel.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "src/core/surface/call.h"
+#include "src/core/surface/client.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+struct grpc_channel {
+  int is_client;
+  gpr_refcount refs;
+  grpc_mdctx *metadata_context;
+  grpc_mdstr *grpc_status_string;
+  grpc_mdstr *grpc_message_string;
+};
+
+#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1))
+
+grpc_channel *grpc_channel_create_from_filters(
+    const grpc_channel_filter **filters, size_t num_filters,
+    const grpc_channel_args *args, grpc_mdctx *mdctx, int is_client) {
+  size_t size =
+      sizeof(grpc_channel) + grpc_channel_stack_size(filters, num_filters);
+  grpc_channel *channel = gpr_malloc(size);
+  channel->is_client = is_client;
+  /* decremented by grpc_channel_destroy */
+  gpr_ref_init(&channel->refs, 1);
+  channel->metadata_context = mdctx;
+  channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status");
+  channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message");
+  grpc_channel_stack_init(filters, num_filters, args, channel->metadata_context,
+                          CHANNEL_STACK_FROM_CHANNEL(channel));
+  return channel;
+}
+
+static void do_nothing(void *ignored, grpc_op_error error) {}
+
+grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method,
+                                    const char *host,
+                                    gpr_timespec absolute_deadline) {
+  grpc_call *call;
+  grpc_metadata md;
+
+  if (!channel->is_client) {
+    gpr_log(GPR_ERROR, "Cannot create a call on the server.");
+    return NULL;
+  }
+
+  call = grpc_call_create(channel, NULL);
+
+#define ADDMD(k, v)                       \
+  do {                                    \
+    md.key = (k);                         \
+    md.value = (char *)(v);               \
+    md.value_length = strlen((v));        \
+    grpc_call_add_metadata(call, &md, 0); \
+  } while (0)
+  ADDMD(":method", "POST");
+  ADDMD(":scheme", "grpc");
+  ADDMD(":path", method);
+  ADDMD(":authority", host);
+  ADDMD("content-type", "application/grpc");
+  if (0 != gpr_time_cmp(absolute_deadline, gpr_inf_future)) {
+    grpc_call_op op;
+    op.type = GRPC_SEND_DEADLINE;
+    op.dir = GRPC_CALL_DOWN;
+    op.flags = 0;
+    op.data.deadline = absolute_deadline;
+    op.done_cb = do_nothing;
+    op.user_data = NULL;
+    grpc_call_execute_op(call, &op);
+  }
+
+  return call;
+}
+
+void grpc_channel_internal_ref(grpc_channel *channel) {
+  gpr_ref(&channel->refs);
+}
+
+void grpc_channel_internal_unref(grpc_channel *channel) {
+  if (gpr_unref(&channel->refs)) {
+    grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
+    grpc_mdstr_unref(channel->grpc_status_string);
+    grpc_mdstr_unref(channel->grpc_message_string);
+    grpc_mdctx_orphan(channel->metadata_context);
+    gpr_free(channel);
+  }
+}
+
+void grpc_channel_destroy(grpc_channel *channel) {
+  grpc_channel_op op;
+  grpc_channel_element *elem;
+
+  op.type = GRPC_CHANNEL_SHUTDOWN;
+  op.dir = GRPC_CALL_DOWN;
+  elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0);
+  elem->filter->channel_op(elem, &op);
+
+  grpc_channel_internal_unref(channel);
+}
+
+grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel) {
+  return CHANNEL_STACK_FROM_CHANNEL(channel);
+}
+
+grpc_mdctx *grpc_channel_get_metadata_context(grpc_channel *channel) {
+  return channel->metadata_context;
+}
+
+grpc_mdstr *grpc_channel_get_status_string(grpc_channel *channel) {
+  return channel->grpc_status_string;
+}
+
+grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel) {
+  return channel->grpc_message_string;
+}
diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h
new file mode 100644
index 0000000..11d4939
--- /dev/null
+++ b/src/core/surface/channel.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_CHANNEL_H__
+#define __GRPC_INTERNAL_SURFACE_CHANNEL_H__
+
+#include "src/core/channel/channel_stack.h"
+
+grpc_channel *grpc_channel_create_from_filters(
+    const grpc_channel_filter **filters, size_t count,
+    const grpc_channel_args *args, grpc_mdctx *mdctx, int is_client);
+
+grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
+grpc_mdctx *grpc_channel_get_metadata_context(grpc_channel *channel);
+grpc_mdstr *grpc_channel_get_status_string(grpc_channel *channel);
+grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel);
+
+void grpc_channel_internal_ref(grpc_channel *channel);
+void grpc_channel_internal_unref(grpc_channel *channel);
+
+#endif  /* __GRPC_INTERNAL_SURFACE_CHANNEL_H__ */
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
new file mode 100644
index 0000000..ec1c847
--- /dev/null
+++ b/src/core/surface/channel_create.c
@@ -0,0 +1,213 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "src/core/channel/census_filter.h"
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/client_setup.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_client_filter.h"
+#include "src/core/channel/http_filter.h"
+#include "src/core/endpoint/resolve_address.h"
+#include "src/core/endpoint/tcp.h"
+#include "src/core/endpoint/tcp_client.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/client.h"
+#include "src/core/surface/surface_em.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+
+typedef struct setup setup;
+
+/* A single setup request (started via initiate) */
+typedef struct {
+  grpc_client_setup_request *cs_request;
+  setup *setup;
+  /* Resolved addresses, or null if resolution not yet completed */
+  grpc_resolved_addresses *resolved;
+  /* which address in resolved should we pick for the next connection attempt */
+  size_t resolved_index;
+} request;
+
+/* Global setup logic (may be running many simultaneous setup requests, but
+   with only one 'active' */
+struct setup {
+  const char *target;
+  grpc_transport_setup_callback setup_callback;
+  void *setup_user_data;
+  grpc_em *em;
+};
+
+static int maybe_try_next_resolved(request *r);
+
+static void done(request *r, int was_successful) {
+  grpc_client_setup_request_finish(r->cs_request, was_successful);
+  if (r->resolved) {
+    grpc_resolved_addresses_destroy(r->resolved);
+  }
+  gpr_free(r);
+}
+
+/* connection callback: tcp is either valid, or null on error */
+static void on_connect(void *rp, grpc_endpoint *tcp) {
+  request *r = rp;
+
+  if (!grpc_client_setup_request_should_continue(r->cs_request)) {
+    if (tcp) {
+      grpc_endpoint_shutdown(tcp);
+      grpc_endpoint_destroy(tcp);
+    }
+    done(r, 0);
+    return;
+  }
+
+  if (!tcp) {
+    if (!maybe_try_next_resolved(r)) {
+      done(r, 0);
+      return;
+    } else {
+      return;
+    }
+  } else {
+    grpc_create_chttp2_transport(
+        r->setup->setup_callback, r->setup->setup_user_data,
+        grpc_client_setup_get_channel_args(r->cs_request), tcp, NULL, 0,
+        grpc_client_setup_get_mdctx(r->cs_request), 1);
+    done(r, 1);
+    return;
+  }
+}
+
+/* attempt to connect to the next available resolved address */
+static int maybe_try_next_resolved(request *r) {
+  grpc_resolved_address *addr;
+  if (!r->resolved) return 0;
+  if (r->resolved_index == r->resolved->naddrs) return 0;
+  addr = &r->resolved->addrs[r->resolved_index++];
+  grpc_tcp_client_connect(on_connect, r, r->setup->em,
+                          (struct sockaddr *)&addr->addr, addr->len,
+                          grpc_client_setup_request_deadline(r->cs_request));
+  return 1;
+}
+
+/* callback for when our target address has been resolved */
+static void on_resolved(void *rp, grpc_resolved_addresses *resolved) {
+  request *r = rp;
+
+  /* if we're not still the active request, abort */
+  if (!grpc_client_setup_request_should_continue(r->cs_request)) {
+    if (resolved) {
+      grpc_resolved_addresses_destroy(resolved);
+    }
+    done(r, 0);
+    return;
+  }
+
+  if (!resolved) {
+    done(r, 0);
+    return;
+  } else {
+    r->resolved = resolved;
+    r->resolved_index = 0;
+    if (!maybe_try_next_resolved(r)) {
+      done(r, 0);
+    }
+  }
+}
+
+static void initiate_setup(void *sp, grpc_client_setup_request *cs_request) {
+  request *r = gpr_malloc(sizeof(request));
+  r->setup = sp;
+  r->cs_request = cs_request;
+  r->resolved = NULL;
+  r->resolved_index = 0;
+  /* TODO(klempner): Make grpc_resolve_address respect deadline */
+  grpc_resolve_address(r->setup->target, "http", on_resolved, r);
+}
+
+static void done_setup(void *sp) {
+  setup *s = sp;
+  gpr_free((void *)s->target);
+  gpr_free(s);
+}
+
+static grpc_transport_setup_result complete_setup(void *channel_stack,
+                                                  grpc_transport *transport,
+                                                  grpc_mdctx *mdctx) {
+  static grpc_channel_filter const *extra_filters[] = {&grpc_http_client_filter,
+                                                       &grpc_http_filter};
+  return grpc_client_channel_transport_setup_complete(
+      channel_stack, transport, extra_filters, GPR_ARRAY_SIZE(extra_filters),
+      mdctx);
+}
+
+/* Create a client channel:
+   Asynchronously: - resolve target
+                   - connect to it (trying alternatives as presented)
+                   - perform handshakes */
+grpc_channel *grpc_channel_create(const char *target,
+                                  const grpc_channel_args *args) {
+  setup *s = gpr_malloc(sizeof(setup));
+  grpc_mdctx *mdctx = grpc_mdctx_create();
+  grpc_channel *channel = NULL;
+#define MAX_FILTERS 3
+  const grpc_channel_filter *filters[MAX_FILTERS];
+  int n = 0;
+  filters[n++] = &grpc_client_surface_filter;
+  if (grpc_channel_args_is_census_enabled(args)) {
+    filters[n++] = &grpc_client_census_filter;
+  }
+  filters[n++] = &grpc_client_channel_filter;
+  GPR_ASSERT(n <= MAX_FILTERS);
+  channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1);
+
+  s->target = gpr_strdup(target);
+  s->em = grpc_surface_em();
+  s->setup_callback = complete_setup;
+  s->setup_user_data = grpc_channel_get_channel_stack(channel);
+
+  grpc_client_setup_create_and_attach(grpc_channel_get_channel_stack(channel),
+                                      args, mdctx, initiate_setup, done_setup,
+                                      s, s->em);
+
+  return channel;
+}
diff --git a/src/core/surface/client.c b/src/core/surface/client.c
new file mode 100644
index 0000000..26abffa
--- /dev/null
+++ b/src/core/surface/client.c
@@ -0,0 +1,115 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/client.h"
+
+#include "src/core/surface/call.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+
+typedef struct { void *unused; } call_data;
+
+typedef struct { void *unused; } channel_data;
+
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+  switch (op->type) {
+    case GRPC_SEND_DEADLINE:
+      grpc_call_set_deadline(elem, op->data.deadline);
+      grpc_call_next_op(elem, op);
+      break;
+    case GRPC_RECV_METADATA:
+      grpc_call_recv_metadata(elem, op);
+      break;
+    case GRPC_RECV_DEADLINE:
+      gpr_log(GPR_ERROR, "Deadline received by client (ignored)");
+      break;
+    case GRPC_RECV_MESSAGE:
+      grpc_call_recv_message(elem, op->data.message, op->done_cb,
+                             op->user_data);
+      break;
+    case GRPC_RECV_HALF_CLOSE:
+      grpc_call_recv_finish(elem, 0);
+      break;
+    case GRPC_RECV_FINISH:
+      grpc_call_recv_finish(elem, 1);
+      break;
+    case GRPC_RECV_END_OF_INITIAL_METADATA:
+      grpc_call_client_initial_metadata_complete(elem);
+      break;
+    default:
+      GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
+      grpc_call_next_op(elem, op);
+  }
+}
+
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  switch (op->type) {
+    case GRPC_ACCEPT_CALL:
+      gpr_log(GPR_ERROR, "Client cannot accept new calls");
+      break;
+    case GRPC_TRANSPORT_CLOSED:
+      gpr_log(GPR_ERROR, "Transport closed");
+      break;
+    default:
+      GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
+      grpc_channel_next_op(elem, op);
+  }
+}
+
+static void init_call_elem(grpc_call_element *elem,
+                           const void *transport_server_data) {}
+
+static void destroy_call_elem(grpc_call_element *elem) {}
+
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args, grpc_mdctx *mdctx,
+                              int is_first, int is_last) {
+  GPR_ASSERT(is_first);
+  GPR_ASSERT(!is_last);
+}
+
+static void destroy_channel_elem(grpc_channel_element *elem) {
+}
+
+const grpc_channel_filter grpc_client_surface_filter = {
+    call_op,              channel_op,
+
+    sizeof(call_data),    init_call_elem,    destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "client",
+};
diff --git a/src/core/surface/client.h b/src/core/surface/client.h
new file mode 100644
index 0000000..eb56727
--- /dev/null
+++ b/src/core/surface/client.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_CLIENT_H__
+#define __GRPC_INTERNAL_SURFACE_CLIENT_H__
+
+#include "src/core/channel/channel_stack.h"
+
+extern const grpc_channel_filter grpc_client_surface_filter;
+
+#endif  /* __GRPC_INTERNAL_SURFACE_CLIENT_H__ */
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
new file mode 100644
index 0000000..a7d6115
--- /dev/null
+++ b/src/core/surface/completion_queue.c
@@ -0,0 +1,392 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/completion_queue.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "src/core/eventmanager/em.h"
+#include "src/core/surface/call.h"
+#include "src/core/surface/event_string.h"
+#include "src/core/surface/surface_em.h"
+#include "src/core/surface/surface_trace.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+
+#define NUM_TAG_BUCKETS 31
+
+/* A single event: extends grpc_event to form a linked list with a destruction
+   function (on_finish) that is hidden from outside this module */
+typedef struct event {
+  grpc_event base;
+  grpc_event_finish_func on_finish;
+  void *on_finish_user_data;
+  struct event *queue_next;
+  struct event *queue_prev;
+  struct event *bucket_next;
+  struct event *bucket_prev;
+} event;
+
+/* Completion queue structure */
+struct grpc_completion_queue {
+  grpc_em *em;
+  int allow_polling;
+
+  /* When refs drops to zero, we are in shutdown mode, and will be destroyable
+     once all queued events are drained */
+  gpr_refcount refs;
+  /* 0 initially, 1 once we've begun shutting down */
+  int shutdown;
+  /* Head of a linked list of queued events (prev points to the last element) */
+  event *queue;
+  /* Fixed size chained hash table of events for pluck() */
+  event *buckets[NUM_TAG_BUCKETS];
+
+#ifndef NDEBUG
+  /* Debug support: track which operations are in flight at any given time */
+  gpr_atm pending_op_count[GRPC_COMPLETION_DO_NOT_USE];
+#endif
+};
+
+/* Default do-nothing on_finish function */
+static void null_on_finish(void *user_data, grpc_op_error error) {}
+
+grpc_completion_queue *grpc_completion_queue_create() {
+  grpc_completion_queue *cc = gpr_malloc(sizeof(grpc_completion_queue));
+  memset(cc, 0, sizeof(*cc));
+  /* Initial ref is dropped by grpc_completion_queue_shutdown */
+  gpr_ref_init(&cc->refs, 1);
+  cc->em = grpc_surface_em();
+  cc->allow_polling = 1;
+  return cc;
+}
+
+void grpc_completion_queue_dont_poll_test_only(grpc_completion_queue *cc) {
+  cc->allow_polling = 0;
+}
+
+/* Create and append an event to the queue. Returns the event so that its data
+   members can be filled in.
+   Requires cc->em->mu locked. */
+static event *add_locked(grpc_completion_queue *cc, grpc_completion_type type,
+                         void *tag, grpc_call *call,
+                         grpc_event_finish_func on_finish, void *user_data) {
+  event *ev = gpr_malloc(sizeof(event));
+  gpr_intptr bucket = ((gpr_intptr)tag) % NUM_TAG_BUCKETS;
+  GPR_ASSERT(!cc->shutdown);
+  ev->base.type = type;
+  ev->base.tag = tag;
+  ev->base.call = call;
+  ev->on_finish = on_finish ? on_finish : null_on_finish;
+  ev->on_finish_user_data = user_data;
+  if (cc->queue == NULL) {
+    cc->queue = ev->queue_next = ev->queue_prev = ev;
+  } else {
+    ev->queue_next = cc->queue;
+    ev->queue_prev = cc->queue->queue_prev;
+    ev->queue_next->queue_prev = ev->queue_prev->queue_next = ev;
+  }
+  if (cc->buckets[bucket] == NULL) {
+    cc->buckets[bucket] = ev->bucket_next = ev->bucket_prev = ev;
+  } else {
+    ev->bucket_next = cc->buckets[bucket];
+    ev->bucket_prev = cc->buckets[bucket]->bucket_prev;
+    ev->bucket_next->bucket_prev = ev->bucket_prev->bucket_next = ev;
+  }
+  gpr_cv_broadcast(&cc->em->cv);
+  return ev;
+}
+
+void grpc_cq_begin_op(grpc_completion_queue *cc, grpc_call *call,
+                      grpc_completion_type type) {
+  gpr_ref(&cc->refs);
+  if (call) grpc_call_internal_ref(call);
+#ifndef NDEBUG
+  gpr_atm_no_barrier_fetch_add(&cc->pending_op_count[type], 1);
+#endif
+}
+
+/* Signal the end of an operation - if this is the last waiting-to-be-queued
+   event, then enter shutdown mode */
+static void end_op_locked(grpc_completion_queue *cc,
+                          grpc_completion_type type) {
+#ifndef NDEBUG
+  GPR_ASSERT(gpr_atm_full_fetch_add(&cc->pending_op_count[type], -1) > 0);
+#endif
+  if (gpr_unref(&cc->refs)) {
+    GPR_ASSERT(!cc->shutdown);
+    cc->shutdown = 1;
+    gpr_cv_broadcast(&cc->em->cv);
+  }
+}
+
+void grpc_cq_end_read(grpc_completion_queue *cc, void *tag, grpc_call *call,
+                      grpc_event_finish_func on_finish, void *user_data,
+                      grpc_byte_buffer *read) {
+  event *ev;
+  gpr_mu_lock(&cc->em->mu);
+  ev = add_locked(cc, GRPC_READ, tag, call, on_finish, user_data);
+  ev->base.data.read = read;
+  end_op_locked(cc, GRPC_READ);
+  gpr_mu_unlock(&cc->em->mu);
+}
+
+void grpc_cq_end_invoke_accepted(grpc_completion_queue *cc, void *tag,
+                                 grpc_call *call,
+                                 grpc_event_finish_func on_finish,
+                                 void *user_data, grpc_op_error error) {
+  event *ev;
+  gpr_mu_lock(&cc->em->mu);
+  ev = add_locked(cc, GRPC_INVOKE_ACCEPTED, tag, call, on_finish, user_data);
+  ev->base.data.invoke_accepted = error;
+  end_op_locked(cc, GRPC_INVOKE_ACCEPTED);
+  gpr_mu_unlock(&cc->em->mu);
+}
+
+void grpc_cq_end_write_accepted(grpc_completion_queue *cc, void *tag,
+                                grpc_call *call,
+                                grpc_event_finish_func on_finish,
+                                void *user_data, grpc_op_error error) {
+  event *ev;
+  gpr_mu_lock(&cc->em->mu);
+  ev = add_locked(cc, GRPC_WRITE_ACCEPTED, tag, call, on_finish, user_data);
+  ev->base.data.write_accepted = error;
+  end_op_locked(cc, GRPC_WRITE_ACCEPTED);
+  gpr_mu_unlock(&cc->em->mu);
+}
+
+void grpc_cq_end_finish_accepted(grpc_completion_queue *cc, void *tag,
+                                 grpc_call *call,
+                                 grpc_event_finish_func on_finish,
+                                 void *user_data, grpc_op_error error) {
+  event *ev;
+  gpr_mu_lock(&cc->em->mu);
+  ev = add_locked(cc, GRPC_FINISH_ACCEPTED, tag, call, on_finish, user_data);
+  ev->base.data.finish_accepted = error;
+  end_op_locked(cc, GRPC_FINISH_ACCEPTED);
+  gpr_mu_unlock(&cc->em->mu);
+}
+
+void grpc_cq_end_client_metadata_read(grpc_completion_queue *cc, void *tag,
+                                      grpc_call *call,
+                                      grpc_event_finish_func on_finish,
+                                      void *user_data, size_t count,
+                                      grpc_metadata *elements) {
+  event *ev;
+  gpr_mu_lock(&cc->em->mu);
+  ev = add_locked(cc, GRPC_CLIENT_METADATA_READ, tag, call, on_finish,
+                  user_data);
+  ev->base.data.client_metadata_read.count = count;
+  ev->base.data.client_metadata_read.elements = elements;
+  end_op_locked(cc, GRPC_CLIENT_METADATA_READ);
+  gpr_mu_unlock(&cc->em->mu);
+}
+
+void grpc_cq_end_finished(grpc_completion_queue *cc, void *tag, grpc_call *call,
+                          grpc_event_finish_func on_finish, void *user_data,
+                          grpc_status status) {
+  event *ev;
+  gpr_mu_lock(&cc->em->mu);
+  ev = add_locked(cc, GRPC_FINISHED, tag, call, on_finish, user_data);
+  ev->base.data.finished = status;
+  end_op_locked(cc, GRPC_FINISHED);
+  gpr_mu_unlock(&cc->em->mu);
+}
+
+void grpc_cq_end_new_rpc(grpc_completion_queue *cc, void *tag, grpc_call *call,
+                         grpc_event_finish_func on_finish, void *user_data,
+                         const char *method, const char *host,
+                         gpr_timespec deadline, size_t metadata_count,
+                         grpc_metadata *metadata_elements) {
+  event *ev;
+  gpr_mu_lock(&cc->em->mu);
+  ev = add_locked(cc, GRPC_SERVER_RPC_NEW, tag, call, on_finish, user_data);
+  ev->base.data.server_rpc_new.method = method;
+  ev->base.data.server_rpc_new.host = host;
+  ev->base.data.server_rpc_new.deadline = deadline;
+  ev->base.data.server_rpc_new.metadata_count = metadata_count;
+  ev->base.data.server_rpc_new.metadata_elements = metadata_elements;
+  end_op_locked(cc, GRPC_SERVER_RPC_NEW);
+  gpr_mu_unlock(&cc->em->mu);
+}
+
+/* Create a GRPC_QUEUE_SHUTDOWN event without queuing it anywhere */
+static event *create_shutdown_event() {
+  event *ev = gpr_malloc(sizeof(event));
+  ev->base.type = GRPC_QUEUE_SHUTDOWN;
+  ev->base.call = NULL;
+  ev->base.tag = NULL;
+  ev->on_finish = null_on_finish;
+  return ev;
+}
+
+grpc_event *grpc_completion_queue_next(grpc_completion_queue *cc,
+                                       gpr_timespec deadline) {
+  event *ev = NULL;
+
+  gpr_mu_lock(&cc->em->mu);
+  for (;;) {
+    if (cc->queue != NULL) {
+      gpr_intptr bucket;
+      ev = cc->queue;
+      bucket = ((gpr_intptr)ev->base.tag) % NUM_TAG_BUCKETS;
+      cc->queue = ev->queue_next;
+      ev->queue_next->queue_prev = ev->queue_prev;
+      ev->queue_prev->queue_next = ev->queue_next;
+      ev->bucket_next->bucket_prev = ev->bucket_prev;
+      ev->bucket_prev->bucket_next = ev->bucket_next;
+      if (ev == cc->buckets[bucket]) {
+        cc->buckets[bucket] = ev->bucket_next;
+        if (ev == cc->buckets[bucket]) {
+          cc->buckets[bucket] = NULL;
+        }
+      }
+      if (cc->queue == ev) {
+        cc->queue = NULL;
+      }
+      break;
+    }
+    if (cc->shutdown) {
+      ev = create_shutdown_event();
+      break;
+    }
+    if (cc->allow_polling && grpc_em_work(cc->em, deadline)) {
+      continue;
+    }
+    if (gpr_cv_wait(&cc->em->cv, &cc->em->mu, deadline)) {
+      gpr_mu_unlock(&cc->em->mu);
+      return NULL;
+    }
+  }
+  gpr_mu_unlock(&cc->em->mu);
+  GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ev->base);
+  return &ev->base;
+}
+
+static event *pluck_event(grpc_completion_queue *cc, void *tag) {
+  gpr_intptr bucket = ((gpr_intptr)tag) % NUM_TAG_BUCKETS;
+  event *ev = cc->buckets[bucket];
+  if (ev == NULL) return NULL;
+  do {
+    if (ev->base.tag == tag) {
+      ev->queue_next->queue_prev = ev->queue_prev;
+      ev->queue_prev->queue_next = ev->queue_next;
+      ev->bucket_next->bucket_prev = ev->bucket_prev;
+      ev->bucket_prev->bucket_next = ev->bucket_next;
+      if (ev == cc->buckets[bucket]) {
+        cc->buckets[bucket] = ev->bucket_next;
+        if (ev == cc->buckets[bucket]) {
+          cc->buckets[bucket] = NULL;
+        }
+      }
+      if (cc->queue == ev) {
+        cc->queue = ev->queue_next;
+        if (cc->queue == ev) {
+          cc->queue = NULL;
+        }
+      }
+      return ev;
+    }
+    ev = ev->bucket_next;
+  } while (ev != cc->buckets[bucket]);
+  return NULL;
+}
+
+grpc_event *grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
+                                        gpr_timespec deadline) {
+  event *ev = NULL;
+
+  gpr_mu_lock(&cc->em->mu);
+  for (;;) {
+    if ((ev = pluck_event(cc, tag))) {
+      break;
+    }
+    if (cc->shutdown) {
+      ev = create_shutdown_event();
+      break;
+    }
+    if (cc->allow_polling && grpc_em_work(cc->em, deadline)) {
+      continue;
+    }
+    if (gpr_cv_wait(&cc->em->cv, &cc->em->mu, deadline)) {
+      gpr_mu_unlock(&cc->em->mu);
+      return NULL;
+    }
+  }
+  gpr_mu_unlock(&cc->em->mu);
+  GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ev->base);
+  return &ev->base;
+}
+
+/* Shutdown simply drops a ref that we reserved at creation time; if we drop
+   to zero here, then enter shutdown mode and wake up any waiters */
+void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
+  if (gpr_unref(&cc->refs)) {
+    gpr_mu_lock(&cc->em->mu);
+    GPR_ASSERT(!cc->shutdown);
+    cc->shutdown = 1;
+    gpr_cv_broadcast(&cc->em->cv);
+    gpr_mu_unlock(&cc->em->mu);
+  }
+}
+
+void grpc_completion_queue_destroy(grpc_completion_queue *cc) {
+  GPR_ASSERT(cc->queue == NULL);
+  gpr_free(cc);
+}
+
+void grpc_event_finish(grpc_event *base) {
+  event *ev = (event *)base;
+  ev->on_finish(ev->on_finish_user_data, GRPC_OP_OK);
+  if (ev->base.call) {
+    grpc_call_internal_unref(ev->base.call);
+  }
+  gpr_free(ev);
+}
+
+void grpc_cq_dump_pending_ops(grpc_completion_queue *cc) {
+#ifndef NDEBUG
+  char tmp[256];
+  char *p = tmp;
+  int i;
+
+  for (i = 0; i < GRPC_COMPLETION_DO_NOT_USE; i++) {
+    p += sprintf(p, " %d", (int)cc->pending_op_count[i]);
+  }
+
+  gpr_log(GPR_INFO, "pending ops:%s", tmp);
+#endif
+}
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
new file mode 100644
index 0000000..0fe5765
--- /dev/null
+++ b/src/core/surface/completion_queue.h
@@ -0,0 +1,102 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__
+#define __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__
+
+/* Internal API for completion channels */
+
+#include <grpc/grpc.h>
+
+/* A finish func is executed whenever the event consumer calls
+   grpc_event_finish */
+typedef void (*grpc_event_finish_func)(void *user_data, grpc_op_error error);
+
+/* Flag that an operation is beginning: the completion channel will not finish
+   shutdown until a corrensponding grpc_cq_end_* call is made */
+void grpc_cq_begin_op(grpc_completion_queue *cc, grpc_call *call,
+                      grpc_completion_type type);
+
+/* grpc_cq_end_* functions pair with a grpc_cq_begin_op
+
+   grpc_cq_end_* common arguments:
+   cc        - the completion channel to queue on
+   tag       - the user supplied operation tag
+   on_finish - grpc_event_finish_func that is called during grpc_event_finish
+               can be NULL to not get a callback
+   user_data - user_data parameter to be passed to on_finish
+
+   Other parameters match the data member of grpc_event */
+
+/* Queue a GRPC_READ operation */
+void grpc_cq_end_read(grpc_completion_queue *cc, void *tag, grpc_call *call,
+                      grpc_event_finish_func on_finish, void *user_data,
+                      grpc_byte_buffer *read);
+/* Queue a GRPC_INVOKE_ACCEPTED operation */
+void grpc_cq_end_invoke_accepted(grpc_completion_queue *cc, void *tag,
+                                 grpc_call *call,
+                                 grpc_event_finish_func on_finish,
+                                 void *user_data, grpc_op_error error);
+/* Queue a GRPC_WRITE_ACCEPTED operation */
+void grpc_cq_end_write_accepted(grpc_completion_queue *cc, void *tag,
+                                grpc_call *call,
+                                grpc_event_finish_func on_finish,
+                                void *user_data, grpc_op_error error);
+/* Queue a GRPC_FINISH_ACCEPTED operation */
+void grpc_cq_end_finish_accepted(grpc_completion_queue *cc, void *tag,
+                                 grpc_call *call,
+                                 grpc_event_finish_func on_finish,
+                                 void *user_data, grpc_op_error error);
+/* Queue a GRPC_CLIENT_METADATA_READ operation */
+void grpc_cq_end_client_metadata_read(grpc_completion_queue *cc, void *tag,
+                                      grpc_call *call,
+                                      grpc_event_finish_func on_finish,
+                                      void *user_data, size_t count,
+                                      grpc_metadata *elements);
+
+void grpc_cq_end_finished(grpc_completion_queue *cc, void *tag, grpc_call *call,
+                          grpc_event_finish_func on_finish, void *user_data,
+                          grpc_status status);
+
+void grpc_cq_end_new_rpc(grpc_completion_queue *cc, void *tag, grpc_call *call,
+                         grpc_event_finish_func on_finish, void *user_data,
+                         const char *method, const char *host,
+                         gpr_timespec deadline, size_t metadata_count,
+                         grpc_metadata *metadata_elements);
+
+/* disable polling for some tests */
+void grpc_completion_queue_dont_poll_test_only(grpc_completion_queue *cc);
+
+void grpc_cq_dump_pending_ops(grpc_completion_queue *cc);
+
+#endif  /* __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__ */
diff --git a/src/core/surface/event_string.c b/src/core/surface/event_string.c
new file mode 100644
index 0000000..0a6a81d
--- /dev/null
+++ b/src/core/surface/event_string.c
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/event_string.h"
+
+#include <stdio.h>
+
+#include <grpc/support/string.h>
+#include <grpc/byte_buffer.h>
+
+static size_t addhdr(char *p, grpc_event *ev) {
+  return sprintf(p, "tag:%p call:%p", ev->tag, (void *)ev->call);
+}
+
+static const char *errstr(grpc_op_error err) {
+  switch (err) {
+    case GRPC_OP_OK:
+      return "OK";
+    case GRPC_OP_ERROR:
+      return "ERROR";
+  }
+  return "UNKNOWN_UNKNOWN";
+}
+
+static size_t adderr(char *p, grpc_op_error err) {
+  return sprintf(p, " err=%s", errstr(err));
+}
+
+char *grpc_event_string(grpc_event *ev) {
+  char buffer[1024];
+  char *p = buffer;
+
+  if (ev == NULL) return gpr_strdup("null");
+
+  switch (ev->type) {
+    case GRPC_QUEUE_SHUTDOWN:
+      p += sprintf(p, "QUEUE_SHUTDOWN");
+      break;
+    case GRPC_READ:
+      p += sprintf(p, "READ: ");
+      p += addhdr(p, ev);
+      if (ev->data.read) {
+        p += sprintf(p, " %d bytes",
+                     (int)grpc_byte_buffer_length(ev->data.read));
+      } else {
+        p += sprintf(p, " end-of-stream");
+      }
+      break;
+    case GRPC_INVOKE_ACCEPTED:
+      p += sprintf(p, "INVOKE_ACCEPTED: ");
+      p += addhdr(p, ev);
+      p += adderr(p, ev->data.invoke_accepted);
+      break;
+    case GRPC_WRITE_ACCEPTED:
+      p += sprintf(p, "WRITE_ACCEPTED: ");
+      p += addhdr(p, ev);
+      p += adderr(p, ev->data.write_accepted);
+      break;
+    case GRPC_FINISH_ACCEPTED:
+      p += sprintf(p, "FINISH_ACCEPTED: ");
+      p += addhdr(p, ev);
+      p += adderr(p, ev->data.write_accepted);
+      break;
+    case GRPC_CLIENT_METADATA_READ:
+      p += sprintf(p, "CLIENT_METADATA_READ: ");
+      p += addhdr(p, ev);
+      p += sprintf(p, " %d elements", (int)ev->data.client_metadata_read.count);
+      break;
+    case GRPC_FINISHED:
+      p += sprintf(p, "FINISHED: ");
+      p += addhdr(p, ev);
+      p += sprintf(p, " status_code=%d details='%s'", ev->data.finished.code,
+                   ev->data.finished.details);
+      break;
+    case GRPC_SERVER_RPC_NEW:
+      p += sprintf(p, "SERVER_RPC_NEW: ");
+      p += addhdr(p, ev);
+      p += sprintf(p, " method='%s' host='%s' %d metadata elements",
+                   ev->data.server_rpc_new.method, ev->data.server_rpc_new.host,
+                   (int)ev->data.server_rpc_new.metadata_count);
+      break;
+    case GRPC_COMPLETION_DO_NOT_USE:
+      p += sprintf(p, "DO_NOT_USE (this is a bug)");
+      p += addhdr(p, ev);
+      break;
+  }
+
+  return gpr_strdup(buffer);
+}
diff --git a/src/core/surface/event_string.h b/src/core/surface/event_string.h
new file mode 100644
index 0000000..30b693e
--- /dev/null
+++ b/src/core/surface/event_string.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__
+#define __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__
+
+#include <grpc/grpc.h>
+
+/* Returns a string describing an event. Must be later freed with gpr_free() */
+char *grpc_event_string(grpc_event *ev);
+
+#endif  /* __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__ */
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
new file mode 100644
index 0000000..92c0ac8
--- /dev/null
+++ b/src/core/surface/init.c
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include "src/core/statistics/census_interface.h"
+#include "src/core/surface/surface_em.h"
+
+void grpc_init() {
+  grpc_surface_em_init();
+  census_init();
+}
+
+void grpc_shutdown() {
+  grpc_surface_em_shutdown();
+  census_shutdown();
+}
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
new file mode 100644
index 0000000..18921c4
--- /dev/null
+++ b/src/core/surface/lame_client.c
@@ -0,0 +1,94 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/lame_client.h"
+
+#include "src/core/channel/channel_stack.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/call.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+
+typedef struct { void *unused; } call_data;
+
+typedef struct { void *unused; } channel_data;
+
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+
+  switch (op->type) {
+    case GRPC_SEND_START:
+      grpc_call_recv_finish(elem, 1);
+      break;
+    case GRPC_SEND_METADATA:
+      grpc_mdelem_unref(op->data.metadata);
+      break;
+    default:
+      break;
+  }
+
+  op->done_cb(op->user_data, GRPC_OP_ERROR);
+}
+
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {}
+
+static void init_call_elem(grpc_call_element *elem,
+                           const void *transport_server_data) {}
+
+static void destroy_call_elem(grpc_call_element *elem) {}
+
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args, grpc_mdctx *mdctx,
+                              int is_first, int is_last) {
+  GPR_ASSERT(is_first);
+  GPR_ASSERT(is_last);
+}
+
+static void destroy_channel_elem(grpc_channel_element *elem) {}
+
+static const grpc_channel_filter lame_filter = {
+    call_op, channel_op,
+
+    sizeof(call_data), init_call_elem, destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "lame-client",
+};
+
+grpc_channel *grpc_lame_client_channel_create() {
+  static const grpc_channel_filter *filters[] = {&lame_filter};
+  return grpc_channel_create_from_filters(filters, 1, NULL, grpc_mdctx_create(),
+                                          1);
+}
diff --git a/src/core/surface/lame_client.h b/src/core/surface/lame_client.h
new file mode 100644
index 0000000..74b9707
--- /dev/null
+++ b/src/core/surface/lame_client.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_
+#define __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_
+
+#include <grpc/grpc.h>
+
+/* Create a lame client: this client fails every operation attempted on it. */
+grpc_channel *grpc_lame_client_channel_create();
+
+#endif /* __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_ */
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
new file mode 100644
index 0000000..f330b83
--- /dev/null
+++ b/src/core/surface/secure_channel_create.c
@@ -0,0 +1,243 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "src/core/channel/census_filter.h"
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/client_setup.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_client_filter.h"
+#include "src/core/channel/http_filter.h"
+#include "src/core/endpoint/resolve_address.h"
+#include "src/core/endpoint/tcp.h"
+#include "src/core/endpoint/tcp_client.h"
+#include "src/core/security/auth.h"
+#include "src/core/security/security_context.h"
+#include "src/core/security/secure_transport_setup.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/client.h"
+#include "src/core/surface/surface_em.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+#include "src/core/tsi/transport_security_interface.h"
+
+typedef struct setup setup;
+
+/* A single setup request (started via initiate) */
+typedef struct {
+  grpc_client_setup_request *cs_request;
+  setup *setup;
+  /* Resolved addresses, or null if resolution not yet completed. */
+  grpc_resolved_addresses *resolved;
+  /* which address in resolved should we pick for the next connection attempt */
+  size_t resolved_index;
+} request;
+
+struct setup {
+  grpc_channel_security_context *security_context;
+  const char *target;
+  grpc_transport_setup_callback setup_callback;
+  void *setup_user_data;
+  grpc_em *em;
+};
+
+static int maybe_try_next_resolved(request *r);
+
+static void done(request *r, int was_successful) {
+  grpc_client_setup_request_finish(r->cs_request, was_successful);
+  if (r->resolved) {
+    grpc_resolved_addresses_destroy(r->resolved);
+  }
+  gpr_free(r);
+}
+
+static void on_secure_transport_setup_done(void *rp,
+                                           grpc_security_status status,
+                                           grpc_endpoint *secure_endpoint) {
+  request *r = rp;
+  if (status != GRPC_SECURITY_OK) {
+    gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
+    done(r, 0);
+  } else {
+    grpc_create_chttp2_transport(
+        r->setup->setup_callback, r->setup->setup_user_data,
+        grpc_client_setup_get_channel_args(r->cs_request), secure_endpoint,
+        NULL, 0, grpc_client_setup_get_mdctx(r->cs_request), 1);
+    done(r, 1);
+  }
+}
+
+/* connection callback: tcp is either valid, or null on error */
+static void on_connect(void *rp, grpc_endpoint *tcp) {
+  request *r = rp;
+
+  if (!grpc_client_setup_request_should_continue(r->cs_request)) {
+    if (tcp) {
+      grpc_endpoint_shutdown(tcp);
+      grpc_endpoint_destroy(tcp);
+    }
+    done(r, 0);
+    return;
+  }
+
+  if (!tcp) {
+    if (!maybe_try_next_resolved(r)) {
+      done(r, 0);
+      return;
+    } else {
+      return;
+    }
+  } else {
+    grpc_setup_secure_transport(&r->setup->security_context->base, tcp,
+                                on_secure_transport_setup_done, r);
+  }
+}
+
+/* attempt to connect to the next available resolved address */
+static int maybe_try_next_resolved(request *r) {
+  grpc_resolved_address *addr;
+  if (!r->resolved) return 0;
+  if (r->resolved_index == r->resolved->naddrs) return 0;
+  addr = &r->resolved->addrs[r->resolved_index++];
+  grpc_tcp_client_connect(on_connect, r, r->setup->em,
+                          (struct sockaddr *)&addr->addr, addr->len,
+                          grpc_client_setup_request_deadline(r->cs_request));
+  return 1;
+}
+
+/* callback for when our target address has been resolved */
+static void on_resolved(void *rp, grpc_resolved_addresses *resolved) {
+  request *r = rp;
+
+  /* if we're not still the active request, abort */
+  if (!grpc_client_setup_request_should_continue(r->cs_request)) {
+    if (resolved) {
+      grpc_resolved_addresses_destroy(resolved);
+    }
+    done(r, 0);
+    return;
+  }
+
+  if (!resolved) {
+    done(r, 0);
+    return;
+  } else {
+    r->resolved = resolved;
+    r->resolved_index = 0;
+    if (!maybe_try_next_resolved(r)) {
+      done(r, 0);
+    }
+  }
+}
+
+static void initiate_setup(void *sp, grpc_client_setup_request *cs_request) {
+  request *r = gpr_malloc(sizeof(request));
+  r->setup = sp;
+  r->cs_request = cs_request;
+  r->resolved = NULL;
+  r->resolved_index = 0;
+  /* TODO(klempner): Make grpc_resolve_address respect deadline */
+  grpc_resolve_address(r->setup->target, "https", on_resolved, r);
+}
+
+static void done_setup(void *sp) {
+  setup *s = sp;
+  gpr_free((void *)s->target);
+  grpc_security_context_unref(&s->security_context->base);
+  gpr_free(s);
+}
+
+static grpc_transport_setup_result complete_setup(void *channel_stack,
+                                                  grpc_transport *transport,
+                                                  grpc_mdctx *mdctx) {
+  static grpc_channel_filter const *extra_filters[] = {&grpc_http_client_filter,
+                                                       &grpc_http_filter};
+  return grpc_client_channel_transport_setup_complete(
+      channel_stack, transport, extra_filters, GPR_ARRAY_SIZE(extra_filters),
+      mdctx);
+}
+
+/* Create a secure client channel:
+   Asynchronously: - resolve target
+                   - connect to it (trying alternatives as presented)
+                   - perform handshakes */
+grpc_channel *grpc_secure_channel_create_internal(
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_context *context) {
+  setup *s;
+  grpc_channel *channel;
+  grpc_arg context_arg;
+  grpc_channel_args *args_copy;
+  grpc_mdctx *mdctx = grpc_mdctx_create();
+#define MAX_FILTERS 4
+  const grpc_channel_filter *filters[MAX_FILTERS];
+  int n = 0;
+  if (grpc_find_security_context_in_args(args) != NULL) {
+    gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
+  }
+
+  s = gpr_malloc(sizeof(setup));
+  context_arg = grpc_security_context_to_arg(&context->base);
+  args_copy = grpc_channel_args_copy_and_add(args, &context_arg);
+  filters[n++] = &grpc_client_surface_filter;
+  if (grpc_channel_args_is_census_enabled(args)) {
+    filters[n++] = &grpc_client_census_filter;
+  }
+  filters[n++] = &grpc_client_auth_filter;
+  filters[n++] = &grpc_client_channel_filter;
+  GPR_ASSERT(n <= MAX_FILTERS);
+  channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1);
+  grpc_channel_args_destroy(args_copy);
+
+  s->target = gpr_strdup(target);
+  s->em = grpc_surface_em();
+  s->setup_callback = complete_setup;
+  s->setup_user_data = grpc_channel_get_channel_stack(channel);
+  s->security_context =
+      (grpc_channel_security_context *)grpc_security_context_ref(
+          &context->base);
+  grpc_client_setup_create_and_attach(grpc_channel_get_channel_stack(channel),
+                                      args, mdctx, initiate_setup, done_setup,
+                                      s, s->em);
+  return channel;
+}
diff --git a/src/core/surface/secure_server_create.c b/src/core/surface/secure_server_create.c
new file mode 100644
index 0000000..bf0f623
--- /dev/null
+++ b/src/core/surface/secure_server_create.c
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+
+#include "src/core/channel/channel_args.h"
+#include "src/core/security/security_context.h"
+#include "src/core/surface/completion_queue.h"
+#include "src/core/surface/server.h"
+#include <grpc/support/log.h>
+
+grpc_server *grpc_secure_server_create_internal(
+    grpc_completion_queue *cq, const grpc_channel_args *args,
+    grpc_security_context *context) {
+  grpc_arg context_arg;
+  grpc_channel_args *args_copy;
+  grpc_server *server;
+  if (grpc_find_security_context_in_args(args) != NULL) {
+    gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
+  }
+
+  context_arg = grpc_security_context_to_arg(context);
+  args_copy = grpc_channel_args_copy_and_add(args, &context_arg);
+  server = grpc_server_create_from_filters(cq, NULL, 0, args_copy);
+  grpc_channel_args_destroy(args_copy);
+  return server;
+}
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
new file mode 100644
index 0000000..99d66ff
--- /dev/null
+++ b/src/core/surface/server.c
@@ -0,0 +1,609 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/server.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "src/core/channel/census_filter.h"
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/surface/call.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/completion_queue.h"
+#include "src/core/surface/surface_em.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include <grpc/support/useful.h>
+
+typedef enum { PENDING_START, ALL_CALLS, CALL_LIST_COUNT } call_list;
+
+typedef struct listener {
+  void *arg;
+  void (*start)(grpc_server *server, void *arg);
+  void (*destroy)(grpc_server *server, void *arg);
+  struct listener *next;
+} listener;
+
+typedef struct call_data call_data;
+typedef struct channel_data channel_data;
+
+struct channel_data {
+  grpc_server *server;
+  grpc_channel *channel;
+  /* linked list of all channels on a server */
+  channel_data *next;
+  channel_data *prev;
+};
+
+struct grpc_server {
+  size_t channel_filter_count;
+  const grpc_channel_filter **channel_filters;
+  grpc_channel_args *channel_args;
+  grpc_completion_queue *cq;
+  grpc_em *em;
+
+  gpr_mu mu;
+
+  void **tags;
+  size_t ntags;
+  size_t tag_cap;
+
+  gpr_uint8 shutdown;
+
+  call_data *lists[CALL_LIST_COUNT];
+  channel_data root_channel_data;
+
+  listener *listeners;
+  gpr_refcount internal_refcount;
+};
+
+typedef struct {
+  call_data *next;
+  call_data *prev;
+} call_link;
+
+typedef enum {
+  /* waiting for metadata */
+  NOT_STARTED,
+  /* inital metadata read, not flow controlled in yet */
+  PENDING,
+  /* flow controlled in, on completion queue */
+  ACTIVATED,
+  /* cancelled before being queued */
+  ZOMBIED
+} call_state;
+
+struct call_data {
+  grpc_call *call;
+
+  call_state state;
+  gpr_timespec deadline;
+
+  gpr_uint8 included[CALL_LIST_COUNT];
+  call_link links[CALL_LIST_COUNT];
+};
+
+#define SERVER_FROM_CALL_ELEM(elem) \
+  (((channel_data *)(elem)->channel_data)->server)
+
+static void do_nothing(void *unused, grpc_op_error ignored) {}
+
+static int call_list_join(grpc_server *server, call_data *call,
+                          call_list list) {
+  if (call->included[list]) return 0;
+  call->included[list] = 1;
+  if (!server->lists[list]) {
+    server->lists[list] = call;
+    call->links[list].next = call->links[list].prev = call;
+  } else {
+    call->links[list].next = server->lists[list];
+    call->links[list].prev = server->lists[list]->links[list].prev;
+    call->links[list].next->links[list].prev =
+        call->links[list].prev->links[list].next = call;
+  }
+  return 1;
+}
+
+static call_data *call_list_remove_head(grpc_server *server, call_list list) {
+  call_data *out = server->lists[list];
+  if (out) {
+    out->included[list] = 0;
+    if (out->links[list].next == out) {
+      server->lists[list] = NULL;
+    } else {
+      server->lists[list] = out->links[list].next;
+      out->links[list].next->links[list].prev = out->links[list].prev;
+      out->links[list].prev->links[list].next = out->links[list].next;
+    }
+  }
+  return out;
+}
+
+static int call_list_remove(grpc_server *server, call_data *call,
+                            call_list list) {
+  if (!call->included[list]) return 0;
+  call->included[list] = 0;
+  if (server->lists[list] == call) {
+    server->lists[list] = call->links[list].next;
+    if (server->lists[list] == call) {
+      server->lists[list] = NULL;
+      return 1;
+    }
+  }
+  GPR_ASSERT(server->lists[list] != call);
+  call->links[list].next->links[list].prev = call->links[list].prev;
+  call->links[list].prev->links[list].next = call->links[list].next;
+  return 1;
+}
+
+static void server_ref(grpc_server *server) {
+  gpr_ref(&server->internal_refcount);
+}
+
+static void server_unref(grpc_server *server) {
+  if (gpr_unref(&server->internal_refcount)) {
+    grpc_channel_args_destroy(server->channel_args);
+    gpr_mu_destroy(&server->mu);
+    gpr_free(server->channel_filters);
+    gpr_free(server->tags);
+    gpr_free(server);
+  }
+}
+
+static int is_channel_orphaned(channel_data *chand) {
+  return chand->next == chand;
+}
+
+static void orphan_channel(channel_data *chand) {
+  chand->next->prev = chand->prev;
+  chand->prev->next = chand->next;
+  chand->next = chand->prev = chand;
+}
+
+static void finish_destroy_channel(void *cd, grpc_em_cb_status status) {
+  channel_data *chand = cd;
+  grpc_server *server = chand->server;
+  /*gpr_log(GPR_INFO, "destroy channel %p", chand->channel);*/
+  grpc_channel_destroy(chand->channel);
+  server_unref(server);
+}
+
+static void destroy_channel(channel_data *chand) {
+  if (is_channel_orphaned(chand)) return;
+  GPR_ASSERT(chand->server != NULL);
+  orphan_channel(chand);
+  server_ref(chand->server);
+  grpc_em_add_callback(chand->server->em, finish_destroy_channel, chand);
+}
+
+static void queue_new_rpc(grpc_server *server, call_data *calld, void *tag) {
+  grpc_call *call = calld->call;
+  grpc_metadata_buffer *mdbuf = grpc_call_get_metadata_buffer(call);
+  size_t count = grpc_metadata_buffer_count(mdbuf);
+  grpc_metadata *elements = grpc_metadata_buffer_extract_elements(mdbuf);
+  const char *host = NULL;
+  const char *method = NULL;
+  size_t i;
+  grpc_metadata status_md;
+
+  for (i = 0; i < count; i++) {
+    if (0 == strcmp(elements[i].key, ":authority")) {
+      host = elements[i].value;
+    } else if (0 == strcmp(elements[i].key, ":path")) {
+      method = elements[i].value;
+    }
+  }
+
+  status_md.key = ":status";
+  status_md.value = "200";
+  status_md.value_length = 3;
+  grpc_call_add_metadata(call, &status_md, GRPC_WRITE_BUFFER_HINT);
+
+  grpc_call_internal_ref(call);
+  grpc_cq_end_new_rpc(server->cq, tag, call,
+                      grpc_metadata_buffer_cleanup_elements, elements, method,
+                      host, calld->deadline, count, elements);
+}
+
+static void start_new_rpc(grpc_call_element *elem) {
+  channel_data *chand = elem->channel_data;
+  call_data *calld = elem->call_data;
+  grpc_server *server = chand->server;
+
+  gpr_mu_lock(&server->mu);
+  if (server->ntags) {
+    calld->state = ACTIVATED;
+    queue_new_rpc(server, calld, server->tags[--server->ntags]);
+  } else {
+    calld->state = PENDING;
+    call_list_join(server, calld, PENDING_START);
+  }
+  gpr_mu_unlock(&server->mu);
+}
+
+static void kill_zombie(void *elem, grpc_em_cb_status status) {
+  grpc_call_destroy(grpc_call_from_top_element(elem));
+}
+
+static void finish_rpc(grpc_call_element *elem, int is_full_close) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  gpr_mu_lock(&chand->server->mu);
+  switch (calld->state) {
+    case ACTIVATED:
+      grpc_call_recv_finish(elem, is_full_close);
+      break;
+    case PENDING:
+      if (!is_full_close) {
+        grpc_call_recv_finish(elem, is_full_close);
+        break;
+      }
+      call_list_remove(chand->server, calld, PENDING_START);
+    /* fallthrough intended */
+    case NOT_STARTED:
+      calld->state = ZOMBIED;
+      grpc_em_add_callback(chand->server->em, kill_zombie, elem);
+      break;
+    case ZOMBIED:
+      break;
+  }
+  gpr_mu_unlock(&chand->server->mu);
+}
+
+static void call_op(grpc_call_element *elem, grpc_call_op *op) {
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+  switch (op->type) {
+    case GRPC_RECV_METADATA:
+      grpc_call_recv_metadata(elem, op);
+      break;
+    case GRPC_RECV_END_OF_INITIAL_METADATA:
+      start_new_rpc(elem);
+      break;
+    case GRPC_RECV_MESSAGE:
+      grpc_call_recv_message(elem, op->data.message, op->done_cb,
+                             op->user_data);
+      break;
+    case GRPC_RECV_HALF_CLOSE:
+      finish_rpc(elem, 0);
+      break;
+    case GRPC_RECV_FINISH:
+      finish_rpc(elem, 1);
+      break;
+    case GRPC_RECV_DEADLINE:
+      grpc_call_set_deadline(elem, op->data.deadline);
+      ((call_data *)elem->call_data)->deadline = op->data.deadline;
+      break;
+    default:
+      GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
+      grpc_call_next_op(elem, op);
+      break;
+  }
+}
+
+static void channel_op(grpc_channel_element *elem, grpc_channel_op *op) {
+  channel_data *chand = elem->channel_data;
+
+  switch (op->type) {
+    case GRPC_ACCEPT_CALL:
+      /* create a call */
+      grpc_call_create(chand->channel,
+                       op->data.accept_call.transport_server_data);
+      break;
+    case GRPC_TRANSPORT_CLOSED:
+      /* if the transport is closed for a server channel, we destroy the
+         channel */
+      gpr_mu_lock(&chand->server->mu);
+      server_ref(chand->server);
+      destroy_channel(chand);
+      gpr_mu_unlock(&chand->server->mu);
+      server_unref(chand->server);
+      break;
+    default:
+      GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
+      grpc_channel_next_op(elem, op);
+      break;
+  }
+}
+
+static void finish_shutdown_channel(void *cd, grpc_em_cb_status status) {
+  channel_data *chand = cd;
+  grpc_channel_op op;
+  op.type = GRPC_CHANNEL_SHUTDOWN;
+  op.dir = GRPC_CALL_DOWN;
+  channel_op(grpc_channel_stack_element(
+                 grpc_channel_get_channel_stack(chand->channel), 0),
+             &op);
+  grpc_channel_internal_unref(chand->channel);
+}
+
+static void shutdown_channel(channel_data *chand) {
+  grpc_channel_internal_ref(chand->channel);
+  grpc_em_add_callback(chand->server->em, finish_shutdown_channel, chand);
+}
+
+static void init_call_elem(grpc_call_element *elem,
+                           const void *server_transport_data) {
+  call_data *calld = elem->call_data;
+  channel_data *chand = elem->channel_data;
+  memset(calld, 0, sizeof(call_data));
+  calld->deadline = gpr_inf_future;
+  calld->call = grpc_call_from_top_element(elem);
+
+  gpr_mu_lock(&chand->server->mu);
+  call_list_join(chand->server, calld, ALL_CALLS);
+  gpr_mu_unlock(&chand->server->mu);
+
+  server_ref(chand->server);
+}
+
+static void destroy_call_elem(grpc_call_element *elem) {
+  channel_data *chand = elem->channel_data;
+  int i;
+
+  gpr_mu_lock(&chand->server->mu);
+  for (i = 0; i < CALL_LIST_COUNT; i++) {
+    call_list_remove(chand->server, elem->call_data, i);
+  }
+  gpr_mu_unlock(&chand->server->mu);
+
+  server_unref(chand->server);
+}
+
+static void init_channel_elem(grpc_channel_element *elem,
+                              const grpc_channel_args *args,
+                              grpc_mdctx *metadata_context, int is_first,
+                              int is_last) {
+  channel_data *chand = elem->channel_data;
+  GPR_ASSERT(is_first);
+  GPR_ASSERT(!is_last);
+  chand->server = NULL;
+  chand->channel = NULL;
+  chand->next = chand->prev = chand;
+}
+
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  channel_data *chand = elem->channel_data;
+  if (chand->server) {
+    gpr_mu_lock(&chand->server->mu);
+    chand->next->prev = chand->prev;
+    chand->prev->next = chand->next;
+    chand->next = chand->prev = chand;
+    gpr_mu_unlock(&chand->server->mu);
+    server_unref(chand->server);
+  }
+}
+
+static const grpc_channel_filter server_surface_filter = {
+    call_op,              channel_op,
+
+    sizeof(call_data),    init_call_elem,    destroy_call_elem,
+
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+
+    "server",
+};
+
+static void early_terminate_requested_calls(grpc_completion_queue *cq,
+                                            void **tags, size_t ntags) {
+  size_t i;
+
+  for (i = 0; i < ntags; i++) {
+    grpc_cq_end_new_rpc(cq, tags[i], NULL, do_nothing, NULL, NULL, NULL,
+                        gpr_inf_past, 0, NULL);
+  }
+}
+
+grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
+                                             grpc_channel_filter **filters,
+                                             size_t filter_count,
+                                             const grpc_channel_args *args) {
+  size_t i;
+  int census_enabled = grpc_channel_args_is_census_enabled(args);
+
+  grpc_server *server = gpr_malloc(sizeof(grpc_server));
+  memset(server, 0, sizeof(grpc_server));
+
+  gpr_mu_init(&server->mu);
+
+  server->cq = cq;
+  server->em = grpc_surface_em();
+  /* decremented by grpc_server_destroy */
+  gpr_ref_init(&server->internal_refcount, 1);
+  server->root_channel_data.next = server->root_channel_data.prev =
+      &server->root_channel_data;
+
+  /* Server filter stack is:
+
+     server_surface_filter - for making surface API calls
+     grpc_server_census_filter (optional) - for stats collection and tracing
+     {passed in filter stack}
+     grpc_connected_channel_filter - for interfacing with transports */
+  server->channel_filter_count = filter_count + 1 + census_enabled;
+  server->channel_filters =
+      gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
+  server->channel_filters[0] = &server_surface_filter;
+  if (census_enabled) {
+    server->channel_filters[1] = &grpc_server_census_filter;
+  }
+  for (i = 0; i < filter_count; i++) {
+    server->channel_filters[i + 1 + census_enabled] = filters[i];
+  }
+
+  server->channel_args = grpc_channel_args_copy(args);
+
+  return server;
+}
+
+void grpc_server_start(grpc_server *server) {
+  listener *l;
+
+  for (l = server->listeners; l; l = l->next) {
+    l->start(server, l->arg);
+  }
+}
+
+grpc_transport_setup_result grpc_server_setup_transport(
+    grpc_server *s, grpc_transport *transport,
+    grpc_channel_filter const **extra_filters, size_t num_extra_filters,
+    grpc_mdctx *mdctx) {
+  size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
+  grpc_channel_filter const **filters =
+      gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
+  size_t i;
+  grpc_channel *channel;
+  channel_data *chand;
+
+  for (i = 0; i < s->channel_filter_count; i++) {
+    filters[i] = s->channel_filters[i];
+  }
+  for (; i < s->channel_filter_count + num_extra_filters; i++) {
+    filters[i] = extra_filters[i - s->channel_filter_count];
+  }
+  filters[i] = &grpc_connected_channel_filter;
+
+  channel = grpc_channel_create_from_filters(filters, num_filters,
+                                             s->channel_args, mdctx, 0);
+  chand = (channel_data *)grpc_channel_stack_element(
+              grpc_channel_get_channel_stack(channel), 0)->channel_data;
+  chand->server = s;
+  server_ref(s);
+  chand->channel = channel;
+
+  gpr_mu_lock(&s->mu);
+  chand->next = &s->root_channel_data;
+  chand->prev = chand->next->prev;
+  chand->next->prev = chand->prev->next = chand;
+  gpr_mu_unlock(&s->mu);
+
+  gpr_free(filters);
+
+  return grpc_connected_channel_bind_transport(
+      grpc_channel_get_channel_stack(channel), transport);
+}
+
+void grpc_server_shutdown(grpc_server *server) {
+  /* TODO(ctiller): send goaway, etc */
+  listener *l;
+  void **tags;
+  size_t ntags;
+
+  /* lock, and gather up some stuff to do */
+  gpr_mu_lock(&server->mu);
+  if (server->shutdown) {
+    gpr_mu_unlock(&server->mu);
+    return;
+  }
+
+  tags = server->tags;
+  ntags = server->ntags;
+  server->tags = NULL;
+  server->ntags = 0;
+
+  server->shutdown = 1;
+  gpr_mu_unlock(&server->mu);
+
+  /* terminate all the requested calls */
+  early_terminate_requested_calls(server->cq, tags, ntags);
+  gpr_free(tags);
+
+  /* Shutdown listeners */
+  for (l = server->listeners; l; l = l->next) {
+    l->destroy(server, l->arg);
+  }
+  while (server->listeners) {
+    l = server->listeners;
+    server->listeners = l->next;
+    gpr_free(l);
+  }
+}
+
+void grpc_server_destroy(grpc_server *server) {
+  channel_data *c;
+  gpr_mu_lock(&server->mu);
+  for (c = server->root_channel_data.next; c != &server->root_channel_data;
+       c = c->next) {
+    shutdown_channel(c);
+  }
+  gpr_mu_unlock(&server->mu);
+
+  server_unref(server);
+}
+
+void grpc_server_add_listener(grpc_server *server, void *arg,
+                              void (*start)(grpc_server *server, void *arg),
+                              void (*destroy)(grpc_server *server, void *arg)) {
+  listener *l = gpr_malloc(sizeof(listener));
+  l->arg = arg;
+  l->start = start;
+  l->destroy = destroy;
+  l->next = server->listeners;
+  server->listeners = l;
+}
+
+grpc_call_error grpc_server_request_call(grpc_server *server, void *tag_new) {
+  call_data *calld;
+
+  grpc_cq_begin_op(server->cq, NULL, GRPC_SERVER_RPC_NEW);
+
+  gpr_mu_lock(&server->mu);
+
+  if (server->shutdown) {
+    gpr_mu_unlock(&server->mu);
+    early_terminate_requested_calls(server->cq, &tag_new, 1);
+    return GRPC_CALL_OK;
+  }
+
+  calld = call_list_remove_head(server, PENDING_START);
+  if (calld) {
+    GPR_ASSERT(calld->state == PENDING);
+    calld->state = ACTIVATED;
+    queue_new_rpc(server, calld, tag_new);
+  } else {
+    if (server->tag_cap == server->ntags) {
+      server->tag_cap = GPR_MAX(3 * server->tag_cap / 2, server->tag_cap + 1);
+      server->tags =
+          gpr_realloc(server->tags, sizeof(void *) * server->tag_cap);
+    }
+    server->tags[server->ntags++] = tag_new;
+  }
+  gpr_mu_unlock(&server->mu);
+
+  return GRPC_CALL_OK;
+}
+
+const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
+  return server->channel_args;
+}
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
new file mode 100644
index 0000000..f0773ab
--- /dev/null
+++ b/src/core/surface/server.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_SERVER_H__
+#define __GRPC_INTERNAL_SURFACE_SERVER_H__
+
+#include "src/core/channel/channel_stack.h"
+#include <grpc/grpc.h>
+#include "src/core/transport/transport.h"
+
+/* Create a server */
+grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
+                                             grpc_channel_filter **filters,
+                                             size_t filter_count,
+                                             const grpc_channel_args *args);
+
+/* Add a listener to the server: when the server starts, it will call start,
+   and when it shuts down, it will call destroy */
+void grpc_server_add_listener(grpc_server *server, void *listener,
+                              void (*start)(grpc_server *server, void *arg),
+                              void (*destroy)(grpc_server *server, void *arg));
+
+/* Setup a transport - creates a channel stack, binds the transport to the
+   server */
+grpc_transport_setup_result grpc_server_setup_transport(
+    grpc_server *server, grpc_transport *transport,
+    grpc_channel_filter const **extra_filters, size_t num_extra_filters,
+    grpc_mdctx *mdctx);
+
+const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
+
+#endif  /* __GRPC_INTERNAL_SURFACE_SERVER_H__ */
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
new file mode 100644
index 0000000..24c5757
--- /dev/null
+++ b/src/core/surface/server_chttp2.c
@@ -0,0 +1,123 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+
+#include "src/core/channel/http_filter.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/endpoint/resolve_address.h"
+#include "src/core/endpoint/tcp_server.h"
+#include "src/core/surface/server.h"
+#include "src/core/surface/surface_em.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+static grpc_transport_setup_result setup_transport(void *server,
+                                                   grpc_transport *transport,
+                                                   grpc_mdctx *mdctx) {
+  static grpc_channel_filter const *extra_filters[] = {&grpc_http_server_filter,
+                                                       &grpc_http_filter};
+  return grpc_server_setup_transport(server, transport, extra_filters,
+                                     GPR_ARRAY_SIZE(extra_filters), mdctx);
+}
+
+static void new_transport(void *server, grpc_endpoint *tcp) {
+  grpc_create_chttp2_transport(setup_transport, server,
+                               grpc_server_get_channel_args(server), tcp, NULL,
+                               0, grpc_mdctx_create(), 0);
+}
+
+/* Server callback: start listening on our ports */
+static void start(grpc_server *server, void *tcpp) {
+  grpc_tcp_server *tcp = tcpp;
+  grpc_tcp_server_start(tcp, new_transport, server);
+}
+
+/* Server callback: destroy the tcp listener (so we don't generate further
+   callbacks) */
+static void destroy(grpc_server *server, void *tcpp) {
+  grpc_tcp_server *tcp = tcpp;
+  grpc_tcp_server_destroy(tcp);
+}
+
+int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
+  grpc_resolved_addresses *resolved = NULL;
+  grpc_tcp_server *tcp = NULL;
+  size_t i;
+  int count = 0;
+
+  resolved = grpc_blocking_resolve_address(addr, "http");
+  if (!resolved) {
+    goto error;
+  }
+
+  tcp = grpc_tcp_server_create(grpc_surface_em());
+  if (!tcp) {
+    goto error;
+  }
+
+  for (i = 0; i < resolved->naddrs; i++) {
+    if (grpc_tcp_server_add_port(tcp,
+                                 (struct sockaddr *)&resolved->addrs[i].addr,
+                                 resolved->addrs[i].len) >= 0) {
+      count++;
+    }
+  }
+  if (count == 0) {
+    gpr_log(GPR_ERROR, "No address added out of total %d resolved",
+            resolved->naddrs);
+    goto error;
+  }
+  if (count != resolved->naddrs) {
+    gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
+            count, resolved->naddrs);
+  }
+  grpc_resolved_addresses_destroy(resolved);
+
+  /* Register with the server only upon success */
+  grpc_server_add_listener(server, tcp, start, destroy);
+
+  return 1;
+
+/* Error path: cleanup and return */
+error:
+  if (resolved) {
+    grpc_resolved_addresses_destroy(resolved);
+  }
+  if (tcp) {
+    grpc_tcp_server_destroy(tcp);
+  }
+  return 0;
+}
diff --git a/src/core/surface/server_create.c b/src/core/surface/server_create.c
new file mode 100644
index 0000000..dcc6ce1
--- /dev/null
+++ b/src/core/surface/server_create.c
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/grpc.h>
+#include "src/core/surface/completion_queue.h"
+#include "src/core/surface/server.h"
+
+grpc_server *grpc_server_create(grpc_completion_queue *cq,
+                                const grpc_channel_args *args) {
+  return grpc_server_create_from_filters(cq, NULL, 0, args);
+}
diff --git a/src/core/surface/surface_em.c b/src/core/surface/surface_em.c
new file mode 100644
index 0000000..e1785d1
--- /dev/null
+++ b/src/core/surface/surface_em.c
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/surface_em.h"
+#include <grpc/support/log.h>
+
+static int initialized = 0;
+static grpc_em em;
+
+grpc_em *grpc_surface_em() {
+  GPR_ASSERT(initialized && "call grpc_init()");
+  return &em;
+}
+
+void grpc_surface_em_init() {
+  GPR_ASSERT(!initialized);
+  initialized = 1;
+  grpc_em_init(&em);
+}
+
+void grpc_surface_em_shutdown() {
+  GPR_ASSERT(initialized);
+  grpc_em_destroy(&em);
+  initialized = 0;
+}
diff --git a/src/core/surface/surface_em.h b/src/core/surface/surface_em.h
new file mode 100644
index 0000000..165f42f
--- /dev/null
+++ b/src/core/surface/surface_em.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_SURFACE_EM_H__
+#define __GRPC_INTERNAL_SURFACE_SURFACE_EM_H__
+
+#include "src/core/eventmanager/em.h"
+
+/* Returns a global singleton event manager for
+   the surface apis, and is passed down to channels and
+   transports as needed. */
+grpc_em *grpc_surface_em();
+
+void grpc_surface_em_init();
+void grpc_surface_em_shutdown();
+
+#endif  /* __GRPC_INTERNAL_SURFACE_SURFACE_EM_H__ */
diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h
new file mode 100644
index 0000000..f6f9acf
--- /dev/null
+++ b/src/core/surface/surface_trace.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__
+#define __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__
+
+#include <grpc/support/log.h>
+
+/* #define GRPC_ENABLE_SURFACE_TRACE 1 */
+
+#ifdef GRPC_ENABLE_SURFACE_TRACE
+#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event)    \
+  do {                                                  \
+    char *_ev = grpc_event_string(event);               \
+    gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \
+    gpr_free(_ev);                                      \
+  } while (0)
+#else
+#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \
+  do {                                               \
+  } while (0)
+#endif
+
+#endif  /* __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__ */
diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h
new file mode 100644
index 0000000..7c0bbe0
--- /dev/null
+++ b/src/core/transport/chttp2/frame.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__
+
+#include <grpc/support/port_platform.h>
+
+/* Common definitions for frame handling in the chttp2 transport */
+
+typedef enum {
+  GRPC_CHTTP2_PARSE_OK,
+  GRPC_CHTTP2_STREAM_ERROR,
+  GRPC_CHTTP2_CONNECTION_ERROR
+} grpc_chttp2_parse_error;
+
+typedef struct {
+  gpr_uint8 end_of_stream;
+  gpr_uint8 need_flush_reads;
+  gpr_uint8 metadata_boundary;
+  gpr_uint8 ack_settings;
+  gpr_uint8 send_ping_ack;
+  gpr_uint8 process_ping_reply;
+
+  gpr_uint32 window_update;
+} grpc_chttp2_parse_state;
+
+#define GRPC_CHTTP2_FRAME_DATA 0
+#define GRPC_CHTTP2_FRAME_HEADER 1
+#define GRPC_CHTTP2_FRAME_CONTINUATION 9
+#define GRPC_CHTTP2_FRAME_RST_STREAM 3
+#define GRPC_CHTTP2_FRAME_SETTINGS 4
+#define GRPC_CHTTP2_FRAME_PING 6
+#define GRPC_CHTTP2_FRAME_WINDOW_UPDATE 8
+
+#define GRPC_CHTTP2_MAX_PAYLOAD_LENGTH ((1 << 14) - 1)
+
+#define GRPC_CHTTP2_DATA_FLAG_END_STREAM 1
+#define GRPC_CHTTP2_FLAG_ACK 1
+#define GRPC_CHTTP2_DATA_FLAG_END_HEADERS 4
+#define GRPC_CHTTP2_DATA_FLAG_PADDED 8
+#define GRPC_CHTTP2_FLAG_HAS_PRIORITY 0x20
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__ */
diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c
new file mode 100644
index 0000000..fbd3b6c
--- /dev/null
+++ b/src/core/transport/chttp2/frame_data.c
@@ -0,0 +1,164 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/frame_data.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include <grpc/support/useful.h>
+#include "src/core/transport/transport.h"
+
+grpc_chttp2_parse_error grpc_chttp2_data_parser_init(
+    grpc_chttp2_data_parser *parser) {
+  parser->state = GRPC_CHTTP2_DATA_FH_0;
+  grpc_sopb_init(&parser->incoming_sopb);
+  return GRPC_CHTTP2_PARSE_OK;
+}
+
+void grpc_chttp2_data_parser_destroy(grpc_chttp2_data_parser *parser) {
+  grpc_sopb_destroy(&parser->incoming_sopb);
+}
+
+grpc_chttp2_parse_error grpc_chttp2_data_parser_begin_frame(
+    grpc_chttp2_data_parser *parser, gpr_uint8 flags) {
+  if (flags & ~GRPC_CHTTP2_DATA_FLAG_END_STREAM) {
+    gpr_log(GPR_ERROR, "unsupported data flags: 0x%02x", flags);
+    return GRPC_CHTTP2_STREAM_ERROR;
+  }
+
+  if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) {
+    parser->is_last_frame = 1;
+  } else {
+    parser->is_last_frame = 0;
+  }
+
+  return GRPC_CHTTP2_PARSE_OK;
+}
+
+grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
+    void *parser, grpc_chttp2_parse_state *state, gpr_slice slice,
+    int is_last) {
+  gpr_uint8 *const beg = GPR_SLICE_START_PTR(slice);
+  gpr_uint8 *const end = GPR_SLICE_END_PTR(slice);
+  gpr_uint8 *cur = beg;
+  grpc_chttp2_data_parser *p = parser;
+
+  if (is_last && p->is_last_frame) {
+    state->end_of_stream = 1;
+    state->need_flush_reads = 1;
+  }
+
+  if (cur == end) {
+    return GRPC_CHTTP2_PARSE_OK;
+  }
+
+  switch (p->state) {
+  fh_0:
+    case GRPC_CHTTP2_DATA_FH_0:
+      p->frame_type = *cur;
+      if (++cur == end) {
+        p->state = GRPC_CHTTP2_DATA_FH_1;
+        return GRPC_CHTTP2_PARSE_OK;
+      }
+      switch (p->frame_type) {
+        case 0:
+          break;
+        case 1:
+          gpr_log(GPR_ERROR, "Compressed GRPC frames not yet supported");
+          return GRPC_CHTTP2_STREAM_ERROR;
+        default:
+          gpr_log(GPR_ERROR, "Bad GRPC frame type 0x%02x", p->frame_type);
+          return GRPC_CHTTP2_STREAM_ERROR;
+      }
+    /* fallthrough */
+    case GRPC_CHTTP2_DATA_FH_1:
+      p->frame_size = ((gpr_uint32)*cur) << 24;
+      if (++cur == end) {
+        p->state = GRPC_CHTTP2_DATA_FH_2;
+        return GRPC_CHTTP2_PARSE_OK;
+      }
+    /* fallthrough */
+    case GRPC_CHTTP2_DATA_FH_2:
+      p->frame_size |= ((gpr_uint32)*cur) << 16;
+      if (++cur == end) {
+        p->state = GRPC_CHTTP2_DATA_FH_3;
+        return GRPC_CHTTP2_PARSE_OK;
+      }
+    /* fallthrough */
+    case GRPC_CHTTP2_DATA_FH_3:
+      p->frame_size |= ((gpr_uint32)*cur) << 8;
+      if (++cur == end) {
+        p->state = GRPC_CHTTP2_DATA_FH_4;
+        return GRPC_CHTTP2_PARSE_OK;
+      }
+    /* fallthrough */
+    case GRPC_CHTTP2_DATA_FH_4:
+      p->frame_size |= ((gpr_uint32)*cur);
+      p->state = GRPC_CHTTP2_DATA_FRAME;
+      ++cur;
+      state->need_flush_reads = 1;
+      grpc_sopb_add_begin_message(&p->incoming_sopb, p->frame_size, 0);
+    /* fallthrough */
+    case GRPC_CHTTP2_DATA_FRAME:
+      if (cur == end) {
+        return GRPC_CHTTP2_PARSE_OK;
+      } else if (end - cur == p->frame_size) {
+        state->need_flush_reads = 1;
+        grpc_sopb_add_slice(&p->incoming_sopb,
+                            gpr_slice_sub(slice, cur - beg, end - beg));
+        p->state = GRPC_CHTTP2_DATA_FH_0;
+        return GRPC_CHTTP2_PARSE_OK;
+      } else if (end - cur > p->frame_size) {
+        state->need_flush_reads = 1;
+        grpc_sopb_add_slice(
+            &p->incoming_sopb,
+            gpr_slice_sub(slice, cur - beg, cur + p->frame_size - beg));
+        cur += p->frame_size;
+        goto fh_0; /* loop */
+      } else {
+        state->need_flush_reads = 1;
+        grpc_sopb_add_slice(&p->incoming_sopb,
+                            gpr_slice_sub(slice, cur - beg, end - beg));
+        p->frame_size -= (end - cur);
+        return GRPC_CHTTP2_PARSE_OK;
+      }
+  }
+
+  gpr_log(GPR_ERROR, "should never reach here");
+  abort();
+  return GRPC_CHTTP2_CONNECTION_ERROR;
+}
+
diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h
new file mode 100644
index 0000000..abe26da
--- /dev/null
+++ b/src/core/transport/chttp2/frame_data.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__
+
+/* Parser for GRPC streams embedded in DATA frames */
+
+#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
+#include "src/core/transport/stream_op.h"
+#include "src/core/transport/chttp2/frame.h"
+
+typedef enum {
+  GRPC_CHTTP2_DATA_FH_0,
+  GRPC_CHTTP2_DATA_FH_1,
+  GRPC_CHTTP2_DATA_FH_2,
+  GRPC_CHTTP2_DATA_FH_3,
+  GRPC_CHTTP2_DATA_FH_4,
+  GRPC_CHTTP2_DATA_FRAME
+} grpc_chttp2_stream_state;
+
+typedef struct {
+  grpc_chttp2_stream_state state;
+  gpr_uint8 is_last_frame;
+  gpr_uint8 frame_type;
+  gpr_uint32 frame_size;
+
+  grpc_stream_op_buffer incoming_sopb;
+} grpc_chttp2_data_parser;
+
+/* initialize per-stream state for data frame parsing */
+grpc_chttp2_parse_error grpc_chttp2_data_parser_init(
+    grpc_chttp2_data_parser *parser);
+
+void grpc_chttp2_data_parser_destroy(grpc_chttp2_data_parser *parser);
+
+/* start processing a new data frame */
+grpc_chttp2_parse_error grpc_chttp2_data_parser_begin_frame(
+    grpc_chttp2_data_parser *parser, gpr_uint8 flags);
+
+/* handle a slice of a data frame - is_last indicates the last slice of a
+   frame */
+grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
+    void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
+
+/* create a slice with an empty data frame and is_last set */
+gpr_slice grpc_chttp2_data_frame_create_empty_close(gpr_uint32 id);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__ */
diff --git a/src/core/transport/chttp2/frame_ping.c b/src/core/transport/chttp2/frame_ping.c
new file mode 100644
index 0000000..9556c0c
--- /dev/null
+++ b/src/core/transport/chttp2/frame_ping.c
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/frame_ping.h"
+
+#include <string.h>
+
+#include <grpc/support/log.h>
+
+gpr_slice grpc_chttp2_ping_create(gpr_uint8 ack, gpr_uint8 *opaque_8bytes) {
+  gpr_slice slice = gpr_slice_malloc(9 + 8);
+  gpr_uint8 *p = GPR_SLICE_START_PTR(slice);
+
+  *p++ = 0;
+  *p++ = 0;
+  *p++ = 8;
+  *p++ = GRPC_CHTTP2_FRAME_PING;
+  *p++ = ack ? 1 : 0;
+  *p++ = 0;
+  *p++ = 0;
+  *p++ = 0;
+  *p++ = 0;
+  memcpy(p, opaque_8bytes, 8);
+
+  return slice;
+}
+
+grpc_chttp2_parse_error grpc_chttp2_ping_parser_begin_frame(
+    grpc_chttp2_ping_parser *parser, gpr_uint32 length, gpr_uint8 flags) {
+  if (flags & 0xfe || length != 8) {
+    gpr_log(GPR_ERROR, "invalid ping: length=%d, flags=%02x", length, flags);
+    return GRPC_CHTTP2_CONNECTION_ERROR;
+  }
+  parser->byte = 0;
+  parser->is_ack = flags;
+  return GRPC_CHTTP2_PARSE_OK;
+}
+
+grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse(
+    void *parser, grpc_chttp2_parse_state *state, gpr_slice slice,
+    int is_last) {
+  gpr_uint8 *const beg = GPR_SLICE_START_PTR(slice);
+  gpr_uint8 *const end = GPR_SLICE_END_PTR(slice);
+  gpr_uint8 *cur = beg;
+  grpc_chttp2_ping_parser *p = parser;
+
+  while (p->byte != 8 && cur != end) {
+    p->opaque_8bytes[p->byte] = *cur;
+    cur++;
+    p->byte++;
+  }
+
+  if (p->byte == 8) {
+    GPR_ASSERT(is_last);
+    if (p->is_ack) {
+      state->process_ping_reply = 1;
+    } else {
+      state->send_ping_ack = 1;
+    }
+  }
+
+  return GRPC_CHTTP2_PARSE_OK;
+}
diff --git a/src/core/transport/chttp2/frame_ping.h b/src/core/transport/chttp2/frame_ping.h
new file mode 100644
index 0000000..a64d536
--- /dev/null
+++ b/src/core/transport/chttp2/frame_ping.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__
+
+#include <grpc/support/slice.h>
+#include "src/core/transport/chttp2/frame.h"
+
+typedef struct {
+  gpr_uint8 byte;
+  gpr_uint8 is_ack;
+  gpr_uint8 opaque_8bytes[8];
+} grpc_chttp2_ping_parser;
+
+gpr_slice grpc_chttp2_ping_create(gpr_uint8 ack, gpr_uint8 *opaque_8bytes);
+
+grpc_chttp2_parse_error grpc_chttp2_ping_parser_begin_frame(
+    grpc_chttp2_ping_parser *parser, gpr_uint32 length, gpr_uint8 flags);
+grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse(
+    void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__ */
diff --git a/src/core/transport/chttp2/frame_rst_stream.c b/src/core/transport/chttp2/frame_rst_stream.c
new file mode 100644
index 0000000..825e156
--- /dev/null
+++ b/src/core/transport/chttp2/frame_rst_stream.c
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/frame_rst_stream.h"
+#include "src/core/transport/chttp2/frame.h"
+
+gpr_slice grpc_chttp2_rst_stream_create(gpr_uint32 id, gpr_uint32 code) {
+  gpr_slice slice = gpr_slice_malloc(13);
+  gpr_uint8 *p = GPR_SLICE_START_PTR(slice);
+
+  *p++ = 0;
+  *p++ = 0;
+  *p++ = 4;
+  *p++ = GRPC_CHTTP2_FRAME_RST_STREAM;
+  *p++ = 0;
+  *p++ = id >> 24;
+  *p++ = id >> 16;
+  *p++ = id >> 8;
+  *p++ = id;
+  *p++ = code >> 24;
+  *p++ = code >> 16;
+  *p++ = code >> 8;
+  *p++ = code;
+
+  return slice;
+}
diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h
new file mode 100644
index 0000000..78aea0f
--- /dev/null
+++ b/src/core/transport/chttp2/frame_rst_stream.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__
+
+#include <grpc/support/slice.h>
+
+gpr_slice grpc_chttp2_rst_stream_create(gpr_uint32 stream_id, gpr_uint32 code);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__ */
diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c
new file mode 100644
index 0000000..488b96a
--- /dev/null
+++ b/src/core/transport/chttp2/frame_settings.c
@@ -0,0 +1,227 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/frame_settings.h"
+
+#include <string.h>
+
+#include "src/core/transport/chttp2/frame.h"
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+/* HTTP/2 mandated initial connection settings */
+const grpc_chttp2_setting_parameters
+    grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS] = {
+        {NULL, 0, 0, 0, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE},
+        {"HEADER_TABLE_SIZE", 4096, 0, 0xffffffff,
+         GRPC_CHTTP2_CLAMP_INVALID_VALUE},
+        {"ENABLE_PUSH", 1, 0, 1, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE},
+        {"MAX_CONCURRENT_STREAMS", 0xffffffffu, 0, 0xffffffffu,
+         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE},
+        {"INITIAL_WINDOW_SIZE", 65535, 0, 0xffffffffu,
+         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE},
+        {"MAX_FRAME_SIZE", 16384, 16384, 16777215,
+         GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE},
+        {"MAX_HEADER_LIST_SIZE", 0xffffffffu, 0, 0xffffffffu,
+         GRPC_CHTTP2_CLAMP_INVALID_VALUE},
+};
+
+static gpr_uint8 *fill_header(gpr_uint8 *out, gpr_uint32 length,
+                              gpr_uint8 flags) {
+  *out++ = length >> 16;
+  *out++ = length >> 8;
+  *out++ = length;
+  *out++ = GRPC_CHTTP2_FRAME_SETTINGS;
+  *out++ = flags;
+  *out++ = 0;
+  *out++ = 0;
+  *out++ = 0;
+  *out++ = 0;
+  return out;
+}
+
+gpr_slice grpc_chttp2_settings_create(gpr_uint32 *old, const gpr_uint32 *new,
+                                      size_t count) {
+  size_t i;
+  size_t n = 0;
+  gpr_slice output;
+  gpr_uint8 *p;
+
+  for (i = 0; i < count; i++) {
+    n += (new[i] != old[i]);
+  }
+
+  output = gpr_slice_malloc(9 + 6 * n);
+  p = fill_header(GPR_SLICE_START_PTR(output), 6 * n, 0);
+
+  for (i = 0; i < count; i++) {
+    if (new[i] != old[i]) {
+      GPR_ASSERT(i);
+      *p++ = i >> 8;
+      *p++ = i;
+      *p++ = new[i] >> 24;
+      *p++ = new[i] >> 16;
+      *p++ = new[i] >> 8;
+      *p++ = new[i];
+      old[i] = new[i];
+    }
+  }
+
+  GPR_ASSERT(p == GPR_SLICE_END_PTR(output));
+
+  return output;
+}
+
+gpr_slice grpc_chttp2_settings_ack_create() {
+  gpr_slice output = gpr_slice_malloc(9);
+  fill_header(GPR_SLICE_START_PTR(output), 0, GRPC_CHTTP2_FLAG_ACK);
+  return output;
+}
+
+grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame(
+    grpc_chttp2_settings_parser *parser, gpr_uint32 length, gpr_uint8 flags,
+    gpr_uint32 *settings) {
+  parser->target_settings = settings;
+  memcpy(parser->incoming_settings, settings,
+         GRPC_CHTTP2_NUM_SETTINGS * sizeof(gpr_uint32));
+  parser->is_ack = 0;
+  parser->state = GRPC_CHTTP2_SPS_ID0;
+  if (flags == GRPC_CHTTP2_FLAG_ACK) {
+    parser->is_ack = 1;
+    if (length != 0) {
+      gpr_log(GPR_ERROR, "non-empty settings ack frame received");
+      return GRPC_CHTTP2_CONNECTION_ERROR;
+    }
+    return GRPC_CHTTP2_PARSE_OK;
+  } else if (flags != 0) {
+    gpr_log(GPR_ERROR, "invalid flags on settings frame");
+    return GRPC_CHTTP2_CONNECTION_ERROR;
+  } else if (length % 6 != 0) {
+    gpr_log(GPR_ERROR, "settings frames must be a multiple of six bytes");
+    return GRPC_CHTTP2_CONNECTION_ERROR;
+  } else {
+    return GRPC_CHTTP2_PARSE_OK;
+  }
+}
+
+grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
+    void *p, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last) {
+  grpc_chttp2_settings_parser *parser = p;
+  const gpr_uint8 *cur = GPR_SLICE_START_PTR(slice);
+  const gpr_uint8 *end = GPR_SLICE_END_PTR(slice);
+
+  if (parser->is_ack) {
+    return GRPC_CHTTP2_PARSE_OK;
+  }
+
+  for (;;) {
+    switch (parser->state) {
+      case GRPC_CHTTP2_SPS_ID0:
+        if (cur == end) {
+          parser->state = GRPC_CHTTP2_SPS_ID0;
+          if (is_last) {
+            memcpy(parser->target_settings, parser->incoming_settings,
+                   GRPC_CHTTP2_NUM_SETTINGS * sizeof(gpr_uint32));
+            state->ack_settings = 1;
+          }
+          return GRPC_CHTTP2_PARSE_OK;
+        }
+        parser->id = ((gpr_uint16)*cur) << 8;
+        cur++;
+      /* fallthrough */
+      case GRPC_CHTTP2_SPS_ID1:
+        if (cur == end) {
+          parser->state = GRPC_CHTTP2_SPS_ID1;
+          return GRPC_CHTTP2_PARSE_OK;
+        }
+        parser->id |= (*cur);
+        cur++;
+      /* fallthrough */
+      case GRPC_CHTTP2_SPS_VAL0:
+        if (cur == end) {
+          parser->state = GRPC_CHTTP2_SPS_VAL0;
+          return GRPC_CHTTP2_PARSE_OK;
+        }
+        parser->value = ((gpr_uint32)*cur) << 24;
+        cur++;
+      /* fallthrough */
+      case GRPC_CHTTP2_SPS_VAL1:
+        if (cur == end) {
+          parser->state = GRPC_CHTTP2_SPS_VAL1;
+          return GRPC_CHTTP2_PARSE_OK;
+        }
+        parser->value |= ((gpr_uint32)*cur) << 16;
+        cur++;
+      /* fallthrough */
+      case GRPC_CHTTP2_SPS_VAL2:
+        if (cur == end) {
+          parser->state = GRPC_CHTTP2_SPS_VAL2;
+          return GRPC_CHTTP2_PARSE_OK;
+        }
+        parser->value |= ((gpr_uint32)*cur) << 8;
+        cur++;
+      /* fallthrough */
+      case GRPC_CHTTP2_SPS_VAL3:
+        if (cur == end) {
+          parser->state = GRPC_CHTTP2_SPS_VAL3;
+          return GRPC_CHTTP2_PARSE_OK;
+        } else {
+          parser->state = GRPC_CHTTP2_SPS_ID0;
+        }
+        parser->value |= *cur;
+        cur++;
+
+        if (parser->id > 0 && parser->id < GRPC_CHTTP2_NUM_SETTINGS) {
+          const grpc_chttp2_setting_parameters *sp =
+              &grpc_chttp2_settings_parameters[parser->id];
+          if (parser->value < sp->min_value || parser->value > sp->max_value) {
+            switch (sp->invalid_value_behavior) {
+              case GRPC_CHTTP2_CLAMP_INVALID_VALUE:
+                parser->value =
+                    GPR_CLAMP(parser->value, sp->min_value, sp->max_value);
+                break;
+              case GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE:
+                gpr_log(GPR_ERROR, "invalid value %u passed for %s",
+                        parser->value, sp->name);
+                return GRPC_CHTTP2_CONNECTION_ERROR;
+            }
+          }
+          parser->incoming_settings[parser->id] = parser->value;
+        } else {
+          gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)",
+                  parser->id, parser->value);
+        }
+        break;
+    }
+  }
+}
diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h
new file mode 100644
index 0000000..74e2b4f
--- /dev/null
+++ b/src/core/transport/chttp2/frame_settings.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__
+
+#include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+#include "src/core/transport/chttp2/frame.h"
+
+typedef enum {
+  GRPC_CHTTP2_SPS_ID0,
+  GRPC_CHTTP2_SPS_ID1,
+  GRPC_CHTTP2_SPS_VAL0,
+  GRPC_CHTTP2_SPS_VAL1,
+  GRPC_CHTTP2_SPS_VAL2,
+  GRPC_CHTTP2_SPS_VAL3
+} grpc_chttp2_settings_parse_state;
+
+/* The things HTTP/2 defines as connection level settings */
+typedef enum {
+  GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE = 1,
+  GRPC_CHTTP2_SETTINGS_ENABLE_PUSH = 2,
+  GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3,
+  GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4,
+  GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE = 5,
+  GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 6,
+  GRPC_CHTTP2_NUM_SETTINGS
+} grpc_chttp2_setting_id;
+
+typedef struct {
+  grpc_chttp2_settings_parse_state state;
+  gpr_uint32 *target_settings;
+  gpr_uint8 is_ack;
+  gpr_uint16 id;
+  gpr_uint32 value;
+  gpr_uint32 incoming_settings[GRPC_CHTTP2_NUM_SETTINGS];
+} grpc_chttp2_settings_parser;
+
+typedef enum {
+  GRPC_CHTTP2_CLAMP_INVALID_VALUE,
+  GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE
+} grpc_chttp2_invalid_value_behavior;
+
+typedef struct {
+  const char *name;
+  gpr_uint32 default_value;
+  gpr_uint32 min_value;
+  gpr_uint32 max_value;
+  grpc_chttp2_invalid_value_behavior invalid_value_behavior;
+} grpc_chttp2_setting_parameters;
+
+/* HTTP/2 mandated connection setting parameters */
+extern const grpc_chttp2_setting_parameters
+    grpc_chttp2_settings_parameters[GRPC_CHTTP2_NUM_SETTINGS];
+
+/* Create a settings frame by diffing old & new, and updating old to be new */
+gpr_slice grpc_chttp2_settings_create(gpr_uint32 *old, const gpr_uint32 *new,
+                                      size_t count);
+/* Create an ack settings frame */
+gpr_slice grpc_chttp2_settings_ack_create();
+
+grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame(
+    grpc_chttp2_settings_parser *parser, gpr_uint32 length, gpr_uint8 flags,
+    gpr_uint32 *settings);
+grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
+    void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__ */
diff --git a/src/core/transport/chttp2/frame_window_update.c b/src/core/transport/chttp2/frame_window_update.c
new file mode 100644
index 0000000..f61714f
--- /dev/null
+++ b/src/core/transport/chttp2/frame_window_update.c
@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/frame_window_update.h"
+
+#include <grpc/support/log.h>
+
+gpr_slice grpc_chttp2_window_update_create(gpr_uint32 id,
+                                           gpr_uint32 window_update) {
+  gpr_slice slice = gpr_slice_malloc(13);
+  gpr_uint8 *p = GPR_SLICE_START_PTR(slice);
+
+  GPR_ASSERT(window_update);
+
+  *p++ = 0;
+  *p++ = 0;
+  *p++ = 4;
+  *p++ = GRPC_CHTTP2_FRAME_WINDOW_UPDATE;
+  *p++ = 0;
+  *p++ = id >> 24;
+  *p++ = id >> 16;
+  *p++ = id >> 8;
+  *p++ = id;
+  *p++ = window_update >> 24;
+  *p++ = window_update >> 16;
+  *p++ = window_update >> 8;
+  *p++ = window_update;
+
+  return slice;
+}
+
+grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame(
+    grpc_chttp2_window_update_parser *parser, gpr_uint32 length,
+    gpr_uint8 flags) {
+  if (flags || length != 4) {
+    gpr_log(GPR_ERROR, "invalid window update: length=%d, flags=%02x", length,
+            flags);
+    return GRPC_CHTTP2_CONNECTION_ERROR;
+  }
+  parser->byte = 0;
+  parser->amount = 0;
+  return GRPC_CHTTP2_PARSE_OK;
+}
+
+grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
+    void *parser, grpc_chttp2_parse_state *state, gpr_slice slice,
+    int is_last) {
+  gpr_uint8 *const beg = GPR_SLICE_START_PTR(slice);
+  gpr_uint8 *const end = GPR_SLICE_END_PTR(slice);
+  gpr_uint8 *cur = beg;
+  grpc_chttp2_window_update_parser *p = parser;
+
+  while (p->byte != 4 && cur != end) {
+    p->amount |= ((gpr_uint32)*cur) << (8 * (3 - p->byte));
+    cur++;
+    p->byte++;
+  }
+
+  if (p->byte == 4) {
+    if (p->amount == 0 || (p->amount & 0x80000000u)) {
+      gpr_log(GPR_ERROR, "invalid window update bytes: %d", p->amount);
+      return GRPC_CHTTP2_CONNECTION_ERROR;
+    }
+    GPR_ASSERT(is_last);
+    state->window_update = p->amount;
+  }
+
+  return GRPC_CHTTP2_PARSE_OK;
+}
diff --git a/src/core/transport/chttp2/frame_window_update.h b/src/core/transport/chttp2/frame_window_update.h
new file mode 100644
index 0000000..4b789fc
--- /dev/null
+++ b/src/core/transport/chttp2/frame_window_update.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__
+
+#include <grpc/support/slice.h>
+#include "src/core/transport/chttp2/frame.h"
+
+typedef struct {
+  gpr_uint8 byte;
+  gpr_uint8 is_connection_update;
+  gpr_uint32 amount;
+} grpc_chttp2_window_update_parser;
+
+gpr_slice grpc_chttp2_window_update_create(gpr_uint32 id,
+                                           gpr_uint32 window_delta);
+
+grpc_chttp2_parse_error grpc_chttp2_window_update_parser_begin_frame(
+    grpc_chttp2_window_update_parser *parser, gpr_uint32 length,
+    gpr_uint8 flags);
+grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
+    void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__ */
diff --git a/src/core/transport/chttp2/gen_hpack_tables.c b/src/core/transport/chttp2/gen_hpack_tables.c
new file mode 100644
index 0000000..cc94a73
--- /dev/null
+++ b/src/core/transport/chttp2/gen_hpack_tables.c
@@ -0,0 +1,589 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* generates constant tables for hpack.c */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <grpc/support/log.h>
+
+/*
+ * first byte LUT generation
+ */
+
+typedef struct {
+  const char *call;
+  /* bit prefix for the field type */
+  unsigned char prefix;
+  /* length of the bit prefix for the field type */
+  unsigned char prefix_length;
+  /* index value: 0 = all zeros, 2 = all ones, 1 otherwise */
+  unsigned char index;
+} spec;
+
+static const spec fields[] = {
+    {"INDEXED_FIELD", 0X80, 1, 1},
+    {"INDEXED_FIELD_X", 0X80, 1, 2},
+    {"LITHDR_INCIDX", 0X40, 2, 1},
+    {"LITHDR_INCIDX_X", 0X40, 2, 2},
+    {"LITHDR_INCIDX_V", 0X40, 2, 0},
+    {"LITHDR_NOTIDX", 0X00, 4, 1},
+    {"LITHDR_NOTIDX_X", 0X00, 4, 2},
+    {"LITHDR_NOTIDX_V", 0X00, 4, 0},
+    {"LITHDR_NVRIDX", 0X10, 4, 1},
+    {"LITHDR_NVRIDX_X", 0X10, 4, 2},
+    {"LITHDR_NVRIDX_V", 0X10, 4, 0},
+    {"MAX_TBL_SIZE", 0X20, 3, 1},
+    {"MAX_TBL_SIZE_X", 0X20, 3, 2},
+};
+
+static const int num_fields = sizeof(fields) / sizeof(*fields);
+
+static unsigned char prefix_mask(unsigned char prefix_len) {
+  unsigned char i;
+  unsigned char out = 0;
+  for (i = 0; i < prefix_len; i++) {
+    out |= 1 << (7 - i);
+  }
+  return out;
+}
+
+static unsigned char suffix_mask(unsigned char prefix_len) {
+  return ~prefix_mask(prefix_len);
+}
+
+static void generate_first_byte_lut() {
+  int i, j, n;
+  const spec *chrspec;
+  unsigned char suffix;
+
+  n = printf("static CALLTYPE first_byte[256] = {");
+  /* for each potential first byte of a header */
+  for (i = 0; i < 256; i++) {
+    /* find the field type that matches it */
+    chrspec = NULL;
+    for (j = 0; j < num_fields; j++) {
+      if ((prefix_mask(fields[j].prefix_length) & i) == fields[j].prefix) {
+        suffix = suffix_mask(fields[j].prefix_length) & i;
+        if (suffix == suffix_mask(fields[j].prefix_length)) {
+          if (fields[j].index != 2) continue;
+        } else if (suffix == 0) {
+          if (fields[j].index != 0) continue;
+        } else {
+          if (fields[j].index != 1) continue;
+        }
+        GPR_ASSERT(chrspec == NULL);
+        chrspec = &fields[j];
+      }
+    }
+    if (chrspec) {
+      n += printf("%s, ", chrspec->call);
+    } else {
+      n += printf("ILLEGAL, ");
+    }
+    /* make some small effort towards readable output */
+    if (n > 70) {
+      printf("\n  ");
+      n = 2;
+    }
+  }
+  printf("};\n");
+}
+
+/*
+ * Huffman decoder table generation
+ */
+
+#define NSYMS 257
+#define MAXHUFFSTATES 1024
+
+/* Constants pulled from the HPACK spec, and converted to C using the vim
+   command:
+   :%s/.*   \([0-9a-f]\+\)  \[ *\([0-9]\+\)\]/{0x\1, \2},/g */
+static const struct {
+  unsigned bits;
+  unsigned length;
+} huffsyms[NSYMS] = {
+      {0x1ff8, 13},
+      {0x7fffd8, 23},
+      {0xfffffe2, 28},
+      {0xfffffe3, 28},
+      {0xfffffe4, 28},
+      {0xfffffe5, 28},
+      {0xfffffe6, 28},
+      {0xfffffe7, 28},
+      {0xfffffe8, 28},
+      {0xffffea, 24},
+      {0x3ffffffc, 30},
+      {0xfffffe9, 28},
+      {0xfffffea, 28},
+      {0x3ffffffd, 30},
+      {0xfffffeb, 28},
+      {0xfffffec, 28},
+      {0xfffffed, 28},
+      {0xfffffee, 28},
+      {0xfffffef, 28},
+      {0xffffff0, 28},
+      {0xffffff1, 28},
+      {0xffffff2, 28},
+      {0x3ffffffe, 30},
+      {0xffffff3, 28},
+      {0xffffff4, 28},
+      {0xffffff5, 28},
+      {0xffffff6, 28},
+      {0xffffff7, 28},
+      {0xffffff8, 28},
+      {0xffffff9, 28},
+      {0xffffffa, 28},
+      {0xffffffb, 28},
+      {0x14, 6},
+      {0x3f8, 10},
+      {0x3f9, 10},
+      {0xffa, 12},
+      {0x1ff9, 13},
+      {0x15, 6},
+      {0xf8, 8},
+      {0x7fa, 11},
+      {0x3fa, 10},
+      {0x3fb, 10},
+      {0xf9, 8},
+      {0x7fb, 11},
+      {0xfa, 8},
+      {0x16, 6},
+      {0x17, 6},
+      {0x18, 6},
+      {0x0, 5},
+      {0x1, 5},
+      {0x2, 5},
+      {0x19, 6},
+      {0x1a, 6},
+      {0x1b, 6},
+      {0x1c, 6},
+      {0x1d, 6},
+      {0x1e, 6},
+      {0x1f, 6},
+      {0x5c, 7},
+      {0xfb, 8},
+      {0x7ffc, 15},
+      {0x20, 6},
+      {0xffb, 12},
+      {0x3fc, 10},
+      {0x1ffa, 13},
+      {0x21, 6},
+      {0x5d, 7},
+      {0x5e, 7},
+      {0x5f, 7},
+      {0x60, 7},
+      {0x61, 7},
+      {0x62, 7},
+      {0x63, 7},
+      {0x64, 7},
+      {0x65, 7},
+      {0x66, 7},
+      {0x67, 7},
+      {0x68, 7},
+      {0x69, 7},
+      {0x6a, 7},
+      {0x6b, 7},
+      {0x6c, 7},
+      {0x6d, 7},
+      {0x6e, 7},
+      {0x6f, 7},
+      {0x70, 7},
+      {0x71, 7},
+      {0x72, 7},
+      {0xfc, 8},
+      {0x73, 7},
+      {0xfd, 8},
+      {0x1ffb, 13},
+      {0x7fff0, 19},
+      {0x1ffc, 13},
+      {0x3ffc, 14},
+      {0x22, 6},
+      {0x7ffd, 15},
+      {0x3, 5},
+      {0x23, 6},
+      {0x4, 5},
+      {0x24, 6},
+      {0x5, 5},
+      {0x25, 6},
+      {0x26, 6},
+      {0x27, 6},
+      {0x6, 5},
+      {0x74, 7},
+      {0x75, 7},
+      {0x28, 6},
+      {0x29, 6},
+      {0x2a, 6},
+      {0x7, 5},
+      {0x2b, 6},
+      {0x76, 7},
+      {0x2c, 6},
+      {0x8, 5},
+      {0x9, 5},
+      {0x2d, 6},
+      {0x77, 7},
+      {0x78, 7},
+      {0x79, 7},
+      {0x7a, 7},
+      {0x7b, 7},
+      {0x7ffe, 15},
+      {0x7fc, 11},
+      {0x3ffd, 14},
+      {0x1ffd, 13},
+      {0xffffffc, 28},
+      {0xfffe6, 20},
+      {0x3fffd2, 22},
+      {0xfffe7, 20},
+      {0xfffe8, 20},
+      {0x3fffd3, 22},
+      {0x3fffd4, 22},
+      {0x3fffd5, 22},
+      {0x7fffd9, 23},
+      {0x3fffd6, 22},
+      {0x7fffda, 23},
+      {0x7fffdb, 23},
+      {0x7fffdc, 23},
+      {0x7fffdd, 23},
+      {0x7fffde, 23},
+      {0xffffeb, 24},
+      {0x7fffdf, 23},
+      {0xffffec, 24},
+      {0xffffed, 24},
+      {0x3fffd7, 22},
+      {0x7fffe0, 23},
+      {0xffffee, 24},
+      {0x7fffe1, 23},
+      {0x7fffe2, 23},
+      {0x7fffe3, 23},
+      {0x7fffe4, 23},
+      {0x1fffdc, 21},
+      {0x3fffd8, 22},
+      {0x7fffe5, 23},
+      {0x3fffd9, 22},
+      {0x7fffe6, 23},
+      {0x7fffe7, 23},
+      {0xffffef, 24},
+      {0x3fffda, 22},
+      {0x1fffdd, 21},
+      {0xfffe9, 20},
+      {0x3fffdb, 22},
+      {0x3fffdc, 22},
+      {0x7fffe8, 23},
+      {0x7fffe9, 23},
+      {0x1fffde, 21},
+      {0x7fffea, 23},
+      {0x3fffdd, 22},
+      {0x3fffde, 22},
+      {0xfffff0, 24},
+      {0x1fffdf, 21},
+      {0x3fffdf, 22},
+      {0x7fffeb, 23},
+      {0x7fffec, 23},
+      {0x1fffe0, 21},
+      {0x1fffe1, 21},
+      {0x3fffe0, 22},
+      {0x1fffe2, 21},
+      {0x7fffed, 23},
+      {0x3fffe1, 22},
+      {0x7fffee, 23},
+      {0x7fffef, 23},
+      {0xfffea, 20},
+      {0x3fffe2, 22},
+      {0x3fffe3, 22},
+      {0x3fffe4, 22},
+      {0x7ffff0, 23},
+      {0x3fffe5, 22},
+      {0x3fffe6, 22},
+      {0x7ffff1, 23},
+      {0x3ffffe0, 26},
+      {0x3ffffe1, 26},
+      {0xfffeb, 20},
+      {0x7fff1, 19},
+      {0x3fffe7, 22},
+      {0x7ffff2, 23},
+      {0x3fffe8, 22},
+      {0x1ffffec, 25},
+      {0x3ffffe2, 26},
+      {0x3ffffe3, 26},
+      {0x3ffffe4, 26},
+      {0x7ffffde, 27},
+      {0x7ffffdf, 27},
+      {0x3ffffe5, 26},
+      {0xfffff1, 24},
+      {0x1ffffed, 25},
+      {0x7fff2, 19},
+      {0x1fffe3, 21},
+      {0x3ffffe6, 26},
+      {0x7ffffe0, 27},
+      {0x7ffffe1, 27},
+      {0x3ffffe7, 26},
+      {0x7ffffe2, 27},
+      {0xfffff2, 24},
+      {0x1fffe4, 21},
+      {0x1fffe5, 21},
+      {0x3ffffe8, 26},
+      {0x3ffffe9, 26},
+      {0xffffffd, 28},
+      {0x7ffffe3, 27},
+      {0x7ffffe4, 27},
+      {0x7ffffe5, 27},
+      {0xfffec, 20},
+      {0xfffff3, 24},
+      {0xfffed, 20},
+      {0x1fffe6, 21},
+      {0x3fffe9, 22},
+      {0x1fffe7, 21},
+      {0x1fffe8, 21},
+      {0x7ffff3, 23},
+      {0x3fffea, 22},
+      {0x3fffeb, 22},
+      {0x1ffffee, 25},
+      {0x1ffffef, 25},
+      {0xfffff4, 24},
+      {0xfffff5, 24},
+      {0x3ffffea, 26},
+      {0x7ffff4, 23},
+      {0x3ffffeb, 26},
+      {0x7ffffe6, 27},
+      {0x3ffffec, 26},
+      {0x3ffffed, 26},
+      {0x7ffffe7, 27},
+      {0x7ffffe8, 27},
+      {0x7ffffe9, 27},
+      {0x7ffffea, 27},
+      {0x7ffffeb, 27},
+      {0xffffffe, 28},
+      {0x7ffffec, 27},
+      {0x7ffffed, 27},
+      {0x7ffffee, 27},
+      {0x7ffffef, 27},
+      {0x7fffff0, 27},
+      {0x3ffffee, 26},
+      {0x3fffffff, 30},
+};
+
+/* represents a set of symbols as an array of booleans indicating inclusion */
+typedef struct { char included[NSYMS]; } symset;
+/* represents a lookup table indexed by a nibble */
+typedef struct { int values[16]; } nibblelut;
+
+/* returns a symset that includes all possible symbols */
+static symset symset_all() {
+  symset x;
+  memset(x.included, 1, sizeof(x.included));
+  return x;
+}
+
+/* returns a symset that includes no symbols */
+static symset symset_none() {
+  symset x;
+  memset(x.included, 0, sizeof(x.included));
+  return x;
+}
+
+/* returns an empty nibblelut */
+static nibblelut nibblelut_empty() {
+  nibblelut x;
+  int i;
+  for (i = 0; i < 16; i++) {
+    x.values[i] = -1;
+  }
+  return x;
+}
+
+/* counts symbols in a symset - only used for debug builds */
+#ifndef NDEBUG
+static int nsyms(symset s) {
+  int i;
+  int c = 0;
+  for (i = 0; i < NSYMS; i++) {
+    c += s.included[i] != 0;
+  }
+  return c;
+}
+#endif
+
+/* global table of discovered huffman decoding states */
+static struct {
+  /* the bit offset that this state starts at */
+  int bitofs;
+  /* the set of symbols that this state started with */
+  symset syms;
+
+  /* lookup table for the next state */
+  nibblelut next;
+  /* lookup table for what to emit */
+  nibblelut emit;
+} huffstates[MAXHUFFSTATES];
+static int nhuffstates = 0;
+
+/* given a number of decoded bits and a set of symbols that are live,
+   return the index into the decoder table for this state.
+   set isnew to 1 if this state was previously undiscovered */
+static int state_index(int bitofs, symset syms, int *isnew) {
+  int i;
+  for (i = 0; i < nhuffstates; i++) {
+    if (huffstates[i].bitofs != bitofs) continue;
+    if (0 != memcmp(huffstates[i].syms.included, syms.included, NSYMS))
+      continue;
+    *isnew = 0;
+    return i;
+  }
+  GPR_ASSERT(nhuffstates != MAXHUFFSTATES);
+  i = nhuffstates++;
+  huffstates[i].bitofs = bitofs;
+  huffstates[i].syms = syms;
+  huffstates[i].next = nibblelut_empty();
+  huffstates[i].emit = nibblelut_empty();
+  *isnew = 1;
+  return i;
+}
+
+/* recursively build a decoding table
+
+   state   - the huffman state that we are trying to fill in
+   nibble  - the current nibble
+   nibbits - the number of bits in the nibble that have been filled in
+   bitofs  - the number of bits of symbol that have been decoded
+   emit    - the symbol to emit on this nibble (or -1 if no symbol has been
+             found)
+   syms    - the set of symbols that could be matched */
+static void build_dec_tbl(int state, int nibble, int nibbits, int bitofs,
+                          int emit, symset syms) {
+  int i;
+  int bit;
+
+  /* If we have four bits in the nibble we're looking at, then we can fill in
+     a slot in the lookup tables. */
+  if (nibbits == 4) {
+    int isnew;
+    /* Find the state that we are in: this may be a new state, in which case
+       we recurse to fill it in, or we may have already seen this state, in
+       which case the recursion terminates */
+    int st = state_index(bitofs, syms, &isnew);
+    GPR_ASSERT(huffstates[state].next.values[nibble] == -1);
+    huffstates[state].next.values[nibble] = st;
+    huffstates[state].emit.values[nibble] = emit;
+    if (isnew) {
+      build_dec_tbl(st, 0, 0, bitofs, -1, syms);
+    }
+    return;
+  }
+
+  assert(nsyms(syms));
+
+  /* A bit can be 0 or 1 */
+  for (bit = 0; bit < 2; bit++) {
+    /* walk over active symbols and see if they have this bit set */
+    symset nextsyms = symset_none();
+    for (i = 0; i < NSYMS; i++) {
+      if (!syms.included[i]) continue; /* disregard inactive symbols */
+      if (((huffsyms[i].bits >> (huffsyms[i].length - bitofs - 1)) & 1) ==
+          bit) {
+        /* the bit is set, include it in the next recursive set */
+        if (huffsyms[i].length == bitofs + 1) {
+          /* additionally, we've gotten to the end of a symbol - this is a
+             special recursion step: re-activate all the symbols, reset
+             bitofs to zero, and recurse */
+          build_dec_tbl(state, (nibble << 1) | bit, nibbits + 1, 0, i,
+                        symset_all());
+          /* skip the remainder of this loop */
+          goto next;
+        }
+        nextsyms.included[i] = 1;
+      }
+    }
+    /* recurse down for this bit */
+    build_dec_tbl(state, (nibble << 1) | bit, nibbits + 1, bitofs + 1, emit,
+                  nextsyms);
+  next:
+    ;
+  }
+}
+
+static nibblelut ctbl[MAXHUFFSTATES];
+static int nctbl;
+
+static int ctbl_idx(nibblelut x) {
+  int i;
+  for (i = 0; i < nctbl; i++) {
+    if (0 == memcmp(&x, ctbl + i, sizeof(nibblelut))) return i;
+  }
+  ctbl[i] = x;
+  nctbl++;
+  return i;
+}
+
+static void dump_ctbl(const char *name) {
+  int i, j;
+  printf("static const gpr_int16 %s[%d*16] = {\n", name, nctbl);
+  for (i = 0; i < nctbl; i++) {
+    for (j = 0; j < 16; j++) {
+      printf("%d,", ctbl[i].values[j]);
+    }
+    printf("\n");
+  }
+  printf("};\n");
+}
+
+static void generate_huff_tables() {
+  int i;
+  build_dec_tbl(state_index(0, symset_all(), &i), 0, 0, 0, -1, symset_all());
+
+  nctbl = 0;
+  printf("static const gpr_uint8 next_tbl[%d] = {", nhuffstates);
+  for (i = 0; i < nhuffstates; i++) {
+    printf("%d,", ctbl_idx(huffstates[i].next));
+  }
+  printf("};\n");
+  dump_ctbl("next_sub_tbl");
+
+  nctbl = 0;
+  printf("static const gpr_uint16 emit_tbl[%d] = {", nhuffstates);
+  for (i = 0; i < nhuffstates; i++) {
+    printf("%d,", ctbl_idx(huffstates[i].emit));
+  }
+  printf("};\n");
+  dump_ctbl("emit_sub_tbl");
+}
+
+int main(void) {
+  generate_huff_tables();
+  generate_first_byte_lut();
+
+  return 0;
+}
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
new file mode 100644
index 0000000..33588a7
--- /dev/null
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -0,0 +1,1212 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/hpack_parser.h"
+
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+#include "src/core/support/murmur_hash.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/string.h>
+#include <grpc/support/useful.h>
+
+/* How parsing works:
+
+   The parser object keeps track of a function pointer which represents the
+   current parse state.
+
+   Each time new bytes are presented, we call into the current state, which
+   recursively parses until all bytes in the given chunk are exhausted.
+
+   The parse state that terminates then saves its function pointer to be the
+   current state so that it can resume when more bytes are available.
+
+   It's expected that most optimizing compilers will turn this code into
+   a set of indirect jumps, and so not waste stack space. */
+
+/* forward declarations for parsing states */
+static int parse_begin(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                       const gpr_uint8 *end);
+static int parse_error(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                       const gpr_uint8 *end);
+
+static int parse_string_prefix(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_key_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                            const gpr_uint8 *end);
+static int parse_value_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                              const gpr_uint8 *end);
+
+static int parse_value0(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end);
+static int parse_value1(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end);
+static int parse_value2(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end);
+static int parse_value3(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end);
+static int parse_value4(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end);
+static int parse_value5up(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                          const gpr_uint8 *end);
+
+static int parse_indexed_field(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end);
+static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                              const gpr_uint8 *end);
+static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p,
+                                const gpr_uint8 *cur, const gpr_uint8 *end);
+
+/* we translate the first byte of a hpack field into one of these decoding
+   cases, then use a lookup table to jump directly to the appropriate parser.
+
+   _X => the integer index is all ones, meaning we need to do varint decoding
+   _V => the integer index is all zeros, meaning we need to decode an additional
+         string value */
+typedef enum {
+  INDEXED_FIELD,
+  INDEXED_FIELD_X,
+  LITHDR_INCIDX,
+  LITHDR_INCIDX_X,
+  LITHDR_INCIDX_V,
+  LITHDR_NOTIDX,
+  LITHDR_NOTIDX_X,
+  LITHDR_NOTIDX_V,
+  LITHDR_NVRIDX,
+  LITHDR_NVRIDX_X,
+  LITHDR_NVRIDX_V,
+  MAX_TBL_SIZE,
+  MAX_TBL_SIZE_X,
+  ILLEGAL
+} first_byte_type;
+
+/* jump table of parse state functions -- order must match first_byte_type
+   above */
+static const grpc_chttp2_hpack_parser_state first_byte_action[] = {
+    parse_indexed_field,   parse_indexed_field_x, parse_lithdr_incidx,
+    parse_lithdr_incidx_x, parse_lithdr_incidx_v, parse_lithdr_notidx,
+    parse_lithdr_notidx_x, parse_lithdr_notidx_v, parse_lithdr_nvridx,
+    parse_lithdr_nvridx_x, parse_lithdr_nvridx_v, parse_max_tbl_size,
+    parse_max_tbl_size_x,  parse_error};
+
+/* indexes the first byte to a parse state function - generated by
+   gen_hpack_tables.c */
+static const gpr_uint8 first_byte_lut[256] = {
+    LITHDR_NOTIDX_V, LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX,
+    LITHDR_NOTIDX,   LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX,
+    LITHDR_NOTIDX,   LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX,
+    LITHDR_NOTIDX,   LITHDR_NOTIDX, LITHDR_NOTIDX, LITHDR_NOTIDX_X,
+    LITHDR_NVRIDX_V, LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
+    LITHDR_NVRIDX,   LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
+    LITHDR_NVRIDX,   LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
+    LITHDR_NVRIDX,   LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX_X,
+    ILLEGAL,         MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE_X,
+    LITHDR_INCIDX_V, LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX,
+    LITHDR_INCIDX,   LITHDR_INCIDX, LITHDR_INCIDX, LITHDR_INCIDX_X,
+    ILLEGAL,         INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD,
+    INDEXED_FIELD,   INDEXED_FIELD, INDEXED_FIELD, INDEXED_FIELD_X,
+};
+
+/* state table for huffman decoding: given a state, gives an index/16 into
+   next_sub_tbl. Taking that index and adding the value of the nibble being
+   considered returns the next state.
+
+   generated by gen_hpack_tables.c */
+static const gpr_uint8 next_tbl[256] = {
+    0,  1,  2,  3,  4,  1,  2, 5,  6,  1, 7,  8,  1,  3,  3,  9,  10, 11, 1,  1,
+    1,  12, 1,  2,  13, 1,  1, 1,  1,  1, 1,  1,  1,  1,  1,  1,  1,  1,  1,  2,
+    14, 1,  15, 16, 1,  17, 1, 15, 2,  7, 3,  18, 19, 1,  1,  1,  1,  20, 1,  1,
+    1,  1,  1,  1,  1,  1,  1, 1,  15, 2, 2,  7,  21, 1,  22, 1,  1,  1,  1,  1,
+    1,  1,  1,  15, 2,  2,  2, 2,  2,  2, 23, 24, 25, 1,  1,  1,  1,  2,  2,  2,
+    26, 3,  3,  27, 10, 28, 1, 1,  1,  1, 1,  1,  2,  3,  29, 10, 30, 1,  1,  1,
+    1,  1,  1,  1,  1,  1,  1, 1,  1,  1, 1,  31, 1,  1,  1,  1,  1,  1,  1,  2,
+    2,  2,  2,  2,  2,  2,  2, 32, 1,  1, 15, 33, 1,  34, 35, 9,  36, 1,  1,  1,
+    1,  1,  1,  1,  37, 1,  1, 1,  1,  1, 1,  2,  2,  2,  2,  2,  2,  2,  26, 9,
+    38, 1,  1,  1,  1,  1,  1, 1,  15, 2, 2,  2,  2,  26, 3,  3,  39, 1,  1,  1,
+    1,  1,  1,  1,  1,  1,  1, 1,  2,  2, 2,  2,  2,  2,  7,  3,  3,  3,  40, 2,
+    41, 1,  1,  1,  42, 43, 1, 1,  44, 1, 1,  1,  1,  15, 2,  2,  2,  2,  2,  2,
+    3,  3,  3,  45, 46, 1,  1, 2,  2,  2, 35, 3,  3,  18, 47, 2,
+};
+/* next state, based upon current state and the current nibble: see above.
+   generated by gen_hpack_tables.c */
+static const gpr_int16 next_sub_tbl[48 * 16] = {
+    1,   204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
+    218, 2,   6,   10,  13,  14,  15,  16,  17,  2,   6,   10,  13,  14,  15,
+    16,  17,  3,   7,   11,  24,  3,   7,   11,  24,  3,   7,   11,  24,  3,
+    7,   11,  24,  4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,
+    4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,
+    199, 200, 201, 202, 203, 4,   8,   4,   8,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   9,   133, 134, 135, 136, 137, 138, 139, 140,
+    141, 142, 143, 144, 145, 146, 147, 3,   7,   11,  24,  3,   7,   11,  24,
+    4,   8,   4,   8,   4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   12,  132, 4,   8,   4,   8,   4,   8,
+    4,   8,   4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   18,  19,  20,  21,  4,   8,   4,
+    8,   4,   8,   4,   8,   4,   8,   0,   0,   0,   22,  23,  91,  25,  26,
+    27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  3,
+    7,   11,  24,  3,   7,   11,  24,  0,   0,   0,   0,   0,   41,  42,  43,
+    2,   6,   10,  13,  14,  15,  16,  17,  3,   7,   11,  24,  3,   7,   11,
+    24,  4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   0,   0,
+    44,  45,  2,   6,   10,  13,  14,  15,  16,  17,  46,  47,  48,  49,  50,
+    51,  52,  57,  4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   53,  54,  55,  56,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
+    68,  69,  70,  71,  72,  74,  0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   73,  75,  76,  77,  78,  79,  80,  81,  82,
+    83,  84,  85,  86,  87,  88,  89,  90,  3,   7,   11,  24,  3,   7,   11,
+    24,  3,   7,   11,  24,  0,   0,   0,   0,   3,   7,   11,  24,  3,   7,
+    11,  24,  4,   8,   4,   8,   0,   0,   0,   92,  0,   0,   0,   93,  94,
+    95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 3,   7,   11,  24,
+    4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,
+    8,   4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 4,
+    8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   0,   0,
+    0,   117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+    131, 2,   6,   10,  13,  14,  15,  16,  17,  4,   8,   4,   8,   4,   8,
+    4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   148,
+    149, 150, 151, 3,   7,   11,  24,  4,   8,   4,   8,   0,   0,   0,   0,
+    0,   0,   152, 153, 3,   7,   11,  24,  3,   7,   11,  24,  3,   7,   11,
+    24,  154, 155, 156, 164, 3,   7,   11,  24,  3,   7,   11,  24,  3,   7,
+    11,  24,  4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    157, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 171, 172,
+    173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
+    188, 189, 190, 191, 192, 193, 194, 195, 196, 4,   8,   4,   8,   4,   8,
+    4,   8,   4,   8,   4,   8,   4,   8,   197, 198, 4,   8,   4,   8,   4,
+    8,   4,   8,   0,   0,   0,   0,   0,   0,   219, 220, 3,   7,   11,  24,
+    4,   8,   4,   8,   4,   8,   0,   0,   221, 222, 223, 224, 3,   7,   11,
+    24,  3,   7,   11,  24,  4,   8,   4,   8,   4,   8,   225, 228, 4,   8,
+    4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   226, 227, 229,
+    230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
+    4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   245, 246, 247, 248, 249, 250, 251, 252,
+    253, 254, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   255,
+};
+/* emission table: indexed like next_tbl, ultimately gives the byte to be
+   emitted, or -1 for no byte, or 256 for end of stream
+
+   generated by gen_hpack_tables.c */
+static const gpr_uint16 emit_tbl[256] = {
+    0,   1,   2,   3,   4,   5,   6,   7,   0,   8,   9,   10,  11,  12,  13,
+    14,  15,  16,  17,  18,  19,  20,  21,  22,  0,   23,  24,  25,  26,  27,
+    28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
+    43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  0,   55,  56,
+    57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  0,
+    71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,
+    86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100,
+    101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+    116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+    131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
+    146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 0,
+    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+    0,   175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
+    189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
+    204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
+    219, 220, 221, 0,   222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
+    233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
+    248,
+};
+/* generated by gen_hpack_tables.c */
+static const gpr_int16 emit_sub_tbl[249 * 16] = {
+    -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+    -1,  48,  48,  48,  48,  48,  48,  48,  48,  49,  49,  49,  49,  49,  49,
+    49,  49,  48,  48,  48,  48,  49,  49,  49,  49,  50,  50,  50,  50,  97,
+    97,  97,  97,  48,  48,  49,  49,  50,  50,  97,  97,  99,  99,  101, 101,
+    105, 105, 111, 111, 48,  49,  50,  97,  99,  101, 105, 111, 115, 116, -1,
+    -1,  -1,  -1,  -1,  -1,  32,  32,  32,  32,  32,  32,  32,  32,  37,  37,
+    37,  37,  37,  37,  37,  37,  99,  99,  99,  99,  101, 101, 101, 101, 105,
+    105, 105, 105, 111, 111, 111, 111, 115, 115, 116, 116, 32,  37,  45,  46,
+    47,  51,  52,  53,  54,  55,  56,  57,  61,  61,  61,  61,  61,  61,  61,
+    61,  65,  65,  65,  65,  65,  65,  65,  65,  115, 115, 115, 115, 116, 116,
+    116, 116, 32,  32,  37,  37,  45,  45,  46,  46,  61,  65,  95,  98,  100,
+    102, 103, 104, 108, 109, 110, 112, 114, 117, -1,  -1,  58,  58,  58,  58,
+    58,  58,  58,  58,  66,  66,  66,  66,  66,  66,  66,  66,  47,  47,  51,
+    51,  52,  52,  53,  53,  54,  54,  55,  55,  56,  56,  57,  57,  61,  61,
+    65,  65,  95,  95,  98,  98,  100, 100, 102, 102, 103, 103, 104, 104, 108,
+    108, 109, 109, 110, 110, 112, 112, 114, 114, 117, 117, 58,  66,  67,  68,
+    69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
+    84,  85,  86,  87,  89,  106, 107, 113, 118, 119, 120, 121, 122, -1,  -1,
+    -1,  -1,  38,  38,  38,  38,  38,  38,  38,  38,  42,  42,  42,  42,  42,
+    42,  42,  42,  44,  44,  44,  44,  44,  44,  44,  44,  59,  59,  59,  59,
+    59,  59,  59,  59,  88,  88,  88,  88,  88,  88,  88,  88,  90,  90,  90,
+    90,  90,  90,  90,  90,  33,  33,  34,  34,  40,  40,  41,  41,  63,  63,
+    39,  43,  124, -1,  -1,  -1,  35,  35,  35,  35,  35,  35,  35,  35,  62,
+    62,  62,  62,  62,  62,  62,  62,  0,   0,   0,   0,   36,  36,  36,  36,
+    64,  64,  64,  64,  91,  91,  91,  91,  69,  69,  69,  69,  69,  69,  69,
+    69,  70,  70,  70,  70,  70,  70,  70,  70,  71,  71,  71,  71,  71,  71,
+    71,  71,  72,  72,  72,  72,  72,  72,  72,  72,  73,  73,  73,  73,  73,
+    73,  73,  73,  74,  74,  74,  74,  74,  74,  74,  74,  75,  75,  75,  75,
+    75,  75,  75,  75,  76,  76,  76,  76,  76,  76,  76,  76,  77,  77,  77,
+    77,  77,  77,  77,  77,  78,  78,  78,  78,  78,  78,  78,  78,  79,  79,
+    79,  79,  79,  79,  79,  79,  80,  80,  80,  80,  80,  80,  80,  80,  81,
+    81,  81,  81,  81,  81,  81,  81,  82,  82,  82,  82,  82,  82,  82,  82,
+    83,  83,  83,  83,  83,  83,  83,  83,  84,  84,  84,  84,  84,  84,  84,
+    84,  85,  85,  85,  85,  85,  85,  85,  85,  86,  86,  86,  86,  86,  86,
+    86,  86,  87,  87,  87,  87,  87,  87,  87,  87,  89,  89,  89,  89,  89,
+    89,  89,  89,  106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107,
+    107, 107, 107, 107, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118,
+    118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 120, 120,
+    120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 122,
+    122, 122, 122, 122, 122, 122, 122, 38,  38,  38,  38,  42,  42,  42,  42,
+    44,  44,  44,  44,  59,  59,  59,  59,  88,  88,  88,  88,  90,  90,  90,
+    90,  33,  34,  40,  41,  63,  -1,  -1,  -1,  39,  39,  39,  39,  39,  39,
+    39,  39,  43,  43,  43,  43,  43,  43,  43,  43,  124, 124, 124, 124, 124,
+    124, 124, 124, 35,  35,  35,  35,  62,  62,  62,  62,  0,   0,   36,  36,
+    64,  64,  91,  91,  93,  93,  126, 126, 94,  125, -1,  -1,  60,  60,  60,
+    60,  60,  60,  60,  60,  96,  96,  96,  96,  96,  96,  96,  96,  123, 123,
+    123, 123, 123, 123, 123, 123, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  92,
+    92,  92,  92,  92,  92,  92,  92,  195, 195, 195, 195, 195, 195, 195, 195,
+    208, 208, 208, 208, 208, 208, 208, 208, 128, 128, 128, 128, 130, 130, 130,
+    130, 131, 131, 131, 131, 162, 162, 162, 162, 184, 184, 184, 184, 194, 194,
+    194, 194, 224, 224, 224, 224, 226, 226, 226, 226, 153, 153, 161, 161, 167,
+    167, 172, 172, 176, 176, 177, 177, 179, 179, 209, 209, 216, 216, 217, 217,
+    227, 227, 229, 229, 230, 230, 129, 132, 133, 134, 136, 146, 154, 156, 160,
+    163, 164, 169, 170, 173, 178, 181, 185, 186, 187, 189, 190, 196, 198, 228,
+    232, 233, -1,  -1,  -1,  -1,  1,   1,   1,   1,   1,   1,   1,   1,   135,
+    135, 135, 135, 135, 135, 135, 135, 137, 137, 137, 137, 137, 137, 137, 137,
+    138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139,
+    139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141,
+    141, 141, 143, 143, 143, 143, 143, 143, 143, 143, 147, 147, 147, 147, 147,
+    147, 147, 147, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150,
+    150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152,
+    152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 157, 157,
+    157, 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 165,
+    165, 165, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 166, 166, 166,
+    168, 168, 168, 168, 168, 168, 168, 168, 174, 174, 174, 174, 174, 174, 174,
+    174, 175, 175, 175, 175, 175, 175, 175, 175, 180, 180, 180, 180, 180, 180,
+    180, 180, 182, 182, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 183,
+    183, 183, 183, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191,
+    191, 191, 191, 191, 197, 197, 197, 197, 197, 197, 197, 197, 231, 231, 231,
+    231, 231, 231, 231, 231, 239, 239, 239, 239, 239, 239, 239, 239, 9,   9,
+    9,   9,   142, 142, 142, 142, 144, 144, 144, 144, 145, 145, 145, 145, 148,
+    148, 148, 148, 159, 159, 159, 159, 171, 171, 171, 171, 206, 206, 206, 206,
+    215, 215, 215, 215, 225, 225, 225, 225, 236, 236, 236, 236, 237, 237, 237,
+    237, 199, 199, 207, 207, 234, 234, 235, 235, 192, 193, 200, 201, 202, 205,
+    210, 213, 218, 219, 238, 240, 242, 243, 255, -1,  203, 203, 203, 203, 203,
+    203, 203, 203, 204, 204, 204, 204, 204, 204, 204, 204, 211, 211, 211, 211,
+    211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 212, 212, 214, 214, 214,
+    214, 214, 214, 214, 214, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222,
+    222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 241,
+    241, 241, 241, 241, 241, 241, 241, 244, 244, 244, 244, 244, 244, 244, 244,
+    245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246,
+    246, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248,
+    248, 248, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251,
+    251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253,
+    253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 2,   2,   2,
+    2,   3,   3,   3,   3,   4,   4,   4,   4,   5,   5,   5,   5,   6,   6,
+    6,   6,   7,   7,   7,   7,   8,   8,   8,   8,   11,  11,  11,  11,  12,
+    12,  12,  12,  14,  14,  14,  14,  15,  15,  15,  15,  16,  16,  16,  16,
+    17,  17,  17,  17,  18,  18,  18,  18,  19,  19,  19,  19,  20,  20,  20,
+    20,  21,  21,  21,  21,  23,  23,  23,  23,  24,  24,  24,  24,  25,  25,
+    25,  25,  26,  26,  26,  26,  27,  27,  27,  27,  28,  28,  28,  28,  29,
+    29,  29,  29,  30,  30,  30,  30,  31,  31,  31,  31,  127, 127, 127, 127,
+    220, 220, 220, 220, 249, 249, 249, 249, 10,  13,  22,  256, 93,  93,  93,
+    93,  126, 126, 126, 126, 94,  94,  125, 125, 60,  96,  123, -1,  92,  195,
+    208, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  128,
+    128, 128, 128, 128, 128, 128, 128, 130, 130, 130, 130, 130, 130, 130, 130,
+    131, 131, 131, 131, 131, 131, 131, 131, 162, 162, 162, 162, 162, 162, 162,
+    162, 184, 184, 184, 184, 184, 184, 184, 184, 194, 194, 194, 194, 194, 194,
+    194, 194, 224, 224, 224, 224, 224, 224, 224, 224, 226, 226, 226, 226, 226,
+    226, 226, 226, 153, 153, 153, 153, 161, 161, 161, 161, 167, 167, 167, 167,
+    172, 172, 172, 172, 176, 176, 176, 176, 177, 177, 177, 177, 179, 179, 179,
+    179, 209, 209, 209, 209, 216, 216, 216, 216, 217, 217, 217, 217, 227, 227,
+    227, 227, 229, 229, 229, 229, 230, 230, 230, 230, 129, 129, 132, 132, 133,
+    133, 134, 134, 136, 136, 146, 146, 154, 154, 156, 156, 160, 160, 163, 163,
+    164, 164, 169, 169, 170, 170, 173, 173, 178, 178, 181, 181, 185, 185, 186,
+    186, 187, 187, 189, 189, 190, 190, 196, 196, 198, 198, 228, 228, 232, 232,
+    233, 233, 1,   135, 137, 138, 139, 140, 141, 143, 147, 149, 150, 151, 152,
+    155, 157, 158, 165, 166, 168, 174, 175, 180, 182, 183, 188, 191, 197, 231,
+    239, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  9,   9,   9,
+    9,   9,   9,   9,   9,   142, 142, 142, 142, 142, 142, 142, 142, 144, 144,
+    144, 144, 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, 145, 145, 148,
+    148, 148, 148, 148, 148, 148, 148, 159, 159, 159, 159, 159, 159, 159, 159,
+    171, 171, 171, 171, 171, 171, 171, 171, 206, 206, 206, 206, 206, 206, 206,
+    206, 215, 215, 215, 215, 215, 215, 215, 215, 225, 225, 225, 225, 225, 225,
+    225, 225, 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 237,
+    237, 237, 237, 199, 199, 199, 199, 207, 207, 207, 207, 234, 234, 234, 234,
+    235, 235, 235, 235, 192, 192, 193, 193, 200, 200, 201, 201, 202, 202, 205,
+    205, 210, 210, 213, 213, 218, 218, 219, 219, 238, 238, 240, 240, 242, 242,
+    243, 243, 255, 255, 203, 204, 211, 212, 214, 221, 222, 223, 241, 244, 245,
+    246, 247, 248, 250, 251, 252, 253, 254, -1,  -1,  -1,  -1,  -1,  -1,  -1,
+    -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  2,   2,   2,   2,   2,   2,   2,
+    2,   3,   3,   3,   3,   3,   3,   3,   3,   4,   4,   4,   4,   4,   4,
+    4,   4,   5,   5,   5,   5,   5,   5,   5,   5,   6,   6,   6,   6,   6,
+    6,   6,   6,   7,   7,   7,   7,   7,   7,   7,   7,   8,   8,   8,   8,
+    8,   8,   8,   8,   11,  11,  11,  11,  11,  11,  11,  11,  12,  12,  12,
+    12,  12,  12,  12,  12,  14,  14,  14,  14,  14,  14,  14,  14,  15,  15,
+    15,  15,  15,  15,  15,  15,  16,  16,  16,  16,  16,  16,  16,  16,  17,
+    17,  17,  17,  17,  17,  17,  17,  18,  18,  18,  18,  18,  18,  18,  18,
+    19,  19,  19,  19,  19,  19,  19,  19,  20,  20,  20,  20,  20,  20,  20,
+    20,  21,  21,  21,  21,  21,  21,  21,  21,  23,  23,  23,  23,  23,  23,
+    23,  23,  24,  24,  24,  24,  24,  24,  24,  24,  25,  25,  25,  25,  25,
+    25,  25,  25,  26,  26,  26,  26,  26,  26,  26,  26,  27,  27,  27,  27,
+    27,  27,  27,  27,  28,  28,  28,  28,  28,  28,  28,  28,  29,  29,  29,
+    29,  29,  29,  29,  29,  30,  30,  30,  30,  30,  30,  30,  30,  31,  31,
+    31,  31,  31,  31,  31,  31,  127, 127, 127, 127, 127, 127, 127, 127, 220,
+    220, 220, 220, 220, 220, 220, 220, 249, 249, 249, 249, 249, 249, 249, 249,
+    10,  10,  13,  13,  22,  22,  256, 256, 67,  67,  67,  67,  67,  67,  67,
+    67,  68,  68,  68,  68,  68,  68,  68,  68,  95,  95,  95,  95,  95,  95,
+    95,  95,  98,  98,  98,  98,  98,  98,  98,  98,  100, 100, 100, 100, 100,
+    100, 100, 100, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103,
+    103, 103, 103, 103, 104, 104, 104, 104, 104, 104, 104, 104, 108, 108, 108,
+    108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 110, 110,
+    110, 110, 110, 110, 110, 110, 112, 112, 112, 112, 112, 112, 112, 112, 114,
+    114, 114, 114, 114, 114, 114, 114, 117, 117, 117, 117, 117, 117, 117, 117,
+    58,  58,  58,  58,  66,  66,  66,  66,  67,  67,  67,  67,  68,  68,  68,
+    68,  69,  69,  69,  69,  70,  70,  70,  70,  71,  71,  71,  71,  72,  72,
+    72,  72,  73,  73,  73,  73,  74,  74,  74,  74,  75,  75,  75,  75,  76,
+    76,  76,  76,  77,  77,  77,  77,  78,  78,  78,  78,  79,  79,  79,  79,
+    80,  80,  80,  80,  81,  81,  81,  81,  82,  82,  82,  82,  83,  83,  83,
+    83,  84,  84,  84,  84,  85,  85,  85,  85,  86,  86,  86,  86,  87,  87,
+    87,  87,  89,  89,  89,  89,  106, 106, 106, 106, 107, 107, 107, 107, 113,
+    113, 113, 113, 118, 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, 120,
+    121, 121, 121, 121, 122, 122, 122, 122, 38,  38,  42,  42,  44,  44,  59,
+    59,  88,  88,  90,  90,  -1,  -1,  -1,  -1,  33,  33,  33,  33,  33,  33,
+    33,  33,  34,  34,  34,  34,  34,  34,  34,  34,  40,  40,  40,  40,  40,
+    40,  40,  40,  41,  41,  41,  41,  41,  41,  41,  41,  63,  63,  63,  63,
+    63,  63,  63,  63,  39,  39,  39,  39,  43,  43,  43,  43,  124, 124, 124,
+    124, 35,  35,  62,  62,  0,   36,  64,  91,  93,  126, -1,  -1,  94,  94,
+    94,  94,  94,  94,  94,  94,  125, 125, 125, 125, 125, 125, 125, 125, 60,
+    60,  60,  60,  96,  96,  96,  96,  123, 123, 123, 123, -1,  -1,  -1,  -1,
+    92,  92,  92,  92,  195, 195, 195, 195, 208, 208, 208, 208, 128, 128, 130,
+    130, 131, 131, 162, 162, 184, 184, 194, 194, 224, 224, 226, 226, 153, 161,
+    167, 172, 176, 177, 179, 209, 216, 217, 227, 229, 230, -1,  -1,  -1,  -1,
+    -1,  -1,  -1,  129, 129, 129, 129, 129, 129, 129, 129, 132, 132, 132, 132,
+    132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 134,
+    134, 134, 134, 134, 134, 136, 136, 136, 136, 136, 136, 136, 136, 146, 146,
+    146, 146, 146, 146, 146, 146, 154, 154, 154, 154, 154, 154, 154, 154, 156,
+    156, 156, 156, 156, 156, 156, 156, 160, 160, 160, 160, 160, 160, 160, 160,
+    163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164,
+    164, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170,
+    170, 170, 173, 173, 173, 173, 173, 173, 173, 173, 178, 178, 178, 178, 178,
+    178, 178, 178, 181, 181, 181, 181, 181, 181, 181, 181, 185, 185, 185, 185,
+    185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187,
+    187, 187, 187, 187, 187, 189, 189, 189, 189, 189, 189, 189, 189, 190, 190,
+    190, 190, 190, 190, 190, 190, 196, 196, 196, 196, 196, 196, 196, 196, 198,
+    198, 198, 198, 198, 198, 198, 198, 228, 228, 228, 228, 228, 228, 228, 228,
+    232, 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233,
+    233, 1,   1,   1,   1,   135, 135, 135, 135, 137, 137, 137, 137, 138, 138,
+    138, 138, 139, 139, 139, 139, 140, 140, 140, 140, 141, 141, 141, 141, 143,
+    143, 143, 143, 147, 147, 147, 147, 149, 149, 149, 149, 150, 150, 150, 150,
+    151, 151, 151, 151, 152, 152, 152, 152, 155, 155, 155, 155, 157, 157, 157,
+    157, 158, 158, 158, 158, 165, 165, 165, 165, 166, 166, 166, 166, 168, 168,
+    168, 168, 174, 174, 174, 174, 175, 175, 175, 175, 180, 180, 180, 180, 182,
+    182, 182, 182, 183, 183, 183, 183, 188, 188, 188, 188, 191, 191, 191, 191,
+    197, 197, 197, 197, 231, 231, 231, 231, 239, 239, 239, 239, 9,   9,   142,
+    142, 144, 144, 145, 145, 148, 148, 159, 159, 171, 171, 206, 206, 215, 215,
+    225, 225, 236, 236, 237, 237, 199, 207, 234, 235, 192, 192, 192, 192, 192,
+    192, 192, 192, 193, 193, 193, 193, 193, 193, 193, 193, 200, 200, 200, 200,
+    200, 200, 200, 200, 201, 201, 201, 201, 201, 201, 201, 201, 202, 202, 202,
+    202, 202, 202, 202, 202, 205, 205, 205, 205, 205, 205, 205, 205, 210, 210,
+    210, 210, 210, 210, 210, 210, 213, 213, 213, 213, 213, 213, 213, 213, 218,
+    218, 218, 218, 218, 218, 218, 218, 219, 219, 219, 219, 219, 219, 219, 219,
+    238, 238, 238, 238, 238, 238, 238, 238, 240, 240, 240, 240, 240, 240, 240,
+    240, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 243,
+    243, 243, 255, 255, 255, 255, 255, 255, 255, 255, 203, 203, 203, 203, 204,
+    204, 204, 204, 211, 211, 211, 211, 212, 212, 212, 212, 214, 214, 214, 214,
+    221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 241, 241, 241,
+    241, 244, 244, 244, 244, 245, 245, 245, 245, 246, 246, 246, 246, 247, 247,
+    247, 247, 248, 248, 248, 248, 250, 250, 250, 250, 251, 251, 251, 251, 252,
+    252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 2,   2,   3,   3,
+    4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   11,  11,  12,  12,  14,
+    14,  15,  15,  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,
+    23,  23,  24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,
+    30,  31,  31,  127, 127, 220, 220, 249, 249, -1,  -1,  10,  10,  10,  10,
+    10,  10,  10,  10,  13,  13,  13,  13,  13,  13,  13,  13,  22,  22,  22,
+    22,  22,  22,  22,  22,  256, 256, 256, 256, 256, 256, 256, 256, 45,  45,
+    45,  45,  45,  45,  45,  45,  46,  46,  46,  46,  46,  46,  46,  46,  47,
+    47,  47,  47,  47,  47,  47,  47,  51,  51,  51,  51,  51,  51,  51,  51,
+    52,  52,  52,  52,  52,  52,  52,  52,  53,  53,  53,  53,  53,  53,  53,
+    53,  54,  54,  54,  54,  54,  54,  54,  54,  55,  55,  55,  55,  55,  55,
+    55,  55,  56,  56,  56,  56,  56,  56,  56,  56,  57,  57,  57,  57,  57,
+    57,  57,  57,  50,  50,  50,  50,  50,  50,  50,  50,  97,  97,  97,  97,
+    97,  97,  97,  97,  99,  99,  99,  99,  99,  99,  99,  99,  101, 101, 101,
+    101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 105, 105, 105, 111, 111,
+    111, 111, 111, 111, 111, 111, 115, 115, 115, 115, 115, 115, 115, 115, 116,
+    116, 116, 116, 116, 116, 116, 116, 32,  32,  32,  32,  37,  37,  37,  37,
+    45,  45,  45,  45,  46,  46,  46,  46,  47,  47,  47,  47,  51,  51,  51,
+    51,  52,  52,  52,  52,  53,  53,  53,  53,  54,  54,  54,  54,  55,  55,
+    55,  55,  56,  56,  56,  56,  57,  57,  57,  57,  61,  61,  61,  61,  65,
+    65,  65,  65,  95,  95,  95,  95,  98,  98,  98,  98,  100, 100, 100, 100,
+    102, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 104, 108, 108, 108,
+    108, 109, 109, 109, 109, 110, 110, 110, 110, 112, 112, 112, 112, 114, 114,
+    114, 114, 117, 117, 117, 117, 58,  58,  66,  66,  67,  67,  68,  68,  69,
+    69,  70,  70,  71,  71,  72,  72,  73,  73,  74,  74,  75,  75,  76,  76,
+    77,  77,  78,  78,  79,  79,  80,  80,  81,  81,  82,  82,  83,  83,  84,
+    84,  85,  85,  86,  86,  87,  87,  89,  89,  106, 106, 107, 107, 113, 113,
+    118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 38,  42,  44,  59,  88,
+    90,  -1,  -1,  33,  33,  33,  33,  34,  34,  34,  34,  40,  40,  40,  40,
+    41,  41,  41,  41,  63,  63,  63,  63,  39,  39,  43,  43,  124, 124, 35,
+    62,  -1,  -1,  -1,  -1,  0,   0,   0,   0,   0,   0,   0,   0,   36,  36,
+    36,  36,  36,  36,  36,  36,  64,  64,  64,  64,  64,  64,  64,  64,  91,
+    91,  91,  91,  91,  91,  91,  91,  93,  93,  93,  93,  93,  93,  93,  93,
+    126, 126, 126, 126, 126, 126, 126, 126, 94,  94,  94,  94,  125, 125, 125,
+    125, 60,  60,  96,  96,  123, 123, -1,  -1,  92,  92,  195, 195, 208, 208,
+    128, 130, 131, 162, 184, 194, 224, 226, -1,  -1,  153, 153, 153, 153, 153,
+    153, 153, 153, 161, 161, 161, 161, 161, 161, 161, 161, 167, 167, 167, 167,
+    167, 167, 167, 167, 172, 172, 172, 172, 172, 172, 172, 172, 176, 176, 176,
+    176, 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 179, 179,
+    179, 179, 179, 179, 179, 179, 209, 209, 209, 209, 209, 209, 209, 209, 216,
+    216, 216, 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 217, 217,
+    227, 227, 227, 227, 227, 227, 227, 227, 229, 229, 229, 229, 229, 229, 229,
+    229, 230, 230, 230, 230, 230, 230, 230, 230, 129, 129, 129, 129, 132, 132,
+    132, 132, 133, 133, 133, 133, 134, 134, 134, 134, 136, 136, 136, 136, 146,
+    146, 146, 146, 154, 154, 154, 154, 156, 156, 156, 156, 160, 160, 160, 160,
+    163, 163, 163, 163, 164, 164, 164, 164, 169, 169, 169, 169, 170, 170, 170,
+    170, 173, 173, 173, 173, 178, 178, 178, 178, 181, 181, 181, 181, 185, 185,
+    185, 185, 186, 186, 186, 186, 187, 187, 187, 187, 189, 189, 189, 189, 190,
+    190, 190, 190, 196, 196, 196, 196, 198, 198, 198, 198, 228, 228, 228, 228,
+    232, 232, 232, 232, 233, 233, 233, 233, 1,   1,   135, 135, 137, 137, 138,
+    138, 139, 139, 140, 140, 141, 141, 143, 143, 147, 147, 149, 149, 150, 150,
+    151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 165, 165, 166, 166, 168,
+    168, 174, 174, 175, 175, 180, 180, 182, 182, 183, 183, 188, 188, 191, 191,
+    197, 197, 231, 231, 239, 239, 9,   142, 144, 145, 148, 159, 171, 206, 215,
+    225, 236, 237, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  199, 199,
+    199, 199, 199, 199, 199, 199, 207, 207, 207, 207, 207, 207, 207, 207, 234,
+    234, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 235, 235, 235, 235,
+    192, 192, 192, 192, 193, 193, 193, 193, 200, 200, 200, 200, 201, 201, 201,
+    201, 202, 202, 202, 202, 205, 205, 205, 205, 210, 210, 210, 210, 213, 213,
+    213, 213, 218, 218, 218, 218, 219, 219, 219, 219, 238, 238, 238, 238, 240,
+    240, 240, 240, 242, 242, 242, 242, 243, 243, 243, 243, 255, 255, 255, 255,
+    203, 203, 204, 204, 211, 211, 212, 212, 214, 214, 221, 221, 222, 222, 223,
+    223, 241, 241, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 250, 250,
+    251, 251, 252, 252, 253, 253, 254, 254, 2,   3,   4,   5,   6,   7,   8,
+    11,  12,  14,  15,  16,  17,  18,  19,  20,  21,  23,  24,  25,  26,  27,
+    28,  29,  30,  31,  127, 220, 249, -1,  10,  10,  10,  10,  13,  13,  13,
+    13,  22,  22,  22,  22,  256, 256, 256, 256,
+};
+
+/* emission helpers */
+static void on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md,
+                   int add_to_table) {
+  if (add_to_table) {
+    grpc_mdelem_ref(md);
+    grpc_chttp2_hptbl_add(&p->table, md);
+  }
+  p->on_header(p->on_header_user_data, md);
+}
+
+static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p,
+                               grpc_chttp2_hpack_parser_string *str) {
+  grpc_mdstr *s = grpc_mdstr_from_buffer(p->table.mdctx, (gpr_uint8 *)str->str,
+                                         str->length);
+  str->length = 0;
+  return s;
+}
+
+/* jump to the next state */
+static int parse_next(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                      const gpr_uint8 *end) {
+  p->state = *p->next_state++;
+  return p->state(p, cur, end);
+}
+
+/* begin parsing a header: all functionality is encoded into lookup tables
+   above */
+static int parse_begin(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                       const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_begin;
+    return 1;
+  }
+
+  return first_byte_action[first_byte_lut[*cur]](p, cur, end);
+}
+
+/* stream dependency and prioritization data: we just skip it */
+static int parse_stream_weight(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_stream_weight;
+    return 1;
+  }
+
+  return parse_begin(p, cur + 1, end);
+}
+
+static int parse_stream_dep3(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                             const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_stream_dep3;
+    return 1;
+  }
+
+  return parse_stream_weight(p, cur + 1, end);
+}
+
+static int parse_stream_dep2(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                             const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_stream_dep2;
+    return 1;
+  }
+
+  return parse_stream_dep3(p, cur + 1, end);
+}
+
+static int parse_stream_dep1(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                             const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_stream_dep1;
+    return 1;
+  }
+
+  return parse_stream_dep2(p, cur + 1, end);
+}
+
+static int parse_stream_dep0(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                             const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_stream_dep0;
+    return 1;
+  }
+
+  return parse_stream_dep1(p, cur + 1, end);
+}
+
+/* emit an indexed field; for now just logs it to console; jumps to
+   begin the next field on completion */
+static int finish_indexed_field(grpc_chttp2_hpack_parser *p,
+                                const gpr_uint8 *cur, const gpr_uint8 *end) {
+  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+  grpc_mdelem_ref(md);
+  on_hdr(p, md, 0);
+  return parse_begin(p, cur, end);
+}
+
+/* parse an indexed field with index < 127 */
+static int parse_indexed_field(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end) {
+  p->index = (*cur) & 0x7f;
+  return finish_indexed_field(p, cur + 1, end);
+}
+
+/* parse an indexed field with index >= 127 */
+static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      finish_indexed_field};
+  p->next_state = and_then;
+  p->index = 0x7f;
+  p->parsing.value = &p->index;
+  return parse_value0(p, cur + 1, end);
+}
+
+/* finish a literal header with incremental indexing: just log, and jump to '
+   begin */
+static int finish_lithdr_incidx(grpc_chttp2_hpack_parser *p,
+                                const gpr_uint8 *cur, const gpr_uint8 *end) {
+  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                              grpc_mdstr_ref(md->key),
+                                              take_string(p, &p->value)),
+         1);
+  return parse_begin(p, cur, end);
+}
+
+/* finish a literal header with incremental indexing with no index */
+static int finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
+                                  const gpr_uint8 *cur, const gpr_uint8 *end) {
+  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                              take_string(p, &p->key),
+                                              take_string(p, &p->value)),
+         1);
+  return parse_begin(p, cur, end);
+}
+
+/* parse a literal header with incremental indexing; index < 63 */
+static int parse_lithdr_incidx(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_value_string, finish_lithdr_incidx};
+  p->next_state = and_then;
+  p->index = (*cur) & 0x3f;
+  return parse_string_prefix(p, cur + 1, end);
+}
+
+/* parse a literal header with incremental indexing; index >= 63 */
+static int parse_lithdr_incidx_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_string_prefix, parse_value_string, finish_lithdr_incidx};
+  p->next_state = and_then;
+  p->index = 0x3f;
+  p->parsing.value = &p->index;
+  return parse_value0(p, cur + 1, end);
+}
+
+/* parse a literal header with incremental indexing; index = 0 */
+static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_key_string, parse_string_prefix, parse_value_string,
+      finish_lithdr_incidx_v};
+  p->next_state = and_then;
+  return parse_string_prefix(p, cur + 1, end);
+}
+
+/* finish a literal header without incremental indexing */
+static int finish_lithdr_notidx(grpc_chttp2_hpack_parser *p,
+                                const gpr_uint8 *cur, const gpr_uint8 *end) {
+  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                              grpc_mdstr_ref(md->key),
+                                              take_string(p, &p->value)),
+         0);
+  return parse_begin(p, cur, end);
+}
+
+/* finish a literal header without incremental indexing with index = 0 */
+static int finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
+                                  const gpr_uint8 *cur, const gpr_uint8 *end) {
+  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                              take_string(p, &p->key),
+                                              take_string(p, &p->value)),
+         0);
+  return parse_begin(p, cur, end);
+}
+
+/* parse a literal header without incremental indexing; index < 15 */
+static int parse_lithdr_notidx(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_value_string, finish_lithdr_notidx};
+  p->next_state = and_then;
+  p->index = (*cur) & 0xf;
+  return parse_string_prefix(p, cur + 1, end);
+}
+
+/* parse a literal header without incremental indexing; index >= 15 */
+static int parse_lithdr_notidx_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_string_prefix, parse_value_string, finish_lithdr_notidx};
+  p->next_state = and_then;
+  p->index = 0xf;
+  p->parsing.value = &p->index;
+  return parse_value0(p, cur + 1, end);
+}
+
+/* parse a literal header without incremental indexing; index == 0 */
+static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_key_string, parse_string_prefix, parse_value_string,
+      finish_lithdr_notidx_v};
+  p->next_state = and_then;
+  return parse_string_prefix(p, cur + 1, end);
+}
+
+/* finish a literal header that is never indexed */
+static int finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
+                                const gpr_uint8 *cur, const gpr_uint8 *end) {
+  grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                              grpc_mdstr_ref(md->key),
+                                              take_string(p, &p->value)),
+         0);
+  return parse_begin(p, cur, end);
+}
+
+/* finish a literal header that is never indexed with an extra value */
+static int finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
+                                  const gpr_uint8 *cur, const gpr_uint8 *end) {
+  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                              take_string(p, &p->key),
+                                              take_string(p, &p->value)),
+         0);
+  return parse_begin(p, cur, end);
+}
+
+/* parse a literal header that is never indexed; index < 15 */
+static int parse_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_value_string, finish_lithdr_nvridx};
+  p->next_state = and_then;
+  p->index = (*cur) & 0xf;
+  return parse_string_prefix(p, cur + 1, end);
+}
+
+/* parse a literal header that is never indexed; index >= 15 */
+static int parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_string_prefix, parse_value_string, finish_lithdr_nvridx};
+  p->next_state = and_then;
+  p->index = 0xf;
+  p->parsing.value = &p->index;
+  return parse_value0(p, cur + 1, end);
+}
+
+/* parse a literal header that is never indexed; index == 0 */
+static int parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
+                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      parse_key_string, parse_string_prefix, parse_value_string,
+      finish_lithdr_nvridx_v};
+  p->next_state = and_then;
+  return parse_string_prefix(p, cur + 1, end);
+}
+
+/* finish parsing a max table size change */
+static int finish_max_tbl_size(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end) {
+  gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index);
+  abort(); /* not implemented */
+  return parse_begin(p, cur, end);
+}
+
+/* parse a max table size change, max size < 15 */
+static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                              const gpr_uint8 *end) {
+  p->index = (*cur) & 0xf;
+  return finish_max_tbl_size(p, cur + 1, end);
+}
+
+/* parse a max table size change, max size >= 15 */
+static int parse_max_tbl_size_x(grpc_chttp2_hpack_parser *p,
+                                const gpr_uint8 *cur, const gpr_uint8 *end) {
+  static const grpc_chttp2_hpack_parser_state and_then[] = {
+      finish_max_tbl_size};
+  p->next_state = and_then;
+  p->index = 0xf;
+  p->parsing.value = &p->index;
+  return parse_value0(p, cur + 1, end);
+}
+
+/* a parse error: jam the parse state into parse_error, and return error */
+static int parse_error(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                       const gpr_uint8 *end) {
+  p->state = parse_error;
+  return 0;
+}
+
+/* parse the 1st byte of a varint into p->parsing.value
+   no overflow is possible */
+static int parse_value0(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_value0;
+    return 1;
+  }
+
+  *p->parsing.value += (*cur) & 0x7f;
+
+  if ((*cur) & 0x80) {
+    return parse_value1(p, cur + 1, end);
+  } else {
+    return parse_next(p, cur + 1, end);
+  }
+}
+
+/* parse the 2nd byte of a varint into p->parsing.value
+   no overflow is possible */
+static int parse_value1(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_value1;
+    return 1;
+  }
+
+  *p->parsing.value += (((gpr_uint32)*cur) & 0x7f) << 7;
+
+  if ((*cur) & 0x80) {
+    return parse_value2(p, cur + 1, end);
+  } else {
+    return parse_next(p, cur + 1, end);
+  }
+}
+
+/* parse the 3rd byte of a varint into p->parsing.value
+   no overflow is possible */
+static int parse_value2(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_value2;
+    return 1;
+  }
+
+  *p->parsing.value += (((gpr_uint32)*cur) & 0x7f) << 14;
+
+  if ((*cur) & 0x80) {
+    return parse_value3(p, cur + 1, end);
+  } else {
+    return parse_next(p, cur + 1, end);
+  }
+}
+
+/* parse the 4th byte of a varint into p->parsing.value
+   no overflow is possible */
+static int parse_value3(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_value3;
+    return 1;
+  }
+
+  *p->parsing.value += (((gpr_uint32)*cur) & 0x7f) << 21;
+
+  if ((*cur) & 0x80) {
+    return parse_value4(p, cur + 1, end);
+  } else {
+    return parse_next(p, cur + 1, end);
+  }
+}
+
+/* parse the 5th byte of a varint into p->parsing.value
+   depending on the byte, we may overflow, and care must be taken */
+static int parse_value4(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end) {
+  gpr_uint8 c;
+  gpr_uint32 cur_value;
+  gpr_uint32 add_value;
+
+  if (cur == end) {
+    p->state = parse_value4;
+    return 1;
+  }
+
+  c = (*cur) & 0x7f;
+  if (c > 0xf) {
+    goto error;
+  }
+
+  cur_value = *p->parsing.value;
+  add_value = ((gpr_uint32)c) << 28;
+  if (add_value > 0xffffffffu - cur_value) {
+    goto error;
+  }
+
+  *p->parsing.value = cur_value + add_value;
+
+  if ((*cur) & 0x80) {
+    return parse_value5up(p, cur + 1, end);
+  } else {
+    return parse_next(p, cur + 1, end);
+  }
+
+error:
+  gpr_log(GPR_ERROR,
+          "integer overflow in hpack integer decoding: have 0x%08x, "
+          "got byte 0x%02x",
+          *p->parsing.value, *cur);
+  return parse_error(p, cur, end);
+}
+
+/* parse any trailing bytes in a varint: it's possible to append an arbitrary
+   number of 0x80's and not affect the value - a zero will terminate - and
+   anything else will overflow */
+static int parse_value5up(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                          const gpr_uint8 *end) {
+  while (cur != end && *cur == 0x80) {
+    ++cur;
+  }
+
+  if (cur == end) {
+    p->state = parse_value5up;
+    return 1;
+  }
+
+  if (*cur == 0) {
+    return parse_next(p, cur + 1, end);
+  }
+
+  gpr_log(GPR_ERROR,
+          "integer overflow in hpack integer decoding: have 0x%08x, "
+          "got byte 0x%02x sometime after byte 4");
+  return parse_error(p, cur, end);
+}
+
+/* parse a string prefix */
+static int parse_string_prefix(grpc_chttp2_hpack_parser *p,
+                               const gpr_uint8 *cur, const gpr_uint8 *end) {
+  if (cur == end) {
+    p->state = parse_string_prefix;
+    return 1;
+  }
+
+  p->strlen = (*cur) & 0x7f;
+  p->huff = (*cur) >> 7;
+  if (p->strlen == 0x7f) {
+    p->parsing.value = &p->strlen;
+    return parse_value0(p, cur + 1, end);
+  } else {
+    return parse_next(p, cur + 1, end);
+  }
+}
+
+/* append some bytes to a string */
+static void append_string(grpc_chttp2_hpack_parser_string *str,
+                          const gpr_uint8 *data, size_t length) {
+  if (length + str->length > str->capacity) {
+    str->capacity = str->length + length;
+    str->str = gpr_realloc(str->str, str->capacity);
+  }
+  memcpy(str->str + str->length, data, length);
+  str->length += length;
+}
+
+/* append a null terminator to a string */
+static void finish_str(grpc_chttp2_hpack_parser_string *str) {
+  gpr_uint8 terminator = 0;
+  append_string(str, &terminator, 1);
+  str->length--; /* don't actually count the null terminator */
+}
+
+/* decode a nibble from a huffman encoded stream */
+static void huff_nibble(grpc_chttp2_hpack_parser *p, gpr_uint8 nibble) {
+  gpr_int16 emit = emit_sub_tbl[16 * emit_tbl[p->huff_state] + nibble];
+  gpr_int16 next = next_sub_tbl[16 * next_tbl[p->huff_state] + nibble];
+  if (emit != -1) {
+    if (emit >= 0 && emit < 256) {
+      gpr_uint8 c = emit;
+      append_string(p->parsing.str, &c, 1);
+    } else {
+      assert(emit == 256);
+    }
+  }
+  p->huff_state = next;
+}
+
+/* decode full bytes from a huffman encoded stream */
+static void add_huff_bytes(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                           const gpr_uint8 *end) {
+  for (; cur != end; ++cur) {
+    huff_nibble(p, *cur >> 4);
+    huff_nibble(p, *cur & 0xf);
+  }
+}
+
+/* decode some string bytes based on the current decoding mode
+   (huffman or not) */
+static void add_str_bytes(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                          const gpr_uint8 *end) {
+  if (p->huff) {
+    add_huff_bytes(p, cur, end);
+  } else {
+    append_string(p->parsing.str, cur, end - cur);
+  }
+}
+
+/* parse a string - tries to do large chunks at a time */
+static int parse_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                        const gpr_uint8 *end) {
+  size_t remaining = p->strlen - p->strgot;
+  size_t given = end - cur;
+  if (remaining <= given) {
+    add_str_bytes(p, cur, cur + remaining);
+    finish_str(p->parsing.str);
+    return parse_next(p, cur + remaining, end);
+  } else {
+    add_str_bytes(p, cur, cur + given);
+    p->strgot += given;
+    p->state = parse_string;
+    return 1;
+  }
+}
+
+/* begin parsing a string - performs setup, calls parse_string */
+static int begin_parse_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                              const gpr_uint8 *end,
+                              grpc_chttp2_hpack_parser_string *str) {
+  p->strgot = 0;
+  str->length = 0;
+  p->parsing.str = str;
+  p->huff_state = 0;
+  return parse_string(p, cur, end);
+}
+
+/* parse the key string */
+static int parse_key_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                            const gpr_uint8 *end) {
+  return begin_parse_string(p, cur, end, &p->key);
+}
+
+/* parse the value string */
+static int parse_value_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                              const gpr_uint8 *end) {
+  return begin_parse_string(p, cur, end, &p->value);
+}
+
+/* PUBLIC INTERFACE */
+
+static void on_header_not_set(void *user_data, grpc_mdelem *md) {
+  char *keyhex =
+      gpr_hexdump(grpc_mdstr_as_c_string(md->key),
+                  GPR_SLICE_LENGTH(md->key->slice), GPR_HEXDUMP_PLAINTEXT);
+  char *valuehex =
+      gpr_hexdump(grpc_mdstr_as_c_string(md->value),
+                  GPR_SLICE_LENGTH(md->value->slice), GPR_HEXDUMP_PLAINTEXT);
+  gpr_log(GPR_ERROR, "on_header callback not set; key=%s value=%s", keyhex,
+          valuehex);
+  gpr_free(keyhex);
+  gpr_free(valuehex);
+  grpc_mdelem_unref(md);
+  abort();
+}
+
+void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p,
+                                   grpc_mdctx *mdctx) {
+  p->on_header = on_header_not_set;
+  p->on_header_user_data = NULL;
+  p->state = parse_begin;
+  p->key.str = NULL;
+  p->key.capacity = 0;
+  p->key.length = 0;
+  p->value.str = NULL;
+  p->value.capacity = 0;
+  p->value.length = 0;
+  grpc_chttp2_hptbl_init(&p->table, mdctx);
+}
+
+void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
+  GPR_ASSERT(p->state == parse_begin);
+  p->state = parse_stream_dep0;
+}
+
+void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) {
+  grpc_chttp2_hptbl_destroy(&p->table);
+  gpr_free(p->key.str);
+  gpr_free(p->value.str);
+}
+
+int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p,
+                                   const gpr_uint8 *beg, const gpr_uint8 *end) {
+  /* TODO(ctiller): limit the distance of end from beg, and perform multiple
+                    steps in the event of a large chunk of data to limit
+                    stack space usage when no tail call optimization is
+                    available */
+  return p->state(p, beg, end);
+}
+
+grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
+    void *hpack_parser, grpc_chttp2_parse_state *state, gpr_slice slice,
+    int is_last) {
+  grpc_chttp2_hpack_parser *parser = hpack_parser;
+  if (!grpc_chttp2_hpack_parser_parse(parser, GPR_SLICE_START_PTR(slice),
+                                      GPR_SLICE_END_PTR(slice))) {
+    return GRPC_CHTTP2_CONNECTION_ERROR;
+  }
+  if (is_last) {
+    if (parser->is_boundary && parser->state != parse_begin) {
+      gpr_log(GPR_ERROR,
+              "end of header frame not aligned with a hpack record boundary");
+      return GRPC_CHTTP2_CONNECTION_ERROR;
+    }
+    state->metadata_boundary = parser->is_boundary;
+    state->end_of_stream = parser->is_eof;
+    state->need_flush_reads = parser->is_eof;
+    parser->on_header = on_header_not_set;
+    parser->on_header_user_data = NULL;
+    parser->is_boundary = 0xde;
+    parser->is_eof = 0xde;
+  }
+  return GRPC_CHTTP2_PARSE_OK;
+}
diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h
new file mode 100644
index 0000000..cf68042
--- /dev/null
+++ b/src/core/transport/chttp2/hpack_parser.h
@@ -0,0 +1,108 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__
+
+#include <stddef.h>
+
+#include <grpc/support/port_platform.h>
+#include "src/core/transport/chttp2/frame.h"
+#include "src/core/transport/chttp2/hpack_table.h"
+#include "src/core/transport/metadata.h"
+
+typedef struct grpc_chttp2_hpack_parser grpc_chttp2_hpack_parser;
+
+typedef int (*grpc_chttp2_hpack_parser_state)(grpc_chttp2_hpack_parser *p,
+                                              const gpr_uint8 *beg,
+                                              const gpr_uint8 *end);
+
+typedef struct {
+  char *str;
+  gpr_uint32 length;
+  gpr_uint32 capacity;
+} grpc_chttp2_hpack_parser_string;
+
+struct grpc_chttp2_hpack_parser {
+  /* user specified callback for each header output */
+  void (*on_header)(void *user_data, grpc_mdelem *md);
+  void *on_header_user_data;
+
+  /* current parse state - or a function that implements it */
+  grpc_chttp2_hpack_parser_state state;
+  /* future states dependent on the opening op code */
+  const grpc_chttp2_hpack_parser_state *next_state;
+  /* the value we're currently parsing */
+  union {
+    gpr_uint32 *value;
+    grpc_chttp2_hpack_parser_string *str;
+  } parsing;
+  /* string parameters for each chunk */
+  grpc_chttp2_hpack_parser_string key;
+  grpc_chttp2_hpack_parser_string value;
+  /* parsed index */
+  gpr_uint32 index;
+  /* length of source bytes for the currently parsing string */
+  gpr_uint32 strlen;
+  /* number of source bytes read for the currently parsing string */
+  gpr_uint32 strgot;
+  /* huffman decoding state */
+  gpr_uint16 huff_state;
+  /* is the current string huffman encoded? */
+  gpr_uint8 huff;
+  /* set by higher layers, used by grpc_chttp2_header_parser_parse to signal
+     it should append a metadata boundary at the end of frame */
+  gpr_uint8 is_boundary;
+  gpr_uint8 is_eof;
+
+  /* hpack table */
+  grpc_chttp2_hptbl table;
+};
+
+void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p,
+                                   grpc_mdctx *mdctx);
+void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p);
+
+void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p);
+
+/* returns 1 on success, 0 on error */
+int grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser *p,
+                                   const gpr_uint8 *beg, const gpr_uint8 *end);
+
+/* wraps grpc_chttp2_hpack_parser_parse to provide a frame level parser for
+   the transport */
+grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
+    void *hpack_parser, grpc_chttp2_parse_state *state, gpr_slice slice,
+    int is_last);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__ */
diff --git a/src/core/transport/chttp2/hpack_table.c b/src/core/transport/chttp2/hpack_table.c
new file mode 100644
index 0000000..8f2ebec
--- /dev/null
+++ b/src/core/transport/chttp2/hpack_table.c
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/hpack_table.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include "src/core/support/murmur_hash.h"
+
+static struct {
+  const char *key;
+  const char *value;
+} static_table[] = {
+      /* 0: */ {NULL, NULL},
+      /* 1: */ {":authority", ""},
+      /* 2: */ {":method", "GET"},
+      /* 3: */ {":method", "POST"},
+      /* 4: */ {":path", "/"},
+      /* 5: */ {":path", "/index.html"},
+      /* 6: */ {":scheme", "http"},
+      /* 7: */ {":scheme", "https"},
+      /* 8: */ {":status", "200"},
+      /* 9: */ {":status", "204"},
+      /* 10: */ {":status", "206"},
+      /* 11: */ {":status", "304"},
+      /* 12: */ {":status", "400"},
+      /* 13: */ {":status", "404"},
+      /* 14: */ {":status", "500"},
+      /* 15: */ {"accept-charset", ""},
+      /* 16: */ {"accept-encoding", "gzip, deflate"},
+      /* 17: */ {"accept-language", ""},
+      /* 18: */ {"accept-ranges", ""},
+      /* 19: */ {"accept", ""},
+      /* 20: */ {"access-control-allow-origin", ""},
+      /* 21: */ {"age", ""},
+      /* 22: */ {"allow", ""},
+      /* 23: */ {"authorization", ""},
+      /* 24: */ {"cache-control", ""},
+      /* 25: */ {"content-disposition", ""},
+      /* 26: */ {"content-encoding", ""},
+      /* 27: */ {"content-language", ""},
+      /* 28: */ {"content-length", ""},
+      /* 29: */ {"content-location", ""},
+      /* 30: */ {"content-range", ""},
+      /* 31: */ {"content-type", ""},
+      /* 32: */ {"cookie", ""},
+      /* 33: */ {"date", ""},
+      /* 34: */ {"etag", ""},
+      /* 35: */ {"expect", ""},
+      /* 36: */ {"expires", ""},
+      /* 37: */ {"from", ""},
+      /* 38: */ {"host", ""},
+      /* 39: */ {"if-match", ""},
+      /* 40: */ {"if-modified-since", ""},
+      /* 41: */ {"if-none-match", ""},
+      /* 42: */ {"if-range", ""},
+      /* 43: */ {"if-unmodified-since", ""},
+      /* 44: */ {"last-modified", ""},
+      /* 45: */ {"link", ""},
+      /* 46: */ {"location", ""},
+      /* 47: */ {"max-forwards", ""},
+      /* 48: */ {"proxy-authenticate", ""},
+      /* 49: */ {"proxy-authorization", ""},
+      /* 50: */ {"range", ""},
+      /* 51: */ {"referer", ""},
+      /* 52: */ {"refresh", ""},
+      /* 53: */ {"retry-after", ""},
+      /* 54: */ {"server", ""},
+      /* 55: */ {"set-cookie", ""},
+      /* 56: */ {"strict-transport-security", ""},
+      /* 57: */ {"transfer-encoding", ""},
+      /* 58: */ {"user-agent", ""},
+      /* 59: */ {"vary", ""},
+      /* 60: */ {"via", ""},
+      /* 61: */ {"www-authenticate", ""},
+};
+
+void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx) {
+  size_t i;
+
+  memset(tbl, 0, sizeof(*tbl));
+  tbl->mdctx = mdctx;
+  tbl->max_bytes = GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE;
+  for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
+    tbl->static_ents[i - 1] = grpc_mdelem_from_strings(
+        mdctx, static_table[i].key, static_table[i].value);
+  }
+}
+
+void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl) {
+  size_t i;
+  for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
+    grpc_mdelem_unref(tbl->static_ents[i]);
+  }
+  for (i = 0; i < tbl->num_ents; i++) {
+    grpc_mdelem_unref(
+        tbl->ents[(tbl->first_ent + i) % GRPC_CHTTP2_MAX_TABLE_COUNT]);
+  }
+}
+
+grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
+                                      gpr_uint32 index) {
+  /* Static table comes first, just return an entry from it */
+  if (index <= GRPC_CHTTP2_LAST_STATIC_ENTRY) {
+    return tbl->static_ents[index - 1];
+  }
+  /* Otherwise, find the value in the list of valid entries */
+  index -= (GRPC_CHTTP2_LAST_STATIC_ENTRY + 1);
+  if (index < tbl->num_ents) {
+    gpr_uint32 offset = (tbl->num_ents - 1 - index + tbl->first_ent) %
+                        GRPC_CHTTP2_MAX_TABLE_COUNT;
+    return tbl->ents[offset];
+  }
+  /* Invalid entry: return error */
+  return NULL;
+}
+
+/* Evict one element from the table */
+static void evict1(grpc_chttp2_hptbl *tbl) {
+  grpc_mdelem *first_ent = tbl->ents[tbl->first_ent];
+  tbl->mem_used -= GPR_SLICE_LENGTH(first_ent->key->slice) +
+                   GPR_SLICE_LENGTH(first_ent->value->slice) +
+                   GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
+  tbl->first_ent = (tbl->first_ent + 1) % GRPC_CHTTP2_MAX_TABLE_COUNT;
+  tbl->num_ents--;
+  grpc_mdelem_unref(first_ent);
+}
+
+void grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
+  /* determine how many bytes of buffer this entry represents */
+  gpr_uint16 elem_bytes = GPR_SLICE_LENGTH(md->key->slice) +
+                          GPR_SLICE_LENGTH(md->value->slice) +
+                          GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
+
+  /* we can't add elements bigger than the max table size */
+  assert(elem_bytes <= tbl->max_bytes);
+
+  /* evict entries to ensure no overflow */
+  while (elem_bytes > tbl->max_bytes - tbl->mem_used) {
+    evict1(tbl);
+  }
+
+  /* copy the finalized entry in */
+  tbl->ents[tbl->last_ent] = md;
+
+  /* update accounting values */
+  tbl->last_ent = (tbl->last_ent + 1) % GRPC_CHTTP2_MAX_TABLE_COUNT;
+  tbl->num_ents++;
+  tbl->mem_used += elem_bytes;
+}
+
+grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
+    const grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
+  grpc_chttp2_hptbl_find_result r = {0, 0};
+  int i;
+
+  /* See if the string is in the static table */
+  for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
+    grpc_mdelem *ent = tbl->static_ents[i];
+    if (md->key != ent->key) continue;
+    r.index = i + 1;
+    r.has_value = md->value == ent->value;
+    if (r.has_value) return r;
+  }
+
+  /* Scan the dynamic table */
+  for (i = 0; i < tbl->num_ents; i++) {
+    int idx = tbl->num_ents - i + GRPC_CHTTP2_LAST_STATIC_ENTRY;
+    grpc_mdelem *ent =
+        tbl->ents[(tbl->first_ent + i) % GRPC_CHTTP2_MAX_TABLE_COUNT];
+    if (md->key != ent->key) continue;
+    r.index = idx;
+    r.has_value = md->value == ent->value;
+    if (r.has_value) return r;
+  }
+
+  return r;
+}
diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h
new file mode 100644
index 0000000..a3a07ad
--- /dev/null
+++ b/src/core/transport/chttp2/hpack_table.h
@@ -0,0 +1,97 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__
+
+#include "src/core/transport/metadata.h"
+#include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+
+/* HPACK header table */
+
+/* last index in the static table */
+#define GRPC_CHTTP2_LAST_STATIC_ENTRY 61
+
+/* Initial table size as per the spec */
+#define GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE 4096
+/* Maximum table size that we'll use */
+#define GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE
+/* Per entry overhead bytes as per the spec */
+#define GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD 32
+/* Maximum number of entries we could possibly fit in the table, given defined
+   overheads */
+#define GRPC_CHTTP2_MAX_TABLE_COUNT                                            \
+  ((GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / \
+   GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD)
+
+/* hpack decoder table */
+typedef struct {
+  grpc_mdctx *mdctx;
+  /* the first used entry in ents */
+  gpr_uint16 first_ent;
+  /* the last used entry in ents */
+  gpr_uint16 last_ent;
+  /* how many entries are in the table */
+  gpr_uint16 num_ents;
+  /* the amount of memory used by the table, according to the hpack algorithm */
+  gpr_uint16 mem_used;
+  /* the max memory allowed to be used by the table, according to the hpack
+     algorithm */
+  gpr_uint16 max_bytes;
+  /* a circular buffer of headers - this is stored in the opposite order to
+     what hpack specifies, in order to simplify table management a little...
+     meaning lookups need to SUBTRACT from the end position */
+  grpc_mdelem *ents[GRPC_CHTTP2_MAX_TABLE_COUNT];
+  grpc_mdelem *static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY];
+} grpc_chttp2_hptbl;
+
+/* initialize a hpack table */
+void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx);
+void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl);
+
+/* lookup a table entry based on its hpack index */
+grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
+                                      gpr_uint32 index);
+/* add a table entry to the index */
+void grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
+/* Find a key/value pair in the table... returns the index in the table of the
+   most similar entry, or 0 if the value was not found */
+typedef struct {
+  gpr_uint16 index;
+  gpr_uint8 has_value;
+} grpc_chttp2_hptbl_find_result;
+grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
+    const grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__ */
diff --git a/src/core/transport/chttp2/hpack_tables.txt b/src/core/transport/chttp2/hpack_tables.txt
new file mode 100644
index 0000000..08842a0
--- /dev/null
+++ b/src/core/transport/chttp2/hpack_tables.txt
@@ -0,0 +1,66 @@
+Static table, from the spec:
+          +-------+-----------------------------+---------------+
+          | Index | Header Name                 | Header Value  |
+          +-------+-----------------------------+---------------+
+          | 1     | :authority                  |               |
+          | 2     | :method                     | GET           |
+          | 3     | :method                     | POST          |
+          | 4     | :path                       | /             |
+          | 5     | :path                       | /index.html   |
+          | 6     | :scheme                     | http          |
+          | 7     | :scheme                     | https         |
+          | 8     | :status                     | 200           |
+          | 9     | :status                     | 204           |
+          | 10    | :status                     | 206           |
+          | 11    | :status                     | 304           |
+          | 12    | :status                     | 400           |
+          | 13    | :status                     | 404           |
+          | 14    | :status                     | 500           |
+          | 15    | accept-charset              |               |
+          | 16    | accept-encoding             | gzip, deflate |
+          | 17    | accept-language             |               |
+          | 18    | accept-ranges               |               |
+          | 19    | accept                      |               |
+          | 20    | access-control-allow-origin |               |
+          | 21    | age                         |               |
+          | 22    | allow                       |               |
+          | 23    | authorization               |               |
+          | 24    | cache-control               |               |
+          | 25    | content-disposition         |               |
+          | 26    | content-encoding            |               |
+          | 27    | content-language            |               |
+          | 28    | content-length              |               |
+          | 29    | content-location            |               |
+          | 30    | content-range               |               |
+          | 31    | content-type                |               |
+          | 32    | cookie                      |               |
+          | 33    | date                        |               |
+          | 34    | etag                        |               |
+          | 35    | expect                      |               |
+          | 36    | expires                     |               |
+          | 37    | from                        |               |
+          | 38    | host                        |               |
+          | 39    | if-match                    |               |
+          | 40    | if-modified-since           |               |
+          | 41    | if-none-match               |               |
+          | 42    | if-range                    |               |
+          | 43    | if-unmodified-since         |               |
+          | 44    | last-modified               |               |
+          | 45    | link                        |               |
+          | 46    | location                    |               |
+          | 47    | max-forwards                |               |
+          | 48    | proxy-authenticate          |               |
+          | 49    | proxy-authorization         |               |
+          | 50    | range                       |               |
+          | 51    | referer                     |               |
+          | 52    | refresh                     |               |
+          | 53    | retry-after                 |               |
+          | 54    | server                      |               |
+          | 55    | set-cookie                  |               |
+          | 56    | strict-transport-security   |               |
+          | 57    | transfer-encoding           |               |
+          | 58    | user-agent                  |               |
+          | 59    | vary                        |               |
+          | 60    | via                         |               |
+          | 61    | www-authenticate            |               |
+          +-------+-----------------------------+---------------+
diff --git a/src/core/transport/chttp2/http2_errors.h b/src/core/transport/chttp2/http2_errors.h
new file mode 100644
index 0000000..d065422
--- /dev/null
+++ b/src/core/transport/chttp2/http2_errors.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__
+
+/* error codes for RST_STREAM from http2 draft 14 section 7 */
+typedef enum {
+  GRPC_CHTTP2_NO_ERROR = 0x0,
+  GRPC_CHTTP2_PROTOCOL_ERROR = 0x1,
+  GRPC_CHTTP2_INTERNAL_ERROR = 0x2,
+  GRPC_CHTTP2_FLOW_CONTROL_ERROR = 0x3,
+  GRPC_CHTTP2_SETTINGS_TIMEOUT = 0x4,
+  GRPC_CHTTP2_STREAM_CLOSED = 0x5,
+  GRPC_CHTTP2_FRAME_SIZE_ERROR = 0x6,
+  GRPC_CHTTP2_REFUSED_STREAM = 0x7,
+  GRPC_CHTTP2_CANCEL = 0x8,
+  GRPC_CHTTP2_COMPRESSION_ERROR = 0x9,
+  GRPC_CHTTP2_CONNECT_ERROR = 0xa,
+  GRPC_CHTTP2_ENHANCE_YOUR_CALM = 0xb,
+  GRPC_CHTTP2_INADEQUATE_SECURITY = 0xc,
+  /* force use of a default clause */
+  GRPC_CHTTP2__ERROR_DO_NOT_USE = -1
+} grpc_chttp2_error_code;
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__ */
diff --git a/src/core/transport/chttp2/status_conversion.c b/src/core/transport/chttp2/status_conversion.c
new file mode 100644
index 0000000..7bd85e8
--- /dev/null
+++ b/src/core/transport/chttp2/status_conversion.c
@@ -0,0 +1,109 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/status_conversion.h"
+
+int grpc_chttp2_grpc_status_to_http2_error(grpc_status_code status) {
+  switch (status) {
+    case GRPC_STATUS_OK:
+      return GRPC_CHTTP2_NO_ERROR;
+    case GRPC_STATUS_CANCELLED:
+      return GRPC_CHTTP2_CANCEL;
+    case GRPC_STATUS_RESOURCE_EXHAUSTED:
+      return GRPC_CHTTP2_ENHANCE_YOUR_CALM;
+    case GRPC_STATUS_PERMISSION_DENIED:
+      return GRPC_CHTTP2_INADEQUATE_SECURITY;
+    case GRPC_STATUS_UNAVAILABLE:
+      return GRPC_CHTTP2_REFUSED_STREAM;
+    default:
+      return GRPC_CHTTP2_INTERNAL_ERROR;
+  }
+}
+
+grpc_status_code grpc_chttp2_http2_error_to_grpc_status(
+    grpc_chttp2_error_code error) {
+  switch (error) {
+    case GRPC_CHTTP2_NO_ERROR:
+      /* should never be received */
+      return GRPC_STATUS_INTERNAL;
+    case GRPC_CHTTP2_CANCEL:
+      return GRPC_STATUS_CANCELLED;
+    case GRPC_CHTTP2_ENHANCE_YOUR_CALM:
+      return GRPC_STATUS_RESOURCE_EXHAUSTED;
+    case GRPC_CHTTP2_INADEQUATE_SECURITY:
+      return GRPC_STATUS_PERMISSION_DENIED;
+    case GRPC_CHTTP2_REFUSED_STREAM:
+      return GRPC_STATUS_UNAVAILABLE;
+    default:
+      return GRPC_STATUS_INTERNAL;
+  }
+}
+
+grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status) {
+  switch (status) {
+    /* these HTTP2 status codes are called out explicitly in status.proto */
+    case 200:
+      return GRPC_STATUS_OK;
+    case 400:
+      return GRPC_STATUS_INVALID_ARGUMENT;
+    case 401:
+      return GRPC_STATUS_UNAUTHENTICATED;
+    case 403:
+      return GRPC_STATUS_PERMISSION_DENIED;
+    case 404:
+      return GRPC_STATUS_NOT_FOUND;
+    case 409:
+      return GRPC_STATUS_ABORTED;
+    case 412:
+      return GRPC_STATUS_FAILED_PRECONDITION;
+    case 429:
+      return GRPC_STATUS_RESOURCE_EXHAUSTED;
+    case 499:
+      return GRPC_STATUS_CANCELLED;
+    case 500:
+      return GRPC_STATUS_UNKNOWN;
+    case 501:
+      return GRPC_STATUS_UNIMPLEMENTED;
+    case 503:
+      return GRPC_STATUS_UNAVAILABLE;
+    case 504:
+      return GRPC_STATUS_DEADLINE_EXCEEDED;
+    /* everything else is unknown */
+    default:
+      return GRPC_STATUS_UNKNOWN;
+  }
+}
+
+int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status) {
+  return 200;
+}
diff --git a/src/core/transport/chttp2/status_conversion.h b/src/core/transport/chttp2/status_conversion.h
new file mode 100644
index 0000000..ae9e7f2
--- /dev/null
+++ b/src/core/transport/chttp2/status_conversion.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__
+
+#include <grpc/grpc.h>
+#include "src/core/transport/chttp2/http2_errors.h"
+
+/* Conversion of grpc status codes to http2 error codes (for RST_STREAM) */
+grpc_chttp2_error_code grpc_chttp2_grpc_status_to_http2_error(
+    grpc_status_code status);
+grpc_status_code grpc_chttp2_http2_error_to_grpc_status(
+    grpc_chttp2_error_code error);
+
+/* Conversion of HTTP status codes (:status) to grpc status codes */
+grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status);
+int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__ */
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
new file mode 100644
index 0000000..d46366d
--- /dev/null
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -0,0 +1,553 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/stream_encoder.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+#include "src/core/transport/chttp2/hpack_table.h"
+#include "src/core/transport/chttp2/timeout_encoding.h"
+#include "src/core/transport/chttp2/varint.h"
+
+#define HASH_FRAGMENT_1(x) ((x)&255)
+#define HASH_FRAGMENT_2(x) ((x >> 8) & 255)
+#define HASH_FRAGMENT_3(x) ((x >> 16) & 255)
+#define HASH_FRAGMENT_4(x) ((x >> 24) & 255)
+
+/* if the probability of this item being seen again is < 1/x then don't add
+   it to the table */
+#define ONE_ON_ADD_PROBABILITY 128
+/* don't consider adding anything bigger than this to the hpack table */
+#define MAX_DECODER_SPACE_USAGE 512
+
+/* what kind of frame our we encoding? */
+typedef enum { HEADER, DATA, NONE } frame_type;
+
+typedef struct {
+  frame_type cur_frame_type;
+  /* number of bytes in 'output' when we started the frame - used to calculate
+     frame length */
+  size_t output_length_at_start_of_frame;
+  /* index (in output) of the header for the current frame */
+  size_t header_idx;
+  /* was the last frame emitted a header? (if yes, we'll need a CONTINUATION */
+  gpr_uint8 last_was_header;
+  /* output stream id */
+  gpr_uint32 stream_id;
+  /* number of flow controlled bytes written */
+  gpr_uint32 output_size;
+  gpr_slice_buffer *output;
+} framer_state;
+
+/* fills p (which is expected to be 9 bytes long) with a data frame header */
+static void fill_header(gpr_uint8 *p, gpr_uint8 type, gpr_uint32 id,
+                        gpr_uint32 len, gpr_uint8 flags) {
+  *p++ = len >> 16;
+  *p++ = len >> 8;
+  *p++ = len;
+  *p++ = type;
+  *p++ = flags;
+  *p++ = id >> 24;
+  *p++ = id >> 16;
+  *p++ = id >> 8;
+  *p++ = id;
+}
+
+/* finish a frame - fill in the previously reserved header */
+static void finish_frame(framer_state *st, int is_header_boundary,
+                         int is_last_in_stream) {
+  gpr_uint8 type = 0xff;
+  switch (st->cur_frame_type) {
+    case HEADER:
+      type = st->last_was_header ? GRPC_CHTTP2_FRAME_CONTINUATION
+                                 : GRPC_CHTTP2_FRAME_HEADER;
+      st->last_was_header = 1;
+      break;
+    case DATA:
+      type = GRPC_CHTTP2_FRAME_DATA;
+      st->last_was_header = 0;
+      is_header_boundary = 0;
+      break;
+    case NONE:
+      return;
+  }
+  fill_header(GPR_SLICE_START_PTR(st->output->slices[st->header_idx]), type,
+              st->stream_id,
+              st->output->length - st->output_length_at_start_of_frame,
+              (is_last_in_stream ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0) |
+                  (is_header_boundary ? GRPC_CHTTP2_DATA_FLAG_END_HEADERS : 0));
+  st->cur_frame_type = NONE;
+}
+
+/* begin a new frame: reserve off header space, remember how many bytes we'd
+   output before beginning */
+static void begin_frame(framer_state *st, frame_type type) {
+  GPR_ASSERT(type != NONE);
+  GPR_ASSERT(st->cur_frame_type == NONE);
+  st->cur_frame_type = type;
+  st->header_idx =
+      gpr_slice_buffer_add_indexed(st->output, gpr_slice_malloc(9));
+  st->output_length_at_start_of_frame = st->output->length;
+}
+
+/* make sure that the current frame is of the type desired, and has sufficient
+   space to add at least about_to_add bytes -- finishes the current frame if
+   needed */
+static void ensure_frame_type(framer_state *st, frame_type type,
+                              int need_bytes) {
+  if (st->cur_frame_type == type &&
+      st->output->length - st->output_length_at_start_of_frame + need_bytes <=
+          GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) {
+    return;
+  }
+  finish_frame(st, type != HEADER, 0);
+  begin_frame(st, type);
+}
+
+/* increment a filter count, halve all counts if one element reaches max */
+static void inc_filter(gpr_uint8 idx, gpr_uint32 *sum, gpr_uint8 *elems) {
+  elems[idx]++;
+  if (elems[idx] < 255) {
+    (*sum)++;
+  } else {
+    int i;
+    *sum = 0;
+    for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_FILTERS; i++) {
+      elems[i] /= 2;
+      (*sum) += elems[i];
+    }
+  }
+}
+
+static void add_header_data(framer_state *st, gpr_slice slice) {
+  size_t len = GPR_SLICE_LENGTH(slice);
+  size_t remaining;
+  if (len == 0) return;
+  ensure_frame_type(st, HEADER, 1);
+  remaining = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
+              st->output_length_at_start_of_frame - st->output->length;
+  if (len <= remaining) {
+    gpr_slice_buffer_add(st->output, slice);
+  } else {
+    gpr_slice_buffer_add(st->output, gpr_slice_split_head(&slice, remaining));
+    add_header_data(st, slice);
+  }
+}
+
+static gpr_uint8 *add_tiny_header_data(framer_state *st, int len) {
+  ensure_frame_type(st, HEADER, len);
+  return gpr_slice_buffer_tiny_add(st->output, len);
+}
+
+static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
+  gpr_uint32 key_hash = elem->key->hash;
+  gpr_uint32 elem_hash = key_hash ^ elem->value->hash;
+  gpr_uint32 new_index = c->tail_remote_index + c->table_elems + 1;
+  gpr_uint32 elem_size = 32 + GPR_SLICE_LENGTH(elem->key->slice) +
+                         GPR_SLICE_LENGTH(elem->value->slice);
+  int drop_ref;
+
+  /* Reserve space for this element in the remote table: if this overflows
+     the current table, drop elements until it fits, matching the decompressor
+     algorithm */
+  /* TODO(ctiller): constant */
+  while (c->table_size + elem_size > 4096) {
+    c->tail_remote_index++;
+    GPR_ASSERT(c->tail_remote_index > 0);
+    GPR_ASSERT(c->table_size >=
+               c->table_elem_size[c->tail_remote_index %
+                                  GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS]);
+    GPR_ASSERT(c->table_elems > 0);
+    c->table_size -= c->table_elem_size[c->tail_remote_index %
+                                        GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS];
+    c->table_elems--;
+  }
+  GPR_ASSERT(c->table_elems < GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS);
+  c->table_elem_size[new_index % GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS] =
+      elem_size;
+  c->table_size += elem_size;
+  c->table_elems++;
+
+  /* Store this element into {entries,indices}_elem */
+  if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem) {
+    /* already there: update with new index */
+    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
+    drop_ref = 1;
+  } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem) {
+    /* already there (cuckoo): update with new index */
+    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
+    drop_ref = 1;
+  } else if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == NULL) {
+    /* not there, but a free element: add */
+    c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = elem;
+    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
+    drop_ref = 0;
+  } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == NULL) {
+    /* not there (cuckoo), but a free element: add */
+    c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = elem;
+    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
+    drop_ref = 0;
+  } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
+             c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
+    /* not there: replace oldest */
+    grpc_mdelem_unref(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
+    c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = elem;
+    c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
+    drop_ref = 0;
+  } else {
+    /* not there: replace oldest */
+    grpc_mdelem_unref(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
+    c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = elem;
+    c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
+    drop_ref = 0;
+  }
+
+  /* do exactly the same for the key (so we can find by that again too) */
+
+  if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key) {
+    c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
+  } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key) {
+    c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
+  } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == NULL) {
+    c->entries_keys[HASH_FRAGMENT_2(key_hash)] = grpc_mdstr_ref(elem->key);
+    c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
+  } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == NULL) {
+    c->entries_keys[HASH_FRAGMENT_3(key_hash)] = grpc_mdstr_ref(elem->key);
+    c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
+  } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] <
+             c->indices_keys[HASH_FRAGMENT_3(key_hash)]) {
+    grpc_mdstr_unref(c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
+    c->entries_keys[HASH_FRAGMENT_2(key_hash)] = grpc_mdstr_ref(elem->key);
+    c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
+  } else {
+    grpc_mdstr_unref(c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
+    c->entries_keys[HASH_FRAGMENT_3(key_hash)] = grpc_mdstr_ref(elem->key);
+    c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
+  }
+
+  if (drop_ref) {
+    grpc_mdelem_unref(elem);
+  }
+}
+
+static void emit_indexed(grpc_chttp2_hpack_compressor *c, gpr_uint32 index,
+                         framer_state *st) {
+  int len = GRPC_CHTTP2_VARINT_LENGTH(index, 1);
+  GRPC_CHTTP2_WRITE_VARINT(index, 1, 0x80, add_tiny_header_data(st, len), len);
+}
+
+static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c,
+                               gpr_uint32 key_index, grpc_mdstr *value,
+                               framer_state *st) {
+  int len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2);
+  int len_val = GPR_SLICE_LENGTH(value->slice);
+  int len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40,
+                           add_tiny_header_data(st, len_pfx), len_pfx);
+  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, 0x00,
+                           add_tiny_header_data(st, len_val_len), len_val_len);
+  add_header_data(st, gpr_slice_ref(value->slice));
+}
+
+static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c,
+                              gpr_uint32 key_index, grpc_mdstr *value,
+                              framer_state *st) {
+  int len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4);
+  int len_val = GPR_SLICE_LENGTH(value->slice);
+  int len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00,
+                           add_tiny_header_data(st, len_pfx), len_pfx);
+  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, 0x00,
+                           add_tiny_header_data(st, len_val_len), len_val_len);
+  add_header_data(st, gpr_slice_ref(value->slice));
+}
+
+static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
+                                 grpc_mdstr *key, grpc_mdstr *value,
+                                 framer_state *st) {
+  int len_key = GPR_SLICE_LENGTH(key->slice);
+  int len_val = GPR_SLICE_LENGTH(value->slice);
+  int len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1);
+  int len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  *add_tiny_header_data(st, 1) = 0x40;
+  GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
+                           add_tiny_header_data(st, len_key_len), len_key_len);
+  add_header_data(st, gpr_slice_ref(key->slice));
+  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, 0x00,
+                           add_tiny_header_data(st, len_val_len), len_val_len);
+  add_header_data(st, gpr_slice_ref(value->slice));
+}
+
+static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
+                                grpc_mdstr *key, grpc_mdstr *value,
+                                framer_state *st) {
+  int len_key = GPR_SLICE_LENGTH(key->slice);
+  int len_val = GPR_SLICE_LENGTH(value->slice);
+  int len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1);
+  int len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1);
+  *add_tiny_header_data(st, 1) = 0x00;
+  GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
+                           add_tiny_header_data(st, len_key_len), len_key_len);
+  add_header_data(st, gpr_slice_ref(key->slice));
+  GRPC_CHTTP2_WRITE_VARINT(len_val, 1, 0x00,
+                           add_tiny_header_data(st, len_val_len), len_val_len);
+  add_header_data(st, gpr_slice_ref(value->slice));
+}
+
+static gpr_uint32 dynidx(grpc_chttp2_hpack_compressor *c, gpr_uint32 index) {
+  return 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY + c->tail_remote_index +
+         c->table_elems - index;
+}
+
+/* encode an mdelem, taking ownership of it */
+static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
+                      framer_state *st) {
+  gpr_uint32 key_hash = elem->key->hash;
+  gpr_uint32 elem_hash = key_hash ^ elem->value->hash;
+  size_t decoder_space_usage;
+  int should_add_elem;
+
+  inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum, c->filter_elems);
+
+  /* is this elem currently in the decoders table? */
+
+  if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem &&
+      c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) {
+    /* HIT: complete element (first cuckoo hash) */
+    emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]),
+                 st);
+    grpc_mdelem_unref(elem);
+    return;
+  }
+
+  if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem &&
+      c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) {
+    /* HIT: complete element (second cuckoo hash) */
+    emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]),
+                 st);
+    grpc_mdelem_unref(elem);
+    return;
+  }
+
+  /* should this elem be in the table? */
+  decoder_space_usage = 32 + GPR_SLICE_LENGTH(elem->key->slice) +
+                        GPR_SLICE_LENGTH(elem->value->slice);
+  should_add_elem = decoder_space_usage < MAX_DECODER_SPACE_USAGE &&
+                    c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >=
+                        c->filter_elems_sum / ONE_ON_ADD_PROBABILITY;
+
+  /* no hits for the elem... maybe there's a key? */
+
+  if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key &&
+      c->indices_keys[HASH_FRAGMENT_2(key_hash)] > c->tail_remote_index) {
+    /* HIT: key (first cuckoo hash) */
+    if (should_add_elem) {
+      emit_lithdr_incidx(c,
+                         dynidx(c, c->indices_keys[HASH_FRAGMENT_2(key_hash)]),
+                         elem->value, st);
+      add_elem(c, elem);
+    } else {
+      emit_lithdr_noidx(c,
+                        dynidx(c, c->indices_keys[HASH_FRAGMENT_2(key_hash)]),
+                        elem->value, st);
+      grpc_mdelem_unref(elem);
+    }
+    return;
+  }
+
+  if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key &&
+      c->indices_keys[HASH_FRAGMENT_3(key_hash)] > c->tail_remote_index) {
+    /* HIT: key (first cuckoo hash) */
+    if (should_add_elem) {
+      emit_lithdr_incidx(c,
+                         dynidx(c, c->indices_keys[HASH_FRAGMENT_3(key_hash)]),
+                         elem->value, st);
+      add_elem(c, elem);
+    } else {
+      emit_lithdr_noidx(c,
+                        dynidx(c, c->indices_keys[HASH_FRAGMENT_3(key_hash)]),
+                        elem->value, st);
+      grpc_mdelem_unref(elem);
+    }
+    return;
+  }
+
+  /* no elem, key in the table... fall back to literal emission */
+
+  if (should_add_elem) {
+    emit_lithdr_incidx_v(c, elem->key, elem->value, st);
+    add_elem(c, elem);
+  } else {
+    emit_lithdr_noidx_v(c, elem->key, elem->value, st);
+    grpc_mdelem_unref(elem);
+  }
+}
+
+#define STRLEN_LIT(x) (sizeof(x) - 1)
+#define TIMEOUT_KEY "grpc-timeout"
+
+static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
+                         framer_state *st) {
+  char timeout_str[32];
+  grpc_chttp2_encode_timeout(gpr_time_sub(deadline, gpr_now()), timeout_str);
+  hpack_enc(c, grpc_mdelem_from_metadata_strings(
+                   c->mdctx, grpc_mdstr_ref(c->timeout_key_str),
+                   grpc_mdstr_from_string(c->mdctx, timeout_str)),
+            st);
+}
+
+gpr_slice grpc_chttp2_data_frame_create_empty_close(gpr_uint32 id) {
+  gpr_slice slice = gpr_slice_malloc(9);
+  fill_header(GPR_SLICE_START_PTR(slice), GRPC_CHTTP2_FRAME_DATA, id, 0, 1);
+  return slice;
+}
+
+void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
+                                       grpc_mdctx *ctx) {
+  memset(c, 0, sizeof(*c));
+  c->mdctx = ctx;
+  c->timeout_key_str = grpc_mdstr_from_string(ctx, "grpc-timeout");
+}
+
+void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
+  int i;
+  for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) {
+    if (c->entries_keys[i]) grpc_mdstr_unref(c->entries_keys[i]);
+    if (c->entries_elems[i]) grpc_mdelem_unref(c->entries_elems[i]);
+  }
+  grpc_mdstr_unref(c->timeout_key_str);
+}
+
+gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
+                                   int eof, gpr_slice_buffer *output,
+                                   gpr_uint32 max_bytes, gpr_uint32 stream_id,
+                                   grpc_chttp2_hpack_compressor *compressor) {
+  framer_state st;
+  gpr_slice slice;
+  grpc_stream_op *op;
+  gpr_uint32 max_take_size;
+  gpr_uint32 curop = 0;
+  gpr_uint32 nops = *ops_count;
+  gpr_uint8 *p;
+
+  GPR_ASSERT(stream_id != 0);
+
+  st.cur_frame_type = NONE;
+  st.last_was_header = 0;
+  st.stream_id = stream_id;
+  st.output = output;
+  st.output_size = 0;
+
+  while (curop < nops) {
+    GPR_ASSERT(st.output_size <= max_bytes);
+    op = &ops[curop];
+    switch (op->type) {
+      case GRPC_NO_OP:
+        curop++;
+        break;
+      case GRPC_OP_FLOW_CTL_CB:
+        op->data.flow_ctl_cb.cb(op->data.flow_ctl_cb.arg, GRPC_OP_OK);
+        curop++;
+        break;
+      case GRPC_OP_METADATA:
+        hpack_enc(compressor, op->data.metadata, &st);
+        curop++;
+        break;
+      case GRPC_OP_DEADLINE:
+        deadline_enc(compressor, op->data.deadline, &st);
+        curop++;
+        break;
+      case GRPC_OP_METADATA_BOUNDARY:
+        ensure_frame_type(&st, HEADER, 0);
+        finish_frame(&st, 1, 0);
+        st.last_was_header = 0; /* force a new header frame */
+        curop++;
+        break;
+      case GRPC_OP_BEGIN_MESSAGE:
+        /* begin op: for now we just convert the op to a slice and fall
+           through - this lets us reuse the slice framing code below */
+        slice = gpr_slice_malloc(5);
+        p = GPR_SLICE_START_PTR(slice);
+        p[0] = 0;
+        p[1] = op->data.begin_message.length >> 24;
+        p[2] = op->data.begin_message.length >> 16;
+        p[3] = op->data.begin_message.length >> 8;
+        p[4] = op->data.begin_message.length;
+        op->type = GRPC_OP_SLICE;
+        op->data.slice = slice;
+      /* fallthrough */
+      case GRPC_OP_SLICE:
+        slice = op->data.slice;
+        if (!GPR_SLICE_LENGTH(slice)) {
+          curop++;
+          break;
+        }
+        if (st.output_size == max_bytes) {
+          goto exit_loop;
+        }
+        if (st.cur_frame_type == DATA &&
+            st.output->length - st.output_length_at_start_of_frame ==
+                GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) {
+          finish_frame(&st, 0, 0);
+        }
+        ensure_frame_type(&st, DATA, 1);
+        max_take_size =
+            GPR_MIN(max_bytes - st.output_size,
+                    GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
+                        st.output_length_at_start_of_frame - st.output->length);
+        if (GPR_SLICE_LENGTH(slice) > max_take_size) {
+          slice = gpr_slice_split_head(&op->data.slice, max_take_size);
+        } else {
+          /* consume this op immediately */
+          curop++;
+        }
+        st.output_size += GPR_SLICE_LENGTH(slice);
+        gpr_slice_buffer_add(output, slice);
+        break;
+    }
+  }
+exit_loop:
+  if (eof && st.cur_frame_type == NONE) {
+    begin_frame(&st, DATA);
+  }
+  finish_frame(&st, 1, eof && curop == nops);
+
+  nops -= curop;
+  *ops_count = nops;
+  memmove(ops, ops + curop, nops * sizeof(grpc_stream_op));
+
+  return st.output_size;
+}
diff --git a/src/core/transport/chttp2/stream_encoder.h b/src/core/transport/chttp2/stream_encoder.h
new file mode 100644
index 0000000..dad6469
--- /dev/null
+++ b/src/core/transport/chttp2/stream_encoder.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__
+
+#include "src/core/transport/chttp2/frame.h"
+#include "src/core/transport/metadata.h"
+#include "src/core/transport/stream_op.h"
+#include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
+
+#define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256
+#define GRPC_CHTTP2_HPACKC_NUM_VALUES 256
+#define GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS (4096 / 32)
+
+typedef struct {
+  gpr_uint32 filter_elems_sum;
+  /* one before the lowest usable table index */
+  gpr_uint32 tail_remote_index;
+  gpr_uint16 table_size;
+  gpr_uint16 table_elems;
+
+  /* filter tables for elems: this tables provides an approximate
+     popularity count for particular hashes, and are used to determine whether
+     a new literal should be added to the compression table or not.
+     They track a single integer that counts how often a particular value has
+     been seen. When that count reaches max (255), all values are halved. */
+  gpr_uint8 filter_elems[GRPC_CHTTP2_HPACKC_NUM_FILTERS];
+
+  /* metadata context */
+  grpc_mdctx *mdctx;
+  /* the string 'grpc-timeout' */
+  grpc_mdstr *timeout_key_str;
+
+  /* entry tables for keys & elems: these tables track values that have been
+     seen and *may* be in the decompressor table */
+  grpc_mdstr *entries_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES];
+  grpc_mdelem *entries_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES];
+  gpr_uint32 indices_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES];
+  gpr_uint32 indices_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES];
+
+  gpr_uint16 table_elem_size[GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS];
+} grpc_chttp2_hpack_compressor;
+
+void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
+                                       grpc_mdctx *mdctx);
+void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c);
+
+gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
+                                   int eof, gpr_slice_buffer *output,
+                                   gpr_uint32 max_bytes, gpr_uint32 stream_id,
+                                   grpc_chttp2_hpack_compressor *compressor);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__ */
diff --git a/src/core/transport/chttp2/stream_map.c b/src/core/transport/chttp2/stream_map.c
new file mode 100644
index 0000000..9ac3a47
--- /dev/null
+++ b/src/core/transport/chttp2/stream_map.c
@@ -0,0 +1,154 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/stream_map.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+void grpc_chttp2_stream_map_init(grpc_chttp2_stream_map *map,
+                                 size_t initial_capacity) {
+  GPR_ASSERT(initial_capacity > 1);
+  map->keys = gpr_malloc(sizeof(gpr_uint32) * initial_capacity);
+  map->values = gpr_malloc(sizeof(void *) * initial_capacity);
+  map->count = 0;
+  map->free = 0;
+  map->capacity = initial_capacity;
+}
+
+void grpc_chttp2_stream_map_destroy(grpc_chttp2_stream_map *map) {
+  gpr_free(map->keys);
+  gpr_free(map->values);
+}
+
+static size_t compact(gpr_uint32 *keys, void **values, size_t count) {
+  size_t i, out;
+
+  for (i = 0, out = 0; i < count; i++) {
+    if (values[i]) {
+      keys[out] = keys[i];
+      values[out] = values[i];
+      out++;
+    }
+  }
+
+  return out;
+}
+
+void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, gpr_uint32 key,
+                                void *value) {
+  size_t count = map->count;
+  size_t capacity = map->capacity;
+  gpr_uint32 *keys = map->keys;
+  void **values = map->values;
+
+  GPR_ASSERT(count == 0 || keys[count - 1] < key);
+  GPR_ASSERT(value);
+
+  if (count == capacity) {
+    if (map->free > capacity / 4) {
+      count = compact(keys, values, count);
+      map->free = 0;
+    } else {
+      /* resize when less than 25% of the table is free, because compaction
+         won't help much */
+      map->capacity = capacity = 3 * capacity / 2;
+      map->keys = keys = gpr_realloc(keys, capacity * sizeof(gpr_uint32));
+      map->values = values = gpr_realloc(values, capacity * sizeof(void *));
+    }
+  }
+
+  keys[count] = key;
+  values[count] = value;
+  map->count = count + 1;
+}
+
+static void **find(grpc_chttp2_stream_map *map, gpr_uint32 key) {
+  size_t min_idx = 0;
+  size_t max_idx = map->count;
+  size_t mid_idx;
+  gpr_uint32 *keys = map->keys;
+  void **values = map->values;
+  gpr_uint32 mid_key;
+
+  if (max_idx == 0) return NULL;
+
+  while (min_idx < max_idx) {
+    /* find the midpoint, avoiding overflow */
+    mid_idx = min_idx + ((max_idx - min_idx) / 2);
+    mid_key = keys[mid_idx];
+
+    if (mid_key < key) {
+      min_idx = mid_idx + 1;
+    } else if (mid_key > key) {
+      max_idx = mid_idx;
+    } else /* mid_key == key */ {
+      return &values[mid_idx];
+    }
+  }
+
+  return NULL;
+}
+
+void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map,
+                                    gpr_uint32 key) {
+  void **pvalue = find(map, key);
+  void *out = NULL;
+  if (pvalue != NULL) {
+    out = *pvalue;
+    *pvalue = NULL;
+    map->free += (out != NULL);
+  }
+  return out;
+}
+
+void *grpc_chttp2_stream_map_find(grpc_chttp2_stream_map *map, gpr_uint32 key) {
+  void **pvalue = find(map, key);
+  return pvalue != NULL ? *pvalue : NULL;
+}
+
+size_t grpc_chttp2_stream_map_size(grpc_chttp2_stream_map *map) {
+  return map->count - map->free;
+}
+
+void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map,
+                                     void (*f)(void *user_data, gpr_uint32 key,
+                                               void *value),
+                                     void *user_data) {
+  size_t i;
+
+  for (i = 0; i < map->count; i++) {
+    if (map->values[i]) {
+      f(user_data, map->keys[i], map->values[i]);
+    }
+  }
+}
diff --git a/src/core/transport/chttp2/stream_map.h b/src/core/transport/chttp2/stream_map.h
new file mode 100644
index 0000000..caaee30
--- /dev/null
+++ b/src/core/transport/chttp2/stream_map.h
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__
+
+#include <grpc/support/port_platform.h>
+
+#include <stddef.h>
+
+/* Data structure to map a gpr_uint32 to a data object (represented by a void*)
+
+   Represented as a sorted array of keys, and a corresponding array of values.
+   Lookups are performed with binary search.
+   Adds are restricted to strictly higher keys than previously seen (this is
+   guaranteed by http2). */
+typedef struct {
+  gpr_uint32 *keys;
+  void **values;
+  size_t count;
+  size_t free;
+  size_t capacity;
+} grpc_chttp2_stream_map;
+
+void grpc_chttp2_stream_map_init(grpc_chttp2_stream_map *map,
+                                 size_t initial_capacity);
+void grpc_chttp2_stream_map_destroy(grpc_chttp2_stream_map *map);
+
+/* Add a new key: given http2 semantics, new keys must always be greater than
+   existing keys - this is asserted */
+void grpc_chttp2_stream_map_add(grpc_chttp2_stream_map *map, gpr_uint32 key,
+                                void *value);
+
+/* Delete an existing key - returns the previous value of the key if it existed,
+   or NULL otherwise */
+void *grpc_chttp2_stream_map_delete(grpc_chttp2_stream_map *map,
+                                    gpr_uint32 key);
+
+/* Return an existing key, or NULL if it does not exist */
+void *grpc_chttp2_stream_map_find(grpc_chttp2_stream_map *map, gpr_uint32 key);
+
+/* How many (populated) entries are in the stream map? */
+size_t grpc_chttp2_stream_map_size(grpc_chttp2_stream_map *map);
+
+/* Callback on each stream */
+void grpc_chttp2_stream_map_for_each(grpc_chttp2_stream_map *map,
+                                     void (*f)(void *user_data, gpr_uint32 key,
+                                               void *value),
+                                     void *user_data);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__ */
diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c
new file mode 100644
index 0000000..2706c36
--- /dev/null
+++ b/src/core/transport/chttp2/timeout_encoding.c
@@ -0,0 +1,176 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/timeout_encoding.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static int round_up(int x, int divisor) {
+  return (x / divisor + (x % divisor != 0)) * divisor;
+}
+
+/* round an integer up to the next value with three significant figures */
+static int round_up_to_three_sig_figs(int x) {
+  if (x < 1000) return x;
+  if (x < 10000) return round_up(x, 10);
+  if (x < 100000) return round_up(x, 100);
+  if (x < 1000000) return round_up(x, 1000);
+  if (x < 10000000) return round_up(x, 10000);
+  if (x < 100000000) return round_up(x, 100000);
+  if (x < 1000000000) return round_up(x, 1000000);
+  return round_up(x, 10000000);
+}
+
+/* encode our minimum viable timeout value */
+static void enc_tiny(char *buffer) { strcpy(buffer, "1n"); }
+
+static void enc_seconds(char *buffer, long sec) {
+  if (sec % 3600 == 0) {
+    sprintf(buffer, "%ldH", sec / 3600);
+  } else if (sec % 60 == 0) {
+    sprintf(buffer, "%ldM", sec / 60);
+  } else {
+    sprintf(buffer, "%ldS", sec);
+  }
+}
+
+static void enc_nanos(char *buffer, int x) {
+  x = round_up_to_three_sig_figs(x);
+  if (x < 100000) {
+    if (x % 1000 == 0) {
+      sprintf(buffer, "%du", x / 1000);
+    } else {
+      sprintf(buffer, "%dn", x);
+    }
+  } else if (x < 100000000) {
+    if (x % 1000000 == 0) {
+      sprintf(buffer, "%dm", x / 1000000);
+    } else {
+      sprintf(buffer, "%du", x / 1000);
+    }
+  } else if (x < 1000000000) {
+    sprintf(buffer, "%dm", x / 1000000);
+  } else {
+    /* note that this is only ever called with times of less than one second,
+       so if we reach here the time must have been rounded up to a whole second
+       (and no more) */
+    strcpy(buffer, "1S");
+  }
+}
+
+static void enc_micros(char *buffer, int x) {
+  x = round_up_to_three_sig_figs(x);
+  if (x < 100000) {
+    if (x % 1000 == 0) {
+      sprintf(buffer, "%dm", x / 1000);
+    } else {
+      sprintf(buffer, "%du", x);
+    }
+  } else if (x < 100000000) {
+    if (x % 1000000 == 0) {
+      sprintf(buffer, "%dS", x / 1000000);
+    } else {
+      sprintf(buffer, "%dm", x / 1000);
+    }
+  } else {
+    sprintf(buffer, "%dS", x / 1000000);
+  }
+}
+
+void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer) {
+  if (timeout.tv_sec < 0) {
+    enc_tiny(buffer);
+  } else if (timeout.tv_sec == 0) {
+    enc_nanos(buffer, timeout.tv_nsec);
+  } else if (timeout.tv_sec < 1000 && timeout.tv_nsec != 0) {
+    enc_micros(buffer,
+               timeout.tv_sec * 1000000 +
+                   (timeout.tv_nsec / 1000 + (timeout.tv_nsec % 1000 != 0)));
+  } else {
+    enc_seconds(buffer, timeout.tv_sec + (timeout.tv_nsec != 0));
+  }
+}
+
+static int is_all_whitespace(const char *p) {
+  while (*p == ' ') p++;
+  return *p == 0;
+}
+
+int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) {
+  gpr_uint32 x = 0;
+  const char *p = buffer;
+  int have_digit = 0;
+  /* skip whitespace */
+  for (; *p == ' '; p++)
+    ;
+  /* decode numeric part */
+  for (; *p >= '0' && *p <= '9'; p++) {
+    gpr_uint32 xp = x * 10 + *p - '0';
+    have_digit = 1;
+    if (xp < x) {
+      *timeout = gpr_inf_future;
+      return 1;
+    }
+    x = xp;
+  }
+  if (!have_digit) return 0;
+  /* skip whitespace */
+  for (; *p == ' '; p++)
+    ;
+  /* decode unit specifier */
+  switch (*p) {
+    case 'n':
+      *timeout = gpr_time_from_nanos(x);
+      break;
+    case 'u':
+      *timeout = gpr_time_from_micros(x);
+      break;
+    case 'm':
+      *timeout = gpr_time_from_millis(x);
+      break;
+    case 'S':
+      *timeout = gpr_time_from_seconds(x);
+      break;
+    case 'M':
+      *timeout = gpr_time_from_minutes(x);
+      break;
+    case 'H':
+      *timeout = gpr_time_from_hours(x);
+      break;
+    default:
+      return 0;
+  }
+  p++;
+  return is_all_whitespace(p);
+}
diff --git a/src/core/transport/chttp2/timeout_encoding.h b/src/core/transport/chttp2/timeout_encoding.h
new file mode 100644
index 0000000..a458256
--- /dev/null
+++ b/src/core/transport/chttp2/timeout_encoding.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H_
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H_
+
+#include <grpc/support/time.h>
+
+/* Encode/decode timeouts to the GRPC over HTTP2 format;
+   encoding may round up arbitrarily */
+void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer);
+int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout);
+
+#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H_ */
diff --git a/src/core/transport/chttp2/varint.c b/src/core/transport/chttp2/varint.c
new file mode 100644
index 0000000..5d551be
--- /dev/null
+++ b/src/core/transport/chttp2/varint.c
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2/varint.h"
+
+int grpc_chttp2_hpack_varint_length(gpr_uint32 tail_value) {
+  if (tail_value < (1 << 7)) {
+    return 2;
+  } else if (tail_value < (1 << 14)) {
+    return 3;
+  } else if (tail_value < (1 << 21)) {
+    return 4;
+  } else if (tail_value < (1 << 28)) {
+    return 5;
+  } else {
+    return 6;
+  }
+}
+
+void grpc_chttp2_hpack_write_varint_tail(gpr_uint32 tail_value,
+                                         gpr_uint8* target, int tail_length) {
+  switch (tail_length) {
+    case 5:
+      target[4] = (gpr_uint8)((tail_value >> 28) | 0x80);
+    case 4:
+      target[3] = (gpr_uint8)((tail_value >> 21) | 0x80);
+    case 3:
+      target[2] = (gpr_uint8)((tail_value >> 14) | 0x80);
+    case 2:
+      target[1] = (gpr_uint8)((tail_value >> 7) | 0x80);
+    case 1:
+      target[0] = (gpr_uint8)((tail_value) | 0x80);
+  }
+  target[tail_length - 1] &= 0x7f;
+}
diff --git a/src/core/transport/chttp2/varint.h b/src/core/transport/chttp2/varint.h
new file mode 100644
index 0000000..7803902
--- /dev/null
+++ b/src/core/transport/chttp2/varint.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__
+
+#include <grpc/support/port_platform.h>
+
+/* Helpers for hpack varint encoding */
+
+/* length of a value that needs varint tail encoding (it's bigger than can be
+   bitpacked into the opcode byte) - returned value includes the length of the
+   opcode byte */
+int grpc_chttp2_hpack_varint_length(gpr_uint32 tail_value);
+
+void grpc_chttp2_hpack_write_varint_tail(gpr_uint32 tail_value,
+                                         gpr_uint8* target, int tail_length);
+
+/* maximum value that can be bitpacked with the opcode if the opcode has a
+   prefix
+   of length prefix_bits */
+#define GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits) ((1 << (8 - (prefix_bits))) - 1)
+
+/* length required to bitpack a value */
+#define GRPC_CHTTP2_VARINT_LENGTH(n, prefix_bits) \
+  ((n) < GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits)   \
+       ? 1                                        \
+       : grpc_chttp2_hpack_varint_length(         \
+             (n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits)))
+
+#define GRPC_CHTTP2_WRITE_VARINT(n, prefix_bits, prefix_or, target, length)   \
+  do {                                                                        \
+    gpr_uint8* tgt = target;                                                  \
+    if ((length) == 1) {                                                      \
+      (tgt)[0] = (prefix_or) | (n);                                           \
+    } else {                                                                  \
+      (tgt)[0] = (prefix_or) | GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits);        \
+      grpc_chttp2_hpack_write_varint_tail(                                    \
+          (n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits), (tgt) + 1, (length)-1); \
+    }                                                                         \
+  } while (0)
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__ */
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
new file mode 100644
index 0000000..8a6b427
--- /dev/null
+++ b/src/core/transport/chttp2_transport.c
@@ -0,0 +1,1615 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/chttp2_transport.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice_buffer.h>
+#include <grpc/support/string.h>
+#include <grpc/support/useful.h>
+#include "src/core/transport/transport_impl.h"
+#include "src/core/transport/chttp2/http2_errors.h"
+#include "src/core/transport/chttp2/hpack_parser.h"
+#include "src/core/transport/chttp2/frame_data.h"
+#include "src/core/transport/chttp2/frame_ping.h"
+#include "src/core/transport/chttp2/frame_rst_stream.h"
+#include "src/core/transport/chttp2/frame_settings.h"
+#include "src/core/transport/chttp2/frame_window_update.h"
+#include "src/core/transport/chttp2/status_conversion.h"
+#include "src/core/transport/chttp2/stream_encoder.h"
+#include "src/core/transport/chttp2/stream_map.h"
+#include "src/core/transport/chttp2/timeout_encoding.h"
+
+#define DEFAULT_WINDOW 65536
+#define MAX_WINDOW 0x7fffffffu
+
+#define CLIENT_CONNECT_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
+#define CLIENT_CONNECT_STRLEN 24
+
+typedef struct transport transport;
+typedef struct stream stream;
+
+/* streams are kept in various linked lists depending on what things need to
+   happen to them... this enum labels each list */
+typedef enum {
+  /* streams that have pending writes */
+  WRITABLE = 0,
+  /* streams that want to send window updates */
+  WINDOW_UPDATE,
+  /* streams that are waiting to start because there are too many concurrent
+     streams on the connection */
+  WAITING_FOR_CONCURRENCY,
+  /* streams that want to callback the application */
+  PENDING_CALLBACKS,
+  /* streams that *ARE* calling back to the application */
+  EXECUTING_CALLBACKS,
+  STREAM_LIST_COUNT /* must be last */
+} stream_list_id;
+
+/* deframer state for the overall http2 stream of bytes */
+typedef enum {
+  /* prefix: one entry per http2 connection prefix byte */
+  DTS_CLIENT_PREFIX_0 = 0,
+  DTS_CLIENT_PREFIX_1,
+  DTS_CLIENT_PREFIX_2,
+  DTS_CLIENT_PREFIX_3,
+  DTS_CLIENT_PREFIX_4,
+  DTS_CLIENT_PREFIX_5,
+  DTS_CLIENT_PREFIX_6,
+  DTS_CLIENT_PREFIX_7,
+  DTS_CLIENT_PREFIX_8,
+  DTS_CLIENT_PREFIX_9,
+  DTS_CLIENT_PREFIX_10,
+  DTS_CLIENT_PREFIX_11,
+  DTS_CLIENT_PREFIX_12,
+  DTS_CLIENT_PREFIX_13,
+  DTS_CLIENT_PREFIX_14,
+  DTS_CLIENT_PREFIX_15,
+  DTS_CLIENT_PREFIX_16,
+  DTS_CLIENT_PREFIX_17,
+  DTS_CLIENT_PREFIX_18,
+  DTS_CLIENT_PREFIX_19,
+  DTS_CLIENT_PREFIX_20,
+  DTS_CLIENT_PREFIX_21,
+  DTS_CLIENT_PREFIX_22,
+  DTS_CLIENT_PREFIX_23,
+  /* frame header byte 0... */
+  /* must follow from the prefix states */
+  DTS_FH_0,
+  DTS_FH_1,
+  DTS_FH_2,
+  DTS_FH_3,
+  DTS_FH_4,
+  DTS_FH_5,
+  DTS_FH_6,
+  DTS_FH_7,
+  /* ... frame header byte 8 */
+  DTS_FH_8,
+  /* inside a http2 frame */
+  DTS_FRAME
+} deframe_transport_state;
+
+typedef struct {
+  stream *head;
+  stream *tail;
+} stream_list;
+
+typedef struct {
+  stream *next;
+  stream *prev;
+} stream_link;
+
+typedef enum {
+  ERROR_STATE_NONE,
+  ERROR_STATE_SEEN,
+  ERROR_STATE_NOTIFIED
+} error_state;
+
+/* We keep several sets of connection wide parameters */
+typedef enum {
+  /* The settings our peer has asked for (and we have acked) */
+  PEER_SETTINGS = 0,
+  /* The settings we'd like to have */
+  LOCAL_SETTINGS,
+  /* The settings we've published to our peer */
+  SENT_SETTINGS,
+  /* The settings the peer has acked */
+  ACKED_SETTINGS,
+  NUM_SETTING_SETS
+} setting_set;
+
+/* Outstanding ping request data */
+typedef struct {
+  gpr_uint8 id[8];
+  void (*cb)(void *user_data);
+  void *user_data;
+} outstanding_ping;
+
+struct transport {
+  grpc_transport base; /* must be first */
+  const grpc_transport_callbacks *cb;
+  void *cb_user_data;
+  grpc_endpoint *ep;
+  grpc_mdctx *metadata_context;
+  gpr_refcount refs;
+  gpr_uint8 is_client;
+
+  gpr_mu mu;
+  gpr_cv cv;
+
+  /* basic state management - what are we doing at the moment? */
+  gpr_uint8 reading;
+  gpr_uint8 writing;
+  gpr_uint8 calling_back;
+  error_state error_state;
+
+  /* stream indexing */
+  gpr_uint32 next_stream_id;
+
+  /* settings */
+  gpr_uint32 settings[NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS];
+  gpr_uint8 sent_local_settings;
+  gpr_uint8 dirtied_local_settings;
+
+  /* window management */
+  gpr_uint32 outgoing_window;
+  gpr_uint32 incoming_window;
+
+  /* deframing */
+  deframe_transport_state deframe_state;
+  gpr_uint8 incoming_frame_type;
+  gpr_uint8 incoming_frame_flags;
+  gpr_uint8 header_eof;
+  gpr_uint32 expect_continuation_stream_id;
+  gpr_uint32 incoming_frame_size;
+  gpr_uint32 incoming_stream_id;
+
+  /* hpack encoding */
+  grpc_chttp2_hpack_compressor hpack_compressor;
+
+  /* various parsers */
+  grpc_chttp2_hpack_parser hpack_parser;
+  /* simple one shot parsers */
+  union {
+    grpc_chttp2_window_update_parser window_update;
+    grpc_chttp2_settings_parser settings;
+    grpc_chttp2_ping_parser ping;
+  } simple_parsers;
+
+  /* state for a stream that's not yet been created */
+  grpc_stream_op_buffer new_stream_sopb;
+
+  /* active parser */
+  void *parser_data;
+  stream *incoming_stream;
+  grpc_chttp2_parse_error (*parser)(void *parser_user_data,
+                                    grpc_chttp2_parse_state *state,
+                                    gpr_slice slice, int is_last);
+
+  gpr_slice_buffer outbuf;
+  gpr_slice_buffer qbuf;
+
+  stream_list lists[STREAM_LIST_COUNT];
+  grpc_chttp2_stream_map stream_map;
+
+  /* metadata object cache */
+  grpc_mdstr *str_grpc_timeout;
+
+  /* pings */
+  outstanding_ping *pings;
+  size_t ping_count;
+  size_t ping_capacity;
+  gpr_int64 ping_counter;
+};
+
+struct stream {
+  gpr_uint32 id;
+
+  gpr_uint32 outgoing_window;
+  gpr_uint32 incoming_window;
+  gpr_uint8 write_closed;
+  gpr_uint8 read_closed;
+  gpr_uint8 cancelled;
+  gpr_uint8 allow_window_updates;
+  gpr_uint8 published_close;
+
+  stream_link links[STREAM_LIST_COUNT];
+  gpr_uint8 included[STREAM_LIST_COUNT];
+
+  grpc_stream_op_buffer outgoing_sopb;
+
+  grpc_chttp2_data_parser parser;
+
+  grpc_stream_state callback_state;
+  grpc_stream_op_buffer callback_sopb;
+};
+
+static const grpc_transport_vtable vtable;
+
+static void push_setting(transport *t, grpc_chttp2_setting_id id,
+                         gpr_uint32 value);
+
+static int prepare_callbacks(transport *t);
+static void run_callbacks(transport *t);
+
+static int prepare_write(transport *t);
+static void finish_write(void *t, grpc_endpoint_cb_status status);
+
+static void lock(transport *t);
+static void unlock(transport *t);
+
+static void drop_connection(transport *t);
+static void end_all_the_calls(transport *t);
+
+static stream *stream_list_remove_head(transport *t, stream_list_id id);
+static void stream_list_remove(transport *t, stream *s, stream_list_id id);
+static void stream_list_add_tail(transport *t, stream *s, stream_list_id id);
+static void stream_list_join(transport *t, stream *s, stream_list_id id);
+
+static void cancel_stream_id(transport *t, gpr_uint32 id,
+                             grpc_status_code local_status,
+                             grpc_chttp2_error_code error_code, int send_rst);
+static void cancel_stream(transport *t, stream *s,
+                          grpc_status_code local_status,
+                          grpc_chttp2_error_code error_code, int send_rst);
+static stream *lookup_stream(transport *t, gpr_uint32 id);
+static void remove_from_stream_map(transport *t, stream *s);
+static void maybe_start_some_streams(transport *t);
+
+static void become_skip_parser(transport *t);
+
+/*
+ * CONSTRUCTION/DESTRUCTION/REFCOUNTING
+ */
+
+static void unref_transport(transport *t) {
+  size_t i;
+
+  if (!gpr_unref(&t->refs)) return;
+
+  gpr_mu_lock(&t->mu);
+
+  GPR_ASSERT(t->ep == NULL);
+
+  gpr_slice_buffer_destroy(&t->outbuf);
+  gpr_slice_buffer_destroy(&t->qbuf);
+  grpc_chttp2_hpack_parser_destroy(&t->hpack_parser);
+  grpc_chttp2_hpack_compressor_destroy(&t->hpack_compressor);
+
+  grpc_mdstr_unref(t->str_grpc_timeout);
+
+  for (i = 0; i < STREAM_LIST_COUNT; i++) {
+    GPR_ASSERT(t->lists[i].head == NULL);
+    GPR_ASSERT(t->lists[i].tail == NULL);
+  }
+
+  GPR_ASSERT(grpc_chttp2_stream_map_size(&t->stream_map) == 0);
+
+  grpc_chttp2_stream_map_destroy(&t->stream_map);
+
+  gpr_mu_unlock(&t->mu);
+  gpr_mu_destroy(&t->mu);
+
+  /* callback remaining pings: they're not allowed to call into the transpot,
+     and maybe they hold resources that need to be freed */
+  for (i = 0; i < t->ping_count; i++) {
+    t->pings[i].cb(t->pings[i].user_data);
+  }
+  gpr_free(t->pings);
+
+  gpr_free(t);
+}
+
+static void ref_transport(transport *t) { gpr_ref(&t->refs); }
+
+static void init_transport(transport *t, grpc_transport_setup_callback setup,
+                           void *arg, const grpc_channel_args *channel_args,
+                           grpc_endpoint *ep, grpc_mdctx *mdctx,
+                           int is_client) {
+  size_t i;
+  int j;
+  grpc_transport_setup_result sr;
+
+  GPR_ASSERT(strlen(CLIENT_CONNECT_STRING) == CLIENT_CONNECT_STRLEN);
+
+  t->base.vtable = &vtable;
+  t->ep = ep;
+  /* one ref is for destroy, the other for when ep becomes NULL */
+  gpr_ref_init(&t->refs, 2);
+  gpr_mu_init(&t->mu);
+  gpr_cv_init(&t->cv);
+  t->metadata_context = mdctx;
+  t->str_grpc_timeout =
+      grpc_mdstr_from_string(t->metadata_context, "grpc-timeout");
+  t->reading = 1;
+  t->writing = 0;
+  t->error_state = ERROR_STATE_NONE;
+  t->next_stream_id = is_client ? 1 : 2;
+  t->is_client = is_client;
+  t->outgoing_window = DEFAULT_WINDOW;
+  t->incoming_window = DEFAULT_WINDOW;
+  t->deframe_state = is_client ? DTS_FH_0 : DTS_CLIENT_PREFIX_0;
+  t->expect_continuation_stream_id = 0;
+  t->pings = NULL;
+  t->ping_count = 0;
+  t->ping_capacity = 0;
+  t->ping_counter = gpr_now().tv_nsec;
+  grpc_chttp2_hpack_compressor_init(&t->hpack_compressor, mdctx);
+  gpr_slice_buffer_init(&t->outbuf);
+  gpr_slice_buffer_init(&t->qbuf);
+  if (is_client) {
+    gpr_slice_buffer_add(&t->qbuf,
+                         gpr_slice_from_copied_string(CLIENT_CONNECT_STRING));
+  }
+  /* 8 is a random stab in the dark as to a good initial size: it's small enough
+     that it shouldn't waste memory for infrequently used connections, yet
+     large enough that the exponential growth should happen nicely when it's
+     needed.
+     TODO(ctiller): tune this */
+  grpc_chttp2_stream_map_init(&t->stream_map, 8);
+  memset(&t->lists, 0, sizeof(t->lists));
+
+  /* copy in initial settings to all setting sets */
+  for (i = 0; i < NUM_SETTING_SETS; i++) {
+    for (j = 0; j < GRPC_CHTTP2_NUM_SETTINGS; j++) {
+      t->settings[i][j] = grpc_chttp2_settings_parameters[j].default_value;
+    }
+  }
+  t->dirtied_local_settings = 1;
+  t->sent_local_settings = 0;
+
+  /* configure http2 the way we like it */
+  if (t->is_client) {
+    push_setting(t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0);
+    push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0);
+  }
+
+  if (channel_args) {
+    for (i = 0; i < channel_args->num_args; i++) {
+      if (0 ==
+          strcmp(channel_args->args[i].key, GRPC_ARG_MAX_CONCURRENT_STREAMS)) {
+        if (t->is_client) {
+          gpr_log(GPR_ERROR, "%s: is ignored on the client",
+                  GRPC_ARG_MAX_CONCURRENT_STREAMS);
+        } else if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
+          gpr_log(GPR_ERROR, "%s: must be an integer",
+                  GRPC_ARG_MAX_CONCURRENT_STREAMS);
+        } else {
+          push_setting(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
+                       channel_args->args[i].value.integer);
+        }
+      }
+    }
+  }
+
+  gpr_mu_lock(&t->mu);
+  t->calling_back = 1;
+  ref_transport(t);
+  gpr_mu_unlock(&t->mu);
+
+  sr = setup(arg, &t->base, t->metadata_context);
+
+  lock(t);
+  t->cb = sr.callbacks;
+  t->cb_user_data = sr.user_data;
+  grpc_chttp2_hpack_parser_init(&t->hpack_parser, t->metadata_context);
+  t->calling_back = 0;
+  gpr_cv_broadcast(&t->cv);
+  unlock(t);
+  unref_transport(t);
+}
+
+static void destroy_transport(grpc_transport *gt) {
+  transport *t = (transport *)gt;
+
+  gpr_mu_lock(&t->mu);
+  while (t->calling_back) {
+    gpr_cv_wait(&t->cv, &t->mu, gpr_inf_future);
+  }
+  t->cb = NULL;
+  gpr_mu_unlock(&t->mu);
+
+  unref_transport(t);
+}
+
+static void close_transport(grpc_transport *gt) {
+  transport *t = (transport *)gt;
+  gpr_mu_lock(&t->mu);
+  if (t->ep) {
+    grpc_endpoint_shutdown(t->ep);
+  }
+  gpr_mu_unlock(&t->mu);
+}
+
+static int init_stream(grpc_transport *gt, grpc_stream *gs,
+                       const void *server_data) {
+  transport *t = (transport *)gt;
+  stream *s = (stream *)gs;
+
+  ref_transport(t);
+
+  if (!server_data) {
+    lock(t);
+    s->id = 0;
+  } else {
+    s->id = (gpr_uint32)(gpr_uintptr)server_data;
+    t->incoming_stream = s;
+    grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
+  }
+
+  s->outgoing_window = DEFAULT_WINDOW;
+  s->incoming_window = DEFAULT_WINDOW;
+  s->write_closed = 0;
+  s->read_closed = 0;
+  s->cancelled = 0;
+  s->allow_window_updates = 0;
+  s->published_close = 0;
+  memset(&s->links, 0, sizeof(s->links));
+  memset(&s->included, 0, sizeof(s->included));
+  grpc_sopb_init(&s->outgoing_sopb);
+  grpc_chttp2_data_parser_init(&s->parser);
+  grpc_sopb_init(&s->callback_sopb);
+
+  if (!server_data) {
+    unlock(t);
+  }
+
+  return 0;
+}
+
+static void destroy_stream(grpc_transport *gt, grpc_stream *gs) {
+  transport *t = (transport *)gt;
+  stream *s = (stream *)gs;
+  size_t i;
+
+  gpr_mu_lock(&t->mu);
+
+  /* await pending callbacks
+     TODO(ctiller): this could be optimized to check if this stream is getting
+     callbacks */
+  while (t->calling_back) {
+    gpr_cv_wait(&t->cv, &t->mu, gpr_inf_future);
+  }
+
+  /* stop parsing if we're currently parsing this stream */
+  if (t->deframe_state == DTS_FRAME && t->incoming_stream_id == s->id &&
+      s->id != 0) {
+    become_skip_parser(t);
+  }
+
+  for (i = 0; i < STREAM_LIST_COUNT; i++) {
+    stream_list_remove(t, s, i);
+  }
+  remove_from_stream_map(t, s);
+
+  gpr_cv_broadcast(&t->cv);
+  gpr_mu_unlock(&t->mu);
+
+  grpc_sopb_destroy(&s->outgoing_sopb);
+  grpc_chttp2_data_parser_destroy(&s->parser);
+  grpc_sopb_destroy(&s->callback_sopb);
+
+  unref_transport(t);
+}
+
+/*
+ * LIST MANAGEMENT
+ */
+
+static stream *stream_list_remove_head(transport *t, stream_list_id id) {
+  stream *s = t->lists[id].head;
+  if (s) {
+    stream *new_head = s->links[id].next;
+    GPR_ASSERT(s->included[id]);
+    if (new_head) {
+      t->lists[id].head = new_head;
+      new_head->links[id].prev = NULL;
+    } else {
+      t->lists[id].head = NULL;
+      t->lists[id].tail = NULL;
+    }
+    s->included[id] = 0;
+  }
+  return s;
+}
+
+static void stream_list_remove(transport *t, stream *s, stream_list_id id) {
+  if (!s->included[id]) return;
+  s->included[id] = 0;
+  if (s->links[id].prev) {
+    s->links[id].prev->links[id].next = s->links[id].next;
+  } else {
+    GPR_ASSERT(t->lists[id].head == s);
+    t->lists[id].head = s->links[id].next;
+  }
+  if (s->links[id].next) {
+    s->links[id].next->links[id].prev = s->links[id].prev;
+  } else {
+    t->lists[id].tail = s->links[id].prev;
+  }
+}
+
+static void stream_list_add_tail(transport *t, stream *s, stream_list_id id) {
+  stream *old_tail;
+  GPR_ASSERT(!s->included[id]);
+  old_tail = t->lists[id].tail;
+  s->links[id].next = NULL;
+  s->links[id].prev = old_tail;
+  if (old_tail) {
+    old_tail->links[id].next = s;
+  } else {
+    s->links[id].prev = NULL;
+    t->lists[id].head = s;
+  }
+  t->lists[id].tail = s;
+  s->included[id] = 1;
+}
+
+static void stream_list_join(transport *t, stream *s, stream_list_id id) {
+  if (s->included[id]) {
+    return;
+  }
+  stream_list_add_tail(t, s, id);
+}
+
+static void remove_from_stream_map(transport *t, stream *s) {
+  if (s->id == 0) return;
+  if (grpc_chttp2_stream_map_delete(&t->stream_map, s->id)) {
+    maybe_start_some_streams(t);
+  }
+}
+
+/*
+ * LOCK MANAGEMENT
+ */
+
+/* We take a transport-global lock in response to calls coming in from above,
+   and in response to data being received from below. New data to be written
+   is always queued, as are callbacks to process data. During unlock() we
+   check our todo lists and initiate callbacks and flush writes. */
+
+static void lock(transport *t) { gpr_mu_lock(&t->mu); }
+
+static void unlock(transport *t) {
+  int start_write = 0;
+  int perform_callbacks = 0;
+  int call_closed = 0;
+  grpc_endpoint *ep = t->ep;
+
+  /* see if we need to trigger a write - and if so, get the data ready */
+  if (ep && !t->writing) {
+    t->writing = start_write = prepare_write(t);
+    if (start_write) {
+      ref_transport(t);
+    }
+  }
+
+  /* gather any callbacks that need to be made */
+  if (!t->calling_back && t->cb) {
+    perform_callbacks = prepare_callbacks(t);
+    if (perform_callbacks) {
+      t->calling_back = 1;
+    }
+    if (t->error_state == ERROR_STATE_SEEN) {
+      call_closed = 1;
+      t->calling_back = 1;
+      t->error_state = ERROR_STATE_NOTIFIED;
+    }
+  }
+
+  if (perform_callbacks || call_closed) {
+    ref_transport(t);
+  }
+
+  /* finally unlock */
+  gpr_mu_unlock(&t->mu);
+
+  /* perform some callbacks if necessary */
+  if (perform_callbacks) {
+    run_callbacks(t);
+  }
+
+  if (call_closed) {
+    t->cb->closed(t->cb_user_data, &t->base);
+  }
+
+  /* write some bytes if necessary */
+  while (start_write) {
+    switch (grpc_endpoint_write(ep, t->outbuf.slices, t->outbuf.count,
+                                finish_write, t, gpr_inf_future)) {
+      case GRPC_ENDPOINT_WRITE_DONE:
+        /* grab the lock directly without wrappers since we just want to
+           continue writes if we loop: no need to check read callbacks again */
+        gpr_mu_lock(&t->mu);
+        t->outbuf.count = 0;
+        t->outbuf.length = 0;
+        t->writing = start_write = prepare_write(t);
+        if (!start_write) {
+          if (!t->reading) {
+            grpc_endpoint_destroy(t->ep);
+            t->ep = NULL;
+            gpr_cv_broadcast(&t->cv);
+            /* endpoint ref: safe because we'll still have the ref for write */
+            unref_transport(t);
+          }
+        }
+        gpr_mu_unlock(&t->mu);
+        if (!start_write) {
+          unref_transport(t);
+        }
+        break;
+      case GRPC_ENDPOINT_WRITE_ERROR:
+        start_write = 0;
+        /* use the wrapper lock/unlock here as we drop_connection, causing
+           read callbacks to be queued (which will be cleared during unlock) */
+        lock(t);
+        t->outbuf.count = 0;
+        t->outbuf.length = 0;
+        t->writing = 0;
+        drop_connection(t);
+        if (!t->reading) {
+          grpc_endpoint_destroy(t->ep);
+          t->ep = NULL;
+          gpr_cv_broadcast(&t->cv);
+          /* endpoint ref: safe because we'll still have the ref for write */
+          unref_transport(t);
+        }
+        unlock(t);
+        unref_transport(t);
+        break;
+      case GRPC_ENDPOINT_WRITE_PENDING:
+        start_write = 0;
+        break;
+    }
+  }
+
+  if (perform_callbacks || call_closed) {
+    lock(t);
+    t->calling_back = 0;
+    gpr_cv_broadcast(&t->cv);
+    unlock(t);
+    unref_transport(t);
+  }
+}
+
+/*
+ * OUTPUT PROCESSING
+ */
+
+static void push_setting(transport *t, grpc_chttp2_setting_id id,
+                         gpr_uint32 value) {
+  const grpc_chttp2_setting_parameters *sp =
+      &grpc_chttp2_settings_parameters[id];
+  gpr_uint32 use_value = GPR_CLAMP(value, sp->min_value, sp->max_value);
+  if (use_value != value) {
+    gpr_log(GPR_INFO, "Requested parameter %s clamped from %d to %d", sp->name,
+            value, use_value);
+  }
+  if (use_value != t->settings[LOCAL_SETTINGS][id]) {
+    t->settings[LOCAL_SETTINGS][id] = use_value;
+    t->dirtied_local_settings = 1;
+  }
+}
+
+static void finish_write(void *tp, grpc_endpoint_cb_status error) {
+  transport *t = tp;
+
+  lock(t);
+  if (error != GRPC_ENDPOINT_CB_OK) {
+    drop_connection(t);
+  }
+  t->outbuf.count = 0;
+  t->outbuf.length = 0;
+  /* leave the writing flag up on shutdown to prevent further writes in unlock()
+     from starting */
+  t->writing = 0;
+  if (!t->reading) {
+    grpc_endpoint_destroy(t->ep);
+    t->ep = NULL;
+    gpr_cv_broadcast(&t->cv);
+    unref_transport(t); /* safe because we'll still have the ref for write */
+  }
+  unlock(t);
+
+  unref_transport(t);
+}
+
+static int prepare_write(transport *t) {
+  stream *s;
+  gpr_slice_buffer tempbuf;
+
+  /* simple writes are queued to qbuf, and flushed here */
+  tempbuf = t->qbuf;
+  t->qbuf = t->outbuf;
+  t->outbuf = tempbuf;
+  GPR_ASSERT(t->qbuf.count == 0);
+
+  if (t->dirtied_local_settings && !t->sent_local_settings) {
+    gpr_slice_buffer_add(
+        &t->outbuf, grpc_chttp2_settings_create(t->settings[SENT_SETTINGS],
+                                                t->settings[LOCAL_SETTINGS],
+                                                GRPC_CHTTP2_NUM_SETTINGS));
+    t->dirtied_local_settings = 0;
+    t->sent_local_settings = 1;
+  }
+
+  /* for each stream that's become writable, frame it's data (according to
+     available window sizes) and add to the output buffer */
+  while (t->outgoing_window && (s = stream_list_remove_head(t, WRITABLE))) {
+    gpr_uint32 written = grpc_chttp2_encode_some(
+        s->outgoing_sopb.ops, &s->outgoing_sopb.nops, s->write_closed,
+        &t->outbuf, GPR_MIN(t->outgoing_window, s->outgoing_window), s->id,
+        &t->hpack_compressor);
+    t->outgoing_window -= written;
+    s->outgoing_window -= written;
+
+    /* if there are no more writes to do and writes are closed, we need to
+       queue a callback to let the application know */
+    if (s->write_closed && s->outgoing_sopb.nops == 0) {
+      stream_list_join(t, s, PENDING_CALLBACKS);
+    }
+
+    /* if there are still writes to do and the stream still has window
+       available, then schedule a further write */
+    if (s->outgoing_sopb.nops && s->outgoing_window) {
+      GPR_ASSERT(!t->outgoing_window);
+      stream_list_add_tail(t, s, WRITABLE);
+    }
+  }
+
+  /* for each stream that wants to update its window, add that window here */
+  while ((s = stream_list_remove_head(t, WINDOW_UPDATE))) {
+    gpr_uint32 window_add = DEFAULT_WINDOW - s->incoming_window;
+    if (!s->read_closed && window_add) {
+      gpr_slice_buffer_add(&t->outbuf,
+                           grpc_chttp2_window_update_create(s->id, window_add));
+      s->incoming_window += window_add;
+    }
+  }
+
+  /* if the transport is ready to send a window update, do so here also */
+  if (t->incoming_window < DEFAULT_WINDOW / 2) {
+    gpr_uint32 window_add = DEFAULT_WINDOW - t->incoming_window;
+    gpr_slice_buffer_add(&t->outbuf,
+                         grpc_chttp2_window_update_create(0, window_add));
+    t->incoming_window += window_add;
+  }
+
+  return t->outbuf.length > 0;
+}
+
+static void maybe_start_some_streams(transport *t) {
+  while (
+      grpc_chttp2_stream_map_size(&t->stream_map) <
+      t->settings[PEER_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]) {
+    stream *s = stream_list_remove_head(t, WAITING_FOR_CONCURRENCY);
+    if (!s) break;
+
+    GPR_ASSERT(s->id == 0);
+    s->id = t->next_stream_id;
+    t->next_stream_id += 2;
+    grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
+    stream_list_join(t, s, WRITABLE);
+  }
+}
+
+static void send_batch(grpc_transport *gt, grpc_stream *gs, grpc_stream_op *ops,
+                       size_t ops_count, int is_last) {
+  transport *t = (transport *)gt;
+  stream *s = (stream *)gs;
+
+  lock(t);
+
+  if (is_last) {
+    s->write_closed = 1;
+  }
+  if (!s->cancelled) {
+    grpc_sopb_append(&s->outgoing_sopb, ops, ops_count);
+    if (is_last && s->outgoing_sopb.nops == 0) {
+      if (s->id != 0) {
+        gpr_slice_buffer_add(&t->qbuf,
+                             grpc_chttp2_data_frame_create_empty_close(s->id));
+      }
+    } else if (s->id == 0) {
+      stream_list_join(t, s, WAITING_FOR_CONCURRENCY);
+      maybe_start_some_streams(t);
+    } else if (s->outgoing_window) {
+      stream_list_join(t, s, WRITABLE);
+    }
+  } else {
+    grpc_stream_ops_unref_owned_objects(ops, ops_count);
+  }
+  if (is_last && s->outgoing_sopb.nops == 0 && s->read_closed) {
+    stream_list_join(t, s, PENDING_CALLBACKS);
+  }
+
+  unlock(t);
+}
+
+static void abort_stream(grpc_transport *gt, grpc_stream *gs,
+                         grpc_status_code status) {
+  transport *t = (transport *)gt;
+  stream *s = (stream *)gs;
+
+  lock(t);
+  cancel_stream(t, s, status, grpc_chttp2_grpc_status_to_http2_error(status),
+                1);
+  unlock(t);
+}
+
+static void send_ping(grpc_transport *gt, void (*cb)(void *user_data),
+                      void *user_data) {
+  transport *t = (transport *)gt;
+  outstanding_ping *p;
+
+  lock(t);
+  if (t->ping_capacity == t->ping_count) {
+    t->ping_capacity = GPR_MAX(1, t->ping_capacity * 3 / 2);
+    t->pings =
+        gpr_realloc(t->pings, sizeof(outstanding_ping) * t->ping_capacity);
+  }
+  p = &t->pings[t->ping_count++];
+  p->id[0] = t->ping_counter >> 56;
+  p->id[1] = t->ping_counter >> 48;
+  p->id[2] = t->ping_counter >> 40;
+  p->id[3] = t->ping_counter >> 32;
+  p->id[4] = t->ping_counter >> 24;
+  p->id[5] = t->ping_counter >> 16;
+  p->id[6] = t->ping_counter >> 8;
+  p->id[7] = t->ping_counter;
+  p->cb = cb;
+  p->user_data = user_data;
+  gpr_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(0, p->id));
+  unlock(t);
+}
+
+/*
+ * INPUT PROCESSING
+ */
+
+static void cancel_stream_inner(transport *t, stream *s, gpr_uint32 id,
+                                grpc_status_code local_status,
+                                grpc_chttp2_error_code error_code,
+                                int send_rst) {
+  char buffer[32];
+  int had_outgoing;
+
+  if (s) {
+    /* clear out any unreported input & output: nobody cares anymore */
+    grpc_sopb_reset(&s->parser.incoming_sopb);
+    had_outgoing = s->outgoing_sopb.nops != 0;
+    grpc_sopb_reset(&s->outgoing_sopb);
+    if (s->cancelled) {
+      send_rst = 0;
+    } else if (!s->read_closed || !s->write_closed || had_outgoing) {
+      s->cancelled = 1;
+      s->read_closed = 1;
+      s->write_closed = 1;
+
+      sprintf(buffer, "%d", local_status);
+      grpc_sopb_add_metadata(
+          &s->parser.incoming_sopb,
+          grpc_mdelem_from_strings(t->metadata_context, "grpc-status", buffer));
+
+      stream_list_join(t, s, PENDING_CALLBACKS);
+    }
+  }
+  if (!id) send_rst = 0;
+  if (send_rst) {
+    gpr_slice_buffer_add(&t->qbuf,
+                         grpc_chttp2_rst_stream_create(id, error_code));
+  }
+}
+
+static void cancel_stream_id(transport *t, gpr_uint32 id,
+                             grpc_status_code local_status,
+                             grpc_chttp2_error_code error_code, int send_rst) {
+  cancel_stream_inner(t, lookup_stream(t, id), id, local_status, error_code,
+                      send_rst);
+}
+
+static void cancel_stream(transport *t, stream *s,
+                          grpc_status_code local_status,
+                          grpc_chttp2_error_code error_code, int send_rst) {
+  cancel_stream_inner(t, s, s->id, local_status, error_code, send_rst);
+}
+
+static void cancel_stream_cb(void *user_data, gpr_uint32 id, void *stream) {
+  cancel_stream(user_data, stream, GRPC_STATUS_UNAVAILABLE,
+                GRPC_CHTTP2_INTERNAL_ERROR, 0);
+}
+
+static void end_all_the_calls(transport *t) {
+  grpc_chttp2_stream_map_for_each(&t->stream_map, cancel_stream_cb, t);
+}
+
+static void drop_connection(transport *t) {
+  if (t->error_state == ERROR_STATE_NONE) {
+    t->error_state = ERROR_STATE_SEEN;
+  }
+  end_all_the_calls(t);
+}
+
+static void maybe_join_window_updates(transport *t, stream *s) {
+  if (s->allow_window_updates && s->incoming_window < DEFAULT_WINDOW / 2) {
+    stream_list_join(t, s, WINDOW_UPDATE);
+  }
+}
+
+static void set_allow_window_updates(grpc_transport *tp, grpc_stream *sp,
+                                     int allow) {
+  transport *t = (transport *)tp;
+  stream *s = (stream *)sp;
+
+  lock(t);
+  s->allow_window_updates = allow;
+  if (allow) {
+    maybe_join_window_updates(t, s);
+  } else {
+    stream_list_remove(t, s, WINDOW_UPDATE);
+  }
+  unlock(t);
+}
+
+static grpc_chttp2_parse_error update_incoming_window(transport *t, stream *s) {
+  if (t->incoming_frame_size > t->incoming_window) {
+    gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d",
+            t->incoming_frame_size, t->incoming_window);
+    return GRPC_CHTTP2_CONNECTION_ERROR;
+  }
+
+  if (t->incoming_frame_size > s->incoming_window) {
+    gpr_log(GPR_ERROR, "frame of size %d overflows incoming window of %d",
+            t->incoming_frame_size, s->incoming_window);
+    return GRPC_CHTTP2_CONNECTION_ERROR;
+  }
+
+  t->incoming_window -= t->incoming_frame_size;
+  s->incoming_window -= t->incoming_frame_size;
+
+  /* if the stream incoming window is getting low, schedule an update */
+  maybe_join_window_updates(t, s);
+
+  return GRPC_CHTTP2_PARSE_OK;
+}
+
+static stream *lookup_stream(transport *t, gpr_uint32 id) {
+  return grpc_chttp2_stream_map_find(&t->stream_map, id);
+}
+
+static grpc_chttp2_parse_error skip_parser(void *parser,
+                                           grpc_chttp2_parse_state *st,
+                                           gpr_slice slice, int is_last) {
+  return GRPC_CHTTP2_PARSE_OK;
+}
+
+static void skip_header(void *tp, grpc_mdelem *md) { grpc_mdelem_unref(md); }
+
+static int init_skip_frame(transport *t, int is_header) {
+  if (is_header) {
+    int is_eoh = t->expect_continuation_stream_id != 0;
+    t->parser = grpc_chttp2_header_parser_parse;
+    t->parser_data = &t->hpack_parser;
+    t->hpack_parser.on_header = skip_header;
+    t->hpack_parser.on_header_user_data = NULL;
+    t->hpack_parser.is_boundary = is_eoh;
+    t->hpack_parser.is_eof = is_eoh ? t->header_eof : 0;
+  } else {
+    t->parser = skip_parser;
+  }
+  return 1;
+}
+
+static void become_skip_parser(transport *t) {
+  init_skip_frame(t, t->parser == grpc_chttp2_header_parser_parse);
+}
+
+static int init_data_frame_parser(transport *t) {
+  stream *s = lookup_stream(t, t->incoming_stream_id);
+  grpc_chttp2_parse_error err = GRPC_CHTTP2_PARSE_OK;
+  if (!s || s->read_closed) return init_skip_frame(t, 0);
+  if (err == GRPC_CHTTP2_PARSE_OK) {
+    err = update_incoming_window(t, s);
+  }
+  if (err == GRPC_CHTTP2_PARSE_OK) {
+    err = grpc_chttp2_data_parser_begin_frame(&s->parser,
+                                              t->incoming_frame_flags);
+  }
+  switch (err) {
+    case GRPC_CHTTP2_PARSE_OK:
+      t->incoming_stream = s;
+      t->parser = grpc_chttp2_data_parser_parse;
+      t->parser_data = &s->parser;
+      return 1;
+    case GRPC_CHTTP2_STREAM_ERROR:
+      cancel_stream(t, s, grpc_chttp2_http2_error_to_grpc_status(
+                              GRPC_CHTTP2_INTERNAL_ERROR),
+                    GRPC_CHTTP2_INTERNAL_ERROR, 1);
+      return init_skip_frame(t, 0);
+    case GRPC_CHTTP2_CONNECTION_ERROR:
+      drop_connection(t);
+      return 0;
+  }
+  gpr_log(GPR_ERROR, "should never reach here");
+  abort();
+  return 0;
+}
+
+static void free_timeout(void *p) { gpr_free(p); }
+
+static void on_header(void *tp, grpc_mdelem *md) {
+  transport *t = tp;
+  stream *s = t->incoming_stream;
+
+  GPR_ASSERT(s);
+  stream_list_join(t, s, PENDING_CALLBACKS);
+  if (md->key == t->str_grpc_timeout) {
+    gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
+    if (!cached_timeout) {
+      /* not already parsed: parse it now, and store the result away */
+      cached_timeout = gpr_malloc(sizeof(gpr_timespec));
+      if (!grpc_chttp2_decode_timeout(grpc_mdstr_as_c_string(md->value),
+                                      cached_timeout)) {
+        gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'",
+                grpc_mdstr_as_c_string(md->value));
+        *cached_timeout = gpr_inf_future;
+      }
+      grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+    }
+    grpc_sopb_add_deadline(&s->parser.incoming_sopb,
+                           gpr_time_add(gpr_now(), *cached_timeout));
+    grpc_mdelem_unref(md);
+  } else {
+    grpc_sopb_add_metadata(&s->parser.incoming_sopb, md);
+  }
+}
+
+static int init_header_frame_parser(transport *t, int is_continuation) {
+  int is_eoh =
+      (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0;
+  stream *s;
+
+  if (is_eoh) {
+    t->expect_continuation_stream_id = 0;
+  } else {
+    t->expect_continuation_stream_id = t->incoming_stream_id;
+  }
+
+  if (!is_continuation) {
+    t->header_eof =
+        (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0;
+  }
+
+  /* could be a new stream or an existing stream */
+  s = lookup_stream(t, t->incoming_stream_id);
+  if (!s) {
+    if (is_continuation) {
+      gpr_log(GPR_ERROR, "stream disbanded before CONTINUATION received");
+      return init_skip_frame(t, 1);
+    }
+    if (t->is_client) {
+      if ((t->incoming_stream_id & 1) &&
+          t->incoming_stream_id < t->next_stream_id) {
+        /* this is an old (probably cancelled) stream */
+      } else {
+        gpr_log(GPR_ERROR, "ignoring new stream creation on client");
+      }
+      return init_skip_frame(t, 1);
+    }
+    t->incoming_stream = NULL;
+    /* if stream is accepted, we set incoming_stream in init_stream */
+    t->cb->accept_stream(t->cb_user_data, &t->base,
+                         (void *)(gpr_uintptr)t->incoming_stream_id);
+    s = t->incoming_stream;
+    if (!s) {
+      gpr_log(GPR_ERROR, "stream not accepted");
+      return init_skip_frame(t, 1);
+    }
+  } else {
+    t->incoming_stream = s;
+  }
+  if (t->incoming_stream->read_closed) {
+    gpr_log(GPR_ERROR, "skipping already closed stream header");
+    t->incoming_stream = NULL;
+    return init_skip_frame(t, 1);
+  }
+  t->parser = grpc_chttp2_header_parser_parse;
+  t->parser_data = &t->hpack_parser;
+  t->hpack_parser.on_header = on_header;
+  t->hpack_parser.on_header_user_data = t;
+  t->hpack_parser.is_boundary = is_eoh;
+  t->hpack_parser.is_eof = is_eoh ? t->header_eof : 0;
+  if (!is_continuation &&
+      (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_HAS_PRIORITY)) {
+    grpc_chttp2_hpack_parser_set_has_priority(&t->hpack_parser);
+  }
+  return 1;
+}
+
+static int init_window_update_frame_parser(transport *t) {
+  int ok = GRPC_CHTTP2_PARSE_OK == grpc_chttp2_window_update_parser_begin_frame(
+                                       &t->simple_parsers.window_update,
+                                       t->incoming_frame_size,
+                                       t->incoming_frame_flags);
+  if (!ok) {
+    drop_connection(t);
+  }
+  t->parser = grpc_chttp2_window_update_parser_parse;
+  t->parser_data = &t->simple_parsers.window_update;
+  return ok;
+}
+
+static int init_ping_parser(transport *t) {
+  int ok = GRPC_CHTTP2_PARSE_OK ==
+           grpc_chttp2_ping_parser_begin_frame(&t->simple_parsers.ping,
+                                               t->incoming_frame_size,
+                                               t->incoming_frame_flags);
+  if (!ok) {
+    drop_connection(t);
+  }
+  t->parser = grpc_chttp2_ping_parser_parse;
+  t->parser_data = &t->simple_parsers.ping;
+  return ok;
+}
+
+static int init_settings_frame_parser(transport *t) {
+  int ok = GRPC_CHTTP2_PARSE_OK ==
+           grpc_chttp2_settings_parser_begin_frame(
+               &t->simple_parsers.settings, t->incoming_frame_size,
+               t->incoming_frame_flags, t->settings[PEER_SETTINGS]);
+  if (!ok) {
+    drop_connection(t);
+  }
+  if (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) {
+    memcpy(t->settings[ACKED_SETTINGS], t->settings[SENT_SETTINGS],
+           GRPC_CHTTP2_NUM_SETTINGS * sizeof(gpr_uint32));
+  }
+  t->parser = grpc_chttp2_settings_parser_parse;
+  t->parser_data = &t->simple_parsers.settings;
+  return ok;
+}
+
+static int init_frame_parser(transport *t) {
+  if (t->expect_continuation_stream_id != 0) {
+    if (t->incoming_frame_type != GRPC_CHTTP2_FRAME_CONTINUATION) {
+      gpr_log(GPR_ERROR, "Expected CONTINUATION frame, got frame type %02x",
+              t->incoming_frame_type);
+      return 0;
+    }
+    if (t->expect_continuation_stream_id != t->incoming_stream_id) {
+      gpr_log(GPR_ERROR,
+              "Expected CONTINUATION frame for stream %08x, got stream %08x",
+              t->expect_continuation_stream_id, t->incoming_stream_id);
+      return 0;
+    }
+    return init_header_frame_parser(t, 1);
+  }
+  switch (t->incoming_frame_type) {
+    case GRPC_CHTTP2_FRAME_DATA:
+      return init_data_frame_parser(t);
+    case GRPC_CHTTP2_FRAME_HEADER:
+      return init_header_frame_parser(t, 0);
+    case GRPC_CHTTP2_FRAME_CONTINUATION:
+      gpr_log(GPR_ERROR, "Unexpected CONTINUATION frame");
+      return 0;
+    case GRPC_CHTTP2_FRAME_RST_STREAM:
+      /* TODO(ctiller): actually parse the reason */
+      cancel_stream_id(
+          t, t->incoming_stream_id,
+          grpc_chttp2_http2_error_to_grpc_status(GRPC_CHTTP2_CANCEL),
+          GRPC_CHTTP2_CANCEL, 0);
+      return init_skip_frame(t, 0);
+    case GRPC_CHTTP2_FRAME_SETTINGS:
+      return init_settings_frame_parser(t);
+    case GRPC_CHTTP2_FRAME_WINDOW_UPDATE:
+      return init_window_update_frame_parser(t);
+    case GRPC_CHTTP2_FRAME_PING:
+      return init_ping_parser(t);
+    default:
+      gpr_log(GPR_ERROR, "Unknown frame type %02x", t->incoming_frame_type);
+      return init_skip_frame(t, 0);
+  }
+}
+
+static int is_window_update_legal(gpr_uint32 window_update, gpr_uint32 window) {
+  return window_update < MAX_WINDOW - window;
+}
+
+static int parse_frame_slice(transport *t, gpr_slice slice, int is_last) {
+  grpc_chttp2_parse_state st;
+  size_t i;
+  memset(&st, 0, sizeof(st));
+  switch (t->parser(t->parser_data, &st, slice, is_last)) {
+    case GRPC_CHTTP2_PARSE_OK:
+      if (st.end_of_stream) {
+        t->incoming_stream->read_closed = 1;
+        stream_list_join(t, t->incoming_stream, PENDING_CALLBACKS);
+      }
+      if (st.need_flush_reads) {
+        stream_list_join(t, t->incoming_stream, PENDING_CALLBACKS);
+      }
+      if (st.metadata_boundary) {
+        grpc_sopb_add_metadata_boundary(
+            &t->incoming_stream->parser.incoming_sopb);
+        stream_list_join(t, t->incoming_stream, PENDING_CALLBACKS);
+      }
+      if (st.ack_settings) {
+        gpr_slice_buffer_add(&t->qbuf, grpc_chttp2_settings_ack_create());
+        maybe_start_some_streams(t);
+      }
+      if (st.send_ping_ack) {
+        gpr_slice_buffer_add(
+            &t->qbuf,
+            grpc_chttp2_ping_create(1, t->simple_parsers.ping.opaque_8bytes));
+      }
+      if (st.process_ping_reply) {
+        for (i = 0; i < t->ping_count; i++) {
+          if (0 ==
+              memcmp(t->pings[i].id, t->simple_parsers.ping.opaque_8bytes, 8)) {
+            t->pings[i].cb(t->pings[i].user_data);
+            memmove(&t->pings[i], &t->pings[i + 1],
+                    (t->ping_count - i - 1) * sizeof(outstanding_ping));
+            t->ping_count--;
+            break;
+          }
+        }
+      }
+      if (st.window_update) {
+        if (t->incoming_stream_id) {
+          /* if there was a stream id, this is for some stream */
+          stream *s = lookup_stream(t, t->incoming_stream_id);
+          if (s) {
+            int was_window_empty = s->outgoing_window == 0;
+            if (!is_window_update_legal(st.window_update, s->outgoing_window)) {
+              cancel_stream(t, s, grpc_chttp2_http2_error_to_grpc_status(
+                                      GRPC_CHTTP2_FLOW_CONTROL_ERROR),
+                            GRPC_CHTTP2_FLOW_CONTROL_ERROR, 1);
+            } else {
+              s->outgoing_window += st.window_update;
+              /* if this window update makes outgoing ops writable again,
+                 flag that */
+              if (was_window_empty && s->outgoing_sopb.nops) {
+                stream_list_join(t, s, WRITABLE);
+              }
+            }
+          }
+        } else {
+          /* transport level window update */
+          if (!is_window_update_legal(st.window_update, t->outgoing_window)) {
+            drop_connection(t);
+          } else {
+            t->outgoing_window += st.window_update;
+          }
+        }
+      }
+      return 1;
+    case GRPC_CHTTP2_STREAM_ERROR:
+      become_skip_parser(t);
+      cancel_stream_id(
+          t, t->incoming_stream_id,
+          grpc_chttp2_http2_error_to_grpc_status(GRPC_CHTTP2_INTERNAL_ERROR),
+          GRPC_CHTTP2_INTERNAL_ERROR, 1);
+      return 1;
+    case GRPC_CHTTP2_CONNECTION_ERROR:
+      drop_connection(t);
+      return 0;
+  }
+  gpr_log(GPR_ERROR, "should never reach here");
+  abort();
+  return 0;
+}
+
+static int process_read(transport *t, gpr_slice slice) {
+  gpr_uint8 *beg = GPR_SLICE_START_PTR(slice);
+  gpr_uint8 *end = GPR_SLICE_END_PTR(slice);
+  gpr_uint8 *cur = beg;
+
+  if (cur == end) return 1;
+
+  switch (t->deframe_state) {
+    case DTS_CLIENT_PREFIX_0:
+    case DTS_CLIENT_PREFIX_1:
+    case DTS_CLIENT_PREFIX_2:
+    case DTS_CLIENT_PREFIX_3:
+    case DTS_CLIENT_PREFIX_4:
+    case DTS_CLIENT_PREFIX_5:
+    case DTS_CLIENT_PREFIX_6:
+    case DTS_CLIENT_PREFIX_7:
+    case DTS_CLIENT_PREFIX_8:
+    case DTS_CLIENT_PREFIX_9:
+    case DTS_CLIENT_PREFIX_10:
+    case DTS_CLIENT_PREFIX_11:
+    case DTS_CLIENT_PREFIX_12:
+    case DTS_CLIENT_PREFIX_13:
+    case DTS_CLIENT_PREFIX_14:
+    case DTS_CLIENT_PREFIX_15:
+    case DTS_CLIENT_PREFIX_16:
+    case DTS_CLIENT_PREFIX_17:
+    case DTS_CLIENT_PREFIX_18:
+    case DTS_CLIENT_PREFIX_19:
+    case DTS_CLIENT_PREFIX_20:
+    case DTS_CLIENT_PREFIX_21:
+    case DTS_CLIENT_PREFIX_22:
+    case DTS_CLIENT_PREFIX_23:
+      while (cur != end && t->deframe_state != DTS_FH_0) {
+        if (*cur != CLIENT_CONNECT_STRING[t->deframe_state]) {
+          gpr_log(GPR_ERROR,
+                  "Connect string mismatch: expected '%c' (%d) got '%c' (%d) "
+                  "at byte %d",
+                  CLIENT_CONNECT_STRING[t->deframe_state],
+                  (int)(gpr_uint8)CLIENT_CONNECT_STRING[t->deframe_state], *cur,
+                  (int)*cur, t->deframe_state);
+          return 0;
+        }
+        ++cur;
+        ++t->deframe_state;
+      }
+      if (cur == end) {
+        return 1;
+      }
+    /* fallthrough */
+    dts_fh_0:
+    case DTS_FH_0:
+      GPR_ASSERT(cur < end);
+      t->incoming_frame_size = ((gpr_uint32)*cur) << 16;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_1;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_1:
+      GPR_ASSERT(cur < end);
+      t->incoming_frame_size |= ((gpr_uint32)*cur) << 8;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_2;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_2:
+      GPR_ASSERT(cur < end);
+      t->incoming_frame_size |= *cur;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_3;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_3:
+      GPR_ASSERT(cur < end);
+      t->incoming_frame_type = *cur;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_4;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_4:
+      GPR_ASSERT(cur < end);
+      t->incoming_frame_flags = *cur;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_5;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_5:
+      GPR_ASSERT(cur < end);
+      t->incoming_stream_id = (((gpr_uint32)*cur) << 24) & 0x7f;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_6;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_6:
+      GPR_ASSERT(cur < end);
+      t->incoming_stream_id |= ((gpr_uint32)*cur) << 16;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_7;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_7:
+      GPR_ASSERT(cur < end);
+      t->incoming_stream_id |= ((gpr_uint32)*cur) << 8;
+      if (++cur == end) {
+        t->deframe_state = DTS_FH_8;
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FH_8:
+      GPR_ASSERT(cur < end);
+      t->incoming_stream_id |= ((gpr_uint32)*cur);
+      t->deframe_state = DTS_FRAME;
+      if (!init_frame_parser(t)) {
+        return 0;
+      }
+      if (t->incoming_frame_size == 0) {
+        if (!parse_frame_slice(t, gpr_empty_slice(), 1)) {
+          return 0;
+        }
+        if (++cur == end) {
+          t->deframe_state = DTS_FH_0;
+          return 1;
+        }
+        goto dts_fh_0; /* loop */
+      }
+      if (++cur == end) {
+        return 1;
+      }
+    /* fallthrough */
+    case DTS_FRAME:
+      GPR_ASSERT(cur < end);
+      if (end - cur == t->incoming_frame_size) {
+        if (!parse_frame_slice(
+                t, gpr_slice_sub_no_ref(slice, cur - beg, end - beg), 1)) {
+          return 0;
+        }
+        t->deframe_state = DTS_FH_0;
+        return 1;
+      } else if (end - cur > t->incoming_frame_size) {
+        if (!parse_frame_slice(
+                t, gpr_slice_sub_no_ref(slice, cur - beg,
+                                        cur + t->incoming_frame_size - beg),
+                1)) {
+          return 0;
+        }
+        cur += t->incoming_frame_size;
+        goto dts_fh_0; /* loop */
+      } else {
+        if (!parse_frame_slice(
+                t, gpr_slice_sub_no_ref(slice, cur - beg, end - beg), 0)) {
+          return 0;
+        }
+        t->incoming_frame_size -= (end - cur);
+        return 1;
+      }
+      gpr_log(GPR_ERROR, "should never reach here");
+      abort();
+  }
+
+  gpr_log(GPR_ERROR, "should never reach here");
+  abort();
+}
+
+/* tcp read callback */
+static void recv_data(void *tp, gpr_slice *slices, size_t nslices,
+                      grpc_endpoint_cb_status error) {
+  transport *t = tp;
+  size_t i;
+  int keep_reading = 0;
+
+  switch (error) {
+    case GRPC_ENDPOINT_CB_SHUTDOWN:
+    case GRPC_ENDPOINT_CB_EOF:
+    case GRPC_ENDPOINT_CB_ERROR:
+    case GRPC_ENDPOINT_CB_TIMED_OUT:
+      lock(t);
+      drop_connection(t);
+      t->reading = 0;
+      if (!t->writing && t->ep) {
+        grpc_endpoint_destroy(t->ep);
+        t->ep = NULL;
+        gpr_cv_broadcast(&t->cv);
+        unref_transport(t); /* safe as we still have a ref for read */
+      }
+      unlock(t);
+      unref_transport(t);
+      break;
+    case GRPC_ENDPOINT_CB_OK:
+      lock(t);
+      for (i = 0; i < nslices && process_read(t, slices[i]); i++)
+        ;
+      unlock(t);
+      keep_reading = 1;
+      break;
+  }
+
+  for (i = 0; i < nslices; i++) gpr_slice_unref(slices[i]);
+
+  if (keep_reading) {
+    grpc_endpoint_notify_on_read(t->ep, recv_data, t, gpr_inf_future);
+  }
+}
+
+/*
+ * CALLBACK LOOP
+ */
+
+static grpc_stream_state compute_state(gpr_uint8 write_closed,
+                                       gpr_uint8 read_closed) {
+  if (write_closed && read_closed) return GRPC_STREAM_CLOSED;
+  if (write_closed) return GRPC_STREAM_SEND_CLOSED;
+  if (read_closed) return GRPC_STREAM_RECV_CLOSED;
+  return GRPC_STREAM_OPEN;
+}
+
+static int prepare_callbacks(transport *t) {
+  stream *s;
+  grpc_stream_op_buffer temp_sopb;
+  int n = 0;
+  while ((s = stream_list_remove_head(t, PENDING_CALLBACKS))) {
+    int execute = 1;
+    temp_sopb = s->parser.incoming_sopb;
+    s->parser.incoming_sopb = s->callback_sopb;
+    s->callback_sopb = temp_sopb;
+
+    s->callback_state = compute_state(
+        s->write_closed && s->outgoing_sopb.nops == 0, s->read_closed);
+    if (s->callback_state == GRPC_STREAM_CLOSED) {
+      remove_from_stream_map(t, s);
+      if (s->published_close) {
+        execute = 0;
+      }
+      s->published_close = 1;
+    }
+
+    if (execute) {
+      stream_list_add_tail(t, s, EXECUTING_CALLBACKS);
+      n = 1;
+    }
+  }
+  return n;
+}
+
+static void run_callbacks(transport *t) {
+  stream *s;
+  while ((s = stream_list_remove_head(t, EXECUTING_CALLBACKS))) {
+    size_t nops = s->callback_sopb.nops;
+    s->callback_sopb.nops = 0;
+    t->cb->recv_batch(t->cb_user_data, &t->base, (grpc_stream *)s,
+                      s->callback_sopb.ops, nops, s->callback_state);
+  }
+}
+
+/*
+ * INTEGRATION GLUE
+ */
+
+static const grpc_transport_vtable vtable = {
+    sizeof(stream), init_stream, send_batch, set_allow_window_updates,
+    destroy_stream, abort_stream, close_transport, send_ping,
+    destroy_transport};
+
+void grpc_create_chttp2_transport(grpc_transport_setup_callback setup,
+                                  void *arg,
+                                  const grpc_channel_args *channel_args,
+                                  grpc_endpoint *ep, gpr_slice *slices,
+                                  size_t nslices, grpc_mdctx *mdctx,
+                                  int is_client) {
+  transport *t = gpr_malloc(sizeof(transport));
+  init_transport(t, setup, arg, channel_args, ep, mdctx, is_client);
+  ref_transport(t);
+  recv_data(t, slices, nslices, GRPC_ENDPOINT_CB_OK);
+}
diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h
new file mode 100644
index 0000000..37eb84e
--- /dev/null
+++ b/src/core/transport/chttp2_transport.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__
+#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__
+
+#include "src/core/endpoint/tcp.h"
+#include "src/core/transport/transport.h"
+
+void grpc_create_chttp2_transport(grpc_transport_setup_callback setup,
+                                  void *arg,
+                                  const grpc_channel_args *channel_args,
+                                  grpc_endpoint *ep, gpr_slice *slices,
+                                  size_t nslices, grpc_mdctx *metadata_context,
+                                  int is_client);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__ */
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
new file mode 100644
index 0000000..ceb77df
--- /dev/null
+++ b/src/core/transport/metadata.c
@@ -0,0 +1,525 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/metadata.h"
+
+#include <stddef.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include "src/core/support/murmur_hash.h"
+#include <grpc/support/time.h>
+
+#define INITIAL_STRTAB_CAPACITY 4
+#define INITIAL_MDTAB_CAPACITY 4
+
+#define KV_HASH(key, value) ((key)->hash ^ (value)->hash)
+
+typedef struct internal_string {
+  /* must be byte compatible with grpc_mdstr */
+  gpr_slice slice;
+  gpr_uint32 hash;
+
+  /* private only data */
+  gpr_uint32 refs;
+  gpr_slice_refcount refcount;
+
+  grpc_mdctx *context;
+
+  struct internal_string *bucket_next;
+} internal_string;
+
+typedef struct internal_metadata {
+  /* must be byte compatible with grpc_mdelem */
+  internal_string *key;
+  internal_string *value;
+
+  /* private only data */
+  void *user_data;
+  void (*destroy_user_data)(void *user_data);
+
+  gpr_uint32 refs;
+  grpc_mdctx *context;
+  struct internal_metadata *bucket_next;
+} internal_metadata;
+
+struct grpc_mdctx {
+  gpr_uint32 hash_seed;
+  int orphaned;
+
+  gpr_mu mu;
+
+  internal_string **strtab;
+  size_t strtab_count;
+  size_t strtab_capacity;
+
+  internal_metadata **mdtab;
+  size_t mdtab_count;
+  size_t mdtab_free;
+  size_t mdtab_capacity;
+};
+
+static void internal_string_ref(internal_string *s);
+static void internal_string_unref(internal_string *s);
+static void discard_metadata(grpc_mdctx *ctx);
+static void gc_mdtab(grpc_mdctx *ctx);
+static void metadata_context_destroy(grpc_mdctx *ctx);
+
+static void lock(grpc_mdctx *ctx) { gpr_mu_lock(&ctx->mu); }
+
+static void unlock(grpc_mdctx *ctx) {
+  /* If the context has been orphaned we'd like to delete it soon. We check
+     conditions in unlock as it signals the end of mutations on a context.
+
+     We need to ensure all grpc_mdelem and grpc_mdstr elements have been deleted
+     first. This is equivalent to saying that both tables have zero counts,
+     which is equivalent to saying that strtab_count is zero (as mdelem's MUST
+     reference an mdstr for their key and value slots).
+
+     To encourage that to happen, we start discarding zero reference count
+     mdelems on every unlock (instead of the usual 'I'm too loaded' trigger
+     case), since otherwise we can be stuck waiting for a garbage collection
+     that will never happen. */
+  if (ctx->orphaned) {
+    /* uncomment if you're having trouble diagnosing an mdelem leak to make
+       things clearer (slows down destruction a lot, however) */
+    /* gc_mdtab(ctx); */
+    if (ctx->mdtab_count && ctx->mdtab_count == ctx->mdtab_free) {
+      discard_metadata(ctx);
+    }
+    if (ctx->strtab_count == 0) {
+      gpr_mu_unlock(&ctx->mu);
+      metadata_context_destroy(ctx);
+      return;
+    }
+  }
+  gpr_mu_unlock(&ctx->mu);
+}
+
+static void ref_md(internal_metadata *md) {
+  if (0 == md->refs++) {
+    md->context->mdtab_free--;
+  }
+}
+
+grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed) {
+  grpc_mdctx *ctx = gpr_malloc(sizeof(grpc_mdctx));
+
+  ctx->orphaned = 0;
+  ctx->hash_seed = seed;
+  gpr_mu_init(&ctx->mu);
+  ctx->strtab = gpr_malloc(sizeof(internal_string *) * INITIAL_STRTAB_CAPACITY);
+  memset(ctx->strtab, 0, sizeof(grpc_mdstr *) * INITIAL_STRTAB_CAPACITY);
+  ctx->strtab_count = 0;
+  ctx->strtab_capacity = INITIAL_STRTAB_CAPACITY;
+  ctx->mdtab = gpr_malloc(sizeof(internal_metadata *) * INITIAL_MDTAB_CAPACITY);
+  memset(ctx->mdtab, 0, sizeof(grpc_mdelem *) * INITIAL_MDTAB_CAPACITY);
+  ctx->mdtab_count = 0;
+  ctx->mdtab_capacity = INITIAL_MDTAB_CAPACITY;
+  ctx->mdtab_free = 0;
+
+  return ctx;
+}
+
+grpc_mdctx *grpc_mdctx_create() {
+  /* This seed is used to prevent remote connections from controlling hash table
+   * collisions. It needs to be somewhat unpredictable to a remote connection.
+   */
+  return grpc_mdctx_create_with_seed(gpr_now().tv_nsec);
+}
+
+static void discard_metadata(grpc_mdctx *ctx) {
+  size_t i;
+  internal_metadata *next, *cur;
+
+  for (i = 0; i < ctx->mdtab_capacity; i++) {
+    cur = ctx->mdtab[i];
+    while (cur) {
+      GPR_ASSERT(cur->refs == 0);
+      next = cur->bucket_next;
+      internal_string_unref(cur->key);
+      internal_string_unref(cur->value);
+      if (cur->user_data) {
+        cur->destroy_user_data(cur->user_data);
+      }
+      gpr_free(cur);
+      cur = next;
+      ctx->mdtab_free--;
+      ctx->mdtab_count--;
+    }
+    ctx->mdtab[i] = NULL;
+  }
+}
+
+static void metadata_context_destroy(grpc_mdctx *ctx) {
+  gpr_mu_lock(&ctx->mu);
+  GPR_ASSERT(ctx->strtab_count == 0);
+  GPR_ASSERT(ctx->mdtab_count == 0);
+  GPR_ASSERT(ctx->mdtab_free == 0);
+  gpr_free(ctx->strtab);
+  gpr_free(ctx->mdtab);
+  gpr_mu_unlock(&ctx->mu);
+  gpr_mu_destroy(&ctx->mu);
+  gpr_free(ctx);
+}
+
+void grpc_mdctx_orphan(grpc_mdctx *ctx) {
+  lock(ctx);
+  GPR_ASSERT(!ctx->orphaned);
+  ctx->orphaned = 1;
+  unlock(ctx);
+}
+
+static void grow_strtab(grpc_mdctx *ctx) {
+  size_t capacity = ctx->strtab_capacity * 2;
+  size_t i;
+  internal_string **strtab = gpr_malloc(sizeof(internal_string *) * capacity);
+  internal_string *s, *next;
+  memset(strtab, 0, sizeof(internal_string *) * capacity);
+
+  for (i = 0; i < ctx->strtab_capacity; i++) {
+    for (s = ctx->strtab[i]; s; s = next) {
+      next = s->bucket_next;
+      s->bucket_next = strtab[s->hash % capacity];
+      strtab[s->hash % capacity] = s;
+    }
+  }
+
+  gpr_free(ctx->strtab);
+  ctx->strtab = strtab;
+  ctx->strtab_capacity = capacity;
+}
+
+static void internal_destroy_string(internal_string *is) {
+  internal_string **prev_next;
+  internal_string *cur;
+  grpc_mdctx *ctx = is->context;
+  for (prev_next = &ctx->strtab[is->hash % ctx->strtab_capacity],
+      cur = *prev_next;
+       cur != is; prev_next = &cur->bucket_next, cur = cur->bucket_next)
+    ;
+  *prev_next = cur->bucket_next;
+  ctx->strtab_count--;
+  gpr_free(is);
+}
+
+static void internal_string_ref(internal_string *s) { ++s->refs; }
+
+static void internal_string_unref(internal_string *s) {
+  GPR_ASSERT(s->refs > 0);
+  if (0 == --s->refs) {
+    internal_destroy_string(s);
+  }
+}
+
+static void slice_ref(void *p) {
+  internal_string *is =
+      (internal_string *)((char *)p - offsetof(internal_string, refcount));
+  grpc_mdctx *ctx = is->context;
+  lock(ctx);
+  internal_string_ref(is);
+  unlock(ctx);
+}
+
+static void slice_unref(void *p) {
+  internal_string *is =
+      (internal_string *)((char *)p - offsetof(internal_string, refcount));
+  grpc_mdctx *ctx = is->context;
+  lock(ctx);
+  internal_string_unref(is);
+  unlock(ctx);
+}
+
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str) {
+  return grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)str, strlen(str));
+}
+
+grpc_mdstr *grpc_mdstr_from_slice(grpc_mdctx *ctx, gpr_slice slice) {
+  grpc_mdstr *result = grpc_mdstr_from_buffer(ctx, GPR_SLICE_START_PTR(slice),
+                                              GPR_SLICE_LENGTH(slice));
+  gpr_slice_unref(slice);
+  return result;
+}
+
+grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *buf,
+                                   size_t length) {
+  gpr_uint32 hash = gpr_murmur_hash3(buf, length, ctx->hash_seed);
+  internal_string *s;
+
+  lock(ctx);
+
+  /* search for an existing string */
+  for (s = ctx->strtab[hash % ctx->strtab_capacity]; s; s = s->bucket_next) {
+    if (s->hash == hash && GPR_SLICE_LENGTH(s->slice) == length &&
+        0 == memcmp(buf, GPR_SLICE_START_PTR(s->slice), length)) {
+      internal_string_ref(s);
+      unlock(ctx);
+      return (grpc_mdstr *)s;
+    }
+  }
+
+  /* not found: create a new string */
+  if (length + 1 < GPR_SLICE_INLINED_SIZE) {
+    /* string data goes directly into the slice */
+    s = gpr_malloc(sizeof(internal_string));
+    s->refs = 1;
+    s->slice.refcount = NULL;
+    memcpy(s->slice.data.inlined.bytes, buf, length);
+    s->slice.data.inlined.bytes[length] = 0;
+    s->slice.data.inlined.length = length;
+  } else {
+    /* string data goes after the internal_string header, and we +1 for null
+       terminator */
+    s = gpr_malloc(sizeof(internal_string) + length + 1);
+    s->refs = 1;
+    s->refcount.ref = slice_ref;
+    s->refcount.unref = slice_unref;
+    s->slice.refcount = &s->refcount;
+    s->slice.data.refcounted.bytes = (gpr_uint8 *)(s + 1);
+    s->slice.data.refcounted.length = length;
+    memcpy(s->slice.data.refcounted.bytes, buf, length);
+    /* add a null terminator for cheap c string conversion when desired */
+    s->slice.data.refcounted.bytes[length] = 0;
+  }
+  s->hash = hash;
+  s->context = ctx;
+  s->bucket_next = ctx->strtab[hash % ctx->strtab_capacity];
+  ctx->strtab[hash % ctx->strtab_capacity] = s;
+
+  ctx->strtab_count++;
+
+  if (ctx->strtab_count > ctx->strtab_capacity * 2) {
+    grow_strtab(ctx);
+  }
+
+  unlock(ctx);
+
+  return (grpc_mdstr *)s;
+}
+
+static void gc_mdtab(grpc_mdctx *ctx) {
+  size_t i;
+  internal_metadata **prev_next;
+  internal_metadata *md, *next;
+
+  for (i = 0; i < ctx->mdtab_capacity; i++) {
+    prev_next = &ctx->mdtab[i];
+    for (md = ctx->mdtab[i]; md; md = next) {
+      next = md->bucket_next;
+      if (md->refs == 0) {
+        internal_string_unref(md->key);
+        internal_string_unref(md->value);
+        if (md->user_data) {
+          md->destroy_user_data(md->user_data);
+        }
+        gpr_free(md);
+        *prev_next = next;
+        ctx->mdtab_free--;
+        ctx->mdtab_count--;
+      } else {
+        prev_next = &md->bucket_next;
+      }
+    }
+  }
+
+  GPR_ASSERT(ctx->mdtab_free == 0);
+}
+
+static void grow_mdtab(grpc_mdctx *ctx) {
+  size_t capacity = ctx->mdtab_capacity * 2;
+  size_t i;
+  internal_metadata **mdtab =
+      gpr_malloc(sizeof(internal_metadata *) * capacity);
+  internal_metadata *md, *next;
+  gpr_uint32 hash;
+  memset(mdtab, 0, sizeof(internal_metadata *) * capacity);
+
+  for (i = 0; i < ctx->mdtab_capacity; i++) {
+    for (md = ctx->mdtab[i]; md; md = next) {
+      hash = KV_HASH(md->key, md->value);
+      next = md->bucket_next;
+      md->bucket_next = mdtab[hash % capacity];
+      mdtab[hash % capacity] = md;
+    }
+  }
+
+  gpr_free(ctx->mdtab);
+  ctx->mdtab = mdtab;
+  ctx->mdtab_capacity = capacity;
+}
+
+static void rehash_mdtab(grpc_mdctx *ctx) {
+  if (ctx->mdtab_free > ctx->mdtab_capacity / 4) {
+    gc_mdtab(ctx);
+  } else {
+    grow_mdtab(ctx);
+  }
+}
+
+grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
+                                               grpc_mdstr *mkey,
+                                               grpc_mdstr *mvalue) {
+  internal_string *key = (internal_string *)mkey;
+  internal_string *value = (internal_string *)mvalue;
+  gpr_uint32 hash = KV_HASH(mkey, mvalue);
+  internal_metadata *md;
+
+  GPR_ASSERT(key->context == ctx);
+  GPR_ASSERT(value->context == ctx);
+
+  lock(ctx);
+
+  /* search for an existing pair */
+  for (md = ctx->mdtab[hash % ctx->mdtab_capacity]; md; md = md->bucket_next) {
+    if (md->key == key && md->value == value) {
+      ref_md(md);
+      internal_string_unref(key);
+      internal_string_unref(value);
+      unlock(ctx);
+      return (grpc_mdelem *)md;
+    }
+  }
+
+  /* not found: create a new pair */
+  md = gpr_malloc(sizeof(internal_metadata));
+  md->refs = 1;
+  md->context = ctx;
+  md->key = key;
+  md->value = value;
+  md->user_data = NULL;
+  md->destroy_user_data = NULL;
+  md->bucket_next = ctx->mdtab[hash % ctx->mdtab_capacity];
+  ctx->mdtab[hash % ctx->mdtab_capacity] = md;
+  ctx->mdtab_count++;
+
+  if (ctx->mdtab_count > ctx->mdtab_capacity * 2) {
+    rehash_mdtab(ctx);
+  }
+
+  unlock(ctx);
+
+  return (grpc_mdelem *)md;
+}
+
+grpc_mdelem *grpc_mdelem_from_strings(grpc_mdctx *ctx, const char *key,
+                                      const char *value) {
+  return grpc_mdelem_from_metadata_strings(ctx,
+                                           grpc_mdstr_from_string(ctx, key),
+                                           grpc_mdstr_from_string(ctx, value));
+}
+
+grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
+                                     gpr_slice value) {
+  return grpc_mdelem_from_metadata_strings(ctx, grpc_mdstr_from_slice(ctx, key),
+                                           grpc_mdstr_from_slice(ctx, value));
+}
+
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
+                                                const char *key,
+                                                const gpr_uint8 *value,
+                                                size_t value_length) {
+  return grpc_mdelem_from_metadata_strings(
+      ctx, grpc_mdstr_from_string(ctx, key),
+      grpc_mdstr_from_buffer(ctx, value, value_length));
+}
+
+grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd) {
+  internal_metadata *md = (internal_metadata *)gmd;
+  grpc_mdctx *ctx = md->context;
+  lock(ctx);
+  ref_md(md);
+  unlock(ctx);
+  return gmd;
+}
+
+void grpc_mdelem_unref(grpc_mdelem *gmd) {
+  internal_metadata *md = (internal_metadata *)gmd;
+  grpc_mdctx *ctx = md->context;
+  lock(ctx);
+  GPR_ASSERT(md->refs);
+  if (0 == --md->refs) {
+    ctx->mdtab_free++;
+  }
+  unlock(ctx);
+}
+
+const char *grpc_mdstr_as_c_string(grpc_mdstr *s) {
+  return (const char *)GPR_SLICE_START_PTR(s->slice);
+}
+
+grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs) {
+  internal_string *s = (internal_string *)gs;
+  grpc_mdctx *ctx = s->context;
+  lock(ctx);
+  internal_string_ref(s);
+  unlock(ctx);
+  return gs;
+}
+
+void grpc_mdstr_unref(grpc_mdstr *gs) {
+  internal_string *s = (internal_string *)gs;
+  grpc_mdctx *ctx = s->context;
+  lock(ctx);
+  internal_string_unref(s);
+  unlock(ctx);
+}
+
+size_t grpc_mdctx_get_mdtab_capacity_test_only(grpc_mdctx *ctx) {
+  return ctx->mdtab_capacity;
+}
+
+size_t grpc_mdctx_get_mdtab_count_test_only(grpc_mdctx *ctx) {
+  return ctx->mdtab_count;
+}
+
+size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *ctx) {
+  return ctx->mdtab_free;
+}
+
+void *grpc_mdelem_get_user_data(grpc_mdelem *md,
+                                void (*if_destroy_func)(void *)) {
+  internal_metadata *im = (internal_metadata *)md;
+  return im->destroy_user_data == if_destroy_func ? im->user_data : NULL;
+}
+
+void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
+                               void *user_data) {
+  internal_metadata *im = (internal_metadata *)md;
+  GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
+  if (im->destroy_user_data) {
+    im->destroy_user_data(im->user_data);
+  }
+  im->destroy_user_data = destroy_func;
+  im->user_data = user_data;
+}
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
new file mode 100644
index 0000000..4b87f70
--- /dev/null
+++ b/src/core/transport/metadata.h
@@ -0,0 +1,132 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_METADATA_H__
+#define __GRPC_INTERNAL_TRANSPORT_METADATA_H__
+
+#include <grpc/support/slice.h>
+
+/* This file provides a mechanism for tracking metadata through the grpc stack.
+   It's not intended for consumption outside of the library.
+
+   Metadata is tracked in the context of a grpc_mdctx. For the time being there
+   is one of these per-channel, avoiding cross channel interference with memory
+   use and lock contention.
+
+   The context tracks unique strings (grpc_mdstr) and pairs of strings
+   (grpc_mdelem). Any of these objects can be checked for equality by comparing
+   their pointers. These objects are reference counted.
+
+   grpc_mdelem can additionally store a (non-NULL) user data pointer. This
+   pointer is intended to be used to cache semantic meaning of a metadata
+   element. For example, an OAuth token may cache the credentials it represents
+   and the time at which it expires in the mdelem user data.
+
+   Combining this metadata cache and the hpack compression table allows us to
+   simply lookup complete preparsed objects quickly, incurring a few atomic
+   ops per metadata element on the fast path.
+
+   grpc_mdelem instances MAY live longer than their refcount implies, and are
+   garbage collected periodically, meaning cached data can easily outlive a
+   single request. */
+
+/* Forward declarations */
+typedef struct grpc_mdctx grpc_mdctx;
+typedef struct grpc_mdstr grpc_mdstr;
+typedef struct grpc_mdelem grpc_mdelem;
+
+/* if changing this, make identical changes in internal_string in metadata.c */
+struct grpc_mdstr {
+  const gpr_slice slice;
+  const gpr_uint32 hash;
+  /* there is a private part to this in metadata.c */
+};
+
+/* if changing this, make identical changes in internal_metadata in
+   metadata.c */
+struct grpc_mdelem {
+  grpc_mdstr *const key;
+  grpc_mdstr *const value;
+  /* there is a private part to this in metadata.c */
+};
+
+/* Create/orphan a metadata context */
+grpc_mdctx *grpc_mdctx_create();
+grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed);
+void grpc_mdctx_orphan(grpc_mdctx *mdctx);
+
+/* Test only accessors to internal state - only for testing this code - do not
+   rely on it outside of metadata_test.c */
+size_t grpc_mdctx_get_mdtab_capacity_test_only(grpc_mdctx *mdctx);
+size_t grpc_mdctx_get_mdtab_count_test_only(grpc_mdctx *mdctx);
+size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *mdctx);
+
+/* Constructors for grpc_mdstr instances; take a variety of data types that
+   clients may have handy */
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str);
+grpc_mdstr *grpc_mdstr_from_slice(grpc_mdctx *ctx, gpr_slice slice);
+grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *str,
+                                   size_t length);
+
+/* Constructors for grpc_mdelem instances; take a variety of data types that
+   clients may have handy */
+grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx, grpc_mdstr *key,
+                                               grpc_mdstr *value);
+grpc_mdelem *grpc_mdelem_from_strings(grpc_mdctx *ctx, const char *key,
+                                      const char *value);
+grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
+                                     gpr_slice value);
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
+                                                const char *key,
+                                                const gpr_uint8 *value,
+                                                size_t value_length);
+
+/* Mutator and accessor for grpc_mdelem user data. The destructor function
+   is used as a type tag and is checked during user_data fetch. */
+void *grpc_mdelem_get_user_data(grpc_mdelem *md,
+                                void (*if_destroy_func)(void *));
+void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
+                               void *user_data);
+
+/* Reference counting */
+grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s);
+void grpc_mdstr_unref(grpc_mdstr *s);
+
+grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md);
+void grpc_mdelem_unref(grpc_mdelem *md);
+
+/* Recover a char* from a grpc_mdstr. The returned string is null terminated.
+   Does not promise that the returned string has no embedded nulls however. */
+const char *grpc_mdstr_as_c_string(grpc_mdstr *s);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_METADATA_H__ */
diff --git a/src/core/transport/stream_op.c b/src/core/transport/stream_op.c
new file mode 100644
index 0000000..c77c8cd
--- /dev/null
+++ b/src/core/transport/stream_op.c
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/stream_op.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include <string.h>
+
+/* Initial number of operations to allocate */
+#define INITIAL_SLOTS 8
+/* Exponential growth function: Given x, return a larger x.
+   Currently we grow by 1.5 times upon reallocation.
+   Assumes INITIAL_SLOTS > 1 */
+#define GROW(x) (3 * (x) / 2)
+
+void grpc_sopb_init(grpc_stream_op_buffer *sopb) {
+  sopb->ops = gpr_malloc(sizeof(grpc_stream_op) * INITIAL_SLOTS);
+  GPR_ASSERT(sopb->ops);
+  sopb->nops = 0;
+  sopb->capacity = INITIAL_SLOTS;
+}
+
+void grpc_sopb_destroy(grpc_stream_op_buffer *sopb) {
+  grpc_stream_ops_unref_owned_objects(sopb->ops, sopb->nops);
+  gpr_free(sopb->ops);
+}
+
+void grpc_sopb_reset(grpc_stream_op_buffer *sopb) {
+  grpc_stream_ops_unref_owned_objects(sopb->ops, sopb->nops);
+  sopb->nops = 0;
+}
+
+void grpc_stream_ops_unref_owned_objects(grpc_stream_op *ops, size_t nops) {
+  int i;
+  for (i = 0; i < nops; i++) {
+    switch (ops[i].type) {
+      case GRPC_OP_SLICE:
+        gpr_slice_unref(ops[i].data.slice);
+        break;
+      case GRPC_OP_METADATA:
+        grpc_mdelem_unref(ops[i].data.metadata);
+        break;
+      case GRPC_OP_FLOW_CTL_CB:
+        ops[i].data.flow_ctl_cb.cb(ops[i].data.flow_ctl_cb.arg, GRPC_OP_ERROR);
+        break;
+      case GRPC_NO_OP:
+      case GRPC_OP_DEADLINE:
+      case GRPC_OP_METADATA_BOUNDARY:
+      case GRPC_OP_BEGIN_MESSAGE:
+        break;
+    }
+  }
+}
+
+static void expand(grpc_stream_op_buffer *sopb) {
+  sopb->capacity = GROW(sopb->capacity);
+  sopb->ops = gpr_realloc(sopb->ops, sizeof(grpc_stream_op) * sopb->capacity);
+  GPR_ASSERT(sopb->ops);
+}
+
+static grpc_stream_op *add(grpc_stream_op_buffer *sopb) {
+  grpc_stream_op *out;
+
+  if (sopb->nops == sopb->capacity) {
+    expand(sopb);
+  }
+  out = sopb->ops + sopb->nops;
+  sopb->nops++;
+  return out;
+}
+
+void grpc_sopb_add_no_op(grpc_stream_op_buffer *sopb) {
+  add(sopb)->type = GRPC_NO_OP;
+}
+
+void grpc_sopb_add_begin_message(grpc_stream_op_buffer *sopb, gpr_uint32 length,
+                                 gpr_uint32 flags) {
+  grpc_stream_op *op = add(sopb);
+  op->type = GRPC_OP_BEGIN_MESSAGE;
+  op->data.begin_message.length = length;
+  op->data.begin_message.flags = flags;
+}
+
+void grpc_sopb_add_metadata_boundary(grpc_stream_op_buffer *sopb) {
+  grpc_stream_op *op = add(sopb);
+  op->type = GRPC_OP_METADATA_BOUNDARY;
+}
+
+void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb, grpc_mdelem *md) {
+  grpc_stream_op *op = add(sopb);
+  op->type = GRPC_OP_METADATA;
+  op->data.metadata = md;
+}
+
+void grpc_sopb_add_deadline(grpc_stream_op_buffer *sopb,
+                            gpr_timespec deadline) {
+  grpc_stream_op *op = add(sopb);
+  op->type = GRPC_OP_DEADLINE;
+  op->data.deadline = deadline;
+}
+
+void grpc_sopb_add_slice(grpc_stream_op_buffer *sopb, gpr_slice slice) {
+  grpc_stream_op *op = add(sopb);
+  op->type = GRPC_OP_SLICE;
+  op->data.slice = slice;
+}
+
+void grpc_sopb_add_flow_ctl_cb(grpc_stream_op_buffer *sopb,
+                               void (*cb)(void *arg, grpc_op_error error),
+                               void *arg) {
+  grpc_stream_op *op = add(sopb);
+  op->type = GRPC_OP_FLOW_CTL_CB;
+  op->data.flow_ctl_cb.cb = cb;
+  op->data.flow_ctl_cb.arg = arg;
+}
+
+void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
+                      size_t nops) {
+  size_t orig_nops = sopb->nops;
+  size_t new_nops = orig_nops + nops;
+
+  if (new_nops > sopb->capacity) {
+    size_t new_capacity = GROW(sopb->capacity);
+    if (new_capacity < new_nops) {
+      new_capacity = new_nops;
+    }
+    sopb->ops = gpr_realloc(sopb->ops, sizeof(grpc_stream_op) * new_capacity);
+    sopb->capacity = new_capacity;
+  }
+
+  memcpy(sopb->ops + orig_nops, ops, sizeof(grpc_stream_op) * nops);
+  sopb->nops = new_nops;
+}
diff --git a/src/core/transport/stream_op.h b/src/core/transport/stream_op.h
new file mode 100644
index 0000000..be60bc2
--- /dev/null
+++ b/src/core/transport/stream_op.h
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__
+#define __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__
+
+#include <grpc/grpc.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/time.h>
+#include "src/core/transport/metadata.h"
+
+/* Operations that can be performed on a stream.
+   Used by grpc_stream_op. */
+typedef enum grpc_stream_op_code {
+  /* Do nothing code. Useful if rewriting a batch to exclude some operations.
+     Must be ignored by receivers */
+  GRPC_NO_OP,
+  GRPC_OP_METADATA,
+  GRPC_OP_DEADLINE,
+  GRPC_OP_METADATA_BOUNDARY,
+  /* Begin a message/metadata element/status - as defined by
+     grpc_message_type. */
+  GRPC_OP_BEGIN_MESSAGE,
+  /* Add a slice of data to the current message/metadata element/status.
+     Must not overflow the forward declared length. */
+  GRPC_OP_SLICE,
+  /* Call some function once this operation has passed flow control. */
+  GRPC_OP_FLOW_CTL_CB
+} grpc_stream_op_code;
+
+/* Arguments for GRPC_OP_BEGIN */
+typedef struct grpc_begin_message {
+  /* How many bytes of data will this message contain */
+  gpr_uint32 length;
+  /* Write flags for the message: see grpc.h GRPC_WRITE_xxx */
+  gpr_uint32 flags;
+} grpc_begin_message;
+
+/* Arguments for GRPC_OP_FLOW_CTL_CB */
+typedef struct grpc_flow_ctl_cb {
+  void (*cb)(void *arg, grpc_op_error error);
+  void *arg;
+} grpc_flow_ctl_cb;
+
+/* Represents a single operation performed on a stream/transport */
+typedef struct grpc_stream_op {
+  /* the operation to be applied */
+  enum grpc_stream_op_code type;
+  /* the arguments to this operation. union fields are named according to the
+     associated op-code */
+  union {
+    grpc_begin_message begin_message;
+    grpc_mdelem *metadata;
+    gpr_timespec deadline;
+    gpr_slice slice;
+    grpc_flow_ctl_cb flow_ctl_cb;
+  } data;
+} grpc_stream_op;
+
+/* A stream op buffer is a wrapper around stream operations that is dynamically
+   extendable.
+   TODO(ctiller): inline a few elements into the struct, to avoid common case
+                  per-call allocations. */
+typedef struct grpc_stream_op_buffer {
+  grpc_stream_op *ops;
+  size_t nops;
+  size_t capacity;
+} grpc_stream_op_buffer;
+
+/* Initialize a stream op buffer */
+void grpc_sopb_init(grpc_stream_op_buffer *sopb);
+/* Destroy a stream op buffer */
+void grpc_sopb_destroy(grpc_stream_op_buffer *sopb);
+/* Reset a sopb to no elements */
+void grpc_sopb_reset(grpc_stream_op_buffer *sopb);
+
+void grpc_stream_ops_unref_owned_objects(grpc_stream_op *ops, size_t nops);
+
+/* Append a GRPC_NO_OP to a buffer */
+void grpc_sopb_add_no_op(grpc_stream_op_buffer *sopb);
+/* Append a GRPC_OP_BEGIN to a buffer */
+void grpc_sopb_add_begin_message(grpc_stream_op_buffer *sopb, gpr_uint32 length,
+                                 gpr_uint32 flags);
+void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb, grpc_mdelem *metadata);
+void grpc_sopb_add_deadline(grpc_stream_op_buffer *sopb, gpr_timespec deadline);
+void grpc_sopb_add_metadata_boundary(grpc_stream_op_buffer *sopb);
+/* Append a GRPC_SLICE to a buffer - does not ref/unref the slice */
+void grpc_sopb_add_slice(grpc_stream_op_buffer *sopb, gpr_slice slice);
+/* Append a GRPC_OP_FLOW_CTL_CB to a buffer */
+void grpc_sopb_add_flow_ctl_cb(grpc_stream_op_buffer *sopb,
+                               void (*cb)(void *arg, grpc_op_error error),
+                               void *arg);
+/* Append a buffer to a buffer - does not ref/unref any internal objects */
+void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
+                      size_t nops);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__ */
diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c
new file mode 100644
index 0000000..d3291bb
--- /dev/null
+++ b/src/core/transport/transport.c
@@ -0,0 +1,85 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/transport/transport.h"
+#include "src/core/transport/transport_impl.h"
+
+size_t grpc_transport_stream_size(grpc_transport *transport) {
+  return transport->vtable->sizeof_stream;
+}
+
+void grpc_transport_close(grpc_transport *transport) {
+  transport->vtable->close(transport);
+}
+
+void grpc_transport_destroy(grpc_transport *transport) {
+  transport->vtable->destroy(transport);
+}
+
+int grpc_transport_init_stream(grpc_transport *transport, grpc_stream *stream,
+                               const void *server_data) {
+  return transport->vtable->init_stream(transport, stream, server_data);
+}
+
+void grpc_transport_send_batch(grpc_transport *transport, grpc_stream *stream,
+                               grpc_stream_op *ops, size_t nops, int is_last) {
+  transport->vtable->send_batch(transport, stream, ops, nops, is_last);
+}
+
+void grpc_transport_set_allow_window_updates(grpc_transport *transport,
+                                             grpc_stream *stream, int allow) {
+  transport->vtable->set_allow_window_updates(transport, stream, allow);
+}
+
+void grpc_transport_destroy_stream(grpc_transport *transport,
+                                   grpc_stream *stream) {
+  transport->vtable->destroy_stream(transport, stream);
+}
+
+void grpc_transport_abort_stream(grpc_transport *transport, grpc_stream *stream,
+                                 grpc_status_code status) {
+  transport->vtable->abort_stream(transport, stream, status);
+}
+
+void grpc_transport_ping(grpc_transport *transport, void (*cb)(void *user_data),
+                         void *user_data) {
+  transport->vtable->ping(transport, cb, user_data);
+}
+
+void grpc_transport_setup_cancel(grpc_transport_setup *setup) {
+  setup->vtable->cancel(setup);
+}
+
+void grpc_transport_setup_initiate(grpc_transport_setup *setup) {
+  setup->vtable->initiate(setup);
+}
diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h
new file mode 100644
index 0000000..1872947
--- /dev/null
+++ b/src/core/transport/transport.h
@@ -0,0 +1,245 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__
+#define __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__
+
+#include <stddef.h>
+
+#include "src/core/transport/stream_op.h"
+
+/* forward declarations */
+typedef struct grpc_transport grpc_transport;
+typedef struct grpc_transport_callbacks grpc_transport_callbacks;
+
+/* grpc_stream doesn't actually exist. It's used as a typesafe
+   opaque pointer for whatever data the transport wants to track
+   for a stream. */
+typedef struct grpc_stream grpc_stream;
+
+/* Represents the send/recv closed state of a stream. */
+typedef enum grpc_stream_state {
+  /* the stream is open for sends and receives */
+  GRPC_STREAM_OPEN,
+  /* the stream is closed for sends, but may still receive data */
+  GRPC_STREAM_SEND_CLOSED,
+  /* the stream is closed for receives, but may still send data */
+  GRPC_STREAM_RECV_CLOSED,
+  /* the stream is closed for both sends and receives */
+  GRPC_STREAM_CLOSED
+} grpc_stream_state;
+
+/* Callbacks made from the transport to the upper layers of grpc. */
+struct grpc_transport_callbacks {
+  /* Allocate a buffer to receive data into.
+     It's safe to call grpc_slice_new() to do this, but performance minded
+     proxies may want to carefully place data into optimal locations for
+     transports.
+     This function must return a valid, non-empty slice.
+
+     Arguments:
+       user_data - the transport user data set at transport creation time
+       transport - the grpc_transport instance making this call
+       stream    - the grpc_stream instance the buffer will be used for, or
+                   NULL if this is not known
+       size_hint - how big of a buffer would the transport optimally like?
+                   the actual returned buffer can be smaller or larger than
+                   size_hint as the implementation finds convenient */
+  struct gpr_slice (*alloc_recv_buffer)(void *user_data,
+                                        grpc_transport *transport,
+                                        grpc_stream *stream, size_t size_hint);
+
+  /* Initialize a new stream on behalf of the transport.
+     Must result in a call to
+     grpc_transport_init_stream(transport, ..., request) in the same call
+     stack.
+     Must not result in any other calls to the transport.
+
+     Arguments:
+       user_data     - the transport user data set at transport creation time
+       transport     - the grpc_transport instance making this call
+       request       - request parameters for this stream (owned by the caller)
+       server_data   - opaque transport dependent argument that should be passed
+                       to grpc_transport_init_stream
+     */
+  void (*accept_stream)(void *user_data, grpc_transport *transport,
+                        const void *server_data);
+
+  /* Process a set of stream ops that have been received by the transport.
+     Called by network threads, so must be careful not to block on network
+     activity.
+
+     If final_state == GRPC_STREAM_CLOSED, the upper layers should arrange to
+     call grpc_transport_destroy_stream.
+
+     Ownership of any objects contained in ops is transferred to the callee.
+
+     Arguments:
+       user_data   - the transport user data set at transport creation time
+       transport   - the grpc_transport instance making this call
+       stream      - the stream this data was received for
+       ops         - stream operations that are part of this batch
+       ops_count   - the number of stream operations in this batch
+       final_state - the state of the stream as of the final operation in this
+                     batch */
+  void (*recv_batch)(void *user_data, grpc_transport *transport,
+                     grpc_stream *stream, grpc_stream_op *ops, size_t ops_count,
+                     grpc_stream_state final_state);
+
+  /* The transport has been closed */
+  void (*closed)(void *user_data, grpc_transport *transport);
+};
+
+/* Returns the amount of memory required to store a grpc_stream for this
+   transport */
+size_t grpc_transport_stream_size(grpc_transport *transport);
+
+/* Initialize transport data for a stream.
+
+   Returns 0 on success, any other (transport-defined) value for failure.
+
+   Arguments:
+     transport   - the transport on which to create this stream
+     stream      - a pointer to uninitialized memory to initialize
+     server_data - either NULL for a client initiated stream, or a pointer
+                   supplied from the accept_stream callback function */
+int grpc_transport_init_stream(grpc_transport *transport, grpc_stream *stream,
+                               const void *server_data);
+
+/* Destroy transport data for a stream.
+
+   Requires: a recv_batch with final_state == GRPC_STREAM_CLOSED has been
+   received by the up-layer. Must not be called in the same call stack as
+   recv_frame.
+
+   Arguments:
+     transport - the transport on which to create this stream
+     stream    - the grpc_stream to destroy (memory is still owned by the
+                 caller, but any child memory must be cleaned up) */
+void grpc_transport_destroy_stream(grpc_transport *transport,
+                                   grpc_stream *stream);
+
+/* Enable/disable incoming data for a stream.
+
+   This effectively disables new window becoming available for a given stream,
+   but does not prevent existing window from being consumed by a sender: the
+   caller must still be prepared to receive some additional data after this
+   call.
+
+   Arguments:
+     transport - the transport on which to create this stream
+     stream    - the grpc_stream to destroy (memory is still owned by the
+                 caller, but any child memory must be cleaned up)
+     allow     - is it allowed that new window be opened up? */
+void grpc_transport_set_allow_window_updates(grpc_transport *transport,
+                                             grpc_stream *stream, int allow);
+
+/* Send a batch of operations on a transport
+
+   Takes ownership of any objects contained in ops.
+
+   Arguments:
+     transport - the transport on which to initiate the stream
+     stream    - the stream on which to send the operations. This must be
+                 non-NULL and previously initialized by the same transport.
+     ops       - an array of operations to apply to the stream - can be NULL
+                 if ops_count == 0.
+     ops_count - the number of elements in ops
+     is_last   - is this the last batch of operations to be sent out */
+void grpc_transport_send_batch(grpc_transport *transport, grpc_stream *stream,
+                               grpc_stream_op *ops, size_t ops_count,
+                               int is_last);
+
+/* Send a ping on a transport
+
+   Calls cb with user data when a response is received.
+   cb *MAY* be called with arbitrary transport level locks held. It is not safe
+   to call into the transport during cb. */
+void grpc_transport_ping(grpc_transport *transport, void (*cb)(void *user_data),
+                         void *user_data);
+
+/* Abort a stream
+
+   Terminate reading and writing for a stream. A final recv_batch with no
+   operations and final_state == GRPC_STREAM_CLOSED will be received locally,
+   and no more data will be presented to the up-layer.
+
+   TODO(ctiller): consider adding a HTTP/2 reason to this function. */
+void grpc_transport_abort_stream(grpc_transport *transport, grpc_stream *stream,
+                                 grpc_status_code status);
+
+/* Close a transport. Aborts all open streams. */
+void grpc_transport_close(struct grpc_transport *transport);
+
+/* Destroy the transport */
+void grpc_transport_destroy(struct grpc_transport *transport);
+
+/* Return type for grpc_transport_setup_callback */
+typedef struct grpc_transport_setup_result {
+  void *user_data;
+  const grpc_transport_callbacks *callbacks;
+} grpc_transport_setup_result;
+
+/* Given a transport, return callbacks for that transport. Used to finalize
+   setup as a transport is being created */
+typedef grpc_transport_setup_result (*grpc_transport_setup_callback)(
+    void *setup_arg, grpc_transport *transport, grpc_mdctx *mdctx);
+
+typedef struct grpc_transport_setup grpc_transport_setup;
+typedef struct grpc_transport_setup_vtable grpc_transport_setup_vtable;
+
+struct grpc_transport_setup_vtable {
+  void (*initiate)(grpc_transport_setup *setup);
+  void (*cancel)(grpc_transport_setup *setup);
+};
+
+/* Transport setup is an asynchronous utility interface for client channels to
+   establish connections. It's transport agnostic. */
+struct grpc_transport_setup {
+  const grpc_transport_setup_vtable *vtable;
+};
+
+/* Initiate transport setup: e.g. for TCP+DNS trigger a resolve of the name
+   given at transport construction time, create the tcp connection, perform
+   handshakes, and call some grpc_transport_setup_result function provided at
+   setup construction time.
+   This *may* be implemented as a no-op if the setup process monitors something
+   continuously. */
+void grpc_transport_setup_initiate(grpc_transport_setup *setup);
+/* Cancel transport setup. After this returns, no new transports should be
+   created, and all pending transport setup callbacks should be completed.
+   After this call completes, setup should be considered invalid (this can be
+   used as a destruction call by setup). */
+void grpc_transport_setup_cancel(grpc_transport_setup *setup);
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__ */
diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h
new file mode 100644
index 0000000..6acdbf2
--- /dev/null
+++ b/src/core/transport/transport_impl.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__
+#define __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__
+
+#include "src/core/transport/transport.h"
+
+typedef struct grpc_transport_vtable {
+  /* Memory required for a single stream element - this is allocated by upper
+     layers and initialized by the transport */
+  size_t sizeof_stream; /* = sizeof(transport stream) */
+
+  /* implementation of grpc_transport_init_stream */
+  int (*init_stream)(grpc_transport *self, grpc_stream *stream,
+                     const void *server_data);
+
+  /* implementation of grpc_transport_send_batch */
+  void (*send_batch)(grpc_transport *self, grpc_stream *stream,
+                     grpc_stream_op *ops, size_t ops_count, int is_last);
+
+  /* implementation of grpc_transport_set_allow_window_updates */
+  void (*set_allow_window_updates)(grpc_transport *self, grpc_stream *stream,
+                                   int allow);
+
+  /* implementation of grpc_transport_destroy_stream */
+  void (*destroy_stream)(grpc_transport *self, grpc_stream *stream);
+
+  /* implementation of grpc_transport_abort_stream */
+  void (*abort_stream)(grpc_transport *self, grpc_stream *stream,
+                       grpc_status_code status);
+
+  /* implementation of grpc_transport_close */
+  void (*close)(grpc_transport *self);
+
+  /* implementation of grpc_transport_ping */
+  void (*ping)(grpc_transport *self, void (*cb)(void *user_data),
+               void *user_data);
+
+  /* implementation of grpc_transport_destroy */
+  void (*destroy)(grpc_transport *self);
+} grpc_transport_vtable;
+
+/* an instance of a grpc transport */
+struct grpc_transport {
+  /* pointer to a vtable defining operations on this transport */
+  const grpc_transport_vtable *vtable;
+};
+
+#endif  /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__ */
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
new file mode 100644
index 0000000..7807e71
--- /dev/null
+++ b/src/core/tsi/fake_transport_security.c
@@ -0,0 +1,515 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/tsi/fake_transport_security.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include "src/core/tsi/transport_security.h"
+
+/* --- Constants. ---*/
+#define TSI_FAKE_FRAME_HEADER_SIZE 4
+#define TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE 64
+#define TSI_FAKE_DEFAULT_FRAME_SIZE 16384
+
+/* --- Structure definitions. ---*/
+
+/* a frame is encoded like this:
+   | size |     data    |
+   where the size field value is the size of the size field plus the size of
+   the data encoded in little endian on 4 bytes.  */
+typedef struct {
+  unsigned char* data;
+  uint32_t size;
+  uint32_t allocated_size;
+  uint32_t offset;
+  int needs_draining;
+} tsi_fake_frame;
+
+typedef enum {
+  TSI_FAKE_CLIENT_INIT = 0,
+  TSI_FAKE_SERVER_INIT = 1,
+  TSI_FAKE_CLIENT_FINISHED = 2,
+  TSI_FAKE_SERVER_FINISHED = 3,
+  TSI_FAKE_HANDSHAKE_MESSAGE_MAX = 4
+} tsi_fake_handshake_message;
+
+typedef struct {
+  tsi_handshaker base;
+  int is_client;
+  tsi_fake_handshake_message next_message_to_send;
+  int needs_incoming_message;
+  tsi_fake_frame incoming;
+  tsi_fake_frame outgoing;
+  tsi_result result;
+} tsi_fake_handshaker;
+
+typedef struct {
+  tsi_frame_protector base;
+  tsi_fake_frame protect_frame;
+  tsi_fake_frame unprotect_frame;
+  uint32_t max_frame_size;
+} tsi_fake_frame_protector;
+
+
+/* --- Utils. ---*/
+
+static const char* tsi_fake_handshake_message_strings[] = {
+    "CLIENT_INIT", "SERVER_INIT", "CLIENT_FINISHED", "SERVER_FINISHED"};
+
+static const char* tsi_fake_handshake_message_to_string(int msg) {
+  if (msg < 0 || msg >= TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
+    gpr_log(GPR_ERROR, "Invalid message %d", msg);
+    return "UNKNOWN";
+  }
+  return tsi_fake_handshake_message_strings[msg];
+}
+
+static tsi_result tsi_fake_handshake_message_from_string(
+    const char* msg_string, tsi_fake_handshake_message* msg) {
+  int i;
+  for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
+    if (!strncmp(msg_string, tsi_fake_handshake_message_strings[i],
+                 strlen(tsi_fake_handshake_message_strings[i]))) {
+      *msg = i;
+      return TSI_OK;
+    }
+  }
+  gpr_log(GPR_ERROR, "Invalid handshake message.");
+  return TSI_DATA_CORRUPTED;
+}
+
+static uint32_t load32_little_endian(const unsigned char* buf) {
+  return ((uint32_t)(buf[0]) | (uint32_t)(buf[1] << 8) |
+          (uint32_t)(buf[2] << 16) | (uint32_t)(buf[3] << 24));
+}
+
+static void store32_little_endian(uint32_t value, unsigned char* buf) {
+  buf[3] = (unsigned char)(value >> 24) & 0xFF;
+  buf[2] = (unsigned char)(value >> 16) & 0xFF;
+  buf[1] = (unsigned char)(value >> 8) & 0xFF;
+  buf[0] = (unsigned char)(value) & 0xFF;
+}
+
+static void tsi_fake_frame_reset(tsi_fake_frame* frame, int needs_draining) {
+  frame->offset = 0;
+  frame->needs_draining = needs_draining;
+  if (!needs_draining) frame->size = 0;
+}
+
+/* Returns 1 if successful, 0 otherwise. */
+static int tsi_fake_frame_ensure_size(tsi_fake_frame* frame) {
+  if (frame->data == NULL) {
+    frame->allocated_size = frame->size;
+    frame->data = malloc(frame->allocated_size);
+    if (frame->data == NULL) return 0;
+  } else if (frame->size > frame->allocated_size) {
+    unsigned char* new_data = realloc(frame->data, frame->size);
+    if (new_data == NULL) {
+      free(frame->data);
+      frame->data = NULL;
+      return 0;
+    }
+    frame->data = new_data;
+    frame->allocated_size = frame->size;
+  }
+  return 1;
+}
+
+/* This method should not be called if frame->needs_framing is not 0.  */
+static tsi_result fill_frame_from_bytes(const unsigned char* incoming_bytes,
+                                        uint32_t* incoming_bytes_size,
+                                        tsi_fake_frame* frame) {
+  uint32_t available_size = *incoming_bytes_size;
+  uint32_t to_read_size = 0;
+  const unsigned char* bytes_cursor = incoming_bytes;
+
+  if (frame->needs_draining) return TSI_INTERNAL_ERROR;
+  if (frame->data == NULL) {
+    frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE;
+    frame->data = malloc(frame->allocated_size);
+    if (frame->data == NULL) return TSI_OUT_OF_RESOURCES;
+  }
+
+  if (frame->offset < TSI_FAKE_FRAME_HEADER_SIZE) {
+    to_read_size = TSI_FAKE_FRAME_HEADER_SIZE - frame->offset;
+    if (to_read_size > available_size) {
+      /* Just fill what we can and exit. */
+      memcpy(frame->data + frame->offset, bytes_cursor, available_size);
+      bytes_cursor += available_size;
+      frame->offset += available_size;
+      *incoming_bytes_size = bytes_cursor - incoming_bytes;
+      return TSI_INCOMPLETE_DATA;
+    }
+    memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
+    bytes_cursor += to_read_size;
+    frame->offset += to_read_size;
+    available_size -= to_read_size;
+    frame->size = load32_little_endian(frame->data);
+    if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES;
+  }
+
+  to_read_size = frame->size - frame->offset;
+  if (to_read_size > available_size) {
+    memcpy(frame->data + frame->offset, bytes_cursor, available_size);
+    frame->offset += available_size;
+    bytes_cursor += available_size;
+    *incoming_bytes_size = bytes_cursor - incoming_bytes;
+    return TSI_INCOMPLETE_DATA;
+  }
+  memcpy(frame->data + frame->offset, bytes_cursor, to_read_size);
+  bytes_cursor += to_read_size;
+  *incoming_bytes_size = bytes_cursor - incoming_bytes;
+  tsi_fake_frame_reset(frame, 1 /* needs_draining */);
+  return TSI_OK;
+}
+
+/* This method should not be called if frame->needs_framing is 0.  */
+static tsi_result drain_frame_to_bytes(unsigned char* outgoing_bytes,
+                                       uint32_t* outgoing_bytes_size,
+                                       tsi_fake_frame* frame) {
+  uint32_t to_write_size = frame->size - frame->offset;
+  if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
+  if (*outgoing_bytes_size < to_write_size) {
+    memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size);
+    frame->offset += *outgoing_bytes_size;
+    return TSI_INCOMPLETE_DATA;
+  }
+  memcpy(outgoing_bytes, frame->data + frame->offset, to_write_size);
+  *outgoing_bytes_size = to_write_size;
+  tsi_fake_frame_reset(frame, 0 /* needs_draining */);
+  return TSI_OK;
+}
+
+static tsi_result bytes_to_frame(unsigned char* bytes, uint32_t bytes_size,
+                                 tsi_fake_frame* frame) {
+  frame->offset = 0;
+  frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE;
+  if (!tsi_fake_frame_ensure_size(frame)) return TSI_OUT_OF_RESOURCES;
+  store32_little_endian(frame->size, frame->data);
+  memcpy(frame->data + TSI_FAKE_FRAME_HEADER_SIZE, bytes, bytes_size);
+  tsi_fake_frame_reset(frame, 1 /* needs draining */);
+  return TSI_OK;
+}
+
+static void tsi_fake_frame_destruct(tsi_fake_frame* frame) {
+  if (frame->data != NULL) free(frame->data);
+}
+
+/* --- tsi_frame_protector methods implementation. ---*/
+
+static tsi_result fake_protector_protect(
+    tsi_frame_protector* self, const unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size, unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size) {
+  tsi_result result = TSI_OK;
+  tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
+  unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE];
+  tsi_fake_frame* frame = &impl->protect_frame;
+  uint32_t saved_output_size = *protected_output_frames_size;
+  uint32_t drained_size = 0;
+  uint32_t* num_bytes_written = protected_output_frames_size;
+  *num_bytes_written = 0;
+
+  /* Try to drain first. */
+  if (frame->needs_draining) {
+    drained_size = saved_output_size - *num_bytes_written;
+    result = drain_frame_to_bytes(protected_output_frames,
+                                  &drained_size, frame);
+    *num_bytes_written += drained_size;
+    protected_output_frames += drained_size;
+    if (result != TSI_OK) {
+      if (result == TSI_INCOMPLETE_DATA) {
+        *unprotected_bytes_size = 0;
+        result = TSI_OK;
+      }
+      return result;
+    }
+  }
+
+  /* Now process the unprotected_bytes. */
+  if (frame->needs_draining) return TSI_INTERNAL_ERROR;
+  if (frame->size == 0) {
+    /* New frame, create a header. */
+    uint32_t written_in_frame_size = 0;
+    store32_little_endian(impl->max_frame_size, frame_header);
+    written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE;
+    result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame);
+    if (result != TSI_INCOMPLETE_DATA) {
+      gpr_log(GPR_ERROR, "fill_frame_from_bytes returned %s",
+              tsi_result_to_string(result));
+      return result;
+    }
+  }
+  result = fill_frame_from_bytes(unprotected_bytes, unprotected_bytes_size,
+                                 frame);
+  if (result != TSI_OK) {
+    if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
+    return result;
+  }
+
+  /* Try to drain again. */
+  if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
+  if (frame->offset != 0) return TSI_INTERNAL_ERROR;
+  drained_size = saved_output_size - *num_bytes_written;
+  result = drain_frame_to_bytes(protected_output_frames, &drained_size, frame);
+  *num_bytes_written += drained_size;
+  if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
+  return result;
+}
+
+static tsi_result fake_protector_protect_flush(
+    tsi_frame_protector* self, unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size, uint32_t* still_pending_size) {
+  tsi_result result = TSI_OK;
+  tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
+  tsi_fake_frame* frame = &impl->protect_frame;
+  if (!frame->needs_draining) {
+    /* Create a short frame. */
+    frame->size = frame->offset;
+    frame->offset = 0;
+    frame->needs_draining = 1;
+    store32_little_endian(frame->size, frame->data);  /* Overwrite header. */
+  }
+  result = drain_frame_to_bytes(protected_output_frames,
+                                protected_output_frames_size, frame);
+  if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
+  *still_pending_size = frame->size - frame->offset;
+  return result;
+}
+
+static tsi_result fake_protector_unprotect(
+    tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
+    uint32_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size) {
+  tsi_result result = TSI_OK;
+  tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
+  tsi_fake_frame* frame = &impl->unprotect_frame;
+  uint32_t saved_output_size = *unprotected_bytes_size;
+  uint32_t drained_size = 0;
+  uint32_t* num_bytes_written = unprotected_bytes_size;
+  *num_bytes_written = 0;
+
+  /* Try to drain first. */
+  if (frame->needs_draining) {
+    /* Go past the header if needed. */
+    if (frame->offset == 0) frame->offset = TSI_FAKE_FRAME_HEADER_SIZE;
+    drained_size = saved_output_size - *num_bytes_written;
+    result = drain_frame_to_bytes(unprotected_bytes, &drained_size,
+                                  frame);
+    unprotected_bytes += drained_size;
+    *num_bytes_written += drained_size;
+    if (result != TSI_OK) {
+      if (result == TSI_INCOMPLETE_DATA) {
+        *protected_frames_bytes_size = 0;
+        result = TSI_OK;
+      }
+      return result;
+    }
+  }
+
+  /* Now process the protected_bytes. */
+  if (frame->needs_draining) return TSI_INTERNAL_ERROR;
+  result = fill_frame_from_bytes(protected_frames_bytes,
+                                 protected_frames_bytes_size, frame);
+  if (result != TSI_OK) {
+    if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
+    return result;
+  }
+
+  /* Try to drain again. */
+  if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
+  if (frame->offset != 0) return TSI_INTERNAL_ERROR;
+  frame->offset = TSI_FAKE_FRAME_HEADER_SIZE;  /* Go past the header. */
+  drained_size = saved_output_size - *num_bytes_written;
+  result = drain_frame_to_bytes(unprotected_bytes, &drained_size, frame);
+  *num_bytes_written += drained_size;
+  if (result == TSI_INCOMPLETE_DATA) result = TSI_OK;
+  return result;
+}
+
+static void fake_protector_destroy(tsi_frame_protector* self) {
+  tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
+  tsi_fake_frame_destruct(&impl->protect_frame);
+  tsi_fake_frame_destruct(&impl->unprotect_frame);
+  free(self);
+}
+
+static const tsi_frame_protector_vtable frame_protector_vtable = {
+    fake_protector_protect, fake_protector_protect_flush,
+    fake_protector_unprotect, fake_protector_destroy,
+};
+
+/* --- tsi_handshaker methods implementation. ---*/
+
+static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
+    tsi_handshaker* self, unsigned char* bytes, uint32_t* bytes_size) {
+  tsi_fake_handshaker* impl = (tsi_fake_handshaker*)self;
+  tsi_result result = TSI_OK;
+  if (impl->needs_incoming_message || impl->result == TSI_OK) {
+    *bytes_size = 0;
+    return TSI_OK;
+  }
+  if (!impl->outgoing.needs_draining) {
+    int next_message_to_send = impl->next_message_to_send + 2;
+    const char* msg_string =
+        tsi_fake_handshake_message_to_string(impl->next_message_to_send);
+    result = bytes_to_frame((unsigned char*)msg_string, strlen(msg_string),
+                            &impl->outgoing);
+    if (result != TSI_OK) return result;
+    if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
+      next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX;
+    }
+    gpr_log(GPR_INFO, "%s prepared %s.", impl->is_client ? "Client" : "Server",
+            tsi_fake_handshake_message_to_string(impl->next_message_to_send));
+    impl->next_message_to_send = next_message_to_send;
+  }
+  result = drain_frame_to_bytes(bytes, bytes_size, &impl->outgoing);
+  if (result != TSI_OK) return result;
+  if (!impl->is_client &&
+      impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
+    /* We're done. */
+    gpr_log(GPR_INFO, "Server is done.");
+    impl->result = TSI_OK;
+  } else {
+    impl->needs_incoming_message = 1;
+  }
+  return TSI_OK;
+}
+
+static tsi_result fake_handshaker_process_bytes_from_peer(
+    tsi_handshaker* self, const unsigned char* bytes, uint32_t* bytes_size) {
+  tsi_result result = TSI_OK;
+  tsi_fake_handshaker* impl = (tsi_fake_handshaker*)self;
+  int expected_msg = impl->next_message_to_send - 1;
+  tsi_fake_handshake_message received_msg;
+
+  if (!impl->needs_incoming_message || impl->result == TSI_OK) {
+    *bytes_size = 0;
+    return TSI_OK;
+  }
+  result = fill_frame_from_bytes(bytes, bytes_size, &impl->incoming);
+  if (result != TSI_OK) return result;
+
+  /* We now have a complete frame. */
+  result = tsi_fake_handshake_message_from_string(
+      (const char*)impl->incoming.data + TSI_FAKE_FRAME_HEADER_SIZE,
+      &received_msg);
+  if (result != TSI_OK) {
+    impl->result = result;
+    return result;
+  }
+  if (received_msg != expected_msg) {
+    gpr_log(GPR_ERROR, "Invalid received message (%s instead of %s)",
+            tsi_fake_handshake_message_to_string(received_msg),
+            tsi_fake_handshake_message_to_string(expected_msg));
+  }
+  gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server",
+          tsi_fake_handshake_message_to_string(received_msg));
+  tsi_fake_frame_reset(&impl->incoming, 0 /* needs_draining */);
+  impl->needs_incoming_message = 0;
+  if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
+    /* We're done. */
+    gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server");
+    impl->result = TSI_OK;
+  }
+  return TSI_OK;
+}
+
+static tsi_result fake_handshaker_get_result(tsi_handshaker* self) {
+  tsi_fake_handshaker* impl = (tsi_fake_handshaker*)self;
+  return impl->result;
+}
+
+static tsi_result fake_handshaker_extract_peer(tsi_handshaker* self,
+                                               tsi_peer* peer) {
+  tsi_result result = tsi_construct_peer(1, peer);
+  if (result != TSI_OK) return result;
+  result = tsi_construct_string_peer_property_from_cstring(
+      TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_FAKE_CERTIFICATE_TYPE,
+      &peer->properties[0]);
+  if (result != TSI_OK) tsi_peer_destruct(peer);
+  return result;
+}
+
+static tsi_result fake_handshaker_create_frame_protector(
+    tsi_handshaker* self, uint32_t* max_protected_frame_size,
+    tsi_frame_protector** protector) {
+  *protector = tsi_create_fake_protector(max_protected_frame_size);
+  if (*protector == NULL) return TSI_OUT_OF_RESOURCES;
+  return TSI_OK;
+}
+
+static void fake_handshaker_destroy(tsi_handshaker* self) {
+  tsi_fake_handshaker* impl = (tsi_fake_handshaker*)self;
+  tsi_fake_frame_destruct(&impl->incoming);
+  tsi_fake_frame_destruct(&impl->outgoing);
+  free(self);
+}
+
+static const tsi_handshaker_vtable handshaker_vtable = {
+    fake_handshaker_get_bytes_to_send_to_peer,
+    fake_handshaker_process_bytes_from_peer,
+    fake_handshaker_get_result,
+    fake_handshaker_extract_peer,
+    fake_handshaker_create_frame_protector,
+    fake_handshaker_destroy,
+};
+
+tsi_handshaker* tsi_create_fake_handshaker(int is_client) {
+  tsi_fake_handshaker* impl = calloc(1, sizeof(tsi_fake_handshaker));
+  impl->base.vtable = &handshaker_vtable;
+  impl->is_client = is_client;
+  impl->result = TSI_HANDSHAKE_IN_PROGRESS;
+  if (is_client) {
+    impl->needs_incoming_message = 0;
+    impl->next_message_to_send = TSI_FAKE_CLIENT_INIT;
+  } else {
+    impl->needs_incoming_message = 1;
+    impl->next_message_to_send = TSI_FAKE_SERVER_INIT;
+  }
+  return &impl->base;
+}
+
+tsi_frame_protector* tsi_create_fake_protector(
+    uint32_t* max_protected_frame_size) {
+  tsi_fake_frame_protector* impl = calloc(1, sizeof(tsi_fake_frame_protector));
+  if (impl == NULL) return NULL;
+  impl->max_frame_size = (max_protected_frame_size == NULL)
+                             ? TSI_FAKE_DEFAULT_FRAME_SIZE
+                             : *max_protected_frame_size;
+  impl->base.vtable = &frame_protector_vtable;
+  return &impl->base;
+}
diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
new file mode 100644
index 0000000..075d518
--- /dev/null
+++ b/src/core/tsi/fake_transport_security.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __FAKE_TRANSPORT_SECURITY_H_
+#define __FAKE_TRANSPORT_SECURITY_H_
+
+#include "src/core/tsi/transport_security_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for FAKE certs. */
+#define TSI_FAKE_CERTIFICATE_TYPE "FAKE"
+
+/* Creates a fake handshaker that will create a fake frame protector.
+
+   No cryptography is performed in these objects. They just simulate handshake
+   messages going back and forth for the handshaker and do some framing on
+   cleartext data for the protector.  */
+tsi_handshaker* tsi_create_fake_handshaker(int is_client);
+
+
+/* Creates a protector directly without going through the handshake phase. */
+tsi_frame_protector* tsi_create_fake_protector(
+    uint32_t* max_protected_frame_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __FAKE_TRANSPORT_SECURITY_H_ */
diff --git a/src/core/tsi/fake_transport_security_test.cc b/src/core/tsi/fake_transport_security_test.cc
new file mode 100644
index 0000000..0ae88e0
--- /dev/null
+++ b/src/core/tsi/fake_transport_security_test.cc
@@ -0,0 +1,151 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/tsi/fake_transport_security.h"
+
+#include "src/core/tsi/transport_security_test_lib.h"
+#include <gtest/gtest.h>
+#include "util/random/permute-inl.h"
+
+namespace {
+
+void CheckStringPeerProperty(const tsi_peer& peer, int property_index,
+                             const char* expected_name,
+                             const char* expected_value) {
+  EXPECT_LT(property_index, peer.property_count);
+  const tsi_peer_property* property = &peer.properties[property_index];
+  EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, property->type);
+  EXPECT_EQ(string(expected_name), string(property->name));
+  EXPECT_EQ(string(expected_value),
+            string(property->value.string.data, property->value.string.length));
+}
+
+class FakeTransportSecurityTest : public tsi::test::TransportSecurityTest {
+ protected:
+  void SetupHandshakers() override {
+    client_handshaker_.reset(tsi_create_fake_handshaker(1));
+    server_handshaker_.reset(tsi_create_fake_handshaker(0));
+  }
+
+  void CheckPeer(tsi_handshaker* handshaker) {
+    tsi_peer peer;
+    EXPECT_EQ(TSI_OK, tsi_handshaker_extract_peer(handshaker, &peer));
+    EXPECT_EQ(1, peer.property_count);
+    CheckStringPeerProperty(peer, 0, TSI_CERTIFICATE_TYPE_PEER_PROPERTY,
+                            TSI_FAKE_CERTIFICATE_TYPE);
+    tsi_peer_destruct(&peer);
+  }
+
+  void CheckHandshakeResults() override {
+    CheckPeer(client_handshaker_.get());
+    CheckPeer(server_handshaker_.get());
+  }
+
+  const tsi::test::TestConfig* config() {
+    return &config_;
+  }
+
+  tsi::test::TestConfig config_;
+};
+
+TEST_F(FakeTransportSecurityTest, Handshake) {
+  PerformHandshake();
+}
+
+TEST_F(FakeTransportSecurityTest, HandshakeSmallBuffer) {
+  config_.handshake_buffer_size = 3;
+  PerformHandshake();
+}
+TEST_F(FakeTransportSecurityTest, PingPong) {
+  PingPong();
+}
+
+TEST_F(FakeTransportSecurityTest, RoundTrip) {
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(FakeTransportSecurityTest, RoundTripSmallMessageBuffer) {
+  config_.message_buffer_allocated_size = 42;
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(FakeTransportSecurityTest, RoundTripSmallProtectedBufferSize) {
+  config_.protected_buffer_size = 37;
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(FakeTransportSecurityTest, RoundTripSmallReadBufferSize) {
+  config_.read_buffer_allocated_size = 41;
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(FakeTransportSecurityTest, RoundTripSmallClientFrames) {
+  config_.set_client_max_output_protected_frame_size(39);
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(FakeTransportSecurityTest, RoundTripSmallServerFrames) {
+  config_.set_server_max_output_protected_frame_size(43);
+  config_.client_message = small_message_;
+  config_.server_message = big_message_;
+  DoRoundTrip();
+}
+
+TEST_F(FakeTransportSecurityTest, RoundTripOddBufferSizes) {
+  int odd_sizes[] = {33, 67, 135, 271, 523};
+  RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes),
+                                 random_.get());
+  permute.Permute();
+  LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2]
+             << "\t" << odd_sizes[3] << "\t" << odd_sizes[4];
+  config_.message_buffer_allocated_size = odd_sizes[0];
+  config_.protected_buffer_size = odd_sizes[1];
+  config_.read_buffer_allocated_size = odd_sizes[2];
+  config_.set_client_max_output_protected_frame_size(odd_sizes[3]);
+  config_.set_server_max_output_protected_frame_size(odd_sizes[4]);
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+}  // namespace
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
new file mode 100644
index 0000000..7bd178b
--- /dev/null
+++ b/src/core/tsi/ssl_transport_security.c
@@ -0,0 +1,1294 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/tsi/ssl_transport_security.h"
+
+#include <limits.h>
+#include <pthread.h>
+
+#include <grpc/support/log.h>
+#include "src/core/tsi/transport_security.h"
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+/* --- Constants. ---*/
+
+#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND 16384
+#define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND 1024
+
+/* TODO(jboeuf): I have not found a way to get this number dynamically from the
+ * SSL structure. This is what we would ultimately want though... */
+#define TSI_SSL_MAX_PROTECTION_OVERHEAD 100
+
+
+/* --- Structure definitions. ---*/
+
+struct tsi_ssl_handshaker_factory {
+  tsi_result (*create_handshaker)(tsi_ssl_handshaker_factory* self,
+                                  const char* server_name_indication,
+                                  tsi_handshaker** handshaker);
+  void (*destroy)(tsi_ssl_handshaker_factory* self);
+};
+
+typedef struct {
+  tsi_ssl_handshaker_factory base;
+  SSL_CTX* ssl_context;
+} tsi_ssl_client_handshaker_factory;
+
+typedef struct {
+  tsi_ssl_handshaker_factory base;
+
+  /* Several contexts to support SNI.
+     The tsi_peer array contains the subject names of the server certificates
+     associated with the contexts at the same index.  */
+  SSL_CTX** ssl_contexts;
+  tsi_peer* ssl_context_x509_subject_names;
+  uint32_t ssl_context_count;
+  unsigned char* alpn_protocol_list;
+  uint32_t alpn_protocol_list_length;
+} tsi_ssl_server_handshaker_factory;
+
+typedef struct {
+  tsi_handshaker base;
+  SSL* ssl;
+  BIO* into_ssl;
+  BIO* from_ssl;
+  tsi_result result;
+} tsi_ssl_handshaker;
+
+typedef struct {
+  tsi_frame_protector base;
+  SSL* ssl;
+  BIO* into_ssl;
+  BIO* from_ssl;
+  unsigned char* buffer;
+  uint32_t buffer_size;
+  uint32_t buffer_offset;
+} tsi_ssl_frame_protector;
+
+
+/* --- Library Initialization. ---*/
+
+static pthread_once_t init_openssl_once = PTHREAD_ONCE_INIT;
+
+static void init_openssl(void) {
+  SSL_library_init();
+  SSL_load_error_strings();
+  OpenSSL_add_all_algorithms();
+}
+
+/* --- Ssl utils. ---*/
+
+static const char* ssl_error_string(int error) {
+  switch (error) {
+    case SSL_ERROR_NONE:
+      return "SSL_ERROR_NONE";
+    case SSL_ERROR_ZERO_RETURN:
+      return "SSL_ERROR_ZERO_RETURN";
+    case SSL_ERROR_WANT_READ:
+      return "SSL_ERROR_WANT_READ";
+    case SSL_ERROR_WANT_WRITE:
+      return "SSL_ERROR_WANT_WRITE";
+    case SSL_ERROR_WANT_CONNECT:
+      return "SSL_ERROR_WANT_CONNECT";
+    case SSL_ERROR_WANT_ACCEPT:
+      return "SSL_ERROR_WANT_ACCEPT";
+    case SSL_ERROR_WANT_X509_LOOKUP:
+      return "SSL_ERROR_WANT_X509_LOOKUP";
+    case SSL_ERROR_SYSCALL:
+      return "SSL_ERROR_SYSCALL";
+    case SSL_ERROR_SSL:
+      return "SSL_ERROR_SSL";
+    default:
+      return "Unknown error";
+  }
+}
+
+/* TODO(jboeuf): Remove when we are past the debugging phase with this code. */
+static void ssl_log_where_info(const SSL* ssl, int where, int flag,
+                               const char* msg) {
+  if (where & flag) {
+    gpr_log(GPR_INFO, "%20.20s - %30.30s  - %5.10s", msg,
+            SSL_state_string_long(ssl), SSL_state_string(ssl));
+  }
+}
+
+/* Used for debugging. TODO(jboeuf): Remove when code is mature enough. */
+static void ssl_info_callback(const SSL* ssl, int where, int ret) {
+  if (ret == 0) {
+    gpr_log(GPR_ERROR, "ssl_info_callback: error occured.\n");
+    return;
+  }
+
+  ssl_log_where_info(ssl, where, SSL_CB_LOOP, "LOOP");
+  ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START");
+  ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE");
+}
+
+/* Gets the subject CN from an X509 cert. */
+static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8,
+                                           uint32_t* utf8_size) {
+  int common_name_index = -1;
+  X509_NAME_ENTRY* common_name_entry = NULL;
+  ASN1_STRING* common_name_asn1 = NULL;
+  X509_NAME* subject_name = X509_get_subject_name(cert);
+  int utf8_returned_size = 0;
+  if (subject_name == NULL) {
+    gpr_log(GPR_ERROR, "Could not get subject name from certificate.");
+    return TSI_NOT_FOUND;
+  }
+  common_name_index =
+      X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1);
+  if (common_name_index == -1) {
+    gpr_log(GPR_ERROR,
+            "Could not get common name of subject from certificate.");
+    return TSI_NOT_FOUND;
+  }
+  common_name_entry = X509_NAME_get_entry(subject_name, common_name_index);
+  if (common_name_entry == NULL) {
+    gpr_log(GPR_ERROR, "Could not get common name entry from certificate.");
+    return TSI_INTERNAL_ERROR;
+  }
+  common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
+  if (common_name_asn1 == NULL) {
+    gpr_log(GPR_ERROR,
+            "Could not get common name entry asn1 from certificate.");
+    return TSI_INTERNAL_ERROR;
+  }
+  utf8_returned_size = ASN1_STRING_to_UTF8(utf8, common_name_asn1);
+  if (utf8_returned_size < 0) {
+    gpr_log(GPR_ERROR, "Could not extract utf8 from asn1 string.");
+    return TSI_OUT_OF_RESOURCES;
+  }
+  *utf8_size = utf8_returned_size;
+  return TSI_OK;
+}
+
+/* Gets the subject CN of an X509 cert as a tsi_peer_property. */
+static tsi_result peer_property_from_x509_common_name(
+    X509* cert, tsi_peer_property* property) {
+  unsigned char* common_name;
+  uint32_t common_name_size;
+  tsi_result result =
+      ssl_get_x509_common_name(cert, &common_name, &common_name_size);
+  if (result != TSI_OK) return result;
+  result = tsi_construct_string_peer_property(
+      TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, (const char*)common_name,
+      common_name_size, property);
+  OPENSSL_free(common_name);
+  return result;
+}
+
+/* Gets the subject SANs from an X509 cert as a tsi_peer_property. */
+static tsi_result peer_property_from_x509_subject_alt_names(
+    X509* cert, tsi_peer_property* property) {
+  int i = 0;
+  int subject_alt_name_count = 0;
+  tsi_result result = TSI_OK;
+  GENERAL_NAMES* subject_alt_names =
+      X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
+  if (subject_alt_names == NULL) {
+    /* Empty list. */
+    return tsi_construct_list_peer_property(
+        TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY, 0, property);
+  }
+
+  subject_alt_name_count = sk_GENERAL_NAME_num(subject_alt_names);
+  result = tsi_construct_list_peer_property(
+      TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY, subject_alt_name_count,
+      property);
+  if (result != TSI_OK) return result;
+
+  /* Reset for DNS entries filtering. */
+  subject_alt_name_count = property->value.list.child_count;
+  property->value.list.child_count = 0;
+
+  for (i = 0; i < subject_alt_name_count; i++) {
+    tsi_peer_property* child_property = NULL;
+    GENERAL_NAME* subject_alt_name =
+        sk_GENERAL_NAME_value(subject_alt_names, i);
+    /* Filter out the non-dns entries names. */
+    if (subject_alt_name->type == GEN_DNS) {
+      unsigned char* dns_name = NULL;
+      int dns_name_size =
+          ASN1_STRING_to_UTF8(&dns_name, subject_alt_name->d.dNSName);
+      if (dns_name_size < 0) {
+        gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string.");
+        result = TSI_INTERNAL_ERROR;
+        break;
+      }
+      child_property =
+          &property->value.list.children[property->value.list.child_count++];
+      result = tsi_construct_string_peer_property(
+          NULL, (const char*)dns_name, dns_name_size, child_property);
+      OPENSSL_free(dns_name);
+      if (result != TSI_OK) break;
+    }
+  }
+  if (result != TSI_OK) tsi_peer_property_destruct(property);
+  sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free);
+  return TSI_OK;
+}
+
+/* Gets information about the peer's X509 cert as a tsi_peer object. */
+static tsi_result peer_from_x509(X509* cert, int include_certificate_type,
+                                 tsi_peer* peer) {
+  /* TODO(jboeuf): Maybe add more properties. */
+  uint32_t property_count = include_certificate_type ? 3 : 2;
+  tsi_result result  = tsi_construct_peer(property_count, peer);
+  if (result != TSI_OK) return result;
+  do {
+    result = peer_property_from_x509_common_name(cert, &peer->properties[0]);
+    if (result != TSI_OK) break;
+    result =
+        peer_property_from_x509_subject_alt_names(cert, &peer->properties[1]);
+    if (result != TSI_OK) break;
+    if (include_certificate_type) {
+      result = tsi_construct_string_peer_property_from_cstring(
+          TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
+          &peer->properties[2]);
+      if (result != TSI_OK) break;
+    }
+  } while (0);
+
+  if (result != TSI_OK) tsi_peer_destruct(peer);
+  return result;
+}
+
+/* Performs an SSL_read and handle errors. */
+static tsi_result do_ssl_read(SSL* ssl, unsigned char* unprotected_bytes,
+                              uint32_t* unprotected_bytes_size) {
+  int read_from_ssl = SSL_read(ssl, unprotected_bytes,
+                               *unprotected_bytes_size);
+  if (read_from_ssl == 0) {
+    gpr_log(GPR_ERROR, "SSL_read returned 0 unexpectedly.");
+    return TSI_INTERNAL_ERROR;
+  }
+  if (read_from_ssl < 0) {
+    read_from_ssl = SSL_get_error(ssl, read_from_ssl);
+    switch (read_from_ssl) {
+      case SSL_ERROR_WANT_READ:
+        /* We need more data to finish the frame. */
+        *unprotected_bytes_size = 0;
+        return TSI_OK;
+      case SSL_ERROR_WANT_WRITE:
+        gpr_log(
+            GPR_ERROR,
+            "Peer tried to renegotiate SSL connection. This is unsupported.");
+        return TSI_UNIMPLEMENTED;
+      case SSL_ERROR_SSL:
+        gpr_log(GPR_ERROR, "Corruption detected.");
+        return TSI_DATA_CORRUPTED;
+      default:
+        gpr_log(GPR_ERROR, "SSL_read failed with error %s.",
+                ssl_error_string(read_from_ssl));
+        return TSI_PROTOCOL_FAILURE;
+    }
+  }
+  *unprotected_bytes_size = read_from_ssl;
+  return TSI_OK;
+}
+
+/* Performs an SSL_write and handle errors. */
+static tsi_result do_ssl_write(SSL* ssl, unsigned char* unprotected_bytes,
+                               uint32_t unprotected_bytes_size) {
+  int ssl_write_result =
+      SSL_write(ssl, unprotected_bytes, unprotected_bytes_size);
+  if (ssl_write_result < 0) {
+    ssl_write_result = SSL_get_error(ssl, ssl_write_result);
+    if (ssl_write_result == SSL_ERROR_WANT_READ) {
+      gpr_log(GPR_ERROR,
+              "Peer tried to renegotiate SSL connection. This is unsupported.");
+      return TSI_UNIMPLEMENTED;
+    } else {
+      gpr_log(GPR_ERROR, "SSL_write failed with error %s.",
+              ssl_error_string(ssl_write_result));
+      return TSI_INTERNAL_ERROR;
+    }
+  }
+  return TSI_OK;
+}
+
+/* Loads an in-memory PEM certificate chain into the SSL context. */
+static tsi_result ssl_ctx_use_certificate_chain(
+    SSL_CTX* context, const unsigned char* pem_cert_chain,
+    uint32_t pem_cert_chain_size) {
+  tsi_result result = TSI_OK;
+  X509* certificate = NULL;
+  BIO* pem = BIO_new_mem_buf((void*)pem_cert_chain, pem_cert_chain_size);
+  if (pem == NULL) return TSI_OUT_OF_RESOURCES;
+
+  do {
+    certificate = PEM_read_bio_X509_AUX(pem, NULL, NULL, "");
+    if (certificate == NULL) {
+      result = TSI_INVALID_ARGUMENT;
+      break;
+    }
+    if (!SSL_CTX_use_certificate(context, certificate)) {
+      result = TSI_INVALID_ARGUMENT;
+      break;
+    }
+    while (1) {
+      X509* certificate_authority = PEM_read_bio_X509(pem, NULL, NULL, "");
+      if (certificate_authority == NULL) break;  /* Done reading. */
+      if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) {
+        X509_free(certificate_authority);
+        result = TSI_INVALID_ARGUMENT;
+        break;
+      }
+      /* We don't need to free certificate_authority as its ownership has been
+         transfered to the context. That is not the case for certificate though.
+      */
+    }
+  } while (0);
+
+  if (certificate != NULL) X509_free(certificate);
+  BIO_free(pem);
+  return result;
+}
+
+/* Loads an in-memory PEM private key into the SSL context. */
+static tsi_result ssl_ctx_use_private_key(SSL_CTX* context,
+                                          const unsigned char* pem_key,
+                                          uint32_t pem_key_size) {
+  tsi_result result = TSI_OK;
+  EVP_PKEY* private_key = NULL;
+  BIO* pem = BIO_new_mem_buf((void*)pem_key, pem_key_size);
+  if (pem == NULL) return TSI_OUT_OF_RESOURCES;
+  do {
+    private_key = PEM_read_bio_PrivateKey(pem, NULL, NULL, "");
+    if (private_key == NULL) {
+      result = TSI_INVALID_ARGUMENT;
+      break;
+    }
+    if (!SSL_CTX_use_PrivateKey(context, private_key)) {
+      result = TSI_INVALID_ARGUMENT;
+      break;
+    }
+  } while (0);
+  if (private_key != NULL) EVP_PKEY_free(private_key);
+  BIO_free(pem);
+  return result;
+}
+
+/* Loads in-memory PEM verification certs into the SSL context and optionally
+   returns the verification cert names (root_names can be NULL). */
+static tsi_result ssl_ctx_load_verification_certs(
+    SSL_CTX* context, const unsigned char* pem_roots,
+    uint32_t pem_roots_size, STACK_OF(X509_NAME)** root_names) {
+  tsi_result result = TSI_OK;
+  uint32_t num_roots = 0;
+  X509* root = NULL;
+  X509_NAME* root_name = NULL;
+  BIO* pem = BIO_new_mem_buf((void*)pem_roots, pem_roots_size);
+  X509_STORE* root_store = SSL_CTX_get_cert_store(context);
+  if (root_store == NULL) return TSI_INVALID_ARGUMENT;
+  if (pem == NULL) return TSI_OUT_OF_RESOURCES;
+  if (root_names != NULL) {
+    *root_names = sk_X509_NAME_new_null();
+    if (*root_names == NULL) return TSI_OUT_OF_RESOURCES;
+  }
+
+  while (1) {
+    root = PEM_read_bio_X509_AUX(pem, NULL, NULL, "");
+    if (root == NULL) break;  /* We're at the end of stream. */
+    if (root_names != NULL) {
+      root_name = X509_get_subject_name(root);
+      if (root_name == NULL) {
+        gpr_log(GPR_ERROR, "Could not get name from root certificate.");
+        result = TSI_INVALID_ARGUMENT;
+        break;
+      }
+      root_name = X509_NAME_dup(root_name);
+      if (root_name == NULL) {
+        result = TSI_OUT_OF_RESOURCES;
+        break;
+      }
+      sk_X509_NAME_push(*root_names, root_name);
+      root_name = NULL;
+    }
+    if (!X509_STORE_add_cert(root_store, root)) {
+      gpr_log(GPR_ERROR, "Could not add root certificate to ssl context.");
+      result = TSI_INTERNAL_ERROR;
+      break;
+    }
+    X509_free(root);
+    num_roots++;
+  }
+
+  if (num_roots == 0) {
+    gpr_log(GPR_ERROR, "Could not load any root certificate.");
+    result = TSI_INVALID_ARGUMENT;
+  }
+
+  if (result != TSI_OK) {
+    if (root != NULL) X509_free(root);
+    if (root_names != NULL) {
+      sk_X509_NAME_pop_free(*root_names, X509_NAME_free);
+      *root_names = NULL;
+      if (root_name != NULL) X509_NAME_free(root_name);
+    }
+  }
+  BIO_free(pem);
+  return result;
+}
+
+
+/* Populates the SSL context with a private key and a cert chain, and sets the
+   cipher list and the ephemeral ECDH key. */
+static tsi_result populate_ssl_context(
+    SSL_CTX* context, const unsigned char* pem_private_key,
+    uint32_t pem_private_key_size,
+    const unsigned char* pem_certificate_chain,
+    uint32_t pem_certificate_chain_size, const char* cipher_list) {
+  tsi_result result = TSI_OK;
+  if (pem_certificate_chain != NULL) {
+    result = ssl_ctx_use_certificate_chain(context, pem_certificate_chain,
+                                           pem_certificate_chain_size);
+    if (result != TSI_OK) {
+      gpr_log(GPR_ERROR, "Invalid cert chain file.");
+      return result;
+    }
+  }
+  if (pem_private_key != NULL) {
+    result =
+        ssl_ctx_use_private_key(context, pem_private_key, pem_private_key_size);
+    if (result != TSI_OK || !SSL_CTX_check_private_key(context)) {
+      gpr_log(GPR_ERROR, "Invalid private key.");
+      return result != TSI_OK ? result : TSI_INVALID_ARGUMENT;
+    }
+  }
+  if ((cipher_list != NULL) && !SSL_CTX_set_cipher_list(context, cipher_list)) {
+    gpr_log(GPR_ERROR, "Invalid cipher list: %s.", cipher_list);
+    return TSI_INVALID_ARGUMENT;
+  }
+  {
+    EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+    if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) {
+      gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key.");
+      result = TSI_INTERNAL_ERROR;
+    }
+    SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
+    EC_KEY_free(ecdh);
+  }
+  return TSI_OK;
+}
+
+/* Extracts the CN and the SANs from an X509 cert as a peer object. */
+static tsi_result extract_x509_subject_names_from_pem_cert(
+    const unsigned char* pem_cert, uint32_t pem_cert_size, tsi_peer* peer) {
+  tsi_result result = TSI_OK;
+  X509* cert = NULL;
+  BIO* pem = BIO_new_mem_buf((void*)pem_cert, pem_cert_size);
+  if (pem == NULL)  return TSI_OUT_OF_RESOURCES;
+
+  cert = PEM_read_bio_X509(pem, NULL, NULL, "");
+  if (cert == NULL) {
+      gpr_log(GPR_ERROR, "Invalid certificate");
+      result = TSI_INVALID_ARGUMENT;
+  } else {
+    result = peer_from_x509(cert, 0, peer);
+  }
+  if (cert != NULL) X509_free(cert);
+  BIO_free(pem);
+  return result;
+}
+
+/* Builds the alpn protocol name list according to rfc 7301. */
+static tsi_result build_alpn_protocol_name_list(
+    const unsigned char** alpn_protocols,
+    const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    unsigned char** protocol_name_list, uint32_t* protocol_name_list_length) {
+  uint16_t i;
+  unsigned char* current;
+  *protocol_name_list = NULL;
+  *protocol_name_list_length = 0;
+  for (i = 0; i < num_alpn_protocols; i++) {
+    if (alpn_protocols_lengths[i] == 0) {
+      gpr_log(GPR_ERROR, "Invalid 0-length protocol name.");
+      return TSI_INVALID_ARGUMENT;
+    }
+    *protocol_name_list_length += alpn_protocols_lengths[i] + 1;
+  }
+  *protocol_name_list = malloc(*protocol_name_list_length);
+  if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES;
+  current = *protocol_name_list;
+  for (i = 0; i < num_alpn_protocols; i++) {
+    *(current++) = alpn_protocols_lengths[i];
+    memcpy(current, alpn_protocols[i], alpn_protocols_lengths[i]);
+    current += alpn_protocols_lengths[i];
+  }
+  /* Safety check. */
+  if ((current - *protocol_name_list) != *protocol_name_list_length) {
+    return TSI_INTERNAL_ERROR;
+  }
+  return TSI_OK;
+}
+
+/* --- tsi_frame_protector methods implementation. ---*/
+
+static tsi_result ssl_protector_protect(
+    tsi_frame_protector* self, const unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size,
+    unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size) {
+  tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
+  int read_from_ssl;
+  uint32_t available;
+  tsi_result result = TSI_OK;
+
+  /* First see if we have some pending data in the SSL BIO. */
+  uint32_t pending_in_ssl = BIO_ctrl_pending(impl->from_ssl);
+  if (pending_in_ssl > 0) {
+    *unprotected_bytes_size = 0;
+    read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
+                             *protected_output_frames_size);
+    if (read_from_ssl < 0) {
+      gpr_log(GPR_ERROR,
+              "Could not read from BIO even though some data is pending");
+      return TSI_INTERNAL_ERROR;
+    }
+    *protected_output_frames_size = read_from_ssl;
+    return TSI_OK;
+  }
+
+  /* Now see if we can send a complete frame. */
+  available = impl->buffer_size - impl->buffer_offset;
+  if (available > *unprotected_bytes_size) {
+    /* If we cannot, just copy the data in our internal buffer. */
+    memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes,
+           *unprotected_bytes_size);
+    impl->buffer_offset += *unprotected_bytes_size;
+    *protected_output_frames_size = 0;
+    return TSI_OK;
+  }
+
+  /* If we can, prepare the buffer, send it to SSL_write and read. */
+  memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, available);
+  result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_size);
+  if (result != TSI_OK) return result;
+
+  read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
+                           *protected_output_frames_size);
+  if (read_from_ssl < 0) {
+    gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
+    return TSI_INTERNAL_ERROR;
+  }
+  *protected_output_frames_size = read_from_ssl;
+  *unprotected_bytes_size = available;
+  impl->buffer_offset = 0;
+  return TSI_OK;
+}
+
+static tsi_result ssl_protector_protect_flush(
+    tsi_frame_protector* self, unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size,
+    uint32_t* still_pending_size) {
+  tsi_result result = TSI_OK;
+  tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
+  int read_from_ssl = 0;
+
+  if (impl->buffer_offset != 0) {
+    result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_offset);
+    if (result != TSI_OK) return result;
+    impl->buffer_offset = 0;
+  }
+
+  *still_pending_size = BIO_ctrl_pending(impl->from_ssl);
+  if (*still_pending_size == 0) return TSI_OK;
+
+  read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
+                           *protected_output_frames_size);
+  if (read_from_ssl <= 0) {
+    gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
+    return TSI_INTERNAL_ERROR;
+  }
+  *protected_output_frames_size = read_from_ssl;
+  *still_pending_size = BIO_ctrl_pending(impl->from_ssl);
+  return TSI_OK;
+}
+
+static tsi_result ssl_protector_unprotect(
+    tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
+    uint32_t* protected_frames_bytes_size,
+    unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size) {
+  tsi_result result = TSI_OK;
+  int written_into_ssl = 0;
+  uint32_t output_bytes_size = *unprotected_bytes_size;
+  uint32_t output_bytes_offset = 0;
+  tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
+
+  /* First, try to read remaining data from ssl. */
+  result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size);
+  if (result != TSI_OK)  return result;
+  if (*unprotected_bytes_size == output_bytes_size) {
+    /* We have read everything we could and cannot process any more input. */
+    *protected_frames_bytes_size = 0;
+    return TSI_OK;
+  }
+  output_bytes_offset = *unprotected_bytes_size;
+  unprotected_bytes += output_bytes_offset;
+  *unprotected_bytes_size = output_bytes_size - output_bytes_offset;
+
+  /* Then, try to write some data to ssl. */
+  written_into_ssl = BIO_write(
+      impl->into_ssl, protected_frames_bytes, *protected_frames_bytes_size);
+  if (written_into_ssl < 0) {
+    gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d",
+            written_into_ssl);
+    return TSI_INTERNAL_ERROR;
+  }
+  *protected_frames_bytes_size = written_into_ssl;
+
+  /* Now try to read some data again. */
+  result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size);
+  if (result == TSI_OK) {
+    /* Don't forget to output the total number of bytes read. */
+    *unprotected_bytes_size += output_bytes_offset;
+  }
+  return result;
+}
+
+static void ssl_protector_destroy(tsi_frame_protector* self) {
+  tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
+  if (impl->buffer != NULL) free(impl->buffer);
+  if (impl->ssl != NULL) SSL_free(impl->ssl);
+  free(self);
+}
+
+static const tsi_frame_protector_vtable frame_protector_vtable = {
+    ssl_protector_protect,
+    ssl_protector_protect_flush,
+    ssl_protector_unprotect,
+    ssl_protector_destroy,
+};
+
+
+/* --- tsi_handshaker methods implementation. ---*/
+
+static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(
+    tsi_handshaker* self, unsigned char* bytes, uint32_t* bytes_size) {
+  tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
+  int bytes_read_from_ssl = 0;
+  if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 ||
+      *bytes_size > INT_MAX) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, *bytes_size);
+  if (bytes_read_from_ssl < 0) {
+    *bytes_size = 0;
+    if (!BIO_should_retry(impl->from_ssl)) {
+      impl->result = TSI_INTERNAL_ERROR;
+      return impl->result;
+    } else {
+      return TSI_OK;
+    }
+  }
+  *bytes_size = (uint32_t)bytes_read_from_ssl;
+  return BIO_ctrl_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
+}
+
+static tsi_result ssl_handshaker_get_result(tsi_handshaker* self) {
+  tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
+  if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) &&
+      SSL_is_init_finished(impl->ssl)) {
+    impl->result = TSI_OK;
+  }
+  return impl->result;
+}
+
+static tsi_result ssl_handshaker_process_bytes_from_peer(
+    tsi_handshaker* self, const unsigned char* bytes,
+    uint32_t* bytes_size) {
+  tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
+  int bytes_written_into_ssl_size = 0;
+  if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  bytes_written_into_ssl_size = BIO_write(impl->into_ssl, bytes, *bytes_size);
+  if (bytes_written_into_ssl_size < 0) {
+    gpr_log(GPR_ERROR, "Could not write to memory BIO.");
+    impl->result = TSI_INTERNAL_ERROR;
+    return impl->result;
+  }
+  *bytes_size = bytes_written_into_ssl_size;
+
+  if (!tsi_handshaker_is_in_progress(self)) {
+    impl->result = TSI_OK;
+    return impl->result;
+  } else {
+    /* Get ready to get some bytes from SSL. */
+    int ssl_result = SSL_do_handshake(impl->ssl);
+    ssl_result = SSL_get_error(impl->ssl, ssl_result);
+    switch (ssl_result) {
+      case SSL_ERROR_WANT_READ:
+        if (BIO_ctrl_pending(impl->from_ssl) == 0) {
+          /* We need more data. */
+          return TSI_INCOMPLETE_DATA;
+        } else {
+          return TSI_OK;
+        }
+      case SSL_ERROR_NONE:
+        return TSI_OK;
+      default: {
+        char err_str[256];
+        ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str));
+        gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.",
+                ssl_error_string(ssl_result), err_str);
+        impl->result = TSI_PROTOCOL_FAILURE;
+        return impl->result;
+      }
+    }
+  }
+}
+
+static tsi_result ssl_handshaker_extract_peer(tsi_handshaker* self,
+                                              tsi_peer* peer) {
+  tsi_result result = TSI_OK;
+  const unsigned char* alpn_selected;
+  unsigned int alpn_selected_len;
+  tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
+  X509* peer_cert = SSL_get_peer_certificate(impl->ssl);
+  if (peer_cert != NULL) {
+    result = peer_from_x509(peer_cert, 1, peer);
+    X509_free(peer_cert);
+    if (result != TSI_OK) return result;
+  }
+  SSL_get0_alpn_selected(impl->ssl, &alpn_selected, &alpn_selected_len);
+  if (alpn_selected != NULL) {
+    uint32_t i;
+    tsi_peer_property* new_properties =
+        calloc(1, sizeof(tsi_peer_property) * (peer->property_count + 1));
+    if (new_properties == NULL) return TSI_OUT_OF_RESOURCES;
+    for (i = 0; i < peer->property_count; i++) {
+      new_properties[i] = peer->properties[i];
+    }
+    result = tsi_construct_string_peer_property(
+        TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char*)alpn_selected,
+        alpn_selected_len, &new_properties[peer->property_count]);
+    if (result != TSI_OK) {
+      free(new_properties);
+      return result;
+    }
+    if (peer->properties != NULL) free(peer->properties);
+    peer->property_count++;
+    peer->properties = new_properties;
+  }
+  return result;
+}
+
+static tsi_result ssl_handshaker_create_frame_protector(
+    tsi_handshaker* self, uint32_t* max_output_protected_frame_size,
+    tsi_frame_protector** protector) {
+  uint32_t actual_max_output_protected_frame_size =
+      TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND;
+  tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
+  tsi_ssl_frame_protector* protector_impl =
+      calloc(1, sizeof(tsi_ssl_frame_protector));
+  if (protector_impl == NULL) {
+    return TSI_OUT_OF_RESOURCES;
+  }
+
+  if (max_output_protected_frame_size != NULL) {
+    if (*max_output_protected_frame_size >
+        TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND) {
+      *max_output_protected_frame_size =
+          TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND;
+    } else if (*max_output_protected_frame_size <
+               TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND) {
+      *max_output_protected_frame_size =
+          TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND;
+    }
+    actual_max_output_protected_frame_size = *max_output_protected_frame_size;
+  }
+  protector_impl->buffer_size =
+      actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD;
+  protector_impl->buffer = malloc(protector_impl->buffer_size);
+  if (protector_impl->buffer == NULL) {
+    gpr_log(GPR_ERROR,
+            "Could not allocated buffer for tsi_ssl_frame_protector.");
+    free(protector_impl);
+    return TSI_INTERNAL_ERROR;
+  }
+
+  /* Transfer ownership of ssl to the frame protector. It is OK as the caller
+   * cannot call anything else but destroy on the handshaker after this call. */
+  protector_impl->ssl = impl->ssl;
+  impl->ssl = NULL;
+  protector_impl->into_ssl = impl->into_ssl;
+  protector_impl->from_ssl = impl->from_ssl;
+
+  protector_impl->base.vtable = &frame_protector_vtable;
+  *protector = &protector_impl->base;
+  return TSI_OK;
+}
+
+static void ssl_handshaker_destroy(tsi_handshaker* self) {
+  tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
+  SSL_free(impl->ssl); /* The BIO objects are owned by ssl */
+  free(impl);
+}
+
+static const tsi_handshaker_vtable handshaker_vtable = {
+    ssl_handshaker_get_bytes_to_send_to_peer,
+    ssl_handshaker_process_bytes_from_peer,
+    ssl_handshaker_get_result,
+    ssl_handshaker_extract_peer,
+    ssl_handshaker_create_frame_protector,
+    ssl_handshaker_destroy,
+};
+
+
+/* --- tsi_ssl_handshaker_factory common methods. --- */
+
+tsi_result tsi_ssl_handshaker_factory_create_handshaker(
+    tsi_ssl_handshaker_factory* self, const char* server_name_indication,
+    tsi_handshaker** handshaker) {
+  if (self == NULL || handshaker == NULL) return TSI_INVALID_ARGUMENT;
+  return self->create_handshaker(self, server_name_indication, handshaker);
+}
+
+void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory* self) {
+  if (self == NULL) return;
+  self->destroy(self);
+}
+
+static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
+                                            const char* server_name_indication,
+                                            tsi_handshaker** handshaker) {
+  SSL* ssl = SSL_new(ctx);
+  BIO* into_ssl = NULL;
+  BIO* from_ssl = NULL;
+  tsi_ssl_handshaker* impl = NULL;
+  *handshaker = NULL;
+  if (ctx == NULL) {
+    gpr_log(GPR_ERROR, "SSL Context is null. Should never happen.");
+    return TSI_INTERNAL_ERROR;
+  }
+  if (ssl == NULL) {
+    return TSI_OUT_OF_RESOURCES;
+  }
+  SSL_set_info_callback(ssl, ssl_info_callback);
+
+  into_ssl = BIO_new(BIO_s_mem());
+  from_ssl = BIO_new(BIO_s_mem());
+  if (into_ssl == NULL || from_ssl == NULL) {
+    gpr_log(GPR_ERROR, "BIO_new failed.");
+    SSL_free(ssl);
+    if (into_ssl != NULL) BIO_free(into_ssl);
+    if (from_ssl != NULL) BIO_free(into_ssl);
+    return TSI_OUT_OF_RESOURCES;
+  }
+  SSL_set_bio(ssl, into_ssl, from_ssl);
+  if (is_client) {
+    int ssl_result;
+    SSL_set_connect_state(ssl);
+    if (server_name_indication != NULL) {
+      if (!SSL_set_tlsext_host_name(ssl, server_name_indication)) {
+        gpr_log(GPR_ERROR, "Invalid server name indication %s.",
+                server_name_indication);
+        SSL_free(ssl);
+        return TSI_INTERNAL_ERROR;
+      }
+    }
+    ssl_result = SSL_do_handshake(ssl);
+    ssl_result = SSL_get_error(ssl, ssl_result);
+    if (ssl_result != SSL_ERROR_WANT_READ) {
+      gpr_log(GPR_ERROR,
+              "Unexpected error received from first SSL_do_handshake call: %s",
+              ssl_error_string(ssl_result));
+      SSL_free(ssl);
+      return TSI_INTERNAL_ERROR;
+    }
+  } else {
+    SSL_set_accept_state(ssl);
+  }
+
+  impl = calloc(1, sizeof(tsi_ssl_handshaker));
+  if (impl == NULL) {
+    SSL_free(ssl);
+    return TSI_OUT_OF_RESOURCES;
+  }
+  impl->ssl = ssl;
+  impl->into_ssl = into_ssl;
+  impl->from_ssl = from_ssl;
+  impl->result = TSI_HANDSHAKE_IN_PROGRESS;
+  impl->base.vtable = &handshaker_vtable;
+  *handshaker = &impl->base;
+  return TSI_OK;
+}
+
+
+/* --- tsi_ssl__client_handshaker_factory methods implementation. --- */
+
+static tsi_result ssl_client_handshaker_factory_create_handshaker(
+    tsi_ssl_handshaker_factory* self, const char* server_name_indication,
+    tsi_handshaker** handshaker) {
+  tsi_ssl_client_handshaker_factory* impl =
+      (tsi_ssl_client_handshaker_factory*)self;
+  return create_tsi_ssl_handshaker(impl->ssl_context, 1, server_name_indication,
+                                   handshaker);
+}
+
+static void ssl_client_handshaker_factory_destroy(
+    tsi_ssl_handshaker_factory* self) {
+  tsi_ssl_client_handshaker_factory* impl =
+      (tsi_ssl_client_handshaker_factory*)self;
+  SSL_CTX_free(impl->ssl_context);
+  free(impl);
+}
+
+
+/* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
+
+static tsi_result ssl_server_handshaker_factory_create_handshaker(
+    tsi_ssl_handshaker_factory* self, const char* server_name_indication,
+    tsi_handshaker** handshaker) {
+  tsi_ssl_server_handshaker_factory* impl =
+      (tsi_ssl_server_handshaker_factory*)self;
+  if (impl->ssl_context_count == 0 || server_name_indication != NULL) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  /* Create the handshaker with the first context. We will switch if needed
+     because of SNI in ssl_server_handshaker_factory_servername_callback.  */
+  return create_tsi_ssl_handshaker(impl->ssl_contexts[0], 0, NULL, handshaker);
+}
+
+static void ssl_server_handshaker_factory_destroy(
+    tsi_ssl_handshaker_factory* self) {
+  tsi_ssl_server_handshaker_factory* impl =
+      (tsi_ssl_server_handshaker_factory*)self;
+  uint32_t i;
+  for (i = 0; i < impl->ssl_context_count; i++) {
+    if (impl->ssl_contexts[i] != NULL) {
+      SSL_CTX_free(impl->ssl_contexts[i]);
+      tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]);
+    }
+  }
+  if (impl->ssl_contexts != NULL) free(impl->ssl_contexts);
+  if (impl->ssl_context_x509_subject_names != NULL) {
+    free(impl->ssl_context_x509_subject_names);
+  }
+  if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list);
+  free(impl);
+}
+
+static int does_entry_match_name(const char* entry, uint32_t entry_length,
+                                 const char* name) {
+  const char* name_subdomain = NULL;
+  if (entry_length == 0) return 0;
+  if (!strncmp(name, entry, entry_length) && (strlen(name) == entry_length)) {
+    return 1;  /* Perfect match. */
+  }
+  if (entry[0] != '*') return 0;
+
+  /* Wildchar subdomain matching. */
+  if (entry_length < 3 || entry[1] != '.') {  /* At least *.x */
+    gpr_log(GPR_ERROR, "Invalid wildchar entry.");
+    return 0;
+  }
+  name_subdomain = strchr(name, '.');
+  if (name_subdomain == NULL || strlen(name_subdomain) < 2) return 0;
+  name_subdomain++;  /* Starts after the dot. */
+  entry += 2;  /* Remove *. */
+  entry_length -= 2;
+  return (!strncmp(entry, name_subdomain, entry_length) &&
+          (strlen(name_subdomain) == entry_length));
+}
+
+static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap,
+                                                             void* arg) {
+  tsi_ssl_server_handshaker_factory* impl =
+      (tsi_ssl_server_handshaker_factory*)arg;
+  uint32_t i = 0;
+  const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+  if (servername == NULL || strlen(servername) == 0) {
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  for (i = 0; i < impl->ssl_context_count; i++) {
+    if (tsi_ssl_peer_matches_name(&impl->ssl_context_x509_subject_names[i],
+                                  servername)) {
+      SSL_set_SSL_CTX(ssl, impl->ssl_contexts[i]);
+      return SSL_TLSEXT_ERR_OK;
+    }
+  }
+  gpr_log(GPR_ERROR, "No match found for server name: %s.", servername);
+  return SSL_TLSEXT_ERR_ALERT_WARNING;
+}
+
+static int server_handshaker_factory_alpn_callback(
+    SSL* ssl, const unsigned char** out, unsigned char* outlen,
+    const unsigned char* in, unsigned int inlen, void* arg) {
+  tsi_ssl_server_handshaker_factory* factory =
+      (tsi_ssl_server_handshaker_factory*)arg;
+  const unsigned char* client_current = in;
+  while ((client_current - in) < inlen) {
+    unsigned char client_current_len = *(client_current++);
+    const unsigned char* server_current = factory->alpn_protocol_list;
+    while ((server_current - factory->alpn_protocol_list) <
+           factory->alpn_protocol_list_length) {
+      unsigned char server_current_len = *(server_current++);
+      if ((client_current_len == server_current_len) &&
+          !memcmp(client_current, server_current, server_current_len)) {
+        *out = server_current;
+        *outlen = server_current_len;
+        return SSL_TLSEXT_ERR_OK;
+      }
+      server_current += server_current_len;
+    }
+    client_current += client_current_len;
+  }
+  return SSL_TLSEXT_ERR_NOACK;
+}
+
+
+/* --- tsi_ssl_handshaker_factory constructors. --- */
+
+tsi_result tsi_create_ssl_client_handshaker_factory(
+    const unsigned char* pem_private_key, uint32_t pem_private_key_size,
+    const unsigned char* pem_cert_chain, uint32_t pem_cert_chain_size,
+    const unsigned char* pem_root_certs, uint32_t pem_root_certs_size,
+    const char* cipher_list, const unsigned char** alpn_protocols,
+    const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    tsi_ssl_handshaker_factory** factory) {
+  SSL_CTX* ssl_context = NULL;
+  tsi_ssl_client_handshaker_factory* impl = NULL;
+  tsi_result result = TSI_OK;
+
+  pthread_once(&init_openssl_once, init_openssl);
+
+  if (factory == NULL) return TSI_INVALID_ARGUMENT;
+  *factory = NULL;
+  if (pem_root_certs == NULL) return TSI_INVALID_ARGUMENT;
+
+  ssl_context = SSL_CTX_new(TLSv1_2_method());
+  if (ssl_context == NULL) {
+    gpr_log(GPR_ERROR, "Could not create ssl context.");
+    return TSI_INVALID_ARGUMENT;
+  }
+  do {
+    result =
+        populate_ssl_context(ssl_context, pem_private_key, pem_private_key_size,
+                             pem_cert_chain, pem_cert_chain_size, cipher_list);
+    if (result != TSI_OK) break;
+    result = ssl_ctx_load_verification_certs(ssl_context, pem_root_certs,
+                                             pem_root_certs_size, NULL);
+    if (result != TSI_OK) {
+      gpr_log(GPR_ERROR, "Cannot load server root certificates.");
+      break;
+    }
+
+    if (num_alpn_protocols != 0) {
+      unsigned char* alpn_protocol_list = NULL;
+      uint32_t alpn_protocol_list_length = 0;
+      int ssl_failed;
+      result = build_alpn_protocol_name_list(
+          alpn_protocols, alpn_protocols_lengths, num_alpn_protocols,
+          &alpn_protocol_list, &alpn_protocol_list_length);
+      if (result != TSI_OK) {
+        gpr_log(GPR_ERROR, "Building alpn list failed with error %s.",
+                tsi_result_to_string(result));
+        break;
+      }
+      ssl_failed = SSL_CTX_set_alpn_protos(ssl_context, alpn_protocol_list,
+                                           alpn_protocol_list_length);
+      free(alpn_protocol_list);
+      if (ssl_failed) {
+        gpr_log(GPR_ERROR, "Could not set alpn protocol list to context.");
+        result = TSI_INVALID_ARGUMENT;
+        break;
+      }
+    }
+  } while (0);
+  if (result != TSI_OK) {
+    SSL_CTX_free(ssl_context);
+    return result;
+  }
+  SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL);
+  /* TODO(jboeuf): Add revocation verification. */
+
+  impl = calloc(1, sizeof(tsi_ssl_client_handshaker_factory));
+  if (impl == NULL) {
+    SSL_CTX_free(ssl_context);
+    return TSI_OUT_OF_RESOURCES;
+  }
+  impl->ssl_context = ssl_context;
+  impl->base.create_handshaker =
+      ssl_client_handshaker_factory_create_handshaker;
+  impl->base.destroy = ssl_client_handshaker_factory_destroy;
+  *factory = &impl->base;
+  return TSI_OK;
+}
+
+tsi_result tsi_create_ssl_server_handshaker_factory(
+    const unsigned char** pem_private_keys,
+    const uint32_t* pem_private_keys_sizes,
+    const unsigned char** pem_cert_chains,
+    const uint32_t* pem_cert_chains_sizes, uint32_t key_cert_pair_count,
+    const unsigned char* pem_client_root_certs,
+    uint32_t pem_client_root_certs_size, const char* cipher_list,
+    const unsigned char** alpn_protocols,
+    const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    tsi_ssl_handshaker_factory** factory) {
+  tsi_ssl_server_handshaker_factory* impl = NULL;
+  tsi_result result = TSI_OK;
+  uint32_t i = 0;
+
+  pthread_once(&init_openssl_once, init_openssl);
+
+  if (factory == NULL) return TSI_INVALID_ARGUMENT;
+  *factory = NULL;
+  if (key_cert_pair_count == 0 || pem_private_keys == NULL ||
+      pem_cert_chains == NULL) {
+    return TSI_INVALID_ARGUMENT;
+  }
+
+  impl = calloc(1, sizeof(tsi_ssl_server_handshaker_factory));
+  if (impl == NULL) return TSI_OUT_OF_RESOURCES;
+  impl->base.create_handshaker =
+      ssl_server_handshaker_factory_create_handshaker;
+  impl->base.destroy = ssl_server_handshaker_factory_destroy;
+  impl->ssl_contexts = calloc(key_cert_pair_count, sizeof(SSL_CTX*));
+  impl->ssl_context_x509_subject_names =
+      calloc(key_cert_pair_count, sizeof(tsi_peer));
+  if (impl->ssl_contexts == NULL ||
+      impl->ssl_context_x509_subject_names == NULL) {
+    tsi_ssl_handshaker_factory_destroy(&impl->base);
+    return TSI_OUT_OF_RESOURCES;
+  }
+  impl->ssl_context_count = key_cert_pair_count;
+
+  if (num_alpn_protocols > 0) {
+    result = build_alpn_protocol_name_list(
+        alpn_protocols, alpn_protocols_lengths, num_alpn_protocols,
+        &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
+    if (result != TSI_OK) {
+      tsi_ssl_handshaker_factory_destroy(&impl->base);
+      return result;
+    }
+  }
+
+  for (i = 0; i < key_cert_pair_count; i++) {
+    do {
+      impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method());
+      if (impl->ssl_contexts[i] == NULL) {
+        gpr_log(GPR_ERROR, "Could not create ssl context.");
+        result = TSI_OUT_OF_RESOURCES;
+        break;
+      }
+      result = populate_ssl_context(
+          impl->ssl_contexts[i], pem_private_keys[i], pem_private_keys_sizes[i],
+          pem_cert_chains[i], pem_cert_chains_sizes[i], cipher_list);
+      if (result != TSI_OK) break;
+
+      if (pem_client_root_certs != NULL) {
+        STACK_OF(X509_NAME)* root_names = NULL;
+        result = ssl_ctx_load_verification_certs(
+            impl->ssl_contexts[i], pem_client_root_certs,
+            pem_client_root_certs_size, &root_names);
+        if (result != TSI_OK) {
+          gpr_log(GPR_ERROR, "Invalid verification certs.");
+          break;
+        }
+        SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names);
+        SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, NULL);
+        /* TODO(jboeuf): Add revocation verification. */
+      }
+
+      result = extract_x509_subject_names_from_pem_cert(
+          pem_cert_chains[i], pem_cert_chains_sizes[i],
+          &impl->ssl_context_x509_subject_names[i]);
+      if (result != TSI_OK) break;
+
+      SSL_CTX_set_tlsext_servername_callback(
+          impl->ssl_contexts[i],
+          ssl_server_handshaker_factory_servername_callback);
+      SSL_CTX_set_tlsext_servername_arg(impl->ssl_contexts[i], impl);
+      SSL_CTX_set_alpn_select_cb(impl->ssl_contexts[i],
+                                 server_handshaker_factory_alpn_callback, impl);
+    } while (0);
+
+    if (result != TSI_OK) {
+      tsi_ssl_handshaker_factory_destroy(&impl->base);
+      return result;
+    }
+  }
+  *factory = &impl->base;
+  return TSI_OK;
+}
+
+/* --- tsi_ssl utils. --- */
+
+int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
+  uint32_t i = 0;
+  const tsi_peer_property* property = tsi_peer_get_property_by_name(
+      peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
+  if (property == NULL ||
+      property->type != TSI_PEER_PROPERTY_TYPE_STRING) {
+    gpr_log(GPR_ERROR,
+            "Invalid x509 subject common name property.");
+    return 0;
+  }
+  if (does_entry_match_name(property->value.string.data,
+                            property->value.string.length, name)) {
+    return 1;
+  }
+
+  property = tsi_peer_get_property_by_name(
+      peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
+  if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_LIST) {
+    gpr_log(GPR_ERROR,
+            "Invalid x509 subject alternative names property.");
+    return 0;
+  }
+
+  for (i = 0; i < property->value.list.child_count; i++) {
+    const tsi_peer_property* alt_name_property =
+        &property->value.list.children[i];
+    if (alt_name_property->type != TSI_PEER_PROPERTY_TYPE_STRING) {
+      gpr_log(GPR_ERROR, "Invalid x509 subject alternative name property.");
+      return 0;
+    }
+    if (does_entry_match_name(alt_name_property->value.string.data,
+                              alt_name_property->value.string.length, name)) {
+      return 1;
+    }
+  }
+  return 0;  /* Not found. */
+}
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
new file mode 100644
index 0000000..2ed3ed8
--- /dev/null
+++ b/src/core/tsi/ssl_transport_security.h
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __SSL_TRANSPORT_SECURITY_H_
+#define __SSL_TRANSPORT_SECURITY_H_
+
+#include "src/core/tsi/transport_security_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */
+#define TSI_X509_CERTIFICATE_TYPE "X509"
+
+/* --- tsi_ssl_handshaker_factory object ---
+
+   This object creates tsi_handshaker objects implemented in terms of the
+   TLS 1.2 specificiation.  */
+
+typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory;
+
+/* Creates a client handshaker factory.
+   - pem_private_key is the buffer containing the PEM encoding of the client's
+     private key. This parameter can be NULL if the client does not have a
+     private key.
+   - pem_private_key_size is the size of the associated buffer.
+   - pem_cert_chain is the buffer containing the PEM encoding of the client's
+     certificate chain. This parameter can be NULL if the client does not have
+     a certificate chain.
+   - pem_cert_chain_size is the size of the associated buffer.
+   - pem_roots_cert is the buffer containing the PEM encoding of the server
+     root certificates. This parameter cannot be NULL.
+   - pem_roots_cert_size is the size of the associated buffer.
+   - cipher_suites contains an optional list of the ciphers that the client
+     supports. The format of this string is described in:
+     https://www.openssl.org/docs/apps/ciphers.html.
+     This parameter can be set to NULL to use the default set of ciphers.
+     TODO(jboeuf): Revisit the format of this parameter.
+   - alpn_protocols is an array containing the protocol names that the
+     handshakers created with this factory support. This parameter can be NULL.
+   - alpn_protocols_lengths is an array containing the lengths of the alpn
+     protocols specified in alpn_protocols. This parameter can be NULL.
+   - num_alpn_protocols is the number of alpn protocols and associated lengths
+     specified. If this parameter is 0, the other alpn parameters must be NULL.
+   - factory is the address of the factory pointer to be created.
+
+   - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
+     where a parameter is invalid.  */
+tsi_result tsi_create_ssl_client_handshaker_factory(
+    const unsigned char* pem_private_key, uint32_t pem_private_key_size,
+    const unsigned char* pem_cert_chain, uint32_t pem_cert_chain_size,
+    const unsigned char* pem_root_certs, uint32_t pem_root_certs_size,
+    const char* cipher_suites, const unsigned char** alpn_protocols,
+    const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    tsi_ssl_handshaker_factory** factory);
+
+/* Creates a server handshaker factory.
+   - version indicates which version of the specification to use.
+   - pem_private_keys is an array containing the PEM encoding of the server's
+     private keys.  This parameter cannot be NULL. The size of the array is
+     given by the key_cert_pair_count parameter.
+   - pem_private_keys_sizes is the array containing the sizes of the associated
+     buffers.
+   - pem_cert_chains is an array containing the PEM encoding of the server's
+     cert chains.  This parameter cannot be NULL. The size of the array is
+     given by the key_cert_pair_count parameter.
+   - pem_cert_chains_sizes is the array containing the sizes of the associated
+     buffers.
+   - key_cert_pair_count indicates the number of items in the private_key_files
+     and cert_chain_files parameters.
+   - pem_client_roots is the buffer containing the PEM encoding of the client
+     root certificates. This parameter may be NULL in which case the server
+     will not ask the client to authenticate itself with a certificate (server-
+     only authentication mode).
+   - pem_client_roots_size is the size of the associated buffer.
+   - cipher_suites contains an optional list of the ciphers that the server
+     supports. The format of this string is described in:
+     https://www.openssl.org/docs/apps/ciphers.html.
+     This parameter can be set to NULL to use the default set of ciphers.
+     TODO(jboeuf): Revisit the format of this parameter.
+   - alpn_protocols is an array containing the protocol names that the
+     handshakers created with this factory support. This parameter can be NULL.
+   - alpn_protocols_lengths is an array containing the lengths of the alpn
+     protocols specified in alpn_protocols. This parameter can be NULL.
+   - num_alpn_protocols is the number of alpn protocols and associated lengths
+     specified. If this parameter is 0, the other alpn parameters must be NULL.
+   - factory is the address of the factory pointer to be created.
+
+   - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
+     where a parameter is invalid.  */
+tsi_result tsi_create_ssl_server_handshaker_factory(
+    const unsigned char** pem_private_keys,
+    const uint32_t* pem_private_keys_sizes,
+    const unsigned char** pem_cert_chains,
+    const uint32_t* pem_cert_chains_sizes, uint32_t key_cert_pair_count,
+    const unsigned char* pem_client_root_certs,
+    uint32_t pem_client_root_certs_size, const char* cipher_suites,
+    const unsigned char** alpn_protocols,
+    const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    tsi_ssl_handshaker_factory** factory);
+
+/* Creates a handshaker.
+  - self is the factory from which the handshaker will be created.
+  - server_name_indication indicates the name of the server the client is
+    trying to connect to which will be relayed to the server using the SNI
+    extension.
+    This parameter must be NULL for a server handshaker factory.
+  - handhshaker is the address of the handshaker pointer to be created.
+
+  - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
+    where a parameter is invalid.  */
+tsi_result tsi_ssl_handshaker_factory_create_handshaker(
+    tsi_ssl_handshaker_factory* self, const char* server_name_indication,
+    tsi_handshaker** handshaker);
+
+/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory
+   while handshakers created with this factory are still in use.  */
+void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory* self);
+
+/* Util that checks that an ssl peer matches a specific name. */
+int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __SSL_TRANSPORT_SECURITY_H_ */
diff --git a/src/core/tsi/ssl_transport_security_test.cc b/src/core/tsi/ssl_transport_security_test.cc
new file mode 100644
index 0000000..a759403
--- /dev/null
+++ b/src/core/tsi/ssl_transport_security_test.cc
@@ -0,0 +1,534 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <memory>
+
+#include "base/commandlineflags.h"
+#include "file/base/helpers.h"
+#include "file/base/options.pb.h"
+#include "file/base/path.h"
+#include "src/core/tsi/transport_security_test_lib.h"
+#include "src/core/tsi/ssl_transport_security.h"
+#include "util/random/permute-inl.h"
+
+namespace {
+
+const char kTestCredsDir[] =
+    "/internal/tsi/test_creds/";
+
+enum AlpnMode {
+  NO_ALPN,
+  ALPN_CLIENT_NO_SERVER,
+  ALPN_SERVER_NO_CLIENT,
+  ALPN_CLIENT_SERVER_OK,
+  ALPN_CLIENT_SERVER_MISMATCH
+};
+
+class SslTestConfig : public tsi::test::TestConfig {
+ public:
+  SslTestConfig()
+      : do_client_authentication(false),
+        subject_name_indication(nullptr),
+        use_bad_client_cert(false),
+        use_bad_server_cert(false),
+        alpn_mode(NO_ALPN) {}
+  bool do_client_authentication;
+  const char* subject_name_indication;
+  bool use_bad_client_cert;
+  bool use_bad_server_cert;
+  AlpnMode alpn_mode;
+};
+
+struct TsiSslHandshakerFactoryDeleter {
+  inline void operator()(tsi_ssl_handshaker_factory* ptr) {
+    tsi_ssl_handshaker_factory_destroy(ptr);
+  }
+};
+typedef std::unique_ptr<tsi_ssl_handshaker_factory,
+                        TsiSslHandshakerFactoryDeleter>
+    TsiSslHandshakerFactoryUniquePtr;
+
+class SslTransportSecurityTest : public tsi::test::TransportSecurityTest {
+ protected:
+  void CheckSubjectAltName(const tsi_peer_property& property,
+                           const string& expected_subject_alt_name) {
+    EXPECT_EQ(property.type, TSI_PEER_PROPERTY_TYPE_STRING);
+    EXPECT_EQ(property.name, nullptr);
+    EXPECT_EQ(
+        string(property.value.string.data, property.value.string.length),
+        expected_subject_alt_name);
+  }
+
+  const tsi_peer_property* CheckBasicAuthenticatedPeerAndGetCommonName(
+      const tsi_peer* peer) {
+    const tsi_peer_property* property =
+        tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY);
+    EXPECT_NE(property, nullptr);
+    EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING);
+    EXPECT_EQ(
+        string(property->value.string.data, property->value.string.length),
+        string(TSI_X509_CERTIFICATE_TYPE));
+    property = tsi_peer_get_property_by_name(
+        peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
+    EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_STRING);
+    return property;
+  }
+
+  void CheckServer0Peer(tsi_peer* peer) {
+    const tsi_peer_property* property =
+        CheckBasicAuthenticatedPeerAndGetCommonName(peer);
+    EXPECT_EQ(
+        string(property->value.string.data, property->value.string.length),
+        string("*.test.google.com.au"));
+    property = tsi_peer_get_property_by_name(
+        peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
+    EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST);
+    EXPECT_EQ(property->value.list.child_count, 0);
+    EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au"));
+    EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au"));
+    EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.test.google.blah"));
+    EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au"));
+    EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.com.au"));
+    tsi_peer_destruct(peer);
+  }
+
+  void CheckServer1Peer(tsi_peer* peer) {
+    const tsi_peer_property* property =
+        CheckBasicAuthenticatedPeerAndGetCommonName(peer);
+    EXPECT_EQ(
+        string(property->value.string.data, property->value.string.length),
+        string("*.test.google.com"));
+    property = tsi_peer_get_property_by_name(
+        peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
+    EXPECT_EQ(property->type, TSI_PEER_PROPERTY_TYPE_LIST);
+    EXPECT_EQ(property->value.list.child_count, 3);
+    CheckSubjectAltName(property->value.list.children[0], "*.test.google.fr");
+    CheckSubjectAltName(property->value.list.children[1],
+                        "waterzooi.test.google.be");
+    CheckSubjectAltName(property->value.list.children[2], "*.test.youtube.com");
+    EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.google.com"));
+    EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "bar.test.google.fr"));
+    EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be"));
+    EXPECT_EQ(1, tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com"));
+    EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com"));
+    EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "test.google.fr"));
+    EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.test.google.be"));
+    EXPECT_EQ(0, tsi_ssl_peer_matches_name(peer, "tartines.youtube.com"));
+    tsi_peer_destruct(peer);
+  }
+
+  void CheckClientPeer(tsi_peer* peer, bool is_authenticated) {
+    if (!is_authenticated) {
+      EXPECT_EQ(peer->property_count,
+                config_.alpn_mode == ALPN_CLIENT_SERVER_OK ? 1 : 0);
+    } else {
+      const tsi_peer_property* property =
+          CheckBasicAuthenticatedPeerAndGetCommonName(peer);
+      EXPECT_EQ(
+          string(property->value.string.data, property->value.string.length),
+          string("testclient"));
+    }
+    tsi_peer_destruct(peer);
+  }
+
+  void SetupHandshakers() override {
+    tsi_ssl_handshaker_factory* client_handshaker_factory;
+    const unsigned char* client_cert = NULL;
+    unsigned int client_cert_size = 0;
+    const unsigned char* client_key = NULL;
+    unsigned int client_key_size = 0;
+    if (config_.do_client_authentication) {
+      if (config_.use_bad_client_cert) {
+        client_cert =
+            reinterpret_cast<const unsigned char*>(badclient_cert_.data());
+        client_cert_size = badclient_cert_.size();
+        client_key =
+            reinterpret_cast<const unsigned char*>(badclient_key_.data());
+        client_key_size = badclient_key_.size();
+      } else {
+        client_cert =
+            reinterpret_cast<const unsigned char*>(client_cert_.data());
+        client_cert_size = client_cert_.size();
+        client_key = reinterpret_cast<const unsigned char*>(client_key_.data());
+        client_key_size = client_key_.size();
+      }
+    }
+    const unsigned char** client_alpn_protocols(nullptr);
+    const unsigned char* client_alpn_protocols_lengths(nullptr);
+    uint16_t num_client_alpn_protocols = 0;
+    if (config_.alpn_mode == ALPN_CLIENT_NO_SERVER ||
+        config_.alpn_mode == ALPN_CLIENT_SERVER_OK ||
+        config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
+      client_alpn_protocols =
+          reinterpret_cast<const unsigned char**>(&client_alpn_protocols_[0]);
+      client_alpn_protocols_lengths = &client_alpn_protocols_lengths_[0];
+      num_client_alpn_protocols = client_alpn_protocols_.size();
+    }
+
+    EXPECT_EQ(tsi_create_ssl_client_handshaker_factory(
+                  client_key, client_key_size, client_cert, client_cert_size,
+                  reinterpret_cast<const unsigned char*>(root_certs_.data()),
+                  root_certs_.size(), NULL, client_alpn_protocols,
+                  client_alpn_protocols_lengths, num_client_alpn_protocols,
+                  &client_handshaker_factory),
+              TSI_OK);
+    client_handshaker_factory_.reset(client_handshaker_factory);
+
+    const unsigned char** server_alpn_protocols(nullptr);
+    const unsigned char* server_alpn_protocols_lengths(nullptr);
+    uint16_t num_server_alpn_protocols = 0;
+    if (config_.alpn_mode == ALPN_SERVER_NO_CLIENT ||
+        config_.alpn_mode == ALPN_CLIENT_SERVER_OK ||
+        config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
+      server_alpn_protocols =
+          reinterpret_cast<const unsigned char**>(&server_alpn_protocols_[0]);
+      server_alpn_protocols_lengths = &server_alpn_protocols_lengths_[0];
+      num_server_alpn_protocols = server_alpn_protocols_.size();
+      if (config_.alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) {
+        // Remove the last element that is common.
+        num_server_alpn_protocols--;
+      }
+    }
+    tsi_ssl_handshaker_factory* server_handshaker_factory;
+    EXPECT_EQ(
+        tsi_create_ssl_server_handshaker_factory(
+            config_.use_bad_server_cert ? &badserver_keys_[0]
+                                        : &server_keys_[0],
+            config_.use_bad_server_cert ? &badserver_keys_sizes_[0]
+                                        : &server_keys_sizes_[0],
+            config_.use_bad_server_cert ? &badserver_certs_[0]
+                                        : &server_certs_[0],
+            config_.use_bad_server_cert ? &badserver_certs_sizes_[0]
+                                        : &server_certs_sizes_[0],
+            config_.use_bad_server_cert ? badserver_keys_.size()
+                                        : server_keys_.size(),
+            config_.do_client_authentication
+                ? reinterpret_cast<const unsigned char*>(root_certs_.data())
+                : NULL,
+            config_.do_client_authentication ? root_certs_.size() : 0, NULL,
+            server_alpn_protocols, server_alpn_protocols_lengths,
+            num_server_alpn_protocols, &server_handshaker_factory),
+        TSI_OK);
+    server_handshaker_factory_.reset(server_handshaker_factory);
+
+    tsi_handshaker* client_handshaker;
+    EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker(
+                  client_handshaker_factory, config_.subject_name_indication,
+                  &client_handshaker),
+              TSI_OK);
+    client_handshaker_.reset(client_handshaker);
+
+    tsi_handshaker* server_handshaker;
+    EXPECT_EQ(tsi_ssl_handshaker_factory_create_handshaker(
+                  server_handshaker_factory, NULL, &server_handshaker),
+              TSI_OK);
+    server_handshaker_.reset(server_handshaker);
+  }
+
+  void CheckAlpn(const tsi_peer* peer) {
+    const tsi_peer_property* alpn_property =
+        tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
+    if (config_.alpn_mode != ALPN_CLIENT_SERVER_OK) {
+      EXPECT_EQ(nullptr, alpn_property);
+    } else {
+      EXPECT_NE(nullptr, alpn_property);
+      EXPECT_EQ(TSI_PEER_PROPERTY_TYPE_STRING, alpn_property->type);
+      string expected_match("baz");
+      EXPECT_EQ(expected_match, string(alpn_property->value.string.data,
+                                       alpn_property->value.string.length));
+    }
+  }
+
+  void CheckHandshakeResults() override {
+    tsi_peer peer;
+
+    bool expect_success =
+        !(config_.use_bad_server_cert ||
+          (config_.use_bad_client_cert && config_.do_client_authentication));
+    tsi_result result = tsi_handshaker_get_result(client_handshaker_.get());
+    EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS);
+    if (expect_success) {
+      EXPECT_EQ(result, TSI_OK);
+      EXPECT_EQ(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer),
+                TSI_OK);
+      CheckAlpn(&peer);
+      // TODO(jboeuf): This is a bit fragile. Maybe revisit.
+      if (config_.subject_name_indication != nullptr) {
+        CheckServer1Peer(&peer);
+      } else {
+        CheckServer0Peer(&peer);
+      }
+    } else {
+      EXPECT_NE(result, TSI_OK);
+      EXPECT_NE(tsi_handshaker_extract_peer(client_handshaker_.get(), &peer),
+                TSI_OK);
+    }
+
+    result = tsi_handshaker_get_result(server_handshaker_.get());
+    EXPECT_NE(result, TSI_HANDSHAKE_IN_PROGRESS);
+    if (expect_success) {
+      EXPECT_EQ(result, TSI_OK);
+      EXPECT_EQ(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer),
+                TSI_OK);
+      CheckAlpn(&peer);
+      CheckClientPeer(&peer, config_.do_client_authentication);
+    } else {
+      EXPECT_NE(result, TSI_OK);
+      EXPECT_NE(tsi_handshaker_extract_peer(server_handshaker_.get(), &peer),
+                TSI_OK);
+    }
+  }
+
+  const tsi::test::TestConfig* config() override {
+    return &config_;
+  }
+
+  SslTransportSecurityTest()
+      : client_alpn_protocols_({"foo", "toto", "baz"}),
+        server_alpn_protocols_({"boooo", "far", "baz"}),
+        client_alpn_protocols_lengths_({3, 4, 3}),
+        server_alpn_protocols_lengths_({5, 3, 3}) {
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.key"),
+        &badserver_key_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badserver.pem"),
+        &badserver_cert_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.key"),
+        &badclient_key_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "badclient.pem"),
+        &badclient_cert_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.key"),
+        &server0_key_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server0.pem"),
+        &server0_cert_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.key"),
+        &server1_key_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "server1.pem"),
+        &server1_cert_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.key"),
+        &client_key_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "client.pem"),
+        &client_cert_, file::Options()));
+    CHECK_OK(file::GetContents(
+        file::JoinPath(FLAGS_test_srcdir, kTestCredsDir, "ca.pem"),
+        &root_certs_, file::Options()));
+    badserver_keys_.push_back(
+        reinterpret_cast<const unsigned char*>(badserver_key_.data()));
+    badserver_certs_.push_back(
+        reinterpret_cast<const unsigned char*>(badserver_cert_.data()));
+    server_keys_.push_back(
+        reinterpret_cast<const unsigned char*>(server0_key_.data()));
+    server_keys_.push_back(
+        reinterpret_cast<const unsigned char*>(server1_key_.data()));
+    server_certs_.push_back(
+        reinterpret_cast<const unsigned char*>(server0_cert_.data()));
+    server_certs_.push_back(
+        reinterpret_cast<const unsigned char*>(server1_cert_.data()));
+    badserver_keys_sizes_.push_back(badserver_key_.size());
+    badserver_certs_sizes_.push_back(badserver_cert_.size());
+    server_keys_sizes_.push_back(server0_key_.size());
+    server_keys_sizes_.push_back(server1_key_.size());
+    server_certs_sizes_.push_back(server0_cert_.size());
+    server_certs_sizes_.push_back(server1_cert_.size());
+  }
+
+  string badserver_key_;
+  string badserver_cert_;
+  string badclient_key_;
+  string badclient_cert_;
+  string server0_key_;
+  string server0_cert_;
+  string server1_key_;
+  string server1_cert_;
+  string client_key_;
+  string client_cert_;
+  string root_certs_;
+  std::vector<const unsigned char*> badserver_keys_;
+  std::vector<const unsigned char*> badserver_certs_;
+  std::vector<const unsigned char*> server_keys_;
+  std::vector<const unsigned char*> server_certs_;
+  std::vector<unsigned int> badserver_keys_sizes_;
+  std::vector<unsigned int> badserver_certs_sizes_;
+  std::vector<unsigned int> server_keys_sizes_;
+  std::vector<unsigned int> server_certs_sizes_;
+  TsiSslHandshakerFactoryUniquePtr client_handshaker_factory_;
+  TsiSslHandshakerFactoryUniquePtr server_handshaker_factory_;
+  std::vector<const char*> client_alpn_protocols_;
+  std::vector<const char*> server_alpn_protocols_;
+  std::vector<unsigned char> client_alpn_protocols_lengths_;
+  std::vector<unsigned char> server_alpn_protocols_lengths_;
+  string matched_alpn_;
+  SslTestConfig config_;
+};
+
+
+TEST_F(SslTransportSecurityTest, LoadInvalidRoots) {
+  tsi_ssl_handshaker_factory* client_handshaker_factory;
+  string invalid_roots("Invalid roots!");
+  EXPECT_EQ(
+      TSI_INVALID_ARGUMENT,
+      tsi_create_ssl_client_handshaker_factory(
+          NULL, 0, NULL, 0,
+          reinterpret_cast<const unsigned char*>(invalid_roots.data()),
+          invalid_roots.size(), NULL, NULL, 0, 0, &client_handshaker_factory));
+}
+
+TEST_F(SslTransportSecurityTest, Handshake) {
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, HandshakeClientAuthentication) {
+  config_.do_client_authentication = true;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, HandshakeSmallBuffer) {
+  config_.handshake_buffer_size = 128;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, HandshakeSNIExactDomain) {
+  // server1 cert contains waterzooi.test.google.be in SAN.
+  config_.subject_name_indication = "waterzooi.test.google.be";
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, HandshakeSNIWildstarDomain) {
+  // server1 cert contains *.test.google.fr in SAN.
+  config_.subject_name_indication = "juju.test.google.fr";
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, BadServerCertFailure) {
+  config_.use_bad_server_cert = true;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, BadClientCertFailure) {
+  config_.use_bad_client_cert = true;
+  config_.do_client_authentication = true;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, AlpnClientNoServer) {
+  config_.alpn_mode = ALPN_CLIENT_NO_SERVER;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, AlpnServerNoClient) {
+  config_.alpn_mode = ALPN_SERVER_NO_CLIENT;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, AlpnClientServeMismatch) {
+  config_.alpn_mode = ALPN_CLIENT_SERVER_MISMATCH;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, AlpnClientServerOk) {
+  config_.alpn_mode = ALPN_CLIENT_SERVER_OK;
+  PerformHandshake();
+}
+
+TEST_F(SslTransportSecurityTest, PingPong) {
+  PingPong();
+}
+
+TEST_F(SslTransportSecurityTest, RoundTrip) {
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(SslTransportSecurityTest, RoundTripSmallMessageBuffer) {
+  config_.message_buffer_allocated_size = 42;
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(SslTransportSecurityTest, RoundTripSmallProtectedBufferSize) {
+  config_.protected_buffer_size = 37;
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(SslTransportSecurityTest, RoundTripSmallReadBufferSize) {
+  config_.read_buffer_allocated_size = 41;
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(SslTransportSecurityTest, RoundTripSmallClientFrames) {
+  config_.set_client_max_output_protected_frame_size(39);
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+TEST_F(SslTransportSecurityTest, RoundTripSmallServerFrames) {
+  config_.set_server_max_output_protected_frame_size(43);
+  config_.client_message = small_message_;
+  config_.server_message = big_message_;
+  DoRoundTrip();
+}
+
+TEST_F(SslTransportSecurityTest, RoundTripOddBufferSizes) {
+  int odd_sizes[] = {33, 67, 135, 271, 523};
+  RandomPermutation<int> permute(odd_sizes, arraysize(odd_sizes),
+                                 random_.get());
+  permute.Permute();
+  LOG(ERROR) << odd_sizes[0] << "\t" << odd_sizes[1] << "\t" << odd_sizes[2]
+             << "\t" << odd_sizes[3] << "\t" << odd_sizes[4];
+  config_.message_buffer_allocated_size = odd_sizes[0];
+  config_.protected_buffer_size = odd_sizes[1];
+  config_.read_buffer_allocated_size = odd_sizes[2];
+  config_.set_client_max_output_protected_frame_size(odd_sizes[3]);
+  config_.set_server_max_output_protected_frame_size(odd_sizes[4]);
+  config_.client_message = big_message_;
+  config_.server_message = small_message_;
+  DoRoundTrip();
+}
+
+}  // namespace
diff --git a/src/core/tsi/test_creds/README b/src/core/tsi/test_creds/README
new file mode 100644
index 0000000..eb8482d
--- /dev/null
+++ b/src/core/tsi/test_creds/README
@@ -0,0 +1,62 @@
+The test credentials (CONFIRMEDTESTKEY) have been generated with the following
+commands:
+
+Bad credentials (badclient.* / badserver.*):
+============================================
+
+These are self-signed certificates:
+
+$ openssl req -x509 -newkey rsa:1024 -keyout badserver.key -out badserver.pem \
+  -days 3650 -nodes
+
+When prompted for certificate information, everything is default except the
+common name which is set to badserver.test.google.com.
+
+
+Valid test credentials:
+=======================
+
+The ca is self-signed:
+----------------------
+
+$ openssl req -x509 -new -newkey rsa:1024 -nodes -out ca.pem -config ca-openssl.cnf -days 3650 -extensions v3_req
+When prompted for certificate information, everything is default.
+
+client is issued by CA:
+-----------------------
+
+$ openssl genrsa -out client.key.rsa 1024
+$ openssl pkcs8 -topk8 -in client.key.rsa -out client.key -nocrypt
+$ rm client.key.rsa
+$ openssl req -new -key client.key -out client.csr
+
+When prompted for certificate information, everything is default except the
+common name which is set to testclient.
+
+$ openssl ca -in client.csr -out client.pem
+
+server0 is issued by CA:
+------------------------
+
+$ openssl genrsa -out server0.key.rsa 1024
+$ openssl pkcs8 -topk8 -in server0.key.rsa -out server0.key -nocrypt
+$ rm server0.key.rsa
+$ openssl req -new -key server0.key -out server0.csr
+
+When prompted for certificate information, everything is default except the
+common name which is set to *.test.google.com.au.
+
+$ openssl ca -in server0.csr -out server0.pem
+
+server1 is issued by CA with a special config for subject alternative names:
+----------------------------------------------------------------------------
+
+$ openssl genrsa -out server1.key.rsa 1024
+$ openssl pkcs8 -topk8 -in server1.key.rsa -out server1.key -nocrypt
+$ rm server1.key.rsa
+$ openssl req -new -key server1.key -out server1.csr -config server1-openssl.cnf
+
+When prompted for certificate information, everything is default except the
+common name which is set to *.test.google.com.
+
+$ openssl ca -in server1.csr -out server1.pem
diff --git a/src/core/tsi/test_creds/badclient.key b/src/core/tsi/test_creds/badclient.key
new file mode 100644
index 0000000..5832685
--- /dev/null
+++ b/src/core/tsi/test_creds/badclient.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALJfYnFn4nkj52WF
+E5W2qUxCfjsEFyuXYYKS/07UPWsv3gpZhtjXgdeGL+dpwEBC0IRDBfGnkMp6YY5S
+O7rnEz0X3r/fvgYy+dEl2jnaA6zgc7RzMGl9U11d56gP9FiDC2190mvP/hpq2xLZ
+CTbIximpmaoQyxuuH1bbYunesIG/AgMBAAECgYAdqJCEzMIyZE7oaW0tOpcB0BiP
+FYoIvH4BKRH8eHvR476mt+YdDhBP1scGUmYeCT4Ej+RgHv2LPTgVYwT9eciP2+E/
+CBCNRel0Sw9JepwW0r+jWJtDY1pp6YXAgNRGX2UflvUsT+o9lZvagf9moLTMyGvU
+uLFnsyfLim1B4vXvWQJBANouZllXGZoSrZLtR3VgV4tzRQvJxu84kLeIk64Ov47X
+pHVBMTRBfzPEhbBodjr1m5OLaVLqkFcXftzRCrbWoKsCQQDRSoLLXOiLrtJ3DLJC
+rX7Y8wrHZrqk5bMdZLGa/UX8RanhVw3+Xp+urd1711umeNJfzu/MCk4a1KkG/CU0
+rqs9AkA4cSx1DD1JSG+yxMNpsAS1xJomFIrsM9vsPt7FdndDwrF+y+CovhDkGYDk
+RAHh+svGfZg/pQK2JRPimAmHhzqFAkEAu6Ya70s2FUeB3Mu9aJs2CD6hg3dQEVkB
+53DI7TX48d9kGW58VX1xnqS02LyWqAPcW5qm1kLHFLdndaPNmBaj4QJBAJugl367
+9d9t/QLTSuULLaoYv2vJT3s1y9HN89EoaDDEkPVfQu6GVEXgIBtim1sI/VPSzI8H
+aXvaTUwblFWSM70=
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/badclient.pem b/src/core/tsi/test_creds/badclient.pem
new file mode 100644
index 0000000..1785970
--- /dev/null
+++ b/src/core/tsi/test_creds/badclient.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICoDCCAgmgAwIBAgIJANIz2/zoRiapMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZGNsaWVudC50ZXN0Lmdvb2dsZS5j
+b20wHhcNMTQwNzI4MjAwODI1WhcNMjQwNzI1MjAwODI1WjBpMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRjbGllbnQudGVzdC5nb29nbGUuY29tMIGf
+MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyX2JxZ+J5I+dlhROVtqlMQn47BBcr
+l2GCkv9O1D1rL94KWYbY14HXhi/nacBAQtCEQwXxp5DKemGOUju65xM9F96/374G
+MvnRJdo52gOs4HO0czBpfVNdXeeoD/RYgwttfdJrz/4aatsS2Qk2yMYpqZmqEMsb
+rh9W22Lp3rCBvwIDAQABo1AwTjAdBgNVHQ4EFgQU523AJMR8Ds9V8fhf7gu1i0MM
+UqAwHwYDVR0jBBgwFoAU523AJMR8Ds9V8fhf7gu1i0MMUqAwDAYDVR0TBAUwAwEB
+/zANBgkqhkiG9w0BAQUFAAOBgQCI/tvSBYH1iyfLaCTBKwpdj36+MkR9EeJJmImx
+X+bjhKWXwsBX4PDMWvdusr++QGUYtyoya+hfYMXRhXua39mD54xgloQNuu9REDwX
+Ffto+aOw3BcYducz6ofxicFK/Y2VeXDurSMpRv5TfGf2Qr6eOOdaRhj6ed7BibHk
+X1VGZA==
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/badserver.key b/src/core/tsi/test_creds/badserver.key
new file mode 100644
index 0000000..abfbde1
--- /dev/null
+++ b/src/core/tsi/test_creds/badserver.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKeZ1e1y29cmBKaW
+oIUwJ5neOJUjx+eD/3nRPe+dvLXEd9+db0fG5RYRR0S3mF1Ywuj4PIxlTW2YprUS
+oGSw+tcqWNIzxv94HjwYFkkvER3AblXcDBh0P2zAkzg+nf9AcAsMh0QpDTyrXtMl
+gqryjq1/vkhFofKMMbY+aXJdG6OBAgMBAAECgYAAgaB51S0A22aMMkxN2rVj6530
+JWWHN4jgD1fGj41wZyWNkWYyq1Ep3ed/N6bIMWp1VbqpGe0/9YQba/D8HOTFHGRt
+72YXnP1e/ds8cxU4x4j1vvqSPtXpMmkiXfXijOvCl9mrMH2xjghFAt6/1Nb9xo1m
+VdcOB8OdSuOIw6CI+QJBAN5FZUbS+bRXDWII/FaAih1DBpwCxhYEN+TXPJBxSen6
+kOzGt5g+mB6YqRMZ/qshshwPq7bsgFGfJ2lIdS2t3GsCQQDBCKifV5AAkOdOUrkK
+HvoX3qnVmyIA8CyvWLcIWpfZ76QAYh0q0StedKdOMXaB1jTeSJ2KU1nlss7UD1Yw
+VbrDAkAwjMHpbW3jiVw//Kx5jIwehiRscWKpLnSzBJyTBFvbwsJjJai2lX2OuVO8
++2GYKb0Iyhd81j3VFkl6grwtpRtPAkB7+n+yt555fpfRKjhGU9b09cHGu7h/OcK5
+bBVCfE0DYHLI/DsXgPiF1g6Onh4rDdUu3xyv9xDKAqnscV099hHZAkEAvcFBfXZs
+tk18N+bUcvXTdZjzZbfLCHlJmwPIspZ8G/6Pn63deg4GVYoCvTwGruah+8y734Ph
+7PskfPgUQlB7Ag==
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/badserver.pem b/src/core/tsi/test_creds/badserver.pem
new file mode 100644
index 0000000..983c979
--- /dev/null
+++ b/src/core/tsi/test_creds/badserver.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICoDCCAgmgAwIBAgIJAPdqwqsKNy81MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZHNlcnZlci50ZXN0Lmdvb2dsZS5j
+b20wHhcNMTQwNzI4MjAwODU0WhcNMjQwNzI1MjAwODU0WjBpMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRzZXJ2ZXIudGVzdC5nb29nbGUuY29tMIGf
+MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmdXtctvXJgSmlqCFMCeZ3jiVI8fn
+g/950T3vnby1xHffnW9HxuUWEUdEt5hdWMLo+DyMZU1tmKa1EqBksPrXKljSM8b/
+eB48GBZJLxEdwG5V3AwYdD9swJM4Pp3/QHALDIdEKQ08q17TJYKq8o6tf75IRaHy
+jDG2PmlyXRujgQIDAQABo1AwTjAdBgNVHQ4EFgQU3u/qvHr9knMBeZyAD7mAA/ec
+8cUwHwYDVR0jBBgwFoAU3u/qvHr9knMBeZyAD7mAA/ec8cUwDAYDVR0TBAUwAwEB
+/zANBgkqhkiG9w0BAQUFAAOBgQA/FmR1SGLguxCCfhp4CYCbrAePSyPWDi48gTwj
+vVZf/OMxdVu/H8sBYFf27BjbrEugAw16DElFtgTZ83pLb2BvkUgb6vBUK5sEkgmh
+z88zBsgDp8aCf4STDOLFZMBh/E9ZKkm1zogbEmlTjFp/ceSpa2gNv7OuN4WiorOh
+Wvw40g==
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/ca-openssl.cnf b/src/core/tsi/test_creds/ca-openssl.cnf
new file mode 100644
index 0000000..e97b945
--- /dev/null
+++ b/src/core/tsi/test_creds/ca-openssl.cnf
@@ -0,0 +1,17 @@
+[req]
+distinguished_name  = req_distinguished_name
+req_extensions = v3_req
+
+[req_distinguished_name]
+countryName           = Country Name (2 letter code)
+countryName_default = AU
+stateOrProvinceName   = State or Province Name (full name)
+stateOrProvinceName_default = Some-State
+organizationName          = Organization Name (eg, company)
+organizationName_default = Internet Widgits Pty Ltd
+commonName            = Common Name (eg, YOUR name)
+commonName_default = testca
+
+[v3_req]
+basicConstraints = CA:true
+keyUsage = critical, keyCertSign
diff --git a/src/core/tsi/test_creds/ca.key b/src/core/tsi/test_creds/ca.key
new file mode 100644
index 0000000..03c4f95
--- /dev/null
+++ b/src/core/tsi/test_creds/ca.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMBA3wVeTGHZR1Ry
+e/i+J8a2cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBl
+LoNY0lSvxDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JA
+HUGodjx+QAi6yCAurUZGvYXGgZSBAgMBAAECgYAxRi8i9BlFlufGSBVoGmydbJOm
+bwLKl9dP3o33ODSP9hok5y6A0w5plWk3AJSF1hPLleK9VcSKYGYnt0clmPVHF35g
+bx2rVK8dOT0mn7rz9Zr70jcSz1ETA2QonHZ+Y+niLmcic9At6hRtWiewblUmyFQm
+GwggIzi7LOyEUHrEcQJBAOXxyQvnLvtKzXiqcsW/K6rExqVJVk+KF0fzzVyMzTJx
+HRBxUVgvGdEJT7j+7P2kcTyafve0BBzDSPIaDyiJ+Y0CQQDWCb7jASFSbu5M3Zcd
+Gkr4ZKN1XO3VLQX10b22bQYdF45hrTN2tnzRvVUR4q86VVnXmiGiTqmLkXcA2WWf
+pHfFAkAhv9olUBo6MeF0i3frBEMRfm41hk0PwZHnMqZ6pgPcGnQMnMU2rzsXzkkQ
+OwJnvAIOxhJKovZTjmofdqmw5odlAkBYVUdRWjsNUTjJwj3GRf6gyq/nFMYWz3EB
+RWFdM1ttkDYzu45ctO2IhfHg4sPceDMO1s6AtKQmNI9/azkUjITdAkApNa9yFRzc
+TBaDNPd5KVd58LVIzoPQ6i7uMHteLXJUWqSroji6S3s4gKMFJ/dO+ZXIlgQgfJJJ
+ZDL4cdrdkeoM
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/ca.pem b/src/core/tsi/test_creds/ca.pem
new file mode 100644
index 0000000..6c8511a
--- /dev/null
+++ b/src/core/tsi/test_creds/ca.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla
+Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
+YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT
+BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7
++L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu
+g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd
+Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau
+sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m
+oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG
+Dfcog5wrJytaQ6UA0wE=
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/client.key b/src/core/tsi/test_creds/client.key
new file mode 100644
index 0000000..f48d073
--- /dev/null
+++ b/src/core/tsi/test_creds/client.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOxUR9uhvhbeVUIM
+s5WbH0px0mehl2+6sZpNjzvE2KimZpHzMJHukVH0Ffkvhs0b8+S5Ut9VNUAqd3IM
+JCCAEGtRNoQhM1t9Yr2zAckSvbRacp+FL/Cj9eDmyo00KsVGaeefA4Dh4OW+ZhkT
+NKcldXqkSuj1sEf244JZYuqZp6/tAgMBAAECgYEAi2NSVqpZMafE5YYUTcMGe6QS
+k2jtpsqYgggI2RnLJ/2tNZwYI5pwP8QVSbnMaiF4gokD5hGdrNDfTnb2v+yIwYEH
+0w8+oG7Z81KodsiZSIDJfTGsAZhVNwOz9y0VD8BBZZ1/274Zh52AUKLjZS/ZwIbS
+W2ywya855dPnH/wj+0ECQQD9X8D920kByTNHhBG18biAEZ4pxs9f0OAG8333eVcI
+w2lJDLsYDZrCB2ocgA3lUdozlzPC7YDYw8reg0tkiRY5AkEA7sdNzOeQsQRn7++5
+0bP9DtT/iON1gbfxRzCfCfXdoOtfQWIzTePWtURt9X/5D9NofI0Rg5W2oGy/MLe5
+/sXHVQJBAIup5XrJDkQywNZyAUU2ecn2bCWBFjwtqd+LBmuMciI9fOKsZtEKZrz/
+U0lkeMRoSwvXE8wmGLjjrAbdfohrXFkCQQDZEx/LtIl6JINJQiswVe0tWr6k+ASP
+1WXoTm+HYpoF/XUvv9LccNF1IazFj34hwRQwhx7w/V52Ieb+p0jUMYGxAkEAjDhd
+9pBO1fKXWiXzi9ZKfoyTNcUq3eBSVKwPG2nItg5ycXengjT5sgcWDnciIzW7BIVI
+JiqOszq9GWESErAatg==
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/client.pem b/src/core/tsi/test_creds/client.pem
new file mode 100644
index 0000000..e332091
--- /dev/null
+++ b/src/core/tsi/test_creds/client.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICHzCCAYgCAQEwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV
+BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
+ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcxNzIzNTYwMloXDTI0MDcxNDIzNTYw
+MlowWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKdGVzdGNsaWVudDCB
+nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7FRH26G+Ft5VQgyzlZsfSnHSZ6GX
+b7qxmk2PO8TYqKZmkfMwke6RUfQV+S+GzRvz5LlS31U1QCp3cgwkIIAQa1E2hCEz
+W31ivbMByRK9tFpyn4Uv8KP14ObKjTQqxUZp558DgOHg5b5mGRM0pyV1eqRK6PWw
+R/bjglli6pmnr+0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAStSm5PM7ubROiKK6/
+T2FkKlhiTOx+Ryenm3Eio59emq+jXl+1nhPySX5G2PQzSR5vd1dIhwgZSR4Gyttk
+tRZ57k/NI1brUW8joiEOMJA/Mr7H7asx7wIRYDE91Fs8GkKWd5LhoPAQj+qdG35C
+OO+svdkmqH0KZo320ZUqdl2ooQ==
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/server0.key b/src/core/tsi/test_creds/server0.key
new file mode 100644
index 0000000..add153c
--- /dev/null
+++ b/src/core/tsi/test_creds/server0.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANOmffupIGC8YDau
+rOF4eKnHwPszgpkkhWzKsVxhNDBxCVYx4TEjG0XWIO0iyRXupZbUC+7N/8HnEVNa
+8F1jYhng14Iiq99cNQbbnuHHhIztmpocrJTxmnhGzoAnRa1Tb+GnAuRoIHRA/V2c
+VUE9tbikQugFx/SPgXAw6tfWB+YvAgMBAAECgYEAoEq9qzUBgoHoVEGiSPiWWe8g
+5p6yUA1qx2QTQyWTAwT4z0DjjfVKmG99bFsl8+hTnJFnoCp/gnjflEOROwkjp5kG
+m0drqOPx1jeipJjpXYTBu49h+WpZ1PF+KhVtxsIm3OOCvh67iWaKyyOVb5Og8aiR
+jl6dn/TdG/dlGD8AfUECQQDuNMle6p0oU8amC6O9wIMBroxx2nFstzE6O35PLEzG
+/tj0kxxn9Jp2TS9mGaLCzSuXmpjlF4+NOWiBPkrLC2TfAkEA43Xg7uEUkaJAz2/W
+m1lIBTLt+4rIQY/2emh33bDcA+rv8rwwrMMIv17/xPx7bs49YqGG5xufD+Rwl6TL
+qFXYsQJAPrOwagax1aKvwJeBw3oAQhoTKAkLIEXcdGqipe6QSzVcIIz0xjxxyEAr
+AOIwoLxnBCISqwMXq2H4K0UdZPMb2wJAdhdYLY1L6YRMk6XjzImg25oidisKZweA
+FvMv8DgHMj2CUAqmVrt3SivfLH1M9C09L3zfFhOAFHcsgX58gav4MQJBANSBnrHj
+tIq4l8z79CPUIuu3QyeEh+XwY8s5qE5CNTck0U59lzp9NvENHbkx3KO896TTerko
++8bXHMLkJkHPXms=
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/server0.pem b/src/core/tsi/test_creds/server0.pem
new file mode 100644
index 0000000..ade75d8
--- /dev/null
+++ b/src/core/tsi/test_creds/server0.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICHDCCAYUCAQQwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV
+BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
+ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcyMjE3NTk0OVoXDTI0MDcxOTE3NTk0
+OVowVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxFDASBgNVBAoM
+C0dvb2dsZSBJbmMuMR0wGwYDVQQDDBQqLnRlc3QuZ29vZ2xlLmNvbS5hdTCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06Z9+6kgYLxgNq6s4Xh4qcfA+zOCmSSF
+bMqxXGE0MHEJVjHhMSMbRdYg7SLJFe6lltQL7s3/wecRU1rwXWNiGeDXgiKr31w1
+Btue4ceEjO2amhyslPGaeEbOgCdFrVNv4acC5GggdED9XZxVQT21uKRC6AXH9I+B
+cDDq19YH5i8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQBtfR5qXG9TTI8YcYh7sA4V
+GeNoplp0x6p7OG0NLvbJqAkUnkvjIkk1m1R2AUHhbkxzx6G75JIOoNJcWrCzywBA
+BIsaTdmnNysf/s1hQJuD3IHiVb+7Ji0jhttnJlYcMid4o0tJO/a2E9YUxR+9cg0i
+obb+Ql3qsvKdWBC1dDLDLw==
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/server1-openssl.cnf b/src/core/tsi/test_creds/server1-openssl.cnf
new file mode 100644
index 0000000..8a02108
--- /dev/null
+++ b/src/core/tsi/test_creds/server1-openssl.cnf
@@ -0,0 +1,26 @@
+[req]
+distinguished_name  = req_distinguished_name
+req_extensions     = v3_req
+
+[req_distinguished_name]
+countryName           = Country Name (2 letter code)
+countryName_default   = US
+stateOrProvinceName   = State or Province Name (full name)
+stateOrProvinceName_default = Illinois
+localityName          = Locality Name (eg, city)
+localityName_default  = Chicago
+organizationName          = Organization Name (eg, company)
+organizationName_default  = Example, Co.
+commonName            = Common Name (eg, YOUR name)
+commonName_max        = 64
+
+[v3_req]
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+subjectAltName = @alt_names
+
+[alt_names]
+DNS.1 = *.test.google.fr
+DNS.2 = waterzooi.test.google.be
+DNS.3 = *.test.youtube.com
+IP.1 = "192.168.1.3"
diff --git a/src/core/tsi/test_creds/server1.key b/src/core/tsi/test_creds/server1.key
new file mode 100644
index 0000000..143a5b8
--- /dev/null
+++ b/src/core/tsi/test_creds/server1.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD
+M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf
+3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY
+AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm
+V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY
+tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p
+dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q
+K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR
+81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff
+DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd
+aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2
+ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3
+XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe
+F98XJ7tIFfJq
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/server1.pem b/src/core/tsi/test_creds/server1.pem
new file mode 100644
index 0000000..8e582e5
--- /dev/null
+++ b/src/core/tsi/test_creds/server1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
+MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
+c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
+JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
+RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
+3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
+BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
+b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
+KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
+wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
+aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c
new file mode 100644
index 0000000..94252e3
--- /dev/null
+++ b/src/core/tsi/transport_security.c
@@ -0,0 +1,372 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/tsi/transport_security.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* --- Utils. --- */
+
+char* tsi_strdup(const char* src) {
+  char* dst;
+  uint32_t len;
+  if (!src) return NULL;
+  len = strlen(src) + 1;
+  dst = malloc(len);
+  if (!dst)  return NULL;
+  memcpy(dst, src, len);
+  return dst;
+}
+
+/* --- tsi_result common implementation. --- */
+
+const char* tsi_result_to_string(tsi_result result) {
+  switch (result) {
+    case TSI_OK:
+      return "TSI_OK";
+    case TSI_UNKNOWN_ERROR:
+      return "TSI_UNKNOWN_ERROR";
+    case TSI_INVALID_ARGUMENT:
+      return "TSI_INVALID_ARGUMENT";
+    case TSI_PERMISSION_DENIED:
+      return "TSI_PERMISSION_DENIED";
+    case TSI_INCOMPLETE_DATA:
+      return "TSI_INCOMPLETE_DATA";
+    case TSI_FAILED_PRECONDITION:
+      return "TSI_FAILED_PRECONDITION";
+    case TSI_UNIMPLEMENTED:
+      return "TSI_UNIMPLEMENTED";
+    case TSI_INTERNAL_ERROR:
+      return "TSI_INTERNAL_ERROR";
+    case TSI_DATA_CORRUPTED:
+      return "TSI_DATA_CORRUPTED";
+    case TSI_NOT_FOUND:
+      return "TSI_NOT_FOUND";
+    case TSI_PROTOCOL_FAILURE:
+      return "TSI_PROTOCOL_FAILURE";
+    case TSI_HANDSHAKE_IN_PROGRESS:
+      return "TSI_HANDSHAKE_IN_PROGRESS";
+    case TSI_OUT_OF_RESOURCES:
+      return "TSI_OUT_OF_RESOURCES";
+    default:
+      return "UNKNOWN";
+  }
+}
+
+
+/* --- tsi_frame_protector common implementation. ---
+
+   Calls specific implementation after state/input validation. */
+
+tsi_result tsi_frame_protector_protect(
+    tsi_frame_protector* self,
+    const unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size,
+    unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size) {
+  if (self == NULL || unprotected_bytes == NULL ||
+      unprotected_bytes_size == NULL || protected_output_frames == NULL ||
+      protected_output_frames_size == NULL) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  return self->vtable->protect(self, unprotected_bytes, unprotected_bytes_size,
+                               protected_output_frames,
+                               protected_output_frames_size);
+}
+
+tsi_result tsi_frame_protector_protect_flush(
+    tsi_frame_protector* self,
+    unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size,
+    uint32_t* still_pending_size) {
+  if (self == NULL || protected_output_frames == NULL ||
+      protected_output_frames == NULL || still_pending_size == NULL) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  return self->vtable->protect_flush(self, protected_output_frames,
+                                     protected_output_frames_size,
+                                     still_pending_size);
+}
+
+tsi_result tsi_frame_protector_unprotect(
+    tsi_frame_protector* self,
+    const unsigned char* protected_frames_bytes,
+    uint32_t* protected_frames_bytes_size,
+    unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size) {
+  if (self == NULL || protected_frames_bytes == NULL ||
+      protected_frames_bytes_size == NULL || unprotected_bytes == NULL ||
+      unprotected_bytes_size == NULL) {
+    return TSI_INVALID_ARGUMENT;
+  }
+  return self->vtable->unprotect(self, protected_frames_bytes,
+                                 protected_frames_bytes_size, unprotected_bytes,
+                                 unprotected_bytes_size);
+}
+
+void tsi_frame_protector_destroy(tsi_frame_protector* self) {
+  if (self == NULL) return;
+  self->vtable->destroy(self);
+}
+
+
+/* --- tsi_handshaker common implementation. ---
+
+   Calls specific implementation after state/input validation. */
+
+tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
+                                                    unsigned char* bytes,
+                                                    uint32_t* bytes_size) {
+  if (self == NULL) return TSI_INVALID_ARGUMENT;
+  if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  return self->vtable->get_bytes_to_send_to_peer(self, bytes, bytes_size);
+}
+
+
+tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker* self,
+                                                  const unsigned char* bytes,
+                                                  uint32_t* bytes_size) {
+  if (self == NULL) return TSI_INVALID_ARGUMENT;
+  if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  return self->vtable->process_bytes_from_peer(self, bytes, bytes_size);
+}
+
+tsi_result tsi_handshaker_get_result(tsi_handshaker* self) {
+  if (self == NULL) return TSI_INVALID_ARGUMENT;
+  if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  return self->vtable->get_result(self);
+}
+
+tsi_result tsi_handshaker_extract_peer(tsi_handshaker* self, tsi_peer* peer) {
+  if (self == NULL || peer == NULL) return TSI_INVALID_ARGUMENT;
+  memset(peer, 0, sizeof(tsi_peer));
+  if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  if (tsi_handshaker_get_result(self) != TSI_OK) {
+    return TSI_FAILED_PRECONDITION;
+  }
+  return self->vtable->extract_peer(self, peer);
+}
+
+tsi_result tsi_handshaker_create_frame_protector(
+    tsi_handshaker* self,
+    uint32_t* max_protected_frame_size,
+    tsi_frame_protector** protector) {
+  tsi_result result;
+  if (self == NULL || protector == NULL) return TSI_INVALID_ARGUMENT;
+  if (self->frame_protector_created) return TSI_FAILED_PRECONDITION;
+  if (tsi_handshaker_get_result(self) != TSI_OK) {
+    return TSI_FAILED_PRECONDITION;
+  }
+  result = self->vtable->create_frame_protector(self, max_protected_frame_size,
+                                                protector);
+  if (result == TSI_OK) {
+    self->frame_protector_created = 1;
+  }
+  return result;
+}
+
+void tsi_handshaker_destroy(tsi_handshaker* self) {
+  if (self == NULL) return;
+  self->vtable->destroy(self);
+}
+
+
+/* --- tsi_peer implementation. --- */
+
+const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* self,
+                                                       const char* name) {
+  uint32_t i;
+  if (self == NULL) return NULL;
+  for (i = 0; i < self->property_count; i++) {
+    const tsi_peer_property* property = &self->properties[i];
+    if (name == NULL && property->name == NULL) {
+      return property;
+    }
+    if (name != NULL && property->name != NULL &&
+        !strcmp(property->name, name)) {
+      return property;
+    }
+  }
+  return NULL;
+}
+
+tsi_peer_property tsi_init_peer_property(void) {
+  tsi_peer_property property;
+  memset(&property, 0, sizeof(tsi_peer_property));
+  return property;
+}
+
+
+static void tsi_peer_destroy_list_property(tsi_peer_property* children,
+                                           uint32_t child_count) {
+  uint32_t i;
+  for (i = 0; i < child_count; i++) {
+    tsi_peer_property_destruct(&children[i]);
+  }
+  free(children);
+}
+
+void tsi_peer_property_destruct(tsi_peer_property* property) {
+  if (property->name != NULL) {
+    free(property->name);
+  }
+  switch (property->type) {
+    case TSI_PEER_PROPERTY_TYPE_STRING:
+      if (property->value.string.data != NULL) {
+        free(property->value.string.data);
+      }
+      break;
+    case TSI_PEER_PROPERTY_TYPE_LIST:
+      tsi_peer_destroy_list_property(property->value.list.children,
+                                     property->value.list.child_count);
+    default:
+      /* Nothing to free. */
+      break;
+  }
+  *property = tsi_init_peer_property();  /* Reset everything to 0. */
+}
+
+void tsi_peer_destruct(tsi_peer* self) {
+  if (self == NULL) return;
+  if (self->properties != NULL) {
+    tsi_peer_destroy_list_property(self->properties, self->property_count);
+    self->properties = NULL;
+  }
+  self->property_count = 0;
+}
+
+tsi_result tsi_construct_signed_integer_peer_property(
+    const char* name, int64_t value, tsi_peer_property* property) {
+  *property = tsi_init_peer_property();
+  property->type = TSI_PEER_PROPERTY_TYPE_SIGNED_INTEGER;
+  if (name != NULL) {
+    property->name = tsi_strdup(name);
+    if (property->name == NULL) return TSI_OUT_OF_RESOURCES;
+  }
+  property->value.signed_int = value;
+  return TSI_OK;
+}
+
+tsi_result tsi_construct_unsigned_integer_peer_property(
+    const char* name, uint64_t value, tsi_peer_property* property) {
+  *property = tsi_init_peer_property();
+  property->type = TSI_PEER_PROPERTY_TYPE_UNSIGNED_INTEGER;
+  if (name != NULL) {
+    property->name = tsi_strdup(name);
+    if (property->name == NULL) return TSI_OUT_OF_RESOURCES;
+  }
+  property->value.unsigned_int = value;
+  return TSI_OK;
+}
+
+tsi_result tsi_construct_real_peer_property(const char* name, double value,
+                                            tsi_peer_property* property) {
+  *property = tsi_init_peer_property();
+  property->type = TSI_PEER_PROPERTY_TYPE_REAL;
+  if (name != NULL) {
+    property->name = tsi_strdup(name);
+    if (property->name == NULL) return TSI_OUT_OF_RESOURCES;
+  }
+  property->value.real = value;
+  return TSI_OK;
+}
+
+tsi_result tsi_construct_allocated_string_peer_property(
+    const char* name, uint32_t value_length, tsi_peer_property* property) {
+  *property = tsi_init_peer_property();
+  property->type = TSI_PEER_PROPERTY_TYPE_STRING;
+  if (name != NULL) {
+    property->name = tsi_strdup(name);
+    if (property->name == NULL) return TSI_OUT_OF_RESOURCES;
+  }
+  if (value_length > 0) {
+    property->value.string.data = calloc(1, value_length);
+    if (property->value.string.data == NULL) {
+      tsi_peer_property_destruct(property);
+      return TSI_OUT_OF_RESOURCES;
+    }
+    property->value.string.length = value_length;
+  }
+  return TSI_OK;
+}
+
+tsi_result tsi_construct_string_peer_property_from_cstring(
+    const char* name, const char* value, tsi_peer_property* property) {
+  return tsi_construct_string_peer_property(name, value, strlen(value),
+                                            property);
+}
+
+tsi_result tsi_construct_string_peer_property(const char* name,
+                                              const char* value,
+                                              uint32_t value_length,
+                                              tsi_peer_property* property) {
+  tsi_result result = tsi_construct_allocated_string_peer_property(
+      name, value_length, property);
+  if (result != TSI_OK) return result;
+  if (value_length > 0) {
+    memcpy(property->value.string.data, value, value_length);
+  }
+  return TSI_OK;
+}
+
+tsi_result tsi_construct_list_peer_property(const char* name,
+                                            uint32_t child_count,
+                                            tsi_peer_property* property) {
+  *property = tsi_init_peer_property();
+  property->type = TSI_PEER_PROPERTY_TYPE_LIST;
+  if (name != NULL) {
+    property->name = tsi_strdup(name);
+    if (property->name == NULL) return TSI_OUT_OF_RESOURCES;
+  }
+  if (child_count > 0) {
+    property->value.list.children =
+        calloc(child_count, sizeof(tsi_peer_property));
+    if (property->value.list.children == NULL) {
+      tsi_peer_property_destruct(property);
+      return TSI_OUT_OF_RESOURCES;
+    }
+    property->value.list.child_count = child_count;
+  }
+  return TSI_OK;
+}
+
+tsi_result tsi_construct_peer(uint32_t property_count, tsi_peer* peer) {
+  memset(peer, 0, sizeof(tsi_peer));
+  if (property_count > 0) {
+    peer->properties = calloc(property_count, sizeof(tsi_peer_property));
+    if (peer->properties == NULL) return TSI_OUT_OF_RESOURCES;
+    peer->property_count = property_count;
+  }
+  return TSI_OK;
+}
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
new file mode 100644
index 0000000..cf9a2b0
--- /dev/null
+++ b/src/core/tsi/transport_security.h
@@ -0,0 +1,118 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __TRANSPORT_SECURITY_H_
+#define __TRANSPORT_SECURITY_H_
+
+#include "src/core/tsi/transport_security_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Base for tsi_frame_protector implementations.
+   See transport_security_interface.h for documentation. */
+typedef struct {
+  tsi_result (*protect)(tsi_frame_protector* self,
+                        const unsigned char* unprotected_bytes,
+                        uint32_t* unprotected_bytes_size,
+                        unsigned char* protected_output_frames,
+                        uint32_t* protected_output_frames_size);
+  tsi_result (*protect_flush)(tsi_frame_protector* self,
+                              unsigned char* protected_output_frames,
+                              uint32_t* protected_output_frames_size,
+                              uint32_t* still_pending_size);
+  tsi_result (*unprotect)(tsi_frame_protector* self,
+                          const unsigned char* protected_frames_bytes,
+                          uint32_t* protected_frames_bytes_size,
+                          unsigned char* unprotected_bytes,
+                          uint32_t* unprotected_bytes_size);
+  void (*destroy)(tsi_frame_protector* self);
+} tsi_frame_protector_vtable;
+
+struct tsi_frame_protector {
+  const tsi_frame_protector_vtable* vtable;
+};
+
+/* Base for tsi_handshaker implementations.
+   See transport_security_interface.h for documentation. */
+typedef struct {
+  tsi_result (*get_bytes_to_send_to_peer)(tsi_handshaker* self,
+                                          unsigned char* bytes,
+                                          uint32_t* bytes_size);
+  tsi_result (*process_bytes_from_peer)(tsi_handshaker* self,
+                                        const unsigned char* bytes,
+                                        uint32_t* bytes_size);
+  tsi_result (*get_result)(tsi_handshaker* self);
+  tsi_result (*extract_peer)(tsi_handshaker* self, tsi_peer* peer);
+  tsi_result (*create_frame_protector)(tsi_handshaker* self,
+                                       uint32_t* max_protected_frame_size,
+                                       tsi_frame_protector** protector);
+  void (*destroy)(tsi_handshaker* self);
+} tsi_handshaker_vtable;
+
+struct tsi_handshaker {
+  const tsi_handshaker_vtable* vtable;
+  int frame_protector_created;
+};
+
+/* Peer and property construction/destruction functions. */
+tsi_result tsi_construct_peer(uint32_t property_count, tsi_peer* peer);
+tsi_peer_property tsi_init_peer_property(void);
+void tsi_peer_property_destruct(tsi_peer_property* property);
+tsi_result tsi_construct_signed_integer_peer_property(
+    const char* name, int64_t value, tsi_peer_property* property);
+tsi_result tsi_construct_unsigned_integer_peer_property(
+    const char* name, uint64_t value, tsi_peer_property* property);
+tsi_result tsi_construct_real_peer_property(const char* name, double value,
+                                            tsi_peer_property* property);
+tsi_result tsi_construct_string_peer_property(const char* name,
+                                              const char* value,
+                                              uint32_t value_length,
+                                              tsi_peer_property* property);
+tsi_result tsi_construct_allocated_string_peer_property(
+    const char* name, uint32_t value_length, tsi_peer_property* property);
+tsi_result tsi_construct_string_peer_property_from_cstring(
+    const char* name, const char* value, tsi_peer_property* property);
+tsi_result tsi_construct_list_peer_property(const char* name,
+                                            uint32_t child_count,
+                                            tsi_peer_property* property);
+
+/* Utils. */
+char* tsi_strdup(const char* src);  /* Sadly, no strdup in C89. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __TRANSPORT_SECURITY_H_ */
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
new file mode 100644
index 0000000..6be72c7
--- /dev/null
+++ b/src/core/tsi/transport_security_interface.h
@@ -0,0 +1,389 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __TRANSPORT_SECURITY_INTERFACE_H_
+#define __TRANSPORT_SECURITY_INTERFACE_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --- tsi result ---  */
+
+typedef enum {
+  TSI_OK = 0,
+  TSI_UNKNOWN_ERROR = 1,
+  TSI_INVALID_ARGUMENT = 2,
+  TSI_PERMISSION_DENIED = 3,
+  TSI_INCOMPLETE_DATA = 4,
+  TSI_FAILED_PRECONDITION = 5,
+  TSI_UNIMPLEMENTED = 6,
+  TSI_INTERNAL_ERROR = 7,
+  TSI_DATA_CORRUPTED = 8,
+  TSI_NOT_FOUND = 9,
+  TSI_PROTOCOL_FAILURE = 10,
+  TSI_HANDSHAKE_IN_PROGRESS = 11,
+  TSI_OUT_OF_RESOURCES = 12
+} tsi_result;
+
+const char* tsi_result_to_string(tsi_result result);
+
+
+/* --- tsi_frame_protector object ---
+
+  This object protects and unprotects buffers once the handshake is done.
+  Implementations of this object must be thread compatible.  */
+
+typedef struct tsi_frame_protector tsi_frame_protector;
+
+/* Outputs protected frames.
+   - unprotected_bytes is an input only parameter and points to the data
+     to be protected.
+   - unprotected_bytes_size is an input/output parameter used by the caller to
+     specify how many bytes are available in unprotected_bytes. The output
+     value is the number of bytes consumed during the call.
+   - protected_output_frames points to a buffer allocated by the caller that
+     will be written.
+   - protected_output_frames_size is an input/output parameter used by the
+     caller to specify how many bytes are available in protected_output_frames.
+     As an output, this value indicates the number of bytes written.
+   - This method returns TSI_OK in case of success or a specific error code in
+     case of failure. Note that even if all the input unprotected bytes are
+     consumed, they may not have been processed into the returned protected
+     output frames. The caller should call the protect_flush method
+     to make sure that there are no more protected bytes buffered in the
+     protector.
+
+   A typical way to call this method would be:
+
+   ------------------------------------------------------------------------
+   unsigned char protected_buffer[4096];
+   uint32_t protected_buffer_size = sizeof(protected_buffer);
+   tsi_result result = TSI_OK;
+   while (message_size > 0) {
+     uint32_t protected_buffer_size_to_send = protected_buffer_size;
+     uint32_t processed_message_size = message_size;
+     result = tsi_frame_protector_protect(protector,
+                                          message_bytes,
+                                          &processed_message_size,
+                                          protected_buffer,
+                                          &protected_buffer_size_to_send);
+     if (result != TSI_OK) break;
+     send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send);
+     message_bytes += processed_message_size;
+     message_size -= processed_message_size;
+
+     // Don't forget to flush.
+     if (message_size == 0) {
+       uint32_t still_pending_size;
+       do {
+         protected_buffer_size_to_send = protected_buffer_size;
+         result = tsi_frame_protector_protect_flush(
+             protector, protected_buffer,
+             &protected_buffer_size_to_send, &still_pending_size);
+         if (result != TSI_OK) break;
+         send_bytes_to_peer(protected_buffer, protected_buffer_size_to_send);
+       } while (still_pending_size > 0);
+     }
+   }
+
+   if (result != TSI_OK) HandleError(result);
+   ------------------------------------------------------------------------  */
+tsi_result tsi_frame_protector_protect(
+    tsi_frame_protector* self,
+    const unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size,
+    unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size);
+
+/* Indicates that we need to flush the bytes buffered in the protector and get
+   the resulting frame.
+   - protected_output_frames points to a buffer allocated by the caller that
+     will be written.
+   - protected_output_frames_size is an input/output parameter used by the
+     caller to specify how many bytes are available in protected_output_frames.
+   - still_pending_bytes is an output parameter indicating the number of bytes
+     that still need to be flushed from the protector.*/
+tsi_result tsi_frame_protector_protect_flush(
+    tsi_frame_protector* self,
+    unsigned char* protected_output_frames,
+    uint32_t* protected_output_frames_size,
+    uint32_t* still_pending_size);
+
+/* Outputs unprotected bytes.
+   - protected_frames_bytes is an input only parameter and points to the
+     protected frames to be unprotected.
+   - protected_frames_bytes_size is an input/output only parameter used by the
+     caller to specify how many bytes are available in protected_bytes. The
+     output value is the number of bytes consumed during the call.
+     Implementations will buffer up to a frame of protected data.
+   - unprotected_bytes points to a buffer allocated by the caller that will be
+     written.
+   - unprotected_bytes_size is an input/output parameter used by the caller to
+     specify how many bytes are available in unprotected_bytes. This
+     value is expected to be at most max_protected_frame_size minus overhead
+     which means that max_protected_frame_size is a safe bet. The output value
+     is the number of bytes actually written.
+
+   - This method returns TSI_OK in case of success. Success includes cases where
+     there is not enough data to output a frame in which case
+     unprotected_bytes_size will be set to 0 and cases where the internal buffer
+     needs to be read before new protected data can be processed in which case
+     protected_frames_size will be set to 0.  */
+tsi_result tsi_frame_protector_unprotect(
+    tsi_frame_protector* self,
+    const unsigned char* protected_frames_bytes,
+    uint32_t* protected_frames_bytes_size,
+    unsigned char* unprotected_bytes,
+    uint32_t* unprotected_bytes_size);
+
+/* Destroys the tsi_frame_protector object.  */
+void tsi_frame_protector_destroy(tsi_frame_protector* self);
+
+
+/* --- tsi_peer objects ---
+
+   tsi_peer objects are a set of properties. The peer owns the properties.  */
+
+/* This property is of type TSI_PEER_PROPERTY_STRING.  */
+#define TSI_CERTIFICATE_TYPE_PEER_PROPERTY "certificate_type"
+
+/* This property is of type TSI_PEER_PROPERTY_STRING.  */
+#define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name"
+
+/* This property is of type TSI_PEER_PROPERTY_LIST and the children contain
+   unnamed (name == NULL) properties of type TSI_PEER_PROPERTY_STRING.  */
+#define TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY \
+  "x509_subject_alternative_names"
+
+/* This property is of type TSI_PEER_PROPERTY_STRING. */
+#define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
+
+/* This property is of type TSI_PEER_PROPERTY_STRING.  */
+#define TSI_MDB_USER_NAME_PEER_PROPERTY "mdb_user_name"
+
+/* This property is of type TSI_PEER_PROPERTY_SIGNED_INTEGER.  */
+#define TSI_MDB_GAIA_ID_PEER_PROPERTY "mdb_gaia_id"
+
+/* Properties of type TSI_PEER_PROPERTY_TYPE_STRING may contain NULL characters
+   just like C++ strings. The length field gives the length of the string.  */
+typedef enum {
+  TSI_PEER_PROPERTY_TYPE_SIGNED_INTEGER,
+  TSI_PEER_PROPERTY_TYPE_UNSIGNED_INTEGER,
+  TSI_PEER_PROPERTY_TYPE_REAL,
+  TSI_PEER_PROPERTY_TYPE_STRING,
+  TSI_PEER_PROPERTY_TYPE_LIST
+} tsi_peer_property_type;
+
+/* The relevant field in the union value is dictated by the type field.
+   name may be NULL in case of an unnamed property. */
+typedef struct tsi_peer_property {
+  char* name;
+  tsi_peer_property_type type;
+  union {
+    int64_t signed_int;
+    uint64_t unsigned_int;
+    double real;
+    struct {
+      char* data;
+      uint32_t length;
+    } string;
+    struct {
+      struct tsi_peer_property* children;
+      uint32_t child_count;
+    } list;
+  } value;
+} tsi_peer_property;
+
+typedef struct {
+  tsi_peer_property* properties;
+  uint32_t property_count;
+} tsi_peer;
+
+/* Gets the first property with the specified name. Iteration over the
+   properties of the peer should be used if the client of the API is expecting
+   several properties with the same name.
+   Returns NULL if there is no corresponding property.  */
+const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* self,
+                                                       const char* name);
+
+/* Destructs the tsi_peer object. */
+void tsi_peer_destruct(tsi_peer* self);
+
+/* --- tsi_handshaker objects ----
+
+   Implementations of this object must be thread compatible.
+
+   A typical usage of this object would be:
+
+   ------------------------------------------------------------------------
+   tsi_result result = TSI_OK;
+   unsigned char buf[4096];
+   uint32_t buf_offset;
+   uint32_t buf_size;
+   while (1) {
+     // See if we need to send some bytes to the peer.
+     do {
+       uint32_t buf_size_to_send = sizeof(buf);
+       result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf,
+                                                         &buf_size_to_send);
+       if (buf_size_to_send > 0) send_bytes_to_peer(buf, buf_size_to_send);
+     } while (result == TSI_INCOMPLETE_DATA);
+     if (result != TSI_OK) return result;
+     if (!tsi_handshaker_is_in_progress(handshaker)) break;
+
+     do {
+       // Read bytes from the peer.
+       buf_size = sizeof(buf);
+       buf_offset = 0;
+       read_bytes_from_peer(buf, &buf_size);
+       if (buf_size == 0) break;
+
+       // Process the bytes from the peer. We have to be careful as these bytes
+       // may contain non-handshake data (protected data). If this is the case,
+       // we will exit from the loop with buf_size > 0.
+       uint32_t consumed_by_handshaker = buf_size;
+       result = tsi_handshaker_process_bytes_from_peer(
+           handshaker, buf, &consumed_by_handshaker);
+       buf_size -= consumed_by_handshaker;
+       buf_offset += consumed_by_handshaker;
+     } while (result == TSI_INCOMPLETE_DATA);
+
+     if (result != TSI_OK) return result;
+     if (!tsi_handshaker_is_in_progress(handshaker)) break;
+   }
+
+   // Check the Peer.
+   tsi_peer peer;
+   do {
+     result = tsi_handshaker_extract_peer(handshaker, &peer);
+     if (result != TSI_OK) break;
+     result = check_peer(&peer);
+   } while (0);
+   tsi_peer_destruct(&peer);
+   if (result != TSI_OK) return result;
+
+   // Create the protector.
+   tsi_frame_protector* protector = NULL;
+   result = tsi_handshaker_create_frame_protector(handshaker, NULL,
+                                                  &protector);
+   if (result != TSI_OK) return result;
+
+   // Do not forget to unprotect outstanding data if any.
+   if (buf_size > 0) {
+     result = tsi_frame_protector_unprotect(protector, buf + buf_offset,
+                                            buf_size, ..., ...);
+     ....
+   }
+   ...
+   ------------------------------------------------------------------------   */
+typedef struct tsi_handshaker tsi_handshaker;
+
+/* Gets bytes that need to be sent to the peer.
+   - bytes is the buffer that will be written with the data to be sent to the
+     peer.
+   - bytes_size is an input/output parameter specifying the capacity of the
+     bytes parameter as input and the number of bytes written as output.
+   Returns TSI_OK if all the data to send to the peer has been written or if
+   nothing has to be sent to the peer (in which base bytes_size outputs to 0),
+   otherwise returns TSI_INCOMPLETE_DATA which indicates that this method
+   needs to be called again to get all the bytes to send to the peer (there
+   was more data to write than the specified bytes_size). In case of a fatal
+   error in the handshake, another specific error code is returned.  */
+tsi_result tsi_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
+                                                    unsigned char* bytes,
+                                                    uint32_t* bytes_size);
+
+/* Processes bytes received from the peer.
+   - bytes is the buffer containing the data.
+   - bytes_size is an input/output parameter specifying the size of the data as
+     input and the number of bytes consumed as output.
+   Return TSI_OK if the handshake has all the data it needs to process,
+   otherwise return TSI_INCOMPLETE_DATA which indicates that this method
+   needs to be called again to complete the data needed for processing. In
+   case of a fatal error in the handshake, another specific error code is
+   returned.  */
+tsi_result tsi_handshaker_process_bytes_from_peer(tsi_handshaker* self,
+                                                  const unsigned char* bytes,
+                                                  uint32_t* bytes_size);
+
+/* Gets the result of the handshaker.
+   Returns TSI_OK if the hanshake completed successfully and there has been no
+   errors. Returns TSI_HANDSHAKE_IN_PROGRESS if the handshaker is not done yet
+   but no error has been encountered so far. Otherwise the handshaker failed
+   with the returned error.  */
+tsi_result tsi_handshaker_get_result(tsi_handshaker* self);
+
+/* Returns 1 if the handshake is in progress, 0 otherwise.  */
+#define tsi_handshaker_is_in_progress(h) \
+  (tsi_handshaker_get_result((h)) == TSI_HANDSHAKE_IN_PROGRESS)
+
+
+/* This method may return TSI_FAILED_PRECONDITION if
+   tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise
+   assuming the handshaker is not in a fatal error state.
+   The caller is responsible for destructing the peer.  */
+tsi_result tsi_handshaker_extract_peer(tsi_handshaker* self, tsi_peer* peer);
+
+/* This method creates a tsi_frame_protector object after the handshake phase
+   is done. After this method has been called successfully, the only method
+   that can be called on this object is Destroy.
+   - max_output_protected_frame_size is an input/output parameter specifying the
+     desired max output protected frame size as input and outputing the actual
+     max output frame size as the output. Passing NULL is OK and will result in
+     the implementation choosing the default maximum protected frame size. Note
+     that this size only applies to outgoing frames (generated with
+     tsi_frame_protector_protect) and not incoming frames (input of
+     tsi_frame_protector_unprotect).
+   - protector is an output parameter pointing to the newly created
+     tsi_frame_protector object.
+   This method may return TSI_FAILED_PRECONDITION if
+   tsi_handshaker_is_in_progress returns 1, it returns TSI_OK otherwise assuming
+   the handshaker is not in a fatal error state.
+   The caller is responsible for destroying the protector.  */
+tsi_result tsi_handshaker_create_frame_protector(
+    tsi_handshaker* self,
+    uint32_t* max_output_protected_frame_size,
+    tsi_frame_protector** protector);
+
+/* This method releases the tsi_handshaker object. After this method is called,
+   no other method can be called on the object.  */
+void tsi_handshaker_destroy(tsi_handshaker* self);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __TRANSPORT_SECURITY_INTERFACE_H_ */
diff --git a/src/core/tsi/transport_security_test_lib.cc b/src/core/tsi/transport_security_test_lib.cc
new file mode 100644
index 0000000..1b630c9
--- /dev/null
+++ b/src/core/tsi/transport_security_test_lib.cc
@@ -0,0 +1,363 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/tsi/transport_security_test_lib.h"
+
+#include <memory>
+
+#include "base/commandlineflags.h"
+#include "src/core/tsi/transport_security_interface.h"
+#include "strings/escaping.h"
+#include "strings/strcat.h"
+#include <gtest/gtest.h>
+#include "util/random/mt_random.h"
+
+namespace {
+
+const char kPingRequest[] = "Ping";
+const char kPongResponse[] = "Pong";
+const int kBigMessageSize = 17000;
+
+}  // namespace
+
+namespace tsi {
+namespace test {
+
+TransportSecurityTest::TransportSecurityTest() : random_(new MTRandom()) {
+  small_message_ = "Chapi Chapo";
+  big_message_ = RandomString(kBigMessageSize);
+}
+
+string TransportSecurityTest::RandomString(int size) {
+  std::unique_ptr<char[]> buffer(new char[size]);
+  for (int i = 0; i < size; i++) {
+    buffer[i] = random_->Rand8();
+  }
+  return string(buffer.get(), size);
+}
+
+void TransportSecurityTest::SendBytesToPeer(bool is_client, unsigned char* buf,
+                                            unsigned int buf_size) {
+  string& channel = is_client ? to_server_channel_ : to_client_channel_;
+  LOG(INFO) << (is_client ? "Client:" : "Server") << " sending " << buf_size
+            << " bytes to peer.";
+  channel.append(reinterpret_cast<const char*>(buf), buf_size);
+}
+
+void TransportSecurityTest::ReadBytesFromPeer(bool is_client,
+                                              unsigned char* buf,
+                                              unsigned int* buf_size) {
+  string& channel = is_client ? to_client_channel_ : to_server_channel_;
+  unsigned int to_read =
+      *buf_size < channel.size() ? *buf_size : channel.size();
+  memcpy(buf, channel.data(), to_read);
+  *buf_size = to_read;
+  channel.erase(0, to_read);
+  LOG(INFO) << (is_client ? "Client:" : "Server") << " read " << to_read
+            << " bytes from peer.";
+}
+
+void TransportSecurityTest::DoHandshakeStep(bool is_client,
+                                            unsigned int buf_allocated_size,
+                                            tsi_handshaker* handshaker,
+                                            string* remaining_bytes) {
+  tsi_result result = TSI_OK;
+  std::unique_ptr<unsigned char[]> buf(new unsigned char[buf_allocated_size]);
+  unsigned int buf_offset;
+  unsigned int buf_size;
+  // See if we need to send some bytes to the peer.
+  do {
+    unsigned int buf_size_to_send = buf_allocated_size;
+    result = tsi_handshaker_get_bytes_to_send_to_peer(handshaker, buf.get(),
+                                                      &buf_size_to_send);
+    if (buf_size_to_send > 0) {
+      SendBytesToPeer(is_client, buf.get(), buf_size_to_send);
+    }
+  } while (result == TSI_INCOMPLETE_DATA);
+  if (!tsi_handshaker_is_in_progress(handshaker)) return;
+
+  do {
+    //  Read bytes from the peer.
+    buf_size = buf_allocated_size;
+    buf_offset = 0;
+    ReadBytesFromPeer(is_client, buf.get(), &buf_size);
+    if (buf_size == 0) break;
+
+    // Process the bytes from the peer. We have to be careful as these bytes
+    // may contain non-handshake data (protected data). If this is the case,
+    // we will exit from the loop with buf_size > 0.
+    unsigned int consumed_by_handshaker = buf_size;
+    result = tsi_handshaker_process_bytes_from_peer(handshaker, buf.get(),
+                                                    &consumed_by_handshaker);
+    buf_size -= consumed_by_handshaker;
+    buf_offset += consumed_by_handshaker;
+  } while (result == TSI_INCOMPLETE_DATA);
+
+  if (!tsi_handshaker_is_in_progress(handshaker)) {
+    remaining_bytes->assign(
+        reinterpret_cast<const char*>(buf.get()) + buf_offset, buf_size);
+  }
+}
+
+void TransportSecurityTest::PerformHandshake() {
+  SetupHandshakers();
+  string remaining_bytes;
+  do {
+    DoHandshakeStep(true, config()->handshake_buffer_size,
+                    client_handshaker_.get(), &remaining_bytes);
+    EXPECT_EQ(0, remaining_bytes.size());
+    DoHandshakeStep(false, config()->handshake_buffer_size,
+                    server_handshaker_.get(), &remaining_bytes);
+    EXPECT_EQ(0, remaining_bytes.size());
+  } while (tsi_handshaker_is_in_progress(client_handshaker_.get()) ||
+           tsi_handshaker_is_in_progress(server_handshaker_.get()));
+  CheckHandshakeResults();
+}
+
+void TransportSecurityTest::SendMessageToPeer(
+    bool is_client, tsi_frame_protector* protector, const string& message,
+    unsigned int protected_buffer_size) {
+  std::unique_ptr<unsigned char[]> protected_buffer(
+      new unsigned char[protected_buffer_size]);
+  unsigned int message_size = message.size();
+  const unsigned char* message_bytes =
+      reinterpret_cast<const unsigned char*>(message.data());
+  tsi_result result = TSI_OK;
+  while (message_size > 0 && result == TSI_OK) {
+    unsigned int protected_buffer_size_to_send = protected_buffer_size;
+    unsigned int processed_message_size = message_size;
+    result = tsi_frame_protector_protect(
+        protector, message_bytes, &processed_message_size,
+        protected_buffer.get(), &protected_buffer_size_to_send);
+    EXPECT_EQ(TSI_OK, result);
+    SendBytesToPeer(is_client, protected_buffer.get(),
+                    protected_buffer_size_to_send);
+    message_bytes += processed_message_size;
+    message_size -= processed_message_size;
+
+    // Flush if we're done.
+    if (message_size == 0) {
+      unsigned int still_pending_size;
+      do {
+        protected_buffer_size_to_send = protected_buffer_size;
+        result = tsi_frame_protector_protect_flush(
+            protector, protected_buffer.get(), &protected_buffer_size_to_send,
+            &still_pending_size);
+        EXPECT_EQ(TSI_OK, result);
+        SendBytesToPeer(is_client, protected_buffer.get(),
+                        protected_buffer_size_to_send);
+      } while (still_pending_size > 0 && result == TSI_OK);
+      EXPECT_EQ(TSI_OK, result);
+    }
+  }
+  EXPECT_EQ(TSI_OK, result);
+}
+
+void TransportSecurityTest::ReceiveMessageFromPeer(
+    bool is_client, tsi_frame_protector* protector,
+    unsigned int read_buf_allocated_size,
+    unsigned int message_buf_allocated_size, string* message) {
+  std::unique_ptr<unsigned char[]> read_buffer(
+      new unsigned char[read_buf_allocated_size]);
+  unsigned int read_offset = 0;
+  unsigned int read_from_peer_size = 0;
+  std::unique_ptr<unsigned char[]> message_buffer(
+      new unsigned char[message_buf_allocated_size]);
+  tsi_result result = TSI_OK;
+  bool done = false;
+  while (!done && result == TSI_OK) {
+    if (read_from_peer_size == 0) {
+      read_from_peer_size = read_buf_allocated_size;
+      ReadBytesFromPeer(is_client, read_buffer.get(), &read_from_peer_size);
+      read_offset = 0;
+    }
+    if (read_from_peer_size == 0) done = true;
+    unsigned int message_buffer_size;
+    do {
+      message_buffer_size = message_buf_allocated_size;
+      unsigned int processed_size = read_from_peer_size;
+      result = tsi_frame_protector_unprotect(
+          protector, read_buffer.get() + read_offset, &processed_size,
+          message_buffer.get(), &message_buffer_size);
+      EXPECT_EQ(TSI_OK, result);
+      if (message_buffer_size > 0) {
+        LOG(INFO) << "Wrote " << message_buffer_size << " bytes to message.";
+        message->append(reinterpret_cast<const char*>(message_buffer.get()),
+                        message_buffer_size);
+      }
+      read_offset += processed_size;
+      read_from_peer_size -= processed_size;
+    } while ((read_from_peer_size > 0 || message_buffer_size > 0) &&
+             result == TSI_OK);
+    EXPECT_EQ(TSI_OK, result);
+  }
+  EXPECT_EQ(TSI_OK, result);
+}
+
+void TransportSecurityTest::DoRoundTrip(const string& request,
+                                        const string& response) {
+  PerformHandshake();
+
+  tsi_frame_protector* client_frame_protector;
+  tsi_frame_protector* server_frame_protector;
+  unsigned int client_max_output_protected_frame_size =
+      config()->client_max_output_protected_frame_size();
+  EXPECT_EQ(TSI_OK,
+            tsi_handshaker_create_frame_protector(
+                client_handshaker_.get(),
+                config()->use_client_default_max_output_protected_frame_size()
+                    ? nullptr
+                    : &client_max_output_protected_frame_size,
+                &client_frame_protector));
+
+  unsigned int server_max_output_protected_frame_size =
+      config()->server_max_output_protected_frame_size();
+  EXPECT_EQ(TSI_OK,
+            tsi_handshaker_create_frame_protector(
+                server_handshaker_.get(),
+                config()->use_server_default_max_output_protected_frame_size()
+                    ? nullptr
+                    : &server_max_output_protected_frame_size,
+                &server_frame_protector));
+
+  SendMessageToPeer(true, client_frame_protector, request,
+                    config()->protected_buffer_size);
+  string retrieved_request;
+  ReceiveMessageFromPeer(
+      false, server_frame_protector, config()->read_buffer_allocated_size,
+      config()->message_buffer_allocated_size, &retrieved_request);
+  EXPECT_EQ(request.size(), retrieved_request.size());
+  EXPECT_EQ(strings::b2a_hex(request), strings::b2a_hex(retrieved_request));
+
+  SendMessageToPeer(false, server_frame_protector, response,
+                    config()->protected_buffer_size);
+  string retrieved_response;
+  ReceiveMessageFromPeer(
+      true, client_frame_protector, config()->read_buffer_allocated_size,
+      config()->message_buffer_allocated_size, &retrieved_response);
+  EXPECT_EQ(response.size(), retrieved_response.size());
+  EXPECT_EQ(strings::b2a_hex(response), strings::b2a_hex(retrieved_response));
+
+  tsi_frame_protector_destroy(client_frame_protector);
+  tsi_frame_protector_destroy(server_frame_protector);
+}
+
+void TransportSecurityTest::DoRoundTrip() {
+  DoRoundTrip(config()->client_message, config()->server_message);
+}
+void TransportSecurityTest::PingPong() {
+  PerformHandshake();
+
+  unsigned char to_server[4096];
+  unsigned char to_client[4096];
+  unsigned int max_frame_size = sizeof(to_client);
+  tsi_frame_protector* client_frame_protector;
+  tsi_frame_protector* server_frame_protector;
+  EXPECT_EQ(
+      tsi_handshaker_create_frame_protector(
+          client_handshaker_.get(), &max_frame_size, &client_frame_protector),
+      TSI_OK);
+  EXPECT_EQ(max_frame_size, sizeof(to_client));
+  EXPECT_EQ(
+      tsi_handshaker_create_frame_protector(
+          server_handshaker_.get(), &max_frame_size, &server_frame_protector),
+      TSI_OK);
+  EXPECT_EQ(max_frame_size, sizeof(to_client));
+
+  // Send Ping.
+  unsigned int ping_length = strlen(kPingRequest);
+  unsigned int protected_size = sizeof(to_server);
+  EXPECT_EQ(tsi_frame_protector_protect(
+                client_frame_protector,
+                reinterpret_cast<const unsigned char*>(kPingRequest),
+                &ping_length, to_server, &protected_size),
+            TSI_OK);
+  EXPECT_EQ(ping_length, strlen(kPingRequest));
+  EXPECT_EQ(protected_size, 0);
+  protected_size = sizeof(to_server);
+  unsigned int still_pending_size;
+  EXPECT_EQ(
+      tsi_frame_protector_protect_flush(client_frame_protector, to_server,
+                                        &protected_size, &still_pending_size),
+      TSI_OK);
+  EXPECT_EQ(still_pending_size, 0);
+  EXPECT_GT(protected_size, strlen(kPingRequest));
+
+  // Receive Ping.
+  unsigned int unprotected_size = sizeof(to_server);
+  unsigned int saved_protected_size = protected_size;
+  EXPECT_EQ(tsi_frame_protector_unprotect(server_frame_protector, to_server,
+                                          &protected_size, to_server,
+                                          &unprotected_size),
+            TSI_OK);
+  EXPECT_EQ(saved_protected_size, protected_size);
+  EXPECT_EQ(ping_length, unprotected_size);
+  EXPECT_EQ(string(kPingRequest),
+            string(reinterpret_cast<const char*>(to_server), unprotected_size));
+
+  // Send back Pong.
+  unsigned int pong_length = strlen(kPongResponse);
+  protected_size = sizeof(to_client);
+  EXPECT_EQ(tsi_frame_protector_protect(
+                server_frame_protector,
+                reinterpret_cast<const unsigned char*>(kPongResponse),
+                &pong_length, to_client, &protected_size),
+            TSI_OK);
+  EXPECT_EQ(pong_length, strlen(kPongResponse));
+  EXPECT_EQ(protected_size, 0);
+  protected_size = sizeof(to_client);
+  EXPECT_EQ(
+      tsi_frame_protector_protect_flush(server_frame_protector, to_client,
+                                        &protected_size, &still_pending_size),
+      TSI_OK);
+  EXPECT_EQ(still_pending_size, 0);
+  EXPECT_GT(protected_size, strlen(kPongResponse));
+
+  // Receive Pong.
+  unprotected_size = sizeof(to_server);
+  saved_protected_size = protected_size;
+  EXPECT_EQ(tsi_frame_protector_unprotect(client_frame_protector, to_client,
+                                          &protected_size, to_client,
+                                          &unprotected_size),
+            TSI_OK);
+  EXPECT_EQ(saved_protected_size, protected_size);
+  EXPECT_EQ(pong_length, unprotected_size);
+  EXPECT_EQ(string(kPongResponse),
+            string(reinterpret_cast<const char*>(to_client), unprotected_size));
+
+  tsi_frame_protector_destroy(client_frame_protector);
+  tsi_frame_protector_destroy(server_frame_protector);
+}
+
+}  // namespace test
+}  // namespace tsi
diff --git a/src/core/tsi/transport_security_test_lib.h b/src/core/tsi/transport_security_test_lib.h
new file mode 100644
index 0000000..8c9c764
--- /dev/null
+++ b/src/core/tsi/transport_security_test_lib.h
@@ -0,0 +1,154 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __TRANSPORT_SECURITY_TEST_LIB_H_
+#define __TRANSPORT_SECURITY_TEST_LIB_H_
+
+#include <memory>
+
+#include "base/commandlineflags.h"
+#include "src/core/tsi/transport_security_interface.h"
+#include "strings/strcat.h"
+#include <gtest/gtest.h>
+#include "util/random/mt_random.h"
+
+namespace tsi {
+namespace test {
+
+class TestConfig {
+ public:
+  TestConfig()
+      : client_message("Chapi Chapo"),
+        server_message("Chapi Chapo"),
+        handshake_buffer_size(4096),
+        read_buffer_allocated_size(4096),
+        message_buffer_allocated_size(4096),
+        protected_buffer_size(16384),
+        use_client_default_max_output_protected_frame_size_(true),
+        use_server_default_max_output_protected_frame_size_(true),
+        client_max_output_protected_frame_size_(0),
+        server_max_output_protected_frame_size_(0) {}
+
+  void set_client_max_output_protected_frame_size(unsigned int size) {
+    use_client_default_max_output_protected_frame_size_ = false;
+    client_max_output_protected_frame_size_ = size;
+  }
+  void set_server_max_output_protected_frame_size(unsigned int size) {
+    use_server_default_max_output_protected_frame_size_ = false;
+    server_max_output_protected_frame_size_ = size;
+  }
+  bool use_client_default_max_output_protected_frame_size() const {
+    return use_client_default_max_output_protected_frame_size_;
+  }
+  bool use_server_default_max_output_protected_frame_size() const {
+    return use_server_default_max_output_protected_frame_size_;
+  }
+  unsigned int client_max_output_protected_frame_size() const {
+    return client_max_output_protected_frame_size_;
+  }
+  unsigned int server_max_output_protected_frame_size() const {
+    return server_max_output_protected_frame_size_;
+  }
+
+  string client_message;
+  string server_message;
+  unsigned int handshake_buffer_size;
+  unsigned int read_buffer_allocated_size;
+  unsigned int message_buffer_allocated_size;
+  unsigned int protected_buffer_size;
+
+ private:
+  bool use_client_default_max_output_protected_frame_size_;
+  bool use_server_default_max_output_protected_frame_size_;
+  unsigned int client_max_output_protected_frame_size_;
+  unsigned int server_max_output_protected_frame_size_;
+};
+
+
+struct TsiHandshakerDeleter {
+  inline void operator()(tsi_handshaker* ptr) { tsi_handshaker_destroy(ptr); }
+};
+typedef std::unique_ptr<tsi_handshaker, TsiHandshakerDeleter>
+    TsiHandshakerUniquePtr;
+
+class TransportSecurityTest : public ::testing::Test {
+ protected:
+  TransportSecurityTest();
+  virtual ~TransportSecurityTest() {}
+  virtual const TestConfig* config() = 0;
+  string RandomString(int size);
+  virtual void SetupHandshakers() = 0;
+  // An implementation-specific verification of the validity of the handshake.
+  virtual void CheckHandshakeResults() = 0;
+  // Do a full handshake.
+  void PerformHandshake();
+  // Send a protected message between the client and server.
+  void SendMessageToPeer(bool is_client, tsi_frame_protector* protector,
+                         const string& message,
+                         unsigned int protected_buffer_size);
+  void ReceiveMessageFromPeer(bool is_client, tsi_frame_protector* protector,
+                              unsigned int read_buf_allocated_size,
+                              unsigned int message_buf_allocated_size,
+                              string* message);
+
+  // A simple test that does a handshake and sends a message back and forth
+  void PingPong();
+  // A complicated test that can be configured by modifying config().
+  void DoRoundTrip();
+
+  TsiHandshakerUniquePtr client_handshaker_;
+  TsiHandshakerUniquePtr server_handshaker_;
+
+  string small_message_;
+  string big_message_;
+  std::unique_ptr<RandomBase> random_;
+
+ private:
+  // Functions to send raw bytes between the client and server.
+  void SendBytesToPeer(bool is_client, unsigned char* buf,
+                       unsigned int buf_size);
+  void ReadBytesFromPeer(bool is_client, unsigned char* buf,
+                         unsigned int* buf_size);
+  // Do a single step of the handshake.
+  void DoHandshakeStep(bool is_client, unsigned int buf_allocated_size,
+                       tsi_handshaker* handshaker, string* remaining_bytes);
+  void DoRoundTrip(const string& request, const string& response);
+
+  string to_server_channel_;
+  string to_client_channel_;
+};
+
+}  // namespace test
+}  // namespace tsi
+
+#endif  // __TRANSPORT_SECURITY_TEST_LIB_H_
diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc
new file mode 100644
index 0000000..7a75291
--- /dev/null
+++ b/src/cpp/client/channel.cc
@@ -0,0 +1,212 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/client/channel.h"
+
+#include <chrono>
+#include <string>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/time.h>
+
+#include "src/cpp/rpc_method.h"
+#include "src/cpp/proto/proto_utils.h"
+#include "src/cpp/stream/stream_context.h"
+#include "src/cpp/util/time.h"
+#include <grpc++/config.h>
+#include <google/protobuf/message.h>
+#include <grpc++/client_context.h>
+#include <grpc++/status.h>
+
+namespace grpc {
+
+Channel::Channel(const grpc::string& target) : target_(target) {
+  c_channel_ = grpc_channel_create(target_.c_str(), nullptr);
+}
+
+Channel::~Channel() { grpc_channel_destroy(c_channel_); }
+
+namespace {
+// Poll one event from the compeletion queue. Return false when an error
+// occured or the polled type is not expected. If a finished event has been
+// polled, set finished and set status if it has not been set.
+bool NextEvent(grpc_completion_queue* cq, grpc_completion_type expected_type,
+               bool* finished, bool* status_set, Status* status,
+               google::protobuf::Message* result) {
+  // We rely on the c layer to enforce deadline and thus do not use deadline
+  // here.
+  grpc_event* ev = grpc_completion_queue_next(cq, gpr_inf_future);
+  if (!ev) {
+    return false;
+  }
+  bool ret = ev->type == expected_type;
+  switch (ev->type) {
+    case GRPC_INVOKE_ACCEPTED:
+      ret = ret && (ev->data.invoke_accepted == GRPC_OP_OK);
+      break;
+    case GRPC_READ:
+      ret = ret && (ev->data.read != nullptr);
+      if (ret && !DeserializeProto(ev->data.read, result)) {
+        *status_set = true;
+        *status =
+            Status(StatusCode::DATA_LOSS, "Failed to parse response proto.");
+        ret = false;
+      }
+      break;
+    case GRPC_WRITE_ACCEPTED:
+      ret = ret && (ev->data.write_accepted == GRPC_OP_OK);
+      break;
+    case GRPC_FINISH_ACCEPTED:
+      ret = ret && (ev->data.finish_accepted == GRPC_OP_OK);
+      break;
+    case GRPC_CLIENT_METADATA_READ:
+      break;
+    case GRPC_FINISHED:
+      *finished = true;
+      if (!*status_set) {
+        *status_set = true;
+        StatusCode error_code = static_cast<StatusCode>(ev->data.finished.code);
+        grpc::string details(
+            ev->data.finished.details ? ev->data.finished.details : "");
+        *status = Status(error_code, details);
+      }
+      break;
+    default:
+      gpr_log(GPR_ERROR, "Dropping unhandled event with type %d", ev->type);
+      break;
+  }
+  grpc_event_finish(ev);
+  return ret;
+}
+
+// If finished is not true, get final status by polling until a finished
+// event is obtained.
+void GetFinalStatus(grpc_completion_queue* cq, bool status_set, bool finished,
+                    Status* status) {
+  while (!finished) {
+    NextEvent(cq, GRPC_FINISHED, &finished, &status_set, status, nullptr);
+  }
+}
+
+}  // namespace
+
+// TODO(yangg) more error handling
+Status Channel::StartBlockingRpc(const RpcMethod& method,
+                                 ClientContext* context,
+                                 const google::protobuf::Message& request,
+                                 google::protobuf::Message* result) {
+  Status status;
+  bool status_set = false;
+  bool finished = false;
+  gpr_timespec absolute_deadline;
+  AbsoluteDeadlineTimepoint2Timespec(context->absolute_deadline(),
+                                     &absolute_deadline);
+  grpc_call* call = grpc_channel_create_call(c_channel_, method.name(),
+                                             // FIXME(yangg)
+                                             "localhost", absolute_deadline);
+  context->set_call(call);
+  grpc_completion_queue* cq = grpc_completion_queue_create();
+  context->set_cq(cq);
+  // add_metadata from context
+  //
+  // invoke
+  GPR_ASSERT(grpc_call_start_invoke(call, cq, call, call, call,
+                                    GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK);
+  if (!NextEvent(cq, GRPC_INVOKE_ACCEPTED, &status_set, &finished, &status,
+                 nullptr)) {
+    GetFinalStatus(cq, finished, status_set, &status);
+    return status;
+  }
+  // write request
+  grpc_byte_buffer* write_buffer = nullptr;
+  bool success = SerializeProto(request, &write_buffer);
+  if (!success) {
+    grpc_call_cancel(call);
+    status_set = true;
+    status =
+        Status(StatusCode::DATA_LOSS, "Failed to serialize request proto.");
+    GetFinalStatus(cq, finished, status_set, &status);
+    return status;
+  }
+  GPR_ASSERT(grpc_call_start_write(call, write_buffer, call,
+                                   GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK);
+  grpc_byte_buffer_destroy(write_buffer);
+  if (!NextEvent(cq, GRPC_WRITE_ACCEPTED, &finished, &status_set, &status,
+                 nullptr)) {
+    GetFinalStatus(cq, finished, status_set, &status);
+    return status;
+  }
+  // writes done
+  GPR_ASSERT(grpc_call_writes_done(call, call) == GRPC_CALL_OK);
+  if (!NextEvent(cq, GRPC_FINISH_ACCEPTED, &finished, &status_set, &status,
+                 nullptr)) {
+    GetFinalStatus(cq, finished, status_set, &status);
+    return status;
+  }
+  // start read metadata
+  //
+  if (!NextEvent(cq, GRPC_CLIENT_METADATA_READ, &finished, &status_set, &status,
+                 nullptr)) {
+    GetFinalStatus(cq, finished, status_set, &status);
+    return status;
+  }
+  // start read
+  GPR_ASSERT(grpc_call_start_read(call, call) == GRPC_CALL_OK);
+  if (!NextEvent(cq, GRPC_READ, &finished, &status_set, &status, result)) {
+    GetFinalStatus(cq, finished, status_set, &status);
+    return status;
+  }
+  // wait status
+  GetFinalStatus(cq, finished, status_set, &status);
+  return status;
+}
+
+StreamContextInterface* Channel::CreateStream(const RpcMethod& method,
+                                              ClientContext* context,
+                                              const google::protobuf::Message* request,
+                                              google::protobuf::Message* result) {
+  gpr_timespec absolute_deadline;
+  AbsoluteDeadlineTimepoint2Timespec(context->absolute_deadline(),
+                                     &absolute_deadline);
+  grpc_call* call = grpc_channel_create_call(c_channel_, method.name(),
+                                             // FIXME(yangg)
+                                             "localhost", absolute_deadline);
+  context->set_call(call);
+  grpc_completion_queue* cq = grpc_completion_queue_create();
+  context->set_cq(cq);
+  return new StreamContext(method, context, request, result);
+}
+
+}  // namespace grpc
diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h
new file mode 100644
index 0000000..a97d35e
--- /dev/null
+++ b/src/cpp/client/channel.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_CLIENT_CHANNEL_H__
+#define __GRPCPP_INTERNAL_CLIENT_CHANNEL_H__
+
+#include <grpc++/channel_interface.h>
+#include <grpc++/config.h>
+
+struct grpc_channel;
+
+namespace grpc {
+class StreamContextInterface;
+
+class Channel : public ChannelInterface {
+ public:
+  explicit Channel(const grpc::string& target);
+  ~Channel() override;
+
+  Status StartBlockingRpc(const RpcMethod& method, ClientContext* context,
+                          const google::protobuf::Message& request,
+                          google::protobuf::Message* result) override;
+
+  StreamContextInterface* CreateStream(const RpcMethod& method,
+                                       ClientContext* context,
+                                       const google::protobuf::Message* request,
+                                       google::protobuf::Message* result) override;
+
+ protected:
+  // TODO(yangg) remove this section when we have the general ssl channel API
+  Channel() {}
+  void set_c_channel(grpc_channel* channel) { c_channel_ = channel; }
+
+ private:
+  const grpc::string target_;
+  grpc_channel* c_channel_;  // owned
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_CLIENT_CHANNEL_H__
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
new file mode 100644
index 0000000..78774a7
--- /dev/null
+++ b/src/cpp/client/client_context.cc
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/client_context.h>
+
+#include <grpc/grpc.h>
+
+using std::chrono::system_clock;
+
+namespace grpc {
+
+ClientContext::ClientContext()
+    : call_(nullptr),
+      cq_(nullptr),
+      absolute_deadline_(system_clock::time_point::max()) {}
+
+ClientContext::~ClientContext() {
+  if (call_) {
+    grpc_call_destroy(call_);
+  }
+  if (cq_) {
+    grpc_completion_queue_shutdown(cq_);
+    grpc_completion_queue_destroy(cq_);
+  }
+}
+
+void ClientContext::set_absolute_deadline(
+    const system_clock::time_point& deadline) {
+  absolute_deadline_ = deadline;
+}
+
+system_clock::time_point ClientContext::absolute_deadline() {
+  return absolute_deadline_;
+}
+
+void ClientContext::AddMetadata(const grpc::string& meta_key,
+                                const grpc::string& meta_value) {
+  return;
+}
+
+void ClientContext::StartCancel() {}
+
+}  // namespace grpc
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
new file mode 100644
index 0000000..ea2b6a7
--- /dev/null
+++ b/src/cpp/client/create_channel.cc
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <memory>
+#include <string>
+
+#include "src/cpp/client/channel.h"
+#include <grpc++/channel_interface.h>
+#include <grpc++/create_channel.h>
+
+namespace grpc {
+
+std::shared_ptr<ChannelInterface> CreateChannel(const grpc::string& target) {
+  return std::shared_ptr<ChannelInterface>(new Channel(target));
+}
+
+}  // namespace grpc
diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc
new file mode 100644
index 0000000..18fa4fa
--- /dev/null
+++ b/src/cpp/client/credentials.cc
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <string>
+
+#include <grpc/grpc_security.h>
+
+#include <grpc++/credentials.h>
+
+namespace grpc {
+
+Credentials::Credentials(grpc_credentials* c_creds) : creds_(c_creds) {}
+
+Credentials::~Credentials() { grpc_credentials_release(creds_); }
+grpc_credentials* Credentials::GetRawCreds() { return creds_; }
+
+std::unique_ptr<Credentials> CredentialsFactory::DefaultCredentials() {
+  grpc_credentials* c_creds = grpc_default_credentials_create();
+  std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
+  return cpp_creds;
+}
+
+// Builds SSL Credentials given SSL specific options
+std::unique_ptr<Credentials> CredentialsFactory::SslCredentials(
+    const SslCredentialsOptions& options) {
+  grpc_credentials* c_creds = grpc_ssl_credentials_create(
+      reinterpret_cast<const unsigned char*>(options.pem_root_certs.c_str()),
+      options.pem_root_certs.size(),
+      reinterpret_cast<const unsigned char*>(options.pem_private_key.c_str()),
+      options.pem_private_key.size(),
+      reinterpret_cast<const unsigned char*>(options.pem_cert_chain.c_str()),
+      options.pem_cert_chain.size());
+  std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
+  return cpp_creds;
+}
+
+// Builds credentials for use when running in GCE
+std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() {
+  grpc_credentials* c_creds = grpc_compute_engine_credentials_create();
+  std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
+  return cpp_creds;
+}
+
+
+// Combines two credentials objects into a composite credentials.
+std::unique_ptr<Credentials> CredentialsFactory::ComposeCredentials(
+    const std::unique_ptr<Credentials>& creds1,
+    const std::unique_ptr<Credentials>& creds2) {
+  // Note that we are not saving unique_ptrs to the two credentials
+  // passed in here. This is OK because the underlying C objects (i.e.,
+  // creds1 and creds2) into grpc_composite_credentials_create will see their
+  // refcounts incremented.
+  grpc_credentials* c_creds = grpc_composite_credentials_create(
+      creds1->GetRawCreds(), creds2->GetRawCreds());
+  std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
+  return cpp_creds;
+}
+
+}  // namespace grpc
diff --git a/src/cpp/client/internal_stub.cc b/src/cpp/client/internal_stub.cc
new file mode 100644
index 0000000..ec88ba5
--- /dev/null
+++ b/src/cpp/client/internal_stub.cc
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/client/internal_stub.h"
+
+namespace grpc {}  // namespace grpc
diff --git a/src/cpp/client/internal_stub.h b/src/cpp/client/internal_stub.h
new file mode 100644
index 0000000..0eaa717
--- /dev/null
+++ b/src/cpp/client/internal_stub.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_CLIENT_INTERNAL_STUB_H__
+#define __GRPCPP_INTERNAL_CLIENT_INTERNAL_STUB_H__
+
+#include <memory>
+
+#include <grpc++/channel_interface.h>
+
+namespace grpc {
+
+class InternalStub {
+ public:
+  InternalStub() {}
+  virtual ~InternalStub() {}
+
+  void set_channel(const std::shared_ptr<ChannelInterface>& channel) {
+    channel_ = channel;
+  }
+
+  ChannelInterface* channel() { return channel_.get(); }
+
+ private:
+  std::shared_ptr<ChannelInterface> channel_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_CLIENT_INTERNAL_STUB_H__
diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/proto/proto_utils.cc
new file mode 100644
index 0000000..255d146
--- /dev/null
+++ b/src/cpp/proto/proto_utils.cc
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/proto/proto_utils.h"
+#include <grpc++/config.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/slice.h>
+#include <google/protobuf/message.h>
+
+namespace grpc {
+
+bool SerializeProto(const google::protobuf::Message& msg, grpc_byte_buffer** bp) {
+  grpc::string msg_str;
+  bool success = msg.SerializeToString(&msg_str);
+  if (success) {
+    gpr_slice slice =
+        gpr_slice_from_copied_buffer(msg_str.data(), msg_str.length());
+    *bp = grpc_byte_buffer_create(&slice, 1);
+    gpr_slice_unref(slice);
+  }
+  return success;
+}
+
+bool DeserializeProto(grpc_byte_buffer* buffer, google::protobuf::Message* msg) {
+  grpc::string msg_string;
+  grpc_byte_buffer_reader* reader = grpc_byte_buffer_reader_create(buffer);
+  gpr_slice slice;
+  while (grpc_byte_buffer_reader_next(reader, &slice)) {
+    const char* data = reinterpret_cast<const char*>(
+        slice.refcount ? slice.data.refcounted.bytes
+                       : slice.data.inlined.bytes);
+    msg_string.append(data, slice.refcount ? slice.data.refcounted.length
+                                           : slice.data.inlined.length);
+    gpr_slice_unref(slice);
+  }
+  grpc_byte_buffer_reader_destroy(reader);
+  return msg->ParseFromString(msg_string);
+}
+
+}  // namespace grpc
diff --git a/src/cpp/proto/proto_utils.h b/src/cpp/proto/proto_utils.h
new file mode 100644
index 0000000..11471f1
--- /dev/null
+++ b/src/cpp/proto/proto_utils.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_PROTO_PROTO_UTILS_H__
+#define __GRPCPP_INTERNAL_PROTO_PROTO_UTILS_H__
+
+struct grpc_byte_buffer;
+namespace google {
+namespace protobuf {
+class Message;
+}
+}
+
+namespace grpc {
+
+// Serialize the msg into a buffer created inside the function. The caller
+// should destroy the returned buffer when done with it. If serialization fails,
+// false is returned and buffer is left unchanged.
+bool SerializeProto(const google::protobuf::Message& msg, grpc_byte_buffer** buffer);
+
+// The caller keeps ownership of buffer and msg.
+bool DeserializeProto(grpc_byte_buffer* buffer, google::protobuf::Message* msg);
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_PROTO_PROTO_UTILS_H__
diff --git a/src/cpp/rpc_method.cc b/src/cpp/rpc_method.cc
new file mode 100644
index 0000000..8067f42
--- /dev/null
+++ b/src/cpp/rpc_method.cc
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/rpc_method.h"
+
+namespace grpc {}  // namespace grpc
diff --git a/src/cpp/rpc_method.h b/src/cpp/rpc_method.h
new file mode 100644
index 0000000..24a34be
--- /dev/null
+++ b/src/cpp/rpc_method.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_RPC_METHOD_H__
+#define __GRPCPP_INTERNAL_RPC_METHOD_H__
+
+namespace google {
+namespace protobuf {
+class Message;
+}
+}
+
+namespace grpc {
+
+class RpcMethod {
+ public:
+  enum RpcType {
+    NORMAL_RPC = 0,
+    CLIENT_STREAMING,  // request streaming
+    SERVER_STREAMING,  // response streaming
+    BIDI_STREAMING
+  };
+
+  explicit RpcMethod(const char* name)
+      : name_(name), method_type_(NORMAL_RPC) {}
+  RpcMethod(const char* name, RpcType type) : name_(name), method_type_(type) {}
+
+  const char *name() const { return name_; }
+
+  RpcType method_type() const { return method_type_; }
+
+ private:
+  const char *name_;
+  const RpcType method_type_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_RPC_METHOD_H__
diff --git a/src/cpp/server/async_server.cc b/src/cpp/server/async_server.cc
new file mode 100644
index 0000000..aae2c82
--- /dev/null
+++ b/src/cpp/server/async_server.cc
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/async_server.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc++/completion_queue.h>
+
+namespace grpc {
+
+AsyncServer::AsyncServer(CompletionQueue* cc)
+    : started_(false), shutdown_(false) {
+  server_ = grpc_server_create(cc->cq(), nullptr);
+}
+
+AsyncServer::~AsyncServer() {
+  std::unique_lock<std::mutex> lock(shutdown_mu_);
+  if (started_ && !shutdown_) {
+    lock.unlock();
+    Shutdown();
+  }
+  grpc_server_destroy(server_);
+}
+
+void AsyncServer::AddPort(const grpc::string& addr) {
+  GPR_ASSERT(!started_);
+  int success = grpc_server_add_http2_port(server_, addr.c_str());
+  GPR_ASSERT(success);
+}
+
+void AsyncServer::Start() {
+  GPR_ASSERT(!started_);
+  started_ = true;
+  grpc_server_start(server_);
+}
+
+void AsyncServer::RequestOneRpc() {
+  GPR_ASSERT(started_);
+  std::unique_lock<std::mutex> lock(shutdown_mu_);
+  if (shutdown_) {
+    return;
+  }
+  lock.unlock();
+  grpc_call_error err = grpc_server_request_call(server_, nullptr);
+  GPR_ASSERT(err == GRPC_CALL_OK);
+}
+
+void AsyncServer::Shutdown() {
+  std::unique_lock<std::mutex> lock(shutdown_mu_);
+  if (started_ && !shutdown_) {
+    shutdown_ = true;
+    lock.unlock();
+    // TODO(yangg) should we shutdown without start?
+    grpc_server_shutdown(server_);
+  }
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/async_server_context.cc b/src/cpp/server/async_server_context.cc
new file mode 100644
index 0000000..b231f4b
--- /dev/null
+++ b/src/cpp/server/async_server_context.cc
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/async_server_context.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "src/cpp/proto/proto_utils.h"
+#include <google/protobuf/message.h>
+#include <grpc++/status.h>
+
+namespace grpc {
+
+AsyncServerContext::AsyncServerContext(
+    grpc_call* call, const grpc::string& method, const grpc::string& host,
+    system_clock::time_point absolute_deadline)
+    : method_(method),
+      host_(host),
+      absolute_deadline_(absolute_deadline),
+      request_(nullptr),
+      call_(call) {
+}
+
+AsyncServerContext::~AsyncServerContext() { grpc_call_destroy(call_); }
+
+void AsyncServerContext::Accept(grpc_completion_queue* cq) {
+  grpc_call_accept(call_, cq, this, 0);
+}
+
+bool AsyncServerContext::StartRead(google::protobuf::Message* request) {
+  GPR_ASSERT(request);
+  request_ = request;
+  grpc_call_error err = grpc_call_start_read(call_, this);
+  return err == GRPC_CALL_OK;
+}
+
+bool AsyncServerContext::StartWrite(const google::protobuf::Message& response,
+                                    int flags) {
+  grpc_byte_buffer* buffer = nullptr;
+  if (!SerializeProto(response, &buffer)) {
+    return false;
+  }
+  grpc_call_error err = grpc_call_start_write(call_, buffer, this, flags);
+  grpc_byte_buffer_destroy(buffer);
+  return err == GRPC_CALL_OK;
+}
+
+namespace {
+grpc_status TranslateStatus(const Status& status) {
+  grpc_status c_status;
+  // TODO(yangg)
+  c_status.code = GRPC_STATUS_OK;
+  c_status.details = nullptr;
+  return c_status;
+}
+}  // namespace
+
+bool AsyncServerContext::StartWriteStatus(const Status& status) {
+  grpc_status c_status = TranslateStatus(status);
+  grpc_call_error err = grpc_call_start_write_status(call_, c_status, this);
+  return err == GRPC_CALL_OK;
+}
+
+bool AsyncServerContext::ParseRead(grpc_byte_buffer* read_buffer) {
+  GPR_ASSERT(request_);
+  bool success = DeserializeProto(read_buffer, request_);
+  request_ = nullptr;
+  return success;
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/completion_queue.cc b/src/cpp/server/completion_queue.cc
new file mode 100644
index 0000000..04eb301
--- /dev/null
+++ b/src/cpp/server/completion_queue.cc
@@ -0,0 +1,113 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+// TODO(yangg) maybe move to internal/common
+#include <grpc++/completion_queue.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include "src/cpp/util/time.h"
+#include <grpc++/async_server_context.h>
+
+namespace grpc {
+
+CompletionQueue::CompletionQueue() { cq_ = grpc_completion_queue_create(); }
+
+CompletionQueue::~CompletionQueue() { grpc_completion_queue_destroy(cq_); }
+
+void CompletionQueue::Shutdown() { grpc_completion_queue_shutdown(cq_); }
+
+CompletionQueue::CompletionType CompletionQueue::Next(void** tag) {
+  grpc_event* ev;
+  CompletionType return_type;
+  bool success;
+
+  ev = grpc_completion_queue_next(cq_, gpr_inf_future);
+  if (!ev) {
+    gpr_log(GPR_ERROR, "no next event in queue");
+    abort();
+  }
+  switch (ev->type) {
+    case GRPC_QUEUE_SHUTDOWN:
+      return_type = QUEUE_CLOSED;
+      break;
+    case GRPC_READ:
+      *tag = ev->tag;
+      if (ev->data.read) {
+        success =
+            static_cast<AsyncServerContext*>(ev->tag)->ParseRead(ev->data.read);
+        return_type = success ? SERVER_READ_OK : SERVER_READ_ERROR;
+      } else {
+        return_type = SERVER_READ_ERROR;
+      }
+      break;
+    case GRPC_WRITE_ACCEPTED:
+      *tag = ev->tag;
+      if (ev->data.write_accepted != GRPC_OP_ERROR) {
+        return_type = SERVER_WRITE_OK;
+      } else {
+        return_type = SERVER_WRITE_ERROR;
+      }
+      break;
+    case GRPC_SERVER_RPC_NEW:
+      GPR_ASSERT(!ev->tag);
+      // Finishing the pending new rpcs after the server has been shutdown.
+      if (!ev->call) {
+        *tag = nullptr;
+      } else {
+        *tag = new AsyncServerContext(ev->call, ev->data.server_rpc_new.method,
+                                      ev->data.server_rpc_new.host,
+                                      AbsoluteDeadlineTimespec2Timepoint(
+                                          ev->data.server_rpc_new.deadline));
+      }
+      return_type = SERVER_RPC_NEW;
+      break;
+    case GRPC_FINISHED:
+      *tag = ev->tag;
+      return_type = RPC_END;
+      break;
+    case GRPC_FINISH_ACCEPTED:
+      *tag = ev->tag;
+      return_type = HALFCLOSE_OK;
+      break;
+    default:
+      // We do not handle client side messages now
+      gpr_log(GPR_ERROR, "client-side messages aren't supported yet");
+      abort();
+  }
+  grpc_event_finish(ev);
+  return return_type;
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/rpc_service_method.h b/src/cpp/server/rpc_service_method.h
new file mode 100644
index 0000000..ac2badd
--- /dev/null
+++ b/src/cpp/server/rpc_service_method.h
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_SERVER_RPC_SERVICE_METHOD_H__
+#define __GRPCPP_INTERNAL_SERVER_RPC_SERVICE_METHOD_H__
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "src/cpp/rpc_method.h"
+#include <google/protobuf/message.h>
+#include <grpc++/status.h>
+
+namespace grpc {
+
+// TODO(rocking): we might need to split this file into multiple ones.
+
+// Base class for running an RPC handler.
+class MethodHandler {
+ public:
+  virtual ~MethodHandler() {}
+  struct HandlerParameter {
+    HandlerParameter(const google::protobuf::Message* req, google::protobuf::Message* resp)
+        : request(req), response(resp) {}
+    const google::protobuf::Message* request;
+    google::protobuf::Message* response;
+  };
+  virtual ::grpc::Status RunHandler(const HandlerParameter& param) = 0;
+};
+
+// A wrapper class of an application provided rpc method handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class RpcMethodHandler : public MethodHandler {
+ public:
+  RpcMethodHandler(std::function<::grpc::Status(
+                       ServiceType*, const RequestType*, ResponseType*)> func,
+                   ServiceType* service)
+      : func_(func), service_(service) {}
+
+  ::grpc::Status RunHandler(const HandlerParameter& param) final {
+    // Invoke application function, cast proto messages to their actual types.
+    return func_(service_, dynamic_cast<const RequestType*>(param.request),
+                 dynamic_cast<ResponseType*>(param.response));
+  }
+
+ private:
+  // Application provided rpc handler function.
+  std::function<::grpc::Status(ServiceType*, const RequestType*, ResponseType*)>
+      func_;
+  // The class the above handler function lives in.
+  ServiceType* service_;
+};
+
+// Server side rpc method class
+class RpcServiceMethod : public RpcMethod {
+ public:
+  // Takes ownership of the handler and two prototype objects.
+  RpcServiceMethod(const char* name, MethodHandler* handler,
+                   google::protobuf::Message* request_prototype,
+                   google::protobuf::Message* response_prototype)
+      : RpcMethod(name),
+        handler_(handler),
+        request_prototype_(request_prototype),
+        response_prototype_(response_prototype) {}
+
+  MethodHandler* handler() { return handler_.get(); }
+
+  google::protobuf::Message* AllocateRequestProto() { return request_prototype_->New(); }
+  google::protobuf::Message* AllocateResponseProto() {
+    return response_prototype_->New();
+  }
+
+ private:
+  std::unique_ptr<MethodHandler> handler_;
+  std::unique_ptr<google::protobuf::Message> request_prototype_;
+  std::unique_ptr<google::protobuf::Message> response_prototype_;
+};
+
+// This class contains all the method information for an rpc service. It is
+// used for registering a service on a grpc server.
+class RpcService {
+ public:
+  // Takes ownership.
+  void AddMethod(RpcServiceMethod* method) {
+    methods_.push_back(std::unique_ptr<RpcServiceMethod>(method));
+  }
+
+  RpcServiceMethod* GetMethod(int i) {
+    return methods_[i].get();
+  }
+  int GetMethodCount() const { return methods_.size(); }
+
+ private:
+  std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_SERVER_RPC_SERVICE_METHOD_H__
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
new file mode 100644
index 0000000..9bf4073
--- /dev/null
+++ b/src/cpp/server/server.cc
@@ -0,0 +1,166 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/server.h>
+#include <utility>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "src/cpp/server/rpc_service_method.h"
+#include "src/cpp/server/server_rpc_handler.h"
+#include "src/cpp/server/thread_pool.h"
+#include <grpc++/async_server_context.h>
+#include <grpc++/completion_queue.h>
+
+namespace grpc {
+
+// TODO(rocking): consider a better default value like num of cores.
+static const int kNumThreads = 4;
+
+Server::Server(ThreadPoolInterface* thread_pool)
+    : started_(false),
+      shutdown_(false),
+      num_running_cb_(0),
+      thread_pool_(thread_pool == nullptr ? new ThreadPool(kNumThreads)
+                                          : thread_pool),
+      thread_pool_owned_(thread_pool == nullptr) {
+  server_ = grpc_server_create(cq_.cq(), nullptr);
+}
+
+Server::Server() {
+  // Should not be called.
+  GPR_ASSERT(false);
+}
+
+Server::~Server() {
+  std::unique_lock<std::mutex> lock(mu_);
+  if (started_ && !shutdown_) {
+    lock.unlock();
+    Shutdown();
+  }
+  grpc_server_destroy(server_);
+  if (thread_pool_owned_) {
+    delete thread_pool_;
+  }
+}
+
+void Server::RegisterService(RpcService* service) {
+  for (int i = 0; i < service->GetMethodCount(); ++i) {
+    RpcServiceMethod* method = service->GetMethod(i);
+    method_map_.insert(std::make_pair(method->name(), method));
+  }
+}
+
+void Server::AddPort(const grpc::string& addr) {
+  GPR_ASSERT(!started_);
+  int success = grpc_server_add_http2_port(server_, addr.c_str());
+  GPR_ASSERT(success);
+}
+
+void Server::Start() {
+  GPR_ASSERT(!started_);
+  started_ = true;
+  grpc_server_start(server_);
+
+  // Start processing rpcs.
+  ScheduleCallback();
+}
+
+void Server::AllowOneRpc() {
+  GPR_ASSERT(started_);
+  grpc_call_error err = grpc_server_request_call(server_, nullptr);
+  GPR_ASSERT(err == GRPC_CALL_OK);
+}
+
+void Server::Shutdown() {
+  {
+    std::unique_lock<std::mutex> lock(mu_);
+    if (started_ && !shutdown_) {
+      shutdown_ = true;
+      grpc_server_shutdown(server_);
+
+      // Wait for running callbacks to finish.
+      while (num_running_cb_ != 0) {
+        callback_cv_.wait(lock);
+      }
+    }
+  }
+
+  // Shutdown the completion queue.
+  cq_.Shutdown();
+  void* tag = nullptr;
+  CompletionQueue::CompletionType t = cq_.Next(&tag);
+  GPR_ASSERT(t == CompletionQueue::QUEUE_CLOSED);
+}
+
+void Server::ScheduleCallback() {
+  {
+    std::unique_lock<std::mutex> lock(mu_);
+    num_running_cb_++;
+  }
+  std::function<void()> callback = std::bind(&Server::RunRpc, this);
+  thread_pool_->ScheduleCallback(callback);
+}
+
+void Server::RunRpc() {
+  // Wait for one more incoming rpc.
+  void* tag = nullptr;
+  AllowOneRpc();
+  CompletionQueue::CompletionType t = cq_.Next(&tag);
+  GPR_ASSERT(t == CompletionQueue::SERVER_RPC_NEW);
+
+  AsyncServerContext* server_context = static_cast<AsyncServerContext*>(tag);
+  // server_context could be nullptr during server shutdown.
+  if (server_context != nullptr) {
+    // Schedule a new callback to handle more rpcs.
+    ScheduleCallback();
+
+    RpcServiceMethod* method = nullptr;
+    auto iter = method_map_.find(server_context->method());
+    if (iter != method_map_.end()) {
+      method = iter->second;
+    }
+    ServerRpcHandler rpc_handler(server_context, method);
+    rpc_handler.StartRpc();
+  }
+
+  {
+    std::unique_lock<std::mutex> lock(mu_);
+    num_running_cb_--;
+    if (shutdown_) {
+      callback_cv_.notify_all();
+    }
+  }
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
new file mode 100644
index 0000000..d5d0689
--- /dev/null
+++ b/src/cpp/server/server_builder.cc
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/server_builder.h>
+
+#include <grpc++/server.h>
+
+namespace grpc {
+
+ServerBuilder::ServerBuilder() : thread_pool_(nullptr) {}
+
+void ServerBuilder::RegisterService(RpcService* service) {
+  services_.push_back(service);
+}
+
+void ServerBuilder::AddPort(const grpc::string& addr) {
+  ports_.push_back(addr);
+}
+
+void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) {
+  thread_pool_ = thread_pool;
+}
+
+std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
+  std::unique_ptr<Server> server(new Server(thread_pool_));
+  for (auto* service : services_) {
+    server->RegisterService(service);
+  }
+  for (auto& port : ports_) {
+    server->AddPort(port);
+  }
+  server->Start();
+  return server;
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/server_rpc_handler.cc b/src/cpp/server/server_rpc_handler.cc
new file mode 100644
index 0000000..2d5a081
--- /dev/null
+++ b/src/cpp/server/server_rpc_handler.cc
@@ -0,0 +1,108 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/server/server_rpc_handler.h"
+
+#include <grpc/support/log.h>
+#include "src/cpp/server/rpc_service_method.h"
+#include <grpc++/async_server_context.h>
+
+namespace grpc {
+
+ServerRpcHandler::ServerRpcHandler(AsyncServerContext* server_context,
+                                   RpcServiceMethod* method)
+    : server_context_(server_context),
+      method_(method) {
+}
+
+void ServerRpcHandler::StartRpc() {
+  // Start the rpc on this dedicated completion queue.
+  server_context_->Accept(cq_.cq());
+
+  if (method_ == nullptr) {
+    // Method not supported, finish the rpc with error.
+    // TODO(rocking): do we need to call read to consume the request?
+    FinishRpc(Status(StatusCode::UNIMPLEMENTED, "No such method."));
+    return;
+  }
+
+  // Allocate request and response.
+  std::unique_ptr<google::protobuf::Message> request(method_->AllocateRequestProto());
+  std::unique_ptr<google::protobuf::Message> response(method_->AllocateResponseProto());
+
+  // Read request
+  server_context_->StartRead(request.get());
+  auto type = WaitForNextEvent();
+  GPR_ASSERT(type == CompletionQueue::SERVER_READ_OK);
+
+  // Run the application's rpc handler
+  MethodHandler* handler = method_->handler();
+  Status status = handler->RunHandler(
+      MethodHandler::HandlerParameter(request.get(), response.get()));
+
+  if (status.IsOk()) {
+    // Send the response if we get an ok status.
+    server_context_->StartWrite(*response, 0);
+    type = WaitForNextEvent();
+    if (type != CompletionQueue::SERVER_WRITE_OK) {
+      status = Status(StatusCode::INTERNAL, "Error writing response.");
+    }
+  }
+
+  FinishRpc(status);
+}
+
+CompletionQueue::CompletionType ServerRpcHandler::WaitForNextEvent() {
+  void* tag = nullptr;
+  CompletionQueue::CompletionType type = cq_.Next(&tag);
+  if (type != CompletionQueue::QUEUE_CLOSED &&
+      type != CompletionQueue::RPC_END) {
+    GPR_ASSERT(static_cast<AsyncServerContext*>(tag) == server_context_.get());
+  }
+  return type;
+}
+
+void ServerRpcHandler::FinishRpc(const Status& status) {
+  server_context_->StartWriteStatus(status);
+  CompletionQueue::CompletionType type = WaitForNextEvent();
+  // TODO(rocking): do we care about this return type?
+
+  type = WaitForNextEvent();
+  GPR_ASSERT(type == CompletionQueue::RPC_END);
+
+  cq_.Shutdown();
+  type = WaitForNextEvent();
+  GPR_ASSERT(type == CompletionQueue::QUEUE_CLOSED);
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/server_rpc_handler.h b/src/cpp/server/server_rpc_handler.h
new file mode 100644
index 0000000..ca48fd7
--- /dev/null
+++ b/src/cpp/server/server_rpc_handler.h
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_SERVER_SERVER_RPC_HANDLER_H__
+#define __GRPCPP_INTERNAL_SERVER_SERVER_RPC_HANDLER_H__
+
+#include <memory>
+
+#include <grpc++/completion_queue.h>
+#include <grpc++/status.h>
+
+namespace grpc {
+
+class AsyncServerContext;
+class RpcServiceMethod;
+
+class ServerRpcHandler {
+ public:
+  // Takes ownership of server_context.
+  ServerRpcHandler(AsyncServerContext* server_context,
+                   RpcServiceMethod* method);
+
+  void StartRpc();
+
+ private:
+  CompletionQueue::CompletionType WaitForNextEvent();
+  void FinishRpc(const Status& status);
+
+  std::unique_ptr<AsyncServerContext> server_context_;
+  RpcServiceMethod* method_;
+  CompletionQueue cq_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_SERVER_SERVER_RPC_HANDLER_H__
diff --git a/src/cpp/server/thread_pool.cc b/src/cpp/server/thread_pool.cc
new file mode 100644
index 0000000..ce364c4
--- /dev/null
+++ b/src/cpp/server/thread_pool.cc
@@ -0,0 +1,77 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/server/thread_pool.h"
+
+namespace grpc {
+
+ThreadPool::ThreadPool(int num_threads) {
+  for (int i = 0; i < num_threads; i++) {
+    threads_.push_back(std::thread([=]() {
+      for (;;) {
+        std::unique_lock<std::mutex> lock(mu_);
+        // Wait until work is available or we are shutting down.
+        cv_.wait(lock, [=]() { return shutdown_ || !callbacks_.empty(); });
+        // Drain callbacks before considering shutdown to ensure all work
+        // gets completed.
+        if (!callbacks_.empty()) {
+          auto cb = callbacks_.front();
+          callbacks_.pop();
+          lock.unlock();
+          cb();
+        } else if (shutdown_) {
+          return;
+        }
+      }
+    }));
+  }
+}
+
+ThreadPool::~ThreadPool() {
+  {
+    std::lock_guard<std::mutex> lock(mu_);
+    shutdown_ = true;
+    cv_.notify_all();
+  }
+  for (auto& t : threads_) {
+    t.join();
+  }
+}
+
+void ThreadPool::ScheduleCallback(const std::function<void()>& callback) {
+  std::lock_guard<std::mutex> lock(mu_);
+  callbacks_.push(callback);
+  cv_.notify_all();
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/thread_pool.h b/src/cpp/server/thread_pool.h
new file mode 100644
index 0000000..6fc71d6
--- /dev/null
+++ b/src/cpp/server/thread_pool.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_SERVER_THREAD_POOL_H__
+#define __GRPCPP_INTERNAL_SERVER_THREAD_POOL_H__
+
+#include <grpc++/thread_pool_interface.h>
+
+#include <condition_variable>
+#include <thread>
+#include <mutex>
+#include <queue>
+#include <vector>
+
+namespace grpc {
+
+class ThreadPool : public ThreadPoolInterface {
+ public:
+  explicit ThreadPool(int num_threads);
+  ~ThreadPool();
+
+  void ScheduleCallback(const std::function<void()>& callback) final;
+
+ private:
+  std::mutex mu_;
+  std::condition_variable cv_;
+  bool shutdown_ = false;
+  std::queue<std::function<void()>> callbacks_;
+  std::vector<std::thread> threads_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_SERVER_THREAD_POOL_H__
diff --git a/src/cpp/stream/stream_context.cc b/src/cpp/stream/stream_context.cc
new file mode 100644
index 0000000..07e771f
--- /dev/null
+++ b/src/cpp/stream/stream_context.cc
@@ -0,0 +1,276 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/stream/stream_context.h"
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "src/cpp/rpc_method.h"
+#include "src/cpp/proto/proto_utils.h"
+#include "src/cpp/util/time.h"
+#include <grpc++/client_context.h>
+#include <grpc++/config.h>
+#include <google/protobuf/message.h>
+
+namespace grpc {
+
+// Client only ctor
+StreamContext::StreamContext(const RpcMethod& method, ClientContext* context,
+                             const google::protobuf::Message* request,
+                             google::protobuf::Message* result)
+    : is_client_(true),
+      method_(&method),
+      context_(context),
+      request_(request),
+      result_(result),
+      invoke_ev_(nullptr),
+      read_ev_(nullptr),
+      write_ev_(nullptr),
+      reading_(false),
+      writing_(false),
+      got_read_(false),
+      got_write_(false),
+      peer_halfclosed_(false),
+      self_halfclosed_(false),
+      stream_finished_(false),
+      waiting_(false) {
+  GPR_ASSERT(method_->method_type() != RpcMethod::RpcType::NORMAL_RPC);
+}
+
+StreamContext::~StreamContext() { cq_poller_.join(); }
+
+void StreamContext::PollingLoop() {
+  grpc_event* ev = nullptr;
+  gpr_timespec absolute_deadline;
+  AbsoluteDeadlineTimepoint2Timespec(context_->absolute_deadline(),
+                                     &absolute_deadline);
+  std::condition_variable* cv_to_notify = nullptr;
+  std::unique_lock<std::mutex> lock(mu_, std::defer_lock);
+  while (1) {
+    cv_to_notify = nullptr;
+    lock.lock();
+    if (stream_finished_ && !reading_ && !writing_) {
+      return;
+    }
+    lock.unlock();
+    ev = grpc_completion_queue_next(context_->cq(), absolute_deadline);
+    lock.lock();
+    if (!ev) {
+      stream_finished_ = true;
+      final_status_ = Status(StatusCode::DEADLINE_EXCEEDED);
+      std::condition_variable* cvs[3] = {reading_ ? &read_cv_ : nullptr,
+                                         writing_ ? &write_cv_ : nullptr,
+                                         waiting_ ? &finish_cv_ : nullptr};
+      got_read_ = reading_;
+      got_write_ = writing_;
+      read_ev_ = nullptr;
+      write_ev_ = nullptr;
+      lock.unlock();
+      for (int i = 0; i < 3; i++) {
+        if (cvs[i]) cvs[i]->notify_one();
+      }
+      break;
+    }
+    switch (ev->type) {
+      case GRPC_READ:
+        GPR_ASSERT(reading_);
+        got_read_ = true;
+        read_ev_ = ev;
+        cv_to_notify = &read_cv_;
+        reading_ = false;
+        break;
+      case GRPC_FINISH_ACCEPTED:
+      case GRPC_WRITE_ACCEPTED:
+        got_write_ = true;
+        write_ev_ = ev;
+        cv_to_notify = &write_cv_;
+        writing_ = false;
+        break;
+      case GRPC_FINISHED: {
+        grpc::string error_details(
+            ev->data.finished.details ? ev->data.finished.details : "");
+        final_status_ = Status(static_cast<StatusCode>(ev->data.finished.code),
+                               error_details);
+        grpc_event_finish(ev);
+        stream_finished_ = true;
+        if (waiting_) {
+          cv_to_notify = &finish_cv_;
+        }
+        break;
+      }
+      case GRPC_INVOKE_ACCEPTED:
+        invoke_ev_ = ev;
+        cv_to_notify = &invoke_cv_;
+        break;
+      case GRPC_CLIENT_METADATA_READ:
+        grpc_event_finish(ev);
+        break;
+      default:
+        grpc_event_finish(ev);
+        // not handling other types now
+        gpr_log(GPR_ERROR, "unknown event type");
+        abort();
+    }
+    lock.unlock();
+    if (cv_to_notify) {
+      cv_to_notify->notify_one();
+    }
+  }
+}
+
+void StreamContext::Start(bool buffered) {
+  // TODO(yangg) handle metadata send path
+  int flag = buffered ? GRPC_WRITE_BUFFER_HINT : 0;
+  grpc_call_error error = grpc_call_start_invoke(
+      context_->call(), context_->cq(), this, this, this, flag);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  // kicks off the poller thread
+  cq_poller_ = std::thread(&StreamContext::PollingLoop, this);
+  std::unique_lock<std::mutex> lock(mu_);
+  while (!invoke_ev_) {
+    invoke_cv_.wait(lock);
+  }
+  lock.unlock();
+  GPR_ASSERT(invoke_ev_->data.invoke_accepted == GRPC_OP_OK);
+  grpc_event_finish(invoke_ev_);
+}
+
+namespace {
+// Wait for got_event with event_cv protected by mu, return event.
+grpc_event* WaitForEvent(bool* got_event, std::condition_variable* event_cv,
+                         std::mutex* mu, grpc_event** event) {
+  std::unique_lock<std::mutex> lock(*mu);
+  while (*got_event == false) {
+    event_cv->wait(lock);
+  }
+  *got_event = false;
+  return *event;
+}
+}  // namespace
+
+bool StreamContext::Read(google::protobuf::Message* msg) {
+  std::unique_lock<std::mutex> lock(mu_);
+  if (stream_finished_) {
+    peer_halfclosed_ = true;
+    return false;
+  }
+  reading_ = true;
+  lock.unlock();
+
+  grpc_call_error err = grpc_call_start_read(context_->call(), this);
+  GPR_ASSERT(err == GRPC_CALL_OK);
+
+  grpc_event* ev = WaitForEvent(&got_read_, &read_cv_, &mu_, &read_ev_);
+  if (!ev) {
+    return false;
+  }
+  GPR_ASSERT(ev->type == GRPC_READ);
+  bool ret = true;
+  if (ev->data.read) {
+    if (!DeserializeProto(ev->data.read, msg)) {
+      ret = false;  // parse error
+                    // TODO(yangg) cancel the stream.
+    }
+  } else {
+    ret = false;
+    peer_halfclosed_ = true;
+  }
+  grpc_event_finish(ev);
+  return ret;
+}
+
+bool StreamContext::Write(const google::protobuf::Message* msg, bool is_last) {
+  bool ret = true;
+  grpc_event* ev = nullptr;
+
+  std::unique_lock<std::mutex> lock(mu_);
+  if (stream_finished_) {
+    self_halfclosed_ = true;
+    return false;
+  }
+  writing_ = true;
+  lock.unlock();
+
+  if (msg) {
+    grpc_byte_buffer* out_buf = nullptr;
+    if (!SerializeProto(*msg, &out_buf)) {
+      FinishStream(Status(StatusCode::INVALID_ARGUMENT,
+                          "Failed to serialize request proto"),
+                   true);
+      return false;
+    }
+    int flag = is_last ? GRPC_WRITE_BUFFER_HINT : 0;
+    grpc_call_error err =
+        grpc_call_start_write(context_->call(), out_buf, this, flag);
+    grpc_byte_buffer_destroy(out_buf);
+    GPR_ASSERT(err == GRPC_CALL_OK);
+
+    ev = WaitForEvent(&got_write_, &write_cv_, &mu_, &write_ev_);
+    if (!ev) {
+      return false;
+    }
+    GPR_ASSERT(ev->type == GRPC_WRITE_ACCEPTED);
+
+    ret = ev->data.write_accepted == GRPC_OP_OK;
+    grpc_event_finish(ev);
+  }
+  if (is_last) {
+    grpc_call_error err = grpc_call_writes_done(context_->call(), this);
+    GPR_ASSERT(err == GRPC_CALL_OK);
+    ev = WaitForEvent(&got_write_, &write_cv_, &mu_, &write_ev_);
+    if (!ev) {
+      return false;
+    }
+    GPR_ASSERT(ev->type == GRPC_FINISH_ACCEPTED);
+    grpc_event_finish(ev);
+    self_halfclosed_ = true;
+  }
+  return ret;
+}
+
+const Status& StreamContext::Wait() {
+  std::unique_lock<std::mutex> lock(mu_);
+  // TODO(yangg) if not halfclosed cancel the stream
+  GPR_ASSERT(self_halfclosed_);
+  GPR_ASSERT(peer_halfclosed_);
+  GPR_ASSERT(!waiting_);
+  waiting_ = true;
+  while (!stream_finished_) {
+    finish_cv_.wait(lock);
+  }
+  return final_status_;
+}
+
+void StreamContext::FinishStream(const Status& status, bool send) { return; }
+
+}  // namespace grpc
diff --git a/src/cpp/stream/stream_context.h b/src/cpp/stream/stream_context.h
new file mode 100644
index 0000000..b7f462f
--- /dev/null
+++ b/src/cpp/stream/stream_context.h
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_STREAM_STREAM_CONTEXT_H__
+#define __GRPCPP_INTERNAL_STREAM_STREAM_CONTEXT_H__
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+
+#include <grpc++/status.h>
+#include <grpc++/stream_context_interface.h>
+
+namespace google {
+namespace protobuf {
+class Message;
+}
+}
+
+struct grpc_event;
+
+namespace grpc {
+class ClientContext;
+class RpcMethod;
+
+class StreamContext : public StreamContextInterface {
+ public:
+  StreamContext(const RpcMethod& method, ClientContext* context,
+                const google::protobuf::Message* request, google::protobuf::Message* result);
+  ~StreamContext();
+  // Start the stream, if there is a final write following immediately, set
+  // buffered so that the messages can be sent in batch.
+  void Start(bool buffered) override;
+  bool Read(google::protobuf::Message* msg) override;
+  bool Write(const google::protobuf::Message* msg, bool is_last) override;
+  const Status& Wait() override;
+  void FinishStream(const Status& status, bool send) override;
+
+  const google::protobuf::Message* request() override { return request_; }
+  google::protobuf::Message* response() override { return result_; }
+
+ private:
+  void PollingLoop();
+  bool BlockingStart();
+  bool is_client_;
+  const RpcMethod* method_;         // not owned
+  ClientContext* context_;          // now owned
+  const google::protobuf::Message* request_;  // not owned
+  google::protobuf::Message* result_;         // not owned
+
+  std::thread cq_poller_;
+  std::mutex mu_;
+  std::condition_variable invoke_cv_;
+  std::condition_variable read_cv_;
+  std::condition_variable write_cv_;
+  std::condition_variable finish_cv_;
+  grpc_event* invoke_ev_;
+  // TODO(yangg) make these two into queues to support concurrent reads and
+  // writes
+  grpc_event* read_ev_;
+  grpc_event* write_ev_;
+  bool reading_;
+  bool writing_;
+  bool got_read_;
+  bool got_write_;
+  bool peer_halfclosed_;
+  bool self_halfclosed_;
+  bool stream_finished_;
+  bool waiting_;
+  Status final_status_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_STREAM_STREAM_CONTEXT_H__
diff --git a/src/cpp/util/status.cc b/src/cpp/util/status.cc
new file mode 100644
index 0000000..66be26d
--- /dev/null
+++ b/src/cpp/util/status.cc
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <grpc++/status.h>
+
+namespace grpc {
+
+const Status& Status::OK = Status();
+const Status& Status::Cancelled = Status(StatusCode::CANCELLED);
+
+}  // namespace grpc
diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc
new file mode 100644
index 0000000..207bebf
--- /dev/null
+++ b/src/cpp/util/time.cc
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/cpp/util/time.h"
+
+#include <grpc/support/time.h>
+
+using std::chrono::duration_cast;
+using std::chrono::nanoseconds;
+using std::chrono::seconds;
+using std::chrono::system_clock;
+
+namespace grpc {
+
+void AbsoluteDeadlineTimepoint2Timespec(const system_clock::time_point& from,
+                                        gpr_timespec* to) {
+  system_clock::duration deadline = from.time_since_epoch();
+  seconds secs = duration_cast<seconds>(deadline);
+  nanoseconds nsecs = duration_cast<nanoseconds>(deadline - secs);
+  to->tv_sec = secs.count();
+  to->tv_nsec = nsecs.count();
+}
+
+system_clock::time_point AbsoluteDeadlineTimespec2Timepoint(gpr_timespec t) {
+  system_clock::time_point tp;
+  tp += seconds(t.tv_sec);
+  tp += nanoseconds(t.tv_nsec);
+  return tp;
+}
+
+}  // namespace grpc
diff --git a/src/cpp/util/time.h b/src/cpp/util/time.h
new file mode 100644
index 0000000..c21fba7
--- /dev/null
+++ b/src/cpp/util/time.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_INTERNAL_UTIL_TIME_H__
+#define __GRPCPP_INTERNAL_UTIL_TIME_H__
+
+#include <chrono>
+
+#include <grpc/support/time.h>
+
+namespace grpc {
+
+// from and to should be absolute time.
+void AbsoluteDeadlineTimepoint2Timespec(
+    const std::chrono::system_clock::time_point& from, gpr_timespec* to);
+
+std::chrono::system_clock::time_point AbsoluteDeadlineTimespec2Timepoint(
+    gpr_timespec t);
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_INTERNAL_UTIL_TIME_H__