diff --git a/src/dcspy/aircraft.py b/src/dcspy/aircraft.py index a3a42031d..85e2d8c63 100644 --- a/src/dcspy/aircraft.py +++ b/src/dcspy/aircraft.py @@ -1,5 +1,6 @@ from __future__ import annotations +from collections import OrderedDict from collections.abc import Sequence from itertools import cycle from logging import getLogger @@ -7,6 +8,7 @@ from pprint import pformat from re import search from tempfile import gettempdir +from threading import Timer from typing import ClassVar try: @@ -17,10 +19,14 @@ from PIL import Image, ImageDraw, ImageFont from dcspy import default_yaml, load_yaml -from dcspy.models import (DEFAULT_FONT_NAME, NO_OF_LCD_SCREENSHOTS, AircraftKwargs, AnyButton, ApacheAllDrawModesKwargs, ApacheEufdMode, BiosValue, LcdButton, - LcdInfo, RequestModel, RequestType) +from dcspy.models import (DEFAULT_FONT_NAME, NO_OF_LCD_SCREENSHOTS, AircraftKwargs, AnyButton, ApacheAllDrawModesKwargs, ApacheEufdMode, BiosValue, EffectInfo, + LcdButton, LcdInfo, LedEffectType, LedSupport, RequestModel, RequestType) +from dcspy.sdk.led_sdk import LedSdkManager from dcspy.utils import KeyRequest, replace_symbols, substitute_symbols +# todo: to be removed +RED_PULSE = EffectInfo(type=LedEffectType.PULSE, rgb=(100, 0, 0), duration=0, interval=10) +YELLOW_PULSE = EffectInfo(type=LedEffectType.PULSE, rgb=(100, 100, 0), duration=0, interval=10) LOG = getLogger(__name__) @@ -63,6 +69,11 @@ def __init__(self, lcd_type: LcdInfo) -> None: self.lcd = lcd_type self.cfg = load_yaml(full_path=default_yaml) self.bios_data: dict[str, BiosValue] = {} + self.led = LedSdkManager(target_dev=LedSupport.LOGI_DEVICETYPE_RGB) # todo: do we need copy it here? + self.led_stack: dict[str, EffectInfo] = OrderedDict() + self.led_effect = True + self.led_counter = 16 + self.led_shutdown = Timer(3.2, self.led.logi_led_shutdown) if self.bios_name: self.key_req = KeyRequest(yaml_path=default_yaml.parent / f'{self.bios_name}.yaml', get_bios_fn=self.get_bios) self.bios_data.update(self.key_req.cycle_button_ctrl_name) @@ -101,6 +112,42 @@ def get_bios(self, selector: str, default: BiosValue = '') -> BiosValue: except (KeyError, ValueError): return default + def led_handler(self, selector: str, value: int, effect: EffectInfo) -> None: + """ + Switch on and off LED effect for DCS-BIOS selector. + + :param selector: + :param value: + :param effect: + """ + self.bios_data[selector] = value + if self.led_effect and not self.led_counter: + if value: + LOG.debug(f'LED on {selector} val: {value} with {effect}') + self.led.logi_led_shutdown() + self.led_counter = 16 + LOG.debug(f'Th: {self.led_shutdown}') + self.led_shutdown = Timer(3.2, self.led.logi_led_shutdown) + self.led_shutdown.start() + self.led.start_led_effect(effect=effect) + self.led_stack[selector] = effect + else: + LOG.debug(f'LED off {selector}') + self._popitem_and_reply_last_effect(selector) + else: + self.led_counter -= 1 + LOG.debug(f'Couter: {value} {self.led_counter}') + + def _popitem_and_reply_last_effect(self, selector: str) -> None: + del self.led_stack[selector] + if self.led_stack: + selector, effect = self.led_stack.popitem() + LOG.debug(f'Replay effect for {selector}') + value = int(self.bios_data[selector]) + self.led_handler(selector, value, effect) + else: + self.led.logi_led_shutdown() + def __repr__(self) -> str: return f'{super().__repr__()} with: {pformat(self.__dict__)}' diff --git a/src/dcspy/models.py b/src/dcspy/models.py index 71d152da6..fa3ab8be3 100644 --- a/src/dcspy/models.py +++ b/src/dcspy/models.py @@ -641,13 +641,33 @@ def make_empty(cls) -> GuiPlaneInputRequest: return cls(identifier='', request='', widget_iface='') -class LedConstants(Enum): - """LED constants.""" - LOGI_LED_DURATION_INFINITE = 0 +class LedSupport(Enum): + """LED supported types.""" + LOGI_DEVICETYPE_NONE = 0 LOGI_DEVICETYPE_MONOCHROME = 1 LOGI_DEVICETYPE_RGB = 2 LOGI_DEVICETYPE_ALL = 3 # LOGI_DEVICETYPE_MONOCHROME | LOGI_DEVICETYPE_RGB + def __str__(self) -> str: + return self.name.split('_')[-1] + + +class LedEffectType(Enum): + """LED effect type.""" + FLASH = 'flash' + PULSE = 'pulse' + NONE = 'none' + + def __str__(self) -> str: + return self.value + +# todo: rename it +class EffectInfo(BaseModel): + type: LedEffectType + rgb: tuple[int, int, int] # todo: think of conversion 0-255 -> 0-100% where to do it? + duration: int + interval: int + class LcdButton(Enum): """LCD Buttons.""" @@ -870,6 +890,8 @@ class LogitechDeviceModel(BaseModel): btn_m_range: tuple[int, int] = (0, 0) lcd_keys: Sequence[LcdButton] = () lcd_info: LcdInfo = NoneLcd + led_type: LedSupport = LedSupport.LOGI_DEVICETYPE_NONE + comments: str = '' def get_key_at(self, row: int, col: int) -> AnyButton | None: """ @@ -919,17 +941,15 @@ def cols(self) -> int: return max([self.no_g_modes, mouse_btn_exist, lcd_btn_exists]) def __str__(self) -> str: - result = [] - if self.lcd_info.type.value: - result.append(f'{self.lcd_info}') - if self.lcd_keys: - lcd_buttons = ', '.join([str(lcd_btn) for lcd_btn in self.lcd_keys]) - result.append(f'LCD Buttons: {lcd_buttons}') - if self.no_g_modes and self.no_g_keys: - result.append(f'G-Keys: {self.no_g_keys} in {self.no_g_modes} modes') - if self.btn_m_range[0] and self.btn_m_range[1]: - result.append(f'Mouse Buttons: {self.btn_m_range[0]} to {self.btn_m_range[1]}') - return '\n'.join(result) + details = [ + str(self.lcd_info) if self.lcd_info.type.value else None, + f"LCD Buttons: {', '.join(map(str, self.lcd_keys))}" if self.lcd_keys else None, + f"G-Keys: {self.no_g_keys} in {self.no_g_modes} modes" if self.no_g_modes and self.no_g_keys else None, + f"Mouse Buttons: {self.btn_m_range[0]} to {self.btn_m_range[1]}" if all(self.btn_m_range) else None, + f"LED support: {self.led_type}" if self.led_type.value else None, # todo: test this + f"Comments: {self.comments}" if self.comments else None, # todo: test this + ] + return '\n'.join(filter(None, details)) @property def g_keys(self) -> Sequence[Gkey]: @@ -960,23 +980,37 @@ def lcd_name(self) -> str: G19 = LogitechDeviceModel(klass='G19', no_g_modes=3, no_g_keys=12, lcd_info=LcdColor, - lcd_keys=(LcdButton.LEFT, LcdButton.RIGHT, LcdButton.OK, LcdButton.CANCEL, LcdButton.UP, LcdButton.DOWN, LcdButton.MENU)) + lcd_keys=(LcdButton.LEFT, LcdButton.RIGHT, LcdButton.OK, LcdButton.CANCEL, LcdButton.UP, LcdButton.DOWN, LcdButton.MENU), + led_type=LedSupport.LOGI_DEVICETYPE_RGB) G13 = LogitechDeviceModel(klass='G13', no_g_modes=3, no_g_keys=29, lcd_info=LcdMono, - lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR)) + lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR), + led_type=LedSupport.LOGI_DEVICETYPE_RGB) G15v1 = LogitechDeviceModel(klass='G15v1', no_g_modes=3, no_g_keys=18, lcd_info=LcdMono, - lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR)) + lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR), + led_type=LedSupport.LOGI_DEVICETYPE_MONOCHROME, + comments='Highest RGB given is <33%, the color will be off, if >33% and <66%, the ' + 'brightness will be low, and when >66%, the brightness will be high') # todo: make nicer descriptions G15v2 = LogitechDeviceModel(klass='G15v2', no_g_modes=3, no_g_keys=6, lcd_info=LcdMono, - lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR)) + lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR), + led_type=LedSupport.LOGI_DEVICETYPE_MONOCHROME, + comments='Highest RGB given is <33%, the color will be off, if >33% and <66%, the ' + 'brightness will be low, and when >66%, the brightness will be high') G510 = LogitechDeviceModel(klass='G510', no_g_modes=3, no_g_keys=18, lcd_info=LcdMono, - lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR)) + lcd_keys=(LcdButton.ONE, LcdButton.TWO, LcdButton.THREE, LcdButton.FOUR), + led_type=LedSupport.LOGI_DEVICETYPE_RGB) LCD_KEYBOARDS_DEV = [G19, G510, G15v1, G15v2, G13] -G910 = LogitechDeviceModel(klass='G910', no_g_modes=3, no_g_keys=9) -G710 = LogitechDeviceModel(klass='G710', no_g_modes=3, no_g_keys=6) -G110 = LogitechDeviceModel(klass='G110', no_g_modes=3, no_g_keys=12) +G910 = LogitechDeviceModel(klass='G910', no_g_modes=3, no_g_keys=9, led_type=LedSupport.LOGI_DEVICETYPE_RGB) +G710 = LogitechDeviceModel(klass='G710', no_g_modes=3, no_g_keys=6, led_type=LedSupport.LOGI_DEVICETYPE_MONOCHROME, + comments='Highest value for R, G or B defines brightness') +G110 = LogitechDeviceModel(klass='G110', no_g_modes=3, no_g_keys=12, led_type=LedSupport.LOGI_DEVICETYPE_RGB, + comments='green it will be ignored') G103 = LogitechDeviceModel(klass='G103', no_g_modes=3, no_g_keys=6) -G105 = LogitechDeviceModel(klass='G105', no_g_modes=3, no_g_keys=6) -G11 = LogitechDeviceModel(klass='G11', no_g_modes=3, no_g_keys=18) +G105 = LogitechDeviceModel(klass='G105', no_g_modes=3, no_g_keys=6, led_type=LedSupport.LOGI_DEVICETYPE_MONOCHROME, + comments='Highest value for R, G or B defines brightness') +G11 = LogitechDeviceModel(klass='G11', no_g_modes=3, no_g_keys=18, led_type=LedSupport.LOGI_DEVICETYPE_MONOCHROME, + comments='Highest RGB given is <33%, the color will be off, if >33% and <66%, the brightness ' + 'will be low, and when >66%, the brightness will be high') KEYBOARDS_DEV = [G910, G710, G110, G103, G105, G11] G35 = LogitechDeviceModel(klass='G35', no_g_modes=1, no_g_keys=3) @@ -985,8 +1019,9 @@ def lcd_name(self) -> str: G933 = LogitechDeviceModel(klass='G933', no_g_modes=1, no_g_keys=3) HEADPHONES_DEV = [G35, G633, G930, G933] -G600 = LogitechDeviceModel(klass='G600', btn_m_range=(6, 20)) -G300 = LogitechDeviceModel(klass='G300', btn_m_range=(6, 9)) +G600 = LogitechDeviceModel(klass='G600', btn_m_range=(6, 20), led_type=LedSupport.LOGI_DEVICETYPE_RGB) +G300 = LogitechDeviceModel(klass='G300', btn_m_range=(6, 9), led_type=LedSupport.LOGI_DEVICETYPE_RGB, + comments='When calling the LED, if <50%, the color will be off, and when >50%, the color will be on') G400 = LogitechDeviceModel(klass='G400', btn_m_range=(6, 8)) G700 = LogitechDeviceModel(klass='G700', btn_m_range=(1, 13)) G9 = LogitechDeviceModel(klass='G9', btn_m_range=(4, 8)) diff --git a/src/dcspy/qt_gui.py b/src/dcspy/qt_gui.py index c88175ae5..70a9917d2 100644 --- a/src/dcspy/qt_gui.py +++ b/src/dcspy/qt_gui.py @@ -26,14 +26,15 @@ from PySide6.QtGui import (QAction, QActionGroup, QColor, QColorConstants, QFont, QGuiApplication, QIcon, QPixmap, QShowEvent, QStandardItemModel, QStyleHints, QTextCharFormat) from PySide6.QtUiTools import QUiLoader -from PySide6.QtWidgets import (QApplication, QButtonGroup, QCheckBox, QComboBox, QCompleter, QDialog, QDockWidget, QFileDialog, QGroupBox, QLabel, QLineEdit, - QListView, QMainWindow, QMenu, QMessageBox, QProgressBar, QPushButton, QRadioButton, QSlider, QSpinBox, QStatusBar, - QSystemTrayIcon, QTableWidget, QTabWidget, QTextBrowser, QTextEdit, QToolBar, QToolBox, QWidget) +from PySide6.QtWidgets import (QApplication, QButtonGroup, QCheckBox, QComboBox, QCompleter, QDialog, QDockWidget, QDoubleSpinBox, QFileDialog, QGroupBox, + QLabel, QLineEdit, QListView, QMainWindow, QMenu, QMessageBox, QProgressBar, QPushButton, QRadioButton, QSlider, QSpinBox, + QStatusBar, QSystemTrayIcon, QTableWidget, QTabWidget, QTextBrowser, QTextEdit, QToolBar, QToolBox, QWidget) from dcspy import default_yaml, qtgui_rc from dcspy.models import (ALL_DEV, BIOS_REPO_NAME, CTRL_LIST_SEPARATOR, DCSPY_REPO_NAME, AnyButton, ControlDepiction, ControlKeyData, DcspyConfigYaml, - FontsConfig, Gkey, GuiPlaneInputRequest, GuiTab, LcdButton, LcdMono, LcdType, LogitechDeviceModel, MouseButton, MsgBoxTypes, Release, - RequestType, SystemData, __version__) + EffectInfo, FontsConfig, Gkey, GuiPlaneInputRequest, GuiTab, LcdButton, LcdMono, LcdType, LedEffectType, LedSupport, + LogitechDeviceModel, MouseButton, MsgBoxTypes, Release, RequestType, SystemData, __version__) +from dcspy.sdk.led_sdk import LedSdkManager from dcspy.starter import DCSpyStarter from dcspy.utils import (CloneProgress, check_bios_ver, check_dcs_bios_entry, check_dcs_ver, check_github_repo, check_ver_at_github, collect_debug_data, count_files, defaults_cfg, detect_system_color_mode, download_file, generate_bios_jsons_with_lupa, get_all_git_refs, @@ -61,6 +62,7 @@ def __init__(self, cli_args=Namespace(), cfg_dict: DcspyConfigYaml | None = None """ super().__init__() UiLoader().load_ui(':/ui/ui/qtdcs.ui', self) + self.led = LedSdkManager(name='DCSpy', target_dev=LedSupport.LOGI_DEVICETYPE_RGB) # todo: where to keep it for simulation purpose self._find_children() self.config = cfg_dict if not cfg_dict: @@ -92,12 +94,14 @@ def __init__(self, cli_args=Namespace(), cfg_dict: DcspyConfigYaml | None = None self.dw_device.setFloating(True) self.bg_rb_input_iface = QButtonGroup(self) self.bg_rb_device = QButtonGroup(self) + self.led_effect = EffectInfo(type=LedEffectType.NONE, rgb=(0,0,0), duration=0, interval=0) self._init_tray() self._init_combo_plane() self._init_menu_bar() self.apply_configuration(cfg=self.config) self._init_settings() self._init_devices() + self._init_led() self._init_autosave() self._trigger_refresh_data() @@ -236,6 +240,39 @@ def _init_menu_bar(self) -> None: color_mode.addAction(self.a_mode_system) color_mode.triggered.connect(self._switch_color_mode) + def _init_led(self) -> None: + """Initialize LED related stuff.""" + self.combo_effect_type.addItems([LedEffectType.PULSE.name, LedEffectType.FLASH.name]) + + self.pb_stop_sim.clicked.connect(self._stop_led) + self.pb_start_sim.clicked.connect(self._start_led) + self.sp_interval.valueChanged.connect(self._set_led_effect) + self.sp_duration.valueChanged.connect(self._set_led_effect) + self.sp_sleep.valueChanged.connect(self._set_led_effect) + self.sp_r.valueChanged.connect(self._set_led_effect) + self.sp_g.valueChanged.connect(self._set_led_effect) + self.sp_b.valueChanged.connect(self._set_led_effect) + self.combo_effect_type.currentIndexChanged.connect(self._set_led_effect) + + + def _set_led_effect(self) -> None: + """Set LED effect.""" + # todo: how to save it in a config file + self.led_effect = EffectInfo(type=getattr(LedEffectType, self.combo_effect_type.currentText()), + rgb=(int(self.sp_r.value()), int(self.sp_g.value()), int(self.sp_b.value())), + duration=self.sp_duration.value(), interval=self.sp_interval.value()) + + def _start_led(self): + self.led.logi_led_init() + self.led.logi_led_set_target_device(LedSupport.LOGI_DEVICETYPE_RGB) # todo: take from device + LOG.debug(f'Start LED effect: {self.led_effect}') + self.led.start_led_effect(effect=self.led_effect) + + def _stop_led(self): + self.led.logi_led_stop_effects() + LOG.debug('Stopped LED effect') + self.led.logi_led_shutdown() + def _init_autosave(self) -> None: """Initialize of autosave.""" widget_dict = { @@ -458,6 +495,7 @@ def _load_table_gkeys(self) -> None: def _generate_table(self) -> None: """Generate a table of combo boxes with completer functionality.""" ctrl_list_without_sep = [item for item in self.ctrl_list if item and CTRL_LIST_SEPARATOR not in item] + self.combo_ctrl.addItems(self.ctrl_list) # todo: move to better place for row in range(0, self.device.rows.total): for col in range(0, self.device.cols): self._make_combo_with_completer_at(row, col, ctrl_list_without_sep) @@ -1744,6 +1782,18 @@ def _find_children(self) -> None: self.pb_bios_check: QPushButton = self.findChild(QPushButton, 'pb_bios_check') # type: ignore[assignment] self.pb_bios_repair: QPushButton = self.findChild(QPushButton, 'pb_bios_repair') # type: ignore[assignment] + # todo: move to correct places, change widgets types + self.pb_stop_sim: QPushButton = self.findChild(QPushButton, 'pb_stop_sim') # type: ignore[assignment] + self.pb_start_sim: QPushButton = self.findChild(QPushButton, 'pb_start_sim') # type: ignore[assignment] + self.combo_ctrl: QComboBox = self.findChild(QComboBox, 'combo_ctrl') # type: ignore[assignment] + self.combo_effect_type: QComboBox = self.findChild(QComboBox, 'combo_effect_type') # type: ignore[assignment] + self.sp_interval: QSpinBox = self.findChild(QSpinBox, 'sp_interval') # type: ignore[assignment] + self.sp_duration: QSpinBox = self.findChild(QSpinBox, 'sp_duration') # type: ignore[assignment] + self.sp_sleep: QDoubleSpinBox = self.findChild(QDoubleSpinBox, 'sp_sleep') # type: ignore[assignment] + self.sp_r: QSpinBox = self.findChild(QSpinBox, 'sp_r') # type: ignore[assignment] + self.sp_g: QSpinBox = self.findChild(QSpinBox, 'sp_g') # type: ignore[assignment] + self.sp_b: QSpinBox = self.findChild(QSpinBox, 'sp_b') # type: ignore[assignment] + self.cb_autostart: QCheckBox = self.findChild(QCheckBox, 'cb_autostart') # type: ignore[assignment] self.cb_show_gui: QCheckBox = self.findChild(QCheckBox, 'cb_show_gui') # type: ignore[assignment] self.cb_check_ver: QCheckBox = self.findChild(QCheckBox, 'cb_check_ver') # type: ignore[assignment] diff --git a/src/dcspy/qtgui_rc.py b/src/dcspy/qtgui_rc.py index d528489f7..d5127c2b8 100644 --- a/src/dcspy/qtgui_rc.py +++ b/src/dcspy/qtgui_rc.py @@ -622647,438 +622647,467 @@ \x8a\xa9\xd1\xfe:LOFg-\x00\xce\x86_\x89\xe9\ \xf8\xe2\xec\x1b`\xda\xa4\xb5\x84\x8bS\x0a\x8f\xff\x00\x1c\ ?\x09m\ -\x00\x00\x1a\xdb\ +\x00\x00\x1c\xb0\ \x00\ -\x01Z\x04x\xda\xed]Is\xe38\xb2\xbeO\xc4\xfc\ -\x07\x86O\xd51-k\xa1dY\x0e\xb7'j\xe9Z\ -\xa2\xcb\xddUew\xf5\xbb)(\x12\x96\xf0L\x11,\ -\x10\x94\xad\x89>\xcd\x7f{\xff\xeb\x01 Eq\x01\xc1\ -]\x16\x15<\xd9\x22\x93X\x12\x89/\x13\x99\x09\xe0\xfa\ -\xdf\xcfkS\xd9\x00\xec@d\xfdr6<\x1f\x9c)\ -\xc0\xd2\x91\x01\xad\xe5/g\x7f\xde\xbf\xef]\x9e\xfd\xfb\ -\xe6\x9f\xff\xb8v\xe1\x9ejL\xa9\xe83\xe5Zs\xc9\ -\x0a\xe1\x9b[\xa8\xaf\xb4\xff\xfb\xaf\xf2\xc5\xa4\xff\x10\xed\ -\xba\xef?g$\xba\xa99\xce\xcdW\xf2Nw\xae\xfb\ -\xde\x0f\xf6\xf8\x09\x1aK@\x14\xfe\xe0\x97\xb3\xaf\xb7\x1a\ -\xb4\xfe\x82\x96\x81\x9e\xce\x14K[\x03\xfa\x88}\xc1k\ -Q\xaem\x8cl\x80\xc9\xd6\x7f\xb5\x04h\x0d\x08\xdez\ -o\x95k\x0ct\xe2\xfd\xab\x5c?\xdf\x0c\xae\xfb\xcf\xbb\ -_[\xf6k\xbb\xfbE\xeb$\xab\x9b\xd9\x94>\xf3\xfe\ -\xf5\x9f\xaf\x00\x5c\xae\xc8\xcdt@_\xf8\xff{\x05\xf7\ -\x83\x92\xaf\xfb\xbb6\x08[\xb4\x86\x16\x5c\xbb\xeb;\xf8\ -\x1f\xb0k\x94C\xff\x8fV<\x19\xe4\xaf8\xf8:\xa3\ -\xe2'\xce\xb3{H\xcc}\xc5\x04\xd3\xb1\xbby\xf7\xf6\ -\xce\xde\xd2\x82\xbc_\xb9\x8b\xfa\xa4#kW\x12\xa4\xff\ -;t\x900p\x90\x8buJs~\xde\xffA\x96.\ -<\xff\x81\xf5\xb3]/,\x84\xd7\x9a\x89\x1e\x1en\xae\ -\xfa\xfc\x93>\x5c/\xfb\x86\xee\xd8\xdb\xf9\xd3\x0a\x12p\ -\xeel\x96\xd7\xfd\x9cd~\xa5\xc2\x16\xc7\x84\xe6/\xfe\ -s'0:\xb0\x08\xd6L\x8ff\xd7\x05S\xdb\x22w\ -\xff\xc5\x07\x0c\x8d\xcf\xfc\xd1\xee\xab\xe5\xfe\xc9\xae?\xb4\ -)k\x05\xa3\xa7_\xce\xe8\x5c\xd0\x91\xe9\xae-\xf6\xaf\ -\xff:Q\xe6\xf77\xe89Z&\x9d'\x04\xea\x9a\x19\ --\xd7/9\xf8\x95\xe8\xce\xbd\xb6\x88\xf6\x88<\xcd\xd7\ -t^\xec\x0bH\x0e\x9a\xeebL\xfb\xfd\xc92\xc0s\ -\x98\x8e\x8e\x8a\xbb^\x00\xcc\xe4\xdf\xff/TH\x94\xad\ -\xe2\xd6\xc4\x9a\xa2-\xe6\x06\xd8@\x1d8\xd1j4B\ -\x05l\xe1\x12\xe0\x13\xc2\xbd\xfc\xecH\xf2\x89Q\xd0n\ -\xb1\x98`\xb8\x01\xbd\xb5k\x12h@\xe7Q*Q\x22\ -\xd2\xb0T\x05\x5c\x08\xda.\xed\x11\x09M\xae\x1d\xcdn\ -\x8ey\x1c\x89\xcc\xb2\x8c\xd2\x0b\x08\xe4|\x12gd \ -\x98\xa3\xbd`\x0e\xe3\x0c\x8cK\x15B&\x95\xd0` \ -\xfd\x9f\xd1\x8f\xf2\xcbU\x96l\xa5\xcaW\xb6\x8c\xd9s\ -S7\x92\x95\xc9\xc1?L\x19\xd2\x03\xe1\xc7\x11\x95\x10\ -~\x11\xd1\x0e\xb1fR\x90\xbe\x98L\xa3x\x1d&\xf1\ -\xe1Z\xbd\x9cD\xa1;\xc2\x06Q\x83R\x99\x93g.\ -\x15\x9fO\x929\xa5\xa3\xb5M+\xc3=S\xb3\x09\xb2\ -esJH*\x98S\x12\xc9\x17\xf6\xd0\xd4\x16\xc0\x14\ -t\xd1\x9fO\xbf\x81\xed\x02i\xd8p\x94'HV\xca\ -\xe7\xb7\xefDS-\xab\xd2\x22Sn8\x141<\x98\ -w\xc3\xf4y'\x92\xefo\x9a\x01\xd1\x1b\x97\x10:\x8e\ -~]x1_\x0e'\x9b\x91\xe0\xeb\xa4U\xa1=\xc7\ -\xac\x8a8\x9b\xf66\x86P\x82G\x83\xcbT\x09\x0e\xdb\ -\x1f\xe3T\x19\x8e\x1a#JNI\x16\xf4\xe5\x01YD\ -\xdc\x09\xf6F\xdc<\x1bA\x8b\xf0\xca\x87#ZY\xf0\ -KH\xbc@\xa6qC\xb0\x0b\xae\xfb\xfc_aOR\ -\xea*\xd4\x13\x02\x9eSz\xe2\x8b\xe6\x87\xe1D\xd9\x8c\ -\xd2$\xb5hub\x10(\x85\x03\xe9P\xf0\x81\x89\xe4\ -\xb9m\xa5\x02@\x88 e\xda\x97\xe9Wy\xc9\x1e\x8e\ -\xd4<\x92=\x1b\xd4.\xd9\xbc\xda%\x10\xc1}\xd4\xbc\ -\x93\xa2\xc7\xa0\x12z\x0c;\xf48m\xf4\x18\xb6\x0e=\ -\x86Y\xe81\xec\xd0\xa3\x1az\x0c\xeaA\x8fY\x87\x1d\ -'\x8c\x1d\xb3\x96\x01\xc7L\x0e\x1b\xb3\x0e4j\x03\x8d\ -\x0a\x0b\x96\xc9p\xd0\xa1\xc6\xe9\xa2\x06\x1d\xdev\xc1\x06\ -m\xb0\x147\x82\xf7\x1dp\x94\x05\x8eQ=\xd6\x86\xda\ -\xe1\xc6\x09[\x1bj\xcb\xac\x0dUnm\xa8\x1dh\x14\ -\x07\x8d\xeb\xbe\xe7_M\xc4\x00\x84\xa5dE\x00,t\ -\x5c1\x80\xe1d\x94\x19\x03\x18\x0e\xda\x1b\x03\x80\x96\xed\ -\x92\xde\xa3\xefg\x97\x85\x00D\x94\x87\x8e\x0007\xfe\ -!\x82\x00#i\x10`\x5cO\x10\xa0s\xe2\x9d\xb2j\ -l\x9b\x07/\xc3\x7f\xd7y\xef*\xda\xd3j=\xa01\ -\xe8\x0c\xeaSF\x8dA\xdb,\xeaA\x86I=\xe8l\ -\xea\x8a\xc01\xaeg!>\x98t\xc0q\xca\xc01i\ -\x1bpL2\x80c\xd2\x01\xc71d\x1b\xcc:\xd7\xff\ -)\x03\xc7\xacm\xae\xffY\x86\xeb\x7f\xd6\xb9\xfek\x04\ -\x8e\x0aK\x95i\x07\x1c\xa7\x0c\x1c\xd3\xb6\x01\xc74\x03\ -8\xa6\x1dp\xd4\xe8\xe3\xa8\xb2T\xe9\x80\xe3\xb4=\xa3\ -\x83\xb6\xb9F\x07\x19\xbe\xd1\x0e8^8\xe8\ -\xcc\x1eV\x95X.^\xf3\x0d\xa8irs\x14\xe7e\ -\xfa\x02KKv\xd8\xe46\x5c\xf6\xde\x13\x0c\xd7>\xa0\ -J\x114\xa65b\xf9\xfc\xe0\xac{\x18,\x10\x222\ -aL\x90\xbd\x94\x08V0\xa4\xed\xad'\x8a\xf5\x88!\ -\x17t\xc5\xb5\x0d\x8d\x00\x87\x1a\xb1X\x91\xad6j\x16\ -;\xafrV\xa9\xdf\x80v\xc1 ]\x22\xd3\x92V\x99\ -\xe8\x17\xa1k\x5c\xe2\xc4\x9e\x8b\x9c.\x8a\x9c\x88\x99w\ -\xdd;W+\xae|\xc1\xc2]V]\xf9~\xa7\x0d\x89\ -\xae|)\xba\x11j\xb9\x9b\xfe\xeaW\x15\xaf~\xcb(\ -\x09S7\xe6\x8e\x8e\x01\xb0\xa8\x81S\xd3\xfa\xe3V{\ -\x04\xecv#e_\xb0\x02h\x17\xb6\x04\xae\x81gE\ -x\xd3\x87\x9a\x83K\x84\x0c>\xa1\x08\x1d\x81\x85I\xa5\ -\x8eB\x1d-\xe4@\x0b\xe1;m\x13ojk\xa64\ -D\xe76m/z05\x0c\xc2\xff\xca\xee\xbe\x92~\ -s \xe5RFN\xa9\xf8,\x90\x03\xeaZ\xa7,\x97\ -\xccdY#\x0c\x14*\x88\xda\x8b\xcb\xe1[d\x9a@\ -'^\x8bL\xb4l\x8fb\xd1m\xe9\xc28x}\xc4\ -\xb2e0\xd0\x9e\x03K[\x98'+`\xbf\xf2\xde)\ -\x5c?)D[\xb4\xcbp1\xa1Cz\x06 \x1a4\ -\x9dL\xeb%I|,\xb2'\xb4\x90uo\xea\xcf\x99\ -\x98\x9c\xd5\x87$\x5c\xa8\xb9\xec\xb5f\xa8W\xc0\xb4{\ -\xda\x82Z8\xb21\x8eS\xb5\xd2>\x1d\x16\xb5O\x17\ -s\x16Nv\xaaY\xa7\xefY\x11\x8d\xc6eTY\x5c\ -f\x5ch9)\x04jc\x9e\x12\xdb/:M\x5c\x07\ -(\x8e\x0dt\xa8\x99\x0a+\x92C\xf3\xfb\xde\xf0B\xf9\ -\x0ei9\xca\xbb_\xdf)\xaf\x90en\x95\x0f\xc3\xd9\ -O\xad\x99B\x06\xed\x0fZ\xf6X\xef{\x9ae\xf4X\ -\xd7d\x93)\x9d\xfe\xa0\x8e\x06\xb5\x90d\x08\xbc\xd8\xac\ -\xdds\xf6\xab\x06\xd1`\x1dG\xa6vN\xc8\xc3a}\ -\xd4\xc5<~\x9f\xf9)4\xe1#i\xe6\xa3\x1az\x7f\ -\x0b\x0c\xe8\xae\xaf\x0e\xdb\xf3Q\xd5\x9e\xab5\xf4\xfc\x8e\ -\xce\x0f\xf3\xea\xc5\x86<\x87\xe0\xdf\x99\xd0\x00x\xd7\xf3\ -\x953_\xf3\xc1\xca\x8b\x89\x08\xb3 \x02\x8f\xc8\x08\xf9\ -\x00,w}\xf3\x95\x5c]\xfd\xb1'\xbc\xba\xfaH?\ -\xfb\x0f\xad@3\xaf\xfb\x9c\xa2\x9a\x9d\x0a\xf5\xc7/\xc8\ -\x81\x19\x8d\xf0zzuu\x1f\x22\xf7~9\xaf\x17h\ -\x03\xeaj\xca'\x8b\x00\xbc\xd1LaSh\x0d\x0b\x80\ -o\x86\x14<\xbd\xff\x8e0R%\x98\x0b\xe3\x1a\xe6\xc2\ -\xef\x94\xea\xc0SaP\xb1\xdf5\xf4\xfa\xb3\x86\x97/\ -\xd8\xed2\x08`\xb2&w\x00pJ\x000\xaa&\x11\ -\x0eSc\x9dD\x9c\x92D\xc87\xba\xcb\xa1\xd1C\x88\ -\x1a\xc0q\xf0b\x96Q\xf1>{vQ\xfb:=\xaa\ -\xd2i>\xf1\xdb\xd1\xe7\xda\x5c*\xa3z\xd3^\x93+\ -\xa8\xc2\x89\xaf\xbd7\x9f\xfe\xb8k\xd4\xc72=k2\ -\x17q\x01\x11\xb5*\xe0\xa6&O\xf87\xb0t)\x02\ -)\x18\x98@s\x80\x82\xb0\xc2\x0a\x0f\x92G^Y\x00\ -\x18\xca\x12\x92]\xc2\x180\x0e\xe4\x11\xff\x93\xb6\x867\ -e7h\xbb6]\xb5\xc6\xdbC\xd9&s\xee\x04\xaf\ -_.#1}J\xe6\xf3\xeb0il$=1\x18\ -th),\x08l(\x1fh1\xce\x8b\xc1\xfd\xb04\ -{\xf2NV/\xbee\x08\x19\xb4\xa0\xcc\xbby\xd0L\ -\x87oh\xa2\xffW\x9by9\x92\xc9\xac\xadBm,\ -H\xd9\x0e\xd9L\xf0\xb7n\x5c)\x0b\xacY\xfa\xeag\ -\x85h\xcb\x9f)s\xd6kH\x8e\xd9\x09\x97\x92\xcc\xed\ -\xa57\xf0\xe1i\x22\xf9.\x02WG\x90\x7f'\xd3y\ -]\xea\xdd\x01L~a`\xb1\x15\xd8Yf\xeb\x8aW\ -y+\xf7\xaf\xf46\x10\x99\x80doc\x89\x10\xbeT\ -\xd2g\x15\xc9k<\xe7\xb3F\xd09\xdd\xb4O\x0b\x90\ -'\x84\x1f{\xba\x86\x0d\x99\xd0%\xe9^j\x07U%\ -\x99\xc3\xc0\xd6\xf2!^\xc6\x88\x7f\xe3\x05\xb5'\xec\x0b\ -\x80\x0d\xad\x9e\xd7}i\xbc7I\xd8\x9e\xfc\x09I\x94\ -\xf8\x9a.2t\x80c\xe9\xb2w\xfca\xf6\xa2^\xe6\ -\x05Mq\x81~\xf7\xab\x10z\x1d\xd3\xd7\xf9\xb1\x8a\xd9\ -\xb6\xf0\x8f\xd0\xa2&\xbdC\x0c:\x08\x22\x9bS\xbcE\ -=8t!mw\xfang\xfa8ug\xbapW\ -zZ\xd3)1g\xe6\x81v\x8c/\x1f\xc1\xb6\xd1\xed\ -\xe2\xd0\xb2]\xd2[jk:\xbd_`\xa3\xf8\x87\xde\ -o\xb4\x83Mm\x13\x1f\x9d\xe5\x98B\xe1\xc5\xb9\x9a\xe1\ -/\xbbgK\xc7\xd8(=\xf9\x83\xd4/0\x83\xc79\ -\xab\x8fu\xf6c\x22!~\x15D \xfc\xe7q1\x16\ -*\x9c|\xe9x\xb6\xe8F\xa6\xdcF\xcb>\x0f\x8f\xed\ -\xe9\x03,\x17\x8f\x1a\xc8:0M\x85.\x99\x9eV\xd4\ -\xaac\xbcHU-2\xd4\xcd\xa7\xc4\x22-\xd8U\x5c\ -S\x95)\xba\xac\x84*K\xd1d\xc0\x80\xa4g\xb8\xde\ -Fei*\xbb\x882M\x97I\xae\xaaJ\xb9\xe2K\ -\xa8\xc8J\x0b\x95\xa3\x89\x5c4\xc5\x85\x8aoW\xd0]\ -\x8c\xd9fP\xdb\xd4,\xfa\x0bY\x0fp\xe9b\xae\x97\ -\x0e U\xc9&\xb4B\xae\x0c\xa4\xbbk\xda\xe4\x1e\x1b\ -\x8a\x9ef\x9aR+IL|\x04\xd2%H\xf7\x98\xd6\ -\x22Xl\x8f\xaf\x17\xd2d+|\xc7].\x81\xc3\x80\ -\x8b2\xde5%\x07\x05\xd4'X\xbf\x07\xb5\xfbu^\ -\xd5Q\xa9f\xc2\xa5\xc5\xc6RX3\x1d\x19f\xd9\xbd\ -\xde\x11\xbd7\xb5\xa5\xff\xf3\x1b3\x99\xfeN{{\x8f\ -5h\xd2\xa6\xa5\x12|\x7f\x0bX\x1c\x99v\xa1\x90\xc0\ -$\xda\xbfp\x0dc+j\xbb\xee\xf3\xc6\xb1\xa9\xcaZ\ -\xdb&\xe0\xb5\xe9\x859V\xbb\x88\xde\xd1\x05F\xc8#\ -\x1an_\xb6\xa4\xcaO!K;\xad\xc97\x86'\x83\ -\xf4\xa3\x9a\x82k\x0e/\xa6\xd3\xe9h\x98~\xd7a\xda\ -aME\x04\xfd(\xa6\x1b\xb5l\x19+\x85\xb7(f\ -e1\x14\xa9\xc6\x1b1I5l\x05R\xbd\x9e\x8df\ -\xba@R\xcb\xa8L-\x05\x84_\xb8\x8a\x95[\xbb\x83\ -r\xd6\xae\xd4\xb4\x9f\x09-\xdd\x1c\x19t94\xc9E\ -\x1d\x9a\xe4~k\x03fp:@\xc3\xfaJ\xa1\xca\x93\ -\x99(\x04\xd3\xdes\x0f\xda\xcet\xd0 \xd6\xb1\xf6@\ -~\xf66\x84\xf2^\x04\xe62$\x0e\xafP\x81\x0e\xfd\ -\xda\x86\xf4\x11\x8b7\x98\xd0^ \xe6\xa1:\x84\x9dc\ -\x03\xbd\x8c\x06*\x8c\xa79\xfc\xfd9\xc6nR\xc7\xd8\ -\xbd\xf6\xc7\xc4\xe3\xfd+\x12\x19\xca\x9f\x0e\xc0\xf4]\x03\ -:\xd5\x9fG\xf5S\xbd\xba@sn\x83;\x07Q\xfd\ -92V\x13\x01R\xd6\xc6p\x80\x94\xb7\xd9\x93\xa8l\ -\x91e\x9a\xf8\x0b;\x7fe\x9bf\x0d\xd8\xfc\xad\xb2b\ -\xff3y\xfd\xe5\xec\x0b\x8f&c`\x9c)\x9b\xfd\xd3\ -\xf7\xf09%\xf6\xbdB\x98r\x0e\x10\x9d\x1a\x10\xd4*\ -\xd8\xff\x12\xd0\xb2\x90\xab\xff\x96\xaa\x9b\xd0\xaf\x14+\xc2\ -k]\x15!H\xcb\xe3L;\x5c\xf4A[CsK\ -\xd7\xfe.\x86L\x06\xfd\xdf\x82\xf6\x09K\xa8\xd5\xcai\ -\x8d*`\xae\x84\xb4\xcd\xbf<\x1dbw\xd4\xab 3\ -\xa2\x98\xa9\xf4\x1d:\x90V\xf4\x89v\xd1yAc&\ -e:\xab%\xa7\xb3\x07AG7\x9d\x87\xc77\x9d\x8f\ -A\x077#\xed\xf5\x9b\xd2u\xc5\x12\xf8N\xe8&c\ -\x09\xf2-\xea\x87\x09(\xa4\x1e\x87\xa8\xaf\xae\ -~G\xec\xff\x8a\xc2F\xcb\xe6;\xab4\x9d\xc9\x10[\ -.;\x02d\xf7W\xe5\xf7Ij\xde(*u\xba\x0e\ -\x1cnC\xbf\xd9\xfe\x06\xb6|\x0d\xf0w\xfeOn\x91\ -\xeb\x80tz\xf6\xf0\x0d\x15<\x07\xe0\xd0;9\xfd\x1d\ -_\xa9h9[\x14\xff\x827H\xe4*hFy\x8d\ -\x8a+\xe9Y%%=\x1c4\xa3\x9cs\x19\x87\x89'\ -\xb1rb\xf1\x8c\xe2i\x07\xd1s\x07\x12\xe1\x91Dl\ -\x18\xa3%\xa6\xb2\xf8F\x0b\xec\x03\xdb\x7f\xb4\xd0b\xd1\ -\x91<\x1ao\xa7\x86\xc4Z(\x85\xc3\xa2\xe1\xf3\x97\xa5\ -\xf1\xe2\xa5\xdb\x02\xc4\xc5\x8b,\xf4\xf8\xe0e\xf3I\x18\ -CO\x1e\x90\x9eou\x15=\x16]r\xf4x\x01\x86\ -\xc9\xaa\xa8R\xb6 \x0e^0\x06\x9e\x12\xfff;\x22\ -\xb5\x1e]\xa8o\x17\x9a\xfe\xd8\xe3\xcc\x94\x85\xc0\xd3\xe9\ -E\x0b\xa3\xc3\xcb\x02\xb2\xe5\xa2 \xde\xedRF\xa2\x0b\ -K\x19\xb2\x9b\x162d\xb7C\xc6\x90]H\xc4v\xe4\ -\xc7 a\xba\x998m\xb2\x98\x1c\xfc\xfa\x0c\x89\xe4h\ -\xe2\xeab\xf0\x96\xb5\xf0(\xe5\xc0;\xbc\xbe\xe7\xac\x5c\ -b\xa0'K&\x03B\xd2Z\xc7?a(D\x09b\ -\xaf\xc3/#\xaf\x225\xc5%\xe8\x96Z\xc6!\x9d\xce\ -\xae\x82\xd8\xeb\xf38\xdb\x97\x00\xad\x01\xc1\x81\x0b\xf4\x1a\ -Sc0h\xce3S\xe6\xcf\xc1\xcf-\xfb\x19t\xd9\ -\xcfs\x98M\xe3\x89\x0e\xbb\xec\x06U\x8d\xe55\x5c\xf7\ -\xf7\xa5\xc7Y(\xeaE\xb8\x0b\xef\xe1\xde\x22\x90o\x83\ -\x0e<2\xf4\x8b\x98D&\xc6\xedZ3\x0c\xcf \xde\ -\x85\xe9|\xcd\xde\x97\x11P\xb8O}\xef\x00[\xc3\x1a\ -AXV\x04\x15h@\xe8\x22\xf0Ac\xf9\x15\xd2\xca\ -\xb4\x0d\xf0<\xda\x15\xab\xfc\xe1\xc2\xa0WQA\xcd\xe2\ -\xfcG`\xda\xc58\xcf\xbe(\xc1y\x0cl\x84\xc9\x1c\ -:\x8e\x0bd]1\xa0\xa3#lTd\x08?\xb4\xd1\ -;\x11>\x9b\xec\x07\xa9X\x9bw\xf2\xbc\xbfaGF\ -\xc8w\x8e\xe4\xa03\x90EI\xca\x8d\xe8w\x08\x9e\x8a\ -\x8d(\xfb\x22sD3j\xbd\xa7\x1a\x8a\x02\xd1\x9c\x03\ -\xea\xbe\x06\xf9\x91\x06A\xf4\xce\xfbXq\xc861\xab\ -\x05p,`\x18\xafv\xce\x0eQ\xdc'\x89\x0b\xc8\x98\ -\x8e\xcbI\xb5\x00\x0e4@6\x9dk1\x17l0\x96\ -Q-\x91\xc5\xb5\x88\x8b$'\xb3\xd87\xa5x\xb4\xa6\ -\x1f\xce=-(\xed\x16\xa734\xfc\x98Me2\xfc\ -O\xed\xbc\x00\xf0\xd8\xcd6\xc4\x1b\xedt\xf9O\xcaS\ -\x95\xe9\x19\xf0\xb9\xda\x1c\xf7.\xe5\x89lCH\xa32\ -\xc0\x06\xeai\xb3W\xd4<\xae\xfe\xfa\x12\x02>\xa7e\ -\x04\x1c\xc6\xfb\xd9\xe6\x03]5\x127\xec\x14p\xf8\x83\ -\xfdp$\xdc\x9bt\x1cB\xe4\xbb\xb1\x13\xdb\x1bO\xd0\ -\xa2\xa6\xd5}Xn#\xf7\xf4)\xec\xf3X\xc6a\xc2\ -T\x88\x87\x10\xd0&\x1cA\x14\x87\x0d\xb3\x0a\x89_\xcc\ -\x19\xc9\xee\xf4M\x1du\x94f\xe9\x8c\x12\x96\xce\xfe\xf3\ -D\xcd\x89@\x9a\xc7\xc0\xd7\x18\x04G.{>\xd0{\ -d\xdf\xef\xdf\x85]\x9e\x898ZZ\xa1o\xe8\x87\x8f\ -Q\xce$\x16\x9c\x82\xc2\xe4VQ\x86Q\x94e}d\ -N\xae\x5cvP^%\x9bS\xc7\x96kUb\xc6\xe7\ -\x9c\xf0e*\x13\x99G\xd9\xd6Q\xb6\xe9P\xa6-I\ -\xe3I\x8a)\xef\x90\xfe\x18\x0d\x85\x1bO\x91]u)\ -a\xc7\xac\x099\xba\x98\xa4\xcc\xc8\xf1\xe5\xa0\xc8\x94\xcc\ -N\xfc\x16U?\x19\x8dG\x97\xd3FZ\xe0\xe1\xe4\xa7\ -\xd0\xa28\x9e\x03Pr'alA\x9b\xd5\x8e\x98[\ -\xc1\xc7\xea~\xbe\x8f\x1fL\xa4\xb1[\x052\xf1'\xa3\ -\x18@\x15\x10\xde\xa7\xf4x\x81\x99\xbdL]]\xed\xff\ -\x7f\xef\xd1\x86\x1f1\xd7\x04\xd3\x0f\x7f\xe7\xff\xe4=k\ -x\xc1on=-\x14\x8a\x9ed\xf5K3M\xf4\x04\ -\x0c\x86\xed\xb1\xbeE\xeab\xefY2\xa7\x19}\xe4\x14\ -\xa8I\xa2u\xbd\xbd\x9f\x8a\x9f+\x92\xa1x\xe3J\xc6\ -\x88\xb4((z\x977\x16\x0d\x04$\xd5\x8c4Yf\ -_\xf6[d\x11\x10:n\xbe\xf0\x0dE\xfb8S\xd4\ -\xfd\x96\xfb \xb6p>s\xe6\x19l\xc1\xad\x8al*\ -\x8a\xf6\x0d\x89\xbcG\xc52`\x06\x89@\x8f\x17[\x9b\ -\xa6%\x86d\x9f\xd3\x09\x08\xd3\xf1\x04\xbc\x98#;=\ -\xf7\xa0L\xe6A^\x8ffz\xd6A\xf9\x9c\x83\x02u\ -\xa7\x1c\xef)\xdf\x13S\xd1\xfb,\xdd\xfc<\x92\x8a\xcd\ -7\xcd\x80(\xea\x9d\xc6\x8b\xf9F\xc3\x90\x89\x05\x15 \ -`S#\xcdu\x8e4\x1a\xf2\x07\xbbA\x01Z:\xe6\ -\x87\xff\xf1\x18&\xdf\xf0\xf4\x04\x89\xbe:\xff\xe7?^\ -o(\x06\xf2\x9biXB\xf0\xae[\x0a\xeb\x96\xf2h\ -\xa1\x85\xc3\x0e\x0c\xb4\x11\x03#\xc8\xdc\xa6\x00;\x0a<\ -\x07\xe7\xca\x86q\x92\x1f'\xb8\xc0L\xe1[\xc0q\xce\ -\x1b\xf2\xb4\x7f\x8f4\x8b\xf6\xe6(\xbd\xee<\x01\x91\xda\ -\x8d2w{\x94\xa6\x818\x8b\x9f\xb5\x93z\x88\x9a\xf4\ -\x9c\x0e\xf5\xac^\xb8\x92\x9c\xd1\x91s\xb0\xb2\xcf\xe7\x10\ -mI\xcc8\x9b#\xebd\x0e\xc1\x06\xc4\xb4QI\x9c\ -\xc9!\x1b\x95\x8b\xfa\xf0\xc7v\x9d\xd5|\xe1==N\ -\xe0a\xa7{2Ha-U\xbc\x962\xb0\xf0\xf7\x1f\ -0\x18\xa1\x10\xb4R\xf8\x0d/#\x85\xeb\xe1\xc6\xf0\xe3\ -\xcb\xbe\x0dG\x89\x1c\xbfAB\xc0\xea\x0b\xb5\x87\x80\xf4\ -\xf0\xa0$]c\x082M\x05\x90\x5c\xf2\xf9\xf2\xb6U\ -F\x92\x00\xed\x01\xb2\x80B\x97\xfd\x14\xa1\xf8\x01\xb9\x9e\ -nd\x22\xcb\x16\xe9TH\x1f\xc1ysY*\xe48\ -#\xc7,\x06L\x17\x82F|)\x9dE\xd6\x98\x1cN\ -\x9a\xb2\xd9\xd6\xd0:n\xa3\xcd\x00\xa7d\xb4\xd1\xde\x1c\ -\xaf\xd1\x86\xc1\x9a.k2\xed\xb60Yc\x02\xaf\xd6\ -'\xf0\xfaV7\x8f\x15\x80\xdf\xb2\xb6)d\x85\x91\xbb\ -\xf4v&r1w\x94\x07\x88\x1d\xb2_\xb1h\x96A\ -\xa9\x80\x15L\x87\x9f\x156\x08\x0a\xcbX\xe2/\xe9\x0c\ - \xfe\x9c0a0'\xd6\x88\x16\xe2\xcd\x17Z&\xa3\ -\xf3\xe6\x05\xb79\x1e\xd8\xde5O,\x99\xa1\xd7\xd4\x04\ -\xf0\xba\xe8\x1c-\xd6?b~0\x88\x86\x81Ay.\ -\x93~\x11ec\x13`T\xdf\x04\xe0\x03\xed\xc1=\x15\ -\x9fV\x80\xbd\xed\xfb[\xe2x\x1f\x96m\xd7$\xb0G\ -\x09}\xca\x17\x16\xf3\xf7\xfbj\x8e\x15\xe4\x97\xa8gc\ -\xb0\x81\xc8\x95\x8ay\x82\xac\xb9\xf5y#2NA\xb3\ -\x15^\xa8V\xcb\xf8\xb1z\x9f\xa8\xf0Z\xb4\x03\x19\xf2\ -\xbd'iL\xb6\x07\xf5\xc9\xb6\x17\x81=R\x99\xbeG\ -\xcb%\x95\xd6\x05 O\x80\xda';\xa1v\xb2L\x13\ -\xf2\x84z\xdc(\x10\x08uS\xf2\xeb\xb5\xf5(\xe5v\ -w|\xa2\xd4\xfc\x8e\x115&\xbb\xb3\x1a\x8do\xd7!\ -h\xfdr\xb2+\xb1Ky\xcb\x8eR\x18l\xbeUO\ -\x07=Z\x92+\xdd\xbb \xa2lN]\x97\xc24\xc1\ -u1\x87\x15\x8ar\xc9\xf9\xd1ob\xc9\xfa\xe5b\xc9\ -\x17\xe5b\xc9\x0fl\xe4\x89\xf8B\xa8<\x01\xe5\xcc \ -\xf9\xb8\xd0\xe6\xc1\xd8mo\xec\xd0\xdb%\xc2\xdb\xb3\xd2\ -\xf3\xd0/\xe0\xaa\xc0T\xace\xbfM\xac#\x06pt\ -\x0c\xedlU+\xe9\xcb\xbb}\x19/\xdd\x1dh0\xb7\ -\xd7\x03\x04\xb8to>\x05E\xbctg\xb0f-A\ -\xe9~|c_7\xdf\x05IH\xb1\x0b(\xd6\x1dP\ -,\x86\xd8Q\xeah\xc2b\xe1\xecE?\xa1\xb3\x89\xec\ -\xbdG\x7f\xdf~\x1d\xf9{\xedO\xc1k*\xa1\xeew\ -\x14}RO:\xdd;.\x16Jr\xbf\xcc\x91\xe5\xd2\ -\xeds\xe2\x0a\x1b\x0a\x93\x9c\xd9t1\xf4\xdeI\xb5\xcc\ -\xfc\x89\xa1w4\xdb4\x05)\xea\x99\xf2\xb2\x5c\xeb\xf4\ -\x0d\x03\xf1\xd9\x9de\xf0\xa7\xdf\x9c\xb9r\x17=j{\ -\xb3\xcb\x0fY\xec,\x83\xc6\x19\ -\xc5oZr\xa9\x01\x9ey\x1d\xd3\x9e\xa8\x06\x13\x895\ -\x98 e\xd7\xcf\xf2\xfc\xf2w\xdf5\xce'\xa2=\x03\ -\xa7\xf7\x00-\xcd\xd2\x814\xd4+\xa2\xac\xae(x7\ -+\x22\x81l\x8b`M8P#\xc7S\xf7\xdee\xd2\ -\xd53\x95E\xd7\xf8\x95\x05\xf2\xd7&\xf9\xd7\x87\x8a\xa3\ -'u\x91\x1c\xeb\xf0\x09\x9d/9(\xeb\x19B\xcf}\ -P\x8bj/]\x9eL$\xdeU\x10\x89\xfd\x0e\xee\xe6\ -\x97\x87u\xdf\xafVj@\xd9\xddt_\x92w\xd2\x95\ -\x1d\xcf\x8c\xab\xee*\x99lw\x15\xf4\x99\xbf\xdf\xbc\xf9\ -A\xf5*\x92\x0ee\x98\xa4\xba\x0a\xf3J\xabe\xf4\xfc\ -\xb2\x94;\x807\xa0\x82\xb5\x15>w\xb2A^7t\ -@c\xa9i\x94<\xc5\xb2\xec\x0cJ=r\xb3\xd8\x08\ -\x04\xa7=fD\xabK\xfa\xda\x9b\x1c\xc6:\xce@,\ -7\x88\xf1S\x22K\x8fa\xca\x81\x96E\x860r\xfe\ -G\xe3\x83P\xd3\xad\xf7e\xd8\xfe\xe6\xd3\x1fw\xcd8\ -kz\xb9\x8b\x96\x8eD\xe8P\xaeF\xcdD\x11sX\ -x\xce\xe1{\xee\xca\xb7\x7f\x7fZ\xd8\xc1\x9b\xcf\xce\xee\ -\xcen}\xde\x81\xcdWZ6/\xfc3\xd1^\x86\x1b\ -^\xe5\xf5\xf1#Gy\xd9\x1c\xf1N\x7f{\x19\x86\xf0\ -\xba\xcb\xb7?t\x80[[\x16q|K\xad\xe6\x90\x8c\ -\x04\xca\x10Me\x90\xfd\xcc\x18T\x8b\xd0\xf1\x92\x94\xe4\ -\xe9}\x85\xc7\x8c\x1f\xcd\xd7\x96!\xdb\xb9\xc8]\xc7\x06\ -\x96\x91\xc7\x99\x1e\xa6\xacn\xe5S^\xd5c\xe2\xd3\x82\ -\xea\x18<\xff\xfc\xc5\xb6\x0c\x1fw\xb5z\x17\xe4\xf5\xa0\ -\xc5r\x052\x1d\xb3\x02\xea\xea\x16&\xe7Z=6&\ -/\xaa\xd8P\x86\xb3\x09\xaew\x8ct<2h\xe9\xa6\ -k\x00\xc5D:O\xdd\x8a\xf1\xb7\xef}\x1f\xf9\xe8\x9a\ -\xb2\xc3\x02\xbct\xbf\x90\xfd\x03\xbf-\x0e`\xe0~\xb3\ -;\x1d\x9c\xa5\xaf\xf0\x07\xfe[\xb8\xb44\xf3\x86Z\xca\ -,\xca\xf1\x8a]\xd5\xe6=\xf1^c\xa0\x03H\xb9\x7f\ -\xf3\x95\xbc\xd3\x1d~.\xb3\xf7\xdb\xff\xdaD\xe4\x86\x17\ -\xcb\xbfd\xbf\xbc\x17+v_\xcc\x8e]\xec\x87\xe2\xdd\ -\x80\xe75\x9d_\xd1q\x16:=\xfa\xe2r\x16=?\ -\xfa\xe2b\xba?A\xfa\xba\xcfJ\x10\x94f\x00\x87@\ -\x8b\xf3*Q\xe4x\x18+RM+\xd2\xfb\xdfg_\ -?\xc6\xbfT~\x06\xd9\xeab\x86\x12\xbey\xc0x\xc5\ -\xa6Z*S\x83\xe4f1c\xa9\x9c\xff\xea\xad\x14\x83\ -bJs\xf8\xf22vB\xb7:\xa9\xca\xe1d\x91\x97\ -\x93\x9a9\x1c\x9c\x88P\x81\xc9\xe1C\xab\x9a\xe7\xf3t\ -6\x8a1eT\x95\xcf\xb3I\x9c\xcf\xea\xb0f>/\ -g\xfc\xc6\x9b\xb2,^.\xf8EqN*{\xdfA\ -\xa7&\xfe\x0e\xa7j\x94\x19#u\x5c\x91\xbf#5\x86\ -\x14\xa3\xda\x91b9\x1c\xa8\xed\xe0\xefx\x12\x87\xcd\xf1\ -\xb4\x15\xfc\x9d\xb4T~\xc7\x17\x836\xf0w\xd8R\xf1\ -m\x0b{\xdb\x0a\xbf\xed\x80\x07u\xd0\x12\xfe\xaa\xc3I\ -\x1b\xd5\x9b\xdaV\xf4\x1dM\xdb\xc0\xdeq[\xc4w2\ -n\xa5u6\x1e\x8cZ\x22\xbf\x83a\x1b\xd5\xdb\xa4-\ -\xfcM\xc0o;\xf8{\xd1\x16|H\xc8o;\xf0\xe1\ -\xa2-\xf2\x9b\xc0\xdf\x96\xc8\xaf\xda\xd6\xd5q;\xec\x87\ -ik\xf1\xa1\x1d\xcb\x8bi[\x96oI\xf9m\x05\xfe\ -\xceZj=\xb4Czgj[\x9d\x0f\xe3Q;\xf8\ -\xdbV\xed\xd6\x0a\xfe\xae\x9f'\xc3\xcb\x96\x9ag\xc7\x0f\ -\x10+gn\x80\x85\xbb\xe4<\x9a\xb3\x139\xc4\xacv\ -\xf8\xf5'\xb7hC\xf9D\xabI\x0fy\xb2\x0e\xccg\ -\xa9\xcc\xfe\xdd]\xef\xbe/\xcd\xe6\x91z\x19\x8b&\x0f\ -.+\xb2\xf9b:\x89\x179+\xce\xe6\xf0oFq\ -\xddw!\xfd\xf3\xff3\xbaE\x16\ +\x01u\xe8x\xda\xed][s\xdb8\xb2~\xdf\xaa\xfd\ +\x0f,?ejG\xb6(J\x96\xe5r\xbc\x95\xc4\x93\ +Lj\x92\x99$\xf6fN\xd5\xd6)\x15E\xc2\x12\x8e\ +)\x82!A\xdb\xda\x9a\xa7\xf3\xdf\xce\xff:\x00HJ\ +\xbc\x80\xe0\x0d\x94E\x15\xf3\x12\x8b\x04q\xe9n|\xdd\ +h4\x1aW\xff|^[\xca#p=\x88\xec\xd7'\ +\xea\xe9\xf0D\x01\xb6\x81Lh/_\x9f\xfc\xeb\xee\xfd\ +\xe0\xe2\xe4\x9f\xd7\x7f\xff\xdb\x95\x0fw\xa5\xc6\xa4\x14y\ +\xa6\x5c\xe9>^!\xf7\xfa34V\xfa\xff\xfd\xaf\xf2\ +\xc5\x22\x7f`\xfd\xea,|N\x8b\x18\x96\xeey\xd7_\ +\xf1\x8d\xe1]\x9d\x05?\xe8\xe3'h.\x01V\xd8\x83\ +\xd7'_?\xeb\xd0\xfe\x13\xda&z:Ql}\x0d\ +\xc8#\xfa\x05kE\xb9r\x5c\xe4\x00\x17o\xc2WK\ +\x80\xd6\x00\xbb\x9b\xe0\xadr\xe5\x02\x03\x07\x7f*W\xcf\ +\xd7\xc3\xab\xb3\xe7\xe8\xd7\x86\xfe\xdaD\xbfH\x9bxu\ +=\x9b\x92g\xc1\x9f\xe1\xf3\x15\x80\xcb\x15\xbe\x9e\x0e\xc9\ +\x8b\xf0\xef\xa0\xe2\xb3m\xcdWgQ\x1f\xb8=ZC\ +\x1b\xae\xfd\xf5-\xfc\x0f\x88:\xe5\x91\xbf\x93\x0dO\x86\ +\xe5\x1b\xde~]\xd0\xf0\x13\xa3\xd9\x1d\xc4\xd6\xaea\xec\ +\x12\xde]\xdf\xbc\xbbu6\xa4\xa2\xe0W\xe9\xaa>\x1a\ +\xc8\x8ej\x82\xe4o\x8f0\xc9\x05\x1e\xf2]\x83\x949\ +==\xfb\x81\x97><\xfd\xe1\x1a'\xd1(l\xe4\xae\ +u\x0b\xdd\xdf__\x9e\xb1O\xce\xe0zyf\x1a\x9e\ +\xb3\x99?\xad \x06\xa7\xde\xe3\xf2\xea\xacd\xb1\xb0Q\ +n\x8fSB\xf3'\xfb\x19\x09\x8c\x01l\xec\xeaVP\ +&\x1a\x82\xa5o\x90\xbf\xfb\xe2\x83\x0b\xcdO\xecQ\xf4\ +\xd5r\xf7$\x1a\x0f\xe9\xcaZq\xd1\xd3\xeb\x132\x17\ +\x0cd\xf9k\x9b\xfe\x19\xbe\xce\xd4\xf9\xfd-zN\xd6\ +I\xe6\x09\x86\x86n%\xeb\x0dk\xde\xfe\xca\x0c\xe7N\ +_$G\x84\x9f\xe6k2/v\x15d\x99f\xf8\xae\ +K\xc6\xfd\xd16\xc1s\xbc\x1c\xe1\x8a\xbf^\x00\x97\xca\ +\x7f\xf8W\xac\x92$Y\xf9\xbdIuE_\xccM\xf0\ +\x08\x0d\xe0%\x9b\xd11\x11\xb0\x85\x8fAX\x10\xee\xe4\ +'*RN\x8c\xb6\xfd\xe6\x8b\x89\x0b\x1f\xc1`\xed[\ +\x18\x9a\xd0{\x10J\x14\xafh\x5c\xaa\xb6T\xd8\xf6]\ +8\x22\x1c\x9b\x5cQ\x99h\x8e\x05\x14I\xcc\xb2\x82\xda\ ++\x08\xe4|\x92&\xe4V0G;\xc1T\xd3\x04L\ +K\x15B\x16\x91\xd0-#\xc3\x9f\xc9\x8f\xca\xcbU\x91\ +l\xe5\xcaW\xb1\x8c9s\xcb0\xb3\x8d\x89\xc1?^\ +2\xa6\x07\xe2\x8f\x13*!\xfe\x22\xa1\x1dR\xdd$ \ +}>\x99&\xf1:^$\x84k\xedb\x92\x84\xee\x04\ +\x19x\x1d\xca%N\x99\xb9T}>\x09\xe6\x94\x81\xd6\ +\x0ei\xcc\x1dX\xba\x83\x91#\x9aS\xdc\xa2\x9c9%\ +\x90|\xee\x08-}\x01,\xce\x10\xc3\xf9\xf4\x1b\xd8,\ +\x90\xee\x9a\x9e\xf2\x04\xf1J\xf9\xf4\xee\x867\xd5\x8a\x1a\ +\xad2\xe5T\x95G\xf0\xed\xbcS\xf3\xe7\x1dO\xbe\xbf\ +\xe9&Do}\x8c\x09\x1f\xc3\xb6\xdc\xc5|\xa9N\x1e\ +G\x9c\xaf\xb3V\x85\xfe\x9c\xb2*\xd2d\xda\xd9\x18\x5c\ +\x09\x1e\x0d/r%8n\x7f\x8cse8i\x8c(\ +%%\x993\x96{dc\xfe \xe8\x1b~\xf7\x1c\x04\ +m\xcc\x1aWG\xa4\xb1\xed/n\xe1\x05\xb2\xcck\xec\ +\xfa\xe0\xea\x8c\xfd\xc9\x1dIN[\x95F\x82\xc1s\xce\ +HB\xd1\xfc\xa0N\x94\xc7Q\x9e\xa4Vm\x8e\x0f\x02\ +\xb5p \x1f\x0a>P\x91\xd8\x91^\xb4}\xc8/\xdb\xfe\x06\xe2\xaf\xdb\x16[\ +\xdf5\xd4N\xda\x0f\xdf\xd5\x0e\xca\x8dw1\xecu\xa3\ +L\xdd\xa8u\xcc\x8b\xa7\x89\x9dxZ\xef\xc3;\x0c\x1f\ +\x9e6\xecQ\xe3\x88}xZ\xd7|xZ\x81\x0fO\ +\xeb-\xea\x86\xc0!'\xee\xff\x5c\xd3z\xe08^\xe0\ + \xec\xed\x16p\x90\x0e\x0b\x81c\xfb\xbe\x07\x8e\x97u\ +\xfe\xcfz\xe08n\x8bC\xeb\x9a\xc5\xa1\x15X\x1c=\ +p\xbc\xb8\x0fo\x8d|\xaf\xf7\xdf\xed\xd1\x7f\xc7\x08.\ +r\xda\xc5\x0a\xb4\xef\xa9\xfb\xcc\xd8\xdf\xba\x97n|\xd2\ +\xfe\x16\xd6x\xd8\xe7\xf79b\xf5G\xd8\xdb-\xf5G\ +:,T\x7f\xdb\xf7\xbd\xfa{\xd9\xf8\xfeI\x0f\x1c\xc7\ +\x0c\x1c\x93\xae\x01\xc7\xa4\x008&=pH\xf4\xd45\ +\xb08\xce\x87}\xd0\xcc1{\xea\x86\x1ds\xf1\x93\x0e\ +\x8b=u\xc3\xde\xc5\x7f\x10.~\xad\x07\x8e\xa3\x8e(\ +\xe8\x1aph\x05\xc0\xa1\xf5\xc0!\x118FM|\x1c\ +=p\x1c\xb5\x8fc\xd85\x1f\xc7\xb0\xc0\xc7\xd1\x03\xc7\ +AD#M{\xe08f\xe0\x98v\x0d8\xa6\x05\xc0\ +1\xed\x81\xe3@\x82\x0az\xd88\xe2\x90\x82\x8e\x05\x14\ +\x88\xc3\x09z\xc0\x90\x06\x18\xf5\x97(\xeb\xe7\x89z\xd1\ +c\xc6\xd1b\xc6\xe7\xff\x22\xfc\xed\x14l\xb0\x1e\x8b\x90\ +#V\xa0\x07\x0f\x09[\xb1\xa3&;*\xfdV\xecQ\ +\xef\xa8\x8c\xba\xb6\xa32*\xd8Q\xe9\xb7b\xdb\x0ea\ +\xe4>\xcd\xd6\xcb\xa9\x93\xf3e\xf1\x85\x9b\x84\x8b\x98\xc8\ +g\xed\x1b7\xf97k\xda\x09\xb9q\x5cp\x0f\x5c`\ +\x1b\xc0\x1bx\x1b\x8f\x8c$\x11\x10h\xa7\x87\xda\xca=\ +\x9a\xb7\xe1@\xdb\xbaHs\x9c{\x91fb\xf7\x9d\xfe\ +\xe99:Go\xa4y\xf5\xc1E\xbe\x13\xbbUs\x19\ +\xfd.\xb8V\x93C\x03Eteo\x09\x91\xafD\x88\ +\xf3l\xdbe7\x14\xd3$\xf8\xe2{\xab\xa4\xd6t\x16\ +s\xd3\xf0L\xe8\xf2\x94n\x9a\x10\x08Yw\xd0\xe1j\ +\xd8p\xfc\x9f\x90\xa1c\x88l\x05\xdd+\xd0\xf6\xb0n\ +Y\xc1oB&\xe5O\xe4Z\xa6\xf2\xea\x0f\x07\xd8o\ +\x01\xd6\x7f\xca\xc7r!V\x94T\x1b1\x06)\xf7D\ +q\x01WN{y\x9a\xa3\x8e\xe2\xc8\xd1\x1bAwE\ +A\xbe\xf1\x12\xb9\xbaC0\xaa<\xc0\xcd\xc1\xdb\xb2W\ +L\xa4\xe5\xed\xdd\x0a\x18\x0f\xb1)g,\xe6\xba\x8f\x11\ +\x91\x0b\x17\xcb\x11\xb8[Z\x95\xc2&!i\x15\x02\x1b\ ++O+`+\xba\xe3X0\x94E\xd6\x9c\xb7\x1fi\ +{C\x86\xa7X\xbao\x1b\xabD\xaf:#{\xff\xb3\ +\x5c\x03\xdb\x17\xc9^\xbc\xc4^eoXI\xf6>A\ +\x1b\xfcb\xc2-\xa2Z\xa0cHW\x9bNZ\xd39\ +\xea\xad\xd0\xd3\x9c\xc8\x8e\x1cJ}\xbcW\xe8t \xad\ +\x003\x9c\x13\x84\x5c\x1b\x85\xd4c\x13\xd2)\x81\x05\xa3\ +`\x97<\xd3ms;\x8d\xa1e)\x0b@'\x13\xf9\ +\xd8\xdc\xcf\xf4\xbd%#W>\xfc\xebc\x00\x22\x0c8\ +d5\xbd\x87\xb9\xfb\x08\xc1\xd3\x80\xfc2\x80n\x11\xc3\ +pM\xd6k\xd0\x10Me\xc1\x07{\x9d\xd9jS\x89\ +e\xe25\x7f\x04\x92&7CqVg(\xb0\xa4f\ +\x8fNn\xd3\xa7\xef\x03\xc1\xf0\x9d=\xaa\x14Ng:\ +#\x96\xcf\xf7\xdez\xe0\x82\x05BX$\x8c\x99b/\ +%\x82\x0d\x0cig\x13\x88\xa2\x1c1d\x82\xae\xf8\x8e\ +\xa9c\xe0\x11#\xd6UD\xab\x0d\xc9b\x174N\x1b\ +\x0d;\xd0-\x18$KdR\xd3\xaa\x10\xfd\x12\xe5Z\ +\x978\xbe\xe7\xa2\xa4\x8b\xa2$b\x96]\xf7\xce\xb5\x86\ ++_\xb0\xf0\x97MW\xbe\xdfIG\x92+_\x82n\ +\x98X\xeeV\xb8\xfa\xd5\xf8\xab\xdf:J\xc22\xcc\xb9\ +g\xb8\x00\xd8\xc4\xc0\x91\xb4\xfe\xf8\xac?\x00z\xbd\x91\ +\xb2\xabX\x01d\x08\x1b\x0c\xd7 \xb0\x22\x82\xe9C\xcc\ +\xc1%B&\x9bP\x98p`a\x11\xa9#PG*\ +\xd9\xd3B\xf8V\x7fLw\xb53S\x1a\xa2S\x87\xf4\ +\x17\xdd[\xba\x0b\xe2\x7f\x8a.\xbf\x12~\xb3'\xe5R\ +GN\x89\xf8,\x90\x07d\xadS\x96Kj\xb2\xac\x91\ +\x0b\x14\x22\x88\xfa\x8b\xcb\xe1;dY\xc0\xc0A\x8f,\ +\xb4\xec\x8eb1\x1c\xe1\xc2x\xfb\xfa\x80e\xcb\xa4\xa0\ +=\x07\xb6\xbe\xb0\x8eV\xc0~a\xa3S\x98~R\xb0\ +\xbe\xe8\x96\xe1bA\x0f\x0fL\x80uhy\x85\xd6K\ +\xb6\xf0\xa1\xc8\x1e\xd7B6\x82\xa9?\xa7br\x22\x0f\ +I\x98P3\xd9\xeb\x0c\xabW\xc0r\x06\xfa\x82X8\ +\x22\x1e\xa7Ku\xd2>U\xab\xda\xa7\x8b9\xddN\xf6\ +\x9aY\xa7\xefi\x15\xad\xee\xcbh\xa2}\x99q\xa5\xe5\ +$\x17\xa8\xcdy\xce\xde~\xd5i\xe2{@\xf1\x1c`\ +@\xddRh\x95\x0c\x9a\xdf\x0f\xd4s\xe5;$\xf5(\ +7\xbf\xdc(\xaf\x90mm\x94\x0f\xea\xec\xa7\xceL!\ +\x93\x8c\x07-\x07t\xf4\x03\xdd6\x07th\xa2\xc9\x94\ +_~\xaf\x8e\x06\xad\x92dp\xbc\xd8\xb4\xdfs\xfaK\ +\x82h\xd0\x81#K?\xc5\xf8~\xbf>\xeaj\x1e\xbf\ +O,\x0bM<%\xcd|$a\xf4\x9f\x81\x09\xfd\xf5\ +\xe5~G>j:rM\xc2\xc8o\xc9\xfc\xb0._\ +\x8c\xe5%\x04\xff\xd6\x82&p\xa3\x91\xaf\xbc\xf9\x9a1\ +\xab,&\x22\x97n\x22\xb0\x1d\x19.\x1d\x80\xed\xaf\xaf\ +\xbf\xe2\xcb\xcb?v\x05//\x7f%\x9f\xfd\x874\xa0\ +[Wg\xacD3;\x15\x1a\x0f_\x90\x07\x0b:\x11\ +\x8c\xf4\xf2\xf2.V<\xf8\xe5\xbdY\xa0G \xab+\ +\x1fm\x0c\xdcG\xdd\xe2v\x85\xb4\xb0\x00\xee\xb5J\xc0\ +3\xf8\xeb\x00w\xaa8sa,a.\xfcNJ\xed\ +y*\x0c\x1b\x8e[\xc2\xa8?\xe9\xee\xf2\x05\x87]\x07\ +\x01,\xda\xe5\x1e\x00\x8e\x09\x00F\xcd$\xc2\xa3j\xac\ +\x97\x88c\x92\x08\xf1Aw14\x06\x08!\x01\x1c\x87\ +/f\x19U\x1fs`\x17uo\xd0\xa3&\x83f\x13\ +\xbf\x1bc\x96\xe6R\x19\xc9\x0d{\xcd\xae\xa0*\x07\xbe\ +\x0e\xde~\xfc\xe3\xb6U\x1f\xcb\xf4\xa4\xcdX\xc4\x05D\ +\xc4\xaa\x80\x8f\x92<\xe1\xdf\xc0\xd2'\x08\xa4\xb8\xc0\x02\ +\xba\x07\x14\xe4*\xb4\xf2m\xf0\xc8+\x1b\x00SYB\ +\x1c\x05\x8c\x01sO\x1e\xf1\x7f\x91\xde\xb0\xaeDL\x8b\ +\xfat\xd9\x19o\x0f!\x9b\xc8\xb9\xb3}\xfdr\x11\x89\ +\xf9S\xb2\x9c_\x87Jc+\xe1\x89[\xa6C[\xa1\ +\x9b\xc0\xa6\xf2\x81T\xe3\xbd\x18\xdc\xab\xb5\xc9Sv\xb2\ +\x06\xfb[&\x97@\x0bB\xbc\xeb{\xdd\xf2\xd8\x81&\ +\xf2w\xb3\x99W\x22\x98\xcc\xde(\xc4\xc6\x82\x84\xec\x90\ +\xce\x84\xf0\xe8\xc6\xa5\xb2pu\xdbX\xfd\xac`}\xf9\ +3!\xcez\x0d\xf1!;\xe1r\x82\xb9\x83\xf0\x06\xc6\ +\x9e6\x82\xef\x12pu\x00\xf1w\x22\x9d\xd7\x87\xde\xed\ +\xc1\xe4\xe7n,v\x02;\xeb\x1c]\x09\x1a\xef\xe4\xf9\ +\x95\xc1#D\x16\xc0\xc5\xc7X\x12\x05_*\xe8\xb3\x89\ +\xe4\xb5\x1e\xf3)\x11t\x8e7\xec\xd3\x06\xf8\x09\xb9\x0f\ +\x03CwM\x91\xd0e\xcb\xbd\xd4\x09\xaaF2\xe7\x02\ +G/\x87x\x05\x1c\xff\xc6*\xea\xce\xb6/\x00\x0e\xb4\ +\x07\xc1\xf0\x85\xfb\xbd\xd9\x82\xdd\x89\x9f\x10\xec\x12_\x91\ +E\x86\x01\xdcT\xb8\xec-{X\xbc\xa8\x17yAs\ +\x5c\xa0\xdf\xc3&\xb8^\xc7\xfcu~\xaaaz,\xfc\ +Wh\x13\x93\xde\xc3&a\x02\xcf\xe6\xe4\x1fQ\xdf&\ +]\xc8;\x9d\x1e\x9dL\x1f\xe7\x9eL\xe7\x9eJ\xcf\xeb\ +:)\xcc\x88\xb9\xa7\x13\xe3\xcb\x07\xb0i\xf5\xb88\xb4\ +\x1d\x1f\x0f\x96\xfa\x9aL\xef\x178(\xfea\xf0\x1b\x19\ +`[\xc7\xc4G'%\xa6P|q\xae\x15\xf8\xcb\xee\ +\xe8\xd21\xc5\xa5\xa7\x90Ig\x15f\xf0\xb8d\xf3\xa9\ +\xc1\xfe\x9a\x09\x88_mw \xc2\xe7i1\xe6*\x9c\ +r\xe1x\x0e\xefF\xa6\xd2F\xcb.\x0e\x8f\x9e\xe9\x03\ +4\x16\x8f\x18\xc8\x06\xb0,\x85,\x99\x9eV\xc4\xaa\xa3\ +\xb4\xc8U-\x22\xd4-\xa7\xc4\x12=\x88\x1a\x96\xd4d\ +\x8e.\xab\xa1\xcar4\x190!\x1e\x98~pPY\ +\x18\xca\xce+\x99\xa7\xcb\x04WU\xe5\x5c\xf1\xc5Ud\ +\xb5\x85\xca\xd3y.\x9a\xeaB\xc5\x8e+\x18\xbe\xeb\xd2\ +\xc3\xa0\x8e\xa5\xdb\xe4\x17\xb2\xef\xe1\xd2w\x99^\xda\x83\ +Te\xbb\xd0\x09\xb92\x91\xe1\xafI\x97\x07\x94\x15\x03\ +\xdd\xb2\x84V\x12\xbf\xf0\x01H\x17'\xdcc*E\xb0\ +\xe8\x19\xdf`K\x93\xae\xf0=\x7f\xb9\x04\x1e\x05.B\ +x\xdf\x12$\x0a\x90'X\xbfo[\x0f\xdb\xbc\x94\xd1\ +\xa8n\xc1\xa5My\xc9m\x99p\x86Zvo\xa2B\ +\xef-}\x19\xfe\xfcFM\xa6\xbf\xf2\xde\xde\xb9:\xb4\ +H\xd7r\x0b|\x7f\x07\xe8>2\x19B%\x81\xc9\xf4\ +\x7f\xe1\x9b\xe6\x86\xd7w#\xa4\x8d\xe7\x10\x95\xb5v,\ +\xc0Z3*SL\xba\x88\xde\x92\x05F\xcc#\x1a\xef\ +_\xb1\xa4\x8a\xb3\x90\xe5ek\x0a\x8d\xe1\xc90?U\ +Sd\x0e\xab\xe7\xd3\xe9t\xa4\xe6\xdfu\x98\x97\xac\xa9\ +\x8a\xa0\x1f\xc4t#\x96-%%\xf7\x16\xc5\xa2(\x86\ +*\xcd\x04\x1c\x134CW \xcd\xdby\xd4-\x1f\x08\ +Z\x19\xd5i\xa5\x82\xf0sW\xb1bkwX\xcf\xda\ +\x15\x9a\xf63\xae\xa5[\x22\x82\xae\x84&9\x97\xa1I\ +\xee6\x0e\xa0\x06\xa7\x07t\xd7X)DyR\x13\x05\ +\xbbd\xf4\xcc\x83\x16\x99\x0e:t\x0dW\xbf\xc7?\x07\ +\x07B\xd9(\xb6\xe62\xc4\x1ekP\x81\x1e\xf9\xda\x81\ +\xe4\x11\xddo\xb0\xa0\xb3@\xd4C\xb5\x0f;\xc7\x01F\ +\x1d\x0dT\x19OK\xf8\xfbK\xf0n\x22\x83woB\ +\x9e\x04\xb4\x7f\x85\x13\xac\xfci\x0fD\x8f:\xd0\xab\xfe\ +2\xaa\x9f\xe8\xd5\x05\x9a3\x1b\xdc\xdb\x8b\xea/\x11\xb1\ +\x9a\xd9 \xa5}\x8co\x90\xb2>\x07\x12U,\xb2T\ +\x13\x7f\xa1\xf9W6y\xd6\x80\xc3\xde*+\xfa7\x95\ +\xd7\xd7'_\xd8n\xb2\x0b\xcc\x13\xe5q\xf7\xf4=|\ +\xce\xd9\xfb^!\x97P\x0e`\x83\x18\x10\xc4*\xd8\xfd\ +\xe2\x94\xa5[\xae\xe1[\xa2nb\xbfr\xac\x88\xa0w\ +M\x84 /\x8e3/\xb9\xe8\xbd\xbe\x86\xd6\x86\xac\xfd\ +}\x17R\x19\x0c\x7fs\xfa\xc7\xadA\xaa\x95\xd3\x19U\ +@]\x09y\x87\x7fY8D\x94\xea\x95\x13\x19Q\xcd\ +T\xfa\x0e=H\x1a\xfaH\x86\xe8\xbd\xa01\x933\x9d\ +\xb5\x9a\xd39\x80\xa0\x83\x9b\xce\xea\xe1M\xe7C\xd0\xc1\ +\xedH\xbb|SZ\xd2^\xc2I]\x1f\xfd\xa7_n\ +\xaa8\xe8K\xcd\x14\x03\xbb\xa9\x10\xdd4w\x96\x00\xad\ +\x01v\xd33\xe4\xca%p\x98\xa6\xed\xf3\xb5J\xe4\xf6\ +9\xfdxs=%\x8f3{O\xe1\x8e\xd1\xb9\xca_\ +%G+\xe4QN\x82\xee\xab\xb3L\x17\xf8\xd2\xc0\x93\ +\x84\x12\x16\xac:\x94I\x98)\x9f0\xe3|\xc2\xcc\x0a\ +\xe8\xa2\x9e7\xa4K\x19cx\xe7\xbbgz\xd2\xca\x09\ +p\x91KxU&\xe1\xd9}k\xd5(\x7fqH\x94\ +\x8f\x8e\x7f(\xff^{\xff\xbd\x07\xe2\x8f\xa4\x12\x7f\xd6\ +m\xe2\xdf\x84\xfb\x18m\x10?\xeb\x97\x84\xdc\x93>\xcd\ +8\xa0]TFdu\xd86\x22\x97t\xdaE\xd6\xe7\ +\x8c\xfe\xe3\x1a\xa0%\xab\xe7\xf9\xea\xa2\xca\xb5a\x85\x9a\ +\xeb\xf1\xd5\x0c\xa5h\x1f3kZ_\xa1\x1c\x15[\x09\ +\xec\xcbf,\x0f-5\x99<=\xaf\xae\xaa\xc6\xb3\x03\ +B\xcb[\x0b\x00G\xf9\xb7t\xa4\xbca\x09\xaa\xb2\xf3\ +\xca\xa3\xed\xc9d\xc0\xa4\xfa\xa4\x9a\xee}R\x99\xc0\x80\ +k\xdd\xf2r\x04_\x95>\xa3LF\xfe\xeb\xe1\xa9:\ +L\xfc\xbb:\x0b\xdf\xc8\xe12?P\x81\x1e\x22\x98{\ +p\xbd\x0f\xecTU\x01\x9f'\xfb\xe6\xb3h\xa2\x11T\ +\xb5t\x0c$\xcf\xb3\x1c\x0e G6\x03&\x17]g\ +\x00!\x8ad\xe2\xf3\xd7\xe7\xe0\xfe\x9e\xe6b\xa3^\x17\ +\x99\x0c\x18]\x1c\x9e\xf5PW\x05\x8f\xa5\x12f\xd6m\ +\x15L]\xdc\xad\xafS\xdc}\xac\xcf\xd5Y>\xc9\xcf\ +\xa7\x87e\xc9\xaa\x95l\xcdJv\xac:l\x7f}\xb2\ +\xdc\x8br=Z~\xd6#\xfaB\xaaB\x9d\xf6D/\ +\xa7-&Re=\xc7\xdd\xad\x9ewD]|\xdb\x83\ +C\xf1\x5c\xaa\xa0\x0f;N\xf1\x0f{\xa0\xf8t/\xb6\ +zW(\xfe\xb6\x19\xc5k\x1d\x17b\xc9\x8e\xdb<.\ +$\xceB\xbd\x9f3C\xb9wK\xc882\xa4\x9e\x94\ +J\xb1#>&\xc4\x99\x1c\x17\x85\x09ux\x11a\xf1\ +\x84\xc5\x0a\xddy\xbf\xac\x98Q\xa7Y*\xa1\xa2\xec\xcc\ +\x99\x9ckA\x06y\x96\x84\xd6\xe3\x84.\x97\x0d\xcd\x8d\ +T\xf3$'\xfa\xa3\xf4\xb9\xc2\xbc\xa0\xdcm\x03\xc3\xa6\ +-8\xfa\x12\xdcb\xe0\xb47\x06~\xc0\xef\xcezi\ +Z\xbf\xc7\x98\x98\x9bxN^C5N\x97\x16$\xd8\ ++\xdd\xb40\xb5^\x93\xbcz\x12\xe7\x9dZ\xf3H\x22\ +\xc1\x8dx6\x1c\x0c8Z\xa0l@\x1d?\x9c\xael\ +0]\xe9\xbb\xc3\x8b\xee\x0d\xe7\x06\xe5\x95f\xb6\x05m\ +\xf0\xa7\xab;\x9f\x91\x09\xf2\x98\x1dQ\xed\xf2\xf2S\xac\ +\xf4\xe5\xe5\xef\x88\xfe\xddP\xd8H\xddl\xf7\x5c7\xa8\ +\x0c\xd1\x88X\x8f\x83\xeca\xe0\xed]\xb64\xeb\x14\x91\ +:\xc3\x00\x1e\x0b\x93{\xbb\xf9\x0dlX\x98\xdf_\xe5\ +?\xf9\x8c|\x0f\xe4\x97\xa7\x0f\xdf\x12\xc1\xf3\x80\x1b{\ +'.\x7f\xcb\x82\x11\xf5\x92=J\x7f\xc1:\xc4\x8b\x06\ +nGy\x8d\xaa+\xe9Y#%\xad\x0e\xdbQ\xce\xa5\ +\xe2\xbf2OR\xf5\xa4\x8e,U?Y\x9cL-\x9e\ +9\x01\x95\xf1\xe9\xbbh\xe9\x12Y|\xabo\xed\x03'\ +|\xb4\xd0\x0b\x1cy\x22\xbfT#\x87\x17e_\x18y\ +\x9a\xae^\x98\xf9\xab\x82\xd1\x9e\xa2K1\x9drw\x9f\ +\xc44\xe2\x07P&o>\x16\xdc.,c+\x824\ +\xd1\xa4n\xceQ\xd7\x8a\xc7\x5cs\x8e\xb8\xd2\xa4\xa7\xfa\ +\xc0!\x12\xbe\xd0\x8d\x87\x01#\xa6\xe8\x94k~y\xde\ +\xc2h\xff\xb2\x80\x0a\xf6\x9a\xf9\x09\xed\xeaHte)\ +CN\xdbBVi\xbf\xeb\x05e\x0c9\x95D,*\ +~\x08\x12fX\x99\x0b\xe5\xaa\xc9\xc1/\xcf\x10\x0bn\ +\x1f\x95\x10\x05J{x\x90r\x10\xdcO=\xf0V>\ +6\xd1\x93-\x92\x01nQ\xa9\xfc\xcf\x18\x0a\xc9\x02\xa9\ +\xd7\xf1\x97\x89W\x89\x96\xd2\x12\xf4\x99X\xc61\x9dN\ +o{\xdf\xe9\xf3\x22\x8f_\xc2\xd5w\xf5|\x1d\xf7\xf0\ +]m\xae\xe3\x8e\xbdh\xf7w\x9a>\xcb\x1c\xf9\xf24\ +-\xe5\xcb\x8b;\xf1\xd2$\xe4\x8d\x22>\x84\xf7pg\ +\x11\x883\x1do=2\xe4\x8b\x94Df\xf8v\xa5\x9b\ +f`\x10G'\xf1B\xcd~&*@\xe0>\xf7\xbd\ +\x07\x1c\xdd\xd51rEU\x10\x81\x06\x98,\x02\xefu\ +z\x84Z\xd8\x98\xfe\x08\x82C+\x0d\x9b\xfc\xe1\xc3\xed\ +\xa8\x92\x82ZD\xf9_\x81\xe5T\xa3<\xfd\xa2\x06\xe5\ +]\xe0 \x17\xcf\xa1\xe7\xf9@4\x14\x13z\x06r\xcd\ +\x86\x04a\xf7\xb2\x05\x97>\x17\x17\xfb\x81\x1b\xb6\x16\x5c\ +.\x1d\xe6\xe4\x13\x15d\xc9\xe1J\x943\x91M\x8a\xd4\ +\xe3\xe8w\x08\x9e\xaaq\x94~Q\xc8\xd1\x82V\xef\x88\ +\x86\x22@4g\x80\xbakA\x9c\xb5|\x1b\xbd\x10|\ +\xacxx\x93\x99\xd5\x1c8\xe6\x10\x8c5;\xa7\xf7\xa4\ +\xed\xf2@q\x8aQ\x1dW\xb2\xd4\x02x\xd0\x04\xc5\xe5\ +|\x9b\xba`\xb7\xbcLj\x89\x22\xaa%\x5c$%\x89\ +E\xbf\xa9E\xa35\xf9p\x1ehA\xe1\xb0X9S\ +w\x1f\x8aKY\x14\xffs\x07\xcf\x01\xbc\x15z\x9a\xe3\ +\x80\xdb\xf9\xf2\x9f\x95\xa7&\xd3sK\xe7fs\x9cu\ +=\x99i,\xaf\x94\x09\x1e\xa1\x917{y\xddc\xea\ +\xefLP\x80\xcdiQ\x01\x06\xe3g\xc5\xe6\x03Y5\ +b?\xee\x14\xf0\xd8\x83\x1d;2\xeeM\xc2\x87X\xf1\ +\x88w|{\xe3\x09\xda\xc4\xb4\xba\x8b\xcbm,]\xae\ +\xb3Q\xe8\xe7\xa9\xa4\x22\x19S!\xbd\x85\x80\x1e\xe3\x87\ +\x04\xf9'\x03\x8b*\xa1R\x14\xcf\xe5\x92H\xe0\x12\x9a\ +:\xda(\xcf\xd2\x19e,\x9d\xdd\xe7\x99\x963\x1bi\ +\x01\x01\xdf\xb8`{\xabj\xe0\x03\xbdC\xce\xdd\xee]\ +\xdc\xe5\x99\xd9G\xcb\xab\xf4-\xf9\xf0!I\x99\xcc\x82\ +\x93S\x99\xd8**0\x8a\x8a\xac\x8f\xc2\xc9U\xca\x0e\ +*\xabdK\xea\xd8z\xbd\xca\xcc\xf8\x92\x13\xbeNc\ +<\xf3\xa8\xd8:*6\x1d\xea\xf4%k<\x091\xe5\ +\x06\x19\x0f\xc9\xadp\xf3)\x9183g\xdb\xb1hB\ +\x8e\xce'93r|1\xac2%\x8bs;\xf1\x9a\ +\x9f\x8c\xc6\xa3\x8bi+=\x08p\xf2clQ\x9c\x8e\ +\x01\xa8\x99,4\xb5\xa0-\xeaG\xca\xad\x10b\xf5Y\ +\xb9\x8f\xef-\xa4\xd3\x8b\xc3\x0b\xf1\xa7\xa0\x1a@\x14\x90\ +\xbb;\xb5\x1fl\xcc\xecd\xea\xf2r\xf7\xf7\xfb\xa0l\ +\xfc\x11uMP\xfd\xf0W\xf9O\xde\xd3\x8eW\xfc\xe6\ +s\xa0\x85b\xbb'E\xe3\xd2-\x0b=\x01\x93b{\ +jl\x89\xb6\xe8{\x9a\xaf\xc5J>\xf2*\xb4$\xd0\ +\xbaAzW%\x8c\x15)P\xbci%c&z\xb4\ +\xad:J\x0d\x91\xdc\x08\xc8\xaa\x19a\xb0\xcc\xaenz\ +\xc2\x18\xc4n\x94N\xef\x8c|\xcf\xec\x8cDY\x953\ +If\x93\xee\xb7\xd2w-\xc5C\x03\x0b\xafY\xda\x1d\ +\xcf%S\x91\x97\x1a\x90\xe7=\xaa\x16\x013\xccl\xf4\ +\x04{k\xd3\xbc\xc0\x90\xe2\xab\xf8\x00\xa6:\x1e\x83\x17\ +sd\xe7\xc7\x1e\xd4\x89<(\xeb\xd1\xcc\x8f:\xa8\x1f\ +sP\xa1\xed\x9c\x1b\xfc\xea\x9c\xd8*\xed}\x16\xe67\ +\x1e\x09\xc5\xe6\x9bnB\x94\xf4N\xbb\x8b\xf9\xa3\xeeB\ +*\x16D\x80\x80C\x8c4\xdf;\xd0\xdd\x90?\xe8%\ +\xe9\xd06\x5cv\xbf\x17\xdb\xc3d9\x0d\x9f 6V\ +\xa7\x7f\xff\xdb\x9bG\x82\x81\xb4o,\xe7O4,\x85\ +\x0eKy\xb0\xd1\xc2\xa3w\x829\x88\x82\x11\xa4nS\ +\xe0z\x0a<\x05\xa7\xca#\xa5$\xbb1l\xe1R\x85\ +o\x03\xcf;m\xc9\xd3\xfe=\xd1-2\x9a\x83\xf4\xba\ +\xb3\x00Db7\x8a\xdc\xed\xc92-\xec\xb3\x84Q;\ +\xb9\xf7$\x09S\xf1\x17\x9c\xdf\xad\x0cW\x824\xfc%\ +\x99U\x9c\x82\x9f\x97u\xb4 \xfd~Q\xf2}N\x8e\ +\xd1<\xaed\xd2\xee\x8b\xb8r.\x0f\x7f\x1c\xdf[\xcd\ +\x17\xc1\xd3\xc3\x04\x1ez\x81\x1f\x85\x14\xdaS%\xe8)\ +\x05\x8b0\xc5\x18\x85\x11\x02A+\x85\xba\x1d\x95\x91\xc2\ +\xf4pk\xf8\xf1e\xd7\x87\x83D\x8e\xdf \xc6`\xf5\ +\x85\xd8C@x?H\xb6\x5ck\x082\xcd\x05\x90R\ +\xf2\xf9\xf2\xb6UA\x90\x00\x19\x01\xb2\x81B\x96\xfd\x04\ +\xa1\xd8\x1d\x98\x81n\xa4\x22K\x17\xe9DH\x1f\xc0i\ +{Q*\xf80w\x8e\xe9\x1e0Y\x08\x9a\xe9\xa5t\ +Q\xb1\xd6\xe4p\xd2\x96\xcd\xb6\x86\xf6a\x1bm&8\ +&\xa3\x8d\x8c\xe6p\x8d6\x17\xac\xc9\xb2\xa6\xd0n\x8b\ +\x17kM\xe05y\x02ol\x0c\xebP\x01\xf8\x1d\xed\ +\x9b\x82W.\xf2\x97A\xf2Q&\xe6\x9er\x0f]\x0f\ +\xefV,\xbam\x92R\xc0\xdeN\x87\x9f\x15\xca\x04\x85\ +F,\xb1\x97d\x06\xe0pNXp;'\xd6\x88T\ +\x12\xcc\x17R'-\x17\xcc\x0bfs\xdc\xd3\xf4\x94\x81\ +XRC\xaf\xad\x09\x10\x0c\xd1;X\xac\x7fpY\xee\ +\x7f\xdd\x05&\xa1\xb9H\xfay%[\x9b\x00#y\x13\ +\x801:\x80{\x22>\x9d\x00{'\xf4\xb7\xa4\xf1>\ +.\xdb\xbe\x85\xe1\x80\x14\x0cK\xbe\xb0\x98\xbf\xdf5s\ +\xa8 \xbfD\x03\xc7\x05\x8f\x10\xf9B1\xcf\x14ko\ +}\xde\x8a\x8c\x13\xd0\xec\x84\x17\xaa\xd32~\xa8\xde'\ +\x22\xbc6\x19@\x81|\xef\x8a\xb4&\xdbCy\xb2\x1d\ +\xec\xc0\x1e\xa8L\xdf\xa1\xe5\x92H\xeb\x02\xe0'@\xec\ +\x93H\xa8\xbd\x22\xd3\x04?\xa1\x013\x0a8B\xdd\x96\ +\xfc\x06}=H\xb9\x8dnH\x13\x9a\xdf\xa9B\xad\xc9\ +\xeeL\xa2\xf1\xed{\x18\xad_Nv\x05v)\xeb\xd9\ +A\x0a\x83\xc3\x8e\xea\x19`@j\xf2\x85g\x17x%\ +\xdbS\xd7\xb50\x8d\x9e\xe1\x8c\x9f\x81\xb5\xc0\x9e\x85\xa2\ +^p~\xf2\x9bT\xb0~\xbd\xbd\xe4\xf3z{\xc9\xf7\ +\x94\xf3l'\xa1\xde\x86r\xe1&\xf9\xb8\xd2\xe1\xc1\xe4\ +\xd1\xcc9\xbd\xd7r\x89\xd2\x89C\xaa\xcc\xc3\xb0\x82\xcb\ +\xa6)9\xaa\x9e\xb7I\x0d\xc4\x04\x9e\xe1B\xa7X\xd5\ +\x8aRC\xef\xeax\xe9\xe1@\x93\xba\xbd\xee!pk\ +\x8f\xe6\xe3\xb6\x8a\x97\x1e\x8c\xab\xdbKP{\x1c\xdf\xe8\ +\xd7\xed\x0fA\xb0\xa5\xd8o(\xca\xdeP\xac\x86\xd8\xc9\ +\xd2\xc9\x80\xc5\xca\xd1\x8ba@g\x1b\xd1{\x0f\xe1\xb9\ +}\x19\xf1{\xdd\x0f\xc1k+\xa0\xeew\x94|\x22'\ +\x9c\xee\x86\x89\x85\x92=/s`\xb1t\xbb\x98\xb8\xca\ +\x86\xc2\xa4d4]\x0a\xbd#\xa9\x16\x99?)\xf4N\ +F\x9b\xe6 \x85\x9c)/\x8a\xb5\xce?0\x90\x9e\xdd\ +E\x06\x7f\x9e\xbb\x02\xe2\x95\xbf\x18\x10\xdb\xe3\xa1\xe0\x94\ +2\xafd\xb5x\xde\x18\x89\xb7\x9a\x91\x0dVa\x83\x15\ +\x0a-\x91:F&.\xc9\xe2!\xe1\xadS,\x88\xf4\ +\x7fZA\xf1\xc5\xeb\x99b\x8di\xf5\x86\x8e\x92w\x92\ +\xba0\xa4\x9c(\xe9o(\x06\x18\x81R\x7fc\x04\xca\ +\xfcs\xf8\xfa\xf2\x92\xb5@\xffL\x9e\xf7\xa8\xca\x88\x1f\ +\xb8}.\xfc\x10z\xd8~`\xa94\xff\x8a\xdb$\xf8\ +\xd7F$O\x1e\xbd\xc2\xd3w\xad\xd3\x09\xeb\xcf\xc0\x1b\ +\xdcC[\xb7\x0d \xdc\xea\xe5\x95l\xae(\xd80\x1b\ +\x22\x81\xe8\x88\xa0$\x1c\x90H\xf1\xdc\xb3w\x85\xe5\xe4\ +L\xe5\xe0(\x97\x1c \x7fc\xe1\x7f|h\xc8=\xa1\ +\x8b\xe4P\xd9\xc7u\xbe\x94()\x87\x85\x81\xfb@\x8a\ +j\xaf]\x9fH$n\x1a\x88\xc4\xee\x04w\xfb\xcbC\ +d\xf8\xf4\xaa\xfb\x01mt\xa0[\x968~\x97[\xb8\ +9CIu\xca\x17:`9\xfc\xa4\xd5E\xf7\x90;\ +\xd5\xab\x15\x9al\xb7\x0d\xf4Yx\xde\xbc}\xa6\x06\x0d\ +\x09Y\x19/\xd2\x5c\x85\x05\xb5I\xe1^X\x97r\x0b\ +\xdcG\xd0\xc0\xda\x8a\xe7\x9dl\x91\xd6-%h\xac5\ +\x8d\xb2Y,\xeb\xce\xa0\xdc\x94\x9b\xd58\xb0\xcd\xf6X\ +\xb0[]\xd3\xd7\xde&\x1be\xe4@\xac\xc7\xc4t\x96\ +\xc8\xda<\xccIhY\x85\x85\x89\xfc\x1f\xad3\xc1\x06\ +\xf8\x09\xb9\x0f\x03\xa3\xc0\xaa\xc8\x96kL\xf6\xb7\x1f\xff\ +\xb8m\xc7Y3(]\xb5\x90\x13\xb1\xa4\x5c\xad\x9a\x89\ +<\xe2\xd0\xed9\x8f\x9d\xb9\xab\xdf\xff]\xb6\xb0\xbdw\ +\x9f\xe6\xee.\xee}Y\xc6\x96\xab\xad\x98\x16aN\xb4\ +\x97\xa1F\xd0\xb8\ +\x8cG\xdd\xa0oW\xb5['\xe8\xbb~\x9e\xa8\x17\x1d\ +5\xcf\x0e\x1f V\xde\xdc\x04\x0b\x7f\xc9h4\xa7\x19\ +9\xf8\xa4\xf6\xd8\xf5'\x9f\xd1#\xa1\x13i&\x7f\xcb\ +\x93\x0e`>\xcb%\xf6\xef\xfe:\xfa\xbe6\x99G\xda\ +Ej7yx\xd1\x90\xcc\xe7\xd3I\xba\xcaYu2\ +\xc7\x7f\xd3\x12Wg>$\xff\xfd?\xedd\x22$\ \x00\x00\x04\x8e\ <\ svg width=\x2264\x22 h\ @@ -649121,147 +649150,147 @@ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x1a\x00\x02\x00\x00\x00G\x00\x00\x00\x05\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x07\xb4\x00\x00\x00\x00\x00\x01\x00\x9a\xdbI\ +\x00\x00\x07\xb4\x00\x00\x00\x00\x00\x01\x00\x9a\xdd\x1e\ \x00\x00\x01\x93A\x0c\x9cT\ -\x00\x00\x092\x00\x00\x00\x00\x00\x01\x00\x9c\x05\xf0\ +\x00\x00\x092\x00\x00\x00\x00\x00\x01\x00\x9c\x07\xc5\ \x00\x00\x01\x93A\x0c\x9cc\ -\x00\x00\x07V\x00\x00\x00\x00\x00\x01\x00\x9a\xc6\xaa\ +\x00\x00\x07V\x00\x00\x00\x00\x00\x01\x00\x9a\xc8\x7f\ \x00\x00\x01\x93A\x0c\x9c_\ -\x00\x00\x0bD\x00\x00\x00\x00\x00\x01\x00\x9d-K\ +\x00\x00\x0bD\x00\x00\x00\x00\x00\x01\x00\x9d/ \ \x00\x00\x01\x93A\x0c\x9c]\ -\x00\x00\x0bh\x00\x00\x00\x00\x00\x01\x00\x9d/\xa1\ +\x00\x00\x0bh\x00\x00\x00\x00\x00\x01\x00\x9d1v\ \x00\x00\x01\x93A\x0c\x9cd\ -\x00\x00\x08`\x00\x00\x00\x00\x00\x01\x00\x9b=l\ +\x00\x00\x08`\x00\x00\x00\x00\x00\x01\x00\x9b?A\ \x00\x00\x01\x93A\x0c\x9cR\ -\x00\x00\x0b\x1c\x00\x00\x00\x00\x00\x01\x00\x9d(?\ +\x00\x00\x0b\x1c\x00\x00\x00\x00\x00\x01\x00\x9d*\x14\ \x00\x00\x01\x93A\x0c\x9cV\ -\x00\x00\x09\x5c\x00\x00\x00\x00\x00\x01\x00\x9c\x11\xef\ +\x00\x00\x09\x5c\x00\x00\x00\x00\x00\x01\x00\x9c\x13\xc4\ \x00\x00\x01\x93A\x0c\x9cW\ -\x00\x00\x06\xa2\x00\x00\x00\x00\x00\x01\x00\x9a\xa9K\ +\x00\x00\x06\xa2\x00\x00\x00\x00\x00\x01\x00\x9a\xab \ \x00\x00\x01\x93A\x0c\x9cb\ -\x00\x00\x08\x98\x00\x00\x00\x00\x00\x01\x00\x9b\xc1\xbc\ +\x00\x00\x08\x98\x00\x00\x00\x00\x00\x01\x00\x9b\xc3\x91\ \x00\x00\x01\x93A\x0c\x9bf\ -\x00\x00\x0a\x80\x00\x00\x00\x00\x00\x01\x00\x9c\xa4{\ +\x00\x00\x0a\x80\x00\x00\x00\x00\x00\x01\x00\x9c\xa6P\ \x00\x00\x01\x93A\x0c\x9b\x84\ -\x00\x00\x08\x1a\x00\x00\x00\x00\x00\x01\x00\x9b\x10\x83\ +\x00\x00\x08\x1a\x00\x00\x00\x00\x00\x01\x00\x9b\x12X\ \x00\x00\x01\x93A\x0c\x9b\x9c\ -\x00\x00\x0c4\x00\x00\x00\x00\x00\x01\x00\x9d\xed\x1d\ +\x00\x00\x0c4\x00\x00\x00\x00\x00\x01\x00\x9d\xee\xf2\ \x00\x00\x01\x93A\x0c\x9c_\ -\x00\x00\x04\x8e\x00\x00\x00\x00\x00\x01\x00\x98\xd3O\ +\x00\x00\x04\x8e\x00\x00\x00\x00\x00\x01\x00\x98\xd5$\ \x00\x00\x01\x93A\x0c\x9cS\ -\x00\x00\x0aV\x00\x00\x00\x00\x00\x01\x00\x9c\x91\xc0\ +\x00\x00\x0aV\x00\x00\x00\x00\x00\x01\x00\x9c\x93\x95\ \x00\x00\x01\x93A\x0c\x9c[\ -\x00\x00\x05X\x00\x00\x00\x00\x00\x01\x00\x99\xe3G\ +\x00\x00\x05X\x00\x00\x00\x00\x00\x01\x00\x99\xe5\x1c\ \x00\x00\x01\x93A\x0c\x9c3\ -\x00\x00\x0a\x96\x00\x00\x00\x00\x00\x01\x00\x9c\xcd%\ +\x00\x00\x0a\x96\x00\x00\x00\x00\x00\x01\x00\x9c\xce\xfa\ \x00\x00\x01\x95\xaf\xc1\xa0E\ -\x00\x00\x05j\x00\x00\x00\x00\x00\x01\x00\x9a\x06\xbf\ +\x00\x00\x05j\x00\x00\x00\x00\x00\x01\x00\x9a\x08\x94\ \x00\x00\x01\x93A\x0c\x9c]\ -\x00\x00\x08\xcc\x00\x00\x00\x00\x00\x01\x00\x9b\xee\xdd\ +\x00\x00\x08\xcc\x00\x00\x00\x00\x00\x01\x00\x9b\xf0\xb2\ \x00\x00\x01\x93A\x0c\x9cV\ -\x00\x00\x08\xae\x00\x00\x00\x00\x00\x01\x00\x9b\xe9\x8c\ +\x00\x00\x08\xae\x00\x00\x00\x00\x00\x01\x00\x9b\xeba\ \x00\x00\x01\x93A\x0c\x9cd\ -\x00\x00\x0a\x06\x00\x00\x00\x00\x00\x01\x00\x9cu\x15\ +\x00\x00\x0a\x06\x00\x00\x00\x00\x00\x01\x00\x9cv\xea\ \x00\x00\x01\x93A\x0c\x9cc\ -\x00\x00\x06\xf8\x00\x00\x00\x00\x00\x01\x00\x9a\xba\xe8\ +\x00\x00\x06\xf8\x00\x00\x00\x00\x00\x01\x00\x9a\xbc\xbd\ \x00\x00\x01\x96\x9dK\x1a\x05\ -\x00\x00\x03|\x00\x00\x00\x00\x00\x01\x00\x98\x1a]\ +\x00\x00\x03|\x00\x00\x00\x00\x00\x01\x00\x98\x1c2\ \x00\x00\x01\x93A\x0c\x9cW\ -\x00\x00\x09\xc4\x00\x01\x00\x00\x00\x01\x00\x9cl\x13\ +\x00\x00\x09\xc4\x00\x01\x00\x00\x00\x01\x00\x9cm\xe8\ \x00\x00\x01\x96\x9dK\x1a\x05\ -\x00\x00\x080\x00\x00\x00\x00\x00\x01\x00\x9b7\xda\ +\x00\x00\x080\x00\x00\x00\x00\x00\x01\x00\x9b9\xaf\ \x00\x00\x01\x93A\x0c\x9cU\ -\x00\x00\x08\x04\x00\x00\x00\x00\x00\x01\x00\x9a\xe8\xc9\ +\x00\x00\x08\x04\x00\x00\x00\x00\x00\x01\x00\x9a\xea\x9e\ \x00\x00\x01\x93A\x0c\x9b\xdb\ -\x00\x00\x09\x16\x00\x00\x00\x00\x00\x01\x00\x9b\xf6}\ +\x00\x00\x09\x16\x00\x00\x00\x00\x00\x01\x00\x9b\xf8R\ \x00\x00\x01\x93A\x0c\x9cU\ -\x00\x00\x05\x02\x00\x00\x00\x00\x00\x01\x00\x99\x8e\xcb\ +\x00\x00\x05\x02\x00\x00\x00\x00\x00\x01\x00\x99\x90\xa0\ \x00\x00\x01\x93A\x0c\x9b\xe1\ -\x00\x00\x0cZ\x00\x00\x00\x00\x00\x01\x00\x9d\xf8\xab\ +\x00\x00\x0cZ\x00\x00\x00\x00\x00\x01\x00\x9d\xfa\x80\ \x00\x00\x01\x93A\x0c\x9b\xe3\ -\x00\x00\x0a\xdc\x00\x01\x00\x00\x00\x01\x00\x9d\x0c\x19\ +\x00\x00\x0a\xdc\x00\x01\x00\x00\x00\x01\x00\x9d\x0d\xee\ \x00\x00\x01\x93A\x0c\x9c`\ -\x00\x00\x07*\x00\x01\x00\x00\x00\x01\x00\x9a\xc0\x19\ +\x00\x00\x07*\x00\x01\x00\x00\x00\x01\x00\x9a\xc1\xee\ \x00\x00\x01\x93A\x0c\x9cV\ -\x00\x00\x04h\x00\x00\x00\x00\x00\x01\x00\x98\xb4g\ +\x00\x00\x04h\x00\x00\x00\x00\x00\x01\x00\x98\xb6<\ \x00\x00\x01\x93A\x0c\x9cc\ -\x00\x00\x0b\xb6\x00\x00\x00\x00\x00\x01\x00\x9d\x92%\ +\x00\x00\x0b\xb6\x00\x00\x00\x00\x00\x01\x00\x9d\x93\xfa\ \x00\x00\x01\x93A\x0c\x9c\x00\ -\x00\x00\x0b\xcc\x00\x00\x00\x00\x00\x01\x00\x9d\xbd\x22\ +\x00\x00\x0b\xcc\x00\x00\x00\x00\x00\x01\x00\x9d\xbe\xf7\ \x00\x00\x01\x93A\x0c\x9c\x04\ -\x00\x00\x05\xda\x00\x00\x00\x00\x00\x01\x00\x9ab\xc8\ +\x00\x00\x05\xda\x00\x00\x00\x00\x00\x01\x00\x9ad\x9d\ \x00\x00\x01\x93A\x0c\x9cN\ -\x00\x00\x04\x08\x00\x00\x00\x00\x00\x01\x00\x98e\x16\ +\x00\x00\x04\x08\x00\x00\x00\x00\x00\x01\x00\x98f\xeb\ \x00\x00\x01\x93A\x0c\x9cP\ -\x00\x00\x04\xc8\x00\x01\x00\x00\x00\x01\x00\x99S\xad\ +\x00\x00\x04\xc8\x00\x01\x00\x00\x00\x01\x00\x99U\x82\ \x00\x00\x01\x93A\x0c\x9cZ\ -\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x01\x00\x9d\xeb\x1f\ +\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x01\x00\x9d\xec\xf4\ \x00\x00\x01\x93A\x0c\x9c^\ -\x00\x00\x04(\x00\x00\x00\x00\x00\x01\x00\x98l\x92\ +\x00\x00\x04(\x00\x00\x00\x00\x00\x01\x00\x98ng\ \x00\x00\x01\x93A\x0c\x9c_\ -\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x98%\xe4\ +\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x98'\xb9\ \x00\x00\x01\x93A\x0c\x9c\x0d\ -\x00\x00\x04R\x00\x00\x00\x00\x00\x01\x00\x98\x82\xba\ +\x00\x00\x04R\x00\x00\x00\x00\x00\x01\x00\x98\x84\x8f\ \x00\x00\x01\x93A\x0c\x9c(\ -\x00\x00\x0cp\x00\x00\x00\x00\x00\x01\x00\x9e\x1aT\ +\x00\x00\x0cp\x00\x00\x00\x00\x00\x01\x00\x9e\x1c)\ \x00\x00\x01\x93A\x0c\x9c*\ -\x00\x00\x060\x00\x00\x00\x00\x00\x01\x00\x9a\x97K\ +\x00\x00\x060\x00\x00\x00\x00\x00\x01\x00\x9a\x99 \ \x00\x00\x01\x93A\x0c\x9cT\ -\x00\x00\x0b\xe2\x00\x00\x00\x00\x00\x01\x00\x9d\xe7\x88\ +\x00\x00\x0b\xe2\x00\x00\x00\x00\x00\x01\x00\x9d\xe9]\ \x00\x00\x01\x93A\x0c\x9c]\ -\x00\x00\x05\x94\x00\x00\x00\x00\x00\x01\x00\x9a\x1a\x11\ +\x00\x00\x05\x94\x00\x00\x00\x00\x00\x01\x00\x9a\x1b\xe6\ \x00\x00\x01\x93A\x0c\x9c-\ -\x00\x00\x04\xb2\x00\x00\x00\x00\x00\x01\x00\x99*L\ +\x00\x00\x04\xb2\x00\x00\x00\x00\x00\x01\x00\x99,!\ \x00\x00\x01\x93A\x0c\x9c.\ -\x00\x00\x08\x84\x00\x00\x00\x00\x00\x01\x00\x9b\x94i\ +\x00\x00\x08\x84\x00\x00\x00\x00\x00\x01\x00\x9b\x96>\ \x00\x00\x01\x93A\x0c\x9b\x9c\ -\x00\x00\x05\xc6\x00\x00\x00\x00\x00\x01\x00\x9aDT\ +\x00\x00\x05\xc6\x00\x00\x00\x00\x00\x01\x00\x9aF)\ \x00\x00\x01\x93A\x0c\x9b\xb4\ -\x00\x00\x04\xee\x00\x00\x00\x00\x00\x01\x00\x99Z\xf4\ +\x00\x00\x04\xee\x00\x00\x00\x00\x00\x01\x00\x99\x5c\xc9\ \x00\x00\x01\x93A\x0c\x9b\xd4\ -\x00\x00\x07\x88\x00\x00\x00\x00\x00\x01\x00\x9a\xd8\xd6\ +\x00\x00\x07\x88\x00\x00\x00\x00\x00\x01\x00\x9a\xda\xab\ \x00\x00\x01\x93A\x0c\x9cP\ -\x00\x00\x0b\xa2\x00\x00\x00\x00\x00\x01\x00\x9dn\xb8\ +\x00\x00\x0b\xa2\x00\x00\x00\x00\x00\x01\x00\x9dp\x8d\ \x00\x00\x01\x93A\x0c\x9b\xde\ -\x00\x00\x0c\x86\x00\x00\x00\x00\x00\x01\x00\x9eF\xda\ +\x00\x00\x0c\x86\x00\x00\x00\x00\x00\x01\x00\x9eH\xaf\ \x00\x00\x01\x93A\x0c\x9cP\ -\x00\x00\x06\xce\x00\x00\x00\x00\x00\x01\x00\x9a\xae\xce\ +\x00\x00\x06\xce\x00\x00\x00\x00\x00\x01\x00\x9a\xb0\xa3\ \x00\x00\x01\x93A\x0c\x9cY\ -\x00\x00\x08\xf0\x00\x00\x00\x00\x00\x01\x00\x9b\xf1\xb5\ +\x00\x00\x08\xf0\x00\x00\x00\x00\x00\x01\x00\x9b\xf3\x8a\ \x00\x00\x01\x93A\x0c\x9cM\ -\x00\x00\x09\x92\x00\x00\x00\x00\x00\x01\x00\x9c8\x90\ +\x00\x00\x09\x92\x00\x00\x00\x00\x00\x01\x00\x9c:e\ \x00\x00\x01\x93A\x0c\x9cX\ -\x00\x00\x05\xf2\x00\x00\x00\x00\x00\x01\x00\x9a\x8c\x98\ +\x00\x00\x05\xf2\x00\x00\x00\x00\x00\x01\x00\x9a\x8em\ \x00\x00\x01\x93A\x0c\x9c\x5c\ -\x00\x00\x050\x00\x00\x00\x00\x00\x01\x00\x99\xdbL\ +\x00\x00\x050\x00\x00\x00\x00\x00\x01\x00\x99\xdd!\ \x00\x00\x01\x93A\x0c\x9cX\ -\x00\x00\x05\xaa\x00\x00\x00\x00\x00\x01\x00\x9a?x\ +\x00\x00\x05\xaa\x00\x00\x00\x00\x00\x01\x00\x9aAM\ \x00\x00\x01\x93A\x0c\x9cY\ -\x00\x00\x09|\x00\x00\x00\x00\x00\x01\x00\x9c\x15\xee\ +\x00\x00\x09|\x00\x00\x00\x00\x00\x01\x00\x9c\x17\xc3\ \x00\x00\x01\x93A\x0c\x9c4\ -\x00\x00\x07\xea\x00\x00\x00\x00\x00\x01\x00\x9a\xe1\x14\ +\x00\x00\x07\xea\x00\x00\x00\x00\x00\x01\x00\x9a\xe2\xe9\ \x00\x00\x01\x93A\x0c\x9c\x5c\ -\x00\x00\x0a\xc6\x00\x00\x00\x00\x00\x01\x00\x9c\xea\xe9\ +\x00\x00\x0a\xc6\x00\x00\x00\x00\x00\x01\x00\x9c\xec\xbe\ \x00\x00\x01\x93A\x0c\x9c;\ -\x00\x00\x0b\x8c\x00\x00\x00\x00\x00\x01\x00\x9d@\xed\ +\x00\x00\x0b\x8c\x00\x00\x00\x00\x00\x01\x00\x9dB\xc2\ \x00\x00\x01\x93A\x0c\x9c=\ -\x00\x00\x09\xac\x00\x00\x00\x00\x00\x01\x00\x9c@\x8f\ +\x00\x00\x09\xac\x00\x00\x00\x00\x00\x01\x00\x9cBd\ \x00\x00\x01\x93A\x0c\x9b\xb9\ -\x00\x00\x05\x18\x00\x00\x00\x00\x00\x01\x00\x99\xad\xaf\ +\x00\x00\x05\x18\x00\x00\x00\x00\x00\x01\x00\x99\xaf\x84\ \x00\x00\x01\x93A\x0c\x9b\xbe\ -\x00\x00\x0a>\x00\x00\x00\x00\x00\x01\x00\x9c\x7f\x13\ +\x00\x00\x0a>\x00\x00\x00\x00\x00\x01\x00\x9c\x80\xe8\ \x00\x00\x01\x93A\x0c\x9c^\ -\x00\x00\x0a\xee\x00\x00\x00\x00\x00\x01\x00\x9d\x1a1\ +\x00\x00\x0a\xee\x00\x00\x00\x00\x00\x01\x00\x9d\x1c\x06\ \x00\x00\x01\x93A\x0c\x9cO\ -\x00\x00\x06X\x00\x00\x00\x00\x00\x01\x00\x9a\x9e\x10\ +\x00\x00\x06X\x00\x00\x00\x00\x00\x01\x00\x9a\x9f\xe5\ \x00\x00\x01\x93A\x0c\x9cX\ -\x00\x00\x03\xa6\x00\x00\x00\x00\x00\x01\x00\x98\x1e\xef\ +\x00\x00\x03\xa6\x00\x00\x00\x00\x00\x01\x00\x98 \xc4\ \x00\x00\x01\x96\x9dK\x1a\x05\ -\x00\x00\x09\xe2\x00\x00\x00\x00\x00\x01\x00\x9cpJ\ +\x00\x00\x09\xe2\x00\x00\x00\x00\x00\x01\x00\x9cr\x1f\ \x00\x00\x01\x93A\x0c\x9cZ\ -\x00\x00\x03\xe6\x00\x00\x00\x00\x00\x01\x00\x98V}\ +\x00\x00\x03\xe6\x00\x00\x00\x00\x00\x01\x00\x98XR\ \x00\x00\x01\x93A\x0c\x9cZ\ -\x00\x00\x06l\x00\x00\x00\x00\x00\x01\x00\x9a\xa7\x0d\ +\x00\x00\x06l\x00\x00\x00\x00\x00\x01\x00\x9a\xa8\xe2\ \x00\x00\x01\x93A\x0c\x9c^\ \x00\x00\x00\x1a\x00\x02\x00\x00\x00\x18\x00\x00\x00M\ \x00\x00\x00\x00\x00\x00\x00\x00\ @@ -649316,9 +649345,9 @@ \x00\x00\x00\x10\x00\x02\x00\x00\x00\x02\x00\x00\x00f\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x03P\x00\x01\x00\x00\x00\x01\x00\x97\xfav\ -\x00\x00\x01\x98\x86\x0c\x5c\x97\ +\x00\x00\x01\x98\x86\x9d\x16\x03\ \x00\x00\x03f\x00\x01\x00\x00\x00\x01\x00\x97\xff~\ -\x00\x00\x01\x96\x9dK\x1a\x94\ +\x00\x00\x01\x98\xae!\xabU\ " def qInitResources(): diff --git a/src/dcspy/sdk/led_sdk.py b/src/dcspy/sdk/led_sdk.py index b718c9d3e..86d236ff4 100644 --- a/src/dcspy/sdk/led_sdk.py +++ b/src/dcspy/sdk/led_sdk.py @@ -1,183 +1,182 @@ from logging import getLogger -from threading import Event -from time import sleep from _cffi_backend import Lib from cffi import FFI -from dcspy.models import LedConstants, LedDll +from dcspy.models import EffectInfo, LedDll, LedEffectType, LedSupport from dcspy.sdk import load_dll LOG = getLogger(__name__) -LED_DLL: Lib = load_dll(LedDll) # type: ignore[assignment] - - -def logi_led_init() -> bool: - """ - Make sure there isn't already another instance running and then makes the necessary initializations. - - It saves the current lighting for all connected and supported devices. This function will also stop any effect - currently going on the connected devices. - :return: A result of execution - """ - try: - return LED_DLL.LogiLedInit() # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_init_with_name(name: str) -> bool: - """ - Make sure there isn't already another instance running and then makes the necessary initializations. - - It saves the current lighting for all connected and supported devices. - This function will also stop any effect currently going on the connected devices. Passing a name into this - function will make the integration show up with a given custom name. The name is set only once, the first - time this function or logi_led_init() is called. - :param name: The referred name for this integration to show u as - :return: A result of execution - """ - try: - return LED_DLL.LogiLedInitWithName(FFI().new('wchar_t[]', name)) # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_set_target_device(target_device: LedConstants) -> bool: - """ - Set the target device type for future calls. - - The default target device is LOGI_DEVICETYPE_ALL, therefore, if no call is made to LogiLedSetTargetDevice - the SDK will apply any function to all the connected devices. - :param target_device: One or a combination of the following values: - LOGI_DEVICETYPE_MONOCHROME, LOGI_DEVICETYPE_RGB, LOGI_DEVICETYPE_ALL - :return: A result of execution - """ - try: - return LED_DLL.LogiLedSetTargetDevice(target_device.value) # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_save_current_lighting() -> bool: - """ - Save the current lighting so that it can be restored after a temporary effect is finished. - - For example, if flashing a red warning sign for a few seconds, you would call the logi_led_save_current_lighting() - function just before starting the warning effect. - :return: A result of execution - """ - try: - return LED_DLL.LogiLedSaveCurrentLighting() # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_restore_lighting() -> bool: - """ - Restore the last saved lighting. - - It should be called after a temporary effect is finished. - For example, if flashing a red warning sign for a few seconds, you would call this function right - after the warning effect is finished. - :return: A result of execution - """ - try: - return LED_DLL.LogiLedRestoreLighting() # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_set_lighting(rgb: tuple[int, int, int]) -> bool: - """ - Set the lighting on connected and supported devices. - - Do not call this function immediately after logi_led_init(), instead of wait a little of time after logi_led_init(). - For devices that only support a single color, the highest percentage value given of the three colors will - define the intensity. For monochrome device, Logitech Gaming Software will proportionally reduce - the value of the highest color, according to the user hardware brightness setting. - - :param rgb: Tuple with integer range 0 to 100 as an amount of red, green, blue - :return: A result of execution - """ - try: - return LED_DLL.LogiLedSetLighting(*rgb) # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_flash_lighting(rgb: tuple[int, int, int], duration: int, interval: int) -> bool: - """ - Save the current lighting, plays the flashing effect on the targeted devices. - - Finally, restores the saved lighting. - :param rgb: Tuple with integer range 0 to 100 as an amount of red, green, blue - :param duration: Parameter can be set (in millisecond) to LOGI_LED_DURATION_INFINITE - to make the effect run until stopped with logi_led_stop_effects() - :param interval: Duration of the flashing interval in millisecond - :return: A result of execution - """ - try: - return LED_DLL.LogiLedFlashLighting(*rgb, duration, interval) # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_pulse_lighting(rgb: tuple[int, int, int], duration: int, interval: int) -> bool: - """ - Save the current lighting, plays the pulsing effect on the targeted devices. - - Finally, restores the saved lighting. - :param rgb: Tuple with integer values range 0 to 100 as an amount of red, green, blue. - :param duration: Parameter can be set (in millisecond) to LOGI_LED_DURATION_INFINITE - to make the effect run until stopped with logi_led_stop_effects(). - :param interval: Duration of the flashing interval in millisecond. - :return: A result of execution. - """ - try: - return LED_DLL.LogiLedPulseLighting(*rgb, duration, interval) # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_stop_effects() -> bool: - """ - Stop any of the preset effect. - - Started from logi_led_flash_lighting() or logi_led_pulse_lighting(). - :return: A result of execution - """ - try: - return LED_DLL.LogiLedStopEffects() # type: ignore[attr-defined] - except AttributeError: - return False - - -def logi_led_shutdown() -> None: - """Restore the last saved lighting and frees memory used by the SDK.""" - try: - LED_DLL.LogiLedShutdown() # type: ignore[attr-defined] - except AttributeError: - pass - - -def start_led_pulse(rgb: tuple[int, int, int], duration: int, interval: int, event: Event) -> None: - """ - Start the pulsing red effect in the thread on the keyboard. - - :param rgb: Tuple with integer values range 0 to 100 as an amount of red, green, blue. - :param duration: Parameter can be set (in millisecond) to 0 (zero) to make the effect run until an event is set. - :param interval: Flashing an interval in millisecond. - :param event: Stop event for infinite loop. - """ - LOG.debug('Start LED thread') - logi_led_init() - sleep(0.05) - logi_led_set_target_device(LedConstants.LOGI_DEVICETYPE_ALL) - sleep_time = duration + 0.2 - logi_led_pulse_lighting(rgb, duration, interval) - sleep(sleep_time) - while not event.is_set(): - sleep(0.2) - logi_led_shutdown() - LOG.debug('Stop LED thread') + + +class LedSdkManager: + """LED SDK manager.""" + + def __init__(self, name: str = '', target_dev: LedSupport = LedSupport.LOGI_DEVICETYPE_ALL) -> None: + """ + Create Led SDK manager. + + :param name: A name of the LED integration + :param target_device: One or a combination of the following values: + LOGI_DEVICETYPE_MONOCHROME, LOGI_DEVICETYPE_RGB, LOGI_DEVICETYPE_ALL + """ + if name: + self.led_dll: Lib = load_dll(LedDll) # type: ignore[assignment] + result = self.logi_led_init_with_name(name=name) + else: + result = self.logi_led_init() + # todo: maybe sleep needed + self.logi_led_set_target_device(target_dev) + LOG.debug(f'LED is turned on: {result}') + + def logi_led_init(self) -> bool: + """ + Make sure there isn't already another instance running and then makes the necessary initializations. + + It saves the current lighting for all connected and supported devices. This function will also stop any effect + currently going on the connected devices. + :return: A result of execution + """ + try: + return self.led_dll.LogiLedInit() # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_init_with_name(self, name: str) -> bool: + """ + Make sure there isn't already another instance running and then makes the necessary initializations. + + It saves the current lighting for all connected and supported devices. + This function will also stop any effect currently going on the connected devices. Passing a name into this + function will make the integration show up with a given custom name. The name is set only once, the first + time this function or logi_led_init() is called. + :param name: The referred name for this integration + :return: A result of execution + """ + try: + return self.led_dll.LogiLedInitWithName(FFI().new('wchar_t[]', name)) # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_set_target_device(self, target_device: LedSupport) -> bool: + """ + Set the target device type for future calls. + + The default target device is LOGI_DEVICETYPE_ALL, therefore, if no call is made to LogiLedSetTargetDevice + the SDK will apply any function to all the connected devices. + :param target_device: One or a combination of the following values: + LOGI_DEVICETYPE_MONOCHROME, LOGI_DEVICETYPE_RGB, LOGI_DEVICETYPE_ALL + :return: A result of execution + """ + try: + return self.led_dll.LogiLedSetTargetDevice(target_device.value) # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_save_current_lighting(self) -> bool: + """ + Save the current lighting so that it can be restored after a temporary effect is finished. + + For example, if flashing a red warning sign for a few seconds, you would call the logi_led_save_current_lighting() + function just before starting the warning effect. + :return: A result of execution + """ + try: + return self.led_dll.LogiLedSaveCurrentLighting() # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_restore_lighting(self) -> bool: + """ + Restore the last saved lighting. + + It should be called after a temporary effect is finished. + For example, if flashing a red warning sign for a few seconds, you would call this function right + after the warning effect is finished. + :return: A result of execution + """ + try: + return self.led_dll.LogiLedRestoreLighting() # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_set_lighting(self, rgb: tuple[int, int, int]) -> bool: + """ + Set the lighting on connected and supported devices. + + Do not call this function immediately after logi_led_init(), instead of wait a little of time after logi_led_init(). + For devices that only support a single color, the highest percentage value given of the three colors will + define the intensity. For monochrome device, Logitech Gaming Software will proportionally reduce + the value of the highest color, according to the user hardware brightness setting. + + :param rgb: Tuple with integer range 0 to 100 as an amount of red, green, blue + :return: A result of execution + """ + try: + return self.led_dll.LogiLedSetLighting(*rgb) # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_flash_lighting(self, rgb: tuple[int, int, int], duration: int, interval: int) -> bool: + """ + Save the current lighting, plays the flashing effect on the targeted devices. + + Finally, restores the saved lighting. + :param rgb: Tuple with integer range 0 to 100 as an amount of red, green, blue + :param duration: Parameter can be set (in millisecond) to 0 (zero) + to make the effect run until stopped with logi_led_stop_effects() + :param interval: Duration of the flashing interval in millisecond + :return: A result of execution + """ + try: + return self.led_dll.LogiLedFlashLighting(*rgb, duration, interval) # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_pulse_lighting(self, rgb: tuple[int, int, int], duration: int, interval: int) -> bool: + """ + Save the current lighting, plays the pulsing effect on the targeted devices. + + Finally, restores the saved lighting. + :param rgb: Tuple with integer values range 0 to 100 as an amount of red, green, blue. + :param duration: Parameter can be set (in millisecond) to 0 (zero) + to make the effect run until stopped with logi_led_stop_effects(). + :param interval: Duration of the flashing interval in millisecond. + :return: A result of execution. + """ + try: + return self.led_dll.LogiLedPulseLighting(*rgb, duration, interval) # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_stop_effects(self) -> bool: + """ + Stop any of the preset effect. + + Started from logi_led_flash_lighting() or logi_led_pulse_lighting(). + :return: A result of execution + """ + try: + return self.led_dll.LogiLedStopEffects() # type: ignore[attr-defined] + except AttributeError: + return False + + def logi_led_shutdown(self) -> None: + """Restore the last saved lighting and frees memory used by the SDK.""" + try: + self.led_dll.LogiLedShutdown() # type: ignore[attr-defined] + except AttributeError: + pass + + def start_led_effect(self, effect: EffectInfo) -> bool: + """ + Start the pulsing red effect in the thread on the keyboard. + + :param effect: Led effect info object containing RGB, duration, and interval. + """ + result = False + if effect.type == LedEffectType.PULSE: + result = self.logi_led_pulse_lighting(rgb=effect.rgb, duration=effect.duration, interval=effect.interval) + elif effect.type == LedEffectType.FLASH: + result = self.logi_led_flash_lighting(rgb=effect.rgb, duration=effect.duration, interval=effect.interval) + return result diff --git a/src/dcspy/ui/qtdcs.ui b/src/dcspy/ui/qtdcs.ui index c14e2e489..596afbccc 100644 --- a/src/dcspy/ui/qtdcs.ui +++ b/src/dcspy/ui/qtdcs.ui @@ -216,8 +216,8 @@ 0 0 - 152 - 105 + 657 + 385 @@ -409,8 +409,8 @@ 0 0 - 152 - 74 + 657 + 385 @@ -544,8 +544,8 @@ 0 0 - 236 - 105 + 657 + 385 @@ -1359,6 +1359,251 @@ + + + LED + + + + + 10 + 70 + 261 + 24 + + + + + + + 70 + 40 + 91 + 16 + + + + Controller + + + + + + 400 + 40 + 81 + 16 + + + + Interval [ms] + + + + + + 490 + 40 + 81 + 16 + + + + Duration [ms] + + + + + + 380 + 70 + 101 + 24 + + + + 99999 + + + 30 + + + + + + 490 + 70 + 91 + 24 + + + + 99999 + + + 4000 + + + + + + 600 + 40 + 49 + 16 + + + + Sleep [s] + + + + + + 590 + 70 + 71 + 24 + + + + 1 + + + 0.100000000000000 + + + + + + 490 + 110 + 75 + 24 + + + + Simulate + + + + + + 580 + 110 + 75 + 24 + + + + Stop + + + + + + 280 + 70 + 91 + 24 + + + + + + + 290 + 40 + 49 + 16 + + + + Type + + + + + + 400 + 190 + 67 + 24 + + + + 100 + + + 100 + + + + + + 490 + 190 + 67 + 24 + + + + 100 + + + + + + 570 + 190 + 67 + 24 + + + + 100 + + + + + + 410 + 160 + 49 + 16 + + + + R + + + + + + 500 + 160 + 49 + 16 + + + + G + + + + + + 580 + 160 + 49 + 16 + + + + B + + + diff --git a/tests/test_led_sdk.py b/tests/test_led_sdk.py index 2415aa216..963fa1462 100644 --- a/tests/test_led_sdk.py +++ b/tests/test_led_sdk.py @@ -2,13 +2,13 @@ from pytest import mark -from dcspy.models import LedConstants +from dcspy.models import EffectInfo, LedEffectType, LedSupport @mark.parametrize('function, args, result', [ ('logi_led_init', (), False), ('logi_led_init_with_name', ('name',), False), - ('logi_led_set_target_device', (LedConstants.LOGI_DEVICETYPE_MONOCHROME,), False), + ('logi_led_set_target_device', (LedSupport.LOGI_DEVICETYPE_MONOCHROME,), False), ('logi_led_save_current_lighting', (), False), ('logi_led_restore_lighting', (), False), ('logi_led_set_lighting', ((1, 2, 3),), False), @@ -20,38 +20,28 @@ 'set lighting', 'flash lighting', 'pulse lighting', 'stop effects', 'shutdown', ]) def test_all_failure_cases(function, args, result): - from dcspy.sdk import led_sdk - led_sdk.LED_DLL = None + from dcspy.sdk.led_sdk import LedSdkManager + + led_sdk = LedSdkManager('test') + led_sdk.led_dll = None assert getattr(led_sdk, function)(*args) is result -@mark.slow -def test_start_led_pulse(): - from concurrent.futures import ThreadPoolExecutor - from threading import Event - from time import sleep - - from dcspy.sdk import led_sdk - - rgb = (100, 0, 0) - duration = 1 - interval = 1 - event = Event() - - def pulse_led(_rgb, _duration, _interval, _event): - with patch.object(led_sdk, 'logi_led_init', return_value=True) as logi_led_init, \ - patch.object(led_sdk, 'logi_led_set_target_device', return_value=True) as logi_led_set_target_device, \ - patch.object(led_sdk, 'logi_led_pulse_lighting', return_value=True) as logi_led_pulse_lighting, \ - patch.object(led_sdk, 'logi_led_shutdown', return_value=True) as logi_led_shutdown: - led_sdk.start_led_pulse(_rgb, _duration, _interval, _event) - logi_led_init.assert_called_once() - logi_led_set_target_device.assert_called_once_with(LedConstants.LOGI_DEVICETYPE_ALL) - logi_led_pulse_lighting.assert_called_once_with(_rgb, _duration, _interval) - logi_led_shutdown.assert_called_once() - return True - - with ThreadPoolExecutor() as executor: - future = executor.submit(pulse_led, rgb, duration, interval, event) - sleep(1.3) - event.set() - assert future.result() +def test_start_led_effect_pulse(): + from dcspy.sdk.led_sdk import LedSdkManager + + led_sdk = LedSdkManager('test') + effect, rgb, duration, interval = LedEffectType.PULSE, (100, 0, 0), 1, 1 + + with patch.object(led_sdk, 'logi_led_pulse_lighting', return_value=True) as logi_led_pulse_lighting: + led_sdk.start_led_effect(effect=EffectInfo(type=effect, rgb=rgb, duration=duration, interval=interval)) + logi_led_pulse_lighting.assert_called_once_with(rgb=rgb, duration=duration, interval=interval) + +def test_start_led_effect_flash(): + from dcspy.sdk.led_sdk import LedSdkManager + + led_sdk = LedSdkManager('test') + effect, rgb, duration, interval = LedEffectType.FLASH, (0, 0, 100), 2, 2 + with patch.object(led_sdk, 'logi_led_flash_lighting', return_value=True) as logi_led_flash_lighting: + led_sdk.start_led_effect(effect=EffectInfo(type=effect, rgb=rgb, duration=duration, interval=interval)) + logi_led_flash_lighting.assert_called_once_with(rgb=rgb, duration=duration, interval=interval) diff --git a/uml/classes.puml b/uml/classes.puml index b6fdd699a..4c6601a33 100644 --- a/uml/classes.puml +++ b/uml/classes.puml @@ -267,6 +267,19 @@ package models { + black = 0x000000 } + class LedEffectType { + FLASH = 'flash' + PULSE = 'pulse' + NONE = 'none' + } + + class EffectInfo <<(M,orange)>> { + type: LedEffectType + rgb: Tuple[int, int, int] + duration: int + interval: int + } + class ApacheEufdMode <<(E,yellow)>> { + IDM = 'idm' + WCA = 'wca' @@ -301,7 +314,9 @@ ZigZagIterator --* RequestModel LogitechDeviceModel -* LogitechDevice RequestModel --* KeyRequest CycleButton -* RequestModel +LedEffectType -* EffectInfo } + package sdk{ class LcdSdkManager <<(L,lightblue)>> { + lcd_dll: CDLL @@ -322,6 +337,7 @@ package sdk{ # _clear_color(bool) } class led_sdk <<(L,lightblue)>> { + + led_dll: CDLL + logi_led_init() + logi_led_init_with_name(str) + logi_led_set_target_device(LedConstants) @@ -332,7 +348,7 @@ package sdk{ + logi_led_pulse_lighting(Tuple[int, int, int], int, int) + logi_led_stop_effects() + logi_led_shutdown() - + start_led_pulse(Tuple[int, int, int], int, int, Event) + + start_led_effect(EffectInfo) } class GkeySdkManager <<(L,lightblue)>> { + key_dll: CDLL @@ -363,6 +379,7 @@ LcdInfo --* LogitechDevice LogitechDevice *-- ProtocolParser LogitechDevice *-- LcdSdkManager LogitechDevice *-- GkeySdkManager +EffectInfo *- LedSdkManager LcdInfo --* BasicAircraft BasicAircraft *-- StringBuffer