diff options
Diffstat (limited to 'circuitpython/lib/nrfutil/nordicsemi/dfu')
31 files changed, 12211 insertions, 0 deletions
diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/__init__.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/__init__.py new file mode 100644 index 0000000..8f8006e --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/__init__.py @@ -0,0 +1,29 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Package marker file.""" diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/crc16.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/crc16.py new file mode 100644 index 0000000..2db4af6 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/crc16.py @@ -0,0 +1,44 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +def calc_crc16(binary_data, crc=0xffff): + """ + Calculates CRC16 on binary_data + + :param int crc: CRC value to start calculation with + :param bytearray binary_data: Array with data to run CRC16 calculation on + :return int: Calculated CRC value of binary_data + """ + + for b in binary_data: + crc = (crc >> 8 & 0x00FF) | (crc << 8 & 0xFF00) + crc ^= ord(b) + crc ^= (crc & 0x00FF) >> 4 + crc ^= (crc << 8) << 4 + crc ^= ((crc & 0x00FF) << 4) << 1 + return crc & 0xFFFF diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu.py new file mode 100644 index 0000000..a018cbe --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu.py @@ -0,0 +1,232 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Python standard library +import os +import tempfile +import shutil +import logging +from time import time, sleep +from datetime import datetime, timedelta + +# Nordic libraries +from nordicsemi.exceptions import * +from nordicsemi.dfu.package import Package +from nordicsemi.dfu.dfu_transport import DfuEvent +from nordicsemi.dfu.model import HexType +from nordicsemi.dfu.manifest import SoftdeviceBootloaderFirmware + +logger = logging.getLogger(__name__) + + +class Dfu(object): + """ Class to handle upload of a new hex image to the device. """ + + def __init__(self, zip_file_path, dfu_transport): + """ + Initializes the dfu upgrade, unpacks zip and registers callbacks. + + @param zip_file_path: Path to the zip file with the firmware to upgrade + @type zip_file_path: str + @param dfu_transport: Transport backend to use to upgrade + @type dfu_transport: nordicsemi.dfu.dfu_transport.DfuTransport + @return + """ + self.zip_file_path = zip_file_path + self.ready_to_send = True + self.response_opcode_received = None + + self.temp_dir = tempfile.mkdtemp(prefix="nrf_dfu_") + self.unpacked_zip_path = os.path.join(self.temp_dir, 'unpacked_zip') + self.manifest = Package.unpack_package(self.zip_file_path, self.unpacked_zip_path) + + if dfu_transport: + self.dfu_transport = dfu_transport + + self.dfu_transport.register_events_callback(DfuEvent.TIMEOUT_EVENT, self.timeout_event_handler) + self.dfu_transport.register_events_callback(DfuEvent.ERROR_EVENT, self.error_event_handler) + + def __del__(self): + """ + Destructor removes the temporary directory for the unpacked zip + :return: + """ + shutil.rmtree(self.temp_dir) + + def error_event_handler(self, log_message=""): + """ + Event handler for errors, closes the transport backend. + :param str log_message: The log message for the error. + :return: + """ + if self.dfu_transport.is_open(): + self.dfu_transport.close() + + logger.error(log_message) + + def timeout_event_handler(self, log_message): + """ + Event handler for timeouts, closes the transport backend. + :param log_message: The log message for the timeout. + :return: + """ + if self.dfu_transport.is_open(): + self.dfu_transport.close() + + logger.error(log_message) + + @staticmethod + def _read_file(file_path): + """ + Reads a file and returns the content as a string. + + :param str file_path: The path to the file to read. + :return str: Content of the file. + """ + buffer_size = 4096 + + file_content = "" + + with open(file_path, 'rb') as binary_file: + while True: + data = binary_file.read(buffer_size) + + if data: + file_content += data + else: + break + + return file_content + + def _wait_while_opening_transport(self): + timeout = 10 + start_time = datetime.now() + + while not self.dfu_transport.is_open(): + timed_out = datetime.now() - start_time > timedelta(0, timeout) + + if timed_out: + log_message = "Failed to open transport backend" + raise NordicSemiException(log_message) + + sleep(0.1) + + + def _dfu_send_image(self, program_mode, firmware_manifest): + """ + Does DFU for one image. Reads the firmware image and init file. + Opens the transport backend, calls setup, send and finalize and closes the backend again. + @param program_mode: What type of firmware the DFU is + @type program_mode: nordicsemi.dfu.model.HexType + @param firmware_manifest: The manifest for the firmware image + @type firmware_manifest: nordicsemi.dfu.manifest.Firmware + @return: + """ + + if firmware_manifest is None: + raise MissingArgumentException("firmware_manifest must be provided.") + + if self.dfu_transport.is_open(): + raise IllegalStateException("Transport is already open.") + + self.dfu_transport.open() + self._wait_while_opening_transport() + + softdevice_size = 0 + bootloader_size = 0 + application_size = 0 + + bin_file_path = os.path.join(self.unpacked_zip_path, firmware_manifest.bin_file) + firmware = self._read_file(bin_file_path) + + dat_file_path = os.path.join(self.unpacked_zip_path, firmware_manifest.dat_file) + init_packet = self._read_file(dat_file_path) + + if program_mode == HexType.SD_BL: + if not isinstance(firmware_manifest, SoftdeviceBootloaderFirmware): + raise NordicSemiException("Wrong type of manifest") + softdevice_size = firmware_manifest.sd_size + bootloader_size = firmware_manifest.bl_size + firmware_size = len(firmware) + if softdevice_size + bootloader_size != firmware_size: + raise NordicSemiException( + "Size of bootloader ({} bytes) and softdevice ({} bytes)" + " is not equal to firmware provided ({} bytes)".format( + bootloader_size, softdevice_size, firmware_size)) + + elif program_mode == HexType.SOFTDEVICE: + softdevice_size = len(firmware) + + elif program_mode == HexType.BOOTLOADER: + bootloader_size = len(firmware) + + elif program_mode == HexType.APPLICATION: + application_size = len(firmware) + + start_time = time() + logger.info("Starting DFU upgrade of type %s, SoftDevice size: %s, bootloader size: %s, application size: %s", + program_mode, + softdevice_size, + bootloader_size, + application_size) + + logger.info("Sending DFU start packet") + self.dfu_transport.send_start_dfu(program_mode, softdevice_size, bootloader_size, + application_size) + + logger.info("Sending DFU init packet") + self.dfu_transport.send_init_packet(init_packet) + + logger.info("Sending firmware file") + self.dfu_transport.send_firmware(firmware) + + self.dfu_transport.send_validate_firmware() + + self.dfu_transport.send_activate_firmware() + + end_time = time() + logger.info("\nDFU upgrade took {0}s".format(end_time - start_time)) + + self.dfu_transport.close() + + def dfu_send_images(self): + """ + Does DFU for all firmware images in the stored manifest. + :return: + """ + if self.manifest.softdevice_bootloader: + self._dfu_send_image(HexType.SD_BL, self.manifest.softdevice_bootloader) + + if self.manifest.softdevice: + self._dfu_send_image(HexType.SOFTDEVICE, self.manifest.softdevice) + + if self.manifest.bootloader: + self._dfu_send_image(HexType.BOOTLOADER, self.manifest.bootloader) + + if self.manifest.application: + self._dfu_send_image(HexType.APPLICATION, self.manifest.application) diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport.py new file mode 100644 index 0000000..67c4354 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport.py @@ -0,0 +1,204 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Python specific imports +import abc +import logging + +# Nordic Semiconductor imports +from nordicsemi.dfu.util import int32_to_bytes + +logger = logging.getLogger(__name__) + + +class DfuEvent: + PROGRESS_EVENT = 1 + TIMEOUT_EVENT = 2 + ERROR_EVENT = 3 + + +class DfuTransport(object): + """ + This class as an abstract base class inherited from when implementing transports. + + The class is generic in nature, the underlying implementation may have missing semantic + than this class describes. But the intent is that the implementer shall follow the semantic as + best as she can. + """ + __metaclass__ = abc.ABCMeta + + @staticmethod + def create_image_size_packet(softdevice_size=0, bootloader_size=0, app_size=0): + """ + Creates an image size packet necessary for sending start dfu. + + @param softdevice_size: Size of SoftDevice firmware + @type softdevice_size: int + @param bootloader_size: Size of bootloader firmware + @type softdevice_size: int + @param app_size: Size of application firmware + :return: The image size packet + :rtype: str + """ + softdevice_size_packet = int32_to_bytes(softdevice_size) + bootloader_size_packet = int32_to_bytes(bootloader_size) + app_size_packet = int32_to_bytes(app_size) + image_size_packet = softdevice_size_packet + bootloader_size_packet + app_size_packet + return image_size_packet + + @abc.abstractmethod + def __init__(self): + self.callbacks = {} + + @abc.abstractmethod + def open(self): + """ + Open a port if appropriate for the transport. + :return: + """ + pass + + @abc.abstractmethod + def close(self): + """ + Close a port if appropriate for the transport. + :return: + """ + pass + + @abc.abstractmethod + def is_open(self): + """ + Returns if transport is open. + + :return bool: True if transport is open, False if not + """ + pass + + @abc.abstractmethod + def send_start_dfu(self, program_mode, softdevice_size=0, bootloader_size=0, app_size=0): + """ + Send packet to initiate DFU communication. Returns when packet is sent or timeout occurs. + + This call will block until packet is sent. + If timeout or errors occurs exception is thrown. + + :param nordicsemi.dfu.model.HexType program_mode: Type of firmware to upgrade + :param int softdevice_size: Size of softdevice firmware + :param int bootloader_size: Size of bootloader firmware + :param int app_size: Size of application firmware + :return: + """ + pass + + @abc.abstractmethod + def send_init_packet(self, init_packet): + """ + Send init_packet to device. + + This call will block until init_packet is sent and transfer of packet is complete. + If timeout or errors occurs exception is thrown. + + :param str init_packet: Init packet as a str. + :return: + """ + pass + + @abc.abstractmethod + def send_firmware(self, firmware): + """ + Start sending firmware to device. + + This call will block until transfer of firmware is complete. + If timeout or errors occurs exception is thrown. + + :param str firmware: + :return: + """ + pass + + @abc.abstractmethod + def send_validate_firmware(self): + """ + Send request to device to verify that firmware has been correctly transferred. + + This call will block until validation is sent and validation is complete. + If timeout or errors occurs exception is thrown. + + :return bool: True if firmware validated successfully. + """ + pass + + @abc.abstractmethod + def send_activate_firmware(self): + """ + Send command to device to activate new firmware and restart the device. + The device will start up with the new firmware. + + Raises an nRFException if anything fails. + + :return: + """ + pass + + def register_events_callback(self, event_type, callback): + """ + Register a callback. + + :param DfuEvent callback: + :return: None + """ + if event_type not in self.callbacks: + self.callbacks[event_type] = [] + + self.callbacks[event_type].append(callback) + + def unregister_events_callback(self, callback): + """ + Unregister a callback. + + :param callback: # TODO: add documentation for callback + :return: None + """ + for event_type in self.callbacks.keys(): + if callback in self.callbacks[event_type]: + self.callbacks[event_type].remove(callback) + + def _send_event(self, event_type, **kwargs): + """ + Method for sending events to registered callbacks. + + If callbacks throws exceptions event propagation will stop and this method be part of the track trace. + + :param DfuEvent event_type: + :param args: Arguments to callback function + :return: + """ + if event_type in self.callbacks.keys(): + for callback in self.callbacks[event_type]: + callback(**kwargs) diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_ble.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_ble.py new file mode 100644 index 0000000..ff56750 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_ble.py @@ -0,0 +1,327 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Python standard library +from time import sleep +from datetime import datetime, timedelta +import abc +import logging + +# Nordic libraries +from nordicsemi.exceptions import NordicSemiException, IllegalStateException +from nordicsemi.dfu.util import int16_to_bytes +from nordicsemi.dfu.dfu_transport import DfuTransport, DfuEvent + +logger = logging.getLogger(__name__) + + +# BLE DFU OpCodes : +class DfuOpcodesBle(object): + """ DFU opcodes used during DFU communication with bootloader + + See http://developer.nordicsemi.com/nRF51_SDK/doc/7.2.0/s110/html/a00949.html#gafa9a52a3e6c43ccf00cf680f944d67a3 + for further information + """ + INVALID_OPCODE = 0 + START_DFU = 1 + INITIALIZE_DFU = 2 + RECEIVE_FIRMWARE_IMAGE = 3 + VALIDATE_FIRMWARE_IMAGE = 4 + ACTIVATE_FIRMWARE_AND_RESET = 5 + SYSTEM_RESET = 6 + REQ_PKT_RCPT_NOTIFICATION = 8 + RESPONSE = 16 + PKT_RCPT_NOTIF = 17 + + +class DfuErrorCodeBle(object): + """ DFU error code used during DFU communication with bootloader + + See http://developer.nordicsemi.com/nRF51_SDK/doc/7.2.0/s110/html/a00949.html#gafa9a52a3e6c43ccf00cf680f944d67a3 + for further information + """ + SUCCESS = 1 + INVALID_STATE = 2 + NOT_SUPPORTED = 3 + DATA_SIZE_EXCEEDS_LIMIT = 4 + CRC_ERROR = 5 + OPERATION_FAILED = 6 + + @staticmethod + def error_code_lookup(error_code): + """ + Returns a description lookup table for error codes received from peer. + + :param int error_code: Error code to parse + :return str: Textual description of the error code + """ + code_lookup = {DfuErrorCodeBle.SUCCESS: "SUCCESS", + DfuErrorCodeBle.INVALID_STATE: "Invalid State", + DfuErrorCodeBle.NOT_SUPPORTED: "Not Supported", + DfuErrorCodeBle.DATA_SIZE_EXCEEDS_LIMIT: "Data Size Exceeds Limit", + DfuErrorCodeBle.CRC_ERROR: "CRC Error", + DfuErrorCodeBle.OPERATION_FAILED: "Operation Failed"} + + return code_lookup.get(error_code, "UNKOWN ERROR CODE") + +# Service UUID. For further information, look at the nRF51 SDK documentation V7.2.0: +# http://developer.nordicsemi.com/nRF51_SDK/doc/7.2.0/s110/html/a00071.html#ota_spec_number +UUID_DFU_SERVICE = '000015301212EFDE1523785FEABCD123' +# Characteristic UUID +UUID_DFU_PACKET_CHARACTERISTIC = '000015321212EFDE1523785FEABCD123' +UUID_DFU_CONTROL_STATE_CHARACTERISTIC = '000015311212EFDE1523785FEABCD123' +# Descriptor UUID +UUID_CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR = 0x2902 + +# NOTE: If packet receipt notification is enabled, a packet receipt +# notification will be received for each 'num_of_packets_between_notif' +# number of packets. +# +# Configuration tip: Increase this to get lesser notifications from the DFU +# Target about packet receipts. Make it 0 to disable the packet receipt +# notification + +NUM_OF_PACKETS_BETWEEN_NOTIF = 10 +DATA_PACKET_SIZE = 20 + + +class DfuTransportBle(DfuTransport): + + def __init__(self): + super(DfuTransportBle, self).__init__() + + def open(self): + super(DfuTransportBle, self).open() + + def is_open(self): + return super(DfuTransportBle, self).is_open() + + def close(self): + super(DfuTransportBle, self).close() + + def _wait_for_condition(self, condition_function, expected_condition_value=True, timeout=10, + waiting_for="condition"): + """ + Waits for condition_function to be true + Will timeout after 60 seconds + + :param function condition_function: The function we are waiting for to return true + :param str timeout_message: Message that should be logged + :return: + """ + + start_time = datetime.now() + + while condition_function() != expected_condition_value: + timeout_message = "Timeout while waiting for {0}.".format(waiting_for) + timed_out = datetime.now() - start_time > timedelta(0, timeout) + if timed_out: + self._send_event(DfuEvent.TIMEOUT_EVENT, log_message=timeout_message) + raise NordicSemiException(timeout_message) + + if not self.is_open(): + log_message = "Disconnected from device while waiting for {0}.".format(waiting_for) + raise IllegalStateException(log_message) + + sleep(0.1) + + if self.get_last_error() != DfuErrorCodeBle.SUCCESS: + error_message = "Error occoured while waiting for {0}. Error response {1}." + error_code = DfuErrorCodeBle.error_code_lookup(self.get_last_error()) + error_message = error_message.format(waiting_for, error_code) + self._send_event(DfuEvent.ERROR_EVENT, log_message=error_message) + raise NordicSemiException(error_message) + + @abc.abstractmethod + def send_packet_data(self, data): + """ + Send data to the packet characteristic + + :param str data: The data to be sent + :return: + """ + pass + + @abc.abstractmethod + def send_control_data(self, opcode, data=""): + """ + Send data to the control characteristic + + :param int opcode: The opcode for the operation command sent to the control characteristic + :param str data: The data to be sent + :return: + """ + pass + + @abc.abstractmethod + def get_received_response(self): + """ + Returns True if the transport layer has received a response it expected + + :return: bool + """ + pass + + def clear_received_response(self): + """ + Clears the received response status, sets it to False. + + :return: + """ + pass + + @abc.abstractmethod + def is_waiting_for_notification(self): + """ + Returns True if the transport layer is waiting for a notification + + :return: bool + """ + pass + + def set_waiting_for_notification(self): + """ + Notifies the transport layer that it should wait for notification + + :return: + """ + pass + + @abc.abstractmethod + def get_last_error(self): + """ + Returns the last error code + + :return: DfuErrorCodeBle + """ + pass + + def _start_dfu(self, program_mode, image_size_packet): + logger.debug("Sending 'START DFU' command") + self.send_control_data(DfuOpcodesBle.START_DFU, chr(program_mode)) + logger.debug("Sending image size") + self.send_packet_data(image_size_packet) + self._wait_for_condition(self.get_received_response, waiting_for="response for START DFU") + self.clear_received_response() + + def send_start_dfu(self, program_mode, softdevice_size=0, bootloader_size=0, app_size=0): + super(DfuTransportBle, self).send_start_dfu(program_mode, softdevice_size, bootloader_size, app_size) + image_size_packet = DfuTransport.create_image_size_packet(softdevice_size, bootloader_size, app_size) + + self._send_event(DfuEvent.PROGRESS_EVENT, progress=0, log_message="Setting up transfer...") + + try: + self._start_dfu(program_mode, image_size_packet) + except IllegalStateException: + # We got disconnected. Try to send Start DFU again in case of buttonless dfu. + self.close() + self.open() + + if not self.is_open(): + raise IllegalStateException("Failed to reopen transport backend.") + + self._start_dfu(program_mode, image_size_packet) + + def send_init_packet(self, init_packet): + super(DfuTransportBle, self).send_init_packet(init_packet) + init_packet_start = chr(0x00) + init_packet_end = chr(0x01) + + logger.debug("Sending 'INIT DFU' command") + self.send_control_data(DfuOpcodesBle.INITIALIZE_DFU, init_packet_start) + + logger.debug("Sending init data") + for i in range(0, len(init_packet), DATA_PACKET_SIZE): + data_to_send = init_packet[i:i + DATA_PACKET_SIZE] + self.send_packet_data(data_to_send) + + logger.debug("Sending 'Init Packet Complete' command") + self.send_control_data(DfuOpcodesBle.INITIALIZE_DFU, init_packet_end) + self._wait_for_condition(self.get_received_response, timeout=60, waiting_for="response for INITIALIZE DFU") + self.clear_received_response() + + if NUM_OF_PACKETS_BETWEEN_NOTIF: + packet = int16_to_bytes(NUM_OF_PACKETS_BETWEEN_NOTIF) + logger.debug("Send number of packets before device sends notification") + self.send_control_data(DfuOpcodesBle.REQ_PKT_RCPT_NOTIFICATION, packet) + + def send_firmware(self, firmware): + def progress_percentage(part, complete): + """ + Calculate progress percentage + :param int part: Part value + :param int complete: Completed value + :return: int: Percentage complete + """ + return min(100, (part + DATA_PACKET_SIZE) * 100 / complete) + + super(DfuTransportBle, self).send_firmware(firmware) + packets_sent = 0 + last_progress_update = -1 # Last packet sequence number when an update was fired to the event system + bin_size = len(firmware) + logger.debug("Send 'RECEIVE FIRMWARE IMAGE' command") + self.send_control_data(DfuOpcodesBle.RECEIVE_FIRMWARE_IMAGE) + + for i in range(0, bin_size, DATA_PACKET_SIZE): + progress = progress_percentage(i, bin_size) + + if progress != last_progress_update: + self._send_event(DfuEvent.PROGRESS_EVENT, progress=progress, log_message="Uploading firmware") + last_progress_update = progress + + self._wait_for_condition(self.is_waiting_for_notification, expected_condition_value=False, + waiting_for="notification from device") + + data_to_send = firmware[i:i + DATA_PACKET_SIZE] + + log_message = "Sending Firmware bytes [{0}, {1}]".format(i, i + len(data_to_send)) + logger.debug(log_message) + + packets_sent += 1 + + if NUM_OF_PACKETS_BETWEEN_NOTIF != 0: + if (packets_sent % NUM_OF_PACKETS_BETWEEN_NOTIF) == 0: + self.set_waiting_for_notification() + + self.send_packet_data(data_to_send) + + self._wait_for_condition(self.get_received_response, waiting_for="response for RECEIVE FIRMWARE IMAGE") + self.clear_received_response() + + def send_validate_firmware(self): + super(DfuTransportBle, self).send_validate_firmware() + logger.debug("Sending 'VALIDATE FIRMWARE IMAGE' command") + self.send_control_data(DfuOpcodesBle.VALIDATE_FIRMWARE_IMAGE) + self._wait_for_condition(self.get_received_response, waiting_for="response for VALIDATE FIRMWARE IMAGE") + self.clear_received_response() + logger.info("Firmware validated OK.") + + def send_activate_firmware(self): + super(DfuTransportBle, self).send_activate_firmware() + logger.debug("Sending 'ACTIVATE FIRMWARE AND RESET' command") + self.send_control_data(DfuOpcodesBle.ACTIVATE_FIRMWARE_AND_RESET) diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_serial.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_serial.py new file mode 100644 index 0000000..0036c90 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/dfu_transport_serial.py @@ -0,0 +1,337 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Python imports +import time +from datetime import datetime, timedelta +import binascii +import logging +import click + +# Python 3rd party imports +from serial import Serial + +# Nordic Semiconductor imports +from nordicsemi.dfu.util import slip_parts_to_four_bytes, slip_encode_esc_chars, int16_to_bytes, int32_to_bytes +from nordicsemi.dfu import crc16 +from nordicsemi.exceptions import NordicSemiException +from nordicsemi.dfu.dfu_transport import DfuTransport, DfuEvent + + +logger = logging.getLogger(__name__) + + +class DfuTransportSerial(DfuTransport): + + DEFAULT_BAUD_RATE = 115200 + DEFAULT_FLOW_CONTROL = False + DEFAULT_SERIAL_PORT_TIMEOUT = 1.0 # Timeout time on serial port read + SERIAL_PORT_OPEN_WAIT_TIME = 0.1 + NRF52_RESET_WAIT_TIME = 0.1 + ACK_PACKET_TIMEOUT = 1.0 # Timeout time for for ACK packet received before reporting timeout through event system + SEND_INIT_PACKET_WAIT_TIME = 0.5 # 1.0 # Time to wait before communicating with bootloader after init packet is sent + + # SEND_START_DFU_WAIT_TIME = 10.0 # Time to wait before communicating with bootloader after start DFU packet is sent + # ADADFRUIT: + # - After Start packet is sent, nrf5x will start to erase flash page, each page takes 2.05 - 89.7 ms + # nrfutil need to wait accordingly for the image size + # - After sending all data -> send command to activate new firmware --> nrf52 erase bank0 and copy image + # from bank1 to bank0 (if dual bank) nrfutil need to wait otherwise and re-open serial could cause flash corruption + + # T erase page for nrf52832 is (2.05 to 89.7 ms), nrf52840 is ~85 ms max + FLASH_PAGE_ERASE_MAX_TIME = 0.085 + + # T write word for nrf52832 is (6.7 to 338 us), nrf52840 is ~41 us max + FLASH_WORD_WRITE_AVG_TIME = 0.000041 + + FLASH_PAGE_SIZE = 4096 # 4K for nrf52 + DFU_PACKET_MAX_SIZE = 512 # The DFU packet max size + + def __init__(self, com_port, baud_rate=DEFAULT_BAUD_RATE, flow_control=DEFAULT_FLOW_CONTROL, single_bank=False, timeout=DEFAULT_SERIAL_PORT_TIMEOUT): + super(DfuTransportSerial, self).__init__() + self.com_port = com_port + self.baud_rate = baud_rate + self.flow_control = 1 if flow_control else 0 + self.single_bank = single_bank + self.timeout = timeout + self.serial_port = None + self.total_size = 167936 # default is max application size + self.sd_size = 0 + """:type: serial.Serial """ + + def open(self): + super(DfuTransportSerial, self).open() + + try: + self.serial_port = Serial(port=self.com_port, baudrate=self.baud_rate, rtscts=self.flow_control, timeout=self.timeout) + except Exception, e: + raise NordicSemiException("Serial port could not be opened on {0}. Reason: {1}".format(self.com_port, e.message)) + + # Wait for the system to reset + time.sleep(DfuTransportSerial.SERIAL_PORT_OPEN_WAIT_TIME) + def open(self): + super(DfuTransportSerial, self).open() + + try: + self.serial_port = Serial(port=self.com_port, baudrate=self.baud_rate, rtscts=self.flow_control, timeout=self.timeout) + except Exception, e: + raise NordicSemiException("Serial port could not be opened on {0}. Reason: {1}".format(self.com_port, e.message)) + + time.sleep(DfuTransportSerial.SERIAL_PORT_OPEN_WAIT_TIME) + + # Toggle DTR to reset the board and enter DFU mode + self.serial_port.setDTR(False) + time.sleep(0.05) + self.serial_port.setDTR(True) + + # Delay to allow device to boot up + time.sleep(DfuTransportSerial.NRF52_RESET_WAIT_TIME) + + def close(self): + super(DfuTransportSerial, self).close() + self.serial_port.close() + + def is_open(self): + super(DfuTransportSerial, self).is_open() + + if self.serial_port is None: + return False + + return self.serial_port.isOpen() + + def send_validate_firmware(self): + super(DfuTransportSerial, self).send_validate_firmware() + return True + + def send_init_packet(self, init_packet): + super(DfuTransportSerial, self).send_init_packet(init_packet) + + frame = int32_to_bytes(DFU_INIT_PACKET) + frame += init_packet + frame += int16_to_bytes(0x0000) # Padding required + + packet = HciPacket(frame) + self.send_packet(packet) + time.sleep(DfuTransportSerial.SEND_INIT_PACKET_WAIT_TIME) + + def get_erase_wait_time(self): + return (((self.total_size)//self.FLASH_PAGE_SIZE)+1)*self.FLASH_PAGE_ERASE_MAX_TIME + + def get_activate_wait_time(self): + if (self.single_bank and (self.sd_size == 0)): + # Single bank and not updating SD+Bootloader, we can skip bank1 -> bank0 delay + # but still need to delay bootloader setting save (1 flash page) + return self.FLASH_PAGE_ERASE_MAX_TIME; + else: + # Activate wait time including time to erase bank0 and transfer bank1 -> bank0 + write_wait_time = ((self.total_size // 4) + 1) * self.FLASH_WORD_WRITE_AVG_TIME + return self.get_erase_wait_time() + write_wait_time + + def send_start_dfu(self, mode, softdevice_size=None, bootloader_size=None, app_size=None): + super(DfuTransportSerial, self).send_start_dfu(mode, softdevice_size, bootloader_size, app_size) + + frame = int32_to_bytes(DFU_START_PACKET) + frame += int32_to_bytes(mode) + frame += DfuTransport.create_image_size_packet(softdevice_size, bootloader_size, app_size) + + packet = HciPacket(frame) + self.send_packet(packet) + + self.sd_size = softdevice_size + self.total_size = softdevice_size+bootloader_size+app_size + #logger.info("Wait after Init Packet %s second", self.get_erase_wait_time()) + time.sleep( self.get_erase_wait_time() ) + + def send_activate_firmware(self): + super(DfuTransportSerial, self).send_activate_firmware() + + # Dual bank bootloader will erase the bank 0 with Application size & Transfer App size from bank1 to bank0 + # There must a enough delay before finished to prevent Arduino IDE reopen Serial Monitor which cause pin reset + # Single bank bootloader could skip this delay if package contains only application firmware + click.echo("\nActivating new firmware") + + # logger.info("Wait after activating %s second", self.get_activate_wait_time()) + time.sleep( self.get_activate_wait_time() ) + + def send_firmware(self, firmware): + super(DfuTransportSerial, self).send_firmware(firmware) + + def progress_percentage(part, whole): + return int(100 * float(part)/float(whole)) + + frames = [] + self._send_event(DfuEvent.PROGRESS_EVENT, progress=0, done=False, log_message="") + + for i in range(0, len(firmware), DfuTransportSerial.DFU_PACKET_MAX_SIZE): + data_packet = HciPacket(int32_to_bytes(DFU_DATA_PACKET) + firmware[i:i + DfuTransportSerial.DFU_PACKET_MAX_SIZE]) + frames.append(data_packet) + + frames_count = len(frames) + + # Send firmware packets + for count, pkt in enumerate(frames): + self.send_packet(pkt) + self._send_event(DfuEvent.PROGRESS_EVENT, + log_message="", + progress=progress_percentage(count, frames_count), + done=False) + + # Send data stop packet + frame = int32_to_bytes(DFU_STOP_DATA_PACKET) + packet = HciPacket(frame) + self.send_packet(packet) + + self._send_event(DfuEvent.PROGRESS_EVENT, progress=100, done=False, log_message="") + + def send_packet(self, pkt): + attempts = 0 + last_ack = None + packet_sent = False + + logger.debug("PC -> target: {0}".format(pkt)) + + while not packet_sent: + self.serial_port.write(pkt.data) + attempts += 1 + ack = self.get_ack_nr() + + if last_ack is None: + break + + if ack == (last_ack + 1) % 8: + last_ack = ack + packet_sent = True + + if attempts > 3: + raise Exception("Three failed tx attempts encountered on packet {0}".format(pkt.sequence_number)) + + def get_ack_nr(self): + def is_timeout(start_time, timeout_sec): + return not (datetime.now() - start_time <= timedelta(0, timeout_sec)) + + uart_buffer = '' + start = datetime.now() + + while uart_buffer.count('\xC0') < 2: + # Disregard first of the two C0 + temp = self.serial_port.read(6) + + if temp: + uart_buffer += temp + + if is_timeout(start, DfuTransportSerial.ACK_PACKET_TIMEOUT): + # reset HciPacket numbering back to 0 + HciPacket.sequence_number = 0 + self._send_event(DfuEvent.TIMEOUT_EVENT, + log_message="Timed out waiting for acknowledgement from device.") + + # quit loop + break + + # read until you get a new C0 + # RESUME_WORK + + if len(uart_buffer) < 2: + raise NordicSemiException("No data received on serial port. Not able to proceed.") + + logger.debug("PC <- target: {0}".format(binascii.hexlify(uart_buffer))) + data = self.decode_esc_chars(uart_buffer) + + # Remove 0xC0 at start and beginning + data = data[1:-1] + + # Extract ACK number from header + return (data[0] >> 3) & 0x07 + + @staticmethod + def decode_esc_chars(data): + """Replace 0xDBDC with 0xCO and 0xDBDD with 0xDB""" + result = [] + + data = bytearray(data) + + while len(data): + char = data.pop(0) + + if char == 0xDB: + char2 = data.pop(0) + + if char2 == 0xDC: + result.append(0xC0) + elif char2 == 0xDD: + result.append(0xDB) + else: + raise Exception('Char 0xDB NOT followed by 0xDC or 0xDD') + else: + result.append(char) + + return result + +DATA_INTEGRITY_CHECK_PRESENT = 1 +RELIABLE_PACKET = 1 +HCI_PACKET_TYPE = 14 + +DFU_INIT_PACKET = 1 +DFU_START_PACKET = 3 +DFU_DATA_PACKET = 4 +DFU_STOP_DATA_PACKET = 5 + +DFU_UPDATE_MODE_NONE = 0 +DFU_UPDATE_MODE_SD = 1 +DFU_UPDATE_MODE_BL = 2 +DFU_UPDATE_MODE_APP = 4 + + +class HciPacket(object): + """Class representing a single HCI packet""" + + sequence_number = 0 + + def __init__(self, data=''): + HciPacket.sequence_number = (HciPacket.sequence_number + 1) % 8 + self.temp_data = '' + self.temp_data += slip_parts_to_four_bytes(HciPacket.sequence_number, + DATA_INTEGRITY_CHECK_PRESENT, + RELIABLE_PACKET, + HCI_PACKET_TYPE, + len(data)) + self.temp_data += data + # Add escape characters + crc = crc16.calc_crc16(self.temp_data, crc=0xffff) + + self.temp_data += chr(crc & 0xFF) + self.temp_data += chr((crc & 0xFF00) >> 8) + + self.temp_data = slip_encode_esc_chars(self.temp_data) + + self.data = chr(0xc0) + self.data += self.temp_data + self.data += chr(0xc0) + + def __str__(self): + return binascii.hexlify(self.data) diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/init_packet.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/init_packet.py new file mode 100644 index 0000000..ccf8c34 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/init_packet.py @@ -0,0 +1,131 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from enum import Enum +import struct + + +INIT_PACKET_USES_CRC16 = 0 +INIT_PACKET_USES_HASH = 1 +INIT_PACKET_EXT_USES_ECDS = 2 + + +class PacketField(Enum): + DEVICE_TYPE = 1 + DEVICE_REVISION = 2 + APP_VERSION = 3 + REQUIRED_SOFTDEVICES_ARRAY = 4 + OPT_DATA = 5 + NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID = 6 + NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH = 7 + NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH = 8 + NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16 = 9 + NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS = 10 + + +class Packet(object): + """ + Class that implements the INIT packet format. + http://developer.nordicsemi.com/nRF51_SDK/doc/7.1.0/s110/html/a00065.html + """ + + UNSIGNED_SHORT = "H" + UNSIGNED_INT = "I" + UNSIGNED_CHAR = "B" + CHAR_ARRAY = "s" + + def __init__(self, init_packet_fields): + """ + + :param init_packet_fields: Dictionary with packet fields + """ + self.init_packet_fields = init_packet_fields + + def generate_packet(self): + """ + Generates a binary packet from provided init_packet_fields provided in constructor. + This version includes the extended data + + :return str: Returns a string representing the init_packet (in binary) + + """ + # Create struct format string based on keys that are + # present in self.init_packet_fields + format_string = self.__generate_struct_format_string() + args = [] + + # If you got error message AttributeError: 'int' object has no attribute 'value'. + # Uncomment line 84 and comment out line 85 and run 'python setup.py install' + #for key in sorted(self.init_packet_fields.keys(), key=lambda x: x): + for key in sorted(self.init_packet_fields.keys(), key=lambda x: x.value): + # Add length to fields that required that + if key in [PacketField.REQUIRED_SOFTDEVICES_ARRAY, + PacketField.OPT_DATA]: + args.append(len(self.init_packet_fields[key])) + args.extend(self.init_packet_fields[key]) + else: + args.append(self.init_packet_fields[key]) + + return struct.pack(format_string, *args) + + def __generate_struct_format_string(self): + format_string = "<" # Use little endian format with standard sizes for python, + # see https://docs.python.org/2/library/struct.html + + # If you got error message AttributeError: 'int' object has no attribute 'value'. + # Uncomment line 102 and comment out line 103 and run 'python setup.py install' + #for key in sorted(self.init_packet_fields.keys(), key=lambda x: x): + for key in sorted(self.init_packet_fields.keys(), key=lambda x: x.value): + if key in [PacketField.DEVICE_TYPE, + PacketField.DEVICE_REVISION, + ]: + format_string += Packet.UNSIGNED_SHORT + + elif key in [PacketField.APP_VERSION]: + format_string += Packet.UNSIGNED_INT + elif key in [PacketField.REQUIRED_SOFTDEVICES_ARRAY]: + array_elements = self.init_packet_fields[key] + format_string += Packet.UNSIGNED_SHORT # Add length field to format packet + + for _ in range(len(array_elements)): + format_string += Packet.UNSIGNED_SHORT + elif key in [PacketField.OPT_DATA]: + format_string += Packet.UNSIGNED_SHORT # Add length field to optional data + format_string += "{0}{1}".format(len(self.init_packet_fields[key]), Packet.CHAR_ARRAY) + elif key in [PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID]: + format_string += Packet.UNSIGNED_INT # Add the extended packet id field + elif key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH: + format_string += Packet.UNSIGNED_INT # Add the firmware length field + elif key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH: + format_string += "32{0}".format(Packet.CHAR_ARRAY) # SHA-256 requires 32 bytes + elif key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16: + format_string += Packet.UNSIGNED_SHORT + elif key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS: + format_string += "64{0}".format(Packet.CHAR_ARRAY) # ECDS based on P-256 using SHA-256 requires 64 bytes + + return format_string diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/__init__.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/__init__.py new file mode 100644 index 0000000..068036d --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/__init__.py @@ -0,0 +1,1286 @@ +# Copyright (c) 2005-2013, Alexander Belchenko +# All rights reserved. +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# * Redistributions of source code must retain +# the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce +# the above copyright notice, this list of conditions +# and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the author nor the names +# of its contributors may be used to endorse +# or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +'''Intel HEX file format reader and converter. + +@author Alexander Belchenko (alexander dot belchenko at gmail dot com) +@version 1.5 +''' + + +__docformat__ = "javadoc" + + +from array import array +from binascii import hexlify, unhexlify +from bisect import bisect_right +import os +import sys + +from compat import asbytes, asstr + + +class _DeprecatedParam(object): + pass + +_DEPRECATED = _DeprecatedParam() + + +class IntelHex(object): + ''' Intel HEX file reader. ''' + + def __init__(self, source=None): + ''' Constructor. If source specified, object will be initialized + with the contents of source. Otherwise the object will be empty. + + @param source source for initialization + (file name of HEX file, file object, addr dict or + other IntelHex object) + ''' + # public members + self.padding = 0x0FF + # Start Address + self.start_addr = None + + # private members + self._buf = {} + self._offset = 0 + + if source is not None: + if isinstance(source, basestring) or getattr(source, "read", None): + # load hex file + self.loadhex(source) + elif isinstance(source, dict): + self.fromdict(source) + elif isinstance(source, IntelHex): + self.padding = source.padding + if source.start_addr: + self.start_addr = source.start_addr.copy() + self._buf = source._buf.copy() + else: + raise ValueError("source: bad initializer type") + + def _decode_record(self, s, line=0): + '''Decode one record of HEX file. + + @param s line with HEX record. + @param line line number (for error messages). + + @raise EndOfFile if EOF record encountered. + ''' + s = s.rstrip('\r\n') + if not s: + return # empty line + + if s[0] == ':': + try: + bin = array('B', unhexlify(asbytes(s[1:]))) + except (TypeError, ValueError): + # this might be raised by unhexlify when odd hexascii digits + raise HexRecordError(line=line) + length = len(bin) + if length < 5: + raise HexRecordError(line=line) + else: + raise HexRecordError(line=line) + + record_length = bin[0] + if length != (5 + record_length): + raise RecordLengthError(line=line) + + addr = bin[1]*256 + bin[2] + + record_type = bin[3] + if not (0 <= record_type <= 5): + raise RecordTypeError(line=line) + + crc = sum(bin) + crc &= 0x0FF + if crc != 0: + raise RecordChecksumError(line=line) + + if record_type == 0: + # data record + addr += self._offset + for i in xrange(4, 4+record_length): + if not self._buf.get(addr, None) is None: + raise AddressOverlapError(address=addr, line=line) + self._buf[addr] = bin[i] + addr += 1 # FIXME: addr should be wrapped + # BUT after 02 record (at 64K boundary) + # and after 04 record (at 4G boundary) + + elif record_type == 1: + # end of file record + if record_length != 0: + raise EOFRecordError(line=line) + raise _EndOfFile + + elif record_type == 2: + # Extended 8086 Segment Record + if record_length != 2 or addr != 0: + raise ExtendedSegmentAddressRecordError(line=line) + self._offset = (bin[4]*256 + bin[5]) * 16 + + elif record_type == 4: + # Extended Linear Address Record + if record_length != 2 or addr != 0: + raise ExtendedLinearAddressRecordError(line=line) + self._offset = (bin[4]*256 + bin[5]) * 65536 + + elif record_type == 3: + # Start Segment Address Record + if record_length != 4 or addr != 0: + raise StartSegmentAddressRecordError(line=line) + if self.start_addr: + raise DuplicateStartAddressRecordError(line=line) + self.start_addr = {'CS': bin[4]*256 + bin[5], + 'IP': bin[6]*256 + bin[7], + } + + elif record_type == 5: + # Start Linear Address Record + if record_length != 4 or addr != 0: + raise StartLinearAddressRecordError(line=line) + if self.start_addr: + raise DuplicateStartAddressRecordError(line=line) + self.start_addr = {'EIP': (bin[4]*16777216 + + bin[5]*65536 + + bin[6]*256 + + bin[7]), + } + + def loadhex(self, fobj): + """Load hex file into internal buffer. This is not necessary + if object was initialized with source set. This will overwrite + addresses if object was already initialized. + + @param fobj file name or file-like object + """ + if getattr(fobj, "read", None) is None: + fobj = open(fobj, "r") + fclose = fobj.close + else: + fclose = None + + self._offset = 0 + line = 0 + + try: + decode = self._decode_record + try: + for s in fobj: + line += 1 + decode(s, line) + except _EndOfFile: + pass + finally: + if fclose: + fclose() + + def loadbin(self, fobj, offset=0): + """Load bin file into internal buffer. Not needed if source set in + constructor. This will overwrite addresses without warning + if object was already initialized. + + @param fobj file name or file-like object + @param offset starting address offset + """ + fread = getattr(fobj, "read", None) + if fread is None: + f = open(fobj, "rb") + fread = f.read + fclose = f.close + else: + fclose = None + + try: + self.frombytes(array('B', asbytes(fread())), offset=offset) + finally: + if fclose: + fclose() + + def loadfile(self, fobj, format): + """Load data file into internal buffer. Preferred wrapper over + loadbin or loadhex. + + @param fobj file name or file-like object + @param format file format ("hex" or "bin") + """ + if format == "hex": + self.loadhex(fobj) + elif format == "bin": + self.loadbin(fobj) + else: + raise ValueError('format should be either "hex" or "bin";' + ' got %r instead' % format) + + # alias (to be consistent with method tofile) + fromfile = loadfile + + def fromdict(self, dikt): + """Load data from dictionary. Dictionary should contain int keys + representing addresses. Values should be the data to be stored in + those addresses in unsigned char form (i.e. not strings). + The dictionary may contain the key, ``start_addr`` + to indicate the starting address of the data as described in README. + + The contents of the dict will be merged with this object and will + overwrite any conflicts. This function is not necessary if the + object was initialized with source specified. + """ + s = dikt.copy() + start_addr = s.get('start_addr') + if start_addr is not None: + del s['start_addr'] + for k in s.keys(): + if type(k) not in (int, long) or k < 0: + raise ValueError('Source dictionary should have only int keys') + self._buf.update(s) + if start_addr is not None: + self.start_addr = start_addr + + def frombytes(self, bytes, offset=0): + """Load data from array or list of bytes. + Similar to loadbin() method but works directly with iterable bytes. + """ + for b in bytes: + self._buf[offset] = b + offset += 1 + + def _get_start_end(self, start=None, end=None, size=None): + """Return default values for start and end if they are None. + If this IntelHex object is empty then it's error to + invoke this method with both start and end as None. + """ + if (start,end) == (None,None) and self._buf == {}: + raise EmptyIntelHexError + if size is not None: + if None not in (start, end): + raise ValueError("tobinarray: you can't use start,end and size" + " arguments in the same time") + if (start, end) == (None, None): + start = self.minaddr() + if start is not None: + end = start + size - 1 + else: + start = end - size + 1 + if start < 0: + raise ValueError("tobinarray: invalid size (%d) " + "for given end address (%d)" % (size,end)) + else: + if start is None: + start = self.minaddr() + if end is None: + end = self.maxaddr() + if start > end: + start, end = end, start + return start, end + + def tobinarray(self, start=None, end=None, pad=_DEPRECATED, size=None): + ''' Convert this object to binary form as array. If start and end + unspecified, they will be inferred from the data. + @param start start address of output bytes. + @param end end address of output bytes (inclusive). + @param pad [DEPRECATED PARAMETER, please use self.padding instead] + fill empty spaces with this value + (if pad is None then this method uses self.padding). + @param size size of the block, used with start or end parameter. + @return array of unsigned char data. + ''' + if not isinstance(pad, _DeprecatedParam): + print "IntelHex.tobinarray: 'pad' parameter is deprecated." + if pad is not None: + print "Please, use IntelHex.padding attribute instead." + else: + print "Please, don't pass it explicitly." + print "Use syntax like this: ih.tobinarray(start=xxx, end=yyy, size=zzz)" + else: + pad = None + return self._tobinarray_really(start, end, pad, size) + + def _tobinarray_really(self, start, end, pad, size): + if pad is None: + pad = self.padding + + bin = array('B') + + if self._buf == {} and None in (start, end): + return bin + + if size is not None and size <= 0: + raise ValueError("tobinarray: wrong value for size") + + start, end = self._get_start_end(start, end, size) + + for i in xrange(start, end+1): + bin.append(self._buf.get(i, pad)) + + return bin + + def tobinstr(self, start=None, end=None, pad=_DEPRECATED, size=None): + ''' Convert to binary form and return as a string. + @param start start address of output bytes. + @param end end address of output bytes (inclusive). + @param pad [DEPRECATED PARAMETER, please use self.padding instead] + fill empty spaces with this value + (if pad is None then this method uses self.padding). + @param size size of the block, used with start or end parameter. + @return string of binary data. + ''' + if not isinstance(pad, _DeprecatedParam): + print "IntelHex.tobinstr: 'pad' parameter is deprecated." + if pad is not None: + print "Please, use IntelHex.padding attribute instead." + else: + print "Please, don't pass it explicitly." + print "Use syntax like this: ih.tobinstr(start=xxx, end=yyy, size=zzz)" + else: + pad = None + return self._tobinstr_really(start, end, pad, size) + + def _tobinstr_really(self, start, end, pad, size): + return asstr(self._tobinarray_really(start, end, pad, size).tostring()) + + def tobinfile(self, fobj, start=None, end=None, pad=_DEPRECATED, size=None): + '''Convert to binary and write to file. + + @param fobj file name or file object for writing output bytes. + @param start start address of output bytes. + @param end end address of output bytes (inclusive). + @param pad [DEPRECATED PARAMETER, please use self.padding instead] + fill empty spaces with this value + (if pad is None then this method uses self.padding). + @param size size of the block, used with start or end parameter. + ''' + if not isinstance(pad, _DeprecatedParam): + print "IntelHex.tobinfile: 'pad' parameter is deprecated." + if pad is not None: + print "Please, use IntelHex.padding attribute instead." + else: + print "Please, don't pass it explicitly." + print "Use syntax like this: ih.tobinfile(start=xxx, end=yyy, size=zzz)" + else: + pad = None + if getattr(fobj, "write", None) is None: + fobj = open(fobj, "wb") + close_fd = True + else: + close_fd = False + + fobj.write(self._tobinstr_really(start, end, pad, size)) + + if close_fd: + fobj.close() + + def todict(self): + '''Convert to python dictionary. + + @return dict suitable for initializing another IntelHex object. + ''' + r = {} + r.update(self._buf) + if self.start_addr: + r['start_addr'] = self.start_addr + return r + + def addresses(self): + '''Returns all used addresses in sorted order. + @return list of occupied data addresses in sorted order. + ''' + aa = self._buf.keys() + aa.sort() + return aa + + def minaddr(self): + '''Get minimal address of HEX content. + @return minimal address or None if no data + ''' + aa = self._buf.keys() + if aa == []: + return None + else: + return min(aa) + + def maxaddr(self): + '''Get maximal address of HEX content. + @return maximal address or None if no data + ''' + aa = self._buf.keys() + if aa == []: + return None + else: + return max(aa) + + def __getitem__(self, addr): + ''' Get requested byte from address. + @param addr address of byte. + @return byte if address exists in HEX file, or self.padding + if no data found. + ''' + t = type(addr) + if t in (int, long): + if addr < 0: + raise TypeError('Address should be >= 0.') + return self._buf.get(addr, self.padding) + elif t == slice: + addresses = self._buf.keys() + ih = IntelHex() + if addresses: + addresses.sort() + start = addr.start or addresses[0] + stop = addr.stop or (addresses[-1]+1) + step = addr.step or 1 + for i in xrange(start, stop, step): + x = self._buf.get(i) + if x is not None: + ih[i] = x + return ih + else: + raise TypeError('Address has unsupported type: %s' % t) + + def __setitem__(self, addr, byte): + """Set byte at address.""" + t = type(addr) + if t in (int, long): + if addr < 0: + raise TypeError('Address should be >= 0.') + self._buf[addr] = byte + elif t == slice: + if not isinstance(byte, (list, tuple)): + raise ValueError('Slice operation expects sequence of bytes') + start = addr.start + stop = addr.stop + step = addr.step or 1 + if None not in (start, stop): + ra = range(start, stop, step) + if len(ra) != len(byte): + raise ValueError('Length of bytes sequence does not match ' + 'address range') + elif (start, stop) == (None, None): + raise TypeError('Unsupported address range') + elif start is None: + start = stop - len(byte) + elif stop is None: + stop = start + len(byte) + if start < 0: + raise TypeError('start address cannot be negative') + if stop < 0: + raise TypeError('stop address cannot be negative') + j = 0 + for i in xrange(start, stop, step): + self._buf[i] = byte[j] + j += 1 + else: + raise TypeError('Address has unsupported type: %s' % t) + + def __delitem__(self, addr): + """Delete byte at address.""" + t = type(addr) + if t in (int, long): + if addr < 0: + raise TypeError('Address should be >= 0.') + del self._buf[addr] + elif t == slice: + addresses = self._buf.keys() + if addresses: + addresses.sort() + start = addr.start or addresses[0] + stop = addr.stop or (addresses[-1]+1) + step = addr.step or 1 + for i in xrange(start, stop, step): + x = self._buf.get(i) + if x is not None: + del self._buf[i] + else: + raise TypeError('Address has unsupported type: %s' % t) + + def __len__(self): + """Return count of bytes with real values.""" + return len(self._buf.keys()) + + def write_hex_file(self, f, write_start_addr=True): + """Write data to file f in HEX format. + + @param f filename or file-like object for writing + @param write_start_addr enable or disable writing start address + record to file (enabled by default). + If there is no start address in obj, nothing + will be written regardless of this setting. + """ + fwrite = getattr(f, "write", None) + if fwrite: + fobj = f + fclose = None + else: + fobj = open(f, 'w') + fwrite = fobj.write + fclose = fobj.close + + # Translation table for uppercasing hex ascii string. + # timeit shows that using hexstr.translate(table) + # is faster than hexstr.upper(): + # 0.452ms vs. 0.652ms (translate vs. upper) + if sys.version_info[0] >= 3: + table = bytes(range(256)).upper() + else: + table = ''.join(chr(i).upper() for i in range(256)) + + + + # start address record if any + if self.start_addr and write_start_addr: + keys = self.start_addr.keys() + keys.sort() + bin = array('B', asbytes('\0'*9)) + if keys == ['CS','IP']: + # Start Segment Address Record + bin[0] = 4 # reclen + bin[1] = 0 # offset msb + bin[2] = 0 # offset lsb + bin[3] = 3 # rectyp + cs = self.start_addr['CS'] + bin[4] = (cs >> 8) & 0x0FF + bin[5] = cs & 0x0FF + ip = self.start_addr['IP'] + bin[6] = (ip >> 8) & 0x0FF + bin[7] = ip & 0x0FF + bin[8] = (-sum(bin)) & 0x0FF # chksum + fwrite(':' + + asstr(hexlify(bin.tostring()).translate(table)) + + '\n') + elif keys == ['EIP']: + # Start Linear Address Record + bin[0] = 4 # reclen + bin[1] = 0 # offset msb + bin[2] = 0 # offset lsb + bin[3] = 5 # rectyp + eip = self.start_addr['EIP'] + bin[4] = (eip >> 24) & 0x0FF + bin[5] = (eip >> 16) & 0x0FF + bin[6] = (eip >> 8) & 0x0FF + bin[7] = eip & 0x0FF + bin[8] = (-sum(bin)) & 0x0FF # chksum + fwrite(':' + + asstr(hexlify(bin.tostring()).translate(table)) + + '\n') + else: + if fclose: + fclose() + raise InvalidStartAddressValueError(start_addr=self.start_addr) + + # data + addresses = self._buf.keys() + addresses.sort() + addr_len = len(addresses) + if addr_len: + minaddr = addresses[0] + maxaddr = addresses[-1] + + if maxaddr > 65535: + need_offset_record = True + else: + need_offset_record = False + high_ofs = 0 + + cur_addr = minaddr + cur_ix = 0 + + while cur_addr <= maxaddr: + if need_offset_record: + bin = array('B', asbytes('\0'*7)) + bin[0] = 2 # reclen + bin[1] = 0 # offset msb + bin[2] = 0 # offset lsb + bin[3] = 4 # rectyp + high_ofs = int(cur_addr>>16) + b = divmod(high_ofs, 256) + bin[4] = b[0] # msb of high_ofs + bin[5] = b[1] # lsb of high_ofs + bin[6] = (-sum(bin)) & 0x0FF # chksum + fwrite(':' + + asstr(hexlify(bin.tostring()).translate(table)) + + '\n') + + while True: + # produce one record + low_addr = cur_addr & 0x0FFFF + # chain_len off by 1 + chain_len = min(15, 65535-low_addr, maxaddr-cur_addr) + + # search continuous chain + stop_addr = cur_addr + chain_len + if chain_len: + ix = bisect_right(addresses, stop_addr, + cur_ix, + min(cur_ix+chain_len+1, addr_len)) + chain_len = ix - cur_ix # real chain_len + # there could be small holes in the chain + # but we will catch them by try-except later + # so for big continuous files we will work + # at maximum possible speed + else: + chain_len = 1 # real chain_len + + bin = array('B', asbytes('\0'*(5+chain_len))) + b = divmod(low_addr, 256) + bin[1] = b[0] # msb of low_addr + bin[2] = b[1] # lsb of low_addr + bin[3] = 0 # rectype + try: # if there is small holes we'll catch them + for i in range(chain_len): + bin[4+i] = self._buf[cur_addr+i] + except KeyError: + # we catch a hole so we should shrink the chain + chain_len = i + bin = bin[:5+i] + bin[0] = chain_len + bin[4+chain_len] = (-sum(bin)) & 0x0FF # chksum + fwrite(':' + + asstr(hexlify(bin.tostring()).translate(table)) + + '\n') + + # adjust cur_addr/cur_ix + cur_ix += chain_len + if cur_ix < addr_len: + cur_addr = addresses[cur_ix] + else: + cur_addr = maxaddr + 1 + break + high_addr = int(cur_addr>>16) + if high_addr > high_ofs: + break + + # end-of-file record + fwrite(":00000001FF\n") + if fclose: + fclose() + + def tofile(self, fobj, format): + """Write data to hex or bin file. Preferred method over tobin or tohex. + + @param fobj file name or file-like object + @param format file format ("hex" or "bin") + """ + if format == 'hex': + self.write_hex_file(fobj) + elif format == 'bin': + self.tobinfile(fobj) + else: + raise ValueError('format should be either "hex" or "bin";' + ' got %r instead' % format) + + def gets(self, addr, length): + """Get string of bytes from given address. If any entries are blank + from addr through addr+length, a NotEnoughDataError exception will + be raised. Padding is not used.""" + a = array('B', asbytes('\0'*length)) + try: + for i in xrange(length): + a[i] = self._buf[addr+i] + except KeyError: + raise NotEnoughDataError(address=addr, length=length) + return asstr(a.tostring()) + + def puts(self, addr, s): + """Put string of bytes at given address. Will overwrite any previous + entries. + """ + a = array('B', asbytes(s)) + for i in xrange(len(a)): + self._buf[addr+i] = a[i] + + def getsz(self, addr): + """Get zero-terminated string from given address. Will raise + NotEnoughDataError exception if a hole is encountered before a 0. + """ + i = 0 + try: + while True: + if self._buf[addr+i] == 0: + break + i += 1 + except KeyError: + raise NotEnoughDataError(msg=('Bad access at 0x%X: ' + 'not enough data to read zero-terminated string') % addr) + return self.gets(addr, i) + + def putsz(self, addr, s): + """Put string in object at addr and append terminating zero at end.""" + self.puts(addr, s) + self._buf[addr+len(s)] = 0 + + def dump(self, tofile=None): + """Dump object content to specified file object or to stdout if None. + Format is a hexdump with some header information at the beginning, + addresses on the left, and data on right. + + @param tofile file-like object to dump to + """ + + if tofile is None: + tofile = sys.stdout + # start addr possibly + if self.start_addr is not None: + cs = self.start_addr.get('CS') + ip = self.start_addr.get('IP') + eip = self.start_addr.get('EIP') + if eip is not None and cs is None and ip is None: + tofile.write('EIP = 0x%08X\n' % eip) + elif eip is None and cs is not None and ip is not None: + tofile.write('CS = 0x%04X, IP = 0x%04X\n' % (cs, ip)) + else: + tofile.write('start_addr = %r\n' % start_addr) + # actual data + addresses = self._buf.keys() + if addresses: + addresses.sort() + minaddr = addresses[0] + maxaddr = addresses[-1] + startaddr = int(minaddr>>4)*16 + endaddr = int((maxaddr>>4)+1)*16 + maxdigits = max(len(str(endaddr)), 4) + templa = '%%0%dX' % maxdigits + range16 = range(16) + for i in xrange(startaddr, endaddr, 16): + tofile.write(templa % i) + tofile.write(' ') + s = [] + for j in range16: + x = self._buf.get(i+j) + if x is not None: + tofile.write(' %02X' % x) + if 32 <= x < 127: # GNU less does not like 0x7F (128 decimal) so we'd better show it as dot + s.append(chr(x)) + else: + s.append('.') + else: + tofile.write(' --') + s.append(' ') + tofile.write(' |' + ''.join(s) + '|\n') + + def merge(self, other, overlap='error'): + """Merge content of other IntelHex object into current object (self). + @param other other IntelHex object. + @param overlap action on overlap of data or starting addr: + - error: raising OverlapError; + - ignore: ignore other data and keep current data + in overlapping region; + - replace: replace data with other data + in overlapping region. + + @raise TypeError if other is not instance of IntelHex + @raise ValueError if other is the same object as self + (it can't merge itself) + @raise ValueError if overlap argument has incorrect value + @raise AddressOverlapError on overlapped data + """ + # check args + if not isinstance(other, IntelHex): + raise TypeError('other should be IntelHex object') + if other is self: + raise ValueError("Can't merge itself") + if overlap not in ('error', 'ignore', 'replace'): + raise ValueError("overlap argument should be either " + "'error', 'ignore' or 'replace'") + # merge data + this_buf = self._buf + other_buf = other._buf + for i in other_buf: + if i in this_buf: + if overlap == 'error': + raise AddressOverlapError( + 'Data overlapped at address 0x%X' % i) + elif overlap == 'ignore': + continue + this_buf[i] = other_buf[i] + # merge start_addr + if self.start_addr != other.start_addr: + if self.start_addr is None: # set start addr from other + self.start_addr = other.start_addr + elif other.start_addr is None: # keep existing start addr + pass + else: # conflict + if overlap == 'error': + raise AddressOverlapError( + 'Starting addresses are different') + elif overlap == 'replace': + self.start_addr = other.start_addr +#/IntelHex + + +class IntelHex16bit(IntelHex): + """Access to data as 16-bit words. Intended to use with Microchip HEX files.""" + + def __init__(self, source=None): + """Construct class from HEX file + or from instance of ordinary IntelHex class. If IntelHex object + is passed as source, the original IntelHex object should not be used + again because this class will alter it. This class leaves padding + alone unless it was precisely 0xFF. In that instance it is sign + extended to 0xFFFF. + + @param source file name of HEX file or file object + or instance of ordinary IntelHex class. + Will also accept dictionary from todict method. + """ + if isinstance(source, IntelHex): + # from ihex8 + self.padding = source.padding + self.start_addr = source.start_addr + # private members + self._buf = source._buf + self._offset = source._offset + elif isinstance(source, dict): + raise IntelHexError("IntelHex16bit does not support initialization from dictionary yet.\n" + "Patches are welcome.") + else: + IntelHex.__init__(self, source) + + if self.padding == 0x0FF: + self.padding = 0x0FFFF + + def __getitem__(self, addr16): + """Get 16-bit word from address. + Raise error if only one byte from the pair is set. + We assume a Little Endian interpretation of the hex file. + + @param addr16 address of word (addr8 = 2 * addr16). + @return word if bytes exists in HEX file, or self.padding + if no data found. + """ + addr1 = addr16 * 2 + addr2 = addr1 + 1 + byte1 = self._buf.get(addr1, None) + byte2 = self._buf.get(addr2, None) + + if byte1 != None and byte2 != None: + return byte1 | (byte2 << 8) # low endian + + if byte1 == None and byte2 == None: + return self.padding + + raise BadAccess16bit(address=addr16) + + def __setitem__(self, addr16, word): + """Sets the address at addr16 to word assuming Little Endian mode. + """ + addr_byte = addr16 * 2 + b = divmod(word, 256) + self._buf[addr_byte] = b[1] + self._buf[addr_byte+1] = b[0] + + def minaddr(self): + '''Get minimal address of HEX content in 16-bit mode. + + @return minimal address used in this object + ''' + aa = self._buf.keys() + if aa == []: + return 0 + else: + return min(aa)>>1 + + def maxaddr(self): + '''Get maximal address of HEX content in 16-bit mode. + + @return maximal address used in this object + ''' + aa = self._buf.keys() + if aa == []: + return 0 + else: + return max(aa)>>1 + + def tobinarray(self, start=None, end=None, size=None): + '''Convert this object to binary form as array (of 2-bytes word data). + If start and end unspecified, they will be inferred from the data. + @param start start address of output data. + @param end end address of output data (inclusive). + @param size size of the block (number of words), + used with start or end parameter. + @return array of unsigned short (uint16_t) data. + ''' + bin = array('H') + + if self._buf == {} and None in (start, end): + return bin + + if size is not None and size <= 0: + raise ValueError("tobinarray: wrong value for size") + + start, end = self._get_start_end(start, end, size) + + for addr in xrange(start, end+1): + bin.append(self[addr]) + + return bin + + +#/class IntelHex16bit + + +def hex2bin(fin, fout, start=None, end=None, size=None, pad=None): + """Hex-to-Bin convertor engine. + @return 0 if all OK + + @param fin input hex file (filename or file-like object) + @param fout output bin file (filename or file-like object) + @param start start of address range (optional) + @param end end of address range (inclusive; optional) + @param size size of resulting file (in bytes) (optional) + @param pad padding byte (optional) + """ + try: + h = IntelHex(fin) + except HexReaderError, e: + txt = "ERROR: bad HEX file: %s" % str(e) + print(txt) + return 1 + + # start, end, size + if size != None and size != 0: + if end == None: + if start == None: + start = h.minaddr() + end = start + size - 1 + else: + if (end+1) >= size: + start = end + 1 - size + else: + start = 0 + + try: + if pad is not None: + # using .padding attribute rather than pad argument to function call + h.padding = pad + h.tobinfile(fout, start, end) + except IOError, e: + txt = "ERROR: Could not write to file: %s: %s" % (fout, str(e)) + print(txt) + return 1 + + return 0 +#/def hex2bin + + +def bin2hex(fin, fout, offset=0): + """Simple bin-to-hex convertor. + @return 0 if all OK + + @param fin input bin file (filename or file-like object) + @param fout output hex file (filename or file-like object) + @param offset starting address offset for loading bin + """ + h = IntelHex() + try: + h.loadbin(fin, offset) + except IOError, e: + txt = 'ERROR: unable to load bin file:', str(e) + print(txt) + return 1 + + try: + h.tofile(fout, format='hex') + except IOError, e: + txt = "ERROR: Could not write to file: %s: %s" % (fout, str(e)) + print(txt) + return 1 + + return 0 +#/def bin2hex + + +def diff_dumps(ih1, ih2, tofile=None, name1="a", name2="b", n_context=3): + """Diff 2 IntelHex objects and produce unified diff output for their + hex dumps. + + @param ih1 first IntelHex object to compare + @param ih2 second IntelHex object to compare + @param tofile file-like object to write output + @param name1 name of the first hex file to show in the diff header + @param name2 name of the first hex file to show in the diff header + @param n_context number of context lines in the unidiff output + """ + def prepare_lines(ih): + from cStringIO import StringIO + sio = StringIO() + ih.dump(sio) + dump = sio.getvalue() + lines = dump.splitlines() + return lines + a = prepare_lines(ih1) + b = prepare_lines(ih2) + import difflib + result = list(difflib.unified_diff(a, b, fromfile=name1, tofile=name2, n=n_context, lineterm='')) + if tofile is None: + tofile = sys.stdout + output = '\n'.join(result)+'\n' + tofile.write(output) + + +class Record(object): + """Helper methods to build valid ihex records.""" + + def _from_bytes(bytes): + """Takes a list of bytes, computes the checksum, and outputs the entire + record as a string. bytes should be the hex record without the colon + or final checksum. + + @param bytes list of byte values so far to pack into record. + @return String representation of one HEX record + """ + assert len(bytes) >= 4 + # calculate checksum + s = (-sum(bytes)) & 0x0FF + bin = array('B', bytes + [s]) + return ':' + asstr(hexlify(bin.tostring())).upper() + _from_bytes = staticmethod(_from_bytes) + + def data(offset, bytes): + """Return Data record. This constructs the full record, including + the length information, the record type (0x00), the + checksum, and the offset. + + @param offset load offset of first byte. + @param bytes list of byte values to pack into record. + + @return String representation of one HEX record + """ + assert 0 <= offset < 65536 + assert 0 < len(bytes) < 256 + b = [len(bytes), (offset>>8)&0x0FF, offset&0x0FF, 0x00] + bytes + return Record._from_bytes(b) + data = staticmethod(data) + + def eof(): + """Return End of File record as a string. + @return String representation of Intel Hex EOF record + """ + return ':00000001FF' + eof = staticmethod(eof) + + def extended_segment_address(usba): + """Return Extended Segment Address Record. + @param usba Upper Segment Base Address. + + @return String representation of Intel Hex USBA record. + """ + b = [2, 0, 0, 0x02, (usba>>8)&0x0FF, usba&0x0FF] + return Record._from_bytes(b) + extended_segment_address = staticmethod(extended_segment_address) + + def start_segment_address(cs, ip): + """Return Start Segment Address Record. + @param cs 16-bit value for CS register. + @param ip 16-bit value for IP register. + + @return String representation of Intel Hex SSA record. + """ + b = [4, 0, 0, 0x03, (cs>>8)&0x0FF, cs&0x0FF, + (ip>>8)&0x0FF, ip&0x0FF] + return Record._from_bytes(b) + start_segment_address = staticmethod(start_segment_address) + + def extended_linear_address(ulba): + """Return Extended Linear Address Record. + @param ulba Upper Linear Base Address. + + @return String representation of Intel Hex ELA record. + """ + b = [2, 0, 0, 0x04, (ulba>>8)&0x0FF, ulba&0x0FF] + return Record._from_bytes(b) + extended_linear_address = staticmethod(extended_linear_address) + + def start_linear_address(eip): + """Return Start Linear Address Record. + @param eip 32-bit linear address for the EIP register. + + @return String representation of Intel Hex SLA record. + """ + b = [4, 0, 0, 0x05, (eip>>24)&0x0FF, (eip>>16)&0x0FF, + (eip>>8)&0x0FF, eip&0x0FF] + return Record._from_bytes(b) + start_linear_address = staticmethod(start_linear_address) + + +class _BadFileNotation(Exception): + """Special error class to use with _get_file_and_addr_range.""" + pass + +def _get_file_and_addr_range(s, _support_drive_letter=None): + """Special method for hexmerge.py script to split file notation + into 3 parts: (filename, start, end) + + @raise _BadFileNotation when string cannot be safely split. + """ + if _support_drive_letter is None: + _support_drive_letter = (os.name == 'nt') + drive = '' + if _support_drive_letter: + if s[1:2] == ':' and s[0].upper() in ''.join([chr(i) for i in range(ord('A'), ord('Z')+1)]): + drive = s[:2] + s = s[2:] + parts = s.split(':') + n = len(parts) + if n == 1: + fname = parts[0] + fstart = None + fend = None + elif n != 3: + raise _BadFileNotation + else: + fname = parts[0] + def ascii_hex_to_int(ascii): + if ascii is not None: + try: + return int(ascii, 16) + except ValueError: + raise _BadFileNotation + return ascii + fstart = ascii_hex_to_int(parts[1] or None) + fend = ascii_hex_to_int(parts[2] or None) + return drive+fname, fstart, fend + + +## +# IntelHex Errors Hierarchy: +# +# IntelHexError - basic error +# HexReaderError - general hex reader error +# AddressOverlapError - data for the same address overlap +# HexRecordError - hex record decoder base error +# RecordLengthError - record has invalid length +# RecordTypeError - record has invalid type (RECTYP) +# RecordChecksumError - record checksum mismatch +# EOFRecordError - invalid EOF record (type 01) +# ExtendedAddressRecordError - extended address record base error +# ExtendedSegmentAddressRecordError - invalid extended segment address record (type 02) +# ExtendedLinearAddressRecordError - invalid extended linear address record (type 04) +# StartAddressRecordError - start address record base error +# StartSegmentAddressRecordError - invalid start segment address record (type 03) +# StartLinearAddressRecordError - invalid start linear address record (type 05) +# DuplicateStartAddressRecordError - start address record appears twice +# InvalidStartAddressValueError - invalid value of start addr record +# _EndOfFile - it's not real error, used internally by hex reader as signal that EOF record found +# BadAccess16bit - not enough data to read 16 bit value (deprecated, see NotEnoughDataError) +# NotEnoughDataError - not enough data to read N contiguous bytes +# EmptyIntelHexError - requested operation cannot be performed with empty object + +class IntelHexError(Exception): + '''Base Exception class for IntelHex module''' + + _fmt = 'IntelHex base error' #: format string + + def __init__(self, msg=None, **kw): + """Initialize the Exception with the given message. + """ + self.msg = msg + for key, value in kw.items(): + setattr(self, key, value) + + def __str__(self): + """Return the message in this Exception.""" + if self.msg: + return self.msg + try: + return self._fmt % self.__dict__ + except (NameError, ValueError, KeyError), e: + return 'Unprintable exception %s: %s' \ + % (repr(e), str(e)) + +class _EndOfFile(IntelHexError): + """Used for internal needs only.""" + _fmt = 'EOF record reached -- signal to stop read file' + +class HexReaderError(IntelHexError): + _fmt = 'Hex reader base error' + +class AddressOverlapError(HexReaderError): + _fmt = 'Hex file has data overlap at address 0x%(address)X on line %(line)d' + +# class NotAHexFileError was removed in trunk.revno.54 because it's not used + + +class HexRecordError(HexReaderError): + _fmt = 'Hex file contains invalid record at line %(line)d' + + +class RecordLengthError(HexRecordError): + _fmt = 'Record at line %(line)d has invalid length' + +class RecordTypeError(HexRecordError): + _fmt = 'Record at line %(line)d has invalid record type' + +class RecordChecksumError(HexRecordError): + _fmt = 'Record at line %(line)d has invalid checksum' + +class EOFRecordError(HexRecordError): + _fmt = 'File has invalid End-of-File record' + + +class ExtendedAddressRecordError(HexRecordError): + _fmt = 'Base class for extended address exceptions' + +class ExtendedSegmentAddressRecordError(ExtendedAddressRecordError): + _fmt = 'Invalid Extended Segment Address Record at line %(line)d' + +class ExtendedLinearAddressRecordError(ExtendedAddressRecordError): + _fmt = 'Invalid Extended Linear Address Record at line %(line)d' + + +class StartAddressRecordError(HexRecordError): + _fmt = 'Base class for start address exceptions' + +class StartSegmentAddressRecordError(StartAddressRecordError): + _fmt = 'Invalid Start Segment Address Record at line %(line)d' + +class StartLinearAddressRecordError(StartAddressRecordError): + _fmt = 'Invalid Start Linear Address Record at line %(line)d' + +class DuplicateStartAddressRecordError(StartAddressRecordError): + _fmt = 'Start Address Record appears twice at line %(line)d' + +class InvalidStartAddressValueError(StartAddressRecordError): + _fmt = 'Invalid start address value: %(start_addr)s' + + +class NotEnoughDataError(IntelHexError): + _fmt = ('Bad access at 0x%(address)X: ' + 'not enough data to read %(length)d contiguous bytes') + +class BadAccess16bit(NotEnoughDataError): + _fmt = 'Bad access at 0x%(address)X: not enough data to read 16 bit value' + +class EmptyIntelHexError(IntelHexError): + _fmt = "Requested operation cannot be executed with empty object" diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/compat.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/compat.py new file mode 100644 index 0000000..3f48350 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/intelhex/compat.py @@ -0,0 +1,57 @@ +# Copyright (c) 2011, Bernhard Leiner +# All rights reserved. +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# * Redistributions of source code must retain +# the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce +# the above copyright notice, this list of conditions +# and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the author nor the names +# of its contributors may be used to endorse +# or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +'''Compatibility functions for python 2 and 3. + +@author Bernhard Leiner (bleiner AT gmail com) +@version 1.0 +''' + +__docformat__ = "javadoc" + + +import sys + +if sys.version_info[0] >= 3: + def asbytes(s): + if isinstance(s, bytes): + return s + return s.encode('latin1') + def asstr(s): + if isinstance(s, str): + return s + return s.decode('latin1') +else: + asbytes = str + asstr = str + diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/manifest.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/manifest.py new file mode 100644 index 0000000..c65e7dd --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/manifest.py @@ -0,0 +1,239 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Python libraries +import json +import binascii +import os + +# Nordic libraries +from nordicsemi.exceptions import NotImplementedException +from nordicsemi.dfu.init_packet import PacketField +from nordicsemi.dfu.model import HexType, FirmwareKeys + + +class ManifestGenerator(object): + def __init__(self, dfu_version, firmwares_data): + """ + The Manifest Generator constructor. Needs a data structure to generate a manifest from. + + :type float dfu_version: The dfu version number to state in manifest + :type dict firmwares_data: The firmwares data structure describing the Nordic DFU package + """ + self.dfu_version = dfu_version + self.firmwares_data = firmwares_data + self.manifest = None + + def generate_manifest(self): + self.manifest = Manifest() + self.manifest.dfu_version = self.dfu_version + + for key in self.firmwares_data: + firmware_dict = self.firmwares_data[key] + + if key == HexType.SD_BL: + _firmware = SoftdeviceBootloaderFirmware() + _firmware.bl_size = firmware_dict[FirmwareKeys.BL_SIZE] + _firmware.sd_size = firmware_dict[FirmwareKeys.SD_SIZE] + else: + _firmware = Firmware() + + # Strip path, add only filename + _firmware.bin_file = os.path.basename(firmware_dict[FirmwareKeys.BIN_FILENAME]) + _firmware.dat_file = os.path.basename(firmware_dict[FirmwareKeys.DAT_FILENAME]) + + init_packet_data = InitPacketData() + + for init_packet_data_key in firmware_dict[FirmwareKeys.INIT_PACKET_DATA]: + field = firmware_dict[FirmwareKeys.INIT_PACKET_DATA][init_packet_data_key] + + if init_packet_data_key == PacketField.APP_VERSION: + init_packet_data.application_version = field + elif init_packet_data_key == PacketField.DEVICE_TYPE: + init_packet_data.device_type = field + elif init_packet_data_key == PacketField.DEVICE_REVISION: + init_packet_data.device_revision = field + elif init_packet_data_key == PacketField.REQUIRED_SOFTDEVICES_ARRAY: + init_packet_data.softdevice_req = field + elif init_packet_data_key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID: + init_packet_data.ext_packet_id = field + elif init_packet_data_key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH: + init_packet_data.firmware_length = field + elif init_packet_data_key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH: + init_packet_data.firmware_hash = binascii.hexlify(field) + elif init_packet_data_key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16: + init_packet_data.firmware_crc16 = field + elif init_packet_data_key == PacketField.NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS: + init_packet_data.init_packet_ecds = binascii.hexlify(field) + else: + raise NotImplementedException( + "Support for init packet data type {0} not implemented yet.".format(init_packet_data_key)) + + _firmware.init_packet_data = init_packet_data + + if key == HexType.APPLICATION: + self.manifest.application = _firmware + elif key == HexType.BOOTLOADER: + self.manifest.bootloader = _firmware + elif key == HexType.SOFTDEVICE: + self.manifest.softdevice = _firmware + elif key == HexType.SD_BL: + self.manifest.softdevice_bootloader = _firmware + else: + raise NotImplementedException("Support for firmware type {0} not implemented yet.".format(key)) + + return self.to_json() + + def to_json(self): + def remove_none_entries(d): + if not isinstance(d, dict): + return d + + return dict((k, remove_none_entries(v)) for k, v in d.iteritems() if v is not None) + + return json.dumps({'manifest': self.manifest}, + default=lambda o: remove_none_entries(o.__dict__), + sort_keys=True, indent=4, + separators=(',', ': ')) + + +class InitPacketData(object): + def __init__(self, + device_type=None, + device_revision=None, + application_version=None, + softdevice_req=None, + ext_packet_id=None, + firmware_length=None, + firmware_hash=None, + firmware_crc16=None, + init_packet_ecds=None + ): + """ + The InitPacketData data model. + + :param int device_type: device type + :param int device_revision: device revision + :param int application_version: application version + :param list softdevice_req: softdevice requirements + :param int ext_packet_id: packet extension id + :param int firmware_length: firmware length + :param str firmware_hash: firmware hash + :param int firmware_crc16: firmware CRC-16 calculated value + :param str init_packet_ecds: Init packet signature + :return: InitPacketData + """ + self.device_type = device_type + self.device_revision = device_revision + self.application_version = application_version + self.softdevice_req = softdevice_req + self.ext_packet_id = ext_packet_id + self.firmware_length = firmware_length + self.firmware_hash = firmware_hash + self.firmware_crc16 = firmware_crc16 + self.init_packet_ecds = init_packet_ecds + + +class Firmware(object): + def __init__(self, + bin_file=None, + dat_file=None, + init_packet_data=None): + """ + The firmware datamodel + + :param str bin_file: Firmware binary file + :param str dat_file: Firmware .dat file (init packet for Nordic DFU) + :param dict init_packet_data: Initial packet data + :return: + """ + self.dat_file = dat_file + self.bin_file = bin_file + + if init_packet_data: + self.init_packet_data = InitPacketData(**init_packet_data) + + +class SoftdeviceBootloaderFirmware(Firmware): + def __init__(self, + bin_file=None, + dat_file=None, + init_packet_data=None, + sd_size=None, + bl_size=None): + """ + The SoftdeviceBootloaderFirmware data model + + :param str bin_file: Firmware binary file + :param str dat_file: Firmware .dat file (init packet for Nordic DFU) + :param int sd_size: The softdevice size + :param int bl_size: The bootloader size + :return: SoftdeviceBootloaderFirmware + """ + super(SoftdeviceBootloaderFirmware, self).__init__( + bin_file, + dat_file, + init_packet_data) + self.sd_size = sd_size + self.bl_size = bl_size + + +class Manifest: + def __init__(self, + application=None, + bootloader=None, + softdevice=None, + softdevice_bootloader=None, + dfu_version=None): + """ + The Manifest data model. + + :param dict application: Application firmware in package + :param dict bootloader: Bootloader firmware in package + :param dict softdevice: Softdevice firmware in package + :param dict softdevice_bootloader: Combined softdevice and bootloader firmware in package + :return: Manifest + """ + self.softdevice_bootloader = \ + SoftdeviceBootloaderFirmware(**softdevice_bootloader) if softdevice_bootloader else None + + self.softdevice = Firmware(**softdevice) if softdevice else None + self.bootloader = Firmware(**bootloader) if bootloader else None + self.application = Firmware(**application) if application else None + self.dfu_version = dfu_version + + @staticmethod + def from_json(data): + """ + Parses a manifest according to Nordic DFU package specification. + + :param str data: The manifest in string format + :return: Manifest + """ + kwargs = json.loads(data) + return Manifest(**kwargs['manifest']) diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/model.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/model.py new file mode 100644 index 0000000..a5c3426 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/model.py @@ -0,0 +1,46 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from enum import Enum + + +class HexType(object): + SOFTDEVICE = 1 + BOOTLOADER = 2 + SD_BL = 3 + APPLICATION = 4 + + +class FirmwareKeys(Enum): + ENCRYPT = 1 + FIRMWARE_FILENAME = 2 + BIN_FILENAME = 3 + DAT_FILENAME = 4 + INIT_PACKET_DATA = 5 + SD_SIZE = 6 + BL_SIZE = 7 diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/nrfhex.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/nrfhex.py new file mode 100644 index 0000000..67a5d5c --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/nrfhex.py @@ -0,0 +1,168 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from nordicsemi.dfu import intelhex +from struct import unpack + + +class nRFHex(intelhex.IntelHex): + """ + Converts and merges .hex and .bin files into one .bin file. + """ + + info_struct_address_base = 0x00003000 + info_struct_address_offset = 0x1000 + + info_struct_magic_number = 0x51B1E5DB + info_struct_magic_number_offset = 0x004 + + s1x0_mbr_end_address = 0x1000 + s132_mbr_end_address = 0x3000 + + def __init__(self, source, bootloader=None): + """ + Constructor that requires a firmware file path. + Softdevices can take an optional bootloader file path as parameter. + + :param str source: The file path for the firmware + :param str bootloader: Optional file path to bootloader firmware + :return: None + """ + super(nRFHex, self).__init__() + + self.file_format = 'hex' + + if source.endswith('.bin'): + self.file_format = 'bin' + + self.loadfile(source, self.file_format) + + self._removeuicr() + + self.bootloaderhex = None + + if bootloader is not None: + self.bootloaderhex = nRFHex(bootloader) + + def _removeuicr(self): + uicr_start_address = 0x10000000 + maxaddress = self.maxaddr() + if maxaddress >= uicr_start_address: + for i in range(uicr_start_address, maxaddress + 1): + self._buf.pop(i, 0) + + def address_has_magic_number(self, address): + try: + potential_magic_number = self.gets(address, 4) + potential_magic_number = unpack('I', potential_magic_number)[0] + return nRFHex.info_struct_magic_number == potential_magic_number + except Exception: + return False + + def get_softdevice_variant(self): + potential_magic_number_address = nRFHex.info_struct_address_base + nRFHex.info_struct_magic_number_offset + + if self.address_has_magic_number(potential_magic_number_address): + return "s1x0" + + for i in xrange(4): + potential_magic_number_address += nRFHex.info_struct_address_offset + + if self.address_has_magic_number(potential_magic_number_address): + return "s132" + + return "unknown" + + def get_mbr_end_address(self): + softdevice_variant = self.get_softdevice_variant() + + if softdevice_variant == "s132": + return nRFHex.s132_mbr_end_address + else: + return nRFHex.s1x0_mbr_end_address + + def minaddr(self): + min_address = super(nRFHex, self).minaddr() + + # Lower addresses are reserved for master boot record + if self.file_format != 'bin': + min_address = max(self.get_mbr_end_address(), min_address) + + return min_address + + def size(self): + """ + Returns the size of the source. + :return: int + """ + min_address = self.minaddr() + max_address = self.maxaddr() + + size = max_address - min_address + 1 + + # Round up to nearest word + word_size = 4 + number_of_words = (size + (word_size - 1)) / word_size + size = number_of_words * word_size + + return size + + def bootloadersize(self): + """ + Returns the size of the bootloader. + :return: int + """ + if self.bootloaderhex is None: + return 0 + + return self.bootloaderhex.size() + + def tobinfile(self, fobj, start=None, end=None, pad=None, size=None): + """ + Writes a binary version of source and bootloader respectivly to fobj which could be a + file object or a file path. + + :param str fobj: File path or object the function writes to + :return: None + """ + # If there is a bootloader this will make the recursion call use the samme file object. + if getattr(fobj, "write", None) is None: + fobj = open(fobj, "wb") + close_fd = True + else: + close_fd = False + + start_address = self.minaddr() + size = self.size() + super(nRFHex, self).tobinfile(fobj, start=start_address, size=size) + + if self.bootloaderhex is not None: + self.bootloaderhex.tobinfile(fobj) + + if close_fd: + fobj.close() diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/package.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/package.py new file mode 100644 index 0000000..68c1d80 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/package.py @@ -0,0 +1,369 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Python standard library +import os +import tempfile +import shutil + +# 3rd party libraries +from zipfile import ZipFile +import hashlib + + +# Nordic libraries +from nordicsemi.exceptions import NordicSemiException +from nordicsemi.dfu.nrfhex import * +from nordicsemi.dfu.init_packet import * +from nordicsemi.dfu.manifest import ManifestGenerator, Manifest +from nordicsemi.dfu.model import HexType, FirmwareKeys +from nordicsemi.dfu.crc16 import * + +from signing import Signing + + +class Package(object): + """ + Packages and unpacks Nordic DFU packages. Nordic DFU packages are zip files that contains firmware and meta-information + necessary for utilities to perform a DFU on nRF5X devices. + + The internal data model used in Package is a dictionary. The dictionary is expressed like this in + json format: + + { + "manifest": { + "bootloader": { + "bin_file": "asdf.bin", + "dat_file": "asdf.dat", + "init_packet_data": { + "application_version": null, + "device_revision": null, + "device_type": 5, + "firmware_hash": "asdfasdkfjhasdkfjashfkjasfhaskjfhkjsdfhasjkhf", + "softdevice_req": [ + 17, + 18 + ] + } + } + } + + Attributes application, bootloader, softdevice, softdevice_bootloader shall not be put into the manifest if they are null + + """ + + DEFAULT_DEV_TYPE = 0xFFFF + DEFAULT_DEV_REV = 0xFFFF + DEFAULT_APP_VERSION = 0xFFFFFFFF + DEFAULT_SD_REQ = [0xFFFE] + DEFAULT_DFU_VER = 0.5 + MANIFEST_FILENAME = "manifest.json" + + def __init__(self, + dev_type=DEFAULT_DEV_TYPE, + dev_rev=DEFAULT_DEV_REV, + app_version=DEFAULT_APP_VERSION, + sd_req=DEFAULT_SD_REQ, + app_fw=None, + bootloader_fw=None, + softdevice_fw=None, + dfu_ver=DEFAULT_DFU_VER, + key_file=None): + """ + Constructor that requires values used for generating a Nordic DFU package. + + :param int dev_type: Device type init-packet field + :param int dev_rev: Device revision init-packet field + :param int app_version: App version init-packet field + :param list sd_req: Softdevice Requirement init-packet field + :param str app_fw: Path to application firmware file + :param str bootloader_fw: Path to bootloader firmware file + :param str softdevice_fw: Path to softdevice firmware file + :param float dfu_ver: DFU version to use when generating init-packet + :param str key_file: Path to Signing key file (PEM) + :return: None + """ + self.dfu_ver = dfu_ver + + init_packet_vars = {} + + if dev_type is not None: + init_packet_vars[PacketField.DEVICE_TYPE] = dev_type + + if dev_rev is not None: + init_packet_vars[PacketField.DEVICE_REVISION] = dev_rev + + if app_version is not None: + init_packet_vars[PacketField.APP_VERSION] = app_version + + if sd_req is not None: + init_packet_vars[PacketField.REQUIRED_SOFTDEVICES_ARRAY] = sd_req + + self.firmwares_data = {} + + if app_fw: + self.__add_firmware_info(HexType.APPLICATION, + app_fw, + init_packet_vars) + + if bootloader_fw: + self.__add_firmware_info(HexType.BOOTLOADER, + bootloader_fw, + init_packet_vars) + + if softdevice_fw: + self.__add_firmware_info(HexType.SOFTDEVICE, + softdevice_fw, + init_packet_vars) + + if key_file: + self.dfu_ver = 0.8 + self.key_file = key_file + + def generate_package(self, filename, preserve_work_directory=False): + """ + Generates a Nordic DFU package. The package is a zip file containing firmware(s) and metadata required + for Nordic DFU applications to perform DFU onn nRF5X devices. + + :param str filename: Filename for generated package. + :param bool preserve_work_directory: True to preserve the temporary working directory. + Useful for debugging of a package, and if the user wants to look at the generated package without having to + unzip it. + :return: None + """ + work_directory = self.__create_temp_workspace() + + if Package._is_bootloader_softdevice_combination(self.firmwares_data): + # Removing softdevice and bootloader data from dictionary and adding the combined later + softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) + bootloader_fw_data = self.firmwares_data.pop(HexType.BOOTLOADER) + + softdevice_fw_name = softdevice_fw_data[FirmwareKeys.FIRMWARE_FILENAME] + bootloader_fw_name = bootloader_fw_data[FirmwareKeys.FIRMWARE_FILENAME] + + new_filename = "sd_bl.bin" + sd_bl_file_path = os.path.join(work_directory, new_filename) + + nrf_hex = nRFHex(softdevice_fw_name, bootloader_fw_name) + nrf_hex.tobinfile(sd_bl_file_path) + + softdevice_size = nrf_hex.size() + bootloader_size = nrf_hex.bootloadersize() + + self.__add_firmware_info(HexType.SD_BL, + sd_bl_file_path, + softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], + softdevice_size, + bootloader_size) + + for key in self.firmwares_data: + firmware = self.firmwares_data[key] + + # Normalize the firmware file and store it in the work directory + firmware[FirmwareKeys.BIN_FILENAME] = \ + Package.normalize_firmware_to_bin(work_directory, firmware[FirmwareKeys.FIRMWARE_FILENAME]) + + # Calculate the hash for the .bin file located in the work directory + bin_file_path = os.path.join(work_directory, firmware[FirmwareKeys.BIN_FILENAME]) + + init_packet_data = firmware[FirmwareKeys.INIT_PACKET_DATA] + + if self.dfu_ver <= 0.5: + firmware_hash = Package.calculate_crc16(bin_file_path) + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash + elif self.dfu_ver == 0.6: + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_CRC16 + firmware_hash = Package.calculate_crc16(bin_file_path) + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash + elif self.dfu_ver == 0.7: + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_HASH + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int(Package.calculate_file_size(bin_file_path)) + firmware_hash = Package.calculate_sha256_hash(bin_file_path) + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash + elif self.dfu_ver == 0.8: + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_EXT_USES_ECDS + firmware_hash = Package.calculate_sha256_hash(bin_file_path) + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int(Package.calculate_file_size(bin_file_path)) + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash + temp_packet = self._create_init_packet(firmware) + signer = Signing() + signer.load_key(self.key_file) + signature = signer.sign(temp_packet) + init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS] = signature + + # Store the .dat file in the work directory + init_packet = self._create_init_packet(firmware) + init_packet_filename = firmware[FirmwareKeys.BIN_FILENAME].replace(".bin", ".dat") + + with open(os.path.join(work_directory, init_packet_filename), 'wb') as init_packet_file: + init_packet_file.write(init_packet) + + firmware[FirmwareKeys.DAT_FILENAME] = \ + init_packet_filename + + # Store the manifest to manifest.json + manifest = self.create_manifest() + + with open(os.path.join(work_directory, Package.MANIFEST_FILENAME), "w") as manifest_file: + manifest_file.write(manifest) + + # Package the work_directory to a zip file + Package.create_zip_package(work_directory, filename) + + # Delete the temporary directory + if not preserve_work_directory: + shutil.rmtree(work_directory) + + @staticmethod + def __create_temp_workspace(): + return tempfile.mkdtemp(prefix="nrf_dfu_") + + @staticmethod + def create_zip_package(work_directory, filename): + files = os.listdir(work_directory) + + with ZipFile(filename, 'w') as package: + for _file in files: + file_path = os.path.join(work_directory, _file) + package.write(file_path, _file) + + @staticmethod + def calculate_file_size(firmware_filename): + b = os.path.getsize(firmware_filename) + return b + + @staticmethod + def calculate_sha256_hash(firmware_filename): + read_buffer = 4096 + + digest = hashlib.sha256() + + with open(firmware_filename, 'rb') as firmware_file: + while True: + data = firmware_file.read(read_buffer) + + if data: + digest.update(data) + else: + break + + return digest.digest() + + @staticmethod + def calculate_crc16(firmware_filename): + """ + Calculates CRC16 has on provided firmware filename + + :type str firmware_filename: + """ + data_buffer = b'' + read_size = 4096 + + with open(firmware_filename, 'rb') as firmware_file: + while True: + data = firmware_file.read(read_size) + + if data: + data_buffer += data + else: + break + + return calc_crc16(data_buffer, 0xffff) + + def create_manifest(self): + manifest = ManifestGenerator(self.dfu_ver, self.firmwares_data) + return manifest.generate_manifest() + + @staticmethod + def _is_bootloader_softdevice_combination(firmwares): + return (HexType.BOOTLOADER in firmwares) and (HexType.SOFTDEVICE in firmwares) + + def __add_firmware_info(self, firmware_type, filename, init_packet_data, sd_size=None, bl_size=None): + self.firmwares_data[firmware_type] = { + FirmwareKeys.FIRMWARE_FILENAME: filename, + FirmwareKeys.INIT_PACKET_DATA: init_packet_data.copy(), + # Copying init packet to avoid using the same for all firmware + } + + if firmware_type == HexType.SD_BL: + self.firmwares_data[firmware_type][FirmwareKeys.SD_SIZE] = sd_size + self.firmwares_data[firmware_type][FirmwareKeys.BL_SIZE] = bl_size + + @staticmethod + def _create_init_packet(firmware_data): + p = Packet(firmware_data[FirmwareKeys.INIT_PACKET_DATA]) + return p.generate_packet() + + @staticmethod + def normalize_firmware_to_bin(work_directory, firmware_path): + firmware_filename = os.path.basename(firmware_path) + new_filename = firmware_filename.replace(".hex", ".bin") + new_filepath = os.path.join(work_directory, new_filename) + + if not os.path.exists(new_filepath): + temp = nRFHex(firmware_path) + temp.tobinfile(new_filepath) + + return new_filepath + + @staticmethod + def unpack_package(package_path, target_dir): + """ + Unpacks a Nordic DFU package. + + :param str package_path: Path to the package + :param str target_dir: Target directory to unpack the package to + :return: Manifest Manifest: Returns a manifest back to the user. The manifest is a parse datamodel + of the manifest found in the Nordic DFU package. + """ + + if not os.path.isfile(package_path): + raise NordicSemiException("Package {0} not found.".format(package_path)) + + target_dir = os.path.abspath(target_dir) + target_base_path = os.path.dirname(target_dir) + + if not os.path.exists(target_base_path): + raise NordicSemiException("Base path to target directory {0} does not exist.".format(target_base_path)) + + if not os.path.isdir(target_base_path): + raise NordicSemiException("Base path to target directory {0} is not a directory.".format(target_base_path)) + + if os.path.exists(target_dir): + raise NordicSemiException( + "Target directory {0} exists, not able to unpack to that directory.", + target_dir) + + with ZipFile(package_path, 'r') as pkg: + pkg.extractall(target_dir) + + with open(os.path.join(target_dir, Package.MANIFEST_FILENAME), 'r') as f: + _json = f.read() + """:type :str """ + + return Manifest.from_json(_json) diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py new file mode 100644 index 0000000..ca98eb1 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py @@ -0,0 +1,149 @@ +# Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. +# +# The information contained herein is property of Nordic Semiconductor ASA. +# Terms and conditions of usage are described in detail in NORDIC +# SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. +# +# Licensees are granted free, non-transferable use of the information. NO +# WARRANTY of ANY KIND is provided. This heading must NOT be removed from +# the file. + +import hashlib +import binascii + +try: + from ecdsa import SigningKey + from ecdsa.curves import NIST256p + from ecdsa.keys import sigencode_string +except Exception: + print "Failed to import ecdsa, cannot do signing" + +from nordicsemi.exceptions import InvalidArgumentException, IllegalStateException + + +class Signing(object): + """ + Class for singing of hex-files + """ + def gen_key(self, filename): + """ + Generate a new Signing key using NIST P-256 curve + """ + self.sk = SigningKey.generate(curve=NIST256p) + + with open(filename, "w") as sk_file: + sk_file.write(self.sk.to_pem()) + + def load_key(self, filename): + """ + Load signing key (from pem file) + """ + with open(filename, "r") as sk_file: + sk_pem = sk_file.read() + + self.sk = SigningKey.from_pem(sk_pem) + + sk_hex = "".join(c.encode('hex') for c in self.sk.to_string()) + + def sign(self, init_packet_data): + """ + Create signature for init package using P-256 curve and SHA-256 as hashing algorithm + Returns R and S keys combined in a 64 byte array + """ + # Add assertion of init_packet + if self.sk is None: + raise IllegalStateException("Can't save key. No key created/loaded") + + # Sign the init-packet + signature = self.sk.sign(init_packet_data, hashfunc=hashlib.sha256, sigencode=sigencode_string) + return signature + + def verify(self, init_packet, signature): + """ + Verify init packet + """ + # Add assertion of init_packet + if self.sk is None: + raise IllegalStateException("Can't save key. No key created/loaded") + + vk = self.sk.get_verifying_key() + + # Verify init packet + try: + vk.verify(signature, init_packet, hashfunc=hashlib.sha256) + except: + return False + + return True + + def get_vk(self, output_type): + """ + Get verification key (as hex, code or pem) + """ + if self.sk is None: + raise IllegalStateException("Can't get key. No key created/loaded") + + if output_type is None: + raise InvalidArgumentException("Invalid output type for signature.") + elif output_type == 'hex': + return self.get_vk_hex() + elif output_type == 'code': + return self.get_vk_code() + elif output_type == 'pem': + return self.get_vk_pem() + else: + raise InvalidArgumentException("Invalid argument. Can't get key") + + def get_vk_hex(self): + """ + Get the verification key as hex + """ + if self.sk is None: + raise IllegalStateException("Can't get key. No key created/loaded") + + vk = self.sk.get_verifying_key() + vk_hexlify = binascii.hexlify(vk.to_string()) + + vk_hex = "Verification key Qx: {0}\n".format(vk_hexlify[0:64]) + vk_hex += "Verification key Qy: {0}".format(vk_hexlify[64:128]) + + return vk_hex + + def get_vk_code(self): + """ + Get the verification key as code + """ + if self.sk is None: + raise IllegalStateException("Can't get key. No key created/loaded") + + vk = self.sk.get_verifying_key() + vk_hex = binascii.hexlify(vk.to_string()) + + vk_x_separated = "" + vk_x_str = vk_hex[0:64] + for i in xrange(0, len(vk_x_str), 2): + vk_x_separated += "0x" + vk_x_str[i:i+2] + ", " + vk_x_separated = vk_x_separated[:-2] + + vk_y_separated = "" + vk_y_str = vk_hex[64:128] + for i in xrange(0, len(vk_y_str), 2): + vk_y_separated += "0x" + vk_y_str[i:i+2] + ", " + vk_y_separated = vk_y_separated[:-2] + + vk_code = "static uint8_t Qx[] = {{ {0} }};\n".format(vk_x_separated) + vk_code += "static uint8_t Qy[] = {{ {0} }};".format(vk_y_separated) + + return vk_code + + def get_vk_pem(self): + """ + Get the verification key as PEM + """ + if self.sk is None: + raise IllegalStateException("Can't get key. No key created/loaded") + + vk = self.sk.get_verifying_key() + vk_pem = vk.to_pem() + + return vk_pem diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/__init__.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/__init__.py new file mode 100644 index 0000000..8f8006e --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/__init__.py @@ -0,0 +1,29 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Package marker file.""" diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar.hex b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar.hex new file mode 100644 index 0000000..d3bf4c9 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar.hex @@ -0,0 +1,828 @@ +:020000040003F7 +:10C800007834002065CA030077CA030079CA0300A0 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000007BCA0300C0 +:10C8300000000000000000007DCA03007FCA030062 +:10C8400081CA030081CA030081CA030081CA0300B0 +:10C8500081CA030000000000ADDF030081CA0300AD +:10C8600081CA030081CA030081CA030081CA030090 +:10C8700081CA030081CA030081CA030081CA030080 +:10C8800081CA0300E9D8030081CA030081CA0300FA +:10C89000FFD8030081CA0300D5E4030081CA030066 +:10C8A00081CA030081CA03000000000000000000EC +:10C8B0000000000000000000000000000000000078 +:10C8C00000F002F800F040F80CA030C80838241836 +:10C8D0002D18A246671EAB4654465D46AC4201D1B8 +:10C8E00000F032F87E460F3E0FCCB64601263342AA +:10C8F00000D0FB1AA246AB4633431847583100001C +:10C9000078310000103A02D378C878C1FAD85207BB +:10C9100001D330C830C101D504680C6070470000F5 +:10C920000023002400250026103A01D378C1FBD84B +:10C93000520700D330C100D50B6070471FB5C04609 +:10C94000C0461FBD10B510BD03F03EF81146FFF7FD +:10C95000F5FF00F0BEF803F056F803B4FFF7F2FF5E +:10C9600003BC03F05BF80000026882F308884368A8 +:10C9700018470000401E00BF00BF00BF00BF00BF3F +:10C9800000BF00BF00BF00BF00BF00BF00BFF1D1AC +:10C990007047000070B505460C46164602E00FCC05 +:10C9A0000FC5103E102EFAD2082E02D303CC03C5B9 +:10C9B000083E042E07D301CC01C5361F03E02178C1 +:10C9C0002970641C6D1C761EF9D270BD10B500F084 +:10C9D0001DF8002805D01F491D484860C8131E498E +:10C9E00088611E48018CC9B201290ED1818C0907CA +:10C9F0000BD1018D0906090F042906D1808D00068F +:10CA0000000F02D116490120886010BD1348018C27 +:10CA1000C9B2012917D1818C090714D1018D0906EA +:10CA20000A0F03D1828D1206120F0ED0090F0129B1 +:10CA300003D1828D1206120F07D0032903D1808DF6 +:10CA40000006000F01D00020704701207047000051 +:10CA5000DFFF07C000050040006C0040C00F00F081 +:10CA6000000600400A4802680F210A430260094894 +:10CA7000804709480047FEE7FEE7FEE7FEE7FEE7DE +:10CA8000FEE7000005480649064A074B70470000CC +:10CA900024050040CDC90300C1C803007828002048 +:10CAA00078340020782C0020782C0020964800292B +:10CAB000016005D1012095490004C86000F0D8F854 +:10CAC00070470A4601469248F0E710B501F0CEFDE6 +:10CAD00010BD1CB50020694608718E490120086010 +:10CAE0008C49103908608B49091F0860102000F03C +:10CAF000C7F80C2000F0C4F80F2000F0C1F8864DF4 +:10CB000028680524A403A04204D084A2F2210020B6 +:10CB1000FFF7CCFF79216869C902884204D07FA25F +:10CB2000F4210020FFF7C2FF012000070069012166 +:10CB30008902884204D079A2F5210020FFF7B6FFD0 +:10CB400079480090794B05220321002000F0FAFE7D +:10CB5000002803D071A2A421FFF7A8FF7349022087 +:10CB6000283901F089FA002803D06CA29921FFF737 +:10CB70009DFF65486E4B6F4A0121001D01F08DFB42 +:10CB8000002803D065A2B421FFF790FF6A4B502222 +:10CB90006A49082001F07AFC002803D05FA2D62160 +:10CBA000FFF784FF664801F08DFC002803D05BA2EC +:10CBB000D921FFF77BFF614A14215032082001F090 +:10CBC0001BF9002803D055A2E121FFF76FFF01F008 +:10CBD000A3FB002803D051A2FF21FFF767FF01A9A3 +:10CBE000082001F0B4FB002804D0FF214BA2033140 +:10CBF000FFF75CFF01F09BFB002804D0FF2147A258 +:10CC00000631FFF753FF68460079002804D120461B +:10CC100000F077FA00280FD101203C490003C860DA +:10CC200000F0EFFA002804D0FF213CA20E31FFF7FC +:10CC30003DFF0C2000F024F8204600F062FA0028A6 +:10CC40000BD0102000F01CF80C2000F019F80F2079 +:10CC500000F016F8204600F000FB102000F010F85D +:10CC60000C2000F00DF80F2000F00AF800F000F89A +:10CC7000BFF34F8F34493348C860BFF34F8FFEE78F +:10CC8000012181402148816070471CB501910090CD +:10CC90002E4A0821684601F0C3F81CBD1CB500905F +:10CCA000684601712A4A082101F0BAF81CBD10B586 +:10CCB0000021284A084601F0B3F810BD10B504461B +:10CCC000082905D0FF2124A214310020FFF7EEFE31 +:10CCD00021686068884710BD10B50446082904D053 +:10CCE00029A29B210020FFF7E1FE216820798847D7 +:10CCF00010BD10B5002904D02FA298210020FFF705 +:10CD0000D5FE01F085FB10BD042000200005005079 +:10CD1000EFBEADDE40070050001000102E2E5C6DFF +:10CD200061696E2E630000008BCC03003C21002063 +:10CD30009DCC030066060000AFCC03007C230020DE +:10CD4000CBCA03000400FA0500ED00E0BDCC0300EF +:10CD5000D9CC0300F3CC03002E2E5C2E2E5C2E2E9D +:10CD60005C2E2E5C2E2E5C496E636C7564655C6176 +:10CD700070705F636F6D6D6F6E5C6170705F746912 +:10CD80006D65722E680000002E2E5C2E2E5C2E2EFD +:10CD90005C2E2E5C2E2E5C496E636C7564655C6146 +:10CDA00070705F636F6D6D6F6E5C6170705F6275E8 +:10CDB00074746F6E2E6800002E2E5C2E2E5C2E2E4C +:10CDC0005C2E2E5C2E2E5C496E636C7564655C7304 +:10CDD000645F636F6D6D6F6E5C736F6674646576B0 +:10CDE0006963655F68616E646C65722E680000003F +:10CDF00010460A4610B5B2494C68042C03D1022AE9 +:10CE000001D1002806D0002803D0AEA24E21FFF7A2 +:10CE10004DFE10BD8A69002AFBD01946904710BD0F +:10CE200010B5A74B01201870032000F0A3F910BD26 +:10CE300010B5A34C2078002801D0082010BD6069EF +:10CE400000F056FE002803D09EA27121FFF72EFEAF +:10CE50000F2100224904606900F00DFE040003D098 +:10CE600098A27421FFF722FE204610BDF0B59B4921 +:10CE700087B09948924D08600024A1276C7029461C +:10CE8000BF026C802431954801F039FD00281CD187 +:10CE90000520294680032431486028460146496A16 +:10CEA000C1611C3051264760B60202A800F0FEF9AD +:10CEB0000498FE2802D13868401C0ED080483146C4 +:10CEC0001C3001F06DFD002802D06C6007B0F0BD91 +:10CED0000220019A009900F04DF97948804A00211A +:10CEE000143000F081FD002803D076A2A521FFF7C1 +:10CEF000DDFD0F2100224904686900F0BCFD002817 +:10CF000003D070A2A921FFF7D1FDEE6001202C61B2 +:10CF100068600020DAE76A498861704770B5684C3C +:10CF20000546E068854201D90C2070BDA80701D0F4 +:10CF3000062070BD6068012801D0082070BDFFF791 +:10CF400077FF0028FAD10221A560616070BD70B53D +:10CF5000050004D0287A800703D0102070BD0E2071 +:10CF600070BD574C6068022805D0032803D0042800 +:10CF700003D0082070BD042060606868A168860046 +:10CF800020698019884204D90020C04320610C2008 +:10CF900070BDFFF74DFF0028FAD14948A968324615 +:10CFA0001C30236901F0CCFC0028F1D121698919DA +:10CFB0002161A2689142EBD0092070BDF8B5404CC8 +:10CFC00005466068022802D0032805D101E003204D +:10CFD00060602069002801D00820F8BDFFF728FF15 +:10CFE0000028FAD13D4B0021403B08E0AA688E00A2 +:10CFF000965962789700521CDE516270491C6A682B +:10D000008A42F3D8F8BD70B52D4C6068042805D16C +:10D0100005206060A1682069884201D0082516E0DB +:10D02000FFF706FF050012D1A12000228002A168AF +:10D0300001F0CAF929496080403962780988002ADC +:10D0400003D0884201D00B2070BD062060602846C6 +:10D0500070BD3EB51A4C6068062802D008252846E7 +:10D060003EBD606900F044FD002804D0FF2115A2F8 +:10D070009631FFF71BFD1248A168243001F090FCA7 +:10D08000002804D0FF210FA29A31FFF70FFD0C48B2 +:10D0900000231C3041680830A26801F051FC0500F3 +:10D0A000DDD1009061886A469180A2680292019960 +:10D0B00000F060F8D3E710B5042000F05BF810BD75 +:10D0C000142000202E2E5C6466755F6475616C5FB1 +:10D0D00062616E6B2E630000F1CD03005C250020C1 +:10D0E00021CE030010B57B480368012B02D1022931 +:10D0F00000D10160100003D077A23421FFF7D6FCE5 +:10D1000010BD38B505250024AD03401B15D1684678 +:10D1100000F0F4F80098016801290ED181880029F7 +:10D1200008D0C1680022284601F04EF9009989888C +:10D13000814201D1012400E00024204638BD10B511 +:10D14000044664481021001D01F0B2FB002803D002 +:10D1500061A28521FFF7AAFC5E4800231022214628 +:10D16000001D01F027FB002803D05BA28B21FFF7F5 +:10D170009DFC10BD17B581B0684600F0BFF801995D +:10D180005948544C002913D003291CD0FE220129F0 +:10D1900023D002292CD0042909D101F0BAFD00289E +:10D1A00003D04DA2BE21FFF781FC042020601FBDEB +:10D1B0006946098981800399C1600121FF2282604B +:10D1C0000160216010E001F0A4FD002803D042A21C +:10D1D000A421FFF76BFC0320E8E7002181800260B7 +:10D1E000C1600099896881603F48FFF7A8FF1FBDB3 +:10D1F00000990B6803608B888380C9688260C16076 +:10D20000F2E73EB5394800901020019001200290CD +:10D2100001F051FA00281FD12E496846091D01F07E +:10D2200071FA002818D1FFF721FE002814D101F06F +:10D230005FFE0546274C3DDF002803D026A246218D +:10D24000FFF734FC00F062FE2068022803D00328B8 +:10D2500001D00428EFD128463EBD70B511DF00286B +:10D2600004D0FF211CA20A31FFF720FC2049002036 +:10D270000B681F4C012180340A4682401A4204D0B8 +:10D28000C506ED0E0A46AA402260401CC0B2202806 +:10D29000F2D313DF002804D0FF210FA20F31FFF7D4 +:10D2A00005FC0520800300F025F870BD1FB5094975 +:10D2B000044600231022091D684601F0BAFA0098BE +:10D2C000206068468088A0800398E0600298A06093 +:10D2D0001FBD0000402000202E2E5C626F6F746C1A +:10D2E0006F616465722E630068250020E5D003003D +:10D2F00000E100E010B5FFF737FB10BD0149016008 +:10D300007047000000FC030030B585B0002822D033 +:10D310000388F64CA34220D0F54B1B78002B1CD081 +:10D32000F34B10255B1C1D705970002401259A7069 +:10D33000032269460A820094019402940394C289EC +:10D340000A808D708C8004A902910393008869463D +:10D35000A6DF05B030BD0E20FBE70820F9E7F0B5E9 +:10D3600089B004460227684607730D468783608AA2 +:10D3700008AB07AA0021A5DF0026002804D0616AB7 +:10D38000002917D0884715E06846008CC007C00FF9 +:10D3900010D068460682208803A9A8DF002810D193 +:10D3A000A97E0B0002F041FB093A0F11191B1D1F4A +:10D3B00038223A00FF20FE3069460882208803A9FF +:10D3C000A8DF09B0F0BD009601E001200CE0226A60 +:10D3D0006946204690470020F3E70097F7E70320CF +:10D3E00002E0042000E005200090F0E7288B0328ED +:10D3F00005D2032208212046FFF786FFE1E7287FB8 +:10D40000E97E000208436946888003D00620009028 +:10D41000226ADEE70720FAE70920E5E70322EAE7C8 +:10D4200030B585B00D46040032D0002D30D02868CC +:10D4300000282DD00020C043AE4B20800FCB04939A +:10D4400001AB07C3AC4869460880891C01A862DFAC +:10D4500000281CD1A21C69460120A0DF002816D19B +:10D46000684680782071204600F0C0F800280ED170 +:10D47000204600F0F9F8002809D128682062686881 +:10D48000002800D060629A4901200870002060E7FF +:10D490000E205EE73EB5002820D000291ED0026A8B +:10D4A000002A1BD00A88102A19D0112A28D0502A05 +:10D4B00017D0512A12D10446891D087802280DD1AF +:10D4C0004888E289904209D1891C2046FFF747FF2E +:10D4D000002803D0616A002900D088473EBD8988B2 +:10D4E00010E0CA88C3889A42F8D1082200928A7F45 +:10D4F0006B461A7120310291026A694690473EBD1F +:10D500000021C94301803EBDF0B585B00A46050043 +:10D510002DD02888754988422BD07548007800287E +:10D5200027D0734C1020641C2070072060700127E6 +:10D53000A7700321684601820026E11C104600F016 +:10D540004CF801466846008A091868460182009630 +:10D55000019602960396E98901808770868004A867 +:10D560000394029028886946A6DF05B0F0BD0E201E +:10D57000FBE70820F9E7F0B585B00A46050028D09A +:10D5800028885A49884226D059480078002822D055 +:10D59000574C1120641C2070012768460782002622 +:10D5A000611C104600F019F801466846008A091807 +:10D5B000684601820096019602960396E9890180E9 +:10D5C0008770868004A80394029028886946A6DFA5 +:10D5D000CBE70E20C9E70820C7E70870020A4A70A7 +:10D5E000020C8A70000EC8700420704730B58FB0EE +:10D5F00005461C21684602F024F969460878042192 +:10D600000843694608700024019403940494059427 +:10D610000694287908A9887037486946801C0884D0 +:10D62000601C00070794000F0C77103048778A7F42 +:10D63000F9200240921CE7200240012002438A7731 +:10D64000142109A802F0FDF808A8099007A80A907B +:10D6500069468C851420CC8508860D946888AB1D9E +:10D6600009AAA2DF0FB030BD30B58FB005461C212E +:10D67000684602F0E6F86946087808210843102257 +:10D68000104369460870002401940394049405949F +:10D690000694287908A9887017486946401C0884B0 +:10D6A000601C00070794000F0C7710304877887FC4 +:10D6B000F9210840801CF72108401043012108434C +:10D6C00069468877142109A802F0BBF808A80990D8 +:10D6D00007A80A9069468C851720CC8508860D948A +:10D6E0002B4668880E3309AAA2DFBBE7FFFF0000C4 +:10D6F0004C20002044FA0300301500008307FF226D +:10D70000DB0E9A408907090E994000280BDA0007C2 +:10D71000000F08388308FC489B001B18D869904309 +:10D720000843D86170478308F8489B001B181868A5 +:10D730009043084318607047F0B5F54F28217C6886 +:10D7400041430D19F9684A1C09D028224A43161989 +:10D75000AB68B268934204D8D21AB2606962F860CA +:10D76000F0BD0A4602E00A46796A9B1B4E1C0BD0AC +:10D7700028264E433719BE689E42F4D328264E43CE +:10D780003619B768FF1AB760AB60696228214A434F +:10D7900011194862F0BDF8B5DD4CE568681C36D05B +:10D7A000DC48002640682169401A07023F0A1AE057 +:10D7B0002820454360682A189068B84215D86369E4 +:10D7C0003F1A8619556A002B0AD0116AD06998470A +:10D7D000002808D0FF21D0A25531FFF767F902E0F9 +:10D7E000D169106A8847681CE2D1A178E07881424B +:10D7F00006D1401CC0B2E070022801D10020E070C8 +:10D80000C3490006800D18310E5000F0D3F9F8BD61 +:10D81000F8B50446BE48C1680091467856E0BC4859 +:10D82000F10082688D184BE0601C07D0B84A2821AF +:10D8300052686143204689184C6A20E028781821F4 +:10D8400041436A68401CC0B252182870A9788842C7 +:10D8500001D100202870AE4B506828215B684143FD +:10D86000C9181368012B2DD10B7E002B2AD1936888 +:10D87000CB60D3680B6113694B6152690A62A44A99 +:10D88000CF681369BC46FA1A1202AF4F120ABA42A5 +:10D8900002D20B69D21809E062469A1A12020B6989 +:10D8A000120A934201D99A1A00E000228A600022EB +:10D8B000CA600A6101220A76921E4A62FFF73CFFA3 +:10D8C000601CB1D1287869788842ADD13046761E87 +:10D8D000F6B20028A3D18E48C1680098814201D0D9 +:10D8E0000120F8BD0020F8BD98490020086048607C +:10D8F0008860C86095494039086048604BE7F0B5DA +:10D90000002087B0C043029081480669C568684618 +:10D9100000F056F9074600F070F90446002F05D0D4 +:10D9200002AA3146009800F0B0F901240298FFF7EE +:10D930006FFF002801D1002C02D0284600F0CEF95C +:10D9400007B0F0BDFFB59807002481B00F4615461B +:10D950001E4600280BD1002E09D000F01AF96C49A0 +:10D960000A9848610F70324600204E6008E0072098 +:10D9700005B0F0BD28234343D4509B181C76401CAF +:10D98000B842F7DB28204743BB19032048700F46F5 +:10D9900018468B6019461830002218232E465E4325 +:10D9A000D3005B181C705C709D7058603018521C5E +:10D9B000032AF5DB0020C043F860BC70FC70012432 +:10D9C00063482405046003211420FFF797FE614893 +:10D9D0000460504C0198A06003211120FFF78EFED7 +:10D9E000606838610020C3E770B5494C6568002D58 +:10D9F00006D0002A06D0002804D00023247809E0AD +:10DA0000082070BD072070BD28265E43AE59002E49 +:10DA100004D05B1CA342F7DB042070BD2824012640 +:10DA20005C432E516419E26161600360002070BDA7 +:10DA300035494868C005C00D17D0103807D5020712 +:10DA4000120F083A920892005118C96904E081083F +:10DA50002E4A8900891809688007C00EC1408804D1 +:10DA6000000E012803D0032803D0022070470020B5 +:10DA7000704701207047FEB50446254817464268A6 +:10DA80000D46002A0CD001788C4201D2052D01D21E +:10DA90000720FEBD2146282359435358012B01D0AE +:10DAA0000820FEBD8818406801281DD00026FFF719 +:10DAB000BFFFC0001649019089684018694600F010 +:10DAC00050F9002812D001214460016011494968D1 +:10DAD0000830E2C00E4901988968411800984870E2 +:10DAE00000F068F80020FEBD2E46E0E70420FEBDF1 +:10DAF000F8B5074D04466868002832D029788C4272 +:10DB00002AD30720F8BD000000ED00E000E400E0AB +:10DB100054200020001501402E2E5C2E2E5C2E2E4F +:10DB20005C2E2E5C2E2E5C536F757263655C61708B +:10DB3000705F636F6D6D6F6E5C6170705F74696D47 +:10DB400065722E6300000000FFFF7F00401101405E +:10DB500080E200E000E100E0282161434058012814 +:10DB600001D00820CEE7FFF763FFC600A86869462A +:10DB7000301800F0F6F8002809D0022112C0A86879 +:10DB800031180098487000F015F80020BAE704201A +:10DB9000B8E710B50121924A48041060914A40103C +:10DBA0009060904A403A90608F4841602F20FEF785 +:10DBB000E1FE10BD01208A490005803108607047F0 +:10DBC00010B58A4900238A78CC78A24212D0521C20 +:10DBD000D2B28A70022A00D18B708A78834B92006D +:10DBE00018339A580260086910180002000A086188 +:10DBF000012010BD0360002010BDF8B57B48C1684E +:10DC00000091457833E07948E90080680E1834784F +:10DC10002AE0182060437168641C0818B178E4B2E7 +:10DC2000A14200D100240168022902D003291BD19E +:10DC300013E06E4A40682821526841438F18397EAC +:10DC4000002911D000F09FF8002038760CE028273A +:10DC50007843C0180276406A03E0644900224B68AA +:10DC6000C868471CF3D1C8607078A042D1D128465B +:10DC70006D1EEDB20028C6D15C48C1680098814293 +:10DC800001D001203EE700203CE7F7B5574C0025C6 +:10DC90006768E3681EE028215943C9198E688642E7 +:10DCA00002D9301A886017E0801B751900268E6033 +:10DCB0000E764E699C464B6AB646002E0AD0019EEF +:10DCC00076193602360ACE6076460E6116684E62C6 +:10DCD00061461160591CDED1E360FEBDF8B54349D1 +:10DCE000CA68531C3AD028235A434B68D218966806 +:10DCF0003F4A54680F69401CE11B0D022D0AED1CC0 +:10DD00000121002810D1374A08045060354A403AB2 +:10DD10005060384A40001060314A803A1060324802 +:10DD200001602F20FEF726FEB54200D23546E819E5 +:10DD300000022F49000A403108602D494968001B44 +:10DD4000091B0902090A0002C91C000A814204D900 +:10DD500001202349400480310860D3E6FFF719FF12 +:10DD6000D0E642788378521C934200D10022037897 +:10DD7000934201D1002070470A6041684078182220 +:10DD800050430818704770B5184DEA686B68144620 +:10DD9000114606E0814207D00A4628267143C91879 +:10DDA000496A4E1CF6D170BD002EFCD08A4204D1C7 +:10DDB00028204443E018406AE86028204143C818FE +:10DDC000282481686243406AD2185062421CEAD01B +:10DDD00028225043C01882685118816070BD00002D +:10DDE00080E100E040130140001001405420002079 +:10DDF0000015014080E200E030B5CB0008339DB251 +:10DE000093070024002B01D0072030BD564B9A60A9 +:10DE10005219DA605C701C7058809980002030BD07 +:10DE2000F7B5514C82B060880F4681426CD8002013 +:10DE3000694608704E494D4D4868C005C00D16D062 +:10DE4000103807D50207120F083A920892005118AD +:10DE5000C96904E08108474A890089180968800770 +:10DE6000C00EC1408804060E012E01D10AE004262E +:10DE700068462BDF02280BD0002803D03EA2592190 +:10DE8000FEF714FE6078A188884203D2401C02E0AD +:10DE900072B6F7E700202278C0B2904207D06578CA +:10DEA0006078884201DA401C00E000206070012E9A +:10DEB0000BD062B6684600782CDF022805D0002817 +:10DEC00003D02DA26121FEF7F1FD2848854219D02B +:10DED000A068EE0004998151029900290CD0002F0E +:10DEE0000AD060883A464543E068281801F04AFCA9 +:10DEF000A0683018878002E000213018818000205F +:10DF000005B0F0BD0420FBE70920F9E70EB504E0F9 +:10DF100068468188029A0098904702AA01A968463B +:10DF200000F003F80028F3D00EBD70B50E4B0524A9 +:10DF30005D781E78B54215D01D781C789E88B44255 +:10DF400001DA641C00E000241C705C88DE686C430D +:10DF5000A41904609B68E800C418A4880C801858B1 +:10DF600000241060204670BD74200020FFFF0000D8 +:10DF700000ED00E000E400E02E2E5C2E2E5C2E2E44 +:10DF80005C2E2E5C2E2E5C536F757263655C617027 +:10DF9000705F636F6D6D6F6E5C6170705F736368EF +:10DFA0006564756C65722E6300000000F8B59048DA +:10DFB000006900908F490020C863032504462D04A2 +:10DFC00037E01421426861438B1801228068A24027 +:10DFD00002422CD0D868C2430098424018680240E0 +:10DFE000002001268640114631420FD0DF683946B5 +:10DFF000314223D02946B743DF607F4E8700BE19E8 +:10E000003768AF43376037680F433760401C2028BC +:10E01000E7D300989968164686433140009E5868B9 +:10E020001640304002460A4301D01A699047641CEA +:10E03000E4B2724841788C42C3D3F8BD012149044F +:10E040003743D9E7F0B56D4A002153681422504395 +:10E050000124694D03273F041E5822468A40164278 +:10E0600006D08A0052191668BE43166016681660FC +:10E07000491C2029F0D3F0BD10B5002903D08A0730 +:10E080000024002A01D0072010BD5C4A0B465160D5 +:10E0900010701421547041431846946001F0D1FB74 +:10E0A00000205749C0438860564840210160564AC5 +:10E0B0001068FF231B0498430B0418431060534857 +:10E0C0000160002010BDF8B54C4F84467D68002DDE +:10E0D00007D0002B07D078783C78A04205D30420E5 +:10E0E000F8BD0820F8BD0720F8BD0E4614241643DD +:10E0F00044432E5164192361A26061606146087037 +:10E10000411C7970FFF79EFF0020F8BDF0B53B4A37 +:10E110005168002904D05378984203D30720F0BDFA +:10E120000820F0BD334B0025DD63314B1C69976837 +:10E13000002F02D1324EDB057360012686403E433C +:10E140009660142250434218D560002201230D58D6 +:10E1500093401D4216D025461D4202D003252D04B2 +:10E1600005E001256D044618F7681F43F760224B50 +:10E170009600F3181E6803273F04BE431E601E6806 +:10E180002E431E60521C202AE0D30020F0BD70B543 +:10E190001A4C05466068002804D06078854203D395 +:10E1A000072070BD082070BD2846FFF74BFF0121F6 +:10E1B000A068A9408843A06003D101201049C0078E +:10E1C0008860002070BD0D4B5A68002A04D05B782F +:10E1D000984203D307207047082070471423584300 +:10E1E0008018034A12690068024000200A607047E4 +:10E1F00000050050406100400007005084200020CE +:10E200000063004080E200E004E400E000E100E0A0 +:10E21000F8B55D4C054669466078FFF7D4FF0028E5 +:10E220002AD10099E0680B460140A0682E46984329 +:10E230000843064020D000251BE00C20616868439D +:10E240004118087801228240324210D08A68002AA0 +:10E250000DD06369002B09D001461046984700286D +:10E2600005D04AA22921FEF721FC00E090476D1C51 +:10E27000EDB220788542E0D3F8BD70B5424D04463A +:10E280000E46A869FFF734FC002805D13443224626 +:10E290002969A869FFF7EFFB70BDF8B50C46052AA0 +:10E2A00001D20720F8BD384D002168602C70E9606C +:10E2B0006B612A61A9600A4617E00C2363431B18AF +:10E2C0001D785E683D4FB600AD00ED192E605E789A +:10E2D000002E01D0012500E000251F78BD40294314 +:10E2E000002E17D00023BB401A432346641EE4B21D +:10E2F000002BE2D12448324B8260C160401CFFF702 +:10E30000E2FE0028CED120482E4A00211830FFF727 +:10E310006BFBF8BD0123E6E710B51B4841680029F7 +:10E3200003D04078FFF7F2FE10BD082010BD10B5F5 +:10E33000154C6068002808D06078FFF728FF002897 +:10E3400002D1A069FFF7D4FB10BD082010BDF8B5BD +:10E350000D4C064660680D46002811D0694660786D +:10E36000FFF731FF00280AD101220098B240024293 +:10E3700008D0E068104000D0012028700020F8BDCF +:10E380000820F8BDA068F5E7902000202E2E5C2E16 +:10E390002E5C2E2E5C2E2E5C2E2E5C536F757263BF +:10E3A000655C6170705F636F6D6D6F6E5C617070E6 +:10E3B0005F627574746F6E2E63000000000700507A +:10E3C0007BE2030011E2030010B50446002A02D0EC +:10E3D0001088002210E00A48FBE7030A000203430A +:10E3E000A05C584003061B0F43401803584083B2FB +:10E3F0001806C00C5840521C8A42EED310BD0000D3 +:10E40000FFFF000010B508461146FEF75AFB10BD8D +:10E41000F8B5394C2078002837D02069002807D07B +:10E420000025E068002805D00026002D04D013E068 +:10E430000125F6E70126F8E768464EDF052806D0F5 +:10E44000002806D02DA26921FEF730FB04E001254B +:10E4500002E0216900988847002E12D16088694641 +:10E460000880A06860DF052806D0002806D023A217 +:10E470008021FEF71BFB04E0012602E0E168A068B2 +:10E480008847002DD8D0002ECFD0F8BD70B5002918 +:10E4900001D08C0701D0072070BD174C0125A16069 +:10E4A00062802449636010DF0028F5D125701620B2 +:10E4B00023DF70BD002803D00F49C86000207047DB +:10E4C0000E207047002803D00B49086100207047D8 +:10E4D0000E20704710B508484068002808D08047D3 +:10E4E000002804D0FF2105A23331FEF7DFFA10BD6A +:10E4F000FFF78EFF10BD0000AC2000202E2E5C2EFA +:10E500002E5C2E2E5C2E2E5C2E2E5C536F7572634D +:10E51000655C73645F636F6D6D6F6E5C736F667463 +:10E520006465766963655F68616E646C65722E63AD +:10E530000000000005E4030018225043F94A0021BE +:10E540008018017181604161012281610261C160B5 +:10E55000704770B5F34E18223078F34C504382194F +:10E56000121D13780F211069E568042B02D0022BCD +:10E570000DD024E001210907096989B201F074F97D +:10E58000401950DF01001AD1E068401C14E05169C5 +:10E590009368526840194919521B01251818AD0299 +:10E5A000AA4202D2920851DF02E0FF22013251DF7B +:10E5B000010004D1E0684019E0600120B070084615 +:10E5C00070BDF8B5D74C0546A77826460420767866 +:10E5D000002F01D1002E17D00A2E28D020788019C4 +:10E5E000C0B20A2801D30A38C0B2182670430019F5 +:10E5F0000571826106C98360426101610699C1604B +:10E600006078401C607011E0002020702571A261CC +:10E6100003C9A360616120610698E0600120607019 +:10E62000FFF797FF002801D0112800D10020F8BD86 +:10E6300038B50246BB4818230178594308180369C6 +:10E640000179022B0CD014246343B64CF434E45803 +:10E65000042909D08368009383691030A04738BD2E +:10E66000B14B10331C68F3E70023F4E710B5AD4954 +:10E6700002468B780020012B1CD100238B70022ACC +:10E6800003D0032A16D10D2012E00A7818235A432A +:10E690005118091D0A78042A04D1A34A4968D2688E +:10E6A000914201D8FFF7C4FF00F0A8F9002801D07B +:10E6B000FFF7BEFF10BD70B500249B4D9948EC607C +:10E6C00004704470847026463046FFF735FF761C90 +:10E6D0000A2EF9D3012109076C6048690969401EB7 +:10E6E00089B24843EC60A8608E48F43004608460CE +:10E6F0000461C4608C48103004608480012028705C +:10E70000002070BDF0B5884D2A78002A1DD0002861 +:10E710001DD000291BD00268002A18D0012424072C +:10E72000426823699BB29A420DD8102A0BD38368A2 +:10E73000002B08D05343AA6866699B182769BFB2AB +:10E740007E43B34205D90720F0BD0820F0BD0E205E +:10E75000F0BD6B68012B1CD00B604A601946142574 +:10E760006943704DF4354E19726007686F50416807 +:10E77000B1608168F16041688068002541436D1C8B +:10E780002069ADB280B2884205D2206980B2091AF0 +:10E7900002E00420F0BD0021206980B282182069C7 +:10E7A00080B28842EBD960485B1C8260356143606F +:10E7B0000020F0BDF8B505465B481F4600781446BA +:10E7C0000E46002807D0002E07D0002D05D028685F +:10E7D000002818D103E00820F8BD0E20F8BD5148EC +:10E7E000F430016800290ED0C268816840684A434D +:10E7F00010186A68904206D9002C04D0A14202D3B6 +:10E80000E019884201D90720F8BD304600F0F0F841 +:10E8100000280CD0F01900F0EBF8002807D02346B0 +:10E820003246294602200097FFF7CBFEF8BD1020A4 +:10E83000F8BDF8B507463C481D46007816460C461C +:10E84000002807D0002C07D0002F05D02068002812 +:10E8500018D103E00820F8BD0E20F8BD3148F4308F +:10E86000016800290ED0C268816840684A431018C8 +:10E870006268904206D9002E04D0B14202D37019CA +:10E88000884201D90720F8BD384600F0B1F80028C9 +:10E890000CD0781900F0ACF8002807D06068324638 +:10E8A0004119384600F06EFF0020F8BD1020F8BD79 +:10E8B00038B51D490978002905D0002805D0016820 +:10E8C000002912D103E0082038BD0E2038BD154ABA +:10E8D0000021F4321368002B07D09468D368634397 +:10E8E00054681B194468A34201D8072038BD136936 +:10E8F0000091014600220420FFF763FE38BD0A4A5A +:10E900001278002A12D0002812D0002910D00268F4 +:10E91000002A0DD0044A10321368002B0AD00420BC +:10E920007047000078250020C02000200820F7E76D +:10E930000E20F5E702230B60006810600020EFE76F +:10E94000F8B505463F481E46007817460C46002895 +:10E9500007D0002C07D0002D05D0286802281BD135 +:10E9600003E00820F8BD0E20F8BD364810300068DE +:10E97000002811D0084600F03BF800280ED0A0195E +:10E9800000F036F8002809D03B46224629460220EE +:10E990000096FFF716FEF8BD0720F8BD1020F8BD61 +:10E9A00038B5044627480A460078002805D0002CD0 +:10E9B00005D02068022819D103E0082038BD0E20B8 +:10E9C00038BD20481030006800280FD00120000713 +:10E9D000006981B2501E00F047FF0021431C0A4627 +:10E9E000009121460420FFF7ECFD38BD072038BD1B +:10E9F000800701D0002093E7012091E770B5124D08 +:10EA0000182128780F4C414349198968E2689142DE +:10EA100009D8FFF791FD0020E0606878401E68701B +:10EA20002878401C287068780024002807D0FFF759 +:10EA300090FD040003D0112C01D0FFF7F9FD204612 +:10EA400070BD0000C0200020782500204B48002128 +:10EA500001704C484A4A02608160C160016108222D +:10EA60004161426081610846704710B500291DD0A0 +:10EA700000220A60434A5368002B1BD0202817D875 +:10EA80005B1E5360D0682423401CD060106914685A +:10EA90004343E3180B60012383409169401C1943F1 +:10EAA0004007400F91611061002010BD0E2010BD85 +:10EAB0000C2010BD042010BDF0B5324A0646916806 +:10EAC00000292BD057691020791A4907490F14687B +:10EAD0000B4624254D436519B54206D1012495699D +:10EAE0008C4065400020956104E0491C4907490FAE +:10EAF0008F42EED1491C4E07760F956901210C46D5 +:10EB00009C402B4623420AD19368002B07D05B1E02 +:10EB1000936053685B1C53603346F0E70420F0BDFC +:10EB2000184A2423117C1268491E4907490F59438A +:10EB3000203150500020704770B500281AD00029AD +:10EB400018D0104AD368002B16D05B1ED360936890 +:10EB500024265B1C9360536915681C467343EE18AA +:10EB600020330660E858641C08606007400F50615D +:10EB7000002070BD0E2070BD042070BDD820002084 +:10EB800080260020A027002010B500280BD0FC48CC +:10EB9000FC49808888420FD0132176DF00280BD0F3 +:10EBA000F9A2702106E00846FFF786FF002803D08F +:10EBB000F5A27621FDF77AFF10BD08280CD004DC01 +:10EBC000002807D006280FD108E00B280AD00C280F +:10EBD0000AD105E0012070470220704703207047EA +:10EBE00004207047042901D0062070470520704793 +:10EBF00010B50A46044603211046FFF7DEFF024621 +:10EC000003212046FEF780FB002803D0DEA2B821B6 +:10EC1000FDF74CFF10BDF0B5054608790E4685B0EE +:10EC200081070AD0032211462846FEF76DFB002813 +:10EC300021D0FF21D4A2253146E0D14900901031E6 +:10EC4000FFF713FF010013D1CD4CB168009A206982 +:10EC500000F098FD0098FFF763FF002801D00146FF +:10EC600006E0C74869461030FFF766FF010004D090 +:10EC70002846FFF7BDFF05B0F0BD00988008029060 +:10EC8000032001902069039001A8FEF760F90700B6 +:10EC90000CD0092F1BD02069FFF70EFF002803D0EE +:10ECA00001462846FFF7A4FF3946E1E73079E188BD +:10ECB00001224018E08003212846FEF725FB0028AA +:10ECC000D9D0FF21B0A25531FDF7F0FED3E730795E +:10ECD000E188401881B2E18060780028CBD060895B +:10ECE000401E0004000C6081C5D12846FEF743FC9D +:10ECF000002804D0FF21A4A26631FDF7D7FE2089A9 +:10ED00006081B8E710B5FF219FA2A131FDF7CEFECB +:10ED100010BD10B59A4C9B49A088884208D0132199 +:10ED200076DF002811D098A29D49FDF7BFFE0CE0C8 +:10ED3000A078002809D074DF002804D0984992A256 +:10ED4000FF39FDF7B3FE0020A07000F05CFA002848 +:10ED500004D093498CA20931FDF7A8FE002010BD14 +:10ED600070B50D6804460120854A2B0000F05DFE59 +:10ED70000A333032061624464B354F23FEF743F94B +:10ED80000421FFF71AFF024604212046FEF7BCFAD1 +:10ED9000002810D0FF217CA2D33140E0FFF7B9FF5B +:10EDA000002804D0FF2178A2D931FDF77FFEFEF7BD +:10EDB00050F9002809D170BDFFF7ABFF002804D03F +:10EDC000FF2171A2E531FDF771FEFEF774F970BD08 +:10EDD000022000E00320D06070BDD2682046012AE6 +:10EDE00006D0022A07D0032AF6D1FFF714FF70BD20 +:10EDF00000F0E8F870BD00F00EF970BD5070888822 +:10EE00001081508170BD00205070108170BDD1887C +:10EE10002046FEF779FB0028F8D05BA26149FDF798 +:10EE200045FE70BD10B5564CA07800280AD15E484A +:10EE300073DF002804D05B4953A21331FDF736FE7F +:10EE40000120A07010BD10B54D4C0188A388132976 +:10EE500025D007DC102917D0112914D120780028DB +:10EE600017D018E0522925D055290CD180790028D7 +:10EE700009D11321184676DF002804D0494942A25F +:10EE80005C31FDF713FE10BD8088A0800020A070CB +:10EE900010BDFFF7C7FF0020C043A08010BD384A57 +:10EEA0001846143200217FDF0028F7D03D4936A2F2 +:10EEB0005431E6E7002211461846A9DF0028EDD0BC +:10EEC0004D2131A2C900DCE710B5044600F0CCF9B1 +:10EED000354821461430FEF7DDFA2046FFF7B3FF30 +:10EEE00010BD10B5B72128A28900FDF7DFFD10BDC8 +:10EEF00010B5234888B00024C4602C48FFF7DAFA24 +:10EF000000283BD12A48FEF706F8FFF79FFD0028AE +:10EF100034D100F0B1F827480090274801902248EA +:10EF200069461430FEF77CFA002804D01C4916A26A +:10EF30003B39FDF7BBFD00F0C3F81C21684600F02B +:10EF400080FC1E4801900120800302900094032160 +:10EF500068460173C4810474194806900594684694 +:10EF600000F02DF9002804D0FF2107A2B831FDF7E9 +:10EF70009DFD00F0DAF8FFF755FF002008B010BD46 +:10EF8000E0200020FFFF00002E2E5C6466755F7499 +:10EF900072616E73706F72745F626C652E630000D5 +:10EFA0002A03000006020000BC270020C9EE03006F +:10EFB00089EB030061ED0300E3EE0300CD0C0000DC +:10EFC00005ED030070B505460879042809D0032231 +:10EFD00001212846FEF798F900281BD05B4ACC2176 +:10EFE00016E08C68204600F02EFCE1780002000A52 +:10EFF00009060843FDF792FF0121FFF7DEFD0246F7 +:10F0000001212846FEF780F9002803D04F4ADD2170 +:10F01000FDF74CFD70BDFEB50446012000908868E8 +:10F0200002900879002283070FD08007800F042206 +:10F03000121A0020034606E00E79029D3618B6002B +:10F04000401CAB51C0B29042F6D3087980188008BA +:10F0500001906846FDF7B2FF0221FFF7AEFD0246C0 +:10F0600002212046FEF750F9002804D0FF21374A3C +:10F070001031FDF71BFDFEBD0EB51120694608726B +:10F08000072233A102A87CDF002803D02F4A32498F +:10F09000FDF70CFD002000900922694601900A80CE +:10F0A0000C224A808880FF209130C88068467ADF31 +:10F0B000002804D05521254AC900FDF7F7FC0EBDF4 +:10F0C00010B592B00621684601712448017968465E +:10F0D0008170234901803C2102A800F0B2FB02208C +:10F0E00002900024684644730121018201A8059022 +:10F0F000684681830890214602A800F025FA00287E +:10F1000004D01549114A2831FDF7D0FC13481421C9 +:10F11000143800F096FB11481438047044600472EF +:10F1200028210182448212B029E70E491E2008805E +:10F13000887801221043E12210400C30DF22104079 +:10F1400088700720C87010200871704788EF03008E +:10F1500044667554617267009E020000D02700204B +:10F1600030150000F420002038B56749674A488808 +:10F1700090420FD04A78664C521CD2B24A70237B20 +:10F18000934208D3083175DF002803D0A169002914 +:10F1900000D0884738BD00254D70217C002907D05C +:10F1A0003B2176DF002803D0A169002900D08847E1 +:10F1B00061690029EED068460095884738BD70B572 +:10F1C000054601461C225248FDF7E4FB4E4C002642 +:10F1D00026702968002907D00822A01800F0D2FA6A +:10F1E000204608307ADF02E0474808307BDF0028FD +:10F1F00008D1401E608044486670464A0021001DC8 +:10F20000FEF7F2FB70BD10B53F484068FEF770FC9A +:10F2100010BDF8B53C48103000F069F800263A4DB2 +:10F220003B4C002806D06169002919D001200090CC +:10F23000684614E02878002804D0616900290FD0BE +:10F240000096F5E7687800280CD0A168002268686D +:10F25000FEF711FC002803D0A169002900D08847DF +:10F260002E70F8BD6168F1E7F8B5294C02880027D7 +:10F27000254DE689102A18D029464968112A21D03F +:10F28000122A2DD0502A0FD1801D0288B2420BD1F4 +:10F29000028B022A08D1C27E837E10021843C00767 +:10F2A000C00F13D0FFF7B5FFF8BD81886980014614 +:10F2B000154808220E31103000F064FA6F70002EED +:10F2C000F0D0F8BD0020C04368806F700846FEF79C +:10F2D0000FFC0028F5D0A1690029F2D08847F8BDBD +:10F2E000811D09480822103000F04CFADAE7418805 +:10F2F000054808300288914204D34088814201D8F1 +:10F300000120704700207047FC200020FFFF000014 +:10F31000F827002069F10300FFB583B007460020FD +:10F320000C9C8646267805463AE07868A900411884 +:10F330000A88684682804988C1800022694601A8FF +:10F3400064DF002810D1684601780598814226D1F3 +:10F350007046002801D0002200E00222207889189F +:10F3600041181F2902D90C2007B0F0BD71460029B1 +:10F3700008D1401CC0B2411C069B049A21701A544B +:10F3800001208646217806980A18694601A864DF9C +:10F390000028E9D1694620780978401820706D1C52 +:10F3A0003888A842C1DC7046002804D0207806992D +:10F3B000801B401E88550020D6E7F8B51546069CF0 +:10F3C0001E46074602220094FFF7A6FF002806D13A +:10F3D00033461022294638460094FFF79DFFF8BDBA +:10F3E000F7B582B00026054616700068144600285E +:10F3F00005D02846039900F0DFF806002DD1687982 +:10F4000000281BD02078039F001D1F2824D86846A1 +:10F4100079DF002821D121780322481C20707A54FA +:10F4200021781922481C20707A542078C119684626 +:10F43000008800F0BCF82178401820702989002944 +:10F4400023D001208446EA680398002A07D0227856 +:10F4500053189B1C1F2B04D90C2005B0F0BD0720AE +:10F46000FBE71346521C491C2270C15422786746A0 +:10F47000511C2170875423782A891818E96800F0F4 +:10F4800081F92078297A401820702869002815D041 +:10F490000021415622788C46D01C03991F28DBD8C6 +:10F4A000501C022320708B5422780A23501C207099 +:10F4B0008B5420786246431C23700A54A88A002883 +:10F4C00009D028460094062202211430039BFFF73E +:10F4D00074FF0600C1D1A88B002809D028460094EB +:10F4E000072203211C30039BFFF767FF0600B4D1FE +:10F4F000A88C002809D02846009415221421243015 +:10F50000039BFFF75AFF0600A7D1E86A002805D041 +:10F510002246039900F085F806009ED1286B00284A +:10F5200005D02246039900F0BBF8060095D138209B +:10F53000405D002806D022462846039900F0E2F8F4 +:10F5400006008AD1304688E770B50D4692B000219A +:10F550006A46117007241171002812D00189002910 +:10F5600005D0C168002902D00978490702D4204695 +:10F5700012B070BD02A9FFF733FF0028F8D102AE28 +:10F5800000E00026002D0BD028890028EFD101AA29 +:10F590000AA92846FFF724FF0028E9D10AAA00E0BB +:10F5A0000022684603790178304672DFE0E7087090 +:10F5B000000A487002207047F8B514780746A01C6E +:10F5C00015460E461F2803D83879801C1F2801D9FC +:10F5D0000C20F8BD1D20001B80B2694686460880BD +:10F5E0003019801C7DDF0028F3D13868022805D14E +:10F5F00068460088704501D8092107E0387908215C +:10F60000002801D0704501D968460088421C325557 +:10F61000641CE2B2B1542978801C081828700020BC +:10F62000F8BDF8B50D4611780646881D14461F280A +:10F6300001D90C20F8BD33880720062BFAD31927EF +:10F64000FF01BB4202D94E4A9342F3D17288062A87 +:10F65000F0D3BA4202D94A4FBA42EBD1484FBB422B +:10F6600003D0BA4201D09342E4D8481C052220704E +:10F670006A5420781222411C21702A5420784119A2 +:10F680003088FFF794FF21784018C0B220704119EC +:10F690007088FFF78CFF2178401820700020F8BD9B +:10F6A00070B5054600790E46801C1446C0B211782C +:10F6B000821C8A181F2A01D90C2070BD0A46491CD9 +:10F6C000401C2170B0542078FF22411C217032541C +:10F6D000207881192888FFF76AFF21784018C0B286 +:10F6E0002070AA88002A09D0A968002908D08019AA +:10F6F00000F048F82078297940182070002070BD6B +:10F70000072070BDF7B582B002981446406B0F46D3 +:10F71000002832D0029800252030009028E002987E +:10F72000416B0C2068430E18217830794A1CC01CAC +:10F730002270785420781622411C21703A54207887 +:10F74000C1193088FFF733FF21784018C0B220700C +:10F75000B288002A09D0B16800290ED0C01900F083 +:10F7600011F820783179401820706D1C0098EDB2A6 +:10F77000007EA842D3D800206FE607206DE6000087 +:10F78000FFFF0000F8B5042A2CD3830712D00B78B2 +:10F79000491C0370401C521E83070BD00B78491C78 +:10F7A0000370401C521E830704D00B78491C037061 +:10F7B000401C521E8B079B0F05D0C91ADF00202367 +:10F7C000DE1B08C90AE0FDF7E5F8F8BD1D4608C9CB +:10F7D000FD401C46B4402C4310C0121F042AF5D231 +:10F7E000F308C91A521EF0D40B78491C0370401C50 +:10F7F000521EEAD40B78491C0370401C521EE4D4FC +:10F8000009780170F8BD01E004C0091F0429FBD28A +:10F810008B0701D50280801CC90700D00270704799 +:10F8200000290BD0C30702D00270401C491E0229D8 +:10F8300004D3830702D50280801C891EE3E70022DF +:10F84000EEE70022DFE70378C27819464378120614 +:10F850001B0219438378C0781B0419431143090222 +:10F86000090A000608437047002203098B422CD383 +:10F87000030A8B4211D300239C464EE003460B4300 +:10F880003CD4002243088B4231D303098B421CD362 +:10F89000030A8B4201D394463FE0C3098B4201D354 +:10F8A000CB01C01A524183098B4201D38B01C01A8C +:10F8B000524143098B4201D34B01C01A5241030903 +:10F8C0008B4201D30B01C01A5241C3088B4201D3B2 +:10F8D000CB00C01A524183088B4201D38B00C01A5F +:10F8E000524143088B4201D34B00C01A5241411A86 +:10F8F00000D201465241104670475DE0CA0F00D069 +:10F900004942031000D34042534000229C46030961 +:10F910008B422DD3030A8B4212D3FC22890112BAE7 +:10F92000030A8B420CD3890192118B4208D38901BF +:10F9300092118B4204D389013AD0921100E08909D7 +:10F94000C3098B4201D3CB01C01A524183098B42B8 +:10F9500001D38B01C01A524143098B4201D34B01A1 +:10F96000C01A524103098B4201D30B01C01A524104 +:10F97000C3088B4201D3CB00C01A524183088B428B +:10F9800001D38B00C01A5241D9D243088B4201D314 +:10F990004B00C01A5241411A00D2014663465241FF +:10F9A0005B10104601D34042002B00D549427047FE +:10F9B00063465B1000D3404201B50020C046C046FC +:10F9C00002BD704770477047754600F023F8AE4699 +:10F9D000050069465346C008C000854618B020B5EA +:10F9E000FDF750F860BC00274908B6460026C0C5A0 +:10F9F000C0C5C0C5C0C5C0C5C0C5C0C5C0C5403DE7 +:10FA000049008D4670470446C046C0462046FCF774 +:10FA1000A4FF000000487047142800200149182066 +:10FA2000ABBEFEE726000200704730B47446641E89 +:10FA30002578641CAB4200D21D46635D5B00E31871 +:10FA400030BC184723D1BCEA5F782315DEEF1212D1 +:10FA50000000000074FA03000020002014010000E0 +:10FA600004C9030088FB0300142100206413000074 +:10FA700020C903000024F40000000000080000007A +:10FA80000300000000000000000000000000000073 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000000000000000026 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB300000000000000000000000000000000000C5 +:10FB400000000000000000000000000000000000B5 +:10FB50000000000000000000FFFF000000000000A7 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:08FB800000000000000000007D +:040000050003C8C16B +:00000001FF diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar_wanted.bin b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar_wanted.bin Binary files differnew file mode 100644 index 0000000..b040cdf --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/bar_wanted.bin diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo.hex b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo.hex new file mode 100644 index 0000000..f5acd72 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo.hex @@ -0,0 +1,4835 @@ +:020000040000FA +:10000000481C0020992B0100F1160100CF2A0100A5 +:1000100000000000000000000000000000000000E0 +:100020000000000000000000000000000D2C010096 +:100030000000000000000000F1160100F1160100B0 +:10004000752C01007B2C0100F1160100F116010056 +:10005000F1160100F1160100F1160100F116010080 +:10006000812C0100F1160100F1160100872C01001E +:10007000F11601008D2C0100B9020000FF81000083 +:10008000F1160100F1160100F1160100F116010050 +:10009000F1160100F1160100F1160100F116010040 +:1000A000932C0100992C0100F1160100F1160100BA +:1000B000F1160100F1160100F1160100F116010020 +:1000C00000F002F812F04FFD0CA030C808382418D8 +:1000D0002D18A246671EAB4654465D46AC4201D180 +:1000E00012F041FD7E460F3E0FCCB646012633424C +:1000F00000D0FB1AA246AB46334318475C2C0100E4 +:100100008C2C0100103A02D378C878C1FAD8520773 +:1001100001D330C830C101D504680C6070470000BD +:100120000023002400250026103A01D378C1FBD813 +:10013000520700D330C100D50B6070471FB5C046D1 +:10014000C04612F093FC04B00FB41FBD826902498F +:100150008161024810447047610100000100000005 +:1001600001B41EB400B50FF067FE01B401988646D5 +:1001700001BC01B01EBD0000F0B4404649465246E5 +:100180005B460FB402A0013001B50648004700BF2E +:1001900001BC86460FBC8046894692469B46F0BC11 +:1001A00070470000C1000000401E00BF00BF00BF3C +:1001B00000BF00BF00BF00BF00BF00BF00BF00BF47 +:1001C00000BFF1D17047000070B505460C461646D9 +:1001D00002E00FCC0FC5103E102EFAD2082E02D32B +:1001E00003CC03C5083E042E07D301CC01C5361F3E +:1001F00003E021782970641C6D1C761EF9D270BD55 +:100200008307FF22DB0E9A408907090E99400028D8 +:100210000BDA0007000F0838830828489B001B18DA +:10022000D86990430843D8617047830824489B00ED +:100230001B181868904308431860704710B50446AF +:1002400000210120FFF7DCFF00211820FFF7D8FF75 +:1002500000210B20FFF7D4FF02211920FFF7D0FF68 +:1002600002210D20FFF7CCFF02210E20FFF7C8FF6F +:1002700002210F20FFF7C4FF0221C81FFFF7C0FFB4 +:1002800003211620FFF7BCFF03211520FFF7B8FF5D +:10029000204600F019F8002010BD49210180704768 +:1002A00010B500F04FF810BD0648704710B500F0CB +:1002B0004AF810BD704770477047000000ED00E03D +:1002C00000E400E003F900C330B50546384C95B0B2 +:1002D00006202070A01CFFF7E0FF5920A0803548C1 +:1002E00061880069344A80B2D269344B120C98425A +:1002F00004D18A4208D032A1B42003E0884203D05E +:100300002FA1B72012F0DDFB334802F057F9044665 +:10031000072000F0D7F92146254800F015FA6D1E98 +:10032000072D0AD8302168460170857001F0CCF99C +:10033000002802D009A800F065FC204601F0BBFAB5 +:1003400015B030BD704710B50C46014660390B2919 +:1003500003D8214601F01CFF06E001466C39032951 +:1003600004D8214601F047FF206010BD01467039D6 +:100370001F2903D8214600F03FF8F5E701469039E0 +:100380000F2903D8214600F0C1F8EDE70146A03956 +:100390000F2903D8214600F029F9E5E70146B039D5 +:1003A0000F2903D8214600F006F9DDE70120DBE73D +:1003B000140000200010001040000010FFFF00009B +:1003C0007372635C636F72655F66756E6374696F89 +:1003D0006E732E63000000006D1C000070477047B4 +:1003E00070477047704770477047704710B50128D5 +:1003F00001D100F0CEF910BD10B57038030012F035 +:1004000065FC150C10141C20232A31363B3F434752 +:100410004E535A626A72797E8300086803F0FDFBCE +:1004200010BD086803F050FC10BD0C790B7B8A6886 +:100430000868214603F06EFC10BD086803F0E8FC74 +:1004400010BD03F0BAF910BD08884A6880B21146A1 +:1004500003F06CFE10BD0A790888114680B203F0E3 +:10046000BCFE10BD087840B203F0C7FE10BD08887E +:1004700080B203F0E3FE10BD086803F0F2FE10BD89 +:10048000086803F00AFF10BD086803F036FF10BDCE +:10049000088982B209C9194603F061FF10BD05C978 +:1004A000114603F0B0FF10BD08884A6880B21146BB +:1004B00003F0CEFF10BD0B7908888A6880B2194618 +:1004C00004F010F810BD0B7908888A6880B21946CC +:1004D00004F0B9F810BD08884B688A6880B21946E4 +:1004E00004F0FAF810BD08884A6880B2114604F09A +:1004F00045F910BD088880B204F05EF910BD088887 +:1005000080B204F07CF910BD012010BD10B5903808 +:10051000030012F0DBFB09060F161D242C363F46A4 +:100520004E0088888A6883B20888194680B204F031 +:1005300030FD10BD08884A6880B2114604F086FD7F +:1005400010BD08884A6880B2114604F0C9FD10BD8C +:1005500008884A6880B2114604F0FFFD10BD088883 +:100560004B688A6880B2194604F030FE10BD0889D5 +:1005700082B2888883B20888194680B204F065FE8A +:1005800010BD08894B6882B20888194680B204F011 +:100590009AFE10BD08884A6880B2114604F0CAFE6F +:1005A00010BD888882B20888114680B204F05EFFD0 +:1005B00010BD012010BD10B5B02805D0B12808D05D +:1005C000B2280BD0012010BD088880B205F042FA95 +:1005D00010BD088880B205F06DFA10BD08884B6820 +:1005E0008A6880B2194605F076FA10BD10B5A038B9 +:1005F000030012F06BFB0B070E172028323C434D13 +:10060000545D65004B6808788A68194606F090FDCD +:1006100010BD88888A6883B20888194680B206F0BF +:100620009CFD10BD08884C68CB688A6880B2214662 +:1006300006F0A3FD10BD08884B688A6880B2194691 +:1006400006F0BDFD10BD8888CB6884B208888A6832 +:1006500080B2214606F0DDFD10BD8888CB6884B2EB +:1006600008888A6880B2214606F0E3FD10BD08883C +:100670004A6880B2114606F00BFE10BD088982B2AE +:10068000888883B20888194680B206F00BFE10BD38 +:1006900008884A6880B2114606F024FE10BD088919 +:1006A0004B6882B20888194680B206F0A1FE10BDE0 +:1006B00008884B688A6880B2194606F05EFF10BD54 +:1006C000012010BD10B507F09BF80FF0CFF907F02F +:1006D00049FD0FF01DFB07F0B3FD07F0D1FC10BD85 +:1006E0001CB50446002069460870204608F020FD2D +:1006F0006946204608F0DEFB002803D1FBA1B120AB +:1007000012F0DFF901A9204608F033FB002803D1DD +:10071000F6A1B62012F0D5F9684600781CBD70B578 +:10072000F74D002428462C7620308471C47112F0D5 +:10073000DBFA284640380470203084738474847651 +:100740002C74AC7070BDEAE710B50C46ED49828898 +:100750008A8042884A800078087008460A38847087 +:1007600008F0DDFAFFF7DBFF204609F01FFDE44A41 +:10077000E0321146383908461446813808F04AFDFF +:100780002146E0480AF0FDFF08F0C9FC12F0ACFA7F +:1007900010BD10B50120FFF721FE10BDF8B509F01E +:1007A0004CF9D84DD64C0A3D022802D0207C0028B6 +:1007B0007CD0207E0026102819D1A078002803D0F4 +:1007C000CAA1D14812F07DF9CD48E838817A89076D +:1007D0000DD50146267160398989E180C17A21727F +:1007E00081896181C089A0810120A0702676C44FD3 +:1007F000203FB87C002859D1C4486946808908F058 +:1008000059FB002805D06946687809784018687057 +:1008100004E0C520B5A1C00012F053F9207C0028E7 +:1008200038D0BA488189FF300930406D80898142D3 +:1008300004D0B548ADA1223012F043F9B348808905 +:1008400008F0DEFB002804D1AF48A8A1283012F040 +:1008500038F908F04CFC00281CD0AC488089FFF720 +:100860003FFF697840186870A5484038416D2031D5 +:100870000A7C012A0DD1A54A3E779289C287487C1D +:1008800020700120B876207E102801D0282800D1C1 +:10089000267626746978002908D09C488289FF3022 +:1008A0000930C28601870120B8746E7009F0BAF869 +:1008B000002805D1207C002802D0A87801F0A2FEF3 +:1008C000F8BDF8B50F460446FFF768FF8C4D403D74 +:1008D00028788B4E002813D0002F10D1307E0028AE +:1008E00004D0FF2081A1BE3012F0EBF82C22A91C0D +:1008F000204611F049FF0E202070002028708FE064 +:100900007F4D203DA87B002818D0002FF7D1307EE6 +:10091000102808D0282806D0002804D0FF2073A172 +:10092000CA3012F0CEF80120E070E87BA070287C7D +:1009300060700F2020700020A87371E00121204614 +:1009400008F00EFC002807D0307C002851D1394631 +:10095000204608F005FCF8BDA97C69480C380090D9 +:1009600068480A38002913D00178052910D2002FD1 +:1009700056D1491C0170002666700D2020700120A0 +:1009800028750622A01C009911F0FEFEAE7447E007 +:100990005C4800210A380170B078002814D0002F7C +:1009A0003ED1307E002803D050A1594812F089F87A +:1009B000002565700120524920700A22091DA01CE3 +:1009C00011F0E2FEB5702BE0394620460AF046FEF3 +:1009D000002825D1A87C002805D0002F20D1494827 +:1009E0000A380178C5E7A87E002802D0307C0028AC +:1009F00001D00020F8BD002F12D1307E002804D095 +:100A00008D203AA1800012F05CF8002666700A2062 +:100A10003B4920700622091FA01C11F0B5FEAE76DE +:100A20000120F8BD10B53648017E002908D1007CB0 +:100A3000012805D001210020FFF743FF002801D045 +:100A4000072010BD012010BD10B5012409F0F8FBEE +:100A50000443FFF7E7FF044308F062FB014621432C +:100A6000084610BDF8B51D4614460E4608F0A1F91B +:100A7000002807D0684608F0A7F9002803D0002C0A +:100A800007D101E00120F8BD992018A1800012F0E3 +:100A900018F808F045F9A04204D21D4813A15830B7 +:100AA00012F00FF8009807F0B9FD3146009807F0F2 +:100AB000C7FDE2B22946009807F07EFF08F096F9DC +:100AC000002804D19D2009A1800011F0FAFF08F050 +:100AD00029FB0E4800244030C17B002902D0C4739A +:100AE00009F080FC0948C480CCE700007372635CA5 +:100AF0006C6C5F6374726C2E73302E6300000000A8 +:100B0000E0020020240000200B06000098010020D5 +:100B10000D02000010B50179002907D001290AD083 +:100B2000F749FE2011F0CDFF002010BD831D428843 +:100B30000488022103E042880488831D01212046A5 +:100B4000FFF790FF10BDF8B51F4615460E46044648 +:100B500008F073FF022803D0EA48007C00281FD069 +:100B6000E9488089208008F04BFA002803D1E44945 +:100B7000E64811F0A6FF0524684608F04CFA002864 +:100B80000ED0009807F094FD3070022809D001289B +:100B900007D008F080FA641E2406240EECD1002051 +:100BA000F8BD3946009807F01FFF2880002804D1BF +:100BB000D648D349123011F084FF08F06CFA0028AF +:100BC00004D1AF20CE49800011F07BFF0120F8BD99 +:100BD00038B50446831D821C6946FFF7B4FF002820 +:100BE0000DD00020607168460078012808D00228E6 +:100BF00006D0FF20C249203011F063FF012038BD2C +:100C00002071FBE700215CE670B5BE4C0546403C18 +:100C10002078002803D1BB48007E002803D0B849C3 +:100C2000BB4811F04EFF287808F093FB28780AF0B3 +:100C3000EEFE00202071012060713921E1702070EA +:100C400070BD70B5AF4D0446403D2878002803D1F3 +:100C5000AC48007E002804D0AD48A949183811F0EE +:100C600030FFA94E2188B089884203D108F0E5FE03 +:100C7000022807D002202871012068713821E9700C +:100C8000287070BD7F2070769F48E1782030C17356 +:100C9000A17881730020EEE710B59A4C403C207893 +:100CA000002807D19748007E002803D108F0C5FE30 +:100CB000032804D161209249C00011F002FF91493C +:100CC00000202031C8712071012060713A21E1704B +:100CD000207010BD70B58B4C0646403C2078002833 +:100CE00007D18848007E002803D108F0A6FE03281B +:100CF00004D186488249783011F0E3FE814D2035D9 +:100D0000E87908280CD2E87910220001001968302F +:100D1000314600F09FFDE879401CE871002000E0BA +:100D200007202071012060713B21E170207070BDAF +:100D3000F8B5744C0546403C2078002803D1714832 +:100D4000007E002804D072486D49443811F0B9FE85 +:100D5000A878002801D0012804D1A888FF21F53106 +:100D6000884204D96A4866493E3811F0AAFE664EA8 +:100D70002988B089884203D108F05FFE022807D095 +:100D800002202071012060713621E1702070F8BDD1 +:100D90005D48002720308772A988B185012131760E +:100DA000A978012900D00021817257484030C07BCA +:100DB000002801D009F016FB2771E3E770B5514C0C +:100DC0000546403C2078002807D14E48007E002888 +:100DD00003D108F032FE002804D04D484849673856 +:100DE00011F06FFE287809F02EFA00202071012002 +:100DF00060713021E170207070BD70B5414C0546C6 +:100E0000403C2078002803D13E48007E002804D0D2 +:100E10003F483B490D3011F054FE287800280BD094 +:100E2000012809D0022807D06878402804D3384820 +:100E30003349143011F045FE284608F0F6FD00282D +:100E400001D0002000E00C202071012060713421CD +:100E5000E170207070BD70B52A4C0546403C20788A +:100E6000002807D12748007E002803D108F0E5FDBF +:100E7000002804D0264822495C3811F022FE297847 +:100E8000002914D00A2912D0142910D01E290ED0FE +:100E900028290CD032290AD04B2908D0642906D041 +:100EA000FF2904D01A481649503811F00AFE284686 +:100EB00009F028FA00202071012060713321E170CF +:100EC000207070BD70B50F4C0546403C207800285E +:100ED00003D10C4A107E002804D00D48084975380B +:100EE00011F0EFFD062229460A4811F04DFC0020C2 +:100EF0002071012060713221E170207070BD00000E +:100F0000EC0A0000E002002098010020A30200008B +:100F1000910500001D00002070B5F84C05462078B2 +:100F2000002804D120464030007E002803D0F44938 +:100F3000F44811F0C6FD00216956042914D0002997 +:100F400012D0081D10D0001D0ED0001D0CD0001DA9 +:100F50000AD0001D08D00A3006D0283104D0A120C4 +:100F6000E749C00011F0ADFDE74829780170012084 +:100F700060713121E1702070C0E710B5DF4C20783E +:100F8000002804D120464030007E002804D067208D +:100F9000DB49000111F095FD07F0C2FEE08007F08B +:100FA00087FF207200202071012060710521E1700F +:100FB000207010BDF8B5D14C07462034A07B2546E3 +:100FC0002035002805D1287E002802D1A8780028E5 +:100FD00004D0CC48CA492A3811F073FD08F02DFD21 +:100FE0001026022822D1C9483988808988421DD11B +:100FF000C249483908460A7F6038807A002A03D0FF +:1010000080070CD40C200CE0800708D40620087759 +:10101000BE484030C07B002801D009F0E3F92E76AD +:101020000020E07326740120A073F8BD0220F8E7C9 +:1010300010B5B24C2078002804D120464030007E04 +:10104000002804D0AF48AE493C3811F03AFD0020EA +:1010500020710E20A0700F20E070FF20A0710020F2 +:10106000C0432081AA480178A1728188A18140886B +:10107000E08101206071207010BD10B59F4C207878 +:10108000002804D120464030007E002804D0DB2018 +:101090009B49800011F015FD0821A01D0EF082FD76 +:1010A00000202071012060712B21E170207010BDA3 +:1010B00070B5924D04462878002804D12846403067 +:1010C000007E002804D0B7208D49C00011F0F9FC43 +:1010D0008E4810222146303800F0BCFB8B4810228D +:1010E000A118203800F0B6FB884830380EF061FEB9 +:1010F0008649102210392C46A81D00F0ABFB0020B9 +:1011000020710E20A0702A20E070012060712070F4 +:10111000F4E6F8B5794C05462034A07B2646203607 +:10112000002802D1307E002804D076487449DC388B +:1011300011F0C7FCA978052912D0132910D0142961 +:101140000ED015290CD01A290AD0292908D03D29FA +:1011500006D03B2904D06B486949D43811F0B1FC62 +:1011600028886C49884204D966486549CB3811F013 +:10117000A8FC08F062FC0C212827022809D163484A +:101180002A888089904215D15C484838027E002A1E +:1011900001D0E17310E0A97841760121017637761C +:1011A0000020E07359484030C07B002804D009F08B +:1011B00019F901E00220E07327740120A073F8BD43 +:1011C00070B54E4C05462078002804D122464032A6 +:1011D000107E002804D083204949C00011F071FC22 +:1011E0004648294660300622054611F0CDFA012016 +:1011F000A8710021217160711721E17020707DE6D6 +:10120000F0B5414F85B0403F3D7A06463B480078F7 +:10121000002804D13846A038007E002803D0384981 +:101220003D4811F04EFC3078002806D0012804D04B +:101230000D203349800111F044FC082D39D2324889 +:1012400020380190C469307800282CD0012804D0BF +:1012500031482B490F3011F034FC29460831012068 +:10126000884004430120A84020430090B179234CDA +:1012700008027279690009191043FF310131888130 +:10128000B01C11F0E2FA717800020843A9000919B4 +:10129000C031C862387A401C387201990098C86120 +:1012A0000020207108E0294608310120884084434D +:1012B000D8E7124807210171012110480B22417122 +:1012C000C270017005B0F0BD10B50C4C207800283C +:1012D00004D120464030007E002804D00E48084942 +:1012E0000E3811F0EEFB11F0FFFC00202071012000 +:1012F00060710A21E170207010BD0000A002002082 +:10130000EC0A000006050000C00300209801002040 +:1013100024000020FF0E00003F03000010B508F07D +:101320000AFF002803D0FC49FC4811F0CAFB07F073 +:10133000F5FE07F0D8FC0AF016FA002804D0F748AA +:10134000F5490E3011F0BDFB07F039FF002804D03D +:10135000F248F149123011F0B4FB11F0C5FCF0482D +:1013600000240470FFF7DBF9EE480121047141719C +:101370000222C2700170BFE770B5EA4D04462878BA +:10138000002804D128464030007E002804D0EF20F9 +:10139000E149800011F095FB20781F2801D8601CDE +:1013A00004D1DE48DC49DE3011F08BFB00202871CF +:1013B0002078611C07F0BCFF012068712021E970D2 +:1013C00028709BE5F8B5D74C054620782646403670 +:1013D00000280CD1307E002809D108F02EFB00280F +:1013E00002D1307C002807D0287800280ED0CB48C6 +:1013F000C949EB3011F065FB2878012806D0002898 +:1014000004D0C648C449F03011F05BFB0120607184 +:1014100028780027C44D01280BD0002008F074FE66 +:10142000002844D00C2020711B20E0700120207087 +:10143000F8BD0C20207107F003FF0028F4D0BA4853 +:1014400002210C300EF037FB002806D00F21A889AE +:10145000090211F013FAA98100E0AF8101220321F2 +:10146000B14807F0E9FAB04808F051F8A88907F048 +:1014700059FC002803D1A849AC4811F022FBA889E7 +:10148000002107F053FE002804D0A848A249001DFF +:1014900011F017FB317F708B08F0D9FE002804D0C3 +:1014A000A2489D49083011F00CFB2771BCE7277159 +:1014B000307C0028B8D1A889FFF712F9B4E770B5DD +:1014C000984D04462878002804D128464030007EF4 +:1014D000002804D0954890493B3811F0F2FA207862 +:1014E0001F2801D8601C04D190488B493A3811F06C +:1014F000E8FA002028712078611C07F02DFF0120F8 +:1015000068711A21E9702870F8E4F8B5854D044631 +:1015100028780C272E464036002806D1307E002839 +:1015200003D108F08AFA032804D16F207A49C00059 +:1015300011F0C7FA6079002801D001282FD1A079D5 +:10154000002801D001282AD1A07B002805D001283D +:1015500003D0022801D0032821D1607B40071ED090 +:10156000618801208003814202D82288824201D909 +:1015700020790CE02079002804D0022805D0032827 +:1015800003D004E0202904D209E0A02A01D20128D6 +:1015900005D12088884207D92079012804D06348E2 +:1015A0005D495F3811F08DFA20887083207930779B +:1015B0006079002802D0012803D00CE05C4A0021A9 +:1015C00005E0584A60329079002804D00121204675 +:1015D00007F03AFE074601202F7168711821E97063 +:1015E0002870F8BD70B54F4C05462078002804D10E +:1015F00020464030007E002804D04C484649B63092 +:1016000011F05FFA08F019FA0C2102280ED14648B1 +:101610002A8883899A4219D10246C032137F002B4F +:1016200004D1807E0E2803D00F2801D0217103E061 +:1016300005201077002020710E20A0702E20E07071 +:101640002888E08001206071207057E40220F2E7D2 +:1016500070B5344C05462078002804D1204640302F +:10166000007E002804D031482B498A3011F029FA35 +:1016700008F0E3F90C2102280ED12B482A8883892F +:101680009A421FD10646C036327F002A04D1807E9E +:101690000E2803D00F2801D0217109E02148102223 +:1016A000A91C1E3811F070F804203077002020713A +:1016B0000E20A0702D20E0702888E080012060714D +:1016C00020701BE40220F2E710B501780B0011F046 +:1016D000FDFA3C90904590906590909090484B908A +:1016E00090905E619090909090904F3590393D90A1 +:1016F00090909041909090909090905390575B90E4 +:101700001F319078686C7074907C90878B84809087 +:10171000801CFFF79DFF6AE0EC0A0000DF0200007A +:10172000C0030020A002002098010020E90300006F +:101730001D000020801CFFF755FF58E0801CFFF7BC +:10174000E4FE54E0801CFFF7BAFE50E0801CFFF777 +:1017500039FE4CE0801CFFF70FFE48E0FFF7DEFD8E +:1017600045E0FFF7B1FD42E0801CFFF749FD3EE098 +:10177000801CFFF725FD3AE0801CFFF7CAFC36E02D +:10178000801CFFF795FC32E0FFF777FC2FE0FFF7B6 +:101790004FFC2CE0801CFFF70DFC28E0FFF7EDFB71 +:1017A00025E0801CFFF7B8FB21E0801CFFF78AFBD7 +:1017B0001DE0801CFFF74FFB19E0801CFFF71DFBAD +:1017C00015E0801CFFF7FAFA11E0801CFFF7B0FA71 +:1017D0000DE0801CFFF77EFA09E0FFF75DFA06E0F6 +:1017E000801CFFF72EFA02E0801CFFF70DFA0120A3 +:1017F00082E5002080E510B51D491E4811F061F911 +:101800007AE570B51D4A012411461B4D4031030095 +:1018100011F05CFA05191C1C04191C00012200219E +:10182000154807F009F91548002148380177417734 +:10183000C03808F068FD002804D00E480C49D330A9 +:1018400011F03FF964E40C74556561E46D200849BA +:101850000001F5E730B5134606E0CC18203CE47FE4 +:10186000D51A44555B1EDBB2002BF6D130BD00000B +:10187000EC0A0000CA05000098010020A002002028 +:1018800010B5030011F022FA070805080B0B0E0E25 +:10189000110003F0FAFF10BD01F0BAFF10BD0BF00C +:1018A0009BFF10BD0DF004FE10BDFF20F8A17D30A0 +:1018B00011F007F910BD7FB5F94AFA4C51689268EA +:1018C0000192009120700823F74A1946F7480EF05C +:1018D00093FB0025F6480EF0ADFB6D1CEDB2072D15 +:1018E000F8D3F1490320803140020BF0C7FF0028F4 +:1018F00003D0E7A1912011F0E4F81E220221ED4867 +:101900000AF077FBEB481E22032110300BF0EBF8B6 +:10191000E8480722342174300AF0C4FAE5484C2123 +:10192000283010F090FFE3496A46743108464C387D +:101930004164FF317B31816401211172039002F017 +:1019400016F902A80CF0CCFA002803D0D0A1A520EB +:1019500011F0B7F8D54802222421A8380AF0A2FADB +:10196000D24802222C215C380AF09CFAD2490B2082 +:101970000DF08AFE002803D0C5A1B22011F0A1F815 +:1019800003F070FF03F076F904F0D6FD6B46CB4A06 +:101990000821CBA002F04BF8002803D0BCA1B9204D +:1019A00011F08FF8012005F0C8F8002803D0B8A185 +:1019B000BB2011F086F87921C900C44810F043FF1C +:1019C000C249B74A0020135C0D18401CC0B2EB702E +:1019D0000428F8D3002060606070A0707FBD70B5EF +:1019E000BB4E0546706A94B00C46401C04D1B06AE8 +:1019F000C0430004000C0BD0306AC007C00F287031 +:101A0000706A10F033FFB06A2071000A607113E051 +:101A10002B206946087009A968460AF089FA00284F +:101A200003D09BA1DF2011F04CF801202870062282 +:101A30000AA9204610F0A8FE2878002815D0607961 +:101A4000C0210843607117206946087000A806226B +:101A50002146023010F098FE09A968460AF068FA9B +:101A6000002816D08AA1F42011E0322069460870BF +:101A700000A806222146023010F086FE09A9684619 +:101A80000AF056FA002804D0FF2081A1013011F09D +:101A900018F814B070BDF0B58D4C0646206895B0AE +:101AA0000D463746401C0837002808D16068401CA6 +:101AB00005D1A068401C02D1E068401C11D020680C +:101AC000314610F0D3FE6068311D10F0CFFEA068E3 +:101AD000394610F0CBFEE06831460C3110F0C6FEFE +:101AE00025E02B206946087009A968460AF020FA0B +:101AF000002804D0FF2066A1203010F0E2FF082269 +:101B00000AA9304610F040FE2B206946087009A94A +:101B100068460AF00DFA002804D0FF205CA12730A7 +:101B200010F0CFFF08220AA9384610F02DFE2069D8 +:101B30002E46401C0836002808D16069401C05D19B +:101B4000A069401C02D1E069401C12D020692946DE +:101B500010F08CFE6069291D10F088FEA0693146E6 +:101B600010F084FEE06929460C3110F07FFE15B0BC +:101B7000F0BD2B246846047009A90AF0D9F90028A1 +:101B800004D0FF2042A1453010F09BFF082209AF8E +:101B90000AA9284610F0F8FD6846047009A90AF061 +:101BA000C7F9002804D0FF2039A14C3010F089FF7C +:101BB0000822391D304610F0E7FDD8E710B50021A6 +:101BC00008460EF0ECFA002101200EF0E8FA0021A0 +:101BD00002200EF0E4FA002103200EF0E0FA0021CA +:101BE00004200EF0DCFA002105200EF0D8FA10BD1A +:101BF00010B5364CA0780A2804D3FF2024A19630D3 +:101C000010F05FFF20786021484300190830002160 +:101C100001704178E722C908C900C91C1140417010 +:101C2000204A0121517010BD70B51E4C607800280B +:101C30000ED0264800250178491CC9B201700A2936 +:101C400000D105708178491C81700EF072FB6570BF +:101C500070BD70B5134C05466068002804D0FF20A5 +:101C60000BA1BF3010F02DFF656070BD70B50D4E3B +:101C7000164DFFF7BDFF7168044600292AD0602287 +:101C8000FEF7A2FAFFF7D0FF00207060F1E7000036 +:101C90007372635C686F73745F636F72652E630049 +:101CA000F82C01002C000020C40300206C1100203F +:101CB00081180000440A0020141000203412000093 +:101CC0006E52463531383232000000004C0C002094 +:101CD000800000102879002852D0FE480AF0F2F85F +:101CE0006060002804D1FF20FB49DD3010F0E9FEE0 +:101CF00060680AF045F9002810D0204601F0A5F8E8 +:101D00006078010707D5C008C000401C60702879C2 +:101D1000401E287126E0EF48616829E0ED486168BF +:101D20000AF0D9F8687900282AD0EA484C380AF035 +:101D3000C9F86060002803D1E749E84810F0C1FE07 +:101D400060680AF021F9002815D0204603F0DCFD78 +:101D50006078010709D5C008C000801C60706879F0 +:101D6000401E6871FFF760FF83E7DA4861684C380E +:101D70000AF0B1F87DE7D74861684C380AF0ABF853 +:101D800070BDF7B505460078002700090C463E46B1 +:101D9000062804D0D148D049223010F092FE287A8B +:101DA00000280ED0012814D0CC48CB49433010F085 +:101DB00088FE0298002C068001D0278066800020D3 +:101DC000FEBD02270926002C0ED0A889A080A87B82 +:101DD00008E003271426002C06D02869E060A88AB2 +:101DE0002082287B2072E4E702980680E7E770B53E +:101DF0000E4600211C4619801546030010F066FFB0 +:101E00000723050B1711231D2300224629463046C0 +:101E100003F046FD70BD22462946304601F09BFA8C +:101E200070BD22462946304604F081FA70BD224634 +:101E30002946304602F052FF70BD22462946304600 +:101E4000FFF79FFF70BD4D20A349C00010F039FE81 +:101E5000032070BD01469F4810B54C380AF03BF88E +:101E60009F494879401CC0B24871012803D19D4860 +:101E7000007800F0C7FB10BDF8B505460720400705 +:101E80000F460A18012189038A4209D2002D02D087 +:101E90002818884204D2E81C80088000A84201D09B +:101EA0001020F8BD8E488178002911D03988009122 +:101EB0004178602251430C18083420783B460007D3 +:101EC000000F00222146FFF792FF060004D015E024 +:101ED000002038800520F8BD002D13D039880098E7 +:101EE000814201D90C260DE020783B460007000F07 +:101EF0002A462146FFF77BFF060005D00C2E01D0B5 +:101F0000002038803046F8BD754D6878401CC0B25E +:101F100068700A2801D100206870A878401EA87057 +:101F200061784807400F022810D00128EAD169489B +:101F3000616809F0D0FF2879401CC0B228710128DF +:101F4000E0D16848007800F05DFBDBE7C806D9D433 +:101F50006068FFF77FFFD5E770B504466248164614 +:101F60000D46814204D15D485B49DB3010F0A9FD8C +:101F7000012E05D059485849EB3010F0A2FD70BD34 +:101F80005848012181706620207000202072A581B0 +:101F9000A17370BD70B516460D46040001D1FFF760 +:101FA00027FE662101700121017229680161A9885B +:101FB00081820673002C01D1FFF736FE70BD072128 +:101FC0004907012241189203914201D31020704722 +:101FD0000721017000207047052210B5920390423E +:101FE0000ED301239B04C21A404B9A4208D3404BA4 +:101FF000984205D2072252078A18DB139A4201D36E +:10200000102010BD0DF079FB10BD052310B59B030A +:1020100099420ED301239B04344CCB1AA34208D31C +:10202000334B994205D2E3020124D318A403A342FF +:1020300001D3102010BD022803D0102801D00920A0 +:1020400010BD0DF080FB0028FAD0052010BD70B542 +:1020500005239B03984212D301239B04234CC31AEC +:10206000A3420CD3224B984209D2E4020D19DB1390 +:102070009D4204D2002A04D014199C4201D310209E +:1020800070BD0DF086FB0028FAD0072070BD10B59A +:1020900004460720400701212018890394B0884294 +:1020A00002D3102014B010BD01F0ADFD002801D006 +:1020B0001120F7E70F2008A9087369460BA809F05B +:1020C00037FF0028EED16846007A207068464089C4 +:1020D00060800FE010110020901C0000FF01000044 +:1020E0004C0C00202C000020FFFF00000000FC1F13 +:1020F0000040002068468089A0800020D2E710B50B +:1021000094B0044601F07FFD002801D01120C9E7FA +:10211000002C01D00720C5E7392168460170002155 +:10212000817009A909F004FF002803D01549164859 +:1021300010F0C7FC0020B5E770B5144C0846A17834 +:10214000002913D000280FD0072252070123851839 +:102150009B039D4203D20568AA189A4201D310201E +:1021600070BD8288002A03D0012903D0082070BDE9 +:10217000092070BD04F042FA0028FAD10021A170B4 +:1021800070BD0000901C0000790300002C000020AE +:1021900010B56038030010F099FD07050A0E131AF8 +:1021A00021252C0005C91146FFF766FE10BD086801 +:1021B000FFF705FF10BD05C91146FFF70DFF10BD64 +:1021C0004B6808788A681946FFF71FFF10BD4B68F7 +:1021D0008A6808681946FFF73AFF10BD0868FFF7DC +:1021E00056FF10BD08884A6880B21146FFF7A4FF69 +:1021F00010BD012010BD10B56C2801D0012010BD0C +:102200000878FFF77CFF10BD10B5EFF31080C4070E +:10221000E40F72B6D6484178491C417040780128D5 +:1022200001D10EF0ABF8002C00D162B610BD70B534 +:10223000CF4CE07800280AD10125E570FFF7E4FFD4 +:102240000EF0A4F8002804D000200EF077F800204B +:1022500070BDC84865714560F9E770B5EFF310804F +:10226000C507ED0F72B6C24C6078002803D1C2A139 +:102270008F2010F026FC6078401E60706078002887 +:1022800001D10EF07FF8002D00D162B670BD10B5FF +:10229000B748C178002904D000214171C170FFF70F +:1022A000DCFF002010BD10B504460EF06FF8B049F9 +:1022B000C978084000D001202060002010BDF8B58A +:1022C0000246AB4C0026A6710820042101251027E8 +:1022D000130010F0FBFC0D080A0C0E101214161E51 +:1022E000262123252800257122E0022001E021710A +:1022F0001EE020711CE027711AE02020F9E701267A +:1023000016E0FFF781FF0EF041F80028FBD002260F +:102310000EE02171A5710BE02771FBE7202000E0A2 +:1023200040202071F6E7FF2093A17E3010F0C9FB1A +:102330000EF038F8002809D00EF03AF8B04205D176 +:1023400030460EF038F80028FAD024E0012080074B +:10235000C5608D4A002151608C4A9661854B0222EE +:102360005A6085608A4803690569DB43DB06DB1731 +:102370005B1C10273D430561834D00E020BF6F6863 +:10238000002FFBD0002B03D1076910239F43076167 +:10239000784882606960A07900280CD00DF0F6FFC3 +:1023A00005460DF053FF7B4A002D02D0A260E0608D +:1023B00001E0E260A060002E01D100F0B1F8F8BDAC +:1023C00010B504460DF0E8FF002805D0684901204B +:1023D000C8704A78521C4A702046FFF770FF10BD43 +:1023E000F8B5694FB8680025012802D1BD600DF02D +:1023F000A5FF7868012800D17D60386801265C4C13 +:10240000012814D13D606079002803D000200DF030 +:1024100095FF65712078002809D00DF0B7FF0028DE +:1024200005D05948C038866300060661A670386931 +:1024300001282CD13D6100F068F801208007466139 +:10244000A079002815D00DF0A1FF00900DF0FEFE40 +:102450000099002901D0E16800E0A168411A022931 +:1024600001DA8A1C13DC0099002901D0E06000E049 +:10247000A060FFF7C9FE0DF089FF002806D0424892 +:10248000C038866300060661A67000E02670F86812 +:10249000012819D100F039F800F037F800F035F8CC +:1024A000A078002804D1FF2033A1053010F009FBEB +:1024B000FD60A5702570FFF7D0FE0DF042FA0028F0 +:1024C00002D03148C038C663F8BD10B5284CE0785A +:1024D000002801D10DF056FF01208107886100F02E +:1024E00014F8A07800280BD0274CE068002803D10E +:1024F0000DF061FF0028F8D10020E06000F005F841 +:1025000000201C49C043886010BD08B550206946B2 +:1025100008806A461088411E11800028F9D108BD44 +:10252000F8B5144819278760174900200860C8606B +:102530000DF02CFFBD0701240D4E002805D01248D8 +:10254000C03884632C61B47000E03470FFF75CFE27 +:10255000084847600D4930798863FFF7D6FFAC61C2 +:10256000FFF7D3FF0849002008616C61F8BD000047 +:1025700034000020000300407372635C736F635F7C +:10258000636C6F636B2E6300000100400005004028 +:1025900000ED00E0FFFFFF7F01203F49400608609B +:1025A0003E4908603E490A68FF231B029A43831292 +:1025B0001A430A60384980390860704710B50246EE +:1025C0000420384904E0C3005B181B79002B0AD0B3 +:1025D0000346401EC0B2002BF5D133A1432010F0BA +:1025E00070FAFF2010BDC300CA50002259184A716A +:1025F0008A7101220A7110BD2A4A0021C000801888 +:102600000171704710B50446042803D326A1522057 +:1026100010F057FA2348E1000C182079012803D064 +:1026200021A1532010F04DFA6079A179401CC0B26D +:10263000814200D060710120174940068031086056 +:1026400010BD70B5164800680004800F022803D042 +:1026500015A1692010F035FA124E194C0325207887 +:10266000C10088190279012A07D1427983799A42F7 +:1026700003D042798271705880472078401CC0B2E4 +:102680002070042801D30020207028466D1EEDB272 +:102690000028E4D170BD000080E100E080E200E0AD +:1026A00018E400E08C1100207372635C736F635F49 +:1026B0007369676E616C6C696E672E630000000061 +:1026C000440000208107C90E002808DA0007000F27 +:1026D000083880082C4A80008018C06904E080080F +:1026E0002A4A800080180068C8400006800F7047A2 +:1026F00010B50D20FFF7E6FFC4B20420C043FFF77A +:10270000E1FFC0B2844203D021A11A2010F0D9F910 +:1027100010BD0121234A48031060234B00221A6098 +:10272000224A5160224A1060224A11601D498039B4 +:102730000860704701211B4A480310601D4A516020 +:10274000194A002111601A490860704710B51649EE +:102750000868012804D00EA1562010F0B2F910BD6F +:10276000154880680022C0B20A600DF041FA10BD21 +:1027700010B50D4801680029FCD0FFF7E7FF0120E4 +:102780000B494003086010BD00ED00E000E400E0EC +:102790007372635C736F635F68616C5F726E672EE8 +:1027A0006300000080E100E000D1004000D3004061 +:1027B00080E200E000D0004000D5004030B40121AC +:1027C000BB48C9020160CD1005604A030260B948E8 +:1027D00003681B021B0A036004680023240A240206 +:1027E0000460B5480468240A24020460B348012444 +:1027F00044608460B24C23606360A360B14B196095 +:102800001D601A60B04B19601A600121016030BC74 +:10281000704710B40121A648CC0204600A0202608D +:102820000B060360A54841608160A549002008604F +:1028300048608860A34804600260036010BC704771 +:102840000121A048C9020160C91001607047002839 +:1028500005D0012805D0022805D19C4870479C4826 +:1028600070479C48704710B59BA18B2010F029F948 +:10287000002010BD70B500219E4C9F4D9F4A904B8B +:10288000002808D001281DD0022822D092A1B32010 +:1028900010F017F970BD01200004A060A86011605D +:1028A0001960974B42109A60964A9060804A0012D5 +:1028B0001060954801608648016094480160944822 +:1028C000017070BD01204004A060A8605160596093 +:1028D00070BD01208004A060A8609160996070BD07 +:1028E000F8B59446834A844D00240127744E00288D +:1028F00008D0012836D0022844D077A1E82010F073 +:10290000E0F8F8BD891E0902090A01200004906060 +:1029100034606860794A1160012B21D000217C4A23 +:102920007C4B517061463D31DC63DF637A4B5C6008 +:1029300002249C6004241C61734B196073490F606E +:10294000604B891519606F4B58605F48016074488F +:102950007249C16086606A49600348601770F8BDBB +:102960000121DCE701205B4E40046E4F012B04D1B6 +:102970003460506068603960F8BD906034606860B1 +:102980003960F8BD0120514E8004674F012BF4D10E +:10299000EEE766484068704770B5494D28680026E4 +:1029A000544C012806D1A068C00303D501200004BF +:1029B000A0602E606868012809D1A068800306D550 +:1029C00001204004A0606E6001200EF05BFAA86850 +:1029D000012809D1A068400306D501208004A06029 +:1029E000AE6002200EF04EFA70BD10B5484908786E +:1029F000002818D00120424AC0039060414A40009C +:102A000090602B4A001210603F4A00201060304A4C +:102A100010603E4A106008704A78002A02D0487060 +:102A20000EF030FA10BD0320FAE7012040490006FD +:102A300008607047012023490006086070470120A4 +:102A40003B4940050860704701201E494005086069 +:102A5000704730490020C8637047410A354AC005B5 +:102A6000C00D5043801C5143400A0818704710B4F1 +:102A7000314C430B63431B0C5C020C602D4C6343D5 +:102A8000C31A2E485C0258432A4B400D4343E31AB5 +:102A90000124DB0324041B191B1613700A68101889 +:102AA000086010BC704710B50EF0B6FA10BD0000FB +:102AB00080E100E008E400E018E400E000B000403D +:102AC00040B1004080E200E000E100E048B1004099 +:102AD0004081004044B100407372635C72656D5F79 +:102AE00068616C5F6576656E745F74696D65722E82 +:102AF0006300000000B3004040B3004040B5004018 +:102B000000F5014000830040408500400082004005 +:102B100045000020C08F004000850040008000403C +:102B200080F5014044B5004048B5004000B5004084 +:102B300000E200E0093D0000378600006F0C010054 +:102B400010B50EF055FA10BD012001218140064A52 +:102B5000116000BF00200549C8630120C8637047A9 +:102B600000200249C863704780E100E0C01F0040B8 +:102B700070B5FF4D044629680300A03110F0A6F897 +:102B800008053E08080E1D2C3242FAA1D22033E07F +:102B9000887F012832D0F7A1D8202DE001F058FE1F +:102BA00005282BD001F054FE062827D001F050FE56 +:102BB000072823D0EFA1DB201EE001F049FE032807 +:102BC0001CD001F045FE062818D001F041FE072870 +:102BD00014D0E8A1E0200FE0887F05280ED0E5A101 +:102BE000E52009E001F034FE052807D001F030FEB1 +:102BF000062803D0DFA1E8200FF063FF2868A0308B +:102C0000847770BDDBA1EC20F6E7D949C1220968C1 +:102C1000525CD206920F05D1A0318A8A824201D13C +:102C2000887D70470020704770B5044611202070E1 +:102C30000021CF4D61702968C0318978002908D002 +:102C400003290ED0042910D0FF20CAA116300FF09E +:102C500038FF20780009012802D92868807E60703A +:102C600070BD0007000F203002E00007000F303079 +:102C70002070EEE730B50388C249C34C8B4202D0C6 +:102C80009A1FA2421ED242888A4202D0951FA542B4 +:102C900018D2934216D883887D24E400A34211D829 +:102CA000C088884205D0B84D04460A3C2D1FAC426E +:102CB00008D2884208D08A4206D05B1C5A43C00022 +:102CC000824201DD072030BD002030BDFFB500226B +:102CD000099B002802D0994205DC5CE0002902D162 +:102CE000002004B0F0BD0920FBE7845C002C12D06A +:102CF00085186F780D2F4CD010DC3B000FF0E6FFED +:102D00000A421B2A2A303032323A3A42835C002B84 +:102D10003FD1521CD2B28A42F8DBE1E7122F31D008 +:102D200004DC0E2F35D00F2F2CD132E0142F11D010 +:102D3000152F27D116E0022CD5D1AB78039C072B99 +:102D4000237001D25B0701D40A20CAE7029B012449 +:102D50001B7814E0E343DB0708E0012C08D011E006 +:102D60000620BEE70F2523072D075B19002BF4D0A3 +:102D70003046B6E7029B1B789C070AD40224234303 +:102D8000029C2370835C521C9A18D2B28A4204DDE2 +:102D9000A9E70B20A5E7192676028A42A5DB9FE763 +:102DA00005E00278401C002A01D0002070470A4646 +:102DB000491E89B2002AF4D10120704730B56C4D0C +:102DC0000021286887B0C943A0308182002484751F +:102DD000214606200DF0E3F9002105200DF0DFF972 +:102DE000002102200DF0DBF90120FFF7C1FE286869 +:102DF000BF210C54C0300470012069460870684639 +:102E00000BF08FF807B030BD10B5594A94B0126876 +:102E1000A032927F042A0AD028236A461370508079 +:102E2000132906D03B2904D0072014B010BD082078 +:102E3000FBE71171104609A909F07AF8040002D1E4 +:102E40000420FFF795FE2046EFE7F0B59BB00400A5 +:102E500003D148A14D480FF034FE72202070606805 +:102E6000002701780826491F414D0B000FF02EFF67 +:102E70000F096ECBFB6E70F9F8AA6E6E6E6EF7F6E8 +:102E80006E002868A030807F032804D0972039A1E5 +:102E900080000FF016FE002108460DF080F96078E2 +:102EA00010233043607028680146C0314A781A43C5 +:102EB0004A7061688A783C2A45D08E880146012292 +:102EC000A0318A756268D2890A836268128A4A834D +:102ED0006268528A8A838E8261680622C979C173C8 +:102EE0006168103008310FF04FFC0520FFF740FEFD +:102EF0002868C2210F54017FFB2211400177B021C5 +:102F000009584A7A920892004A72C782304602F003 +:102F1000B5FC002804D01D4816A122300FF0D1FDC9 +:102F2000304601F0C7FE002804D04F2011A1C00098 +:102F30000FF0C7FD304603F00FFB002806D0134802 +:102F40000CA1273023E10120FFF712FE1BB0F0BDDA +:102F5000878801F07DFC052820D001F079FC062847 +:102F60001CD001F075FC072818D001F071FC0FE0AF +:102F7000480000207372635C6761705F636F726505 +:102F80002E630000FFFF00007B0C000053020000D6 +:102F9000042803D0FB49FC480FF093FD60783043D0 +:102FA00060702868C030417831434170FFF706FFF8 +:102FB000384602F068FC384601F082FE384603F0DD +:102FC00001FBC3E701F044FC052810D001F040FCF0 +:102FD00006280CD001F03CFC072808D001F038FC92 +:102FE000042804D0E848E74913300FF06AFD606810 +:102FF000807902F000FD0028A8D06178314361702B +:103000006168C880A2E701F023FC052810D001F018 +:103010001FFC06280CD001F01BFC072808D001F08B +:1030200017FC042804D05520D649C0000FF049FDF4 +:103030006078304360706068C1882868A030018380 +:10304000616809894183616849898183002102207F +:103050000DF0A5F82868A030C77777E70CE167E1A5 +:103060006FE070E0FFE701F0F3FB052810D001F0FE +:10307000EFFB06280CD001F0EBFB072808D001F08D +:10308000E7FB042804D0C048BE4935300FF019FDD5 +:103090002868BE21095C042993D0807D40063CD578 +:1030A000606802210C30FFF77BFE002835D0606895 +:1030B0000821001DFFF774FE00282ED02868014665 +:1030C00080310A6B527A920708D1C222125C002A20 +:1030D00008D1C28AD30505D5D20703D1C38A4022BD +:1030E0009343C382C38A80229343C3822D236A46BB +:1030F0001370A030808A5080CB698A694869096A58 +:1031000001AC0DC4049109A9684608F011FF00281C +:10311000A3D09D489B49573039E062682868A421B4 +:1031200092890A5261680822091DA6300FF02CFB13 +:1031300010A806742868A630159014A80AF0F1FEAD +:1031400004E70121817101F083FB052810D001F013 +:103150007FFB06280CD001F07BFB072808D001F08C +:1031600077FB042804D0884886497B300FF0A9FCFF +:103170002868BE21095C0429E2D061688A79002AA6 +:1031800002D08978002905D07F487E49E1300FF0D0 +:1031900098FCDBE6617831436170B0210958497AC7 +:1031A0008907890F01294DD1817D09064AD4017F04 +:1031B000490701D5042100E00321C03081702B2094 +:1031C0006946087009A9684608F0B2FE002804D0D4 +:1031D0006D486C4997300FF074FC69462868098D7A +:1031E00001830E2210A90A7468491591027A0A70A7 +:1031F000024609324A600F320A61521D8A6010325B +:10320000CA60133A4A618A328A61921CCA61423AA0 +:103210000A6210324A6210328A62403A8A63D21FCE +:10322000CA63521C54300A64486414A80CF004F8B1 +:10323000022815D0002813D053485249BF300FF050 +:1032400040FC0DE0817D4906017F490701D504213D +:1032500000E00321C0308170002106200CF09FFFA8 +:103260002868C18A0A0602D440229143C1828AB2E8 +:1032700080218A43C28269E62868A030807F0328C3 +:1032800004D041483F49ED300FF01BFC00210846B7 +:103290000CF085FF60781023304360702868014689 +:1032A000C0314A781A434A7061688A783C2A00D152 +:1032B00049E68E8801460122A0318A756268D2896A +:1032C0000A836268128A4A836268528A8A838E827B +:1032D00061680622C979C1736168103008310FF046 +:1032E00053FA0520FFF744FC2868C2210F54017FE0 +:1032F000FB2211400177C782304602F0BFFA002856 +:1033000004D0E3201F4980000FF0DBFB304601F0C2 +:10331000D1FC002803D01B491D480FF0D2FB3046DA +:1033200003F01AF90028A6D019481649801C2EE788 +:1033300060783043607009E600290BD0888015481A +:103340000068A030028BCA80028B0A81428B4A81BE +:10335000808B88817047F7B5064600780C460027B9 +:10336000010982B03D4601296FD00A4800680090EB +:10337000C03002296AD0072910D00A2967D0014934 +:103380000548DAE1742F0000860200000C120020CC +:103390008F030000480000201105000071680A78C2 +:1033A000521F13000FF092FC0F09B054B0B02F5B06 +:1033B0005B47B0B0B0B0656FB0008A783C2A1BD0D4 +:1033C00010271625002C7DD08888A0807068A21D4B +:1033D000C08920827068C089E0817068008A60823C +:1033E0007068408AA082716808460831C07901F08F +:1033F00034FA0020607375E019270725002CE2D00D +:103400000021A17171E011270725002CDBD08988EC +:103410000091A1807168F7228979A17141781140EA +:103420004170009802F030FA009801F04DFC0098CD +:1034300003F0D6F8ACE101270925002CC3D0888819 +:10344000A080706880792072A2E160E09DE178E060 +:10345000888812270E252146FFF76EFF98E118276E +:103460000825002CAFD08888A080A01DFFF7DCFBCA +:103470008EE11A270725002CA5D04888A080706807 +:103480000079A07184E18A783C2A32D01027162571 +:10349000002C98D08888A0807068C08920827068CD +:1034A000C089E0817068008A60827068408AA0826A +:1034B0007168607B497D40084000C907C90F084317 +:1034C000607300E036E17168C007497DC00F4908AC +:1034D0004900084360737168A21D08460831C0792D +:1034E00001F0BBF9FB480068C0304178EF22114081 +:1034F00031E119270725002C88D00021A1714278DD +:10350000EF210A40427043E1F349F44815E1307A73 +:10351000012803D0F148F04917300EE112270E259B +:1035200070892146FFF708FF002C87D0707840078C +:10353000400F032888D1E7480068C0304178FB225B +:10354000D5E7E4490968A031002C01D08A8AA2801D +:10355000327A921E13000FF0B9FB073B4651EEDBA7 +:103560006B05EE0013270C25002C85D0F1688978B7 +:103570008907890F0129217A27D04908490021723A +:10358000FD221140F268E32392785207D20F5200D5 +:10359000114321720022E2801940F3681B785B0717 +:1035A000DB0E19432172DF231940F3685B78DB07D8 +:1035B0009B0E194321726272F1680122C978A172CF +:1035C00001781143F722114016E001221143D6E79A +:1035D00015270C25002C8FD0F06806220068A11D4D +:1035E0000EF032F8D4E016270725002C84D0317B6A +:1035F000A1710178082219E00170C9E01427122591 +:10360000002C92D000980099C07BA21D103101F0CF +:1036100024F9B089E081207C01210843F921084088 +:103620002074AC480068C030017802221143E3E7FF +:1036300017273825002C7DD03221A01D0FF001F96D +:103640000020A071207A03210843A24A2072116849 +:10365000FB260B7F30405B07DB0F9B00184320727B +:10366000B0204058407A800751D0A07A8A7D400827 +:10367000D2074000D20F1043FD221040A0728B7D74 +:1036800030409B07DB0F9B00184308231843EF23B0 +:103690001840A0728A7DE07AD206D20F30409200A4 +:1036A0001043E072F72210408A7DD206D20FD2007A +:1036B0001043E072088BA0812046102264310E3046 +:1036C0000FF062F88349A07F0968C0078A7EC00FA7 +:1036D00052001043A0770A7F400852074000D20FE3 +:1036E0001043A077084644304DC820344DC4303CC8 +:1036F0003D20405C224630323E3101F0AEF8754844 +:1037000000688030006B417A8908890041723FE08F +:10371000327B022A14D017273825002C2ED0012AFC +:103720001BD0032A1BD0042A1CD0052A1AD06A49B0 +:103730006A4801E022E024E0B1300FF0C2F927E04E +:1037400019270725002C19D0898AA1800121A17190 +:1037500041784908490041701AE0012000E0022048 +:10376000A07106E0707B0007000F8030A071052A71 +:1037700002D00020E0710BE00120FBE704980580F7 +:103780000CE09F205449C000D7E7317A002908D0C7 +:103790000498002C058001D027806580002005B0AA +:1037A000F0BD19270725002CE8D00021C943A180CE +:1037B0000021A1714178FD2299E600B595B001F094 +:1037C00047F8022803D001F043F8032819D11B2140 +:1037D00008A801730021817369460BA808F0A8FBB3 +:1037E000002804D1684640781B2802D0032015B079 +:1037F00000BD002108460CF0D2FC68468078002805 +:1038000001D00820F3E70120FFF7B2F90020EEE72E +:1038100070B500252F4C002807D0022817D0A9200A +:103820002D49C0000FF04DF970BDFFF7C6FF00280D +:10383000FAD1FEF7DDF9222101700572FEF7F4F9E5 +:103840002068C030417802221143417070BDFEF7FC +:10385000CFF912210170012101722168A0318A8AF9 +:103860004281CD77FEF7E0F92068C030417804222C +:10387000EAE770B50D46040004D155201649000151 +:103880000FF01FF92078012804D0134914480FF0D5 +:1038900018F970BDA18813480E4E814209D1E28803 +:1038A000824206D130681321A030808AFFF7ACFA3B +:1038B00070BD814202D1E088002815D01220287006 +:1038C000687808210843687007CC083507C50021CF +:1038D00011E0000048000020742F00003D040000AB +:1038E0006E050000FFFF0000002278231146022031 +:1038F0000CF0B3FB02213068A030C17770BDF748EF +:103900000068C0308078704738B5F44C05460178BF +:1039100020680B00A0300FF0D9F909863506067132 +:1039200013365A758600807F052803D0EC49ED4890 +:103930000FF0C7F820680422017F114301775DE092 +:10394000A98800291ED0808AE74988421AD0A86831 +:10395000002804D1E348E2490F300FF0B2F8A8681C +:1039600006220A38A86000902068AB88A030808AC0 +:10397000042101F0B7FE002804D0DA48D8491430F9 +:103980000FF09FF838BD2979807F02290BD00428D9 +:10399000F8D0284600F072FF20681321A030808AFA +:1039A000FFF732FA38BD062804D0CE48CC491E3085 +:1039B0000FF087F8284600F061FF20680122C03030 +:1039C0004178114341700520FFF7D2F838BD00F06F +:1039D0003FFF052808D000F03BFF042804D0C14871 +:1039E000BF493C300FF06DF80ECDC0480361C26096 +:1039F0008160A2210170FEF72CF938BD284600F045 +:103A00003DFF38BD00F024FF052808D000F020FF5E +:103A1000062804D0B348B2494D300FF052F80720C1 +:103A2000FFF7A6F8EAE7AF48AD495630A8E7FFB57B +:103A300093B00124684603218470C9021D460180A9 +:103A400009F063FF00226946012003F027F80646CB +:103A500009F05FFF002E5CD1684615218470490291 +:103A6000018000271C2101A808970EF0ECFE012020 +:103A70000146103108A801700020014608A84170D5 +:103A80008178F9200140891C214308A8817068468B +:103A9000017902263143017114998185C7851F215F +:103AA000018608A80A9013980D906846099009F0BD +:103AB0002CFF0EAA09A901A802F0D4FD074609F0BF +:103AC00028FF002F02D0384617B0F0BD834F68465C +:103AD0003968008F4880684684708549018008A84D +:103AE0008078F9210840801C4108490008A88170AD +:103AF00068468685068615A80D9009F006FF0EAA71 +:103B000009A901A802F0AEFD064609F002FF002E49 +:103B100001D03046D8E768463968008F88807449FC +:103B200068468470C91C0180298810A801806988B2 +:103B30004180A9888180E988C18008216846818503 +:103B4000018610A80D9009F0E0FE0EAA09A901A8AF +:103B500002F088FD044609F0DCFE002C01D020466E +:103B6000B2E768463968008FC8800020ACE770B5BE +:103B700004465E48C421A8300EF065FE5B48574DF0 +:103B8000A83000212860C943A030818200268675B4 +:103B90000120FEF7EDFF2868BF210E5401460931D0 +:103BA0000830FDF71CFF296808462D311D30FDF750 +:103BB00072FF002C26D02868B0210C501E21A18154 +:103BC000217A8F2211401031217201461831216172 +:103BD00009396161491CA1610839E161491C21620F +:103BE0009B31616287392160103161601339E16274 +:103BF000091F21637E3121643039616310318430C3 +:103C0000A163E06370BD35480068A030807F042860 +:103C100001D0002070470120704730B504460520D0 +:103C2000800395B0844208D3012080043149201AD2 +:103C3000884202D33048844202D3102015B030BDF0 +:103C400026490868A030807F012801D00820F5E7C8 +:103C5000FFF7D9FF002801D01120EFE70D68012000 +:103C600028722278002A08D024491720012A0AD075 +:103C7000022A1FD0032A25D121E03220694608708C +:103C80000020287205E0A2799209032A1AD1694618 +:103C9000087000A80622611C02300EF075FD28464F +:103CA0000622611C09300EF06FFD09A9684608F074 +:103CB0003FF9C3E7A2799209012A03D1E7E7A27984 +:103CC0009209E4D00846B9E707214907012210B557 +:103CD00041189203914213D3102010BD48000020D8 +:103CE000742F000085050000FFFF0000AC110020CC +:103CF000012A00000000FC1F0040002002320000EA +:103D0000F949024609680B7A0931184600F0A5FD09 +:103D10000020E2E7FFB599B005460020694608712A +:103D2000087208A9087408751E461446052001216A +:103D300080038904ED4AEE4B002D06D085420DD359 +:103D40006F1A97420AD39D4208D2002C09D08442B0 +:103D500004D3601A904201D39C4202D310201DB0BC +:103D6000F0BD2846204318D01F270CAB01AA0097AE +:103D700028461A99FEF7AAFF0028F0D10DAB02AA37 +:103D8000314620460097FEF7A1FF0028E7D168469C +:103D9000007AC10703D00A20E1E70720DFE78007A8 +:103DA00005D568460079800701D50B20D7E7FFF7D6 +:103DB0002AFF002801D01120D1E703AF002D0FD03A +:103DC0001A20694608731A9888732946F81C1A9AAB +:103DD0000EF0DAFC0EA903A808F0AAF80028BED15C +:103DE000002C0ED02021684601738673324621468E +:103DF000F81C0EF0C9FC0EA903A808F099F80028D9 +:103E0000ADD1B94908A80968007C08700020A6E770 +:103E1000F0B5044695B0002014900520800384423C +:103E200075D301208004B14F201AB8426FD3B04837 +:103E300084426CD2207801280CD105216068890366 +:103E4000884264D301218904411AB9425FD3A84949 +:103E500088425CD200F0FCFC022809D000F0F8FC9B +:103E6000032805D0A048BE210068095C012902D0C2 +:103E7000082015B0F0BDC121095CCA06920F03D11C +:103E80008A0701D4490701D51120F2E721780129D9 +:103E900015D0228A974D1346203BAB4272D202299D +:103EA00001D0032901D1A02A6CD3012907D00278BF +:103EB000D20704D0628A002A64D0B42A62D80029CA +:103EC00006D0012908D0022904D003295AD110E0D4 +:103ED000002512E0022510E061680125097800291B +:103EE0000BD0012907D0022905D0032903D082482D +:103EF000BFE7032501E001211491217A002907D0B1 +:103F0000012907D0022907D003293BD106E037E079 +:103F1000002604E0012602E0022600E00326002D30 +:103F200001D0022D3FD1002E3DD0E168002929D0DB +:103F30000A79002A27D0082A24D80B7B9C46082B14 +:103F400020D8002A0CD005230A689B039A4217D375 +:103F500001239B04D31ABB4212D3654B9A420FD262 +:103F60006246002A13D0896805229203914207D342 +:103F7000012292048A1ABA4202D35D4A914206D3C0 +:103F8000102076E75EE00B7B002B5BD0D5E7017855 +:103F9000890702D05848401E6BE7022D03D1022E3C +:103FA00050D0032E4ED0182269460A70228A4A80C9 +:103FB000228A8A808D71007A0127002802D0012888 +:103FC0007ED102E00020C87100E0CF711498087221 +:103FD000217802A80130012922D006210EF031FCFF +:103FE00007216846C173067409A907F0A1FF0028DC +:103FF000C7D10A206946087009A9684607F098FFEA +:104000000028BED13A206946087009A9684607F021 +:104010008FFF0028B5D1002D08D0022D06D04AE030 +:1040200061680622491C0EF0AFFBD9E7002E42D092 +:10403000002623E00168B00009580978002903D060 +:10404000012905D0072014E700216A46917001E09C +:1040500069468F70E16806220968095800A8491C62 +:1040600003300EF091FB0B206946087009A96846E1 +:1040700007F05EFF002884D1761CF6B2E068017973 +:10408000B142D7D8002612E08068B100415800A89C +:10409000102202300EF078FB3B206946087009A917 +:1040A000684607F045FF0028CDD1761CF6B2E068DF +:1040B000017BB142E8D81B2168460170877000E09F +:1040C0002EE009A907F034FF0028BCD108A84079E8 +:1040D0001B2825D1002D15D0012D0FD0022D21D068 +:1040E000032D12D11EE00000480000200000FC1F3C +:1040F00000400020E13F0000023200000320FEF7F4 +:1041000037FD11E00320FEF733FD608A00280BD055 +:1041100000228300114610460BF09FFF002803D0B9 +:104120000320A6E60220EEE70020A2E670B586B0E6 +:104130000C0006460CD00520800384424BD301209E +:104140008004FD49201A884245D3FC48844242D26B +:10415000FB4DBF212868095C022903D0C03040789C +:10416000400702D5112006B070BD002C04D02046B7 +:10417000FEF780FD0028F6D13046FEF746FD012807 +:1041800003D0022823D0EF48EDE721001BD10820FF +:1041900069468882286801ABC08805AA002103F01F +:1041A00048F80028DFD16846808A082801D003201B +:1041B000D9E7684681888181C188C18101890182EE +:1041C0004189418203A9304601F0E5FBCBE7002C91 +:1041D00001D00620C7E71020C5E770B50C4605469C +:1041E000FEF713FD012803D0022801D0D54870BD89 +:1041F00021462846FEF708FE70BD00B50146143082 +:1042000095B0192801D2880707D008461E3004D07F +:104210000A3002D0072015B000BDFFF7F4FC0028DB +:1042200001D01120F7E7C648312200684170684686 +:104230000270817009A907F07BFEECE701B582B03E +:10424000022069460880BE4802AB00686A46808842 +:10425000002102F073FE69460988022900D003207C +:104260000EBD38B502216A46118007214907012297 +:1042700041189203914201D3102038BDB049034642 +:1042800009686A468C880021204602F0D2FF694600 +:1042900009880229F1D0032038BD3EB50446082024 +:1042A0006946088005208003844208D301208004E9 +:1042B000A149201A884202D3A048844201D3102089 +:1042C0003EBD2046FEF7D6FC0028F9D1208869467D +:1042D00088806088C880A0880881E08848819848E4 +:1042E00001AB00686A46C088002102F027FE6946DB +:1042F00009880829E4D003203EBD1FB504460820E4 +:104300006946888105208003844208D30120800407 +:104310008949201A884202D38848844202D3102057 +:1043200004B0DAE486486B46006803AAC08800211E +:1043300002F07FFF0028F3D169468989082901D05E +:104340000320EDE769460988218069464988618034 +:1043500069468988A1806946C988E180E0E7FEB5A1 +:1043600005460520800317460E46814208D30121E9 +:104370008904714A731A934202D3704B9E4201D34F +:104380001020FEBD1F2F01D90C20FEBD6C4C8542B4 +:104390002AD3681A904227D39D4225D2206801A9CA +:1043A000408802F07DFD0028EFD1287869464871E9 +:1043B000206801A9408802F056FD0028E5D1694631 +:1043C0000090087802210843694608704979090776 +:1043D00003D0082108436946087020686946408870 +:1043E00002F0EBFC0028D0D169460F8120683346EB +:1043F000408802AA002102F0A1FD69460989B9425C +:10440000C3D00320FEBD38B50C4607210122490761 +:104410009203002802D04318934202D261189142BD +:1044200001D3102038BD21886A461180002801D0B0 +:1044300000290BD04249034609684D8800212846CF +:1044400002F0F7FE69460988218038BD0C2038BD8E +:1044500010B50C460521890386B08C4208D3012192 +:104460008904354A611A914202D334498C4202D3FD +:10447000102006B031E432490968A031897F05294E +:1044800001D00820F5E7FEF7C0FB012803D0022881 +:1044900026D02C48EDE720881E2801D20720E8E727 +:1044A0000620FEF765FB052168460170007981084A +:1044B000A0788900C007C00F014368460171FB2046 +:1044C0000140A0788007C00F800001436846017159 +:1044D0002188C18009F025FD0028CAD00320C8E743 +:1044E0000620C6E770B586B014460D46FEF78DFB74 +:1044F000012803D0022801D0124834E6104EC02112 +:104500003068095CC90706D0BE21095C042902D0C5 +:10451000002D02D05AE0082025E6052189038C42AF +:1045200008D301218904044A611A914202D3034944 +:104530008C4209D3102016E60000FC1F004000202A +:104540004800002001300000A178C906490F042965 +:104550000CD8E178072909D3102907D822798A4293 +:1045600004D3102A02D822881E2A01D00720FAE597 +:104570008030026BF7239172026B2179D172026B4A +:10458000117A1940A3789B06DB0FDB0019431172E7 +:10459000026B21889181026BA378517ADB0789082D +:1045A0008900DB0F19435172FB231940A378026B7A +:1045B0009B07DB0F9B0019435172006BA278017AB5 +:1045C000D206C908C900520F114301720B20694677 +:1045D0000870852D25D008DC002D1AD0812D1AD029 +:1045E000822D1AD0832D08D119E0862D1BD0882D5D +:1045F0001BD0892D1BD08A2D1BD00B2008710520C4 +:10460000FEF7B6FA684609F08CFC002813D00320A8 +:10461000A9E50020F2E70120F0E70220EEE7032001 +:10462000ECE70520EAE70620E8E70820E6E70920AE +:10463000E4E70A20E2E73068C03001784908490021 +:10464000017000208FE570B5924E0D46316886B03E +:10465000C03109781446090701D4082083E5FEF724 +:10466000D4FA012803D0022801D08B487BE5002D25 +:1046700013D005208003844208D301208004874999 +:10468000201A884202D38648844201D310206AE56A +:10469000012D0BD0022D02D106E0002C01D0072005 +:1046A00061E50020029005E0022000E0012069465B +:1046B00008710294032069460870684609F031FCCD +:1046C000002801D003204EE53068F722C030017881 +:1046D00011400170002046E570B594B014460E46B6 +:1046E000FEF793FA012804D0022802D06A4814B0D9 +:1046F00070BD684D2868C0300078800701D408205C +:10470000F5E7002C01D00720F1E7FFF77CFA00283D +:1047100001D01120EBE7002E1DD02D21684601703D +:104720002C68B420015B684641801022B11C01A8AE +:104730000EF02AF8207FFB210840B17CC907490F01 +:1047400008432077B07CFF214008A076E08A8231C0 +:104750000843E08207E02E21684601702868A030F7 +:10476000818A6846418009A9684607F0E1FB29680B +:10477000FD23C0310A781A400A70B8E710B50C461C +:10478000FEF743FA012803D0022801D0424810BDA9 +:1047900005208003844208D3012080043F49201A69 +:1047A000884202D33E48844201D3102010BD2046E7 +:1047B000FEF73AFA002010BD10B594B00446FEF79B +:1047C00024FA012804D0022802D0334814B010BDC6 +:1047D00030480068A030807F04280ED03820694619 +:1047E00008704C8001200871487109A9684607F0DB +:1047F0009FFB0028EAD00B20E8E70020E6E710B591 +:1048000094B00446FEF701FA012803D0022801D033 +:104810002148DBE71F480068A030807F04280BD0C8 +:104820003820694608704C8000200871487109A939 +:10483000684607F07DFBC9E70020C7E71548006818 +:10484000A030807F052801D30120704700207047E9 +:1048500010480068A030807F704708B513460028D4 +:1048600006D010A00068009048796A468009105C64 +:1048700018700622581C0DF087FF08BD10B50446BD +:10488000FDF7B6F9A22101700ECC08300EC0FDF77D +:10489000CBF910BD48000020013000000000FC1FD3 +:1048A000004000200302FF01FFB581B001980E46D1 +:1048B000C078174610360E37022809D0032840D09A +:1048C00005287DD0F2A1F7480EF0FBF805B0F0BD49 +:1048D000CC890A2060430E30188031230A98002AC0 +:1048E0000380F3D04868008890800020D080108139 +:1048F000097B9481891FCDB21AE0308871683880B5 +:1049000048780A7800021043F880C8788A78000254 +:1049100010433881BA1C091D28460AF014FF002DE7 +:1049200001D0002802D000203871788008360A377C +:104930002046641EA4B20028DFD101990020C8706F +:10494000C4E7CC890A2060430E30188032230A98CD +:10495000002A0380BAD04868002500889080D5805E +:104960001581087B401FC0B20090948142E07168BD +:1049700032880878FA803A79C30752085200DB0F70 +:104980001A43FD231A408307DB0F5B001A43FB2306 +:104990001A404307DB0F9B001A43F7231A40030713 +:1049A000DB0FDB001A43EF231A40C306DB0F1B01AA +:1049B0001A43DF231A408306DB0F5B011A4300E032 +:1049C00020E0BF231A404306DB0F9B011A433A71D4 +:1049D000C00978718A784B781002184338813A46BA +:1049E000C91C00980AF0AFFE002801D0BD703D80C0 +:1049F00008360A372046641EA4B20028B7D10198B1 +:104A0000C57063E7087BCC89801E85B228460830D4 +:104A100060431030188034230A98002A03808FD016 +:104A200048681746008890800020D08010819481CB +:104A30001037E000D581C0190CE03088388000982C +:104A400078602A46716800980DF09EFE009808363E +:104A50000837401900902046641EA4B20028ECD10B +:104A60006BE7FFB50546C07881B00C460A9E03008F +:104A70000EF02CF90BA3071733414F6D8F9D9D9DB1 +:104A8000A300207B1746082806D0032804D08548B9 +:104A90007FA153300EF015F804990E2008803020C5 +:104AA0000CE0207B1746042804D07E4878A17030A3 +:104AB0000EF007F804990E20088031203080002F76 +:104AC00044D060680088B880607AFF300130F88098 +:104AD000E08938810020B88137E0207B1746042820 +:104AE00004D070486AA18C300DF0EBFF04990E20C1 +:104AF00008803220E2E7207B1746022804D069486C +:104B000063A1A8300DF0DDFF04990E20088033204A +:104B1000D4E7207B1746042804D062485CA1C33048 +:104B20000DF0CFFF04981021018034203080002F39 +:104B30000CD060680088B880607AFF300130F8805F +:104B4000E08938810020B881F881E870BEE6207BDA +:104B50001746052806D0062804D052484CA1E0305C +:104B60000DF0AFFF04981221018035203080002F16 +:104B7000ECD060680088B880607AFF300130F8803F +:104B8000E0893881E089B88100203882A988F981DC +:104B9000DBE7207B1746072804D042483CA1F730CA +:104BA0000DF08FFF04990E200880362086E70096CE +:104BB0002846049B00F02BFD88E635A13A480DF00D +:104BC00080FF83E670B5054600780C460826030092 +:104BD0000EF07CF8124C3434241C380A0A0A0A0AF3 +:104BE0000A0A0A0A0A0A0A4C6878002804D02E48E1 +:104BF00027A12C300DF065FF002C03D12A4824A1F9 +:104C00002D3008E060783043607020E0002CF9D14E +:104C100025481FA135300DF054FFF3E7002904D0DB +:104C200021481BA13D300DF04CFFFCF7E1FF04468D +:104C3000407830436070FCF7F7FF08E01A4814A191 +:104C4000473002E0184812A14C300DF03AFF002C1A +:104C50000AD06078000707D593202070204658229C +:104C600029460830FBF7B0FA002070BD0E4808A1B5 +:104C70005030EAE710B500200C4C0D490346C20045 +:104C80008C525218401C0006D370000EF7D010BD95 +:104C90007372635C67617474635F636F72652E63C4 +:104CA000000000005A020000B2030000FFFF0000F5 +:104CB0004C000020FD4908800120887000207047CA +:104CC000FA4900208870704710B50021F748C943A1 +:104CD00001800021C17007F065F9D8E7F7B584B00D +:104CE0000546002768460781878068680C4600886B +:104CF00000F0EAFB0646287A032805D0002E03D1EF +:104D0000EB49EC480DF0DDFE287A2146C01E123139 +:104D1000009103000DF0DAFF0FF1F0EF3D09AA4614 +:104D20005C6D34B3CCF28B8BEF00F078012803D0AC +:104D3000DF49AD200DF0C5FEA8896946C0000E30E0 +:104D4000888030200881002C22D068680188A180EA +:104D5000E7802781A989A18100200DE0C100B279F7 +:104D600009190A74B288CA8182005219D3894B8208 +:104D7000128A401C8A8280B2A1898142EED8D6E094 +:104D800002A8009001AB22462946304600F0CAFB3B +:104D9000F0E002A8009001AB22462946304600F020 +:104DA00003FCE7E0F07806281AD0FF20C049223043 +:104DB00014E068680188A180E7802781A989A18122 +:104DC000B188E181E9892182EA89296900982BE08B +:104DD000F078062804D0FF20B5493C300DF071FE74 +:104DE000E88969461230888035200881002CE0D19E +:104DF000C0E0F078072804D0FF20AD4956300DF010 +:104E000060FEA88969460E30888036200881002C13 +:104E1000BED068680188A180E7802781A989A18127 +:104E20002046AA890E3029690DF0AEFC7FE0E889A2 +:104E30006946123080B2382288800A81002C78D0EE +:104E400068680188A180E7802781A989A181287AE3 +:104E5000102809D00221A173E9892182EA892969F0 +:104E600000980DF091FC85E00121F4E702A8009084 +:104E700001AB224629463046FFF716FD7AE0F0786E +:104E8000082803D08A498C480DF01BFE142069467F +:104E9000888037200881002C6CD068680188A18048 +:104EA000E7802781A989A18167820120A0733EE064 +:104EB000F078092804D080487D4917300DF001FEB4 +:104EC000288A69461430888037200881002C51D008 +:104ED00068680188A180E78004212781A173A989DE +:104EE000A181E9892182298A618220462A8A143097 +:104EF000696999E702E038E01CE024E0F0780A28CC +:104F000004D06D486A4932300DF0DBFD142069464B +:104F1000888037200881002C2CD068680188A18007 +:104F2000E78027810521A173A78127826782F77017 +:104F300020E017E002A8009001AB22462946304647 +:104F4000FFF78FFD16E00D206946392288800A811F +:104F5000002C07D00120E08054480188A1802781DF +:104F6000277307E00699088010E0524850493C300A +:104F70000DF0A7FD6846069980880880002C05D0B2 +:104F8000684600892080684680886080002007B0DD +:104F9000F0BDF7B594B015460F46149800F09FFA8F +:104FA00004000AD0032000F087FB022802D2E07838 +:104FB000002804D0112017B0F0BD4048FBE71720AF +:104FC000694601260883002D0FD003216846017130 +:104FD0001021018210A80246059004A928460AF073 +:104FE000D8FB00280DD00720E5E7082168460171AD +:104FF00000210781C943418105218673C90281814E +:105000000CE0A878A0712888A080684605218673E6 +:10501000C902818100210781C943418109AA023265 +:1050200006A901A806F0F7FF002802D000F06AFAEE +:10503000C1E707A800906846038B04220321149857 +:1050400000F050FB0028B6D1E670B4E770B592B01E +:105050000D0006460ED000F042FA04000CD00320EA +:1050600000F02AFB022802D2E078002806D01120A6 +:1050700012B070BD1020FBE71048F9E71721684611 +:10508000818004210172298881816988C18101217F +:1050900081740B4901820AAA023201A902A806F012 +:1050A000BAFF00280ED000F02DFAE1E74C000020F6 +:1050B000904C00003B04000063020000013000003F +:1050C0000228000008A80090684683880422032173 +:1050D000304600F007FB0028CAD10221E170C7E783 +:1050E00070B592B00D0006460DD000F0F8F904003E +:1050F0000BD0032000F0E0FA022802D2E07800286A +:1051000005D01120B4E71020B2E7FA48B0E7172124 +:105110006846818004210172298881816988C18162 +:1051200001218174F44901820AAA023201A902A86C +:1051300006F071FF002802D000F0E4F998E708A813 +:1051400000906846838804220321304600F0CAFAA2 +:1051500000288DD10321E1708AE770B592B00D006F +:1051600006460DD000F0BBF904000BD0032000F080 +:10517000A3FA022802D2E078002805D0112077E7B0 +:10518000102075E7DB4873E7022168460172298821 +:1051900081816988C181172181800AAA023201A90F +:1051A00002A806F038FF002802D000F0ABF95FE754 +:1051B00008A800906846838804220321304600F046 +:1051C00091FA0028DBD10421E17051E7F0B591B0EC +:1051D00015000E4607460ED000F081F904000CD0F1 +:1051E000032000F069FA022802D2E078002806D0F5 +:1051F000112011B0F0BD1020FBE7BE48F9E71721E0 +:105200006846818004210172298881816988C18171 +:10521000B1788174318801820AAA023201A902A8F8 +:1052200006F0F9FE002802D000F06CF9E1E708A8CA +:1052300000906846838804220321384600F052FA21 +:105240000028D6D10521E170D3E7F7B592B0154615 +:105250000E46129800F043F904000AD0032000F033 +:105260002BFA022802D2E078002804D0112015B0D1 +:10527000F0BDA048FBE70627002D12D06846077254 +:105280008681C581A5801720694688800AAA0232D6 +:1052900001A902A806F0BFFE002807D000F032F9ED +:1052A000E5E70521684601728681EBE708A80090D2 +:1052B0006846838804220321129800F013FA00281C +:1052C000D5D1E770D3E7F7B592B016460D000ED0F2 +:1052D000129800F004F904000BD0032000F0ECF960 +:1052E000022802D2E078002805D01120BFE7102064 +:1052F000BDE78048BBE7072768460772868117210C +:10530000049581800AAA023201A902A806F083FE50 +:10531000002802D000F0F6F8A9E708A80090684637 +:10532000838804220321129800F0DCF900289ED122 +:10533000E7709CE7F3B5172091B00C46002915D013 +:1053400021780B000DF0C2FC062B05051A041C2B5E +:105350001520C01EE28880B2002A02D0A368002B6C +:1053600004D0824204D90C2013B0F0BD1020FBE71A +:10537000042905D0A088002811D101E00620F3E718 +:10538000119800F0ACF805000BD02078092701280F +:105390001AD0022807D0042824D0052835D00720A9 +:1053A000E2E75448E0E76846077161880181E188D7 +:1053B0004181A06808260390304600F07DF9072857 +:1053C00029D34C48801CCFE70C21684601716188C5 +:1053D0000181E1884181A06803900EE0E87800280F +:1053E00011D118E00D216846017161880181A18801 +:1053F0004181E1888181A06804900326304600F055 +:105400005BF90228EAD31120AEE70E21684601714C +:10541000217B0172F1E717216846018309AA023254 +:1054200006A901A806F0F7FD002802D000F06AF8EE +:105430009AE707A800906846038B0422314611982A +:1054400000F050F900288FD12178012907D00229D6 +:105450008AD0042905D0052905D0032084E7082136 +:1054600002E0EF7080E70A21E9707DE730B591B086 +:105470000C46054600F033F8002808D0032000F061 +:105480001BF9022805D31B48801C11B030BD1948F8 +:10549000FBE70F216846017104811721018309AAE6 +:1054A000023206A901A806F0B6FD002802D000F0DD +:1054B00029F8EAE707A800906846038B0422032135 +:1054C000284600F00FF9E0E70C49884205D00C4966 +:1054D0000988814201D10A4870470020704710B501 +:1054E000FFF7F2FF002802D08178C90700D1002021 +:1054F00010BD00000130000003280000FFFF000085 +:105500004C000020002806D0012805D0052805D031 +:10551000062805D0032070471120704708207047E7 +:105520005C487047FFB583B003980C9EC0781D4659 +:1055300014460F46012803D05749D2200DF0C1FA76 +:10554000F889C0000E30288030203080387B001F62 +:10555000C0B20190002C26D078680088A08000207E +:10556000E0802081F889A081002616E0F00005196E +:10557000C01900902A4641690E3201980AF0E3F8FA +:10558000002802D000202874E8810098761C008A48 +:1055900068820098B6B2408AA882A089B042E5D855 +:1055A00003990020C870F2E4F8B50646C0781F469B +:1055B00014460D46042804D0FF20374903300DF06F +:1055C00080FAA889062148430E3038803321069896 +:1055D000002C01801AD068680088A0800020E0803C +:1055E0002081A989A18103460CE019460622514376 +:1055F0004A190919D789CF81977C8F74128A5B1C4D +:105600000A829BB2A1899942EFD8F070F8BD70B5BB +:1056100014460546142204981A8037220280002C72 +:1056200018D0486800260088A080487AFF300130F2 +:10563000E080C8892081C889A0816682E87808282E +:1056400009D0092811D00A2819D0134913480DF0A0 +:1056500038FAEE7070BD087B0C2804D00F480E4954 +:105660000C380DF02EFA012012E0087B0D2804D032 +:105670000A48094908380DF024FA042008E0087B9C +:105680000E2804D005480449001F0DF01AFA052021 +:10569000A073DEE702300000904C000081030000A0 +:1056A00001460020FA4A02E0401C082803D24300C9 +:1056B000D35A8B42F8D1704730B50446F44A0020E3 +:1056C000163A117953790AE05518AD79A54201D1FE +:1056D000401CC0B2491CC9B2102900D100218B4224 +:1056E000F2D130BDFFB5EA4881B0163841790A9C45 +:1056F000491CCDB21E46102D00D10025E4481638B5 +:105700000079A84202D1042005B0F0BD0820FFF7BF +:10571000D3FF0746072804D9FF20DEA1A5300DF0EE +:10572000D0F90298082801D1072F17D001982080BE +:10573000301D6080002060712071E6800398208118 +:10574000204606F019FC00280AD0D14802991638E4 +:105750004379821D995445710020D5E7D248D3E79B +:10576000FF20CCA1B7300DF0ACF90320CCE7F0B5A9 +:105770008DB0044600256846057116468C46062005 +:10578000FFF79AFF00281CD121780127C8070028BD +:1057900001D0132917D9684687766178C17602212E +:1057A0008183C58304A8009070680C2300880522BB +:1057B0000621FFF797FF002803D0B6A185200DF042 +:1057C00080F90DB0F0BDB24816380278002AF8D042 +:1057D000427863789A42F4D1012918D0132919D15B +:1057E0006146062916D10570002101200AF0D7FC78 +:1057F00068460771706801886846C1800021C94306 +:105800000181607922790102114368461AE06146FC +:10581000062908D0684600790028D2D0314601A870 +:10582000FEF727F8CDE70570002101200AF0B7FC4C +:105830006846077160792279010211436846018147 +:105840000021C9434181E9E7914810B5002116388C +:1058500001704A1E428041700171417101200AF0BD +:105860009EFC10BD10B5FFF7EFFF002088490246EF +:105870004300401CCA520828FAD310BD8449163987 +:10588000488000207047DFE770470EB50121684669 +:10589000017086498180C1800021FDF7EAFF0EBDBD +:1058A000F7B505460078002700090C463E4601285A +:1058B00004D0FF2077A168300DF003F9287A022880 +:1058C0000CD0FF2073A17E300DF0FBF80298002C65 +:1058D000068001D0278066800020FEBDEA897027FF +:1058E00010460A3086B2002C0BD068680088A08071 +:1058F000A8892081E28020460A3029690CF044FF03 +:10590000E4E702980680E7E7F0B543680246D979F4 +:105910009C79090221435C7A1E7A25025C88981DD5 +:105920003543241F87B0A1421DD11B79022B1AD108 +:10593000042D1AD0052D2AD0062D1AD0402D12D3B1 +:10594000061D0F4614462846FFF7AAFE08280AD06F +:105950001120207002202072A581E78126616078E5 +:1059600008210843607007B0F0BD001D00F0E1F8A9 +:10597000F9E7041D0D46FEF761FF0028F3D006216C +:10598000684601700194057208F0CBFAEBE7001D40 +:10599000FFF7EDFEE7E710B53D4C8AB0163C2278E4 +:1059A000012A26D012236A46937363789B1CD37313 +:1059B000082313820B8853824B8893828B88D3826F +:1059C000C988118301A900910C2305220721FFF743 +:1059D00089FE00280BD10022F023114601200AF095 +:1059E0003CFB012020706078801C607000200AB0B1 +:1059F00010BD1120FBE7F0B5254C0027163C87B001 +:105A00000646A51D1FE060792179884204D1112046 +:105A100020A140010DF055F82079405D042804D004 +:105A2000082808D17F1CFFB205E0072069460870EE +:105A3000684608F076FA2079401CC0B22071102820 +:105A400001D1002020713046761EF6B20028DAD14E +:105A5000384688E710B50446402801D2072010BD1B +:105A6000FFF71EFE082802D03120000210BD0021E1 +:105A7000074802E0491C082903D24A00825A002A3A +:105A8000F8D1082914D049004452002010BD00006C +:105A90002E1300207372635C6C326361705F636FFE +:105AA00072652E630000000003300000FFFF00005D +:105AB0000420EBE700B5402801D2072000BDFFF726 +:105AC000EFFD082805D000213B4A4000115208464E +:105AD00000BD052000BDF0B58BB016460C00074692 +:105AE00007D0002E05D06188402904D207200BB0D2 +:105AF000F0BD1020FBE72088002801D0172801D92D +:105B00000C20F4E70846FFF7CBFD08280FD02588C6 +:105B100003A82A46314602300CF036FE01A8009058 +:105B200062882B4608213846FFF7DCFDDFE70520B9 +:105B3000DDE7F0B50E46074601468BB01446012559 +:105B4000304606F0E5FB08281DD10020694608858F +:105B50000120FFF7B1FD002802D117206946088512 +:105B600003AB02330AAA39463046009406F0E3FF3D +:105B700000280AD0022819D0032804D0FF200F499A +:105B800002300CF09EFF2846B1E76846038D002BDB +:105B9000F9D001A800906068042200880121FFF775 +:105BA000A1FD0028EFD00549EC20EAE76078002548 +:105BB000102108436070E6E72E130020945A00007D +:105BC000002803D08178012939D101E010207047E5 +:105BD0000188FA4A881A914233D01BDCF84A881AA5 +:105BE00091422ED00BDC00292BD00320C002081AD2 +:105BF00027D0012825D001210903401A07E00128F8 +:105C00001FD002281DD0FF281BD0FF3801380028E4 +:105C100015D116E0FF220132811A904211D008DC22 +:105C200001280ED002280CD0FE280AD0FF2806D169 +:105C300007E0012905D0022903D0032901D0002063 +:105C400070470F20704700B50A2821D008DC0300F8 +:105C50000DF03CF80A1C2024241A24282224261A99 +:105C6000102819D008DC0B2816D00C2814D00D28C9 +:105C70001AD00F2808D111E011280FD0822807D0A0 +:105C800084280DD085280DD0032000BD002000BD44 +:105C9000052000BDCB4800BD072000BD0F2000BD82 +:105CA000042000BD062000BD0C2000BD70B50029F9 +:105CB0000BD0CB1FFA3B81241E46CDB2112B1BD239 +:105CC000012805D0022806D009E0002010701DE050 +:105CD000FF20043001E0FF200330814218D0330060 +:105CE0000CF0F4FF111613131613161613161616CE +:105CF00013131313161316000846FF3881381F2894 +:105D000003D9FF39FE39022902D81570002070BD71 +:105D10001470072070BD00B503000CF0D7FF060417 +:105D200006040C080A0C002000BD112000BD07204D +:105D300000BD082000BD032000BD00780207120F3F +:105D400004D0012A05D0022A0AD10EE0000907D1A9 +:105D500008E00009012805D0022803D0032801D05B +:105D60000720704708700020704706207047002801 +:105D700007D0012807D0022807D0032807D0072022 +:105D80007047002004E0112002E0212000E03120D3 +:105D900008700020704738B50C4605004FD06946A2 +:105DA000FFF7CBFF002822D12088032189028843F6 +:105DB000694609788907090D084320806946681CEF +:105DC000FFF7BBFF002812D1218803200003814385 +:105DD000684600788007800C01432180A87840073E +:105DE000820F2020012A03D0022A03D0072038BDC9 +:105DF000814300E00143218088B20105890F08D06A +:105E0000012189038843A9780907C90F8903084339 +:105E1000208080B28104890F0AD0A9784004C90685 +:105E2000C90F400CC903084320808004800F02D1B1 +:105E30002088400403D5208840210843208000208A +:105E400038BD70B504460020088015466068FFF72D +:105E5000A2FF002815D12189A089814210D861684C +:105E6000594E8978C90707D0711E884208D8314633 +:105E70000CF004FD298009E0FF21FF31884201D99F +:105E80000C2070BDFF30FF300330288060688078C0 +:105E9000C007A08903D031460CF0F0FC03E0FF30CE +:105EA000FF30033081B22980206881784748017330 +:105EB00020684649008820394885002070BD10B50B +:105EC000137804785B08E4075B00E40F2343137046 +:105ED000FD2423400478A407E40F640023431370D7 +:105EE000FB24234004786407E40FA40023431370C9 +:105EF000F724234004782407E40FE40023431370BD +:105F0000EF2423400478E406E40F240123431370B4 +:105F1000DF2423400478A406E40F640123431370B4 +:105F20000078BF244006C00F234080010343137054 +:105F3000002906D00878C10701D1800701D50120CA +:105F400000E00020C0015906490E0843107010BD42 +:105F500030B50A8803239B0204889A4323059D0FCA +:105F600002D1A3049C0F01D09B0F00E001239B02F0 +:105F70001A4303230A801B039A4303889804840F5F +:105F800002D11805830F01D0800F00E0012000032B +:105F900002430A8030BDF3B591B00D0018D01198BE +:105FA000002818D0122128460CF04BFC01A9012032 +:105FB00007F0A8FD00242646374677E002290000B6 +:105FC00001280000023000000102000060130020E0 +:105FD000102013B0F0BD0720FBE76846007C0128C5 +:105FE0000BD16846C1890520C002081A0AD00128D1 +:105FF0000AD002280CD003280CD0042C0ED0052C7B +:106000000FD10DE0012400E002246846868908E0F3 +:10601000032406E068460424878902E0052400E0A2 +:10602000062468468189119881423FD12C74002E44 +:106030003AD00BA800900CAB10220021304607F09C +:10604000F3FD002820D16846808D2A46C0B20CA9F5 +:1060500009F079FB002817D1AE81002F24D00BA8BE +:10606000009006AB13220021384607F0DDFD002822 +:106070000AD16846808D06A9C01E0331C0B22A1D10 +:1060800009F061FB002801D00320A2E76846817E69 +:10609000427E08021043E881062C05D16846007C48 +:1060A000A8726846C0892881002092E701A807F0FD +:1060B00031FD002891D0FFF7C6FD8AE7002804D003 +:1060C000012903D0022904D003207047F949C98D62 +:1060D00002E0F8494031C988814201D1002070476F +:1060E0000720704730B5F34C0025608B91B0C00B92 +:1060F0002ED1216900292BD0207B800728D40122B2 +:1061000068460271027200224272228B8281A28A48 +:10611000828204911721018309AA0023023206A971 +:1061200001A807F0BBF8002803D0FFF7F4FD11B079 +:1061300030BD207B02210843207307A800906946E8 +:106140000B8B208804220121FFF7CCFA05460BE0D7 +:10615000FBF74EFD842101700921017218341ECC19 +:106160000C301EC0FBF760FD2846E0E710B5D14CAF +:10617000034621690020002909D02146012210315F +:106180001846FBF707FF00202061A0820120217B39 +:10619000F9221140217310BD70B50C4605461C2133 +:1061A00020460CF04EFB00202080002D08D0012D51 +:1061B00004D0C1A1C5480CF084FC70BD062000E0ED +:1061C0000520A07070BD10B507F090FA10BDFEB5A7 +:1061D0000546007800260C46374603000CF076FD95 +:1061E0000C91070C1D962F462F46486C89916868C4 +:1061F0000A38FBF72FFE89E0002904D0B348AEA18E +:106200001B300CF05EFCFBF7F3FC044640780821E1 +:1062100008436070FBF708FD78E0002C04D1BB2038 +:10622000A5A180000CF04DFC284601F05BFA002887 +:106230006CD06078082108436070022666E0E88828 +:10624000694608800190002C04D1A0489AA12F3003 +:106250000CF037FC287807281CD10198C00B19D006 +:10626000944800218171A988818012E003264DE0C5 +:10627000002C04D1C52090A180000CF022FC8D4898 +:10628000017B89070BD50069002802D0E888C00B84 +:106290003CD00226607808210843607036E0291D52 +:1062A0008EC918308EC02838018802260122204667 +:1062B000FBF752FE0127EDE7002C04D183487EA1B5 +:1062C00064300CF0FEFB7B480821007B4007C00FC8 +:1062D0004600607808436070002E17D128790128A5 +:1062E00002D16879002811D02046FFF73FFF07460A +:1062F0000CE0002CCED10D206FA180010CF0E1FB51 +:10630000C8E772486CA17A300CF0DBFB002C0CD093 +:106310006078000709D5002F07D18420207020461F +:10632000582229460830F9F74FFF3046FEBDF7B531 +:10633000027A88B00C46054620460C30049006923E +:1063400016300027921E02903E460A31594813002B +:106350000CF0BCFC0ADF06E62AE62AE66A98C6E6E6 +:106360004288002A02D052270726DDE051271E2648 +:10637000002C7DD06A684F481288A2800122A27149 +:106380008079C0004019C089FFF705FE002877D149 +:1063900048488179C9004919C98921818079C0009B +:1063A0004019408AA083BFE0688A009006980728B9 +:1063B00017D1E889C00B14D000985127223086B23B +:1063C000002C55D0A8890499FFF7E5FD002857D186 +:1063D00068680088A0800220A071A889208101201F +:1063E00041E000985027203086B2002C40D0A88988 +:1063F000FFF7D1FD002843D168680088A080A889F4 +:10640000E080287A07280AD002202072288AA083F8 +:106410000098E083204669692030009A01E001205D +:10642000F3E70CF0B1F97FE0698A00910169002976 +:1064300002D0E989C90B22D00099512722318EB2AE +:1064400000218171A9898180002C5FD00088A08003 +:10645000A8890499FFF79FFD002811D10220A0719F +:10646000A88920810420A072288AE083009801E096 +:106470004CE005E020846969009A0298D1E7032086 +:106480000BB0F0BD007B400702D55127222601E06A +:1064900050272026002C39D06868502F0088A08013 +:1064A00016D00220A0712146287B0831FFF774FE28 +:1064B0003AE00000401300207372635C67617474FB +:1064C000735F636F72652E6300000000CB020000F3 +:1064D000287BA11DFFF760FE0020FFF747FE23E0A9 +:1064E000A9890089884207D154270626002C0DD09F +:1064F00068680088A08017E053270826002C05D084 +:1065000068680088A080A889E0800DE00A9806806D +:1065100010E055270726002CF8D00020A07103E0DA +:10652000FD49FE480CF0CDFA0A98002C068001D0F7 +:10653000278066800020A3E7F948002101722038F7 +:10654000418081718180027BF923520852001A40F8 +:10655000027301618182704770B5F14C86B0203CB6 +:10656000208000206080A071A0806946012007F093 +:10657000C9FA102608E00199088802461207D20FCE +:10658000B043120110430880684607F0C3FA0500C3 +:10659000F1D02069002804D0E048DF4931300CF008 +:1065A00090FA207B800704D5DC48DB4932300CF0C0 +:1065B00088FA822D04D02846FFF745FB06B070BD4F +:1065C0000020FBE7D64810B52038017B012211439B +:1065D0000173002141808171818006F05BFA10BD5A +:1065E00010B5CF4C0020C043203C20800020FFF796 +:1065F000BDFD207B40084000207310BD70B5C84D24 +:106600000446203D287B800704D5C448C249493050 +:106610000CF057FA287BC00706D12888C149884268 +:1066200002D02869002801D0082070BD002C08D0B5 +:10663000A088162801D2092070BD20682861A08892 +:10664000A882FFF74FFD70BD10B50C4607F04BFA5E +:10665000002803D0B049B4480CF033FA2046FFF7C5 +:10666000F2FA10BDF0B5AE4D0446203591B00020D1 +:10667000089068820E462882E8812946E8804039E1 +:106680000886694608830885088688838882A44826 +:106690000E90007A1746012808D0022806D0032859 +:1066A00004D0042802D0082011B0F0BD05239B03BC +:1066B0009C421CD3012080049C49221A8A4216D392 +:1066C0009B4A944213D29E4211D3331A8B420ED36B +:1066D00096420CD26268002A16D005239B039A4288 +:1066E00005D3101A884202D39148824201D3102068 +:1066F000DAE760892189884203D801225202914257 +:1067000001D90C20D0E7089010AA0CA93046FFF759 +:1067100098FB0028C8D106A92069FFF73CFB002898 +:10672000C2D1206900280CD0607880070028684614 +:10673000008B03DA8004800F56D002E08004800FC3 +:1067400052D105A96069FFF726FB0028ACD160692A +:10675000002808D06846808A0105890F012943D1A5 +:106760008004800F40D007A9A069FFF714FB002820 +:106770009AD16846008B800636D46846808A8006A7 +:1067800032D46846808B81062ED4A169002906D0B8 +:106790000105890F012927D18004800F24D0E068EA +:1067A000002804D0007800281ED01C281CD25C4A87 +:1067B000611C123220460992FFF781FB0321002061 +:1067C0008902884301218902411868460D9101859B +:1067D0000121817457490182514A0FA9153230684D +:1067E00008F0D7FF002801D007205DE708A8007F48 +:1067F0004B49C01CC2B26A7100201031FF320090B8 +:106800000190FF3203460291039003320AA904A8C3 +:1068100007F004F9002827D141482038008E0B905A +:106820003F4833893830326901461239029100936A +:106830000192039010A90A8873890CA9306807F0A7 +:10684000EDF801007AD13648E98811308170090AE3 +:10685000C1700026009631386A79008E3146099B56 +:1068600007F05BF8002802D0FFF7EDF91CE70E985F +:10687000807CC00928D068460D990185012181746A +:10688000292109020182AE81287B61784008C9076D +:106890004000C90F08432873FD2108406178204A51 +:1068A0008907C90F4900084328732A32901C022126 +:1068B000029200910190002303961F4A0AA904A89E +:1068C00007F0ACF80100BDD1606800283FD0206916 +:1068D00000280DD106A90CA8FFF73AFB60788007C5 +:1068E00006D46946088B0321090388436946088357 +:1068F0000120694688740F48FE3008820E492089BD +:10690000891E0BF0BBFF62680548089B2E3003967A +:1069100000930192029012E0B8640000220400008B +:1069200060130020FFFF0000260600000000FC1F8F +:1069300000400020032800000302000086E00A4611 +:10694000002306A904A807F069F801007ED1207889 +:10695000C10601D480062BD56846068460690028EC +:106960000DD105A90CA8FFF7F3FA6846818A032028 +:1069700080028143012080020918684681826946AD +:10698000888A482108436946888201208874F8482B +:106990000882F84908AA022001920291009000237F +:1069A0000396F54A05A904A807F038F8010062D15A +:1069B0002078C0072DD068460684A06900280DD134 +:1069C00007A90CA8FFF7C4FA6846808B0321890247 +:1069D0008843012189024118684681836846818B7A +:1069E000402001436846818301218174E04908AA5F +:1069F000491C0182DF480221801C01920091029013 +:106A000000230396DC4A07A904A807F007F8010051 +:106A100031D1E068002832D068460D990185012106 +:106A20008174D349891C0182E16808A80A78027040 +:106A300049784170E068418868464184E06801799E +:106A400008A80171E068C18808A800E013E041715E +:106A5000090A8171C7480722001D08A90092019107 +:106A60000290412200230396D2000AA904A806F04E +:106A7000D5FF010003D00B98FFF7E6FD14E60321D4 +:106A80000E98002F017207D0E8883880E889788056 +:106A9000288AB880688AF880002005E6F0B50124CD +:106AA0008BB016460F46012802D002281BD104E005 +:106AB000684605218474C90202E06846AF498474BF +:106AC0000182002F11D00321002089028843012177 +:106AD000890241186846018506AA05A9384608F0CA +:106AE00058FE002803D00720CAE41020C8E4A14DB6 +:106AF000B878303D287338882F46203F78856A461D +:106B0000127D0020294606AB00920E310193FF3220 +:106B1000029103900346FF3203320AA904A806F04B +:106B20007DFF002802D0FFF78EF8A9E4002E01D0E7 +:106B3000F88D30802C720020A2E470B592B0064629 +:106B4000012508A885708E496846018406F0DDFE9F +:106B5000002208A90120FFF7A1FF044606F0D9FE94 +:106B6000002C02D0204612B070BD0024002E3ED072 +:106B70001C2168460BF067FE68460178202001431F +:106B80006846017008A885707E49684601841194A2 +:106B90000794817FF9200140891C68468177002095 +:106BA0000146684601770020014668464177042186 +:106BB0008185C485018607A80A9011A80D9008A8B0 +:106BC000099006F0A2FE0EAA09A96846FFF74AFD41 +:106BD000054606F09EFE002D01D02846C3E7654815 +:106BE0006946098F503801816946898F4181614822 +:106BF000303804720020B6E7F7B55E4E9CB0002135 +:106C0000303E0091317A012904D0022902D00820B7 +:106C10001FB0F0BD57495039CA8D824201D00620BD +:106C2000F6E71D98824201D10720F1E75348012180 +:106C300010AA9176401C1083002003239B02024679 +:106C40009A438B02D31810AA93846A4691844E49C2 +:106C5000D18410AA9077908317AA0A926A469185E8 +:106C60000C9009A806F075FF00242546274604A9C4 +:106C700009A806F071FF002810D0822877D1002CD7 +:106C80006AD0002D68D010A80481458100240475C5 +:106C900018A8807812AD012860D077E06846807D22 +:106CA000002F1FD0012853D16846818A3348401CE9 +:106CB000814219D114A800906846408A0EAB102278 +:106CC000002106F0B1FF002874D110A8008A042822 +:106CD00001D0062849D16846018F1D98814237D1DD +:106CE0000F2095E7012833D16846808A0521C90223 +:106CF000884202D0491C88422AD11E485038C18D92 +:106D00006846408A814201D1012700E00027002C1B +:106D100001D0002D0DD01D99884219D114A90091E0 +:106D200004460EAB1022002106F07EFF002841D160 +:106D300001E0009D0CE010A8008A022801D0102874 +:106D400013D1C0B218AA0EA908F0FDFC00280CD17E +:106D50006846408A00908AE7052059E72A1D15A950 +:106D600018A808F016FD002810D0032050E721E0F5 +:106D700002290000901300200302000001280000F7 +:106D800001180000052A0000FFFF000010A8007D88 +:106D90000023001DC2B210A802751E98029019A906 +:106DA00001950394009216A806F038FE002801D140 +:106DB00002213172FEF747FF2AE73EB50B46401E1F +:106DC00084B201AA00211846FFF779F806F09DFD6C +:106DD00002A8009001AB01220021204606F09DFD93 +:106DE000044606F096FD68460089012803D0FE4956 +:106DF000FE480BF066FE2046FEF725FF3EBDF0B5CF +:106E0000FB4E0446307A89B00F46032804D004288C +:106E100002D0082009B0F0BD04AA06A92046FFF759 +:106E200010F80500F6D1F24823893830226901466E +:106E30001039029100930192039069460A8A63898E +:106E400006A9206806F0EAFD002802D0FEF7FBFE46 +:106E5000E0E7002F03D0E648203000893880042086 +:106E600030722846D6E738B50C00054608D0002217 +:106E7000694606F033FF002804D0FEF7E4FE38BD73 +:106E8000102038BD69462046FEF785FF0028F8D15E +:106E9000A0786946C207D20F284606F03AFFECE711 +:106EA0003EB50C0008D002AA694606F017FF00287C +:106EB00004D0FEF7C8FE3EBD10203EBD0321204693 +:106EC0000BF0BFFC6846008801A90005800FFEF7A3 +:106ED0004EFF00280BD16846007920706846008874 +:106EE00001A98004800FFEF742FF002801D0032093 +:106EF0003EBD684600796070A278EF200240684687 +:106F00000088C10B09010A43F7210A404104C90F57 +:106F1000C9000A43A270F9210A40800601D5012068 +:106F200000E00220400069460243097A5008400010 +:106F3000C907C90F0843A07000203EBDFEB51D461D +:106F400014000E46074615D0002D13D006F0DDFCC8 +:106F500001A8009022882B463146384606F0DDFC19 +:106F6000054668468088208006F0D3FC2846FEF758 +:106F70006AFEFEBD1020FEBDF0B50C46002199B0A2 +:106F80000746684681850D46002C11D0E068002830 +:106F900006D0A06800280BD002886B469A85018035 +:106FA000A078012806D0022804D0072019B0F0BD2F +:106FB0001020FBE72088002807D0401E80B201A9DE +:106FC00006F0A0FD002842D136E08A48EEE7694687 +:106FD0008A8921888A420BD26846007C00250128D4 +:106FE0002CD16846C0898449884227D1012525E0F3 +:106FF0008A4203D1002D2FD06D1C01E0022D02D05A +:10700000032D1BD31FE06946097C012916D169466F +:10701000794BCA895B1ED11A9A421DD005DC77488C +:10702000101A19D0012809D116E0012914D0FF390E +:10703000013903D1032506E00D26B60201A806F0AA +:1070400069FD0028C3D0822804D0002806D0FEF7AE +:10705000FAFDABE7022DFAD13046A7E7E068002839 +:1070600013D006F052FC0BA800906A46A188208835 +:10707000928DE36806F051FC054606F04AFC002DAF +:1070800019D16846A168808D088002980078C006F2 +:1070900001D55B488AE706F038FC0EA800906846E8 +:1070A00080890CAB0222002106F0BEFD054606F0E9 +:1070B00030FC002D01D02846C9E76846008F022821 +:1070C00001D0032072E7A078012808A8007C03D033 +:1070D00080070ED4082069E7C007FBD00820FEF720 +:1070E000EBFA072802D34348401C5FE7082502203B +:1070F00001E00225032069460876218868468183DD +:107100001721818611AA002302320DA906A806F0D4 +:10711000C5F8002802D0FEF7FEFD47E70FA8009053 +:107120006846838E042229463846FEF7DBFA3DE79F +:1071300070B5064615460C460846FEF741FD002888 +:107140000AD106F0E2FB2A4621463046FFF7A6FCAC +:10715000044606F0DEFB204670BD70B514460D46B1 +:10716000064606F0D2FB224629463046FFF744FD8C +:10717000044606F0CEFB204670BD70B51E46144690 +:107180000D001AD0002C18D06168002915D00121FB +:10719000FEF794FF00280FD12068FEF711FD0028AC +:1071A0000AD106F0B2FB324621462846FFF75AFACA +:1071B000044606F0AEFB204670BD102070BD70B5D1 +:1071C00015460C0023D00221FEF778FF00281DD1C0 +:1071D0002068FEF7F5FC002818D106F096FB29463A +:1071E0002046FFF70CFE0DE0B86400003C060000EE +:1071F0006013002002300000032800000028000077 +:1072000001340000044606F084FB204670BD1020C7 +:1072100070BDF8B51C4615460E46074600F01FFA2D +:10722000002805D123462A4631463846FFF786FE18 +:10723000F8BDFFB583B01E4615000F460FD006F00F +:1072400064FB01A800900023F74A3946039806F032 +:10725000EBFC044606F05DFB002C03D014E010208C +:1072600007B0F0BD002E0CD006F04FFB00200090C0 +:107270002A8833463946039806F0D6FC044606F0C1 +:1072800048FB6846808828802046FEF7DCFCE7E75C +:10729000002906D0E54B0A885B899A4201D8E44868 +:1072A000704769E610B586B004236C46A382DF4BB5 +:1072B0005C898C4201D2914202D9DD4806B010BDF2 +:1072C0006C462182628200210091019119892180FE +:1072D0000221A17005A9029104A903916946FFF753 +:1072E0004BFEEBE7F0B591B00D4681206946087181 +:1072F00005F002FC0646002D08D02878CB4C01286A +:1073000006D0022828D0072011B0F0BD1020FBE7DE +:10731000A98801AAFEF7CAFC0028F5D1B00734D528 +:1073200068460079002820D1A879C0071DD006F052 +:10733000ECFA002000906A892989A088EB6806F0A1 +:10734000ECFA6946087106F0E4FA69460879002803 +:107350000BD0FEF778FCD7E7A98801AAFEF7A6FCB8 +:107360000028D1D1342006420FD001216846017295 +:10737000017301794173F00609D5A188684601823D +:10738000A18A01832069059004E00820BCE7A08859 +:1073900069460882FAF72CFC05461720694688835F +:1073A0000AAA2B46023207A902A805F077FF074672 +:1073B0006878000701D5FAF737FC002F03D038466C +:1073C000FEF7A9FCA0E7F00603D5207B06210843C1 +:1073D0002073B00602D50020FEF7C8FE08A8009072 +:1073E00069468B8B208804220121FEF77BF98BE70D +:1073F000F0B5002695B014460D4600290FD0022C9A +:107400004FD3A71EBAB288480AF02EF929191039AD +:10741000CA7B8B7B11021943884242D1BCB201A9BD +:10742000012006F06FFB7AE0029F3888010776D5CD +:10743000002D41D0A9190691CA788B78361D11020A +:10744000B6B219438919A1422BD869468A8906998F +:107450004B7809781B020B439A4222D1C00623D5F0 +:1074600006F053FA07A800900698AB19C178807807 +:107470000A0206990243487809780002084300216D +:1074800006F04BFA009006F044FA009800283ED12E +:107490000698C178827808026946898B1043884231 +:1074A00002D00B2015B0F0BD0698C1788278080292 +:1074B0001043801986B22EE0C0062CD5002007AA02 +:1074C00001461154401C80B21028FAD306F01DFA70 +:1074D00006A800906846002380891022194606F00D +:1074E000A3FB0090002803D006F013FA00980EE0EA +:1074F0000BA86946009088890A8B07AB002106F02B +:107500000CFA009006F005FA0098002803D0FEF768 +:107510009AFBC7E703E0388810218843388001A828 +:1075200006F0F8FA002800D17EE7404D698800296E +:1075300021D0012268460276027700244477018434 +:10754000172181850EAA234602320BA906A805F051 +:10755000A5FE002802D0FEF7DEFBA3E70CA80090F2 +:1075600069468B8D288804220121FEF7BBF800288C +:1075700098D16C8096E7002094E7F0B5002487B09E +:1075800015460E46002A04D002A9012006F0BAFAD8 +:1075900040E0102064E60398007800073AD506F032 +:1075A000B4F901A8009068460023008A1E4A1946D3 +:1075B00006F03AFB074606F0ACF9002F23D1002E67 +:1075C00023D068468088298820183719001D8142F9 +:1075D00036D36946098A3970090A797069468988FB +:1075E000B970090AF97006F090F901A8694600908F +:1075F000088A8A883B1D002106F016FB074606F024 +:1076000088F9002F01D003202AE6684680882018D8 +:10761000001D84B202A806F07DFA0028BBD08228A3 +:1076200008D0FEF710FB1BE6FFFF00004013002010 +:1076300002300000002E0ED02988A01C814201D209 +:107640000C200DE62246314639480AF00DF8311972 +:107650000870000A4870A41C2C80002000E600B5C9 +:1076600085B06946FEF797FC00280AD16846007C81 +:1076700003000BF02BFB08052F2F2F2F08080531D7 +:10768000032005B000BD68468078012807D1684610 +:1076900000880321C902401A1CD001281AD068466C +:1076A0008079012806D16846808815214902401A50 +:1076B00005280FD96846807A012811D168460189CA +:1076C00029200002081A05D0022803D0032801D07F +:1076D000042805D10F20D4E7164917480BF0F1F91B +:1076E0000020CEE738B5154A0021518003791AE011 +:1076F000CC002418A46800946C462488250707D57C +:10770000E50605D5D90008182038C08B508006E062 +:10771000640406D59171C9000818C08890800120C2 +:1077200038BD491CC9B28B42E2D8002038BD0000E8 +:10773000FFFF0000B8640000330200004013002087 +:10774000F8B50125F84902260E603F27F7493F02A8 +:107750008F60F7490022CA63CD63F649C96A0907F9 +:107760000ED4F4494031CB6AF34A53620B6B9362F7 +:107770004B6BD3628B6B1363C96BD3051943516396 +:10778000EE49EF4CC969002829D001282BD0FF20F1 +:10779000ECA16E300BF095F9EE48A063FF200430A9 +:1077A00060632563EC49032008602061E44996206A +:1077B00040314860DD48E94940304163E649FC39E1 +:1077C0000163E649091FC163E349F0398163D74882 +:1077D0004760E34910204860E2480660F8BDE2488F +:1077E0006061E24804E0E148E0306061DF48801F0A +:1077F0000143A161D0E70120D0494006C86170472C +:1078000010B5CE4C0020A070214660702031487029 +:1078100008746061A072A06209F02AFBA061204692 +:10782000343009F038FF002804D0FF20C5A13A30D9 +:107830000BF047F901204006E0610020FFF780FFD0 +:1078400010BDBE49012008707047BC490020087077 +:10785000704770477047BA4940310028086802D025 +:107860000122104301E0400840000860704770B5F5 +:107870000C46B24D01460622E81C0AF085FF6C72E8 +:1078800070BDAE48203040787047AC4A917050705F +:10789000704770B50D460446082904D9FF20A9A1F8 +:1078A000CB300BF00EF90022B14809E0910063588B +:1078B00009180B6053001B191B8C0B62521CD2B2AF +:1078C000AA42F3D3206BAA494031086070BD0B2354 +:1078D000DB4310B5C21A9A4998421FD008DC1C320B +:1078E00022D00A2A20D0142A1CD0182A08D117E046 +:1078F000083011D004280DD0082809D00C2805D054 +:10790000FF2090A1F7300BF0DCF810BD04200CE054 +:1079100000200AE0FC2008E0F82006E0F42004E063 +:10792000F02002E0EC2000E0D820C86010BD8348C1 +:107930002030007B704710B5814CC17861620AF03D +:1079400084FF0002E06110BD252808D0262808D059 +:10795000272808D041000A2807D8091D06E002217F +:1079600005E01A2103E0502101E0891DC9B2744AE3 +:107970009160734940314861704770494861704770 +:1079800070B56E4DA87200F028FBA87AC0073CD0F5 +:10799000714C2068800703D46AA176480BF091F8F7 +:1079A000A87A010619D5800707D5724865A1801C01 +:1079B0000BF087F8A87A00060FD55C4E2878403681 +:1079C000012811D0002804D0A3205EA180000BF074 +:1079D00078F869487061A8693061A87A800714D581 +:1079E0002068C00708D102E06348001FF2E7A52025 +:1079F00054A180000BF065F8A87A4007206801D5F3 +:107A0000042100E008210843206070BD70B5012406 +:107A10004A4D002807D0012818D002281AD055480E +:107A200048A145380BE000F0D8FA53482978001FE8 +:107A3000012907D0002907D04E4842A158380BF041 +:107A400040F870BD046070BD446070BD8120FFF7D8 +:107A500097FF70BD00F0C1FA6869002804D145485D +:107A600038A150380BF02DF86969A86A40184349CD +:107A7000C8602E484249403001623F490C314162A2 +:107A80002A49001548603F4884602C48203004741F +:107A900070BDF8B50C2069460870314C6068C006AE +:107AA000C50F1026A66034480021FC300161324B1E +:107AB00001221B1F1A610BE000BF00BF00BF00BF07 +:107AC00000BF00BF00BF00BF6B461A78521E1A707D +:107AD0006A461278002A02D00269002AECD00161BD +:107AE00068460078002804D1224816A131380AF0EF +:107AF000E8FF002D00D06660F8BD10490020C86185 +:107B0000704710B50AF0A1FE00020D49000AC863D3 +:107B100010BD054902200860704703490220086033 +:107B2000104908607047000080E100E000F5014066 +:107B3000C01F004080000010001700409C13002070 +:107B4000001500407372635C68616C5F7263732E32 +:107B5000630000005B06000000120040448000400B +:107B60000013004080E200E006010200250003004F +:107B7000001600407B0200000410004040850040D9 +:107B80004C81004000050040FB4902200860C9E725 +:107B9000FA490870C6E710B5F94809F084FD0028D5 +:107BA00004D02B20F74900010AF08BFF10BD10B55F +:107BB000F34809F090FD10BDF3494860B2E7F04981 +:107BC00010B53439F14B0022C8605A60896A081830 +:107BD000EF49486000F008FA10BDE94810B5C2212D +:107BE0003438C160E94A00215160806AE849C230F6 +:107BF000486000F0F9F910BDE64900208861C861CD +:107C0000DF493439C860E24948608BE7DC4900202D +:107C10003439886286E73F20DE49000240398860B7 +:107C200080E7D748DA493438806AFE30886079E7DF +:107C3000D7490020886075E7D74801681022914332 +:107C40000160D649012088616CE7D5490020C861F0 +:107C5000D148016810221143016063E700B5FFF7C6 +:107C6000EBFFC74900203439087400BD00B5FFF7A9 +:107C7000ECFFC34901203439087400BDC849CA6902 +:107C8000012A01D000204DE7BF4A403292685206D7 +:107C9000520E524202700020C861012042E7F8B53E +:107CA000BF4C2069012806D00021B548343800783F +:107CB000012802D004E04021F7E7E268012A04D05D +:107CC00000220A43012802D004E02022F9E761687B +:107CD000012905D000211143B24A002802D007E053 +:107CE0001021F8E71368012B02D1E368012B04D0BF +:107CF00000230B43002802D007E00823F9E71168AE +:107D0000002902D1E168012905D000221A439F4EC3 +:107D1000002802D004E00422F8E77168012904D0A9 +:107D200000211143002802D004E00221F9E7606835 +:107D3000012829D000259C480D4301680906090E39 +:107D400002D06169012900D000218D4F143F3973A1 +:107D500000680006000E02D0A069012800D00020B3 +:107D600078738B488068002803D000F0ABFA0128B4 +:107D700000D00020B8730021E16021616160616181 +:107D8000A16171602846F8BD0125D4E77C48012136 +:107D90001438C173C6E6F8B5794E0127143E307C1D +:107DA0000025002827D07C4C206800902560FFF734 +:107DB00070FE009820607A48C560056145604561A5 +:107DC000856174490015403988607848856030467F +:107DD000203801787148012909D0002909D0694962 +:107DE00073480AF06EFE0AF06BFF3574F8BD076049 +:107DF000F9E74760F7E7FFF752FF04460020F0730A +:107E0000634842685E4D343D6A620068A862297822 +:107E1000002909D1A978002906D05B4B5B681B7843 +:107E20000B406978994309D000213170E10707D0F0 +:107E3000104602F031FC0121A86A08E03770F5E72E +:107E4000A10601D5022102E0A10702D5002102F01E +:107E500030FC4D4F796806220931E81C0AF067FCB6 +:107E6000002807D1687A79680978C909884201D160 +:107E7000012000E000207070204600F0BBF83F4871 +:107E8000C2270078002815D0012828D002283BD02E +:107E900003285AD03B4947480AF013FE287C0028A3 +:107EA00004D02878002865D0FFF7C6FE287800287F +:107EB00061D08BE0A00701D501F001FC200703D5BC +:107EC0000120EF6001F034FC600703D50020EF6073 +:107ED00001F02EFCA006E1D501F09EFBDEE7A00735 +:107EE00001D503F08BFE200703D50120EF6003F0DE +:107EF00005FE600703D50020EF6003F0FFFDA0063C +:107F0000CCD503F087FDC9E7A00703D5BF20044007 +:107F100009F07EFB200705D5BF2004400120EF605B +:107F200009F075FB600705D5BF2004400020EF6015 +:107F300009F06DFBA00603D5BF20044009F066FBE5 +:107F40006006ABD509F065FBA8E7A00701D509F0ED +:107F500063FB200703D50120EF6009F05CFB60079D +:107F600003D50020EF6009F056FBA00696D509F076 +:107F700051FB93E720E022E000E100E05400002004 +:107F8000D0130020447B00000015004040810040D9 +:107F90004085004040F501400012004000100040C4 +:107FA0000011004000140040401600400005004051 +:107FB0006F0300009F040000FFF747FE76E7E868C4 +:107FC000002803D0A96A091826484160F07B0028E0 +:107FD00000D10BE70AF074FEF8BD234903200860C6 +:107FE0002249002008619DE520482149C1612149BD +:107FF000816197E570B50546FFF7EFFF1E4CA17A4A +:10800000080701D568071CD41C4AC80605D5507B53 +:10801000002802D0907B002813D0880602D5107863 +:1080200000280ED1480602D55078002809D000203B +:108030008A070026002A07DA4A0704D5012222709F +:1080400002E00120F4E72670CA0709D0AA0705D488 +:10805000890705D5002803D0A80601D4FFF719FD2C +:10806000A67270BD408500400012004040F50140FE +:1080700010100040448100409C130020BC130020DD +:108080002E48002101704170704770B506461446B5 +:108090000D46012000F072F828490120284B087095 +:1080A0009E60DC601D6170BDF8B50446012000F0E3 +:1080B00065F822490120087021494C6021490026B9 +:1080C0004E601121204D8902A960204F002C0AD05A +:1080D000012C03D01EA140200AF0F3FC3E601120C9 +:1080E00080026860F8BD386001208002F9E710B5B1 +:1080F0001248017800290ED01121134A890291609B +:1081000010494A680021002A03D0154A12684270BB +:1081100000E041700170002000F030F810BD074809 +:108120000178002907D007484068002802D00C4891 +:108130000068C0B2704740787047000055000020CA +:1081400000F5004000F1004000F5014000F2004061 +:108150007372635C68616C5F63636D2E6300000023 +:1081600000F4004001202949C0030860284900208C +:1081700008701120274980028860704770B5244D2F +:1081800004462878A04207D0002C05D0002803D050 +:1081900021A14D200AF095FC2878A04210D00020A3 +:1081A00022492C70002C23D01A4A214D214B8032B9 +:1081B000012C06D0022C13D017A16A200AF081FCF2 +:1081C00070BD0860022008604D6112481A494030B5 +:1081D00001624362081D10601648001D506070BDAA +:1081E0000860032008604D6114481060536070BD42 +:1081F00008600860112007498002886070BD10B5D2 +:1082000005A173200AF05DFC10BD000080E100E0D4 +:108210005700002000F501407372635C68616C5F79 +:1082200063636D5F6161722E6300000000F50040C2 +:10823000D413002000F000400011004048810040AD +:10824000364800210170417010218170704770B56F +:10825000064614460D460220FFF790FF01202F49E5 +:108260002F4A0870E41E14619660556070BD10B509 +:108270000220FFF783FF29490120087029480021C7 +:1082800001604160816028490014486010BD10B54C +:10829000224C2078002811D00120234980038860D7 +:1082A00000F02EF80021002804D0012060701F4843 +:1082B000006801E061701020A07021700020FFF7BD +:1082C0005DFF10BD10B515480178002905D000F0FC +:1082D00017F8002800D0012010BD407810BD10B55F +:1082E0000E480178002909D000F00AF8002803D0D0 +:1082F0000E480068C0B210BD102010BD807810BDBF +:1083000008480168002905D04168002902D080682A +:10831000002801D00020704701207047580000203D +:1083200000F5004000F1004000F5014000F400407D +:1083300010B528210AF085FA10BD40788006800E1D +:10834000704740788006800EC01C70472820704718 +:1083500070B5054600780A0700090001120F1043A6 +:1083600028700B000AF0B2FC070507050705090590 +:108370000B00062408E00C2406E0222404E000247C +:10838000FEA158200AF09DFB6878800980012043F7 +:10839000687070BD00780007000F704710B50622A6 +:1083A000C01C0AF0F1F910BD0B4610B5C11C062225 +:1083B00018460AF0E9F910BD10B5062209300AF096 +:1083C000E3F910BD0B46014610B5062209311846E7 +:1083D0000AF0DAF910BD0278BF23C9071A40490E26 +:1083E0000A430270704700784006C00F7047027859 +:1083F0005206520EC9010A43027070470078C00944 +:10840000704770B50C460546C11C2046062209304F +:108410000AF0BAF920784006400E20702978490603 +:10842000C90FC9010843207070BD70B515460E46CE +:1084300004461F2A03D9D1A1A9200AF042FB2046F5 +:108440002A46314609300AF09FF96078AD1D80094F +:108450008001A906890E0843607070BD70B505469D +:1084600040780E468406A40E062C03D2C3A1B92080 +:108470000AF027FBA41FE4B21F2C00D91F242946B1 +:108480002246093130460AF07FF9204670BD70B5AA +:1084900015460E4604461F2A03D9B8A1CD200AF07E +:1084A00010FB20462A46314609300AF06DF9607803 +:1084B000AD1D80098001A906890E0843607070BD5A +:1084C00070B5044640780E468506AD0E062D03D2E3 +:1084D000AAA1DE200AF0F5FAAD1FEDB21F2D03D9D7 +:1084E000A6A1E2200AF0EDFA21462A4609313046DB +:1084F0000AF04AF9284670BD10B504220F300AF080 +:1085000043F910BD0B46014610B504220F31184641 +:108510000AF03AF910BD10B5032213300AF034F90D +:1085200010BD0B46014610B50322133118460AF060 +:108530002BF910BD4176090A81767047817E427E13 +:10854000080210437047C176090A01777047017F1E +:10855000C27E0802104370474177090A817770474D +:10856000817F427F080210437047C175090A017676 +:108570007047017EC27D08021043704781757047C5 +:10858000807D704720300279C90652095201C90E18 +:108590000A430271704720300079C006C00E704750 +:1085A00020300279D206D20E49010A430271704787 +:1085B000203000794009704710B505221F300AF0BD +:1085C000E3F810BD0B46014610B505221F311846D1 +:1085D0000AF0DAF810BD30B5411C837E0A46190254 +:1085E000D37D447E927D1B0221431343674D827DE0 +:1085F0008C1FAC4210D8002A0ED0082A0CD88A4210 +:108600000AD28B4208D8817F427F08021043A91DFD +:10861000884201D8012030BD002030BD00210A462B +:108620004254491C2229FBDB70474078C006C00E2B +:1086300070474078C006C00EC01C704722207047AB +:1086400010B502788B07920892009B0F1A430270B4 +:108650004278520952014270012908D0022906D0FD +:10866000032905D0FF2045A1A3300AF02AFA10BD46 +:1086700001210A43427010BD10B502788B079208A1 +:1086800092009B0F1A4302704278520952014270C5 +:10869000012908D0022906D0032905D0FF2037A1DF +:1086A000BD300AF00EFA10BD01210A43427010BD20 +:1086B00000788007800F70470278FB23C9071A40B3 +:1086C000490F0A430270704700784007C00F704797 +:1086D0000278F723C9071A40090F0A43027070474E +:1086E00000780007C00F70470278EF23C9071A40CF +:1086F000C90E0A43027070470078C006C00F704769 +:1087000070B50546C1700B000AF0E0FA0E080A0CBD +:108710000E1012120C14141212160C180C2413E062 +:10872000082411E002240FE017240DE00D240BE0D3 +:10873000012409E0092407E0062405E0452000247F +:108740000EA1C0000AF0BDF968784009400120433D +:10875000687070BDC078704770B5044640780E46AA +:10876000C506ED0E1B2D03D904A109480AF0A9F98D +:108770006019C01C042231460CE000007372635C77 +:10878000756C5F7064752E63000000007A0C000049 +:108790003A02000009F0F8FF70BD70B50446407859 +:1087A0000E46C506ED0E1B2D03D9A049A0480AF0C0 +:1087B00088F96119C91C0422304609F0E5FF70BD33 +:1087C000C171090A01727047017AC2790802104327 +:1087D00070474172090A81727047817A427A0802B1 +:1087E00010437047C172090A01737047017BC27A56 +:1087F0000802104370474171090A817170478179FD +:108800004279080210437047017170470079704740 +:108810004173090A81737047817B427B08021043D0 +:10882000704730B5411C037A0A46C47919022143C6 +:10883000537914791B0223437E4D00798C1FAC427F +:1088400010D800280ED008280CD888420AD28B42B3 +:1088500008D8D07A917A00020843A91D884201D82D +:10886000012030BD002030BD10B50522001D09F0EB +:108870008BFF10BD0B4610B5011D0522184609F0EF +:1088800083FF10BD4172090A81727047817A427A72 +:10889000080210437047017170470079704710B5A6 +:1088A0000822001D09F070FF10BD0B4610B5011D18 +:1088B0000822184609F068FF10BD0A78027349784B +:1088C00041737047027B0A70407B4870704710B557 +:1088D00008220E3009F058FF10BD0B46014610B5B6 +:1088E00008220E31184609F04FFF10BD10B50422C2 +:1088F000163009F049FF10BD0B46014610B50422A1 +:108900001631184609F040FF10BD10B50822001DB1 +:1089100009F03AFF10BD0B4610B5011D082218469C +:1089200009F032FF10BD10B504220C3009F02CFF05 +:1089300010BD0B46014610B504220C31184609F053 +:1089400023FF10BD017170474171090A81717047A1 +:10895000C171090A017270470079704781794279C3 +:10896000080210437047017AC27908021043704729 +:108970000171704700797047017170470079704745 +:1089800010B50822001D09F0FFFE10BD0B4610B502 +:10899000011D0822184609F0F7FE10BD10B5082287 +:1089A000001D09F0F1FE10BD0B4610B5011D082297 +:1089B000184609F0E9FE10BD70B515460E4604468E +:1089C0001B2A04D93720194900010AF07AF82A46EF +:1089D0003146E01C09F0D8FE6078E9064009400104 +:1089E000C90E0843607070BD70B5054640780E46EC +:1089F000C406E40E1B2C04D9DF200C4980000AF0C9 +:108A000060F82246E91C304609F0BEFE204670BDE3 +:108A10004078C006C00E1B2801D8012070470020F6 +:108A2000704710B5222209F0AFFE10BD7C87000010 +:108A3000430200007A0C0000FEB50F4601460646D0 +:108A40000546C031203640350446032F04D0002FA0 +:108A50002BD0012F29D049E000206080A080E08049 +:108A600020816081A082E082E873A074E074A07627 +:108A7000E076A073E0732074607430740123AB73EC +:108A80006882E88208762146A883603108702883CE +:108A90002873687320776077B072B0730872487279 +:108AA00088720A7488746883FEBD00206882E88238 +:108AB000012F50D0E08B0090608C0190C000009995 +:108AC00009F0DCFE401C80B2A882009919224143C3 +:108AD0009202914201DD401EA8827D200002009991 +:108AE00009F0CCFE401CE883002F01D0022FDBD11F +:108AF000307AC006C00E30720020E872221824219D +:108B00008B5C4032D9075B08DE07C90FF60F71187E +:108B10005B08DE07F60F71185B08DE07F60F7118A9 +:108B20005B08DE07F60F71185B08DE07F60F711899 +:108B30005B08DE07F60F71185B0859189171EA7A25 +:108B4000401C5118C0B2E9720528D7D3002FABD111 +:108B500000202874FEBD4A7F2046E030022A12D051 +:108B6000097F022913D050A1722009F0AAFF012029 +:108B700000900190E08B698B4843009909F08CFECE +:108B8000688301989AE7818800910089F1E7018A5A +:108B90000091808AEDE770B504464034E67A0546D8 +:108BA000002E68D0252E66D8002964D03C20405D78 +:108BB000227B48431018252109F060FE08462173E6 +:108BC0004207C908520F3C4B691820319A5C097959 +:108BD0008A4367D0314609F051FE491CCAB20020D1 +:108BE00006E0002804D0291840314979511ACAB248 +:108BF000291846235B5C93423AD320310979C94353 +:108C0000CB07DB17D21A521E1206120E34D08B0776 +:108C1000DB17D21A521E1206120E2FD04B07DB178B +:108C2000D21A521E1206120E2BD00B07DB17D21AC5 +:108C3000521E1206120E27D0CB06DB17D21A521E76 +:108C40001206120E23D08B06DB17D21A521E120602 +:108C5000120E1FD04B06DB17D21A521E1206120E2E +:108C60001BD00906C917511A491E0A06120E17D041 +:108C7000401C0528B5DB70BDC00013E0C000401CDF +:108C800010E0C000801C0DE0C000C01C0AE0C00065 +:108C9000001D07E0C000401D04E0C000801D01E091 +:108CA000C000C01D607370BD7372635C6C6C5F75D7 +:108CB00074696C2E63000000042D010010B5FF489C +:108CC0000021017041708170C17041718171C17169 +:108CD000083008F0E0FC002804D0FF20F8A1843020 +:108CE00009F0EFFE10BD10B5F44900204872081DD0 +:108CF00008F0D1FC002804D0FF20F1A1C33009F016 +:108D0000E0FEFFF7DBFFF148FFF788FC0021EF48AA +:108D1000FFF7EAFC0121ED48FFF792FC10BDE2E706 +:108D20001B207047E5494A7A002A01D0002070478D +:108D3000488101204872704710B5E0494A7A002AFC +:108D400002D04989814201D0002010BDDB48001DBE +:108D500008F0A9FC002804D0FF20D9A1B43009F004 +:108D6000B0FED648001D08F0B6FCFFF7A7FF0120B3 +:108D700010BD70B5D14C0025627A002A02D06289FC +:108D8000824201D00D700DE0227863789A4203D3BD +:108D900022786378D21A04E062782378D21A1023FA +:108DA0009A1A0A70FFF7C8FF002801D065720120E7 +:108DB00070BDC2494A7A002A04D04989814201D152 +:108DC0000120704700207047BC490A784B78521C3C +:108DD0001207120F9A4207D0097822225143BC4A47 +:108DE000891801600120704700207047B34801785E +:108DF0004278491C0907090F914206D00178491CA5 +:108E00000907090F01700120704700207047AB4926 +:108E10004A7A002A04D04989814201D10120704751 +:108E200000207047A5490A784B789A4207D04978C4 +:108E300022225143A64A8918016001207047002070 +:108E4000704710B59D4C20786178884216D06078C4 +:108E5000401C0007000F6070201D08F024FC002853 +:108E600004D0E078401CE070012010BDA078401CC8 +:108E7000A0709248001D08F02EFCF5E7002010BD00 +:108E80008E4801784078814201D10120704700204E +:108E900070478A4801784278914202D3017840783D +:108EA00003E041780078081A1021081AC0B2704710 +:108EB0000F20704770B5814C0D46617A002916D09D +:108EC0006189814213D100262E70201D08F0EBFB32 +:108ED000002805D1A0782870A670201D08F0FBFBA3 +:108EE0002878E17840182870E670012070BD0020D5 +:108EF00070BD76490160704770494A7A002A04D0F3 +:108F00004989814201D101207047002070476B4997 +:108F10004979002901D0002070476E490160012085 +:108F2000704766484179002901D00020704701212F +:108F300041710846704761494A7A002A04D049893C +:108F4000814201D101207047002070475B49497977 +:108F5000012901D0002070475E490160012070475F +:108F600056484179012901D0002070470021417104 +:108F70000120704751484079012801D001207047F5 +:108F8000002070474D494A7A002A04D0498981421D +:108F900001D1012070470020704770B5474C05464D +:108FA000A0790721401C09F069FCE079814208D0D2 +:108FB000A0792221484347492231401828600120E6 +:108FC00070BD002070BD10B53C4C0721A079401C3D +:108FD00009F054FCE079814207D0A0790721401CB8 +:108FE00009F04CFCA171012010BD002010BD3348D8 +:108FF0008179C079814201D10120704700207047FA +:109000002E494A7A002A04D04989814201D101209F +:1090100070470020704710B504462848083008F013 +:1090200042FB002815D125498879CA7990420CD095 +:10903000C8792221484327492231401820601F481F +:10904000083008F048FB012010BD1C48083008F02B +:1090500042FB002010BD10B504461848083008F047 +:1090600022FB002815D115498879CA7990420CD085 +:10907000C8792221484317492231401820600F48FF +:10908000083008F028FB012010BD0C48083008F01B +:1090900022FB002010BD094810B5083008F003FB82 +:1090A000002822D1054CA079E17988421AD0E079D4 +:1090B0000721401C09F0E2FBE1710DE05C0000209B +:1090C0007372635C646D5F712E6300002F17002064 +:1090D000FF1300201F1600202046083008F0FBFA7E +:1090E000012010BD0C4808F0F6FA002010BD0A4817 +:1090F00008388179C079814201D101207047002070 +:109100007047054808388179C079814201D1012032 +:1091100070470020704700006400002070477047CF +:10912000FF2070477047704700207047002070474D +:1091300000207047002070470020704700207047D3 +:1091400000207047002070470020704701207047C2 +:1091500000207047002070470020704700207047B3 +:10916000F8B5FA4D0446A87F002600280CD0002947 +:1091700023D1667010202070E87FA0702846203030 +:109180000078E070AE7718E0287A012801D000203E +:10919000F8BD002911D16670EC49687A01270A31BF +:1091A000002801D0132000E0052020701422A01C0C +:1091B00009F0EAFAA7716E722E720120F8BDF8B5B7 +:1091C000E3480078002802D00C273846F8BD002775 +:1091D000DE4D3C46203DAF74EF742F7528466F730B +:1091E0002038DA4E47737771687D002804D0FEF787 +:1091F0001FFDFFF74CF86C7534727472B477D34866 +:109200002430FFF795F8D1484C30FFF791F8D0485B +:109210004470DAE710B5CE4C00232370CB4C203CD1 +:109220006375CA4B01241C71603B583307C3FFF7B9 +:10923000C6FF002803D0C7A1FF2009F042FC10BDE3 +:10924000C2482038807C7047F8B5C04D0646407B48 +:10925000203DE873BD4837791346AF73B27B827106 +:109260000446603C217006221946601C09F08CFA05 +:10927000B07960730622F11DE01D09F085FA687B64 +:109280000126002800D0EE74B0484038407B00280A +:1092900000D02E75002F09D0012F09D0022F24D025 +:1092A000032F43D0FF20ABA14B3013E000211DE082 +:1092B000A64801212430FFF74BF8A448E11D2430D3 +:1092C000FFF77AF8607B002807D0012807D0FF203D +:1092D000A0A1413009F0F5FB0CE0002100E00121E4 +:1092E0009A482430FFF783F804E006219748243099 +:1092F000FFF72EF89548611C2430FFF74FF893488C +:1093000021782430FFF767F8904804214C30FFF7AC +:109310001FF88E48611C4C30FFF740F88B482178CD +:109320004C30FFF758F8AE740020F8BD0221DDE79D +:1093300070B50446854D0020203D287528462246FC +:10934000323809F021FA2846203844730120287564 +:1093500070BD7E490871704710B57C4C0022203CDE +:10936000E274607302462046123809F00DFA0120BB +:10937000E07410BDF8B500F02DFB744C0025203CC6 +:10938000607D002804D0FEF753FCFEF780FF657572 +:109390006F4E3570FEF70BFCA07B012804D0002136 +:1093A000084601F02DF9F8BD0021022001F028F94E +:1093B000664C207A0127002809D0A07F0028F2D12E +:1093C0000520E077204620300570A777F8BD70783B +:1093D0000028FBD05D4906226039487BE073C91D37 +:1093E0000846693009F0D0F93C20A07227727570E8 +:1093F000F8BD10B5554C203CE17B207CCA0701D05C +:10940000C2070BD08A070FD582070DD42620FEF79E +:109410009BFA207C02210843207410BD2520FEF712 +:1094200093FA207C0121F6E74907F6D54007F4D4EA +:109430002720FEF789FA207C0421ECE770B5444828 +:109440000078002861D1414C203CA07C00285CD0F1 +:10945000FEF7A1FB0026267466743046FEF798FBE3 +:109460000020FEF76DF93F48FEF765FA2546403DBE +:10947000296E8857FEF72BFA3A48C01EFEF741FBCB +:10948000FEF7BAFBFFF7B5FFFEF7DBF9FEF77CFB53 +:109490000120FEF7BBFA0F210520FEF7F6F9297827 +:1094A000681CFEF7E4F9A07B01280AD0E07C0028C4 +:1094B00007D0214612390846627B5630FEF7B5FFC9 +:1094C000E674207D002808D0204840380146427BC1 +:1094D00012398C30FEF7DBFF2675E86D0178002924 +:1094E00003D00178001DFEF7D4F9A86D017800299A +:1094F00007D00178154A401C7732FEF7A8FE0120FC +:109500006075FEF754FB002070BD0C2070BD104943 +:109510004860704770B50546FEF76EFB002D06D01B +:109520000020FEF72DFAFEF78CF9FFF762FF074CDB +:10953000203C607C002819D0A07B012803D105A124 +:10954000094809F0BEFAFFF715FF70BDB4170020F7 +:10955000680000207372635C6C6C5F6164762E63DC +:10956000000000000F2D0100CF0300000126002D98 +:1095700004D00220FEF74AFAFE484671FD48243026 +:10958000FEF71AFB012008F03CF8FEF762F9A07B19 +:1095900000280ED001280CD002280AD003280AD0B7 +:1095A000F549F64809F08DFAE07B217C884306D026 +:1095B00009E0032000E00120FEF7E2F9F4E7A07BD8 +:1095C000012803D06674EE480670BEE700202074C0 +:1095D000F9E710B5FEF7DFFAE948007800280ED168 +:1095E000E4482038807C002809D00020FFF792FF53 +:1095F000F6F7F9FEDF480079012806D007E000F011 +:10960000E9F9FEF7D4FA0C2010BD09F059FB00204F +:1096100010BDDB494870704770B500F0AFFE002800 +:1096200019D0FF202D30FEF7A8F9D54E3078D14C57 +:10963000012813D0022801D003282ED0CE49D148CA +:1096400009F03FFA3078002807D0F6F7CCFE2079F1 +:1096500001282CD030E0FFF78DFE76E7C54D203D88 +:10966000A87B032819D0FEF7B8FA687D002803D03C +:10967000FEF7FDFDFEF7D5FABE487430FEF79CFA02 +:10968000012007F0BFFFA87B01280BD0A1796F2034 +:10969000012906D0032904D004E00120FFF73AFF96 +:1096A000D0E77F20FEF76CF902203070CAE76079BE +:1096B000002801D1FEF76AFB0020607145E770B514 +:1096C000AC4C203C607D002803D0FEF7B1FAFEF7D9 +:1096D000DEFD00F053FE00281CD0A94D287802289A +:1096E00004D0A848A4492B3009F0EBF9A07B01284D +:1096F00013D0FF202D30FEF740F90120FFF70AFFBD +:109700002878002808D0F6F76EFE9A4C20790128B8 +:1097100006D00AE0FFF72EFE17E799208000EAE75F +:109720006079002801D1FEF731FB002060710CE761 +:10973000F8B50446FEF7FBF80546FEF7C3FD012821 +:1097400000D0002000908E480078022804D08D4878 +:109750008949673009F0B5F9864E203E707D0028B2 +:1097600003D0FEF765FAFEF792FDFEF745FA814851 +:109770007430FEF70FFE21007E4C07464DD0FEF7F9 +:1097800080F80028FAD03B0009F0A0FA06474747C6 +:1097900004471D47B07B0128F0D00098054304D151 +:1097A000A079002801D0022837D172484C30FEF74A +:1097B00003FA012007F025FF0120FEF7E1F87048C9 +:1097C00003210170F5E06B4F74373846D438F978CF +:1097D000C27991421BD13979027A914217D17979B4 +:1097E000427A914213D1B979827A91420FD1F979B3 +:1097F000C27A91420BD1397A027B914207D13978F2 +:10980000407B4906C90F814201D1012100E00021BE +:10981000B07B012802D0002803D0C3E0002908D182 +:10982000C0E00098054304D1A079002801D00128A8 +:109830007ED150487430FEF7CEFE002878D0504DCF +:109840004C49686804228331323008F09DFF387833 +:109850003E214006C20F68680A540622F91C3F30B8 +:1098600008F092FF4349686803228731363008F0D8 +:109870008BFF6868BA7D39210A543E4974310A7EEB +:10988000CB7D12021A4342878A7E4B7E12021A4314 +:10989000C2830A7FCB7E110219430184354974319A +:1098A0008A7F4B7F1102194341843249052293314B +:1098B000243008F069FF2F486D68943001792F46F5 +:1098C000C906C90E20373977007940097877207AA0 +:1098D000002810D0A07F002858D1607A002801D03D +:1098E000132000E005202349E07700202031087094 +:1098F0000120A0774AE01F48717D1030002925D053 +:109900000021A172A989A181B97FE17329460622AC +:109910003F3108F039FFE88BE082288C2083688C87 +:109920006083787F2077607F00994008400000E0E6 +:1099300038E008436077FEF7D2FC617F4000C9073A +:10994000C90F01436177012060721EE00021A172FE +:10995000A989A181B97FE173294606223F3108F028 +:1099600013FFE88BE082288C2083688C6083787FEB +:10997000207709E0B417002054950000ED030000A3 +:10998000680000206B02000001202072194D0020A9 +:10999000287000F01FF8FEF70AF90120696800F04E +:1099A0002FFE06E0FF202D30FDF7E7FF0120FFF737 +:1099B000B1FD1048007800280BD0F6F714FD20798F +:1099C000012804D16079002801D1FEF7DFF90020D9 +:1099D0006071F8BD10B5FEF719F9FEF70DF9FEF745 +:1099E00058F80020FDF7CCFFFEF715F9FEF795F8C3 +:1099F00010BD0000680000208107C90E002808DAA9 +:109A00000007000F08388008F94A80008018C069F4 +:109A100004E08008F74A800080180068C84000060B +:109A2000800F7047F448C07D7047F44800780028E4 +:109A300001D00020704701207047F048007870473F +:109A400010B5EE4A1378EC4CA47DA34202D007F087 +:109A500059F910BD1078032803D1E8490120891D68 +:109A6000887000F04AFE10BD38B5E44DE24CAD1DE3 +:109A7000687801281ED00121684606F041F8684642 +:109A80000078DF49000208F0F9FE68684118606854 +:109A900007F08FF86060DB48A060A18A00200029F1 +:109AA00010D06070032121702073A07ED249FFF78F +:109AB000C7FF38BD7D21C900606807F07AF8606093 +:109AC000D148E9E70121A18202216170EAE7FFB5EF +:109AD000C94C85B01C3461680191A1680391C749E4 +:109AE0001E46891E4A6807995388C91A89B202918D +:109AF000002E04D025463C3521464C3102E0BE4DB7 +:109B0000114664310091BC4F03213C372970002875 +:109B100018D0BA49891E4968403101287ED00228F0 +:109B20005CD003287BD0B9A1BC4808F0CAFF2878D4 +:109B3000002E75D0032804D0B848B4A1093008F02D +:109B4000C0FF35E1A068002804D1B448AFA1663851 +:109B500008F0B7FFA948B149801E40686031408FC6 +:109B600048434018069900F0CEFDE061A348AB4998 +:109B7000801E40686031C08B4843069900F0C3FDE9 +:109B80009E492062891E4B68A44A598FA0686032A2 +:109B9000514386464118E069A04A091A4C3A89188F +:109BA0008C462033E1629D4A597E60325143411810 +:109BB0000818FF3016306062A06261467046081ACD +:109BC000FF38974935388842B1D29649884204D245 +:109BD00092488EA1593808F074FFD0E0508F8F4A18 +:109BE0002169603250430818069900F08CFDE0614D +:109BF00082488A49801E40686031C08B484306997C +:109C000000F081FD2062A068002804D183487FA174 +:109C1000513808F056FF7948801E02E02FE05EE0E0 +:109C2000C1E040685621095A7F4B0029418F2269C3 +:109C30001DD059435118E269891AE1626269E168ED +:109C4000794B5143E26989183922125C5A438A18C8 +:109C50005118FF3114316162C08B216A5843411A97 +:109C600072480818A062A168E06A401A81E059436E +:109C70005118E269891A6268D3398918DDE7C88A00 +:109C8000002802D0A068002804D164485FA13938B8 +:109C900008F017FF59486449801E4068C28B4A4348 +:109CA000216A8E46511AE1628C4656226369125A25 +:109CB000E168D21A5943E3692030CB187146514309 +:109CC000407E594A5918504308184018FF30143044 +:109CD0006062564861466044A062A06848E0D08B4C +:109CE000514A5043226A801A029A5043E062C88A5D +:109CF000002805D0002E19D0B87D002816D0A1E08C +:109D0000002E02D0B87D0028F6D10198002802D09C +:109D10000398002804D141483CA1213808F0D1FE25 +:109D20000198E16AD3380818E06207E0019800283A +:109D300004D08D2035A1C00008F0C3FE2F48801E3E +:109D400042685620815A02980818216A4843400008 +:109D5000FF3014306062D08B334A5043411A33488D +:109D60000818A0622448C07D00280BD0E16A03983F +:109D7000081AFF382A492338884200D3D7E6022040 +:109D80002870D4E606F072FC01461B48006907F013 +:109D9000C7FBE16A081AFF3821491E388842EDD214 +:109DA000012009B0F0BD032802D1144907204870F2 +:109DB0001148E16A006906F0FCFE6860A16A606A09 +:109DC000884202D90098016001E00099086000987B +:109DD000174900680818A8600848801E40688188F4 +:109DE0000798081A00B2002824DD022023E00000B2 +:109DF00000ED00E000E400E05018002072000020B8 +:109E000010270000F82A0000B78913007372635C02 +:109E10006C6C5F6C6D2E73302E630000820400004A +:109E20004707000082020000E204000061FCFFFF1F +:109E3000EF160000002068702E73002E04D0B87D4D +:109E4000002801D00220ACE701204640BE76F7484A +:109E5000807E2946FFF7F4FD0020A2E7F8B5F3481D +:109E60003C30807EF14FF24D3C461C3400280CD033 +:109E70006968208F4988884207D17878002804D102 +:109E8000A920EC49C00008F01CFE06F0EFFB0146DB +:109E9000386907F045FB00F044FC6968228F4B8865 +:109EA0001E18B24202DB521C228702E0401C181826 +:109EB0002087208F0A89904201D1401C2087B88AD0 +:109EC000032802D2401CB88201E0208F8880084617 +:109ED0004030828A408A4988101A401E401886B253 +:109EE00017E028786B6841002033D3485B7F415AE4 +:109EF0005B00C05A081881B2207E0023FFF7E7FDFF +:109F0000002811D0012810D00B20CA49C00108F048 +:109F1000D8FD228FB01A00B20028E2DA6868082162 +:109F20002030417400F0A7FDF8BD208F401C208731 +:109F3000EFE770B5BD4C00261C3466600120A660BA +:109F400000F0C9FBBA481F21801C41700078B74D52 +:109F5000030008F0BBFE044545033745B3482670AF +:109F60003C30807EB24E002806D106F07FFB216C8B +:109F700007F0D6FA002811DC7068228F41888A42E7 +:109F800004D10289511A4181428003E0511A418172 +:109F9000218F41806868206428610BE0A18E706881 +:109FA0004288891A4181A18E4180216C69602961B2 +:109FB000E16C4166706801F0FFFB00280DD09D49FF +:109FC0009E4808E068682861FFF738FA002804D046 +:109FD0009A489849401D08F074FDF6F704FA70BDE0 +:109FE000964894490C30F6E7F8B505468F4A0120AB +:109FF0003C3290758D4C17466576213F00260B004C +:10A0000008F064FE09061D2E4E2B69691C64690068 +:10A0100020768748801C0078022807D0384607F051 +:10A0200042FB002803D1A07EA84200D12676207EE4 +:10A03000002803D1FFF77DFF00F0A0FBF8BD207ED4 +:10A04000002806D006F064FA6676384607F043FB2F +:10A0500001E000F075FB2676F8BDFDF79CFEF8BD2B +:10A060007348801C017802290ED0A17E0078A94295 +:10A070000DD0002804D0FF206E497B3008F021FD70 +:10A08000284606F0D8FAF8BDFFF7E8FEF8BD032829 +:10A0900003D0FF206749813015E0FFF7E5FCF8BDEC +:10A0A000A07EA84204D0FF206249873008F009FD55 +:10A0B0005F48801C01780229E6D000780328ECD0A4 +:10A0C000FF205C498E3008F0FCFCE6E7284606F0ED +:10A0D000B2FA6676F8BDFF2056499D3008F0F1FCD3 +:10A0E000F8BD524988755248801C00E020BF0278B4 +:10A0F0008B7D9A42FAD00078002803D000200022FD +:10A100008A7570470120FAE710B500280BD00128A6 +:10A1100005D04A484749853808F0D3FC09E00320B8 +:10A12000FFF7DFFF01E000F049FB002801D000202D +:10A1300010BD0C2010BDF8B5FF273D4D1F24D037B2 +:10A14000AD1C2E78330008F0C1FD040811030C117A +:10A150000220FFF7C6FF002801D000240FE00C24E6 +:10A160000AE00120FFF7D0FF044603E031493846FA +:10A1700008F0A7FC002C02D02878B042E1D1287862 +:10A18000002804D0FF202B49D53008F09AFC27493D +:10A1900000201C3108761C39887501226A70244A17 +:10A1A00008325070C87508612046F8BD70B5044685 +:10A1B0000120FFF721FCC5B20B20FFF71DFCC0B248 +:10A1C000854204D0FF201B49A73008F07AFC01200B +:10A1D000FFF712FCC5B21820FFF70EFCC0B2854293 +:10A1E00004D0FF201349A83008F06BFC0420C043C2 +:10A1F000FFF702FCC5B21920FFF7FEFBC0B2854293 +:10A2000004D0FF200B49A93008F05BFC08484470DB +:10A2100006481B3007F03FFA05490020891C0870EA +:10A2200002498875FFF787FF70BD000050180020B5 +:10A23000700000200C9E0000142D0100220300007D +:10A24000F74840787047F649891E08707047F3B5A3 +:10A2500081B006F0E9F9F349884200D20846FF30A0 +:10A260009930EF4D87B22878002801D00C20FEBD30 +:10A27000ED4806F08CF9ED4CA076E9490320087012 +:10A2800000268D1DAE70A07E002804D19720E849DD +:10A29000800008F016FC0298012827D0E5490198B3 +:10A2A00048436860012028700146684605F028FC94 +:10A2B00068460078E049000208F0E0FA0D4606F032 +:10A2C000D5F9791906F075FC6060DC48A0600320C0 +:10A2D0002070022060702673A07ED449FFF7B0FB87 +:10A2E000CF48A682072141700020FEBD06F0BEF9CE +:10A2F000394606F05EFC6060D148A0602E700120F7 +:10A300006870E4E7704770B5C5490A78002A01D043 +:10A310000C2089E702220A70C14CC44DA41E1C35D2 +:10A320006060287E002804D0C248C1494E3008F041 +:10A33000C8FB207800234100C248425A616820319E +:10A34000497F4900405A101881B21A461846FFF753 +:10A35000BEFB002804D0B748B549503008F0B1FB27 +:10A36000002068610121E8602976B049888262682E +:10A370005188491E51802887A88655E770B5A8489E +:10A380000124801D4078A94D002813D028461C3098 +:10A390008168AD48814202D8AA7D032A00D10024F9 +:10A3A000814207D9A87D032801D0012000E00020C8 +:10A3B000FFF72FF9A87D032800D10024204633E7BA +:10A3C0009A481C300178491C0170026B81689142E7 +:10A3D00004D8007E012801D001207047002070477A +:10A3E0000020704770B5914C1C34207E032849D161 +:10A3F0000021204620308175894DAD1E68684030AF +:10A40000007C00283ED106F031F988490A690146EE +:10A41000104607F085F8002834DD00F082F96968FD +:10A42000401C4A888018A0860889A28E904229D9AB +:10A430004888088140318A8A498A511A491E081879 +:10A4400086B21AE0287841007E48425A6968203175 +:10A45000497F4900405A1018A28E81B2207E012304 +:10A46000FFF735FB00280DD001280CD0022809D0B9 +:10A470006C486F49C43808F024FBA08E301A00B233 +:10A480000028DFDAD0E6A08E401CA086F5E7F8B5FC +:10A49000664C634F00251C34BF1E012819D00720CD +:10A4A000B91C487006F034F8604E304675761B30A3 +:10A4B00007F011F97878F8F7A5F8B5827868314691 +:10A4C0004088208701203C318875002000F003F986 +:10A4D000F8BD267E52495B48891E0A7853004A68B7 +:10A4E00011462031032E18D0267E022E21D0267E42 +:10A4F000012ED7D1497FC35A4900405A12891818F2 +:10A5000081B200230120FFF7E2FA0028CAD04548B3 +:10A510004749213808F0D5FAC4E76561E560497F0D +:10A52000C35A4900405A1289181881B200230320E7 +:10A53000E9E75626B65A6661497FC35A4900405A30 +:10A540001289181881B200230220FFF7C0FA0121F6 +:10A550002176DAE7F8B5324E0021B61D7078334C1B +:10A560000D46002801D075701AE03078002809D017 +:10A570000121684605F0C4FA684600782E490002B9 +:10A5800008F07CF970684118606806F012FB6060A2 +:10A59000257302206070607E2449FFF751FAA5827E +:10A5A00005F0B6FF214865761B3007F094F81C488B +:10A5B000801E4078F8F726F8002000F08CF8F8BDEF +:10A5C00010B5030008F082FB060A0E0406130916F4 +:10A5D000012000E0002000F037F910BD0120FFF756 +:10A5E00056FF10BD114903201C31087610BD00F044 +:10A5F0003DF910BD0B480E498E3008F062FA10BDCF +:10A6000070B50A4D002821D0054EB61D012828D06E +:10A61000022837D003480649AD3008F052FA03E665 +:10A6200072000020F6050000E99F0000501800208D +:10A630000C9E00007102000010270000F82A0000A4 +:10A64000B7891300142D01002E841300FFF782FF39 +:10A65000A97D9448002901D01F2100E00721417005 +:10A66000E2E5002490487470047600F046F8032078 +:10A67000F7F7C7F805F04CFF8B486C76401E07F0E3 +:10A680002AF8D1E5FFF766FF0120B07000F035F839 +:10A690000420F7F7B6F8C7E582490978022907D1FF +:10A6A00081490A78002A03D148600A6B10180863B0 +:10A6B000704710B57C4A00290BD0012906D0022929 +:10A6C00006D07A497A4808F0FCF910BD401E00E037 +:10A6D000401F906010BD744910B51C39C875002822 +:10A6E00005D0F5F781FE0220F5F778FE10BDF5F7ED +:10A6F0007CFE0120F5F77AFE10BD6A48002101704A +:10A7000001214170704710B504460020002907D090 +:10A71000684808F0B3F80146204608F0AFF8401C3E +:10A7200010BD10B500280AD05E49634A891E4968E9 +:10A73000C98B51435C4A126A891A08F09FF810BD10 +:10A7400010B558480078030008F0C0FA0414140348 +:10A750000A1401F035F900280BD05449574806E097 +:10A76000FEF737FF002804D054485049001D08F078 +:10A77000A8F910BD51484D490B30F8E710B505F068 +:10A7800053FF4849891E4968CA8B4B494A43464989 +:10A790000B6AD21AD33AFF2332330A63984202D2A9 +:10A7A0004748101802E0101A464A801808634648C5 +:10A7B0000A6B824200D81046086310BDF0B53A4CCF +:10A7C000032685B01C3CA67520461B30009001E096 +:10A7D00020BF009806F067FF0028F9D10025A57575 +:10A7E00030480178032903D0007800281DD021E0EB +:10A7F000A07E002803D12D49344808F062F9A77ED5 +:10A80000684606710221417105F030FF0290FF2079 +:10A81000F5300390012168460174A57601A93846F8 +:10A8200006F070FAFFF769FF0CE01E48801D817882 +:10A83000012906D00024009806F04DFF204605B0FF +:10A84000F0BD85700124F6E710B5002803D0002084 +:10A85000FFF71DFE04E01348801E4078F7F7D2FE94 +:10A86000FFF74BFF0020F6F7CCFF10BD10B50E4AE6 +:10A87000114B106AD0600B48801E4068C18B594351 +:10A8800011610146E0314B8843870C7839231C5411 +:10A890008B88C383CB880384098941840220107686 +:10A8A00010BD0000720000206C1800200C9E0000FB +:10A8B000C306000040420F00E20400004303000012 +:10A8C000A5F8FFFFD6F9FFFF1612000029020000CD +:10A8D000F8B5FEF7DEFA0646FEF74CFBF94D0746E3 +:10A8E0006879F94C002809D0012823D0022826D005 +:10A8F00003282ED0FF20F5A1BC3033E0F2481430FD +:10A90000FEF724FB002801D003200FE0EE481430AE +:10A91000FEF788FA002804D020696030007A002809 +:10A9200006D0E9481430FEF7E4FA012068711BE014 +:10A930000220FBE7E4481430FEF7DBFA14E0E248BB +:10A940001430FEF76FFA00280ED1FF20DFA1AE30E1 +:10A9500008E0DD481430FEF7F9FA002804D1FF20A2 +:10A96000DAA1B63008F0ADF86169F7220878104036 +:10A970000870AA79D207120F1043FB22104008700A +:10A98000EA79D207520F104308706B79EF22022B3D +:10A9900004D0012B07D0032B07D00CE0012E06D8E2 +:10A9A000002F04D007E07F1E3E43002E03D010404E +:10A9B0001022104300E010400870287C002811D0BD +:10A9C000687901280ED0BF484A38FDF7F5F8BD492F +:10A9D00020694A3978306269FDF757FB0020FDF79E +:10A9E00063FB04E00846FDF7E7F8FDF780FB6069CC +:10A9F0000078C00606D4A0690078C00602D4E079C9 +:10AA0000002802D0A079002801D0012000E0032016 +:10AA1000FCF7B6FF0320207001202071F8BDAA4882 +:10AA200010B51830FEF7B9FAA74C002802D0002064 +:10AA3000607004E001206070A2484A38A061A1481B +:10AA4000407C002802D06078002805D0A069FDF77E +:10AA5000B3F8FDF74CFB10BD9A484A38FDF7ACF847 +:10AA6000984A20694A3AA030A169FDF70EFB0120FF +:10AA7000FDF71AFB10BD10B5934900220869302379 +:10AA80008276C27601221A544030007C002803D01E +:10AA90000A700021022001E000210320FFF790FD51 +:10AAA00010BD70B5884C6079C20620460169084621 +:10AAB0004030002A01DA002202E0C28A4B89D21813 +:10AAC0000B46C282C0331A7E002A03D0428B4D89C6 +:10AAD00052194283627A002A03D03D2001F0A3F884 +:10AAE00052E08A7E032A4FD0227A002A13D05007E0 +:10AAF00001D4D00601D51E2036E0100701D53D2037 +:10AB000032E0D00705D1900703D470A1734807F055 +:10AB1000D8FF2A2028E060310978002905D0818BF0 +:10AB20004A1C8283C28B91420FD2597F062902D0E0 +:10AB3000197F062905D1018B4A1C0283C28B9142E1 +:10AB400003D2428B818A8A4201D322200CE0827B8D +:10AB5000408A002A0FD006280FD35A48C07B01280C +:10AB600001D03E2000E0082001F05DF82069807EE1 +:10AB7000032809D001E08842F5D20120207000218D +:10AB80000846FFF71DFD70BDFFF775FF70BD10B5DE +:10AB90004C494D48CA7B002A2BD0012A29D0022AD1 +:10ABA00027D0032A04D049A14D4807F08AFF10BDE1 +:10ABB000897B02290FD007291BD00069014640314B +:10ABC0008A8A498A511A891E89B2032900D303212E +:10ABD000028951180BE00069014640314A8A032A74 +:10ABE00001D2018903E04288898A5118491C818079 +:10ABF00010BD0069F5E700B5030008F067F806042A +:10AC0000070B0F12121700290ED00FE0491E022960 +:10AC10000AD90BE0491F012906D907E0072903D00B +:10AC200004E00A390C2901D8012000BD002000BD34 +:10AC3000FEB5054624481430FEF769F9002804D112 +:10AC40003D2022A1400107F03CFF1F4C6069FDF749 +:10AC5000E5FC03216069FDF70FFD6069EF220178D3 +:10AC6000114001702946FDF74BFD002601272B00FE +:10AC700008F02CF80E5D5D085D1D6161155D4D5D90 +:10AC8000613D385D20697121095C002901D00621F0 +:10AC900001E0C030417E6069FDF7FDFD4BE0A06939 +:10ACA000FDF758FD01466069FDF766FE43E0216946 +:10ACB0006069D031FDF729FE216960699531FDF7A2 +:10ACC00032FE38E006190020800000207372635CB9 +:10ACD0006C6C5F736C6176652E630000610200002E +:10ACE0006F08000006216069FDF742FE23E0E0687E +:10ACF00001786069FDF726FEE06881886069FDF7EC +:10AD000023FEE06841886069FDF722FE13E00096AB +:10AD1000019620696030007C002803D069460878DD +:10AD20003843087069466069FDF738FE03E0FA4968 +:10AD3000FA4807F0C6FEFEF7F4F8002804D1F748F9 +:10AD4000F549801D07F0BDFE0C2D07D0072D04D05E +:10AD500020695C210E5260300770FEBD20694030D2 +:10AD60000683FEBDF0B5EE4CDC2021698DB0405C61 +:10AD7000042809D0052834D16031487A002829D028 +:10AD800001204874022026E01022EA31684600F0D3 +:10AD90007AFF21691022C83104A800F074FF6846C8 +:10ADA00005F007F8216908AA6CCA0F46CB67783707 +:10ADB0008A670846FE608030BD60074620376CC752 +:10ADC0000023036343630120A0310876D54948740A +:10ADD000052000E00D20FFF72BFF21690020C03186 +:10ADE00008770DB0F0BDF8B5CD481430FEF78FF8F8 +:10ADF000002842D0CA4C207A00283ED12069002584 +:10AE0000C030007EC74E00280BD0B17B0120FFF779 +:10AE1000F2FE002805D1B17B0420FFF7ECFE0028EC +:10AE200006D020690127C030407F062807D00CE0FB +:10AE300020695A210D526030457402202FE0B17B09 +:10AE40000420FFF7D8FE002810D0B07B030007F0E5 +:10AE50003DFF173F3F3F3F1E3F3F3F3D3F203F3FAE +:10AE60003F292C3F3F3F3F3F3F2F3F0020696A2152 +:10AE7000095CC90702D0C0304577F8BD0C20FFF748 +:10AE8000D7FE20696030817A39438172F8BD07208E +:10AE900005E0FEF7ACF80028F8D075740B20FFF73A +:10AEA000C7FEF8BD00F0FEFEF8BDFFF75BFFF8BD82 +:10AEB0002069002180308160C160057437740620EC +:10AEC000FFF7B6FE206960300570F8BD0920E6E79F +:10AED00000F0B2FEF8BD70B5924DA87B072831D1C5 +:10AEE0008F4CDE2220694188125A491C914229D197 +:10AEF000217A002926D10146E0318B88C28B93420A +:10AF000007D1CA88068CB24203D10A89468CB24264 +:10AF10000AD0844A8689283A9680D380CB881381C8 +:10AF2000098951810121117001221146FDF784FD2B +:10AF300000210420FFF744FB21690020C03148773D +:10AF4000A873E87370BD70B5764CA07B162803D04B +:10AF50007149754807F0B5FD7148002102697148D3 +:10AF60006032117211702838067C0B250123002EE7 +:10AF700006D0027B002A12D14573817303730EE061 +:10AF8000567A002E06D051722288828281740C2259 +:10AF9000027404E022888282817483750574A1732F +:10AFA00070BDF8B55E4DA879800723D5287A0028B2 +:10AFB00020D15C4C0120A17BFFF71DFE002819D198 +:10AFC00068690026C0780127030007F07FFE0E594C +:10AFD0005908592E3B4F0A591459205245590220FD +:10AFE00021E0A07B042804D04F484B49333807F0B8 +:10AFF00068FDA673F8BDA07B082804D04A484649DE +:10B000002D3807F05EFD286960300670F1E7A07BFF +:10B010000A2804D015204049800107F052FD286914 +:10B02000603007720B20A073F8BDA07B0E2804D0FF +:10B030003D4839491F3807F044FD286960300772E0 +:10B040000F20F0E7A07B0F2804D03748324918388A +:10B0500007F037FD1120E6E7A07B0F2804D0324827 +:10B060002D49123807F02DFD1320DCE7FFF76BFFA9 +:10B07000F8BD2869C030417F0629F9D14677F8BD6F +:10B0800029482549813007F01CFDF8BD10B5254C35 +:10B090000020A17BFFF7AFFD002804D1204801224A +:10B0A000017A114301720420A07310BD10B51C4C2D +:10B0B000DD212069095C002903D0217A0122114396 +:10B0C00021726030807A800715D4A069FDF744FCB6 +:10B0D00021696031C872A069FDF740FC21696031C7 +:10B0E0008881A069FDF73FFC216902226031C88197 +:10B0F000887A10438872206900220146C0310B7F94 +:10B10000062B13D06A231B5CDB0703D106234B7786 +:10B110004030028310BD0000CCAC0000E40700000A +:10B120008000002006190020660500000A77F1E77C +:10B13000F8B5FE48817B0020FFF75DFDFC4C012641 +:10B14000002807D120696030407A002802D1207A97 +:10B1500030432072216900255C204552602046540E +:10B16000C831A069FDF7B9FB2169A0699131FDF7EC +:10B17000C3FB2169042208469131B93007F004FB72 +:10B18000EA482838017C0827002906D0017B0029DD +:10B1900012D14773857306730EE0216905468989CC +:10B1A0004182E249A0691439FDF77FFBDF49A069BC +:10B1B0000C39FDF787FB2F74DC480E218173F8BD35 +:10B1C00070B5DA4D0020A97BFFF715FDD84C00289B +:10B1D00003D1207A012108432072A069FDF721FBE9 +:10B1E00000280ED0A069FDF717FB2169DE2250521E +:10B1F000498800F0A2FD002806D0282000F013FDA9 +:10B2000070BDFFF743FF70BDA069FDF7FFFA21692C +:10B21000E0310870A069FDF7F2FA2169E031488059 +:10B22000A069FDF7D1FA2169E0318880A069FDF7B6 +:10B23000D4FA2169E031C880A069FDF7D7FA216905 +:10B24000E03108810720A87370BDF8B5B84CA0792B +:10B25000C0076ED0207A00286BD1B44D0120A97BA5 +:10B26000FFF7C9FC002853D1A0690027C17802224A +:10B2700001260B0007F02AFD0D161308354A4A383F +:10B280004C474A1929444A00FDF707FB2169DA2295 +:10B290005054AE735C20475260310E7038E000F0BD +:10B2A00057FD35E0FFF78CFF32E0A97B0020FFF768 +:10B2B000A2FC002802D1207A3043207220695C2150 +:10B2C0000F52603006700A2018E0A87B0B2802D0CD +:10B2D000207A104320722F742069603046720C204F +:10B2E0000CE0FFF725FF13E0A87B112802D0207A9D +:10B2F000104320722069603007701620A87307E0A1 +:10B30000FFF7D4FE04E000F0F0FC01E0FFF7BEFE22 +:10B31000FDF759FE002803D18649874807F0D1FB85 +:10B32000206900238030016B426B491C5A41426303 +:10B330000163F8BDF8B57D4F787C002802D1387CD8 +:10B34000002801D0FCF7D3FEFCF760FCFCF754FCAE +:10B350000020FCF715FBFCF79CFBFCF75CFCFCF702 +:10B36000DCFBFCF724FCF87B01260025704C002850 +:10B370000FD16079C10705D00220F87320694030F1 +:10B38000857302E0800717D5FE7300210120FFF7C7 +:10B3900017F9F87B012802D0022808D00CE0607968 +:10B3A000C00709D00220F8732069403085736079A6 +:10B3B000000701D50320F87300F0EEFCFFF713FD42 +:10B3C0002079002801D03D8102E03889401C388175 +:10B3D0006079C007206904D072210D544030458245 +:10B3E00003E04030418A491C4182E079002806D0C0 +:10B3F00021696031887C022806D8401C8874206945 +:10B400006030807C022804D93D817D8120696030D4 +:10B410008574B97B0020FFF7EEFB002802D1B87BD2 +:10B4200006284BD120690146C0310A7F062A45D043 +:10B43000497F062942D03D49C97B03293ED160306E +:10B44000807C00283AD1FDF71BFD002836D0FDF79F +:10B4500091FD002832D02169C88801282ED90A46DA +:10B460004032D673908A578A831E9F4201DB0120A7 +:10B4700002E0C01B401E80B22C4B0F8C1B89BB42CC +:10B4800001D3012302E0FB1A5B1C9BB2984200D956 +:10B490001846012800D1D5732A22525C002A11D007 +:10B4A000224A898D52898A4201D3012102E0891AF8 +:10B4B000491C89B2884205D9084603E02169012068 +:10B4C0004031CD7321694A8810180881FFF75FFB6E +:10B4D0002069122215490C3007F056F9FFF7E1FAFE +:10B4E000FEF77EFF002808D010482838817F002909 +:10B4F00003D121698989018486770D481830FDF7C9 +:10B50000AAFD00280FD0A06900788007800F0128CD +:10B5100009D0022807D0FDF7BEFD002803D1054958 +:10B52000064807F0CEFA2069403009E006190020ED +:10B5300080000020CCAC0000DF040000720300009B +:10B540000574F8BD70B5FE4C607900283DD0FD4D06 +:10B55000022811D1FDF775FC002804D17320FA49A7 +:10B56000000107F0AEFA2A69002380329068D168A2 +:10B57000401C5941D16090600026667120790128F5 +:10B5800004D12671A87910210843A871E078012818 +:10B5900016D1E670A87908210843A871FDF7E0FCF0 +:10B5A000002804D1E920E849C00007F08AFA296997 +:10B5B000002380318A68C868521C58418A60C8607C +:10B5C000A079012802D00120A07170BDA67170BDC4 +:10B5D000F8B5DC4CDA4DA269002710780421830706 +:10B5E0009B0FE8790126012B11D0022B0FD0032BE2 +:10B5F00001D0207A2FE06178002905D1AE70A179C1 +:10B600003143A17122E0EF71F8BDEE71F8BD5278BF +:10B61000D3061BD060780028F8D1D006C00E1B28B6 +:10B6200017D8607908436071FDF7CDFC002803D17D +:10B63000C549C64807F045FA206900238030026BEF +:10B64000416B521C594102634163E8790128DCD106 +:10B65000D9E7207A102108432072F8BD70B5B84DA3 +:10B660000446283D287B002600280AD0002976D1F0 +:10B67000667010202070687BA070A87BE0702E732D +:10B680006DE02878002810D0002968D16670072066 +:10B69000207005E02E700A22A91CA01C07F074F887 +:10B6A00028780028F6D1A67059E0287C002839D0E7 +:10B6B000002954D1297CA3480B0007F007FB0D2E6D +:10B6C0002E2E2E2E2E2E2E112E2E22082E0066709D +:10B6D0000C212170A97CA17000698089A0801AE0EA +:10B6E00008216670217000690A468089944960804B +:10B6F0001439201D07F048F891484A38C08FA081BE +:10B7000009E066700B212170A97CA1700069808915 +:10B71000A080A87DA0712E7421E08B498C4807F091 +:10B72000D0F91CE0AA7F86480838002A08D00029F2 +:10B7300015D166701121217000886080AE770EE00F +:10B740007F4A083A9378002B0BD0002907D1667006 +:10B750001221217081886180C088A08096700120AC +:10B7600070BD002070BD77480078012801D00C2002 +:10B770007047734900202839087008730874887767 +:10B78000704770B56F4C064620780D46002804D0EF +:10B790006F486D493F3007F094F90120E660E07290 +:10B7A000E5612070FFF7DFFF002804D09320664991 +:10B7B000000107F086F970BDF8B5624C21780129C7 +:10B7C00002D12178012901D00C20F8BD014605469F +:10B7D000206112220C315A4806F0D6FF012740356D +:10B7E0002F74574D2888FDF712FB002827D0288892 +:10B7F000FDF7C8FB002822D02888FDF77DFB002834 +:10B800001DD02888FDF797FB002818D0FCF7C3F956 +:10B8100020690026C088002824D04A481430FDF74B +:10B8200076FB00281ED02069C030007E002819D089 +:10B83000A97B0120FFF7DFF9002802D012E01220D7 +:10B84000F8BDA97B0420FFF7D6F900280AD12169A9 +:10B850005A20465260314E740220FFF7E9F9206900 +:10B860004030C67320694189491E8AB229898918E6 +:10B870002981297B002902D06E812E7302E069891B +:10B8800089186981014640314B8A9B184B82C388D5 +:10B89000012B01D85B1CC380002A01D072221654F0 +:10B8A000AA7B032A16D0C97B002915D02989008CD0 +:10B8B000814211D2FDF7E4FA00280DD020692A2137 +:10B8C000095C00290BD06989808D814207D3A6705D +:10B8D000E7700CE0A7700AE0A670E67007E06889E0 +:10B8E0000021401C6881A7700520FEF769FE2069D1 +:10B8F0004F210E54A178002930D12030807A0028C1 +:10B9000000D06E810120FBF71BFF20693630FCF769 +:10B91000F8F820693230FCF70EF8E169002008568B +:10B92000FBF7D5FF0120FCF733F9FBF78EFFFCF79F +:10B930002BF90120FCF76AF82069406E0AE000004C +:10B940000619002080000020CCAC00007B0700001E +:10B95000E7080000FCF733F9FFF761F8A87B05283A +:10B9600001D0062816D12069DE224188125A891A90 +:10B9700009B200290EDB01460522E0312430F4F73C +:10B9800023FC012202212069FDF756F82069C0300E +:10B990004677AE7320694189FDF7FDF82069403094 +:10B9A000407BFBF7D1FF6671E671A6712672A67225 +:10B9B0006672267102202070FCF7F9F80020F8BDAD +:10B9C00010B5FE4C2078022801D00C2010BDFCF7E9 +:10B9D000E2F8A078002802D0FFF7ACFC15E000F0F8 +:10B9E0001AF920692030807B012809D0FCF736F94C +:10B9F000FBF730FFF4F7F7FCE07A012803D004E00E +:10BA0000FCF734F9F4E707F05BF9002010BDEB49CF +:10BA1000C872704710B5E94C2078032803D0E84974 +:10BA2000E84807F04EF8E84801218278002A06D05D +:10BA3000002282700171A27904231A43A271626903 +:10BA40001378DB439B0707D1C378002B04D1C17067 +:10BA5000A07902210843A0711078C00606D4A0691D +:10BA60000078C00602D4E07900280CD06078002865 +:10BA700009D1A079002806D1FEF7A2FC002802D047 +:10BA8000207A002802D0FFF755FC03E0FEF7C7FF3D +:10BA900000F0C1F82078012806D0F4F7A4FCE07A81 +:10BAA000012801D1FCF772F910BD38B5C34C2069EB +:10BAB0002030807B012820D1A07A00281DD1684643 +:10BAC000FCF7DCF8002818D021692F20405C012801 +:10BAD00010D1BD4A0D236D460020D356285683420F +:10BAE00008D050738989283A918411462031887191 +:10BAF00001208870A07A401CA07238BD70B5AF4C90 +:10BB000006462078042804D0AE48AD49553006F0EA +:10BB1000D8FF607910210843AB4D6071002E47D0EB +:10BB2000FCF7FDFA61780126084300280ED1687CF5 +:10BB300000280BD0A0694178C90607D00078E979C0 +:10BB40000007C00F884201D1667247E0E078002804 +:10BB500009D0A0694178C90605D10078C00602D491 +:10BB6000FFF7A3FF3AE0FFF7A0FFA069A9790078EB +:10BB70004007C00F884205D0FFF7E4FC6079082138 +:10BB800008436071A069E97900780007C00F884216 +:10BB900001D1FFF71DFD6079304360710020E07135 +:10BBA000A079000702D5A87B022817D0207A13E0DD +:10BBB000022108436071E079401CC0B2E0710128A5 +:10BBC0000CD8687C00280CD07F484A384078C106E1 +:10BBD000C90E052905D2C006002802D0FFF7AAFB2E +:10BBE00001E0FEF775FE2078012806D0F4F7FBFB94 +:10BBF000E07A012801D1FCF7C9F870BD10B56F4893 +:10BC00000078042804D06F486D49B73006F059FF1A +:10BC1000FFF790FB10BD10B50720FBF7B1FE674999 +:10BC20000420087010BD6549312209695054664AE4 +:10BC3000032090738876704710B5604C2069C0303F +:10BC4000007F00281ED06048817B0020FEF7D3FFD4 +:10BC5000002817D02069DC21095C0B0007F036F8BA +:10BC6000071212121212120512006030807AC007F9 +:10BC700008D10C20FEF7DCFF206901226030817AB8 +:10BC80001143817210BD10B5002A0AD0002306E0CE +:10BC9000D41A6418203CE47FC4545B1CDBB293428A +:10BCA000F6D310BD10B503F02AFF0C281CD3434C6B +:10BCB00008212069D03003F023FF002806D0206936 +:10BCC0000421953003F01CFF002803D13C493F4874 +:10BCD00006F0F7FE2169042208469531BD3006F0D2 +:10BCE00053FD0420FEF7A4FF10BD7CB5364E0020A6 +:10BCF000B17BFEF780FF0125304C002802D1207A6D +:10BD0000284320726946A069FCF74EFE6846007819 +:10BD10000021C207D20F684602702069002A02D0B3 +:10BD20006030057401E06030017420695C221152BA +:10BD3000603005700820B0737CBD401A244900B201 +:10BD4000884201DC002801DC012070470020704798 +:10BD500070B51D4D0020A97BFEF74DFF174C002844 +:10BD600003D1207A012108432072A069FCF78EFDDF +:10BD70002169DE2250524988FFF7DFFF002803D0F7 +:10BD80002820FFF750FF70BD2169A069E031FCF762 +:10BD900071FD0520A87370BD70B500F054F8074C14 +:10BDA000094D6079400716D5A97B0520FEF723FFD2 +:10BDB000002810D0207A082108430BE080000020E2 +:10BDC000CCAC00001D0A000006190020640600002B +:10BDD000FE7F00002072FFF738FA00F012F8FFF73C +:10BDE000E0F8A079C00609D5A87B030006F06EFF35 +:10BDF00006060606060604060620A873FFF76BF87B +:10BE000070BD10B525488179490714D5017A0029FC +:10BE100011D12349897B0B0006F058FF080D050D51 +:10BE20000D0D0E0D100D0069002260210A54C03066 +:10BE3000807EFFF7F8FE10BD012100E002210069BD +:10BE4000C030417710BD10B51448817909071DD560 +:10BE5000017A00291AD1124A947B230006F036FF9A +:10BE60001416160B1616161616161616161616167F +:10BE7000161616161716006960300170407C0028EF +:10BE800001D0062000E01620FFF7CDFE10BD0069AE +:10BE9000603001720170917310BD000080000020BD +:10BEA0000619002010B5031D03600020521E04E097 +:10BEB0005C181C60401C2346C0B29042F8DB002096 +:10BEC000186010BD01460A680020002A02D0104602 +:10BED00012680A60704702680A60016070470000DB +:10BEE00000B51A2822D00ADC030006F0EFFE0D117F +:10BEF0001F131F1F191915171F1F1F1B1F002A288B +:10BF000014DD3A38030006F0E1FE030F11091100B9 +:10BF1000002000BD1E4800BD042000BD0D2000BD56 +:10BF20000F2000BD082000BD112000BD032000BD72 +:10BF300010B50C46F5F7C8FB00281AD02046F4F7D8 +:10BF400061FE002812D020780E280BD00F2809D0CF +:10BF5000022807D0032805D00EA1772006F0B1FDF6 +:10BF6000002010BDA078FFF7BBFF10BD09A17D2008 +:10BF7000F4E708A18320F1E710B5F4F7CBFD10BD7D +:10BF800010B5F4F73FFE10BD10B5F4F721FE10BD5B +:10BF9000013000007372635C686F73745F6863697B +:10BFA0002E630000F0B597B00021032004F0F7F8ED +:10BFB0000025FE4E022775807574347C12E0F0680F +:10BFC000E1004018818800290CD0858069460F70F7 +:10BFD0004D7001680291808869468880002168461A +:10BFE000F8F7F0FD2046641EE4B20028E7D117B050 +:10BFF000F0BDEE4BD86019741A80D3E7EB49EC4BD7 +:10C000004A8800201A4200D00120497C002901D032 +:10C01000082108437047F7B504460E460078012111 +:10C02000E34A8140521C114098B0E04A0091518887 +:10C03000E04B994205D0009B002B05D0DC4B194208 +:10C0400002D001201BB0F0BD009BD84A194351809B +:10C050001A9D002D11D00020287022781A980027F0 +:10C06000401C130006F032FE10EF0D152137555D10 +:10C070006A39AFAB85B3EEEDECEF0B28EDD00420C1 +:10C08000E0E702212970A1880170090A41700320AC +:10C0900093E004212970A1880170090A4170E188A8 +:10C0A0008170090AC170052087E006212970A188E6 +:10C0B0000170090A4170E1888170090AC170218903 +:10C0C0000171090A4171A289E81D216906F05CFB32 +:10C0D000A089C01D71E0082129702178082901D1AB +:10C0E00010212970A1880170090A4170E1888170CE +:10C0F000090AC1700520308020466A1D01A9083058 +:10C1000003F047FB00287DD1694630880979401843 +:10C1100053E00A212970A1880170090A41700320A7 +:10C120000AE00C212970A1880170090A4170E18898 +:10C130008170090AC170052030809DE0A088844686 +:10C140004000401C81B2308888425BD3052959D316 +:10C150000E202870002008E0A36842009B5A521964 +:10C1600053701B0A401C937080B26045F4D3318039 +:10C17000B6E08E49487C002873D0401E4874C868D9 +:10C1800021790822C9004518A9882868401808386C +:10C19000A16806F0F9FA0221684601710021417197 +:10C1A00028680390A98868460181002101A8F8F752 +:10C1B00009FD0020A880002E00D0308090E0297872 +:10C1C000802211432970297840221143297029784F +:10C1D0008909890112312970A1880170090A417009 +:10C1E000E288E81CA16806F0CFFAE088C01C308025 +:10C1F0002878410640D5C00972D0012168460171F6 +:10C20000002100E02BE041713188ED1C091D018106 +:10C210001A980390E08840190490001D634D059022 +:10C22000297C68460176002101A8F8F7CBFC074677 +:10C2300030880C303080022F06D0002F50D060E0C4 +:10C240003CE032E01CE059E06946097EE868CA003B +:10C2500080182A7C914202D28188002902D00427CA +:10C260004FE02EE0697C491C69741A99016031889D +:10C2700081800020308044E04C48A188C1802FE0BC +:10C2800029788909890116312970A1880170090A64 +:10C290004170E1888170090AC1702289681DE168D6 +:10C2A00006F072FA2089401D46E72878800980014F +:10C2B000183028702079687002207EE73B480A0415 +:10C2C00001D405271DE00289A3889A4201D00627E0 +:10C2D00017E01E222A70012249043280490C418055 +:10C2E000009800280DD0314D002228881146830087 +:10C2F000032003F0B2FE2078287107E00020308090 +:10C3000003272A48009942888A434280384699E6A2 +:10C31000F7B59AB002000C4606D0172A04D8234875 +:10C32000244B4088984202D107201DB0F0BD2378ED +:10C330005D0601D4DB0901D00820F6E700236D4635 +:10C340002B706B701D462378611C9F06931E1893FB +:10C35000531E19939BB2169302AB1793134BBF0E48 +:10C36000DE883B0006F0B2FC208511F15EF16BF136 +:10C37000A3F1C6F1F2F1FBF1EEF1EDF1ECF1F1F127 +:10C38000EBF1EAF1E9F1E8F185F1052A71D1042236 +:10C3900069460A7005490A7969460A71E178A37805 +:10C3A0000A021A436946CA80227905E0181900205A +:10C3B000FE710000FFFF00004A7061788906890E57 +:10C3C0000C2923D009DC891E0B0006F07FFC091321 +:10C3D00052155219521B521D520012291CD004DC56 +:10C3E0000E2915D01029D1D114E0162916D01829FC +:10C3F000CCD115E0800700E04007002839DA2AE1B7 +:10C400000007FAE7C006F8E78006F6E74006F4E71B +:10C410000006F2E7C005F0E7C004EEE78004ECE7B1 +:10C420004004EAE7800724D5032AAFD105206A46F5 +:10C430001070487809780002084390800BE14007AB +:10C44000F1D5062A15D31898617880B2012902D057 +:10C4500002299BD101E0022700E01027062269464D +:10C460000A7000228A8001AEA11C0236BA1C179203 +:10C4700018E0B6E04A780B7812021A433280801E28 +:10C48000891C1890B21C1691384603F05CF9169975 +:10C4900018986B469A88C919C01BB61D521C9A8001 +:10C4A000179A80B28242E5D900289CD1D3E00007D8 +:10C4B000B9D51998694682B2072008700020888093 +:10C4C000601C891D11E0437806781B0233430B8002 +:10C4D000C37886781B0233434B806E46121FB388A5 +:10C4E000001D091D5B1C92B2B380042AEBD2002A06 +:10C4F00077D1B0E0C00674D5022A72D3189808210B +:10C5000082B2684601700021C18063780371A01C6B +:10C5100017990EE04678077836023E430E80861C57 +:10C520004E606F46D21AFE88C0180831761C92B24F +:10C53000FE809342EED9DAE76FE076E065E051E005 +:10C5400046E01EE014E00AE000E0A0E0800648D5E6 +:10C5500009206A46107096801698D0800FE0400639 +:10C560003FD50A22684602708680169AC28006E08D +:10C57000000636D50B206A461070169890800291FE +:10C5800069E0C0052DD5022A7FD318980C2182B20C +:10C59000684601700021C18063780371A01C17995F +:10C5A00013E04678077836023E430E80C6788778D7 +:10C5B00036023E434E80061D4E606F46D21AFE88FC +:10C5C000C0180831761C92B2FE809342E9D98EE7FA +:10C5D000C0045AD5012A58D10D21684601708680C1 +:10C5E00039E052E0800450D5052A4ED30E23684628 +:10C5F00003708680C8788B78010219436846C18031 +:10C60000521F0281601D039025E040043DD5012AA0 +:10C610003BD10F20694608701DE0030435D44B78E8 +:10C620000E781B023343244E3381032A2DD31B2F54 +:10C6300027D011236E46337001261F4BF60330437B +:10C64000588048780B780102194368468180D21ED1 +:10C65000C280E01C029020788006800E1B280AD041 +:10C660001D2808D00021032003F099FD12484188BD +:10C67000C90BC903418068461C99F8F7A3FA2846FC +:10C6800053E610206B461870DBE70725F7E708250F +:10C69000F5E700B50022D243074997B04A80032846 +:10C6A00007D1032268460270097901710021F8F769 +:10C6B00089FA17B000BD000018190020FFB589B035 +:10C6C0000020019009981027FE4C1E4615460828A8 +:10C6D00006D0E06901F05EF8002809D03770BEE0AE +:10C6E000288809213843108013980227017016E02A +:10C6F000E169012088710521E269C9029180E1693F +:10C700008872E169F0480881E1690020887328880F +:10C7100020210843288011211398042701701398C1 +:10C720000225801C0290307806900A203070E5487F +:10C730001830049001F00DFA0020059020462C30AE +:10C7400003906DE00998102808D1022D06D00199B8 +:10C750000298A28D401A8270110AC170E08D0A9968 +:10C76000884202D901F0D5F806E0884204D1069843 +:10C77000002801D030701CE00298E18D0170090A98 +:10C78000417012980088401BC01B82B2FF20C01B62 +:10C79000904200D2024607A8009002980021C319D7 +:10C7A000E08D01F041FA3070002805D0C0B2832836 +:10C7B00058D0E08D20833EE00598002804D0206CFE +:10C7C00000790A282CD336E06846808BC119C9B29B +:10C7D0000191022D0DD01399019A4978914202D10D +:10C7E000228F824208D00191206C0178032908D061 +:10C7F00023E0084613994870206C0178042906D07C +:10C8000007E000790A2818D20120059008E0E18DA0 +:10C81000818002990198081802900198281885B221 +:10C820000399049801F098F9002804D1129800881F +:10C83000401BB84286DA022D0DD00998102806D187 +:10C8400002990198A28D081A8270110AC17012987B +:10C85000058000203070206C0078032802D0002072 +:10C860000DB0F0BD0220FBE7F8B5964A0026126D28 +:10C87000002A2ED0401F934D84B24035E88A2346CB +:10C880000833AF8AC318BB4222D88B784F781B027B +:10C8900010183B4303701B0A43700B79CF781A02C0 +:10C8A0003A438270120AC2700471220A427122460F +:10C8B000491D801D05F068FFE88AA41D001980B29B +:10C8C0008049E882096D002208180270427000E079 +:10C8D00009263046F8BD30B57A4B028840339B8A32 +:10C8E000934213D9774B1C6DA3185C781D782402F2 +:10C8F0002C430BD05C791D7924022C436404640C16 +:10C90000A41D1219028000200B6030BD822030BDB2 +:10C91000F0B585B0074600266846068155E00198C7 +:10C92000417802780D0215434179027908021043DB +:10C9300000044AD43D8003A8002301220090520243 +:10C940001946284601F070F9040044D1684601896F +:10C9500001820198417902790902114343780278F2 +:10C960001C021443AC421CD10A041AD44A0401210B +:10C97000520C89030A430096C1788078090201436A +:10C980000023204600F0C9FF040010D10199487926 +:10C990000A79000210430122D20310430871000AF1 +:10C9A000487101A904A8FFF796FF0400D1D00199AE +:10C9B00000964878097800020843694600238A896E +:10C9C000194600F0AAFF822C05D101A902A8FFF7A1 +:10C9D00082FF0400A3D06846068109E001994879E6 +:10C9E0000A79000210434004400C0871000A4871A3 +:10C9F00001A902A8FFF76FFF0028EFD0822C02D018 +:10CA0000204605B0F0BD0020FBE7F7B584B0144622 +:10CA10000646002700F079FF2A480025006D00280F +:10CA20002FD0059801282CD12046FFF771FF070071 +:10CA300027D1002E29D06846058118E00199487851 +:10CA40000978000208432080019B009558791979E4 +:10CA50000202D8780A4301029F78587839431F7838 +:10CA600000029B1D384300F058FF002805D101A9A2 +:10CA700002A8FFF730FF0028E0D0822800D1002074 +:10CA80000746002E01D00F48056500F042FF3846EA +:10CA900007B0F0BDF0B597B00021042003F07FFB94 +:10CAA000084F00243D467C8040356C73AC73287B76 +:10CAB000B96CC00008380E18B08800280DD00120CD +:10CAC000694603E02C190020012800000870306836 +:10CAD000019000216846F9F77AFBB4803C65AC828E +:10CAE000EC8217B0F0BDFE4B9864184640300173DD +:10CAF0001A803838D861CDE7F949002049880A07FB +:10CB000000D501200A06120F01D002221043CA05E7 +:10CB100001D5042210438A0501D51022104349058E +:10CB200001D520210843EE494031497B002901D03D +:10CB3000082108437047FFB5A7B00400289816469F +:10CB40001B9022D00178E6484D0642882292024688 +:10CB500040320092002D14DB8A06920E1E2A0ED05F +:10CB6000229A5205520E10D13288172A0DD3009AFC +:10CB7000927B002A09D1DB4D229AAA4205D0CA092C +:10CB800006D08A06920E122A02D003202BB0F0BDE6 +:10CB9000D348826C0098007B2590C000083810189C +:10CBA0001F9048060CD40098407B002808D00099BC +:10CBB00088731F99289808601F9884800220E5E7F1 +:10CBC000002718A90F7069460F72C54902AA0A64A6 +:10CBD000309A4A6410A90F850F861B981D4600786D +:10CBE00020908106BE4B601F24901A462C32219261 +:10CBF0002898DA691833890E1E93401C0B0006F042 +:10CC000065F81FFDFD11FD1AFD90FDFCFDFBFDFA11 +:10CC1000FDF9FDFCFDF8FDFDFDF7FDF6FDFDFDFD5B +:10CC2000FDF5FD00032C7BD10320287017226A70CC +:10CC30000022AA70E0E2052CF5D1417802780902C1 +:10CC40001143A74B10AA19831185C278807812026C +:10CC500002435A8300297DD091427BD80021184697 +:10CC600081720181491E01841E9800F072FF052027 +:10CC70002870A81C1D900220009021991E9800F099 +:10CC80006BFF002803D047E018A90870F0E2944831 +:10CC90002030807C012803D002206870102002E040 +:10CCA00001206870022022908D48303023900022AD +:10CCB00020A9239802F06DFD00282AD120A8007831 +:10CCC0002299814225D132880099801C511A8142D3 +:10CCD0001FDB83481D99C08D0870000A48701D989D +:10CCE00020A9801C1D9000981D9A801C00902398FC +:10CCF00002F04FFD20A909781D9840181D9000985A +:10CD0000401880B2009021991E9800F025FF00285D +:10CD1000CDD0009802288DD10A2018A908706CE2A5 +:10CD20006DE0072C6BD341780378090219436C4BF3 +:10CD30008446198310AB1985C37880781B02184389 +:10CD4000674B0029588305D0814203D8012118463A +:10CD5000817200E0A4E061464B7909791B020B4324 +:10CD6000038100218173104600F014FD00280FD1CB +:10CD70005B480121C26991710522C369D2029A8080 +:10CD8000C2699172C26958491181C06900218173D9 +:10CD90005349E01F08841B98C01D48621E9800F08C +:10CDA000D8FE07202870681C009001201D904C4878 +:10CDB0000021C18530E01D98012815D04848C1697F +:10CDC000897901292FD000981038C17B807B090216 +:10CDD000014300980170090A41700098801C00907E +:10CDE0001D98801C80B21D903D4809E013E2BEE111 +:10CDF0007AE1D8E00DE2A0E080E03BE01EE2B6E0A0 +:10CE0000C18D00980170090A41700098801C009043 +:10CE10001D98801C80B21D9021991E9800F09CFEE8 +:10CE2000002802D006E0818DD3E731881D98081ACA +:10CE30000428C0DA1D98012800D16DE72848C1698F +:10CE40008979012903D0828D26498A4205D1818DB5 +:10CE500000980170090A417009E000981038C17B00 +:10CE6000827B0802009910430870000A48701D98E0 +:10CE7000801CC1E1072C01D0152C78D141780378B2 +:10CE800009021943164B198310AB1985C3788078B2 +:10CE90001B02034312480029438301D0994201D960 +:10CEA0000120F1E60E480121817200210181817388 +:10CEB000052C07D024981B99C0B2491D02F043FCF1 +:10CEC0000028BAD100200649C04308841B98009668 +:10CED0000195007818AB8006800E1CAA002105E0A1 +:10CEE0002C190020FFFF000001280000FFF7E6FBDF +:10CEF0000746FE4810A9008B08857EE1032CBCD1B3 +:10CF0000402210A90A86417802780802F7491043A6 +:10CF1000088310A9088520A9009131886B1C491E3F +:10CF20008AB2002100F080FE18A90870002830D1D4 +:10CF30000B20287020A8008833E0052C9DD180218B +:10CF400010AB1986014640780B780202E7481A4375 +:10CF50000283CB7889781B021943E44B104619846D +:10CF600010AB1A85E24A914202D307208CE697E083 +:10CF70003F23DE4A9B021943118421AA0092328882 +:10CF80006B1C521E92B200F04FFE18A908700028C8 +:10CF900003D08328B1D102272FE10D20287020A8CB +:10CFA0008088401C28E120990C22C9095143C91CE2 +:10CFB0001E91A14204D92098400671D500201BE1A2 +:10CFC000417800780902014310A801851B98007878 +:10CFD00042062898C01C1D90002A62DA05206A4685 +:10CFE00010721B980078C00944D00822684602726B +:10CFF0008181A01A87B268468782289806901E9879 +:10D00000201A81B26846C1811D980490401805F02D +:10D010001CFC079006982599C0190890491E08A87D +:10D02000017102A83099F9F7D2F807460021684645 +:10D030000172002F1BD0022F18D1009808A9007B85 +:10D040000979401E884210DDA848289A836CC900DF +:10D050005A50816C08A80079C000001D0C5200983D +:10D060000099407B401C4873C7E00527EAE0062092 +:10D0700069460872002000901E980021201A209016 +:10D0800082B21B9B10A8DB1C008D00F046FC014601 +:10D0900018A80170002268460272832903D003E0B9 +:10D0A00093E00720E4E702271B98007840060ED59E +:10D0B0008E484188C90506D510AA018B128D914270 +:10D0C00001D100214162002018A9087094E0FF21DD +:10D0D000013110A80186018D8448018320990184C3 +:10D0E0001D994162132085E0052C6ED341780378A9 +:10D0F0000A021A4310A90A859446092269460A724F +:10D100000021009101222499D20311438AB2C178EF +:10D11000807809021B9B01435B1D604600F0FDFB0C +:10D1200018A90870002269460A720122520210A949 +:10D130000A86832802D0002805D099E06B48098D23 +:10D14000018302277EE06948006D002807D0204651 +:10D150001B99FFF789FB18A9087000284DD12B46B1 +:10D16000324620461B9900F024FB074645E01B98F9 +:10D17000022C4078009064D1002801D0012860D1B1 +:10D180000A2168460172009901731AAA00200099C9 +:10D19000FFF73BFC0146684641730021817302A8FA +:10D1A0003099F9F714F80746002168460172012109 +:10D1B000890210A80186022F08D04C48006C8079A3 +:10D1C000002807D018A9087020E04BE047490098D4 +:10D1D000088337E0002F03D0812018A9087031E0C0 +:10D1E0001AAA01200099FFF710FC18A9087000285E +:10D1F00003D119202870012030806846007A002869 +:10D2000004D002A83099F8F7E2FF0746002F2BD090 +:10D2100018E0062038E522993448090711D5012C79 +:10D220000FD10B2269460A72C08888810021042030 +:10D2300002F0B5FF082010A90886BFE62098400636 +:10D2400010D50327294810AA4188128E1143418026 +:10D250005005400E04D01F99289808601F988480BC +:10D26000384693E404200FE518A8007800280ED073 +:10D27000012028701B980078687010A8008DA87095 +:10D28000000AE87018A80078287105203080174837 +:10D2900010AA4188128E91434180E1E7FFB506460E +:10D2A0009FB000201B903178012088401149124A1C +:10D2B000084010A908860D494988914203D00028EA +:10D2C00004D0080702D5012023B0F0BD219D00271E +:10D2D0002F7020983C46018810A8018418A8077177 +:10D2E00000F013FB6846077202A907E02C19002022 +:10D2F0000102000009F80000FFFF0000FA48016485 +:10D3000001464031826C1A91097BC90008395718CF +:10D3100022994164307801282AD0022809D00328B4 +:10D3200079D12878800980011D302870EE48B188B5 +:10D33000C1803078022804D12878800980011B3010 +:10D34000287001A8009010A8008CEB1CC01E82B2AF +:10D35000B088002100F068FC0028E1D1B188697034 +:10D36000090AA9706946888810A9C01C08842DE1A3 +:10D37000717918A801713079012802D00228CFD123 +:10D38000E6E0D9487F2340881B010246184010ABD5 +:10D390001886802840D006DC102810D020280ED017 +:10D3A00040280AD120E0FF38013859D0FF38013831 +:10D3B0006AD0FF38FF3802387ED0052491E0D006CD +:10D3C00001D5082000E010201B9004206946087257 +:10D3D0000020888118A800900195318919AB1CAAFA +:10D3E0001B98FFF76BF977E0BF4B3289188B8242AD +:10D3F0004FD10A221B92002973D101A9009110A9D3 +:10D40000098C6B1C491E8AB2002100F00DFC18A982 +:10D4100008710B2017E0F6E0B34B3289188B82427B +:10D4200037D10C221B9200295BD101A9009110A9D0 +:10D43000098C491E8AB21946098C6B1C00F0F4FB5A +:10D4400018A908710D2028706946888810A9401C09 +:10D450000884042069460872A348008B888140E054 +:10D46000A14A3389108B834213D112231B930029C5 +:10D4700037D1536A002B05D00091128C00F04DFA81 +:10D4800018A9087113205EE097483289038B9A42ED +:10D4900001D00424E7E016221B92026D002A09D174 +:10D4A000F268002A06D002651A98328A82821A9A95 +:10D4B0000020D082002900E02FE012D1B88839681E +:10D4C000FFF7D2F918A9087100280AD1B8882B46AD +:10D4D00018AA396800F06DF90446022818D0042C07 +:10D4E00016D0B88800280FD06846007A002804D0EB +:10D4F00002A82299F8F76BFE0446012069460872DB +:10D50000386803900020B880002C5FD0052C7BD0B9 +:10D510006846007A032873D0A5E018201B900029E4 +:10D5200005D071483189018300210165D9E76E4832 +:10D530000246017E18320120FFF767FA18A9087128 +:10D540000028CED119202870012010A90884C8E72E +:10D550001A98407B002856D0307AC0001358001D1E +:10D560000193105A1D9000291AD100F0D2F906201B +:10D5700069460872002000901D980F3882B2019809 +:10D580008178437808021843019B0021DB1C00F0DE +:10D59000C4F918A90871002269460A72832830D09C +:10D5A000002118A8017110A80184012168460172A8 +:10D5B000019803901A981A99407B401E48731A9854 +:10D5C000807B002802D01A99401E887310A8008E14 +:10D5D0007F21090102468A431DD04348002200886A +:10D5E00011468300042002F038FD3F483178017174 +:10D5F00010A94088098E08433B4948800FE003E0AA +:10D600002BE002242FE00524374810AA4188128E0F +:10D610009143418027E034494A8882434A806846E2 +:10D62000007A002805D03048416C02A8F8F7CFFDF9 +:10D63000044618A80079002815D01B9868700120AE +:10D6400028702948008BA870000AE87018A8007993 +:10D650002871052110A8018405E02348416C02A827 +:10D66000F8F7B5FD044600F054F91F48408840051E +:10D67000400E20D11A98807B00281CD1B888002841 +:10D6800019D0209910AA098811842299009139682B +:10D6900018AA219BFFF74FFA044602280BD001205D +:10D6A000694608723868039002A82299F8F78FFD3E +:10D6B00004460020B88010A8018C209801802046E4 +:10D6C00002E600B50022D243074997B04A800428F9 +:10D6D00007D1022268460270097901710021F8F72A +:10D6E00076FD17B000BD00002C19002010B5394C94 +:10D6F00003780022216C012B02D0022B44D126E0BA +:10D700000B78002B01D0042B03D10A71226C03216A +:10D710001170216C83880A79D200921D8B52216C82 +:10D720000A79D20008328918C2880A80216C0389DC +:10D730000A79D2000A328B524289206C0179C900E1 +:10D740000C314252216C0879401C087120E00A74A7 +:10D75000226C81889180216CC288CA80226C0189E8 +:10D760001181226C41895181216CC068C860616C53 +:10D77000206CF8F72CFD0146022807D0206C007CB5 +:10D78000002802D1002903D0812010BD832010BDC4 +:10D79000002010BD8178012909D100880521C90226 +:10D7A000884202D0491C884201D1002070470520E0 +:10D7B000704710B51488844201D2052010BD17248B +:10D7C0001C701080421E491C581C04F0DDFF002014 +:10D7D00010BD00002C19002010B50446FEF759FFBB +:10D7E0002046FFF76EFF10BD10B58B78002B11D0CF +:10D7F00082789A4207D10B88002B0BD003E0091DD9 +:10D800008B78002B08D08B789A42F8D103880C884B +:10D81000A342F4D1002010BD812010BD10B5002915 +:10D8200002D001290DD102E00088000501E0008846 +:10D830008004800F07D001281CD0022809D00328BB +:10D8400010D0812010BD002901D0032010BD02207E +:10D8500010BDF6F754F803280CD004280AD000288D +:10D8600006D009E0F6F74BF8042803D0022803D0CD +:10D87000052010BD002010BD0F2010BDF3B5C81C41 +:10D8800080080E46800081B0B04201D08620FEBDE7 +:10D89000FE4C354626600198A08000202081E08063 +:10D8A00014E0B807A978800D0843F94904F0E6FFB1 +:10D8B000E088401CE080B80607D42089401880B278 +:10D8C00020810199081A8019A8600C352F887807E3 +:10D8D000E7D40020A072FEBDEC480C22C18800896C +:10D8E0005143081880B2704770B51346E74A45188F +:10D8F0009488AC4201D2842070BD126810180A4688 +:10D90000194604F041FF002070BDE04901208872F3 +:10D910007047DE49002088727047FFB589B09704D0 +:10D920000E460546BF0C029200F017FA040021D003 +:10D93000002069460873D548807A012812D0012159 +:10D940002046FFF76BFF002815D12078400609D547 +:10D950000221684601730582218841828682C7823E +:10D960000C9806900298000407D500273E46012532 +:10D9700001970CE001200DB0F0BD2078A178800760 +:10D98000800D0843C249019004F078FF0D460298CB +:10D9900040040AD50198A84207D12088E178800583 +:10D9A000800F00020843B04201D3AE4201D90720E4 +:10D9B000E1E7B81980B20290A84201D90D20DAE758 +:10D9C0006846007B002804D003A8F8F7FCFB002879 +:10D9D000D1D10198A8420BD12088032109028843A4 +:10D9E00002998905890F0902084320800298E07096 +:10D9F0001298002800D007800C9800280CD02078BE +:10DA0000000609D4A0683A4680190C9904F0BCFEBF +:10DA100020881021884320800020ACE7FFB59B4D73 +:10DA200081B00E46E8882F680C21009048433C18CE +:10DA30009749039804F022FF0A462889E11B84468F +:10DA40000C314018318880B28B0601D5002300E0EC +:10DA500013461818AB8880B2834202D8842005B0E0 +:10DA6000F0BD0098894D401C80B2E88021800D995E +:10DA7000002900D00C600399A170E2702188039DF9 +:10DA80008908AD058900AD0F294303252D02A9435F +:10DA90009505AD0F2D0229430425294321800C99BA +:10DAA000002900D0088001998978A171019909881D +:10DAB000A1803178890601D50B9905E0734962444C +:10DAC00092B20A81991AC919A16000212173327892 +:10DAD000920601D50020C2E700910B9B0A9A049997 +:10DAE000FFF71BFFBBE710B5044600F036F900282E +:10DAF00006D06649641ECC8000210170084610BD26 +:10DB0000012010BD002803D0401E0880002070476F +:10DB10000120704710B55D490288CB889A4201D335 +:10DB2000822010BD0B680C21514359180B88CC780A +:10DB30009B059B0F1B02234341608C7904738C88E7 +:10DB40004481C3818968521C0161028002810020E6 +:10DB500010BD012101827047FEB505460020C0437B +:10DB6000088068680F468178684681706868018817 +:10DB70006846018000218171288A2C88A04200D348 +:10DB800004462C8234E0288A401C2882301D6968B3 +:10DB9000FFF72AFE002829D139883E48814201D169 +:10DBA000601E38806888A04227D33088F1788005CD +:10DBB000800F0002084302906946301DFFF714FEF3 +:10DBC000002813D12989334881421AD000213046D8 +:10DBD000FFF724FE002809D12A890298824205D144 +:10DBE000E968B06804F0A3FD00280AD0641CA4B260 +:10DBF000204600F0B2F80600C5D1641E2C828220B7 +:10DC0000FEBD7C80B079B871B088B880308838812A +:10DC100030788007810DB078014379810298B8810E +:10DC2000B06838610020FEBDFFB585B014460F46D0 +:10DC3000059800F092F8050037D01448BE05807AA8 +:10DC4000B60D012815D000212846FFF7E7FD002872 +:10DC500029D1287840060CD5012168460170059924 +:10DC600081802988C18006814481F8F7ACFA0028B8 +:10DC700019D12888AA788107890D11438005800F62 +:10DC8000EA7800021043BE4211D005E0841900205A +:10DC900001020000FFFF0000374A914207D3611ED6 +:10DCA000814204DD0B2009B0F0BD0120FBE7864274 +:10DCB00001D90720F7E7801B82B2A24200D9224691 +:10DCC0000E98002800D002800898002804D0A86888 +:10DCD0008119089804F058FD0020E4E770B5144657 +:10DCE0000D4600F03AF800280DD001882980002C5C +:10DCF0000DD0017880788907890D01431E48814243 +:10DD000003D2012002E0012070BD0020207000201D +:10DD100070BD70B516460D4600F01FF804000DD01A +:10DD20002D882580FF2E16D0A807A178800D0843E6 +:10DD3000114904F0A3FD002E06D101E0012070BDC1 +:10DD4000FF31FF31033189B2A170A8088000890535 +:10DD5000890F08432080002070BD0849CA8882428C +:10DD600007D3002805D00C22096850430C38081846 +:10DD70007047002070470000010200008419002055 +:10DD8000F0B585B00E4605460020694608707078EB +:10DD9000FE49C00003900C58FD4F002D0ED0022DFF +:10DDA00073D0002C72D02078801E030004F08EFF08 +:10DDB00009837F7F7F83797F77727F00002C03D177 +:10DDC000F4A16B2004F07DFE2078801E030004F097 +:10DDD0007DFF09065E5E5E19365E50545E00307847 +:10DDE000062803D0EBA1762004F06BFEB8687168BA +:10DDF000806A032204F0C8FC0120694608700028EC +:10DE000035D1CEE730780C2803D0E2A1812004F090 +:10DE100058FEE0680078002806D0B8687168C06BCA +:10DE2000102204F0B1FC28E0B8681021406B04F027 +:10DE300008FDB868C16A406B0A787168F1E730780C +:10DE40000D2803D0D3A1942004F03BFE04206946A2 +:10DE5000087071684878097800020843B9684A6A0E +:10DE60005178127809021143484069468880084673 +:10DE700008E0C8A1AF2004F024FE6846007800281E +:10DE80008FD06846F5F740FD8BE727E01CE0C1A185 +:10DE9000B420F0E7B8686169406CFEF71CF8A1692E +:10DEA00000E0E168B868406CFEF715F803E0B9A13E +:10DEB000E32004F006FEB8682146406CFEF70BF83C +:10DEC000B24A039900205050022D07D0002D05D0F2 +:10DED000012D03D0AFA1EF2004F0F3FD05B0F0BD9C +:10DEE00010B501780124012902D0022910D112E0D5 +:10DEF0004268A748002182600170A4486C38C1665E +:10DF0000016741678167928902214C3001F083F9F2 +:10DF10000024204610BDFF209EA11C3004F0D1FD3E +:10DF2000F7E7F0B505469EA103C997B01491139089 +:10DF3000002108A8017595482A781030944C049067 +:10DF40002078012605903746A068130004F0BEFE35 +:10DF50000CEE073098EFF5EBEAE9E8E8E7EE217020 +:10DF60000124FF2655360D4610A80570457001F0B6 +:10DF700063F90746012803D086A1304604F0A1FDCD +:10DF800010A93846FFF7FCFE2046641EE4B20028C4 +:10DF9000EAD10A20694608706846029501F02AFA1B +:10DFA000002803D0FF207BA15E3066E00026E6E279 +:10DFB000006B0078C0072ED06846077001F01AFA8F +:10DFC000002804D0FF2073A1713004F07AFDA0680E +:10DFD000406CFDF777FF050004D1FF206DA1743080 +:10DFE00004F06FFD08984078C1006848455006204D +:10DFF0002870A068016869600069A8606448C01C56 +:10E00000E860284601F0F6F9022804D0FF2061A15B +:10E010007E3004F056FDA068006B00784007C5D53F +:10E020006846077001F0E6F9002804D0FF2059A1E6 +:10E03000863004F046FDA068406CFDF743FF050004 +:10E0400004D1FF2053A1893004F03BFD08984078AB +:10E05000C1004E48455006202870A06801686960DC +:10E060000069A8604A48401DE860284601F0C2F9EE +:10E0700002289BD0FF2047A1933004F022FD95E7B2 +:10E08000A8680028684632D001712879012833D069 +:10E09000022804D0FF203FA1AD3004F012FD3B4820 +:10E0A00010221030A96804F06FFB38481030014688 +:10E0B000103148602078C1062DD5EF21084020702E +:10E0C000032069460870314810300290684601F01C +:10E0D000B3F80446022808D0002C06D0012C04D046 +:10E0E000FF202CA1BE3004F0ECFC69462AE1077148 +:10E0F000264820304160DDE7244A04986C3AD16715 +:10E1000041608160C1600621A86803F087FA1F4959 +:10E1100010310860C9E720210843207046E758E124 +:10E1200014E1D6E0A3E046E007E000E031E2FF20A2 +:10E1300018A1E73004F0C5FC21E2172269460A72F3 +:10E140000F7089788A08297992008907890F0A4314 +:10E1500069468A70FB210A4029794907C90F89005D +:10E160000A4369468A70EA888A80826C02A96846F6 +:10E1700001F082F9002804D0FF2006A1F73004F056 +:10E18000A0FC052108A8017568460DE0FC190020D7 +:10E19000A00000207372635C736D2E6300000000AA +:10E1A00004411A8800A48000017A0187A068002633 +:10E1B000806C0F90E7E16846077001F01BF90028BA +:10E1C00003D0FD49FD4804F07CFCA068406CFDF7DD +:10E1D00079FE060004D18320F749800004F071FC29 +:10E1E000A068406CFDF76EFE070004D1F348F249C9 +:10E1F000801D04F066FCF2488068406CFDF762FE0A +:10E20000040004D1ED48EC49093004F05AFC0898A8 +:10E210004078C100EB4846500A203070287A3071AF +:10E220006868E74DB060A868806C30611720307373 +:10E2300077613046B46101F0DDF80446022808D069 +:10E24000002C06D0012C04D01120DB49400104F041 +:10E2500038FC2046316AFFF793FD297805220A40F1 +:10E26000042A00D0A2E6FB22114029702AE0059979 +:10E270004908490021708A071CD5FD2211402170F0 +:10E280000F216A46117017211171806C0290684647 +:10E2900000F0D2FF0546022808D0002D06D0012D3F +:10E2A00004D0C648C4493A3004F00BFC69462846FD +:10E2B000FFF766FD2078052101400429D2D1FB211A +:10E2C00008402070072008A90875BD4880780876A6 +:10E2D0006CE66846077001F08DF8002804D0B74856 +:10E2E000B549543004F0EDFBA068406CFDF7EAFD41 +:10E2F000060004D11320B049400104F0E2FBA068FD +:10E30000406CFDF7DFFD070004D1AC48AA495A3044 +:10E3100004F0D7FB08984078C100AA48465007206F +:10E320003070A068406870606868F760B060304620 +:10E3300001F060F8040004D0A0489F49653004F063 +:10E34000C0FB316A2046FFF71BFD2FE668460770C9 +:10E3500001F050F8002804D0984897497A3004F02A +:10E36000B0FB08984778A068406CFDF7ABFD06004D +:10E3700004D151209049C00004F0A3FBA068406C78 +:10E38000FDF7A0FD040004D18C488B49823004F0D5 +:10E3900098FB8C48F900465008182A694260092009 +:10E3A000307068687060A868B060A889B0818548DE +:10E3B0006C3830611030B4617061304601F01AF889 +:10E3C000022804D07D487C49903004F07AFB2F75F8 +:10E3D000ECE57C4B00212033197002216A46117054 +:10E3E00001932979002902D0184601709BE07449F5 +:10E3F00003220C314968FB230A708A7800259208B1 +:10E4000092001A408A70027A1207D20F4A706D4A3F +:10E4100020325560C37ACB70837A13724469537A81 +:10E4200024785B08E4075B00E40F2343537284699C +:10E43000D460FD242340C4692478E407A40F234357 +:10E440005372036A13614D710D71437A5C4A9C07E4 +:10E450000C32A40F1268012C04D19478A407A40FE5 +:10E46000012C1DD09B089B00437293785B0702D45C +:10E47000437A5B0728D5037A13AD5B075B0FDC009B +:10E480005B00E318147864001B19DBB2DC082C5D18 +:10E490005D076D0F06235B1BDC40A3079B0F14E099 +:10E4A000037A54795B065B0F1C404C711379062587 +:10E4B0002B400B71DB002343414C63708B789B082E +:10E4C0009B005B1C8B70D0E700238C78FB252C40D5 +:10E4D000457A6D07ED0FAD002C438C70047A64070C +:10E4E000640F0C705178012908D1017A090705D50C +:10E4F000032108A801750221017614E0022B1ED029 +:10E50000012B21D02F4B00216C3B049AD96751601D +:10E510009160D16019467C310A4610325160417ACF +:10E52000FB2211404172684600F086FE040021D0B3 +:10E53000012C20D02049244804F0C3FA1BE003201A +:10E5400008A908750F76EEE70598000704D5C320E3 +:10E550001949800004F0B5FA1A4C0D211034E01C62 +:10E5600004F06FF9204610304460022008A90875B5 +:10E570000E94D8E7002669462046FFF701FC08A85C +:10E58000007D002802D00DA8F5F7BEF9304617B07F +:10E59000F0BDCB2008498000CCE5F0B5054697B02A +:10E5A0000C460020694608700548064E2F78483E04 +:10E5B000017882680AE0000094E10000090200008E +:10E5C000A0000020FC1900201F0300003B0004F005 +:10E5D0007DFB0BA8820724394A6977778D9AA800BA +:10E5E0002B20694608730CA903A8FDF7A1FC00289D +:10E5F00003D05349534804F064FA53490D9804F08A +:10E600003DF952480160524869680160AA68426059 +:10E6100001910820694608708CE08A0610D5DF2237 +:10E620001140017003202070484810304168A160FB +:10E630004068002802D00020207177E00120FBE72D +:10E64000102256E02B2069460873404903A85C3924 +:10E65000FDF76EFC002804D03A483949293004F00F +:10E6600030FA04201BE02A206946087303A8102210 +:10E670000230696804F088F807A810220230A968FF +:10E6800004F082F8314903A85C39FDF751FC0028F9 +:10E6900004D02C482A493A3004F013FA052020709F +:10E6A000666043E02A79002A02D0012211430170FA +:10E6B00005206946087028798880A868029039E0AA +:10E6C000106B4023018819430180106C6968102287 +:10E6D00004F05AF82AE0FB22114001700620694636 +:10E6E0000870A96868680291019023E0CB0703D005 +:10E6F0000222114301704AE70F2020701720207179 +:10E70000906CA06012E0537A9B0706D0126B44789D +:10E710001388FF3401342343138004221143017012 +:10E7200004E0084806497C3004F0CBF968460078DC +:10E730000028E0D06846F5F7E7F828E701207047A1 +:10E7400094E100004D03000040420F000C1A00202D +:10E75000AC00002070B504780D460646230004F096 +:10E76000B5FA0B1C181C1C1C1C07181C1C181C00C0 +:10E770000021052001F013FDB068007805280CD0B9 +:10E78000FA480022008811468300052001F065FC4C +:10E7900003E00021052001F002FD002D0ED0002035 +:10E7A000287029463046FFF7F8FEF1482978005DC9 +:10E7B000884201D1032070BD022070BD0021304687 +:10E7C000FFF7EBFE002070BD30B5E8494B68497A91 +:10E7D0000A0111460C315C5C032C0CD00446002568 +:10E7E0002034257125725C5CA500AA18641C5C5459 +:10E7F0009850032030BD062030BDF0B504462646B3 +:10E8000020360D463279012008218FB0002A0CD025 +:10E81000012A21D0022A2BD0032A04D12A78052AE2 +:10E8200001D1297000200FB0F0BD01203071606867 +:10E8300000280AD0A0690170616841602169816087 +:10E840006169C160FFF7C0FFEDE70720287020690C +:10E8500068606069A86009E029780729E3D102208F +:10E86000307105202870C248203868600320DAE73C +:10E8700029780529D7D1A08910280AD9103880B263 +:10E88000A081A1681023091803A86A6800F033FE6C +:10E890002DE0102804D0C1B20BAA1020A76809E00F +:10E8A00010232269A16817E0491EC9B2401EC0B2F8 +:10E8B0007B5C13540029F7D100280AD0401EC0B257 +:10E8C00080211154002102E0401EC0B211540028E2 +:10E8D000FAD1626910230BA907A800F00CFE1023DF +:10E8E00007A903A86A6800F006FE0320307160687B +:10E8F000019003A8029005206946087029466846E1 +:10E90000FFF728FF8FE7F0B5044626460D46203670 +:10E91000317901208DB000290BD0012938D002298E +:10E9200005D12978052902D10920287000200DB0D1 +:10E93000F0BD217D6846CA07D20F02738807C10F58 +:10E9400068460174012203A905A800F0CCFD04A9C2 +:10E95000012205AF481D00F0C6FD0722B81CE16882 +:10E9600000F0C1FD07A807220130216900F0BBFDBE +:10E970006068019009A80290102305AAA16800F020 +:10E98000BAFD01203071052168460170294621E059 +:10E9900029780529CBD1062203A8E16900F0A3FD5F +:10E9A00004A806220230A16900F09DFD042106A8FA +:10E9B00000F091FD6068019007A80290102303AA5F +:10E9C000696800F098FD02203071052069460870E2 +:10E9D00029466846FFF7BEFEA9E7F0B5074685B0B1 +:10E9E0000C460020694608703E466248203632795F +:10E9F0008179133801250078130004F067F9180DA8 +:10EA0000FEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EF9E +:10EA1000EEEDECEBEAE9E8E7B968039100291BD0D9 +:10EA2000012269460A7003220A710A224A71396971 +:10EA30000291397900297DD0039A1278002A7AD080 +:10EA40000C2A78D2130004F041F90BF009F0354D8F +:10EA50008498B1F2EEEDF0000020BEE30021062024 +:10EA600001F09DFB3879072866D1424D133D287887 +:10EA7000022802D000287FD101E0002028700398EE +:10EA80000079C11F0A2901D30A249AE16870394824 +:10EA90000722C01F039900F026FD01203071287065 +:10EAA0000220694608703348801F01903869401C75 +:10EAB00002903BE211293DD12E4D133D0228DAD1BF +:10EAC00068686978007A884201D9062479E1039957 +:10EAD00026481022491C303800F005FD032028701C +:10EAE000022046E11129E6D1224C133C0428C2D170 +:10EAF0000520207003991D481022491C203800F081 +:10EB0000F2FC062030717869032101706268516857 +:10EB1000416016492039816021460C31C160C91D10 +:10EB20000161017D537A49084900DB07DB0F194376 +:10EB3000017502E064E34AE387E1D3688361FD2362 +:10EB40001940537A9B07DB0F5B001943017511696C +:10EB500079E10229AFD1002868D005206946087103 +:10EB60000398407848713869029045E3601A0020A4 +:10EB70004C2D0100C700002073E011299BD1F84CF7 +:10EB800006286ED1A0680399406B1022491C00F042 +:10EB9000AAFC0620694608703869029000200871B6 +:10EBA00001466846FFF7D6FD072058E00B299AD1A9 +:10EBB000EB4C07287ED1A0680399C06A0222491C49 +:10EBC00000F091FCA0680822006B17E00EE10AE358 +:10EBD000F3E2D3E2B9E2AEE28EE265E24FE248E26E +:10EBE00028E2FDE1E7E1D0E1C6E1BFE1ADE16DE1A1 +:10EBF0004AE12BE1DCE0BFE0B0E076E00399C91C1C +:10EC000000F071FC0621684601703869029000210D +:10EC100068460171FFF79EFD20461330417949088F +:10EC200049003EE041E01DE001E05CE0E2E2112944 +:10EC300090D1CB4C08283DD1A0680399806B10225D +:10EC4000491C00F050FC06206946087038690290A3 +:10EC50000020087101466846FFF77CFD09202070FE +:10EC6000BDE227E0082989D1BD49092822D10398AE +:10EC700042788868C16B0A700399006C0622891C6F +:10EC800000F031FC062168460170386902900021CD +:10EC900068460171FFF75EFDB14813304179FD22EE +:10ECA0001FE041714FE230717EE01129C0D1AC49C3 +:10ECB0000A2801D0082484E088680399406C102257 +:10ECC000491C00F010FC062168460170386902906A +:10ECD000002168460171FFF73DFDA14813304179DD +:10ECE000FB221140DDE707246BE0217802297DD16A +:10ECF0009B490128FBD162684A6014780846002CC1 +:10ED00005DD106216A46117039690291072111719E +:10ED1000029902240C70CA785207520FCA704B79BC +:10ED20005B075B0F4B718B795B075B0F8B71D207B6 +:10ED300001D18A714A7105460A794078824200D22F +:10ED40006A7087480722133000F0CDFB00202C703A +:10ED5000307101466846FFF7FDFC40E22178042946 +:10ED6000C5D1032871D108227E48616800F0BBFB41 +:10ED7000032030710420E3E121780429B7D1784FD2 +:10ED80000328B4D1774808220830616800F0ABFB53 +:10ED90000420307178684168002907D00321217070 +:10EDA000002121714068A060032531E20320C7E102 +:10EDB000207803289BD1207900281BD00446002C02 +:10EDC00014D0062168460170386902900221684615 +:10EDD0000171029805210170447000216846FFF717 +:10EDE000B9FC012168460170042100E0A2E1017133 +:10EDF000447105E25A49A06849680028486001D179 +:10EE000059484860052030717869032202704A68C9 +:10EE10004260544A8260524A0C32C260D21D026182 +:10EE2000027D4B7A5208DB075200DB0F1A43027552 +:10EE3000CB688361FD231A404B7A9B07DB0F5B0095 +:10EE40001A4302750969C16194E1F2E02178092948 +:10EE500086D14349032891D10420087006206946D1 +:10EE6000087038690290112008710298032101701E +:10EE7000401C1022616800F036FB00216846FFF755 +:10EE800069FC00203071AAE12178092992D1052876 +:10EE900090D13449626820391020401EC0B20B5C0A +:10EEA000145CA34203D000200424307189E70028B9 +:10EEB000F3D107203071786904210170284949682D +:10EEC0004968416027498160103952E120780A2859 +:10EED000BED106216846017038690290112168464A +:10EEE0000171029804210170401C10221D4900F09C +:10EEF000FAFA00216846FFF72DFC194810214078E6 +:10EF00006268091AC9B2101800F0E5FA6068019049 +:10EF100013481330C178C9070FD08179002902D175 +:10EF20004079002809D00820307109E1214668465F +:10EF3000DFE0054601287CD06AE1072069460870B9 +:10EF400000216846FFF706FC4BE120780E289DD192 +:10EF50000348616881604969407808700920A2E629 +:10EF6000B4000020501A00202C2D0100C80701D049 +:10EF70000A20E3E00F2096E620780F2859D1A068F8 +:10EF80003861207938730B20F3E620780428F5D116 +:10EF90006168F84C0822A068C06900F0A4FA0C204F +:10EFA000307178690722B9690270A268D36843603A +:10EFB000D2698260DDE020780D28DFD1ED4D6168F7 +:10EFC000A86802230269806900F095FA0D2030716B +:10EFD000786906210170A9688A68426009695FE062 +:10EFE00020780C28CAD1E34D6168A8686A78006A65 +:10EFF00000F079FA6878AA681021091A126AC9B271 +:10F00000101800F068FA062168460170386902900D +:10F01000112268460271029810220170A968401CF2 +:10F02000096A00F060FA00216846FFF793FB0E20A2 +:10F030005AE0A2E020780F287CD1062069460870AB +:10F04000386902900B200871029C0720C94D20707E +:10F05000A86802228169601C00F045FAA8680822AD +:10F06000C169E01C00F03FFA00216846FFF772FB1F +:10F0700080E7880701D5102060E0132013E6207890 +:10F080000F287AD1A0683861207938731120307147 +:10F09000786906210170B7498968C9684160B64935 +:10F0A0008160B549091D64E020780C2865D1B14D17 +:10F0B0006168A8681022406A00F015FA06216846C7 +:10F0C0000170386902901121684601710298082187 +:10F0D0000170A968401C496A102200F004FA00215E +:10F0E0006846FFF737FB122030710921684601702E +:10F0F0002146FFF72FFB1CE720780F281AD10621A5 +:10F1000068460170386902900821684601710298CA +:10F1100009210170974989680A78D207D20F427095 +:10F1200049680622801C00F0DEF900216846FFF7DE +:10F1300011FBA2E769E0480705D5142030710920CA +:10F1400069460870F2E61620ADE520780F2853D105 +:10F15000A0683861207938731520307178690621EC +:10F160000170844989688A684260096981608249BE +:10F17000891DC160FFF728FBDBE63DE020780C2805 +:10F1800043D161687B4C1022A068806A00F0ABF923 +:10F1900006206946087038690290112008710298AB +:10F1A0000A210170A168401C896A102200F09BF9B5 +:10F1B00000216846FFF7CEFAC5E76E481330407964 +:10F1C00000280ED0C10703D06A480621017006E06E +:10F1D000800701D5082000E00A2066490870002554 +:10F1E00016E017205FE56349002805D00020307144 +:10F1F00008700A206946087068460078002804D024 +:10F2000000216846FFF7A6FA00255A480021017040 +:10F21000284605B0F0BD10B5584BFF245C7258600D +:10F2200019721A80002204E0491EC9B20B010C3386 +:10F23000C2540029F8D110BDF0B5504E0546717A80 +:10F2400001208DB0FF2971D00127727A73681101F6 +:10F250005C180C31595C8900091F64586A70217868 +:10F260000B0003F033FD0B960709272C59818D4ABB +:10F270004F5492002F7075E0214620310A91097990 +:10F280000120002902D001296DD10EE060680190B3 +:10F2900005A802900D21C01C00F01DF9032205A84D +:10F2A000A16800F020F90A984EE02978052974D168 +:10F2B000062156E029462046FFF725FB69E0214656 +:10F2C0002031069109790120002902D0012964D159 +:10F2D0000EE06068019007A802900822E16800F043 +:10F2E00002F9082209A8A16800F0FDF806982BE0B1 +:10F2F0002978052951D10A2133E02946204600F01A +:10F3000005F946E029462046FFF777FA41E029460D +:10F310002046FFF762FB3CE0214620310591097948 +:10F320000120002903D0012937D116E056E060689A +:10F33000019007A802900822A16800F0D4F80821E3 +:10F3400009A800F0C8F805986946077105200870FB +:10F3500029466846FFF7FEF91BE0297805291CD1EC +:10F360000B212970002018E02946204600F014F9EE +:10F370000FE00000B4000020242D0100601A0020DE +:10F380002946204600F038F903E029462046FFF7D9 +:10F39000D5F9002801D001280CD12562717A736853 +:10F3A00009010C315A5C521E1206120E5A5401D039 +:10F3B00003204AE70328FCD0737A726819011D0103 +:10F3C0000D312C46515C7172FF270D3417550C35E9 +:10F3D000545D002C02D0FF2903D173720DB0F0BD33 +:10F3E00021460C010D34145DFF2CF9D109010D31BA +:10F3F0005354F3E770B5A24C0546607A21460346A4 +:10F400004A6811E0010108460C30105C08E0401E1B +:10F41000C0B286008E199659AE4201D1042070BD4B +:10F420000028F4D10D31505CFF28EBD19448002125 +:10F43000007A01E0491CC9B2884204D90E010C3699 +:10F44000965D002EF6D1884201D8052070BD0801D6 +:10F450000D30135461722846FFF7B6F9032806D021 +:10F46000617A626809010D31515C617270BD284694 +:10F470002830FFF7E1FE70BD10B504780123012CA0 +:10F4800014D10C78022C11D30B23137083785B07F3 +:10F490005B0F537002220A708088002805D0830019 +:10F4A00000221146062000F0D8FD0023184610BDAA +:10F4B0000EB50022012105280AD0062807D168468A +:10F4C00001700221017142710021FFF766F80EBD43 +:10F4D00068460170F6E7002202E0491EC9B24254B4 +:10F4E0000029FAD1704703E0521ED2B28B5C8354DC +:10F4F000002AF9D1704730B505E05B1EDBB2CC5C69 +:10F50000D55C6C40C454002BF7D130BD3EB50446E9 +:10F5100020300D4602790121002A02D0012A39D17A +:10F520000EE06168019157490291012101710520A6 +:10F530006946087029466846FFF70CF9014629E03C +:10F540002878052826D169681022A06800F087F87D +:10F550006868C07B000606D54A4AA06810231032AE +:10F560000146FFF7C8FF1022A168E06800F077F8B5 +:10F57000A068C07B000606D5424AE068102310321E +:10F580000146FFF7B8FF07202870A0686860E068B0 +:10F590000021A86008463EBDF0B5044626460F4649 +:10F5A00020363179012089B0002909D0012905D1FF +:10F5B0003978052902D10C203870002009B0F0BD3F +:10F5C000606803AD01900295022203A8A168FFF7CD +:10F5D0008AFF0222A81CE168FFF785FF0C21281D85 +:10F5E000FFF779FF01203071052069460870394620 +:10F5F0006846FFF7AFF8E1E710B5034620331C7902 +:10F600000122002C04D0012C10D0022C25D11EE0A8 +:10F6100001211971C16806220A70406848601948C2 +:10F62000801F8860801CC86008460CE00C780C2C99 +:10F6300013D102221A71C268052313704968516000 +:10F64000806890601046FFF7BFF8024605E0087832 +:10F650000B2802D10D2008700022104610BD10B5F5 +:10F66000002409E00B78521E5B0023430370401C0A +:10F670000B78491CD2B2DC09002AF3D110BD00007E +:10F68000601A00202C2D010070B50D46040012D028 +:10F69000002D10D02101284603F0D3F81022544940 +:10F6A000284603F071F8524801210838018044804F +:10F6B0004560002070BD012070BD70B54C4E002427 +:10F6C0000546083E11E0716820014018817BAA7B45 +:10F6D000914209D1C17BEA7B914205D10C22294696 +:10F6E00003F025F8002806D0641C30888442EADB49 +:10F6F0000020C04370BD204670BD70B50D460600A9 +:10F700000AD0002D08D03A4C083C20886188401C63 +:10F71000884203D9042070BD102070BD3046FFF729 +:10F72000CCFF002801DB0F2070BD2088616800013C +:10F7300040181022314603F027F82088401C208012 +:10F740002870002070BD70B514460D001FD0002C2D +:10F750001DD00021A170022802D0102817D108E086 +:10F76000687829780002084311D00121A170108027 +:10F770000BE02846FFF7A1FF002808DB401CA07023 +:10F78000687B297B000208432080002070BD012097 +:10F7900070BD70B5054614460E000AD000203070CA +:10F7A000A878012807D004D9114908390A8890425D +:10F7B0000BD9012070BD002C04D028782070288837 +:10F7C000000A50700220087010E0002C0CD049682C +:10F7D0000001411810391022204602F0D5FF287888 +:10F7E00020732888000A607310203070002070BDDC +:10F7F000D8000020734909680160002070477149F2 +:10F8000008600020704701216F4A704B002803D028 +:10F81000012805D06E48704791630020187001E000 +:10F82000D1631970002070476A4901200860684858 +:10F83000801C70470422684B6649002805D05A6036 +:10F84000086901221043086108E008694008400087 +:10F8500008619A605C490020C031886000207047D0 +:10F860005C490622002808D0012809D002280DD0C2 +:10F8700003280FD05648401C70470869904302E0A7 +:10F8800008699043801C0861002070470869904314 +:10F89000001DF8E708691043F5E74E494A6A02433C +:10F8A0004A62002070474B494A6A82434A620020FC +:10F8B00070474849496A0160002070474549CA6954 +:10F8C0000243CA61002070474249CA698243CA6143 +:10F8D000002070473F49C96901600020704730B57A +:10F8E0000546002072B601463A4A384C4032002D97 +:10F8F00011D00123012D0CD0022D02D0072062B6B9 +:10F9000030BDA3706478002C01D09363F7E7916356 +:10F91000F5E7A170F9E7A170F9E72F4904208860A5 +:10F9200029490020C03188602849012008702B49EE +:10F930000A688023120A12021A430A6028490860E2 +:10F94000704722480078704770B5EFF31080C50704 +:10F95000ED0F72B61D4C6078401C0006000E607002 +:10F9600003D120A1CC2003F0ACF86078012806D1A7 +:10F97000A078002803D01749012040318863002D6A +:10F9800000D162B670BD70B5EFF31080C507ED0F02 +:10F9900072B60E4C6078002803D112A1DC2003F06F +:10F9A00090F86078401E0006000E607006D1A078C6 +:10F9B000002803D00749002040318863002D00D182 +:10F9C00062B670BD0004004040000040E800002026 +:10F9D00004200000000500400003004000E400E0B7 +:10F9E00000E100E07372635C736F635F706F776553 +:10F9F000722E63008107C90E002808DA0007000F85 +:10FA000008388008B94A80008018C06904E080087E +:10FA1000B74A800080180068C8400006800F704711 +:10FA2000B44948788978884201D3401A02E02122FB +:10FA3000511A0818C0B27047AE4923314878897806 +:10FA4000884201D3401A02E02122511A0818C0B29C +:10FA50007047A849463148788978884201D3401ACE +:10FA600002E02122511A0818C0B27047A04810B510 +:10FA70000C300168FF22120291430122D20311438C +:10FA800001609C49002023314870887023394870F8 +:10FA90008870463148708870974801F0FCFD9648A0 +:10FAA000401C01F0F8FDF2F723FE00F015F910BD3F +:10FAB00020207047B4E770B50C4605460026FFF7D6 +:10FAC000AFFF8C49A04214D30A46203A00232046B7 +:10FAD000641EE4B200280BD08878105C2870887807 +:10FAE0006D1C401CC0B288702128F0D18B70EEE7ED +:10FAF000012600F0F1F8304670BD202070479BE7EA +:10FB000070B50C4605460026FFF796FF794923316C +:10FB1000A04214D30A46203A00232046641EE4B2D1 +:10FB200000280BD08878105C287088786D1C401CE9 +:10FB3000C0B288702128F0D18B70EEE7012600F06A +:10FB4000CBF8304670BD202101700020704710B501 +:10FB50000446FFF77EFF2070002010BD70B50C46F4 +:10FB60000546FFF776FF63494631A04215D30A46A2 +:10FB7000203A00232046641EE4B200280BD0887887 +:10FB8000105C287088786D1C401CC0B288702128D9 +:10FB9000F0D18B70EEE7002400E0584C00F09CF8A8 +:10FBA000204670BD70B50C460546212904D9FF20BA +:10FBB00053A1473002F085FF4C484068103840B2EE +:10FBC000FFF718FFC6B20D20FFF714FFC0B2864240 +:10FBD00007D2FF204AA14D3002F073FF01E0F2F797 +:10FBE000C7FD21462846FFF766FF0028F7D070BD05 +:10FBF000F8B5404E07462336B1787078212200F0E0 +:10FC000060F8354623353B4C00280ED0A17860784B +:10FC1000212200F056F8002814D0A9786878212213 +:10FC200000F04FF800281AD025E032497078C91C3E +:10FC30000F547078401CC0B2707021281BD1002076 +:10FC4000707018E02B49607820390F546078401CA0 +:10FC5000C0B2607021280ED1002060700BE02549F1 +:10FC6000687826310F546878401CC0B2687021282B +:10FC700001D100206870B1787078212200F021F85D +:10FC800000281DD0A1786078212200F01AF8002801 +:10FC900016D0A9786878212200F013F800280FD038 +:10FCA000F2F748FD144801F0FEFC012149038842A7 +:10FCB00003D013A1C12002F004FF0F4801F00BFD97 +:10FCC000F8BD401C884205D0904201D1002901D0E6 +:10FCD000002070470120704710B5074801F0E3FC91 +:10FCE000002801D1F2F715FD10BD000000ED00E085 +:10FCF00000E400E08C1A0020EB0000200720000048 +:10FD00007372635C736F635F72616E642E63000075 +:10FD100010B5284801F0BFFC002803D026A11D2003 +:10FD200002F0CFFE2348401C01F0B5FC002803D0B0 +:10FD300021A1212002F0C5FE10BDF1B5224D6F6852 +:10FD400001261C4801F0AFFC1A4C002803D1002604 +:10FD5000601C01F0C0FC1D4A1D490120506000BF1D +:10FD600000BF00BF00BF00BF00230B604B60009BC3 +:10FD70006B60106000BF00BF00BF00BF00BF08681D +:10FD8000002802D148680028F9D048680028E4D14A +:10FD9000002E04D06F60601C01F085FC07E0601C41 +:10FDA00001F081FC0028D3D1024801F094FC00202E +:10FDB000F8BDC2E7ED0000207372635C736F635F90 +:10FDC0006563622E6300000000E5004000E0004033 +:10FDD00000E1004030B5EFF31081CC07E40F72B6BC +:10FDE0001D4A116910230D461D431561002C00D1D9 +:10FDF00062B61A4DC406E40E0120A0402C680442ED +:10FE00000DD0C8060AD4EFF31080C007C00F72B639 +:10FE1000116999431161002800D162B630BD20BF3D +:10FE200040BF20BFEAE70E4908784A78401CC0B2BC +:10FE3000904200D008707047084A094820BF40BF70 +:10FE400020BF4178037843701368002B02D10378F8 +:10FE50008B42F3D00020704700ED00E000E200E0AC +:10FE6000EF000020FEB5F44C07466068FF213E011C +:10FE700081552178FF2913D00901083141583246B4 +:10FE8000491E083209020192090A805800F0CBF994 +:10FE9000002802D02478254615E06168207888552E +:10FEA0002770FEBDE448426801981158280100906F +:10FEB0000830105800F0B7F9002806D1DE482C466B +:10FEC000416800980D5CFF2DECD1DB4821014068B2 +:10FED00085554754FEBD70B5D74A04460020157AB3 +:10FEE00053680AE00201561C9E5DA64203D10C3203 +:10FEF0009A588A4204D0401CC0B28542F2D8FF20F2 +:10FF000070BDF8B5CC4F3E7801F042FB0146FF2EA4 +:10FF100071D03401254678680835405900F083F9DE +:10FF200002280CD97868405901F025FB01F030FB1C +:10FF300001467868405900F076F902285BD8BE493E +:10FF40004868025D0A70A11C425C002A0CD0521E57 +:10FF5000425441590122D20589180902090A415126 +:10FF60003046FFF77FFF30E0631CC25C0092221D29 +:10FF700094468258002A10D001239B029A420FD93E +:10FF80009205920D43595703DB191B021B0A43517B +:10FF90006346C3589A1A920A09E0FF21C1540AE045 +:10FFA000435952039A181202120A42510022425433 +:10FFB0003046FFF757FFA0480C344168C2680098EC +:10FFC000095980001258009890479B4C2078FF28D0 +:10FFD00011D0000161680830085801F0CCFA01F036 +:10FFE000D7FA01462078626800010830105800F006 +:10FFF0001AF9022886D3F8BDF8B51C4615460E46F8 +:020000040001F9 +:100000000746FF2B03D38DA1D12002F05AFD8A4869 +:10001000FF21C760456004720674017000224270BF +:10002000104604E00201521C401CA954C0B2A04278 +:10003000F8D3F8BD70B5804C06466578207C8542C3 +:1000400003D37EA1E42002F03CFDE068A900465005 +:100050006078401C6070284670BDFFB581B01D46B9 +:10006000FF2401F095FA744F064679780198814291 +:1000700003D872A1F22002F024FD6F480021037A18 +:10008000406810E00A019446521C825CFF2A25D089 +:10009000019FBA4205D162460C328758029A9742B4 +:1000A0001ED0491CC9B28B42ECD8FF2C18D02101BC +:1000B0004A1C019B83540B460C33029AC250039B8B +:1000C0005D4F0022012B0ED00B1DC25001239B025D +:1000D0009D4216D9AA05920D08D008E00C46E0E72B +:1000E000FF2005B0F0BD0B1DC550EFE71A465303C6 +:1000F0009B190E461B0208361B0AAA1A8351920A44 +:1001000009E0002D00D101256B039B191D022D0A6A +:100110000B460833C550891C42543D463E78204664 +:10012000FFF7A0FE2878B04214D0000169680830BB +:10013000085801F020FA01F02BFA29786A680901C1 +:10014000083152580146104600F06DF8022801D2DD +:10015000FFF7D7FE0198C4E770B50C46054601F0DD +:1001600017FA064621462846FFF7B5FEFF2814D0A9 +:10017000314D04012046696808300858314600F0C6 +:1001800052F80121090340186968A41C095D400B5D +:10019000002901D08902081870BD002070BDF3B598 +:1001A00081B00F460198FFF796FEFF282AD0224E15 +:1001B0003578726829460C4604E0844205D025460D +:1001C0002301D45CFF2CF8D11CE0FF2C1AD0A542EF +:1001D0001CD10801105C3070FF2815D000010830D8 +:1001E000105801F0C8F901F0D3F90146307872686F +:1001F00000010830105800F016F8022806D2FFF768 +:1002000080FE03E00020FEBD01F0BDF939460198F3 +:10021000FFF7A2FF22017168FF23541C0B558A5C73 +:100220002B01CA54FEBD401A00020121000AC90573 +:10023000884200D900207047D81A00207372635C8E +:10024000736F635F74696D65722E6300F0B500248F +:100250001C4A01211C4B0803546018601B4B1C6096 +:100260001B4C20601B480469E443E406E61704695C +:10027000761C10252C430461174C6160174D2960D2 +:1002800000E020BF1F68002FFBD0002E03D10769BC +:100290001026B743076190688005906801D5104A21 +:1002A00010436960A160002119600121084A090317 +:1002B0001160F0BD10B50446FFF7C8FF20600020B4 +:1002C00010BD000000C5004080E100E000C100401A +:1002D00080E200E000ED00E000C3004000C000400C +:1002E00000FCFFFF70B51F490A68002A17D00023E1 +:1002F0001D4601244A68521C4A60092A00D34D60F9 +:100300000E792246B2400E6816420AD072B60B68C9 +:1003100093430B6062B649680160002070BD052000 +:1003200070BD5B1C092BE5D30FA1362002F0C9FB81 +:10033000F5E701201049800508607047EFF3108150 +:10034000CA07D20F72B601218140064803681943DB +:100350000160002A00D162B6EBE70248002101608B +:1003600041607047F40000207372635C736F635FD9 +:100370006576742E6300000000E200E00120810732 +:100380000860704701208107486070471048C068C6 +:10039000C00700D0012070470D488068C00700D01A +:1003A000012070470A484069C00700D0012070470B +:1003B0000748C069704706498A69D20306D589692A +:1003C0008907890F814201D10120704700207047C1 +:1003D00000040040F8B5FE4C607A217A88421BD0B8 +:1003E0000126FC4D0027207A215C14200A46424356 +:1003F0005019037C052B10D0062B19D0072B23D0C6 +:10040000437C012B2BD02120F3A1400102F059FBAA +:10041000617A207A8142E6D1F8BD0674207A401CC8 +:100420004007400F2072491CC8B2AA58022109E0B7 +:100430000674207A401C4007400F2072491CC8B245 +:10044000AA5803219047E3E70674207A401C40072E +:10045000400F2072491CC8B2AA580821F2E747741D +:10046000207A401C4007400F2072491CC8B2AA588D +:100470000721E7E770B5DB4D05202871DA48002435 +:1004800044700470183044720472D84801F003F9C3 +:10049000D7480474AC71D748611E41606C70847792 +:1004A000C4772C704477D448022104704470D34838 +:1004B000047528300470491EFAD10120F2F7DAF9E8 +:1004C0000020F2F7D7F90120A870F2F765F8CC48C0 +:1004D000F2F774F8CB4C2070CB48F2F76FF86070ED +:1004E000F2F76CF970BD10B5F2F793F9C54C2078AE +:1004F000F2F782F86078F2F77FF8BA4CE0780028DB +:1005000005D0FFF740FAF1F7A8FE0020E07010BD1B +:1005100070B5B44CA078002805D0FF20AEA1B23051 +:1005200002F0CFFA70BDA079002804D1FF20AAA163 +:10053000953002F0C6FA0125A5700026A671207933 +:10054000042114225043A34AAA4C80180174606805 +:10055000401C04D0481F60600120F2F78BF9002096 +:10056000F2F788F9F2F76CF9F2F773FAF2F7F8FAA2 +:10057000A1480078022804D0032804D1E07F002895 +:1005800001D0A57700E0A677F2F74FFA70BD0346D9 +:1005900090490420142242435218203A127F002A24 +:1005A00004D0401E0006000EF4D1704714224243CE +:1005B00051180A46403AD362012220390A7770471F +:1005C000012805D0032805D1002903D10020704758 +:1005D0000029FBD010B4874C00236377864A00289B +:1005E00090700CD002280AD007291AD20B007B4445 +:1005F0001B79DB189F441505070D0F111300D370ED +:1006000003E01B2000E03A20D0700120607710BC8E +:1006100070475820F8E77720F6E79620F4E7B520F2 +:10062000F2E710BC0020704710B573484078F2F72D +:1006300014FA80B210BD411E1422504310B5654A11 +:100640008418203C032902D8207F002803D162A10E +:100650006E4802F036FA207F012804D001205EA106 +:10066000400202F02EFA0020207710BD70B55E4CDB +:1006700060782178884201D1012500E00025F2F759 +:1006800088F9F2F7EAF961782278914201D10121E3 +:1006900000E00021A942EBD170BDF7B58CB0064651 +:1006A0000D98401EC1B20090029114204143494868 +:1006B0000D1828460195007C2D1D07282BD1444F8D +:1006C00000203C7A797AA14222D03A5D02998A428E +:1006D00007D1002803D040A14D4802F0F2F90120D3 +:1006E00001E0002804D0611C4907490F795C3955A5 +:1006F000641C6407797A640FA142E6D1002807D010 +:10070000787A002802D0787A401E00E007207872BC +:100710000199012008740099324C0D9803290FD8D3 +:10072000142148432B4940182038007F002807D067 +:100730000198007C012807D00E98C07A012807D0C4 +:1007400025A1344802F0BDF90E98C07A012839D1AC +:100750000198204B007C02280FD01D4C607A217A32 +:10076000401C4007400F884203D11BA12A4802F0D9 +:10077000A8F901990120487434E12079029A0146D0 +:10078000904206D0014614277843C018807C9042DE +:10079000F8D12279824208D1217914225143C91813 +:1007A000897C21710121617107E014224243D21832 +:1007B00014277943927CC9188A7414220521504366 +:1007C000C01881740E98007A06283BD226E00000FB +:1007D000D41B0020EC1A00207372635C72656D2ECE +:1007E00063000000001C0020BC1B0020071C002030 +:1007F000C01B0020E01B0020FE000020E81A0020A3 +:1008000003FF0000FC000020D5030100FF010000F1 +:10081000450200004E0200005B02000003007B4422 +:100820001B79DB189F44020C0A08060400200FE025 +:10083000B4200DE073200BE0322009E00A2007E02D +:10084000062005E0FF20F749443002F03AF9002085 +:1008500003900E98C07A02280E9824D0807A2872CD +:100860000E9803990068401A28600E99097A0029A9 +:1008700061D00221401A0002000A28600E98016827 +:10088000406808186860C01D0002000A68600E9881 +:100890000627407AA8720E98007A6872FFF776FDF4 +:1008A00000284AD053E04168007A00282DD0022069 +:1008B00009180398C01D09182079052827D0DA489F +:1008C000039A4078904200D81046801A4218D748C0 +:1008D000921D8446207914235843D54BC018436891 +:1008E00080689B1B801B1B0200021B0A000A9A42A5 +:1008F00004D8CE4A934201D8604508D92079142201 +:100900005043CB4A801880680CE00420D0E7C648EA +:10091000039A4078904200D81046801A8019801DB2 +:100920000002000A286040180002000A68600020E7 +:1009300028726868A7E704219CE7687A032806D232 +:10094000002804D0039838210F1A32200390B649AA +:100950000878012801D003280AD1487803998842F1 +:1009600006D9B449C97F002902D10399401AC71991 +:100970002968AE488B1B69681A02891B0591090218 +:10098000120A090A97421ED8074682421BD8B9426A +:1009900019D82079012205282FD0002001210491A7 +:1009A00021799C46059B14225143A14A89184A6823 +:1009B000921B9A4203D28A68921B62452BD800226E +:1009C0000AAF3A5430E0019905209B4C0874607AD4 +:1009D000217A401C4007400F884203D197A19A48D2 +:1009E00002F06FF8617A02986054607A401C400708 +:1009F000400F607200200FB0F0BD019802230299F1 +:100A000003742379052B00D02379837421716271DB +:100A100001200FB0F0BD01220AAF3A548A7BAF7AB1 +:100A2000BA4201D800220492897C401CC0B2052938 +:100A300003D0049A002AB6D1A1E00498002877D008 +:100A400025790520002704900AA8C05D012827D039 +:100A500004951420454376487F1C2818857CFFB2F6 +:100A6000052DF1D1019802230374714F20790528D7 +:100A700053D025790520049001984068811B1420EB +:100A80006843C0194268921B8A4262D92079A84201 +:100A90004FD1019902980B742279052A42D142E084 +:100AA0002079A8420BD121791420414360480818CD +:100AB000807C2071012060710020207011E004987A +:100AC000052803D15DA1614801F0FBFF28461421F0 +:100AD0004843574914234018827C049858434018CF +:100AE0008274284614214843514906224018027452 +:100AF0005148417A007A491C4907490F814203D184 +:100B00004EA1534801F0DDFF4B48417A4554417AEC +:100B1000491C4907490F41729BE7227901990298C4 +:100B2000052A00D022798A7420710120607123E0A7 +:100B300025E00498052803D140A1464801F0C1FFF3 +:100B4000049814225043C019029981740198857445 +:100B500012E0807C052807D0049505468FD137A187 +:100B60003D4801F0AEFF21E014214D43E919029800 +:100B7000887401990520887401200FB0F0BD019898 +:100B800005212D4C0174607A217A401C4007400FEA +:100B9000884203D129A1314801F093FF617A02987C +:100BA0006054607A401C4007400F607200200FB014 +:100BB000F0BD70B50D460646294900242046891B24 +:100BC000A04103D21DA1274801F07BFF2649002048 +:100BD000491BA04103D219A1244801F072FF244A05 +:100BE00070190021821A8C4101D32249401870BD2E +:100BF000F8B5401EC0B2142148430D494518687B22 +:100C000006283DD203007B441B79DB189F44023643 +:100C100034080604002067E0B4203AE0732038E08E +:100C2000322036E0D8070100FE000020FFFF3F0021 +:100C3000EC1A0020E01B0020D41B00207372635CC0 +:100C400072656D2E63000000A3020000DE0200004A +:100C5000E302000007030000170300001D0300006B +:100C6000FF7F841E290300000020A1072A03000043 +:100C70000080841E00807BE10A200AE0062008E054 +:100C8000FF20FE49443001F01CFF697B0020002951 +:100C90002AD0022140186968002440180C21000263 +:100CA0006956000A002921DBF1F7D7FEF44A06460F +:100CB0000C27EF570021101AA14103D2EF49F14848 +:100CC00001F0FFFEF0490020C91BA04103D2EB490F +:100CD000EE4801F0F6FEEE4AF0190021821A8C412E +:100CE00001D3EC494018F8BD0421D3E7F1F7B5FE74 +:100CF0000C21695600224018E149091AA241F2D29A +:100D00004042F8BDF0B5074683B0E3480E46029076 +:100D100000F0C9FCE14C00282ED0E14D287C0028D1 +:100D200003D0E0A1E24801F0CCFE012028742F732B +:100D3000DB4D30782872707868722A460A3229466C +:100D40007068F1F794FE0A2028560F2804DD1F383A +:100D5000A8722868401C28600021B0686A4600918B +:100D6000117101AA6946F1F782FE6A460420105605 +:100D70000F2846DD012045E060782178401C4007BF +:100D8000400F884203D1C7A1CA4801F09AFE60789B +:100D90000101C94809180F73617809010D183078ED +:100DA0002872707868722A460A3229467068F1F70C +:100DB0005EFE0A2028560F2804DD1F38A872286816 +:100DC000401C28600021B0686A460091117101AA98 +:100DD0006946F1F74CFE6A46042010560F2801DDE3 +:100DE000012000E00020009940186860307BE87224 +:100DF0006078401C4007400F6070029800F06BFC68 +:100E000005E00020009940186860307BE872607847 +:100E10002178884224D0A9480579052D22D0F1F700 +:100E2000B8FD14214D43A64969180A7C042A17D03D +:100E3000032A15D04B6889681B1A091A180209027F +:100E4000A04A000A090A06280AD31346904207D886 +:100E5000994205D860782178884201D0F1F7E5FD04 +:100E600003B0F0BD607821788842F7D103B0F0BDBF +:100E700010B50020F1F7EBFC10BD10B50120F1F723 +:100E8000E6FC10BDF8B5074602281ED08B4C207931 +:100E9000052803D183A18C4801F013FE0020A07027 +:100EA0000125A571207903211422854E5043801914 +:100EB0000174F1F7BFFD3800844F0BD001281FD01B +:100EC00003286FD077A1824838E082480078F1F794 +:100ED00099FBF8BD65700020F1F7CCFC7968481CDF +:100EE00004D0012300221846F1F7FAFC2079217979 +:100EF000401CC0B214225143725801219047F8BDE2 +:100F00000120F1F7B7FC607800280CD07868401C0D +:100F100009D020792179401CC0B214225143725863 +:100F200006219047F8BD387E01280AD0022812D049 +:100F3000032824D0042836D05AA1674801F0C1FD07 +:100F4000F8BD2078002804D000202070F1F777FD4C +:100F5000FD77002024E0E078002804D1FEF7F4FCBF +:100F6000F1F752F9E57020792179401CC0B21422C2 +:100F7000514372580021904700203876F8BD397AE5 +:100F800038680123411A00221846F1F7A9FC20789D +:100F9000002804D000202070F1F751FDFD770220D9 +:100FA0003876F8BD1AE0397F38680123411A0022EB +:100FB0001846F1F795FCE078002804D1FEF7C4FC50 +:100FC000F1F722F9E57020792179401CC0B2142292 +:100FD00051437258002190473D76F8BD2079217920 +:100FE000401CC0B214225143725805219047F8BDED +:100FF00010B5324C2079052803D12AA1374801F0D9 +:1010000060FD20792179401CC0B2142251432C4A42 +:1010100052580421904710BDF0B583B00526F1F772 +:10102000B8FC054629484068401C03D01DA12C4847 +:1010300001F047FD214C21792A480190052956D01D +:101040002179142041431E480918097C04294ED0F7 +:101050002179142251430818007C03287ED001987E +:10106000184902684068521B401B12020002120A13 +:10107000000A062A72D30B468A4235E03C0C010076 +:10108000FF7F841E290300000020A1072A0300001F +:101090000080841E00807BE1071C0020BC1B002018 +:1010A000C01B00207372635C72656D2E63000000CC +:1010B0006E0300005F0300003C1B0020001C0020AA +:1010C000EC1A0020FFFF3F00A2030000E01B0020FD +:1010D000F3030000FC000020E7030000FA03000017 +:1010E0002B040000EC1B002038D8984236D8002092 +:1010F00060702079052808D1F648407F002804D088 +:10110000F548C1784170817801702079052814D0A4 +:10111000207914214843F1494018007C04280CD15F +:1011200026792279012014235A4352181074227907 +:101130005A435118897C21716071E94F7878397868 +:10114000884215D038780101E6480A183978090133 +:101150000818017B2846FFF7A0FA00E071E1387813 +:10116000401C4007400F3870787839788842E9D1C0 +:10117000DD4F387C002806D0397B3A462846FFF7F9 +:101180008CFA00203874052E1BD0142031464143C0 +:10119000D2480818017C012913D10721D34F0174CB +:1011A000787A401C0840397A884203D1D0A1D348CC +:1011B00001F087FC787A3E54787A401C4007400F53 +:1011C0007872207905287DD0607900287BD00020B6 +:1011D0006071217914204143C048BE4F0E18C849A0 +:1011E000B3687268F6688E604B600A60797D00298A +:1011F00010D0022621791422B84851430818407BA8 +:10120000062815D203007B441B79DB189F44040E8B +:101210000C0A08060426EDE700200FE0B4200DE0DC +:1012200073200BE0322009E00A2007E0062005E0E9 +:10123000FF20AFA1443001F044FC00203872797DDA +:10124000022901D001290FD1F96809184A1B12029D +:10125000120A382A08D90320787532390802000AA0 +:10126000F860322038720AE0322808D2E07800288C +:101270000ED1FEF769FBF0F7C7FF012007E0E07829 +:10128000002805D0FEF77FFBF0F7E7FF0020E070B5 +:10129000914A0621507838771278012A01D0032A22 +:1012A00006D1012222703A7A904201D9811A891D11 +:1012B000BA7F002A00D0891C2378002B01D1002A94 +:1012C00061D001E088E098E08C468E490091019958 +:1012D0000B6849685B1B491B09021B02090A1B0AB0 +:1012E00001919C451CD8874DAB4219D8019B0099B0 +:1012F0008B4215D8397A884223D9FB68421A9A1A48 +:101300001202120A101880190002000AFA603860EE +:10131000002914D0032038760006000E3ED144E0A8 +:1013200000202070B877397A002925D0F868401855 +:1013300080190002000A3860022038762EE0012071 +:10134000E9E781420BD9FA68511889190902090A9B +:101350003960002801D00420DDE70220DBE7002A05 +:1013600003D163A1684801F0ACFBF8688019000262 +:10137000000A3860002004E0F96889190902090AA6 +:101380003960387611E0387A00281DD0F9680818DD +:1013900080190002000A386002203876F8680123BC +:1013A000811900221846F1F79BFA2079142148434D +:1013B0004A490C2240188256012300203968F1F76F +:1013C0008FFAF1F7C1FB18E0F86880190002000AF3 +:1013D000386000203876E8E70120F1F74BFA00206A +:1013E000F1F748FAF1F72CFAE078002805D0FEF77B +:1013F000CAFAF0F732FF0020E070364DA87F0028CF +:1014000004D0F1F71CFB0020E877A877687F00285C +:1014100004D03148C178417081780170207800286B +:1014200006D000202C49E8770978002900D12070E7 +:101430002E48417A007A814203D034484078F1F74F +:10144000E1F803B0F0BDF0B5314C0746207983B028 +:10145000052803D126A12F4801F033FB2079142160 +:101460001E4E48438019007C032803D020A12A483F +:1014700001F027FB174D6868401C03D01CA12748CA +:1014800001F01FFB20791421484381190C200856D4 +:1014900000216A4600911171C01901AA6946F1F74D +:1014A000E6FA6A46042010560F2801DD012000E00C +:1014B000002000994018296840180102090A696053 +:1014C0006078002804D0012300221846F1F708FABA +:1014D00003B0F0BDE01B0020FE000020EC1A00204D +:1014E000BC1B00203C1B0020C01B0020D41B002084 +:1014F0007372635C72656D2E630000005C04000013 +:10150000EC1B0020FFFF3F00AE040000FC000020A9 +:10151000001C00200B0500000C0500000D0500005C +:10152000F8B51D4D0A1A00242346551BA34106D3C6 +:10153000194E431A254600279E1BBD4101D2104675 +:10154000F8BD164E0025B21AA54103D2721C101A1E +:101550004018F8BD114D0022EB1AA24104D26A1CBA +:10156000511A08184042F8BD53200DA1000101F0A6 +:10157000A8FA0020F8BD10B5014601230022022080 +:10158000F1F7AEF910BD10B50220F1F773F910BDF7 +:1015900010B5F1F7FEF910BD0020A107FF7F841EF2 +:1015A0007372635C72656D2E6300000010B50146B6 +:1015B00020220A4801F0E8F808490020C8770846C8 +:1015C00010BD0749012048610648074A0168914259 +:1015D00001D100210160704770477047081C00204E +:1015E0000005004004010020EFBEADDE064A107089 +:1015F0005170704704481C2201784171427001709B +:101600007047704770477047080100207047704767 +:1016100070477047704770477047704730B5034652 +:10162000002002460DE09C5C2546303D0A2D02D389 +:101630000020C04330BD0A25684330382018521CB2 +:10164000D2B28A42EFD330BD70B50D46144608E0E1 +:101650000A2101F013F92A193031203A641ED1779A +:10166000E4B2002CF4D170BD10B5002310E0040AE0 +:1016700000020443A0B2CC5C44402006000F60404E +:101680000407240C44402006C00C60405B1C9BB245 +:101690009342ECD310BD002101700846704701460B +:1016A000002008707047EFF31081C907C90F72B6A8 +:1016B0000278012A01D0012200E0002201230370F8 +:1016C000002900D162B6002A01D000207047012015 +:1016D00040037047E7E7EFF31081C907C90F72B6FF +:1016E00000220270002900D162B600207047F2E7A4 +:1016F0000348004703480449024A034B704700006F +:10170000312B0100481C0020481C002010B5203857 +:101710000C46030001F0DAFA331B1F23272C313764 +:101720003C41474D5054585C606D71656974787CDC +:101730008084888C9094989C9FA2A6AAAEB2B8BCD4 +:10174000C0C5CACFE9F0F3D3D7E0DBE4F8002068E6 +:10175000FFF7A1FFD6E02068FFF7A5FFD2E02068E1 +:10176000FFF7B9FFCEE0207840B200F0F3F9C9E00E +:10177000207840B200F011FAC4E02078616840B2ED +:1017800000F024FABEE0207840B200F034FAB9E06C +:10179000207840B200F03FFAB4E02078217940B2DE +:1017A00000F04AFAAEE02078616840B200F074FAC6 +:1017B000A8E000F080FAA5E0206800F084FAA1E03B +:1017C000207800F099FA9DE02068FEF7BCF999E0D6 +:1017D0002068FEF7BCF995E021792068FEF7BEF994 +:1017E00090E02068FEF706F88CE02068FEF707F826 +:1017F00088E02078FEF707F884E0FEF715F881E02E +:101800002078FEF717F87DE02078FEF729F879E0D8 +:101810002068FEF742F875E02068FEF744F871E0B2 +:101820002068FEF746F86DE02068FEF747F869E0AB +:101830002068FEF749F865E02068FEF74BF861E0A4 +:101840002068FEF74CF85DE00846EEF77FFC59E0B3 +:10185000F0F7EDFC56E0F0F71AFD53E02068F0F7E2 +:1018600022FD4FE0206800F079FA4BE0206800F09C +:101870007BFA47E0206800F07CFA43E02078A26819 +:10188000616800F07BFA3DE0207800F083FA39E0EF +:10189000207800F08BFA35E02078616800F093FA48 +:1018A00030E02078616800F09AFA2BE02179207806 +:1018B00000F0ACFB26E02068FEF73FFA22E020684B +:1018C000FEF710FD1EE02068FEF7F4FC1AE020464B +:1018D00007C800F078FC15E0206800F0C0FC11E0BB +:1018E0006168206800F0E2FC0CE0206800F04EFE29 +:1018F00008E009E003E0FFE700F061FE02E0206895 +:1019000000F079FE206010BD0120086010BD0000CD +:1019100010B572B600F0E4F800280BD0EEF7C0FC6A +:10192000FEF7E1FD00F039FB72490020C8628862D1 +:101930007149086062B6002010BDF3B50025012092 +:101940000007C06A81B0C0430006000E0AD16B4890 +:101950000168491C05D000686949884202D069487D +:10196000FEBD012572B600F0BBF8002801D062B6BA +:1019700088E0EEF701FCEEF797FC634C634A002128 +:101980002368CB40DB0720D00346CB40DB0718D1D0 +:101990004BB2002B07DA1E07360F083EB608B6001A +:1019A000B618F66904E09E08594FB600F619366875 +:1019B0009B07DB0EDE4033069B0F012B05D0032B6C +:1019C00003D062B64F48401EFEBD491C2029D7D324 +:1019D000019C01204F49230001F078F914222424AE +:1019E0002424242424240B0D1012142016181A1C4D +:1019F0001E2F002400E00124C86314E00224FBE74A +:101A00000324F9E70424F7E70824F5E70924F3E7BA +:101A10000A24F1E70B24EFE70C24EDE70524EBE7BC +:101A2000072400E00624D06901210002000AC9074A +:101A30000843D061002D04D009E062B60120000304 +:101A4000FEBD2C4D3448E862EEF72EFCA8622A4910 +:101A500032480860324902980860EEF725FC2146BA +:101A600000F082FAFEF706FD00F04CFC00F0FEFAF2 +:101A70000198EEF7E3FB040062B603D0FFF748FFDE +:101A80002046FEBD0020FEBD10B5044600F028F83B +:101A9000002800D001202070002010BD21491848E6 +:101AA00008600020704710B50C46102808D0112897 +:101AB0000BD012280CD013280ED00120086010BDC6 +:101AC00061682068FFF739FF08E0FFF721FF05E0B4 +:101AD0002068FFF7D9FF01E0FFF7E0FF206010BDAD +:101AE00005480E490068884201D101207047002056 +:101AF00070470000000500400401002000100010A5 +:101B0000004001000210000000E100E000ED00E0F4 +:101B100000E400E04000004000200000EFBEADDE29 +:101B200010010020000000208107C90E002808DAFB +:101B30000007000F08388008814A80008018C069BB +:101B400004E080087F4A800080180068C8400006D2 +:101B5000800F704710B5044600F0DBF8002813D062 +:101B60002046FFF7E1FFC0B200F0E1F800280DD0F9 +:101B70007549E2060B78D20E01209040002B08D068 +:101B80004A681043486006E0704810BD6F48401C2A +:101B900010BD6F490860002010BD10B5044600F06C +:101BA000B8F800280BD06849E2060B78D20E012065 +:101BB0009040002B05D04A6882434A6004E06348A5 +:101BC00010BD634980310860002010BD70B50D461E +:101BD000044600F09EF800280BD05E480068E2063C +:101BE000D20E01219140084000D001202860002041 +:101BF00070BD564870BD10B5044600F08AF8002844 +:101C000007D0E106C90E0120884052490860002033 +:101C100010BD4E4810BD10B5044600F07AF80028FB +:101C200008D0E106C90E012088404A498031086089 +:101C3000002010BD454810BD70B50D46044600F0AB +:101C400068F8002819D0284600F071F8002816D04E +:101C5000A007C20EFF209040A907090E9140002C5A +:101C600010DA2207120F083A9308354A9B009B1896 +:101C7000DA6982430A43DA610CE0344870BD3348C4 +:101C8000401C70BDA3082F4A9B009B181A68824312 +:101C90000A431A60002070BD70B50C46054600F07E +:101CA00038F8002805D02846FFF73EFF20700020B6 +:101CB00070BD264870BDBFF34F8F21492648C860CC +:101CC000BFF34F8FFEE770B51F4C0546217801200A +:101CD00000290ED1207072B600F06EF91C4E8036CD +:101CE00031688143616000F067F9C043306062B6DB +:101CF00000202870002070BD13490A78002A06D001 +:101D0000002804D1124A48681060002008700020A2 +:101D1000704710B50446202805DA00F04DF901217E +:101D2000A140084201D0002010BD012010BD0128B3 +:101D300003D0032801D00020704701207047000025 +:101D400000ED00E000E400E01401002001200000AC +:101D500000E100E000E200E00400FA05364909680D +:101D6000C9B20160002070473349C0B2486000200A +:101D700070473149C0B2886000207047082801D3FD +:101D80002E4870472C4BC0001033C01801604260D1 +:101D900000207047022802D32848401C7047284979 +:101DA000C00040180121016000207047022802D3C2 +:101DB0002248401C70472249C000091D40180121DB +:101DC000016000207047022802D31C48401C704765 +:101DD0001C4A80008018C9B20160002070470228A8 +:101DE00002D31648401C7047164A800080180068CD +:101DF000C0B208600020704710B5FF200E49C043F4 +:101E000088600D4B082210330021D000C0180160FB +:101E10004160521C102AF8D30A4B00208200D218CD +:101E2000022801D3116002E01468E4B21460401C7F +:101E30000428F3D310BD000000F501400820000085 +:101E400000F0014000F80140F8B504468007002585 +:101E50000126002804DA5A48C563C6630220844379 +:101E6000E00404D55748C563C6638014844360000A +:101E700003D55548456080058443E00504D55348A3 +:101E8000C563C66380158443A00404D55048C56368 +:101E9000C6634014844360042704C00FF90F8842CE +:101EA00003D04CA1612000F00CFEB80F0AD04E49BF +:101EB000CD634E48C563C563CE63C663C663032066 +:101EC0008003844320050AD5494FFD632F20EEF798 +:101ED0006BF9FE632F20EEF767F9F8148443002CAA +:101EE00003DAFFF789FF640064084248044203D024 +:101EF00038A1902000F0E5FDF8BDF0B500210A46BC +:101F0000FF230446CC40E4072AD04CB2E606F60E86 +:101F10000125B540384E3560384E3560002C11DA59 +:101F200025072D0F083DAE08354DB6007619F56929 +:101F3000A407E70E1C46BC40A5431446BC402543FD +:101F4000F5610DE0A6082F4DB60076193568A40797 +:101F5000E70E1C46BC40A5431446BC4025433560F3 +:101F6000491C2029CDD3F0BD70B5274C0D4620600B +:101F7000FFF76AFF2068FFF7C0FF2846F0F720FA56 +:101F8000FDF7C6FEFDF772FDFFF736FFFDF7C5FC56 +:101F9000F0F702FB00F06AF870BD10B51A4C20682B +:101FA000FFF752FF2068FFF7A8FFFFF725FFF0F7C4 +:101FB0008CFA0020206010BD1348006870470000B4 +:101FC000C01F0040C0CF004000E50140C08F00406E +:101FD000C0DF00407372635C736F635F636F6E6634 +:101FE00069672E6300000000C0EF0040C0FF0040A2 +:101FF000C0BF0040FEFF0FFC80E100E080E200E097 +:1020000000ED00E000E400E01C01002070B50024B9 +:1020100002460D4620462146002A1ED0012A04D041 +:10202000022A04D0032A1ED103E0012002E002208C +:1020300013E003202B0000F049FE07160507090BEB +:102040000D0F1600012108E0022106E0032104E043 +:10205000042102E0052100E00621FEF7B1FA002884 +:1020600001D0204670BD0724FBE700009B490020FB +:10207000087088709A490870704770B5974C0E4682 +:102080006178884203D097A15A2000F01AFD0325F9 +:10209000330000F01BFE0953063030535353534AAC +:1020A00053002078022803D08EA15E2000F009FDA5 +:1020B0002570A078022802D0012804D014E0A0687E +:1020C00000F004FB10E000250BE0E0680168A06868 +:1020D00000F00DFBA068001DA060E068001D6D1CF5 +:1020E000E06020698542F0D30020A070FEF710FA6E +:1020F0000420207070BD2078022803D079A17620BA +:1021000000F0DFFC60687649401C6060032801D85D +:102110004D7003E0062806D80220487070496078A8 +:10212000FEF7F0FD70BD032003E0A0780028FAD18F +:102130000220FEF703F900F0C7F870BD69A19E20E8 +:1021400000F0BFFC70BD70B50546644C00206060B7 +:102150002078012803D063A1A52000F0B2FC6049DB +:10216000022008738D6003224A7020706078FEF7A9 +:10217000C9FD70BD10B5594CA078002802D1207857 +:10218000002801D0112010BD5A48FEF700FA6070F7 +:102190006078002803D001202070002010BD0320AB +:1021A00010BD10B50124020B64040121524BA04262 +:1021B00002D29140186802E0203A586891400840E5 +:1021C00000D0012010BDF8B50E46910005464F190C +:1021D00014463F1F009100F09CFA00998002891973 +:1021E000091FB14201D2012200E00022002C03D0DD +:1021F000FF2101318C4201D90920F8BD3F498D42B0 +:1022000019D3AF4217D3854205D2874203D228465D +:102210003043800701D01020F8BD8E420BD3002A36 +:1022200009D12846FFF7BDFF002804D13846FFF743 +:10223000B8FF002801D00F20F8BDFFF79BFF002852 +:10224000FAD126480121C66085600461817020466C +:10225000312148431430FFF776FF0020F8BD10B558 +:1022600004462648800A84420BD300F052FAA0426A +:1022700001D8102010BDA0020446FFF792FF0028ED +:1022800001D00F2010BDFFF775FF0028FAD11348C9 +:102290000221846081701A48FFF755FF002010BDAD +:1022A0001648010B01208840401E704700B50B46C0 +:1022B0000246FFF7F5FF104201D00F2000BD0E4887 +:1022C00002604360002000BD10B5044C6078FEF74A +:1022D000B2F900202070A07010BD00002001002085 +:1022E000281C00207372635C736F635F666C61739C +:1022F000682E63007B2001000006004000400100C2 +:1023000010540000E349002048700870887048604D +:10231000E1490873704710B5E048826A81158A4325 +:10232000DC498B691A438262826A0223C9699A4333 +:102330000A438262FEF7ECF810BD002814D0417801 +:10234000002901D001290ED18168D54A6439914212 +:1023500009D24068D349884205D8CE494978012935 +:1023600003D1002801D0002070470120704770B5CC +:102370000446FEF782FD0068002803D0CAA1802031 +:1023800000F09FFB0126C34D002C06D020780028CA +:102390002BD0012827D0022801D0EE7023E0287826 +:1023A000002820D16068FFF7C8FF0028F5D06068DA +:1023B0000078002800D00220B74E30706068806836 +:1023C0009630B06060684168E868FEF7F2FB7060C4 +:1023D000606803244078002808D07470AE49A8785B +:1023E000FEF790FC6C70FFF796FF70BD02207070D6 +:1023F000F4E7F8B5A74C0D46A178884203D0AAA10E +:10240000BF2000F05EFB284600270526A24D0300F2 +:1024100000F05CFC09061135587F8997B8A2B80016 +:102420006078032806D06078022803D09EA1C320DC +:1024300000F047FBF8BD6078032806D060780228DA +:1024400003D099A1C72000F03CFB04206070E77026 +:102450002078002802D0FEF75BF8F8BDA86896380F +:10246000FEF7F1FF6868E0608C48816A82151140D0 +:10247000A161806A02210840E06100205CE0607890 +:10248000032806D06078022803D087A1E22000F05C +:1024900018FB2078002802D000F0EFF8F8BD607833 +:1024A000032802D02069410020E004202DE07A4971 +:1024B000A078FEF727FCF8BD0420FDF73FFF0120C0 +:1024C0006070F8BD6078032807D06078022804D0D7 +:1024D000FF2075A1043000F0F4FA20780028DBD149 +:1024E0006078032810D06868A06076492161A068F0 +:1024F000FEF75FFB686069686069FFF711F868497B +:1025000063318842D8DCD2E70520FDF717FF6670FB +:10251000F8BD6078042804D0FF2063A1263000F0C5 +:10252000D0FA022008E06078042804D0FF205EA1E1 +:102530002B3000F0C6FA012061688847FFF717FFCB +:10254000F8BD6078042804D0FF2057A1303000F097 +:10255000B8FAFFF7E0FEF8BD6078042804D0FF2049 +:1025600051A1353000F0ADFA2078002894D1E07800 +:10257000002805D00620FDF7E1FE6670E770F8BD83 +:102580000720C2E7FF2048A14B3051E770B5050096 +:1025900005D0404C6078002803D0112070BD102079 +:1025A00070BD4948FDF7F3FFA070A078002804D063 +:1025B000656001206070002070BD032070BD10B503 +:1025C00034480178002901D0112010BD417800293C +:1025D0000BD0417805290AD04178012907D0012183 +:1025E00001704078052802D003E00F2010BD00F0F4 +:1025F00044F8002010BD70B5264C064660780528CA +:1026000004D06078012801D00F2070BD002E25D0A5 +:102610003046FFF792FE002822D060781E4D012838 +:1026200020D07168E068FEF7C4FA6860B068963040 +:10263000A8603078002800D0032028707078002827 +:1026400017D0032068706078052814D002206070CD +:102650001149A078FEF756FB002070BD102070BD18 +:10266000072070BDFEF702F86061A0601549216186 +:10267000D9E70220E6E70320E9E710B5054CA0788A +:10268000FDF7D9FF0820FDF759FE0020607020708B +:1026900010BD000034010020381C0020000500405F +:1026A0003D860100FF1FA1077372635C736F635F58 +:1026B000726164696F5F74696D65736C6F742E63AA +:1026C0000000000024080000F3230100134A022147 +:1026D000516013490B68002BFCD0906008680028FB +:1026E000FCD00020506008680028FCD0704710B56E +:1026F0000A4B01225A600A4A1468002CFCD001607F +:1027000010680028FCD00020586010680028FCD019 +:1027100010BD0120000740697047000000E501403E +:1027200000E40140704770477047704770470346A8 +:1027300010B50B439B070FD1042A0DD308C810C94D +:10274000121FA342F8D018BA21BA884201D9012039 +:1027500010BD0020C04310BD002A03D0D30703D012 +:10276000521C07E0002010BD03780C78401C491C67 +:102770001B1B07D103780C78401C491C1B1B01D183 +:10278000921EF1D1184610BDF8B5042A2CD3830748 +:1027900012D00B78491C0370401C521E83070BD0CB +:1027A0000B78491C0370401C521E830704D00B7821 +:1027B000491C0370401C521E8B079B0F05D0C91A81 +:1027C000DF002023DE1B08C90AE0EDF7FDFCF8BDA1 +:1027D0001D4608C9FD401C46B4402C4310C0121FC2 +:1027E000042AF5D2F308C91A521EF0D40B78491CFA +:1027F0000370401C521EEAD40B78491C0370401C25 +:10280000521EE4D409780170F8BD01E004C0091F2C +:102810000429FBD28B0701D50280801CC90700D098 +:102820000270704700290BD0C30702D00270401C11 +:10283000491E022904D3830702D50280801C891E09 +:10284000E3E70022EEE70022DFE70378C2781946CB +:10285000437812061B0219438378C0781B0419437E +:1028600011430902090A000608437047020A08706A +:102870004A70020C8A70020ECA7070470022030967 +:102880008B4273D3030A8B4258D3030B8B423CD346 +:10289000030C8B4221D312E003460B437FD400226A +:1028A00043088B4274D303098B425FD3030A8B42E4 +:1028B00044D3030B8B4228D3030C8B420DD3FF224E +:1028C000090212BA030C8B4202D31212090265D01C +:1028D000030B8B4219D300E0090AC30B8B4201D3CF +:1028E000CB03C01A5241830B8B4201D38B03C01A16 +:1028F0005241430B8B4201D34B03C01A5241030B8D +:102900008B4201D30B03C01A5241C30A8B4201D33D +:10291000CB02C01A5241830A8B4201D38B02C01AE8 +:102920005241430A8B4201D34B02C01A5241030A5F +:102930008B4201D30B02C01A5241CDD2C3098B4244 +:1029400001D3CB01C01A524183098B4201D38B01C1 +:10295000C01A524143098B4201D34B01C01A524164 +:1029600003098B4201D30B01C01A5241C3088B42A9 +:1029700001D3CB00C01A524183088B4201D38B0094 +:10298000C01A524143088B4201D34B00C01A524136 +:10299000411A00D201465241104670475DE0CA0F0D +:1029A00000D04942031000D34042534000229C46CD +:1029B00003098B422DD3030A8B4212D3FC228901D7 +:1029C00012BA030A8B420CD3890192118B4208D3AD +:1029D000890192118B4204D389013AD0921100E00F +:1029E0008909C3098B4201D3CB01C01A5241830923 +:1029F0008B4201D38B01C01A524143098B4201D350 +:102A00004B01C01A524103098B4201D30B01C01A7A +:102A10005241C3088B4201D3CB00C01A52418308F4 +:102A20008B4201D38B00C01A5241D9D243088B424A +:102A300001D34B00C01A5241411A00D201466346ED +:102A400052415B10104601D34042002B00D5494251 +:102A5000704763465B1000D3404201B50020C0467A +:102A6000C04602BD704770477047704710B500F010 +:102A700077F810BD30B58C180278401C13071B0F77 +:102A800001D10378401C120906D10278401C03E0F2 +:102A90000578401C0D70491C5B1EF9D101E00B70DC +:102AA000491C521EFBD1A142E6D3002030BD0000DC +:102AB00001231B68134B1860134B1960134B1A60EA +:102AC0007047134A134B13607246053AF0E7114AF8 +:102AD0000F4B1B689A420ED10D4B002018600198D5 +:102AE0000D4B04B598470CBC9E46024602980099CF +:102AF0000A4B1B68184706980599094B1B68DB6849 +:102B0000184700005C0100206001002064010020E3 +:102B100054010020EFBEADDEAD1501001001002014 +:102B2000000000200B4A12680B4B9A420AD1004762 +:102B3000084A1268084B9A4204D101B5FDF773F9AF +:102B400003BC8E4605490968EFF305808000014407 +:102B50000968084704010020EFBEADDE0000002038 +:102B60001C481D497047FFF7FBFFEDF7E7FA00BD72 +:102B700001200007C06AC0B2FF2804D117481849D5 +:102B80000968884202D0174817490160174A136044 +:102B90005B68184720BFFDE7154B1B680F4999423A +:102BA00002D018688842F5D004D1124B18680B493E +:102BB0008842EFD080F308880F49884204DD0F482F +:102BC000026802210A4302600D4880470D48804791 +:102BD0000D480047481C0020481C0020FFFFFFFF55 +:102BE000001000102C050040040000000000002030 +:102BF00014100010004001000020002024050040B7 +:102C0000C3150100712B0100B12A01001248704563 +:102C100002D1EFF3098101E0EFF3088188690238FE +:102C20000078102812DB20280EDB0C4A12680C4BAF +:102C30009A4203D1602804DB0A4A10470220086048 +:102C40007047094A10470000084A1047084A1268AE +:102C50002C32126810470000FDFFFFFF0401002026 +:102C6000EFBEADDEAD0200000D170100A71A010096 +:102C7000000000200A480B4908470B48094908474B +:102C80000A48084908470A480649084709480549C3 +:102C9000084709480349084708480249084700000F +:102CA000E1230000252B0100412B0000EB2900004F +:102CB000992900004D270000A72A000043260000A4 +:102CC00003B40148019001BD0500002030B47446F2 +:102CD000641E2578641CAB4200D21D46635D5B0018 +:102CE000E31830BC1847000002490020C8612039B1 +:102CF00008727047A003002000020206FFFFFFFFDA +:102D00000000FFFF0102040810204080555555D6F1 +:102D1000BE898E00F401FA00960064004B00320078 +:102D20001E0014000100030000000100000000006C +:102D3000000000000000000000000000870000000C +:102D4000000000000000000000000000000002037E +:102D5000040500000E0F0000882D01000400002073 +:102D60001000000004010000982D01001400002054 +:102D700054010000742A0100C02D010068010020E8 +:102D8000E01A0000200100000249022208681042F7 +:102D9000FCD0704700E200E0A1074E56FF9900CD3D +:102DA00029023501022B013601000100D83720FB32 +:102DB000349B5F8074800010027001E4B52A01002A +:020000041000EA +:1010000000400100FFFFFFFFFFFFFFFFFFFFFFFFAB +:041010004900FFFF95 +:04000005000000C136 +:00000001FF diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo_wanted.bin b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo_wanted.bin Binary files differnew file mode 100644 index 0000000..b7e4cf7 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foo_wanted.bin diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foobar_wanted.bin b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foobar_wanted.bin Binary files differnew file mode 100644 index 0000000..06b77f5 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/foobar_wanted.bin diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/pca10028_nrf51422_xxac_blinky.bin b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/pca10028_nrf51422_xxac_blinky.bin Binary files differnew file mode 100644 index 0000000..b745f0d --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/pca10028_nrf51422_xxac_blinky.bin diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s130_nrf51_mini.hex b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s130_nrf51_mini.hex new file mode 100644 index 0000000..6e27ce8 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s130_nrf51_mini.hex @@ -0,0 +1,894 @@ +:020000040000FA +:10000000C0070000D1060000D1000000B1060000CA +:1000100000000000000000000000000000000000E0 +:100020000000000000000000000000005107000078 +:100030000000000000000000DB000000E500000000 +:10004000EF000000F9000000030100000D010000B6 +:1000500017010000210100002B0100003501000004 +:100060003F01000049010000530100005D01000054 +:1000700067010000710100007B01000085010000A4 +:100080008F01000099010000A3010000AD010000F4 +:10009000B7010000C1010000CB010000D501000044 +:1000A000DF010000E9010000F3010000FD01000094 +:1000B00007020000110200001B02000025020000E0 +:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24 +:1000D00008205A49096809580847382057490968CB +:1000E000095808473C2055490968095808474020E5 +:1000F0005249096809580847442050490968095875 +:10010000084748204D490968095808474C204B4981 +:10011000096809580847502048490968095808479C +:100120005420464909680958084758204349096836 +:10013000095808475C204149096809580847602068 +:100140003E4909680958084764203C49096809582C +:100150000847682039490968095808476C20374919 +:100160000968095808477020344909680958084740 +:100170007420324909680958084778202F490968CE +:10018000095808477C202D490968095808478020EC +:100190002A490968095808478420284909680958E4 +:1001A0000847882025490968095808478C202349B1 +:1001B00009680958084790202049096809580847E4 +:1001C00094201E4909680958084798201B49096866 +:1001D000095808479C201949096809580847A02070 +:1001E0001649096809580847A4201449096809589C +:1001F0000847A8201149096809580847AC200F4949 +:10020000096809580847B0200C4909680958084787 +:10021000B4200A49096809580847B82007490968FD +:1002200009580847BC2005490968095808470000D3 +:1002300003480449024A034B7047000000000020B5 +:10024000C0070000C00700000122D84B5A6000BF61 +:10025000D74A1268002AFBD0016000BFD44A126856 +:10026000002AFBD00022D14B5A6000BFD04A12684E +:10027000002AFBD07047F0B505460E46174600240D +:1002800006E0A200B158A2005019FFF7DDFF641C80 +:10029000BC42F6D30020F0BD0120C043C549086030 +:1002A000401048607047014601229204086890425D +:1002B00001D9102070470020FCE7F0B505460C4638 +:1002C0001646002706E028462168FFF7BDFF2D1DD2 +:1002D000241D7F1CB742F6D3F0BD70B505460C4611 +:1002E0002E460BE0304600F075F9FF2C01D80024B3 +:1002F00001E0FF3C013C012080023618002CF1D1C6 +:1003000070BD0146012212044868904201D90920BB +:100310007047A9484069401C01D10F20F8E7002030 +:10032000F6E7FEB504462068030000F037FA05043E +:100330002B4249598B00201DFFF7E3FF0546002D96 +:1003400001D02846FEBDFFF7A7FF0120C00200F044 +:1003500041F9042221469948FFF78DFF002801D07A +:100360000320EFE708222146944800F06DF90028A9 +:1003700006D1002192480068FFF766FF00F00CF9F3 +:100380000320DFE7A768E6686068019031463846D9 +:10039000FFF7A3FF324638460199FFF78EFFB20000 +:1003A0003846019900F050F9002800D1CAE703202F +:1003B000C8E700F0E3F9834800688349086041E03A +:1003C00060680190E668A0680090B200009901980A +:1003D00000F03AF90746002F00D1B3E70E20B1E74D +:1003E000201DFFF760FF0546002D01D02846A9E734 +:1003F0006068002807D1FFF74FFF0320800200F05C +:10040000E9F800F0C9F8FFF747FF0120C00200F04B +:10041000E1F8042221466948FFF72DFF002801D0AA +:1004200003208FE708222146644800F00DF90028D8 +:1004300006D1002162480068FFF706FF00F0ACF823 +:1004400003207FE700BF00207CE770B505460C461F +:10045000182D04D12068FFF764FF206002E001201E +:10046000206000BF00BF70BDF0B589B05248406940 +:1004700003905248806881000398081802900398FE +:10048000000B01900121090302984018401E000B47 +:1004900000900124002520462946019A00F0C4F866 +:1004A0000022401E91410791069001260027304608 +:1004B0003946009A00F0B8F80022401E914105919B +:1004C0000490049BDB43059AD2430698184307998E +:1004D00011430791069037490698086007984860CD +:1004E00009B0F0BD70B53448446934488568466841 +:1004F000AA003146204600F0A7F8002801D00020CD +:1005000070BD0120FCE72D484068002801D0012083 +:1005100000E000200546FFF7E5FF002807D0FFF7C1 +:10052000BBFE0320800200F055F800F035F8FFF71D +:100530009BFF002D0ED020484669204884684768FC +:1005400021463046FFF7C9FE224639463046FFF7BE +:10055000B4FE00BF00F020F810B5184844681A48EF +:100560000460204600F0DCF810BD15480068006803 +:10057000401C01D100BFFEE710480068002802D0EF +:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B +:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB +:1005A000C860BFF34F8F00BFFEE7000000E50140C9 +:1005B00000E40140000600400010001000080000A8 +:1005C000B8070000BC070000000000200400FA0586 +:1005D00000ED00E010B50146104B1A6808460223F2 +:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC +:1005F00004D0904202D20A4B186101E0084B986087 +:1006000000BF084B1B68002BFBD00023044C636029 +:1006100000BF044B1B68002BFBD010BD0010001066 +:1006200000E5014000E4014010B5202A04DB01464A +:10063000203A9140002010BD914020239C1A03468F +:10064000E3401943904010BD034610B50B439B0790 +:100650000FD1042A0DD308C810C9121FA342F8D025 +:1006600018BA21BA884201D9012010BD0020C04328 +:1006700010BD002A03D0D30703D0521C07E000208E +:1006800010BD03780C78401C491C1B1B07D1037854 +:100690000C78401C491C1B1B01D1921EF1D118463D +:1006A00010BD70477047704710B500F007F810BDD7 +:1006B000014B1B68DB6818470000002019481A49E5 +:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716 +:1006D0001649174C24688C420BD1164B1B68994263 +:1006E0000CD1154B154A1360186810498842EDD09B +:1006F0000AE0134880F30888124B18470F4A13602A +:1007000018680A498842E1D080F308880E49884277 +:1007100004DD0E48026802210A4302605B68184744 +:100720000346DFE7C0070000C0070000FFFFFFFF30 +:10073000000C000014100010001000000000002049 +:10074000000400206B05000000200020240500406C +:100750000D48704502D1EFF3098101E0EFF3088104 +:10076000886902380078182802D1C046074A104725 +:10077000074A12682C3212681047000000B5054B7A +:10078000054A9B58984700BDFDFFFFFF4B04000042 +:1007900000000020001000000400000030B4744687 +:1007A000641E2578641CAB4204D3635D5B00E318D0 +:1007B00030BC18471D46F8E7000C00000010000090 +:10100000F0210020FDB101005D22000063B101006C +:1010100000000000000000000000000000000000D0 +:101020000000000000000000000000006DB20100A0 +:1010300000000000000000005D2200005D220000B2 +:10104000D9B20100DFB201005D2200005D22000084 +:101050005D2200005D2200005D2200005D22000094 +:10106000E5B201005D2200005D220000EBB201004C +:101070005D220000F1B20100F7B20100FDB20100F3 +:101080005D2200005D2200005D2200005D22000064 +:101090005D2200005D2200005D2200005D22000054 +:1010A00003B3010009B301005D2200005D220000CE +:1010B0005D2200005D2200005D2200005D22000034 +:1010C00000F002F81AF07BF80CA030C80838241899 +:1010D0002D18A246671EAB4654465D46AC4201D170 +:1010E0001AF06DF87E460F3E0FCCB646012633420D +:1010F00000D0FB1AA246AB46334318477CA301003D +:10110000ACA30100103A02D378C878C1FAD85207CC +:1011100001D330C830C101D504680C6070470000AD +:101120000023002400250026103A01D378C1FBD803 +:10113000520700D330C100D50B6070471FB5C046C1 +:10114000C04619F0DEFF04B00FB41FBDF0B4404636 +:10115000494652465B460FB402A0013001B506482D +:10116000004700BF01BC86460FBC804689469246B8 +:101170009B46F0BC70470000C11000008269024924 +:101180008161024810447047911100000100000085 +:1011900001B41EB400B501F000FF01B40198864609 +:1011A00001BC01B01EBD0000401E00BF00BF00BF5B +:1011B00000BF00BF00BF00BF00BF00BF00BF00BF37 +:1011C00000BFF1D17047000070B505460C461646C9 +:1011D00002E00FCC0FC5103E102EFAD2082E02D31B +:1011E00003CC03C5083E042E07D301CC01C5361F2E +:1011F00003E021782970641C6D1C761EF9D270BD45 +:101200008307FF22DB0E9A408907090E99400028C8 +:101210000BDA0007000F0838830828489B001818CD +:10122000C36993430B43C3617047830824489B0001 +:101230001B181868904308431860704710B504469F +:1012400000210120FFF7DCFF00211820FFF7D8FF65 +:1012500000210B20FFF7D4FF02211920FFF7D0FF58 +:1012600002210D20FFF7CCFF02210E20FFF7C8FF5F +:1012700002210F20FFF7C4FF0221C81FFFF7C0FFA4 +:1012800003211620FFF7BCFF03211520FFF7B8FF4D +:10129000204600F019F8002010BD6721018070473A +:1012A00010B500F020F810BD0648704710B500F0EA +:1012B00022F810BD704770477047000000ED00E055 +:1012C00000E400E003F9004370B505462D4C08200A +:1012D0002070A01CFFF7E1FF5920A080294620467E +:1012E00000F0B3FB70BD10B500F0B8FB254900203D +:1012F000891E087010BDF8B5224E0446B61E30781F +:1013000001270D46002807D0204660380B2808D852 +:10131000204600F059FF2BE0602CF9D01A480860F5 +:10132000F8BD20466C38032803D8204600F08DFF16 +:101330001EE0204670381F2803D8204600F047F9E9 +:1013400016E0204690380F2803D8204600F0EAF82F +:101350000EE02046A0380F2803D8204600F076F88B +:1013600006E02046B0380F2804D8204600F0E2F905 +:10137000286000E02F60602CD2D128680028CFD1EF +:101380003770F8BD1A000020013000000120254907 +:10139000C003086024490020087007202349C005C5 +:1013A0008860704770B5204D04462878A04207D069 +:1013B000002C05D0002803D01DA14D2019F0CBFE34 +:1013C0002878A0420ED000211E4A18482C70002C0C +:1013D0001BD01D4B012C06D0022C0DD014A168206F +:1013E00019F0B9FE70BD1160022111605361032133 +:1013F00009068160416070BD116003211160536175 +:101400000121C9058160416070BD11601160072133 +:10141000C905816070BD10B505A1712019F09BFE52 +:1014200010BD000080E100E02000002000F5014038 +:101430007372635C68616C5F63636D5F6161722E80 +:101440006300000000F500408401002010B5A038C2 +:10145000030019F0A1FF0B070E172028313A414B6A +:10146000525C65004B6808788A68194603F0D9F920 +:1014700010BD88888A6883B20888194680B203F054 +:10148000DFF910BD08884C68CB688A6880B22146B5 +:1014900003F0DAF910BD08884B688A6880B21946F3 +:1014A00003F0EEF910BD88888A6883B2088819466F +:1014B00080B203F0FAF910BD88888A6883B2088880 +:1014C000194680B203F034FA10BD08884A6880B229 +:1014D000114603F073FA10BD088982B2888883B27E +:1014E0000888194680B203F074FA10BD08884A686B +:1014F00080B2114603F091FA10BD08894C6882B29F +:101500000888CB6880B2214603F00AFB10BD08882A +:101510004C68CB688A6880B2214603F01BFC10BD82 +:10152000012010BD10B59038030019F035FF0906F1 +:101530000F161D242C363F464E0088888A6883B2D9 +:101540000888194680B204F01DF910BD08884A6861 +:1015500080B2114604F051F910BD08884A6880B283 +:10156000114604F056F910BD08884A6880B2114649 +:1015700004F05CF910BD08884B688A6880B219468F +:1015800004F067F910BD088982B2888883B20888A0 +:10159000194680B204F066F910BD08894B6882B222 +:1015A0000888194680B204F07CF910BD08884A68A2 +:1015B00080B2114604F087F910BD888882B208888D +:1015C000114680B204F0DBF910BD012010BD10B54A +:1015D0007038030019F0E0FE1B0F15192125282F84 +:1015E000363B4044484C53585F68707881889095EA +:1015F000999CA2A5AC004A680878114607F019FC2E +:1016000010BD086807F066FC10BD0C790B7B8A687A +:101610000868214607F06FFC10BD086807F000FD60 +:1016200010BD07F08CF910BD08884A6880B21146D9 +:1016300007F034FE10BD0A790888114680B207F021 +:10164000C4FE10BD087840B207F0CDFE10BD08887A +:1016500080B207F0E1FE10BD086807F0EFFE10BD94 +:10166000086801F0ECFB10BD086801F016FC10BD25 +:10167000088982B209C9194607F0F8FE10BD05C9EC +:10168000114607F042FF10BD08884A6880B2114633 +:1016900009F0FAF910BD0C790888CB688A6880B225 +:1016A000214609F0CDFA10BD0B7908888A6880B20E +:1016B000194609F07DFC10BD08884B688A6880B225 +:1016C000194609F0EEFC10BD08884C68CB688A68A2 +:1016D00080B2214609F053FD10BD08884A6880B2E7 +:1016E000114609F08CFD10BD0B7908880A7A80B28A +:1016F000194607F02DFF10BD088880B207F02DFFB6 +:1017000010BD086807F030FF10BD07F0FCF810BDF1 +:101710008A6809C9194607F08CFF10BD07F0DCF88C +:1017200010BD08884A6880B2114608F05BF810BD09 +:10173000012010BD10B5B02805D0B12808D0B228BE +:101740000BD0012010BD088880B20AF056F910BDF8 +:10175000088880B20AF070F910BD08884B688A6862 +:1017600080B219460AF079F910BD000010B50300E7 +:1017700019F012FE0A0609060C0C0F0F06060612D7 +:1017800007F005F910BD09F027FF10BD01F042FA7E +:1017900010BD06F075FA10BDFAA1FE4819F0DBFC89 +:1017A00010BD7FB5FC49054603C901900291132085 +:1017B000800169468881F94A0F2310460A2128389A +:1017C0000AF043FE0024F6480AF05DFE641CE4B211 +:1017D0000A2CF8D304200090F04801231A4603A9EC +:1017E000F0300AF05DFA002804D0FF20E5A1533064 +:1017F00019F0B1FC686800F024FC00211E220846A4 +:1018000004F040F907F0C6FA02222421E54801F06D +:101810007FFBE44801222C214C3001F079FBE149A7 +:101820000B20B03901F000FA002804D0FF20D5A128 +:10183000673019F090FC09F09FFE02F075F901ABDA +:1018400000220821D8A007F085F9002804D0FF2045 +:10185000CCA16D3019F07FFC284602F0C2FC0028B4 +:1018600004D0FF20C7A16F3019F075FCDB2189007F +:10187000D04819F045FBCF48012141710221817107 +:101880000621C1717FBD10B5CA4CA078092804D3C8 +:10189000FF20BCA1A73019F05EFC207860214843EE +:1018A000001900210173417BF722C908C900C91C36 +:1018B0001140EF22114041730121E1700C3010BD45 +:1018C00070B50E4600211C4619801546030019F01C +:1018D00063FD0723050B1711231D2300224629460C +:1018E000304609F096FE70BD22462946304606F085 +:1018F00098FE70BD22462946304601F0C2FF70BDF9 +:1019000022462946304603F0C0FD70BD22462946D6 +:10191000304600F010FC70BD9E489AA1D53819F0F1 +:101920001AFC032070BD70B5A24CE078002818D0D6 +:101930002078602148430019407B00254007400F74 +:1019400001190879401E08712078401CC0B220702F +:10195000092800D12570A078401CA0700AF01DFF56 +:10196000E57070BD9348C079002800D08BE77047C0 +:1019700070B5904DA86800280CD0FFF7F3FF002841 +:1019800062D06022A968FFF71FFCFFF7CCFF0020A0 +:10199000A860EFE76879002856D0FFF774FF044687 +:1019A00080484C3001F0C4FA6060002804D1C9209E +:1019B00074A1800019F0CFFB60680AF0EAF80028F3 +:1019C0000DD0204606F011FD6078010703D5C00850 +:1019D000C000401C2BE0734861684C302DE071481A +:1019E00061684C3001F0ADFA00F05AFB00282BD1B1 +:1019F000FFF749FF04466B4801F09AFA606000283F +:101A000004D164485FA16D3019F0A5FB60680AF04D +:101A1000C4F8002814D0606800886080204609F06F +:101A20002BFE6078010706D5C008C000801C6070DE +:101A3000FFF779FF9EE75B48616801F082FA99E75A +:101A40005848616801F07DFA70BD10B55A4CE160EC +:101A5000A0605A4800F034FC607010BD5649002068 +:101A60000870704770B5564E0546706A94B00C46C3 +:101A7000401C04D1B06AC0430004000C0BD0306A93 +:101A8000C007C00F2870706A19F03CFAB06A207164 +:101A9000000A607114E02B206946087009A96846A5 +:101AA0000AF04BF8002804D0972036A1800019F0E6 +:101AB00052FB0120287006220AA9204619F0C1F91C +:101AC0002878002803D06079C0210843607114B0E1 +:101AD00070BDF0B53A4C0646206895B00D463746C5 +:101AE0000837401C08D16068401C05D1A068401C24 +:101AF00002D1E068401C11D02068314619F002FA8A +:101B00006068311D19F0FEF9A068394619F0FAF93C +:101B1000E06831460C3119F0F5F925E02B206946D3 +:101B2000087009A968460AF008F8002804D0194886 +:101B300014A1553819F00FFB08220AA9304619F0F4 +:101B400080F92B206946087009A9684609F0F5FF5D +:101B5000002804D0A3200BA1800019F0FCFA082271 +:101B60000AA9384619F06DF920692E460836401C3E +:101B700029D16069401C26D1A069401C23D1E069AD +:101B8000401C1FE07372635C686F73745F636F72F5 +:101B9000652E6300DA020000B4B30100D801002012 +:101BA0006D170000A40B00206E52463531383232DA +:101BB00000000000880700202400002071190000A8 +:101BC0008000001012D02069294619F09BF9606945 +:101BD000291D19F097F9A069314619F093F9E069C8 +:101BE00029460C3119F08EF915B0F0BD2B2468464A +:101BF000047009A909F0A1FF002803D0F649F748AD +:101C000019F0A9FA082209AF28460AA919F019F90A +:101C10006846047009A909F090FF002804D0EF4835 +:101C2000ED49C01D19F097FA0822391D304619F008 +:101C300008F9D9E770B5EA4C0546A068002804D039 +:101C40000320E549000219F086FAA56070BD10B5C1 +:101C50000146E44801F075F9E1498879401CC0B2B9 +:101C60008871012803D1E048407800F04DFB10BD99 +:101C700070B50446DD4816460D46814204D1D7486A +:101C8000D549CB3019F067FA012E05D0E120D249B1 +:101C9000800019F060FA70BD66202070002020726C +:101CA000A5810120A07370BD70B515460C4606468F +:101CB000FFF758FE00280CD06621017046800121F4 +:101CC000017221680161A18881820573FFF72BFEF3 +:101CD00070BD1321304607F078FB70BDC2494968DA +:101CE000884201D210207047032101700020704704 +:101CF00070B5BD4C05462078002694B0002801D070 +:101D00000820E4E6BA4A6260954201D21020DEE67D +:101D10006868002809D00921D82804D3C31C9B086F +:101D20009B00834205D00846D1E60320400268604C +:101D30000EE0012109074B6B896B4B43AD49511AEA +:101D40000122591AD202891A814201D20421EAE7FA +:101D500000F052FF6178A0680CF04EFBE068401E76 +:101D600007280BD8302269460A70887068460DF043 +:101D700088FF002802D009A80CF0FBFC2846FFF7DA +:101D800010FD012020703046A1E6F8B504469648C3 +:101D90000F464068814208D3002C01D0844204D30E +:101DA000E01C80088000A04201D01020F8BD8C48C3 +:101DB0008178002911D039880091417860225143FF +:101DC0000D18287B0C350007000F3B4600222946E2 +:101DD000FFF776FD060004D015E0002038800520CE +:101DE000F8BD002C13D039880098814201D90C2607 +:101DF0000DE028783B460007000F22462946FFF7F2 +:101E00005FFD060005D00C2E01D000203880304642 +:101E1000F8BD734C6078401CC0B26070092801D1D5 +:101E200000206070A078401EA07068784107490FBC +:101E300001290ED0022906D003291AD066496E481E +:101E400019F089F9E3E7C006E1D46868FFF7FFFEFF +:101E5000DDE7644869684C3001F073F86079401C34 +:101E6000C0B260710128D2D15F48407800F04CFACE +:101E7000CDE7E079401CE071C9E7604A10B59042B7 +:101E800009D3594A0124A4045268A04201D39042C4 +:101E900001D3914201D2102010BD00F0FEFE10BD12 +:101EA000564B10B5994209D34F4B0124A4045B68EB +:101EB000A14201D3994201D39A4201D2102010BD10 +:101EC000022803D0102801D0092010BD00F00BFF1C +:101ED0000028FAD0052010BD484B10B598420DD30C +:101EE000414B0124A4045B68A04201D3984205D36E +:101EF000994203D3002A03D09A4201D2102010BD88 +:101F000000F017FF0028FAD0072010BD10B50446D6 +:101F1000354894B04068844202D2102014B010BDFD +:101F20000F2008A9087369460BA809F006FE0028CF +:101F3000F4D16846007A207068464089608068461F +:101F40008089A0800020E9E710B500290BD0264A3F +:101F50005268914202D30B68934201D2102010BD07 +:101F60008A88002A02D001F037FE10BD092010BD7A +:101F700010B5224A94B091420ED31B4A01239B0410 +:101F80005268994201D3914206D3441E1E2C41D877 +:101F9000994203D3914201D21020BFE7012837D1E3 +:101FA00008780024C007C00F002803D0032069462A +:101FB000887001E06846847038206946087009A975 +:101FC000684609F0BAFD002804D004480CA18B38FB +:101FD00019F0C1F82046A1E7841B0000AA02000006 +:101FE00088070020A40B002024000020FFFF000031 +:101FF00000220020000000202104000000C0010099 +:102000007372635C686F73745F636F72652E6300D5 +:10201000072083E70246203A1F2AF9D806F001FE7E +:102020007CE710B5604A5268914201D2102010BD81 +:102030000246203A1F2A02D806F068FE10BD07208B +:1020400010BD70B50546594C002020702046461939 +:1020500055484660E01C80088000A04204D0FF2064 +:102060005349293019F077F801200007C06AC043AE +:102070000006000E03D14F480068401C03D04E48B4 +:102080004E49301AC862A8B20422214604F00DF964 +:10209000002804D0FF204649393019F05CF870BDA3 +:1020A000F0B595B03B2008A9087369460BA809F064 +:1020B00044FD002804D0FF203D49813019F04BF841 +:1020C0003F4E00246D4630E02F19B87DC10706D081 +:1020D000400704D460004019C08809F0E9FB394882 +:1020E000807900281FD0B87D80071CD5600040197A +:1020F000C0880022062109F0F7FB002813D03C21FC +:1021000008A8017360004019C1886846C185694606 +:102110000BA809F012FD06000BD0FF2024499630D1 +:1021200019F019F805E0641CE4B268460079A04291 +:10213000CAD8304658E5F7B50546007800270009AB +:102140000C463E46062804D0FF201949BF3019F03E +:1021500002F8287A00280ED0012814D0FF20144954 +:10216000E03018F0F8FF0298002C068001D027809C +:1021700066800020FEBD02270926002C10D0A88909 +:10218000A080A87B0AE003271426002C08D06888CA +:10219000A0802869E060A88A2082287B2072E2E77C +:1021A00002980680E5E700002400002000220020BD +:1021B000002000000010001000000020000500407A +:1021C000043000008807002010B56038030019F0C3 +:1021D000E3F80A060A0F13181F252930353A086854 +:1021E000FFF786FD10BD05C91146FFF7CEFD10BDF6 +:1021F0000868FFF773FD10BD05C91146FFF73DFEE6 +:1022000010BD4B6808788A681946FFF749FE10BD73 +:102210008A6809C91946FFF75FFE10BD0868FFF715 +:1022200075FE10BD08884A6880B21146FFF78CFE23 +:1022300010BD05C91146FFF79BFE10BD05C911462B +:10224000FFF7EFFE10BD012010BD01207047000018 +:102250000E4A12680C498A420AD118470B4A126882 +:10226000094B9A4204D101B500F08EFE03BC8E46A4 +:10227000074909680958084706480749054A064BAF +:102280007047000000000000BEBAFECA64000020D3 +:1022900004000020F0210020F021002001203F490F +:1022A000400608603E4908603E490A68FF231B0259 +:1022B0009A4383121A430A6038498039086070478C +:1022C00010B502460420384904E0C3005B181B79AE +:1022D000002B0AD00346401EC0B2002BF5D133A11B +:1022E000432018F038FFFF2010BDC300CA50002261 +:1022F00059184A718A7101220A7110BD2A4A0021B7 +:10230000C00080180171704710B50446042803D33B +:1023100026A1522018F01FFF2348E1000C18207955 +:10232000012803D021A1532018F015FF6079A1796D +:10233000401CC0B2814200D06071012017494006A4 +:102340008031086010BD70B5164804250068164E2F +:102350000004800F1B4C02281AD014A1692018F029 +:10236000FAFE15E02078C10088190279012A07D108 +:10237000427983799A4203D04279827170588047BA +:102380002078401CC0B22070042801D300202070A7 +:1023900028466D1EEDB20028E4D170BD80E100E05A +:1023A00080E200E018E400E0200C00207372635C1F +:1023B000736F635F7369676E616C6C696E672E63C0 +:1023C000000000003400002010B5EFF31080C407B7 +:1023D000E40F72B6D2484178491C41704078012818 +:1023E00001D10AF0FFF9002C00D162B610BD70B522 +:1023F000CB4CE07800280AD10125E570FFF7E4FF17 +:102400000AF0F8F9002804D000200AF0CBF90020E7 +:1024100070BDC44865714560F9E770B5EFF3108091 +:10242000C507ED0F72B6BE4C6078002803D1BEA17F +:102430008F2018F090FE6078401E60706078002851 +:1024400001D10AF0D3F9002D00D162B670BD10B5EC +:10245000B348C178002904D000214171C170FFF751 +:10246000DCFF002010BD10B504460AF0C3F9AC49EA +:10247000C978084000D001202060002010BDF8B5C8 +:102480000246A74C0026A67108200421012510272A +:10249000130018F081FF0D080A0C0E101214161EFE +:1024A000262123252800257122E0022001E0217148 +:1024B0001EE020711CE027711AE02020F9E70126B8 +:1024C00016E0FFF781FF0AF095F90028FBD00226FD +:1024D0000EE02171A5710BE02771FBE7202000E0E1 +:1024E00040202071F6E7FF208FA1763018F033FEF0 +:1024F0000AF08CF9002809D00AF08EF9B04205D113 +:1025000030460AF08CF90028FAD02CE00120800730 +:10251000C560894900224A60884A9661814B02223F +:102520005A60856086480269D243D206D51702698F +:1025300010231A4302610F466D1C00E020BF78682B +:102540000028FBD030460AF06AF90028FAD0002DA6 +:1025500004D17B48026910218A430261714902203B +:10256000886000207860A07900280CD00AF042F939 +:1025700005460AF09FF8734A002D02D0A260E06081 +:1025800001E0E260A060002E01D100F0A5F8F8BDE6 +:1025900010B504460AF034F9002805D0604901203E +:1025A000C8704A78521C4A702046FFF768FF10BD79 +:1025B000F8B5614DA8680026012802D1AE600AF086 +:1025C000F1F86868012800D16E6028680127544C32 +:1025D000012812D12E606079002803D000200AF073 +:1025E000E1F866712078002807D00AF003F9002886 +:1025F00003D0012080070761A770286901282AD12C +:102600002E6100F05FF8012080074761A079002863 +:1026100015D00AF0EFF800900AF04CF80099002964 +:1026200001D0E16800E0A168411A022901DA8A1CA0 +:1026300011DC0099002901D0E06000E0A060FFF704 +:10264000C3FE0AF0D7F8002804D0012080070761F4 +:10265000A77000E02770E868012812D100F032F876 +:1026600000F030F800F02EF8A078002804D1FF2008 +:102670002DA1033018F06FFDEE60A6702670FFF7F5 +:10268000CCFEF8BD10B5264CE078002801D10AF048 +:10269000ADF801208107886100F014F8A0780028C7 +:1026A0000BD0254CE068002803D10AF0B8F80028C8 +:1026B000F8D10020E06000F005F800201949C0437F +:1026C000886010BD08B55020694608806A461088A9 +:1026D000411E1180FAD208BDF8B51248192787604B +:1026E000154900200860C8600AF084F8BE0701247C +:1026F0000B4D002802D03461AC7000E02C70FFF765 +:1027000063FE084847600D4928798863FFF7DAFFC0 +:10271000B461FFF7D7FF0849002008617461F8BD74 +:1027200038000020000300407372635C736F635FC6 +:10273000636C6F636B2E6300000100400005004076 +:1027400000ED00E0FFFFFF7F8107C90E002808DAD7 +:102750000007000F083880082E4A80008018C069E2 +:1027600004E080082C4A800080180068C8400006F9 +:10277000800F704710B50D20FFF7E6FFC4B20420AC +:10278000C043FFF7E1FFC0B2844203D023A11A2067 +:1027900018F0E1FC26490120486010BD0121254ABE +:1027A00048031060244B00221A60244A5160244AD6 +:1027B0001060244A11601F49803908607047012168 +:1027C0001C4A480310601F4A51601B4A00211160D7 +:1027D0001B490860704710B517490868012804D0E4 +:1027E0000EA1572018F0B7FC10BD114880680022D8 +:1027F000C0B20A6009F0BEFC10BD10B50E480168F9 +:102800000029FCD0FFF7E7FF01200D4940030860D5 +:1028100010BD000000ED00E000E400E07372635CB6 +:10282000736F635F68616C5F726E672E6300000098 +:1028300000D5004080E100E000D1004000D300401E +:1028400080E200E000D0004030B40121BC48C90261 +:102850000160CD1005604A030260BA4803681B029C +:102860001B0A036004680023240A24020460B6489B +:102870000468240A24020460B4480124446084608B +:10288000B34C23606360A360B24B19601D601A6093 +:10289000B14B19601A600121016030BC704710B45F +:1028A0000121A748CA0202600B0203600C06046003 +:1028B000A64841608160A94841680029FCD1A4492B +:1028C0000020086048608860A248026003600460DD +:1028D00010BC704701219F48C9020160C910016006 +:1028E0007047002805D0012805D0022805D19C4852 +:1028F00070479C4870479C48704710B59BA18B203F +:1029000018F029FC002010BD70B500219E4C9F4D91 +:102910009F4A8F4B002808D001281DD0022822D0C2 +:1029200092A1B32018F017FC70BD01200004A06034 +:10293000A86011601960974BC2039A60964A906034 +:102940007F4A0012106095480160864801609448F3 +:1029500001609448017070BD01204004A060A8602F +:102960005160596070BD01208004A060A860916032 +:10297000996070BDF8B59446834A8B4F834D00240F +:102980000126002808D0012832D0022840D077A1A3 +:10299000E82018F0E0FBF8BD891E0902090A0120B1 +:1029A000000490603C6468606C4A1164012B1DD087 +:1029B00000217C4A7D4B51706146DC63DE637C4BB9 +:1029C0005C6002249C6004241C61744B3D311960DE +:1029D00073490E605F4B891519606F4B58605E48F4 +:1029E00001606C49C00548601670F8BD0121E0E740 +:1029F0000120704E4004704F012B04D134645060AC +:102A000068603964F8BD9060346468603964F8BD0A +:102A100001206A4E80046A4F012BF4D1EEE74F4843 +:102A20004068704770B54A4D28680026564C01280A +:102A300006D1A068C00303D501200004A0602E6069 +:102A40006868012809D1A068800306D501204004E8 +:102A5000A0606E6001200AF0B9FEA868012809D1C3 +:102A6000A068400306D501208004A060AE6002206B +:102A70000AF0ACFE70BD10B54A490878002818D09D +:102A80000120444AC0079060434AC00B90602C4A22 +:102A900000121060414A00201060324A1060404A23 +:102AA000106008704A78002A02D048700AF08EFE42 +:102AB00010BD0320FAE70120424900060860704774 +:102AC0000120244900060860704701203D49400567 +:102AD0000860704701201F4940050860704733496E +:102AE0000020C86388151B4908607047410A364AB0 +:102AF000C005C00D5043801C5143400A0818704760 +:102B000010B4324C430B63431B0C5C020C602E4C24 +:102B10006343C31A2E485C0258432B4B400D43437A +:102B2000E31A0124DB0324041B191B1613700A6823 +:102B30001018086010BC704710B50AF01BFF10BDDC +:102B400080E100E008E400E018E400E000B00040AC +:102B500040B1004080E200E000E100E000B500404C +:102B600048B100404081004044B100407372635C52 +:102B700072656D5F68616C5F6576656E745F7469C0 +:102B80006D65722E6300000000B3004040B300404A +:102B900040B5004000F50140008300404085004002 +:102BA000008200404800002000B10040C08F00407B +:102BB0000085004004B1004004B5004008B1004069 +:102BC00008B5004000E200E0093D00003786000043 +:102BD0006F0C010010B50AF0B9FE10BD00200449C9 +:102BE000C863012001218140024A116000BF704783 +:102BF000C01F004080E200E010B50DF05DF909F063 +:102C0000F7F9FEF7C3FB0FF0F5FA0DF08FFF0DF0AB +:102C10001BFF10BD70B50C46054603F0A7FA214610 +:102C200028460EF0C2FF70BD70B50D46040012D0EC +:102C3000002D10D02101284618F060F910225449C7 +:102C4000284618F0FEF852480121083801804480D7 +:102C50004560002070BD012070BD70B54C4E002451 +:102C60000546083E11E0716820014018817BAA7B6F +:102C7000914209D1C17BEA7B914205D10C222946C0 +:102C800018F0B2F8002806D0641C30888442EADBD1 +:102C90000020C04370BD204670BD70B50D460600D3 +:102CA0000AD0002D08D03A4C083C20886188401C8E +:102CB000884203D9042070BD102070BD3046FFF754 +:102CC000CCFF002801DB401C0AE02088616800017D +:102CD00040181022314618F0B4F82088401C20809B +:102CE0002870002070BD70B514460D001FD0002C58 +:102CF0001DD00021A170022802D0102817D108E0B1 +:102D0000687829780002084311D00121A170108051 +:102D10000BE02846FFF7A1FF002808DB401CA0704D +:102D2000687B297B000208432080002070BD0120C1 +:102D300070BD70B5054614460E000AD000203070F4 +:102D4000A878012807D004D9114908390A88904287 +:102D50000BD9012070BD002C04D028782070288861 +:102D6000000A50700220087010E0002C0CD0496856 +:102D70000001411810222046103918F062F8287816 +:102D800020732888000A607310203070002070BD06 +:102D9000540000205A4910B5884207D30121890404 +:102DA000884205D357490968884201D2102010BDD6 +:102DB0000146012005F0CBF810BD30B5044693B0B4 +:102DC00000200D46079014210BA818F099F81C213B +:102DD000684618F095F86A46112010770020507761 +:102DE000107802210843107007A80C90012008AA4F +:102DF000907245486A4610850AA80B902088108476 +:102E000060885084A0889084E088D084907FF921E5 +:102E10000840801C4008400090770820908610876A +:102E200008A80F9010AA0BA9684600F05CFF0028C4 +:102E300003D110A800882880002013B030BD3EB513 +:102E400004460820694608802D48844207D30120A3 +:102E50008004844205D32B480068844201D21020AC +:102E60003EBD2146012005F072F80028F8D12088E7 +:102E7000694688806088C880A0880881E088488189 +:102E800005F065FE01AB6A46002101F0BBFB694617 +:102E900009880829E4D003203EBD1FB50446002060 +:102EA000029008206946088115480391844207D39F +:102EB00001208004844206D312480068844202D272 +:102EC000102004B010BD05F042FE014602AA0F48D2 +:102ED00001F02EFD0028F4D169460989082901D0A6 +:102EE0000320EEE7694609882180694649886180A8 +:102EF00069468988A1806946C988E180E1E70000C8 +:102F000000C0010028000020042A0000FFFF00008C +:102F100010B5031D03600020521E04E05C181C6005 +:102F2000401C2346C0B29042F8DB0020186010BD60 +:102F300001460A680020002A02D0104612680A6082 +:102F4000704702680A6001607047000010B50146D2 +:102F50002022094817F075FF07490020C877084666 +:102F600010BD0649012048610548064A01689142A2 +:102F700001D1002101607047B00E00200005004023 +:102F800064000020BEBAFECA0C4908784A78401C8A +:102F9000C0B2904200D008707047094A074820BF6D +:102FA00040BF20BF4178037843701368002B02D1E3 +:102FB00003788B42F3D00020704700006B000020A4 +:102FC00000E200E00A4A022151600A490B68002B26 +:102FD000FCD0906008680028FCD000205060086891 +:102FE0000028FCD0704701200007406970470000AE +:102FF00000E5014000E401407047704770477047AA +:1030000010FFFFFFDBE5B15100C001006700FFFFCB +:1030100003B40148019001BD09000020002803D03D +:103020008178012939D101E0102070470188FE4ADA +:10303000881A914233D01BDCFC4A881A91422ED068 +:103040000BDC00292BD00320C002081A27D001284E +:1030500025D001210903401A07E001281FD00228CA +:103060001DD0FF281BD0FF380138002815D116E0ED +:10307000FF220132811A904211D008DC01280ED0C3 +:1030800002280CD0FE280AD0FF2806D107E001292B +:1030900005D0022903D0032901D0002070470F205A +:1030A000704700B50B2826D009DC030018F074F92E +:1030B0000B1D2125251B25292325271F1B00112832 +:1030C0001BD008DC0C2816D00D281CD00F2814D0DB +:1030D000102808D10FE0822809D084280FD0852835 +:1030E0000FD0872811D0032000BD002000BD05208F +:1030F00000BDCF4800BD072000BD0F2000BD04204B +:1031000000BD062000BD0C2000BD0D20800200BDCA +:1031100070B500290BD0CB1FFA3B81241E46CDB2DF +:10312000112B1BD2012805D0022806D009E000206F +:1031300010701DE0FF20043001E0FF2003308142C9 +:1031400018D0330018F028F9111613131613161699 +:103150001316161613131313161316000846FF380A +:1031600081381F2803D9FF39FE39022902D815708A +:10317000002070BD1470072070BD00B5030018F06A +:103180000BF9060406040C080A0C002000BD1120EF +:1031900000BD072000BD082000BD032000BD007851 +:1031A0000207120F04D0012A05D0022A0AD10EE02C +:1031B000000907D108E00009012805D0022803D042 +:1031C000032801D0072070470870002070470620B0 +:1031D0007047002807D0012807D0022807D003280D +:1031E00007D007207047002004E0112002E02120D2 +:1031F00000E0312008700020704738B50C4605000B +:103200004FD06946FFF7CBFF002822D12088032149 +:1032100089028843694609788907090D0843208097 +:103220006946681CFFF7BBFF002812D121880320E4 +:1032300000038143684600788007800C01432180A9 +:10324000A8784007820F2020012A03D0022A03D049 +:10325000072038BD814300E00143218088B2010589 +:10326000890F08D0012189038843A9780907C90F6C +:1032700089030843208080B28104890F0AD0A9788D +:103280004004C906C90F400CC903084320808004CC +:10329000800F02D12088400403D5208840210843B4 +:1032A0002080002038BD70B50446002008801546F7 +:1032B0006068FFF7A2FF002815D12189A08981420B +:1032C00010D861688978C90708D00121490288426D +:1032D00008D8491C17F01EFE298009E0FF21FF31A4 +:1032E000884201D90C2070BDFF30FF3003302880A8 +:1032F000002070BD10B5137804785B08E4075B000C +:10330000E40F23431370FD2423400478A407E40F43 +:10331000640023431370FB24234004786407E40F04 +:10332000A40023431370F724234004782407E40FF8 +:10333000E40023431370EF2423400478E406E40FF1 +:10334000240123431370DF2423400478A406E40FF0 +:103350006401234313700078BF244006C00F23404C +:10336000800103431370002906D00878C10701D1FA +:10337000800701D5012000E00020C0015906490E58 +:103380000843107010BD30B50A8803239B020488DF +:103390009A4323059D0F02D1A3049C0F01D09B0FDC +:1033A00000E001239B021A4303230A801B039A4374 +:1033B00003889804840F02D11805830F01D0800F71 +:1033C00000E00120000302430A8030BDF3B593B052 +:1033D0000D000FD0139800280FD01221284617F0A7 +:1033E0008DFD03AAFF21012003F0D5F80024264615 +:1033F00037467AE0102015B0F0BD0720FBE768469D +:10340000807D01280BD16846818A0520C002081AF8 +:1034100010D0012810D0022812D0032812D0042C7A +:1034200014D0052C15D113E002290000012800005A +:1034300003300000012400E002246846468A08E0C8 +:10344000032406E068460424478A02E0052400E0DD +:1034500006246846418A1398814246D12C74002E76 +:1034600041D00DAA0EA905200292019100901023CF +:103470000022FF21304603F02FF9002823D16846AF +:10348000808E2A46C0B20EA9FFF72DFC00281AD163 +:10349000AE81002F27D00DA9052008AE0291009023 +:1034A000132300220196FF21384603F015F9002866 +:1034B00009D16846808EF11CC01EC0B22A1DFFF7DC +:1034C00012FC002801D0032095E708A881784278F3 +:1034D00008021043E881062C05D16846807DA87259 +:1034E0006846808A2881002085E703A803F05CF8FD +:1034F000002884D0FFF7D5FD7DE7002805D0FE4ADF +:10350000012903D0022903D003207047518800E02D +:103510009188814201D1002070470720704770B523 +:103520000C4605461C21204617F0E8FC00202080B0 +:10353000002D08D0012D04D0F0A1F54817F00BFEA6 +:1035400070BD062000E00520A07070BD70B592B07F +:103550001546064601206A461071107453740846D9 +:1035600008300395029048889082FEF7FBF904002A +:1035700019D06580172069468883203600940AABED +:103580007178023307AA01A80EF017F90646607891 +:10359000000701D5FEF7C7F9002E0AD03046FFF725 +:1035A000ECFD12B070BD1321284605F00EFF03207C +:1035B000F7E708A800906846838B0422012128467B +:1035C00007F0B3FEEDE770B506468AB000200D4661 +:1035D00007900590069003A90490052402460291E5 +:1035E0000190102300942946304603F075F8002816 +:1035F0000DD108A804A9009102900194684683891E +:1036000000222946304602F083FE002801D0FFF751 +:1036100048FD0AB070BD10B50EF0D5FA10BDF0B57A +:1036200089B000260546059600780C460827030059 +:1036300017F0B2FE0CFD070C390B75759BBEFCD361 +:10364000E3FD68680A38FEF702FB07E1A88800225C +:1036500080B20421009008F067FB0290002C04D097 +:10366000AB48A6A16E3017F076FD0298002804D171 +:10367000A748A2A16F3017F06EFD0298009908309C +:103680000DF0D0FCFEF76EF9040007D060783843E7 +:10369000607000986080FEF746F9E1E01321009821 +:1036A00005F093FEEAE0002C04D1BD2093A1800038 +:1036B00017F051FD60880022042108F035FB0090CE +:1036C000002804D192488DA1883017F044FD00995C +:1036D000002008802A7994461EE0C3005B199B688D +:1036E00007936B469B8B1A0708D5DA0606D560460A +:1036F000C20050194038C08F088006E05B0409D52D +:103700000871C2005019C0884880607838436070E2 +:103710000226A3E0401CC0B28445DED89EE0E888C3 +:10372000694608800090002C04D1794873A1983034 +:1037300017F011FD2878062813D10098C00B10D07F +:1037400060880022042108F0EFFA060004D17048D6 +:103750006AA1A23017F0FFFC00203071A8887080A9 +:1037600039E060783843607078E0002C04D1684814 +:1037700062A1B43017F0EFFC60880022042108F049 +:10378000D3FA0090002804D161485CA1B73017F04B +:10379000E2FC009808300EF068FA0121484002D19E +:1037A000E888C00B5AD0009861880226C180D8E70B +:1037B000002C04D1564851A1D03017F0CCFC6088C1 +:1037C0000022042108F0B0FA002804D150484BA18F +:1037D000D33017F0C0FC0226C3E7002C04D14C48BC +:1037E00046A1DC3017F0B7FC022661880122204692 +:1037F000FEF73EFA01200590B3E7A889002280B2C7 +:103800000421009008F090FA0746002C04D04048AC +:103810003AA1EE3017F09FFC002F04D13C4837A1AD +:10382000EF3017F098FC6868029001E009E010E0C2 +:10383000288969468881012202A90098FEF734FA96 +:103840000CE0002C8DD16D202CA1C00017F083FC62 +:1038500087E72F4829A1FE3017F07DFC002C0DD002 +:10386000607800070AD50598002807D184202070C9 +:103870002046582229460830FDF7A6FC304609B0FC +:10388000F0BDF7B50C460546007A224688B00A32EC +:103890000492921C01920027811E16323E4602922B +:1038A0000B0017F079FD08F405F348488ED0F2F3C9 +:1038B00068880022042108F037FA0190002803D11B +:1038C0000EA1144817F047FC01980088002802D088 +:1038D0005227072600E151271E26002C70D0688849 +:1038E000A0800120A071019804990079C0004019BE +:1038F000C089FFF76BFD0FE0400C00207372635C22 +:1039000067617474735F636F72652E6300000000FB +:103910006F0200008603000000287DD10198007925 +:10392000C0004019C089208101980079C000401969 +:10393000408AA083F0E0698A0091062820D1E889B6 +:10394000C00B1DD008462230512786B2002CC5D0AE +:10395000A8890199FFF73AFD002872D16888A080F4 +:103960000220A071A88920810120A072288AE0830A +:10397000009820846969009A029817F062FACBE0F7 +:1039800008462030502786B2002CA7D0A889049979 +:10399000FFF71CFD002854D16888A080A889E0802A +:1039A000287A06280AD002202072288AA08300984C +:1039B000E083204669692030009ADEE70120F3E7C2 +:1039C0008FE068880022042108F0AEF90690688A2A +:1039D00000900698002803D1FD49FE4817F0BBFB74 +:1039E000069808300EF041F90121484002D1E889DB +:1039F000C00B25D000985127223086B2002C7AD0F7 +:103A00006888A080A8890199FFF7E0FC002818D1F8 +:103A10000220A071A88900E013E020810420A07298 +:103A2000288AE083009820846969009A029817F038 +:103A300008FA0699002008710698A98941806BE070 +:103A400003200BB0F0BD688804F0DDF900906888B1 +:103A50000022042108F068F901900098002804D1A0 +:103A6000DC48DB492C3017F076FB0198002804D1A4 +:103A7000D848D7492D3017F06EFB0198D649C08839 +:103A8000884205D05127222604E01EE03FE035E0C1 +:103A900050272026002C2ED06888A080502F07D0D9 +:103AA0000220A0712146287B0831FFF738FD33E062 +:103AB000287BA11DFFF733FD6A8800230199009838 +:103AC000FFF744FD0028BCD126E0C449A889C98875 +:103AD000814207D154270626002C0CD06888A0808C +:103AE0001AE008E053270826002C04D06888A0803C +:103AF000A889E08010E00A98068013E05527072681 +:103B0000002CF8D0A889A0800020A07104E08D20AE +:103B1000AF49C00017F01FFB0A98002C068001D0A7 +:103B20002780668000208CE7AC4900200870704731 +:103B300030B585B00C4601F0DBF90546FF2804D10D +:103B4000A448A349953017F006FB0020208020717F +:103B50006080401EE0802046294608300DF056FA6D +:103B60006A462946012002F016FD102412E068463C +:103B7000808800070ED56846C0882946FFF723FDD8 +:103B800068468188FF2321438180C0882946019AA5 +:103B900002F02CFE684602F007FD0028E7D005B0D1 +:103BA00030BD0A46014610B5104608300DF042FA05 +:103BB00010BD70B505460022042108F0B5F80400D8 +:103BC00004D184488249B73017F0C5FA2046294607 +:103BD00008300DF027FA70BDF0B591B00C460746DD +:103BE00004F011F9050005D02878222804D2082015 +:103BF00011B0F0BD7A48FBE700220421384608F0F6 +:103C000093F80646002C02D0A08800280CD0012092 +:103C1000694608710220087400204874002C05D001 +:103C2000A0880883206802E00920E1E70883059066 +:103C30003046083003970290FDF794FE040018D038 +:103C40006780172069468883203500940AAB69781D +:103C5000023307AA01A80DF0B0FD05466078000701 +:103C600001D5FDF760FE002D09D02846FFF785FA43 +:103C7000BEE71321384605F0A8FB0320B8E708A8E3 +:103C800000906846838B04220121384607F04DFBE3 +:103C90000021C943F180ABE7FFB585B00E9E778860 +:103CA000384604F0B0F8054600220421384608F0F2 +:103CB0003BF80446002D03D145494A4817F04BFA1A +:103CC000002C04D147484249401C17F044FA0834FC +:103CD000089869460394C1C105A80DC820356978C4 +:103CE0000DF0DAF9CBE5F0B50446002099B00D46A9 +:103CF00001460D9010A88181164601818180374AC6 +:103D000068469180018510A80180684601878185F9 +:103D100081841078012808D0022806D0032804D016 +:103D2000042802D0082019B0F0BD2F4A944273D362 +:103D30002E4F0121890438688C4201D3844278D304 +:103D4000294A954275D3012189048D4201D38542C8 +:103D50006FD36168002913D0234A914269D30122AD +:103D60009204914201D3814263D3608921898842C0 +:103D700003D801225202914201D90C20D3E70D90C1 +:103D800016AA0EA92846FFF78EFA0028CBD168683C +:103D900080784007800F02280AD16846008F80048F +:103DA000800F05D02869002802D03968884240D3A6 +:103DB0000AA92069FFF721FA0028B4D12069002858 +:103DC0001CD0607880076846008D14D580040FE011 +:103DD000FC380000EE030000FFFF0000400C002054 +:103DE000023000000C05000000C001002800002087 +:103DF000800F68D002E08004800F64D16846008D97 +:103E0000810618D58004800F606806D0002812D083 +:103E1000396888420DD302E00BE000280BD0FE4940 +:103E2000884206D301218904884204D33968884234 +:103E300001D2102077E709A96069FFF7DEF90028B1 +:103E40009CD16069002808D06846808C0105890FE4 +:103E5000012938D18004800F35D00BA9A069FFF764 +:103E6000CCF900288AD16846808C80062BD468461D +:103E7000808D810627D4A169002906D00105890F0C +:103E8000012920D18004800F1DD0E068002804D0D3 +:103E90000078002817D01C2815D204AA611C2046DF +:103EA000FFF728FA0121890210A80180012768463E +:103EB0008773DA49818104AA033217A92868FEF7BB +:103EC00038FF002801D007202DE710A8007F15A992 +:103ED000C01CC2B200200C920190FF320090034639 +:103EE0000291FF3203A80332109902F0ACFA0028C5 +:103EF00026D110A9888A0F902A892969C84801917A +:103F00000092029010A90A8B6B8928680E9902F022 +:103F10009AFA01007ED1C2480025001F81886846B8 +:103F20004174090A8174052104A86A4623C210A8B5 +:103F30002A46FF21808A0C9B02F0EAF9002802D071 +:103F4000FFF7AFF8EFE66846007C0322C1090020C6 +:103F5000920290430122920280181490002928D0E6 +:103F6000014610A8018068462921877309028181D2 +:103F7000058608A8007C0023410860784900C00736 +:103F8000C00F014308A80174FD2001406078A54AD4 +:103F90008007C00F4000014308A801740CA902204B +:103FA00001910090029503A8109902F04CFA0100CB +:103FB00030D16068002828D0206900280DD10AA9D6 +:103FC0000EA8FFF7E0F96078800706D46946088DEF +:103FD0000321090388436946088590496846877329 +:103FE000FE3181818F492089891E16F093FF626816 +:103FF0000D9811AB0192009002930A46002303A88A +:00000001FF diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s132_nrf52_mini.hex b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s132_nrf52_mini.hex new file mode 100644 index 0000000..825af2f --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/firmwares/s132_nrf52_mini.hex @@ -0,0 +1,910 @@ +:020000040000FA +:10000000C0080000DD0700000D050000BD0700006E +:1000100017050000210500002B050000000000006E +:100020000000000000000000000000006108000067 +:100030000000000000000000350500003F05000042 +:1000400049050000530500005D050000670500003C +:10005000710500007B050000850500008F0500008C +:1000600099050000A3050000AD050000B7050000DC +:10007000C1050000CB050000D5050000DF0500002C +:10008000E9050000F3050000FD050000070600007B +:10009000110600001B060000250600002F060000C8 +:1000A00039060000430600004D0600005706000018 +:1000B000610600006B060000750600007F06000068 +:1000C00089060000930600009D060000A7060000B8 +:1000D000B1060000BB060000C5060000CF06000008 +:1000E000D9060000E3060000ED060000F706000058 +:1000F000010700000B070000150700001F070000A4 +:100100002B070000370700001FB500F003F88DE84B +:100110000F001FBD00F058BB2DE9F04105460E460B +:100120001746002406E056F8241005EB840000F082 +:10013000D9F9641CBC42F6D30020BDE8F081014629 +:100140000868B0F5002F01D3102070470020FCE7AD +:100150002DE9F04105460C461646002706E02846E4 +:10016000216800F0BFF92D1D241D7F1CB742F6D376 +:10017000BDE8F08170B505460C462E460BE03046D2 +:1001800000F09EF9B4F5806F01D2002401E0A4F5DF +:10019000806406F58056002CF1D170BD0146D1E98E +:1001A000000200EB8200B0F5002F09D84FF01020BC +:1001B000406904234A6803FB0200B0F5002F01D90F +:1001C000092070474FF010204069401C08B90F20EB +:1001D000F7E70020F5E72DE9F041044620680528FF +:1001E00047D2DFE800F0032A40475700201DFFF701 +:1001F000D5FF054615B12846BDE8F08100F044F969 +:1002000000BF4FF4805000F05BF900BF042221468C +:100210009148FFF781FF08B10320EDE7082221464E +:100220008D4800F09BFA30B900218C48006800F03E +:1002300059F900F002F90320DEE7A668E56867686F +:1002400029463046FFF796FF2A4639463046FFF7E3 +:100250007FFFAA003946304600F080FA08B9002036 +:10026000CAE70320C8E700F013FB4FF440507C4975 +:10027000086041E06568E668A768B200394628462C +:1002800000F06CFA8046B8F1000F01D10020B3E70E +:100290000E20B1E7201DFFF752FF05460DB128469D +:1002A000AAE7606848B900F0EFF800BF4FF40050CB +:1002B00000F006F900BF00F0C0F800F0E5F800BF5C +:1002C0004FF4805000F0FCF800BF04222146624841 +:1002D000FFF722FF08B103208EE7082221465E487F +:1002E00000F03CFA30B900215C48006800F0FAF8F0 +:1002F00000F0A3F803207FE700BF00207CE770B583 +:1003000005460C46182D04D12068FFF764FF2060D5 +:1003100002E00120206000BF00BF70BD2DE9FF4159 +:100320004FF0102044694C48806804EB8005260B90 +:1003300005F6FF70070B00200090019002900390DB +:1003400000BF0BE041095DF8211000F01F030122FE +:100350009A40114342094DF82210401CB042F1D39B +:1003600038460BE041095DF8211000F01F0301221F +:100370009A40114342094DF82210401C8028F1D3C5 +:10038000684600F073F8BDE8FF8170B54FF01020AB +:100390004469314885684668AA003146204600F025 +:1003A000DDF908B1002070BD0120FCE72A48406853 +:1003B00008B1012000E000200546FFF7E6FF48B144 +:1003C00000F062F800BF4FF4005000F079F800BF71 +:1003D00000F033F8FFF7A2FF7DB14FF0102046691F +:1003E0001D488468476821463046FFF7C3FE224611 +:1003F00039463046FFF7ACFE00BF00F01EF810B5DE +:100400001548446816480460204600F015FA10BDEF +:10041000124800680068401C08B900BFFEE70E489B +:10042000006810B1042806D101E0FFF7BFFFFFF715 +:10043000E6FF00BFFEE700BFFEE7BFF34F8F0948AE +:10044000006800F4E06008490843001D05490860A1 +:10045000BFF34F8F00BFFEE700100000B40800009C +:10046000000000200CED00E00000FA050F4A0168D2 +:100470001160121D416811600C4A103281681160D0 +:10048000121DC168116070476FF0060007490860CF +:10049000C010064914310860091F08600349091D8E +:1004A000086070470249086070470000000600407D +:1004B00008E5014000BF134800680028FBD07047E2 +:1004C00010B50446022010490860FFF7F3FF2046EC +:1004D000FFF7E8FFFFF7EEFF00200B490860FFF78A +:1004E000E9FF10BD00B502460120074B1860FFF779 +:1004F000E1FF1160FFF7DEFF0020034B1860FFF7FC +:10050000D9FF00BD00E4014004E501400820904906 +:1005100009680958084710208D4909680958084793 +:1005200014208B4909680958084718208849096828 +:1005300009580847382086490968095808473C2067 +:1005400083490968095808474020814909680958C2 +:10055000084744207E4909680958084748207C49D3 +:100560000968095808474C2079490968095808471B +:100570005020774909680958084754207449096888 +:1005800009580847582072490968095808475C20EB +:100590006F4909680958084760206D49096809587A +:1005A000084764206A49096809580847682068496B +:1005B0000968095808476C206549096809580847BF +:1005C0007020634909680958084774206049096820 +:1005D0000958084778205E490968095808477C206F +:1005E0005B49096809580847802059490968095832 +:1005F0000847842056490968095808478820544903 +:100600000968095808478C20514909680958084762 +:1006100090204F4909680958084794204C490968B7 +:100620000958084798204A490968095808479C20F2 +:100630004749096809580847A020454909680958E9 +:100640000847A4204249096809580847A82040499A +:10065000096809580847AC203D4909680958084706 +:10066000B0203B49096809580847B420384909684F +:1006700009580847B8203649096809580847BC2076 +:100680003349096809580847C020314909680958A1 +:100690000847C4202E49096809580847C8202C4932 +:1006A000096809580847CC202949096809580847AA +:1006B000D0202749096809580847D82024490968E3 +:1006C00009580847DC202249096809580847E020F2 +:1006D0001F49096809580847E4201D490968095855 +:1006E0000847E8201A49096809580847EC201849C2 +:1006F000096809580847F02015490968095808474A +:10070000F4201349096809580847F8201049096876 +:1007100009580847FC200E490968095808475FF442 +:1007200080700B490968095808475FF482700849CE +:100730000968095808475FF4847005490968095831 +:100740000847000003480449024A034B7047000071 +:1007500000000020C0080000C008000040EA0103BB +:1007600010B59B070FD1042A0DD310C808C9121F5A +:100770009C42F8D020BA19BA884201D9012010BD94 +:100780004FF0FF3010BD1AB1D30703D0521C07E061 +:10079000002010BD10F8013B11F8014B1B1B07D1C5 +:1007A00010F8013B11F8014B1B1B01D1921EF1D136 +:1007B000184610BD7047704770470000014B1B681A +:1007C000DB681847000000201C481D497047FFF7F0 +:1007D000FBFFFFF799FC00BD20BFFDE74FF0FF31A5 +:1007E000184C24688C420DD1174B1B6899420ED1CE +:1007F000164B1B68164A136018684FF0FF31884289 +:10080000EAD00BE0134880F30888134B1847104ACE +:10081000136018684FF0FF318842DDD080F30888FC +:100820004FF02021884204DD0C48026802210A436F +:1008300002605B68184700000346DBE7C008000061 +:10084000C00800000020000014100010B0080000D4 +:1008500000000020000400201104000024050040D6 +:100860006FF00200704502D1EFF3098101E0EFF370 +:100870000881886902380078182803D100E0000058 +:10088000074A1047074A12682C32126810470000C6 +:1008900000B5054B1B68054A9B58984700BD0000F2 +:1008A000FF02000000000020B0080000040000006B +:0C08B00000300000002000000024F400D4 +:10300000F0210020C1D50100E14100001FD50100E1 +:10301000E1410000E1410000E1410000000000004A +:1030200000000000000000000000000025D60100A4 +:10303000E141000000000000E1410000E14100002A +:103040008DD6010093D60100E1410000E14100006E +:10305000E1410000E1410000E1410000E1410000E8 +:1030600099D60100E1410000E14100009FD6010036 +:10307000E1410000A5D60100ABD60100B1D60100A8 +:10308000E1410000E1410000E1410000E1410000B8 +:10309000E1410000E1410000E1410000E1410000A8 +:1030A000B7D60100BDD60100E1410000E1410000BA +:1030B000E1410000E1410000E1410000E141000088 +:1030C000E1410000E1410000E1410000E141000078 +:1030D000E1410000E1410000E1410000E141000068 +:1030E000E1410000E1410000E1410000E141000058 +:1030F000E1410000E1410000E1410000E141000048 +:10310000E1410000E141000000F002F81AF035FA58 +:103110000AA090E8000C82448344AAF10107DA4532 +:1031200001D11AF02AFAAFF2090EBAE80F0013F033 +:10313000010F18BFFB1A43F00103184788A60100CE +:10314000B8A601000A4410F8014B14F00F0508BF9F +:1031500010F8015B240908BF10F8014B6D1E05D063 +:1031600010F8013B6D1E01F8013BF9D1641E03D03C +:10317000641E01F8015BFBD19142E4D3704700006B +:10318000103A24BF78C878C1FAD8520724BF30C893 +:1031900030C144BF04680C60704700000023002465 +:1031A00000250026103A28BF78C1FBD8520728BF57 +:1031B00030C148BF0B6070471FB51AF09CFA00F091 +:1031C00031F88DE80F001FBDF0B440464946524625 +:1031D0005B460FB402A0013001B50648004700BFAE +:1031E00001BC86460FBC8046894692469B46F0BC91 +:1031F00070470000093100008269034981614FF086 +:1032000001001044704700000D32000001B41EB4EC +:1032100000B501F0E0FE01B40198864601BC01B0A2 +:103220001EBD00001AF0A6B910B504460021012009 +:1032300000F034F80021182000F030F800210B20B5 +:1032400000F02CF80221192000F028F802210D20AE +:1032500000F024F802210E2000F020F802210F20B7 +:1032600000F01CF80221C81F00F018F803211620F6 +:1032700000F014F80321152000F010F8204600F0AB +:103280001FF8002010BD68210180704700F028B8A9 +:103290000A48704700F02CB8704770474907090E7C +:1032A000002806DA00F00F0000F1E02080F8141D7D +:1032B000704700F1E02080F80014704703F90043E4 +:1032C00070B5304C054608202070A01CFFF7DBFFCE +:1032D0005920A08029462046BDE8704000F0C5BBBB +:1032E00010B500F0CCFB27490020891E087010BDE6 +:1032F0002DE9F041234E0446B61E0D4630780127D5 +:1033000038B1A4F160000B280AD8204600F024FF51 +:103310002DE0602CF9D043F201000860BDE8F08197 +:10332000A4F16C00032803D8204600F050FF1EE0F3 +:10333000A4F170001F2803D8204600F041F916E0E0 +:10334000A4F190000F2803D8204600F0EEF80EE01C +:10335000A4F1A0000F2803D8204600F079F806E079 +:10336000A4F1B0000F2804D8204600F0E2F928604C +:1033700000E02F60602CD1D128680028CED13770B2 +:10338000CCE700001A0000204FF0E0214FF400408D +:10339000C1F8800124490020087024494FF0607072 +:1033A0000860704770B5204D04462878A0421CBFC5 +:1033B000002C002803D01EA14C201AF0AAF828786F +:1033C000A04208BF70BD2C701E49184A00200CB3E3 +:1033D0001D4DDFF878C0131F012C07D0022C0FD031 +:1033E000BDE8704012A167201AF093B8086002206F +:1033F0000860CCF800504FF040701060186070BD4D +:10340000086003200860CCF800504FF40000106002 +:10341000186070BD086008604FF06070106070BD8B +:1034200003A170201AF075B82000002008F50140B3 +:103430007372635C68616C5F63636D5F6161722E60 +:103440006300000000F500408801002014F50040F2 +:1034500030B4A0380B2865D2DFE800F0060D161F47 +:10346000273039404A515B00D1E90132087830BC3D +:10347000194603F06CB988888A6883B2088830BC22 +:1034800080B2194603F073B9D1E9022308884C6869 +:1034900080B2214630BC03F06BB9D1E90132088813 +:1034A00030BC80B2194603F07EB988888A6883B23E +:1034B000088830BC80B2194603F08AB988888A68C7 +:1034C00083B2088830BC80B2194603F0C8B90888B6 +:1034D0004A6830BC80B2114603F00DBA088982B246 +:1034E000888883B2088830BC80B2194603F00DBAD0 +:1034F00008884A6830BC80B2114603F02CBA0889AB +:103500004C6882B20888CB68214630BC80B203F098 +:1035100090BAD1E9022308884C6880B2214630BCB9 +:1035200003F08DBB30BC012070479038092845D28C +:10353000DFE800F0050D13191F262F373D0088889E +:103540008A6883B20888194680B204F0B3B8088844 +:103550004A6880B2114604F0F0B808884A6880B220 +:10356000114604F0F8B808884A6880B2114604F0A1 +:1035700000B9D1E901320888194680B204F00EB9C9 +:10358000088982B2888883B20888194680B204F01C +:103590000AB908894B6882B20888194680B204F0DB +:1035A00023B908884A6880B2114604F02EB9888889 +:1035B00082B20888114680B204F088B901207047B1 +:1035C00030B470381B287DD2DFE800F00E141820CC +:1035D00024272E353A3F43474B535960697179840C +:1035E0008B93989C9FA6A90008784A6830BC114626 +:1035F00007F025BC086830BC07F070BC0C790B7B69 +:103600008A680868214630BC07F078BC086830BC7E +:1036100007F009BD30BC07F056B908884A6830BCCD +:1036200080B2114607F027BE08880A7930BC80B204 +:10363000114607F0BEBE087830BC40B207F0C9BEE4 +:10364000088830BC80B207F0DFBE086830BC07F0E5 +:10365000EDBE086830BC01F011BC086830BC01F058 +:103660003DBC088982B2D1E9000330BC194607F09D +:10367000FFBED1E9000230BC114607F04ABF0888FE +:103680004A6830BC80B2114609F011BAD1E9022370 +:103690000C790888214630BC80B209F0D0BA08887D +:1036A0000B798A6830BC80B2194609F07BBCD1E93D +:1036B0000132088830BC80B2194609F0EBBCD1E970 +:1036C000022300E032E008884C6880B2214630BC1A +:1036D00009F046BD08884A6830BC80B2114609F03E +:1036E0007ABD08880A7A0B7930BC80B2194607F097 +:1036F00031BF088830BC80B207F02FBF086830BCEB +:1037000007F030BF30BC07F0BFB8D1E900038A68CA +:1037100030BC194607F08EBF30BC07F09EB8088851 +:103720004A6830BC80B2114608F055B830BC012060 +:103730007047B02805D0B12807D0B22809D00120A1 +:103740007047088880B20AF035B9088880B20AF05C +:1037500050B9D1E901320888194680B20AF05AB945 +:103760000A280ED2DFE800F005070509090B0B0552 +:10377000050507F0D0B809F0FFBE01F060BA06F009 +:103780002DBAFEA140F2E22019F0C3BE7FB5FF4979 +:103790000646FF4AD1E90001CDE901014FF49860E6 +:1037A000ADF80C000F230A21A2F128000AF02FFE29 +:1037B0000024AFF253000AF04BFE641CE4B20A2C62 +:1037C000F7D304200090F24801231A4603A9F030F1 +:1037D0000AF031FA20B1E9A14FF4AD7019F099FE69 +:1037E000EC4C002075682070EB4920462844486066 +:1037F000E01C20F00300A04204D0E8A14FF4977031 +:1038000019F087FEA8B20422214604F09CFC20B1E6 +:10381000E2A14FF4A07019F07CFE00211E220846A0 +:1038200004F0A0F807F0CCFA02222421DF4801F0CE +:103830008DFBDE4801222C214C3001F087FBDB4957 +:103840000B20B03901F006FA20B1CCA14FF4B770CB +:1038500019F05FFE09F062FE02F045F901AB0022AB +:103860000821D3A007F06AF920B1C4A14FF4BA70BF +:1038700019F04FFE304602F06EFC20B1BFA14FF4AC +:10388000BB7019F046FE4FF45B71CC4819F00DFE89 +:10389000CA4801214171022181710621C1717FBD98 +:1038A00010B5C64CA078092804D3B4A14FF4D77042 +:1038B00019F02FFE207800EB400004EB401010F8C8 +:1038C0000C1F21F0FF010170417821F00701C91C94 +:1038D00021F0180141700121E17010BD70B50D4655 +:1038E000002114461980072828D2DFE800F02704B9 +:1038F0000B191227200021462846BDE870401A46C1 +:1039000009F05BBE21462846BDE870401A4606F025 +:1039100041BE21462846BDE870401A4601F08CBFE2 +:1039200021462846BDE870401A4603F003BD2146F3 +:103930002846BDE870401A4600F0D1BB8FA140F286 +:103940000D2019F0E6FD032070BD70B59B4CE078AA +:10395000002819D02078002500EB400004EB40102F +:10396000407B00F0070001190879401E087120789B +:10397000401CC0B22070092800D12570A078401CDE +:10398000A0700AF015FFE57070BD8C48C079002862 +:1039900000D085E7704770B5884DA86860B1FFF723 +:1039A000F4FF002860D06022A96819F02AFDFFF713 +:1039B000CCFF0020A860F0E76879002854D0FFF71A +:1039C0006FFF044679484C3001F0D0FA606020B9AE +:1039D0006AA14FF44B7019F09CFD60680AF0AAF8D8 +:1039E00068B1204606F0AEFC6078010703D520F0F0 +:1039F0000700401C29E06D4861684C302BE06B48A3 +:103A000061684C3001F0BBFA00F01EFB00282BD19E +:103A1000FFF746FF0446654801F0A8FA606020B948 +:103A200056A140F24F3019F074FD60680AF084F836 +:103A3000A0B1606800886080204609F0F3FD6078DE +:103A4000010706D520F00700801C6070FFF77DFF9E +:103A5000A3E75648616801F092FA9EE76168BDE805 +:103A60007040524801F08BBA70BD10B54A4CC4E9A1 +:103A70000201AFF2DD0000F0E2FB607010BD4649CC +:103A800000200870704730B505464FF080500C4656 +:103A9000D0F8A41095B0491C05D1D0F8A810C9439E +:103AA0000904090C08D050F8A01F01F00101297089 +:103AB00041682160806812E02B208DF8000009A980 +:103AC00068460AF00FF820B12CA14FF4197019F0D4 +:103AD00020FD012028700A982060BDF82C00A080ED +:103AE0002878002803D0607940F0C000607115B0DC +:103AF00030BDF0B54FF080540746D4F8800095B043 +:103B00000D462B26401C0BD1D4F88400401C07D155 +:103B1000D4F88800401C03D1D4F88C00401C0BD092 +:103B2000D4F880003860D4F884007860D4F8880035 +:103B3000B860D4F88C001EE08DF82C6069460BA8A4 +:103B400009F0D0FF20B10DA140F28D2019F0E1FC69 +:103B500001983860029878608DF82C6069460BA84F +:103B600009F0C0FF20B105A14FF4257019F0D1FC78 +:103B70000198B8600298F86022E000007372635CFC +:103B8000686F73745F636F72652E630000D7010006 +:103B9000DC01002000220020240000207372635CFE +:103BA000686F73745F636F72652E6300A80B0020EB +:103BB0006E52463531383232000000008C0700204A +:103BC000D4F89000401C0BD1D4F89400401C07D1CD +:103BD000D4F89800401C03D1D4F89C00401C08D0B5 +:103BE00054F8900F286060686860A068A860E0687A +:103BF00020E08DF8006009A9684609F073FF28B13C +:103C0000AFF2880140F2B22019F083FC0A982860D4 +:103C10000B9868608DF8006009A9684609F062FF9A +:103C200028B1AFF2A80140F2B92019F072FC0A984D +:103C3000A8600B98E86015B0F0BD70B5F84C05466B +:103C4000A06828B1AFF2CC014FF4427019F061FCCA +:103C5000A56070BD10B50146F24801F090F9F04939 +:103C60008879401CC0B28871012805D1EE4840789F +:103C7000BDE8104000F005BB10BD70B50446A1F5CD +:103C80007F4016460D46FF3805D1AFF2101140F2C5 +:103C90007D3019F03EFC012E07D0AFF22011BDE8B7 +:103CA00070404FF4637019F034BC207820F00F009E +:103CB000801D20F0F0006030207000202072A5816F +:103CC0000120A07370BD70B515460C460646FFF77F +:103CD0005CFE90B1017821F00F01891D21F0F00107 +:103CE0006031017046800121017221680161A18863 +:103CF00081820573BDE8704027E63046BDE870401C +:103D0000132107F056BBC8494968884201D21020E8 +:103D10007047032101700020704770B5C24C054602 +:103D200094B02078002610B1082014B070BDBF4AAE +:103D30006260954201D21020F7E7686848B1092116 +:103D4000D82804D3C31C23F00303834205D00846BC +:103D5000EBE74FF4C06068600DE0B549891A4FF099 +:103D60008052D2F80C2101EB8221A1F50061814241 +:103D700001D20421EBE700F053FF6178A0680CF05A +:103D800048FCE068401E07280BD830218DF8001051 +:103D90008DF8020068460EF018F810B109A80CF072 +:103DA000F3FD2846FFF7F2FC012020703046BCE707 +:103DB0002DE9F05FDFF870B204460F46DBF804002F +:103DC000814207D30CB1844204D3E01C20F00300ED +:103DD000A04202D01020BDE8F09F91484FF00008AB +:103DE000817899B14178824601EB410100EB4115A0 +:103DF000B7F8009015F80C0F3B4600F00F000022BA +:103E00002946FFF76BFD060004D013E0A7F80080F9 +:103E10000520E0E794B13988494501D90C260DE029 +:103E200028783B4600F00F0022462946FFF756FD52 +:103E3000060005D00C2E01D0A7F800803046CAE756 +:103E40009AF801005446401CC0B28AF801000928C3 +:103E500001D184F80180A078401EA070687800F03D +:103E60000701012910D0022908D003291CD0AFF284 +:103E7000F42140F2294019F04CFBDFE7C006DDD405 +:103E80006868FFF7E7FED9E7664869684C3001F0DB +:103E900076F86079401CC0B260710128CED19BF8E1 +:103EA000010000F0EEF9C9E7E079401C8AF807004C +:103EB000C4E7604A904208D35B4AB0F5802F52684D +:103EC00001D3904201D3914201D21020704700F0FB +:103ED000F8BE584B10B5994208D3534BB1F5802F1B +:103EE0005B6801D3994201D39A4201D2102010BDE0 +:103EF000022803D0102801D0092010BD00F006FFD1 +:103F00000028FAD0052010BD4A4B10B598420BD3BB +:103F1000454BB0F5802F5B6801D3984204D399429A +:103F200002D31AB19A4201D2102010BD00F00DFF49 +:103F30000028FAD0072010BD10B504463A4894B0C6 +:103F40004068844202D2102014B010BD0F208DF8BA +:103F5000000009A9684609F0C5FD0028F4D19DF8C4 +:103F60002C002070BDF82E006080BDF83000A080CD +:103F70000020E9E751B12C4A5268914202D30B6804 +:103F8000934201D2102070478A880AB101F008BE1E +:103F90000920704710B5274A94B091420ED3224AA7 +:103FA0004FF480239942526801D3914206D3441EB4 +:103FB0001E2C25D8994203D3914201D21020C3E789 +:103FC00001281BD108784FF0000410F0010F03D036 +:103FD00003208DF8020001E08DF8024038208DF8B2 +:103FE000000009A9684609F07DFD28B1AFF25441EF +:103FF00040F2272019F08DFA2046A5E70720A3E715 +:10400000A0F120021F2AF9D814B0BDE8104006F034 +:1040100019BE054A526891420ED210207047000026 +:104020008C070020A80B0020240000200022002084 +:104030000000002000F00100A0F120021F2A01D89A +:1040400006F07ABE0720E9E7F0B595B03B208DF881 +:104050002C0069460BA809F045FD28B1AFF2C44118 +:104060004FF4C47019F055FA43F2040600246D466B +:104070002FE02F19B87DC10706D0400704D405EB07 +:104080004400C08809F0F3FB32488079F8B1B87D6C +:1040900080071CD505EB44000022C088062109F0EA +:1040A00003FCA0B13C208DF82C0005EB44006946D0 +:1040B000C088ADF82E000BA809F014FD06000CD046 +:1040C000AFF2285140F29D1019F023FA05E0641C6C +:1040D000E4B29DF80400A042CBD83046ABE52DE910 +:1040E000F04105460C4600270078062190463E46E2 +:1040F000B1EB101F05D0AFF25C514FF4E37019F033 +:1041000008FA287A80B1012815D0AFF2705140F238 +:10411000E71019F0FEF900BFA8F800600CB1278085 +:1041200066800020BDE8F081022709267CB1A889BD +:10413000A080A87B09E00327142644B16888A080EA +:104140002869E060A88A2082287B2072E4E7A8F82A +:104150000060E6E78C07002060380A2835D2DFE8E7 +:1041600000F005080D10151B21242A2F0868FFF701 +:10417000D4BDD1E900021146FFF71ABE0868FFF767 +:10418000C2BDD1E900021146FFF793BED1E9013269 +:1041900008781946FFF79DBED1E900038A681946E1 +:1041A000FFF7B2BE0868FFF7C7BE08884A6880B24A +:1041B0001146FFF7DFBED1E900021146FFF7EABE64 +:1041C000D1E900021146FFF724BF0120704701200A +:1041D000704700000E4A12680C498A420AD11847FB +:1041E0000B4A1268094B9A4204D101B500F0EAFE6D +:1041F00003BC8E460749096809580847064807491D +:10420000054A064B7047000000000000BEBAFECA17 +:104210006400002004000020F0210020F021002094 +:104220004FF0E0214FF00070C1F88001C1F880022A +:10423000394B402283F80024C1F80001704710B5C3 +:1042400002460420354903E001EBC0031B7943B16A +:10425000401EC0B2F8D232A1432019F05AF9FF2013 +:1042600010BD41F8302001EBC00100224A718A7173 +:1042700001220A7110BD294A002102EBC000017120 +:10428000704710B50446042803D325A1522019F025 +:1042900040F9224800EBC4042079012803D020A172 +:1042A000532019F036F96079A179401CC0B28142DF +:1042B00000D060714FF0E0214FF00070C1F80002B3 +:1042C00010BD70B51448042590F80004134E400941 +:1042D000194C02281BD012A1692019F01AF916E016 +:1042E000217806EBC1000279012A08D1427983794D +:1042F0009A4204D04279827156F831008047207882 +:10430000401CC0B22070042801D3002020706D1E14 +:10431000EDB2E5D270BD000019E000E0240C0020F1 +:104320007372635C736F635F7369676E616C6C69F2 +:104330006E672E63000000003400002010B5EFF31C +:10434000108000F0010472B6D0484178491C4170D9 +:104350004078012801D10AF053FA002C00D162B64E +:1043600010BD70B5C94CE07848B90125E570FFF77C +:10437000E5FF0AF04DFA20B100200AF020FA0020F3 +:1043800070BD4FF08040A571C0F80453F7E770B5D9 +:10439000EFF3108000F0010572B6BC4C607818B9DC +:1043A000BBA1912019F0B5F86078401E607060786C +:1043B00008B90AF029FA002D00D162B670BDB348E1 +:1043C00010B5C17821B100218171C170FFF7DFFF05 +:1043D000002010BD10B504460AF01AFAAB49C9789E +:1043E000084000D001202060002010BD2DE9F05FC2 +:1043F0000026A64C08210422102320270125B046C0 +:10440000E6714FF0020A0D282CD2DFE800F0070910 +:104410000C0E101214161F2124262800657126E0A8 +:1044200084F805A023E0627121E061711FE06371EF +:104430001DE067711BE0012619E0FFF77FFF00BF59 +:104440000AF0E6F90028FBD0022610E0627100E0D5 +:104450006171E5710BE06371FBE76771F9E740207B +:104460006071F6E78AA140F2651019F052F80AF07F +:10447000DCF948B10AF0E0F9B04205D130460AF063 +:10448000DFF90028FAD032E04FF08047FD60C7F82E +:10449000048183490E60C7F804A3BD60C7F810818A +:1044A000DFF800B2DBF80010C94341F3001101F15D +:1044B0000109DBF8001041F01001CBF8001000E01A +:1044C00020BFD7F804010028FAD030460AF0B8F926 +:1044D0000028FAD0B9F1000F05D1DBF8001021F067 +:1044E0001001CBF80010C7F808A3C7F80481E079E1 +:1044F00060B10AF08DF907460AF0DAF86FF0004172 +:1045000017B1C4E9021001E0C4E902011EB184F848 +:104510000480BDE8F09F2571BDE8F05F00F094B81D +:1045200010B504460AF07AF928B158490120C8703C +:104530004A78521C4A702046BDE8104056E72DE9E3 +:10454000F0414FF08045D5F808010026012803D13D +:10455000C5F808610AF033F9D5F80401012801D142 +:10456000C5F80461D5F800010127484C01280ED197 +:10457000C5F80061A07918B100200AF020F9A671F1 +:10458000207820B10AF044F908B12F61A770207992 +:1045900030B3D5F81001012824D1C5F810616F613E +:1045A000E079B0B10AF034F980460AF081F8B8F148 +:1045B000000F01D0E16800E0A168411A022902DA87 +:1045C00011F1020F0EDCB8F1000F01D0E06000E045 +:1045D000A060FFF7B3FE0AF01BF910B12F61A770BE +:1045E00000E02770D5F80C0101280ED1A07818B989 +:1045F00027A1F12018F08DFFC5F80C612A4800684A +:10460000A6702670BDE8F041C1E6BDE8F08170B546 +:104610001E4DE87808B90AF0F7F801208407A06178 +:10462000A87850B1D4F80C0120B900200AF008F99C +:104630000028F7D10020C4F80C014FF0FF30C4F877 +:1046400008031A48006870BD2DE9F0411927BC071E +:10465000C4F808734FF00008C4F80081C4F80C8156 +:104660000AF0D6F8094E012510B12561B57000E0B9 +:104670003570FFF763FEC4F804730949707920317F +:104680000860A561C4F810816561BEE738000020AC +:104690007372635C736F635F636C6F636B2E630035 +:1046A0001805004010ED00E00C0100400803004038 +:1046B00010B50D2000F06DF8C4B26FF0040000F0EA +:1046C00068F8C0B2844203D039A11B2018F021FF42 +:1046D0003C490120086010BD70B50D2000F043F882 +:1046E000394C0020C4F800010125C4F804530D2002 +:1046F00000F044F825604FF0E0216014C1F800019B +:1047000070BD10B50D2000F02EF82F48012141603A +:104710000021C0F800112D480068BDE810400D20B0 +:1047200000F02CB82849D1F80001012803D020A1BD +:104730005E2018F0EEBE2348001D00680022C0B2C3 +:10474000C1F800212149096809F0C3BC10B51E4811 +:10475000D0F800110029FBD0FFF7E4FFBDE81040BE +:104760000D2000F00BB800F01F020121914040091C +:10477000800000F1E020C0F88011704700F01F02B7 +:10478000012191404009800000F1E020C0F8801232 +:104790007047002806DA00F00F0000F1E02090F8E2 +:1047A000140D03E000F1E02090F800044009704788 +:1047B0007372635C736F635F68616C5F726E672EA8 +:1047C0006300000004D5004000D0004000D100404C +:1047D00030B44FF0E0204FF400644FF0010C0021A2 +:1047E000C0F88041E510C0F880516303C0F8803103 +:1047F000E34A82F80014D21E82F80014E14A82F8DB +:104800000014E14AC2F804C0C2F808C0C2F840115E +:10481000C2F84411C2F84811DC490968C0F8804266 +:10482000C0F88052C0F88032C0F80041C0F80031B2 +:10483000C2F800C030BC704770B401204FF0E023D4 +:10484000C6024FF0000CC3F880610402C3F8804137 +:104850000506C3F88051CC4A50609060CC4801688E +:104860000029FCD1C2F840C1C2F844C1C2F848C115 +:10487000C6480068C3F88062C3F88042C3F880521B +:1048800070BC70474FF0E0204FF40061C0F8801218 +:10489000C910C0F880127047002804BFBD48704797 +:1048A000012804BFBC487047022804BFB7487047BE +:1048B00010B59120B9A118F02CFE002010BDB2490E +:1048C000002238B1012825D002282FD0B3A1BF2063 +:1048D00018F01FBE4FF48030C1F80803C1F8480338 +:1048E000B54B1A60C1F84021B4490968B44BC10303 +:1048F0001960B449C1F808034FF0E0230012C3F86F +:104900008001B1480260C1F84021C1F80022AF48DF +:10491000027070474FF40030C1F80803C1F8480333 +:10492000AB480260C1F844219B480AE04FF4802064 +:10493000C1F80803C1F84803A6480260C1F848213D +:10494000924800687047F0B4DFF83CC204260025A6 +:10495000012440B101283FD0022857D0F0BC8FA1DC +:10496000F42018F0D6BD881E20F07F414FF480302F +:10497000CCF80803CCF84051CCF84403CCF84015EF +:10498000012B14BF00210121904B59708D494C60BF +:10499000CC60DFF844C2CCF80050904D4FF0020CD0 +:1049A000C5F800C0DFF838C2CCF80060DFF818C2E4 +:1049B0003D32CCF80020C1F800424FF0E02C8A15BF +:1049C000CCF88022C1F80403CCF800210804854902 +:1049D00008601C70F0BC704783484FF40032012B14 +:1049E0000AD100BFC0F84051CCF80423CCF84423CE +:1049F000C0F84015F0BC7047CCF80823C0F840510F +:104A0000CCF84423C0F84015F0BC704777484FF409 +:104A10008022012BF0D1E5E75D480068704770B552 +:104A2000594CD4F84001002501280AD1D4F80803D4 +:104A300010F4803F05D04FF48030C4F80803C4F868 +:104A40004051D4F8440101280DD1D4F8080310F4E2 +:104A5000003F08D04FF40030C4F80803C4F84451B4 +:104A600001200AF0CCFFD4F8480101280DD1D4F878 +:104A7000080310F4802F08D04FF48020C4F80803F6 +:104A8000C4F8485102200AF0BAFF4048006870BDDF +:104A90004E490878E0B14A4A4FF000401060494A58 +:104AA000C00BC2F8080303124FF0E02C0020CCF832 +:104AB0008031454B1860C2F84001C2F8000208700E +:104AC0004A78002A08BF7047487000200AF097BF54 +:104AD00003200AF094BF4FF0E0214FF08070C1F83E +:104AE000000270474FF0E0214FF08070C1F8800263 +:104AF00070474FF0E0214FF40010C1F800027047FA +:104B00004FF0E0214FF40010C1F8800270472D48AB +:104B100001214160C1604FF0E0218015C1F88002A1 +:104B20007047410A43F609525143C0F3080010FB95 +:104B300002F000F5807001EB50207047430B48F203 +:104B4000376C03FB0CF31B0C4FEA432CC1F800C07D +:104B5000DFF89CC003FB0C0326484CF2F72C5843AB +:104B6000400D10FB0CFC0CEB432303F580735B1230 +:104B700013700A681044086070470BF045B80000D5 +:104B80000BE000E018E000E000B0004048B1004059 +:104B900004B500404081004044B100407372635C42 +:104BA00072656D5F68616C5F6576656E745F746970 +:104BB0006D65722E6300000040B5004040B10040BA +:104BC00008F501400080004040850040480000207A +:104BD00044B5004048B500400485004008850040C9 +:104BE0001085004004F5014004B0004008B00040CA +:104BF000F7C2FFFF6F0C010010B50AF0EAFF10BD0D +:104C0000002005490860012001218140034A430931 +:104C100042F8231000BF7047FC1F004080E200E014 +:104C200010B50DF0EDF909F094F9FEF7ADFB0FF0BA +:104C30004FFB0EF0ADF8BDE810400EF02FB870B588 +:104C40000C46054603F0E2F921462846BDE87040CF +:104C50000FF06FB870B50D46040011D085B1210179 +:104C6000284618F000FC10224F49284618F084FB13 +:104C70004D4801210838018044804560002070BD06 +:104C8000012070BD70B5484E00240546083E10E076 +:104C90007068AA7B00EB0410817B914208D1C17B34 +:104CA000EA7B914204D10C22294618F039FB30B13D +:104CB000641C30888442EBDB4FF0FF3070BD20462F +:104CC00070BD70B50D46060009D045B1364C083CA4 +:104CD00020886188401C884203D9042070BD1020C0 +:104CE00070BD3046FFF7CEFF002801DB401C0AE014 +:104CF00021886068102200EB0110314618F03CFB5F +:104D00002088401C20802870002070BD70B514469B +:104D10000D0018D0BCB10021A170022802D01028CB +:104D200011D105E0288870B10121A170108008E040 +:104D30002846FFF7A7FF002805DB401CA070A889C4 +:104D40002080002070BD012070BD70B5054614465E +:104D50000E000BD000203070A878012808D005D9AB +:104D60001149A1F108010A8890420AD9012070BDB9 +:104D700024B1287820702888000A5070022008701A +:104D80000FE064B14968102201EB00112046103990 +:104D900018F0F2FA287820732888000A607310202F +:104DA0003070002070BD000054000020654988422A +:104DB00006D3B0F5802F05D363490968884201D234 +:104DC000102070470146012005F074B830B593B04B +:104DD000044600200D460090142101A818F065FB40 +:104DE0001C2108A818F061FB9DF80000CDF808D040 +:104DF00020F00F00401C20F0F00010308DF8000073 +:104E00009DF8010006AA20F0FF008DF801009DF832 +:104E1000200001A940F002008DF8200001208DF84B +:104E2000460042F60420ADF8440011A80190208805 +:104E3000ADF83C006088ADF83E00A088ADF84000B9 +:104E4000E088ADF842009DF8020020F00600801CCA +:104E500020F001008DF802000820ADF80C00ADF83C +:104E600010000FA8059008A800F02AFF002803D121 +:104E7000BDF818002880002013B030BD3EB50446B0 +:104E80000820ADF800002F48844206D3B4F5802FE7 +:104E900005D32D480068844201D210203EBD214632 +:104EA000012005F007F80028F8D12088ADF80400AB +:104EB0006088ADF80600A088ADF80800E088ADF87D +:104EC0000A0005F038FE01AB6A46002101F03CFB08 +:104ED000BDF800100829E1D003203EBD1FB50446EF +:104EE000002002900820ADF808001648CDF80CD03C +:104EF000844206D3B4F5802F06D313480068844259 +:104F000002D2102004B010BD05F015FE014602AA21 +:104F10004FF6FF7001F0A3FC0028F3D1BDF8081094 +:104F2000082901D00320EDE7BDF800102180BDF86D +:104F300002106180BDF80410A180BDF80610E18068 +:104F4000E0E7000000F001002800002010B5031D7C +:104F500003600020521E04E05C181C60401C2346C5 +:104F6000C0B29042F8DB0020186010BD024600205D +:104F70001168002902D0084609681160704702686C +:104F80000A6001607047000010B501462022094800 +:104F900018F0F2F907490020C877084610BD064905 +:104FA000012008600548064A0168914201D10021AC +:104FB00001607047B40E002014050040640000201A +:104FC000BEBAFECA0C4908784A78401CC0B290426A +:104FD00000D00870704708484FF0E02220BF40BF63 +:104FE00020BF417803784370D2F8003213B90378B8 +:104FF0008B42F3D0002070476B0000207047704751 +:1050000010FFFFFFDBE5B15100F001006800FFFF7A +:1050100040F2090CC2F2000C6047000018B1817820 +:1050200001293CD101E010207047018842F60213AB +:10503000C81A4FF48072994233D01CDC42F6010347 +:10504000A1EB030099422CD00CDCF9B1B1F5C05FA3 +:1050500027D06FF4C050081823D0A0F57060FF3837 +:105060001DD11EE001281CD002281AD0FF2818D01C +:10507000904214D115E0904213D008DC012810D0E2 +:1050800002280ED0FE280CD0FF2808D109E0A0F598 +:105090008070013805D0012803D0022801D00020FB +:1050A00070470F2070470B2826D008DC1BD2DFE8A2 +:1050B00000F01C2025251A25292325271E0011284C +:1050C0001CD008DC0C2817D00D281DD00F2815D0B7 +:1050D000102808D110E0822809D0842810D0852813 +:1050E00010D0872812D00320704700207047052079 +:1050F000704743F203007047072070470F20704746 +:1051000004207047062070470C2070474FF4505021 +:10511000704730B551B1A1F201158123CCB2112DE8 +:105120001CD2012805D0022808D00AE00020107007 +:105130001DE0A1F5807003381BD002E0B1F5817F3E +:1051400017D0112D15D2DFE805F014111114111428 +:10515000141114141411111111141100A1F5C070BF +:105160001F2803D9A1F2FD11022902D814700020D2 +:1051700030BD1370072030BD06280CD2DFE800F0E8 +:105180000305030B07090020704711207047072013 +:1051900070470820704703207047007810F00F0216 +:1051A00004D0012A05D0022A0AD10EE0000907D155 +:1051B00008E00009012805D0022803D0032801D007 +:1051C000072070470870002070470620704738B1EC +:1051D000012809D002280FD0032815D007207047D6 +:1051E000087820F0FF0016E0087820F00F00401C3F +:1051F00020F0F00010300EE0087820F00F00401C86 +:1052000020F0F000203006E0087820F00F00401C6D +:1052100020F0F000303008700020704738B50C46A0 +:10522000050041D06946FFF7B8FF002819D19DF865 +:105230000010208861F38B2020806946681CFFF7EE +:10524000ACFF00280DD19DF80010208861F30D30CF +:105250002080A978C1F34101012903D0022904D09B +:10526000072038BD20F0200001E040F02000208021 +:1052700080B210F4406F04D0A978C90861F38E3071 +:10528000208080B210F4405F07D0A978090961F34B +:10529000CF30208010F4405F02D12088400403D535 +:1052A000208840F040002080002038BD70B50446C2 +:1052B0000020088015466068FFF7B0FF002816D16F +:1052C0002089A189884211D860688078C0070AD0F7 +:1052D000B1F5007F0AD840F20120B1FBF0F200FBEB +:1052E0001210288007E0B1F5FF7F01D90C2070BDB6 +:1052F00001F201212980002070BD10B504781378D7 +:1053000064F3000313700478640864F341031370BA +:105310000478A40864F3820313700478E40864F347 +:10532000C30313700478240964F30413137004781E +:10533000640964F3451313700078800960F38613E1 +:10534000137031B10878C10701D1800701D5012060 +:1053500000E0002060F3C713137010BD028812F440 +:10536000406F02D0C2F3812306E012F4405F02D006 +:10537000C2F3013300E001230A8863F38B220A8021 +:10538000008810F4405F02D0C0F3013006E010F452 +:10539000406F02D0C0F3812000E0012060F30D32A5 +:1053A0000A8070472DE9F04792B00D00804613D077 +:1053B000B8F1000F14D01221284618F054F803AAAF +:1053C000FF21012003F04BF80024264637464FF416 +:1053D00020596FF4205A6DE0102012B0BDE8F0871C +:1053E0000720FAE79DF8160001280AD1BDF814003D +:1053F00048450BD010EB0A000AD001280CD0022837 +:105400000CD0042C0ED0052C0FD10DE0012400E0AF +:105410000224BDF8126008E0032406E00424BDF86D +:10542000127002E0052400E00624BDF81210414588 +:1054300040D12C7486B34FF005090DF134080EAA43 +:10544000CDF80090CDE9012810230022FF2130463D +:1054500003F0A1F8F0B9BDF834002A46C0B20EA995 +:10546000FFF754FCB0B9AE81B7B108AECDF80090EB +:10547000CDE9016813230022FF21384603F08BF8A1 +:1054800040B9BDF83400F11CC01EC0B22A1DFFF7A0 +:105490003DFC10B10320A0E70AE0BDF82100E8813F +:1054A000062C05D19DF81600A872BDF814002881BD +:1054B000002092E703A802F0DAFF002892D0FFF75D +:1054C000F2FD8AE7002805D0FE4A012903D002290F +:1054D00003D003207047518800E09188814201D1B8 +:1054E000002070470720704770B50C4605461C2108 +:1054F000204617F0B8FF0020208055B1012D06D0BE +:10550000BDE87040F0A140F26F2018F002B806200C +:1055100000E00520A07070BD70B592B00646012075 +:105520008DF814008DF808008DF8153001F1080091 +:10553000CDE9030248881546ADF81800FEF725FAB4 +:10554000040018D065801720ADF80400009496F888 +:1055500021100DF12A0301AA02A80EF004FA064652 +:105560006078000701D5FEF7F0F956B13046FFF735 +:1055700003FE12B070BD1321284605F01AFF032068 +:10558000F7E708A80090BDF804300422012128465E +:1055900007F0ABFEEDE770B506468AB000200D4679 +:1055A000059005240490069003A900940790CDE986 +:1055B0000101024610232946304602F0ECFF68B98B +:1055C00004A9009108A8CDE90140BDF80C300022E3 +:1055D0002946304602F0F0FD002801D0FFF763FDB8 +:1055E0000AB070BD0EF0B3BB2DE9FC47054600279D +:1055F00000780C46B846B9460C286FD2DFE800F0B8 +:10560000FF060B360A6F6F95B5F7C8D768680A387A +:10561000FEF720FBF8E0A888002280B28146042132 +:1056200008F04CFB064624B1A7A140F2DD2017F09C +:1056300070FF26B9A4A140F2DE2017F06AFF4946A8 +:1056400006F108000DF019FEFEF79FF9040008D0DE +:10565000607840F008006070A4F80290FEF775F9D9 +:10566000D3E01321484605F0A4FEE2E024B996A158 +:105670004FF43D7017F04DFF60880022042108F0C0 +:105680001DFB060004D190A140F2F72017F041FF66 +:10569000A6F80090002029791DE000BF05EBC002AC +:1056A000128992B2130707D5D30605D505EBC100C1 +:1056B00030F8020C308006E052040AD5307105EB58 +:1056C000C000C08870806078022740F008006070D9 +:1056D0009AE0401CC0B28142E0D895E08FE0E888B3 +:1056E000ADF8000024B978A140F2073017F011FF9F +:1056F0002878062814D1BDF80000000410D5608871 +:105700000022042108F0DAFA060004D16EA140F26A +:10571000113017F0FEFE86F80490A888708035E0FE +:10572000607840F0080060706EE024B966A140F235 +:10573000233017F0EEFE60880022042108F0BEFA44 +:10574000060004D160A140F2263017F0E2FE06F117 +:1057500008000EF050FB90F0010F02D1E888000421 +:1057600052D560880227F080DAE724B956A140F2CA +:105770003F3017F0CEFE60880022042108F09EFA28 +:1057800020B951A140F2423017F0C3FE0227C7E70B +:1057900024B94DA140F24B3017F0BBFE02276188BF +:1057A00001222046FEF769FA4FF00108B8E7A88900 +:1057B000002280B28146042108F080FA064624B116 +:1057C00041A140F25D3017F0A4FE26B93EA140F29F +:1057D0005E3017F09EFE686800902889ADF80400DE +:1057E000012269464846FEF76EFA0DE0FFE7002CFD +:1057F00096D135A14FF45A7017F08BFE90E732A185 +:1058000040F26D3017F085FE9CB16078000710D52E +:10581000B8F1000F0DD12078582220F00F00001DA4 +:1058200020F0F00080302070294604F1080017F0C5 +:10583000E8FD3846BDE8FC872DE9FE4F05460C46DD +:10584000007A0A31029104F10C010191904600277F +:105850001631821E3E464FF0020B4FF0010A0091B6 +:10586000082A7DD2DFE802F0F5047C43438CCFF4B4 +:1058700068880022042108F021FA5FEA000904D1B7 +:1058800011A140F2863017F044FEB9F8000010B1C3 +:105890005227072601E151271E26002C6FD0688869 +:1058A000A08084F806A099F80400029905EBC000D6 +:1058B000C089FFF777FD00287DD199F8040005EB3A +:1058C000C0000BE0440C00207372635C6761747469 +:1058D000735F636F72652E6300000000C0892081D2 +:1058E00099F8040005EBC000408AA083F4E0B5F805 +:1058F0001290062821D1E88900041ED5512709F10C +:10590000220086B2002CC9D0A8890199FFF74AFD70 +:10591000002876D16888A08084F806B0A889208104 +:1059200084F80AA0288AE083A4F820904A4669698E +:10593000DDF8000017F020FDCEE0502709F120002F +:1059400086B2002CAAD0A8890299FFF72BFD002867 +:1059500057D16888A080A889E080287A062800E0CE +:10596000B4E00AD002202072288AA083A4F81E90F6 +:105970004A4604F120006969DCE70120F3E790E082 +:1059800068880022042108F099F9B5F812A05FEAAE +:10599000000905D1AFF2D00140F2EE3017F0B9FDA9 +:1059A00009F108000EF027FA90F0010F02D1E88902 +:1059B000000425D500E024E00AF12200512786B238 +:1059C000002C77D06888A080A8890199FFF7EAFCAD +:1059D000002816D184F806B0A88920810420A0727E +:1059E000288AE083A4F820A052466969009817F03D +:1059F000C3FC002089F80400A989A9F802106BE013 +:105A00000320BDE8FE8F688804F0AEF982466888FE +:105A10000022042108F052F98146BAF1000F05D1A5 +:105A2000AFF25C1140F21A4017F073FDB9F1000FAC +:105A300005D1AFF26C1140F21B4017F06AFDB9F8C6 +:105A40000600A0F57F41FF3904D05127222603E04C +:105A50001CE032E0502720261CB36888A080502F1D +:105A600007D084F806B0287B04F10801FFF73CFD5D +:105A700032E0287BA11DFFF737FD6A8800234946E5 +:105A80005046FFF749FD0028BBD125E0FE49A88913 +:105A9000C988814206D15427062614B16888A0809F +:105AA0001AE007E05327082624B16888A080A88957 +:105AB000E08011E0A8F8006013E055270726002CCD +:105AC000F8D0A889A0800020A07105E0AFF20821DD +:105AD0004FF48D6017F01DFDA8F800600CB1278011 +:105AE000668000208DE7E84900200870704730B5D7 +:105AF00085B00C4601F079F90546FF2805D1AFF2D3 +:105B0000382140F2834017F004FD002020802071EE +:105B100060804FF6FF70E080294604F108000DF028 +:105B2000A0FB6A462946012002F099FC16E000BF5E +:105B3000BDF80400000711D5BDF806002946FFF79F +:105B40002AFDBDF80400FF2340F01000ADF804006A +:105B5000BDF806002946019A02F0B2FD684602F03F +:105B600086FC0028E4D005B030BD0A46014602F1AB +:105B700008000DF088BB70B505460022042108F02E +:105B80009DF8040005D1AFF2C02140F2A54017F006 +:105B9000C0FC294604F10800BDE870400DF06DBB63 +:105BA000F0B591B00C46074604F0DEF8050005D0CC +:105BB0002878222805D2082011B0F0BD43F2020057 +:105BC000FAE700220421384608F078F806460CB1BE +:105BD000A08870B101208DF8040002208DF810001B +:105BE00000208DF8110034B1A088ADF818002068AD +:105BF00003E00920E0E7ADF81800059006F1080081 +:105C0000CDE90207FDF7C1FE040017D06780172019 +:105C1000ADF81C00009495F821100DF12A0307AA95 +:105C200001A80DF0A0FE05466078000701D5FDF73C +:105C30008CFE4DB12846FFF79FFABDE71321384689 +:105C400005F0B7FB0320B7E708A80090BDF81C30AB +:105C500004220121384607F048FB4FF6FF71F1801E +:105C6000AAE72DE9FF5F83460E9E98469146778806 +:105C70008A46384604F078F8054600220421384662 +:105C800008F01CF804462DB9AFF2C43140F20C50B4 +:105C900017F03FFC2CB9AFF2D03140F20D5017F0A5 +:105CA00038FC0834CDE90274CDE9008695F821105E +:105CB0004B46524658460DF013FB04B0BDE8F09F2A +:105CC0002DE9F04F9BB00D464FF000096E49ADF83D +:105CD0001490ADF81890ADF81C90A1F80490ADF8B0 +:105CE0000C90ADF810900446ADF82490ADF82090DB +:105CF00008781646CB46012809D0022807D0032889 +:105D000005D0042803D008201BB0BDE8F08F5F4801 +:105D100084425FD35E4F4FF480229442396801D3AE +:105D20008C4257D38046454554D39246554501D3BE +:105D30008D424FD3606878B140454BD3504501D375 +:105D4000884247D360892189884202D8B1F5007F13 +:105D500001D90C20D8E781460CAA04A92846FFF7F0 +:105D6000A5FA0028D0D168688078C0F341000228E5 +:105D700009D1BDF8100010F4405F04D0286910B1BB +:105D80003968884226D303A92069FFF747FA00281B +:105D9000BAD1206948B160788007BDF80C0000F4E2 +:105DA000405001D5F0B300E0E0BBBDF80C00810627 +:105DB00012D510F4405F606804D068B13968884239 +:105DC00008D300E040B1404504D3504504D33968BE +:105DD000884201D2102097E708A96069FFF71EFAF0 +:105DE000002891D1606940B1BDF82000C0F3812145 +:105DF000012937D110F4405F34D009A9A069FFF719 +:105E00000DFA002880D1BDF8200080062AD4BDF804 +:105E10002400810626D4A16941B1C0F38121012962 +:105E200020D100E01EE010F4405F1BD0E06818B104 +:105E30000078B8B11C2815D20DAA611C2046FFF7C6 +:105E40005CFA01278DF84A7042F60300DA46ADF895 +:105E500048004FF4806B0DF1370215A92868FEF752 +:105E600074FF08B107204FE79DF8540014A9C01C27 +:105E7000CDF800A0CDE901A100F0FF08002308F251 +:105E80000122594612A805E0440C002000F0010050 +:105E90002800002002F02DFA30BBBDF850000A9017 +:105EA000FD492A8928690092CDE901016B89BDF875 +:105EB00030202868049902F01CFA01007ED1DFF836 +:105EC000D8B35546ABF1040B0521BBF80400ADF87F +:105ED00035000DA88DE8230043460022FF21BDF8C0 +:105EE000500002F069F910B1FFF7DDF80CE79DF8FA +:105EF00034004FF0020A01064FF48060804622D53C +:105F000001468DF84A704FF42450ADF84800ADF8C2 +:105F10004C5062789DF84C00002362F300008DF82D +:105F20004C006278CDF800A0520862F341008DF871 +:105F30004C0013AACDE9012540F2032212A802F079 +:105F4000D8F901003AD1606840B3206960B903A96B +:105F500004A8FFF703FA6078800705D4BDF80C00A9 +:105F600020F44050ADF80C008DF84A7042F6011054 +:105F7000ADF84800208940F20121B0FBF1F201FBAD +:105F80001202606807ABCDF80090CDE90103002351 +:105F900012A8039902F0ADF901000FD12078C106D3 +:105FA00001D480062CD5ADF82C50606968B908A9D9 +:105FB00004A8FFF7D3F9BDF8200000E077E020F453 +:105FC000406000F58060ADF82000BDF8200006A913 +:105FD00040F0C800ADF820008DF84A7042F602107B +:105FE000ADF848000BAACDF800A0CDE901210023AF +:105FF00040F2032212A8089902F07BF9010056D161 +:00000001FF diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/key.pem b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/key.pem new file mode 100644 index 0000000..84fdffc --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEID2WUBCe/4kLhl5ekJ+O8PtprcahUNFE3RIm5htQzDedoAoGCCqGSM49 +AwEHoUQDQgAEZY2i7duYH2l9rnIg1oIXq+0/uHAF7IoFubVru6oX9GCQm67NrXIm +wgS2ErZi/0/MvRsMkIQQkNg6Wc2tbJgdTA== +-----END EC PRIVATE KEY----- diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_dfu_transport_serial.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_dfu_transport_serial.py new file mode 100644 index 0000000..2f9c4e8 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_dfu_transport_serial.py @@ -0,0 +1,136 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import logging +import os +import unittest + +# Nordic Semiconductor imports +import sys +from nordicsemi.dfu.dfu_transport import DfuEvent +from nordicsemi.dfu import crc16 +from nordicsemi.dfu.init_packet import PacketField, Packet +from nordicsemi.dfu.model import HexType +from nordicsemi.dfu.dfu_transport_serial import DfuTransportSerial + + +def setup_logging(): + root = logging.getLogger() + root.setLevel(logging.DEBUG) + + ch = logging.StreamHandler(sys.stdout) + ch.setLevel(logging.DEBUG) + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + ch.setFormatter(formatter) + root.addHandler(ch) + + +@unittest.skip('Ignoring these tests since they take too much time to run.') +class TestDfuTransportSerial(unittest.TestCase): + DEVKEY_PORT = "NORDICSEMI_PCA10028_1_PORT" + + def setUp(self): + setup_logging() + + # Assert that environment variables are setUp before starting tests. + # TODO: create generic functionality for fetching environment variables that map + # TODO: communication ports to PCA versions + # TODO: setup target nRF5X device to a given state (bootloader+sd+application) + if self.DEVKEY_PORT not in os.environ: + self.fail("Environment variable {0} not found. " + "Must specify serial port with development kit connected." + .format(self.DEVKEY_PORT)) + + self.transport = DfuTransportSerial(os.environ[self.DEVKEY_PORT], + baud_rate=38400, + flow_control=True) + + def tearDown(self): + if self.transport and self.transport.is_open(): + self.transport.close() + + def test_open_close(self): + self.transport.open() + self.assertTrue(self.transport.is_open()) + self.transport.close() + self.assertFalse(self.transport.is_open()) + + def test_dfu_methods(self): + def timeout_callback(log_message): + logging.debug("timeout_callback. Message: %s", log_message) + + def progress_callback(progress, log_message, done): + logging.debug("Log message: %s, Progress: %d, done: %s", log_message, progress, done) + + def error_callback(log_message=""): + logging.error("Log message: %s", log_message) + + self.transport.register_events_callback(DfuEvent.TIMEOUT_EVENT, timeout_callback) + self.transport.register_events_callback(DfuEvent.PROGRESS_EVENT, progress_callback) + self.transport.register_events_callback(DfuEvent.ERROR_EVENT, error_callback()) + + firmware = '' + test_firmware_path = os.path.join("firmwares", "pca10028_nrf51422_xxac_blinky.bin") + + with open(test_firmware_path, 'rb') as f: + while True: + data = f.read() + + if data: + firmware += data + else: + break + + crc = crc16.calc_crc16(firmware, 0xffff) + + self.transport.open() + + # Sending start DFU command to target + self.transport.send_start_dfu(HexType.APPLICATION, + app_size=len(firmware), + softdevice_size=0, + bootloader_size=0) + + # Sending DFU init packet to target + init_packet_vars = { + PacketField.DEVICE_TYPE: 1, + PacketField.DEVICE_REVISION: 2, + PacketField.APP_VERSION: 0xfffa, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [0x005a], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16: crc + } + pkt = Packet(init_packet_vars) + self.transport.send_init_packet(pkt.generate_packet()) + + # Sending firmware to target + self.transport.send_firmware(firmware) + + # Validating firmware + self.transport.send_validate_firmware() + self.transport.send_activate_firmware() + self.transport.close() diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_init_packet.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_init_packet.py new file mode 100644 index 0000000..eaef3ec --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_init_packet.py @@ -0,0 +1,123 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest +from nordicsemi.dfu.init_packet import * + + +class TestInitPacket(unittest.TestCase): + def setUp(self): + pass + + def test_generate_packet_a(self): + init_packet_vars = { + PacketField.DEVICE_TYPE: 1, + PacketField.DEVICE_REVISION: 2, + PacketField.APP_VERSION: 3, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [1111, 2222, 3333, 4444], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID: 2, + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH: + "\xc9\xd3\xbfi\xf2\x1e\x88\xa01\x1e\r\xd2BSa\x12\xf8BW\x9b\xef&Z$\xbd\x02U\xfdD?u\x9e", + PacketField.NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS: + '1\xd7B8\x129\xaa\xc3\xe6\x8b\xe2\x01\xd11\x17\x01\x00\xae\x1e\x04\xf9~q\xcd\xbfv"\xdan\xc0f2\xd49' + + '\xdc\xc7\xf8\xae\x16VV\x17\x90\xa3\x96\xadxPa\x0bs\xfe\xbdi]\xb2\x95\x81\x99\xe4\xb0\xcf\xe9\xda' + } + + ip = Packet(init_packet_vars) + data = ip.generate_packet() + self.assertEqual(data, ("\x01\x00" # Device type + "\x02\x00" # Device revision + "\x03\x00\x00\x00" # App version + "\x04\x00" # Softdevice array length + "\x57\x04" # Softdevice entry #1 + "\xae\x08" # Softdevice entry #2 + "\x05\x0d" # Softdevice entry #3 + "\x5c\x11" # Softdevice entry #4 + "\x02\x00\x00\x00" # ext packet id + "\xc9\xd3\xbfi\xf2\x1e\x88\xa01\x1e\r\xd2BSa\x12" # Firmware hash, part one + "\xf8BW\x9b\xef&Z$\xbd\x02U\xfdD?u\x9e" # Firmware hash, part two + '1\xd7B8\x129\xaa\xc3\xe6\x8b\xe2\x01\xd11\x17\x01' # Init packet ECDS, part 1 + '\x00\xae\x1e\x04\xf9~q\xcd\xbfv"\xdan\xc0f2\xd49' # Init packet ECDS, part 2 + '\xdc\xc7\xf8\xae\x16VV\x17\x90\xa3\x96\xadxPa\x0b' # Init packet ECDS, part 3 + 's\xfe\xbdi]\xb2\x95\x81\x99\xe4\xb0\xcf\xe9\xda' # Init packet ECDS, part 4 + ) + ) + + def test_generate_packet_b(self): + init_packet_vars = { + PacketField.DEVICE_TYPE: 1, + PacketField.DEVICE_REVISION: 2, + PacketField.APP_VERSION: 0xffeeffee, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [1111, 2222, 3333], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID: 1, + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH: + "\xc9\xd3\xbfi\xf2\x1e\x88\xa01\x1e\r\xd2BSa\x12\xf8BW\x9b\xef&Z$\xbd\x02U\xfdD?u\x9e" + } + + ip = Packet(init_packet_vars) + data = ip.generate_packet() + self.assertEqual(data, ("\x01\x00" # Device type + "\x02\x00" # Device revision + "\xee\xff\xee\xff" # App version + "\x03\x00" # Softdevice array length + "\x57\x04" # Softdevice entry #1 + "\xae\x08" # Softdevice entry #2 + "\x05\x0d" # Softdevice entry #3 + "\x01\x00\x00\x00" # ext packet id + "\xc9\xd3\xbfi\xf2\x1e\x88\xa01\x1e\r\xd2BSa\x12" # Firmware hash, part one + "\xf8BW\x9b\xef&Z$\xbd\x02U\xfdD?u\x9e" # Firmware hash, part two + ) + ) + + def test_generate_packet_c(self): + init_packet_vars = { + PacketField.DEVICE_TYPE: 1, + PacketField.DEVICE_REVISION: 2, + PacketField.APP_VERSION: 0xffeeffee, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [1111, 2222, 3333], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID: 0, + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16: 0xfaae + } + + ip = Packet(init_packet_vars) + data = ip.generate_packet() + self.assertEqual(data, ("\x01\x00" # Device type + "\x02\x00" # Device revision + "\xee\xff\xee\xff" # App version + "\x03\x00" # Softdevice array length + "\x57\x04" # Softdevice entry #1 + "\xae\x08" # Softdevice entry #2 + "\x05\x0d" # Softdevice entry #3 + "\x00\x00\x00\x00" # ext packet id + "\xae\xfa" # CRC-16 checksum for firmware + ) + ) + + +if __name__ == '__main__': + unittest.main() diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_manifest.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_manifest.py new file mode 100644 index 0000000..f2755fe --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_manifest.py @@ -0,0 +1,201 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import copy +import json +import unittest + +from nordicsemi.dfu.init_packet import PacketField +from nordicsemi.dfu.manifest import ManifestGenerator, Manifest +from nordicsemi.dfu.model import HexType +from nordicsemi.dfu.package import FirmwareKeys + + +class TestManifest(unittest.TestCase): + def setUp(self): + self.firmwares_data_a = {} + + init_packet_data_a = { + PacketField.DEVICE_TYPE: 1, + PacketField.DEVICE_REVISION: 2, + PacketField.APP_VERSION: 1000, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [22, 11], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID: 2, + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH: 1234, + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH: + '\xc9\xd3\xbfi\xf2\x1e\x88\xa01\x1e\r\xd2BSa\x12\xf8BW\x9b\xef&Z$\xbd\x02U\xfdD?u\x9e', + PacketField.NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS: + '1\xd7B8\x129\xaa\xc3\xe6\x8b\xe2\x01\xd11\x17\x01\x00\xae\x1e\x04\xf9~q\xcd\xbfv"\xdan\xc0f2\xd49' + + '\xdc\xc7\xf8\xae\x16VV\x17\x90\xa3\x96\xadxPa\x0bs\xfe\xbdi]\xb2\x95\x81\x99\xe4\xb0\xcf\xe9\xda' + } + + self.firmwares_data_a[HexType.APPLICATION] = { + FirmwareKeys.BIN_FILENAME: "app_fw.bin", + FirmwareKeys.DAT_FILENAME: "app_fw.dat", + FirmwareKeys.INIT_PACKET_DATA: init_packet_data_a, + FirmwareKeys.ENCRYPT: False} + + self.firmwares_data_a[HexType.SD_BL] = { + FirmwareKeys.BIN_FILENAME: "sd_bl_fw.bin", + FirmwareKeys.DAT_FILENAME: "sd_bl_fw.dat", + FirmwareKeys.INIT_PACKET_DATA: copy.copy(init_packet_data_a), # Fake the hash + FirmwareKeys.BL_SIZE: 50, + FirmwareKeys.SD_SIZE: 90 + } + + self.firmwares_data_b = {} + + init_packet_data_b = { + PacketField.DEVICE_TYPE: 1, + PacketField.DEVICE_REVISION: 2, + PacketField.APP_VERSION: 1000, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [22, 11], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16: 0xfaae + } + + self.firmwares_data_b[HexType.APPLICATION] = { + FirmwareKeys.BIN_FILENAME: "app_fw.bin", + FirmwareKeys.DAT_FILENAME: "app_fw.dat", + FirmwareKeys.INIT_PACKET_DATA: init_packet_data_b + } + + self.firmwares_data_b[HexType.BOOTLOADER] = { + FirmwareKeys.BIN_FILENAME: "bootloader_fw.bin", + FirmwareKeys.DAT_FILENAME: "bootloader_fw.dat", + FirmwareKeys.INIT_PACKET_DATA: copy.copy(init_packet_data_b), # Fake the hash + } + + self.firmwares_data_c = {} + + init_packet_data_c = { + PacketField.DEVICE_TYPE: 1, + PacketField.DEVICE_REVISION: 2, + PacketField.APP_VERSION: 1000, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [22, 11], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16: 0xfaae + } + + self.firmwares_data_c[HexType.SOFTDEVICE] = { + FirmwareKeys.BIN_FILENAME: "softdevice_fw.bin", + FirmwareKeys.DAT_FILENAME: "softdevice_fw.dat", + FirmwareKeys.INIT_PACKET_DATA: init_packet_data_c + } + + def test_generate_manifest(self): + r = ManifestGenerator(0.5, self.firmwares_data_a) + + _json = json.loads(r.generate_manifest()) + + # Test for presence of attributes in document + self.assertIn('manifest', _json) + + manifest = _json['manifest'] + self.assertIn('application', manifest) + + application = manifest['application'] + self.assertIn('init_packet_data', application) + self.assertIn('dat_file', application) + self.assertIn('bin_file', application) + + init_packet_data = application['init_packet_data'] + self.assertIn('firmware_hash', init_packet_data) + self.assertIn('softdevice_req', init_packet_data) + self.assertIn('device_revision', init_packet_data) + self.assertIn('device_type', init_packet_data) + self.assertIn('application_version', init_packet_data) + + # Test for values in document + self.assertEqual("app_fw.bin", application['bin_file']) + self.assertEqual("app_fw.dat", application['dat_file']) + + self.assertEqual(2, init_packet_data['ext_packet_id']) + self.assertEqual(1234, init_packet_data['firmware_length']) + self.assertEqual('c9d3bf69f21e88a0311e0dd242536112f842579bef265a24bd0255fd443f759e', + init_packet_data['firmware_hash']) + self.assertEqual('31d742381239aac3e68be201d131170100ae1e04f97e71cdbf7622da6ec06632d439dcc7f8ae1656561790a396ad7850610b73febd695db2958199e4b0cfe9da', + init_packet_data['init_packet_ecds']) + self.assertEqual(1000, init_packet_data['application_version']) + self.assertEqual(1, init_packet_data['device_type']) + self.assertEqual(2, init_packet_data['device_revision']) + self.assertEqual([22, 11], init_packet_data['softdevice_req']) + + # Test softdevice_bootloader + bl_sd = manifest['softdevice_bootloader'] + self.assertIsNotNone(bl_sd) + self.assertEqual(90, bl_sd['sd_size']) + self.assertEqual(50, bl_sd['bl_size']) + + # Test for values in document + self.assertEqual("sd_bl_fw.bin", bl_sd['bin_file']) + self.assertEqual("sd_bl_fw.dat", bl_sd['dat_file']) + + def test_manifest_a(self): + r = ManifestGenerator(0.5, self.firmwares_data_a) + m = Manifest.from_json(r.generate_manifest()) + self.assertIsNotNone(m) + self.assertIsNotNone(m.application) + self.assertEqual("app_fw.bin", m.application.bin_file) + self.assertEqual("app_fw.dat", m.application.dat_file) + self.assertIsNone(m.bootloader) + self.assertIsNone(m.softdevice) + self.assertIsNotNone(m.softdevice_bootloader) + self.assertEqual(90, m.softdevice_bootloader.sd_size) + self.assertEqual(50, m.softdevice_bootloader.bl_size) + self.assertEqual("sd_bl_fw.bin", m.softdevice_bootloader.bin_file) + self.assertEqual("sd_bl_fw.dat", m.softdevice_bootloader.dat_file) + + def test_manifest_b(self): + r = ManifestGenerator("0.5", self.firmwares_data_b) + m = Manifest.from_json(r.generate_manifest()) + self.assertIsNotNone(m) + self.assertIsNotNone(m.application) + self.assertEqual("app_fw.bin", m.application.bin_file) + self.assertEqual("app_fw.dat", m.application.dat_file) + self.assertIsNotNone(m.bootloader) + self.assertEqual("bootloader_fw.bin", m.bootloader.bin_file) + self.assertEqual("bootloader_fw.dat", m.bootloader.dat_file) + self.assertIsNone(m.softdevice) + self.assertIsNone(m.softdevice_bootloader) + self.assertEqual(0xfaae, m.application.init_packet_data.firmware_crc16) + self.assertEqual(0xfaae, m.bootloader.init_packet_data.firmware_crc16) + + + def test_manifest_c(self): + r = ManifestGenerator("0.5", self.firmwares_data_c) + m = Manifest.from_json(r.generate_manifest()) + self.assertIsNotNone(m) + self.assertIsNone(m.application) + self.assertIsNone(m.bootloader) + self.assertIsNotNone(m.softdevice) + self.assertEqual('softdevice_fw.bin', m.softdevice.bin_file) + self.assertEqual('softdevice_fw.dat', m.softdevice.dat_file) + self.assertIsNone(m.softdevice_bootloader) + self.assertEqual(0xfaae, m.softdevice.init_packet_data.firmware_crc16) + +if __name__ == '__main__': + unittest.main() diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_nrfhex.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_nrfhex.py new file mode 100644 index 0000000..e2f2f2d --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_nrfhex.py @@ -0,0 +1,134 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os + +import unittest +import nordicsemi.dfu.nrfhex as nrfhex +import nordicsemi.dfu.intelhex as intelhex + + +class TestnRFHex(unittest.TestCase): + def setUp(self): + script_abspath = os.path.abspath(__file__) + script_dirname = os.path.dirname(script_abspath) + os.chdir(script_dirname) + + def comparefiles(self, actual, wanted): + actualfile = intelhex.IntelHex() + actualfile.loadfile(actual, format="bin") + + wantedfile = intelhex.IntelHex() + wantedfile.loadfile(wanted, format="bin") + + self.assertEqual(actualfile.minaddr(), wantedfile.minaddr()) + self.assertEqual(actualfile.maxaddr(), wantedfile.maxaddr()) + + minaddress = actualfile.minaddr() + maxaddress = actualfile.maxaddr() + + length = maxaddress - minaddress + + actualfile_data = actualfile.gets(minaddress, length) + wantedfile_data = wantedfile.gets(minaddress, length) + + self.assertEqual(actualfile_data, wantedfile_data) + + def test_tobinfile_single_file_without_uicr_content(self): + nrf = nrfhex.nRFHex("firmwares/bar.hex") + nrf.tobinfile("firmwares/bar.bin") + + self.comparefiles("firmwares/bar.bin", "firmwares/bar_wanted.bin") + + def test_tobinfile_single_file_with_uicr_content(self): + nrf = nrfhex.nRFHex("firmwares/foo.hex") + nrf.tobinfile("firmwares/foo.bin") + + self.comparefiles("firmwares/foo.bin", "firmwares/foo_wanted.bin") + + def test_tobinfile_single_bin_file(self): + nrf = nrfhex.nRFHex("firmwares/bar_wanted.bin") + nrf.tobinfile("firmwares/bar.bin") + + self.comparefiles("firmwares/bar.bin", "firmwares/bar_wanted.bin") + + def test_tobinfile_two_hex_files(self): + nrf = nrfhex.nRFHex("firmwares/foo.hex", "firmwares/bar.hex") + nrf.tobinfile("firmwares/foobar.bin") + + self.comparefiles("firmwares/foobar.bin", "firmwares/foobar_wanted.bin") + + def test_tobinfile_one_hex_one_bin(self): + nrf = nrfhex.nRFHex("firmwares/foo_wanted.bin", "firmwares/bar.hex") + nrf.tobinfile("firmwares/foobar.bin") + + self.comparefiles("firmwares/foobar.bin", "firmwares/foobar_wanted.bin") + + def test_tobinfile_one_bin_one_hex(self): + nrf = nrfhex.nRFHex("firmwares/foo.hex", "firmwares/bar_wanted.bin") + nrf.tobinfile("firmwares/foobar.bin") + + self.comparefiles("firmwares/foobar.bin", "firmwares/foobar_wanted.bin") + + def test_tobinfile_two_bin(self): + nrf = nrfhex.nRFHex("firmwares/foo_wanted.bin", "firmwares/bar_wanted.bin") + nrf.tobinfile("firmwares/foobar.bin") + + self.comparefiles("firmwares/foobar.bin", "firmwares/foobar_wanted.bin") + + def test_sizes(self): + nrf = nrfhex.nRFHex("firmwares/foo.hex", "firmwares/bar.hex") + + self.assertEqual(nrf.get_mbr_end_address(), 0x1000) + self.assertEqual(nrf.minaddr(), 0x1000) + self.assertEqual(nrf.size(), 73152) + self.assertEqual(nrf.bootloadersize(), 13192) + + nrf = nrfhex.nRFHex("firmwares/s132_nrf52_mini.hex") + + self.assertEqual(nrf.get_mbr_end_address(), 0x3000) + self.assertEqual(nrf.minaddr(), 0x3000) + self.assertEqual(nrf.size(), 12288) + self.assertEqual(nrf.bootloadersize(), 0) + + def test_get_softdevice_variant(self): + nrf = nrfhex.nRFHex("firmwares/foo.hex") + + self.assertEqual(nrf.get_softdevice_variant(), "unknown") + + nrf = nrfhex.nRFHex("firmwares/s130_nrf51_mini.hex") + + self.assertEqual(nrf.get_softdevice_variant(), "s1x0") + + nrf = nrfhex.nRFHex("firmwares/s132_nrf52_mini.hex") + + self.assertEqual(nrf.get_softdevice_variant(), "s132") + + +if __name__ == '__main__': + unittest.main() diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_package.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_package.py new file mode 100644 index 0000000..36dbda0 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_package.py @@ -0,0 +1,164 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import json +import os +import tempfile +import unittest +from zipfile import ZipFile +import shutil + +from nordicsemi.dfu.package import Package + + +class TestPackage(unittest.TestCase): + def setUp(self): + self.work_directory = tempfile.mkdtemp(prefix="nrf_dfu_tests_") + + def tearDown(self): + shutil.rmtree(self.work_directory, ignore_errors=True) + + def test_generate_package_application(self): + self.p = Package( + dev_type=1, + dev_rev=2, + app_version=100, + sd_req=[0x1000, 0xfffe], + app_fw="firmwares/bar.hex" + ) + + pkg_name = "mypackage.zip" + + self.p.generate_package(pkg_name, preserve_work_directory=False) + expected_zip_content = ["manifest.json", "bar.bin", "bar.dat"] + + with ZipFile(pkg_name, 'r') as pkg: + infolist = pkg.infolist() + + for file_information in infolist: + self.assertTrue(file_information.filename in expected_zip_content) + self.assertGreater(file_information.file_size, 0) + + # Extract all and load json document to see if it is correct regarding to paths + pkg.extractall(self.work_directory) + + with open(os.path.join(self.work_directory, 'manifest.json'), 'r') as f: + _json = json.load(f) + self.assertEqual(u'bar.bin', _json['manifest']['application']['bin_file']) + self.assertEqual(u'bar.dat', _json['manifest']['application']['dat_file']) + self.assertTrue(u'softdevice' not in _json['manifest']) + self.assertTrue(u'softdevice_bootloader' not in _json['manifest']) + self.assertTrue(u'bootloader' not in _json['manifest']) + + def test_generate_package_sd_bl(self): + self.p = Package(dev_type=1, + dev_rev=2, + app_version=100, + sd_req=[0x1000, 0xfffe], + softdevice_fw="firmwares/foo.hex", + bootloader_fw="firmwares/bar.hex") + + pkg_name = "mypackage.zip" + + self.p.generate_package(pkg_name, preserve_work_directory=False) + + expected_zip_content = ["manifest.json", "sd_bl.bin", "sd_bl.dat"] + + with ZipFile(pkg_name, 'r') as pkg: + infolist = pkg.infolist() + + for file_information in infolist: + self.assertTrue(file_information.filename in expected_zip_content) + self.assertGreater(file_information.file_size, 0) + + # Extract all and load json document to see if it is correct regarding to paths + pkg.extractall(self.work_directory) + + with open(os.path.join(self.work_directory, 'manifest.json'), 'r') as f: + _json = json.load(f) + self.assertEqual(u'sd_bl.bin', _json['manifest']['softdevice_bootloader']['bin_file']) + self.assertEqual(u'sd_bl.dat', _json['manifest']['softdevice_bootloader']['dat_file']) + + def test_unpack_package_a(self): + self.p = Package(dev_type=1, + dev_rev=2, + app_version=100, + sd_req=[0x1000, 0xffff], + softdevice_fw="firmwares/bar.hex", + dfu_ver=0.6) + pkg_name = os.path.join(self.work_directory, "mypackage.zip") + self.p.generate_package(pkg_name, preserve_work_directory=False) + + unpacked_dir = os.path.join(self.work_directory, "unpacked") + manifest = self.p.unpack_package(os.path.join(self.work_directory, pkg_name), unpacked_dir) + self.assertIsNotNone(manifest) + self.assertEqual(u'bar.bin', manifest.softdevice.bin_file) + self.assertEqual(0, manifest.softdevice.init_packet_data.ext_packet_id) + self.assertIsNotNone(manifest.softdevice.init_packet_data.firmware_crc16) + + def test_unpack_package_b(self): + self.p = Package(dev_type=1, + dev_rev=2, + app_version=100, + sd_req=[0x1000, 0xffff], + softdevice_fw="firmwares/bar.hex", + dfu_ver=0.7) + pkg_name = os.path.join(self.work_directory, "mypackage.zip") + self.p.generate_package(pkg_name, preserve_work_directory=False) + + unpacked_dir = os.path.join(self.work_directory, "unpacked") + manifest = self.p.unpack_package(os.path.join(self.work_directory, pkg_name), unpacked_dir) + self.assertIsNotNone(manifest) + self.assertEqual(u'bar.bin', manifest.softdevice.bin_file) + self.assertEqual(1, manifest.softdevice.init_packet_data.ext_packet_id) + self.assertIsNone(manifest.softdevice.init_packet_data.firmware_crc16) + self.assertIsNotNone(manifest.softdevice.init_packet_data.firmware_hash) + + def test_unpack_package_c(self): + self.p = Package(dev_type=1, + dev_rev=2, + app_version=100, + sd_req=[0x1000, 0xffff], + softdevice_fw="firmwares/bar.hex", + key_file="key.pem") + pkg_name = os.path.join(self.work_directory, "mypackage.zip") + self.p.generate_package(pkg_name, preserve_work_directory=False) + + unpacked_dir = os.path.join(self.work_directory, "unpacked") + manifest = self.p.unpack_package(os.path.join(self.work_directory, pkg_name), unpacked_dir) + self.assertIsNotNone(manifest) + self.assertEqual(u'bar.bin', manifest.softdevice.bin_file) + self.assertEqual(2, manifest.softdevice.init_packet_data.ext_packet_id) + self.assertIsNone(manifest.softdevice.init_packet_data.firmware_crc16) + self.assertIsNotNone(manifest.softdevice.init_packet_data.firmware_hash) + self.assertIsNotNone(manifest.softdevice.init_packet_data.init_packet_ecds) + self.assertEqual(manifest.dfu_version, 0.8) + + +if __name__ == '__main__': + unittest.main() diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_signing.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_signing.py new file mode 100644 index 0000000..3b19fb0 --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/tests/test_signing.py @@ -0,0 +1,155 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import binascii +import os +import shutil +import tempfile +import unittest + +from nordicsemi.dfu.signing import Signing +from nordicsemi.dfu.init_packet import Packet, PacketField + + +class TestSinging(unittest.TestCase): + def setUp(self): + script_abspath = os.path.abspath(__file__) + script_dirname = os.path.dirname(script_abspath) + os.chdir(script_dirname) + + def test_gen_key(self): + self.work_directory = tempfile.mkdtemp(prefix="nrf_signing_tests_") + + key_file_name = 'key.pem' + key_file_path = os.path.join(self.work_directory, key_file_name) + + signing = Signing() + signing.gen_key(key_file_path) + + self.assertTrue(os.path.exists(key_file_path)) + + shutil.rmtree(self.work_directory, ignore_errors=True) + + def test_load_key(self): + key_file_name = 'key.pem' + + signing = Signing() + signing.load_key(key_file_name) + + self.assertEqual(64, len(binascii.hexlify(signing.sk.to_string()))) + + def test_sign_and_verify(self): + key_file_name = 'key.pem' + + signing = Signing() + signing.load_key(key_file_name) + + init_packet_fields = { + PacketField.DEVICE_TYPE: 0xFFFF, + PacketField.DEVICE_REVISION: 0xFFFF, + PacketField.APP_VERSION: 0xFFFFFFFF, + PacketField.REQUIRED_SOFTDEVICES_ARRAY: [0xFFFE], + PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID: 2, + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH: 1234, + PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH: + '\xc9\xd3\xbfi\xf2\x1e\x88\xa01\x1e\r\xd2BSa\x12\xf8BW\x9b\xef&Z$\xbd\x02U\xfdD?u\x9e', + } + init_packet = Packet(init_packet_fields) + init_packet_data = init_packet.generate_packet() + + signature = signing.sign(init_packet_data) + + self.assertTrue(signing.verify(init_packet_data, signature)) + + init_packet_fields[PacketField.NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS] = signature + + init_packet = Packet(init_packet_fields) + init_packet_data = init_packet.generate_packet() + + self.assertFalse(signing.verify(init_packet_data, signature)) + + def test_get_vk(self): + key_file_name = 'key.pem' + + signing = Signing() + signing.load_key(key_file_name) + + vk_str = signing.get_vk('hex') + vk_hex = signing.get_vk_hex() + self.assertEqual(vk_hex, vk_str) + + vk_str = signing.get_vk('code') + vk_code = signing.get_vk_code() + self.assertEqual(vk_code, vk_str) + + vk_str = signing.get_vk('pem') + vk_pem = signing.get_vk_pem() + self.assertEqual(vk_pem, vk_str) + + def test_get_vk_hex(self): + key_file_name = 'key.pem' + expected_vk_hex = "Verification key Qx: 658da2eddb981f697dae7220d68217abed3fb87005ec8a05b9b56bbbaa17f460\n" \ + "Verification key Qy: 909baecdad7226c204b612b662ff4fccbd1b0c90841090d83a59cdad6c981d4c" + + signing = Signing() + signing.load_key(key_file_name) + + vk_hex = signing.get_vk_hex() + + self.assertEqual(expected_vk_hex, vk_hex) + + def test_get_vk_code(self): + key_file_name = 'key.pem' + + expected_vk_code = "static uint8_t Qx[] = { 0x65, 0x8d, 0xa2, 0xed, 0xdb, 0x98, 0x1f, 0x69, 0x7d, " \ + "0xae, 0x72, 0x20, 0xd6, 0x82, 0x17, 0xab, 0xed, 0x3f, 0xb8, 0x70, 0x05, 0xec, " \ + "0x8a, 0x05, 0xb9, 0xb5, 0x6b, 0xbb, 0xaa, 0x17, 0xf4, 0x60 };\n" \ + "static uint8_t Qy[] = { 0x90, 0x9b, 0xae, 0xcd, 0xad, 0x72, 0x26, 0xc2, 0x04, " \ + "0xb6, 0x12, 0xb6, 0x62, 0xff, 0x4f, 0xcc, 0xbd, 0x1b, 0x0c, 0x90, 0x84, 0x10, " \ + "0x90, 0xd8, 0x3a, 0x59, 0xcd, 0xad, 0x6c, 0x98, 0x1d, 0x4c };" + + signing = Signing() + signing.load_key(key_file_name) + + vk_code = signing.get_vk_code() + + self.assertEqual(expected_vk_code, vk_code) + + def test_get_vk_pem(self): + key_file_name = 'key.pem' + expected_vk_pem = "-----BEGIN PUBLIC KEY-----\n" \ + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZY2i7duYH2l9rnIg1oIXq+0/uHAF\n" \ + "7IoFubVru6oX9GCQm67NrXImwgS2ErZi/0/MvRsMkIQQkNg6Wc2tbJgdTA==\n" \ + "-----END PUBLIC KEY-----\n" + + signing = Signing() + signing.load_key(key_file_name) + + vk_pem = signing.get_vk_pem() + + self.assertEqual(expected_vk_pem, vk_pem) diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/util.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/util.py new file mode 100644 index 0000000..a7040fb --- /dev/null +++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/util.py @@ -0,0 +1,179 @@ +# Copyright (c) 2015, Nordic Semiconductor +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Nordic Semiconductor ASA nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Nordic libraries +from nordicsemi.exceptions import NordicSemiException + + +# TODO: Create query function that maps query-result strings with functions +def query_func(question, default=False): + """ + Ask a string question + No input defaults to "no" which results in False + """ + valid = {"yes": True, "y": True, "no": False, "n": False} + if default is True: + prompt = " [Y/n]" + else: + prompt = " [y/N]" + + while True: + print "%s %s" % (question, prompt) + choice = raw_input().lower() + if choice == '': + return default + elif choice in valid: + return valid[choice] + else: + print "Please respond with y/n" + + +def convert_uint16_to_array(value): + """ + Converts a int to an array of 2 bytes (little endian) + + :param int value: int value to convert to list + :return list[int]: list with 2 bytes + """ + byte0 = value & 0xFF + byte1 = (value >> 8) & 0xFF + return [byte0, byte1] + + +def convert_uint32_to_array(value): + """ + Converts a int to an array of 4 bytes (little endian) + + :param int value: int value to convert to list + :return list[int]: list with 4 bytes + """ + byte0 = value & 0xFF + byte1 = (value >> 8) & 0xFF + byte2 = (value >> 16) & 0xFF + byte3 = (value >> 24) & 0xFF + return [byte0, byte1, byte2, byte3] + + +def slip_parts_to_four_bytes(seq, dip, rp, pkt_type, pkt_len): + """ + Creates a SLIP header. + + For a description of the SLIP header go to: + http://developer.nordicsemi.com/nRF51_SDK/doc/7.2.0/s110/html/a00093.html + + :param int seq: Packet sequence number + :param int dip: Data integrity check + :param int rp: Reliable packet + :param pkt_type: Payload packet + :param pkt_len: Packet length + :return: str with SLIP header + """ + ints = [0, 0, 0, 0] + ints[0] = seq | (((seq + 1) % 8) << 3) | (dip << 6) | (rp << 7) + ints[1] = pkt_type | ((pkt_len & 0x000F) << 4) + ints[2] = (pkt_len & 0x0FF0) >> 4 + ints[3] = (~(sum(ints[0:3])) + 1) & 0xFF + + return ''.join(chr(b) for b in ints) + + +def int32_to_bytes(value): + """ + Converts a int to a str with 4 bytes + + :param value: int value to convert + :return: str with 4 bytes + """ + ints = [0, 0, 0, 0] + ints[0] = (value & 0x000000FF) + ints[1] = (value & 0x0000FF00) >> 8 + ints[2] = (value & 0x00FF0000) >> 16 + ints[3] = (value & 0xFF000000) >> 24 + return ''.join(chr(b) for b in ints) + + +def int16_to_bytes(value): + """ + Converts a int to a str with 4 bytes + + :param value: int value to convert + :return: str with 4 bytes + """ + + ints = [0, 0] + ints[0] = (value & 0x00FF) + ints[1] = (value & 0xFF00) >> 8 + return ''.join(chr(b) for b in ints) + + +def slip_decode_esc_chars(data): + """Decode esc characters in a SLIP package. + + Replaces 0xDBDC with 0xCO and 0xDBDD with 0xDB. + + :return: str decoded data + :type str data: data to decode + """ + result = [] + while len(data): + char = data.pop(0) + if char == 0xDB: + char2 = data.pop(0) + if char2 == 0xDC: + result.append(0xC0) + elif char2 == 0xDD: + result.append(0xDB) + else: + raise NordicSemiException('Char 0xDB NOT followed by 0xDC or 0xDD') + else: + result.append(char) + return result + + +def slip_encode_esc_chars(data_in): + """Encode esc characters in a SLIP package. + + Replace 0xCO with 0xDBDC and 0xDB with 0xDBDD. + + :type str data_in: str to encode + :return: str with encoded packet + """ + result = [] + data = [] + for i in data_in: + data.append(ord(i)) + + while len(data): + char = data.pop(0) + if char == 0xC0: + result.extend([0xDB, 0xDC]) + elif char == 0xDB: + result.extend([0xDB, 0xDD]) + else: + result.append(char) + return ''.join(chr(i) for i in result) |