From 06633ef1d17280b6e61f0451ffde13841da5b8df Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Thu, 19 Jun 2014 17:29:35 +0200 Subject: [PATCH] Cleanup --- Modem/Modem_user.mk | 3 - Modem/compression/heatshrink_common.h | 19 - Modem/compression/heatshrink_config.h | 24 - Modem/compression/heatshrink_decoder.c | 376 ----- Modem/compression/heatshrink_decoder.h | 101 -- Modem/compression/heatshrink_encoder.c | 640 -------- Modem/compression/heatshrink_encoder.h | 109 -- Modem/protocol/mp1.c | 1039 ------------- Modem/protocol/mp1.h | 110 -- buildrev.h | 2 +- images/Modem.elf | Bin 0 -> 186636 bytes images/Modem.hex | 1876 ++++++++++++++++++++++++ 12 files changed, 1877 insertions(+), 2422 deletions(-) delete mode 100644 Modem/compression/heatshrink_common.h delete mode 100644 Modem/compression/heatshrink_config.h delete mode 100644 Modem/compression/heatshrink_decoder.c delete mode 100644 Modem/compression/heatshrink_decoder.h delete mode 100644 Modem/compression/heatshrink_encoder.c delete mode 100644 Modem/compression/heatshrink_encoder.h delete mode 100644 Modem/protocol/mp1.c delete mode 100644 Modem/protocol/mp1.h create mode 100755 images/Modem.elf create mode 100644 images/Modem.hex diff --git a/Modem/Modem_user.mk b/Modem/Modem_user.mk index 88c61a6..3c4909c 100644 --- a/Modem/Modem_user.mk +++ b/Modem/Modem_user.mk @@ -12,11 +12,8 @@ Modem_USER_CSRC = \ $(Modem_SRC_PATH)/main.c \ $(Modem_HW_PATH)/hardware.c \ $(Modem_HW_PATH)/afsk.c \ - $(Modem_HW_PATH)/protocol/mp1.c \ $(Modem_HW_PATH)/protocol/SimpleSerial.c \ $(Modem_HW_PATH)/protocol/KISS.c \ - $(Modem_HW_PATH)/compression/heatshrink_decoder.c \ - $(Modem_HW_PATH)/compression/heatshrink_encoder.c \ # # Files included by the user. diff --git a/Modem/compression/heatshrink_common.h b/Modem/compression/heatshrink_common.h deleted file mode 100644 index 27275d4..0000000 --- a/Modem/compression/heatshrink_common.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef HEATSHRINK_H -#define HEATSHRINK_H - -#define HEATSHRINK_AUTHOR "Scott Vokes " - -/* Version 0.3.0 */ -#define HEATSHRINK_VERSION_MAJOR 0 -#define HEATSHRINK_VERSION_MINOR 3 -#define HEATSHRINK_VERSION_PATCH 0 - -#define HEATSHRINK_MIN_WINDOW_BITS 4 -#define HEATSHRINK_MAX_WINDOW_BITS 15 - -#define HEATSHRINK_MIN_LOOKAHEAD_BITS 2 - -#define HEATSHRINK_LITERAL_MARKER 0x01 -#define HEATSHRINK_BACKREF_MARKER 0x00 - -#endif diff --git a/Modem/compression/heatshrink_config.h b/Modem/compression/heatshrink_config.h deleted file mode 100644 index f618e2d..0000000 --- a/Modem/compression/heatshrink_config.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef HEATSHRINK_CONFIG_H -#define HEATSHRINK_CONFIG_H - -/* Should functionality assuming dynamic allocation be used? */ -#define HEATSHRINK_DYNAMIC_ALLOC 1 - -#if HEATSHRINK_DYNAMIC_ALLOC - /* Optional replacement of malloc/free */ - #define HEATSHRINK_MALLOC(SZ) malloc(SZ) - #define HEATSHRINK_FREE(P, SZ) free(P) -#else - /* Required parameters for static configuration */ - #define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 200 - #define HEATSHRINK_STATIC_WINDOW_BITS 8 - #define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4 -#endif - -/* Turn on logging for debugging. */ -#define HEATSHRINK_DEBUGGING_LOGS 0 - -/* Use indexing for faster compression. (This requires additional space.) */ -#define HEATSHRINK_USE_INDEX 0 - -#endif diff --git a/Modem/compression/heatshrink_decoder.c b/Modem/compression/heatshrink_decoder.c deleted file mode 100644 index e6bd640..0000000 --- a/Modem/compression/heatshrink_decoder.c +++ /dev/null @@ -1,376 +0,0 @@ -#include -#include -#include "heatshrink_decoder.h" - -/* States for the polling state machine. */ -typedef enum { - HSDS_EMPTY, /* no input to process */ - HSDS_INPUT_AVAILABLE, /* new input, completely unprocessed */ - HSDS_YIELD_LITERAL, /* ready to yield literal byte */ - HSDS_BACKREF_INDEX_MSB, /* most significant byte of index */ - HSDS_BACKREF_INDEX_LSB, /* least significant byte of index */ - HSDS_BACKREF_COUNT_MSB, /* most significant byte of count */ - HSDS_BACKREF_COUNT_LSB, /* least significant byte of count */ - HSDS_YIELD_BACKREF, /* ready to yield back-reference */ - HSDS_CHECK_FOR_MORE_INPUT, /* check if input is exhausted */ -} HSD_state; - -#if HEATSHRINK_DEBUGGING_LOGS -#include -#include -#include -#define LOG(...) fprintf(stderr, __VA_ARGS__) -#define ASSERT(X) assert(X) -static const char *state_names[] = { - "empty", - "input_available", - "yield_literal", - "backref_index", - "backref_count", - "yield_backref", - "check_for_more_input", -}; -#else -#define LOG(...) /* no-op */ -#define ASSERT(X) /* no-op */ -#endif - -typedef struct { - uint8_t *buf; /* output buffer */ - size_t buf_size; /* buffer size */ - size_t *output_size; /* bytes pushed to buffer, so far */ -} output_info; - -#define NO_BITS ((uint32_t)-1) - -/* Forward references. */ -static uint32_t get_bits(heatshrink_decoder *hsd, uint8_t count); -static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte); - -#if HEATSHRINK_DYNAMIC_ALLOC -heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, - uint8_t window_sz2, - uint8_t lookahead_sz2) { - if ((window_sz2 < HEATSHRINK_MIN_WINDOW_BITS) || - (window_sz2 > HEATSHRINK_MAX_WINDOW_BITS) || - (input_buffer_size == 0) || - (lookahead_sz2 < HEATSHRINK_MIN_LOOKAHEAD_BITS) || - (lookahead_sz2 > window_sz2)) { - return NULL; - } - size_t buffers_sz = (1 << window_sz2) + input_buffer_size; - size_t sz = sizeof(heatshrink_decoder) + buffers_sz; - heatshrink_decoder *hsd = HEATSHRINK_MALLOC(sz); - if (hsd == NULL) { return NULL; } - hsd->input_buffer_size = input_buffer_size; - hsd->window_sz2 = window_sz2; - hsd->lookahead_sz2 = lookahead_sz2; - heatshrink_decoder_reset(hsd); - LOG("-- allocated decoder with buffer size of %zu (%zu + %u + %u)\n", - sz, sizeof(heatshrink_decoder), (1 << window_sz2), input_buffer_size); - return hsd; -} - -void heatshrink_decoder_free(heatshrink_decoder *hsd) { - size_t buffers_sz = (1 << hsd->window_sz2) + hsd->input_buffer_size; - size_t sz = sizeof(heatshrink_decoder) + buffers_sz; - HEATSHRINK_FREE(hsd, sz); - (void)sz; /* may not be used by free */ -} -#endif - -void heatshrink_decoder_reset(heatshrink_decoder *hsd) { - size_t buf_sz = 1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd); - size_t input_sz = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd); - memset(hsd->buffers, 0, buf_sz + input_sz); - hsd->state = HSDS_EMPTY; - hsd->input_size = 0; - hsd->input_index = 0; - hsd->bit_index = 0x00; - hsd->current_byte = 0x00; - hsd->output_count = 0; - hsd->output_index = 0; - hsd->head_index = 0; - hsd->bit_accumulator = 0x00000000; -} - -/* Copy SIZE bytes into the decoder's input buffer, if it will fit. */ -HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, - uint8_t *in_buf, size_t size, size_t *input_size) { - if ((hsd == NULL) || (in_buf == NULL) || (input_size == NULL)) { - return HSDR_SINK_ERROR_NULL; - } - - size_t rem = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd) - hsd->input_size; - if (rem == 0) { - *input_size = 0; - return HSDR_SINK_FULL; - } - - size = rem < size ? rem : size; - LOG("-- sinking %zd bytes\n", size); - /* copy into input buffer (at head of buffers) */ - memcpy(&hsd->buffers[hsd->input_size], in_buf, size); - hsd->input_size += size; - if (hsd->state == HSDS_EMPTY) { - hsd->state = HSDS_INPUT_AVAILABLE; - hsd->input_index = 0; - } - *input_size = size; - return HSDR_SINK_OK; -} - - -/***************** - * Decompression * - *****************/ - -#define BACKREF_COUNT_BITS(HSD) (HEATSHRINK_DECODER_LOOKAHEAD_BITS(HSD)) -#define BACKREF_INDEX_BITS(HSD) (HEATSHRINK_DECODER_WINDOW_BITS(HSD)) - -// States -static HSD_state st_input_available(heatshrink_decoder *hsd); -static HSD_state st_yield_literal(heatshrink_decoder *hsd, - output_info *oi); -static HSD_state st_backref_index_msb(heatshrink_decoder *hsd); -static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd); -static HSD_state st_backref_count_msb(heatshrink_decoder *hsd); -static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd); -static HSD_state st_yield_backref(heatshrink_decoder *hsd, - output_info *oi); -static HSD_state st_check_for_input(heatshrink_decoder *hsd); - -HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, - uint8_t *out_buf, size_t out_buf_size, size_t *output_size) { - if ((hsd == NULL) || (out_buf == NULL) || (output_size == NULL)) { - return HSDR_POLL_ERROR_NULL; - } - *output_size = 0; - - output_info oi; - oi.buf = out_buf; - oi.buf_size = out_buf_size; - oi.output_size = output_size; - - while (1) { - LOG("-- poll, state is %d (%s), input_size %d\n", - hsd->state, state_names[hsd->state], hsd->input_size); - uint8_t in_state = hsd->state; - switch (in_state) { - case HSDS_EMPTY: - return HSDR_POLL_EMPTY; - case HSDS_INPUT_AVAILABLE: - hsd->state = st_input_available(hsd); - break; - case HSDS_YIELD_LITERAL: - hsd->state = st_yield_literal(hsd, &oi); - break; - case HSDS_BACKREF_INDEX_MSB: - hsd->state = st_backref_index_msb(hsd); - break; - case HSDS_BACKREF_INDEX_LSB: - hsd->state = st_backref_index_lsb(hsd); - break; - case HSDS_BACKREF_COUNT_MSB: - hsd->state = st_backref_count_msb(hsd); - break; - case HSDS_BACKREF_COUNT_LSB: - hsd->state = st_backref_count_lsb(hsd); - break; - case HSDS_YIELD_BACKREF: - hsd->state = st_yield_backref(hsd, &oi); - break; - case HSDS_CHECK_FOR_MORE_INPUT: - hsd->state = st_check_for_input(hsd); - break; - default: - return HSDR_POLL_ERROR_UNKNOWN; - } - - /* If the current state cannot advance, check if input or output - * buffer are exhausted. */ - if (hsd->state == in_state) { - if (*output_size == out_buf_size) { return HSDR_POLL_MORE; } - return HSDR_POLL_EMPTY; - } - } -} - -static HSD_state st_input_available(heatshrink_decoder *hsd) { - uint32_t bits = get_bits(hsd, 1); // get tag bit - if (bits) { - return HSDS_YIELD_LITERAL; - } else if (HEATSHRINK_DECODER_WINDOW_BITS(hsd) > 8) { - return HSDS_BACKREF_INDEX_MSB; - } else { - hsd->output_index = 0; - return HSDS_BACKREF_INDEX_LSB; - } -} - -static HSD_state st_yield_literal(heatshrink_decoder *hsd, - output_info *oi) { - /* Emit a repeated section from the window buffer, and add it (again) - * to the window buffer. (Note that the repetition can include - * itself.)*/ - if (*oi->output_size < oi->buf_size) { - uint32_t byte = get_bits(hsd, 8); - if (byte == NO_BITS) { return HSDS_YIELD_LITERAL; } /* out of input */ - uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; - uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; - uint8_t c = byte & 0xFF; - LOG("-- emitting literal byte 0x%02x ('%c')\n", c, isprint(c) ? c : '.'); - buf[hsd->head_index++ & mask] = c; - push_byte(hsd, oi, c); - return HSDS_CHECK_FOR_MORE_INPUT; - } else { - return HSDS_YIELD_LITERAL; - } -} - -static HSD_state st_backref_index_msb(heatshrink_decoder *hsd) { - uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); - ASSERT(bit_ct > 8); - uint32_t bits = get_bits(hsd, bit_ct - 8); - LOG("-- backref index (msb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_MSB; } - hsd->output_index = bits << 8; - return HSDS_BACKREF_INDEX_LSB; -} - -static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd) { - uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); - uint32_t bits = get_bits(hsd, bit_ct < 8 ? bit_ct : 8); - LOG("-- backref index (lsb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_LSB; } - hsd->output_index |= bits; - hsd->output_index++; - uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); - hsd->output_count = 0; - return (br_bit_ct > 8) ? HSDS_BACKREF_COUNT_MSB : HSDS_BACKREF_COUNT_LSB; -} - -static HSD_state st_backref_count_msb(heatshrink_decoder *hsd) { - uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); - ASSERT(br_bit_ct > 8); - uint32_t bits = get_bits(hsd, br_bit_ct - 8); - LOG("-- backref count (msb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_MSB; } - hsd->output_count = bits << 8; - return HSDS_BACKREF_COUNT_LSB; -} - -static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd) { - uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); - uint32_t bits = get_bits(hsd, br_bit_ct < 8 ? br_bit_ct : 8); - LOG("-- backref count (lsb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_LSB; } - hsd->output_count |= bits; - hsd->output_count++; - return HSDS_YIELD_BACKREF; -} - -static HSD_state st_yield_backref(heatshrink_decoder *hsd, - output_info *oi) { - size_t count = oi->buf_size - *oi->output_size; - if (count > 0) { - if (hsd->output_count < count) count = hsd->output_count; - uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; - uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; - uint16_t neg_offset = hsd->output_index; - LOG("-- emitting %zu bytes from -%u bytes back\n", count, neg_offset); - ASSERT(neg_offset < mask + 1); - ASSERT(count <= 1 << BACKREF_COUNT_BITS(hsd)); - - for (size_t i=0; ihead_index - neg_offset) & mask]; - push_byte(hsd, oi, c); - buf[hsd->head_index & mask] = c; - hsd->head_index++; - LOG(" -- ++ 0x%02x\n", c); - } - hsd->output_count -= count; - if (hsd->output_count == 0) { return HSDS_CHECK_FOR_MORE_INPUT; } - } - return HSDS_YIELD_BACKREF; -} - -static HSD_state st_check_for_input(heatshrink_decoder *hsd) { - return (hsd->input_size == 0) ? HSDS_EMPTY : HSDS_INPUT_AVAILABLE; -} - -/* Get the next COUNT bits from the input buffer, saving incremental progress. - * Returns NO_BITS on end of input, or if more than 31 bits are requested. */ -static uint32_t get_bits(heatshrink_decoder *hsd, uint8_t count) { - if (count > 31) { return NO_BITS; } - LOG("-- popping %u bit(s)\n", count); - - /* If we aren't able to get COUNT bits, suspend immediately, because we - * don't track how many bits of COUNT we've accumulated before suspend. */ - if (hsd->input_size == 0) { - if (hsd->bit_index < (1 << (count - 1))) { return NO_BITS; } - } - - for (int i = 0; i < count; i++) { - if (hsd->bit_index == 0x00) { - if (hsd->input_size == 0) { - LOG(" -- out of bits, suspending w/ accumulator of %u (0x%02x)\n", - hsd->bit_accumulator, hsd->bit_accumulator); - return NO_BITS; - } - hsd->current_byte = hsd->buffers[hsd->input_index++]; - LOG(" -- pulled byte 0x%02x\n", hsd->current_byte); - if (hsd->input_index == hsd->input_size) { - hsd->input_index = 0; /* input is exhausted */ - hsd->input_size = 0; - } - hsd->bit_index = 0x80; - } - hsd->bit_accumulator <<= 1; - if (hsd->current_byte & hsd->bit_index) { - hsd->bit_accumulator |= 0x01; - if (0) { - LOG(" -- got 1, accumulator 0x%04x, bit_index 0x%02x\n", - hsd->bit_accumulator, hsd->bit_index); - } - } else { - if (0) { - LOG(" -- got 0, accumulator 0x%04x, bit_index 0x%02x\n", - hsd->bit_accumulator, hsd->bit_index); - } - } - hsd->bit_index >>= 1; - } - - uint32_t res = 0; - res = hsd->bit_accumulator; - hsd->bit_accumulator = 0x00000000; - if (count > 1) { LOG(" -- accumulated %08x\n", res); } - return res; -} - -HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd) { - if (hsd == NULL) { return HSDR_FINISH_ERROR_NULL; } - switch (hsd->state) { - case HSDS_EMPTY: - return HSDR_FINISH_DONE; - - /* If we want to finish with no input, but are in these states, it's - * because the 0-bit padding to the last byte looks like a backref - * marker bit followed by all 0s for index and count bits. */ - case HSDS_BACKREF_INDEX_LSB: - case HSDS_BACKREF_INDEX_MSB: - case HSDS_BACKREF_COUNT_LSB: - case HSDS_BACKREF_COUNT_MSB: - return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; - /* fall through */ - default: - return HSDR_FINISH_MORE; - } -} - -static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte) { - LOG(" -- pushing byte: 0x%02x ('%c')\n", byte, isprint(byte) ? byte : '.'); - oi->buf[(*oi->output_size)++] = byte; - (void)hsd; -} diff --git a/Modem/compression/heatshrink_decoder.h b/Modem/compression/heatshrink_decoder.h deleted file mode 100644 index c1eb144..0000000 --- a/Modem/compression/heatshrink_decoder.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef HEATSHRINK_DECODER_H -#define HEATSHRINK_DECODER_H - -#include -#include -#include "heatshrink_common.h" -#include "heatshrink_config.h" - -typedef enum { - HSDR_SINK_OK, /* data sunk, ready to poll */ - HSDR_SINK_FULL, /* out of space in internal buffer */ - HSDR_SINK_ERROR_NULL=-1, /* NULL argument */ -} HSD_sink_res; - -typedef enum { - HSDR_POLL_EMPTY, /* input exhausted */ - HSDR_POLL_MORE, /* more data remaining, call again w/ fresh output buffer */ - HSDR_POLL_ERROR_NULL=-1, /* NULL arguments */ - HSDR_POLL_ERROR_UNKNOWN=-2, -} HSD_poll_res; - -typedef enum { - HSDR_FINISH_DONE, /* output is done */ - HSDR_FINISH_MORE, /* more output remains */ - HSDR_FINISH_ERROR_NULL=-1, /* NULL arguments */ -} HSD_finish_res; - -#if HEATSHRINK_DYNAMIC_ALLOC -#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(BUF) \ - ((BUF)->input_buffer_size) -#define HEATSHRINK_DECODER_WINDOW_BITS(BUF) \ - ((BUF)->window_sz2) -#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ - ((BUF)->lookahead_sz2) -#else -#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_) \ - HEATSHRINK_STATIC_INPUT_BUFFER_SIZE -#define HEATSHRINK_DECODER_WINDOW_BITS(_) \ - (HEATSHRINK_STATIC_WINDOW_BITS) -#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ - (HEATSHRINK_STATIC_LOOKAHEAD_BITS) -#endif - -typedef struct { - uint16_t input_size; /* bytes in input buffer */ - uint16_t input_index; /* offset to next unprocessed input byte */ - uint16_t output_count; /* how many bytes to output */ - uint16_t output_index; /* index for bytes to output */ - uint16_t head_index; /* head of window buffer */ - uint16_t bit_accumulator; - uint8_t state; /* current state machine node */ - uint8_t current_byte; /* current byte of input */ - uint8_t bit_index; /* current bit index */ - -#if HEATSHRINK_DYNAMIC_ALLOC - /* Fields that are only used if dynamically allocated. */ - uint8_t window_sz2; /* window buffer bits */ - uint8_t lookahead_sz2; /* lookahead bits */ - uint16_t input_buffer_size; /* input buffer size */ - - /* Input buffer, then expansion window buffer */ - uint8_t buffers[]; -#else - /* Input buffer, then expansion window buffer */ - uint8_t buffers[(1 << HEATSHRINK_DECODER_WINDOW_BITS(_)) - + HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_)]; -#endif -} heatshrink_decoder; - -#if HEATSHRINK_DYNAMIC_ALLOC -/* Allocate a decoder with an input buffer of INPUT_BUFFER_SIZE bytes, - * an expansion buffer size of 2^WINDOW_SZ2, and a lookahead - * size of 2^lookahead_sz2. (The window buffer and lookahead sizes - * must match the settings used when the data was compressed.) - * Returns NULL on error. */ -heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, - uint8_t expansion_buffer_sz2, uint8_t lookahead_sz2); - -/* Free a decoder. */ -void heatshrink_decoder_free(heatshrink_decoder *hsd); -#endif - -/* Reset a decoder. */ -void heatshrink_decoder_reset(heatshrink_decoder *hsd); - -/* Sink at most SIZE bytes from IN_BUF into the decoder. *INPUT_SIZE is set to - * indicate how many bytes were actually sunk (in case a buffer was filled). */ -HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, - uint8_t *in_buf, size_t size, size_t *input_size); - -/* Poll for output from the decoder, copying at most OUT_BUF_SIZE bytes into - * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ -HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, - uint8_t *out_buf, size_t out_buf_size, size_t *output_size); - -/* Notify the dencoder that the input stream is finished. - * If the return value is HSDR_FINISH_MORE, there is still more output, so - * call heatshrink_decoder_poll and repeat. */ -HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd); - -#endif diff --git a/Modem/compression/heatshrink_encoder.c b/Modem/compression/heatshrink_encoder.c deleted file mode 100644 index 9eed0d1..0000000 --- a/Modem/compression/heatshrink_encoder.c +++ /dev/null @@ -1,640 +0,0 @@ -#include -#include -#include -#include "heatshrink_encoder.h" - -#include "cfg/debug.h" // Debug configuration from BertOS - -typedef enum { - HSES_NOT_FULL, /* input buffer not full enough */ - HSES_FILLED, /* buffer is full */ - HSES_SEARCH, /* searching for patterns */ - HSES_YIELD_TAG_BIT, /* yield tag bit */ - HSES_YIELD_LITERAL, /* emit literal byte */ - HSES_YIELD_BR_INDEX, /* yielding backref index */ - HSES_YIELD_BR_LENGTH, /* yielding backref length */ - HSES_SAVE_BACKLOG, /* copying buffer to backlog */ - HSES_FLUSH_BITS, /* flush bit buffer */ - HSES_DONE, /* done */ -} HSE_state; - -#if HEATSHRINK_DEBUGGING_LOGS -#include -#include -#include -#define LOG(...) fprintf(stderr, __VA_ARGS__) -#define ASSERT(X) assert(X) -static const char *state_names[] = { - "not_full", - "filled", - "search", - "yield_tag_bit", - "yield_literal", - "yield_br_index", - "yield_br_length", - "save_backlog", - "flush_bits", - "done", -}; -#else -#define LOG(...) /* no-op */ -//#define ASSERT(X) /* no-op */ -#endif - -// Encoder flags -enum { - FLAG_IS_FINISHING = 0x01, - FLAG_HAS_LITERAL = 0x02, - FLAG_ON_FINAL_LITERAL = 0x04, - FLAG_BACKLOG_IS_PARTIAL = 0x08, - FLAG_BACKLOG_IS_FILLED = 0x10, -}; - -typedef struct { - uint8_t *buf; /* output buffer */ - size_t buf_size; /* buffer size */ - size_t *output_size; /* bytes pushed to buffer, so far */ -} output_info; - -#define MATCH_NOT_FOUND ((uint16_t)-1) - -static uint16_t get_input_offset(heatshrink_encoder *hse); -static uint16_t get_input_buffer_size(heatshrink_encoder *hse); -static uint16_t get_lookahead_size(heatshrink_encoder *hse); -static void add_tag_bit(heatshrink_encoder *hse, output_info *oi, uint8_t tag); -static int can_take_byte(output_info *oi); -static int is_finishing(heatshrink_encoder *hse); -static int backlog_is_partial(heatshrink_encoder *hse); -static int backlog_is_filled(heatshrink_encoder *hse); -static int on_final_literal(heatshrink_encoder *hse); -static void save_backlog(heatshrink_encoder *hse); -static int has_literal(heatshrink_encoder *hse); - -/* Push COUNT (max 8) bits to the output buffer, which has room. */ -static void push_bits(heatshrink_encoder *hse, uint8_t count, uint8_t bits, - output_info *oi); -static uint8_t push_outgoing_bits(heatshrink_encoder *hse, output_info *oi); -static void push_literal_byte(heatshrink_encoder *hse, output_info *oi); - -#if HEATSHRINK_DYNAMIC_ALLOC -heatshrink_encoder *heatshrink_encoder_alloc(uint8_t window_sz2, - uint8_t lookahead_sz2) { - if ((window_sz2 < HEATSHRINK_MIN_WINDOW_BITS) || - (window_sz2 > HEATSHRINK_MAX_WINDOW_BITS) || - (lookahead_sz2 < HEATSHRINK_MIN_LOOKAHEAD_BITS) || - (lookahead_sz2 > window_sz2)) { - return NULL; - } - - /* Note: 2 * the window size is used because the buffer needs to fit - * (1 << window_sz2) bytes for the current input, and an additional - * (1 << window_sz2) bytes for the previous buffer of input, which - * will be scanned for useful backreferences. */ - size_t buf_sz = (2 << window_sz2); - - //kprintf("Trying to allocate: %d\n", buf_sz); - heatshrink_encoder *hse = HEATSHRINK_MALLOC(sizeof(*hse) + buf_sz); - if (hse == NULL) { return NULL; } - hse->window_sz2 = window_sz2; - hse->lookahead_sz2 = lookahead_sz2; - heatshrink_encoder_reset(hse); - -#if HEATSHRINK_USE_INDEX - size_t index_sz = buf_sz*sizeof(uint16_t); - hse->search_index = HEATSHRINK_MALLOC(index_sz + sizeof(struct hs_index)); - if (hse->search_index == NULL) { - HEATSHRINK_FREE(hse, sizeof(*hse) + buf_sz); - return NULL; - } - hse->search_index->size = index_sz; -#endif - - LOG("-- allocated encoder with buffer size of %zu (%u byte input size)\n", - buf_sz, get_input_buffer_size(hse)); - return hse; -} - -void heatshrink_encoder_free(heatshrink_encoder *hse) { - size_t buf_sz = (2 << HEATSHRINK_ENCODER_WINDOW_BITS(hse)); -#if HEATSHRINK_USE_INDEX - size_t index_sz = sizeof(struct hs_index) + hse->search_index->size; - HEATSHRINK_FREE(hse->search_index, index_sz); - (void)index_sz; -#endif - HEATSHRINK_FREE(hse, sizeof(heatshrink_encoder) + buf_sz); - (void)buf_sz; -} -#endif - -void heatshrink_encoder_reset(heatshrink_encoder *hse) { - size_t buf_sz = (2 << HEATSHRINK_ENCODER_WINDOW_BITS(hse)); - memset(hse->buffer, 0, buf_sz); - hse->input_size = 0; - hse->state = HSES_NOT_FULL; - hse->match_scan_index = 0; - hse->flags = 0; - hse->bit_index = 0x80; - hse->current_byte = 0x00; - hse->match_length = 0; - - hse->outgoing_bits = 0x0000; - hse->outgoing_bits_count = 0; - - #ifdef LOOP_DETECT - hse->loop_detect = (uint32_t)-1; - #endif -} - -HSE_sink_res heatshrink_encoder_sink(heatshrink_encoder *hse, - uint8_t *in_buf, size_t size, size_t *input_size) { - if ((hse == NULL) || (in_buf == NULL) || (input_size == NULL)) { - return HSER_SINK_ERROR_NULL; - } - - /* Sinking more content after saying the content is done, tsk tsk */ - if (is_finishing(hse)) { return HSER_SINK_ERROR_MISUSE; } - - /* Sinking more content before processing is done */ - if (hse->state != HSES_NOT_FULL) { return HSER_SINK_ERROR_MISUSE; } - - uint16_t write_offset = get_input_offset(hse) + hse->input_size; - uint16_t ibs = get_input_buffer_size(hse); - uint16_t rem = ibs - hse->input_size; - uint16_t cp_sz = rem < size ? rem : size; - - memcpy(&hse->buffer[write_offset], in_buf, cp_sz); - *input_size = cp_sz; - hse->input_size += cp_sz; - - LOG("-- sunk %u bytes (of %zu) into encoder at %d, input buffer now has %u\n", - cp_sz, size, write_offset, hse->input_size); - if (cp_sz == rem) { - LOG("-- internal buffer is now full\n"); - hse->state = HSES_FILLED; - } - - return HSER_SINK_OK; -} - - -/*************** - * Compression * - ***************/ - -static uint16_t find_longest_match(heatshrink_encoder *hse, uint16_t start, - uint16_t end, const uint16_t maxlen, uint16_t *match_length); -static void do_indexing(heatshrink_encoder *hse); - -static HSE_state st_step_search(heatshrink_encoder *hse); -static HSE_state st_yield_tag_bit(heatshrink_encoder *hse, - output_info *oi); -static HSE_state st_yield_literal(heatshrink_encoder *hse, - output_info *oi); -static HSE_state st_yield_br_index(heatshrink_encoder *hse, - output_info *oi); -static HSE_state st_yield_br_length(heatshrink_encoder *hse, - output_info *oi); -static HSE_state st_save_backlog(heatshrink_encoder *hse); -static HSE_state st_flush_bit_buffer(heatshrink_encoder *hse, - output_info *oi); - -HSE_poll_res heatshrink_encoder_poll(heatshrink_encoder *hse, - uint8_t *out_buf, size_t out_buf_size, size_t *output_size) { - if ((hse == NULL) || (out_buf == NULL) || (output_size == NULL)) { - return HSER_POLL_ERROR_NULL; - } - if (out_buf_size == 0) { - LOG("-- MISUSE: output buffer size is 0\n"); - return HSER_POLL_ERROR_MISUSE; - } - *output_size = 0; - - output_info oi; - oi.buf = out_buf; - oi.buf_size = out_buf_size; - oi.output_size = output_size; - - while (1) { - LOG("-- polling, state %u (%s), flags 0x%02x\n", - hse->state, state_names[hse->state], hse->flags); - - uint8_t in_state = hse->state; - switch (in_state) { - case HSES_NOT_FULL: - return HSER_POLL_EMPTY; - case HSES_FILLED: - do_indexing(hse); - hse->state = HSES_SEARCH; - break; - case HSES_SEARCH: - hse->state = st_step_search(hse); - break; - case HSES_YIELD_TAG_BIT: - hse->state = st_yield_tag_bit(hse, &oi); - break; - case HSES_YIELD_LITERAL: - hse->state = st_yield_literal(hse, &oi); - break; - case HSES_YIELD_BR_INDEX: - hse->state = st_yield_br_index(hse, &oi); - break; - case HSES_YIELD_BR_LENGTH: - hse->state = st_yield_br_length(hse, &oi); - break; - case HSES_SAVE_BACKLOG: - hse->state = st_save_backlog(hse); - break; - case HSES_FLUSH_BITS: - hse->state = st_flush_bit_buffer(hse, &oi); - case HSES_DONE: - return HSER_POLL_EMPTY; - default: - LOG("-- bad state %s\n", state_names[hse->state]); - return HSER_POLL_ERROR_MISUSE; - } - - if (hse->state == in_state) { - /* Check if output buffer is exhausted. */ - if (*output_size == out_buf_size) return HSER_POLL_MORE; - } - } -} - -HSE_finish_res heatshrink_encoder_finish(heatshrink_encoder *hse) { - if (hse == NULL) { return HSER_FINISH_ERROR_NULL; } - LOG("-- setting is_finishing flag\n"); - hse->flags |= FLAG_IS_FINISHING; - if (hse->state == HSES_NOT_FULL) { hse->state = HSES_FILLED; } - return hse->state == HSES_DONE ? HSER_FINISH_DONE : HSER_FINISH_MORE; -} - -static HSE_state st_step_search(heatshrink_encoder *hse) { - uint16_t window_length = get_input_buffer_size(hse); - uint16_t lookahead_sz = get_lookahead_size(hse); - uint16_t msi = hse->match_scan_index; - LOG("## step_search, scan @ +%d (%d/%d), input size %d\n", - msi, hse->input_size + msi, 2*window_length, hse->input_size); - - bool fin = is_finishing(hse); - if (msi >= hse->input_size - (fin ? 0 : lookahead_sz)) { - /* Current search buffer is exhausted, copy it into the - * backlog and await more input. */ - LOG("-- end of search @ %d, saving backlog\n", msi); - return HSES_SAVE_BACKLOG; - } - - uint16_t input_offset = get_input_offset(hse); - uint16_t end = input_offset + msi; - - uint16_t start = 0; - if (backlog_is_filled(hse)) { /* last WINDOW_LENGTH bytes */ - start = end - window_length + 1; - } else if (backlog_is_partial(hse)) { /* clamp to available data */ - start = end - window_length + 1; - if (start < lookahead_sz) { start = lookahead_sz; } - } else { /* only scan available input */ - start = input_offset; - } - - uint16_t max_possible = lookahead_sz; - if (hse->input_size - msi < lookahead_sz) { - max_possible = hse->input_size - msi; - } - - uint16_t match_length = 0; - uint16_t match_pos = find_longest_match(hse, - start, end, max_possible, &match_length); - - if (match_pos == MATCH_NOT_FOUND) { - LOG("ss Match not found\n"); - hse->match_scan_index++; - hse->flags |= FLAG_HAS_LITERAL; - hse->match_length = 0; - return HSES_YIELD_TAG_BIT; - } else { - LOG("ss Found match of %d bytes at %d\n", match_length, match_pos); - hse->match_pos = match_pos; - hse->match_length = match_length; - - return HSES_YIELD_TAG_BIT; - } -} - -static HSE_state st_yield_tag_bit(heatshrink_encoder *hse, - output_info *oi) { - if (can_take_byte(oi)) { - if (hse->match_length == 0) { - add_tag_bit(hse, oi, HEATSHRINK_LITERAL_MARKER); - return HSES_YIELD_LITERAL; - } else { - add_tag_bit(hse, oi, HEATSHRINK_BACKREF_MARKER); - hse->outgoing_bits = hse->match_pos - 1; - hse->outgoing_bits_count = HEATSHRINK_ENCODER_WINDOW_BITS(hse); - return HSES_YIELD_BR_INDEX; - } - } else { - return HSES_YIELD_TAG_BIT; /* output is full, continue */ - } -} - -static HSE_state st_yield_literal(heatshrink_encoder *hse, - output_info *oi) { - if (can_take_byte(oi)) { - push_literal_byte(hse, oi); - hse->flags &= ~FLAG_HAS_LITERAL; - if (on_final_literal(hse)) { return HSES_FLUSH_BITS; } - return hse->match_length > 0 ? HSES_YIELD_TAG_BIT : HSES_SEARCH; - } else { - return HSES_YIELD_LITERAL; - } -} - -static HSE_state st_yield_br_index(heatshrink_encoder *hse, - output_info *oi) { - if (can_take_byte(oi)) { - LOG("-- yielding backref index %u\n", hse->match_pos); - if (push_outgoing_bits(hse, oi) > 0) { - return HSES_YIELD_BR_INDEX; /* continue */ - } else { - hse->outgoing_bits = hse->match_length - 1; - hse->outgoing_bits_count = HEATSHRINK_ENCODER_LOOKAHEAD_BITS(hse); - return HSES_YIELD_BR_LENGTH; /* done */ - } - } else { - return HSES_YIELD_BR_INDEX; /* continue */ - } -} - -static HSE_state st_yield_br_length(heatshrink_encoder *hse, - output_info *oi) { - if (can_take_byte(oi)) { - LOG("-- yielding backref length %u\n", hse->match_length); - if (push_outgoing_bits(hse, oi) > 0) { - return HSES_YIELD_BR_LENGTH; - } else { - hse->match_scan_index += hse->match_length; - hse->match_length = 0; - return HSES_SEARCH; - } - } else { - return HSES_YIELD_BR_LENGTH; - } -} - -static HSE_state st_save_backlog(heatshrink_encoder *hse) { - if (is_finishing(hse)) { - /* copy remaining literal (if necessary) */ - if (has_literal(hse)) { - hse->flags |= FLAG_ON_FINAL_LITERAL; - return HSES_YIELD_TAG_BIT; - } else { - return HSES_FLUSH_BITS; - } - } else { - LOG("-- saving backlog\n"); - save_backlog(hse); - return HSES_NOT_FULL; - } -} - -static HSE_state st_flush_bit_buffer(heatshrink_encoder *hse, - output_info *oi) { - if (hse->bit_index == 0x80) { - LOG("-- done!\n"); - return HSES_DONE; - } else if (can_take_byte(oi)) { - LOG("-- flushing remaining byte (bit_index == 0x%02x)\n", hse->bit_index); - oi->buf[(*oi->output_size)++] = hse->current_byte; - LOG("-- done!\n"); - return HSES_DONE; - } else { - return HSES_FLUSH_BITS; - } -} - -static void add_tag_bit(heatshrink_encoder *hse, output_info *oi, uint8_t tag) { - LOG("-- adding tag bit: %d\n", tag); - push_bits(hse, 1, tag, oi); -} - -static uint16_t get_input_offset(heatshrink_encoder *hse) { - return get_input_buffer_size(hse); -} - -static uint16_t get_input_buffer_size(heatshrink_encoder *hse) { - return (1 << HEATSHRINK_ENCODER_WINDOW_BITS(hse)); - (void)hse; -} - -static uint16_t get_lookahead_size(heatshrink_encoder *hse) { - return (1 << HEATSHRINK_ENCODER_LOOKAHEAD_BITS(hse)); - (void)hse; -} - -static void do_indexing(heatshrink_encoder *hse) { -#if HEATSHRINK_USE_INDEX - /* Build an index array I that contains flattened linked lists - * for the previous instances of every byte in the buffer. - * - * For example, if buf[200] == 'x', then index[200] will either - * be an offset i such that buf[i] == 'x', or a negative offset - * to indicate end-of-list. This significantly speeds up matching, - * while only using sizeof(uint16_t)*sizeof(buffer) bytes of RAM. - * - * Future optimization options: - * 1. Since any negative value represents end-of-list, the other - * 15 bits could be used to improve the index dynamically. - * - * 2. Likewise, the last lookahead_sz bytes of the index will - * not be usable, so temporary data could be stored there to - * dynamically improve the index. - * */ - struct hs_index *hsi = HEATSHRINK_ENCODER_INDEX(hse); - uint16_t last[256]; - memset(last, 0xFF, sizeof(last)); - - uint8_t * const data = hse->buffer; - int16_t * const index = hsi->index; - - const uint16_t input_offset = get_input_offset(hse); - const uint16_t end = input_offset + hse->input_size; - - for (uint16_t i=0; iflags & FLAG_IS_FINISHING; -} - -static int backlog_is_partial(heatshrink_encoder *hse) { - return hse->flags & FLAG_BACKLOG_IS_PARTIAL; -} - -static int backlog_is_filled(heatshrink_encoder *hse) { - return hse->flags & FLAG_BACKLOG_IS_FILLED; -} - -static int on_final_literal(heatshrink_encoder *hse) { - return hse->flags & FLAG_ON_FINAL_LITERAL; -} - -static int has_literal(heatshrink_encoder *hse) { - return (hse->flags & FLAG_HAS_LITERAL); -} - -static int can_take_byte(output_info *oi) { - return *oi->output_size < oi->buf_size; -} - -/* Return the longest match for the bytes at buf[end:end+maxlen] between - * buf[start] and buf[end-1]. If no match is found, return -1. */ -static uint16_t find_longest_match(heatshrink_encoder *hse, uint16_t start, - uint16_t end, const uint16_t maxlen, uint16_t *match_length) { - LOG("-- scanning for match of buf[%u:%u] between buf[%u:%u] (max %u bytes)\n", - end, end + maxlen, start, end + maxlen - 1, maxlen); - uint8_t *buf = hse->buffer; - - uint16_t match_maxlen = 0; - uint16_t match_index = MATCH_NOT_FOUND; - const uint16_t break_even_point = 3; - uint16_t len = 0; - uint8_t * const needlepoint = &buf[end]; -#if HEATSHRINK_USE_INDEX - struct hs_index *hsi = HEATSHRINK_ENCODER_INDEX(hse); - int16_t pos = hsi->index[end]; - - while (pos >= start) { - uint8_t * const pospoint = &buf[pos]; - len = 0; - - for (len = 1; len < maxlen; len++) { - if (pospoint[len] != needlepoint[len]) break; - } - - if (len > match_maxlen) { - match_maxlen = len; - match_index = pos; - if (len == maxlen) { break; } /* won't find better */ - } - pos = hsi->index[pos]; - } -#else - for (int16_t pos=end - 1; pos >= (int16_t)start; pos--) { - for (len=0; len cmp buf[%d] == 0x%02x against %02x (start %u)\n", - pos + len, buf[pos + len], needlepoint[len], start); - } - if (buf[pos + len] != needlepoint[len]) { break; } - } - if (len > match_maxlen) { - match_maxlen = len; - match_index = pos; - if (len == maxlen) { break; } /* don't keep searching */ - } - } -#endif - - if (match_maxlen >= break_even_point) { - LOG("-- best match: %u bytes at -%u\n", - match_maxlen, end - match_index); - *match_length = match_maxlen; - return end - match_index; - } - LOG("-- none found\n"); - return MATCH_NOT_FOUND; -} - -static uint8_t push_outgoing_bits(heatshrink_encoder *hse, output_info *oi) { - uint8_t count = 0; - uint8_t bits = 0; - if (hse->outgoing_bits_count > 8) { - count = 8; - bits = hse->outgoing_bits >> (hse->outgoing_bits_count - 8); - } else { - count = hse->outgoing_bits_count; - bits = hse->outgoing_bits; - } - - if (count > 0) { - LOG("-- pushing %d outgoing bits: 0x%02x\n", count, bits); - push_bits(hse, count, bits, oi); - hse->outgoing_bits_count -= count; - } - return count; -} - -/* Push COUNT (max 8) bits to the output buffer, which has room. - * Bytes are set from the lowest bits, up. */ -static void push_bits(heatshrink_encoder *hse, uint8_t count, uint8_t bits, - output_info *oi) { - ASSERT(count <= 8); - LOG("++ push_bits: %d bits, input of 0x%02x\n", count, bits); - - /* If adding a whole byte and at the start of a new output byte, - * just push it through whole and skip the bit IO loop. */ - if (count == 8 && hse->bit_index == 0x80) { - oi->buf[(*oi->output_size)++] = bits; - } else { - for (int i=count - 1; i>=0; i--) { - bool bit = bits & (1 << i); - if (bit) { hse->current_byte |= hse->bit_index; } - if (0) { - LOG(" -- setting bit %d at bit index 0x%02x, byte => 0x%02x\n", - bit ? 1 : 0, hse->bit_index, hse->current_byte); - } - hse->bit_index >>= 1; - if (hse->bit_index == 0x00) { - hse->bit_index = 0x80; - LOG(" > pushing byte 0x%02x\n", hse->current_byte); - oi->buf[(*oi->output_size)++] = hse->current_byte; - hse->current_byte = 0x00; - } - } - } -} - -static void push_literal_byte(heatshrink_encoder *hse, output_info *oi) { - uint16_t processed_offset = hse->match_scan_index - 1; - uint16_t input_offset = get_input_offset(hse) + processed_offset; - uint8_t c = hse->buffer[input_offset]; - LOG("-- yielded literal byte 0x%02x ('%c') from +%d\n", - c, isprint(c) ? c : '.', input_offset); - push_bits(hse, 8, c, oi); -} - -static void save_backlog(heatshrink_encoder *hse) { - size_t input_buf_sz = get_input_buffer_size(hse); - - uint16_t msi = hse->match_scan_index; - - /* Copy processed data to beginning of buffer, so it can be - * used for future matches. Don't bother checking whether the - * input is less than the maximum size, because if it isn't, - * we're done anyway. */ - uint16_t rem = input_buf_sz - msi; // unprocessed bytes - uint16_t shift_sz = input_buf_sz + rem; - - memmove(&hse->buffer[0], - &hse->buffer[input_buf_sz - rem], - shift_sz); - - if (backlog_is_partial(hse)) { - /* The whole backlog is filled in now, so include it in scans. */ - hse->flags |= FLAG_BACKLOG_IS_FILLED; - } else { - /* Include backlog, except for the first lookahead_sz bytes, which - * are still undefined. */ - hse->flags |= FLAG_BACKLOG_IS_PARTIAL; - } - hse->match_scan_index = 0; - hse->input_size -= input_buf_sz - rem; -} diff --git a/Modem/compression/heatshrink_encoder.h b/Modem/compression/heatshrink_encoder.h deleted file mode 100644 index 18c1773..0000000 --- a/Modem/compression/heatshrink_encoder.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef HEATSHRINK_ENCODER_H -#define HEATSHRINK_ENCODER_H - -#include -#include -#include "heatshrink_common.h" -#include "heatshrink_config.h" - -typedef enum { - HSER_SINK_OK, /* data sunk into input buffer */ - HSER_SINK_ERROR_NULL=-1, /* NULL argument */ - HSER_SINK_ERROR_MISUSE=-2, /* API misuse */ -} HSE_sink_res; - -typedef enum { - HSER_POLL_EMPTY, /* input exhausted */ - HSER_POLL_MORE, /* poll again for more output */ - HSER_POLL_ERROR_NULL=-1, /* NULL argument */ - HSER_POLL_ERROR_MISUSE=-2, /* API misuse */ -} HSE_poll_res; - -typedef enum { - HSER_FINISH_DONE, /* encoding is complete */ - HSER_FINISH_MORE, /* more output remaining; use poll */ - HSER_FINISH_ERROR_NULL=-1, /* NULL argument */ -} HSE_finish_res; - -#if HEATSHRINK_DYNAMIC_ALLOC -#define HEATSHRINK_ENCODER_WINDOW_BITS(HSE) \ - ((HSE)->window_sz2) -#define HEATSHRINK_ENCODER_LOOKAHEAD_BITS(HSE) \ - ((HSE)->lookahead_sz2) -#define HEATSHRINK_ENCODER_INDEX(HSE) \ - ((HSE)->search_index) -struct hs_index { - uint16_t size; - int16_t index[]; -}; -#else -#define HEATSHRINK_ENCODER_WINDOW_BITS(_) \ - (HEATSHRINK_STATIC_WINDOW_BITS) -#define HEATSHRINK_ENCODER_LOOKAHEAD_BITS(_) \ - (HEATSHRINK_STATIC_LOOKAHEAD_BITS) -#define HEATSHRINK_ENCODER_INDEX(HSE) \ - (&(HSE)->search_index) -struct hs_index { - uint16_t size; - int16_t index[2 << HEATSHRINK_STATIC_WINDOW_BITS]; -}; -#endif - -typedef struct { - uint16_t input_size; /* bytes in input buffer */ - uint16_t match_scan_index; - uint16_t match_length; - uint16_t match_pos; - uint16_t outgoing_bits; /* enqueued outgoing bits */ - uint8_t outgoing_bits_count; - uint8_t flags; - uint8_t state; /* current state machine node */ - uint8_t current_byte; /* current byte of output */ - uint8_t bit_index; /* current bit index */ -#if HEATSHRINK_DYNAMIC_ALLOC - uint8_t window_sz2; /* 2^n size of window */ - uint8_t lookahead_sz2; /* 2^n size of lookahead */ -#if HEATSHRINK_USE_INDEX - struct hs_index *search_index; -#endif - /* input buffer and / sliding window for expansion */ - uint8_t buffer[]; -#else - #if HEATSHRINK_USE_INDEX - struct hs_index search_index; - #endif - /* input buffer and / sliding window for expansion */ - uint8_t buffer[2 << HEATSHRINK_ENCODER_WINDOW_BITS(_)]; -#endif -} heatshrink_encoder; - -#if HEATSHRINK_DYNAMIC_ALLOC -/* Allocate a new encoder struct and its buffers. - * Returns NULL on error. */ -heatshrink_encoder *heatshrink_encoder_alloc(uint8_t window_sz2, - uint8_t lookahead_sz2); - -/* Free an encoder. */ -void heatshrink_encoder_free(heatshrink_encoder *hse); -#endif - -/* Reset an encoder. */ -void heatshrink_encoder_reset(heatshrink_encoder *hse); - -/* Sink up to SIZE bytes from IN_BUF into the encoder. - * INPUT_SIZE is set to the number of bytes actually sunk (in case a - * buffer was filled.). */ -HSE_sink_res heatshrink_encoder_sink(heatshrink_encoder *hse, - uint8_t *in_buf, size_t size, size_t *input_size); - -/* Poll for output from the encoder, copying at most OUT_BUF_SIZE bytes into - * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ -HSE_poll_res heatshrink_encoder_poll(heatshrink_encoder *hse, - uint8_t *out_buf, size_t out_buf_size, size_t *output_size); - -/* Notify the encoder that the input stream is finished. - * If the return value is HSER_FINISH_MORE, there is still more output, so - * call heatshrink_encoder_poll and repeat. */ -HSE_finish_res heatshrink_encoder_finish(heatshrink_encoder *hse); - -#endif diff --git a/Modem/protocol/mp1.c b/Modem/protocol/mp1.c deleted file mode 100644 index 4447998..0000000 --- a/Modem/protocol/mp1.c +++ /dev/null @@ -1,1039 +0,0 @@ -#include "mp1.h" -#include "hardware.h" -#include "config.h" -#include // Used for random -#include -#include -#include // Timer driver from BertOS - -#include "compression/heatshrink_encoder.h" -#include "compression/heatshrink_decoder.h" - -// We need an indicator to tell us whether we -// should send a parity byte. This happens -// whenever two normal bytes of data has been -// sent. We also keep the last sent byte in -// memory because we need it to calculate the -// parity byte. -static bool sendParityBlock = false; -static uint8_t lastByte = 0x00; - -// We also need a buffer for compressing and -// decompressing packet data. -#if MP1_ENABLE_COMPRESSION - static uint8_t compressionBuffer[MP1_MAX_DATA_SIZE]; -#endif - -#if SERIAL_DEBUG -// An int to hold amount of free RAM updated -// by the FREE_RAM function; -static int FREE_RAM; -#endif - -// The GET_BIT macro is used in the interleaver -// and deinterleaver to access single bits of a -// byte. -INLINE bool GET_BIT(uint8_t byte, int n) { return (byte & (1 << (8-n))) == (1 << (8-n)); } - -// This function calculates and returns a parity -// byte for two input bytes. The parity byte is -// used for correcting errors in the transmission. -// The error correction algorithm is a standard -// (12,8) Hamming code. -INLINE bool BIT(uint8_t byte, int n) { return ((byte & BV(n-1))>>(n-1)); } -static uint8_t mp1ParityBlock(uint8_t first, uint8_t other) { - uint8_t parity = 0x00; - - parity = ((BIT(first, 1) ^ BIT(first, 2) ^ BIT(first, 4) ^ BIT(first, 5) ^ BIT(first, 7))) + - ((BIT(first, 1) ^ BIT(first, 3) ^ BIT(first, 4) ^ BIT(first, 6) ^ BIT(first, 7))<<1) + - ((BIT(first, 2) ^ BIT(first, 3) ^ BIT(first, 4) ^ BIT(first, 8))<<2) + - ((BIT(first, 5) ^ BIT(first, 6) ^ BIT(first, 7) ^ BIT(first, 8))<<3) + - - ((BIT(other, 1) ^ BIT(other, 2) ^ BIT(other, 4) ^ BIT(other, 5) ^ BIT(other, 7))<<4) + - ((BIT(other, 1) ^ BIT(other, 3) ^ BIT(other, 4) ^ BIT(other, 6) ^ BIT(other, 7))<<5) + - ((BIT(other, 2) ^ BIT(other, 3) ^ BIT(other, 4) ^ BIT(other, 8))<<6) + - ((BIT(other, 5) ^ BIT(other, 6) ^ BIT(other, 7) ^ BIT(other, 8))<<7); - - return parity; -} - -// This decode function retrieves the buffer of -// received, deinterleaved and error-corrected -// bytes, inspects the header and determines -// whether there is padding to be removed, and -// whether the packet is compressed. If it is -// it is decompressed before being passed to -// the registered callback. -static void mp1Decode(MP1 *mp1) { - MP1Packet packet; // A decoded packet struct - uint8_t *buffer = mp1->buffer; // Get the buffer from the protocol context - - // Get the header and "remove" it from the buffer - uint8_t header = buffer[0]; - buffer++; - - // If header indicates a padded packet, remove - // padding - uint8_t padding = header >> 4; - if (header & MP1_HEADER_PADDED) { - for (int i = 0; i < padding; i++) { - buffer++; - } - } - - if (SERIAL_DEBUG) kprintf("[TS=%d] ", mp1->packetLength); - - // Set the payload length of the packet to the counted - // length minus 1, so we remove the checksum - packet.dataLength = mp1->packetLength - 2 - (header & MP1_HEADER_PADDED)*padding; - - // Check if we have received a compressed packet - if (MP1_ENABLE_COMPRESSION && (header & MP1_HEADER_COMPRESSION)) { - // If we have, we decompress it and use the - // decompressed data for the packet - #if MP1_ENABLE_COMPRESSION - if (SERIAL_DEBUG) kprintf("[CS=%d] ", packet.dataLength); - size_t decompressedSize = decompress(buffer, packet.dataLength); - if (SERIAL_DEBUG) kprintf("[DS=%d]", decompressedSize); - packet.dataLength = decompressedSize; - memcpy(mp1->buffer, compressionBuffer, decompressedSize); - #endif - } else { - // If the packet was not compressed, we shift - // the data in our buffer back down to the actual - // beginning of the buffer array, since we incremented - // the pointer address for removing the header and - // padding. - for (unsigned long i = 0; i < packet.dataLength; i++) { - mp1->buffer[i] = buffer[i]; - } - } - - // Set the data field of the packet to our buffer - packet.data = mp1->buffer; - - // If a callback have been specified, let's - // call it and pass the decoded packet - if (mp1->callback) mp1->callback(&packet); -} - - -//////////////////////////////////////////////////////////// -// The Poll function reads data from the modem, handles // -// frame recognition and passes data on to higher layers // -// if valid packets are found // -//////////////////////////////////////////////////////////// -void mp1Poll(MP1 *mp1) { - int byte; // A place to store our read byte - - // Read bytes from the modem until we reach EOF - while ((byte = kfile_getc(mp1->modem)) != EOF) { - // We read something from the modem, so we - // set the settleTimer - mp1->settleTimer = timer_clock(); - - ///////////////////////////////////////////// - // This following block handles forward // - // error correction using an interleaved // - // (12,8) Hamming code // - ///////////////////////////////////////////// - - // If we have started reading (received an - // HDLC_FLAG), we will start looking at the - // incoming data and perform forward error - // correction on it. - - - if ((mp1->reading && (byte != AX25_ESC )) || (mp1->reading && (mp1->escape && (byte == AX25_ESC || byte == HDLC_FLAG || byte == HDLC_RESET)))) { - // We have a byte, increment our read counter - mp1->readLength++; - - // Check if we have read three bytes. If we - // have, we should now have a block of two - // data bytes and a parity byte. This block - if (mp1->readLength % MP1_INTERLEAVE_SIZE == 0) { - // If the last character in the block - // looks like a control character, we - // need to set the escape indicator to - // false, since the next byte will be - // read immediately after the FEC - // routine, and thus, the normal reading - // code will not reset the indicator. - if (byte == AX25_ESC || byte == HDLC_FLAG || byte == HDLC_RESET) mp1->escape = false; - - // The block is interleaved, so we will - // first put the received bytes in the - // deinterleaving buffer - for (int i = 1; i < MP1_INTERLEAVE_SIZE; i++) { - mp1->interleaveIn[i-1] = mp1->buffer[mp1->packetLength-(MP1_INTERLEAVE_SIZE-i)]; - } - mp1->interleaveIn[MP1_INTERLEAVE_SIZE-1] = byte; - - // We then deinterleave the block - mp1Deinterleave(mp1); - - // Adjust the packet length, since we will get - // parity bytes in the data buffer with block - // sizes larger than 3 - mp1->packetLength -= MP1_INTERLEAVE_SIZE/3 - 1; - - // For each 3-byte block in the deinterleaved - // bytes, we apply forward error correction - for (int i = 0; i < MP1_INTERLEAVE_SIZE; i+=3) { - // We now calculate a parity byte on the - // received data. - - // Deinterleaved data bytes - uint8_t a = mp1->interleaveIn[i]; - uint8_t b = mp1->interleaveIn[i+1]; - - // Deinterleaved parity byte - uint8_t p = mp1->interleaveIn[i+2]; - - mp1->calculatedParity = mp1ParityBlock(a, b); - - // By XORing the calculated parity byte - // with the received parity byte, we get - // what is called the "syndrome". This - // number will tell us if we had any - // errors during transmission, and if so - // where they are. Using Hamming code, we - // can only detect single bit errors in a - // byte though, which is why we interleave - // the data, since most errors will usually - // occur in bursts of more than one bit. - // With 2 data byte interleaving we can - // correct 2 consecutive bit errors. - uint8_t syndrome = mp1->calculatedParity ^ p; - if (syndrome == 0x00) { - // If the syndrome equals 0, we either - // don't have any errors, or the error - // is unrecoverable, so we don't do - // anything - } else { - // If the syndrome is not equal to 0, - // there is a problem, and we will try - // to correct it. We first need to split - // the syndrome byte up into the two - // actual syndrome numbers, one for - // each data byte. - uint8_t syndromes[2]; - syndromes[0] = syndrome & 0x0f; - syndromes[1] = (syndrome & 0xf0) >> 4; - - // Then we look at each syndrome number - // to determine what bit in the data - // bytes to correct. - for (int i = 0; i < 2; i++) { - uint8_t s = syndromes[i]; - uint8_t correction = 0x00; - if (s == 1 || s == 2 || s == 4 || s == 8) { - // This signifies an error in the - // parity block, so we actually - // don't need any correction - continue; - } - - // The following determines what - // bit to correct according to - // the syndrome value. - if (s == 3) correction = 0x01; - if (s == 5) correction = 0x02; - if (s == 6) correction = 0x04; - if (s == 7) correction = 0x08; - if (s == 9) correction = 0x10; - if (s == 10) correction = 0x20; - if (s == 11) correction = 0x40; - if (s == 12) correction = 0x80; - - // And finally we apply the correction - if (i == 1) a ^= correction; - if (i == 0) b ^= correction; - - // This is just for testing purposes. - // Nice to know when corrections were - // actually made. - if (s != 0) mp1->correctionsMade += 1; - } - } - - // We now update the checksum of the packet - // with the deinterleaved and possibly - // corrected bytes. - mp1->checksum_in ^= a; - mp1->checksum_in ^= b; - mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE)+((i/3)*2)] = a; - mp1->buffer[mp1->packetLength-(MP1_DATA_BLOCK_SIZE-1)+((i/3)*2)] = b; - } - - continue; - } - } - ///////////////////////////////////////////// - // End of forward error correction block // - ///////////////////////////////////////////// - - // This next part of the poll function handles - // the reading from the modem, and looks for - // starts and ends of transmissions. It also - // handles escape characters by discarding them - // so they don't get put into the output data. - - // Let's first check if we have read an HDLC_FLAG. - if (!mp1->escape && byte == HDLC_FLAG) { - // We are not in an escape sequence and we - // found a HDLC_FLAG. This can mean two things: - if (mp1->readLength >= MP1_MIN_FRAME_LENGTH) { - // We already have more data than the minimum - // frame length, which means the flag signifies - // the end of the packet. Pass control to the - // decoder. - // - // We also set the settle timer to indicate - // the time the frame completed reading. - mp1->settleTimer = timer_clock(); - if ((mp1->checksum_in & 0xff) == 0x00) { - if (SERIAL_DEBUG) kprintf("[CHK-OK] [C=%d] ", mp1->correctionsMade); - mp1Decode(mp1); - } else { - // Checksum was incorrect, we don't do anything, - // but you can enable the decode anyway, if you - // need it for testing or debugging - if (PASSALL) { - if (SERIAL_DEBUG) kprintf("[CHK-ER] [C=%d] ", mp1->correctionsMade); - mp1Decode(mp1); - } - } - } - // If the above is not the case, this must be the - // beginning of a frame - mp1->reading = true; - mp1->packetLength = 0; - mp1->readLength = 0; - mp1->checksum_in = MP1_CHECKSUM_INIT; - mp1->correctionsMade = 0; - - // We have indicated that we are reading, - // and reset the length counter. Now we'll - // continue to the next byte. - continue; - } - - if (!mp1->escape && byte == HDLC_RESET) { - // Not good, we got a reset. The transmitting - // party may have encountered an error. We'll - // stop receiving this packet immediately. - mp1->reading = false; - continue; - } - - if (!mp1->escape && byte == AX25_ESC) { - // We found an escape character. We'll set - // the escape seqeunce indicator so we don't - // interpret the next byte as a reset or flag - mp1->escape = true; - - // We then continue reading the next byte. - continue; - } - - // Now let's get to the actual reading of the data - if (mp1->reading) { - if (mp1->packetLength < MP1_MAX_FRAME_LENGTH + MP1_INTERLEAVE_SIZE) { - // If the length of the current incoming frame is - // still less than our max length, put the incoming - // byte in the buffer. When we have collected 3 - // bytes, they will be processed by the error - // correction part above. - mp1->buffer[mp1->packetLength++] = byte; - } else { - // If not, we have a problem: The buffer has overrun - // We need to stop receiving, and the packet will be - // dropped :( - mp1->reading = false; - } - } - - // We need to set the escape sequence indicator back - // to false after each byte. - mp1->escape = false; - } - - if (kfile_error(mp1->modem)) { - // If there was an error from the modem, we'll be rude - // and just reset it. No error handling is done for now. - kfile_clearerr(mp1->modem); - } -} - -// This is called to actually send the bytes -// after they have been interleaved -static void mp1WriteByte(MP1 *mp1, uint8_t byte) { - // If we are sending something that looks - // like an HDLC special byte, send an escape - // character first - if (byte == HDLC_FLAG || - byte == HDLC_RESET || - byte == AX25_ESC) { - kfile_putc(AX25_ESC, mp1->modem); - } - kfile_putc(byte, mp1->modem); -} - -// This is an intermediary function that -// receives outgoing bytes, and adds -// interleaving and a parity byte to the -// outgoing data in blocks of two data -// bytes. The actual transmitted block will -// be 3 bytes long due to the added parity -// byte. -static void mp1Putbyte(MP1 *mp1, uint8_t byte) { - mp1Interleave(mp1, byte); - - if (sendParityBlock) { - uint8_t p = mp1ParityBlock(lastByte, byte); - mp1Interleave(mp1, p); - } - - lastByte = byte; - sendParityBlock ^= true; -} - -// This function accepts a buffer with data -// to be transmitted, and structures it into -// a valid packet. -void mp1Send(MP1 *mp1, void *_buffer, size_t length) { - // Reset our parity tx indicator - sendParityBlock = false; - - // Open transmitter and wait for MP1_TXDELAY msecs - AFSK_HW_PTT_ON(); - ticks_t start = timer_clock(); - #if MP1_USE_TX_QUEUE - if (!mp1->queueProcessing) { - while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { - cpu_relax(); - } - } - #else - while (timer_clock() - start < ms_to_ticks(MP1_TXDELAY)) { - cpu_relax(); - } - #endif - - - // Get the transmit data buffer - uint8_t *buffer = (uint8_t *)_buffer; - - // Initialize checksum to zero - mp1->checksum_out = MP1_CHECKSUM_INIT; - - // We also reset the interleave counter to zero - mp1->interleaveCounter = 0; - - // We start out assuming we should not use - // compression. - bool packetCompression = false; - - // We then try to compress the data to see - // if we can save some space with compression. - #if MP1_ENABLE_COMPRESSION - size_t compressedSize = compress(buffer, length); - if (compressedSize != 0 && compressedSize < length) { - // Compression saved us some space, we'll - // send the paket compressed - packetCompression = true; - // Write the compressed data into the - // outgoing data buffer - memcpy(buffer, compressionBuffer, compressedSize); - - // Make sure to set the length of the - // data to the new (compressed) length - length = compressedSize; - } else { - // We are not going to use compression, - // so we don't do anything. - } - #endif - - // Transmit the HDLC_FLAG to signify start of TX - kfile_putc(HDLC_FLAG, mp1->modem); - - // We now need to construct a header, that - // can tell the receiving end whether the - // packet is compressed. Since a packet must - // have an even number of total payload bytes - // (including the header), we check the length - // of the outgoing data, and if it is not even, - // we add a single byte of padding to the - // packet. Remember that we also send a single - // byte checksum at the end of the packet, so - // the header and checksum bytes together don't - // change whether the payload length is even - // or not. The payload length needs to be even - // since we are sending a parity byte for every - // two data bytes sent, and because interleaving - // happens in blocks of three bytes. - uint8_t header = 0x00; - - // If we are using compression, set the - // appropriate header flag to true. - if (packetCompression) header ^= MP1_HEADER_COMPRESSION; - - // We check if the data length matches our - // required block size - uint8_t padding = (length+2) % MP1_DATA_BLOCK_SIZE; - - if (padding != 0) { - // If it does not, we set the appropriate - // header flag to indicate that we are - // padding this packet. - header ^= MP1_HEADER_PADDED; - - // And calculate how much padding we need - padding = MP1_DATA_BLOCK_SIZE - padding; - - // And put the amount of padding we are - // going to append in the header - header ^= (padding << 4); - - // We then update the checksum with the - // header byte and queue it for transmit - mp1->checksum_out = mp1->checksum_out ^ header; - mp1Putbyte(mp1, header); - - // We now update the checksum with the - // padding bytes, and queue these for - // transmission as well. - for (int i = 0; i < padding; i++) { - mp1->checksum_out = mp1->checksum_out ^ MP1_PADDING; - mp1Putbyte(mp1, MP1_PADDING); - } - } else { - // If the length already matches, we - // just update the checksum with the - // header byte and queue it. - mp1->checksum_out = mp1->checksum_out ^ header; - mp1Putbyte(mp1, header); - } - - // Now we'll transmit the actual data of - // the packet. We continously increment the - // pointer address of the buffer while - // passing it to the intermediary output - // function. Everytime the interleaving - // counter reaches 3, a block will be - // transmitted. - while (length--) { - mp1->checksum_out = mp1->checksum_out ^ *buffer; - mp1Putbyte(mp1, *buffer++); - } - - // Finally we write the checksum to the - // end of the packet. - mp1Putbyte(mp1, mp1->checksum_out); - - // And transmit a HDLC_FLAG to signify - // end of the transmission. - kfile_putc(HDLC_FLAG, mp1->modem); - - // Turn off manual PTT - #if MP1_USE_TX_QUEUE - if (!mp1->queueProcessing) AFSK_HW_PTT_OFF(); - #else - AFSK_HW_PTT_OFF(); - #endif -} - -// This function accepts a frame and stores -// it in the transmission queue -#if MP1_USE_TX_QUEUE - void mp1QueueFrame(MP1 *mp1, void *_buffer, size_t length) { - if (mp1->queueLength < MP1_TX_QUEUE_LENGTH) { - uint8_t *buffer = (uint8_t *)_buffer; - mp1->frameLengths[mp1->queueLength] = length; - memcpy(mp1->frameQueue[mp1->queueLength++], buffer, length); - } - } -#endif - -// This function processes the transmission -// queue. -#if MP1_USE_TX_QUEUE - void mp1ProcessQueue(MP1 *mp1) { - int i = 0; - while (mp1->queueLength) { - mp1Send(mp1, mp1->frameQueue[i], mp1->frameLengths[i]); - i++; - mp1->queueLength--; - } - AFSK_HW_PTT_OFF(); - } -#endif - -// A simple form of P-persistent CSMA. -// Everytime we have heard activity -// on the channel, we wait at least -// MP1_SETTLE_TIME milliseconds after the -// activity has ceased. We then pick a random -// number, and if it is less than -// MP1_P_PERSISTENCE, we transmit. -bool mp1CarrierSense(MP1 *mp1) { - if (MP1_ENABLE_CSMA) { - if (mp1->randomSeed == 0) { - mp1->randomSeed = timer_clock(); - srand(mp1->randomSeed); - } - - if (timer_clock() - mp1->settleTimer > ms_to_ticks(MP1_SETTLE_TIME)) { - uint8_t r = rand() % 255; - if (r < MP1_P_PERSISTENCE) { - return false; - } else { - mp1->settleTimer = timer_clock() - MP1_SETTLE_TIME + MP1_SLOT_TIME; - return true; - } - } else { - return true; - } - } else { - return false; - } -} - -// This function will simply initialize -// the protocol context and allocate the -// needed memory. -void mp1Init(MP1 *mp1, KFile *modem, mp1_callback_t callback) { - // Allocate memory for our protocol "object" - memset(mp1, 0, sizeof(*mp1)); - // Set references to our modem "object" and - // a callback for when a packet has been decoded - mp1->modem = modem; - mp1->callback = callback; - mp1->settleTimer = timer_clock(); - mp1->randomSeed = 0; - #if MP1_USE_TX_QUEUE - mp1->queueLength = 0; - mp1->queueProcessing = false; - #endif -} - -// A handy debug function that can determine -// how much available memory we have left. -#if SERIAL_DEBUG -int freeRam(void) { - extern int __heap_start, *__brkval; - int v; - FREE_RAM = (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); - return FREE_RAM; -} -#endif - -// This function compresses data using -// the Heatshrink library -#if MP1_ENABLE_COMPRESSION -size_t compress(uint8_t *input, size_t length) { - heatshrink_encoder *hse = heatshrink_encoder_alloc(8, 4); - if (hse == NULL) { - if (SERIAL_DEBUG) kprintf("Could not allocate compressor\n"); - return 0; - } - - size_t written = 0; - size_t sunk = 0; - heatshrink_encoder_sink(hse, input, length, &sunk); - int status = heatshrink_encoder_finish(hse); - - if (sunk < length) { - heatshrink_encoder_free(hse); - return 0; - } else { - if (status == HSER_FINISH_MORE) { - heatshrink_encoder_poll(hse, compressionBuffer, MP1_MAX_FRAME_LENGTH, &written); - } - } - - heatshrink_encoder_free(hse); - return written; -} -#endif - -// This function decompresses data using -// the Heatshrink library -#if MP1_ENABLE_COMPRESSION -size_t decompress(uint8_t *input, size_t length) { - heatshrink_decoder *hsd = heatshrink_decoder_alloc(MP1_MAX_FRAME_LENGTH, 8, 4); - if (hsd == NULL) { - if (SERIAL_DEBUG) kprintf("Could not allocate decompressor\n"); - return 0; - } - - size_t written = 0; - size_t sunk = 0; - heatshrink_decoder_sink(hsd, input, length, &sunk); - int status = heatshrink_decoder_finish(hsd); - - if (sunk < length) { - heatshrink_decoder_free(hsd); - return 0; - } else { - if (status == HSER_FINISH_MORE) { - heatshrink_decoder_poll(hsd, compressionBuffer, MP1_MAX_FRAME_LENGTH, &written); - } - } - - heatshrink_decoder_free(hsd); - return written; -} -#endif - - -// Following is the functions responsible -// for interleaving and deinterleaving -// blocks of data. The interleaving table -// for 3-byte interleaving is also included. -// The table for 12-byte is much simpler, -// and should be inferable from looking -// at the function. - -/////////////////////////////// -// Interleave-table (3-byte) // -/////////////////////////////// -// -// Non-interleaved: -// aaaaaaaa bbbbbbbb cccccccc -// 12345678 12345678 12345678 -// M L -// S S -// B B -// -// Interleaved: -// abcabcab cabcabca bcabcabc -// 11144477 22255578 63336688 -// -/////////////////////////////// - -void mp1Interleave(MP1 *mp1, uint8_t byte) { - mp1->interleaveOut[mp1->interleaveCounter] = byte; - mp1->interleaveCounter++; - if (mp1->interleaveCounter == MP1_INTERLEAVE_SIZE) { - // We have the bytes we need for interleaving - // in the buffer and are ready to interleave them. - #if MP1_INTERLEAVE_SIZE == 3 - // This is for 3-byte interleaving - uint8_t a = (GET_BIT(mp1->interleaveOut[0], 1) << 7) + - (GET_BIT(mp1->interleaveOut[1], 1) << 6) + - (GET_BIT(mp1->interleaveOut[2], 1) << 5) + - (GET_BIT(mp1->interleaveOut[0], 4) << 4) + - (GET_BIT(mp1->interleaveOut[1], 4) << 3) + - (GET_BIT(mp1->interleaveOut[2], 4) << 2) + - (GET_BIT(mp1->interleaveOut[0], 7) << 1) + - (GET_BIT(mp1->interleaveOut[1], 7)); - mp1WriteByte(mp1, a); - - uint8_t b = (GET_BIT(mp1->interleaveOut[2], 2) << 7) + - (GET_BIT(mp1->interleaveOut[0], 2) << 6) + - (GET_BIT(mp1->interleaveOut[1], 2) << 5) + - (GET_BIT(mp1->interleaveOut[2], 5) << 4) + - (GET_BIT(mp1->interleaveOut[0], 5) << 3) + - (GET_BIT(mp1->interleaveOut[1], 5) << 2) + - (GET_BIT(mp1->interleaveOut[2], 7) << 1) + - (GET_BIT(mp1->interleaveOut[0], 8)); - mp1WriteByte(mp1, b); - - uint8_t c = (GET_BIT(mp1->interleaveOut[1], 6) << 7) + - (GET_BIT(mp1->interleaveOut[2], 3) << 6) + - (GET_BIT(mp1->interleaveOut[0], 3) << 5) + - (GET_BIT(mp1->interleaveOut[1], 3) << 4) + - (GET_BIT(mp1->interleaveOut[2], 6) << 3) + - (GET_BIT(mp1->interleaveOut[0], 6) << 2) + - (GET_BIT(mp1->interleaveOut[1], 8) << 1) + - (GET_BIT(mp1->interleaveOut[2], 8)); - - mp1WriteByte(mp1, c); - #elif MP1_INTERLEAVE_SIZE == 12 - // This is for 12-byte interleaving - uint8_t a = (GET_BIT(mp1->interleaveOut[0], 1) << 7) + - (GET_BIT(mp1->interleaveOut[1], 1) << 6) + - (GET_BIT(mp1->interleaveOut[3], 1) << 5) + - (GET_BIT(mp1->interleaveOut[4], 1) << 4) + - (GET_BIT(mp1->interleaveOut[6], 1) << 3) + - (GET_BIT(mp1->interleaveOut[7], 1) << 2) + - (GET_BIT(mp1->interleaveOut[9], 1) << 1) + - (GET_BIT(mp1->interleaveOut[10],1)); - mp1WriteByte(mp1, a); - - uint8_t b = (GET_BIT(mp1->interleaveOut[0], 2) << 7) + - (GET_BIT(mp1->interleaveOut[1], 2) << 6) + - (GET_BIT(mp1->interleaveOut[3], 2) << 5) + - (GET_BIT(mp1->interleaveOut[4], 2) << 4) + - (GET_BIT(mp1->interleaveOut[6], 2) << 3) + - (GET_BIT(mp1->interleaveOut[7], 2) << 2) + - (GET_BIT(mp1->interleaveOut[9], 2) << 1) + - (GET_BIT(mp1->interleaveOut[10],2)); - mp1WriteByte(mp1, b); - - uint8_t c = (GET_BIT(mp1->interleaveOut[0], 3) << 7) + - (GET_BIT(mp1->interleaveOut[1], 3) << 6) + - (GET_BIT(mp1->interleaveOut[3], 3) << 5) + - (GET_BIT(mp1->interleaveOut[4], 3) << 4) + - (GET_BIT(mp1->interleaveOut[6], 3) << 3) + - (GET_BIT(mp1->interleaveOut[7], 3) << 2) + - (GET_BIT(mp1->interleaveOut[9], 3) << 1) + - (GET_BIT(mp1->interleaveOut[10],3)); - mp1WriteByte(mp1, c); - - uint8_t d = (GET_BIT(mp1->interleaveOut[0], 4) << 7) + - (GET_BIT(mp1->interleaveOut[1], 4) << 6) + - (GET_BIT(mp1->interleaveOut[3], 4) << 5) + - (GET_BIT(mp1->interleaveOut[4], 4) << 4) + - (GET_BIT(mp1->interleaveOut[6], 4) << 3) + - (GET_BIT(mp1->interleaveOut[7], 4) << 2) + - (GET_BIT(mp1->interleaveOut[9], 4) << 1) + - (GET_BIT(mp1->interleaveOut[10],4)); - mp1WriteByte(mp1, d); - - uint8_t e = (GET_BIT(mp1->interleaveOut[0], 5) << 7) + - (GET_BIT(mp1->interleaveOut[1], 5) << 6) + - (GET_BIT(mp1->interleaveOut[3], 5) << 5) + - (GET_BIT(mp1->interleaveOut[4], 5) << 4) + - (GET_BIT(mp1->interleaveOut[6], 5) << 3) + - (GET_BIT(mp1->interleaveOut[7], 5) << 2) + - (GET_BIT(mp1->interleaveOut[9], 5) << 1) + - (GET_BIT(mp1->interleaveOut[10],5)); - mp1WriteByte(mp1, e); - - uint8_t f = (GET_BIT(mp1->interleaveOut[0], 6) << 7) + - (GET_BIT(mp1->interleaveOut[1], 6) << 6) + - (GET_BIT(mp1->interleaveOut[3], 6) << 5) + - (GET_BIT(mp1->interleaveOut[4], 6) << 4) + - (GET_BIT(mp1->interleaveOut[6], 6) << 3) + - (GET_BIT(mp1->interleaveOut[7], 6) << 2) + - (GET_BIT(mp1->interleaveOut[9], 6) << 1) + - (GET_BIT(mp1->interleaveOut[10],6)); - mp1WriteByte(mp1, f); - - uint8_t g = (GET_BIT(mp1->interleaveOut[0], 7) << 7) + - (GET_BIT(mp1->interleaveOut[1], 7) << 6) + - (GET_BIT(mp1->interleaveOut[3], 7) << 5) + - (GET_BIT(mp1->interleaveOut[4], 7) << 4) + - (GET_BIT(mp1->interleaveOut[6], 7) << 3) + - (GET_BIT(mp1->interleaveOut[7], 7) << 2) + - (GET_BIT(mp1->interleaveOut[9], 7) << 1) + - (GET_BIT(mp1->interleaveOut[10],7)); - mp1WriteByte(mp1, g); - - uint8_t h = (GET_BIT(mp1->interleaveOut[0], 8) << 7) + - (GET_BIT(mp1->interleaveOut[1], 8) << 6) + - (GET_BIT(mp1->interleaveOut[3], 8) << 5) + - (GET_BIT(mp1->interleaveOut[4], 8) << 4) + - (GET_BIT(mp1->interleaveOut[6], 8) << 3) + - (GET_BIT(mp1->interleaveOut[7], 8) << 2) + - (GET_BIT(mp1->interleaveOut[9], 8) << 1) + - (GET_BIT(mp1->interleaveOut[10],8)); - mp1WriteByte(mp1, h); - - uint8_t p = (GET_BIT(mp1->interleaveOut[2], 1) << 7) + - (GET_BIT(mp1->interleaveOut[2], 5) << 6) + - (GET_BIT(mp1->interleaveOut[5], 1) << 5) + - (GET_BIT(mp1->interleaveOut[5], 5) << 4) + - (GET_BIT(mp1->interleaveOut[8], 1) << 3) + - (GET_BIT(mp1->interleaveOut[8], 5) << 2) + - (GET_BIT(mp1->interleaveOut[11],1) << 1) + - (GET_BIT(mp1->interleaveOut[11],5)); - mp1WriteByte(mp1, p); - - uint8_t q = (GET_BIT(mp1->interleaveOut[2], 2) << 7) + - (GET_BIT(mp1->interleaveOut[2], 6) << 6) + - (GET_BIT(mp1->interleaveOut[5], 2) << 5) + - (GET_BIT(mp1->interleaveOut[5], 6) << 4) + - (GET_BIT(mp1->interleaveOut[8], 2) << 3) + - (GET_BIT(mp1->interleaveOut[8], 6) << 2) + - (GET_BIT(mp1->interleaveOut[11],2) << 1) + - (GET_BIT(mp1->interleaveOut[11],6)); - mp1WriteByte(mp1, q); - - uint8_t s = (GET_BIT(mp1->interleaveOut[2], 3) << 7) + - (GET_BIT(mp1->interleaveOut[2], 7) << 6) + - (GET_BIT(mp1->interleaveOut[5], 3) << 5) + - (GET_BIT(mp1->interleaveOut[5], 7) << 4) + - (GET_BIT(mp1->interleaveOut[8], 3) << 3) + - (GET_BIT(mp1->interleaveOut[8], 7) << 2) + - (GET_BIT(mp1->interleaveOut[11],3) << 1) + - (GET_BIT(mp1->interleaveOut[11],7)); - mp1WriteByte(mp1, s); - - uint8_t t = (GET_BIT(mp1->interleaveOut[2], 4) << 7) + - (GET_BIT(mp1->interleaveOut[2], 8) << 6) + - (GET_BIT(mp1->interleaveOut[5], 4) << 5) + - (GET_BIT(mp1->interleaveOut[5], 8) << 4) + - (GET_BIT(mp1->interleaveOut[8], 4) << 3) + - (GET_BIT(mp1->interleaveOut[8], 8) << 2) + - (GET_BIT(mp1->interleaveOut[11],4) << 1) + - (GET_BIT(mp1->interleaveOut[11],8)); - mp1WriteByte(mp1, t); - - #endif - - mp1->interleaveCounter = 0; - } -} - - -void mp1Deinterleave(MP1 *mp1) { - #if MP1_INTERLEAVE_SIZE == 3 - uint8_t a = (GET_BIT(mp1->interleaveIn[0], 1) << 7) + - (GET_BIT(mp1->interleaveIn[1], 2) << 6) + - (GET_BIT(mp1->interleaveIn[2], 3) << 5) + - (GET_BIT(mp1->interleaveIn[0], 4) << 4) + - (GET_BIT(mp1->interleaveIn[1], 5) << 3) + - (GET_BIT(mp1->interleaveIn[2], 6) << 2) + - (GET_BIT(mp1->interleaveIn[0], 7) << 1) + - (GET_BIT(mp1->interleaveIn[1], 8)); - - uint8_t b = (GET_BIT(mp1->interleaveIn[0], 2) << 7) + - (GET_BIT(mp1->interleaveIn[1], 3) << 6) + - (GET_BIT(mp1->interleaveIn[2], 4) << 5) + - (GET_BIT(mp1->interleaveIn[0], 5) << 4) + - (GET_BIT(mp1->interleaveIn[1], 6) << 3) + - (GET_BIT(mp1->interleaveIn[2], 1) << 2) + - (GET_BIT(mp1->interleaveIn[0], 8) << 1) + - (GET_BIT(mp1->interleaveIn[2], 7)); - - uint8_t c = (GET_BIT(mp1->interleaveIn[0], 3) << 7) + - (GET_BIT(mp1->interleaveIn[1], 1) << 6) + - (GET_BIT(mp1->interleaveIn[2], 2) << 5) + - (GET_BIT(mp1->interleaveIn[0], 6) << 4) + - (GET_BIT(mp1->interleaveIn[1], 4) << 3) + - (GET_BIT(mp1->interleaveIn[2], 5) << 2) + - (GET_BIT(mp1->interleaveIn[1], 7) << 1) + - (GET_BIT(mp1->interleaveIn[2], 8)); - - mp1->interleaveIn[0] = a; - mp1->interleaveIn[1] = b; - mp1->interleaveIn[2] = c; - #elif MP1_INTERLEAVE_SIZE == 12 - uint8_t a = (GET_BIT(mp1->interleaveIn[0], 1) << 7) + - (GET_BIT(mp1->interleaveIn[1], 1) << 6) + - (GET_BIT(mp1->interleaveIn[2], 1) << 5) + - (GET_BIT(mp1->interleaveIn[3], 1) << 4) + - (GET_BIT(mp1->interleaveIn[4], 1) << 3) + - (GET_BIT(mp1->interleaveIn[5], 1) << 2) + - (GET_BIT(mp1->interleaveIn[6], 1) << 1) + - (GET_BIT(mp1->interleaveIn[7], 1)); - - uint8_t b = (GET_BIT(mp1->interleaveIn[0], 2) << 7) + - (GET_BIT(mp1->interleaveIn[1], 2) << 6) + - (GET_BIT(mp1->interleaveIn[2], 2) << 5) + - (GET_BIT(mp1->interleaveIn[3], 2) << 4) + - (GET_BIT(mp1->interleaveIn[4], 2) << 3) + - (GET_BIT(mp1->interleaveIn[5], 2) << 2) + - (GET_BIT(mp1->interleaveIn[6], 2) << 1) + - (GET_BIT(mp1->interleaveIn[7], 2)); - - uint8_t p = (GET_BIT(mp1->interleaveIn[8], 1) << 7) + - (GET_BIT(mp1->interleaveIn[9], 1) << 6) + - (GET_BIT(mp1->interleaveIn[10],1) << 5) + - (GET_BIT(mp1->interleaveIn[11],1) << 4) + - (GET_BIT(mp1->interleaveIn[8], 2) << 3) + - (GET_BIT(mp1->interleaveIn[9], 2) << 2) + - (GET_BIT(mp1->interleaveIn[10],2) << 1) + - (GET_BIT(mp1->interleaveIn[11],2)); - - uint8_t c = (GET_BIT(mp1->interleaveIn[0], 3) << 7) + - (GET_BIT(mp1->interleaveIn[1], 3) << 6) + - (GET_BIT(mp1->interleaveIn[2], 3) << 5) + - (GET_BIT(mp1->interleaveIn[3], 3) << 4) + - (GET_BIT(mp1->interleaveIn[4], 3) << 3) + - (GET_BIT(mp1->interleaveIn[5], 3) << 2) + - (GET_BIT(mp1->interleaveIn[6], 3) << 1) + - (GET_BIT(mp1->interleaveIn[7], 3)); - - uint8_t d = (GET_BIT(mp1->interleaveIn[0], 4) << 7) + - (GET_BIT(mp1->interleaveIn[1], 4) << 6) + - (GET_BIT(mp1->interleaveIn[2], 4) << 5) + - (GET_BIT(mp1->interleaveIn[3], 4) << 4) + - (GET_BIT(mp1->interleaveIn[4], 4) << 3) + - (GET_BIT(mp1->interleaveIn[5], 4) << 2) + - (GET_BIT(mp1->interleaveIn[6], 4) << 1) + - (GET_BIT(mp1->interleaveIn[7], 4)); - - uint8_t q = (GET_BIT(mp1->interleaveIn[8], 3) << 7) + - (GET_BIT(mp1->interleaveIn[9], 3) << 6) + - (GET_BIT(mp1->interleaveIn[10],3) << 5) + - (GET_BIT(mp1->interleaveIn[11],3) << 4) + - (GET_BIT(mp1->interleaveIn[8], 4) << 3) + - (GET_BIT(mp1->interleaveIn[9], 4) << 2) + - (GET_BIT(mp1->interleaveIn[10],4) << 1) + - (GET_BIT(mp1->interleaveIn[11],4)); - - uint8_t e = (GET_BIT(mp1->interleaveIn[0], 5) << 7) + - (GET_BIT(mp1->interleaveIn[1], 5) << 6) + - (GET_BIT(mp1->interleaveIn[2], 5) << 5) + - (GET_BIT(mp1->interleaveIn[3], 5) << 4) + - (GET_BIT(mp1->interleaveIn[4], 5) << 3) + - (GET_BIT(mp1->interleaveIn[5], 5) << 2) + - (GET_BIT(mp1->interleaveIn[6], 5) << 1) + - (GET_BIT(mp1->interleaveIn[7], 5)); - - uint8_t f = (GET_BIT(mp1->interleaveIn[0], 6) << 7) + - (GET_BIT(mp1->interleaveIn[1], 6) << 6) + - (GET_BIT(mp1->interleaveIn[2], 6) << 5) + - (GET_BIT(mp1->interleaveIn[3], 6) << 4) + - (GET_BIT(mp1->interleaveIn[4], 6) << 3) + - (GET_BIT(mp1->interleaveIn[5], 6) << 2) + - (GET_BIT(mp1->interleaveIn[6], 6) << 1) + - (GET_BIT(mp1->interleaveIn[7], 6)); - - uint8_t s = (GET_BIT(mp1->interleaveIn[8], 5) << 7) + - (GET_BIT(mp1->interleaveIn[9], 5) << 6) + - (GET_BIT(mp1->interleaveIn[10],5) << 5) + - (GET_BIT(mp1->interleaveIn[11],5) << 4) + - (GET_BIT(mp1->interleaveIn[8], 6) << 3) + - (GET_BIT(mp1->interleaveIn[9], 6) << 2) + - (GET_BIT(mp1->interleaveIn[10],6) << 1) + - (GET_BIT(mp1->interleaveIn[11],6)); - - uint8_t g = (GET_BIT(mp1->interleaveIn[0], 7) << 7) + - (GET_BIT(mp1->interleaveIn[1], 7) << 6) + - (GET_BIT(mp1->interleaveIn[2], 7) << 5) + - (GET_BIT(mp1->interleaveIn[3], 7) << 4) + - (GET_BIT(mp1->interleaveIn[4], 7) << 3) + - (GET_BIT(mp1->interleaveIn[5], 7) << 2) + - (GET_BIT(mp1->interleaveIn[6], 7) << 1) + - (GET_BIT(mp1->interleaveIn[7], 7)); - - uint8_t h = (GET_BIT(mp1->interleaveIn[0], 8) << 7) + - (GET_BIT(mp1->interleaveIn[1], 8) << 6) + - (GET_BIT(mp1->interleaveIn[2], 8) << 5) + - (GET_BIT(mp1->interleaveIn[3], 8) << 4) + - (GET_BIT(mp1->interleaveIn[4], 8) << 3) + - (GET_BIT(mp1->interleaveIn[5], 8) << 2) + - (GET_BIT(mp1->interleaveIn[6], 8) << 1) + - (GET_BIT(mp1->interleaveIn[7], 8)); - - uint8_t t = (GET_BIT(mp1->interleaveIn[8], 7) << 7) + - (GET_BIT(mp1->interleaveIn[9], 7) << 6) + - (GET_BIT(mp1->interleaveIn[10],7) << 5) + - (GET_BIT(mp1->interleaveIn[11],7) << 4) + - (GET_BIT(mp1->interleaveIn[8], 8) << 3) + - (GET_BIT(mp1->interleaveIn[9], 8) << 2) + - (GET_BIT(mp1->interleaveIn[10],8) << 1) + - (GET_BIT(mp1->interleaveIn[11],8)); - - mp1->interleaveIn[0] = a; - mp1->interleaveIn[1] = b; - mp1->interleaveIn[2] = p; - mp1->interleaveIn[3] = c; - mp1->interleaveIn[4] = d; - mp1->interleaveIn[5] = q; - mp1->interleaveIn[6] = e; - mp1->interleaveIn[7] = f; - mp1->interleaveIn[8] = s; - mp1->interleaveIn[9] = g; - mp1->interleaveIn[10] = h; - mp1->interleaveIn[11] = t; - - #endif -} \ No newline at end of file diff --git a/Modem/protocol/mp1.h b/Modem/protocol/mp1.h deleted file mode 100644 index f617d1e..0000000 --- a/Modem/protocol/mp1.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef PROTOCOL_MP1 -#define PROTOCOL_MP1 - -#include -#include - -// Options -#define MP1_ENABLE_TCP_COMPATIBILITY false -#if MP1_ENABLE_TCP_COMPATIBILITY - #define MP1_ENABLE_COMPRESSION false - #define MP1_ENABLE_CSMA true -#else - #define MP1_ENABLE_COMPRESSION true - #define MP1_ENABLE_CSMA false -#endif - -// Frame sizing & checksum -#define MP1_INTERLEAVE_SIZE 12 -#if MP1_ENABLE_COMPRESSION - #define MP1_MAX_FRAME_LENGTH 22 * MP1_INTERLEAVE_SIZE - #define MP1_USE_TX_QUEUE false -#else - #define MP1_MAX_FRAME_LENGTH 25 * MP1_INTERLEAVE_SIZE - #define MP1_USE_TX_QUEUE true - #define MP1_TX_QUEUE_LENGTH 2 - #define MP1_QUEUE_TX_WAIT 16UL -#endif -#define MP1_HEADER_SIZE 1 -#define MP1_CHECKSUM_SIZE 1 -#define MP1_MAX_DATA_SIZE MP1_MAX_FRAME_LENGTH - MP1_HEADER_SIZE - MP1_CHECKSUM_SIZE -#define MP1_MIN_FRAME_LENGTH MP1_INTERLEAVE_SIZE -#define MP1_DATA_BLOCK_SIZE ((MP1_INTERLEAVE_SIZE/3)*2) -#define MP1_CHECKSUM_INIT 0xAA - -// These two parameters are used for -// P-persistent CSMA -#define MP1_SETTLE_TIME 100UL // The minimum wait time before even considering sending -#define MP1_SLOT_TIME 100UL // The time to wait if deciding not to send -#define MP1_P_PERSISTENCE 85UL // The probability (between 0 and 255) for sending -#define MP1_TXDELAY 0UL // Delay between turning on the transmitter and sending - -// We need to know some basic HDLC flag bytes -#define HDLC_FLAG 0x7E -#define HDLC_RESET 0x7F -#define AX25_ESC 0x1B - -// We also define a few header flags and what -// to send as padding if we need to pad a -// packet. Due to forward error correction, -// packets must have an even number of bytes. -#define MP1_PADDING 0x55 -#define MP1_HEADER_PADDED 0x01 -#define MP1_HEADER_COMPRESSION 0x02 - -// Just a forward declaration that this struct exists -struct MP1Packet; - -// The type of a callback function for passing -// back a decoded packet -typedef void (*mp1_callback_t)(struct MP1Packet *packet); - -// Struct for a protocol context -typedef struct MP1 { - uint8_t buffer[MP1_MAX_FRAME_LENGTH+MP1_INTERLEAVE_SIZE]; // A buffer for incoming packets - KFile *modem; // KFile access to the modem - size_t packetLength; // Counter for received packet length - size_t readLength; // This is the full read length, including parity bytes - uint8_t calculatedParity; // Calculated parity for incoming data block - mp1_callback_t callback; // The function to call when a packet has been received - uint8_t checksum_in; // Rolling checksum for incoming packets - uint8_t checksum_out; // Rolling checksum for outgoing packets - bool reading; // True when we have seen a HDLC flag - bool escape; // We need to know if we are in an escape sequence - ticks_t settleTimer; // Timer used for carrier sense settling - long correctionsMade; // A counter for how many corrections were made to a packet - uint8_t interleaveCounter; // Keeps track of when we have received an entire interleaved block - uint8_t interleaveOut[MP1_INTERLEAVE_SIZE]; // A buffer for interleaving bytes before they are sent - uint8_t interleaveIn[MP1_INTERLEAVE_SIZE]; // A buffer for storing interleaved bytes before they are deinterleaved - uint8_t randomSeed; // A seed for the pseudo-random number generator - #if MP1_USE_TX_QUEUE - bool queueProcessing; // For sending queued frames without preamble after first one - size_t queueLength; // The length of the transmission queue - size_t frameLengths[MP1_TX_QUEUE_LENGTH]; // The lengths of the frames in the queue - uint8_t frameQueue[MP1_TX_QUEUE_LENGTH] // A buffer for a queued frame - [MP1_MAX_DATA_SIZE]; - #endif -} MP1; - -// A struct encapsulating a network packet -typedef struct MP1Packet { - const uint8_t *data; // Pointer to the actual data in the packet - size_t dataLength; // The length of the received data -} MP1Packet; - -// Declarations of functions -void mp1Init(MP1 *mp1, KFile *modem, mp1_callback_t callback); -void mp1Read(MP1 *mp1, int byte); -void mp1Poll(MP1 *mp1); -void mp1Send(MP1 *mp1, void *_buffer, size_t length); -void mp1QueueFrame(MP1 *mp1, void *_buffer, size_t length); -void mp1ProcessQueue(MP1 *mp1); -bool mp1CarrierSense(MP1 *mp1); - -int freeRam(void); -size_t compress(uint8_t *input, size_t length); -size_t decompress(uint8_t *input, size_t length); -void mp1Deinterleave(MP1 *mp1); -void mp1Interleave(MP1 *mp1, uint8_t byte); - -#endif \ No newline at end of file diff --git a/buildrev.h b/buildrev.h index f468eed..1ce718b 100644 --- a/buildrev.h +++ b/buildrev.h @@ -1,2 +1,2 @@ -#define VERS_BUILD 2121 +#define VERS_BUILD 2127 #define VERS_HOST "shard" diff --git a/images/Modem.elf b/images/Modem.elf new file mode 100755 index 0000000000000000000000000000000000000000..1d2e840c1471decd301fa8ebe649f19d8b23c2c4 GIT binary patch literal 186636 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 literal 0 HcmV?d00001 diff --git a/images/Modem.hex b/images/Modem.hex new file mode 100644 index 0000000..8f29fdd --- /dev/null +++ b/images/Modem.hex @@ -0,0 +1,1876 @@ +:100000000C9495080C94B2080C94B2080C94B208A5 +:100010000C94B2080C94B2080C94B2080C94B20878 +:100020000C94B2080C94B2080C94B2080C94B20868 +:100030000C94B2080C94B2080C944A0D0C94B208BB +:100040000C94B2080C94EA090C948D090C944F0995 +:100050000C94B2080C94891A0C94B2080C94B2084F +:100060000C94B2080C94B208756E6974203C20534D +:1000700045525F434E5400626572746F732F637014 +:10008000752F6176722F6472762F7365725F6D655E +:1000900067612E630073697A65203E2031006265D6 +:1000A00072746F732F7374727563742F6669666FE1 +:1000B0006275662E680066642D3E68772D3E727804 +:1000C00062756666657200626572746F732F647222 +:1000D000762F7365722E630066642D3E68772D3E21 +:1000E000747862756666657200626572746F732FEC +:1000F0006472762F7365722E63002166642D3E69EB +:10010000735F6F70656E00626572746F732F6472D7 +:10011000762F7365722E6300756E6974203C2063C0 +:100120006F756E746F66287365725F68616E646C5C +:1001300065732900626572746F732F6472762F7312 +:1001400065722E6300706F72742D3E69735F6F70FD +:10015000656E00626572746F732F6472762F7365BB +:10016000722E630066642D3E5F74797065203D3D9C +:10017000204B46545F53455249414C0062657274AE +:100180006F732F6472762F7365722E680021746905 +:100190006D65725F696E697469616C697A65640026 +:1001A000626572746F732F6472762F74696D6572F5 +:1001B0002E63002674696D65722D3E6C696E6B004E +:1001C000626572746F732F6472762F74696D6572D5 +:1001D0002E630066642D3E72656164006265727410 +:1001E0006F732F696F2F6B66696C652E680066648C +:1001F0002D3E777269746500626572746F732F6942 +:100200006F2F6B66696C652E68006275665F706F34 +:10021000696E746572203E3D20627566006265728B +:10022000746F732F6D776172652F666F726D617475 +:1002300077722E63006368616E6E656C0062657232 +:10024000746F732F6E65742F617832352E6300637F +:10025000747800626572746F732F6E65742F6178A5 +:1002600032352E63006973616C6E756D28632920C9 +:100270007C7C2063203D3D2027202700626572742E +:100280006F732F6E65742F617832352E630063743F +:10029000782D3E6372635F6F7574203D3D20415839 +:1002A00032355F4352435F434F52524543540062DD +:1002B0006572746F732F6E65742F617832352E639B +:1002C00000706174685F6C656E203E3D2032006294 +:1002D0006572746F732F6E65742F617832352E637B +:1002E000007061746800626572746F732F6E65745C +:1002F0002F617832352E630066642D3E636C656134 +:100300007265727200626572746F732F696F2F6B02 +:1003100066696C652E680066642D3E6572726F7248 +:1003200000626572746F732F696F2F6B66696C65FD +:100330002E680025733A204F6E6C79206672616DCD +:10034000657320776974686F7574206C6179657264 +:10035000332070726F746F636F6C206172652068F8 +:10036000616E646C65642C20676F74205B2530328D +:10037000585D0A0025733A204F6E6C79205549204C +:100380006672616D6573206172652068616E646C70 +:1003900065642C20676F74205B253032585D0A003D +:1003A00025733A204368616E6E656C206572726FCA +:1003B00072205B253034785D0A0000008911122319 +:1003C0009B322446AD573665BF74488CC19D5AAFE9 +:1003D000D3BE6CCAE5DB7EE9F7F8811008019333E0 +:1003E0001A22A5562C47B7753E64C99C408DDBBFC9 +:1003F00052AEEDDA64CBFFF976E802218B301002C1 +:1004000099132667AF763444BD554AADC3BC588EA8 +:10041000D19F6EEBE7FA7CC8F5D983310A2091129F +:100420001803A7772E66B5543C45CBBD42ACD99E88 +:10043000508FEFFB66EAFDD874C904428D531661F4 +:100440009F702004A9153227BB364CCEC5DF5EED68 +:10045000D7FC6888E1997AABF3BA85520C4397715F +:100460001E60A1142805B3373A26CDDE44CFDFFD48 +:1004700056ECE9986089FBBB72AA06638F72144040 +:100480009D512225AB343006B9174EEFC7FE5CCC28 +:10049000D5DD6AA9E3B8788AF19B87730E6295501F +:1004A0001C41A3352A24B1163807CFFF46EEDDDC08 +:1004B00054CDEBB962A8F99A708B088481951AA77C +:1004C00093B62CC2A5D33EE1B7F04008C919522B10 +:1004D000DB3A644EED5F766DFF7C899400859BB7B7 +:1004E00012A6ADD224C3BFF136E0C1184809D33BF0 +:1004F0005A2AE55E6C4FF77D7E6C0AA583B4188698 +:1005000091972EE3A7F23CC0B5D14229CB38500ACF +:10051000D91B666FEF7E744CFD5D8BB502A4999676 +:100520001087AFF326E2BDD034C1C3394A28D11AAF +:10053000580BE77F6E6EF55C7C4D0CC685D71EE5CB +:1005400097F42880A1913AA3B3B2444ACD5B56698F +:10055000DF78600CE91D722FFB3E8DD604C79FF536 +:1005600016E4A9902081BBB332A2C55A4C4BD7796F +:100570005E68E11C680DF33F7A2E0EE787F61CC417 +:1005800095D52AA1A3B03882B193466BCF7A54484F +:10059000DD59622DEB3C700EF91F8FF706E69DD4F6 +:1005A00014C5ABB122A0B9923083C77B4E6AD5582F +:1005B0005C49E33D6A2CF11E780F6368203C3D20C6 +:1005C00035004D6F64656D2F686172647761726587 +:1005D0002E630066642D3E5F74797065203D3D207A +:1005E0004B46545F4146534B004D6F64656D2F6120 +:1005F00066736B2E6800808183848687898A8C8EDF +:100600008F9192949597989A9B9D9EA0A2A3A5A640 +:10061000A7A9AAACADAFB0B2B3B5B6B7B9BABCBDB5 +:10062000BEC0C1C2C4C5C6C8C9CACBCDCECFD0D248 +:10063000D3D4D5D6D7D9DADBDCDDDEDFE0E1E2E307 +:10064000E4E5E6E7E8E9EAEAEBECEDEEEEEFF0F1FF +:10065000F1F2F3F3F4F5F5F6F6F7F8F8F9F9FAFA3A +:10066000FAFBFBFCFCFCFDFDFDFDFEFEFEFEFEFFBD +:10067000FFFFFFFFFFFF2D2D2D2D2D2D2D2D2D2DBE +:100680002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9A +:100690002D2D2D2D2D2D2D2D0A0048202020202000 +:1006A000202020205072696E7420636F6E66696727 +:1006B00075726174696F6E0A00432020202020202B +:1006C000202020436C65617220636F6E66696775D8 +:1006D000726174696F6E0A004C2020202020202057 +:1006E00020204C6F616420636F6E6669677572616C +:1006F00074696F6E0A0053202020202020202020C3 +:100700005361766520636F6E66696775726174699F +:100710006F6E0A00563C312F303E20202020536956 +:100720006C656E74206D6F6465206F6E2F6F6666EA +:100730000A0A00763C312F303E2020202056657278 +:10074000626F7365206D6F6465206F6E2F6F6666D4 +:100750000A0070693C312F303E2020205072696EB3 +:100760007420494E464F206F6E2F6F66660A0A004E +:10077000706D3C312F303E2020205072696E742005 +:1007800044415441206F6E2F6F66660A0070703CC2 +:10079000312F303E2020205072696E742050415419 +:1007A00048206F6E2F6F66660A0070643C312F30F0 +:1007B0003E2020205072696E7420445354206F6E86 +:1007C0002F6F66660A0070733C312F303E20202068 +:1007D0005072696E7420535243206F6E2F6F66669D +:1007E0000A006D613C312F303E2020204175746F2E +:1007F0006D61746963206D65737361676520414342 +:100800004B206F6E2F6F66660A0A006D723C737321 +:1008100069643E20205265747279206C6173742083 +:100820006D6573736167650A006D733C737369640A +:100830003E2020536574206D657373616765207277 +:100840006563697069656E7420535349440A006D8D +:10085000633C63616C6C3E2020536574206D65734E +:100860007361676520726563697069656E74206382 +:10087000616C6C7369676E0A006C743C732F613E27 +:1008800020202053656C6563742073796D626F6CF2 +:10089000207461626C6520287374616E6461726497 +:1008A0002F616C7465726E617465290A0A006C733D +:1008B0003C73796D3E20202053656C656374207312 +:1008C000796D626F6C0A006C643C302D393E2020DB +:1008D0002053657420616E74656E6E612064697268 +:1008E000656374697669747920696E666F0A006C55 +:1008F000673C302D393E20202053657420616E7492 +:10090000656E6E61206761696E20696E666F0A00B0 +:100910006C683C302D393E20202053657420616E78 +:1009200074656E6E612068656967687420696E66BB +:100930006F0A006C703C302D393E202020536574C6 +:1009400020545820706F77657220696E666F0A00B8 +:100950006C6C6F3C4C4F4E3E2020536574206C6194 +:1009600074697475646520284E4D45412D666F721B +:100970006D61742C2065672030373230312E373569 +:1009800057290A006C6C613C4C41543E2020536551 +:1009900074206C6174697475646520284E4D4541FE +:1009A0002D666F726D61742C206567203439303389 +:1009B0002E35304E290A0073323C737369643E2031 +:1009C0002053657420504154483220535349440AFF +:1009D0000A0073313C737369643E202053657420B0 +:1009E000504154483120535349440A0073643C73C6 +:1009F0007369643E20205365742064657374696E66 +:100A00006174696F6E20535349440A0073633C73E9 +:100A10007369643E202053657420796F757220538A +:100A20005349440A00323C63616C6C3E20202053E1 +:100A300065742050415448322063616C6C7369675F +:100A40006E0A0A00313C63616C6C3E2020205365C5 +:100A5000742050415448312063616C6C7369676E37 +:100A60000A00643C63616C6C3E2020205365742056 +:100A700064657374696E6174696F6E2063616C6C18 +:100A80007369676E0A00633C63616C6C3E202020D2 +:100A900053657420796F75722063616C6C7369673C +:100AA0006E0A00233C6D73673E2020202053656E44 +:100AB000642041505253206D6573736167650A0A63 +:100AC00000403C636D743E2020202053656E6420FE +:100AD0006C6F636174696F6E2075706461746520FA +:100AE00028636D74203D206F7074696F6E616C2097 +:100AF000636F6D6D656E74290A00213C64617461D9 +:100B00003E20202053656E642072617720706163FF +:100B10006B65740A0053657269616C20636F6D6D5B +:100B2000616E64733A0A002D2D2D2D2D2D2D2D2D46 +:100B30002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DE5 +:100B40002D2D2D2D2D2D2D2D2D0A0053796D626FFC +:100B50006C3A2025630A0053796D626F6C207461D2 +:100B6000626C653A207374616E646172640A00534A +:100B7000796D626F6C207461626C653A20616C748F +:100B800065726E6174650A004469726563746976A2 +:100B90006974793A2025640A004761696E3A202514 +:100BA000640A004865696768743A2025640A005041 +:100BB0006F7765723A2025640A004175746F2D6164 +:100BC000636B206D657373616765733A204F66666A +:100BD0000A004175746F2D61636B206D65737361DD +:100BE0006765733A204F6E0A0050617468323A208C +:100BF000252E36732D25640A0050617468313A2021 +:100C0000252E36732D25640A0044657374696E6160 +:100C100074696F6E3A20252E36732D25640A0043C1 +:100C2000616C6C7369676E3A20252E36732D2564CE +:100C30000A00436F6E66696775726174696F6E3A18 +:100C40000A00300A004572726F723A20496E76616E +:100C50006C696420636F6D6D616E640A00310A0017 +:100C60004D657373616765206175746F2D61636B8A +:100C70002064697361626C65640A00310A004D6525 +:100C80007373616765206175746F2D61636B206597 +:100C90006E61626C65640A00310A005265747269A3 +:100CA0006564206C617374206D6573736167650A98 +:100CB00000310A000A002D25640A004D6573736136 +:100CC000676520726563697069656E743A20252EC8 +:100CD000367300310A000A002D25640A004D657341 +:100CE0007361676520726563697069656E743A2027 +:100CF000252E367300310A0053656C656374656494 +:100D0000207374616E646172642073796D626F6CBC +:100D1000207461626C650A0053656C656374656478 +:100D200020616C7465726E6174652073796D626F99 +:100D30006C207461626C650A0053796D626F6C207F +:100D400073657420746F2025630A004469726563BB +:100D50007469766974792073657420746F202564D2 +:100D60006465670A004469726563746976697479B9 +:100D70002073657420746F206F6D6E690A00310AEC +:100D800000310A004761696E2073657420746F201A +:100D9000256464420A00310A00416E74656E6E611A +:100DA000206865696768742073657420746F2025F6 +:100DB0006C646D204141540A00310A00506F776520 +:100DC000722073657420746F202564770A00310ADD +:100DD000004C6F6E67746974756465207365742068 +:100DE000746F20252E39730A00310A004C61746932 +:100DF000747564652073657420746F20252E3873B4 +:100E00000A00310A005072696E7420494E464F2024 +:100E100064697361626C65640A00310A005072692A +:100E20006E7420494E464F20656E61626C65640A9F +:100E300000310A005072696E7420444154412064AC +:100E4000697361626C65640A00310A005072696EF0 +:100E500074204441544120656E61626C65640A00EF +:100E6000310A005072696E74205041544820646900 +:100E70007361626C65640A00310A005072696E74B5 +:100E8000205041544820656E61626C65640A0031EF +:100E90000A005072696E742044535420646973616F +:100EA000626C65640A00310A005072696E742044F5 +:100EB000535420656E61626C65640A00310A00500B +:100EC00072696E74205352432064697361626C6569 +:100ED000640A00310A005072696E74205352432034 +:100EE000656E61626C65640A00310A005061746865 +:100EF000323A20252E36732D25640A00310A00501F +:100F0000617468313A20252E36732D25640A00312C +:100F10000A0044657374696E6174696F6E3A2025C6 +:100F20002E36732D25640A00310A0043616C6C7300 +:100F300069676E3A20252E36732D25640A00310A22 +:100F40000050617468323A20252E36732D25640ACC +:100F500000310A0050617468313A20252E36732D15 +:100F600025640A00310A0044657374696E6174690E +:100F70006F6E3A20252E36732D25640A00310A0043 +:100F800043616C6C7369676E3A20252E36732D258C +:100F9000640A00310A004D657373616765207365EB +:100FA0006E740A00310A004C6F636174696F6E20C1 +:100FB0007570646174652073656E740A00310A008F +:100FC0005061636B65742073656E740A00310A00AA +:100FD000436F6E66696775726174696F6E207361C5 +:100FE0007665640A00300A004572726F723A204ECC +:100FF0006F2073746F72656420636F6E66696775C6 +:10100000726174696F6E20746F206C6F6164210A65 +:1010100000436F6E66696775726174696F6E206CEC +:101020006F616465640A00310A00436F6E66696728 +:1010300075726174696F6E20636C65617265642E90 +:10104000205265737461727420746F206C6F6164D8 +:101050002064656661756C74732E0A002D2D2D2D2C +:101060002D2D2D2D2D2D2D2D2D2D2D0A004D6F6467 +:10107000656D2072656164790A0044656661756C0E +:101080007420636F6E66696775726174696F6E2034 +:101090006C6F61646564210A00756E7369676E65C3 +:1010A000642E696F2F6D6963726F617072730A00CD +:1010B0004D6963726F415052532076302E32610A6F +:1010C000002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D7D +:1010D0000A006275665F706F696E746572203E3DCE +:1010E0002062756600626572746F732F6D7761722E +:1010F000652F666F726D617477722E6300203D20DC +:10110000307825700A00496E76616C6964207074CD +:10111000723A20003A2000417373657274696F6EF1 +:10112000206661696C65643A200011241FBECFEF10 +:10113000D8E0DEBFCDBF12E0A0E0B1E0E8EEF3E71B +:1011400002C005900D92A233B107D9F716E0A2E3D1 +:10115000B2E001C01D92AB3DB107E1F70E94B319A7 +:101160000C94F2390C9400001092C00088E980932E +:10117000C10008951092C1000895FC01228521113B +:1011800005C021E0228788EB8093C10008959A0171 +:10119000AB01CA01B9019695879577956795605C13 +:1011A0007D4B804F9F4F0E9408382150310930936A +:1011B000C5002093C4000895E2ECF0E08081A4E033 +:1011C000660F771FAA95E1F78F7C862B80830895A1 +:1011D0009FB7F89484B1886284B99FBF8FB7F894A1 +:1011E000229A8FBF8FB7F89424988FBF80ED8CBD63 +:1011F0008CB581608CBD8DB58E7F8DBD08951CBC76 +:101200009FB7F89484B1837C84B99FBF08950895F3 +:101210000895FC01828508956FB7F894DC011A9651 +:101220002C911A97211120C0E0913A06F0913B06CB +:10123000478D50A121A132A142175307A9F021E007 +:101240001A962C93A78DB0A185A196A1A817B907CE +:1012500019F483A194A104C0A78DB0A1CD0101967A +:1012600090A3878F8C918EBD6FBF0895CF93DF932E +:10127000EC018230910544F049E953E067E770E002 +:1012800088E690E00E9497352BE02C9FC0012D9FAF +:10129000900D11248A5F9E4FDF91CF9108951F9288 +:1012A0000F920FB60F9211242F933F938F939F931A +:1012B000AF93BF93EF93FF93E0913806F091390617 +:1012C000278D30A181A192A12817390731F488E92F +:1012D0008093C1001092100113C0A78DB0A185A109 +:1012E00096A1A817B90719F483A194A104C0A78DEA +:1012F000B0A1CD01019690A3878F8C918093C600F9 +:10130000FF91EF91BF91AF919F918F913F912F915D +:101310000F900FBE0F901F9018951F920F920FB64F +:101320000F9211242F933F934F935F938F939F932B +:10133000AF93BF93EF93FF93E0913806F091390696 +:1013400097A58091C0008871892B87A75091C6000E +:1013500027A130A583A594A52817390739F421A51D +:1013600032A585A596A52817390761F021A532A5D4 +:1013700087A190A5019741E02817390709F040E0BF +:10138000842F01C081E080FF04C087A5816087A70A +:1013900012C0A1A5B2A55C9321A532A585A596A5ED +:1013A0002817390719F483A594A503C081A592A530 +:1013B000019692A781A7FF91EF91BF91AF919F9165 +:1013C0008F915F914F913F912F910F900FBE0F9092 +:1013D0001F9018951F920F920FB60F9211242F9302 +:1013E0003F934F938F939F93AF93BF93EF93FF934D +:1013F000E0913A06F0913B0627A130A583A594A57C +:101400002817390739F421A532A585A596A52817EF +:10141000390761F021A532A587A190A5019741E088 +:101420002817390709F040E0842F01C081E080FDD2 +:1014300013C08EB5A1A5B2A58C9321A532A585A513 +:1014400096A52817390719F483A594A503C081A58B +:1014500092A5019692A781A7E0913A06F0913B06EA +:10146000278D30A181A192A12817390799F0A78D66 +:10147000B0A185A196A1A817B90719F483A194A1D9 +:1014800004C0A78DB0A1CD01019690A3878F8C9148 +:101490008EBD02C010921B01FF91EF91BF91AF91E1 +:1014A0009F918F914F913F912F910F900FBE0F9071 +:1014B0001F9018959FB7F89483E085BB14BC15BCAA +:1014C00082E084BD85B5836085BD16BC89EF87BD8C +:1014D000EEE6F0E080818E7F808380818260808371 +:1014E0009FBF0895CF93DF93EC01FB015FB7F894A2 +:1014F000278D30A183A194A128173907E9F421A1F0 +:1015000032A185A196A128173907B1F481E05FBF08 +:1015100080FD11C04FB7F894A1A1B2A1CC9321A135 +:1015200032A185A196A12817390799F483A194A126 +:1015300092A381A314C0DACF81A192A1278D30A1FB +:101540002150310941E08217930709F040E0842FD0 +:10155000DECF21A132A12F5F3F4F32A321A34FBF86 +:1015600080A991A9DC01ED91FC910084F185E02D29 +:101570000995CE019927DF91CF910895FC014FB7CE +:10158000F89427A130A581A592A54FBF2817390748 +:1015900039F087A5897B79F024C087A5897BC9F7B5 +:1015A0004FB7F89427A130A581A592A54FBF281762 +:1015B000390799F3EECF2FB7F894A7A1B0A585A569 +:1015C00096A5A817B90719F483A594A504C0A7A1E7 +:1015D000B0A5CD01019690A787A38C912FBF90E075 +:1015E00008958FEF9FEF0895AF92BF92CF92DF9251 +:1015F000EF92FF920F931F93CF93DF937C015B01D8 +:101600006A01FC0100891189228933890C34124551 +:101610002544334541F04CEB50E06CE771E084E643 +:1016200091E00E949735E50100E010E00C151D05E2 +:1016300059F0C7010E94BE0A8F3F2FEF920721F099 +:101640000F5F1F4F8993F2CFC801DF91CF911F9198 +:101650000F91FF90EF90DF90CF90BF90AF900895E3 +:10166000AF92BF92CF92DF92EF92FF920F931F93B0 +:10167000CF93DF937C015B016A01FC010089118932 +:10168000228933890C3412452544334541F04CEB13 +:1016900050E06CE771E084E691E00E949735E50147 +:1016A00000E010E00C151D0561F08991B701992744 +:1016B00087FD90950E94720A019619F00F5F1F4FE7 +:1016C000F1CFC801DF91CF911F910F91FF90EF9063 +:1016D000DF90CF90BF90AF900895CF93DF93EC0150 +:1016E000488959896A897B894C34524565447345D8 +:1016F00041F04CEB50E06CE771E084E691E00E9431 +:1017000097358FA590E0DF91CF910895CF93DF9328 +:10171000EC01488959896A897B894C345245654472 +:10172000734541F04CEB50E06CE771E084E691E0EA +:101730000E9497351FA6DF91CF910895CF93DF9335 +:10174000EC01488959896A897B894C345245654442 +:10175000734549F04CEB50E06CE771E084E691E0B2 +:101760000E94973500C02F8D38A189A19AA1281712 +:101770003907C9F788A999A9DC01ED91FC91028488 +:10178000F385E02D09958111EECF80E090E0DF91A7 +:10179000CF910895FC014FB7F89427A130A581A5FA +:1017A00092A54FBF28173907B1F02FB7F894A7A11A +:1017B000B0A585A596A5A817B90719F483A594A582 +:1017C00004C0A7A1B0A5CD01019690A787A38C91D5 +:1017D0002FBF90E008958FEF9FEF08956FB7F894B3 +:1017E000FC0147A150A521A532A56FBF81E042179A +:1017F000530709F480E00895DC01D0968D919C9107 +:10180000D197DC01ED91FC910480F581E02D0994E4 +:10181000EF92FF920F931F93CF93DF93EC018B0115 +:101820006230710540F042E651E064E371E088E126 +:1018300091E00E949735F801EE0FFF1FE85CF94F29 +:10184000D183C0838E8D882341F045E651E067E067 +:1018500071E08AEF90E00E94973581E08E8F1D8FB6 +:101860000C8FC8010E94360999AB88ABDC01129637 +:101870008D919C911397892B41F44DE651E069EECF +:1018800070E088ED90E00E949735E8A9F9A984817D +:101890009581892B41F44EE651E067EC70E086EBD0 +:1018A00090E00E949735E8A9F9A9E680F7800281C7 +:1018B0001381B2E0EB16F10440F441E251E06EE92D +:1018C00070E085E990E00E9497351CA30BA31AA352 +:1018D00009A318A30F8FC7010197800F911F9EA323 +:1018E0008DA3E8A9F9A9E084F18404811581E2E0DF +:1018F000EE16F10440F441E251E06EE970E085E952 +:1019000090E00E9497351CA70BA71AA709A718A754 +:101910000FA3C7010197800F911F9EA78DA788A9CC +:1019200099A9DC01ED91FC910190F081E02DBE01BF +:10193000099540E855E260E070E0CE010E94FC0BA2 +:101940001FA6CE01DF91CF911F910F91FF90EF90D5 +:1019500008954FB7F894FC0121A532A530A727A31D +:101960004FBF08954FB7F894FC0121A132A130A3D5 +:10197000278F4FBF0895CF93DF93EC010E94A90CEE +:10198000CE01DF91CF910C94B20CCF93DF93EC0199 +:10199000488959896A897B894C3452456544734525 +:1019A00041F04CEB50E06CE771E084E691E00E947E +:1019B00097358E8D811108C04BE851E063E571E0E9 +:1019C00085E491E00E9497351E8ECE010E949E0B09 +:1019D00088A999A9DC01ED91FC910280F381E02DA9 +:1019E000099519AA18AACE010E94BB0C80E090E0CC +:1019F000DF91CF910895CF93DF93EC014889598906 +:101A00006A897B894C3452456544734541F04CEBFF +:101A100050E06CE771E084E691E00E949735CE01DA +:101A20000E94C50C6C8D7D8DCE010E94080CCE01EC +:101A3000DF91CF910895FC01CB0122E3DF011D92DC +:101A40002A95E9F74CE452E565E473E5408B518B48 +:101A5000628B738B2BEF3CE03583248325EC3CE0D9 +:101A60003783268324EF3AE03183208320E33BE071 +:101A7000338322832EE93BE0338722872DE63BE048 +:101A80003587248726E83BE037872687BC01CF01CE +:101A90000C94080C1F920F920FB60F9211240F9303 +:101AA0001F932F933F934F935F936F937F938F93E6 +:101AB0009F93AF93BF93CF93DF93EF93FF93809167 +:101AC0003C0690913D06A0913E06B0913F060196DE +:101AD000A11DB11D80933C0690933D06A0933E0648 +:101AE000B0933F060BEA1AEBC0917202D0917302D9 +:101AF00088819981892BD1F18FB7F89440913C0668 +:101B000050913D0660913E0670913F068FBF8885DB +:101B10009985AA85BB85481B590B6A0B7B0B77FD02 +:101B200025C0CF3FD10509F048F42BEC30E040EC64 +:101B300051E063EB71E0CE010E94AD35EA81FB819B +:101B40008881998191838083E881F9818A819B8151 +:101B5000938382831B821A82198218821B8B0A8BC1 +:101B6000EC85FD85CE010C960995BECFFF91EF91D6 +:101B7000DF91CF91BF91AF919F918F917F916F91A5 +:101B80005F914F913F912F911F910F910F900FBE39 +:101B90000F901F90189586E792E0909373028093C0 +:101BA00072021092750210927402109277021092D3 +:101BB000760282E792E09093790280937802109205 +:101BC0003C0610923D0610923E0610923F060E947F +:101BD0005A0A80914006882341F041E951E060EAC9 +:101BE00071E08DE891E00E94973581E08093400696 +:101BF0000895EF92FF920F931F93CF93DF931F925D +:101C0000CDB7DEB77C018B018983DB0112968D9104 +:101C10009C911397892B41F44EE051E068EF71E0FD +:101C20008EEE91E00E949735D8011296ED91FC91CD +:101C3000139741E050E0BE016F5F7F4FC8010995E7 +:101C4000019719F4C701992702C08FEF9FEF0F90FA +:101C5000DF91CF911F910F91FF90EF9008950F9317 +:101C60001F93CF93DF931F92CDB7DEB78C01DC01BA +:101C70008D919C91892B41F442EF50E06CED71E025 +:101C800083ED91E00E949735D801ED91FC9141E000 +:101C900050E0BE016F5F7F4FC8010995019719F4AD +:101CA000898190E002C08FEF9FEF0F90DF91CF917D +:101CB0001F910F910895CF93DF93CDB7DEB79E01AB +:101CC000275F3F4F4D815E8169EF7DE08F81988571 +:101CD0000E94880EDF91CF9108950F931F93CF93A9 +:101CE000DF938C01EB018991882359F0B801992782 +:101CF00087FD90950E94F90D8F3F2FEF920799F77E +:101D000002C080E090E0DF91CF911F910F91089584 +:101D10002F923F924F925F926F927F928F929F92FB +:101D2000AF92BF92CF92DF92EF92FF920F931F93E9 +:101D3000CF93DF93CDB7DEB7C45AD1090FB6F8946D +:101D4000DEBF0FBECDBFFC01C856DF4F798368836D +:101D5000C859D040C656DF4F59834883CA59D0402E +:101D60005901C257DF4F19821882CE58D0409E01C8 +:101D70002F5F3F4FC957DF4F39832883C758D04063 +:101D8000AE014A575F4FC757DF4F59834883C95841 +:101D9000D0409F012F5F3F4FC456DF4F39832883C8 +:101DA000CC59D0408081853291F1882309F427C72E +:101DB000C656DF4F68817981CA59D040C856DF4F77 +:101DC000E881F981C859D0400995C257DF4FC880D2 +:101DD000D980CE58D040FFEFCF1ADF0AC557DF4F6A +:101DE000B982A882CB58D040C257DF4FD982C8826F +:101DF000CE58D040C557DF4FA880B980CB58D040CF +:101E0000C456DF4FE881F981CC59D040C2CF8181DF +:101E1000853251F4AF014E5F5F4FC456DF4F598397 +:101E20004883CC59D040C4CFC456DF4FA881B98174 +:101E3000CC59D040C256DF4F1882CE59D040C3573C +:101E4000DF4F1882CD58D040CF56DF4F1882C1598E +:101E5000D040CE56DF4F1882C259D040FD018D913F +:101E60008B3209F45EC060F48032E9F0833209F00D +:101E70005FC031E0C357DF4F3883CD58D040EECF3D +:101E80008D3251F0803309F053C041E0C256DF4F2C +:101E90004883CE59D040E2CF21E0CF56DF4F288390 +:101EA000C159D040DBCF392D3C7F932ECE56DF4F2A +:101EB0004881C259D040942ACD56DF4F5881C3592A +:101EC000D04050FB92F8CF56DF4F8881C159D040A7 +:101ED00080FB93F8C057DF4F9881C059D04090FBEA +:101EE00094F8CC56DF4FE881C459D040E0FB95F818 +:101EF000C357DF4FF881CD58D040F0FB96F8CB5652 +:101F0000DF4F2881C559D04020FB97F8892D837079 +:101F100009F0A4CF81E0CE56DF4F8883C259D0406C +:101F20009DCF51E0CE56DF4F5883C259D04096CF57 +:101F3000C357DF4F9881CD58D040C056DF4F9883AC +:101F4000C05AD0408A3229F0DF01212C312C2AE0FE +:101F500013C0C5010296D5012D903C9037FE09C0F3 +:101F6000319421943108B1E0CF56DF4FB883C15985 +:101F7000D04031965C0112C0FD018D9190ED980F1B +:101F80009A3060F4F1012E9F10012F9F300C112424 +:101F9000F0E32F1A3108280E311CEECFCF56DF4F59 +:101FA0002881C159D040222329F0C256DF4F188220 +:101FB000CE59D04080818E3221F581818A3231F034 +:101FC000DF011196612C712C2AE009C0D5016D90BA +:101FD0007C90329695012E5F3F4F590115C0FD014F +:101FE0008D9190ED980F9A3078F4A301249F3001E1 +:101FF000259F700C112450E3651A7108680E711C3E +:10200000EECF66246A94762CDF018D918836D9F064 +:1020100018F48C3459F01FC08C3641F08A37D9F44B +:10202000C057DF4F1882C059D04006C081E0C0576A +:10203000DF4F8883C059D040FD01CC56DF4F188256 +:10204000C459D04012C0FD0191E0CC56DF4F9883B7 +:10205000C459D04005C0CC56DF4F1882C459D04077 +:10206000C057DF4F1882C059D040DF011196C456C7 +:10207000DF4FB983A883CC59D0408080B5E68B165A +:1020800009F408C2B815ECF023E5821609F453C030 +:10209000281564F035E4831609F4FCC147E484167E +:1020A00009F4F0C1882009F465C42AC053E68516F6 +:1020B00071F158150CF4CBC088E5881609F48DC071 +:1020C0001FC090E7891609F471C0981564F0A7E65F +:1020D0008A1609F4D7C18A160CF4DBC1B9E68B164F +:1020E00009F4B5C00DC0E5E78E1609F476C0F8E72F +:1020F0008F1609F46DC023E7821202C0D12C1DC0D7 +:10210000C557DF4FB982A882CB58D0403FC4A50144 +:102110004E5F5F4FC557DF4F59834883CB58D04040 +:10212000D5018C918983D12C8E010E5F1F4FFE014A +:1021300031965F0139C4DD24D39495012E5F3F4F62 +:10214000C557DF4F39832883CB58D040D501AD9098 +:10215000BC90A114B10421F4A0E2AA2EA1E0BA2EF1 +:1021600077FE04C0F0E16F2EF7E27F2E8501DD20BF +:10217000C1F0F8018491882309F416C4C8018A19B2 +:102180009B09861597050CF00FC40F5F1F4FF1CF09 +:10219000C8018A199B09861597050CF005C40F5FC5 +:1021A0001F4FD8018C918111F3CFFEC3F5013296F8 +:1021B000C557DF4FF983E883CB58D040D5016D91E7 +:1021C0007C9180E090E0E4E7EE2EE1E0FE2E2BC073 +:1021D00074E8E72E71E0F72E04C064E7E62E61E0B4 +:1021E000F62EC057DF4FB881C059D040BB2371F0E5 +:1021F000F5013496C557DF4FF983E883CB58D040BB +:10220000D5016D917D918D919C910DC0C501029676 +:10221000F50160817181C557DF4F99838883CB5861 +:10222000D04080E090E021E0CD56DF4F2883C359B5 +:10223000D04035E7831205C0CD56DF4F1882C35911 +:10224000D040CE56DF4F1882C259D04042C0C0574E +:10225000DF4F4881C059D040442371F0C501049636 +:10226000C557DF4F99838883CB58D040D5016D91F6 +:102270007D918D919C910FC0F5013296C557DF4F2E +:10228000F983E883CB58D040D5016D917C918827A4 +:1022900077FD8095982F97FF13C090958095709546 +:1022A00061957F4F8F4F9F4FCD56DF4F1882C35997 +:1022B000D040B2E0CE56DF4FB883C259D04005C0FF +:1022C000CD56DF4F1882C359D04054E7E52E51E078 +:1022D000F52EE1E0CB56DF4FE883C559D0406115BC +:1022E00071058105910529F4CB56DF4F1882C55938 +:1022F000D0406114710441F4CB56DF4FF881C559C9 +:10230000D040FF2309F47CC0CD56DF4F2881C3594C +:10231000D0408E010A571F4F2130A9F02AE030E04B +:1023200040E050E00E940838F701E60FF71F808177 +:10233000D8018E938D01B901CA016115710581051E +:10234000910561F715C0FB01EF70FF27EE0DFF1D32 +:102350002081F80122938F0144E096958795779527 +:1023600067954A95D1F7611571058105910559F772 +:1023700077FE49C0C256DF4FF881CE59D040FF23C7 +:1023800009F441C0292D2C7F922ECE56DF4F388183 +:10239000C259D040932ACD56DF4F4881C359D0400F +:1023A00040FB92F8CF56DF4F5881C159D04050FBC7 +:1023B00093F8C057DF4F8881C059D04080FB94F814 +:1023C000CC56DF4F9881C459D04090FB95F8C35745 +:1023D000DF4FA881CD58D040A0FB96F8CB56DF4FF9 +:1023E000B881C559D040B0FB97F8292D237081E002 +:1023F00090E011F480E090E03101681A790A03C09E +:102400008E010A571F4FC757DF4F88819981C958DE +:10241000D040801B910BF80120E35F0186159705E2 +:102420001CF422930196F9CFC357DF4FE881CD58B2 +:10243000D040EE23A1F0CB56DF4FF881C559D040F4 +:10244000FF2369F0882D8F7D883549F4F501319798 +:10245000808222E0A21AB10880E3D5018C93C9578B +:10246000DF4FE881F981C758D040AE16BF0608F0AB +:1024700095C247EB52E06DE172E08AE092E00E9483 +:1024800097358CC28A948A9411E06114710449F0E2 +:1024900002C0812C10E077FE07C026E0622E712C6E +:1024A00003C066246394712C95012C5F3F4FC55780 +:1024B000DF4F39832883CB58D040D501CD90DD90B4 +:1024C000ED90FC9020E030E0A901C701B6010E9428 +:1024D000373687FF0AC0F7FAF094F7F8F094B2E0C5 +:1024E000CE56DF4FB883C259D040C156DF4F188354 +:1024F000CF59D040AA24A394B12CAC0EBD1EA20C7F +:10250000B31C20E030E040E85FE3C701B6010E9461 +:10251000863787FD32C0412C512C27EB33E44AEB40 +:1025200051E5C701B6010E94863787FD0EC029EF2D +:1025300032E045E150E5C701B6010E943B366B0130 +:102540007C01EAE04E0E511CE8CF20E030E040E292 +:1025500051E4C701B6010E94863787FD49C020E0DB +:1025600030E040E251E4C701B6010E943B366B0106 +:102570007C01FFEF4F1A5F0AE8CF20E030E0A901AD +:10258000C701B6010E943736412C512C882381F1B6 +:102590002FEF36EE4BED5EE2C701B6010E943736F3 +:1025A000181674F029EF32E045E150E5C701B60195 +:1025B0000E948A376B017C012AE0421A5108E8CF59 +:1025C00020E030E040E85FE3C701B6010E94373603 +:1025D00087FF0EC020E030E040E251E4C701B601C1 +:1025E0000E948A376B017C0131E0431A5108E8CF21 +:1025F000112301F14614570444F44CEF44164FEFF5 +:1026000054061CF064187508812C51E0651A710895 +:1026100081E0C357DF4F9881CD58D0409827C156ED +:10262000DF4F9883CF59D040A1E0C357DF4FA88335 +:10263000CD58D04081104BC057FE3DC080E3E1E053 +:10264000F0E0EC0FFD1FE20DF31D8083F501611436 +:10265000710459F4C357DF4FB881CD58D040B11140 +:1026600004C0319680E090E006C032968EE2D5013B +:1026700011968C93C30192012F5F3F4F280F391F92 +:1026800040E38F018217930729F0009719F04193D7 +:102690000197F7CF930120953095421653060CF41D +:1026A000D1C03C01E1E0F0E0CA56DF4FF983E88396 +:1026B000C659D0405CC02227332724193509CA5691 +:1026C000DF4F39832883C659D040850150C085012A +:1026D000CA56DF4F19821882C659D04048C0C70178 +:1026E000B6010E94A336CF55DF4F688379838A8372 +:1026F0009B83C15AD040CF55DF4F48815981C15A81 +:10270000D040BA01882777FD8095982F0E94D63651 +:102710009B01AC01C701B6010E94D23520E030E038 +:1027200040E251E40E948A376B017C0198012F5FDF +:102730003F4FCF55DF4F8881C15AD040805DD801CF +:102740008C93CA56DF4F88819981C659D040019633 +:10275000CA56DF4FE881F981C659D040EF2B91F07E +:10276000CA56DF4F99838883C659D0408901CA561B +:10277000DF4F28813981C659D040621673060CF0AC +:10278000AECF14C06114710439F4C357DF4FF88120 +:10279000CD58D040FF2339F098012E5F3F4FEEE235 +:1027A000D8011196EC9381E090E0DACF20E030E0A0 +:1027B00040EA50E4C701B6010E94863787FD42C057 +:1027C000F80181E090E030E322912E3251F0820F47 +:1027D0008A3321F0808380E090E003C0308381E081 +:1027E00090E0AE16BF0680F3892B61F18820B9F026 +:1027F000F801AE16BF0678F4DF018E919D018E328E +:1028000039F4CF010297DC018C918083F90101C07A +:1028100080833197EECFBFEF4B1A5B0A0BC00F5F7F +:102820001F4FF801AE16BF0628F4DF018E9180839A +:10283000FD01F8CF81E3E1E0F0E0EC0FFD1FE20DD8 +:10284000F31D8083C156DF4FE881CF59D040EE237E +:1028500049F0F8018291803311F48F01FACF8E3262 +:1028600009F48F018820B1F1D8018C92C801029639 +:1028700057FE07C02DE211962C93519441945108B4 +:1028800003C02BE2F80121838C01065F1F4F20E07B +:1028900030E02F5F3F4FF8013196C2016AE070E0EF +:1028A0000E94F437805DD8018C932B01611571056E +:1028B00011F08F01EECF22303105DCF3E21BF30B78 +:1028C000199781918E932150310912161306CCF37A +:1028D00009501109C256DF4FB881CE59D040BB23F1 +:1028E00009F461C0E92DEC7F9E2ECE56DF4FF881B2 +:1028F000C259D0409F2ACD56DF4F2881C359D040BE +:1029000020FB92F8CF56DF4F3881C159D04030FBC1 +:1029100093F8C057DF4F4881C059D04040FB94F82E +:10292000CC56DF4F5881C459D04050FB95F8C05663 +:10293000DF4F8881C05AD04080FB96F8CB56DF4FDE +:102940009881C559D04090FB97F8292D237081E0DC +:1029500090E011F480E090E09101281B390BF50123 +:1029600040E35F01C8018E1B9F0B82179307DCF4C5 +:102970004293F7CFC557DF4FB982A882CB58D040DA +:10298000C456DF4FF983E883CC59D040D12C0FE1F6 +:1029900011E08CE1A82E81E0B82E06C0D12C8E016A +:1029A0000A571F4F01C0D12C0A191B0920163106E6 +:1029B0000CF440C0A92DAC7F9A2ECE56DF4FB881C3 +:1029C000C259D0409B2ACD56DF4FE881C359D04031 +:1029D000E0FB92F8CF56DF4FF881C159D040F0FBB1 +:1029E00093F8C057DF4F2881C059D04020FB94F89E +:1029F000CC56DF4F3881C459D04030FB95F8C056D3 +:102A0000DF4F4881C05AD04040FB96F8CB56DF4F8D +:102A10005881C559D04050FB97F87101E01AF10A6E +:102A2000292D237081E090E011F480E090E0E81A15 +:102A3000F90A02C0E12CF12CCF56DF4F8881C15931 +:102A4000D040811122C031E0E31AF108F7FC1DC02B +:102A5000C656DF4F68817981CA59D04080E2C85696 +:102A6000DF4FE881F981C859D0400995C257DF4F3F +:102A700028813981CE58D0402F5F3F4FC257DF4F5A +:102A800039832883CE58D040DECF492D4C7F942EF9 +:102A9000CE56DF4F5881C259D040952ACD56DF4FD0 +:102AA0008881C359D04080FB92F8CF56DF4F988180 +:102AB000C159D04090FB93F8C057DF4FA881C0594F +:102AC000D040A0FB94F8CC56DF4FB881C459D04019 +:102AD000B0FB95F8C056DF4FE881C05AD040E0FB0C +:102AE00096F8CB56DF4FF881C559D040F0FB97F8E8 +:102AF000892D837001F1813011F48BE201C08DE2E8 +:102B0000C656DF4F68817981CA59D040C856DF4F19 +:102B1000E881F981C859D0400995C257DF4F288113 +:102B20003981CE58D0402F5F3F4FC257DF4F398396 +:102B30002883CE58D040D1100AC03501C257DF4F8C +:102B4000A880B980CE58D040A618B70821C0C25777 +:102B5000DF4FC880D980CE58D040AC18BD08015096 +:102B6000110917FD2DC0F501EC0DFD1D8491C65610 +:102B7000DF4F68817981CA59D040C856DF4FE8815C +:102B8000F981C859D0400995FFEFCF1ADF0AE7CF86 +:102B90006501C60CD71C0150110917FD11C0C6569E +:102BA000DF4F68817981CA59D040D3018D913D01B1 +:102BB000C856DF4FE881F981C859D0400995E8CF60 +:102BC000CF56DF4FF881C159D040FF2309F40CC91B +:102BD00021E0E21AF108F7FC07C9C656DF4F688109 +:102BE0007981CA59D04080E2C856DF4FE881F98127 +:102BF000C859D0400995FFEFCF1ADF0AE9CFC25775 +:102C0000DF4F88819981CE58D040CC55DF4F0FB629 +:102C1000F894DEBF0FBECDBFDF91CF911F910F9112 +:102C2000FF90EF90DF90CF90BF90AF909F908F90EC +:102C30007F906F905F904F903F902F900895CF922C +:102C4000DF92EF92FF920F931F93CF93DF931F9228 +:102C5000CDB7DEB77C01462F82E8860F9701265B51 +:102C60003E4F6901823010F06B3149F4F60160810A +:102C700071818BE190E049830E94F90D4981D70170 +:102C8000A05BBE4F2C9111965C911197842F90E020 +:102C9000FC01E227EE0FFF1FE654FC4F2591349113 +:102CA000052F10E0202731272D933C93F6016081FA +:102CB00071810F90DF91CF911F910F91FF90EF9055 +:102CC000DF90CF900C94F90D2F923F924F925F922C +:102CD0006F927F928F929F92AF92BF92CF92DF922C +:102CE000EF92FF920F931F93CF93DF93CDB7DEB791 +:102CF000C455D1090FB6F894DEBF0FBECDBF8C010D +:102D00005C0126EBA21A2EEFB20A4C014BEA841AA0 +:102D10004EEF940A7C0184EBE81A8EEFF80AD50195 +:102D20008D919C910E942F0E8F3FBFEF9B0709F45E +:102D300041C1F401208121110CC18E37910509F0A8 +:102D4000FAC0D7014D915C91F801E25BFE4F1F0183 +:102D50004231510508F4E1C080819181883B904F58 +:102D600009F0DBC0D801FE013896CE010E962D91F8 +:102D70002695203209F420E02193E817F907B9F7E6 +:102D8000D80116968C91169786958F708E87179618 +:102D9000FE013196CF0106962D912695203209F439 +:102DA00020E02193E817F907B9F7F8013D96D8011B +:102DB0001D968C9186958F708F8329964FAC29979D +:102DC000512C61E070E0808180FF19C028965FAED1 +:102DD000289729964FAE29972181822F90E02B9634 +:102DE0009FAF8EAF2B97039709F463C01F922F9369 +:102DF0008DE991E09F938F9384E793E068C0B7E0FB +:102E0000B51520F366246394712C6C0E7D1E27E0AB +:102E1000529E600C711C1124CF01019663969FAFE6 +:102E20008EAF639780E090E0252D30E06396AEADE5 +:102E3000BFAD6397DD906396BFAFAEAF6397D69497 +:102E4000B0E2DB1202C0C12C01C0CD2CD301A80F0F +:102E5000B91F1E96CC9201968630910539F73796A8 +:102E60009081B7E0CB2EC29ED001C39EB00D11243D +:102E7000CC24C394D12CCC0EDD1EAC0DBD1D892FEE +:102E800086958F7054968C9397FF08C0CB0102C033 +:102E9000880F991F2A95E2F7482A09C0DB0102C072 +:102EA000AA0FBB1F2A95E2F79D0120954222539459 +:102EB0008ACF82812C968FAF2C97803F99F01F92FA +:102EC0008F938DE991E09F938F9383E393E09F939A +:102ED0008F930E9415350F900F900F900F900F90C9 +:102EE0000F901BC0339642505109C8018E1B9F0B97 +:102EF000480F591F60965FAF4EAF60972E96FFAF99 +:102F0000EEAF2E97F801EE5AFE4F0190F081E02DC2 +:102F1000309719F0CE010196099581E0F801EC5A3D +:102F2000FE4F80838FEF9FEFD1018D939C93F7012C +:102F300011821082F4CE8F37910529F4F801EC5AF2 +:102F4000FE4F1082ECCE8B31910519F481E0808325 +:102F5000E6CEF801EC5AFE4F2081222341F1D70141 +:102F60002D913C912A34B1E03B0700F5A9014F5F58 +:102F70005F4FF70151834083F801E20FF31F808315 +:102F8000D801A25BBE4F2D913C911197F901E82722 +:102F9000FF27EE0FFF1FE654FC4F85919491232FDE +:102FA0003327822793278D939C9301C01082D401ED +:102FB0001C92B5CEF50100811181D8011C968D912E +:102FC0009C911D97892B41F449E451E061E273E043 +:102FD00087E193E00E949735D8011C96ED91FC9112 +:102FE0001D97C8010995892B09F444C0F50100819A +:102FF0001181D8011C968D919C911D97892B41F4CC +:1030000049E451E061E273E087E193E00E94973583 +:10301000D8011C96ED91FC911D97C80109959F93CD +:103020008F9382EA91E09F938F9380EA93E09F933E +:103030008F930E941535F501008111810F900F903B +:103040000F900F900F900F90D8011E968D919C912C +:103050001F97892B41F442E551E065E073E088EF6A +:1030600092E00E949735D8011E96ED91FC911F9732 +:10307000C8010995CC5ADF4F0FB6F894DEBF0FBEDA +:10308000CDBFDF91CF911F910F91FF90EF90DF9017 +:10309000CF90BF90AF909F908F907F906F905F90F8 +:1030A0004F903F902F9008952F923F924F925F92B2 +:1030B0006F927F928F929F92AF92BF92CF92DF9248 +:1030C000EF92FF920F931F93CF93DF93CDB7DEB7AD +:1030D0002C970FB6F894DEBF0FBECDBF9C878B87B1 +:1030E0007B015A01288739871D830C83611571057F +:1030F00041F448EF50E066EE72E081EE92E00E940B +:10310000973522E0A216B10440F449EF50E06FEC8D +:1031100072E081EC92E00E9497354B845C8480EBF6 +:10312000481A8EEF580A8FEF9FEFF2019183808348 +:103130006B847C84F6EB6F1AFEEF7F0AF3016081EB +:1031400071818EE790E00E94F90DC12CD12CC50150 +:1031500001979F838E83CA14DB0409F468C021E0C1 +:1031600029838E819F81C816D90609F01982F7013B +:1031700001900020E9F78F01015011090E191F0974 +:103180000730110510F006E010E0C8018E0D9F1DFC +:103190009B838A8317018A819B812816390601F156 +:1031A000F10121911F01822E912CC4012A870E94D6 +:1031B00093392A85892B51F4203241F04BED50E0B0 +:1031C0006CE772E085E692E00E949735C4010E94A8 +:1031D000A739682F660F8B859C850E941F16DBCF51 +:1031E0000630110599F0812C912CE6E0F0E0E01B0F +:1031F000F10B8F018016910648F460E48B859C8565 +:103200000E941F16FFEF8F1A9F0AF4CF89818066F4 +:10321000F7016681660F682B8B859C850E941F16BF +:10322000FFEFCF1ADF0A27E0E20EF11C94CF63E034 +:103230008B859C850E941F1660EF8B859C850E9464 +:103240001F1608851985EC80FD80E00EF11E0E1515 +:103250001F0541F0F80161918F018B859C850E94CB +:103260001F16F5CFF2016081118160958B859C85D9 +:103270000E941F16612F60958B859C850E941F16EA +:10328000F20180819181883B904F41F042E151E011 +:103290006FEA72E08EE892E00E949735F301608158 +:1032A00071818EE790E02C960FB6F894DEBF0FBECA +:1032B000CDBFDF91CF911F910F91FF90EF90DF90E5 +:1032C000CF90BF90AF909F908F907F906F905F90C6 +:1032D0004F903F902F900C94F90DEF92FF920F9327 +:1032E0001F93CF93DF93EC018B017A01009741F498 +:1032F00042E451E063E572E08FE492E00E9497358A +:103300000115110541F443E451E06DE372E085E3FA +:1033100092E00E94973586E591E0FE019C011192B2 +:1033200021503040E1F7FE01E65BFE4F1183008340 +:10333000FE01EE5AFE4FF182E082FE01E05BFE4F9D +:103340008FEF9FEF91838083C25BDE4F99838883E9 +:10335000DF91CF911F910F91FF90EF9008956AEC4C +:1033600073E00C94CE2178940E94CB0D60E070E065 +:103370008AEC93E00E941B0D40E855E260E070E0AB +:103380008AEC93E00E94FC0B86E08093C20060E030 +:1033900070E082E595E00E94341F4FEA59E162E552 +:1033A00075E08CEF93E00E946D190E94D9208FB7D1 +:1033B000F894C0903C06D0903D06E0903E06F09018 +:1033C0003F068FBFC1E08CEF93E00E9464168091AE +:1033D0007A0281112EC08AEC93E00E94EE0B8823C2 +:1033E00041F18AEC93E00E94CA0B80937D02909396 +:1033F0007E0220917B0230917C02F901E158FD4F61 +:10340000A9014F5F5F4F808350937C0240937B0202 +:103410002934314010F0C0937A028FB7F894C090ED +:103420003C06D0903D06E0903E06F0903F068FBFF0 +:103430001BC080917B0290917C02892BA9F02FB751 +:10344000F89480913C0690913D06A0913E06B09183 +:103450003F062FBF8C199D09AE09BF090397A1052F +:10346000B10514F0C0937A0280917A02882309F49E +:10347000AACF60917B0270917C022CEF33E04AEC82 +:1034800053E08FE792E00E94282610927A02109271 +:103490007C0210927B0297CFCF93DF93EC01709365 +:1034A0002D0660932C068630910544F041E250E0F1 +:1034B00062EC75E08AEB95E00E94973510928000EF +:1034C00089E18093810081E896E090938700809362 +:1034D00086008C2F806480937C0087B121E030E0EF +:1034E00001C0220FCA95EAF7922F9095892387B9D8 +:1034F00088B1892388B980917E00822B80937E00D9 +:1035000087E080937B008CEE80937A00DF91CF91EF +:1035100008951F920F920FB60F9211242F933F938D +:103520004F935F936F937F938F939F93AF93BF93CB +:10353000EF93FF9380E286BB6091780070917900F1 +:103540007695679576956795605880912C06909151 +:103550002D060E944B1C80914206882349F08091E1 +:103560002C0690912D060E941B1E807F886007C04C +:1035700080914106882311F088E801C080E88BB96A +:10358000FF91EF91BF91AF919F918F917F916F913B +:103590005F914F913F912F910F900FBE0F901F9011 +:1035A0001895AF92BF92CF92DF92EF92FF920F9356 +:1035B0001F93CF93DF936C01EB017A01DC015096EE +:1035C0000D911D912D913C9153970D341B44234532 +:1035D000364441F04EE650E069EE75E083ED95E04B +:1035E0000E9497355E01CE018E0D9F1DF601EB57AF +:1035F000FF4FA816B90671F4C5018C1B9D0BDF9116 +:10360000CF911F910F91FF90EF90DF90CF90BF90DF +:10361000AF9008956FB7F894408151812281338132 +:103620006FBF4217530741F32FB7F894C0903C0681 +:10363000D0903D06E0903E06F0903F062FBF6FB75A +:10364000F89440815181228133816FBF4217530723 +:10365000A9F44FB7F89400913C0610913D062091D3 +:103660003E0630913F064FBF0C191D092E093F0938 +:10367000101611061206130614F7BECF6FB7F89492 +:1036800020813181468157812417350719F44481FF +:10369000558105C020813181A9014F5F5F4F518362 +:1036A0004083D9012C916FBFD5012D935D01A1CF2E +:1036B0006F927F928F929F92AF92BF92CF92DF9242 +:1036C000EF92FF920F931F93CF93DF93EC018B0147 +:1036D0007A0188899989AA89BB898D349B44A3453D +:1036E000B64441F04EE650E069EE75E083ED95E0BA +:1036F0000E949735F801A8014E0D5F1D99249394FF +:10370000BB24B3943E0187E7680E711C20E430E0CF +:1037100065E370E088E0E82EF12CE417F50709F482 +:103720004EC0AFB6F894CFA4D8A88BA99CA9C81650 +:10373000D90639F4C9A8DAA88DA99EA9C816D90650 +:1037400069F0C9A8DAA88FA598A90197882483945D +:10375000C816D90609F0812C882D01C081E0AFBEC2 +:1037600080FDDFCFD190AFB6F89489A99AA9DC018A +:10377000DC92C9A8DAA88DA99EA9C816D90619F4A1 +:103780008BA99CA903C089A99AA901969AAB89AB78 +:10379000AFBED3018C9181110CC03EA72DA71CA6F2 +:1037A0001BA61AA69C92299A7BA36AA35B9AB09245 +:1037B00042068FB7F894FDA2ECA28FBFAECFCF0127 +:1037C000801B910BDF91CF911F910F91FF90EF9094 +:1037D000DF90CF90BF90AF909F908F907F906F9031 +:1037E0000895CF93DF93EC01488959896A897B89D1 +:1037F0004D345B446345764441F04EE650E069EE5B +:1038000075E083ED95E00E949735C958DF4F8881B8 +:103810008111FDCF80E090E0DF91CF910895CF93AB +:10382000DF93EC01488959896A897B894D345B446F +:103830006345764441F04EE650E069EE75E083ED75 +:1038400095E00E9497352FB7F894C852DF4F8881D2 +:1038500099812FBFDF91CF910895CF93DF93EC0132 +:10386000488959896A897B894D345B44634576442C +:1038700041F04EE650E069EE75E083ED95E00E9480 +:1038800097358FB7F894C852DF4F198218828FBFCF +:10389000DF91CF910895EF92FF920F931F93CF93F3 +:1038A000DF93FC018C0101531F4FD8014D915C91B6 +:1038B000DC01A353BF4F4D935C93DC01A858BF4F6D +:1038C0008D919C91119716962D913C911797821787 +:1038D000930729F414962D913C91159706C08D916C +:1038E0009C9111979C012F5F3F4F11963C932E9313 +:1038F000EC012881260290011124359527953595F4 +:103900002795E801398328837F01D3EDED0EF11C63 +:10391000E701888199818F010F521F4FE801998338 +:10392000888395958795840F951F820F931FE701D4 +:1039300099838883AF014B525F4F21E01816190617 +:103940000CF020E0EA018881880F822B8883129690 +:103950008D919C911397EC01688312962D913C9167 +:10396000139716968D919C9117972817390729F46C +:1039700014968D919C91159705C012968D919C91EE +:103980001397019613969C938E931297DA019C914C +:10399000892F8695869589278370DF01AA52BF4FAC +:1039A000833039F48C91803214F48F5F01C08150E0 +:1039B0008C938C91885F8C9380340CF435C18F7319 +:1039C0008C93DF01A952BF4F8C91880F97702BEF1A +:1039D000290F233010F0933009F481608C939C916F +:1039E000892F8695892780958170968D990F892BCF +:1039F000868F8E3709F04EC0DF01AB57BF4F2D9138 +:103A00003C91119714968D919C9115972817390721 +:103A100059F412962D913C91139716968D919C9185 +:103A200017972817390779F012962D913C91139723 +:103A30008D919C911197019741E02817390709F062 +:103A400040E0842F01C081E080FDDDC01296CD9161 +:103A5000DC9113978EE7888312962D913C911397F2 +:103A600016968D919C9117972817390729F414966B +:103A70008D919C91159705C012968D919C911397ED +:103A8000019613969C938E93129781E081A32A9AB4 +:103A900041E0BCC0982F9F779F3719F411A22A9854 +:103AA000C3C091A1992309F4BFC0982F9F739E337F +:103AB00009F4BAC080FF03C080A1806880A3878D0D +:103AC0008F5F878F90A1883008F4ACC0DF01AB57BF +:103AD000BF4F82E8890F823018F09B3109F04BC04C +:103AE0002D913C91119714968D919C9115972817C3 +:103AF000390759F412962D913C91139716968D9192 +:103B00009C9117972817390779F012962D913C91BF +:103B100013978D919C911197019741E028173907D0 +:103B200009F040E0842F01C081E080FD20C01296A2 +:103B3000CD91DC9113978BE1888312962D913C9166 +:103B4000139716968D919C9117972817390729F48A +:103B500014968D919C91159705C012968D919C910C +:103B60001397019613969C938E93129704C011A2FB +:103B70002A9840E001C041E02D913C9111971496A4 +:103B80008D919C9115972817390759F412962D910C +:103B90003C91139716968D919C911797281739078A +:103BA00079F012962D913C9113978D919C911197DC +:103BB000019751E02817390709F050E0852F01C01F +:103BC00081E080FD20C080A11296CD91DC911397F9 +:103BD000888312962D913C91139716968D919C9106 +:103BE00017972817390729F414968D919C911597EA +:103BF00005C012968D919C911397019613969C93F4 +:103C00008E93129703C011A22A9840E010A2178E3B +:103C100041110AC0E852FF4F8081918181609183F8 +:103C2000808302C0969590A3DF91CF911F910F9151 +:103C3000FF90EF900895DC0196968C9196978111F4 +:103C4000EAC098968C9198978111A0C09F962D916B +:103C50003C91D097D1968D919C91D2972817390796 +:103C600039F494968D919C919597892B09F45CC0B9 +:103C700099968C919997811103C09A961C929A9764 +:103C800081E099968C93999792968D919C919397B8 +:103C9000009789F59F962D913C91D097D1968D9163 +:103CA0009C91D2972817390751F494968D919C9145 +:103CB0009597019795969C938E93949721C09F9684 +:103CC000ED91FC91D097D5968D919C91D697E81760 +:103CD000F90729F4D3968D919C91D49706C09F96AD +:103CE000ED91FC91D097CF010196D0969C938E9345 +:103CF0009F97808106C0019793969C938E9392978D +:103D00008EE797968C93979797968C9197978B3190 +:103D100099F59F962D913C91D097D1968D919C913C +:103D2000D2972817390749F45B9810924206A95890 +:103D3000BF4F1C92299880E008959F96ED91FC91C9 +:103D4000D097D5968D919C91D697E817F90729F4CD +:103D5000D3968D919C91D49706C09F96ED91FC913E +:103D6000D097CF010196D0969C938E939F97808198 +:103D700097968C93979706C08E57823018F4999631 +:103D80001C92999781E098968C93989799962C918C +:103D900099979D968D919C919E972223A9F09A9632 +:103DA0002C919A97253080F09A961C929A9780349D +:103DB000910519F485E790E002C080E490E09E96BA +:103DC0009C938E939D9723C098963C919897979635 +:103DD0002C919797232341F09A968C919A978F5F15 +:103DE0009A968C939A970FC09A961C929A978034C1 +:103DF000910519F485E790E002C080E490E09E967A +:103E00009C938E939D97330F98963C93989788E058 +:103E100096968C9396979D96ED91FC919E979B9686 +:103E20008D919C919C97E80FF91F9F0131709C9692 +:103E30003C932E939B9796968C919697815096964D +:103E40008C93FF27E038F10530F08FEF90E0AC0164 +:103E50004E1B5F0BFA01EA50FA4F84912F3F310558 +:103E600011F008F080950895CF93DF93EC01CB011A +:103E70002AEDFE0111922A95E9F77D8F6C8F20E4DF +:103E800030E03EA72DA79E0120583F4FFE01E85885 +:103E9000FF4F3583248333832283318320839E0124 +:103EA0002C573F4F378326839E0123573F4FDE0118 +:103EB000AB57BF4F15963C932E93149713963C9394 +:103EC0002E93129711963C932E939E0124533F4FAD +:103ED00017963C932E9316979E01295C3F4F3CAB5F +:103EE0002BAB3AAB29AB38AB2FA79E012A583F4FDB +:103EF0003EAB2DAB24E030E0A281B3811C92628105 +:103F00007381468157816417750719F4448155817F +:103F100004C0428153814F5F5F4F538342832150DE +:103F200031092115310541F7BE010E944C1A8AB1B1 +:103F3000886F8AB9219A229A4DE45BE463E576E4BE +:103F4000488B598B6A8B7B8B88E59BE19B838A83AB +:103F500081ED9AE19983888381EF9BE19B878A8732 +:103F60008FE09CE19D878C878DE29CE19F878E8707 +:103F7000DF91CF9108956FEF8AE290E00E94E039DF +:103F800080914B01882341F08AE290E19F938F93C7 +:103F90000E9415350F900F9080914B0181110CC03C +:103FA00080913706811108C087E290E19F938F933B +:103FB0000E9415350F900F900895CF938AE290E0FC +:103FC0000E94C839893609F0C7C046E050E064E273 +:103FD00070E085E491E00E94B83946E050E06EE17F +:103FE00070E08FE391E00E94B83946E050E068E16C +:103FF00070E089E391E00E94B83946E050E062E168 +:1040000070E081E391E00E94B83981E190E00E9484 +:10401000C83990E0909334068093330680E190E0B5 +:104020000E94C83990E090933206809331068FE069 +:1040300090E00E94C83990E0909338018093370156 +:104040008EE090E00E94C83990E090933001809318 +:104050002F018DE090E00E94C83991E0811101C0EC +:1040600090E0909350018CE090E00E94C83991E07C +:10407000811101C090E090934F018BE090E00E948D +:10408000C83991E0811101C090E090934E018AE01F +:1040900090E00E94C83991E0811101C090E09093B6 +:1040A0004D0189E090E00E94C83991E0811101C082 +:1040B00090E090934C0188E090E00E94C839C1E004 +:1040C000811101C0C0E0C0934B0187E090E00E94E5 +:1040D000C83991E0811101C090E09093370686E0E5 +:1040E00090E00E94C83980932C0185E090E00E9406 +:1040F000C83980932B0184E090E00E94C8398093F6 +:104100002A0183E090E00E94C8398093290182E06F +:1041100090E00E94C83980932E0181E090E00E94D7 +:10412000C83980932D0180E090E00E94C83991E069 +:10413000811101C090E090932E06CC23C1F18091B3 +:1041400036068823A1F181E190E19F938F930E942D +:1041500015350F900F902BC080913606882381F083 +:104160008091370681110CC080914B01882341F06A +:1041700088EE9FE09F938F930E9415350F900F90CC +:1041800080913606882381F08091370681110CC01A +:1041900080914B01811108C085EE9FE09F938F9322 +:1041A0000E9415350F900F9081E080933506CF91D6 +:1041B00008950E94DD1F81E08093360680914B01B7 +:1041C0008823E9F12FEF85EA9EE02150804090405E +:1041D000E1F700C0000081EC90E19F938F930E9473 +:1041E000153580EB90E19F938F930E94153589E9F7 +:1041F00090E19F938F930E9415350F900F900F9031 +:104200000F900F900F9080913506882341F08AE738 +:1042100090E19F938F930E9415350F900F908DE63C +:1042200090E19F938F930E9415358CE590E19F93C9 +:104230008F930E9415350F900F900F900F90089557 +:1042400046E050E064E270E085E491E00E94D039FD +:1042500046E050E06EE170E08FE391E00E94D039DB +:1042600046E050E068E170E089E391E00E94D039D7 +:1042700046E050E062E170E081E391E00E94D039D5 +:104280006091330681E190E00E94E039609131064F +:1042900080E190E00E94E039609137018FE090E08A +:1042A0000E94E03960912F018EE090E00E94E03999 +:1042B000609150018DE090E00E94E03960914F01E3 +:1042C0008CE090E00E94E03960914E018BE090E03C +:1042D0000E94E03960914D018AE090E00E94E0394F +:1042E00060914C0189E090E00E94E03960914B01BF +:1042F00088E090E00E94E0396091370687E090E026 +:104300000E94E03960912C0186E090E00E94E03943 +:1043100060912B0185E090E00E94E03960912A01D4 +:1043200084E090E00E94E0396091290183E090E010 +:104330000E94E03960912E0182E090E00E94E03915 +:1043400060912D0181E090E00E94E03960912E069D +:1043500080E090E00E94E03969E68AE290E00E9405 +:10436000E03980914B01882341F080ED9FE09F93DD +:104370008F930E9415350F900F9080914B01811102 +:104380000CC080913706811108C08DEC9FE09F938F +:104390008F930E9415350F900F9008958F929F92E2 +:1043A000AF92BF92CF92DF92EF92FF920F931F9343 +:1043B000CF93DF93EC014B01809150018823F1F002 +:1043C00080914C01882329F06DEA71E0C4010E94BC +:1043D0006D0E8E811F928F93DF93CF9383EB91E0CD +:1043E0009F938F939F928F920E945B0EEDB7FEB7C3 +:1043F00038960FB6F894FEBF0FBEEDBF80914F0107 +:10440000882339F180914C01882361F08EEB91E093 +:104410009F938F939F928F920E945B0E0F900F90AD +:104420000F900F908D851F928F93CE0107969F93CB +:104430008F9383EB91E09F938F939F928F920E9433 +:104440005B0E8DB79EB708960FB6F8949EBF0FBE51 +:104450008DBF80914E01811105C080914D01811168 +:1044600037C05CC080914C01882329F064EC71E076 +:10447000C4010E946D0E8E01025F1F4FE12CF12CD2 +:104480005E0196E4A90EB11C83EBC82E81E0D82E04 +:10449000F501808190E0E816F906FCF6F8018681C6 +:1044A0001F928F931F930F93DF92CF929F928F92C1 +:1044B0000E945B0EFFEFEF1AFF0A095F1F4F8DB7D7 +:1044C0009EB708960FB6F8949EBF0FBE8DBFE0CF83 +:1044D00080914C01882329F06BEC71E0C4010E94AB +:1044E0006D0EFE01E55BFF4F81818F9380818F937D +:1044F000C35BDF4F89818F9388818F9322ED31E0F9 +:104500003F932F939F928F920E945B0E8DB79EB721 +:1045100008960FB6F8949EBF0FBE8DBF67ED71E091 +:10452000C401DF91CF911F910F91FF90EF90DF9029 +:10453000CF90BF90AF909F908F900C946D0E0F9383 +:104540001F939C01CA0146E0EFE3F1E0A1E6B6E06B +:1045500001900D924A95E1F740913106409367062C +:1045600046E0E5E4F1E0A0ECB6E001900D924A955A +:10457000E1F7409133064093C60646E0E9E3F1E0F7 +:10458000A8E6B6E001900D924A95E1F74091370117 +:1045900040936E0646E0E1E3F1E0A0EDB6E0019065 +:1045A0000D924A95E1F740912F014093D60647E0DE +:1045B000E1E6F6E0A3E4B6E001900D924A95E1F75A +:1045C00047E0E0ECF6E0AAE4B6E001900D924A95EF +:1045D000E1F747E0E8E6F6E0A1E5B6E001900D92EC +:1045E0004A95E1F747E0E0EDF6E0A8E5B6E0019096 +:1045F0000D924A95E1F78B0144E050E063E476E0E8 +:104600000E9454181F910F9108956F927F929F926C +:10461000AF92BF92CF92DF92EF92FF920F931F93D0 +:10462000CF93DF931F92CDB7DEB75C018B016A0198 +:104630007B0184E1E80EF11C20912C012A3098F4D2 +:1046400080912B018A3078F480912A018A3058F4C5 +:1046500080912901893038F47B01EBE1EE0EF11CE9 +:104660009924939401C0912CC70129830E946C382E +:104670003C018DE3F301808380912E01818780913D +:104680002D01838B88E0E8EBF6E0D30111960190D1 +:104690000D928A95E1F789E0E7ECF6E0D3011A96EE +:1046A00001900D928A95E1F72981911003C0C30111 +:1046B000449617C080E5F301848B88E4858B87E4FA +:1046C000868B205D278B80912B01805D808F809170 +:1046D0002A01805D818F80912901805D828FC301D5 +:1046E0004B960115110521F0A801B5010E94AF39C3 +:1046F000A601B701C3010E949F22C3010F90DF9161 +:10470000CF911F910F91FF90EF90DF90CF90BF90CE +:10471000AF909F907F906F900C9404398F929F92EE +:10472000AF92BF92CF92DF92EF92FF920F931F93BF +:10473000CF93DF935C016A018B016434710510F043 +:1047400003E410E078012FE0E20EF11CC7010E94A3 +:104750006C38EC018AE3888387E090E020E030E069 +:104760000197009769F0F901E159F94F408144231D +:10477000B9F32F5F3F4FFE01E20FF31F4083F0CFED +:1047800080912701909128018F3F4FEF940779F096 +:10479000FE01E20FF31F4DE241838A3091054CF494 +:1047A0002E5F3F4FFE01E20FF31F805D808380E2AA +:1047B00009C091E392832D5F3F4FFE01E20FF31F8B +:1047C0008A5DF4CF293031053CF42F5F3F4FFE0165 +:1047D000E20FF31F8083F6CFFE01E20FF31F8AE39F +:1047E00081830115110581F0A801B501CE010B9659 +:1047F0000E94AF39A801B50185E796E00E94AF3964 +:104800001093600600935F0680912F06909130060A +:104810000196883E23E092072CF490933006809313 +:104820002F0604C01092300610922F06FE01E00FF2 +:10483000F11F8BE7838700912F06109130069AE0D5 +:10484000892E912CC801B4010E94F4379C0144E6E2 +:10485000A42EB12CC801B5010E94F437821B930B22 +:10486000B4010E94F437AB01C801861B970B821B71 +:10487000930BB5010E94F437605D6487405D458706 +:10488000205D2687A601B701CE010E949F22CE019E +:10489000DF91CF911F910F91FF90EF90DF90CF901C +:1048A000BF90AF909F908F900C94043920912F0669 +:1048B00030913006215031093093300620932F0675 +:1048C00060915F0670916006AC0185E796E00C94FC +:1048D0008E2382E39CE09F938F930E9415358091F5 +:1048E00034068F93809133068F9385E491E09F93F4 +:1048F0008F938FE19CE09F938F930E941535809159 +:1049000032068F93809131068F938FE391E09F93CE +:104910008F9389E09CE09F938F930E94153580913F +:1049200038018F93809137018F9389E391E09F93B2 +:104930008F9389EF9BE09F938F930E941535809111 +:1049400030018F9380912F018F9381E391E09F93AA +:104950008F9389EE9BE09F938F930E9415358DB7BF +:104960009EB74A960FB6F8949EBF0FBE8DBF80913A +:104970002E06882319F082ED9BE002C08AEB9BE0B3 +:104980009F938F930E9415350F900F9080912C016B +:104990008A3061F01F928F938FEA9BE09F938F93F1 +:1049A0000E9415350F900F900F900F9080912B0162 +:1049B0008A3061F01F928F9383EA9BE09F938F93DD +:1049C0000E9415350F900F900F900F9080912A0143 +:1049D0008A3061F01F928F9389E99BE09F938F93B8 +:1049E0000E9415350F900F900F900F908091290124 +:1049F0008A3061F01F928F9388E89BE09F938F939A +:104A00000E9415350F900F900F900F9080912E01FE +:104A10008C3541F48FE69BE09F938F930E94153570 +:104A20000F900F9080912E018F3241F487E59BE02B +:104A30009F938F930E9415350F900F9020912D0119 +:104A4000822F992787FD90959F932F938BE49BE06E +:104A50009F938F930E9415350F900F900F900F909A +:104A6000089587E29BE09F938F930E94153585E11F +:104A70009BE09F938F930E9415358AEF9AE09F9356 +:104A80008F930E94153581EC9AE09F938F930E943B +:104A9000153583EA9AE09F938F930E94153586E837 +:104AA0009AE09F938F930E94153582E69AE09F9338 +:104AB0008F930E94153584E49AE09F938F930E9410 +:104AC000153585E29AE09F938F930E9415358CE00F +:104AD0009AE09F938F930E9415358CEE99E09F93F7 +:104AE0008F930E94153582ED99E09F938F930E94DA +:104AF000153587EB99E09F938F930E94153584E8D5 +:104B000099E09F938F930E94153580E599E09F93DC +:104B10008F930E94153583E399E09F938F930E94B2 +:104B200015358DB79EB780960FB6F8949EBF0FBE11 +:104B30008DBF80E199E09F938F930E9415358FEE92 +:104B400098E09F938F930E94153587EC98E09F9390 +:104B50008F930E9415358EEA98E09F938F930E9461 +:104B6000153589E798E09F938F930E9415358FE460 +:104B700098E09F938F930E94153589E298E09F9368 +:104B80008F930E9415358BE098E09F938F930E943E +:104B9000153582EE97E09F938F930E94153586EC32 +:104BA00097E09F938F930E9415358AEA97E09F9331 +:104BB0008F930E9415358DE897E09F938F930E9405 +:104BC000153580E797E09F938F930E94153582E516 +:104BD00097E09F938F930E94153583E397E09F930F +:104BE0008F930E94153584E197E09F938F930E94E5 +:104BF00015358DB79EB780960FB6F8949EBF0FBE41 +:104C00008DBF86EF96E09F938F930E94153588EDB8 +:104C100096E09F938F930E94153589EB96E09F93C2 +:104C20008F930E9415358AE996E09F938F930E9497 +:104C3000153586E796E09F938F930E9415358DB7C3 +:104C40009EB70A960FB6F8949EBF0FBE8DBF08950B +:104C50000F931F93CF93DF93EC01FA01A901611524 +:104C6000710509F4CBC68881813209F5623071057E +:104C700008F480C661507109CE0101960E949F22FE +:104C800080914B01882341F080EC9FE09F938F93AC +:104C90000E9415350F900F9080914B018111AEC687 +:104CA000809137068111AAC68DEB9FE079C68034CA +:104CB000E9F461507109CE0101960E9405238091AB +:104CC0004B01882341F087EA9FE09F938F930E94D6 +:104CD00015350F900F9080914B0181118FC68091F7 +:104CE000370681118BC684EA9FE05AC68332E9F405 +:104CF00061507109CE0101960E948E2380914B0173 +:104D0000882341F086E99FE09F938F930E94153599 +:104D10000F900F9080914B01811170C680913706E2 +:104D200081116CC683E99FE03BC6883631F4DF9180 +:104D3000CF911F910F910C943125883431F4DF917C +:104D4000CF911F910F910C946924833531F4DF9139 +:104D5000CF911F910F910C942021833431F4DF9176 +:104D6000CF911F910F910C94BB1F8C3431F4DF91C4 +:104D7000CF911F910F910C94DD1F833609F052C023 +:104D80006430710508F4F6C5E5E4F1E081E090E0F7 +:104D90009C012150310986179707A9F087309105AA +:104DA00081F0DE01A80FB91F2C91222331F02A30A7 +:104DB00021F02D3011F0208301C010820196319630 +:104DC000E7CF26E030E02630310539F0F901EB5B22 +:104DD000FE4F10822F5F3F4FF6CF80914B0188230B +:104DE000B1F0809134068F93809133068F9385E4E0 +:104DF00091E09F938F9380E89FE09F938F930E9411 +:104E000015350F900F900F900F900F900F9080918D +:104E10004B018111F3C5809137068111EFC58DE7F4 +:104E20009FE0BEC5843609F052C06430710508F4B5 +:104E3000A1C5EFE3F1E081E090E09C012150310950 +:104E400086179707A9F08730910581F0DE01A80F3A +:104E5000B91F2C91222331F02A3021F02D3011F08E +:104E6000208301C0108201963196E7CF26E030E022 +:104E70002630310539F0F901E15CFE4F10822F5FD9 +:104E80003F4FF6CF80914B018823B1F080913206DD +:104E90008F93809131068F938FE391E09F938F934F +:104EA00087E69FE09F938F930E9415350F900F9098 +:104EB0000F900F900F900F9080914B0181119EC524 +:104EC0008091370681119AC584E69FE069C58133D8 +:104ED00009F052C06230710508F44CC5E9E3F1E015 +:104EE00081E090E09C012150310986179707A9F0D5 +:104EF0008730910581F0DE01A80FB91F2C91222384 +:104F000031F02A3021F02D3011F0208301C01082C1 +:104F100001963196E7CF26E030E02630310539F0B2 +:104F2000F901E75CFE4F10822F5F3F4FF6CF809173 +:104F30004B018823B1F0809138018F938091370124 +:104F40008F9389E391E09F938F9384E59FE09F93F4 +:104F50008F930E9415350F900F900F900F900F9028 +:104F60000F9080914B01811149C5809137068111C5 +:104F700045C581E59FE014C5823309F052C0623017 +:104F8000710508F4F7C4E1E3F1E081E090E09C01F1 +:104F90002150310986179707A9F08730910581F0D4 +:104FA000DE01A80FB91F2C91222331F02A3021F005 +:104FB0002D3011F0208301C0108201963196E7CF89 +:104FC00026E030E02630310539F0F901EF5CFE4F84 +:104FD00010822F5F3F4FF6CF80914B018823B1F0B5 +:104FE000809130018F9380912F018F9381E391E025 +:104FF0009F938F9381E49FE09F938F930E94153539 +:105000000F900F900F900F900F900F9080914B0189 +:105010008111F4C4809137068111F0C48EE39FE0C2 +:10502000BFC4833709F0EFC06330710508F4A2C430 +:105030008B010150110989818336C1F502301105B8 +:1050400021F08B8190E0869703C08A8190E0C09721 +:10505000909334068093330680914B018823B1F0FE +:10506000809134068F93809133068F9385E491E08D +:105070009F938F938BE29FE09F938F930E941535B0 +:105080000F900F900F900F900F900F9080914B0109 +:1050900081110CC080913706811108C088E29FE021 +:1050A0009F938F930E9415350F900F9089818436BE +:1050B000C1F50230110521F08B8190E0869703C085 +:1050C0008A8190E0C0979093320680933106809158 +:1050D0004B018823B1F0809132068F938091310685 +:1050E0008F938FE391E09F938F9382E19FE09F9353 +:1050F0008F930E9415350F900F900F900F900F9087 +:105100000F9080914B0181110CC080913706811165 +:1051100008C08FE09FE09F938F930E9415350F90FA +:105120000F9089818133C1F50230110521F08B8107 +:1051300090E0869703C08A8190E0C09790933801F1 +:105140008093370180914B018823B1F08091380121 +:105150008F93809137018F9389E391E09F938F9391 +:105160008FEF9EE09F938F930E9415350F900F90C5 +:105170000F900F900F900F9080914B0181110CC0F8 +:1051800080913706811108C08CEF9EE09F938F932A +:105190000E9415350F900F908981823309F02EC43B +:1051A0000230110521F08B8190E0869703C08A813F +:1051B00090E0C0979093300180932F0180914B0134 +:1051C0008823B1F0809130018F9380912F018F93CC +:1051D00081E391E09F938F938CEE9EE09F938F935A +:1051E0000E9415350F900F900F900F900F900F9019 +:1051F00080914B01811102C4809137068111FEC359 +:1052000089EE9EE0CDC3803709F02CC16330710573 +:1052100008F4B0C389818337C9F59A8180914B0125 +:105220009133C1F491E090935001882341F086EDD1 +:105230009EE09F938F930E9415350F900F90809161 +:105240004B01811123C08091370681111FC083ED6E +:105250009EE016C010925001882341F08FEB9EE033 +:105260009F938F930E9415350F900F9080914B0163 +:1052700081110CC080913706811108C08CEB9EE033 +:105280009F938F930E9415350F900F9089818436DC +:10529000C9F59A8180914B019133C1F491E09093CB +:1052A0004F01882341F089EA9EE09F938F930E94EB +:1052B00015350F900F9080914B01811123C0809183 +:1052C000370681111FC086EA9EE016C010924F017A +:1052D000882341F082E99EE09F938F930E941535C9 +:1052E0000F900F9080914B0181110CC08091370677 +:1052F000811108C08FE89EE09F938F930E9415351F +:105300000F900F9089818037C9F59A8180914B0168 +:105310009133C1F491E090934E01882341F08BE7E3 +:105320009EE09F938F930E9415350F900F90809170 +:105330004B01811123C08091370681111FC088E77E +:105340009EE016C010924E01882341F083E69EE055 +:105350009F938F930E9415350F900F9080914B0172 +:1053600081110CC080913706811108C080E69EE053 +:105370009F938F930E9415350F900F9089818D36E2 +:10538000C9F59A8180914B019133C1F491E09093DA +:105390004D01882341F08CE49EE09F938F930E94FF +:1053A00015350F900F9080914B01811123C0809192 +:1053B000370681111FC089E49EE016C010924D018E +:1053C000882341F084E39EE09F938F930E941535DC +:1053D0000F900F9080914B0181110CC08091370686 +:1053E000811108C081E39EE09F938F930E94153541 +:1053F0000F900F908981893609F000C39A818091BE +:105400004B019133C1F491E090934C01882341F01A +:105410008DE19EE09F938F930E9415350F900F9022 +:1054200080914B018111EAC2809137068111E6C259 +:105430008AE19EE0B5C210924C01882341F085E0DC +:105440009EE09F938F930E9415350F900F9080914F +:105450004B018111D3C2809137068111CFC282E006 +:105460009EE09EC28637C1F48981813331F481E0A8 +:1054700080934B018AED91E004C010924B0180EFC4 +:1054800091E09F938F93FF93EF930E945B0E0F9099 +:105490000F900F900F90B2C2863581F489818133CD +:1054A00041F481E08093370610924B0187E092E04F +:1054B000E8CF109237068CE192E0E3CF8C3609F00A +:1054C0003FC16330710508F455C289818C3609F0FB +:1054D0005CC0615071098A81813651F56A3071056D +:1054E00008F48CC288E0FE013396A8EBB6E0019088 +:1054F0000D928A95E1F780914B01882371F088EB3A +:1055000096E09F938F938CEE9DE09F938F930E94E4 +:1055100015350F900F900F900F9080914B018111D6 +:105520006DC280913706811169C289EE9DE038C253 +:105530008F3609F063C26B30710508F45FC289E0F1 +:10554000FE013396A7ECB6E001900D928A95E1F743 +:1055500080914B01882371F087EC96E09F938F93A5 +:1055600081ED9DE09F938F930E9415350F900F90D2 +:105570000F900F9080914B01811140C280913706AE +:1055800081113CC28EEC9DE00BC2803729F58A81E7 +:1055900080538A3008F032C280932C0190914B01E5 +:1055A000992379F08802C00111249F938F938CEB8B +:1055B0009DE09F938F930E9415350F900F900F9051 +:1055C0000F9080914B01811119C280913706811192 +:1055D00015C289EB9DE0E4C18836B9F58A81805314 +:1055E0008A3008F00BC280932B0190914B019923D4 +:1055F00009F1A1E0B0E002C0AA0FBB1F8A95E2F753 +:1056000028EE33E00E94ED3728E431E040E050E03E +:105610000E942A385F934F933F932F9389E99DE02F +:105620009F938F930E9415350F900F900F900F90BE +:105630000F900F9080914B018111E0C1809137064E +:105640008111DCC186E99DE0ABC1873631F52A8145 +:1056500020532A3008F0D2C120932A0180914B01B7 +:10566000882381F0822F992787FD90959F932F9310 +:1056700084E89DE09F938F930E9415350F900F90C3 +:105680000F900F9080914B018111B8C18091370626 +:105690008111B4C181E89DE083C18436C9F58A8156 +:1056A00080538A3008F0AAC1893009F488E08093D9 +:1056B000290180914B0181110CC080913706811125 +:1056C00008C08EE79DE09F938F930E9415350F9041 +:1056D0000F9080914B01882309F490C1809129019A +:1056E000811108C085E69DE09F938F930E94153538 +:1056F0000F900F9080912901882309F47FC12DE23A +:10570000829FC00111249F938F938BE49DE013C06F +:10571000833709F04CC12A8120932D0180914B01E0 +:10572000882309F46BC1822F992787FD90959F9359 +:105730002F9389E39DE09F938F930E941535A7CE09 +:105740008D3609F017C16230710508F413C1CB0121 +:1057500001972981233609F060C0019709F44EC1F1 +:10576000EFE6F6E022966250710980E090E086173D +:10577000970781F08630910569F02991222331F055 +:105780002A3021F02D3011F0208301C010820196C3 +:105790003196EDCF8630910531F0FC01E159F94F9A +:1057A00010820196F7CF80914B01882359F18FE643 +:1057B00096E09F938F938DED9CE09F938F930E9433 +:1057C000153580912701909128010F900F900F902F +:1057D0000F908F3F2FEF920769F09F938F9388ED83 +:1057E0009CE09F938F930E9415350F900F900F9020 +:1057F0000F9008C086ED9CE09F938F930E94153513 +:105800000F900F9080914B018111F8C08091370665 +:105810008111F4C083ED9CE0C3C0233709F057C069 +:105820008130910509F4EAC0029721F08B8190E064 +:10583000869703C08A8190E0C09790932801809357 +:1058400027018091270190912801409730F08FEF38 +:105850009FEF909328018093270180914B0188232B +:1058600059F18FE696E09F938F938BEB9CE09F938B +:105870008F930E94153580912701909128010F90F8 +:105880000F900F900F908F3F2FEF920769F09F932B +:105890008F9386EB9CE09F938F930E9415350F901A +:1058A0000F900F900F9008C084EB9CE09F938F9314 +:1058B0000E9415350F900F9080914B0181119EC071 +:1058C0008091370681119AC081EB9CE069C0223734 +:1058D000D1F4CA010E94562480914B01882341F0E3 +:1058E0008BE99CE09F938F930E9415350F900F904A +:1058F00080914B01811182C08091370681117EC059 +:1059000088E99CE04DC0213609F078C09A818091E9 +:105910004B019133C1F491E090932E06882341F01E +:105920008EE79CE09F938F930E9415350F900F9008 +:1059300080914B01811162C08091370681115EC058 +:105940008BE79CE02DC010922E06882341F080E664 +:105950009CE09F938F930E9415350F900F9080913C +:105960004B0181114BC080913706811147C08DE5F5 +:105970009CE016C080914B01882341F085E49CE0B7 +:105980009F938F930E9415350F900F9080914B013C +:10599000811134C080913706811130C082E49CE0CF +:1059A0009F938F930E9415350F900F9027C08437D7 +:1059B00029F59A8180914B01913641F49CE59093B1 +:1059C0002E01882381F088E19DE007C09FE290933B +:1059D0002E01882341F088EF9CE09F938F930E94D3 +:1059E00015350F900F9080914B01811107C0809168 +:1059F0003706811103C085EF9CE0D2CFDF91CF91B4 +:105A00001F910F9108952F923F924F925F926F9244 +:105A10007F928F929F92AF92BF92CF92DF92EF923E +:105A2000FF920F931F93CF93DF93CDB7DEB7C45A86 +:105A3000D1090FB6F894DEBF0FBECDBFC856DF4FF9 +:105A400099838883C859D040C656DF4F79836883CD +:105A5000CA59D040C456DF4F59834883CC59D040EF +:105A60005901C257DF4F19821882CE58D0409E018B +:105A70002F5F3F4FC957DF4F39832883C758D04026 +:105A8000AE014A575F4FC757DF4F59834883C95804 +:105A9000D040C856DF4F08811981C859D0400F5FE8 +:105AA0001F4FC856DF4FE881F981C859D040849113 +:105AB000853291F1882309F448C7C456DF4F6881C5 +:105AC0007981CC59D040C656DF4FE881F981CA5957 +:105AD000D0400995C257DF4FE880F980CE58D040BA +:105AE000FFEFEF1AFF0AC557DF4FB982A882CB58E4 +:105AF000D040C856DF4F19830883C859D040C257D9 +:105B0000DF4FF982E882CE58D040C557DF4FA880DA +:105B1000B980CB58D040BDCFF8018491853259F57A +:105B2000C856DF4F28813981C859D0402E5F3F4F7A +:105B3000C856DF4F39832883C859D040C456DF4F39 +:105B400068817981CC59D040C656DF4FE881F98110 +:105B5000CA59D0400995C257DF4FE880F980CE5826 +:105B6000D040FFEFEF1AFF0AC557DF4FB982A88276 +:105B7000CB58D040C4CFC256DF4F1882CE59D04048 +:105B8000C357DF4F1882CD58D040C057DF4F18821F +:105B9000C059D040CF56DF4F1882C159D040F801CC +:105BA0002491C80101962B3209F458C060F42032C8 +:105BB000E9F0233209F05AC0F1E0C357DF4FF88310 +:105BC000CD58D04051C02D3251F0203309F04EC095 +:105BD00021E0C256DF4F2883CE59D04045C0F1E0C6 +:105BE000C057DF4FF883C059D0403EC0232D2C7FD3 +:105BF000322ECF56DF4F3881C159D040332ACE568E +:105C0000DF4F4881C259D04040FB32F8C057DF4FC8 +:105C10005881C059D04050FB33F820FA34F8CD56A3 +:105C2000DF4FA881C359D040A0FB35F8C357DF4FE1 +:105C3000B881CD58D040B0FB36F8CC56DF4FE88164 +:105C4000C459D040E0FB37F8232D237069F441E0BC +:105C5000CF56DF4F4883C159D04006C031E0CF5600 +:105C6000DF4F3883C159D0408C0199CFC357DF4FE4 +:105C70005881CD58D040C056DF4F5883C05AD040CD +:105C8000F80124912A3221F0612C712C3AE025C0D0 +:105C900095012E5F3F4FD5016D907C9077FE09C036 +:105CA000719461947108B1E0C057DF4FB883C05957 +:105CB000D0408C01590116C02A33A0F40F5F1F4F4A +:105CC000FC018491A301349F3001359F700C112495 +:105CD00050E3651A7108680E711CC801F80124911F +:105CE000203350F7C057DF4FF881C059D040FF2311 +:105CF00029F0C256DF4F1882CE59D040F801849166 +:105D00008E3249F5319684918A3229F08F01412CE7 +:105D1000512C3AE01AC0D5014D905C900E5F1F4F98 +:105D2000F50132965F011AC02A33C0F40F5F1F4F8E +:105D3000FC018491A201349F2001359F500C112455 +:105D400050E3451A5108480E511CC801F80124912E +:105D5000203350F703C044244A94542CF801249172 +:105D6000C8010196283699F018F42C3439F017C080 +:105D70002C3621F02A3799F4212C02C022242394B6 +:105D80008C01CD56DF4F1882C359D0400EC08C0114 +:105D9000F1E0CD56DF4FF883C359D04005C0CD5652 +:105DA000DF4F1882C359D040212C98012F5F3F4FFD +:105DB000C856DF4F39832883C859D040F801D490A2 +:105DC000C956DF4FD882C759D040F5E6DF1609F42F +:105DD00002C2FD15ECF023E5D21609F453C02D15CF +:105DE00064F035E4D31609F4F6C147E4D41609F497 +:105DF000E1C1DD2009F46FC42AC053E6D51671F164 +:105E00005D150CF4C6C088E5D81609F48DC01FC016 +:105E100090E7D91609F471C09D1564F0A7E6DA166B +:105E200009F4C8C1DA160CF4D1C1B9E6DB1609F4DD +:105E3000B0C00DC0E5E7DE1609F476C0F8E7DF165E +:105E400009F46DC023E7D21202C0F12C1DC0C55762 +:105E5000DF4FB982A882CB58D04049C4A5014E5F1C +:105E60005F4FC557DF4F59834883CB58D040D5018A +:105E70008C918983F12C8E010E5F1F4FFE013196AC +:105E80004F0143C4FF24F39495012E5F3F4FC55744 +:105E9000DF4F39832883CB58D040D5018D909C901B +:105EA0008114910421F4A5E58A2EA1E09A2E57FED3 +:105EB00004C0F0E14F2EF7E25F2E8401FF20C1F015 +:105EC000F8018491882309F420C4C801881999092C +:105ED000841595050CF019C40F5F1F4FF1CFC80151 +:105EE00088199909841595050CF00FC40F5F1F4F91 +:105EF000D8018C918111F3CF08C4F5013296C557B2 +:105F0000DF4FF983E883CB58D040D5016D917C9168 +:105F100080E090E0E4E7EE2EE1E0FE2E26C074E89B +:105F2000E72E71E0F72E04C064E7E62E61E0F62E5E +:105F3000222071F0F5013496C557DF4FF983E883CD +:105F4000CB58D040D5016D917D918D919C910DC024 +:105F5000C5010296F50160817181C557DF4F9983B4 +:105F60008883CB58D04080E090E021E0CE56DF4FD0 +:105F70002883C259D04035E7D31205C0CE56DF4F33 +:105F80001882C259D040CF56DF4F1882C159D04035 +:105F90003EC0222079F0A5014C5F5F4FC557DF4F0F +:105FA00059834883CB58D040D5016D917D918D9117 +:105FB0009C910FC0F5013296C557DF4FF983E883F6 +:105FC000CB58D040D5016D917C91882777FD809585 +:105FD000982F97FF13C090958095709561957F4F8E +:105FE0008F4F9F4FCE56DF4F1882C259D040B2E03C +:105FF000CF56DF4FB883C159D04005C0CE56DF4FD2 +:106000001882C259D04054E7E52E51E0F52EE1E068 +:10601000CC56DF4FE883C459D04061157105810526 +:10602000910529F4CC56DF4F1882C459D040411451 +:10603000510441F4CC56DF4FF881C459D040FF23BE +:1060400009F476C0CE56DF4F2881C259D0408E0168 +:106050000A571F4F2130A9F02AE030E040E050E01D +:106060000E940838F701E60FF71F8081D8018E9350 +:106070008D01B901CA01611571058105910561F7AD +:1060800015C0FB01EF70FF27EE0DFF1D2081F80109 +:1060900022938F0144E096958795779567954A9569 +:1060A000D1F7611571058105910559F757FE43C078 +:1060B000C256DF4FF881CE59D040FF23E1F1232DA6 +:1060C0002C7F322ECF56DF4F3881C159D040332A32 +:1060D000CE56DF4F4881C259D04040FB32F8C057FE +:1060E000DF4F5881C059D04050FB33F820FA34F8C4 +:1060F000CD56DF4F8881C359D04080FB35F8C35758 +:10610000DF4F9881CD58D04090FB36F8CC56DF4F0A +:10611000A881C459D040A0FB37F8232D237081E01B +:1061200090E011F480E090E02301481A590A03C07E +:106130008E010A571F4FC757DF4F88819981C95871 +:10614000D040801B910BF80120E34F018415950589 +:106150001CF422930196F9CFC357DF4FB881CD5875 +:10616000D040BB23A1F0CC56DF4FE881C459D040CA +:10617000EE2369F08D2D8F7D883549F4F401319738 +:10618000D082F2E08F1A910880E3D4018C93C95732 +:10619000DF4FE881F981C758D0408E169F0608F07E +:1061A000AEC247EB52E065EE70E182ED90E10E94F5 +:1061B0009735A5C2DA94DA94C956DF4FD882C75909 +:1061C000D04011E04114510469F006C0C956DF4FB8 +:1061D0001882C759D04010E057FE07C026E0422E73 +:1061E000512C03C044244394512C95012C5F3F4F04 +:1061F000C557DF4F39832883CB58D040D501CD9088 +:10620000DD90ED90FC9020E030E0A901C701B601DF +:106210000E94373687FF0AC0F7FAF094F7F8F09437 +:10622000B2E0CF56DF4FB883C159D040C156DF4FDF +:106230001883CF59D04088248394912C8C0E9D1EB6 +:10624000860C971C20E030E040E85FE3C701B60110 +:106250000E94863787FD32C0A12CB12C27EB33E496 +:106260004AEB51E5C701B6010E94863787FD0EC093 +:1062700029EF32E045E150E5C701B6010E943B3607 +:106280006B017C01EAE0AE0EB11CE8CF20E030E00B +:1062900040E251E4C701B6010E94863787FD49C03C +:1062A00020E030E040E251E4C701B6010E943B36F5 +:1062B0006B017C01FFEFAF1ABF0AE8CF20E030E0AE +:1062C000A901C701B6010E943736A12CB12C882341 +:1062D00081F12FEF36EE4BED5EE2C701B6010E9471 +:1062E0003736181674F029EF32E045E150E5C70162 +:1062F000B6010E948A376B017C012AE0A21AB1081C +:10630000E8CF20E030E040E85FE3C701B6010E943B +:10631000373687FF0EC020E030E040E251E4C7018D +:10632000B6010E948A376B017C0131E0A31AB108E3 +:10633000E8CF112321F1A414B50464F44CEFA416A2 +:106340004FEFB4063CF04A185B08C956DF4F18827D +:10635000C759D04051E0451A510881E0C357DF4F7B +:106360009881CD58D0409827C156DF4F9883CF5998 +:10637000D040A1E0C357DF4FA883CD58D040C956C5 +:10638000DF4FB881C759D040B1114CC0B7FE3EC0F5 +:1063900080E3E1E0F0E0EC0FFD1FE60DF71D8083E8 +:1063A0004114510461F4C357DF4FE881CD58D04008 +:1063B000E11105C0F401319680E090E007C0F401DE +:1063C00032968EE2D40111968C93C20195012F5F13 +:1063D0003F4F280F391F40E38F018217930729F0A1 +:1063E000009719F041930197F7CF920120953095CE +:1063F000A216B3060CF4D6C02C01E1E0F0E0CB56B7 +:10640000DF4FF983E883C559D0405CC0222733278A +:106410002A193B09CB56DF4F39832883C559D04011 +:10642000840150C08401CB56DF4F19821882C559B0 +:10643000D04048C0C701B6010E94A336CF55DF4FF8 +:10644000688379838A839B83C15AD040CF55DF4FBD +:1064500048815981C15AD040BA01882777FD80957B +:10646000982F0E94D6369B01AC01C701B6010E944D +:10647000D23520E030E040E251E40E948A376B01DF +:106480007C0198012F5F3F4FCF55DF4F8881C15A64 +:10649000D040805DD8018C93CB56DF4F88819981A5 +:1064A000C559D0400196CB56DF4FE881F981C559D7 +:1064B000D040EF2B91F0CB56DF4F99838883C5599D +:1064C000D0408901CB56DF4F28813981C559D04052 +:1064D000421653060CF0AECF14C04114510439F4E7 +:1064E000C357DF4FF881CD58D040FF2339F09801D2 +:1064F0002E5F3F4FEEE2D8011196EC9381E090E0E1 +:10650000DACF20E030E040EA50E4C701B6010E9453 +:10651000863787FD47C0F80181E090E030E32291A3 +:106520002E3251F0820F8A3321F0808380E090E098 +:1065300003C0308381E090E08E169F0680F3892BA4 +:1065400089F1C956DF4F3881C759D0403323B9F09C +:10655000F8018E169F0678F4DF018E919D018E3230 +:1065600039F4CF010297DC018C918083F90101C0DD +:1065700080833197EECFBFEFAB1ABB0A0BC00F5F22 +:106580001F4FF8018E169F0628F4DF018E9180833D +:10659000FD01F8CF81E3E1E0F0E0EC0FFD1FE60D37 +:1065A000F71D8083C156DF4FE881CF59D040EE23DD +:1065B00049F0F8018291803311F48F01FACF8E32C5 +:1065C00009F48F01C956DF4FF881C759D040FF2326 +:1065D000B9F1D801FC93C8010296B7FE07C02DE2BD +:1065E00011962C93B194A194B10804C02BE2D80168 +:1065F00011962C938C01065F1F4F20E030E02F5F37 +:106600003F4FF8013196C5016AE070E00E94F4370F +:10661000805DD8018C935B016115710511F08F01CC +:10662000EECF22303105DCF3E21BF30B1997819199 +:106630008E932150310912161306CCF3095011091B +:10664000C256DF4FB881CE59D040BB2309F45CC09D +:10665000E32DEC7F3E2ECF56DF4FF881C159D0405D +:106660003F2ACE56DF4F2881C259D04020FB32F856 +:10667000C057DF4F3881C059D04030FB33F820FA83 +:1066800034F8CD56DF4F4881C359D04040FB35F830 +:10669000C056DF4F5881C05AD04050FB36F8CC5618 +:1066A000DF4F8881C459D04080FB37F8232D2370F9 +:1066B00081E090E011F480E090E09301281B390B19 +:1066C000F40140E34F01C8018E1B9F0B8217930713 +:1066D000DCF44293F7CFC557DF4FB982A882CB587D +:1066E000D040C856DF4F19830883C859D040F12CD9 +:1066F00004E511E081E5882E81E0982E06C0F12C9A +:106700008E010A571F4F01C0F12C08191909601694 +:106710007106DCF1932D9C7F392ECF56DF4FA88177 +:10672000C159D0403A2ACE56DF4FB881C259D04025 +:10673000B0FB32F8C057DF4FE881C059D040E0FBD2 +:1067400033F820FA34F8CD56DF4FF881C359D040E2 +:10675000F0FB35F8C056DF4F2881C05AD04020FBEF +:1067600036F8CC56DF4F3881C459D04030FB37F86B +:106770006301C01AD10A232D237081E090E011F447 +:1067800080E090E0C81AD90A02C0C12CD12CC057B1 +:10679000DF4F4881C059D040411122C031E0C31AB7 +:1067A000D108D7FC1DC0C456DF4F68817981CC5910 +:1067B000D04080E2C656DF4FE881F981CA59D04007 +:1067C0000995C257DF4F28813981CE58D0402F5FBD +:1067D0003F4FC257DF4F39832883CE58D040DECF9A +:1067E000432D4C7F342ECF56DF4F5881C159D040B6 +:1067F000352ACE56DF4F8881C259D04080FB32F80F +:10680000C057DF4F9881C059D04090FB33F820FA31 +:1068100034F8CD56DF4FA881C359D040A0FB35F8DE +:10682000C056DF4FB881C05AD040B0FB36F8CC56C6 +:10683000DF4FE881C459D040E0FB37F8832D8370E7 +:1068400001F1813011F48BE201C08DE2C456DF4FBB +:1068500068817981CC59D040C656DF4FE881F981F3 +:10686000CA59D0400995C257DF4F28813981CE5887 +:10687000D0402F5F3F4FC257DF4F39832883CE5818 +:10688000D040F11009C0C257DF4FA880B980CE5860 +:10689000D040A818B90822C0C257DF4FE880F9805D +:1068A000CE58D0405401AE18BF080150110917FD51 +:1068B0002DC0F501EE0DFF1D8491C456DF4F688198 +:1068C0007981CC59D040C656DF4FE881F981CA5949 +:1068D000D0400995FFEFEF1AFF0AE7CF7501E80CEA +:1068E000F91C0150110917FD11C0C456DF4F688112 +:1068F0007981CC59D040D4018D914D01C656DF4FDE +:10690000E881F981CA59D0400995E8CFC057DF4FD7 +:10691000F881C059D040FF2309F4F1C821E0C21A20 +:10692000D108D7FCECC8C456DF4F68817981CC59B7 +:10693000D04080E2C656DF4FE881F981CA59D04085 +:106940000995FFEFEF1AFF0AE9CFC257DF4F8881A1 +:106950009981CE58D040CC55DF4F0FB6F894DEBFAA +:106960000FBECDBFDF91CF911F910F91FF90EF90A0 +:10697000DF90CF90BF90AF909F908F907F906F905F +:106980005F904F903F902F9008959091C00095FF99 +:10699000FCCF8A3041F09091C00090649093C00089 +:1069A0008093C60008959091C00090649093C000B9 +:1069B0009DE09093C6009091C00095FFFCCFEBCF77 +:1069C000CF939B01C091C1004091C10048604093AA +:1069D000C1004091C1004F794093C10040E050E0B8 +:1069E00065EC74E30E94032D8091C00086FFFCCF0C +:1069F000C093C100CF910895CF93C091C1009091F1 +:106A0000C10098609093C1009091C1009F799093CC +:106A1000C10060E070E00E94C5348091C00086FF34 +:106A2000FCCFC093C100CF910895CF93DF93CDB732 +:106A3000DEB7FE01359681919191BF010E94E0344D +:106A4000DF91CF9108951F93CF93DF931091C100F1 +:106A50002091C10028602093C1002091C1002F79AE +:106A60002093C100FC018491EF012196882331F02D +:106A700060E070E00E94C534FE01F5CF8091C00057 +:106A800086FFFCCF1093C100DF91CF911F91089535 +:106A9000AF92BF92CF92DF92EF92FF920F931F932C +:106AA000CF93DF936C0185E0E82EF12C00E117E233 +:106AB000C0E0D0E09AE0A92EB12CC601B8010E9436 +:106AC000F4376C016115710529F4209719F4013030 +:106AD000110529F480E3860F0E94FC342196C80139 +:106AE000B5010E94F4378B0181E0E81AF108E11446 +:106AF000F10419F7CE01DF91CF911F910F91FF9013 +:106B0000EF90DF90CF90BF90AF900895CF93DF9339 +:106B1000EB010E9423358AE30E94FC34CE010E94DF +:106B2000483584E191E1DF91CF910C942335CF93E7 +:106B3000DF93EC01CB01BA010E94863587E191E138 +:106B40000E942335CE010E9423358AE00E94FC3446 +:106B500081E090E0DF91CF9108950F931F93CF9341 +:106B6000DF93182F092FEB01B901CA010E94863566 +:106B700086E091E10E942335CE010E9423350F93D8 +:106B80001F938DEF90E19F938F930E9415350F9087 +:106B90000F900F900F9081E090E0DF91CF911F91C7 +:106BA0000F9108955058BB27AA270ED075C166D102 +:106BB00030F06BD120F031F49F3F11F41EF45BC133 +:106BC0000EF4E095E7FB51C1E92F77D180F3BA17B6 +:106BD000620773078407950718F071F49EF58FC15B +:106BE0000EF4E0950B2EBA2FA02D0B01B9019001E8 +:106BF0000C01CA01A0011124FF27591B99F0593F2C +:106C000050F4503E68F11A16F040A22F232F342F73 +:106C10004427585FF3CF469537952795A795F040C1 +:106C20005395C9F77EF41F16BA0B620B730B840BD6 +:106C3000BAF09150A1F0FF0FBB1F661F771F881F8E +:106C4000C2F70EC0BA0F621F731F841F48F48795E6 +:106C500077956795B795F7959E3F08F0B3CF9395D5 +:106C6000880F08F09927EE0F979587950895D9D04A +:106C700008F481E008950CD00FC107D140F0FED098 +:106C800030F021F45F3F19F0F0C0511139C1F3C069 +:106C900014D198F39923C9F35523B1F3951B550BE0 +:106CA000BB27AA2762177307840738F09F5F5F4FDF +:106CB000220F331F441FAA1FA9F333D00E2E3AF020 +:106CC000E0E830D091505040E695001CCAF729D03A +:106CD000FE2F27D0660F771F881FBB1F2617370789 +:106CE0004807AB07B0E809F0BB0B802DBF01FF27B9 +:106CF00093585F4F2AF09E3F510568F0B6C000C11F +:106D00005F3FECF3983EDCF3869577956795B795F2 +:106D1000F7959F5FC9F7880F911D9695879597F90D +:106D20000895E1E0660F771F881FBB1F6217730786 +:106D30008407BA0720F0621B730B840BBA0BEE1F9B +:106D400088F7E095089504D06894B111D9C00895EA +:106D5000BCD088F09F5790F0B92F9927B751A0F079 +:106D6000D1F0660F771F881F991F1AF0BA95C9F7DF +:106D700012C0B13081F0C3D0B1E00895C0C0672F18 +:106D8000782F8827B85F39F0B93FCCF3869577958F +:106D90006795B395D9F73EF4909580957095619578 +:106DA0007F4F8F4F9F4F0895E89409C097FB3EF4A3 +:106DB00090958095709561957F4F8F4F9F4F992348 +:106DC000A9F0F92F96E9BB279395F69587957795C6 +:106DD0006795B795F111F8CFFAF4BB0F11F460FF86 +:106DE0001BC06F5F7F4F8F4F9F4F16C0882311F0DE +:106DF00096E911C0772321F09EE8872F762F05C0F2 +:106E0000662371F096E8862F70E060E02AF09A958C +:106E1000660F771F881FDAF7880F9695879597F981 +:106E20000895990F0008550FAA0BE0E8FEEF16161B +:106E30001706E807F907C0F012161306E407F5076E +:106E400098F0621B730B840B950B39F40A2661F0E2 +:106E5000232B242B252B21F408950A2609F4A14085 +:106E6000A6958FEF811D811D089597F99F6780E892 +:106E700070E060E008959FEF80EC089500240A948C +:106E80001616170618060906089500240A94121605 +:106E90001306140605060895092E0394000C11F438 +:106EA000882352F0BB0F40F4BF2B11F460FF04C0E5 +:106EB0006F5F7F4F8F4F9F4F089557FD9058440F3E +:106EC000551F59F05F3F71F04795880F97FB991F49 +:106ED00061F09F3F79F08795089512161306140606 +:106EE000551FF2CF4695F1DF08C016161706180693 +:106EF000991FF1CF86957105610508940895E8946E +:106F0000BB2766277727CB0197F908958ADF08F416 +:106F10008FEF08950BD0C0CFB1DF28F0B6DF18F0A7 +:106F2000952309F0A2CFA7CF1124EACFC6DFA0F3A3 +:106F3000959FD1F3950F50E0551F629FF001729F0E +:106F4000BB27F00DB11D639FAA27F00DB11DAA1F2D +:106F5000649F6627B00DA11D661F829F2227B00D7A +:106F6000A11D621F739FB00DA11D621F839FA00D05 +:106F7000611D221F749F3327A00D611D231F849F55 +:106F8000600D211D822F762F6A2F11249F575040AC +:106F90008AF0E1F088234AF0EE0FFF1FBB1F661F47 +:106FA000771F881F91505040A9F79E3F510570F000 +:106FB0005CCFA6CF5F3FECF3983EDCF386957795E8 +:106FC0006795B795F795E7959F5FC1F7FE2B880FFB +:106FD000911D9695879597F908950E944938B7FFB6 +:106FE0000895821B930B089597FB072E16F40094C7 +:106FF00007D077FD09D00E94583807FC05D03EF431 +:10700000909581959F4F0895709561957F4F089554 +:10701000A1E21A2EAA1BBB1BFD010DC0AA1FBB1F9C +:10702000EE1FFF1FA217B307E407F50720F0A21B0E +:10703000B30BE40BF50B661F771F881F991F1A947B +:1070400069F760957095809590959B01AC01BD01A5 +:10705000CF010895052E97FB1EF400940E9441383D +:1070600057FD07D00E94083807FC03D04EF40C945B +:10707000413850954095309521953F4F4F4F5F4F88 +:10708000089590958095709561957F4F8F4F9F4F94 +:107090000895A29FB001B39FC001A39F700D811DF1 +:1070A0001124911DB29F700D811D1124911D089511 +:1070B000AA1BBB1B51E107C0AA1FBB1FA617B7071E +:1070C00010F0A61BB70B881F991F5A95A9F780953A +:1070D0009095BC01CD010895CF93DF938230910547 +:1070E00010F482E090E0E091D906F091DA0620E019 +:1070F00030E0A0E0B0E0309739F14081518148178D +:107100005907B8F04817590771F482819381109795 +:1071100029F013969C938E9312972CC09093DA06C5 +:107120008093D90627C02115310531F04217530746 +:1071300018F0A901DB0101C0EF019A01BD01DF01D7 +:107140000280F381E02DD7CF21153105F9F0281BFE +:10715000390B2430310580F48A819B8161157105DA +:1071600021F0FB019383828304C09093DA0680931D +:10717000D906FE01329644C0FE01E20FF31F81934F +:10718000919322503109398328833AC02091D70640 +:107190003091D806232B41F4209102013091030154 +:1071A0003093D8062093D706209100013091010139 +:1071B0002115310541F42DB73EB74091040150919E +:1071C0000501241B350BE091D706F091D806E21794 +:1071D000F307A0F42E1B3F0B2817390778F0AC01FA +:1071E0004E5F5F4F2417350748F04E0F5F1F5093D7 +:1071F000D8064093D7068193919302C0E0E0F0E077 +:10720000CF01DF91CF910895CF93DF93009709F4D9 +:1072100087C0FC01329713821282C091D906D091A7 +:10722000DA06209781F420813181280F391F80915F +:10723000D7069091D8068217930779F5F093D80670 +:10724000E093D7066DC0DE0120E030E0AE17BF0747 +:1072500050F412964D915C9113979D014115510583 +:1072600009F1DA01F3CFB383A28340815181840F06 +:10727000951F8A179B0771F48D919C911197840F2C +:10728000951F02969183808312968D919C911397FE +:10729000938382832115310529F4F093DA06E09374 +:1072A000D9063EC0D9011396FC93EE9312974D91E7 +:1072B0005D91A40FB51FEA17FB0779F480819181D6 +:1072C000840F951F0296D90111969C938E9382810B +:1072D000938113969C938E931297E0E0F0E08A815D +:1072E0009B81009719F0FE01EC01F9CFCE010296C7 +:1072F00028813981820F931F2091D7063091D806BB +:107300002817390769F4309729F41092DA06109299 +:10731000D90602C013821282D093D806C093D70632 +:10732000DF91CF910895911106C080538A5010F0DB +:10733000865C06C0089599278827089585FDFBCFB0 +:1073400080629111F8CF81568A51E0F7089591112A +:10735000089581568A5108F4805285580895FB019A +:10736000DC0102C001900D9241505040D8F70895C1 +:10737000DC01CB01FC01F999FECF06C0F2BDE1BDF5 +:10738000F89A319600B40D9241505040B8F70895E4 +:10739000F999FECF92BD81BDF89A992780B50895DD +:1073A000DC01A40FB51F4150504048F0CB01840FC1 +:1073B000951F2E910E94E13941505040D0F7089519 +:1073C000262FF999FECF92BD81BDF89A019700B49E +:1073D000021639F01FBA20BD0FB6F894FA9AF99A3E +:0873E0000FBE0895F894FFCFE1 +:1073E8000000DB0620006801520232022000200063 +:1073F800005C013202320200000000003F3F3F0003 +:107408003C4E554C4C3E00FFFF0A0A0A0A6E2F02FA +:10741800005749444532000100574944453100416D +:10742800505A4D444D4E4F43414C4C01010101010E +:10743800013F3F3F003C4E554C4C3E00E808FF08DA +:10744800070908090C090909B408BA08C708DC08BB +:10745800BD080909303132333435363738394142BD +:107468004344454630313233343536373839616232 +:1074780063646566252E3673002D256400574152D6 +:107488004E00455252003A252E2A730A00535243A1 +:107498003A20005B252E36732D25645D2000445369 +:1074A800543A2000504154483A2000444154413A4B +:1074B8002000252E2A73000D0A00566572626F732C +:1074C80065206D6F646520656E61626C65640A0095 +:1074D800566572626F7365206D6F646520646973A9 +:1074E80061626C65640A0053696C656E74206D6F27 +:1074F800646520656E61626C65640A0053696C6539 +:107508006E74206D6F64652064697361626C656474 +:027518000A0067 +:00000001FF