From fa0418390df706917f2a93e9c941126edac99e86 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 21:29:44 -0400 Subject: [PATCH 001/123] Create python-package-conda.yml --- .github/workflows/python-package-conda.yml | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/python-package-conda.yml diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml new file mode 100644 index 0000000..384f9b7 --- /dev/null +++ b/.github/workflows/python-package-conda.yml @@ -0,0 +1,34 @@ +name: Python Package using Conda + +on: [push] + +jobs: + build-linux: + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: '3.10' + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + - name: Install dependencies + run: | + conda env update --file environment.yml --name base + - name: Lint with flake8 + run: | + conda install flake8 + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + conda install pytest + pytest From 678a9f678a873e0b1ae7a36783a3bd1a465bdde6 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 21:30:42 -0400 Subject: [PATCH 002/123] Added anaconda build --- README.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 114f218..fa28ce7 100644 --- a/README.rst +++ b/README.rst @@ -18,8 +18,7 @@ It has been tested on Linux OS only, but should be compatible with Windows as we 2. run: - **python3 gshock_server.py [----multi-watch]** - (the --multi-watch parameter is used if you have multiple watches) + **python3 gshock_server.py [----multi-watch]** (the --multi-watch parameter is used if you have multiple watches) 3. To set the time on your G-Shock, press the ``lower-right`` button and the watch will connect to the app, allowing the app to set the watch's time. From 78ff3fa7469eb6418a52d73a2c6ebb3533648e9d Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 21:35:51 -0400 Subject: [PATCH 003/123] Added anaconda build --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index fa28ce7..7eb2dba 100644 --- a/README.rst +++ b/README.rst @@ -18,7 +18,7 @@ It has been tested on Linux OS only, but should be compatible with Windows as we 2. run: - **python3 gshock_server.py [----multi-watch]** (the --multi-watch parameter is used if you have multiple watches) + **python3 gshock_server.py [--multi-watch]** (the --multi-watch parameter is used if you have multiple watches) 3. To set the time on your G-Shock, press the ``lower-right`` button and the watch will connect to the app, allowing the app to set the watch's time. From fc31201f3758936d68c3fedf63183e9c9ea5ebc5 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 21:42:35 -0400 Subject: [PATCH 004/123] Added anaconda build --- environment.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 environment.yml diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..34daefd --- /dev/null +++ b/environment.yml @@ -0,0 +1,25 @@ +name: demo-dsproject +channels: + - defaults + - conda-forge + - pytorch +dependencies: + - python>=3.6 + - pip + # BASICS + - pip: + - -e . # install git checkout of demo-dsproject in editable mode + - pytz + - bleak + - reactivex + + # DEVELOPMENT ONLY PACKAGES (could also be kept in a separate environment file) + - jupyterlab + - pytest + - pytest-cov + - tox + - pre_commit + - nbdime + - nbstripout + - sphinx + - recommonmark \ No newline at end of file From 02d138bce7426854fc43b53a764d99b52002bd1a Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 21:45:36 -0400 Subject: [PATCH 005/123] Added anaconda build --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 34daefd..ae73450 100644 --- a/environment.yml +++ b/environment.yml @@ -1,4 +1,4 @@ -name: demo-dsproject +name: gshock-time-server channels: - defaults - conda-forge From ac328db977b184470b06162f775de1430a776a98 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 21:58:23 -0400 Subject: [PATCH 006/123] Added anaconda build --- setup.cfg | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/setup.cfg b/setup.cfg index 62eef66..9be4db5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -84,14 +84,16 @@ testing = # in order to write a coverage file that can be read by Jenkins. # CAUTION: --cov flags may prohibit setting breakpoints while debugging. # Comment those flags to avoid this pytest issue. -addopts = - --cov gshocktimeserver --cov-report term-missing - --verbose -norecursedirs = - dist - build - .tox -testpaths = tests + +# addopts = +# --cov gshocktimeserver --cov-report term-missing +# --verbose +# norecursedirs = +# dist +# build +# .tox +# testpaths = tests + # Use pytest markers to select/deselect specific tests # markers = # slow: mark tests as slow (deselect with '-m "not slow"') From b7279ed1f2ad5498cfc84ac1a1426d1797998f30 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 22:05:13 -0400 Subject: [PATCH 007/123] Added anaconda build --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 9be4db5..3a671b1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -78,7 +78,7 @@ testing = # pyscaffold.cli = # awesome = pyscaffoldext.awesome.extension:AwesomeExtension -[tool:pytest] +# [tool:pytest] # Specify command line options as you would do when invoking pytest directly. # e.g. --cov-report html (or xml) for html/xml output or --junitxml junit.xml # in order to write a coverage file that can be read by Jenkins. From 1a6c19e382edaf2d68e1f4421c41a3d364713662 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 22:20:50 -0400 Subject: [PATCH 008/123] Added anaconda build --- environment.yml | 14 +++++++------- setup.cfg | 18 +++++++++--------- tests/conftest.py | 9 ++++++++- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/environment.yml b/environment.yml index ae73450..f1e683f 100644 --- a/environment.yml +++ b/environment.yml @@ -14,12 +14,12 @@ dependencies: - reactivex # DEVELOPMENT ONLY PACKAGES (could also be kept in a separate environment file) - - jupyterlab + # - jupyterlab - pytest - pytest-cov - - tox - - pre_commit - - nbdime - - nbstripout - - sphinx - - recommonmark \ No newline at end of file + # - tox + # - pre_commit + # - nbdime + # - nbstripout + # - sphinx + # - recommonmark \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 3a671b1..7408ce7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -78,21 +78,21 @@ testing = # pyscaffold.cli = # awesome = pyscaffoldext.awesome.extension:AwesomeExtension -# [tool:pytest] +[tool:pytest] # Specify command line options as you would do when invoking pytest directly. # e.g. --cov-report html (or xml) for html/xml output or --junitxml junit.xml # in order to write a coverage file that can be read by Jenkins. # CAUTION: --cov flags may prohibit setting breakpoints while debugging. # Comment those flags to avoid this pytest issue. -# addopts = -# --cov gshocktimeserver --cov-report term-missing -# --verbose -# norecursedirs = -# dist -# build -# .tox -# testpaths = tests +addopts = + --cov gshocktimeserver --cov-report term-missing + --verbose +norecursedirs = + dist + build + .tox +testpaths = tests # Use pytest markers to select/deselect specific tests # markers = diff --git a/tests/conftest.py b/tests/conftest.py index e9fb1c6..8ee8bad 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,4 +7,11 @@ - https://docs.pytest.org/en/stable/writing_plugins.html """ -# import pytest +import pytest + +def inc(x): + return x + 1 + + +def test_answer(): + assert inc(3) == 4 \ No newline at end of file From 11d48b97c8f500bba8cf7226e1f31435cefe6863 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 22:41:31 -0400 Subject: [PATCH 009/123] Added anaconda build --- environment.yml | 14 +++++++------- tests/conftest.py | 23 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/environment.yml b/environment.yml index f1e683f..ae73450 100644 --- a/environment.yml +++ b/environment.yml @@ -14,12 +14,12 @@ dependencies: - reactivex # DEVELOPMENT ONLY PACKAGES (could also be kept in a separate environment file) - # - jupyterlab + - jupyterlab - pytest - pytest-cov - # - tox - # - pre_commit - # - nbdime - # - nbstripout - # - sphinx - # - recommonmark \ No newline at end of file + - tox + - pre_commit + - nbdime + - nbstripout + - sphinx + - recommonmark \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 8ee8bad..6a07782 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,9 +9,24 @@ import pytest -def inc(x): - return x + 1 +class Fruit: + def __init__(self, name): + self.name = name + def __eq__(self, other): + return self.name == other.name + + +@pytest.fixture +def my_fruit(): + return Fruit("apple") + + +@pytest.fixture +def fruit_basket(my_fruit): + return [Fruit("banana"), my_fruit] + + +def test_my_fruit_in_basket(my_fruit, fruit_basket): + assert my_fruit in fruit_basket -def test_answer(): - assert inc(3) == 4 \ No newline at end of file From d6bf94774db6d1a546b45e59a2474353b6459654 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 22:50:49 -0400 Subject: [PATCH 010/123] Added anaconda build --- tests/conftest.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6a07782..e109599 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,25 +8,5 @@ """ import pytest - -class Fruit: - def __init__(self, name): - self.name = name - - def __eq__(self, other): - return self.name == other.name - - -@pytest.fixture -def my_fruit(): - return Fruit("apple") - - -@pytest.fixture -def fruit_basket(my_fruit): - return [Fruit("banana"), my_fruit] - - -def test_my_fruit_in_basket(my_fruit, fruit_basket): - assert my_fruit in fruit_basket +import gshocktimeserver From 0b4fe60ab7b2845a9ebc9295a81fca4024ee6f14 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 5 Jun 2023 22:58:51 -0400 Subject: [PATCH 011/123] Added anaconda build --- .github/workflows/python-package-conda.yml | 8 ++++---- tests/conftest.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 384f9b7..ab5acda 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -28,7 +28,7 @@ jobs: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - conda install pytest - pytest + # - name: Test with pytest + # run: | + # conda install pytest + # pytest diff --git a/tests/conftest.py b/tests/conftest.py index e109599..49309bc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,5 +8,5 @@ """ import pytest -import gshocktimeserver + From d25eaa6a3fd82de33abf590ddf3c138cdc3c06ff Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 10:44:07 -0400 Subject: [PATCH 012/123] Update README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 7eb2dba..1966682 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock B5000/B5600/B2100 watches. +This project allows you to setup time on your Casio G-Shock [B5600](https://amzn.to/3Mt68Qb)/[B5000](https://amzn.to/4194M13)/[B2100](https://amzn.to/3MUDCGY) watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From bb1f22ba35ad4a5c11646a5c93348b752f09c475 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 10:47:27 -0400 Subject: [PATCH 013/123] Update README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 1966682..ccbb1b8 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock [B5600](https://amzn.to/3Mt68Qb)/[B5000](https://amzn.to/4194M13)/[B2100](https://amzn.to/3MUDCGY) watches. +This project allows you to setup time on your Casio G-Shock `B5600:https://amzn.to/3Mt68Qb`/ `B5000:https://amzn.to/4194M13`/ `[B2100:https://amzn.to/3MUDCGY` watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From 5d1f8faa0b2439a4224ad8a2a26268a15c94c343 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 10:50:21 -0400 Subject: [PATCH 014/123] Update README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ccbb1b8..f351b23 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock `B5600:https://amzn.to/3Mt68Qb`/ `B5000:https://amzn.to/4194M13`/ `[B2100:https://amzn.to/3MUDCGY` watches. +This project allows you to setup time on your Casio G-Shock `B5600 `__/ `B5000:https://amzn.to/4194M13`/ `[B2100:https://amzn.to/3MUDCGY` watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From 9abf4f56b01925683568ab63ecbc6e914b9fbe35 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 10:51:36 -0400 Subject: [PATCH 015/123] Update README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f351b23..879b64f 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock `B5600 `__/ `B5000:https://amzn.to/4194M13`/ `[B2100:https://amzn.to/3MUDCGY` watches. +This project allows you to setup time on your Casio G-Shock `B5600 `__/ `B5000 __`/ `B2100 `__ watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From 76be99a12073576a2e1efd7f1bc67a60bc01099b Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 10:52:24 -0400 Subject: [PATCH 016/123] Update README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 879b64f..127eafe 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock `B5600 `__/ `B5000 __`/ `B2100 `__ watches. +This project allows you to setup time on your Casio G-Shock `B5600 `__/ `B5000 `__/ `B2100 `__ watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From b2de285ff052cd19a2bf748672c0d2f09330d001 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 10:53:16 -0400 Subject: [PATCH 017/123] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 127eafe..f547430 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock `B5600 `__/ `B5000 `__/ `B2100 `__ watches. +This project allows you to setup time on your Casio G-Shock `B5600 `__/`B5000 `_/ `B2100 `__ watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From dc7095bfd2791a6ea86a99871041123fb7b01723 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 10:53:45 -0400 Subject: [PATCH 018/123] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f547430..a180c82 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock `B5600 `__/`B5000 `_/ `B2100 `__ watches. +This project allows you to setup time on your Casio G-Shock `B5600 `__/`B5000 `_/`B2100 `__ watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From ee93e91c2371397f0233c2ddb49f8cde7825886a Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 19:10:14 -0400 Subject: [PATCH 019/123] Actions --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index ae73450..0c14932 100644 --- a/environment.yml +++ b/environment.yml @@ -10,7 +10,7 @@ dependencies: - pip: - -e . # install git checkout of demo-dsproject in editable mode - pytz - - bleak + # - bleak - reactivex # DEVELOPMENT ONLY PACKAGES (could also be kept in a separate environment file) From bccf1fc3e22bc5646d1785c57581e5e8d4085ff8 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 20:56:58 -0400 Subject: [PATCH 020/123] Cleanup code --- environment.yml | 2 +- src/gshocktimeserver/alarms.py | 15 ++++++------ src/gshocktimeserver/api_tests.py | 12 +++------ src/gshocktimeserver/args.py | 9 ++++--- src/gshocktimeserver/casio_watch.py | 22 ++++++----------- src/gshocktimeserver/configurator.py | 2 +- src/gshocktimeserver/connection.py | 3 +-- src/gshocktimeserver/event.py | 9 ++++++- src/gshocktimeserver/gshock_api.py | 20 +++++++-------- src/gshocktimeserver/gshock_server.py | 19 +++------------ src/gshocktimeserver/logger.py | 14 +++++------ src/gshocktimeserver/mailsener.py | 3 ++- src/gshocktimeserver/scanner.py | 12 ++++----- src/gshocktimeserver/utils.py | 35 ++++++++++++++------------- src/gshocktimeserver/watch_info.py | 6 +++-- tests/conftest.py | 3 +-- 16 files changed, 84 insertions(+), 102 deletions(-) diff --git a/environment.yml b/environment.yml index 0c14932..ae73450 100644 --- a/environment.yml +++ b/environment.yml @@ -10,7 +10,7 @@ dependencies: - pip: - -e . # install git checkout of demo-dsproject in editable mode - pytz - # - bleak + - bleak - reactivex # DEVELOPMENT ONLY PACKAGES (could also be kept in a separate environment file) diff --git a/src/gshocktimeserver/alarms.py b/src/gshocktimeserver/alarms.py index 764381d..562aebc 100644 --- a/src/gshocktimeserver/alarms.py +++ b/src/gshocktimeserver/alarms.py @@ -1,11 +1,10 @@ import json -import logging from casio_constants import CasioConstants -from utils import to_int_array, to_compact_string, to_hex_string +from utils import to_int_array from logger import logger -HOURLY_CHIME_MASK = 0b10000000 -ENABLED_MASK = 0b01000000 +HOURLY_CHIME_MASK = 0b10000000 +ENABLED_MASK = 0b01000000 ALARM_CONSTANT_VALUE = 0x40 CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -95,10 +94,10 @@ def to_json(self, command: str): # replacement to above 2 lines alarms = [] # split int_array into 4 subarrays - subarr1 = int_array[:len(int_array)//4] - subarr2 = int_array[len(int_array)//4:len(int_array)//2] - subarr3 = int_array[len(int_array)//2:len(int_array)*3//4] - subarr4 = int_array[len(int_array)*3//4:] + subarr1 = int_array[:len(int_array) // 4] + subarr2 = int_array[len(int_array) // 4:len(int_array) // 2] + subarr3 = int_array[len(int_array) // 2:len(int_array) * 3 // 4] + subarr4 = int_array[len(int_array) * 3 // 4:] # create json alarms for each subarray alarms.append(self.create_json_alarm(subarr1)) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 4ef5e28..3661819 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -1,4 +1,3 @@ -import logging import json import pytz from datetime import datetime, timezone @@ -6,16 +5,11 @@ from connection import Connection from gshock_api import GshockAPI from casio_watch import settings -from event import Event, create_event_date, RepeatPeriod, day_of_week -from casio_watch import WatchButton -from utils import ( - to_ascii_string, - clean_str, -) -from configurator import conf +from event import Event, create_event_date, RepeatPeriod from scanner import scanner from logger import logger + async def run_api_tests(args): device = await scanner.scan() logger.debug("Found: {}".format(device)) @@ -85,7 +79,7 @@ async def run_api_tests(args): + event_date_str + """}}""" ) - event = Event().create_event(json.loads(event_json_str)) + Event().create_event(json.loads(event_json_str)) reminders = await api.get_reminders() for reminder in reminders: diff --git a/src/gshocktimeserver/args.py b/src/gshocktimeserver/args.py index f1dea30..ec1f842 100644 --- a/src/gshocktimeserver/args.py +++ b/src/gshocktimeserver/args.py @@ -1,6 +1,7 @@ import argparse import sys + class Args: def __init__(self): self.parse_and_store(sys.argv[1:]) @@ -8,17 +9,19 @@ def __init__(self): def parse_and_store(self, args): parser = argparse.ArgumentParser(description="Parser") parser.add_argument( - "--multi-watch", action='store_true', help="--multi-watch allows use of multimple watches" - ) + "--multi-watch", + action='store_true', + help="--multi-watch allows use of multimple watches") parser.add_argument( "--mailto", help="email when time set to email address", required=False ) parser.add_argument( "-l", "--log_level", default="INFO", help="Sets log level", required=False ) - self.args = parser.parse_args(args) + self.args = parser.parse_args(args) def get(self): return self.args + args = Args() diff --git a/src/gshocktimeserver/casio_watch.py b/src/gshocktimeserver/casio_watch.py index 620b1f3..586fcd3 100644 --- a/src/gshocktimeserver/casio_watch.py +++ b/src/gshocktimeserver/casio_watch.py @@ -1,6 +1,5 @@ import json import datetime -import logging from settings import settings from utils import ( to_int_array, @@ -274,18 +273,12 @@ def int_to_month_str(month_int): if int_arr[3] == 0xFF: # 0XFF indicates end of reminders return json.dumps({"end": ""}) - - short_str = to_compact_string(reminder_str) - # get the first byte of the returned data, which indicates the data content. - key = short_str[:4].upper() - + reminder_all = to_int_array(reminder_str) # Remove the first 2 chars: # 0x31 05 <--- 00 23 02 21 23 02 21 00 00 reminder = reminder_all[2:] - reminder_json = {} - time_period = decode_time_period(reminder[0]) reminder_json["enabled"] = time_period[0] reminder_json["repeat_period"] = time_period[1] @@ -320,7 +313,6 @@ def int_to_month_str(month_int): elif int_array[0] == CHARACTERISTICS["CASIO_WORLD_CITIES"]: data_json = {"key": create_key(data), "value": data} - characteristics_array = to_int_array(data) json_obj["CASIO_WORLD_CITIES"] = data_json elif int_array[0] == CHARACTERISTICS["CASIO_DST_WATCH_STATE"]: data_json = {"key": create_key(data), "value": data} @@ -352,14 +344,14 @@ async def callWriter(connection, message: str): await connection.write(0x000C, alarm_command) - elif action == "GET_ALARMS2": + elif action == "GET_ALARMS2": # get the rest of the alarms alarm_command2 = to_compact_string( to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]])) ) await connection.write(0x000C, alarm_command2) - elif action == "SET_ALARMS": + elif action == "SET_ALARMS": alarms_json_arr = json.loads(message).get("value") alarm_casio0 = to_compact_string( to_hex_string( @@ -372,7 +364,7 @@ async def callWriter(connection, message: str): ) await connection.write(0x000E, alarm_casio) - elif action == "SET_REMINDERS": + elif action == "SET_REMINDERS": def reminder_title_from_json(reminder_json): title_str = reminder_json.get("title") @@ -543,7 +535,7 @@ def create_time_period(enabled: bool, repeat_period: str) -> int: logger.info(reminder_time_byte_arr_to_send) await connection.write(0x000E, reminder_time_byte_arr_to_send) - elif action == "GET_SETTINGS": + elif action == "GET_SETTINGS": await connection.write( 0x000C, bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"]]) ) @@ -589,7 +581,7 @@ def encode(settings: dict): 0x000E, to_compact_string(to_hex_string(encoded_settings)) ) - elif action == "GET_TIME_ADJUSTMENT": + elif action == "GET_TIME_ADJUSTMENT": await connection.write( 0x000C, to_compact_string( @@ -597,7 +589,7 @@ def encode(settings: dict): ), ) - elif action == "SET_TIME_ADJUSTMENT": + elif action == "SET_TIME_ADJUSTMENT": value = json.loads(message).get("value") def encode_time_adjustment(time_adjustment): diff --git a/src/gshocktimeserver/configurator.py b/src/gshocktimeserver/configurator.py index c1495c8..0b7eaa2 100644 --- a/src/gshocktimeserver/configurator.py +++ b/src/gshocktimeserver/configurator.py @@ -12,7 +12,7 @@ def get(self, key): try: value = self.config.get("main", key) - except Exception as e: + except Exception: return None else: return value diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index f72ae73..67468e0 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -1,5 +1,3 @@ -import logging - from bleak import BleakClient from bleak.backends.characteristic import BleakGATTCharacteristic from casio_constants import CasioConstants @@ -8,6 +6,7 @@ from casio_watch import to_json, callWriter from logger import logger + class Connection: def __init__(self, device): self.handles_map = self.init_handles_map() diff --git a/src/gshocktimeserver/event.py b/src/gshocktimeserver/event.py index 81cd35a..9488c9b 100644 --- a/src/gshocktimeserver/event.py +++ b/src/gshocktimeserver/event.py @@ -76,7 +76,14 @@ def __init__(self): self.selected = False def __str__(self): - return f"Title: {self.title}, startDate: {self.start_date.__str__()}, endDate: {self.end_date.__str__()}, repeatPeriod: {self.repeat_period}, daysOfWeek: {self.days_of_week}, enabled: {self.enabled}, incompatible: {self.incompatible}, selected: {self.selected}" + return f"""Title: {self.title}, + startDate: {self.start_date.__str__()}, + endDate: {self.end_date.__str__()}, + repeatPeriod: {self.repeat_period}, + daysOfWeek: {self.days_of_week}, + enabled: {self.enabled}, + incompatible: {self.incompatible}, + selected: {self.selected}""" def create_event(self, event_jsn: dict): def get_array_list_from_json_array(json_array: list): diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 2c2d85a..e60790a 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -3,14 +3,12 @@ import json import time -from connection import Connection from data_watcher import data_watcher from utils import ( to_ascii_string, to_int_array, to_compact_string, clean_str, - encode_string ) from result_queue import result_queue, KeyedResult from casio_watch import WatchButton, DtsState @@ -21,7 +19,9 @@ class GshockAPI: """ - This class contains all the API functions. This should the the main interface to the library. + This class contains all the API functions. This should the the main interface to the + library. + Here is how to use it: api = GshockAPI(connection) @@ -78,12 +78,13 @@ async def get_pressed_button(self) -> WatchButton: The return values are interpreted as follows: - - `LOWER_LEFT` - this connection is initiated by a long-press of the lower-left button on the watch. - The app receiving this type of connection can now send and receive commands to the watch. + - `LOWER_LEFT` - this connection is initiated by a long-press of the lower-left + button on the watch.The app receiving this type of connection can now send and + receive commands to the watch. - `LOWER_RIGHT` - this connection is initiated by a short-press of the lower-right button, - which is usually used to set time. But the app can use this signal to perform other arbitrary functions. - Therefore, this button is also referred as `ACTION BUTTON`. + which is usually used to set time. But the app can use this signal to perform other + arbitrary functions. Therefore, this button is also referred as `ACTION BUTTON`. The connection will automatically disconnect in about 20 seconds. - `NO_BUTTON` - this connection is initiated automatically, periodically @@ -173,8 +174,7 @@ def casio_world_cities_callback(keyed_data): res.set_result(value) def process_home_time(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") + pass self.subscribe("CASIO_WORLD_CITIES", casio_world_cities_callback) # self.subscribe("HOME_TIME", process_home_time) @@ -249,8 +249,6 @@ def handle_message(keyed_data): # await self.connection.write(0xE, "1a0412000000") # await self.connection.write(0xE, "1a0418000000") - - async def initialize_for_setting_time(self): # Before we can set time, we must read and write back these values. # Why? Not sure, ask Casio diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index ae6cb5a..b2cba3b 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -1,24 +1,11 @@ import asyncio import sys -from bleak import BleakClient, BleakScanner -from bleak.backends.characteristic import BleakGATTCharacteristic -from bleak.backends.device import BLEDevice -from bleak.backends.scanner import AdvertisementData -from scanner import Scanner from connection import Connection from gshock_api import GshockAPI -from casio_watch import settings -from event import Event, create_event_date, RepeatPeriod, day_of_week from casio_watch import WatchButton from scanner import scanner -from utils import ( - to_ascii_string, - clean_str, -) from configurator import conf -from api_tests import run_api_tests -from mailsener import send_mail_notification from logger import logger from args import args @@ -26,6 +13,7 @@ __copyright__ = "Ivo Zivkov" __license__ = "MIT" + async def main(argv): await run_time_server() # await run_api_tests(args) @@ -34,7 +22,7 @@ async def main(argv): async def run_time_server(): while True: try: - if args.get().multi_watch == True: + if args.get().multi_watch: address = None else: address = conf.get("device.address") @@ -63,9 +51,8 @@ async def run_time_server(): await connection.disconnect() except Exception as e: - logger.error (f"Got error: {e}") + logger.error(f"Got error: {e}") continue if __name__ == "__main__": asyncio.run(main(sys.argv[1:])) - diff --git a/src/gshocktimeserver/logger.py b/src/gshocktimeserver/logger.py index 93bca6b..5f8f8e9 100644 --- a/src/gshocktimeserver/logger.py +++ b/src/gshocktimeserver/logger.py @@ -1,32 +1,32 @@ -from configparser import ConfigParser -from enum import Enum import logging from args import args _logger = logging.getLogger(__name__) + class Logger: log_level = args.get().log_level logging.basicConfig( encoding='utf-8', - level=logging.INFO, # log_level, + level=logging.INFO, # log_level, handlers=[ logging.StreamHandler() ], format="%(asctime)-15s %(name)-8s %(levelname)s: %(message)s", ) - def error (self, *args): + def error(self, *args): _logger.error(args) - def info (self, *args): + def info(self, *args): _logger.info(args) - def debug (self, *args): + def debug(self, *args): _logger.debug(args) - def warn (self, *args): + def warn(self, *args): _logger.warn(args) + logger = Logger() diff --git a/src/gshocktimeserver/mailsener.py b/src/gshocktimeserver/mailsener.py index ae0acac..210815d 100644 --- a/src/gshocktimeserver/mailsener.py +++ b/src/gshocktimeserver/mailsener.py @@ -1,6 +1,7 @@ import smtplib from datetime import date + def send_mail_notification(to_address): # Import the email modules we'll need from email.mime.text import MIMEText @@ -16,4 +17,4 @@ def send_mail_notification(to_address): # envelope header. s = smtplib.SMTP('localhost') s.sendmail(me, [you], msg.as_string()) - s.quit() \ No newline at end of file + s.quit() diff --git a/src/gshocktimeserver/scanner.py b/src/gshocktimeserver/scanner.py index 723bf50..eabda1f 100644 --- a/src/gshocktimeserver/scanner.py +++ b/src/gshocktimeserver/scanner.py @@ -1,4 +1,3 @@ -import logging import sys from bleak import BleakScanner @@ -6,6 +5,7 @@ from watch_info import watch_info from logger import logger + class Scanner: CASIO_SERVICE_UUID = "00001804-0000-1000-8000-00805f9b34fb" @@ -15,18 +15,17 @@ async def scan(self, device_address): if device_address is None: while True: - filter = {"name": "CASIO*"} device = await scanner.find_device_by_filter( lambda d, ad: d.name and d.name.lower().startswith("casio"), - timeout=5*60.0 + timeout=5 * 60.0 ) - logger.debug (f"device: {device}") + logger.debug(f"device: {device}") if device is None: continue watch_info.set_name(device.name) watch_info.set_address(device.address) - + conf.put("device.address", device.address) conf.put("device.name", device.name) break @@ -38,4 +37,5 @@ async def scan(self, device_address): return device -scanner = Scanner() \ No newline at end of file + +scanner = Scanner() diff --git a/src/gshocktimeserver/utils.py b/src/gshocktimeserver/utils.py index 80d0ed3..85c39ae 100644 --- a/src/gshocktimeserver/utils.py +++ b/src/gshocktimeserver/utils.py @@ -3,7 +3,7 @@ def to_casio_cmd(bytesStr): - parts = [bytesStr[i : i + 2] for i in range(0, len(bytesStr), 2)] + parts = [bytesStr[i: i + 2] for i in range(0, len(bytesStr), 2)] hexArr = [int(str, 16) for str in parts] return bytes(hexArr) @@ -34,14 +34,14 @@ def to_hex_string(byte_arr): def remove_prefix(string, prefix): - return string[len(prefix) :] if string.startswith(prefix) else string + return string[len(prefix):] if string.startswith(prefix) else string def to_ascii_string(hexStr, commandLengthToSkip): asciiStr = "" strArrayWithCommand = hexStr.split(" ") if len(strArrayWithCommand) == 1: # no spaces between hex values, i.e. 4C4F4E444F4E - strArrayWithCommand = [hexStr[i : i + 2] for i in range(0, len(hexStr), 2)] + strArrayWithCommand = [hexStr[i: i + 2] for i in range(0, len(hexStr), 2)] # skip command strArray = strArrayWithCommand[commandLengthToSkip:] @@ -49,6 +49,7 @@ def to_ascii_string(hexStr, commandLengthToSkip): asciiStr = bytes.fromhex(asc).decode("ASCII") return asciiStr + def trimNonAsciiCharacters(string): return string.replace("\0", "") @@ -72,7 +73,6 @@ def to_byte_array(string, maxLen): return retArr - def to_hex_string_compact(asciiStr, maxLen): byteArr = bytearray(asciiStr, 'ascii') hexStr = "" @@ -80,21 +80,22 @@ def to_hex_string_compact(asciiStr, maxLen): hexStr += "{:02x}".format(byte) return hexStr + def dec_to_hex(dec): return int(str(hex(dec))[2:]) + def encode_string(ascii_string, maxlen): - # Convert the ascii string into an array of integers - int_arr = [ord(c) for c in ascii_string] - - # Pad the array up to maxlen with zeroes - while len(int_arr) < maxlen: - int_arr.append(0) - - # Convert the array back into a string - hex_string = '' - for i in int_arr: - hex_string += '{:02X}'.format(i) - - return hex_string + # Convert the ascii string into an array of integers + int_arr = [ord(c) for c in ascii_string] + + # Pad the array up to maxlen with zeroes + while len(int_arr) < maxlen: + int_arr.append(0) + + # Convert the array back into a string + hex_string = '' + for i in int_arr: + hex_string += '{:02X}'.format(i) + return hex_string diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index 62edf46..4918209 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -1,6 +1,7 @@ from configparser import ConfigParser from enum import Enum + class WatchInfo: class model(Enum): @@ -12,11 +13,12 @@ def __init__(self) -> None: self.name = "" self.address = "" - def set_name (self, name): + def set_name(self, name): self.name = name self.model = self.model.B2100 if "2100" in name else self.model.B5600 - def set_address (self, address): + def set_address(self, address): self.address = address + watch_info = WatchInfo() diff --git a/tests/conftest.py b/tests/conftest.py index 49309bc..e14abf6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,6 +7,5 @@ - https://docs.pytest.org/en/stable/writing_plugins.html """ -import pytest - +# import pytest From c716a52647d97f1bb2403ac0e1ba5ee50507ce4a Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 20:58:00 -0400 Subject: [PATCH 021/123] Cleanup code --- src/gshocktimeserver/watch_info.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index 4918209..d1a9a0a 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -1,4 +1,3 @@ -from configparser import ConfigParser from enum import Enum From eabbedb1337e80cadc0e9e4d29c90ef2bdcb0458 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 6 Jun 2023 22:44:05 -0400 Subject: [PATCH 022/123] Added build script --- build.sh | 2 ++ 1 file changed, 2 insertions(+) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..7c2f411 --- /dev/null +++ b/build.sh @@ -0,0 +1,2 @@ +python setup.py bdist + From 3038cfc7009c8eabc30bd76e7bf7e6fe42e073b1 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 7 Jun 2023 08:25:21 -0400 Subject: [PATCH 023/123] Added prompts when the program starts --- build.sh | 3 +-- src/gshocktimeserver/api_tests.py | 29 +++++++++++++++++---------- src/gshocktimeserver/gshock_server.py | 15 +++++++++++++- src/gshocktimeserver/scanner.py | 2 +- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/build.sh b/build.sh index 7c2f411..e759b47 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1 @@ -python setup.py bdist - +python3 setup.py bdist diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 3661819..61b1b9a 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -9,10 +9,17 @@ from scanner import scanner from logger import logger - -async def run_api_tests(args): +def prompt(): + print ("========================================================================") + print ("Press and hold lower-left button on your watch for 3 seconds to start...") + print ("========================================================================") + print ("") + +async def run_api_tests(): + prompt() + device = await scanner.scan() - logger.debug("Found: {}".format(device)) + logger.info("Found: {}".format(device)) connection = Connection(device) await connection.connect() @@ -22,16 +29,16 @@ async def run_api_tests(args): await api.get_app_info() pressed_button = await api.get_pressed_button() - logger.debug("pressed button: {}".format(pressed_button)) + logger.info("pressed button: {}".format(pressed_button)) watch_name = await api.get_watch_name() - logger.debug("got watch name: {}".format(watch_name)) + logger.info("got watch name: {}".format(watch_name)) await api.set_time() # await api.reset_hand_to_12() alarms = await api.get_alarms() - logger.debug("alarms: {}".format(alarms)) + logger.info("alarms: {}".format(alarms)) alarms[3]["enabled"] = True alarms[3]["hour"] = 7 @@ -40,17 +47,17 @@ async def run_api_tests(args): await api.set_alarms(alarms) seconds = await api.get_timer() - logger.debug("timer: {} seconds".format(seconds)) + logger.info("timer: {} seconds".format(seconds)) await api.set_timer(seconds + 10) time_adjstment = await api.get_time_adjustment() - logger.debug("time_adjstment: {}".format(time_adjstment)) + logger.info("time_adjstment: {}".format(time_adjstment)) settings.timeAdjustment = True await api.set_time_adjustment(settings) settings_local = await api.get_basic_settings() - logger.debug("settings: {}".format(settings_local)) + logger.info("settings: {}".format(settings_local)) settings_local["button_tone"] = True settings_local["language"] = "Engish" @@ -83,11 +90,11 @@ async def run_api_tests(args): reminders = await api.get_reminders() for reminder in reminders: - logger.debug("reminder: {}".format(reminder.__str__())) + logger.info("reminder: {}".format(reminder.__str__())) await api.set_reminders(reminders) # input("Hit any key to disconnect") await connection.disconnect() - logger.debug("--- END OF TESTS ---") + logger.info("--- END OF TESTS ---") diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index b2cba3b..87f7544 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -8,6 +8,7 @@ from configurator import conf from logger import logger from args import args +from api_tests import run_api_tests __author__ = "Ivo Zivkov" __copyright__ = "Ivo Zivkov" @@ -16,10 +17,21 @@ async def main(argv): await run_time_server() - # await run_api_tests(args) + # await run_api_tests() + + +def prompt(): + print("==============================================================================================") + print("Short-press lower-right button on your watch for 3 seconds to start...") + print("") + print("If Auto-time set on watch, the watch will connect and run automatically up to 4 times per day.") + print("==============================================================================================") + print("") async def run_time_server(): + prompt() + while True: try: if args.get().multi_watch: @@ -54,5 +66,6 @@ async def run_time_server(): logger.error(f"Got error: {e}") continue + if __name__ == "__main__": asyncio.run(main(sys.argv[1:])) diff --git a/src/gshocktimeserver/scanner.py b/src/gshocktimeserver/scanner.py index eabda1f..e46a73f 100644 --- a/src/gshocktimeserver/scanner.py +++ b/src/gshocktimeserver/scanner.py @@ -9,7 +9,7 @@ class Scanner: CASIO_SERVICE_UUID = "00001804-0000-1000-8000-00805f9b34fb" - async def scan(self, device_address): + async def scan(self, device_address = None): scanner = BleakScanner() logger.info("Scanning for devices...") From a042d811fd3957cda74e4fa1488ffb741fc1bfc3 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 7 Jun 2023 08:26:56 -0400 Subject: [PATCH 024/123] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index a180c82..81722a4 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock `B5600 `__/`B5000 `_/`B2100 `__ watches. +This project allows you to setup time on your Casio G-Shock `B5600 `__ / `B5000 `_ / `B2100 `__ watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From 05bfe0587a1cab6f7a22c88c1dcbfe6f5d07615d Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Thu, 8 Jun 2023 15:46:06 -0400 Subject: [PATCH 025/123] Updated distribution script --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index e759b47..8a25de6 100755 --- a/build.sh +++ b/build.sh @@ -1 +1 @@ -python3 setup.py bdist +python3 setup.py bdist_wheel From 75a29e3ebec69ded95520a15f819056a6679956a Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 9 Jun 2023 15:28:51 -0400 Subject: [PATCH 026/123] Display when time updated --- src/gshocktimeserver/api_tests.py | 18 +++++++++--------- src/gshocktimeserver/casio_watch.py | 4 ++-- src/gshocktimeserver/config.ini | 4 ++-- src/gshocktimeserver/connection.py | 4 ++-- src/gshocktimeserver/gshock_api.py | 4 ++-- src/gshocktimeserver/gshock_server.py | 5 ++++- src/gshocktimeserver/logger.py | 2 +- src/gshocktimeserver/scanner.py | 4 ++-- 8 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 61b1b9a..bc7a4a3 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -19,7 +19,7 @@ async def run_api_tests(): prompt() device = await scanner.scan() - logger.info("Found: {}".format(device)) + logger.debug("Found: {}".format(device)) connection = Connection(device) await connection.connect() @@ -29,16 +29,16 @@ async def run_api_tests(): await api.get_app_info() pressed_button = await api.get_pressed_button() - logger.info("pressed button: {}".format(pressed_button)) + logger.debug("pressed button: {}".format(pressed_button)) watch_name = await api.get_watch_name() - logger.info("got watch name: {}".format(watch_name)) + logger.debug("got watch name: {}".format(watch_name)) await api.set_time() # await api.reset_hand_to_12() alarms = await api.get_alarms() - logger.info("alarms: {}".format(alarms)) + logger.debug("alarms: {}".format(alarms)) alarms[3]["enabled"] = True alarms[3]["hour"] = 7 @@ -47,17 +47,17 @@ async def run_api_tests(): await api.set_alarms(alarms) seconds = await api.get_timer() - logger.info("timer: {} seconds".format(seconds)) + logger.debug("timer: {} seconds".format(seconds)) await api.set_timer(seconds + 10) time_adjstment = await api.get_time_adjustment() - logger.info("time_adjstment: {}".format(time_adjstment)) + logger.debug("time_adjstment: {}".format(time_adjstment)) settings.timeAdjustment = True await api.set_time_adjustment(settings) settings_local = await api.get_basic_settings() - logger.info("settings: {}".format(settings_local)) + logger.debug("settings: {}".format(settings_local)) settings_local["button_tone"] = True settings_local["language"] = "Engish" @@ -90,11 +90,11 @@ async def run_api_tests(): reminders = await api.get_reminders() for reminder in reminders: - logger.info("reminder: {}".format(reminder.__str__())) + logger.debug("reminder: {}".format(reminder.__str__())) await api.set_reminders(reminders) # input("Hit any key to disconnect") await connection.disconnect() - logger.info("--- END OF TESTS ---") + logger.debug("--- END OF TESTS ---") diff --git a/src/gshocktimeserver/casio_watch.py b/src/gshocktimeserver/casio_watch.py index 586fcd3..b431fe7 100644 --- a/src/gshocktimeserver/casio_watch.py +++ b/src/gshocktimeserver/casio_watch.py @@ -474,7 +474,7 @@ def hex_to_dec(hex): elif repeat_period == "YEARLY": encode_date(time_detail, start_date, end_date) else: - logger.info( + logger.debug( "Cannot handle Repeat Period: {}".format(repeat_period) ) @@ -532,7 +532,7 @@ def create_time_period(enabled: bool, repeat_period: str) -> int: reminder_time_byte_arr_to_send = to_compact_string( to_hex_string(bytearray(reminder_time_byte_arr)) ) - logger.info(reminder_time_byte_arr_to_send) + logger.debug(reminder_time_byte_arr_to_send) await connection.write(0x000E, reminder_time_byte_arr_to_send) elif action == "GET_SETTINGS": diff --git a/src/gshocktimeserver/config.ini b/src/gshocktimeserver/config.ini index 2373f6b..2c2f23c 100644 --- a/src/gshocktimeserver/config.ini +++ b/src/gshocktimeserver/config.ini @@ -1,4 +1,4 @@ [main] -device.address = DD:85:03:25:62:17 -device.name = CASIO GW-B5600 +device.address = C6:A1:33:29:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index 67468e0..9868f39 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -38,13 +38,13 @@ async def disconnect(self): await self.client.disconnect() async def write(self, handle, data): - logger.info("write: {}".format(data)) + logger.debug("write: {}".format(data)) try: await self.client.write_gatt_char( self.handles_map[handle], to_casio_cmd(data) ) except Exception as e: - logger.info("write failed with exception: {}".format(e)) + logger.debug("write failed with exception: {}".format(e)) async def request(self, request): await self.write(0xC, request) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index e60790a..14c5729 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -387,13 +387,13 @@ async def set_alarms(self, alarms): None """ if not alarms: - self.logger.info("Alarm model not initialised! Cannot set alarm") + self.logger.debug("Alarm model not initialised! Cannot set alarm") return alarms_str = json.dumps(alarms) set_action_cmd = '{{"action":"SET_ALARMS", "value":{} }}'.format(alarms_str) await self.connection.sendMessage(set_action_cmd) - self.logger.info("Returning from setAlarms") + self.logger.debug("Returning from setAlarms") async def get_timer(self): """Get Timer value in seconds. diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 87f7544..3e3d42d 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -1,5 +1,6 @@ import asyncio import sys +from datetime import datetime from connection import Connection from gshock_api import GshockAPI @@ -9,6 +10,7 @@ from logger import logger from args import args from api_tests import run_api_tests +from watch_info import watch_info __author__ = "Ivo Zivkov" __copyright__ = "Ivo Zivkov" @@ -40,7 +42,7 @@ async def run_time_server(): address = conf.get("device.address") device = await scanner.scan(address) - logger.info("Found: {}".format(device)) + logger.debug("Found: {}".format(device)) connection = Connection(device) await connection.connect() @@ -56,6 +58,7 @@ async def run_time_server(): await api.get_app_info() await api.set_time() + print (f"Time set at {datetime.now()} on {watch_info.name}") # You can add mail notification here if you run your mail server. # send_mail_notification(args.mailto) diff --git a/src/gshocktimeserver/logger.py b/src/gshocktimeserver/logger.py index 5f8f8e9..429d783 100644 --- a/src/gshocktimeserver/logger.py +++ b/src/gshocktimeserver/logger.py @@ -20,7 +20,7 @@ def error(self, *args): _logger.error(args) def info(self, *args): - _logger.info(args) + _logger.debug(args) def debug(self, *args): _logger.debug(args) diff --git a/src/gshocktimeserver/scanner.py b/src/gshocktimeserver/scanner.py index e46a73f..de3b3c6 100644 --- a/src/gshocktimeserver/scanner.py +++ b/src/gshocktimeserver/scanner.py @@ -11,7 +11,7 @@ class Scanner: async def scan(self, device_address = None): scanner = BleakScanner() - logger.info("Scanning for devices...") + logger.debug("Scanning for devices...") if device_address is None: while True: @@ -30,7 +30,7 @@ async def scan(self, device_address = None): conf.put("device.name", device.name) break else: - logger.info("Waiting for device by address...") + logger.debug("Waiting for device by address...") device = await scanner.find_device_by_address( device_address, sys.float_info.max ) From fe37801ca9a4d7fa8e185d705f2d2fafb7721a0e Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 23 Jun 2023 09:49:45 -0400 Subject: [PATCH 027/123] Make compatible with Python 3.8 --- .gitignore | 1 + build-and-install.sh | 6 ++++++ build.sh | 1 - src/gshocktimeserver/gshock_server.py | 2 +- src/gshocktimeserver/logger.py | 2 +- 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100755 build-and-install.sh delete mode 100755 build.sh diff --git a/.gitignore b/.gitignore index e9e1e9b..322e1b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # Temporary and binary files +./build-and-install.sh *~ *.py[cod] *.so diff --git a/build-and-install.sh b/build-and-install.sh new file mode 100755 index 0000000..e96d095 --- /dev/null +++ b/build-and-install.sh @@ -0,0 +1,6 @@ +rm -rf ./dist +python3 setup.py bdist_wheel +scp ./dist/*.whl pi@192.168.1.118:/tmp/gshocktimeserver.zip +ssh pi@192.168.1.118 /home/pi/update.sh + + diff --git a/build.sh b/build.sh deleted file mode 100755 index 8a25de6..0000000 --- a/build.sh +++ /dev/null @@ -1 +0,0 @@ -python3 setup.py bdist_wheel diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 3e3d42d..5a07a78 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -24,7 +24,7 @@ async def main(argv): def prompt(): print("==============================================================================================") - print("Short-press lower-right button on your watch for 3 seconds to start...") + print("Short-press lower-right button on your watch to set time...") print("") print("If Auto-time set on watch, the watch will connect and run automatically up to 4 times per day.") print("==============================================================================================") diff --git a/src/gshocktimeserver/logger.py b/src/gshocktimeserver/logger.py index 429d783..38cc8c5 100644 --- a/src/gshocktimeserver/logger.py +++ b/src/gshocktimeserver/logger.py @@ -8,7 +8,7 @@ class Logger: log_level = args.get().log_level logging.basicConfig( - encoding='utf-8', + # encoding='utf-8', (for pythonn 3.9 and higher) level=logging.INFO, # log_level, handlers=[ logging.StreamHandler() From 6b6ee052341968ea315dd5f29dfab6e9116b9a7c Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 27 Jun 2023 22:57:39 -0400 Subject: [PATCH 028/123] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 81722a4..098e1fe 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ It has been tested on Linux OS only, but should be compatible with Windows as we **python3 gshock_server.py [--multi-watch]** (the --multi-watch parameter is used if you have multiple watches) -3. To set the time on your G-Shock, press the ``lower-right`` button and the watch will connect to the app, allowing the app to set the watch's time. +3. To set the time on your G-Shock, short-press the ``lower-right`` button and the watch will connect to the app, allowing the app to set the watch's time. 4. If AUTO TIME ADJUSTEMENT is enabled on the watch, it will sync up to 4 times daily with the app and adjust its time accordingly. From 1e8b8d6dc2169a8662e312826df2c09833ccbe20 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 27 Jun 2023 22:58:54 -0400 Subject: [PATCH 029/123] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 098e1fe..3d2ade3 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ GShockTimeServer Overview: ========= -This project allows you to setup time on your Casio G-Shock `B5600 `__ / `B5000 `_ / `B2100 `__ watches. +This project allows you to set the correct time to your Casio G-Shock `B5600 `__ / `B5000 `_ / `B2100 `__ watches. In addition, this repository provides an API for developing application for the above watches. This is WIP, but you can take a look at the ``api_tests.py`` file on how to use the API. From 74fd3ddcfea4bba7a7aac99c955862e2836278fa Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Tue, 18 Jul 2023 00:03:45 +0400 Subject: [PATCH 030/123] Update README.rst Correction of typos --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 3d2ade3..60ab7e0 100644 --- a/README.rst +++ b/README.rst @@ -41,5 +41,5 @@ If your watch cannot connect, and the ``--multi-watch`` parameter is not used, r To Do: ====== -We are working on a professianal installition. +We are working on a professional installation. From 95f7b5787919f4ad9afbded13915d0dc01d8efd5 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Tue, 18 Jul 2023 01:06:08 +0400 Subject: [PATCH 031/123] Create protocol.md --- protocol.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 protocol.md diff --git a/protocol.md b/protocol.md new file mode 100644 index 0000000..83fae4a --- /dev/null +++ b/protocol.md @@ -0,0 +1,20 @@ + +| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | +|-------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| **0** | | | | | | | | | | | | | | | | | +| **1** | | | | | | | | | | | | | | | | | +| **2** | | | | # | $ | % | & | ' | ( | ) | * | + | , |---| . | / | +| **3** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | +| **4** | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | +| **5** | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ | +| **6** | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | +| **7** | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | | +| **8** | ¥ | ╏ | « | ¬ |---| ⎺ | ° | ± | ´ | · | ¸ | » | ♦ | ♪ | ■ | < | +| **9** | 【 | 】| ◀ | ▶ | √ | y | | | | | | | | | | | +| **a** | . | 。 | 「 | 」 | 、 | ・ | ヲ | ァ | ィ | ゥ | ェ | ォ | ャ | ュ | ョ | ッ | +| **b** | ー | . | ア | . | イ | . | . | . | . | . | . | . | . | . | . | . | +| **c** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| **d** | . | . | . | . | . | . | レ | ロ | ワ | . | . | . | . | . | . | . | +| **e** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| **f** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | + From bc761769cd57194c67e533ea01bf5f6516f1bea7 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Tue, 18 Jul 2023 07:45:46 +0400 Subject: [PATCH 032/123] Update protocol.md --- protocol.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/protocol.md b/protocol.md index 83fae4a..274baf2 100644 --- a/protocol.md +++ b/protocol.md @@ -1,3 +1,5 @@ +JIS X 0201 with additions + | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | |-------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| @@ -12,9 +14,8 @@ | **8** | ¥ | ╏ | « | ¬ |---| ⎺ | ° | ± | ´ | · | ¸ | » | ♦ | ♪ | ■ | < | | **9** | 【 | 】| ◀ | ▶ | √ | y | | | | | | | | | | | | **a** | . | 。 | 「 | 」 | 、 | ・ | ヲ | ァ | ィ | ゥ | ェ | ォ | ャ | ュ | ョ | ッ | -| **b** | ー | . | ア | . | イ | . | . | . | . | . | . | . | . | . | . | . | -| **c** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | -| **d** | . | . | . | . | . | . | レ | ロ | ワ | . | . | . | . | . | . | . | +| **b** | ー | ア | イ | ウ | エ | オ | カ | キ | ク | ケ | コ | サ | シ | ス | セ | ソ | +| **c** | タ | チ | ツ | テ | ト | ナ | ニ | ヌ | ネ | ノ | ハ | ヒ | フ | ヘ | ホ | マ | +| **d** | ミ | ム | メ | モ | ヤ | ユ | ヨ | ラ | リ | ル | レ | ロ | ワ | ン | ゙ | ゚ | | **e** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | | **f** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | - From 76196dae0de002884290e40fba5e41164ed92be0 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Tue, 18 Jul 2023 07:51:04 +0400 Subject: [PATCH 033/123] Update protocol.md --- protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol.md b/protocol.md index 274baf2..39bab3e 100644 --- a/protocol.md +++ b/protocol.md @@ -10,7 +10,7 @@ JIS X 0201 with additions | **4** | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | | **5** | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ | | **6** | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | -| **7** | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | | +| **7** | p | q | r | s | t | u | v | w | x | y | z | { | \| | } | ~ | | | **8** | ¥ | ╏ | « | ¬ |---| ⎺ | ° | ± | ´ | · | ¸ | » | ♦ | ♪ | ■ | < | | **9** | 【 | 】| ◀ | ▶ | √ | y | | | | | | | | | | | | **a** | . | 。 | 「 | 」 | 、 | ・ | ヲ | ァ | ィ | ゥ | ェ | ォ | ャ | ュ | ョ | ッ | From 45798d84ed137ad36d11369667579865cd8f7ecb Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Tue, 18 Jul 2023 07:57:48 +0400 Subject: [PATCH 034/123] Update protocol.md --- protocol.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/protocol.md b/protocol.md index 39bab3e..c521d4a 100644 --- a/protocol.md +++ b/protocol.md @@ -1,4 +1,4 @@ -JIS X 0201 with additions +The Casio watch character table is a mix of [ASCII](https://en.wikipedia.org/wiki/ASCII) and [JIS X 0201](https://en.wikipedia.org/wiki/JIS_X_0201) with additions: | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | @@ -19,3 +19,7 @@ JIS X 0201 with additions | **d** | ミ | ム | メ | モ | ヤ | ユ | ヨ | ラ | リ | ル | レ | ロ | ワ | ン | ゙ | ゚ | | **e** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | | **f** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | + +To be completed : +- empty cells are non used blocks +- dots are fields to be completed. From 59b971a0e362c39138db444166a08b96582db403 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Tue, 18 Jul 2023 13:59:35 +0400 Subject: [PATCH 035/123] Update protocol.md --- protocol.md | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/protocol.md b/protocol.md index c521d4a..4cc32bc 100644 --- a/protocol.md +++ b/protocol.md @@ -1,4 +1,92 @@ -The Casio watch character table is a mix of [ASCII](https://en.wikipedia.org/wiki/ASCII) and [JIS X 0201](https://en.wikipedia.org/wiki/JIS_X_0201) with additions: +# GShock GAB-2100 BLE protocol +## Commands +### Read (char-read-hnd) +0x4 : watch name + +0x6 : device type + +0x9 : TX Power level + +### Write command (char-write-cmd) +#### 0xc +* 10 : Get button pressed +* 22 : Get app info +* 1D00 : Get time zones and DST state of watch +* 1e00 : Get local time zone parameters +* 1e01 : Get WT time zone parameters +* 1f00 : Get local time zone name +* 1f01 : Get WT time zone name + +### Write request (char-write-req) +#### 0xe +* 1D00... : Set time zones and DST state of watch +* 1e00... : Set local time zone parameters +* 1e01... : Set WT time zone parameters +* 1f00... : Set local time zone name +* 1f01... : Set WT time zone name + +#### 0xf +* 100 : ? + +## Data packets + +### 1D00 : time zones and DST state of watch + +``` +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 +1d 00 01 02 03 5b 00 dc 00 ff ff ff ff ff ff +``` + +0 : 1d + +1 : local TZ index + +2 : WT TZ index + +3 : local TZ DST : +* 02 : No DST +* 03 : DST + +4 : WT TZ DST + +5-6 : 2 bytes integer (little-endian) : local City numeric identifier = b06 × 256 + b05 + +7-8 : WT city numeric identifier + +### 1E : Time zone parameters + +``` +0 1 2 3 4 5 6 +1e 01 52 00 16 04 00 +``` + +0 : 1e + +1 : TZ index : + +* 00 : local +* 01 : WT + +2-3 : city numéric identifier + +4 : signed byte : time difference in quarter of an hour (divide by 4 to get it in hour) + +5 : DST offset in quarter of hour : 00 for UTC and 04 for other TZ + +6 : DST rules ? : + +* 00 : UTC and cities without DST +* 01 : USA cities +* 02 : European cities (LON, PAR, ATH) +* 04 : Australia +* 05 : New Zealand (Wellington) +* 12 : Lord Howe Island +* 17 : Chatam Islands +* 2b : Teheran + +## Character table + +The GAB-2100 character table is a mix of [ASCII](https://en.wikipedia.org/wiki/ASCII) and [JIS X 0201](https://en.wikipedia.org/wiki/JIS_X_0201) with additions: | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | From 637c1f86703224df8e2dcba1e97baa3d3de38685 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Tue, 18 Jul 2023 18:42:51 +0400 Subject: [PATCH 036/123] Update protocol.md --- protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol.md b/protocol.md index 4cc32bc..96d5d2e 100644 --- a/protocol.md +++ b/protocol.md @@ -104,7 +104,7 @@ The GAB-2100 character table is a mix of [ASCII](https://en.wikipedia.org/wiki/A | **a** | . | 。 | 「 | 」 | 、 | ・ | ヲ | ァ | ィ | ゥ | ェ | ォ | ャ | ュ | ョ | ッ | | **b** | ー | ア | イ | ウ | エ | オ | カ | キ | ク | ケ | コ | サ | シ | ス | セ | ソ | | **c** | タ | チ | ツ | テ | ト | ナ | ニ | ヌ | ネ | ノ | ハ | ヒ | フ | ヘ | ホ | マ | -| **d** | ミ | ム | メ | モ | ヤ | ユ | ヨ | ラ | リ | ル | レ | ロ | ワ | ン | ゙ | ゚ | +| **d** | ミ | ム | メ | モ | ヤ | ユ | ヨ | ラ | リ | ル | レ | ロ | ワ | ン | ~ | ▫ | | **e** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | | **f** | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | From 78413b253512eb954f5cffceca3b1ed0afc3eb05 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Fri, 28 Jul 2023 21:10:52 +0400 Subject: [PATCH 037/123] Create gatttool_scripts --- gatttool_scripts | 1 + 1 file changed, 1 insertion(+) create mode 100644 gatttool_scripts diff --git a/gatttool_scripts b/gatttool_scripts new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/gatttool_scripts @@ -0,0 +1 @@ + From e5d1b91254719b1a214c1d9a6b49d08436810874 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Fri, 28 Jul 2023 21:11:46 +0400 Subject: [PATCH 038/123] Delete gatttool_scripts --- gatttool_scripts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 gatttool_scripts diff --git a/gatttool_scripts b/gatttool_scripts deleted file mode 100644 index 8b13789..0000000 --- a/gatttool_scripts +++ /dev/null @@ -1 +0,0 @@ - From 4dea233f8b6c633666342e508040a5ae7cdbca49 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Fri, 28 Jul 2023 23:00:32 +0400 Subject: [PATCH 039/123] Create readme.md --- gatttool_scripts/readme.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 gatttool_scripts/readme.md diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md new file mode 100644 index 0000000..8e47c82 --- /dev/null +++ b/gatttool_scripts/readme.md @@ -0,0 +1,35 @@ +# GATTTOOL Scripts + +gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. +Despite is considered as deprecated and replaced by bluetoothctl, but the latter is (to my opinion) more difficult to use. + +gattool can be used as a shell command, for example : + +Long press the bottom left button of the watch to enter in connect mode, then type in a terminal : + +`$ gatttool -b
-t random --char-read -a 0x04` + +with `
` being the mac address of the device, for example D3:60:4F:9A:33:29 + +The answer of this command is` 43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00` + +You can translate it with an hexadecimal converter like xxd : + +```shell +$ echo "43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00" | xxd -r -p;echo +CASIO GA-B2100 +``` + +If you want to set the time of the watch, you will have to issue multiple write requests and commands while the device is connected. +gatttool in command line will not work because it does three actions : connect to the device, issue the command then disconnect. + +gatttool can be used interactively. The latter example could then be done this way : + +```shell +$ gatttool -b D3:60:4F:9A:33:29 -I -t random +[D3:60:4F:9A:33:29] connect +Attempting to connect to D3:60:4F:9A:33:29 +Connection successful +[D3:60:4F:9A:33:29][LE]> char-write-cmd 0xc 10 +Notification handle = 0x000e value: 10 29 33 9a 4f 60 d3 7f 04 03 0f ff ff ff ff 24 00 00 00 +``` From c693d7e68148ceae4a5855581fd951c1721f2295 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Fri, 28 Jul 2023 23:08:08 +0400 Subject: [PATCH 040/123] Update readme.md --- gatttool_scripts/readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index 8e47c82..35ffbb3 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -1,7 +1,7 @@ # GATTTOOL Scripts gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. -Despite is considered as deprecated and replaced by bluetoothctl, but the latter is (to my opinion) more difficult to use. +It is considered as deprecated and replaced by bluetoothctl, but the latter is (to my opinion) more difficult to use. gattool can be used as a shell command, for example : @@ -32,4 +32,7 @@ Attempting to connect to D3:60:4F:9A:33:29 Connection successful [D3:60:4F:9A:33:29][LE]> char-write-cmd 0xc 10 Notification handle = 0x000e value: 10 29 33 9a 4f 60 d3 7f 04 03 0f ff ff ff ff 24 00 00 00 +[D3:60:4F:9A:33:29][LE]> disconnect +[D3:60:4F:9A:33:29][LE]> quit +$ ``` From 3cf3616f33e5ebf3bee043c55ab033526bf94bea Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Fri, 28 Jul 2023 23:21:37 +0400 Subject: [PATCH 041/123] Update readme.md --- gatttool_scripts/readme.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index 35ffbb3..587a7f7 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -1,11 +1,12 @@ # GATTTOOL Scripts +## Overview gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. It is considered as deprecated and replaced by bluetoothctl, but the latter is (to my opinion) more difficult to use. gattool can be used as a shell command, for example : -Long press the bottom left button of the watch to enter in connect mode, then type in a terminal : +Long press the bottom left button of a GShock GA-B2100 to enter in connect mode, then type in a terminal : `$ gatttool -b
-t random --char-read -a 0x04` @@ -36,3 +37,9 @@ Notification handle = 0x000e value: 10 29 33 9a 4f 60 d3 7f 04 03 0f ff ff ff ff [D3:60:4F:9A:33:29][LE]> quit $ ``` + +If you want to write a bash script to issue multiple commands to the watch, you will have to use a command line interaction tool like expect-lite. + +The script setTime.exp provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100 whit gatttool interactive mode. + +# From 6f47cd95d4ace8c3d083548a35286a8ca541b1eb Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Fri, 28 Jul 2023 23:33:41 +0400 Subject: [PATCH 042/123] Update readme.md --- gatttool_scripts/readme.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index 587a7f7..1e7eff1 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -42,4 +42,17 @@ If you want to write a bash script to issue multiple commands to the watch, you The script setTime.exp provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100 whit gatttool interactive mode. -# +## Dependencies + +$ sudo apt install bluez expect-lite + +## Usage + +setTime.exp and encodeTime scripts should be in the same directory. Make them executable with : + +```shell +$ chmod +x setTime.exp encodeTime +``` + +Find the MAC address of your watch + From 04e245df9ecbfbb5cbbe73a8e6ea28794bd63f37 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 00:00:58 +0400 Subject: [PATCH 043/123] Update readme.md --- gatttool_scripts/readme.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index 1e7eff1..23eab9e 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -2,7 +2,8 @@ ## Overview gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. -It is considered as deprecated and replaced by bluetoothctl, but the latter is (to my opinion) more difficult to use. +It is considered as deprecated and replaced by bluetoothctl, but the latter is (to my opinion) more difficult to use +and less documentation is available. gattool can be used as a shell command, for example : @@ -10,11 +11,11 @@ Long press the bottom left button of a GShock GA-B2100 to enter in connect mode, `$ gatttool -b
-t random --char-read -a 0x04` -with `
` being the mac address of the device, for example D3:60:4F:9A:33:29 +with `
` being the mac address of the device, for example `D3:60:4F:9A:33:29` -The answer of this command is` 43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00` +The answer of this command is `43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00` -You can translate it with an hexadecimal converter like xxd : +You can translate it with an hexadecimal converter like `xxd` : ```shell $ echo "43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00" | xxd -r -p;echo @@ -22,9 +23,9 @@ CASIO GA-B2100 ``` If you want to set the time of the watch, you will have to issue multiple write requests and commands while the device is connected. -gatttool in command line will not work because it does three actions : connect to the device, issue the command then disconnect. +gatttool in command line will not work because when invoked it does three actions : connect to the device, issue the command then disconnect. -gatttool can be used interactively. The latter example could then be done this way : +gatttool can be used interactively. The latter example could be done this way : ```shell $ gatttool -b D3:60:4F:9A:33:29 -I -t random From 05e5263865c4a7efe42a43d6a002e8a1f8927be8 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 10:02:15 +0400 Subject: [PATCH 044/123] Update readme.md --- gatttool_scripts/readme.md | 49 ++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index 23eab9e..1da245c 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -1,13 +1,17 @@ # GATTTOOL Scripts ## Overview +Here we will see how to send and script commands to a Casio GShock GA-B2100 from the command line, using gatttool. + +As an example, the script setTime.exp provided here read the time from the computer and send it to the watch. + +All the procedures given here works on GNU-Linux operating systems. gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. -It is considered as deprecated and replaced by bluetoothctl, but the latter is (to my opinion) more difficult to use -and less documentation is available. +It is considered deprecated and replaced by bluetoothctl, but the latter lack of documentation and is (to my opinion) more difficult to use. gattool can be used as a shell command, for example : -Long press the bottom left button of a GShock GA-B2100 to enter in connect mode, then type in a terminal : +Long press the bottom left button of the watch to enter in connect mode, then type in a terminal : `$ gatttool -b
-t random --char-read -a 0x04` @@ -32,16 +36,32 @@ $ gatttool -b D3:60:4F:9A:33:29 -I -t random [D3:60:4F:9A:33:29] connect Attempting to connect to D3:60:4F:9A:33:29 Connection successful -[D3:60:4F:9A:33:29][LE]> char-write-cmd 0xc 10 -Notification handle = 0x000e value: 10 29 33 9a 4f 60 d3 7f 04 03 0f ff ff ff ff 24 00 00 00 +[D3:60:4F:9A:33:29][LE]> char-read-hnd 0x04 +Characteristic value/descriptor: 43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00 [D3:60:4F:9A:33:29][LE]> disconnect [D3:60:4F:9A:33:29][LE]> quit $ ``` +Beware of handle and data values, gatttool documentation is confusing. Write command syntax in interactive mode is : + +`char-write-cmd ` + +* Handle value should be writen in hexadecimal base with 0x prefix. +* Data value should be writen in hexadecimal base **without** 0x prefix. + +Example : `char-write-cmd 0xc 1d00` + +In non interactive mode, the syntax is : + +`gatttool -b
--char-write-req -a -n --listen` + +Here handle value can be written either in hexadecimal with prefix or decimal, but data value should be in hexadecimal base **without** 0x prefix. + If you want to write a bash script to issue multiple commands to the watch, you will have to use a command line interaction tool like expect-lite. -The script setTime.exp provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100 whit gatttool interactive mode. +The script `setTime.exp` provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100 with gatttool interactive mode. + ## Dependencies @@ -51,9 +71,18 @@ $ sudo apt install bluez expect-lite setTime.exp and encodeTime scripts should be in the same directory. Make them executable with : -```shell -$ chmod +x setTime.exp encodeTime -``` +`$ chmod +x setTime.exp encodeTime` + +Find the MAC address of your watch with `bluetoothctl scan on` and press bottom right key of the watch. You should have an answer like : + +`[NEW] Device D3:60:4F:9A:33:29 CASIO GA-B2100` + +Stop the discovery with CtrlC, then open `setTime.exp` and copy the MAC address in the line beginning with `$MAC=` + +Launch the script with the command : + +`$ .\setTime.exp` + +then press bottom right key of the watch. -Find the MAC address of your watch From 6b1e32c66de58d8214fbccf6e3698c311018cac7 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 10:17:38 +0400 Subject: [PATCH 045/123] Update readme.md --- gatttool_scripts/readme.md | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index 1da245c..3b8dd9c 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -42,27 +42,10 @@ Characteristic value/descriptor: 43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00 [D3:60:4F:9A:33:29][LE]> quit $ ``` -Beware of handle and data values, gatttool documentation is confusing. Write command syntax in interactive mode is : - -`char-write-cmd ` - -* Handle value should be writen in hexadecimal base with 0x prefix. -* Data value should be writen in hexadecimal base **without** 0x prefix. - -Example : `char-write-cmd 0xc 1d00` - -In non interactive mode, the syntax is : - -`gatttool -b
--char-write-req -a -n --listen` - -Here handle value can be written either in hexadecimal with prefix or decimal, but data value should be in hexadecimal base **without** 0x prefix. - - -If you want to write a bash script to issue multiple commands to the watch, you will have to use a command line interaction tool like expect-lite. +If you want to automate the process in a script, you will have to use a command line interaction tool like expect-lite. The script `setTime.exp` provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100 with gatttool interactive mode. - ## Dependencies $ sudo apt install bluez expect-lite @@ -86,3 +69,4 @@ Launch the script with the command : then press bottom right key of the watch. + From a6023817533e4cae5f4dd967497d951c612ae777 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 10:33:37 +0400 Subject: [PATCH 046/123] Update readme.md --- gatttool_scripts/readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index 3b8dd9c..c4c71f5 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -4,7 +4,7 @@ Here we will see how to send and script commands to a Casio GShock GA-B2100 from As an example, the script setTime.exp provided here read the time from the computer and send it to the watch. -All the procedures given here works on GNU-Linux operating systems. +All the procedures given here work on GNU-Linux operating systems. gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. It is considered deprecated and replaced by bluetoothctl, but the latter lack of documentation and is (to my opinion) more difficult to use. @@ -48,6 +48,8 @@ The script `setTime.exp` provided here is an expect-lite script which read the t ## Dependencies +You will need to install bluez and expect-lite packages. On Debian and derivatives (Ubuntu, Linux Mint,...), type : + $ sudo apt install bluez expect-lite ## Usage From af2f1d856395301d4be8808ca59ac88bdb39e28e Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 11:04:17 +0400 Subject: [PATCH 047/123] Update protocol.md --- protocol.md | 91 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/protocol.md b/protocol.md index 96d5d2e..71eabe1 100644 --- a/protocol.md +++ b/protocol.md @@ -1,11 +1,19 @@ # GShock GAB-2100 BLE protocol -## Commands -### Read (char-read-hnd) -0x4 : watch name -0x6 : device type +## Overview +Casio bluetooth watches protocol has not been published by the constructor. The following description come from experiment on the watch and analysis of the code of open source softwares dedicated to communicate with these watches : +* [Ivo Zivkov's GShock API](https://github.com/izivkov/GShockAPI) +* [Ivo Zivkov's GShock time server](https://github.com/izivkov/GShockTimeServer) +* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge) +* [Gadgetbridge time zone description](https://codeberg.org/johannesk/Gadgetbridge/src/branch/casio-gw-b5600/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/casio/gwb5600/CasioGWB5600TimeZone.java) + +Syntax and examples come from [gatttool](http://tvaira.free.fr/flower-power/gatttool.txt). -0x9 : TX Power level +## Commands +### Read (char-read-hnd) +* 0x4 : watch name +* 0x6 : device type +* 0x9 : TX Power level ### Write command (char-write-cmd) #### 0xc @@ -67,7 +75,7 @@ * 00 : local * 01 : WT -2-3 : city numéric identifier +2-3 : city numeric identifier 4 : signed byte : time difference in quarter of an hour (divide by 4 to get it in hour) @@ -84,6 +92,31 @@ * 17 : Chatam Islands * 2b : Teheran +## Examples with gatttool +### Installation +gatttool is part of the bluez package. On Debian and derivatives, it could be installed with : + +`sudo apt install bluez` + +### gatttool usage + +Gatttool syntax with examples is described [here](http://tvaira.free.fr/flower-power/gatttool.txt). + +Beware of handle and data values, gatttool documentation is confusing. Write command syntax in interactive mode is : + +`char-write-cmd ` + +* Handle value should be writen in hexadecimal base with 0x prefix. +* Data value should be writen in hexadecimal base **without** 0x prefix. + +Example : `char-write-cmd 0xc 1d00` + +In non interactive mode, the syntax is : + +`gatttool -b
--char-write-req -a -n --listen` + +Here handle value can be written either in hexadecimal with prefix or decimal, but data value should be in hexadecimal base **without** prefix. + ## Character table The GAB-2100 character table is a mix of [ASCII](https://en.wikipedia.org/wiki/ASCII) and [JIS X 0201](https://en.wikipedia.org/wiki/JIS_X_0201) with additions: @@ -111,3 +144,49 @@ The GAB-2100 character table is a mix of [ASCII](https://en.wikipedia.org/wiki/A To be completed : - empty cells are non used blocks - dots are fields to be completed. + + ## City list + + | Index | HB | LB | NAME | OFFSET | DST_OFFSET | DST_RULE | +| ------|----|----|------|--------|------------|----------| +| 313 | 1 | 39 | BAKER_ISLAND | -12 | 1 | 00 | +| 215 | 0 | D7 | PAGO_PAGO | -11 | 1 | 00 | +| 123 | 0 | 7B | HONOLULU | -10 | 1 | 00 | +| 314 | 1 | 3A | MARQUESAS_ISLANDS | -9.5 | 1 | 00 | +| 12 | 0 | 0C | ANCHORAGE | -9 | 1 | 01 | +| 161 | 0 | A1 | LOS_ANGELES | -8 | 1 | 01 | +| 84 | 0 | 54 | DENVER | -7 | 1 | 01 | +| 66 | 0 | 42 | CHICAGO | -6 | 1 | 01 | +| 202 | 0 | CA | NEW_YORK | -5 | 1 | 01 | +| 113 | 0 | 71 | HALIFAX | -4 | 1 | 01 | +| 268 | 1 | 0C | ST.JOHN'S | -3.5 | 1 | 01 | +| 241 | 0 | F1 | RIO_DE_JANEIRO | -3 | 1 | 00 | +| 98 | 0 | 62 | F.DE_NORONHA | -2 | 1 | 00 | +| 233 | 0 | E9 | PRAIA | -1 | 1 | 00 | +| 0 | 0 | 00 | UTC | 0 | 0 | 00 | +| 160 | 0 | A0 | LONDON | 0 | 1 | 02 | +| 220 | 0 | DC | PARIS | 1 | 1 | 02 | +| 19 | 0 | 13 | ATHENS | 2 | 1 | 02 | +| 133 | 0 | 85 | JEDDAH | 3 | 1 | 00 | +| 278 | 1 | 16 | TEHRAN | 3.5 | 1 | 2B | +| 91 | 0 | 5B | DUBAI | 4 | 1 | 00 | +| 136 | 0 | 88 | KABUL | 4.5 | 1 | 00 | +| 139 | 0 | 8B | KARACHI | 5 | 1 | 00 | +| 82 | 0 | 52 | DELHI | 5.5 | 1 | 00 | +| 140 | 0 | 8C | KATHMANDU | 5.75 | 1 | 00 | +| 86 | 0 | 56 | DHAKA | 6 | 1 | 00 | +| 303 | 1 | 2F | YANGON | 6.5 | 1 | 00 | +| 28 | 0 | 1C | BANGKOK | 7 | 1 | 00 | +| 122 | 0 | 7A | HONG_KONG | 8 | 1 | 00 | +| 234 | 0 | EA | PYONGYANG | 9 | 1 | 00 | +| 310 | 1 | 36 | EUCLA | 8.75 | 1 | 00 | +| 281 | 1 | 19 | TOKYO | 9 | 1 | 00 | +| 5 | 0 | 05 | ADELAIDE | 9.5 | 1 | 04 | +| 271 | 1 | 0F | SYDNEY | 10 | 1 | 04 | +| 311 | 1 | 37 | LORD_HOWE_ISLAND | 10.5 | 0.5 | 12 | +| 205 | 0 | CD | NOUMEA | 11 | 1 | 00 | +| 299 | 1 | 2B | WELLINGTON | 12 | 1 | 05 | +| 63 | 0 | 3F | CHATHAM_ISLANDS | 12.75 | 1 | 17 | +| 208 | 0 | D0 | NUKUALOFA | 13 | 1 | 00 | +| 147 | 0 | 93 | KIRITIMATI | 14 | 1 | 00 | + From cb0faf2ca6aef00b983d45948a18153178baad59 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 11:12:57 +0400 Subject: [PATCH 048/123] Update protocol.md --- protocol.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/protocol.md b/protocol.md index 71eabe1..16ec41f 100644 --- a/protocol.md +++ b/protocol.md @@ -1,7 +1,7 @@ # GShock GAB-2100 BLE protocol ## Overview -Casio bluetooth watches protocol has not been published by the constructor. The following description come from experiment on the watch and analysis of the code of open source softwares dedicated to communicate with these watches : +Casio bluetooth watches protocol has not been published by the constructor. The following description comes from experiments on the watch and analysis of the code of open source softwares dedicated to communicate with these watches : * [Ivo Zivkov's GShock API](https://github.com/izivkov/GShockAPI) * [Ivo Zivkov's GShock time server](https://github.com/izivkov/GShockTimeServer) * [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge) @@ -17,7 +17,7 @@ Syntax and examples come from [gatttool](http://tvaira.free.fr/flower-power/gatt ### Write command (char-write-cmd) #### 0xc -* 10 : Get button pressed +* 10 : Get button pressed (and other informations ?) * 22 : Get app info * 1D00 : Get time zones and DST state of watch * 1e00 : Get local time zone parameters @@ -38,6 +38,14 @@ Syntax and examples come from [gatttool](http://tvaira.free.fr/flower-power/gatt ## Data packets +### 10 : button pressed +``` +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +10 29 33 9a 4f 60 d3 7f 04 03 0f ff ff ff ff 24 00 00 00 +``` +8 : 04 : RIGHT BUTTON, 01 : LEFT BUTTON + + ### 1D00 : time zones and DST state of watch ``` @@ -117,6 +125,21 @@ In non interactive mode, the syntax is : Here handle value can be written either in hexadecimal with prefix or decimal, but data value should be in hexadecimal base **without** prefix. +### Examples + +```shell +$ gatttool -b D3:60:4F:9A:33:29 -I -t random +[D3:60:4F:9A:33:29] connect +Attempting to connect to D3:60:4F:9A:33:29 +Connection successful +[D3:60:4F:9A:33:29][LE]> char-write-cmd 0xc 10 +Notification handle = 0x000e value: 10 29 33 9a 4f 60 d3 7f 04 03 0f ff ff ff ff 24 00 00 00 +[D3:60:4F:9A:33:29][LE]> char-read-hnd 0x04 +Characteristic value/descriptor: 43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00 +[D3:60:4F:9A:33:29][LE]> disconnect +[D3:60:4F:9A:33:29][LE]> quit +``` + ## Character table The GAB-2100 character table is a mix of [ASCII](https://en.wikipedia.org/wiki/ASCII) and [JIS X 0201](https://en.wikipedia.org/wiki/JIS_X_0201) with additions: From 7fbd4754c24a083f08492830ccbc893cf924f38b Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 11:25:32 +0400 Subject: [PATCH 049/123] Add files via upload --- gatttool_scripts/encodeTime | 17 ++++++++ gatttool_scripts/setTime.exp | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 gatttool_scripts/encodeTime create mode 100644 gatttool_scripts/setTime.exp diff --git a/gatttool_scripts/encodeTime b/gatttool_scripts/encodeTime new file mode 100644 index 0000000..3fbae58 --- /dev/null +++ b/gatttool_scripts/encodeTime @@ -0,0 +1,17 @@ +#!/bin/bash + +# Read computer time and convert it to Casio time bluetooth packet. + +y=$(date +%Y) +m=$(date +%-m) +d=$(date +%-d) +j=$(($(date +%u)-1)) +H=$(date +%-H) +#H=$((H-1)) +M=$(date +%-M) +#M=$((M-5)) +S=$(date +%-S) +printf "09%02x%02x%02x%02x%02x%02x%02x%02x0001\n" \ + $((y >> 0 & 0xff)) $((y >> 8 & 0xff)) \ + $m $d $H $M $S $j + diff --git a/gatttool_scripts/setTime.exp b/gatttool_scripts/setTime.exp new file mode 100644 index 0000000..e04a9a0 --- /dev/null +++ b/gatttool_scripts/setTime.exp @@ -0,0 +1,81 @@ +#!/usr/bin/env expect-lite + +# This script read time from computer clock +# and send it to a Casio GShock GA-B2100 watch. +# (c) Pierre Brial 2023 +# GNU General Public License version 3 + +*NOINFO + +# Put here the MAC address of the watch (use 'bluetoothctl scan on' to find it) +$MAC=D3:60:4F:9A:33:29 + +>gatttool -b $MAC -I -t random +>connect +<.+successful + +# Get DST state of watch +>char-write-cmd 0xc 1d00 +char-write-req 0xe $a +<.+successfully + +# Get and set Local DST and time zone +>char-write-cmd 0xc 1e00 +char-write-req 0xe $a +<.+successfully + +# Get and set World Time DST and time zone +>char-write-cmd 0xc 1e01 +char-write-req 0xe $a +<.+successfully + +# Get and set time zone name : + +# local : +>char-write-cmd 0xc 1f00 +char-write-req 0xe $a +<.+successfully + +# World time : +>char-write-cmd 0xc 1f01 +char-write-req 0xe $a +<.+successfully + +# Read computer time from script encodeTime : +*FORK getTime +>./encodeTime ++$timef=([a-f,\d]{18}0001) +? $timef == __NO_STRING_CAPTURED__ ? *FAIL +*FORK default + +# Set watch time : +>char-write-req 0xe $timef +<.+successfully + +>disconnect From 79b4eecb90213ef02d2147318ee3229dfd8e532e Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 14:24:54 +0400 Subject: [PATCH 050/123] Update readme.md --- gatttool_scripts/readme.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index c4c71f5..f88f675 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -70,5 +70,12 @@ Launch the script with the command : then press bottom right key of the watch. - - +## References + +* [Casio GA-B2100 protocol](/protocol.md) +* [gatttool Syntax and examples](http://tvaira.free.fr/flower-power/gatttool.txt) +* [Reading Values From a BLE Device](https://www.instructables.com/Reading-Values-From-a-BLE-Device-Using-CSR1010-and/) +* [Ivo Zivkov's GShock API](https://github.com/izivkov/GShockAPI) +* [Ivo Zivkov's GShock time server](https://github.com/izivkov/GShockTimeServer) +* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge) + From 5c30f8944479d557334e100c28ad7679d86fd2e3 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Sat, 29 Jul 2023 14:30:17 +0400 Subject: [PATCH 051/123] Update readme.md --- gatttool_scripts/readme.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md index f88f675..f926146 100644 --- a/gatttool_scripts/readme.md +++ b/gatttool_scripts/readme.md @@ -1,4 +1,5 @@ # GATTTOOL Scripts + ## Overview Here we will see how to send and script commands to a Casio GShock GA-B2100 from the command line, using gatttool. @@ -8,7 +9,6 @@ All the procedures given here work on GNU-Linux operating systems. gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. It is considered deprecated and replaced by bluetoothctl, but the latter lack of documentation and is (to my opinion) more difficult to use. - gattool can be used as a shell command, for example : Long press the bottom left button of the watch to enter in connect mode, then type in a terminal : @@ -28,8 +28,7 @@ CASIO GA-B2100 If you want to set the time of the watch, you will have to issue multiple write requests and commands while the device is connected. gatttool in command line will not work because when invoked it does three actions : connect to the device, issue the command then disconnect. - -gatttool can be used interactively. The latter example could be done this way : +To send multiple commands between connect and disconnect, gatttool has to be used interactively. The latter example could be done this way : ```shell $ gatttool -b D3:60:4F:9A:33:29 -I -t random @@ -44,7 +43,7 @@ $ ``` If you want to automate the process in a script, you will have to use a command line interaction tool like expect-lite. -The script `setTime.exp` provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100 with gatttool interactive mode. +The script `setTime.exp` provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100, using gatttool interactive mode. ## Dependencies From f435d78419a051c8f65e30eb0967842bcafc270a Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Thu, 10 Aug 2023 22:21:26 +0400 Subject: [PATCH 052/123] Add internal links to gatttool scripts and watch protocol --- README.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.rst b/README.rst index 60ab7e0..22902ff 100644 --- a/README.rst +++ b/README.rst @@ -9,6 +9,12 @@ This project allows you to set the correct time to your Casio G-Shock `B5600 Date: Thu, 10 Aug 2023 22:32:36 +0400 Subject: [PATCH 053/123] Update README.rst Correction markdown / rst --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 22902ff..21248c0 100644 --- a/README.rst +++ b/README.rst @@ -11,8 +11,8 @@ but you can take a look at the ``api_tests.py`` file on how to use the API. For those wishing to tinker with the watch from the command line and undestand how it communicates, check theses pages : - * [Gatttool scripts](gatttool_scripts/readme.md) - * [G-Shock GAB-2100 BLE communication protocol](protocol.md) +* `Gatttool scripts `_ +* `G-Shock GAB-2100 BLE communication protocol `_ Usage: From 9149f839242eefa930accdea21e56690a2df1099 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Thu, 10 Aug 2023 22:33:22 +0400 Subject: [PATCH 054/123] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 21248c0..ca40947 100644 --- a/README.rst +++ b/README.rst @@ -12,7 +12,7 @@ but you can take a look at the ``api_tests.py`` file on how to use the API. For those wishing to tinker with the watch from the command line and undestand how it communicates, check theses pages : * `Gatttool scripts `_ -* `G-Shock GAB-2100 BLE communication protocol `_ +* `G-Shock GAB-2100 BLE protocol `_ Usage: From 581315388bcfbe442b8ad18a3d97bd892c8c6293 Mon Sep 17 00:00:00 2001 From: Pierre Brial Date: Thu, 10 Aug 2023 22:33:50 +0400 Subject: [PATCH 055/123] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ca40947..02ea575 100644 --- a/README.rst +++ b/README.rst @@ -9,7 +9,7 @@ This project allows you to set the correct time to your Casio G-Shock `B5600 `_ * `G-Shock GAB-2100 BLE protocol `_ From 422188edfad2a316b28ff830d86c8ea8fae30404 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 11 Aug 2023 18:43:45 -0400 Subject: [PATCH 056/123] Update README.rst --- README.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 02ea575..dee5b51 100644 --- a/README.rst +++ b/README.rst @@ -9,12 +9,6 @@ This project allows you to set the correct time to your Casio G-Shock `B5600 `_ -* `G-Shock GAB-2100 BLE protocol `_ - - Usage: ====== This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. @@ -45,6 +39,13 @@ Troubleshooting: ================ If your watch cannot connect, and the ``--multi-watch`` parameter is not used, remove the "config.ini" file and try again. +Shell Script Option +=================== +For those wishing to tinker with the watch from the command line and undestand how it communicates, check these pages : + +* `Gatttool scripts `_ +* `G-Shock GAB-2100 BLE protocol `_ + To Do: ====== We are working on a professional installation. From f4d64750192196b4b6d53fa58e747f7b7f7d6644 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 11 Aug 2023 18:45:00 -0400 Subject: [PATCH 057/123] Update README.rst --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index dee5b51..c4a2581 100644 --- a/README.rst +++ b/README.rst @@ -39,8 +39,8 @@ Troubleshooting: ================ If your watch cannot connect, and the ``--multi-watch`` parameter is not used, remove the "config.ini" file and try again. -Shell Script Option -=================== +Shell Script Option: +==================== For those wishing to tinker with the watch from the command line and undestand how it communicates, check these pages : * `Gatttool scripts `_ From fa74fa9dc1ecc8ba82724f860a6eb06546e5f0b7 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 5 Sep 2023 18:01:42 -0400 Subject: [PATCH 058/123] Update README.rst --- README.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.rst b/README.rst index c4a2581..60ab7e0 100644 --- a/README.rst +++ b/README.rst @@ -39,13 +39,6 @@ Troubleshooting: ================ If your watch cannot connect, and the ``--multi-watch`` parameter is not used, remove the "config.ini" file and try again. -Shell Script Option: -==================== -For those wishing to tinker with the watch from the command line and undestand how it communicates, check these pages : - -* `Gatttool scripts `_ -* `G-Shock GAB-2100 BLE protocol `_ - To Do: ====== We are working on a professional installation. From c47bf62c15a984952973ab942ae6bfa2a65eeede Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 8 Dec 2023 13:57:51 -0500 Subject: [PATCH 059/123] Model change --- GShockTimeServer.iml | 11 +++++++++++ config.ini | 4 ++-- src/gshocktimeserver/api_tests.py | 6 +++--- src/gshocktimeserver/config.ini | 4 ---- src/gshocktimeserver/connection.py | 8 +++++--- src/gshocktimeserver/watch_info.py | 2 +- 6 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 GShockTimeServer.iml delete mode 100644 src/gshocktimeserver/config.ini diff --git a/GShockTimeServer.iml b/GShockTimeServer.iml new file mode 100644 index 0000000..ac86b81 --- /dev/null +++ b/GShockTimeServer.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/config.ini b/config.ini index 2373f6b..2c2f23c 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = DD:85:03:25:62:17 -device.name = CASIO GW-B5600 +device.address = C6:A1:33:29:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index bc7a4a3..135e069 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -1,5 +1,6 @@ import json import pytz +import time from datetime import datetime, timezone from connection import Connection @@ -32,10 +33,9 @@ async def run_api_tests(): logger.debug("pressed button: {}".format(pressed_button)) watch_name = await api.get_watch_name() - logger.debug("got watch name: {}".format(watch_name)) + logger.info("got watch name: {}".format(watch_name)) await api.set_time() - # await api.reset_hand_to_12() alarms = await api.get_alarms() logger.debug("alarms: {}".format(alarms)) @@ -94,7 +94,7 @@ async def run_api_tests(): await api.set_reminders(reminders) - # input("Hit any key to disconnect") + input("Hit any key to disconnect") await connection.disconnect() logger.debug("--- END OF TESTS ---") diff --git a/src/gshocktimeserver/config.ini b/src/gshocktimeserver/config.ini deleted file mode 100644 index 2c2f23c..0000000 --- a/src/gshocktimeserver/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -[main] -device.address = C6:A1:33:29:7A:07 -device.name = CASIO GA-B2100 - diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index 9868f39..fa5ae23 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -31,14 +31,13 @@ async def connect(self): ) return True except Exception as e: - self.logger.warning(f"Cannot connect: {e}") + logger.warning(f"Cannot connect: {e}") return False async def disconnect(self): await self.client.disconnect() async def write(self, handle, data): - logger.debug("write: {}".format(data)) try: await self.client.write_gatt_char( self.handles_map[handle], to_casio_cmd(data) @@ -47,6 +46,7 @@ async def write(self, handle, data): logger.debug("write failed with exception: {}".format(e)) async def request(self, request): + print("write: {}".format(request)) await self.write(0xC, request) def init_handles_map(self): @@ -55,7 +55,9 @@ def init_handles_map(self): handles_map[0x04] = CasioConstants.CASIO_GET_DEVICE_NAME handles_map[0x06] = CasioConstants.CASIO_APPEARANCE handles_map[0x09] = CasioConstants.TX_POWER_LEVEL_CHARACTERISTIC_UUID - handles_map[0x0C] = CasioConstants.CASIO_READ_REQUEST_FOR_ALL_FEATURES_CHARACTERISTIC_UUID + handles_map[ + 0x0C + ] = CasioConstants.CASIO_READ_REQUEST_FOR_ALL_FEATURES_CHARACTERISTIC_UUID handles_map[0x0E] = CasioConstants.CASIO_ALL_FEATURES_CHARACTERISTIC_UUID handles_map[0x11] = CasioConstants.CASIO_DATA_REQUEST_SP_CHARACTERISTIC_UUID handles_map[0x14] = CasioConstants.CASIO_CONVOY_CHARACTERISTIC_UUID diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index d1a9a0a..86f04f9 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -14,7 +14,7 @@ def __init__(self) -> None: def set_name(self, name): self.name = name - self.model = self.model.B2100 if "2100" in name else self.model.B5600 + self.model = self.model.B5600 if "5600" in name else self.model.B2100 def set_address(self, address): self.address = address From 9a1961f6ab6dcd39d5155342f504d6c9b5cbffbb Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 11 Dec 2023 22:13:16 -0500 Subject: [PATCH 060/123] Added warning --- src/gshocktimeserver/connection.py | 2 +- src/gshocktimeserver/logger.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index fa5ae23..adc3723 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -31,7 +31,7 @@ async def connect(self): ) return True except Exception as e: - logger.warning(f"Cannot connect: {e}") + logger.debug(f"Cannot connect: {e}") return False async def disconnect(self): diff --git a/src/gshocktimeserver/logger.py b/src/gshocktimeserver/logger.py index 38cc8c5..fe1abb0 100644 --- a/src/gshocktimeserver/logger.py +++ b/src/gshocktimeserver/logger.py @@ -28,5 +28,8 @@ def debug(self, *args): def warn(self, *args): _logger.warn(args) + def warning(self, *args): + _logger.warn(args) + logger = Logger() From db43b2360ab07889dba170927241e117167557d0 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 12 Dec 2023 10:05:28 -0500 Subject: [PATCH 061/123] Adding location information when setting time --- README.rst | 2 + config.ini | 4 +- src/gshocktimeserver/casio_constants.py | 1 + src/gshocktimeserver/casio_watch.py | 80 ++++++++++++------------- src/gshocktimeserver/gshock_api.py | 21 ++++++- src/gshocktimeserver/gshock_server.py | 16 +++-- 6 files changed, 75 insertions(+), 49 deletions(-) diff --git a/README.rst b/README.rst index 60ab7e0..8093bbb 100644 --- a/README.rst +++ b/README.rst @@ -35,6 +35,8 @@ Install the following dependencies: pip3 install reactivex + sudo pip3 install geocoder + Troubleshooting: ================ If your watch cannot connect, and the ``--multi-watch`` parameter is not used, remove the "config.ini" file and try again. diff --git a/config.ini b/config.ini index 2c2f23c..bedcf22 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = C6:A1:33:29:7A:07 -device.name = CASIO GA-B2100 +device.address = CD:85:84:03:62:17 +device.name = CASIO GW-B5600 diff --git a/src/gshocktimeserver/casio_constants.py b/src/gshocktimeserver/casio_constants.py index 97d2fdc..2341cfd 100644 --- a/src/gshocktimeserver/casio_constants.py +++ b/src/gshocktimeserver/casio_constants.py @@ -35,4 +35,5 @@ class CasioConstants: "CASIO_REMINDER_TITLE": 0x30, "CASIO_REMINDER_TIME": 0x31, "CASIO_TIMER": 0x18, + "CASIO_MY_LOCATION": 0x24, } diff --git a/src/gshocktimeserver/casio_watch.py b/src/gshocktimeserver/casio_watch.py index b431fe7..a697db4 100644 --- a/src/gshocktimeserver/casio_watch.py +++ b/src/gshocktimeserver/casio_watch.py @@ -1,5 +1,6 @@ import json import datetime +import geocoder from settings import settings from utils import ( to_int_array, @@ -14,6 +15,7 @@ from enum import IntEnum from alarms import alarms_inst, alarm_decoder from logger import logger +from struct import pack CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -273,7 +275,7 @@ def int_to_month_str(month_int): if int_arr[3] == 0xFF: # 0XFF indicates end of reminders return json.dumps({"end": ""}) - + reminder_all = to_int_array(reminder_str) # Remove the first 2 chars: # 0x31 05 <--- 00 23 02 21 23 02 21 00 00 @@ -354,9 +356,7 @@ async def callWriter(connection, message: str): elif action == "SET_ALARMS": alarms_json_arr = json.loads(message).get("value") alarm_casio0 = to_compact_string( - to_hex_string( - alarms_inst.from_json_alarm_first_alarm(alarms_json_arr[0]) - ) + to_hex_string(alarms_inst.from_json_alarm_first_alarm(alarms_json_arr[0])) ) await connection.write(0x000E, alarm_casio0) alarm_casio = to_compact_string( @@ -371,9 +371,7 @@ def reminder_title_from_json(reminder_json): return to_byte_array(title_str, 18) def reminder_time_from_json(reminder_json): - def create_time_detail( - repeat_period, start_date, end_date, days_of_week - ): + def create_time_detail(repeat_period, start_date, end_date, days_of_week): def encode_date(time_detail, start_date, end_date): class Month: JANUARY = 1 @@ -414,9 +412,7 @@ def hex_to_dec(hex): # take the last 2 digits only time_detail[0] = hex_to_dec(start_date["year"] % 2000) - time_detail[1] = hex_to_dec( - string_to_month(start_date["month"]) - ) + time_detail[1] = hex_to_dec(string_to_month(start_date["month"])) time_detail[2] = hex_to_dec(start_date["day"]) time_detail[3] = hex_to_dec( end_date["year"] % 2000 @@ -437,33 +433,19 @@ def hex_to_dec(hex): if days_of_week is not None: for i in range(len(days_of_week)): if days_of_week[i] == "SUNDAY": - day_of_week = ( - day_of_week | ReminderMasks.SUNDAY_MASK - ) + day_of_week = day_of_week | ReminderMasks.SUNDAY_MASK elif days_of_week[i] == "MONDAY": - day_of_week = ( - day_of_week | ReminderMasks.MONDAY_MASK - ) + day_of_week = day_of_week | ReminderMasks.MONDAY_MASK elif days_of_week[i] == "TUESDAY": - day_of_week = ( - day_of_week | ReminderMasks.TUESDAY_MASK - ) + day_of_week = day_of_week | ReminderMasks.TUESDAY_MASK elif days_of_week[i] == "WEDNESDAY": - day_of_week = ( - day_of_week | ReminderMasks.WEDNESDAY_MASK - ) + day_of_week = day_of_week | ReminderMasks.WEDNESDAY_MASK elif days_of_week[i] == "THURSDAY": - day_of_week = ( - day_of_week | ReminderMasks.THURSDAY_MASK - ) + day_of_week = day_of_week | ReminderMasks.THURSDAY_MASK elif days_of_week[i] == "FRIDAY": - day_of_week = ( - day_of_week | ReminderMasks.FRIDAY_MASK - ) + day_of_week = day_of_week | ReminderMasks.FRIDAY_MASK elif days_of_week[i] == "SATURDAY": - day_of_week = ( - day_of_week | ReminderMasks.SATURDAY_MASK - ) + day_of_week = day_of_week | ReminderMasks.SATURDAY_MASK time_detail[6] = day_of_week time_detail[7] = 0 @@ -503,9 +485,7 @@ def create_time_period(enabled: bool, repeat_period: str) -> int: reminder_cmd += bytearray([create_time_period(enabled, repeat_period)]) reminder_cmd += bytearray( - create_time_detail( - repeat_period, start_date, end_date, days_of_week - ) + create_time_detail(repeat_period, start_date, end_date, days_of_week) ) return reminder_cmd @@ -518,9 +498,7 @@ def create_time_period(enabled: bool, repeat_period: str) -> int: title_byte_arr = bytearray([CHARACTERISTICS["CASIO_REMINDER_TITLE"]]) title_byte_arr += bytearray([index + 1]) title_byte_arr += title - title_byte_arr_to_send = to_compact_string( - to_hex_string(title_byte_arr) - ) + title_byte_arr_to_send = to_compact_string(to_hex_string(title_byte_arr)) await connection.write(0x000E, title_byte_arr_to_send) reminder_time_byte_arr = bytearray([]) @@ -606,6 +584,30 @@ def encode_time_adjustment(time_adjustment): elif action == "GET_TIMER": connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_TIMER"]])) + elif action == "SET_MY_LOCATION": + g = geocoder.ip("me") + json_data = json.dumps({"lat": g.latlng[0], "lon": g.latlng[1]}) + print(json_data) + + latitude = g.latlng[0] + longitude = g.latlng[1] + + casio_radio_and_location_to_send = [ + bytearray([0x24]), # CASIO_LOCATION_AND_RADIO_INFORMATION + bytearray([0x00]), # home city + bytearray([0x01]), # always 1 + pack(">d", latitude) if latitude is not None else bytearray(8), + pack(">d", longitude) if longitude is not None else bytearray(8), + bytearray([0x04]), # radio id + ] + + location_send_array = bytearray(b"".join(casio_radio_and_location_to_send)) + + # Print the resulting bytearray if needed + print(location_send_array) + + await connection.write(0x000C, location_send_array) + elif action == "SET_TIMER": seconds = json.loads(message).get("value") @@ -624,9 +626,7 @@ def encode(seconds_str): return arr seconds_as_byte_arr = encode(seconds) - seconds_as_compact_str = to_compact_string( - to_hex_string(seconds_as_byte_arr) - ) + seconds_as_compact_str = to_compact_string(to_hex_string(seconds_as_byte_arr)) await connection.write(0x000E, seconds_as_compact_str) elif action == "SET_TIME": diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 14c5729..db3f14b 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -78,12 +78,12 @@ async def get_pressed_button(self) -> WatchButton: The return values are interpreted as follows: - - `LOWER_LEFT` - this connection is initiated by a long-press of the lower-left - button on the watch.The app receiving this type of connection can now send and + - `LOWER_LEFT` - this connection is initiated by a long-press of the lower-left + button on the watch.The app receiving this type of connection can now send and receive commands to the watch. - `LOWER_RIGHT` - this connection is initiated by a short-press of the lower-right button, - which is usually used to set time. But the app can use this signal to perform other + which is usually used to set time. But the app can use this signal to perform other arbitrary functions. Therefore, this button is also referred as `ACTION BUTTON`. The connection will automatically disconnect in about 20 seconds. @@ -451,6 +451,21 @@ async def set_timer(self, timerValue): """{"action": "SET_TIMER", "value": """ + str(timerValue) + """ }""" ) + async def set_my_location(self): + """Set my long/lat. + + Parameters + ---------- + None + + Returns + ------- + None + """ + await self.connection.sendMessage( + """{"action": "SET_MY_LOCATION", "value": "" }""" + ) + async def get_time_adjustment(self): """Determine if auto-tame adjustment is set or not diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 5a07a78..5cc962b 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -1,5 +1,6 @@ import asyncio import sys + from datetime import datetime from connection import Connection @@ -23,11 +24,17 @@ async def main(argv): def prompt(): - print("==============================================================================================") + print( + "==============================================================================================" + ) print("Short-press lower-right button on your watch to set time...") print("") - print("If Auto-time set on watch, the watch will connect and run automatically up to 4 times per day.") - print("==============================================================================================") + print( + "If Auto-time set on watch, the watch will connect and run automatically up to 4 times per day." + ) + print( + "==============================================================================================" + ) print("") @@ -57,8 +64,9 @@ async def run_time_server(): continue await api.get_app_info() + await api.set_my_location() await api.set_time() - print (f"Time set at {datetime.now()} on {watch_info.name}") + print(f"Time set at {datetime.now()} on {watch_info.name}") # You can add mail notification here if you run your mail server. # send_mail_notification(args.mailto) From a8fe12ceee67ba508648fd814577cdf9acacbae9 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 13 Dec 2023 11:58:14 -0500 Subject: [PATCH 062/123] Can save settings --- src/gshocktimeserver/casio_constants.py | 1 - src/gshocktimeserver/casio_watch.py | 17 +++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gshocktimeserver/casio_constants.py b/src/gshocktimeserver/casio_constants.py index 2341cfd..97d2fdc 100644 --- a/src/gshocktimeserver/casio_constants.py +++ b/src/gshocktimeserver/casio_constants.py @@ -35,5 +35,4 @@ class CasioConstants: "CASIO_REMINDER_TITLE": 0x30, "CASIO_REMINDER_TIME": 0x31, "CASIO_TIMER": 0x18, - "CASIO_MY_LOCATION": 0x24, } diff --git a/src/gshocktimeserver/casio_watch.py b/src/gshocktimeserver/casio_watch.py index a697db4..95a258f 100644 --- a/src/gshocktimeserver/casio_watch.py +++ b/src/gshocktimeserver/casio_watch.py @@ -1,5 +1,6 @@ import json import datetime +import struct import geocoder from settings import settings from utils import ( @@ -593,20 +594,20 @@ def encode_time_adjustment(time_adjustment): longitude = g.latlng[1] casio_radio_and_location_to_send = [ - bytearray([0x24]), # CASIO_LOCATION_AND_RADIO_INFORMATION - bytearray([0x00]), # home city - bytearray([0x01]), # always 1 - pack(">d", latitude) if latitude is not None else bytearray(8), - pack(">d", longitude) if longitude is not None else bytearray(8), - bytearray([0x04]), # radio id + bytes([0x24]), # CASIO_LOCATION_AND_RADIO_INFORMATION + bytes([0x00]), # home city + bytes([0x01]), # always 1 + bytearray(struct.pack(" Date: Sun, 24 Dec 2023 14:47:18 -0500 Subject: [PATCH 063/123] Cleanup --- config.ini | 4 ++-- src/gshocktimeserver/api_tests.py | 14 ++++++++------ src/gshocktimeserver/casio_watch.py | 27 ++------------------------- src/gshocktimeserver/gshock_api.py | 15 --------------- src/gshocktimeserver/gshock_server.py | 1 - 5 files changed, 12 insertions(+), 49 deletions(-) diff --git a/config.ini b/config.ini index bedcf22..0727f89 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:84:03:62:17 -device.name = CASIO GW-B5600 +device.address = C6:A1:40:10:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 135e069..15e6135 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -10,15 +10,17 @@ from scanner import scanner from logger import logger + def prompt(): - print ("========================================================================") - print ("Press and hold lower-left button on your watch for 3 seconds to start...") - print ("========================================================================") - print ("") + print("========================================================================") + print("Press and hold lower-left button on your watch for 3 seconds to start...") + print("========================================================================") + print("") + async def run_api_tests(): prompt() - + device = await scanner.scan() logger.debug("Found: {}".format(device)) @@ -49,7 +51,7 @@ async def run_api_tests(): seconds = await api.get_timer() logger.debug("timer: {} seconds".format(seconds)) - await api.set_timer(seconds + 10) + # await api.set_timer(seconds + 10) time_adjstment = await api.get_time_adjustment() logger.debug("time_adjstment: {}".format(time_adjstment)) diff --git a/src/gshocktimeserver/casio_watch.py b/src/gshocktimeserver/casio_watch.py index 95a258f..815bdbb 100644 --- a/src/gshocktimeserver/casio_watch.py +++ b/src/gshocktimeserver/casio_watch.py @@ -573,42 +573,19 @@ def encode(settings: dict): def encode_time_adjustment(time_adjustment): raw_string = settings.CasioIsAutoTimeOriginalValue + "0x11 0F 0F 0F 06 00 00 00 00 00 01 00 80 30 30" int_array = to_int_array(raw_string) - int_array[12] = 0x80 if time_adjustment == "True" else 0x00 return bytes(int_array) encoded_time_adj = encode_time_adjustment(value) + write_cmd = to_compact_string(to_hex_string(encoded_time_adj)) await connection.write(0x000E, write_cmd) elif action == "GET_TIMER": connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_TIMER"]])) - elif action == "SET_MY_LOCATION": - g = geocoder.ip("me") - json_data = json.dumps({"lat": g.latlng[0], "lon": g.latlng[1]}) - print(json_data) - - latitude = g.latlng[0] - longitude = g.latlng[1] - - casio_radio_and_location_to_send = [ - bytes([0x24]), # CASIO_LOCATION_AND_RADIO_INFORMATION - bytes([0x00]), # home city - bytes([0x01]), # always 1 - bytearray(struct.pack(" Date: Mon, 8 Jan 2024 17:40:44 -0500 Subject: [PATCH 064/123] WIP --- config.ini | 4 +- src/gshocktimeserver/api_tests.py | 102 ++++---- src/gshocktimeserver/casio_constants.py | 2 + src/gshocktimeserver/connection.py | 8 +- src/gshocktimeserver/gshock_api.py | 31 +-- src/gshocktimeserver/gshock_server.py | 4 +- src/gshocktimeserver/message_dispatcher.py | 263 +++++++++++++++++++++ 7 files changed, 327 insertions(+), 87 deletions(-) create mode 100644 src/gshocktimeserver/message_dispatcher.py diff --git a/config.ini b/config.ini index 0727f89..8ef9d8c 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = C6:A1:40:10:7A:07 -device.name = CASIO GA-B2100 +device.address = CD:85:03:12:62:17 +device.name = CASIO GW-B5600 diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 15e6135..9206a2a 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -29,72 +29,72 @@ async def run_api_tests(): api = GshockAPI(connection) - await api.get_app_info() + # await api.get_app_info() - pressed_button = await api.get_pressed_button() - logger.debug("pressed button: {}".format(pressed_button)) + # pressed_button = await api.get_pressed_button() + # logger.debug("pressed button: {}".format(pressed_button)) - watch_name = await api.get_watch_name() - logger.info("got watch name: {}".format(watch_name)) + # watch_name = await api.get_watch_name() + # logger.info("got watch name: {}".format(watch_name)) - await api.set_time() + # await api.set_time() - alarms = await api.get_alarms() - logger.debug("alarms: {}".format(alarms)) + # alarms = await api.get_alarms() + # logger.debug("alarms: {}".format(alarms)) - alarms[3]["enabled"] = True - alarms[3]["hour"] = 7 - alarms[3]["minute"] = 25 - alarms[3]["enabled"] = False - await api.set_alarms(alarms) + # alarms[3]["enabled"] = True + # alarms[3]["hour"] = 7 + # alarms[3]["minute"] = 25 + # alarms[3]["enabled"] = False + # await api.set_alarms(alarms) seconds = await api.get_timer() logger.debug("timer: {} seconds".format(seconds)) - # await api.set_timer(seconds + 10) - time_adjstment = await api.get_time_adjustment() - logger.debug("time_adjstment: {}".format(time_adjstment)) + # # await api.set_timer(seconds + 10) + # time_adjstment = await api.get_time_adjustment() + # logger.debug("time_adjstment: {}".format(time_adjstment)) - settings.timeAdjustment = True - await api.set_time_adjustment(settings) + # settings.timeAdjustment = True + # await api.set_time_adjustment(settings) - settings_local = await api.get_basic_settings() - logger.debug("settings: {}".format(settings_local)) + # settings_local = await api.get_basic_settings() + # logger.debug("settings: {}".format(settings_local)) - settings_local["button_tone"] = True - settings_local["language"] = "Engish" - settings_local["time_format"] = "12h" + # settings_local["button_tone"] = True + # settings_local["language"] = "Engish" + # settings_local["time_format"] = "12h" - await api.set_settings(settings_local) + # await api.set_settings(settings_local) # Create a single event - tz = pytz.timezone("America/Toronto") - dt = datetime.now(timezone.utc) - utc_timestamp = dt.timestamp() - event_date = create_event_date(utc_timestamp, tz) - event_date_str = json.dumps(event_date.__dict__) - event_json_str = ( - """{"title":"Test Event", "time":{"selected":\"""" - + str(False) - + """\", "enabled":\"""" - + str(True) - + """\", "repeat_period":\"""" - + RepeatPeriod.WEEKLY - + """\","days_of_week":\"""" - + "MONDAY" - + """\", "start_date":""" - + event_date_str - + """, "end_date":""" - + event_date_str - + """}}""" - ) - Event().create_event(json.loads(event_json_str)) - - reminders = await api.get_reminders() - for reminder in reminders: - logger.debug("reminder: {}".format(reminder.__str__())) - - await api.set_reminders(reminders) + # tz = pytz.timezone("America/Toronto") + # dt = datetime.now(timezone.utc) + # utc_timestamp = dt.timestamp() + # event_date = create_event_date(utc_timestamp, tz) + # event_date_str = json.dumps(event_date.__dict__) + # event_json_str = ( + # """{"title":"Test Event", "time":{"selected":\"""" + # + str(False) + # + """\", "enabled":\"""" + # + str(True) + # + """\", "repeat_period":\"""" + # + RepeatPeriod.WEEKLY + # + """\","days_of_week":\"""" + # + "MONDAY" + # + """\", "start_date":""" + # + event_date_str + # + """, "end_date":""" + # + event_date_str + # + """}}""" + # ) + # Event().create_event(json.loads(event_json_str)) + + # reminders = await api.get_reminders() + # for reminder in reminders: + # logger.debug("reminder: {}".format(reminder.__str__())) + + # await api.set_reminders(reminders) input("Hit any key to disconnect") diff --git a/src/gshocktimeserver/casio_constants.py b/src/gshocktimeserver/casio_constants.py index 97d2fdc..a094f16 100644 --- a/src/gshocktimeserver/casio_constants.py +++ b/src/gshocktimeserver/casio_constants.py @@ -35,4 +35,6 @@ class CasioConstants: "CASIO_REMINDER_TITLE": 0x30, "CASIO_REMINDER_TIME": 0x31, "CASIO_TIMER": 0x18, + "ERROR": 0xFF, + "UNKNOWN": 0x0A, } diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index adc3723..8779eda 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -1,6 +1,7 @@ from bleak import BleakClient from bleak.backends.characteristic import BleakGATTCharacteristic from casio_constants import CasioConstants +import message_dispatcher from utils import to_casio_cmd from data_watcher import data_watcher from casio_watch import to_json, callWriter @@ -16,11 +17,7 @@ def __init__(self, device): def notification_handler( self, characteristic: BleakGATTCharacteristic, data: bytearray ): - """Simple notification handler which prints the data received.""" - json = to_json(data) - name = list(dict(json).keys())[0] - value = list(dict(json).values())[0] - data_watcher.emit_event(name, value) + message_dispatcher.MessageDispatcher.on_received(data) async def connect(self): try: @@ -67,3 +64,4 @@ def init_handles_map(self): async def sendMessage(self, message): await callWriter(self, message) + # await message_dispatcher.send_to_watch(self, message) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index b5057c0..bfd68a4 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -4,6 +4,7 @@ import time from data_watcher import data_watcher +import message_dispatcher from utils import ( to_ascii_string, to_int_array, @@ -406,34 +407,10 @@ async def get_timer(self): ------- timer_value: Integer, the timer number in seconds as an Int. E.g.: 180 means the timer is set for 3 minutes. """ - return await self._get_timer("18") + return await self._get_timer() - async def _get_timer(self, key): - await self.connection.request(key) - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def decode_value(data: str) -> str: - timer_int_array = to_int_array(data) - - hours = timer_int_array[1] - minutes = timer_int_array[2] - seconds = timer_int_array[3] - - in_seconds = hours * 3600 + minutes * 60 + seconds - return in_seconds - - def get_timer(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") - - seconds = decode_value(value) - res = result_queue.dequeue(key) - res.set_result(seconds) - - self.subscribe("CASIO_TIMER", get_timer) + async def _get_timer(self): + result = await message_dispatcher.TimerIO.request(self.connection) return await result async def set_timer(self, timerValue): diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index e1c3a50..2256422 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -19,8 +19,8 @@ async def main(argv): - await run_time_server() - # await run_api_tests() + # await run_time_server() + await run_api_tests() def prompt(): diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py new file mode 100644 index 0000000..b990ea9 --- /dev/null +++ b/src/gshocktimeserver/message_dispatcher.py @@ -0,0 +1,263 @@ +import asyncio +import json +from typing import Any +import connection +from casio_constants import CasioConstants +from utils import to_compact_string, to_hex_string, to_int_array +from alarms import alarms_inst, alarm_decoder + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class AlarmsIO: + @staticmethod + async def send_to_watch(message): + alarm_command = to_compact_string( + to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]])) + ) + await connection.write(0x000C, alarm_command) + + @staticmethod + async def send_to_watch_set(message): + alarms_json_arr = json.loads(message).get("value") + alarm_casio0 = to_compact_string( + to_hex_string(alarms_inst.from_json_alarm_first_alarm(alarms_json_arr[0])) + ) + await connection.write(0x000E, alarm_casio0) + alarm_casio = to_compact_string( + to_hex_string(alarms_inst.from_json_alarm_secondary_alarms(alarms_json_arr)) + ) + await connection.write(0x000E, alarm_casio) + + @staticmethod + def on_received(message): + print(f"AlarmsIO onReceived: {message}") + + +class EventsIO: + @staticmethod + def send_to_watch_set(message): + print(f"EventsIO sendToWatchSet: {message}") + + @staticmethod + def on_received(message): + print(f"EventsIO onReceived: {message}") + + @staticmethod + def on_received_title(message): + print(f"EventsIO onReceivedTitle: {message}") + + +class SettingsIO: + @staticmethod + def send_to_watch(message): + print(f"SettingsIO sendToWatch: {message}") + + @staticmethod + def send_to_watch_set(message): + print(f"SettingsIO sendToWatchSet: {message}") + + @staticmethod + def on_received(message): + print(f"SettingsIO onReceived: {message}") + + +class TimeAdjustmentIO: + @staticmethod + def send_to_watch(message): + print(f"TimeAdjustmentIO sendToWatch: {message}") + + @staticmethod + def send_to_watch_set(message): + print(f"TimeAdjustmentIO sendToWatchSet: {message}") + + @staticmethod + def on_received(message): + print(f"TimeAdjustmentIO onReceived: {message}") + + +class TimerIO: + result: asyncio.Future[Any] = None + + @staticmethod + async def request(connection): + print(f"TimerIO request") + await connection.request("18") + + loop = asyncio.get_running_loop() + TimerIO.result = loop.create_future() + return TimerIO.result + + @staticmethod + async def send_to_watch(message): + print(f"TimerIO sendToWatch: {message}") + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_TIMER"]])) + + @staticmethod + async def send_to_watch_set(data): + print(f"TimerIO sendToWatchSet: {data}") + + def encode(seconds_str): + in_seconds = int(seconds_str) + hours = in_seconds // 3600 + minutes_and_seconds = in_seconds % 3600 + minutes = minutes_and_seconds // 60 + seconds = minutes_and_seconds % 60 + + arr = bytearray(7) + arr[0] = 0x18 + arr[1] = hours + arr[2] = minutes + arr[3] = seconds + return arr + + seconds_as_byte_arr = encode(seconds) + seconds_as_compact_str = to_compact_string(to_hex_string(seconds_as_byte_arr)) + await connection.write(0x000E, seconds_as_compact_str) + + @staticmethod + def on_received(data): + print(f"TimerIO onReceived: {data}") + + def decode_value(data: str) -> str: + timer_int_array = data + + hours = timer_int_array[1] + minutes = timer_int_array[2] + seconds = timer_int_array[3] + + in_seconds = hours * 3600 + minutes * 60 + seconds + return in_seconds + + decoded = decode_value(data) + seconds = int(decoded) + TimerIO.result.set_result(seconds) + + +class TimeIO: + @staticmethod + def send_to_watch_set(message): + print(f"TimeIO sendToWatchSet: {message}") + + @staticmethod + def on_received(message): + print(f"TimeIO onReceived: {message}") + + +class WatchNameIO: + result: asyncio.Future[Any] = None + + @staticmethod + def on_received(self, data): + print(f"WatchNameIO onReceived: {data}") + + @staticmethod + async def request(self): + print(f"WatchNameIO request: {self}") + + +class DstForWorldCitiesIO: + @staticmethod + def on_received(message): + print(f"DstForWorldCitiesIO onReceived: {message}") + + +class WorldCitiesIO: + @staticmethod + def on_received(message): + print(f"WorldCitiesIO onReceived: {message}") + + +class DstWatchStateIO: + @staticmethod + def on_received(message): + print(f"DstWatchStateIO onReceived: {message}") + + +class WatchConditionIO: + @staticmethod + def on_received(message): + print(f"WatchConditionIO onReceived: {message}") + + +class AppInfoIO: + @staticmethod + def on_received(message): + print(f"AppInfoIO onReceived: {message}") + + +class ButtonPressedIO: + @staticmethod + def on_received(message): + print(f"ButtonPressedIO onReceived: {message}") + + +class ErrorIO: + @staticmethod + def on_received(message): + print(f"ErrorIO onReceived: {message}") + + +class UnknownIO: + @staticmethod + def on_received(message): + print(f"UnknownIO onReceived: {message}") + + +class MessageDispatcher: + watch_senders = { + "GET_ALARMS": AlarmsIO.send_to_watch, + "SET_ALARMS": AlarmsIO.send_to_watch_set, + "SET_REMINDERS": EventsIO.send_to_watch_set, + "GET_SETTINGS": SettingsIO.send_to_watch, + "SET_SETTINGS": SettingsIO.send_to_watch_set, + "GET_TIME_ADJUSTMENT": TimeAdjustmentIO.send_to_watch, + "SET_TIME_ADJUSTMENT": TimeAdjustmentIO.send_to_watch_set, + "GET_TIMER": TimerIO.send_to_watch, + "SET_TIMER": TimerIO.send_to_watch_set, + "SET_TIME": TimeIO.send_to_watch_set, + } + + data_received_messages = { + CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]: AlarmsIO.on_received, + CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]: AlarmsIO.on_received, + CHARACTERISTICS["CASIO_DST_SETTING"]: DstForWorldCitiesIO.on_received, + CHARACTERISTICS["CASIO_REMINDER_TIME"]: EventsIO.on_received, + CHARACTERISTICS["CASIO_REMINDER_TITLE"]: EventsIO.on_received_title, + CHARACTERISTICS["CASIO_TIMER"]: TimerIO.on_received, + CHARACTERISTICS["CASIO_WORLD_CITIES"]: WorldCitiesIO.on_received, + CHARACTERISTICS["CASIO_DST_WATCH_STATE"]: DstWatchStateIO.on_received, + CHARACTERISTICS["CASIO_WATCH_NAME"]: WatchNameIO.on_received, + CHARACTERISTICS["CASIO_WATCH_CONDITION"]: WatchConditionIO.on_received, + CHARACTERISTICS["CASIO_APP_INFORMATION"]: AppInfoIO.on_received, + CHARACTERISTICS["CASIO_BLE_FEATURES"]: ButtonPressedIO.on_received, + CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"]: SettingsIO.on_received, + CHARACTERISTICS["CASIO_SETTING_FOR_BLE"]: TimeAdjustmentIO.on_received, + CHARACTERISTICS["ERROR"]: ErrorIO.on_received, + CHARACTERISTICS["UNKNOWN"]: UnknownIO.on_received, + } + + @staticmethod + def send_to_watch(self, connection, message): + action = message.get("action") + MessageDispatcher.watch_senders[action](connection, message) + + @staticmethod + def on_received(data): + key = data[0] + if key not in MessageDispatcher.data_received_messages: + print(f"Unknown key: {key}") + else: + print(f"Found key: {MessageDispatcher.data_received_messages[key]}") + MessageDispatcher.data_received_messages[key](data) + + +# Usage example +if __name__ == "__main__": + # Simulated messages + sample_message = {"action": "GET_SETTINGS"} + sample_data = "1,2,3,4,5" + + # Simulated message dispatching + MessageDispatcher.send_to_watch(sample_message) + MessageDispatcher.on_received(sample_data) From 985420d5a88c3c8346bf27f306bfec85ce3dc6f8 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 9 Jan 2024 20:17:20 -0500 Subject: [PATCH 065/123] WIP --- config.ini | 4 +- src/gshocktimeserver/__init__.py | 2 + src/gshocktimeserver/api_tests.py | 12 +- src/gshocktimeserver/connection.py | 4 +- src/gshocktimeserver/gshock_api.py | 23 +- src/gshocktimeserver/iolib/__init__.py | 0 src/gshocktimeserver/iolib/timer_io.py | 66 ++++++ src/gshocktimeserver/iolib/watch_name_io.py | 33 +++ src/gshocktimeserver/logger.py | 4 +- src/gshocktimeserver/message_dispatcher.py | 83 +------- src/gshocktimeserver/scanner.py | 9 +- src/gshocktimeserver/watch_info.py | 223 +++++++++++++++++++- 12 files changed, 346 insertions(+), 117 deletions(-) create mode 100644 src/gshocktimeserver/iolib/__init__.py create mode 100644 src/gshocktimeserver/iolib/timer_io.py create mode 100644 src/gshocktimeserver/iolib/watch_name_io.py diff --git a/config.ini b/config.ini index 8ef9d8c..e4cd7c7 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:03:12:62:17 -device.name = CASIO GW-B5600 +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/__init__.py b/src/gshocktimeserver/__init__.py index c8ace5a..0f76b25 100644 --- a/src/gshocktimeserver/__init__.py +++ b/src/gshocktimeserver/__init__.py @@ -1,5 +1,7 @@ import sys +sys.path.append("gshocktimeserver/io") + if sys.version_info[:2] >= (3, 8): # TODO: Import directly (no need for conditional) when `python_requires = >= 3.8` from importlib.metadata import PackageNotFoundError, version # pragma: no cover diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 9206a2a..847eba6 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -34,8 +34,8 @@ async def run_api_tests(): # pressed_button = await api.get_pressed_button() # logger.debug("pressed button: {}".format(pressed_button)) - # watch_name = await api.get_watch_name() - # logger.info("got watch name: {}".format(watch_name)) + watch_name = await api.get_watch_name() + print("got watch name: {}".format(watch_name)) # await api.set_time() @@ -48,8 +48,12 @@ async def run_api_tests(): # alarms[3]["enabled"] = False # await api.set_alarms(alarms) - seconds = await api.get_timer() - logger.debug("timer: {} seconds".format(seconds)) + # seconds = await api.get_timer() + # print("timer: {} seconds".format(seconds)) + + # await api.set_timer(235) + # seconds = await api.get_timer() + # print("timer: {} after setting seconds".format(seconds)) # # await api.set_timer(seconds + 10) # time_adjstment = await api.get_time_adjustment() diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index 8779eda..cc34cae 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -63,5 +63,5 @@ def init_handles_map(self): return handles_map async def sendMessage(self, message): - await callWriter(self, message) - # await message_dispatcher.send_to_watch(self, message) + # await callWriter(self, message) + message_dispatcher.MessageDispatcher.send_to_watch(message) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index bfd68a4..448eedf 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -49,27 +49,10 @@ async def get_watch_name(self): ------- name : String, i.e: "GW-B5600" """ - return await self._get_watch_name("23") + return await self._get_watch_name() - async def _get_watch_name(self, key): - await self.connection.request(key) - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def on_data_received(keyed_data): - _key = "23" - - result_value = keyed_data.get("value") - result_key = keyed_data.get("key") - - if result_key == _key: - result_str = clean_str(to_ascii_string(result_value, 1)) - res = result_queue.dequeue(_key) - res.set_result(result_str) - - self.subscribe("CASIO_WATCH_NAME", lambda data: on_data_received(data)) + async def _get_watch_name(self): + result = await message_dispatcher.WatchNameIO.request(self.connection) return await result async def get_pressed_button(self) -> WatchButton: diff --git a/src/gshocktimeserver/iolib/__init__.py b/src/gshocktimeserver/iolib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/gshocktimeserver/iolib/timer_io.py b/src/gshocktimeserver/iolib/timer_io.py new file mode 100644 index 0000000..c0a5379 --- /dev/null +++ b/src/gshocktimeserver/iolib/timer_io.py @@ -0,0 +1,66 @@ +import asyncio +from typing import Any + +import connection +from utils import to_compact_string, to_hex_string +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class TimerIO: + result: asyncio.Future[Any] = None + + @staticmethod + async def request(connection): + print(f"TimerIO request") + await connection.request("18") + + loop = asyncio.get_running_loop() + TimerIO.result = loop.create_future() + return TimerIO.result + + @staticmethod + async def send_to_watch(message): + print(f"TimerIO sendToWatch: {message}") + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_TIMER"]])) + + @staticmethod + async def send_to_watch_set(data): + print(f"TimerIO sendToWatchSet: {data}") + + def encode(seconds_str): + in_seconds = int(seconds_str) + hours = in_seconds // 3600 + minutes_and_seconds = in_seconds % 3600 + minutes = minutes_and_seconds // 60 + seconds = minutes_and_seconds % 60 + + arr = bytearray(7) + arr[0] = 0x18 + arr[1] = hours + arr[2] = minutes + arr[3] = seconds + return arr + + seconds_as_byte_arr = encode(data) + seconds_as_compact_str = to_compact_string(to_hex_string(seconds_as_byte_arr)) + await connection.write(0x000E, seconds_as_compact_str) + + @staticmethod + def on_received(data): + print(f"TimerIO onReceived") + + def decode_value(data: str) -> str: + timer_int_array = data + + hours = timer_int_array[1] + minutes = timer_int_array[2] + seconds = timer_int_array[3] + + in_seconds = hours * 3600 + minutes * 60 + seconds + return in_seconds + + decoded = decode_value(data) + seconds = int(decoded) + TimerIO.result.set_result(seconds) diff --git a/src/gshocktimeserver/iolib/watch_name_io.py b/src/gshocktimeserver/iolib/watch_name_io.py new file mode 100644 index 0000000..9fff399 --- /dev/null +++ b/src/gshocktimeserver/iolib/watch_name_io.py @@ -0,0 +1,33 @@ +import asyncio +from typing import Any + +import connection +from casio_constants import CasioConstants +from utils import clean_str, to_ascii_string, to_hex_string +from watch_info import WatchInfo + + +class WatchNameIO: + result: asyncio.Future[Any] = None + + @staticmethod + async def request(connection): + print(f"WatchNameIO request") + await connection.request("23") + + loop = asyncio.get_running_loop() + WatchNameIO.result = loop.create_future() + return WatchNameIO.result + # return WatchInfo.name + + @staticmethod + def on_received(data): + print(f"WatchNameIO onReceived: {data}") + hex_str = to_hex_string(data) + ascii_str = to_ascii_string(hex_str, 1) + clean_data = clean_str(ascii_str) + WatchNameIO.result.set_result(clean_data) + + @staticmethod + async def send_to_watch(message): + print(f"WatchNameIO sendToWatch: {message}") diff --git a/src/gshocktimeserver/logger.py b/src/gshocktimeserver/logger.py index fe1abb0..73dd99c 100644 --- a/src/gshocktimeserver/logger.py +++ b/src/gshocktimeserver/logger.py @@ -10,9 +10,7 @@ class Logger: logging.basicConfig( # encoding='utf-8', (for pythonn 3.9 and higher) level=logging.INFO, # log_level, - handlers=[ - logging.StreamHandler() - ], + handlers=[logging.StreamHandler()], format="%(asctime)-15s %(name)-8s %(levelname)s: %(message)s", ) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index b990ea9..da67830 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -1,8 +1,13 @@ +import sys import asyncio import json from typing import Any import connection from casio_constants import CasioConstants + +from iolib.timer_io import TimerIO +from iolib.watch_name_io import WatchNameIO + from utils import to_compact_string, to_hex_string, to_int_array from alarms import alarms_inst, alarm_decoder @@ -76,64 +81,6 @@ def on_received(message): print(f"TimeAdjustmentIO onReceived: {message}") -class TimerIO: - result: asyncio.Future[Any] = None - - @staticmethod - async def request(connection): - print(f"TimerIO request") - await connection.request("18") - - loop = asyncio.get_running_loop() - TimerIO.result = loop.create_future() - return TimerIO.result - - @staticmethod - async def send_to_watch(message): - print(f"TimerIO sendToWatch: {message}") - connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_TIMER"]])) - - @staticmethod - async def send_to_watch_set(data): - print(f"TimerIO sendToWatchSet: {data}") - - def encode(seconds_str): - in_seconds = int(seconds_str) - hours = in_seconds // 3600 - minutes_and_seconds = in_seconds % 3600 - minutes = minutes_and_seconds // 60 - seconds = minutes_and_seconds % 60 - - arr = bytearray(7) - arr[0] = 0x18 - arr[1] = hours - arr[2] = minutes - arr[3] = seconds - return arr - - seconds_as_byte_arr = encode(seconds) - seconds_as_compact_str = to_compact_string(to_hex_string(seconds_as_byte_arr)) - await connection.write(0x000E, seconds_as_compact_str) - - @staticmethod - def on_received(data): - print(f"TimerIO onReceived: {data}") - - def decode_value(data: str) -> str: - timer_int_array = data - - hours = timer_int_array[1] - minutes = timer_int_array[2] - seconds = timer_int_array[3] - - in_seconds = hours * 3600 + minutes * 60 + seconds - return in_seconds - - decoded = decode_value(data) - seconds = int(decoded) - TimerIO.result.set_result(seconds) - - class TimeIO: @staticmethod def send_to_watch_set(message): @@ -141,19 +88,7 @@ def send_to_watch_set(message): @staticmethod def on_received(message): - print(f"TimeIO onReceived: {message}") - - -class WatchNameIO: - result: asyncio.Future[Any] = None - - @staticmethod - def on_received(self, data): - print(f"WatchNameIO onReceived: {data}") - - @staticmethod - async def request(self): - print(f"WatchNameIO request: {self}") + print(f"TimeIO onReceived") class DstForWorldCitiesIO: @@ -238,9 +173,9 @@ class MessageDispatcher: } @staticmethod - def send_to_watch(self, connection, message): - action = message.get("action") - MessageDispatcher.watch_senders[action](connection, message) + def send_to_watch(message): + action = json.loads(message).get("action") + MessageDispatcher.watch_senders[action](message) @staticmethod def on_received(data): diff --git a/src/gshocktimeserver/scanner.py b/src/gshocktimeserver/scanner.py index de3b3c6..9293a9b 100644 --- a/src/gshocktimeserver/scanner.py +++ b/src/gshocktimeserver/scanner.py @@ -9,7 +9,7 @@ class Scanner: CASIO_SERVICE_UUID = "00001804-0000-1000-8000-00805f9b34fb" - async def scan(self, device_address = None): + async def scan(self, device_address=None): scanner = BleakScanner() logger.debug("Scanning for devices...") @@ -17,14 +17,15 @@ async def scan(self, device_address = None): while True: device = await scanner.find_device_by_filter( lambda d, ad: d.name and d.name.lower().startswith("casio"), - timeout=5 * 60.0 + timeout=5 * 60.0, ) logger.debug(f"device: {device}") if device is None: continue - watch_info.set_name(device.name) - watch_info.set_address(device.address) + # watch_info.set_name(device.name) + # watch_info.set_address(device.address) + watch_info.set_name_and_model(device.name) conf.put("device.address", device.address) conf.put("device.name", device.name) diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index 86f04f9..9af22a0 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -1,23 +1,230 @@ from enum import Enum -class WatchInfo: +# class WatchInfo: + +# class model(Enum): +# B5600 = 1 +# B2100 = 2 +# UNKNOWN = 3 + +# def __init__(self) -> None: +# self.name = "" +# self.address = "" + +# def set_name(self, name): +# self.name = name +# self.model = self.model.B5600 if "5600" in name else self.model.B2100 + +# def set_address(self, address): +# self.address = address - class model(Enum): - B5600 = 1 - B2100 = 2 - UNKNOWN = 3 +from enum import Enum + + +class WATCH_MODEL(Enum): + GA = 1 + GW = 2 + DW = 3 + GMW = 4 + GPR = 5 + GST = 6 + MSG = 7 + GB001 = 8 + UNKNOWN = 9 - def __init__(self) -> None: + +class WatchInfo: + def __init__(self): self.name = "" + self.shortName = "" self.address = "" + self.model = WATCH_MODEL.UNKNOWN + self.worldCitiesCount = 2 + self.dstCount = 3 + self.alarmCount = 5 + self.hasAutoLight = False + self.hasReminders = False + self.shortLightDuration = "" + self.longLightDuration = "" + self.weekLanguageSupported = True - def set_name(self, name): + self.models = [ + { + "model": WATCH_MODEL.GW, + "worldCitiesCount": 6, + "dstCount": 3, + "alarmCount": 5, + "hasAutoLight": False, + "hasReminders": True, + "shortLightDuration": "2s", + "longLightDuration": "4s", + }, + { + "model": WATCH_MODEL.GST, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": True, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.GMW, + "worldCitiesCount": 6, + "dstCount": 3, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": True, + "shortLightDuration": "2s", + "longLightDuration": "4s", + }, + { + "model": WATCH_MODEL.GA, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": True, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.GB001, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.MSG, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": True, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.GST, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": True, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.GPR, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.DW, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.GPR, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + "weekLanguageSupported": False, + }, + { + "model": WATCH_MODEL.DW, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + { + "model": WATCH_MODEL.UNKNOWN, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + }, + ] + + self.model_map = {model["model"]: model for model in self.models} + + def set_name_and_model(self, name): self.name = name - self.model = self.model.B5600 if "5600" in name else self.model.B2100 + + parts = self.name.split(" ") + if len(parts) > 1: + self.shortName = parts[1] + + if self.shortName.startswith("GA"): + self.model = WATCH_MODEL.GA + elif self.shortName.startswith("GB"): + self.model = WATCH_MODEL.GB + elif self.shortName.startswith("GM"): + self.model = WATCH_MODEL.GM + elif self.shortName.startswith("GW"): + self.model = WATCH_MODEL.GW + elif self.shortName.startswith("MSG"): + self.model = WATCH_MODEL.MSG + elif self.shortName.startswith("GPR"): + self.model = WATCH_MODEL.GPR + elif self.shortName.startswith("DW"): + self.model = WATCH_MODEL.DW + elif self.shortName.startswith("GST"): + self.model = WATCH_MODEL.GST + elif self.shortName.startswith("GMW"): + self.model = WATCH_MODEL.GMW + else: + self.model = WATCH_MODEL.UNKNOWN + + model_info = self.model_map.get(self.model) + if model_info: + self.hasReminders = model_info["hasReminders"] + self.hasAutoLight = model_info["hasAutoLight"] + self.alarmCount = model_info["alarmCount"] + self.worldCitiesCount = model_info["worldCitiesCount"] + self.dstCount = model_info["dstCount"] + self.shortLightDuration = model_info["shortLightDuration"] + self.longLightDuration = model_info["longLightDuration"] + self.weekLanguageSupported = model_info.get("weekLanguageSupported", True) def set_address(self, address): self.address = address + def get_address(self): + return self.address + + def reset(self): + self.address = "" + self.name = "" + self.shortName = "" + self.model = WATCH_MODEL.UNKNOWN + watch_info = WatchInfo() From 6c7ccbff1abe914663d3c0bec701104ca17fd217 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 10 Jan 2024 18:09:14 -0500 Subject: [PATCH 066/123] WIP --- src/gshocktimeserver/api_tests.py | 8 +-- src/gshocktimeserver/connection.py | 2 +- src/gshocktimeserver/gshock_api.py | 57 +++------------- src/gshocktimeserver/iolib/alarms_io.py | 72 +++++++++++++++++++++ src/gshocktimeserver/iolib/timer_io.py | 8 +-- src/gshocktimeserver/iolib/watch_name_io.py | 11 ++-- src/gshocktimeserver/message_dispatcher.py | 33 ++-------- 7 files changed, 98 insertions(+), 93 deletions(-) create mode 100644 src/gshocktimeserver/iolib/alarms_io.py diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 847eba6..1e5c5b7 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -34,13 +34,13 @@ async def run_api_tests(): # pressed_button = await api.get_pressed_button() # logger.debug("pressed button: {}".format(pressed_button)) - watch_name = await api.get_watch_name() - print("got watch name: {}".format(watch_name)) + # watch_name = await api.get_watch_name() + # print("got watch name: {}".format(watch_name)) # await api.set_time() - # alarms = await api.get_alarms() - # logger.debug("alarms: {}".format(alarms)) + alarms = await api.get_alarms() + print("alarms: {}".format(alarms)) # alarms[3]["enabled"] = True # alarms[3]["hour"] = 7 diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index cc34cae..353d751 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -64,4 +64,4 @@ def init_handles_map(self): async def sendMessage(self, message): # await callWriter(self, message) - message_dispatcher.MessageDispatcher.send_to_watch(message) + await message_dispatcher.MessageDispatcher.send_to_watch(message) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 448eedf..8f80e73 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -314,49 +314,10 @@ async def get_alarms(self): """ alarms_inst.clear() await self._get_alarms() - await self._get_alarms2() return alarms_inst.alarms async def _get_alarms(self): - await self.connection.sendMessage("""{ "action": "GET_ALARMS"}""") - key = "GET_ALARMS" - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def alarms_received(keyed_data): - data = keyed_data.get("value") - key = "GET_ALARMS" - - alarms_inst.add_alarms(data) - - res = result_queue.dequeue(key) - res.set_result(data) - - self.subscribe("ALARMS", alarms_received) - return await result - - async def _get_alarms2(self): - await self.connection.sendMessage("""{ "action": "GET_ALARMS2"}""") - key = "GET_ALARMS2" - - # Alarm.alarms.clear() - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def alarms_received2(keyed_data): - data = keyed_data.get("value") - key = "GET_ALARMS2" - - alarms_inst.add_alarms(data) - - res = result_queue.dequeue(key) - res.set_result(data) - - self.subscribe("ALARMS2", alarms_received2) + result = await message_dispatcher.AlarmsIO.request(self.connection) return await result async def set_alarms(self, alarms): @@ -370,14 +331,14 @@ async def set_alarms(self, alarms): ------- None """ - if not alarms: - self.logger.debug("Alarm model not initialised! Cannot set alarm") - return - - alarms_str = json.dumps(alarms) - set_action_cmd = '{{"action":"SET_ALARMS", "value":{} }}'.format(alarms_str) - await self.connection.sendMessage(set_action_cmd) - self.logger.debug("Returning from setAlarms") + # if not alarms: + # self.logger.debug("Alarm model not initialised! Cannot set alarm") + # return + + # alarms_str = json.dumps(alarms) + # set_action_cmd = '{{"action":"SET_ALARMS", "value":{} }}'.format(alarms_str) + # await self.connection.sendMessage(set_action_cmd) + # self.logger.debug("Returning from setAlarms") async def get_timer(self): """Get Timer value in seconds. diff --git a/src/gshocktimeserver/iolib/alarms_io.py b/src/gshocktimeserver/iolib/alarms_io.py new file mode 100644 index 0000000..85f1db5 --- /dev/null +++ b/src/gshocktimeserver/iolib/alarms_io.py @@ -0,0 +1,72 @@ +import asyncio +import json +from typing import Any +from alarms import alarms_inst, alarm_decoder + +from utils import to_compact_string, to_hex_string +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class AlarmsIO: + result: asyncio.Future[Any] = None + # result2: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection): + await connection.request("GET_ALARMS") + AlarmsIO.connection = connection + + alarms_inst.clear() + await AlarmsIO._get_alarms(connection) + # await AlarmsIO._get_alarms2(connection) + return alarms_inst.alarms + + @staticmethod + async def _get_alarms(connection): + await connection.sendMessage("""{ "action": "GET_ALARMS"}""") + # await connection.request("16") + + loop = asyncio.get_running_loop() + AlarmsIO.result = loop.create_future() + return AlarmsIO.result + + # @staticmethod + # async def _get_alarms2(connection): + # await connection.sendMessage("""{ "action": "GET_ALARMS2"}""") + # # await connection.request("GET_ALARMS2") + + # loop = asyncio.get_running_loop() + # AlarmsIO.result2 = loop.create_future() + # return AlarmsIO.result2 + + @staticmethod + async def send_to_watch(): + alarm_command = to_compact_string( + to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]])) + ) + await AlarmsIO.connection.write(0x000C, alarm_command) + + # alarm_command_2 = to_compact_string( + # to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]])) + # ) + # AlarmsIO.connection.write(0x000C, alarm_command_2) + + @staticmethod + async def send_to_watch_set(message): + alarms_json_arr = json.loads(message).get("value") + alarm_casio0 = to_compact_string( + to_hex_string(alarms_inst.from_json_alarm_first_alarm(alarms_json_arr[0])) + ) + await AlarmsIO.connection.write(0x000E, alarm_casio0) + alarm_casio = to_compact_string( + to_hex_string(alarms_inst.from_json_alarm_secondary_alarms(alarms_json_arr)) + ) + await AlarmsIO.connection.write(0x000E, alarm_casio) + + @staticmethod + def on_received(data): + print(f"AlarmsIO onReceived: {data}") + alarms_inst.add_alarms(data) diff --git a/src/gshocktimeserver/iolib/timer_io.py b/src/gshocktimeserver/iolib/timer_io.py index c0a5379..bc33343 100644 --- a/src/gshocktimeserver/iolib/timer_io.py +++ b/src/gshocktimeserver/iolib/timer_io.py @@ -1,7 +1,6 @@ import asyncio from typing import Any -import connection from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -10,10 +9,12 @@ class TimerIO: result: asyncio.Future[Any] = None + connection = None @staticmethod async def request(connection): print(f"TimerIO request") + TimerIO.connection = connection await connection.request("18") loop = asyncio.get_running_loop() @@ -21,8 +22,7 @@ async def request(connection): return TimerIO.result @staticmethod - async def send_to_watch(message): - print(f"TimerIO sendToWatch: {message}") + async def send_to_watch(connection): connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_TIMER"]])) @staticmethod @@ -45,7 +45,7 @@ def encode(seconds_str): seconds_as_byte_arr = encode(data) seconds_as_compact_str = to_compact_string(to_hex_string(seconds_as_byte_arr)) - await connection.write(0x000E, seconds_as_compact_str) + await TimerIO.connection.write(0x000E, seconds_as_compact_str) @staticmethod def on_received(data): diff --git a/src/gshocktimeserver/iolib/watch_name_io.py b/src/gshocktimeserver/iolib/watch_name_io.py index 9fff399..427c73d 100644 --- a/src/gshocktimeserver/iolib/watch_name_io.py +++ b/src/gshocktimeserver/iolib/watch_name_io.py @@ -1,33 +1,30 @@ import asyncio from typing import Any -import connection from casio_constants import CasioConstants from utils import clean_str, to_ascii_string, to_hex_string -from watch_info import WatchInfo class WatchNameIO: result: asyncio.Future[Any] = None + connection = None @staticmethod async def request(connection): - print(f"WatchNameIO request") + WatchNameIO.connection = connection await connection.request("23") loop = asyncio.get_running_loop() WatchNameIO.result = loop.create_future() return WatchNameIO.result - # return WatchInfo.name @staticmethod def on_received(data): - print(f"WatchNameIO onReceived: {data}") hex_str = to_hex_string(data) ascii_str = to_ascii_string(hex_str, 1) clean_data = clean_str(ascii_str) WatchNameIO.result.set_result(clean_data) @staticmethod - async def send_to_watch(message): - print(f"WatchNameIO sendToWatch: {message}") + async def send_to_watch(): + pass diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index da67830..c134b59 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -7,38 +7,13 @@ from iolib.timer_io import TimerIO from iolib.watch_name_io import WatchNameIO +from iolib.alarms_io import AlarmsIO -from utils import to_compact_string, to_hex_string, to_int_array -from alarms import alarms_inst, alarm_decoder +# from utils import to_compact_string, to_hex_string, to_int_array CHARACTERISTICS = CasioConstants.CHARACTERISTICS -class AlarmsIO: - @staticmethod - async def send_to_watch(message): - alarm_command = to_compact_string( - to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]])) - ) - await connection.write(0x000C, alarm_command) - - @staticmethod - async def send_to_watch_set(message): - alarms_json_arr = json.loads(message).get("value") - alarm_casio0 = to_compact_string( - to_hex_string(alarms_inst.from_json_alarm_first_alarm(alarms_json_arr[0])) - ) - await connection.write(0x000E, alarm_casio0) - alarm_casio = to_compact_string( - to_hex_string(alarms_inst.from_json_alarm_secondary_alarms(alarms_json_arr)) - ) - await connection.write(0x000E, alarm_casio) - - @staticmethod - def on_received(message): - print(f"AlarmsIO onReceived: {message}") - - class EventsIO: @staticmethod def send_to_watch_set(message): @@ -173,9 +148,9 @@ class MessageDispatcher: } @staticmethod - def send_to_watch(message): + async def send_to_watch(message): action = json.loads(message).get("action") - MessageDispatcher.watch_senders[action](message) + await MessageDispatcher.watch_senders[action]() @staticmethod def on_received(data): From 9f9a36127ebf02ca0267a5a4d1efb320bab6db10 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Thu, 11 Jan 2024 10:21:35 -0500 Subject: [PATCH 067/123] Filished alarms --- src/gshocktimeserver/api_tests.py | 14 +++++---- src/gshocktimeserver/gshock_api.py | 16 +++++----- src/gshocktimeserver/iolib/alarms_io.py | 35 ++++++++++++---------- src/gshocktimeserver/message_dispatcher.py | 5 ++-- 4 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 1e5c5b7..6028512 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -42,11 +42,15 @@ async def run_api_tests(): alarms = await api.get_alarms() print("alarms: {}".format(alarms)) - # alarms[3]["enabled"] = True - # alarms[3]["hour"] = 7 - # alarms[3]["minute"] = 25 - # alarms[3]["enabled"] = False - # await api.set_alarms(alarms) + alarms[3]["enabled"] = True + alarms[3]["hour"] = 7 + alarms[3]["minute"] = 25 + alarms[3]["enabled"] = False + + await api.set_alarms(alarms) + + alarms = await api.get_alarms() + print("After Setting: alarms: {}".format(alarms)) # seconds = await api.get_timer() # print("timer: {} seconds".format(seconds)) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 8f80e73..a847d6e 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -331,14 +331,14 @@ async def set_alarms(self, alarms): ------- None """ - # if not alarms: - # self.logger.debug("Alarm model not initialised! Cannot set alarm") - # return - - # alarms_str = json.dumps(alarms) - # set_action_cmd = '{{"action":"SET_ALARMS", "value":{} }}'.format(alarms_str) - # await self.connection.sendMessage(set_action_cmd) - # self.logger.debug("Returning from setAlarms") + if not alarms: + self.logger.debug("Alarm model not initialised! Cannot set alarm") + return + + alarms_str = json.dumps(alarms) + set_action_cmd = '{{"action":"SET_ALARMS", "value":{} }}'.format(alarms_str) + await self.connection.sendMessage(set_action_cmd) + self.logger.debug("Returning from setAlarms") async def get_timer(self): """Get Timer value in seconds. diff --git a/src/gshocktimeserver/iolib/alarms_io.py b/src/gshocktimeserver/iolib/alarms_io.py index 85f1db5..45c723b 100644 --- a/src/gshocktimeserver/iolib/alarms_io.py +++ b/src/gshocktimeserver/iolib/alarms_io.py @@ -22,7 +22,7 @@ async def request(connection): alarms_inst.clear() await AlarmsIO._get_alarms(connection) # await AlarmsIO._get_alarms2(connection) - return alarms_inst.alarms + return AlarmsIO.result @staticmethod async def _get_alarms(connection): @@ -33,26 +33,26 @@ async def _get_alarms(connection): AlarmsIO.result = loop.create_future() return AlarmsIO.result - # @staticmethod - # async def _get_alarms2(connection): - # await connection.sendMessage("""{ "action": "GET_ALARMS2"}""") - # # await connection.request("GET_ALARMS2") + @staticmethod + async def _get_alarms2(connection): + await connection.sendMessage("""{ "action": "GET_ALARMS2"}""") + # await connection.request("GET_ALARMS2") - # loop = asyncio.get_running_loop() - # AlarmsIO.result2 = loop.create_future() - # return AlarmsIO.result2 + loop = asyncio.get_running_loop() + AlarmsIO.result2 = loop.create_future() + return AlarmsIO.result2 @staticmethod - async def send_to_watch(): + async def send_to_watch(message=""): alarm_command = to_compact_string( to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]])) ) await AlarmsIO.connection.write(0x000C, alarm_command) - # alarm_command_2 = to_compact_string( - # to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]])) - # ) - # AlarmsIO.connection.write(0x000C, alarm_command_2) + alarm_command_2 = to_compact_string( + to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]])) + ) + await AlarmsIO.connection.write(0x000C, alarm_command_2) @staticmethod async def send_to_watch_set(message): @@ -68,5 +68,10 @@ async def send_to_watch_set(message): @staticmethod def on_received(data): - print(f"AlarmsIO onReceived: {data}") - alarms_inst.add_alarms(data) + decoded = alarm_decoder.to_json(to_hex_string(data))["ALARMS"] + print(f"AlarmsIO onReceived: {decoded}") + alarms_inst.add_alarms(decoded) + print("len: len(alarms_inst.alarms): ", len(alarms_inst.alarms)) + + if len(alarms_inst.alarms) == 5: + AlarmsIO.result.set_result(alarms_inst.alarms) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index c134b59..fdce4a2 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -149,8 +149,9 @@ class MessageDispatcher: @staticmethod async def send_to_watch(message): - action = json.loads(message).get("action") - await MessageDispatcher.watch_senders[action]() + json_message = json.loads(message) + action = json_message.get("action") + await MessageDispatcher.watch_senders[action](message) @staticmethod def on_received(data): From d71d9107e765da30710db7ce8730ca2e6ce3aa99 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 12 Jan 2024 19:25:31 -0500 Subject: [PATCH 068/123] Optimised setting time --- src/gshocktimeserver/alarms.py | 11 +- src/gshocktimeserver/api_tests.py | 54 +++++-- src/gshocktimeserver/gshock_api.py | 141 ++++++------------ src/gshocktimeserver/iolib/alarms_io.py | 14 -- .../iolib/dst_for_world_cities_io.py | 32 ++++ .../iolib/dst_watch_state_io.py | 33 ++++ src/gshocktimeserver/iolib/time_io.py | 56 +++++++ src/gshocktimeserver/iolib/world_cities_io.py | 34 +++++ src/gshocktimeserver/message_dispatcher.py | 38 +---- 9 files changed, 253 insertions(+), 160 deletions(-) create mode 100644 src/gshocktimeserver/iolib/dst_for_world_cities_io.py create mode 100644 src/gshocktimeserver/iolib/dst_watch_state_io.py create mode 100644 src/gshocktimeserver/iolib/time_io.py create mode 100644 src/gshocktimeserver/iolib/world_cities_io.py diff --git a/src/gshocktimeserver/alarms.py b/src/gshocktimeserver/alarms.py index 562aebc..34b9fc8 100644 --- a/src/gshocktimeserver/alarms.py +++ b/src/gshocktimeserver/alarms.py @@ -88,16 +88,13 @@ def to_json(self, command: str): elif int_array[0] == CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]: int_array.pop(0) - # for item in np.array_split(int_array, 4): - # alarms.append(self.create_json_alarm(item)) - # replacement to above 2 lines alarms = [] # split int_array into 4 subarrays - subarr1 = int_array[:len(int_array) // 4] - subarr2 = int_array[len(int_array) // 4:len(int_array) // 2] - subarr3 = int_array[len(int_array) // 2:len(int_array) * 3 // 4] - subarr4 = int_array[len(int_array) * 3 // 4:] + subarr1 = int_array[: len(int_array) // 4] + subarr2 = int_array[len(int_array) // 4 : len(int_array) // 2] + subarr3 = int_array[len(int_array) // 2 : len(int_array) * 3 // 4] + subarr4 = int_array[len(int_array) * 3 // 4 :] # create json alarms for each subarray alarms.append(self.create_json_alarm(subarr1)) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 6028512..303c2ed 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -1,3 +1,4 @@ +import calendar import json import pytz import time @@ -5,7 +6,7 @@ from connection import Connection from gshock_api import GshockAPI -from casio_watch import settings +from casio_watch import DtsState, settings from event import Event, create_event_date, RepeatPeriod from scanner import scanner from logger import logger @@ -37,20 +38,37 @@ async def run_api_tests(): # watch_name = await api.get_watch_name() # print("got watch name: {}".format(watch_name)) - # await api.set_time() + # world_city = await api.get_dst_for_world_cities(0) + # print("world city: {}".format(world_city)) - alarms = await api.get_alarms() - print("alarms: {}".format(alarms)) + # world_city = await api.get_dst_for_world_cities(1) + # print("world city: {}".format(world_city)) - alarms[3]["enabled"] = True - alarms[3]["hour"] = 7 - alarms[3]["minute"] = 25 - alarms[3]["enabled"] = False + # dst_state = await api.get_dst_watch_state(DtsState.ZERO) + # print("dst_state: {}".format(dst_state)) - await api.set_alarms(alarms) + # dst_state = await api.get_dst_watch_state(DtsState.TWO) + # print("dst_state: {}".format(dst_state)) - alarms = await api.get_alarms() - print("After Setting: alarms: {}".format(alarms)) + time_string = "10:10:30" + seconds = convert_time_string_to_epoch(time_string) + + await api.set_time(seconds) + time.sleep(10) + await api.set_time() + + # alarms = await api.get_alarms() + # print("alarms: {}".format(alarms)) + + # alarms[3]["enabled"] = True + # alarms[3]["hour"] = 7 + # alarms[3]["minute"] = 25 + # alarms[3]["enabled"] = False + + # await api.set_alarms(alarms) + + # alarms = await api.get_alarms() + # print("After Setting: alarms: {}".format(alarms)) # seconds = await api.get_timer() # print("timer: {} seconds".format(seconds)) @@ -108,3 +126,17 @@ async def run_api_tests(): await connection.disconnect() logger.debug("--- END OF TESTS ---") + + +def convert_time_string_to_epoch(time_string): + try: + # Create a datetime object with today's date and the provided time + time_object = datetime.strptime(time_string, "%H:%M:%S") + + # Get the timestamp in seconds since the epoch + timestamp = time_object.timestamp() + + return timestamp + except ValueError: + print("Invalid time format. Please use the format HH:MM:SS.") + return None diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index a847d6e..407220a 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -7,6 +7,7 @@ import message_dispatcher from utils import ( to_ascii_string, + to_hex_string, to_int_array, to_compact_string, clean_str, @@ -139,29 +140,11 @@ async def get_world_cities(self, cityNumber: int): ------- name : String, The name of the requested World City as a String. """ - key = "1f0{}".format(cityNumber) - city = await self._get_world_cities(key) + city = await self._get_world_cities(cityNumber) return city async def _get_world_cities(self, key: str): - await self.connection.request(key) - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def casio_world_cities_callback(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") - - res = result_queue.dequeue(key) - res.set_result(value) - - def process_home_time(keyed_data): - pass - - self.subscribe("CASIO_WORLD_CITIES", casio_world_cities_callback) - # self.subscribe("HOME_TIME", process_home_time) + result = await message_dispatcher.WorldCitiesIO.request(self.connection, key) return await result async def get_dst_for_world_cities(self, cityNumber: int) -> str: @@ -176,25 +159,12 @@ async def get_dst_for_world_cities(self, cityNumber: int) -> str: ------- name : String, Daylight Saving Time state of the requested World City as a String. """ - key = "1e0{}".format(cityNumber) - return await self._get_dst_for_world_cities(key) + return await self._get_dst_for_world_cities(cityNumber) async def _get_dst_for_world_cities(self, key: str) -> str: - await self.connection.request(key) - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def casio_dts_world_cities_callback(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") - - res = result_queue.dequeue(key) - res.set_result(value) - - self.subscribe("CASIO_DST_SETTING", casio_dts_world_cities_callback) - + result = await message_dispatcher.DstForWorldCitiesIO.request( + self.connection, key + ) return await result async def get_dst_watch_state(self, state: DtsState) -> str: @@ -208,75 +178,56 @@ async def get_dst_watch_state(self, state: DtsState) -> str: ------- dst: String, the Daylight Saving Time state of the watch as a String. """ - key = f"1d0{state.value}" - return await self._get_dst_watch_state(key) - - async def _get_dst_watch_state(self, key: str) -> str: - await self.connection.request(key) - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def handle_message(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") - - res = result_queue.dequeue(key) - res.set_result(value) - - self.subscribe("CASIO_DST_WATCH_STATE", handle_message) + return await self._get_dst_watch_state(state) + async def _get_dst_watch_state(self, state: DtsState) -> str: + result = await message_dispatcher.DstWatchStateIO.request( + self.connection, state + ) return await result - # async def reset_hand_to_12 (self): - # await self.connection.write(0xE, "1a0412000000") - # await self.connection.write(0xE, "1a0418000000") - async def initialize_for_setting_time(self): # Before we can set time, we must read and write back these values. # Why? Not sure, ask Casio - async def read_and_rite(function, param): + async def read_and_write(function, param): ret = await function(param) short_str = to_compact_string(ret) await self.connection.write(0xE, short_str) - await read_and_rite(self.get_dst_watch_state, DtsState.ZERO) - await read_and_rite(self.get_dst_watch_state, DtsState.TWO) - await read_and_rite(self.get_dst_watch_state, DtsState.FOUR) + await read_and_write(self.get_dst_watch_state, DtsState.ZERO) + await read_and_write(self.get_dst_watch_state, DtsState.TWO) + await read_and_write(self.get_dst_watch_state, DtsState.FOUR) - await read_and_rite(self.get_dst_for_world_cities, 0) - await read_and_rite(self.get_dst_for_world_cities, 1) - await read_and_rite(self.get_dst_for_world_cities, 2) - await read_and_rite(self.get_dst_for_world_cities, 3) - await read_and_rite(self.get_dst_for_world_cities, 4) - await read_and_rite(self.get_dst_for_world_cities, 5) + await read_and_write(self.get_dst_for_world_cities, 0) + await read_and_write(self.get_dst_for_world_cities, 1) + await read_and_write(self.get_dst_for_world_cities, 2) + await read_and_write(self.get_dst_for_world_cities, 3) + await read_and_write(self.get_dst_for_world_cities, 4) + await read_and_write(self.get_dst_for_world_cities, 5) - await read_and_rite(self.get_world_cities, 0) - await read_and_rite(self.get_world_cities, 1) - await read_and_rite(self.get_world_cities, 2) - await read_and_rite(self.get_world_cities, 3) - await read_and_rite(self.get_world_cities, 4) - await read_and_rite(self.get_world_cities, 5) + await read_and_write(self.get_world_cities, 0) + await read_and_write(self.get_world_cities, 1) + await read_and_write(self.get_world_cities, 2) + await read_and_write(self.get_world_cities, 3) + await read_and_write(self.get_world_cities, 4) + await read_and_write(self.get_world_cities, 5) async def initialize_for_setting_time_b2100(self): - # Before we can set time, we must read and write back these values. - # Why? Not sure, ask Casio - - async def read_and_rite(function, param): + async def read_and_write(function, param): ret = await function(param) - short_str = to_compact_string(ret) + short_str = to_compact_string(to_hex_string(ret)) await self.connection.write(0xE, short_str) - await read_and_rite(self.get_dst_watch_state, DtsState.ZERO) - await read_and_rite(self.get_dst_for_world_cities, 0) - await read_and_rite(self.get_dst_for_world_cities, 1) + await read_and_write(self.get_dst_watch_state, DtsState.ZERO) - await read_and_rite(self.get_world_cities, 0) - await read_and_rite(self.get_world_cities, 1) + await read_and_write(self.get_dst_for_world_cities, 0) + await read_and_write(self.get_dst_for_world_cities, 1) - async def set_time(self): + await read_and_write(self.get_world_cities, 0) + await read_and_write(self.get_world_cities, 1) + + async def set_time(self, current_time=time.time()): """Sets the current time on the watch from the time on the phone. In addition, it can optionally set the Home Time to the current time zone. If timezone changes during travel, the watch will automatically be set to the correct time and timezone after running this function. @@ -290,16 +241,15 @@ async def set_time(self): None """ - if watch_info.model == watch_info.model.B2100: - await self.initialize_for_setting_time_b2100() - else: - await self.initialize_for_setting_time() + # if watch_info.model == watch_info.model.B2100: + await self.initialize_for_setting_time_b2100() + # else: + # await self.initialize_for_setting_time() + + await self._set_time(current_time) - message = { - "action": "SET_TIME", - "value": "{}".format(round(time.time() * 1000)), - } - await self.connection.sendMessage(json.dumps(message)) + async def _set_time(self, current_time): + await message_dispatcher.TimeIO.request(self.connection, current_time) async def get_alarms(self): """Gets the current alarms from the watch. Up to 5 alarms are supported on the watch. @@ -338,7 +288,6 @@ async def set_alarms(self, alarms): alarms_str = json.dumps(alarms) set_action_cmd = '{{"action":"SET_ALARMS", "value":{} }}'.format(alarms_str) await self.connection.sendMessage(set_action_cmd) - self.logger.debug("Returning from setAlarms") async def get_timer(self): """Get Timer value in seconds. diff --git a/src/gshocktimeserver/iolib/alarms_io.py b/src/gshocktimeserver/iolib/alarms_io.py index 45c723b..fca108b 100644 --- a/src/gshocktimeserver/iolib/alarms_io.py +++ b/src/gshocktimeserver/iolib/alarms_io.py @@ -11,7 +11,6 @@ class AlarmsIO: result: asyncio.Future[Any] = None - # result2: asyncio.Future[Any] = None connection = None @staticmethod @@ -21,27 +20,16 @@ async def request(connection): alarms_inst.clear() await AlarmsIO._get_alarms(connection) - # await AlarmsIO._get_alarms2(connection) return AlarmsIO.result @staticmethod async def _get_alarms(connection): await connection.sendMessage("""{ "action": "GET_ALARMS"}""") - # await connection.request("16") loop = asyncio.get_running_loop() AlarmsIO.result = loop.create_future() return AlarmsIO.result - @staticmethod - async def _get_alarms2(connection): - await connection.sendMessage("""{ "action": "GET_ALARMS2"}""") - # await connection.request("GET_ALARMS2") - - loop = asyncio.get_running_loop() - AlarmsIO.result2 = loop.create_future() - return AlarmsIO.result2 - @staticmethod async def send_to_watch(message=""): alarm_command = to_compact_string( @@ -69,9 +57,7 @@ async def send_to_watch_set(message): @staticmethod def on_received(data): decoded = alarm_decoder.to_json(to_hex_string(data))["ALARMS"] - print(f"AlarmsIO onReceived: {decoded}") alarms_inst.add_alarms(decoded) - print("len: len(alarms_inst.alarms): ", len(alarms_inst.alarms)) if len(alarms_inst.alarms) == 5: AlarmsIO.result.set_result(alarms_inst.alarms) diff --git a/src/gshocktimeserver/iolib/dst_for_world_cities_io.py b/src/gshocktimeserver/iolib/dst_for_world_cities_io.py new file mode 100644 index 0000000..66b45ef --- /dev/null +++ b/src/gshocktimeserver/iolib/dst_for_world_cities_io.py @@ -0,0 +1,32 @@ +import asyncio +from typing import Any + +from utils import to_compact_string, to_hex_string +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class DstForWorldCitiesIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection, city_number: int): + print(f"DstForWorldCitiesIO request") + DstForWorldCitiesIO.connection = connection + key = "1e0{}".format(city_number) + await connection.request(key) + + loop = asyncio.get_running_loop() + DstForWorldCitiesIO.result = loop.create_future() + return DstForWorldCitiesIO.result + + @staticmethod + async def send_to_watch(connection): + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_DST_SETTING"]])) + + @staticmethod + def on_received(data): + print(f"DstForWorldCitiesIO onReceived") + DstForWorldCitiesIO.result.set_result(data) diff --git a/src/gshocktimeserver/iolib/dst_watch_state_io.py b/src/gshocktimeserver/iolib/dst_watch_state_io.py new file mode 100644 index 0000000..f2937f4 --- /dev/null +++ b/src/gshocktimeserver/iolib/dst_watch_state_io.py @@ -0,0 +1,33 @@ +import asyncio +from typing import Any +from casio_watch import DtsState + +from utils import to_compact_string, to_hex_string +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class DstWatchStateIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection, state: DtsState): + print(f"DstWatchStateIO request") + DstWatchStateIO.connection = connection + key = f"1d0{state.value}" + await connection.request(key) + + loop = asyncio.get_running_loop() + DstWatchStateIO.result = loop.create_future() + return DstWatchStateIO.result + + @staticmethod + async def send_to_watch(connection): + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_DST_WATCH_STATE"]])) + + @staticmethod + def on_received(data): + print(f"DstWatchStateIO onReceived") + DstWatchStateIO.result.set_result(data) diff --git a/src/gshocktimeserver/iolib/time_io.py b/src/gshocktimeserver/iolib/time_io.py new file mode 100644 index 0000000..bfe327a --- /dev/null +++ b/src/gshocktimeserver/iolib/time_io.py @@ -0,0 +1,56 @@ +import asyncio +import datetime +import json +import time +from typing import Any + +from utils import to_compact_string, to_hex_string +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class TimeIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection, current_time): + TimeIO.connection = connection + + if current_time is None: + current_time = time.time() + + message = { + "action": "SET_TIME", + "value": "{}".format(round(current_time * 1000)), + } + await connection.sendMessage(json.dumps(message)) + + @staticmethod + async def send_to_watch_set(message): + date_time_ms = int(json.loads(message).get("value")) + print("date_time_ms: {}".format(date_time_ms)) + date_time = datetime.datetime.fromtimestamp(date_time_ms / 1000.0) + time_data = TimeEncoder.prepare_current_time(date_time) + time_command = to_hex_string( + bytearray([CHARACTERISTICS["CASIO_CURRENT_TIME"]]) + time_data + ) + await TimeIO.connection.write(0xE, to_compact_string(time_command)) + + +class TimeEncoder: + def prepare_current_time(date: datetime.datetime): + arr = bytearray(10) + year = date.year + arr[0] = year >> 0 & 0xFF + arr[1] = year >> 8 & 0xFF + arr[2] = date.month + arr[3] = date.day + arr[4] = date.hour + arr[5] = date.minute + arr[6] = date.second + arr[7] = date.weekday() + arr[8] = 0 + arr[9] = 1 + return arr diff --git a/src/gshocktimeserver/iolib/world_cities_io.py b/src/gshocktimeserver/iolib/world_cities_io.py new file mode 100644 index 0000000..8c53167 --- /dev/null +++ b/src/gshocktimeserver/iolib/world_cities_io.py @@ -0,0 +1,34 @@ +import asyncio +from typing import Any +from casio_watch import DtsState + +from utils import to_compact_string, to_hex_string +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class WorldCitiesIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection, cityNumber: int): + print(f"DstWatchStateIO request") + WorldCitiesIO.connection = connection + key = "1f0{}".format(cityNumber) + + await connection.request(key) + + loop = asyncio.get_running_loop() + WorldCitiesIO.result = loop.create_future() + return WorldCitiesIO.result + + @staticmethod + async def send_to_watch(connection): + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_WORLD_CITIES"]])) + + @staticmethod + def on_received(data): + print(f"WorldCitiesIO onReceived") + WorldCitiesIO.result.set_result(data) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index fdce4a2..62a9b21 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -4,13 +4,15 @@ from typing import Any import connection from casio_constants import CasioConstants +from iolib.dst_watch_state_io import DstWatchStateIO +from iolib.world_cities_io import WorldCitiesIO +from iolib.dst_for_world_cities_io import DstForWorldCitiesIO +from iolib.time_io import TimeIO from iolib.timer_io import TimerIO from iolib.watch_name_io import WatchNameIO from iolib.alarms_io import AlarmsIO -# from utils import to_compact_string, to_hex_string, to_int_array - CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -56,34 +58,6 @@ def on_received(message): print(f"TimeAdjustmentIO onReceived: {message}") -class TimeIO: - @staticmethod - def send_to_watch_set(message): - print(f"TimeIO sendToWatchSet: {message}") - - @staticmethod - def on_received(message): - print(f"TimeIO onReceived") - - -class DstForWorldCitiesIO: - @staticmethod - def on_received(message): - print(f"DstForWorldCitiesIO onReceived: {message}") - - -class WorldCitiesIO: - @staticmethod - def on_received(message): - print(f"WorldCitiesIO onReceived: {message}") - - -class DstWatchStateIO: - @staticmethod - def on_received(message): - print(f"DstWatchStateIO onReceived: {message}") - - class WatchConditionIO: @staticmethod def on_received(message): @@ -131,13 +105,13 @@ class MessageDispatcher: data_received_messages = { CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]: AlarmsIO.on_received, CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]: AlarmsIO.on_received, + CHARACTERISTICS["CASIO_TIMER"]: TimerIO.on_received, + CHARACTERISTICS["CASIO_WATCH_NAME"]: WatchNameIO.on_received, CHARACTERISTICS["CASIO_DST_SETTING"]: DstForWorldCitiesIO.on_received, CHARACTERISTICS["CASIO_REMINDER_TIME"]: EventsIO.on_received, CHARACTERISTICS["CASIO_REMINDER_TITLE"]: EventsIO.on_received_title, - CHARACTERISTICS["CASIO_TIMER"]: TimerIO.on_received, CHARACTERISTICS["CASIO_WORLD_CITIES"]: WorldCitiesIO.on_received, CHARACTERISTICS["CASIO_DST_WATCH_STATE"]: DstWatchStateIO.on_received, - CHARACTERISTICS["CASIO_WATCH_NAME"]: WatchNameIO.on_received, CHARACTERISTICS["CASIO_WATCH_CONDITION"]: WatchConditionIO.on_received, CHARACTERISTICS["CASIO_APP_INFORMATION"]: AppInfoIO.on_received, CHARACTERISTICS["CASIO_BLE_FEATURES"]: ButtonPressedIO.on_received, From 415ecbd3f06576f0c233f52afed14331cd3c08bd Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 12 Jan 2024 23:00:36 -0500 Subject: [PATCH 069/123] Optimised setting time --- config.ini | 4 +- src/gshocktimeserver/api_tests.py | 9 ++-- src/gshocktimeserver/gshock_api.py | 85 ++++++++++++++++-------------- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/config.ini b/config.ini index e4cd7c7..8ef9d8c 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 +device.address = CD:85:03:12:62:17 +device.name = CASIO GW-B5600 diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 303c2ed..c43fb82 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -50,12 +50,11 @@ async def run_api_tests(): # dst_state = await api.get_dst_watch_state(DtsState.TWO) # print("dst_state: {}".format(dst_state)) - time_string = "10:10:30" - seconds = convert_time_string_to_epoch(time_string) - - await api.set_time(seconds) - time.sleep(10) await api.set_time() + # You can also set arbitrasy time like this: + # time_string = "10:10:30" + # seconds = convert_time_string_to_epoch(time_string) + # await api.set_time(seconds) # alarms = await api.get_alarms() # print("alarms: {}".format(alarms)) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 407220a..2822a26 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -187,45 +187,50 @@ async def _get_dst_watch_state(self, state: DtsState) -> str: return await result async def initialize_for_setting_time(self): - # Before we can set time, we must read and write back these values. - # Why? Not sure, ask Casio - - async def read_and_write(function, param): - ret = await function(param) - short_str = to_compact_string(ret) - await self.connection.write(0xE, short_str) - - await read_and_write(self.get_dst_watch_state, DtsState.ZERO) - await read_and_write(self.get_dst_watch_state, DtsState.TWO) - await read_and_write(self.get_dst_watch_state, DtsState.FOUR) - - await read_and_write(self.get_dst_for_world_cities, 0) - await read_and_write(self.get_dst_for_world_cities, 1) - await read_and_write(self.get_dst_for_world_cities, 2) - await read_and_write(self.get_dst_for_world_cities, 3) - await read_and_write(self.get_dst_for_world_cities, 4) - await read_and_write(self.get_dst_for_world_cities, 5) - - await read_and_write(self.get_world_cities, 0) - await read_and_write(self.get_world_cities, 1) - await read_and_write(self.get_world_cities, 2) - await read_and_write(self.get_world_cities, 3) - await read_and_write(self.get_world_cities, 4) - await read_and_write(self.get_world_cities, 5) - - async def initialize_for_setting_time_b2100(self): - async def read_and_write(function, param): - ret = await function(param) - short_str = to_compact_string(to_hex_string(ret)) - await self.connection.write(0xE, short_str) - - await read_and_write(self.get_dst_watch_state, DtsState.ZERO) - - await read_and_write(self.get_dst_for_world_cities, 0) - await read_and_write(self.get_dst_for_world_cities, 1) - - await read_and_write(self.get_world_cities, 0) - await read_and_write(self.get_world_cities, 1) + await self.read_write_dst_watch_states() + await self.read_write_dst_for_world_cities() + await self.read_write_world_cities() + + async def read_and_write(self, function, param): + ret = await function(param) + short_str = to_compact_string(to_hex_string(ret)) + await self.connection.write(0xE, short_str) + + async def read_write_dst_watch_states(self): + array_of_dst_watch_state = [ + {"function": self.get_dst_watch_state, "state": DtsState.ZERO}, + {"function": self.get_dst_watch_state, "state": DtsState.TWO}, + {"function": self.get_dst_watch_state, "state": DtsState.FOUR}, + ] + + for item in array_of_dst_watch_state[: watch_info.dstCount]: + await self.read_and_write(item["function"], item["state"]) + + async def read_write_dst_for_world_cities(self): + array_of_get_dst_for_world_cities = [ + {"function": self.get_dst_for_world_cities, "city_number": 0}, + {"function": self.get_dst_for_world_cities, "city_number": 1}, + {"function": self.get_dst_for_world_cities, "city_number": 2}, + {"function": self.get_dst_for_world_cities, "city_number": 3}, + {"function": self.get_dst_for_world_cities, "city_number": 4}, + {"function": self.get_dst_for_world_cities, "city_number": 5}, + ] + + for item in array_of_get_dst_for_world_cities[: watch_info.worldCitiesCount]: + await self.read_and_write(item["function"], item["city_number"]) + + async def read_write_world_cities(self): + array_of_world_cities = [ + {"function": self.get_world_cities, "city_number": 0}, + {"function": self.get_world_cities, "city_number": 1}, + {"function": self.get_world_cities, "city_number": 2}, + {"function": self.get_world_cities, "city_number": 3}, + {"function": self.get_world_cities, "city_number": 4}, + {"function": self.get_world_cities, "city_number": 5}, + ] + + for item in array_of_world_cities[: watch_info.worldCitiesCount]: + await self.read_and_write(item["function"], item["city_number"]) async def set_time(self, current_time=time.time()): """Sets the current time on the watch from the time on the phone. In addition, it can optionally set the Home Time @@ -242,7 +247,7 @@ async def set_time(self, current_time=time.time()): """ # if watch_info.model == watch_info.model.B2100: - await self.initialize_for_setting_time_b2100() + await self.initialize_for_setting_time() # else: # await self.initialize_for_setting_time() From 49b566494b312709977946ba6c567c04f102dc5e Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 14 Jan 2024 16:46:42 -0500 Subject: [PATCH 070/123] WIP --- config.ini | 4 +- src/gshocktimeserver/api_tests.py | 8 +- src/gshocktimeserver/gshock_api.py | 49 ++--- src/gshocktimeserver/iolib/events_io.py | 218 +++++++++++++++++++++ src/gshocktimeserver/message_dispatcher.py | 15 +- src/gshocktimeserver/watch_info.py | 65 +++--- 6 files changed, 284 insertions(+), 75 deletions(-) create mode 100644 src/gshocktimeserver/iolib/events_io.py diff --git a/config.ini b/config.ini index 8ef9d8c..e4cd7c7 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:03:12:62:17 -device.name = CASIO GW-B5600 +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index c43fb82..14560ab 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -50,7 +50,7 @@ async def run_api_tests(): # dst_state = await api.get_dst_watch_state(DtsState.TWO) # print("dst_state: {}".format(dst_state)) - await api.set_time() + # await api.set_time() # You can also set arbitrasy time like this: # time_string = "10:10:30" # seconds = convert_time_string_to_epoch(time_string) @@ -115,9 +115,9 @@ async def run_api_tests(): # ) # Event().create_event(json.loads(event_json_str)) - # reminders = await api.get_reminders() - # for reminder in reminders: - # logger.debug("reminder: {}".format(reminder.__str__())) + reminders = await api.get_reminders() + for reminder in reminders: + logger.debug("reminder: {}".format(reminder.__str__())) # await api.set_reminders(reminders) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 2822a26..2acd8af 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -452,7 +452,7 @@ async def get_reminders(self): return reminders - async def get_event_from_watch(self, eventNumber: int): + async def get_event_from_watch(self, event_number: int): """Gets a single event (reminder) from the watch. Parameters @@ -463,33 +463,38 @@ async def get_event_from_watch(self, eventNumber: int): ------- event: `Event` """ - await self.connection.request("30{}".format(eventNumber)) # reminder title - await self.connection.request("31{}".format(eventNumber)) # reminder time + result = await message_dispatcher.EventsIO.request( + self.connection, event_number + ) + return await result - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult("310{}".format(eventNumber), result)) + # await self.connection.request("30{}".format(eventNumber)) # reminder title + # await self.connection.request("31{}".format(eventNumber)) # reminder time - def get_reminders(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") + # loop = asyncio.get_running_loop() + # result = loop.create_future() + # result_queue.enqueue(KeyedResult("310{}".format(eventNumber), result)) - for obj_key in value: - if obj_key == "title": - self.title = value[obj_key] + # def get_reminders(keyed_data): + # value = keyed_data.get("value") + # key = keyed_data.get("key") - elif obj_key == "time": - json_obj = json.loads("{}") - json_obj["title"] = self.title - json_obj["time"] = value.get("time") - event_obj = Event() - event = event_obj.create_event(json_obj) + # for obj_key in value: + # if obj_key == "title": + # self.title = value[obj_key] - res = result_queue.dequeue(key) - res.set_result(event) + # elif obj_key == "time": + # json_obj = json.loads("{}") + # json_obj["title"] = self.title + # json_obj["time"] = value.get("time") + # event_obj = Event() + # event = event_obj.create_event(json_obj) - self.subscribe("REMINDERS", get_reminders) - return await result + # res = result_queue.dequeue(key) + # res.set_result(event) + + # self.subscribe("REMINDERS", get_reminders) + # return await result async def set_reminders(self, events: list): """Sets events (reminders) to the watch. Up to 5 events are supported. diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshocktimeserver/iolib/events_io.py new file mode 100644 index 0000000..ad2b30c --- /dev/null +++ b/src/gshocktimeserver/iolib/events_io.py @@ -0,0 +1,218 @@ +import asyncio +import json +from typing import Any + +from utils import ( + clean_str, + dec_to_hex, + to_ascii_string, + to_compact_string, + to_hex_string, + to_int_array, +) +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class ReminderMasks: + YEARLY_MASK = 0b00001000 + MONTHLY_MASK = 0b00010000 + WEEKLY_MASK = 0b00000100 + + SUNDAY_MASK = 0b00000001 + MONDAY_MASK = 0b00000010 + TUESDAY_MASK = 0b00000100 + WEDNESDAY_MASK = 0b00001000 + THURSDAY_MASK = 0b00010000 + FRIDAY_MASK = 0b00100000 + SATURDAY_MASK = 0b01000000 + + ENABLED_MASK = 0b00000001 + + +class EventsIO: + result: asyncio.Future[Any] = None + connection = None + title = None + + @staticmethod + async def request(connection, event_number): + print(f"EventsIO request") + EventsIO.connection = connection + + await connection.request("30{}".format(event_number)) # reminder title + await connection.request("31{}".format(event_number)) # reminder time + + loop = asyncio.get_running_loop() + EventsIO.result = loop.create_future() + return EventsIO.result + + @staticmethod + def send_to_watch_set(message): + print(f"EventsIO sendToWatchSet: {message}") + + @staticmethod + def on_received(message): + print(f"EventsIO onReceived: {message}") + + def reminder_time_to_json(reminder_str): + def convert_array_list_to_json_array(array_list): + json_array = [] + for item in array_list: + json_array.append(item) + + return json_array + + def decode_time_period(time_period: int) -> tuple: + enabled = False + repeat_period = "" + + if ( + time_period & ReminderMasks.ENABLED_MASK + == ReminderMasks.ENABLED_MASK + ): + enabled = True + + if time_period & ReminderMasks.WEEKLY_MASK == ReminderMasks.WEEKLY_MASK: + repeat_period = "WEEKLY" + elif ( + time_period & ReminderMasks.MONTHLY_MASK + == ReminderMasks.MONTHLY_MASK + ): + repeat_period = "MONTHLY" + elif ( + time_period & ReminderMasks.YEARLY_MASK == ReminderMasks.YEARLY_MASK + ): + repeat_period = "YEARLY" + else: + repeat_period = "NEVER" + + return (enabled, repeat_period) + + def decode_time_detail(time_detail): + def decode_date(time_detail): + def int_to_month_str(month_int): + months = [ + "JANUARY", + "FEBRUARY", + "MARCH", + "APRIL", + "MAY", + "JUNE", + "JULY", + "AUGUST", + "SEPTEMBER", + "OCTOBER", + "NOVEMBER", + "DECEMBER", + ] + if month_int < 1 or month_int > 12: + return "" + else: + return months[month_int - 1] + + date = json.loads("{}") + + date["year"] = dec_to_hex(time_detail[0]) + 2000 + date["month"] = int_to_month_str(dec_to_hex(time_detail[1])) + date["day"] = dec_to_hex(time_detail[2]) + + return date + + result = {} + + # 00 23 02 21 23 02 21 00 00 + # start from here: ^ + # so, skip 1 + start_date = decode_date(time_detail[1:]) + + result["start_date"] = start_date + + # 00 23 02 21 23 02 21 00 00 + # start from here: ^ + # so, skip 4 + end_date = decode_date(time_detail[4:]) + + result["end_date"] = end_date + + day_of_week = time_detail[7] + days_of_week = [] + if day_of_week & ReminderMasks.SUNDAY_MASK == ReminderMasks.SUNDAY_MASK: + days_of_week.append("SUNDAY") + if day_of_week & ReminderMasks.MONDAY_MASK == ReminderMasks.MONDAY_MASK: + days_of_week.append("MONDAY") + if ( + day_of_week & ReminderMasks.TUESDAY_MASK + == ReminderMasks.TUESDAY_MASK + ): + days_of_week.append("TUESDAY") + if ( + day_of_week & ReminderMasks.WEDNESDAY_MASK + == ReminderMasks.WEDNESDAY_MASK + ): + days_of_week.append("WEDNESDAY") + if ( + day_of_week & ReminderMasks.THURSDAY_MASK + == ReminderMasks.THURSDAY_MASK + ): + days_of_week.append("THURSDAY") + if day_of_week & ReminderMasks.FRIDAY_MASK == ReminderMasks.FRIDAY_MASK: + days_of_week.append("FRIDAY") + if ( + day_of_week & ReminderMasks.SATURDAY_MASK + == ReminderMasks.SATURDAY_MASK + ): + days_of_week.append("SATURDAY") + result["days_of_week"] = days_of_week + return result + + reminder_str_hex = to_hex_string(reminder_str) + int_arr = to_int_array(reminder_str_hex) + if int_arr[3] == 0xFF: + # 0XFF indicates end of reminders + return json.dumps({"end": ""}) + + reminder_all = to_int_array(reminder_str_hex) + # Remove the first 2 chars: + # 0x31 05 <--- 00 23 02 21 23 02 21 00 00 + reminder = reminder_all[2:] + reminder_json = {} + time_period = decode_time_period(reminder[0]) + reminder_json["enabled"] = time_period[0] + reminder_json["repeat_period"] = time_period[1] + + time_detail_map = decode_time_detail(reminder) + + reminder_json["start_date"] = time_detail_map["start_date"] + reminder_json["end_date"] = time_detail_map["end_date"] + reminder_json["days_of_week"] = convert_array_list_to_json_array( + time_detail_map["days_of_week"] + ) + + return json.dumps({"time": reminder_json}) + + reminder_json = {} + value = reminder_time_to_json(message[2:]) + return reminder_json + + @staticmethod + def on_received_title(message): + print(f"EventsIO onReceivedTitle: {message}") + EventsIO.title = ReminderDecoder.reminder_title_to_json(message) + print(f"EventsIO title: {EventsIO.title}") + + +class ReminderDecoder: + def reminder_title_to_json(title_byte: str) -> dict: + hex_str = to_hex_string(title_byte) + # ascii_str = to_ascii_string(hex_str, 2) + + int_arr = to_int_array(hex_str) + if int_arr[2] == 0xFF: + # 0XFF indicates end of reminders + return {"end": ""} + reminder_json = {} + + reminder_json["title"] = clean_str(to_ascii_string(hex_str, 2)) + return reminder_json diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index 62a9b21..43b378a 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -12,24 +12,11 @@ from iolib.timer_io import TimerIO from iolib.watch_name_io import WatchNameIO from iolib.alarms_io import AlarmsIO +from iolib.events_io import EventsIO CHARACTERISTICS = CasioConstants.CHARACTERISTICS -class EventsIO: - @staticmethod - def send_to_watch_set(message): - print(f"EventsIO sendToWatchSet: {message}") - - @staticmethod - def on_received(message): - print(f"EventsIO onReceived: {message}") - - @staticmethod - def on_received_title(message): - print(f"EventsIO onReceivedTitle: {message}") - - class SettingsIO: @staticmethod def send_to_watch(message): diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index 9af22a0..386247d 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -1,27 +1,6 @@ from enum import Enum -# class WatchInfo: - -# class model(Enum): -# B5600 = 1 -# B2100 = 2 -# UNKNOWN = 3 - -# def __init__(self) -> None: -# self.name = "" -# self.address = "" - -# def set_name(self, name): -# self.name = name -# self.model = self.model.B5600 if "5600" in name else self.model.B2100 - -# def set_address(self, address): -# self.address = address - -from enum import Enum - - class WATCH_MODEL(Enum): GA = 1 GW = 2 @@ -31,7 +10,8 @@ class WATCH_MODEL(Enum): GST = 6 MSG = 7 GB001 = 8 - UNKNOWN = 9 + GBD = 9 + UNKNOWN = 10 class WatchInfo: @@ -48,6 +28,8 @@ def __init__(self): self.shortLightDuration = "" self.longLightDuration = "" self.weekLanguageSupported = True + self.worldCities: True + self.temperature: True self.models = [ { @@ -161,6 +143,18 @@ def __init__(self): "shortLightDuration": "1.5s", "longLightDuration": "3s", }, + { + "model": WATCH_MODEL.GBD, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + "worldCities": False, + "temperature": False, + }, { "model": WATCH_MODEL.UNKNOWN, "worldCitiesCount": 2, @@ -182,24 +176,27 @@ def set_name_and_model(self, name): if len(parts) > 1: self.shortName = parts[1] - if self.shortName.startswith("GA"): - self.model = WATCH_MODEL.GA - elif self.shortName.startswith("GB"): - self.model = WATCH_MODEL.GB - elif self.shortName.startswith("GM"): - self.model = WATCH_MODEL.GM - elif self.shortName.startswith("GW"): - self.model = WATCH_MODEL.GW - elif self.shortName.startswith("MSG"): + # *** Order matters. Start with the longest shortName first. *** + if self.shortName.startswith("MSG"): self.model = WATCH_MODEL.MSG elif self.shortName.startswith("GPR"): self.model = WATCH_MODEL.GPR - elif self.shortName.startswith("DW"): - self.model = WATCH_MODEL.DW elif self.shortName.startswith("GST"): self.model = WATCH_MODEL.GST + elif self.shortName.startswith("GBD"): + self.model = WATCH_MODEL.GBD elif self.shortName.startswith("GMW"): self.model = WATCH_MODEL.GMW + elif self.shortName.startswith("DW"): + self.model = WATCH_MODEL.DW + elif self.shortName.startswith("GA"): + self.model = WATCH_MODEL.GA + elif self.shortName.startswith("GB"): + self.model = WATCH_MODEL.GB + elif self.shortName.startswith("GM"): + self.model = WATCH_MODEL.GM + elif self.shortName.startswith("GW"): + self.model = WATCH_MODEL.GW else: self.model = WATCH_MODEL.UNKNOWN @@ -213,6 +210,8 @@ def set_name_and_model(self, name): self.shortLightDuration = model_info["shortLightDuration"] self.longLightDuration = model_info["longLightDuration"] self.weekLanguageSupported = model_info.get("weekLanguageSupported", True) + self.worldCities = model_info.get("worldCities", True) + self.temperature = model_info.get("temperature", True) def set_address(self, address): self.address = address From 2e7f499704b7344d3452e3fb530d05bf3b7378d7 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 14 Jan 2024 20:07:00 -0500 Subject: [PATCH 071/123] Remonders WIP --- src/gshocktimeserver/api_tests.py | 30 +++---------------------- src/gshocktimeserver/iolib/events_io.py | 11 ++++----- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 14560ab..8ed089e 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -36,45 +36,21 @@ async def run_api_tests(): # logger.debug("pressed button: {}".format(pressed_button)) # watch_name = await api.get_watch_name() - # print("got watch name: {}".format(watch_name)) - - # world_city = await api.get_dst_for_world_cities(0) - # print("world city: {}".format(world_city)) - - # world_city = await api.get_dst_for_world_cities(1) - # print("world city: {}".format(world_city)) - - # dst_state = await api.get_dst_watch_state(DtsState.ZERO) - # print("dst_state: {}".format(dst_state)) - - # dst_state = await api.get_dst_watch_state(DtsState.TWO) - # print("dst_state: {}".format(dst_state)) + # logger.info("got watch name: {}".format(watch_name)) # await api.set_time() - # You can also set arbitrasy time like this: - # time_string = "10:10:30" - # seconds = convert_time_string_to_epoch(time_string) - # await api.set_time(seconds) # alarms = await api.get_alarms() - # print("alarms: {}".format(alarms)) + # logger.debug("alarms: {}".format(alarms)) # alarms[3]["enabled"] = True # alarms[3]["hour"] = 7 # alarms[3]["minute"] = 25 # alarms[3]["enabled"] = False - # await api.set_alarms(alarms) - # alarms = await api.get_alarms() - # print("After Setting: alarms: {}".format(alarms)) - - # seconds = await api.get_timer() - # print("timer: {} seconds".format(seconds)) - - # await api.set_timer(235) # seconds = await api.get_timer() - # print("timer: {} after setting seconds".format(seconds)) + # logger.debug("timer: {} seconds".format(seconds)) # # await api.set_timer(seconds + 10) # time_adjstment = await api.get_time_adjustment() diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshocktimeserver/iolib/events_io.py index ad2b30c..7028ed9 100644 --- a/src/gshocktimeserver/iolib/events_io.py +++ b/src/gshocktimeserver/iolib/events_io.py @@ -55,6 +55,7 @@ def send_to_watch_set(message): @staticmethod def on_received(message): print(f"EventsIO onReceived: {message}") + data = to_hex_string(message) def reminder_time_to_json(reminder_str): def convert_array_list_to_json_array(array_list): @@ -167,13 +168,12 @@ def int_to_month_str(month_int): result["days_of_week"] = days_of_week return result - reminder_str_hex = to_hex_string(reminder_str) - int_arr = to_int_array(reminder_str_hex) + int_arr = to_int_array(reminder_str) if int_arr[3] == 0xFF: # 0XFF indicates end of reminders return json.dumps({"end": ""}) - reminder_all = to_int_array(reminder_str_hex) + reminder_all = to_int_array(reminder_str) # Remove the first 2 chars: # 0x31 05 <--- 00 23 02 21 23 02 21 00 00 reminder = reminder_all[2:] @@ -193,8 +193,9 @@ def int_to_month_str(month_int): return json.dumps({"time": reminder_json}) reminder_json = {} - value = reminder_time_to_json(message[2:]) - return reminder_json + value = reminder_time_to_json(data[2:]) + EventsIO.result.set_result(value) + # return reminder_json @staticmethod def on_received_title(message): From 3cb520e9de9069387ef6e731bddb55eb508007df Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 15 Jan 2024 17:11:41 -0500 Subject: [PATCH 072/123] WIP --- src/gshocktimeserver/api_tests.py | 8 +- src/gshocktimeserver/gshock_api.py | 40 +----- src/gshocktimeserver/iolib/events_io.py | 161 ++++++++++++++++++++++-- 3 files changed, 166 insertions(+), 43 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 8ed089e..d86960f 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -95,7 +95,13 @@ async def run_api_tests(): for reminder in reminders: logger.debug("reminder: {}".format(reminder.__str__())) - # await api.set_reminders(reminders) + reminders[3]["title"] = "Test Event" + + await api.set_reminders(reminders) + + reminders = await api.get_reminders() + for reminder in reminders: + print("After setting, reminder: {}".format(reminder.__str__())) input("Hit any key to disconnect") diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 2acd8af..06b775b 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -468,34 +468,6 @@ async def get_event_from_watch(self, event_number: int): ) return await result - # await self.connection.request("30{}".format(eventNumber)) # reminder title - # await self.connection.request("31{}".format(eventNumber)) # reminder time - - # loop = asyncio.get_running_loop() - # result = loop.create_future() - # result_queue.enqueue(KeyedResult("310{}".format(eventNumber), result)) - - # def get_reminders(keyed_data): - # value = keyed_data.get("value") - # key = keyed_data.get("key") - - # for obj_key in value: - # if obj_key == "title": - # self.title = value[obj_key] - - # elif obj_key == "time": - # json_obj = json.loads("{}") - # json_obj["title"] = self.title - # json_obj["time"] = value.get("time") - # event_obj = Event() - # event = event_obj.create_event(json_obj) - - # res = result_queue.dequeue(key) - # res.set_result(event) - - # self.subscribe("REMINDERS", get_reminders) - # return await result - async def set_reminders(self, events: list): """Sets events (reminders) to the watch. Up to 5 events are supported. @@ -513,20 +485,20 @@ async def set_reminders(self, events: list): def to_json(events: list): events_json = json.loads("[]") for event in events: - event_json = json.loads(json.dumps(event.__dict__)) + event_json = event # json.loads(json.dumps(event.__dict__)) events_json.append(event_json) return events_json - def get_selected_events(events: list): - selected_events = [event for event in events if event.selected] - return to_json(selected_events) + def get_enabled_events(events: list): + enabled_events = [event for event in events if event["time"]["enabled"]] + return enabled_events # to_json(enabled_events) - selected = get_selected_events(events) + enabled = get_enabled_events(events) await self.connection.sendMessage( """{{\"action\": \"SET_REMINDERS\", \"value\": {}}}""".format( - json.dumps(selected) + json.dumps(enabled) ) ) diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshocktimeserver/iolib/events_io.py index 7028ed9..01a1f55 100644 --- a/src/gshocktimeserver/iolib/events_io.py +++ b/src/gshocktimeserver/iolib/events_io.py @@ -1,11 +1,13 @@ import asyncio import json from typing import Any +from logger import logger from utils import ( clean_str, dec_to_hex, to_ascii_string, + to_byte_array, to_compact_string, to_hex_string, to_int_array, @@ -49,12 +51,157 @@ async def request(connection, event_number): return EventsIO.result @staticmethod - def send_to_watch_set(message): + async def send_to_watch_set(message): print(f"EventsIO sendToWatchSet: {message}") + def reminder_title_from_json(reminder_json): + title_str = reminder_json.get("title") + return to_byte_array(title_str, 18) + + def reminder_time_from_json(reminder_json): + def create_time_detail(repeat_period, start_date, end_date, days_of_week): + def encode_date(time_detail, start_date, end_date): + class Month: + JANUARY = 1 + FEBRUARY = 2 + MARCH = 3 + APRIL = 4 + MAY = 5 + JUNE = 6 + JULY = 7 + AUGUST = 8 + SEPTEMBER = 9 + OCTOBER = 10 + NOVEMBER = 11 + DECEMBER = 12 + + def __init__(self): + pass + + def string_to_month(month_str): + months = { + "january": Month.JANUARY, + "february": Month.FEBRUARY, + "march": Month.MARCH, + "april": Month.APRIL, + "may": Month.MAY, + "june": Month.JUNE, + "july": Month.JULY, + "august": Month.AUGUST, + "september": Month.SEPTEMBER, + "october": Month.OCTOBER, + "november": Month.NOVEMBER, + "december": Month.DECEMBER, + } + return months.get(month_str.lower(), Month.JANUARY) + + def hex_to_dec(hex): + return int(str(hex), 16) + + # take the last 2 digits only + time_detail[0] = hex_to_dec(start_date["year"] % 2000) + time_detail[1] = hex_to_dec(string_to_month(start_date["month"])) + time_detail[2] = hex_to_dec(start_date["day"]) + time_detail[3] = hex_to_dec( + end_date["year"] % 2000 + ) # get the last 2 gits only + time_detail[4] = hex_to_dec(string_to_month(end_date["month"])) + time_detail[5] = hex_to_dec(end_date["day"]) + time_detail[6], time_detail[7] = 0, 0 + + time_detail = [0] * 8 + + if repeat_period == "NEVER": + encode_date(time_detail, start_date, end_date) + + elif repeat_period == "WEEKLY": + encode_date(time_detail, start_date, end_date) + + day_of_week = 0 + if days_of_week is not None: + for i in range(len(days_of_week)): + if days_of_week[i] == "SUNDAY": + day_of_week = day_of_week | ReminderMasks.SUNDAY_MASK + elif days_of_week[i] == "MONDAY": + day_of_week = day_of_week | ReminderMasks.MONDAY_MASK + elif days_of_week[i] == "TUESDAY": + day_of_week = day_of_week | ReminderMasks.TUESDAY_MASK + elif days_of_week[i] == "WEDNESDAY": + day_of_week = day_of_week | ReminderMasks.WEDNESDAY_MASK + elif days_of_week[i] == "THURSDAY": + day_of_week = day_of_week | ReminderMasks.THURSDAY_MASK + elif days_of_week[i] == "FRIDAY": + day_of_week = day_of_week | ReminderMasks.FRIDAY_MASK + elif days_of_week[i] == "SATURDAY": + day_of_week = day_of_week | ReminderMasks.SATURDAY_MASK + + time_detail[6] = day_of_week + time_detail[7] = 0 + + elif repeat_period == "MONTHLY": + encode_date(time_detail, start_date, end_date) + + elif repeat_period == "YEARLY": + encode_date(time_detail, start_date, end_date) + else: + logger.debug( + "Cannot handle Repeat Period: {}".format(repeat_period) + ) + + return time_detail + + def create_time_period(enabled: bool, repeat_period: str) -> int: + time_period = 0 + + if enabled: + time_period = time_period | ReminderMasks.ENABLED_MASK + if repeat_period == "WEEKLY": + time_period = time_period | ReminderMasks.WEEKLY_MASK + elif repeat_period == "MONTHLY": + time_period = time_period | ReminderMasks.MONTHLY_MASK + elif repeat_period == "YEARLY": + time_period = time_period | ReminderMasks.YEARLY_MASK + return time_period + + enabled = reminder_json.get("enabled") + repeat_period = reminder_json.get("repeat_period") + start_date = reminder_json.get("start_date") + end_date = reminder_json.get("end_date") + days_of_week = reminder_json.get("days_of_week") + + reminder_cmd = bytearray() + + reminder_cmd += bytearray([create_time_period(enabled, repeat_period)]) + reminder_cmd += bytearray( + create_time_detail(repeat_period, start_date, end_date, days_of_week) + ) + + return reminder_cmd + + reminders_json_arr = json.loads(message).get("value") + for index, element in enumerate(reminders_json_arr): + reminder_json = element + title = reminder_title_from_json(reminder_json) + + title_byte_arr = bytearray([CHARACTERISTICS["CASIO_REMINDER_TITLE"]]) + title_byte_arr += bytearray([index + 1]) + title_byte_arr += title + title_byte_arr_to_send = to_compact_string(to_hex_string(title_byte_arr)) + await EventsIO.connection.write(0x000E, title_byte_arr_to_send) + + reminder_time_byte_arr = bytearray([]) + reminder_time_byte_arr += bytearray( + [CHARACTERISTICS["CASIO_REMINDER_TIME"]] + ) + reminder_time_byte_arr += bytearray([index + 1]) + reminder_time_byte_arr += reminder_time_from_json(reminder_json) + reminder_time_byte_arr_to_send = to_compact_string( + to_hex_string(bytearray(reminder_time_byte_arr)) + ) + await EventsIO.connection.write(0x000E, reminder_time_byte_arr_to_send) + @staticmethod def on_received(message): - print(f"EventsIO onReceived: {message}") data = to_hex_string(message) def reminder_time_to_json(reminder_str): @@ -192,16 +339,14 @@ def int_to_month_str(month_int): return json.dumps({"time": reminder_json}) - reminder_json = {} - value = reminder_time_to_json(data[2:]) - EventsIO.result.set_result(value) - # return reminder_json + reminder_json = json.loads(reminder_time_to_json(data[2:])) + reminder_json.update(EventsIO.title) + print(reminder_json) + EventsIO.result.set_result(reminder_json) @staticmethod def on_received_title(message): - print(f"EventsIO onReceivedTitle: {message}") EventsIO.title = ReminderDecoder.reminder_title_to_json(message) - print(f"EventsIO title: {EventsIO.title}") class ReminderDecoder: From c7b9b1925b6a248b7db32f8fa56935eb0a317ee2 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 15 Jan 2024 17:32:22 -0500 Subject: [PATCH 073/123] Completed reminders --- src/gshocktimeserver/api_tests.py | 4 ---- src/gshocktimeserver/iolib/events_io.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index d86960f..1e3dd00 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -99,10 +99,6 @@ async def run_api_tests(): await api.set_reminders(reminders) - reminders = await api.get_reminders() - for reminder in reminders: - print("After setting, reminder: {}".format(reminder.__str__())) - input("Hit any key to disconnect") await connection.disconnect() diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshocktimeserver/iolib/events_io.py index 01a1f55..1a4910a 100644 --- a/src/gshocktimeserver/iolib/events_io.py +++ b/src/gshocktimeserver/iolib/events_io.py @@ -194,7 +194,7 @@ def create_time_period(enabled: bool, repeat_period: str) -> int: [CHARACTERISTICS["CASIO_REMINDER_TIME"]] ) reminder_time_byte_arr += bytearray([index + 1]) - reminder_time_byte_arr += reminder_time_from_json(reminder_json) + reminder_time_byte_arr += reminder_time_from_json(reminder_json.get("time")) reminder_time_byte_arr_to_send = to_compact_string( to_hex_string(bytearray(reminder_time_byte_arr)) ) From 3ba9c9e6cc2461ac5768456d2c0f2fbf5fd98563 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 17 Jan 2024 18:44:49 -0500 Subject: [PATCH 074/123] Added anction to skip to the next track --- src/gshocktimeserver/api_tests.py | 25 +++-- src/gshocktimeserver/gshock_api.py | 16 +-- src/gshocktimeserver/iolib/settings_io.py | 123 +++++++++++++++++++++ src/gshocktimeserver/message_dispatcher.py | 15 +-- 4 files changed, 139 insertions(+), 40 deletions(-) create mode 100644 src/gshocktimeserver/iolib/settings_io.py diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 1e3dd00..1995449 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -59,14 +59,17 @@ async def run_api_tests(): # settings.timeAdjustment = True # await api.set_time_adjustment(settings) - # settings_local = await api.get_basic_settings() - # logger.debug("settings: {}".format(settings_local)) + settings_local = await api.get_basic_settings() + print("settings: {}".format(settings_local)) - # settings_local["button_tone"] = True - # settings_local["language"] = "Engish" - # settings_local["time_format"] = "12h" + settings_local["button_tone"] = True + settings_local["language"] = "Engish" + settings_local["time_format"] = "12h" - # await api.set_settings(settings_local) + await api.set_settings(settings_local) + + settings_local = await api.get_basic_settings() + print("After update: settings: {}".format(settings_local)) # Create a single event # tz = pytz.timezone("America/Toronto") @@ -91,13 +94,13 @@ async def run_api_tests(): # ) # Event().create_event(json.loads(event_json_str)) - reminders = await api.get_reminders() - for reminder in reminders: - logger.debug("reminder: {}".format(reminder.__str__())) + # reminders = await api.get_reminders() + # for reminder in reminders: + # logger.debug("reminder: {}".format(reminder.__str__())) - reminders[3]["title"] = "Test Event" + # reminders[3]["title"] = "Test Event" - await api.set_reminders(reminders) + # await api.set_reminders(reminders) input("Hit any key to disconnect") diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 06b775b..e5a1142 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -389,22 +389,8 @@ async def get_basic_settings(self): ------- settings: a list of `Settings` """ - key = "13" - await self.connection.request(key) - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def _get_settings(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") - - settings = json.loads(value) - res = result_queue.dequeue(key) - res.set_result(settings) - self.subscribe("SETTINGS", _get_settings) + result = await message_dispatcher.SettingsIO.request(self.connection) return await result async def set_settings(self, settings): diff --git a/src/gshocktimeserver/iolib/settings_io.py b/src/gshocktimeserver/iolib/settings_io.py new file mode 100644 index 0000000..41c1c5f --- /dev/null +++ b/src/gshocktimeserver/iolib/settings_io.py @@ -0,0 +1,123 @@ +import asyncio +import json +from typing import Any +from settings import settings + +from utils import to_compact_string, to_hex_string, to_int_array +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class SettingsIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection): + print(f"TimerIO request") + SettingsIO.connection = connection + await connection.request("13") + + loop = asyncio.get_running_loop() + SettingsIO.result = loop.create_future() + return SettingsIO.result + + @staticmethod + def send_to_watch(message): + print(f"SettingsIO sendToWatch: {message}") + SettingsIO.connection.write( + 0x000C, bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"]]) + ) + + @staticmethod + async def send_to_watch_set(message): + print(f"SettingsIO sendToWatchSet: {message}") + + def encode(settings: dict): + mask_24_hours = 0b00000001 + MASK_BUTTON_TONE_OFF = 0b00000010 + MASK_LIGHT_OFF = 0b00000100 + POWER_SAVING_MODE = 0b00010000 + + arr = bytearray(12) + arr[0] = CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"] + if settings.time_format == "24h": + arr[1] = arr[1] | mask_24_hours + if not settings.button_tone: + arr[1] = arr[1] | MASK_BUTTON_TONE_OFF + if not settings.auto_light: + arr[1] = arr[1] | MASK_LIGHT_OFF + if not settings.power_saving_mode: + arr[1] = arr[1] | POWER_SAVING_MODE + + if settings.light_duration == "4s": + arr[2] = 1 + if settings.date_format == "DD:MM": + arr[4] = 1 + + language_index = { + "English": 0, + "Spanish": 1, + "French": 2, + "German": 3, + "Italian": 4, + "Russian": 5, + } + arr[5] = language_index.get(settings.language, 0) + + return arr + + encoded_settings = encode(settings) + await SettingsIO.connection.write( + 0x000E, to_compact_string(to_hex_string(encoded_settings)) + ) + + @staticmethod + def on_received(message): + print(f"SettingsIO onReceived: {message}") + + def create_json_settings(setting_string): + mask_24_hours = 0b00000001 + MASK_BUTTON_TONE_OFF = 0b00000010 + MASK_LIGHT_OFF = 0b00000100 + POWER_SAVING_MODE = 0b00010000 + + setting_array = to_int_array(setting_string) + + if setting_array[1] & mask_24_hours != 0: + settings.time_format = "24h" + else: + settings.time_format = "12h" + settings.button_tone = setting_array[1] & MASK_BUTTON_TONE_OFF == 0 + settings.auto_light = setting_array[1] & MASK_LIGHT_OFF == 0 + settings.power_saving_mode = setting_array[1] & POWER_SAVING_MODE == 0 + + if setting_array[4] == 1: + settings.date_format = "DD:MM" + else: + settings.date_format = "MM:DD" + + if setting_array[5] == 0: + settings.language = "English" + if setting_array[5] == 1: + settings.language = "Spanish" + if setting_array[5] == 2: + settings.language = "French" + if setting_array[5] == 3: + settings.language = "German" + if setting_array[5] == 4: + settings.language = "Italian" + if setting_array[5] == 5: + settings.language = "Russian" + + if setting_array[2] == 1: + settings.light_duration = "4s" + else: + settings.light_duration = "2s" + + return json.dumps(settings.__dict__) + + data = to_hex_string(message) + json_data = create_json_settings(data) + SettingsIO.result.set_result(json_data) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index 43b378a..32691bb 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -13,24 +13,11 @@ from iolib.watch_name_io import WatchNameIO from iolib.alarms_io import AlarmsIO from iolib.events_io import EventsIO +from iolib.settings_io import SettingsIO CHARACTERISTICS = CasioConstants.CHARACTERISTICS -class SettingsIO: - @staticmethod - def send_to_watch(message): - print(f"SettingsIO sendToWatch: {message}") - - @staticmethod - def send_to_watch_set(message): - print(f"SettingsIO sendToWatchSet: {message}") - - @staticmethod - def on_received(message): - print(f"SettingsIO onReceived: {message}") - - class TimeAdjustmentIO: @staticmethod def send_to_watch(message): From 282f97ae07ea7a9dce63c4c220f906366f06ff62 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 17 Jan 2024 20:05:25 -0500 Subject: [PATCH 075/123] Completed settings --- src/gshocktimeserver/api_tests.py | 4 ++-- src/gshocktimeserver/iolib/settings_io.py | 25 ++++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 1995449..b16e9ba 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -63,8 +63,8 @@ async def run_api_tests(): print("settings: {}".format(settings_local)) settings_local["button_tone"] = True - settings_local["language"] = "Engish" - settings_local["time_format"] = "12h" + settings_local["language"] = "Russian" + settings_local["time_format"] = "24h" await api.set_settings(settings_local) diff --git a/src/gshocktimeserver/iolib/settings_io.py b/src/gshocktimeserver/iolib/settings_io.py index 41c1c5f..be46474 100644 --- a/src/gshocktimeserver/iolib/settings_io.py +++ b/src/gshocktimeserver/iolib/settings_io.py @@ -2,7 +2,6 @@ import json from typing import Any from settings import settings - from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants @@ -34,7 +33,7 @@ def send_to_watch(message): async def send_to_watch_set(message): print(f"SettingsIO sendToWatchSet: {message}") - def encode(settings: dict): + def encode(settings): mask_24_hours = 0b00000001 MASK_BUTTON_TONE_OFF = 0b00000010 MASK_LIGHT_OFF = 0b00000100 @@ -68,10 +67,22 @@ def encode(settings: dict): return arr - encoded_settings = encode(settings) - await SettingsIO.connection.write( - 0x000E, to_compact_string(to_hex_string(encoded_settings)) - ) + class DotDict(dict): + def __getattr__(self, attr): + if attr in self: + return self[attr] + else: + raise AttributeError(f"'DotDict' object has no attribute '{attr}'") + + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ + + json_setting = json.loads(message).get("value") + # dict_setting = json.load(json_setting) + encoded_stiing = encode(DotDict(json_setting)) + setting_to_set = to_compact_string(to_hex_string(encoded_stiing)) + + await SettingsIO.connection.write(0x000E, setting_to_set) @staticmethod def on_received(message): @@ -119,5 +130,5 @@ def create_json_settings(setting_string): return json.dumps(settings.__dict__) data = to_hex_string(message) - json_data = create_json_settings(data) + json_data = json.loads(create_json_settings(data)) SettingsIO.result.set_result(json_data) From d9e20ed7206e28cb8aedb489b002ff790a8f1686 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 19 Jan 2024 13:17:40 -0500 Subject: [PATCH 076/123] WIP --- src/gshocktimeserver/api_tests.py | 20 ++++----- src/gshocktimeserver/gshock_api.py | 37 +++++++--------- .../iolib/time_adjustement_io.py | 43 +++++++++++++++++++ src/gshocktimeserver/message_dispatcher.py | 15 +------ 4 files changed, 70 insertions(+), 45 deletions(-) create mode 100644 src/gshocktimeserver/iolib/time_adjustement_io.py diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index b16e9ba..5ab05b5 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -53,23 +53,23 @@ async def run_api_tests(): # logger.debug("timer: {} seconds".format(seconds)) # # await api.set_timer(seconds + 10) - # time_adjstment = await api.get_time_adjustment() - # logger.debug("time_adjstment: {}".format(time_adjstment)) + time_adjstment = await api.get_time_adjustment() + print("time_adjstment: {}".format(time_adjstment)) # settings.timeAdjustment = True # await api.set_time_adjustment(settings) - settings_local = await api.get_basic_settings() - print("settings: {}".format(settings_local)) + # settings_local = await api.get_basic_settings() + # print("settings: {}".format(settings_local)) - settings_local["button_tone"] = True - settings_local["language"] = "Russian" - settings_local["time_format"] = "24h" + # settings_local["button_tone"] = True + # settings_local["language"] = "Russian" + # settings_local["time_format"] = "24h" - await api.set_settings(settings_local) + # await api.set_settings(settings_local) - settings_local = await api.get_basic_settings() - print("After update: settings: {}".format(settings_local)) + # settings_local = await api.get_basic_settings() + # print("After update: settings: {}".format(settings_local)) # Create a single event # tz = pytz.timezone("America/Toronto") diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index e5a1142..f0694b9 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -337,25 +337,20 @@ async def get_time_adjustment(self): ------- is_time_adjustement_set: Boolean, True if time-adjustement is set. """ - key = "11" - await self.connection.request(key) + result = await message_dispatcher.TimeAdjustmentIO.request(self.connection) + return await result - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) + # def get_time_adjustment(keyed_data): + # value = keyed_data.get("value") + # key = keyed_data.get("key") + # if key != "11": + # return - def get_time_adjustment(keyed_data): - value = keyed_data.get("value") - key = keyed_data.get("key") - if key != "11": - return + # res = result_queue.dequeue(key) + # time_adjustment = value.get("timeAdjustment", False) + # res.set_result(time_adjustment) - res = result_queue.dequeue(key) - time_adjustment = value.get("timeAdjustment", False) - res.set_result(time_adjustment) - - self.subscribe("TIME_ADJUSTMENT", get_time_adjustment) - return await result + # self.subscribe("TIME_ADJUSTMENT", get_time_adjustment) async def set_time_adjustment(self, settings): """Sets auto-tame adjustment for the watch @@ -368,11 +363,11 @@ async def set_time_adjustment(self, settings): ------- None """ - await self.connection.sendMessage( - """{"action": "SET_TIME_ADJUSTMENT", "value": \"""" - + str(settings.timeAdjustment) - + """\" }""" - ) + # await self.connection.sendMessage( + # """{"action": "SET_TIME_ADJUSTMENT", "value": \"""" + # + str(settings.timeAdjustment) + # + """\" }""" + # ) async def get_basic_settings(self): """Get settings from the watch. Example: diff --git a/src/gshocktimeserver/iolib/time_adjustement_io.py b/src/gshocktimeserver/iolib/time_adjustement_io.py new file mode 100644 index 0000000..9cfc2b8 --- /dev/null +++ b/src/gshocktimeserver/iolib/time_adjustement_io.py @@ -0,0 +1,43 @@ +import asyncio +import json +from typing import Any +from settings import settings +from utils import to_compact_string, to_hex_string, to_int_array +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class TimeAdjustmentIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection): + print(f"TimerIO request") + TimeAdjustmentIO.connection = connection + await connection.request("11") + + loop = asyncio.get_running_loop() + TimeAdjustmentIO.result = loop.create_future() + return TimeAdjustmentIO.result + + @staticmethod + def send_to_watch(message): + print(f"TimeAdjustmentIO sendToWatch: {message}") + TimeAdjustmentIO.connection.write( + 0x000C, bytearray([CHARACTERISTICS["TIME_ADJUSTMENT"]]) + ) + + @staticmethod + def send_to_watch_set(message): + print(f"TimeAdjustmentIO sendToWatchSet: {message}") + + @staticmethod + def on_received(message): + print(f"TimeAdjustmentIO onReceived: {message}") + + data = to_hex_string(message) + json_data = json.loads(data).get("timeAdjustment") + + TimeAdjustmentIO.result.set_result(message) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index 32691bb..bdc7527 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -14,24 +14,11 @@ from iolib.alarms_io import AlarmsIO from iolib.events_io import EventsIO from iolib.settings_io import SettingsIO +from iolib.time_adjustement_io import TimeAdjustmentIO CHARACTERISTICS = CasioConstants.CHARACTERISTICS -class TimeAdjustmentIO: - @staticmethod - def send_to_watch(message): - print(f"TimeAdjustmentIO sendToWatch: {message}") - - @staticmethod - def send_to_watch_set(message): - print(f"TimeAdjustmentIO sendToWatchSet: {message}") - - @staticmethod - def on_received(message): - print(f"TimeAdjustmentIO onReceived: {message}") - - class WatchConditionIO: @staticmethod def on_received(message): From 346c19ee9a5218106607684747a8b3ae31ee901d Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Fri, 19 Jan 2024 18:35:29 -0500 Subject: [PATCH 077/123] Complted time adjustement --- src/gshocktimeserver/api_tests.py | 4 +- src/gshocktimeserver/gshock_api.py | 26 +++------ .../iolib/time_adjustement_io.py | 53 +++++++++++++++++-- 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 5ab05b5..31ca38f 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -54,10 +54,10 @@ async def run_api_tests(): # # await api.set_timer(seconds + 10) time_adjstment = await api.get_time_adjustment() - print("time_adjstment: {}".format(time_adjstment)) + # print("time_adjstment: {}".format(time_adjstment)) # settings.timeAdjustment = True - # await api.set_time_adjustment(settings) + await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) # settings_local = await api.get_basic_settings() # print("settings: {}".format(settings_local)) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index f0694b9..35dc2ed 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -340,34 +340,22 @@ async def get_time_adjustment(self): result = await message_dispatcher.TimeAdjustmentIO.request(self.connection) return await result - # def get_time_adjustment(keyed_data): - # value = keyed_data.get("value") - # key = keyed_data.get("key") - # if key != "11": - # return - - # res = result_queue.dequeue(key) - # time_adjustment = value.get("timeAdjustment", False) - # res.set_result(time_adjustment) - - # self.subscribe("TIME_ADJUSTMENT", get_time_adjustment) - - async def set_time_adjustment(self, settings): + async def set_time_adjustment( + self, time_adjustement: bool, minutes_after_hour: int + ): """Sets auto-tame adjustment for the watch Parameters ---------- - settings: Settings + time_adjustement: bool, True if time-adjustement is set + minutes_after_hour: int, minutes after hour Returns ------- None """ - # await self.connection.sendMessage( - # """{"action": "SET_TIME_ADJUSTMENT", "value": \"""" - # + str(settings.timeAdjustment) - # + """\" }""" - # ) + message = f"""{{"action": "SET_TIME_ADJUSTMENT", "timeAdjustment": "{time_adjustement}", "minutesAfterHour": "{minutes_after_hour}" }}""" + await self.connection.sendMessage(message) async def get_basic_settings(self): """Get settings from the watch. Example: diff --git a/src/gshocktimeserver/iolib/time_adjustement_io.py b/src/gshocktimeserver/iolib/time_adjustement_io.py index 9cfc2b8..247ff56 100644 --- a/src/gshocktimeserver/iolib/time_adjustement_io.py +++ b/src/gshocktimeserver/iolib/time_adjustement_io.py @@ -1,5 +1,6 @@ import asyncio import json +import logging from typing import Any from settings import settings from utils import to_compact_string, to_hex_string, to_int_array @@ -11,6 +12,7 @@ class TimeAdjustmentIO: result: asyncio.Future[Any] = None connection = None + original_value = "" @staticmethod async def request(connection): @@ -30,14 +32,57 @@ def send_to_watch(message): ) @staticmethod - def send_to_watch_set(message): + async def send_to_watch_set(message): print(f"TimeAdjustmentIO sendToWatchSet: {message}") + if TimeAdjustmentIO.original_value == "": + logging.error("TimeAdjustmentIO original value not set") + return None + + time_adjustment = json.loads(message).get("timeAdjustment") == "True" + minutes_after_hour = int(json.loads(message).get("minutesAfterHour")) + + def encode_time_adjustment(time_adjustment, minutes_after_hour): + raw_string = TimeAdjustmentIO.original_value + "0x11 0F 0F 0F 06 00 00 00 00 00 01 00 80 30 30" + int_array = to_int_array(raw_string) + int_array[12] = 0x80 if time_adjustment == False else 0x00 + int_array[13] = int(minutes_after_hour) + return bytes(int_array) + + encoded_time_adj = encode_time_adjustment(time_adjustment, minutes_after_hour) + + write_cmd = to_compact_string(to_hex_string(encoded_time_adj)) + await TimeAdjustmentIO.connection.write(0x000E, write_cmd) + @staticmethod def on_received(message): print(f"TimeAdjustmentIO onReceived: {message}") + TimeAdjustmentIO.original_value = to_hex_string( + message + ) # save original message + + def is_time_adjustment_set(data) -> bool: + # syncing off: 110f0f0f0600500004000100->80<-10d2 + # syncing on: 110f0f0f0600500004000100->00<-10d2 - data = to_hex_string(message) - json_data = json.loads(data).get("timeAdjustment") + # CasioIsAutoTimeOriginalValue.value = data # save original data for future use + return int(data[12]) == 0x00 - TimeAdjustmentIO.result.set_result(message) + def get_minutes_after_hour(data) -> int: + # syncing off: 110f0f0f060050000400010080->10<-d2 + + # CasioIsAutoTimeOriginalValue.value = data # save original data for future use + return int(data[13]) + + timeAdjusted = is_time_adjustment_set(message) + munutesAfterHour = get_minutes_after_hour(message) + valueToSetStr = f"""{{"timeAdjusment": "{timeAdjusted}", + "minutesAfterHour": "{munutesAfterHour}" }}""" + + value = json.loads(valueToSetStr) + TimeAdjustmentIO.result.set_result(value) + + @staticmethod + async def on_received_set(message): + print(f"TimeAdjustmentIO onReceivedSet: {message}") From 898e4d775bce82bc072a0730155964baea874bef Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sat, 20 Jan 2024 18:45:24 -0500 Subject: [PATCH 078/123] Added watch condition --- config.ini | 4 +- src/gshocktimeserver/api_tests.py | 7 ++- src/gshocktimeserver/gshock_api.py | 4 ++ .../iolib/watch_condition_io.py | 60 +++++++++++++++++++ src/gshocktimeserver/message_dispatcher.py | 7 +-- src/gshocktimeserver/watch_info.py | 3 + 6 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 src/gshocktimeserver/iolib/watch_condition_io.py diff --git a/config.ini b/config.ini index e4cd7c7..8ef9d8c 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 +device.address = CD:85:03:12:62:17 +device.name = CASIO GW-B5600 diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 31ca38f..3a5f65b 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -53,11 +53,14 @@ async def run_api_tests(): # logger.debug("timer: {} seconds".format(seconds)) # # await api.set_timer(seconds + 10) - time_adjstment = await api.get_time_adjustment() + # time_adjstment = await api.get_time_adjustment() # print("time_adjstment: {}".format(time_adjstment)) # settings.timeAdjustment = True - await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) + # await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) + + condition = await api.get_watch_condition() + print(f"condition: {condition.__dict__}") # settings_local = await api.get_basic_settings() # print("settings: {}".format(settings_local)) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 35dc2ed..3504c50 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -326,6 +326,10 @@ async def set_timer(self, timerValue): """{"action": "SET_TIMER", "value": """ + str(timerValue) + """ }""" ) + async def get_watch_condition(self): + result = await message_dispatcher.WatchConditionIO.request(self.connection) + return await result + async def get_time_adjustment(self): """Determine if auto-tame adjustment is set or not diff --git a/src/gshocktimeserver/iolib/watch_condition_io.py b/src/gshocktimeserver/iolib/watch_condition_io.py new file mode 100644 index 0000000..d0eabcb --- /dev/null +++ b/src/gshocktimeserver/iolib/watch_condition_io.py @@ -0,0 +1,60 @@ +import asyncio +from typing import Any +from watch_info import WatchInfo +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class WatchConditionIO: + result: asyncio.Future[Any] = None + connection = None + + class WatchConditionValue: + def __init__(self, battery_level_percent: int, temperature: int): + self.battery_level_percent = battery_level_percent + self.temperature = temperature + + @staticmethod + async def request(connection): + print(f"WatchConditionIO request") + WatchConditionIO.connection = connection + await connection.request("28") + + loop = asyncio.get_running_loop() + WatchConditionIO.result = loop.create_future() + return WatchConditionIO.result + + @staticmethod + async def send_to_watch(connection): + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_WATCH_CONDITION"]])) + + @staticmethod + def on_received(data): + print(f"WatchConditionIO onReceived") + + def decode_value(data: str) -> WatchConditionIO.WatchConditionValue: + int_arr = list(map(int, data)) + bytes_data = bytes(int_arr[1:]) + + if len(bytes_data) >= 2: + # Battery level between 15 and 20 for B2100 and between 12 and 19 for B5600. Scale accordingly to % + print(f"battery level row value: {int(bytes_data[0])}") + + battery_level_lower_limit = (15 + 9) / 2 + battery_level_upper_limit = 19.5 + + multiplier = round( + 100.0 / (battery_level_upper_limit - battery_level_lower_limit) + ) + battery_level = int(bytes_data[0]) - battery_level_lower_limit + battery_level_percent = min(max(battery_level * multiplier, 0), 100) + temperature = int(bytes_data[1]) + + return WatchConditionIO.WatchConditionValue( + battery_level_percent, temperature + ) + + return WatchConditionIO.WatchConditionValue(0, 0) + + WatchConditionIO.result.set_result(decode_value(data)) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index bdc7527..194a33b 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -15,16 +15,11 @@ from iolib.events_io import EventsIO from iolib.settings_io import SettingsIO from iolib.time_adjustement_io import TimeAdjustmentIO +from iolib.watch_condition_io import WatchConditionIO CHARACTERISTICS = CasioConstants.CHARACTERISTICS -class WatchConditionIO: - @staticmethod - def on_received(message): - print(f"WatchConditionIO onReceived: {message}") - - class AppInfoIO: @staticmethod def on_received(message): diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index 386247d..dd09600 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -219,6 +219,9 @@ def set_address(self, address): def get_address(self): return self.address + def get_model(self): + return self.model + def reset(self): self.address = "" self.name = "" From 9491e93794e6ef58d3693377f116546fb1fb3da9 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sat, 20 Jan 2024 19:00:19 -0500 Subject: [PATCH 079/123] Added watch condition --- config.ini | 4 ++-- src/gshocktimeserver/api_tests.py | 6 +++--- src/gshocktimeserver/iolib/error_io.py | 4 ++++ src/gshocktimeserver/iolib/time_adjustement_io.py | 10 ++++++---- src/gshocktimeserver/message_dispatcher.py | 7 +------ 5 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 src/gshocktimeserver/iolib/error_io.py diff --git a/config.ini b/config.ini index 8ef9d8c..e4cd7c7 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:03:12:62:17 -device.name = CASIO GW-B5600 +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 3a5f65b..bf2aa8a 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -57,10 +57,10 @@ async def run_api_tests(): # print("time_adjstment: {}".format(time_adjstment)) # settings.timeAdjustment = True - # await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) + await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) - condition = await api.get_watch_condition() - print(f"condition: {condition.__dict__}") + # condition = await api.get_watch_condition() + # print(f"condition: {condition.__dict__}") # settings_local = await api.get_basic_settings() # print("settings: {}".format(settings_local)) diff --git a/src/gshocktimeserver/iolib/error_io.py b/src/gshocktimeserver/iolib/error_io.py new file mode 100644 index 0000000..3f4fe33 --- /dev/null +++ b/src/gshocktimeserver/iolib/error_io.py @@ -0,0 +1,4 @@ +class ErrorIO: + @staticmethod + async def on_received(message): + print(f"ErrorIO onReceived: {message}") diff --git a/src/gshocktimeserver/iolib/time_adjustement_io.py b/src/gshocktimeserver/iolib/time_adjustement_io.py index 247ff56..36b6870 100644 --- a/src/gshocktimeserver/iolib/time_adjustement_io.py +++ b/src/gshocktimeserver/iolib/time_adjustement_io.py @@ -5,6 +5,8 @@ from settings import settings from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants +from iolib.error_io import ErrorIO + CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -12,7 +14,7 @@ class TimeAdjustmentIO: result: asyncio.Future[Any] = None connection = None - original_value = "" + original_value = None @staticmethod async def request(connection): @@ -35,9 +37,9 @@ def send_to_watch(message): async def send_to_watch_set(message): print(f"TimeAdjustmentIO sendToWatchSet: {message}") - if TimeAdjustmentIO.original_value == "": - logging.error("TimeAdjustmentIO original value not set") - return None + if TimeAdjustmentIO.original_value == None: + logging.error("Error: Must call get before set") + return ErrorIO.request("Error: Must call get before set") time_adjustment = json.loads(message).get("timeAdjustment") == "True" minutes_after_hour = int(json.loads(message).get("minutesAfterHour")) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index 194a33b..4669152 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -16,6 +16,7 @@ from iolib.settings_io import SettingsIO from iolib.time_adjustement_io import TimeAdjustmentIO from iolib.watch_condition_io import WatchConditionIO +from iolib.error_io import ErrorIO CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -32,12 +33,6 @@ def on_received(message): print(f"ButtonPressedIO onReceived: {message}") -class ErrorIO: - @staticmethod - def on_received(message): - print(f"ErrorIO onReceived: {message}") - - class UnknownIO: @staticmethod def on_received(message): From c00468bda4016ab050e016ccf4c8ea9280bf07f5 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 21 Jan 2024 13:10:03 -0500 Subject: [PATCH 080/123] Perssed button completed. --- src/gshocktimeserver/api_tests.py | 9 ++- src/gshocktimeserver/gshock_api.py | 76 +------------------ src/gshocktimeserver/iolib/app_info_io.py | 46 +++++++++++ .../iolib/button_pressed_io.py | 74 ++++++++++++++++++ src/gshocktimeserver/iolib/unknown_io.py | 4 + src/gshocktimeserver/message_dispatcher.py | 21 +---- 6 files changed, 135 insertions(+), 95 deletions(-) create mode 100644 src/gshocktimeserver/iolib/app_info_io.py create mode 100644 src/gshocktimeserver/iolib/button_pressed_io.py create mode 100644 src/gshocktimeserver/iolib/unknown_io.py diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index bf2aa8a..a915920 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -30,10 +30,11 @@ async def run_api_tests(): api = GshockAPI(connection) - # await api.get_app_info() + # app_info = await api.get_app_info() + # print("app info: {}".format(app_info)) - # pressed_button = await api.get_pressed_button() - # logger.debug("pressed button: {}".format(pressed_button)) + pressed_button = await api.get_pressed_button() + print("pressed button: {}".format(pressed_button)) # watch_name = await api.get_watch_name() # logger.info("got watch name: {}".format(watch_name)) @@ -57,7 +58,7 @@ async def run_api_tests(): # print("time_adjstment: {}".format(time_adjstment)) # settings.timeAdjustment = True - await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) + # await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) # condition = await api.get_watch_condition() # print(f"condition: {condition.__dict__}") diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 3504c50..8796c0c 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -83,50 +83,7 @@ async def get_pressed_button(self) -> WatchButton: ------- button: WATCH_BUTTON """ - return await self._get_pressed_button("10") - - async def _get_pressed_button(self, key: str) -> WatchButton: - await self.connection.request(key) - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def button_pressed_callback(keyed_data): - """ - RIGHT BUTTON: 0x10 17 62 07 38 85 CD 7F ->04<- 03 0F FF FF FF FF 24 00 00 00 - LEFT BUTTON: 0x10 17 62 07 38 85 CD 7F ->01<- 03 0F FF FF FF FF 24 00 00 00 - RESET: 0x10 17 62 16 05 85 dd 7f ->00<- 03 0f ff ff ff ff 24 00 00 00 // after watch reset - AUTO-TIME: 0x10 17 62 16 05 85 dd 7f ->03<- 03 0f ff ff ff ff 24 00 00 00 // no button pressed - """ - - result_value = keyed_data.get("value") - result_key = keyed_data.get("key") - - ret = WatchButton.INVALID - - if ( - result_key == "10" - and result_value != "" - and len(to_int_array(result_value)) >= 19 - ): - ble_int_arr = to_int_array(result_value) - button_indicator = ble_int_arr[8] - ret = ( - WatchButton.LOWER_LEFT - if (button_indicator == 0 or button_indicator == 1) - else WatchButton.LOWER_RIGHT - if button_indicator == 4 - else WatchButton.NO_BUTTON - if button_indicator == 3 - else WatchButton.INVALID - ) - - res = result_queue.dequeue("10") - res.set_result(ret) - - self.subscribe("BUTTON_PRESSED", button_pressed_callback) - + result = await message_dispatcher.ButtonPressedIO.request(self.connection) return await result async def get_world_cities(self, cityNumber: int): @@ -488,35 +445,8 @@ async def get_app_info(self): ------- app_info: String """ - key = "22" - await self.connection.request(key) - - def set_app_info(data: str): - # App info: - # This is needed to re-enable button D (Lower-right) after the watch has been reset or BLE has been cleared. - # It is a hard-coded value, which is what the official app does as well. - - # If watch was reset, the app info will come as: - # 0x22 FF FF FF FF FF FF FF FF FF FF 00 - # In this case, set it to the hardcoded value bellow, so 'D' button will - # work again. - app_info_compact_str = to_compact_string(data) - if app_info_compact_str == "22FFFFFFFFFFFFFFFFFFFF00": - self.connection.write(0xE, "223488F4E5D5AFC829E06D02") - - loop = asyncio.get_running_loop() - result = loop.create_future() - result_queue.enqueue(KeyedResult(key, result)) - - def subscribe_casio_app_information(keyed_data): - data = keyed_data.get("value") - key = keyed_data.get("key") - - set_app_info(data) - res = result_queue.dequeue(key) - res.set_result("") - - self.subscribe("CASIO_APP_INFORMATION", subscribe_casio_app_information) + + result = await message_dispatcher.AppInfoIO.request(self.connection) return await result def subscribe(self, subject_name, on_next) -> None: diff --git a/src/gshocktimeserver/iolib/app_info_io.py b/src/gshocktimeserver/iolib/app_info_io.py new file mode 100644 index 0000000..962dfa1 --- /dev/null +++ b/src/gshocktimeserver/iolib/app_info_io.py @@ -0,0 +1,46 @@ +import asyncio +from typing import Any + +from utils import to_compact_string, to_hex_string +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class AppInfoIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection): + print(f"AppInfoIO request") + AppInfoIO.connection = connection + await connection.request("22") + + loop = asyncio.get_running_loop() + AppInfoIO.result = loop.create_future() + return AppInfoIO.result + + @staticmethod + async def send_to_watch(connection): + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_APP_INFORMATION"]])) + + @staticmethod + def on_received(data): + print(f"AppInfoIO onReceived") + + def set_app_info(data: str): + # App info: + # This is needed to re-enable button D (Lower-right) after the watch has been reset or BLE has been cleared. + # It is a hard-coded value, which is what the official app does as well. + + # If watch was reset, the app info will come as: + # 0x22 FF FF FF FF FF FF FF FF FF FF 00 + # In this case, set it to the hardcoded value bellow, so 'D' button will + # work again. + app_info_compact_str = to_compact_string(data) + if app_info_compact_str == "22FFFFFFFFFFFFFFFFFFFF00": + AppInfoIO.connection.write(0xE, "223488F4E5D5AFC829E06D02") + + set_app_info(to_hex_string(data)) + AppInfoIO.result.set_result("OK") diff --git a/src/gshocktimeserver/iolib/button_pressed_io.py b/src/gshocktimeserver/iolib/button_pressed_io.py new file mode 100644 index 0000000..e0442b1 --- /dev/null +++ b/src/gshocktimeserver/iolib/button_pressed_io.py @@ -0,0 +1,74 @@ +import asyncio +from enum import IntEnum +from typing import Any + +from utils import to_compact_string, to_hex_string, to_int_array +from casio_constants import CasioConstants + +CHARACTERISTICS = CasioConstants.CHARACTERISTICS + + +class WatchButton(IntEnum): + UPPER_LEFT = 1 + LOWER_LEFT = 2 + UPPER_RIGHT = 3 + LOWER_RIGHT = 4 + NO_BUTTON = 5 + INVALID = 6 + + +class ButtonPressedIO: + result: asyncio.Future[Any] = None + connection = None + + @staticmethod + async def request(connection): + print(f"ButtonPressedIO request") + ButtonPressedIO.connection = connection + await connection.request("10") + + loop = asyncio.get_running_loop() + ButtonPressedIO.result = loop.create_future() + return ButtonPressedIO.result + + @staticmethod + async def send_to_watch(connection): + connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_BLE_FEATURES"]])) + + @staticmethod + async def send_to_watch_set(data): + print(f"TimerIO sendToWatchSet: {data}") + + await ButtonPressedIO.connection.write(0x000E, data) + + @staticmethod + def on_received(data): + print(f"ButtonPressedIO onReceived") + + def button_pressed_callback(data): + """ + RIGHT BUTTON: 0x10 17 62 07 38 85 CD 7F ->04<- 03 0F FF FF FF FF 24 00 00 00 + LEFT BUTTON: 0x10 17 62 07 38 85 CD 7F ->01<- 03 0F FF FF FF FF 24 00 00 00 + RESET: 0x10 17 62 16 05 85 dd 7f ->00<- 03 0f ff ff ff ff 24 00 00 00 // after watch reset + AUTO-TIME: 0x10 17 62 16 05 85 dd 7f ->03<- 03 0f ff ff ff ff 24 00 00 00 // no button pressed + """ + + ret = WatchButton.INVALID + + if len(data) >= 19: + ble_int_arr = to_int_array(to_hex_string(data)) + button_indicator = ble_int_arr[8] + ret = ( + WatchButton.LOWER_LEFT + if (button_indicator == 0 or button_indicator == 1) + else WatchButton.LOWER_RIGHT + if button_indicator == 4 + else WatchButton.NO_BUTTON + if button_indicator == 3 + else WatchButton.INVALID + ) + + return ret + + button = button_pressed_callback(data) + ButtonPressedIO.result.set_result(button) diff --git a/src/gshocktimeserver/iolib/unknown_io.py b/src/gshocktimeserver/iolib/unknown_io.py new file mode 100644 index 0000000..f7d73ce --- /dev/null +++ b/src/gshocktimeserver/iolib/unknown_io.py @@ -0,0 +1,4 @@ +class UnknownIO: + @staticmethod + def on_received(message): + print(f"UnknownIO onReceived: {message}") diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index 4669152..e1aec51 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -4,6 +4,7 @@ from typing import Any import connection from casio_constants import CasioConstants +from iolib.app_info_io import AppInfoIO from iolib.dst_watch_state_io import DstWatchStateIO from iolib.world_cities_io import WorldCitiesIO from iolib.dst_for_world_cities_io import DstForWorldCitiesIO @@ -17,28 +18,12 @@ from iolib.time_adjustement_io import TimeAdjustmentIO from iolib.watch_condition_io import WatchConditionIO from iolib.error_io import ErrorIO +from iolib.unknown_io import UnknownIO +from iolib.button_pressed_io import ButtonPressedIO CHARACTERISTICS = CasioConstants.CHARACTERISTICS -class AppInfoIO: - @staticmethod - def on_received(message): - print(f"AppInfoIO onReceived: {message}") - - -class ButtonPressedIO: - @staticmethod - def on_received(message): - print(f"ButtonPressedIO onReceived: {message}") - - -class UnknownIO: - @staticmethod - def on_received(message): - print(f"UnknownIO onReceived: {message}") - - class MessageDispatcher: watch_senders = { "GET_ALARMS": AlarmsIO.send_to_watch, From abd956692929640a19749d6b2083ec92f71f14a2 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 21 Jan 2024 13:31:14 -0500 Subject: [PATCH 081/123] Completed optimization --- src/gshocktimeserver/api_tests.py | 116 ++-- src/gshocktimeserver/casio_watch.py | 638 ------------------ src/gshocktimeserver/connection.py | 2 - src/gshocktimeserver/device_queue.py | 15 - src/gshocktimeserver/gshock_api.py | 4 +- src/gshocktimeserver/gshock_server.py | 1 - .../iolib/dst_watch_state_io.py | 24 +- src/gshocktimeserver/iolib/timer_io.py | 4 +- src/gshocktimeserver/iolib/world_cities_io.py | 3 - 9 files changed, 85 insertions(+), 722 deletions(-) delete mode 100644 src/gshocktimeserver/casio_watch.py delete mode 100644 src/gshocktimeserver/device_queue.py diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index a915920..8659c73 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -6,7 +6,6 @@ from connection import Connection from gshock_api import GshockAPI -from casio_watch import DtsState, settings from event import Event, create_event_date, RepeatPeriod from scanner import scanner from logger import logger @@ -30,81 +29,80 @@ async def run_api_tests(): api = GshockAPI(connection) - # app_info = await api.get_app_info() - # print("app info: {}".format(app_info)) + app_info = await api.get_app_info() + print("app info: {}".format(app_info)) pressed_button = await api.get_pressed_button() print("pressed button: {}".format(pressed_button)) - # watch_name = await api.get_watch_name() - # logger.info("got watch name: {}".format(watch_name)) + watch_name = await api.get_watch_name() + logger.info("got watch name: {}".format(watch_name)) - # await api.set_time() + await api.set_time() - # alarms = await api.get_alarms() - # logger.debug("alarms: {}".format(alarms)) + alarms = await api.get_alarms() + logger.debug("alarms: {}".format(alarms)) - # alarms[3]["enabled"] = True - # alarms[3]["hour"] = 7 - # alarms[3]["minute"] = 25 - # alarms[3]["enabled"] = False - # await api.set_alarms(alarms) + alarms[3]["enabled"] = True + alarms[3]["hour"] = 7 + alarms[3]["minute"] = 25 + alarms[3]["enabled"] = False + await api.set_alarms(alarms) - # seconds = await api.get_timer() - # logger.debug("timer: {} seconds".format(seconds)) + seconds = await api.get_timer() + logger.debug("timer: {} seconds".format(seconds)) - # # await api.set_timer(seconds + 10) - # time_adjstment = await api.get_time_adjustment() - # print("time_adjstment: {}".format(time_adjstment)) + await api.set_timer(seconds + 10) + time_adjstment = await api.get_time_adjustment() + print("time_adjstment: {}".format(time_adjstment)) - # settings.timeAdjustment = True - # await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) + await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) - # condition = await api.get_watch_condition() - # print(f"condition: {condition.__dict__}") + condition = await api.get_watch_condition() + print(f"condition: {condition.__dict__}") - # settings_local = await api.get_basic_settings() - # print("settings: {}".format(settings_local)) + settings_local = await api.get_basic_settings() + print("settings: {}".format(settings_local)) - # settings_local["button_tone"] = True - # settings_local["language"] = "Russian" - # settings_local["time_format"] = "24h" + settings_local["button_tone"] = True + settings_local["language"] = "Russian" + settings_local["time_format"] = "24h" - # await api.set_settings(settings_local) + await api.set_settings(settings_local) - # settings_local = await api.get_basic_settings() - # print("After update: settings: {}".format(settings_local)) + settings_local = await api.get_basic_settings() + print("After update: settings: {}".format(settings_local)) # Create a single event - # tz = pytz.timezone("America/Toronto") - # dt = datetime.now(timezone.utc) - # utc_timestamp = dt.timestamp() - # event_date = create_event_date(utc_timestamp, tz) - # event_date_str = json.dumps(event_date.__dict__) - # event_json_str = ( - # """{"title":"Test Event", "time":{"selected":\"""" - # + str(False) - # + """\", "enabled":\"""" - # + str(True) - # + """\", "repeat_period":\"""" - # + RepeatPeriod.WEEKLY - # + """\","days_of_week":\"""" - # + "MONDAY" - # + """\", "start_date":""" - # + event_date_str - # + """, "end_date":""" - # + event_date_str - # + """}}""" - # ) - # Event().create_event(json.loads(event_json_str)) - - # reminders = await api.get_reminders() - # for reminder in reminders: - # logger.debug("reminder: {}".format(reminder.__str__())) - - # reminders[3]["title"] = "Test Event" - - # await api.set_reminders(reminders) + tz = pytz.timezone("America/Toronto") + dt = datetime.now(timezone.utc) + utc_timestamp = dt.timestamp() + event_date = create_event_date(utc_timestamp, tz) + event_date_str = json.dumps(event_date.__dict__) + event_json_str = ( + """{"title":"Test Event", "time":{"selected":\"""" + + str(False) + + """\", "enabled":\"""" + + str(True) + + """\", "repeat_period":\"""" + + RepeatPeriod.WEEKLY + + """\","days_of_week":\"""" + + "MONDAY" + + """\", "start_date":""" + + event_date_str + + """, "end_date":""" + + event_date_str + + """}}""" + ) + Event().create_event(json.loads(event_json_str)) + + reminders = await api.get_reminders() + for reminder in reminders: + logger.debug("reminder: {}".format(reminder.__str__())) + + reminders[3]["title"] = "Test Event" + + await api.set_reminders(reminders) input("Hit any key to disconnect") diff --git a/src/gshocktimeserver/casio_watch.py b/src/gshocktimeserver/casio_watch.py deleted file mode 100644 index 815bdbb..0000000 --- a/src/gshocktimeserver/casio_watch.py +++ /dev/null @@ -1,638 +0,0 @@ -import json -import datetime -import struct -import geocoder -from settings import settings -from utils import ( - to_int_array, - to_compact_string, - to_hex_string, - clean_str, - to_ascii_string, - to_byte_array, - dec_to_hex, -) -from casio_constants import CasioConstants -from enum import IntEnum -from alarms import alarms_inst, alarm_decoder -from logger import logger -from struct import pack - -CHARACTERISTICS = CasioConstants.CHARACTERISTICS - - -class WatchButton(IntEnum): - UPPER_LEFT = 1 - LOWER_LEFT = 2 - UPPER_RIGHT = 3 - LOWER_RIGHT = 4 - NO_BUTTON = 5 - INVALID = 6 - - -class DtsState(IntEnum): - ZERO = 0 - TWO = 2 - FOUR = 4 - - -class ReminderMasks: - YEARLY_MASK = 0b00001000 - MONTHLY_MASK = 0b00010000 - WEEKLY_MASK = 0b00000100 - - SUNDAY_MASK = 0b00000001 - MONDAY_MASK = 0b00000010 - TUESDAY_MASK = 0b00000100 - WEDNESDAY_MASK = 0b00001000 - THURSDAY_MASK = 0b00010000 - FRIDAY_MASK = 0b00100000 - SATURDAY_MASK = 0b01000000 - - ENABLED_MASK = 0b00000001 - - -class SettingsDecoder: - def to_json_time_adjustment(settings): - return {"timeAdjustment": settings.time_adjustment} - - -class ReminderDecoder: - def reminder_title_to_json(title_byte: str) -> dict: - int_arr = to_int_array(title_byte) - if int_arr[2] == 0xFF: - # 0XFF indicates end of reminders - return {"end": ""} - reminder_json = {} - - reminder_json["title"] = clean_str(to_ascii_string(title_byte, 2)) - return reminder_json - - -def create_key(data): - short_str = to_compact_string(data) - key_length = 2 - # get the first byte of the returned data, which indicates the data content. - start_of_data = short_str[0:2].upper() - if start_of_data in ["1D", "1E", "1F", "30", "31"]: - key_length = 4 - key = short_str[0:key_length].upper() - return key - - -def to_json(_data): - data = to_hex_string(_data) - int_array = to_int_array(data) - json_obj = {} - if int_array[0] == CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]: - return { - "ALARMS": { - "value": alarm_decoder.to_json(data)["ALARMS"], - "key": "GET_ALARMS", - } - } - - if int_array[0] == CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]: - return { - "ALARMS2": { - "value": alarm_decoder.to_json(data)["ALARMS"], - "key": "GET_ALARMS2", - } - } - - # Add topics so the right component will receive data - elif int_array[0] == CHARACTERISTICS["CASIO_DST_SETTING"]: - data_json = {"key": create_key(data), "value": data} - json_obj["CASIO_DST_SETTING"] = data_json - - elif int_array[0] == CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"]: - - def create_json_settings(setting_string): - mask_24_hours = 0b00000001 - MASK_BUTTON_TONE_OFF = 0b00000010 - MASK_LIGHT_OFF = 0b00000100 - POWER_SAVING_MODE = 0b00010000 - - setting_array = to_int_array(setting_string) - - if setting_array[1] & mask_24_hours != 0: - settings.time_format = "24h" - else: - settings.time_format = "12h" - settings.button_tone = setting_array[1] & MASK_BUTTON_TONE_OFF == 0 - settings.auto_light = setting_array[1] & MASK_LIGHT_OFF == 0 - settings.power_saving_mode = setting_array[1] & POWER_SAVING_MODE == 0 - - if setting_array[4] == 1: - settings.date_format = "DD:MM" - else: - settings.date_format = "MM:DD" - - if setting_array[5] == 0: - settings.language = "English" - if setting_array[5] == 1: - settings.language = "Spanish" - if setting_array[5] == 2: - settings.language = "French" - if setting_array[5] == 3: - settings.language = "German" - if setting_array[5] == 4: - settings.language = "Italian" - if setting_array[5] == 5: - settings.language = "Russian" - - if setting_array[2] == 1: - settings.light_duration = "4s" - else: - settings.light_duration = "2s" - - return json.dumps(settings.__dict__) - - data_json = {"key": create_key(data), "value": create_json_settings(data)} - settings_json = {"SETTINGS": data_json} - return settings_json - - elif int_array[0] == CHARACTERISTICS["CASIO_SETTING_FOR_BLE"]: - settings.CasioIsAutoTimeOriginalValue = data - value_json = SettingsDecoder.to_json_time_adjustment(settings) - data_json = {"key": create_key(data), "value": value_json} - return {"TIME_ADJUSTMENT": data_json} - - elif int_array[0] == CHARACTERISTICS["CASIO_REMINDER_TIME"]: - reminder_json = {} - - def reminder_time_to_json(reminder_str): - def convert_array_list_to_json_array(array_list): - json_array = [] - for item in array_list: - json_array.append(item) - - return json_array - - def decode_time_period(time_period: int) -> tuple: - enabled = False - repeat_period = "" - - if ( - time_period & ReminderMasks.ENABLED_MASK - == ReminderMasks.ENABLED_MASK - ): - enabled = True - - if time_period & ReminderMasks.WEEKLY_MASK == ReminderMasks.WEEKLY_MASK: - repeat_period = "WEEKLY" - elif ( - time_period & ReminderMasks.MONTHLY_MASK - == ReminderMasks.MONTHLY_MASK - ): - repeat_period = "MONTHLY" - elif ( - time_period & ReminderMasks.YEARLY_MASK == ReminderMasks.YEARLY_MASK - ): - repeat_period = "YEARLY" - else: - repeat_period = "NEVER" - - return (enabled, repeat_period) - - def decode_time_detail(time_detail): - def decode_date(time_detail): - def int_to_month_str(month_int): - months = [ - "JANUARY", - "FEBRUARY", - "MARCH", - "APRIL", - "MAY", - "JUNE", - "JULY", - "AUGUST", - "SEPTEMBER", - "OCTOBER", - "NOVEMBER", - "DECEMBER", - ] - if month_int < 1 or month_int > 12: - return "" - else: - return months[month_int - 1] - - date = json.loads("{}") - - date["year"] = dec_to_hex(time_detail[0]) + 2000 - date["month"] = int_to_month_str(dec_to_hex(time_detail[1])) - date["day"] = dec_to_hex(time_detail[2]) - - return date - - result = {} - - # 00 23 02 21 23 02 21 00 00 - # start from here: ^ - # so, skip 1 - start_date = decode_date(time_detail[1:]) - - result["start_date"] = start_date - - # 00 23 02 21 23 02 21 00 00 - # start from here: ^ - # so, skip 4 - end_date = decode_date(time_detail[4:]) - - result["end_date"] = end_date - - day_of_week = time_detail[7] - days_of_week = [] - if day_of_week & ReminderMasks.SUNDAY_MASK == ReminderMasks.SUNDAY_MASK: - days_of_week.append("SUNDAY") - if day_of_week & ReminderMasks.MONDAY_MASK == ReminderMasks.MONDAY_MASK: - days_of_week.append("MONDAY") - if ( - day_of_week & ReminderMasks.TUESDAY_MASK - == ReminderMasks.TUESDAY_MASK - ): - days_of_week.append("TUESDAY") - if ( - day_of_week & ReminderMasks.WEDNESDAY_MASK - == ReminderMasks.WEDNESDAY_MASK - ): - days_of_week.append("WEDNESDAY") - if ( - day_of_week & ReminderMasks.THURSDAY_MASK - == ReminderMasks.THURSDAY_MASK - ): - days_of_week.append("THURSDAY") - if day_of_week & ReminderMasks.FRIDAY_MASK == ReminderMasks.FRIDAY_MASK: - days_of_week.append("FRIDAY") - if ( - day_of_week & ReminderMasks.SATURDAY_MASK - == ReminderMasks.SATURDAY_MASK - ): - days_of_week.append("SATURDAY") - result["days_of_week"] = days_of_week - return result - - int_arr = to_int_array(reminder_str) - if int_arr[3] == 0xFF: - # 0XFF indicates end of reminders - return json.dumps({"end": ""}) - - reminder_all = to_int_array(reminder_str) - # Remove the first 2 chars: - # 0x31 05 <--- 00 23 02 21 23 02 21 00 00 - reminder = reminder_all[2:] - reminder_json = {} - time_period = decode_time_period(reminder[0]) - reminder_json["enabled"] = time_period[0] - reminder_json["repeat_period"] = time_period[1] - - time_detail_map = decode_time_detail(reminder) - - reminder_json["start_date"] = time_detail_map["start_date"] - reminder_json["end_date"] = time_detail_map["end_date"] - reminder_json["days_of_week"] = convert_array_list_to_json_array( - time_detail_map["days_of_week"] - ) - - return json.dumps({"time": reminder_json}) - - value = reminder_time_to_json(data[2:]) - reminder_json["REMINDERS"] = { - "key": create_key(data), - "value": json.loads(value), - } - return reminder_json - - elif int_array[0] == CHARACTERISTICS["CASIO_REMINDER_TITLE"]: - return { - "REMINDERS": { - "key": create_key(data), - "value": ReminderDecoder.reminder_title_to_json(data), - } - } - elif int_array[0] == CHARACTERISTICS["CASIO_TIMER"]: - data_json = {"key": create_key(data), "value": data} - json_obj["CASIO_TIMER"] = data_json - - elif int_array[0] == CHARACTERISTICS["CASIO_WORLD_CITIES"]: - data_json = {"key": create_key(data), "value": data} - json_obj["CASIO_WORLD_CITIES"] = data_json - elif int_array[0] == CHARACTERISTICS["CASIO_DST_WATCH_STATE"]: - data_json = {"key": create_key(data), "value": data} - json_obj["CASIO_DST_WATCH_STATE"] = data_json - elif int_array[0] == CHARACTERISTICS["CASIO_WATCH_NAME"]: - data_json = {"key": create_key(data), "value": data} - json_obj["CASIO_WATCH_NAME"] = data_json - elif int_array[0] == CHARACTERISTICS["CASIO_WATCH_CONDITION"]: - data_json = {"key": create_key(data), "value": data} - json_obj["CASIO_WATCH_CONDITION"] = data_json - elif int_array[0] == CHARACTERISTICS["CASIO_APP_INFORMATION"]: - data_json = {"key": create_key(data), "value": data} - json_obj["CASIO_APP_INFORMATION"] = data_json - elif int_array[0] == CHARACTERISTICS["CASIO_BLE_FEATURES"]: - data_json = {"key": create_key(data), "value": data} - json_obj["BUTTON_PRESSED"] = data_json - return json_obj - - -async def callWriter(connection, message: str): - logger.debug(message) - action_json = json.loads(message) - action = action_json.get("action") - - if action == "GET_ALARMS": - alarm_command = to_compact_string( - to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM"]])) - ) - - await connection.write(0x000C, alarm_command) - - elif action == "GET_ALARMS2": - # get the rest of the alarms - alarm_command2 = to_compact_string( - to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_ALM2"]])) - ) - await connection.write(0x000C, alarm_command2) - - elif action == "SET_ALARMS": - alarms_json_arr = json.loads(message).get("value") - alarm_casio0 = to_compact_string( - to_hex_string(alarms_inst.from_json_alarm_first_alarm(alarms_json_arr[0])) - ) - await connection.write(0x000E, alarm_casio0) - alarm_casio = to_compact_string( - to_hex_string(alarms_inst.from_json_alarm_secondary_alarms(alarms_json_arr)) - ) - await connection.write(0x000E, alarm_casio) - - elif action == "SET_REMINDERS": - - def reminder_title_from_json(reminder_json): - title_str = reminder_json.get("title") - return to_byte_array(title_str, 18) - - def reminder_time_from_json(reminder_json): - def create_time_detail(repeat_period, start_date, end_date, days_of_week): - def encode_date(time_detail, start_date, end_date): - class Month: - JANUARY = 1 - FEBRUARY = 2 - MARCH = 3 - APRIL = 4 - MAY = 5 - JUNE = 6 - JULY = 7 - AUGUST = 8 - SEPTEMBER = 9 - OCTOBER = 10 - NOVEMBER = 11 - DECEMBER = 12 - - def __init__(self): - pass - - def string_to_month(month_str): - months = { - "january": Month.JANUARY, - "february": Month.FEBRUARY, - "march": Month.MARCH, - "april": Month.APRIL, - "may": Month.MAY, - "june": Month.JUNE, - "july": Month.JULY, - "august": Month.AUGUST, - "september": Month.SEPTEMBER, - "october": Month.OCTOBER, - "november": Month.NOVEMBER, - "december": Month.DECEMBER, - } - return months.get(month_str.lower(), Month.JANUARY) - - def hex_to_dec(hex): - return int(str(hex), 16) - - # take the last 2 digits only - time_detail[0] = hex_to_dec(start_date["year"] % 2000) - time_detail[1] = hex_to_dec(string_to_month(start_date["month"])) - time_detail[2] = hex_to_dec(start_date["day"]) - time_detail[3] = hex_to_dec( - end_date["year"] % 2000 - ) # get the last 2 gits only - time_detail[4] = hex_to_dec(string_to_month(end_date["month"])) - time_detail[5] = hex_to_dec(end_date["day"]) - time_detail[6], time_detail[7] = 0, 0 - - time_detail = [0] * 8 - - if repeat_period == "NEVER": - encode_date(time_detail, start_date, end_date) - - elif repeat_period == "WEEKLY": - encode_date(time_detail, start_date, end_date) - - day_of_week = 0 - if days_of_week is not None: - for i in range(len(days_of_week)): - if days_of_week[i] == "SUNDAY": - day_of_week = day_of_week | ReminderMasks.SUNDAY_MASK - elif days_of_week[i] == "MONDAY": - day_of_week = day_of_week | ReminderMasks.MONDAY_MASK - elif days_of_week[i] == "TUESDAY": - day_of_week = day_of_week | ReminderMasks.TUESDAY_MASK - elif days_of_week[i] == "WEDNESDAY": - day_of_week = day_of_week | ReminderMasks.WEDNESDAY_MASK - elif days_of_week[i] == "THURSDAY": - day_of_week = day_of_week | ReminderMasks.THURSDAY_MASK - elif days_of_week[i] == "FRIDAY": - day_of_week = day_of_week | ReminderMasks.FRIDAY_MASK - elif days_of_week[i] == "SATURDAY": - day_of_week = day_of_week | ReminderMasks.SATURDAY_MASK - - time_detail[6] = day_of_week - time_detail[7] = 0 - - elif repeat_period == "MONTHLY": - encode_date(time_detail, start_date, end_date) - - elif repeat_period == "YEARLY": - encode_date(time_detail, start_date, end_date) - else: - logger.debug( - "Cannot handle Repeat Period: {}".format(repeat_period) - ) - - return time_detail - - def create_time_period(enabled: bool, repeat_period: str) -> int: - time_period = 0 - - if enabled: - time_period = time_period | ReminderMasks.ENABLED_MASK - if repeat_period == "WEEKLY": - time_period = time_period | ReminderMasks.WEEKLY_MASK - elif repeat_period == "MONTHLY": - time_period = time_period | ReminderMasks.MONTHLY_MASK - elif repeat_period == "YEARLY": - time_period = time_period | ReminderMasks.YEARLY_MASK - return time_period - - enabled = reminder_json.get("enabled") - repeat_period = reminder_json.get("repeat_period") - start_date = reminder_json.get("start_date") - end_date = reminder_json.get("end_date") - days_of_week = reminder_json.get("days_of_week") - - reminder_cmd = bytearray() - - reminder_cmd += bytearray([create_time_period(enabled, repeat_period)]) - reminder_cmd += bytearray( - create_time_detail(repeat_period, start_date, end_date, days_of_week) - ) - - return reminder_cmd - - reminders_json_arr = json.loads(message).get("value") - for index, element in enumerate(reminders_json_arr): - reminder_json = element - title = reminder_title_from_json(reminder_json) - - title_byte_arr = bytearray([CHARACTERISTICS["CASIO_REMINDER_TITLE"]]) - title_byte_arr += bytearray([index + 1]) - title_byte_arr += title - title_byte_arr_to_send = to_compact_string(to_hex_string(title_byte_arr)) - await connection.write(0x000E, title_byte_arr_to_send) - - reminder_time_byte_arr = bytearray([]) - reminder_time_byte_arr += bytearray( - [CHARACTERISTICS["CASIO_REMINDER_TIME"]] - ) - reminder_time_byte_arr += bytearray([index + 1]) - reminder_time_byte_arr += reminder_time_from_json(reminder_json) - reminder_time_byte_arr_to_send = to_compact_string( - to_hex_string(bytearray(reminder_time_byte_arr)) - ) - logger.debug(reminder_time_byte_arr_to_send) - await connection.write(0x000E, reminder_time_byte_arr_to_send) - - elif action == "GET_SETTINGS": - await connection.write( - 0x000C, bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"]]) - ) - - elif action == "SET_SETTINGS": - - def encode(settings: dict): - mask_24_hours = 0b00000001 - MASK_BUTTON_TONE_OFF = 0b00000010 - MASK_LIGHT_OFF = 0b00000100 - POWER_SAVING_MODE = 0b00010000 - - arr = bytearray(12) - arr[0] = CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"] - if settings.time_format == "24h": - arr[1] = arr[1] | mask_24_hours - if not settings.button_tone: - arr[1] = arr[1] | MASK_BUTTON_TONE_OFF - if not settings.auto_light: - arr[1] = arr[1] | MASK_LIGHT_OFF - if not settings.power_saving_mode: - arr[1] = arr[1] | POWER_SAVING_MODE - - if settings.light_duration == "4s": - arr[2] = 1 - if settings.date_format == "DD:MM": - arr[4] = 1 - - language_index = { - "English": 0, - "Spanish": 1, - "French": 2, - "German": 3, - "Italian": 4, - "Russian": 5, - } - arr[5] = language_index.get(settings.language, 0) - - return arr - - encoded_settings = encode(settings) - await connection.write( - 0x000E, to_compact_string(to_hex_string(encoded_settings)) - ) - - elif action == "GET_TIME_ADJUSTMENT": - await connection.write( - 0x000C, - to_compact_string( - to_hex_string(bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_BLE"]])) - ), - ) - - elif action == "SET_TIME_ADJUSTMENT": - value = json.loads(message).get("value") - - def encode_time_adjustment(time_adjustment): - raw_string = settings.CasioIsAutoTimeOriginalValue - "0x11 0F 0F 0F 06 00 00 00 00 00 01 00 80 30 30" - int_array = to_int_array(raw_string) - int_array[12] = 0x80 if time_adjustment == "True" else 0x00 - return bytes(int_array) - - encoded_time_adj = encode_time_adjustment(value) - - write_cmd = to_compact_string(to_hex_string(encoded_time_adj)) - await connection.write(0x000E, write_cmd) - - elif action == "GET_TIMER": - connection.write(0x000C, bytearray([CHARACTERISTICS["CASIO_TIMER"]])) - - elif action == "SET_TIMER": - seconds = json.loads(message).get("value") - - def encode(seconds_str): - in_seconds = int(seconds_str) - hours = in_seconds // 3600 - minutes_and_seconds = in_seconds % 3600 - minutes = minutes_and_seconds // 60 - seconds = minutes_and_seconds % 60 - - arr = bytearray(7) - arr[0] = 0x18 - arr[1] = hours - arr[2] = minutes - arr[3] = seconds - return arr - - seconds_as_byte_arr = encode(seconds) - seconds_as_compact_str = to_compact_string(to_hex_string(seconds_as_byte_arr)) - await connection.write(0x000E, seconds_as_compact_str) - - elif action == "SET_TIME": - date_time_ms = int(json.loads(message).get("value")) - logger.debug("date_time_ms: {}".format(date_time_ms)) - date_time = datetime.datetime.fromtimestamp(date_time_ms / 1000.0) - time_data = TimeEncoder.prepare_current_time(date_time) - time_command = to_hex_string( - bytearray([CHARACTERISTICS["CASIO_CURRENT_TIME"]]) + time_data - ) - await connection.write(0xE, to_compact_string(time_command)) - - else: - print("callWriter: Unhandled command", action) - - -class TimeEncoder: - def prepare_current_time(date: datetime.datetime): - arr = bytearray(10) - year = date.year - arr[0] = year >> 0 & 0xFF - arr[1] = year >> 8 & 0xFF - arr[2] = date.month - arr[3] = date.day - arr[4] = date.hour - arr[5] = date.minute - arr[6] = date.second - arr[7] = date.weekday() - arr[8] = 0 - arr[9] = 1 - return arr diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index 353d751..2bf8394 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -3,8 +3,6 @@ from casio_constants import CasioConstants import message_dispatcher from utils import to_casio_cmd -from data_watcher import data_watcher -from casio_watch import to_json, callWriter from logger import logger diff --git a/src/gshocktimeserver/device_queue.py b/src/gshocktimeserver/device_queue.py deleted file mode 100644 index 4f8c4b5..0000000 --- a/src/gshocktimeserver/device_queue.py +++ /dev/null @@ -1,15 +0,0 @@ -import queue - - -class DeviceQueue: - def __init__(self): - self.q = queue.Queue() - - def get(self): - return self.q.get(block=True, timeout=None) - - def put(self, item): - self.q.put(item) - - -device_queue = DeviceQueue() diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 8796c0c..fc7d1bb 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -4,6 +4,8 @@ import time from data_watcher import data_watcher +from iolib.dst_watch_state_io import DtsState +from iolib.button_pressed_io import WatchButton import message_dispatcher from utils import ( to_ascii_string, @@ -12,8 +14,6 @@ to_compact_string, clean_str, ) -from result_queue import result_queue, KeyedResult -from casio_watch import WatchButton, DtsState from alarms import alarms_inst from event import Event from watch_info import watch_info diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 2256422..6b21893 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -5,7 +5,6 @@ from connection import Connection from gshock_api import GshockAPI -from casio_watch import WatchButton from scanner import scanner from configurator import conf from logger import logger diff --git a/src/gshocktimeserver/iolib/dst_watch_state_io.py b/src/gshocktimeserver/iolib/dst_watch_state_io.py index f2937f4..cb2aa27 100644 --- a/src/gshocktimeserver/iolib/dst_watch_state_io.py +++ b/src/gshocktimeserver/iolib/dst_watch_state_io.py @@ -1,6 +1,6 @@ import asyncio +from enum import IntEnum from typing import Any -from casio_watch import DtsState from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -8,6 +8,28 @@ CHARACTERISTICS = CasioConstants.CHARACTERISTICS +class DtsState(IntEnum): + ZERO = 0 + TWO = 2 + FOUR = 4 + + +# class ReminderMasks: +# YEARLY_MASK = 0b00001000 +# MONTHLY_MASK = 0b00010000 +# WEEKLY_MASK = 0b00000100 + +# SUNDAY_MASK = 0b00000001 +# MONDAY_MASK = 0b00000010 +# TUESDAY_MASK = 0b00000100 +# WEDNESDAY_MASK = 0b00001000 +# THURSDAY_MASK = 0b00010000 +# FRIDAY_MASK = 0b00100000 +# SATURDAY_MASK = 0b01000000 + +# ENABLED_MASK = 0b00000001 + + class DstWatchStateIO: result: asyncio.Future[Any] = None connection = None diff --git a/src/gshocktimeserver/iolib/timer_io.py b/src/gshocktimeserver/iolib/timer_io.py index bc33343..74c060d 100644 --- a/src/gshocktimeserver/iolib/timer_io.py +++ b/src/gshocktimeserver/iolib/timer_io.py @@ -1,4 +1,5 @@ import asyncio +import json from typing import Any from utils import to_compact_string, to_hex_string @@ -43,7 +44,8 @@ def encode(seconds_str): arr[3] = seconds return arr - seconds_as_byte_arr = encode(data) + data_obj = json.loads(data) + seconds_as_byte_arr = encode(data_obj.get("value")) seconds_as_compact_str = to_compact_string(to_hex_string(seconds_as_byte_arr)) await TimerIO.connection.write(0x000E, seconds_as_compact_str) diff --git a/src/gshocktimeserver/iolib/world_cities_io.py b/src/gshocktimeserver/iolib/world_cities_io.py index 8c53167..bdfe3dc 100644 --- a/src/gshocktimeserver/iolib/world_cities_io.py +++ b/src/gshocktimeserver/iolib/world_cities_io.py @@ -1,8 +1,5 @@ import asyncio from typing import Any -from casio_watch import DtsState - -from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants CHARACTERISTICS = CasioConstants.CHARACTERISTICS From 47bc397e3a73baa2ccd7152098e23022f6d618a2 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 21 Jan 2024 13:49:48 -0500 Subject: [PATCH 082/123] Completed optimization --- src/gshocktimeserver/gshock_server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 6b21893..387ff47 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -5,6 +5,7 @@ from connection import Connection from gshock_api import GshockAPI +from iolib.button_pressed_io import WatchButton from scanner import scanner from configurator import conf from logger import logger From c8059061cc03e2b3090643ec60c882436af72117 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 22 Jan 2024 08:52:19 -0500 Subject: [PATCH 083/123] Fixed logging --- src/gshocktimeserver/api_tests.py | 39 +++++++++++-------- src/gshocktimeserver/connection.py | 2 +- src/gshocktimeserver/gshock_server.py | 14 +++---- src/gshocktimeserver/iolib/app_info_io.py | 5 ++- .../iolib/button_pressed_io.py | 8 ++-- .../iolib/dst_for_world_cities_io.py | 5 ++- .../iolib/dst_watch_state_io.py | 22 ++--------- src/gshocktimeserver/iolib/error_io.py | 2 +- src/gshocktimeserver/iolib/events_io.py | 6 +-- src/gshocktimeserver/iolib/settings_io.py | 9 +++-- .../iolib/time_adjustement_io.py | 11 +++--- src/gshocktimeserver/iolib/time_io.py | 3 +- src/gshocktimeserver/iolib/timer_io.py | 7 ++-- src/gshocktimeserver/iolib/unknown_io.py | 2 +- .../iolib/watch_condition_io.py | 9 +++-- src/gshocktimeserver/iolib/world_cities_io.py | 5 ++- src/gshocktimeserver/logger.py | 5 ++- src/gshocktimeserver/message_dispatcher.py | 5 ++- 18 files changed, 80 insertions(+), 79 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index 8659c73..bd76681 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -12,17 +12,23 @@ def prompt(): - print("========================================================================") - print("Press and hold lower-left button on your watch for 3 seconds to start...") - print("========================================================================") - print("") + logger.info( + "========================================================================" + ) + logger.info( + "Press and hold lower-left button on your watch for 3 seconds to start..." + ) + logger.info( + "========================================================================" + ) + logger.info("") async def run_api_tests(): prompt() device = await scanner.scan() - logger.debug("Found: {}".format(device)) + logger.info("Found: {}".format(device)) connection = Connection(device) await connection.connect() @@ -30,10 +36,10 @@ async def run_api_tests(): api = GshockAPI(connection) app_info = await api.get_app_info() - print("app info: {}".format(app_info)) + logger.info("app info: {}".format(app_info)) pressed_button = await api.get_pressed_button() - print("pressed button: {}".format(pressed_button)) + logger.info("pressed button: {}".format(pressed_button)) watch_name = await api.get_watch_name() logger.info("got watch name: {}".format(watch_name)) @@ -41,7 +47,7 @@ async def run_api_tests(): await api.set_time() alarms = await api.get_alarms() - logger.debug("alarms: {}".format(alarms)) + logger.info("alarms: {}".format(alarms)) alarms[3]["enabled"] = True alarms[3]["hour"] = 7 @@ -50,19 +56,19 @@ async def run_api_tests(): await api.set_alarms(alarms) seconds = await api.get_timer() - logger.debug("timer: {} seconds".format(seconds)) + logger.info("timer: {} seconds".format(seconds)) await api.set_timer(seconds + 10) time_adjstment = await api.get_time_adjustment() - print("time_adjstment: {}".format(time_adjstment)) + logger.info("time_adjstment: {}".format(time_adjstment)) await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) condition = await api.get_watch_condition() - print(f"condition: {condition.__dict__}") + logger.info(f"condition: {condition}") settings_local = await api.get_basic_settings() - print("settings: {}".format(settings_local)) + logger.info("settings: {}".format(settings_local)) settings_local["button_tone"] = True settings_local["language"] = "Russian" @@ -71,7 +77,7 @@ async def run_api_tests(): await api.set_settings(settings_local) settings_local = await api.get_basic_settings() - print("After update: settings: {}".format(settings_local)) + logger.info("After update: settings: {}".format(settings_local)) # Create a single event tz = pytz.timezone("America/Toronto") @@ -95,10 +101,11 @@ async def run_api_tests(): + """}}""" ) Event().create_event(json.loads(event_json_str)) + logger.info("Created event: {}".format(event_json_str)) reminders = await api.get_reminders() for reminder in reminders: - logger.debug("reminder: {}".format(reminder.__str__())) + logger.info("reminder: {}".format(reminder.__str__())) reminders[3]["title"] = "Test Event" @@ -107,7 +114,7 @@ async def run_api_tests(): input("Hit any key to disconnect") await connection.disconnect() - logger.debug("--- END OF TESTS ---") + logger.info("--- END OF TESTS ---") def convert_time_string_to_epoch(time_string): @@ -120,5 +127,5 @@ def convert_time_string_to_epoch(time_string): return timestamp except ValueError: - print("Invalid time format. Please use the format HH:MM:SS.") + logger.info("Invalid time format. Please use the format HH:MM:SS.") return None diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index 2bf8394..8ec81cf 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -41,7 +41,7 @@ async def write(self, handle, data): logger.debug("write failed with exception: {}".format(e)) async def request(self, request): - print("write: {}".format(request)) + logger.info("write: {}".format(request)) await self.write(0xC, request) def init_handles_map(self): diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 387ff47..9dacda7 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -24,18 +24,18 @@ async def main(argv): def prompt(): - print( + logger.info( "==============================================================================================" ) - print("Short-press lower-right button on your watch to set time...") - print("") - print( + logger.info("Short-press lower-right button on your watch to set time...") + logger.info("") + logger.info( "If Auto-time set on watch, the watch will connect and run automatically up to 4 times per day." ) - print( + logger.info( "==============================================================================================" ) - print("") + logger.info("") async def run_time_server(): @@ -65,7 +65,7 @@ async def run_time_server(): await api.get_app_info() await api.set_time() - print(f"Time set at {datetime.now()} on {watch_info.name}") + logger.info(f"Time set at {datetime.now()} on {watch_info.name}") # You can add mail notification here if you run your mail server. # send_mail_notification(args.mailto) diff --git a/src/gshocktimeserver/iolib/app_info_io.py b/src/gshocktimeserver/iolib/app_info_io.py index 962dfa1..2ecc1ba 100644 --- a/src/gshocktimeserver/iolib/app_info_io.py +++ b/src/gshocktimeserver/iolib/app_info_io.py @@ -1,5 +1,6 @@ import asyncio from typing import Any +from logger import logger from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -13,7 +14,7 @@ class AppInfoIO: @staticmethod async def request(connection): - print(f"AppInfoIO request") + logger.info(f"AppInfoIO request") AppInfoIO.connection = connection await connection.request("22") @@ -27,7 +28,7 @@ async def send_to_watch(connection): @staticmethod def on_received(data): - print(f"AppInfoIO onReceived") + logger.info(f"AppInfoIO onReceived") def set_app_info(data: str): # App info: diff --git a/src/gshocktimeserver/iolib/button_pressed_io.py b/src/gshocktimeserver/iolib/button_pressed_io.py index e0442b1..b86abc6 100644 --- a/src/gshocktimeserver/iolib/button_pressed_io.py +++ b/src/gshocktimeserver/iolib/button_pressed_io.py @@ -1,7 +1,7 @@ import asyncio from enum import IntEnum from typing import Any - +from logger import logger from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants @@ -23,7 +23,7 @@ class ButtonPressedIO: @staticmethod async def request(connection): - print(f"ButtonPressedIO request") + logger.info(f"ButtonPressedIO request") ButtonPressedIO.connection = connection await connection.request("10") @@ -37,13 +37,13 @@ async def send_to_watch(connection): @staticmethod async def send_to_watch_set(data): - print(f"TimerIO sendToWatchSet: {data}") + logger.info(f"TimerIO sendToWatchSet: {data}") await ButtonPressedIO.connection.write(0x000E, data) @staticmethod def on_received(data): - print(f"ButtonPressedIO onReceived") + logger.info(f"ButtonPressedIO onReceived") def button_pressed_callback(data): """ diff --git a/src/gshocktimeserver/iolib/dst_for_world_cities_io.py b/src/gshocktimeserver/iolib/dst_for_world_cities_io.py index 66b45ef..5e75c1b 100644 --- a/src/gshocktimeserver/iolib/dst_for_world_cities_io.py +++ b/src/gshocktimeserver/iolib/dst_for_world_cities_io.py @@ -1,5 +1,6 @@ import asyncio from typing import Any +from logger import logger from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -13,7 +14,7 @@ class DstForWorldCitiesIO: @staticmethod async def request(connection, city_number: int): - print(f"DstForWorldCitiesIO request") + logger.info(f"DstForWorldCitiesIO request") DstForWorldCitiesIO.connection = connection key = "1e0{}".format(city_number) await connection.request(key) @@ -28,5 +29,5 @@ async def send_to_watch(connection): @staticmethod def on_received(data): - print(f"DstForWorldCitiesIO onReceived") + logger.info(f"DstForWorldCitiesIO onReceived") DstForWorldCitiesIO.result.set_result(data) diff --git a/src/gshocktimeserver/iolib/dst_watch_state_io.py b/src/gshocktimeserver/iolib/dst_watch_state_io.py index cb2aa27..aa1cea0 100644 --- a/src/gshocktimeserver/iolib/dst_watch_state_io.py +++ b/src/gshocktimeserver/iolib/dst_watch_state_io.py @@ -1,7 +1,7 @@ import asyncio from enum import IntEnum from typing import Any - +from logger import logger from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -14,29 +14,13 @@ class DtsState(IntEnum): FOUR = 4 -# class ReminderMasks: -# YEARLY_MASK = 0b00001000 -# MONTHLY_MASK = 0b00010000 -# WEEKLY_MASK = 0b00000100 - -# SUNDAY_MASK = 0b00000001 -# MONDAY_MASK = 0b00000010 -# TUESDAY_MASK = 0b00000100 -# WEDNESDAY_MASK = 0b00001000 -# THURSDAY_MASK = 0b00010000 -# FRIDAY_MASK = 0b00100000 -# SATURDAY_MASK = 0b01000000 - -# ENABLED_MASK = 0b00000001 - - class DstWatchStateIO: result: asyncio.Future[Any] = None connection = None @staticmethod async def request(connection, state: DtsState): - print(f"DstWatchStateIO request") + logger.info(f"DstWatchStateIO request") DstWatchStateIO.connection = connection key = f"1d0{state.value}" await connection.request(key) @@ -51,5 +35,5 @@ async def send_to_watch(connection): @staticmethod def on_received(data): - print(f"DstWatchStateIO onReceived") + logger.info(f"DstWatchStateIO onReceived") DstWatchStateIO.result.set_result(data) diff --git a/src/gshocktimeserver/iolib/error_io.py b/src/gshocktimeserver/iolib/error_io.py index 3f4fe33..0b54e8b 100644 --- a/src/gshocktimeserver/iolib/error_io.py +++ b/src/gshocktimeserver/iolib/error_io.py @@ -1,4 +1,4 @@ class ErrorIO: @staticmethod async def on_received(message): - print(f"ErrorIO onReceived: {message}") + logger.info(f"ErrorIO onReceived: {message}") diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshocktimeserver/iolib/events_io.py index 1a4910a..4cc553a 100644 --- a/src/gshocktimeserver/iolib/events_io.py +++ b/src/gshocktimeserver/iolib/events_io.py @@ -40,7 +40,7 @@ class EventsIO: @staticmethod async def request(connection, event_number): - print(f"EventsIO request") + logger.info(f"EventsIO request") EventsIO.connection = connection await connection.request("30{}".format(event_number)) # reminder title @@ -52,7 +52,7 @@ async def request(connection, event_number): @staticmethod async def send_to_watch_set(message): - print(f"EventsIO sendToWatchSet: {message}") + logger.info(f"EventsIO sendToWatchSet: {message}") def reminder_title_from_json(reminder_json): title_str = reminder_json.get("title") @@ -341,7 +341,7 @@ def int_to_month_str(month_int): reminder_json = json.loads(reminder_time_to_json(data[2:])) reminder_json.update(EventsIO.title) - print(reminder_json) + logger.info(reminder_json) EventsIO.result.set_result(reminder_json) @staticmethod diff --git a/src/gshocktimeserver/iolib/settings_io.py b/src/gshocktimeserver/iolib/settings_io.py index be46474..2c943e0 100644 --- a/src/gshocktimeserver/iolib/settings_io.py +++ b/src/gshocktimeserver/iolib/settings_io.py @@ -4,6 +4,7 @@ from settings import settings from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants +from logger import logger CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -14,7 +15,7 @@ class SettingsIO: @staticmethod async def request(connection): - print(f"TimerIO request") + logger.info(f"TimerIO request") SettingsIO.connection = connection await connection.request("13") @@ -24,14 +25,14 @@ async def request(connection): @staticmethod def send_to_watch(message): - print(f"SettingsIO sendToWatch: {message}") + logger.info(f"SettingsIO sendToWatch: {message}") SettingsIO.connection.write( 0x000C, bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"]]) ) @staticmethod async def send_to_watch_set(message): - print(f"SettingsIO sendToWatchSet: {message}") + logger.info(f"SettingsIO sendToWatchSet: {message}") def encode(settings): mask_24_hours = 0b00000001 @@ -86,7 +87,7 @@ def __getattr__(self, attr): @staticmethod def on_received(message): - print(f"SettingsIO onReceived: {message}") + logger.info(f"SettingsIO onReceived: {message}") def create_json_settings(setting_string): mask_24_hours = 0b00000001 diff --git a/src/gshocktimeserver/iolib/time_adjustement_io.py b/src/gshocktimeserver/iolib/time_adjustement_io.py index 36b6870..a6c626b 100644 --- a/src/gshocktimeserver/iolib/time_adjustement_io.py +++ b/src/gshocktimeserver/iolib/time_adjustement_io.py @@ -6,6 +6,7 @@ from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants from iolib.error_io import ErrorIO +from logger import logger CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -18,7 +19,7 @@ class TimeAdjustmentIO: @staticmethod async def request(connection): - print(f"TimerIO request") + logger.info(f"TimerIO request") TimeAdjustmentIO.connection = connection await connection.request("11") @@ -28,14 +29,14 @@ async def request(connection): @staticmethod def send_to_watch(message): - print(f"TimeAdjustmentIO sendToWatch: {message}") + logger.info(f"TimeAdjustmentIO sendToWatch: {message}") TimeAdjustmentIO.connection.write( 0x000C, bytearray([CHARACTERISTICS["TIME_ADJUSTMENT"]]) ) @staticmethod async def send_to_watch_set(message): - print(f"TimeAdjustmentIO sendToWatchSet: {message}") + logger.info(f"TimeAdjustmentIO sendToWatchSet: {message}") if TimeAdjustmentIO.original_value == None: logging.error("Error: Must call get before set") @@ -59,7 +60,7 @@ def encode_time_adjustment(time_adjustment, minutes_after_hour): @staticmethod def on_received(message): - print(f"TimeAdjustmentIO onReceived: {message}") + logger.info(f"TimeAdjustmentIO onReceived: {message}") TimeAdjustmentIO.original_value = to_hex_string( message ) # save original message @@ -87,4 +88,4 @@ def get_minutes_after_hour(data) -> int: @staticmethod async def on_received_set(message): - print(f"TimeAdjustmentIO onReceivedSet: {message}") + logger.info(f"TimeAdjustmentIO onReceivedSet: {message}") diff --git a/src/gshocktimeserver/iolib/time_io.py b/src/gshocktimeserver/iolib/time_io.py index bfe327a..c9590ee 100644 --- a/src/gshocktimeserver/iolib/time_io.py +++ b/src/gshocktimeserver/iolib/time_io.py @@ -3,6 +3,7 @@ import json import time from typing import Any +from logger import logger from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -30,7 +31,7 @@ async def request(connection, current_time): @staticmethod async def send_to_watch_set(message): date_time_ms = int(json.loads(message).get("value")) - print("date_time_ms: {}".format(date_time_ms)) + logger.info("date_time_ms: {}".format(date_time_ms)) date_time = datetime.datetime.fromtimestamp(date_time_ms / 1000.0) time_data = TimeEncoder.prepare_current_time(date_time) time_command = to_hex_string( diff --git a/src/gshocktimeserver/iolib/timer_io.py b/src/gshocktimeserver/iolib/timer_io.py index 74c060d..3bfb814 100644 --- a/src/gshocktimeserver/iolib/timer_io.py +++ b/src/gshocktimeserver/iolib/timer_io.py @@ -1,6 +1,7 @@ import asyncio import json from typing import Any +from logger import logger from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -14,7 +15,7 @@ class TimerIO: @staticmethod async def request(connection): - print(f"TimerIO request") + logger.info(f"TimerIO request") TimerIO.connection = connection await connection.request("18") @@ -28,7 +29,7 @@ async def send_to_watch(connection): @staticmethod async def send_to_watch_set(data): - print(f"TimerIO sendToWatchSet: {data}") + logger.info(f"TimerIO sendToWatchSet: {data}") def encode(seconds_str): in_seconds = int(seconds_str) @@ -51,7 +52,7 @@ def encode(seconds_str): @staticmethod def on_received(data): - print(f"TimerIO onReceived") + logger.info(f"TimerIO onReceived") def decode_value(data: str) -> str: timer_int_array = data diff --git a/src/gshocktimeserver/iolib/unknown_io.py b/src/gshocktimeserver/iolib/unknown_io.py index f7d73ce..fa0e599 100644 --- a/src/gshocktimeserver/iolib/unknown_io.py +++ b/src/gshocktimeserver/iolib/unknown_io.py @@ -1,4 +1,4 @@ class UnknownIO: @staticmethod def on_received(message): - print(f"UnknownIO onReceived: {message}") + logger.info(f"UnknownIO onReceived: {message}") diff --git a/src/gshocktimeserver/iolib/watch_condition_io.py b/src/gshocktimeserver/iolib/watch_condition_io.py index d0eabcb..efa84d9 100644 --- a/src/gshocktimeserver/iolib/watch_condition_io.py +++ b/src/gshocktimeserver/iolib/watch_condition_io.py @@ -2,6 +2,7 @@ from typing import Any from watch_info import WatchInfo from casio_constants import CasioConstants +from logger import logger CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -17,7 +18,7 @@ def __init__(self, battery_level_percent: int, temperature: int): @staticmethod async def request(connection): - print(f"WatchConditionIO request") + logger.info(f"WatchConditionIO request") WatchConditionIO.connection = connection await connection.request("28") @@ -31,7 +32,7 @@ async def send_to_watch(connection): @staticmethod def on_received(data): - print(f"WatchConditionIO onReceived") + logger.info(f"WatchConditionIO onReceived") def decode_value(data: str) -> WatchConditionIO.WatchConditionValue: int_arr = list(map(int, data)) @@ -39,7 +40,7 @@ def decode_value(data: str) -> WatchConditionIO.WatchConditionValue: if len(bytes_data) >= 2: # Battery level between 15 and 20 for B2100 and between 12 and 19 for B5600. Scale accordingly to % - print(f"battery level row value: {int(bytes_data[0])}") + logger.info(f"battery level row value: {int(bytes_data[0])}") battery_level_lower_limit = (15 + 9) / 2 battery_level_upper_limit = 19.5 @@ -57,4 +58,4 @@ def decode_value(data: str) -> WatchConditionIO.WatchConditionValue: return WatchConditionIO.WatchConditionValue(0, 0) - WatchConditionIO.result.set_result(decode_value(data)) + WatchConditionIO.result.set_result(decode_value(data).__dict__) diff --git a/src/gshocktimeserver/iolib/world_cities_io.py b/src/gshocktimeserver/iolib/world_cities_io.py index bdfe3dc..2a3283d 100644 --- a/src/gshocktimeserver/iolib/world_cities_io.py +++ b/src/gshocktimeserver/iolib/world_cities_io.py @@ -1,6 +1,7 @@ import asyncio from typing import Any from casio_constants import CasioConstants +from logger import logger CHARACTERISTICS = CasioConstants.CHARACTERISTICS @@ -11,7 +12,7 @@ class WorldCitiesIO: @staticmethod async def request(connection, cityNumber: int): - print(f"DstWatchStateIO request") + logger.info(f"DstWatchStateIO request") WorldCitiesIO.connection = connection key = "1f0{}".format(cityNumber) @@ -27,5 +28,5 @@ async def send_to_watch(connection): @staticmethod def on_received(data): - print(f"WorldCitiesIO onReceived") + logger.info(f"WorldCitiesIO onReceived") WorldCitiesIO.result.set_result(data) diff --git a/src/gshocktimeserver/logger.py b/src/gshocktimeserver/logger.py index 73dd99c..92527ce 100644 --- a/src/gshocktimeserver/logger.py +++ b/src/gshocktimeserver/logger.py @@ -8,17 +8,18 @@ class Logger: log_level = args.get().log_level logging.basicConfig( - # encoding='utf-8', (for pythonn 3.9 and higher) level=logging.INFO, # log_level, handlers=[logging.StreamHandler()], format="%(asctime)-15s %(name)-8s %(levelname)s: %(message)s", ) + logging.basicConfig(level=logging.INFO) + def error(self, *args): _logger.error(args) def info(self, *args): - _logger.debug(args) + _logger.info(args) def debug(self, *args): _logger.debug(args) diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index e1aec51..ba966b3 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -3,6 +3,7 @@ import json from typing import Any import connection +from logger import logger from casio_constants import CasioConstants from iolib.app_info_io import AppInfoIO from iolib.dst_watch_state_io import DstWatchStateIO @@ -67,9 +68,9 @@ async def send_to_watch(message): def on_received(data): key = data[0] if key not in MessageDispatcher.data_received_messages: - print(f"Unknown key: {key}") + logger.info(f"Unknown key: {key}") else: - print(f"Found key: {MessageDispatcher.data_received_messages[key]}") + logger.info(f"Found key: {MessageDispatcher.data_received_messages[key]}") MessageDispatcher.data_received_messages[key](data) From 3c28f4ed4aa051f49214aecc68b89168b94b067c Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 22 Jan 2024 08:54:29 -0500 Subject: [PATCH 084/123] Fixed logging --- config.ini | 4 ++-- src/gshocktimeserver/gshock_server.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config.ini b/config.ini index e4cd7c7..8ef9d8c 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 +device.address = CD:85:03:12:62:17 +device.name = CASIO GW-B5600 diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 9dacda7..2544ceb 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -19,8 +19,8 @@ async def main(argv): - # await run_time_server() - await run_api_tests() + await run_time_server() + # await run_api_tests() def prompt(): From 45a35664b47dfc63c4d5af1fb6f522accec237e5 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 22 Jan 2024 09:17:43 -0500 Subject: [PATCH 085/123] Optomized code --- config.ini | 4 ++-- src/gshocktimeserver/iolib/watch_condition_io.py | 6 +++--- src/gshocktimeserver/watch_info.py | 6 ++++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/config.ini b/config.ini index 8ef9d8c..e4cd7c7 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:03:12:62:17 -device.name = CASIO GW-B5600 +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/iolib/watch_condition_io.py b/src/gshocktimeserver/iolib/watch_condition_io.py index efa84d9..1eebc66 100644 --- a/src/gshocktimeserver/iolib/watch_condition_io.py +++ b/src/gshocktimeserver/iolib/watch_condition_io.py @@ -1,6 +1,6 @@ import asyncio from typing import Any -from watch_info import WatchInfo +from watch_info import watch_info from casio_constants import CasioConstants from logger import logger @@ -42,8 +42,8 @@ def decode_value(data: str) -> WatchConditionIO.WatchConditionValue: # Battery level between 15 and 20 for B2100 and between 12 and 19 for B5600. Scale accordingly to % logger.info(f"battery level row value: {int(bytes_data[0])}") - battery_level_lower_limit = (15 + 9) / 2 - battery_level_upper_limit = 19.5 + battery_level_lower_limit = watch_info.batteryLevelLowerLimit + battery_level_upper_limit = watch_info.batteryLevelUpperLimit multiplier = round( 100.0 / (battery_level_upper_limit - battery_level_lower_limit) diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index dd09600..b5a820e 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -30,6 +30,8 @@ def __init__(self): self.weekLanguageSupported = True self.worldCities: True self.temperature: True + self.batteryLevelLowerLimit: 15 + self.batteryLevelUpperLimit: 20 self.models = [ { @@ -41,6 +43,8 @@ def __init__(self): "hasReminders": True, "shortLightDuration": "2s", "longLightDuration": "4s", + "batteryLevelLowerLimit": 9, + "batteryLevelUpperLimit": 19, }, { "model": WATCH_MODEL.GST, @@ -212,6 +216,8 @@ def set_name_and_model(self, name): self.weekLanguageSupported = model_info.get("weekLanguageSupported", True) self.worldCities = model_info.get("worldCities", True) self.temperature = model_info.get("temperature", True) + self.batteryLevelLowerLimit = model_info.get("batteryLevelLowerLimit", 15) + self.batteryLevelUpperLimit = model_info.get("batteryLevelUpperLimit", 20) def set_address(self, address): self.address = address From 7893e8fe3cc6da6d5d47671f56b13663c9083fd5 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 22 Jan 2024 09:19:53 -0500 Subject: [PATCH 086/123] Optomized code --- src/gshocktimeserver/iolib/error_io.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gshocktimeserver/iolib/error_io.py b/src/gshocktimeserver/iolib/error_io.py index 0b54e8b..acbc156 100644 --- a/src/gshocktimeserver/iolib/error_io.py +++ b/src/gshocktimeserver/iolib/error_io.py @@ -1,3 +1,6 @@ +from logger import logger + + class ErrorIO: @staticmethod async def on_received(message): From cf6d6cfb242a9510d2f088cdd40fa0f99f3812cd Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 22 Jan 2024 09:20:03 -0500 Subject: [PATCH 087/123] Optomized code --- src/gshocktimeserver/iolib/unknown_io.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gshocktimeserver/iolib/unknown_io.py b/src/gshocktimeserver/iolib/unknown_io.py index fa0e599..cc49178 100644 --- a/src/gshocktimeserver/iolib/unknown_io.py +++ b/src/gshocktimeserver/iolib/unknown_io.py @@ -1,3 +1,6 @@ +from logger import logger + + class UnknownIO: @staticmethod def on_received(message): From da5ded03783123e3aa1c59d5a783168a4dab9bea Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 23 Jan 2024 14:54:25 -0500 Subject: [PATCH 088/123] WIP --- README.rst | 2 -- config.ini | 4 ++-- src/gshocktimeserver/iolib/button_pressed_io.py | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 8093bbb..60ab7e0 100644 --- a/README.rst +++ b/README.rst @@ -35,8 +35,6 @@ Install the following dependencies: pip3 install reactivex - sudo pip3 install geocoder - Troubleshooting: ================ If your watch cannot connect, and the ``--multi-watch`` parameter is not used, remove the "config.ini" file and try again. diff --git a/config.ini b/config.ini index e4cd7c7..8ef9d8c 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 +device.address = CD:85:03:12:62:17 +device.name = CASIO GW-B5600 diff --git a/src/gshocktimeserver/iolib/button_pressed_io.py b/src/gshocktimeserver/iolib/button_pressed_io.py index b86abc6..a55048c 100644 --- a/src/gshocktimeserver/iolib/button_pressed_io.py +++ b/src/gshocktimeserver/iolib/button_pressed_io.py @@ -16,7 +16,6 @@ class WatchButton(IntEnum): NO_BUTTON = 5 INVALID = 6 - class ButtonPressedIO: result: asyncio.Future[Any] = None connection = None From 934b1db4b2de50158700c146d46279c6a1de6740 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 31 Jan 2024 11:33:39 -0500 Subject: [PATCH 089/123] Cleanup --- setup.py | 38 +++++++++++++++++++--------- src/gshocktimeserver/result_queue.py | 36 -------------------------- 2 files changed, 26 insertions(+), 48 deletions(-) delete mode 100644 src/gshocktimeserver/result_queue.py diff --git a/setup.py b/setup.py index 3286c2f..4dce78c 100644 --- a/setup.py +++ b/setup.py @@ -6,16 +6,30 @@ PyScaffold helps you to put up the scaffold of your new Python project. Learn more under: https://pyscaffold.org/ """ -from setuptools import setup +from setuptools import setup, find_packages -if __name__ == "__main__": - try: - setup(use_scm_version={"version_scheme": "no-guess-dev"}) - except: # noqa - print( - "\n\nAn error occurred while building the project, " - "please ensure you have the most updated version of setuptools, " - "setuptools_scm and wheel with:\n" - " pip install -U setuptools setuptools_scm wheel\n\n" - ) - raise +setup( + name='gshock_api', + version='0.1', + use_scm_version=True, + packages=find_packages(), + install_requires=[ + 'pytz', 'bleak', 'reactivex' + ], + + author='Ivo Zivkov', + author_email='izivkov@gmail.com', + description='This library allows you to interact with your G-Shock watch from Python', + long_description='This library allows you to interact with your G-Shock watch from Python...', + url='https://github.com/izivkov/GShockTimeServer', + license='MIT', # Choose an appropriate license + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + ], +) \ No newline at end of file diff --git a/src/gshocktimeserver/result_queue.py b/src/gshocktimeserver/result_queue.py deleted file mode 100644 index f652a28..0000000 --- a/src/gshocktimeserver/result_queue.py +++ /dev/null @@ -1,36 +0,0 @@ -class KeyedResult: - def __init__(self, key, result): - self.key = key - self.result = result - - def __str__(self): - return "KeyedResult(key='{}', result={})".format(self.key, self.result) - - -class ResultQueue: - def __init__(self): - self.keyed_result_map = {} - - def enqueue(self, element): - self.keyed_result_map[element.key.upper()] = element.result - - def dequeue(self, _key): - if not self.keyed_result_map: - return None - else: - key = _key.upper() - value = self.keyed_result_map[key] - del self.keyed_result_map[key] - return value - - def is_empty(self): - return not bool(self.keyed_result_map) - - def size(self): - return len(self.keyed_result_map) - - def clear(self): - self.keyed_result_map.clear() - - -result_queue = ResultQueue() From 1cad3da37d9ff018cd1c89db111af72e61ff48eb Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Thu, 16 May 2024 23:05:40 -0400 Subject: [PATCH 090/123] WIP --- config.ini | 4 ++-- setup.py | 8 ++++---- setup.sh | 3 +++ src/{gshocktimeserver => gshock_api}/__init__.py | 4 ++-- src/{gshocktimeserver => gshock_api}/alarms.py | 0 src/{gshocktimeserver => gshock_api}/api_tests.py | 12 ++++++------ src/{gshocktimeserver => gshock_api}/args.py | 0 .../casio_constants.py | 7 +++++-- src/gshock_api/config.ini | 4 ++++ src/{gshocktimeserver => gshock_api}/configurator.py | 0 src/{gshocktimeserver => gshock_api}/connection.py | 0 src/{gshocktimeserver => gshock_api}/data_watcher.py | 0 src/{gshocktimeserver => gshock_api}/event.py | 0 src/{gshocktimeserver => gshock_api}/gshock_api.py | 0 .../gshock_server.py | 4 ++-- .../iolib/__init__.py | 0 .../iolib/alarms_io.py | 0 .../iolib/app_info_io.py | 0 .../iolib/button_pressed_io.py | 0 .../iolib/dst_for_world_cities_io.py | 0 .../iolib/dst_watch_state_io.py | 0 .../iolib/error_io.py | 0 .../iolib/events_io.py | 0 .../iolib/settings_io.py | 0 .../iolib/time_adjustement_io.py | 0 .../iolib/time_io.py | 0 .../iolib/timer_io.py | 0 .../iolib/unknown_io.py | 0 .../iolib/watch_condition_io.py | 0 .../iolib/watch_name_io.py | 0 .../iolib/world_cities_io.py | 0 src/{gshocktimeserver => gshock_api}/logger.py | 0 src/{gshocktimeserver => gshock_api}/mailsener.py | 0 .../message_dispatcher.py | 0 src/{gshocktimeserver => gshock_api}/scanner.py | 3 ++- src/{gshocktimeserver => gshock_api}/settings.py | 0 src/{gshocktimeserver => gshock_api}/utils.py | 0 src/{gshocktimeserver => gshock_api}/watch_info.py | 5 ++++- 38 files changed, 34 insertions(+), 20 deletions(-) create mode 100755 setup.sh rename src/{gshocktimeserver => gshock_api}/__init__.py (88%) rename src/{gshocktimeserver => gshock_api}/alarms.py (100%) rename src/{gshocktimeserver => gshock_api}/api_tests.py (91%) rename src/{gshocktimeserver => gshock_api}/args.py (100%) rename src/{gshocktimeserver => gshock_api}/casio_constants.py (85%) create mode 100644 src/gshock_api/config.ini rename src/{gshocktimeserver => gshock_api}/configurator.py (100%) rename src/{gshocktimeserver => gshock_api}/connection.py (100%) rename src/{gshocktimeserver => gshock_api}/data_watcher.py (100%) rename src/{gshocktimeserver => gshock_api}/event.py (100%) rename src/{gshocktimeserver => gshock_api}/gshock_api.py (100%) rename src/{gshocktimeserver => gshock_api}/gshock_server.py (97%) rename src/{gshocktimeserver => gshock_api}/iolib/__init__.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/alarms_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/app_info_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/button_pressed_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/dst_for_world_cities_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/dst_watch_state_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/error_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/events_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/settings_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/time_adjustement_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/time_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/timer_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/unknown_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/watch_condition_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/watch_name_io.py (100%) rename src/{gshocktimeserver => gshock_api}/iolib/world_cities_io.py (100%) rename src/{gshocktimeserver => gshock_api}/logger.py (100%) rename src/{gshocktimeserver => gshock_api}/mailsener.py (100%) rename src/{gshocktimeserver => gshock_api}/message_dispatcher.py (100%) rename src/{gshocktimeserver => gshock_api}/scanner.py (90%) rename src/{gshocktimeserver => gshock_api}/settings.py (100%) rename src/{gshocktimeserver => gshock_api}/utils.py (100%) rename src/{gshocktimeserver => gshock_api}/watch_info.py (98%) diff --git a/config.ini b/config.ini index 8ef9d8c..e4cd7c7 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:03:12:62:17 -device.name = CASIO GW-B5600 +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 diff --git a/setup.py b/setup.py index 4dce78c..2ea5fd4 100644 --- a/setup.py +++ b/setup.py @@ -9,12 +9,12 @@ from setuptools import setup, find_packages setup( - name='gshock_api', - version='0.1', + name='gshock-api', + version='0.9', use_scm_version=True, packages=find_packages(), install_requires=[ - 'pytz', 'bleak', 'reactivex' + 'pytz', 'bleak', 'reactivex', 'args' ], author='Ivo Zivkov', @@ -32,4 +32,4 @@ 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', ], -) \ No newline at end of file +) diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..8199263 --- /dev/null +++ b/setup.sh @@ -0,0 +1,3 @@ +rm -rf dist/ +python3 setup.py sdist bdist_wheel +twine upload dist/* diff --git a/src/gshocktimeserver/__init__.py b/src/gshock_api/__init__.py similarity index 88% rename from src/gshocktimeserver/__init__.py rename to src/gshock_api/__init__.py index 0f76b25..f55cb3e 100644 --- a/src/gshocktimeserver/__init__.py +++ b/src/gshock_api/__init__.py @@ -1,6 +1,6 @@ import sys -sys.path.append("gshocktimeserver/io") +sys.path.append("gshock_api/io") if sys.version_info[:2] >= (3, 8): # TODO: Import directly (no need for conditional) when `python_requires = >= 3.8` @@ -10,7 +10,7 @@ try: # Change here if project is renamed and does not equal the package name - dist_name = "GShockTimeServer" + dist_name = "gshock-api" __version__ = version(dist_name) except PackageNotFoundError: # pragma: no cover __version__ = "unknown" diff --git a/src/gshocktimeserver/alarms.py b/src/gshock_api/alarms.py similarity index 100% rename from src/gshocktimeserver/alarms.py rename to src/gshock_api/alarms.py diff --git a/src/gshocktimeserver/api_tests.py b/src/gshock_api/api_tests.py similarity index 91% rename from src/gshocktimeserver/api_tests.py rename to src/gshock_api/api_tests.py index bd76681..fa12209 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshock_api/api_tests.py @@ -35,14 +35,14 @@ async def run_api_tests(): api = GshockAPI(connection) - app_info = await api.get_app_info() - logger.info("app info: {}".format(app_info)) + # app_info = await api.get_app_info() + # logger.info("app info: {}".format(app_info)) - pressed_button = await api.get_pressed_button() - logger.info("pressed button: {}".format(pressed_button)) + # pressed_button = await api.get_pressed_button() + # logger.info("pressed button: {}".format(pressed_button)) - watch_name = await api.get_watch_name() - logger.info("got watch name: {}".format(watch_name)) + # watch_name = await api.get_watch_name() + # logger.info("got watch name: {}".format(watch_name)) await api.set_time() diff --git a/src/gshocktimeserver/args.py b/src/gshock_api/args.py similarity index 100% rename from src/gshocktimeserver/args.py rename to src/gshock_api/args.py diff --git a/src/gshocktimeserver/casio_constants.py b/src/gshock_api/casio_constants.py similarity index 85% rename from src/gshocktimeserver/casio_constants.py rename to src/gshock_api/casio_constants.py index a094f16..3f0fb0a 100644 --- a/src/gshocktimeserver/casio_constants.py +++ b/src/gshock_api/casio_constants.py @@ -3,9 +3,12 @@ class CasioConstants: CASIO_APPEARANCE = "00002a01-0000-1000-8000-00805f9b34fb" TX_POWER_LEVEL_CHARACTERISTIC_UUID = "00002a07-0000-1000-8000-00805f9b34fb" CASIO_READ_REQUEST_FOR_ALL_FEATURES_CHARACTERISTIC_UUID = ( - "26eb002c-b012-49a8-b1f8-394fb2032b0f" + # "26eb002c-b012-49a8-b1f8-394fb2032b0f" + "00002a2b-0000-1000-8000-00805f9b34fb" ) - CASIO_ALL_FEATURES_CHARACTERISTIC_UUID = "26eb002d-b012-49a8-b1f8-394fb2032b0f" + # CASIO_ALL_FEATURES_CHARACTERISTIC_UUID = "26eb002d-b012-49a8-b1f8-394fb2032b0f" + CASIO_ALL_FEATURES_CHARACTERISTIC_UUID = "00002a0f-0000-1000-8000-00805f9b34fb" + CASIO_DATA_REQUEST_SP_CHARACTERISTIC_UUID = "26eb0023-b012-49a8-b1f8-394fb2032b0f" CASIO_CONVOY_CHARACTERISTIC_UUID = "26eb0024-b012-49a8-b1f8-394fb2032b0f" SERIAL_NUMBER_STRING = "00002a25-0000-1000-8000-00805f9b34fb" diff --git a/src/gshock_api/config.ini b/src/gshock_api/config.ini new file mode 100644 index 0000000..6b2c56b --- /dev/null +++ b/src/gshock_api/config.ini @@ -0,0 +1,4 @@ +[main] +device.address = D0:F0:D9:6B:99:10 +device.name = CASIO GB-5600B + diff --git a/src/gshocktimeserver/configurator.py b/src/gshock_api/configurator.py similarity index 100% rename from src/gshocktimeserver/configurator.py rename to src/gshock_api/configurator.py diff --git a/src/gshocktimeserver/connection.py b/src/gshock_api/connection.py similarity index 100% rename from src/gshocktimeserver/connection.py rename to src/gshock_api/connection.py diff --git a/src/gshocktimeserver/data_watcher.py b/src/gshock_api/data_watcher.py similarity index 100% rename from src/gshocktimeserver/data_watcher.py rename to src/gshock_api/data_watcher.py diff --git a/src/gshocktimeserver/event.py b/src/gshock_api/event.py similarity index 100% rename from src/gshocktimeserver/event.py rename to src/gshock_api/event.py diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshock_api/gshock_api.py similarity index 100% rename from src/gshocktimeserver/gshock_api.py rename to src/gshock_api/gshock_api.py diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshock_api/gshock_server.py similarity index 97% rename from src/gshocktimeserver/gshock_server.py rename to src/gshock_api/gshock_server.py index 2544ceb..9dacda7 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshock_api/gshock_server.py @@ -19,8 +19,8 @@ async def main(argv): - await run_time_server() - # await run_api_tests() + # await run_time_server() + await run_api_tests() def prompt(): diff --git a/src/gshocktimeserver/iolib/__init__.py b/src/gshock_api/iolib/__init__.py similarity index 100% rename from src/gshocktimeserver/iolib/__init__.py rename to src/gshock_api/iolib/__init__.py diff --git a/src/gshocktimeserver/iolib/alarms_io.py b/src/gshock_api/iolib/alarms_io.py similarity index 100% rename from src/gshocktimeserver/iolib/alarms_io.py rename to src/gshock_api/iolib/alarms_io.py diff --git a/src/gshocktimeserver/iolib/app_info_io.py b/src/gshock_api/iolib/app_info_io.py similarity index 100% rename from src/gshocktimeserver/iolib/app_info_io.py rename to src/gshock_api/iolib/app_info_io.py diff --git a/src/gshocktimeserver/iolib/button_pressed_io.py b/src/gshock_api/iolib/button_pressed_io.py similarity index 100% rename from src/gshocktimeserver/iolib/button_pressed_io.py rename to src/gshock_api/iolib/button_pressed_io.py diff --git a/src/gshocktimeserver/iolib/dst_for_world_cities_io.py b/src/gshock_api/iolib/dst_for_world_cities_io.py similarity index 100% rename from src/gshocktimeserver/iolib/dst_for_world_cities_io.py rename to src/gshock_api/iolib/dst_for_world_cities_io.py diff --git a/src/gshocktimeserver/iolib/dst_watch_state_io.py b/src/gshock_api/iolib/dst_watch_state_io.py similarity index 100% rename from src/gshocktimeserver/iolib/dst_watch_state_io.py rename to src/gshock_api/iolib/dst_watch_state_io.py diff --git a/src/gshocktimeserver/iolib/error_io.py b/src/gshock_api/iolib/error_io.py similarity index 100% rename from src/gshocktimeserver/iolib/error_io.py rename to src/gshock_api/iolib/error_io.py diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshock_api/iolib/events_io.py similarity index 100% rename from src/gshocktimeserver/iolib/events_io.py rename to src/gshock_api/iolib/events_io.py diff --git a/src/gshocktimeserver/iolib/settings_io.py b/src/gshock_api/iolib/settings_io.py similarity index 100% rename from src/gshocktimeserver/iolib/settings_io.py rename to src/gshock_api/iolib/settings_io.py diff --git a/src/gshocktimeserver/iolib/time_adjustement_io.py b/src/gshock_api/iolib/time_adjustement_io.py similarity index 100% rename from src/gshocktimeserver/iolib/time_adjustement_io.py rename to src/gshock_api/iolib/time_adjustement_io.py diff --git a/src/gshocktimeserver/iolib/time_io.py b/src/gshock_api/iolib/time_io.py similarity index 100% rename from src/gshocktimeserver/iolib/time_io.py rename to src/gshock_api/iolib/time_io.py diff --git a/src/gshocktimeserver/iolib/timer_io.py b/src/gshock_api/iolib/timer_io.py similarity index 100% rename from src/gshocktimeserver/iolib/timer_io.py rename to src/gshock_api/iolib/timer_io.py diff --git a/src/gshocktimeserver/iolib/unknown_io.py b/src/gshock_api/iolib/unknown_io.py similarity index 100% rename from src/gshocktimeserver/iolib/unknown_io.py rename to src/gshock_api/iolib/unknown_io.py diff --git a/src/gshocktimeserver/iolib/watch_condition_io.py b/src/gshock_api/iolib/watch_condition_io.py similarity index 100% rename from src/gshocktimeserver/iolib/watch_condition_io.py rename to src/gshock_api/iolib/watch_condition_io.py diff --git a/src/gshocktimeserver/iolib/watch_name_io.py b/src/gshock_api/iolib/watch_name_io.py similarity index 100% rename from src/gshocktimeserver/iolib/watch_name_io.py rename to src/gshock_api/iolib/watch_name_io.py diff --git a/src/gshocktimeserver/iolib/world_cities_io.py b/src/gshock_api/iolib/world_cities_io.py similarity index 100% rename from src/gshocktimeserver/iolib/world_cities_io.py rename to src/gshock_api/iolib/world_cities_io.py diff --git a/src/gshocktimeserver/logger.py b/src/gshock_api/logger.py similarity index 100% rename from src/gshocktimeserver/logger.py rename to src/gshock_api/logger.py diff --git a/src/gshocktimeserver/mailsener.py b/src/gshock_api/mailsener.py similarity index 100% rename from src/gshocktimeserver/mailsener.py rename to src/gshock_api/mailsener.py diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshock_api/message_dispatcher.py similarity index 100% rename from src/gshocktimeserver/message_dispatcher.py rename to src/gshock_api/message_dispatcher.py diff --git a/src/gshocktimeserver/scanner.py b/src/gshock_api/scanner.py similarity index 90% rename from src/gshocktimeserver/scanner.py rename to src/gshock_api/scanner.py index 9293a9b..33dfacd 100644 --- a/src/gshocktimeserver/scanner.py +++ b/src/gshock_api/scanner.py @@ -7,7 +7,8 @@ class Scanner: - CASIO_SERVICE_UUID = "00001804-0000-1000-8000-00805f9b34fb" + # CASIO_SERVICE_UUID = "00001804-0000-1000-8000-00805f9b34fb" + CASIO_SERVICE_UUID = "26eb0002-b012-49a8-b1f8-394fb2032b0f" async def scan(self, device_address=None): scanner = BleakScanner() diff --git a/src/gshocktimeserver/settings.py b/src/gshock_api/settings.py similarity index 100% rename from src/gshocktimeserver/settings.py rename to src/gshock_api/settings.py diff --git a/src/gshocktimeserver/utils.py b/src/gshock_api/utils.py similarity index 100% rename from src/gshocktimeserver/utils.py rename to src/gshock_api/utils.py diff --git a/src/gshocktimeserver/watch_info.py b/src/gshock_api/watch_info.py similarity index 98% rename from src/gshocktimeserver/watch_info.py rename to src/gshock_api/watch_info.py index b5a820e..abbe88d 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshock_api/watch_info.py @@ -11,7 +11,8 @@ class WATCH_MODEL(Enum): MSG = 7 GB001 = 8 GBD = 9 - UNKNOWN = 10 + GB = 10 + UNKNOWN = 11 class WatchInfo: @@ -189,6 +190,8 @@ def set_name_and_model(self, name): self.model = WATCH_MODEL.GST elif self.shortName.startswith("GBD"): self.model = WATCH_MODEL.GBD + elif self.shortName.startswith("GB"): + self.model = WATCH_MODEL.GB elif self.shortName.startswith("GMW"): self.model = WATCH_MODEL.GMW elif self.shortName.startswith("DW"): From 07825b4e8f2f81825853c3f9395731241031318e Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Thu, 16 May 2024 23:20:12 -0400 Subject: [PATCH 091/123] cleanup --- src/gshocktimeserver/config.ini | 4 ++++ src/gshocktimeserver/gshock_server.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 src/gshocktimeserver/config.ini diff --git a/src/gshocktimeserver/config.ini b/src/gshocktimeserver/config.ini new file mode 100644 index 0000000..e4cd7c7 --- /dev/null +++ b/src/gshocktimeserver/config.ini @@ -0,0 +1,4 @@ +[main] +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 + diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 2544ceb..9dacda7 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -19,8 +19,8 @@ async def main(argv): - await run_time_server() - # await run_api_tests() + # await run_time_server() + await run_api_tests() def prompt(): From 08ec433f1bb70763f60f0cc3acc2d4d4f3ac123c Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sat, 18 May 2024 10:44:12 -0400 Subject: [PATCH 092/123] WIP --- config.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.ini b/config.ini index 8ef9d8c..e4cd7c7 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:03:12:62:17 -device.name = CASIO GW-B5600 +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 From a21b6cf1837becf418d3fc12befa73d5d137b68b Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 22 May 2024 21:58:29 -0400 Subject: [PATCH 093/123] Added conda configuration --- environment.yml | 56 ++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/environment.yml b/environment.yml index ae73450..b77bacf 100644 --- a/environment.yml +++ b/environment.yml @@ -1,25 +1,37 @@ -name: gshock-time-server +name: GShockTimeServer channels: - - defaults - conda-forge - - pytorch + - defaults dependencies: - - python>=3.6 - - pip - # BASICS - - pip: - - -e . # install git checkout of demo-dsproject in editable mode - - pytz - - bleak - - reactivex - - # DEVELOPMENT ONLY PACKAGES (could also be kept in a separate environment file) - - jupyterlab - - pytest - - pytest-cov - - tox - - pre_commit - - nbdime - - nbstripout - - sphinx - - recommonmark \ No newline at end of file + - _libgcc_mutex=0.1=conda_forge + - _openmp_mutex=4.5=2_gnu + - async-timeout=4.0.3=pyhd8ed1ab_0 + - bleak=0.22.1=py39hf3d152e_0 + - bzip2=1.0.8=hd590300_5 + - ca-certificates=2024.2.2=hbcca054_0 + - dbus-fast=2.21.2=py39hd1e30aa_0 + - ld_impl_linux-64=2.40=h55db66e_0 + - libffi=3.4.2=h7f98852_5 + - libgcc-ng=13.2.0=h77fa898_7 + - libgomp=13.2.0=h77fa898_7 + - libnsl=2.0.1=hd590300_0 + - libsqlite=3.45.3=h2797004_0 + - libuuid=2.38.1=h0b41bf4_0 + - libxcrypt=4.4.36=hd590300_1 + - libzlib=1.2.13=hd590300_5 + - ncurses=6.5=h59595ed_0 + - openssl=3.3.0=h4ab18f5_2 + - pip=24.0=pyhd8ed1ab_0 + - python=3.9.19=h0755675_0_cpython + - python_abi=3.9=4_cp39 + - pytz=2024.1=pyhd8ed1ab_0 + - reactivex=4.0.4=pyhd8ed1ab_0 + - readline=8.2=h8228510_1 + - setuptools=70.0.0=pyhd8ed1ab_0 + - tk=8.6.13=noxft_h4845f30_101 + - typing-extensions=4.11.0=hd8ed1ab_0 + - typing_extensions=4.11.0=pyha770c72_0 + - tzdata=2024a=h0c530f3_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - xz=5.2.6=h166bdaf_0 +prefix: /home/ivo/anaconda3/envs/GShockTimeServer From 4e44df853f561ba46d7a03c9d9fe7d2881f683af Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Thu, 23 May 2024 22:33:42 -0400 Subject: [PATCH 094/123] WIP --- config.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.ini b/config.ini index e4cd7c7..7af9f51 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 +device.address = CD:85:F3:13:62:17 +device.name = CASIO GW-B5600 From a8da250deaa0219c8843c77a3d1d4e60bb3ab9c3 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sat, 1 Jun 2024 21:56:31 -0400 Subject: [PATCH 095/123] Fix conda file --- .github/workflows/python-package-conda.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index ab5acda..2be9164 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -21,14 +21,3 @@ jobs: - name: Install dependencies run: | conda env update --file environment.yml --name base - - name: Lint with flake8 - run: | - conda install flake8 - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - # - name: Test with pytest - # run: | - # conda install pytest - # pytest From 6a235ee588a327402fdf50139c9d488b51b25cc7 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sat, 1 Jun 2024 22:01:44 -0400 Subject: [PATCH 096/123] Fix conda file --- .github/workflows/python-package-conda.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 2be9164..3caa560 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -20,4 +20,5 @@ jobs: echo $CONDA/bin >> $GITHUB_PATH - name: Install dependencies run: | + conda install -y python=3.10 conda env update --file environment.yml --name base From 6b228fbd2f1c3cf5bdef02eb4c7dbb0412f05082 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 12 Jun 2024 22:05:20 -0400 Subject: [PATCH 097/123] Run server instead ot tests --- build-and-install.sh | 4 +- config.ini | 4 +- src/gshock_api/api_tests.py | 139 ++++++++++++++++++----------------- src/gshock_api/config.ini | 9 --- src/gshock_api/connection.py | 13 +++- src/gshock_api/scanner.py | 2 + 6 files changed, 91 insertions(+), 80 deletions(-) delete mode 100644 src/gshock_api/config.ini diff --git a/build-and-install.sh b/build-and-install.sh index e96d095..66eeddf 100755 --- a/build-and-install.sh +++ b/build-and-install.sh @@ -1,6 +1,6 @@ rm -rf ./dist python3 setup.py bdist_wheel -scp ./dist/*.whl pi@192.168.1.118:/tmp/gshocktimeserver.zip -ssh pi@192.168.1.118 /home/pi/update.sh +scp ./dist/*.whl pi@pizero:/tmp/gshocktimeserver.zip +ssh pi@pizero /home/pi/update.sh diff --git a/config.ini b/config.ini index 7af9f51..6b2c56b 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:F3:13:62:17 -device.name = CASIO GW-B5600 +device.address = D0:F0:D9:6B:99:10 +device.name = CASIO GB-5600B diff --git a/src/gshock_api/api_tests.py b/src/gshock_api/api_tests.py index fa12209..4771ab4 100644 --- a/src/gshock_api/api_tests.py +++ b/src/gshock_api/api_tests.py @@ -35,6 +35,8 @@ async def run_api_tests(): api = GshockAPI(connection) + await gb5600_test(connection, device) + # app_info = await api.get_app_info() # logger.info("app info: {}".format(app_info)) @@ -44,78 +46,83 @@ async def run_api_tests(): # watch_name = await api.get_watch_name() # logger.info("got watch name: {}".format(watch_name)) - await api.set_time() - - alarms = await api.get_alarms() - logger.info("alarms: {}".format(alarms)) - - alarms[3]["enabled"] = True - alarms[3]["hour"] = 7 - alarms[3]["minute"] = 25 - alarms[3]["enabled"] = False - await api.set_alarms(alarms) - - seconds = await api.get_timer() - logger.info("timer: {} seconds".format(seconds)) - - await api.set_timer(seconds + 10) - time_adjstment = await api.get_time_adjustment() - logger.info("time_adjstment: {}".format(time_adjstment)) - - await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) - - condition = await api.get_watch_condition() - logger.info(f"condition: {condition}") - - settings_local = await api.get_basic_settings() - logger.info("settings: {}".format(settings_local)) - - settings_local["button_tone"] = True - settings_local["language"] = "Russian" - settings_local["time_format"] = "24h" - - await api.set_settings(settings_local) - - settings_local = await api.get_basic_settings() - logger.info("After update: settings: {}".format(settings_local)) - - # Create a single event - tz = pytz.timezone("America/Toronto") - dt = datetime.now(timezone.utc) - utc_timestamp = dt.timestamp() - event_date = create_event_date(utc_timestamp, tz) - event_date_str = json.dumps(event_date.__dict__) - event_json_str = ( - """{"title":"Test Event", "time":{"selected":\"""" - + str(False) - + """\", "enabled":\"""" - + str(True) - + """\", "repeat_period":\"""" - + RepeatPeriod.WEEKLY - + """\","days_of_week":\"""" - + "MONDAY" - + """\", "start_date":""" - + event_date_str - + """, "end_date":""" - + event_date_str - + """}}""" - ) - Event().create_event(json.loads(event_json_str)) - logger.info("Created event: {}".format(event_json_str)) - - reminders = await api.get_reminders() - for reminder in reminders: - logger.info("reminder: {}".format(reminder.__str__())) - - reminders[3]["title"] = "Test Event" - - await api.set_reminders(reminders) + # await api.set_time() + + # alarms = await api.get_alarms() + # logger.info("alarms: {}".format(alarms)) + + # alarms[3]["enabled"] = True + # alarms[3]["hour"] = 7 + # alarms[3]["minute"] = 25 + # alarms[3]["enabled"] = False + # await api.set_alarms(alarms) + + # seconds = await api.get_timer() + # logger.info("timer: {} seconds".format(seconds)) + + # await api.set_timer(seconds + 10) + # time_adjstment = await api.get_time_adjustment() + # logger.info("time_adjstment: {}".format(time_adjstment)) + + # await api.set_time_adjustment(time_adjustement=True, minutes_after_hour=10) + + # condition = await api.get_watch_condition() + # logger.info(f"condition: {condition}") + + # settings_local = await api.get_basic_settings() + # logger.info("settings: {}".format(settings_local)) + + # settings_local["button_tone"] = True + # settings_local["language"] = "Russian" + # settings_local["time_format"] = "24h" + + # await api.set_settings(settings_local) + + # settings_local = await api.get_basic_settings() + # logger.info("After update: settings: {}".format(settings_local)) + + # # Create a single event + # tz = pytz.timezone("America/Toronto") + # dt = datetime.now(timezone.utc) + # utc_timestamp = dt.timestamp() + # event_date = create_event_date(utc_timestamp, tz) + # event_date_str = json.dumps(event_date.__dict__) + # event_json_str = ( + # """{"title":"Test Event", "time":{"selected":\"""" + # + str(False) + # + """\", "enabled":\"""" + # + str(True) + # + """\", "repeat_period":\"""" + # + RepeatPeriod.WEEKLY + # + """\","days_of_week":\"""" + # + "MONDAY" + # + """\", "start_date":""" + # + event_date_str + # + """, "end_date":""" + # + event_date_str + # + """}}""" + # ) + # Event().create_event(json.loads(event_json_str)) + # logger.info("Created event: {}".format(event_json_str)) + + # reminders = await api.get_reminders() + # for reminder in reminders: + # logger.info("reminder: {}".format(reminder.__str__())) + + # reminders[3]["title"] = "Test Event" + + # await api.set_reminders(reminders) input("Hit any key to disconnect") await connection.disconnect() logger.info("--- END OF TESTS ---") +async def gb5600_test (connection, device): + # await connection.ble_service_discovery(device) + + await connection.write_with_characteristic("00002a06-0000-1000-8000-00805f9b34fb", "00") + await connection.write_with_characteristic("26eb000f-b012-49a8-b1f8-394fb2032b0f", "FFD5555751482C01020000") def convert_time_string_to_epoch(time_string): try: diff --git a/src/gshock_api/config.ini b/src/gshock_api/config.ini deleted file mode 100644 index 30e2052..0000000 --- a/src/gshock_api/config.ini +++ /dev/null @@ -1,9 +0,0 @@ -[main] -<<<<<<< HEAD:src/gshocktimeserver/config.ini -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 -======= -device.address = D0:F0:D9:6B:99:10 -device.name = CASIO GB-5600B ->>>>>>> 1cad3da37d9ff018cd1c89db111af72e61ff48eb:src/gshock_api/config.ini - diff --git a/src/gshock_api/connection.py b/src/gshock_api/connection.py index 8ec81cf..a9691b5 100644 --- a/src/gshock_api/connection.py +++ b/src/gshock_api/connection.py @@ -5,7 +5,6 @@ from utils import to_casio_cmd from logger import logger - class Connection: def __init__(self, device): self.handles_map = self.init_handles_map() @@ -44,6 +43,18 @@ async def request(self, request): logger.info("write: {}".format(request)) await self.write(0xC, request) + async def write_with_characteristic(self, characteristic, data): + try: + await self.client.write_gatt_char( + characteristic, to_casio_cmd(data) + ) + except Exception as e: + logger.debug("write failed with exception: {}".format(e)) + + async def request(self, request): + logger.info("write: {}".format(request)) + await self.write(0xC, request) + def init_handles_map(self): handles_map = {} diff --git a/src/gshock_api/scanner.py b/src/gshock_api/scanner.py index 33dfacd..aee1d94 100644 --- a/src/gshock_api/scanner.py +++ b/src/gshock_api/scanner.py @@ -14,6 +14,8 @@ async def scan(self, device_address=None): scanner = BleakScanner() logger.debug("Scanning for devices...") + await scanner.discover() + if device_address is None: while True: device = await scanner.find_device_by_filter( From 2aeaf8b203ceca79daf73a1047cf31b4fb5954c7 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 12 Jun 2024 22:20:19 -0400 Subject: [PATCH 098/123] Reverted to before splitting API --- src/gshocktimeserver/config.ini | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/gshocktimeserver/config.ini diff --git a/src/gshocktimeserver/config.ini b/src/gshocktimeserver/config.ini new file mode 100644 index 0000000..e4cd7c7 --- /dev/null +++ b/src/gshocktimeserver/config.ini @@ -0,0 +1,4 @@ +[main] +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 + From 9a1891ef40cd387c390550bc4e426a4561d1f0f1 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 12 Jun 2024 23:12:42 -0400 Subject: [PATCH 099/123] Cleanup --- .github/workflows/python-package-conda.yml | 11 --- Pipfile.lock | 20 ------ build-and-install.sh | 4 +- gatttool_scripts/encodeTime | 17 ----- gatttool_scripts/readme.md | 80 --------------------- gatttool_scripts/setTime.exp | 81 ---------------------- setup.py | 4 +- 7 files changed, 4 insertions(+), 213 deletions(-) delete mode 100644 Pipfile.lock delete mode 100644 gatttool_scripts/encodeTime delete mode 100644 gatttool_scripts/readme.md delete mode 100644 gatttool_scripts/setTime.exp diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index ab5acda..2be9164 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -21,14 +21,3 @@ jobs: - name: Install dependencies run: | conda env update --file environment.yml --name base - - name: Lint with flake8 - run: | - conda install flake8 - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - # - name: Test with pytest - # run: | - # conda install pytest - # pytest diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index eb6410c..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,20 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "fedbd2ab7afd84cf16f128af0619749267b62277b4cb6989ef16d4bef6e4eef2" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.10" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": {}, - "develop": {} -} diff --git a/build-and-install.sh b/build-and-install.sh index e96d095..66eeddf 100755 --- a/build-and-install.sh +++ b/build-and-install.sh @@ -1,6 +1,6 @@ rm -rf ./dist python3 setup.py bdist_wheel -scp ./dist/*.whl pi@192.168.1.118:/tmp/gshocktimeserver.zip -ssh pi@192.168.1.118 /home/pi/update.sh +scp ./dist/*.whl pi@pizero:/tmp/gshocktimeserver.zip +ssh pi@pizero /home/pi/update.sh diff --git a/gatttool_scripts/encodeTime b/gatttool_scripts/encodeTime deleted file mode 100644 index 3fbae58..0000000 --- a/gatttool_scripts/encodeTime +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Read computer time and convert it to Casio time bluetooth packet. - -y=$(date +%Y) -m=$(date +%-m) -d=$(date +%-d) -j=$(($(date +%u)-1)) -H=$(date +%-H) -#H=$((H-1)) -M=$(date +%-M) -#M=$((M-5)) -S=$(date +%-S) -printf "09%02x%02x%02x%02x%02x%02x%02x%02x0001\n" \ - $((y >> 0 & 0xff)) $((y >> 8 & 0xff)) \ - $m $d $H $M $S $j - diff --git a/gatttool_scripts/readme.md b/gatttool_scripts/readme.md deleted file mode 100644 index f926146..0000000 --- a/gatttool_scripts/readme.md +++ /dev/null @@ -1,80 +0,0 @@ -# GATTTOOL Scripts - -## Overview -Here we will see how to send and script commands to a Casio GShock GA-B2100 from the command line, using gatttool. - -As an example, the script setTime.exp provided here read the time from the computer and send it to the watch. - -All the procedures given here work on GNU-Linux operating systems. - -gatttool is a bluez utility that can be used to easily interact with a Bluetooth Low Energy device. -It is considered deprecated and replaced by bluetoothctl, but the latter lack of documentation and is (to my opinion) more difficult to use. -gattool can be used as a shell command, for example : - -Long press the bottom left button of the watch to enter in connect mode, then type in a terminal : - -`$ gatttool -b
-t random --char-read -a 0x04` - -with `
` being the mac address of the device, for example `D3:60:4F:9A:33:29` - -The answer of this command is `43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00` - -You can translate it with an hexadecimal converter like `xxd` : - -```shell -$ echo "43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00" | xxd -r -p;echo -CASIO GA-B2100 -``` - -If you want to set the time of the watch, you will have to issue multiple write requests and commands while the device is connected. -gatttool in command line will not work because when invoked it does three actions : connect to the device, issue the command then disconnect. -To send multiple commands between connect and disconnect, gatttool has to be used interactively. The latter example could be done this way : - -```shell -$ gatttool -b D3:60:4F:9A:33:29 -I -t random -[D3:60:4F:9A:33:29] connect -Attempting to connect to D3:60:4F:9A:33:29 -Connection successful -[D3:60:4F:9A:33:29][LE]> char-read-hnd 0x04 -Characteristic value/descriptor: 43 41 53 49 4f 20 47 41 2d 42 32 31 30 30 00 00 -[D3:60:4F:9A:33:29][LE]> disconnect -[D3:60:4F:9A:33:29][LE]> quit -$ -``` -If you want to automate the process in a script, you will have to use a command line interaction tool like expect-lite. - -The script `setTime.exp` provided here is an expect-lite script which read the time from the computer and send it to a Casio GShock GA-B2100, using gatttool interactive mode. - -## Dependencies - -You will need to install bluez and expect-lite packages. On Debian and derivatives (Ubuntu, Linux Mint,...), type : - -$ sudo apt install bluez expect-lite - -## Usage - -setTime.exp and encodeTime scripts should be in the same directory. Make them executable with : - -`$ chmod +x setTime.exp encodeTime` - -Find the MAC address of your watch with `bluetoothctl scan on` and press bottom right key of the watch. You should have an answer like : - -`[NEW] Device D3:60:4F:9A:33:29 CASIO GA-B2100` - -Stop the discovery with CtrlC, then open `setTime.exp` and copy the MAC address in the line beginning with `$MAC=` - -Launch the script with the command : - -`$ .\setTime.exp` - -then press bottom right key of the watch. - -## References - -* [Casio GA-B2100 protocol](/protocol.md) -* [gatttool Syntax and examples](http://tvaira.free.fr/flower-power/gatttool.txt) -* [Reading Values From a BLE Device](https://www.instructables.com/Reading-Values-From-a-BLE-Device-Using-CSR1010-and/) -* [Ivo Zivkov's GShock API](https://github.com/izivkov/GShockAPI) -* [Ivo Zivkov's GShock time server](https://github.com/izivkov/GShockTimeServer) -* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge) - diff --git a/gatttool_scripts/setTime.exp b/gatttool_scripts/setTime.exp deleted file mode 100644 index e04a9a0..0000000 --- a/gatttool_scripts/setTime.exp +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env expect-lite - -# This script read time from computer clock -# and send it to a Casio GShock GA-B2100 watch. -# (c) Pierre Brial 2023 -# GNU General Public License version 3 - -*NOINFO - -# Put here the MAC address of the watch (use 'bluetoothctl scan on' to find it) -$MAC=D3:60:4F:9A:33:29 - ->gatttool -b $MAC -I -t random ->connect -<.+successful - -# Get DST state of watch ->char-write-cmd 0xc 1d00 -char-write-req 0xe $a -<.+successfully - -# Get and set Local DST and time zone ->char-write-cmd 0xc 1e00 -char-write-req 0xe $a -<.+successfully - -# Get and set World Time DST and time zone ->char-write-cmd 0xc 1e01 -char-write-req 0xe $a -<.+successfully - -# Get and set time zone name : - -# local : ->char-write-cmd 0xc 1f00 -char-write-req 0xe $a -<.+successfully - -# World time : ->char-write-cmd 0xc 1f01 -char-write-req 0xe $a -<.+successfully - -# Read computer time from script encodeTime : -*FORK getTime ->./encodeTime -+$timef=([a-f,\d]{18}0001) -? $timef == __NO_STRING_CAPTURED__ ? *FAIL -*FORK default - -# Set watch time : ->char-write-req 0xe $timef -<.+successfully - ->disconnect diff --git a/setup.py b/setup.py index 4dce78c..159d876 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ from setuptools import setup, find_packages setup( - name='gshock_api', + name='gshocktimeserver', version='0.1', use_scm_version=True, packages=find_packages(), @@ -32,4 +32,4 @@ 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', ], -) \ No newline at end of file +) From 52ef03cebbb027ff7c529a7127d83c137e98116e Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Wed, 12 Jun 2024 23:40:54 -0400 Subject: [PATCH 100/123] Update python-package-conda.yml --- .github/workflows/python-package-conda.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 2be9164..7adb2dc 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -20,4 +20,5 @@ jobs: echo $CONDA/bin >> $GITHUB_PATH - name: Install dependencies run: | + conda update conda conda env update --file environment.yml --name base From 6d90e67022bc9e35a7e52ee6968495679a76a9ff Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Tue, 18 Jun 2024 22:29:08 -0400 Subject: [PATCH 101/123] Fix time setting error --- .readthedocs.yml | 2 +- config.ini | 2 +- environment.yml | 3 +-- setup.py | 2 +- src/gshocktimeserver/config.ini | 4 ++-- src/gshocktimeserver/gshock_api.py | 12 +++++++----- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index a2bcab3..65bdb8f 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -19,7 +19,7 @@ formats: build: os: ubuntu-22.04 tools: - python: "3.11" + python: "3.10" python: install: diff --git a/config.ini b/config.ini index 8ef9d8c..d99d073 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,4 @@ [main] -device.address = CD:85:03:12:62:17 +device.address = E8:3E:76:AC:6A:35 device.name = CASIO GW-B5600 diff --git a/environment.yml b/environment.yml index ae73450..cf823ce 100644 --- a/environment.yml +++ b/environment.yml @@ -4,9 +4,8 @@ channels: - conda-forge - pytorch dependencies: - - python>=3.6 + - python=3.10 - pip - # BASICS - pip: - -e . # install git checkout of demo-dsproject in editable mode - pytz diff --git a/setup.py b/setup.py index 159d876..e2e6173 100644 --- a/setup.py +++ b/setup.py @@ -32,4 +32,4 @@ 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', ], -) +) \ No newline at end of file diff --git a/src/gshocktimeserver/config.ini b/src/gshocktimeserver/config.ini index e4cd7c7..c403f84 100644 --- a/src/gshocktimeserver/config.ini +++ b/src/gshocktimeserver/config.ini @@ -1,4 +1,4 @@ [main] -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 +device.address = EC:71:14:33:FD:51 +device.name = CASIO ECB-30 diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index fc7d1bb..9c57df8 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -189,7 +189,7 @@ async def read_write_world_cities(self): for item in array_of_world_cities[: watch_info.worldCitiesCount]: await self.read_and_write(item["function"], item["city_number"]) - async def set_time(self, current_time=time.time()): + async def set_time(self, current_time=None): """Sets the current time on the watch from the time on the phone. In addition, it can optionally set the Home Time to the current time zone. If timezone changes during travel, the watch will automatically be set to the correct time and timezone after running this function. @@ -203,12 +203,14 @@ async def set_time(self, current_time=time.time()): None """ - # if watch_info.model == watch_info.model.B2100: - await self.initialize_for_setting_time() - # else: - # await self.initialize_for_setting_time() + if current_time == None: + current_time = time.time() + + self.logger.info(f"=======> passed: ${current_time}, ${time.time()}") + await self.initialize_for_setting_time() await self._set_time(current_time) + current_time = None async def _set_time(self, current_time): await message_dispatcher.TimeIO.request(self.connection, current_time) From dca3a672d28a4fc31c58a8e5358432e0254c3954 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sat, 29 Jun 2024 23:04:13 -0400 Subject: [PATCH 102/123] Cleanup --- .gitignore | 1 + config.ini | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 config.ini diff --git a/.gitignore b/.gitignore index 322e1b1..67d184f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ __pycache__/* .idea .vscode tags +config.ini # Package files *.egg diff --git a/config.ini b/config.ini deleted file mode 100644 index d99d073..0000000 --- a/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -[main] -device.address = E8:3E:76:AC:6A:35 -device.name = CASIO GW-B5600 - From c31a451965b51ba0027f59bba13b3f46075c02c1 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Mon, 1 Jul 2024 20:21:02 -0400 Subject: [PATCH 103/123] Added support for Edifice ECB-30 --- src/gshocktimeserver/casio_constants.py | 4 ++ src/gshocktimeserver/config.ini | 4 +- src/gshocktimeserver/gshock_server.py | 3 +- .../iolib/button_pressed_io.py | 5 ++- src/gshocktimeserver/message_dispatcher.py | 5 ++- src/gshocktimeserver/scanner.py | 6 +-- src/gshocktimeserver/watch_info.py | 38 +++++++++++++++++-- 7 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/gshocktimeserver/casio_constants.py b/src/gshocktimeserver/casio_constants.py index a094f16..1bb2a7b 100644 --- a/src/gshocktimeserver/casio_constants.py +++ b/src/gshocktimeserver/casio_constants.py @@ -37,4 +37,8 @@ class CasioConstants: "CASIO_TIMER": 0x18, "ERROR": 0xFF, "UNKNOWN": 0x0A, + + # ECB-30 + "CMD_SET_TIMEMODE": 0x47, + "FIND_PHONE": 0x0A, } diff --git a/src/gshocktimeserver/config.ini b/src/gshocktimeserver/config.ini index c403f84..e4cd7c7 100644 --- a/src/gshocktimeserver/config.ini +++ b/src/gshocktimeserver/config.ini @@ -1,4 +1,4 @@ [main] -device.address = EC:71:14:33:FD:51 -device.name = CASIO ECB-30 +device.address = F6:A1:42:57:7A:07 +device.name = CASIO GA-B2100 diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index 2544ceb..c45ead8 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -70,7 +70,8 @@ async def run_time_server(): # You can add mail notification here if you run your mail server. # send_mail_notification(args.mailto) - await connection.disconnect() + if watch_info.alwaysConnected == False: + await connection.disconnect() except Exception as e: logger.error(f"Got error: {e}") diff --git a/src/gshocktimeserver/iolib/button_pressed_io.py b/src/gshocktimeserver/iolib/button_pressed_io.py index a55048c..02ade09 100644 --- a/src/gshocktimeserver/iolib/button_pressed_io.py +++ b/src/gshocktimeserver/iolib/button_pressed_io.py @@ -22,7 +22,6 @@ class ButtonPressedIO: @staticmethod async def request(connection): - logger.info(f"ButtonPressedIO request") ButtonPressedIO.connection = connection await connection.request("10") @@ -57,6 +56,7 @@ def button_pressed_callback(data): if len(data) >= 19: ble_int_arr = to_int_array(to_hex_string(data)) button_indicator = ble_int_arr[8] + logger.info(f"Buttom code pressed: ${button_indicator}") ret = ( WatchButton.LOWER_LEFT if (button_indicator == 0 or button_indicator == 1) @@ -64,7 +64,8 @@ def button_pressed_callback(data): if button_indicator == 4 else WatchButton.NO_BUTTON if button_indicator == 3 - else WatchButton.INVALID + # assime that all other buttons from watches such as the ECB-30 are for time set + else WatchButton.LOWER_RIGHT ) return ret diff --git a/src/gshocktimeserver/message_dispatcher.py b/src/gshocktimeserver/message_dispatcher.py index ba966b3..030510d 100644 --- a/src/gshocktimeserver/message_dispatcher.py +++ b/src/gshocktimeserver/message_dispatcher.py @@ -24,7 +24,6 @@ CHARACTERISTICS = CasioConstants.CHARACTERISTICS - class MessageDispatcher: watch_senders = { "GET_ALARMS": AlarmsIO.send_to_watch, @@ -56,6 +55,10 @@ class MessageDispatcher: CHARACTERISTICS["CASIO_SETTING_FOR_BLE"]: TimeAdjustmentIO.on_received, CHARACTERISTICS["ERROR"]: ErrorIO.on_received, CHARACTERISTICS["UNKNOWN"]: UnknownIO.on_received, + + # ECB-30 + CHARACTERISTICS["CMD_SET_TIMEMODE"]: UnknownIO.on_received, + CHARACTERISTICS["FIND_PHONE"]: UnknownIO.on_received, } @staticmethod diff --git a/src/gshocktimeserver/scanner.py b/src/gshocktimeserver/scanner.py index 9293a9b..6523147 100644 --- a/src/gshocktimeserver/scanner.py +++ b/src/gshocktimeserver/scanner.py @@ -11,7 +11,7 @@ class Scanner: async def scan(self, device_address=None): scanner = BleakScanner() - logger.debug("Scanning for devices...") + logger.info("Scanning for devices...") if device_address is None: while True: @@ -19,7 +19,7 @@ async def scan(self, device_address=None): lambda d, ad: d.name and d.name.lower().startswith("casio"), timeout=5 * 60.0, ) - logger.debug(f"device: {device}") + logger.info(f"device: {device}") if device is None: continue @@ -31,7 +31,7 @@ async def scan(self, device_address=None): conf.put("device.name", device.name) break else: - logger.debug("Waiting for device by address...") + logger.info("Waiting for device by address...") device = await scanner.find_device_by_address( device_address, sys.float_info.max ) diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index b5a820e..f3d68fa 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -1,5 +1,5 @@ from enum import Enum - +from logger import logger class WATCH_MODEL(Enum): GA = 1 @@ -11,8 +11,8 @@ class WATCH_MODEL(Enum): MSG = 7 GB001 = 8 GBD = 9 - UNKNOWN = 10 - + ECB = 10 + UNKNOWN = 11 class WatchInfo: def __init__(self): @@ -33,6 +33,11 @@ def __init__(self): self.batteryLevelLowerLimit: 15 self.batteryLevelUpperLimit: 20 + self.alwaysConnected = False, + self.findButtonUserDefined = False, + self.hasPowerSavingMode = True, + self.hasDnD = False, + self.models = [ { "model": WATCH_MODEL.GW, @@ -159,6 +164,23 @@ def __init__(self): "worldCities": False, "temperature": False, }, + { + "model": WATCH_MODEL.ECB, + "worldCitiesCount": 2, + "dstCount": 1, + "alarmCount": 5, + "hasAutoLight": True, + "hasReminders": False, + "shortLightDuration": "1.5s", + "longLightDuration": "3s", + "worldCities": True, + "hasTemperature": False, + "hasBatteryLevel": False, + "alwaysConnected": True, + "findButtonUserDefined": True, + "hasPowerSavingMode": False, + "hasDnD": True + }, { "model": WATCH_MODEL.UNKNOWN, "worldCitiesCount": 2, @@ -180,6 +202,8 @@ def set_name_and_model(self, name): if len(parts) > 1: self.shortName = parts[1] + logger.info(f"============> self.shortName: ${self.shortName}") + # *** Order matters. Start with the longest shortName first. *** if self.shortName.startswith("MSG"): self.model = WATCH_MODEL.MSG @@ -201,6 +225,8 @@ def set_name_and_model(self, name): self.model = WATCH_MODEL.GM elif self.shortName.startswith("GW"): self.model = WATCH_MODEL.GW + elif self.shortName == "ECB-10" or self.shortName == "ECB-20" or self.shortName == "ECB-30": + self.model = WATCH_MODEL.ECB else: self.model = WATCH_MODEL.UNKNOWN @@ -219,6 +245,12 @@ def set_name_and_model(self, name): self.batteryLevelLowerLimit = model_info.get("batteryLevelLowerLimit", 15) self.batteryLevelUpperLimit = model_info.get("batteryLevelUpperLimit", 20) + self.alwaysConnected = model_info.get("alwaysConnected", False) + self.findButtonUserDefined = model_info.get("findButtonUserDefined", False) + self.hasPowerSavingMode = model_info.get("hasPowerSavingMode", False) + self.hasDnD = model_info.get("hasDnD", False) + self.hasBatteryLevel = model_info.get("hasBatteryLevel", False) + def set_address(self, address): self.address = address From 11e5fb3ac5ffb767b8ec70fbac489fd2f3720d44 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Thu, 4 Jul 2024 17:01:23 -0400 Subject: [PATCH 104/123] Fix blocking on comand 10 --- src/gshocktimeserver/cancelable_result.py | 38 +++++++++++++++++++ src/gshocktimeserver/config.ini | 4 -- src/gshocktimeserver/connection.py | 1 + src/gshocktimeserver/iolib/alarms_io.py | 3 +- src/gshocktimeserver/iolib/app_info_io.py | 3 +- .../iolib/button_pressed_io.py | 3 +- .../iolib/dst_for_world_cities_io.py | 3 +- .../iolib/dst_watch_state_io.py | 3 +- src/gshocktimeserver/iolib/events_io.py | 3 +- src/gshocktimeserver/iolib/settings_io.py | 3 +- .../iolib/time_adjustement_io.py | 3 +- src/gshocktimeserver/iolib/time_io.py | 3 +- src/gshocktimeserver/iolib/timer_io.py | 3 +- .../iolib/watch_condition_io.py | 3 +- src/gshocktimeserver/iolib/watch_name_io.py | 3 +- src/gshocktimeserver/iolib/world_cities_io.py | 3 +- 16 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 src/gshocktimeserver/cancelable_result.py delete mode 100644 src/gshocktimeserver/config.ini diff --git a/src/gshocktimeserver/cancelable_result.py b/src/gshocktimeserver/cancelable_result.py new file mode 100644 index 0000000..d76cb81 --- /dev/null +++ b/src/gshocktimeserver/cancelable_result.py @@ -0,0 +1,38 @@ +import asyncio +from typing import Any + +class CancelableResult: + def __init__(self, timeout: float = 5.0): + self._timeout = timeout + self._future: asyncio.Future[Any] = asyncio.Future() + + async def get_result(self) -> Any: + try: + return await asyncio.wait_for(self._future, timeout=self._timeout) + except asyncio.TimeoutError: + if not self._future.done(): + self._future.set_result('') + return await self._future + + def set_result(self, result: Any) -> None: + if not self._future.done(): + self._future.set_result(result) + +# Example usage +async def main(): + cancelable_result = CancelableResult(timeout=5) + + # Simulate some async work that might or might not set a result + async def some_async_work(): + await asyncio.sleep(3) # Change this to 6 to test the timeout + cancelable_result.set_result('Result after async work') + + await asyncio.gather(some_async_work(), asyncio.sleep(6)) + + final_result = await cancelable_result.get_result() + print(f'Final result: "{final_result}"') + +# Run the main coroutine +# asyncio.run(main()) + +cancelable_result = CancelableResult() diff --git a/src/gshocktimeserver/config.ini b/src/gshocktimeserver/config.ini deleted file mode 100644 index e4cd7c7..0000000 --- a/src/gshocktimeserver/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -[main] -device.address = F6:A1:42:57:7A:07 -device.name = CASIO GA-B2100 - diff --git a/src/gshocktimeserver/connection.py b/src/gshocktimeserver/connection.py index 8ec81cf..4d307ed 100644 --- a/src/gshocktimeserver/connection.py +++ b/src/gshocktimeserver/connection.py @@ -1,3 +1,4 @@ +import asyncio from bleak import BleakClient from bleak.backends.characteristic import BleakGATTCharacteristic from casio_constants import CasioConstants diff --git a/src/gshocktimeserver/iolib/alarms_io.py b/src/gshocktimeserver/iolib/alarms_io.py index fca108b..d1d18b4 100644 --- a/src/gshocktimeserver/iolib/alarms_io.py +++ b/src/gshocktimeserver/iolib/alarms_io.py @@ -3,6 +3,7 @@ from typing import Any from alarms import alarms_inst, alarm_decoder +from cancelable_result import CancelableResult from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -10,7 +11,7 @@ class AlarmsIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/app_info_io.py b/src/gshocktimeserver/iolib/app_info_io.py index 2ecc1ba..bbec512 100644 --- a/src/gshocktimeserver/iolib/app_info_io.py +++ b/src/gshocktimeserver/iolib/app_info_io.py @@ -1,5 +1,6 @@ import asyncio from typing import Any +from cancelable_result import CancelableResult from logger import logger from utils import to_compact_string, to_hex_string @@ -9,7 +10,7 @@ class AppInfoIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/button_pressed_io.py b/src/gshocktimeserver/iolib/button_pressed_io.py index 02ade09..06f1f3d 100644 --- a/src/gshocktimeserver/iolib/button_pressed_io.py +++ b/src/gshocktimeserver/iolib/button_pressed_io.py @@ -1,6 +1,7 @@ import asyncio from enum import IntEnum from typing import Any +from cancelable_result import CancelableResult from logger import logger from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants @@ -17,7 +18,7 @@ class WatchButton(IntEnum): INVALID = 6 class ButtonPressedIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/dst_for_world_cities_io.py b/src/gshocktimeserver/iolib/dst_for_world_cities_io.py index 5e75c1b..4b784e8 100644 --- a/src/gshocktimeserver/iolib/dst_for_world_cities_io.py +++ b/src/gshocktimeserver/iolib/dst_for_world_cities_io.py @@ -1,5 +1,6 @@ import asyncio from typing import Any +from cancelable_result import CancelableResult from logger import logger from utils import to_compact_string, to_hex_string @@ -9,7 +10,7 @@ class DstForWorldCitiesIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/dst_watch_state_io.py b/src/gshocktimeserver/iolib/dst_watch_state_io.py index aa1cea0..2e6ad1a 100644 --- a/src/gshocktimeserver/iolib/dst_watch_state_io.py +++ b/src/gshocktimeserver/iolib/dst_watch_state_io.py @@ -1,6 +1,7 @@ import asyncio from enum import IntEnum from typing import Any +from cancelable_result import CancelableResult from logger import logger from utils import to_compact_string, to_hex_string from casio_constants import CasioConstants @@ -15,7 +16,7 @@ class DtsState(IntEnum): class DstWatchStateIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshocktimeserver/iolib/events_io.py index 4cc553a..6419c13 100644 --- a/src/gshocktimeserver/iolib/events_io.py +++ b/src/gshocktimeserver/iolib/events_io.py @@ -1,6 +1,7 @@ import asyncio import json from typing import Any +from cancelable_result import CancelableResult from logger import logger from utils import ( @@ -34,7 +35,7 @@ class ReminderMasks: class EventsIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None title = None diff --git a/src/gshocktimeserver/iolib/settings_io.py b/src/gshocktimeserver/iolib/settings_io.py index 2c943e0..79bed86 100644 --- a/src/gshocktimeserver/iolib/settings_io.py +++ b/src/gshocktimeserver/iolib/settings_io.py @@ -1,6 +1,7 @@ import asyncio import json from typing import Any +from cancelable_result import CancelableResult from settings import settings from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants @@ -10,7 +11,7 @@ class SettingsIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/time_adjustement_io.py b/src/gshocktimeserver/iolib/time_adjustement_io.py index a6c626b..96a8792 100644 --- a/src/gshocktimeserver/iolib/time_adjustement_io.py +++ b/src/gshocktimeserver/iolib/time_adjustement_io.py @@ -2,6 +2,7 @@ import json import logging from typing import Any +from cancelable_result import CancelableResult from settings import settings from utils import to_compact_string, to_hex_string, to_int_array from casio_constants import CasioConstants @@ -13,7 +14,7 @@ class TimeAdjustmentIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None original_value = None diff --git a/src/gshocktimeserver/iolib/time_io.py b/src/gshocktimeserver/iolib/time_io.py index c9590ee..5485a00 100644 --- a/src/gshocktimeserver/iolib/time_io.py +++ b/src/gshocktimeserver/iolib/time_io.py @@ -3,6 +3,7 @@ import json import time from typing import Any +from cancelable_result import CancelableResult from logger import logger from utils import to_compact_string, to_hex_string @@ -12,7 +13,7 @@ class TimeIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/timer_io.py b/src/gshocktimeserver/iolib/timer_io.py index 3bfb814..bffd764 100644 --- a/src/gshocktimeserver/iolib/timer_io.py +++ b/src/gshocktimeserver/iolib/timer_io.py @@ -1,6 +1,7 @@ import asyncio import json from typing import Any +from cancelable_result import CancelableResult from logger import logger from utils import to_compact_string, to_hex_string @@ -10,7 +11,7 @@ class TimerIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/watch_condition_io.py b/src/gshocktimeserver/iolib/watch_condition_io.py index 1eebc66..c165235 100644 --- a/src/gshocktimeserver/iolib/watch_condition_io.py +++ b/src/gshocktimeserver/iolib/watch_condition_io.py @@ -1,5 +1,6 @@ import asyncio from typing import Any +from cancelable_result import CancelableResult from watch_info import watch_info from casio_constants import CasioConstants from logger import logger @@ -8,7 +9,7 @@ class WatchConditionIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None class WatchConditionValue: diff --git a/src/gshocktimeserver/iolib/watch_name_io.py b/src/gshocktimeserver/iolib/watch_name_io.py index 427c73d..1dbd4c3 100644 --- a/src/gshocktimeserver/iolib/watch_name_io.py +++ b/src/gshocktimeserver/iolib/watch_name_io.py @@ -3,10 +3,11 @@ from casio_constants import CasioConstants from utils import clean_str, to_ascii_string, to_hex_string +from cancelable_result import CancelableResult class WatchNameIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod diff --git a/src/gshocktimeserver/iolib/world_cities_io.py b/src/gshocktimeserver/iolib/world_cities_io.py index 2a3283d..63e8eba 100644 --- a/src/gshocktimeserver/iolib/world_cities_io.py +++ b/src/gshocktimeserver/iolib/world_cities_io.py @@ -1,13 +1,14 @@ import asyncio from typing import Any from casio_constants import CasioConstants +from cancelable_result import CancelableResult from logger import logger CHARACTERISTICS = CasioConstants.CHARACTERISTICS class WorldCitiesIO: - result: asyncio.Future[Any] = None + result: CancelableResult = None connection = None @staticmethod From 827f32bf967ce2285e6cbd64a48bc03b01077580 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:34:16 -0400 Subject: [PATCH 105/123] Updated README file --- images/pizero.jpg | Bin 0 -> 606199 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/pizero.jpg diff --git a/images/pizero.jpg b/images/pizero.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fab83a5b29f2b733045eb01cb4d65528925945f1 GIT binary patch literal 606199 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πI;t_(#fH_VS`0f~*dS?50xJTEkNQe8xak@|o-SDDRa zB02d+(0I>U`r6{g&s2xzD9T4nS1o(+t4+L^IJpsw=V%q3I_@gRsU)ST^ToA{&g!ck z=^WuycQy3)!`}}#hx{*TZ7>32rb#jCPJfj*L->86=u@rA#%^vG?!1E`e+s?g9}(JU zw!}MwDIY9qc{Jr!)ON6&QATHtHH1hS75m2_27g-fmLxwXtysI%E;T!*xtj{Sl}|xc znB;?mh<+cuY|>jry#`OXA6nw4@MZXvs#`l}qJhb;pzQoX zrd_Bja}T&CtUj-!TB(umbog=3;_I5tRGQHBIimGP3-IgV(*egYK`;RYH`f zE6C==V&P41sVvt&Y?RLVCA%Kg3%4ib%>#jeDBJ35xho^*E7X-qU5S=qlA%YXG&{on zY7iND9MiZU;Ab3~f>Ko@$q4;ZBYnZ}5G6y2MJBurO*jhP2WN&KnC~ls_ z102k+kKr|b)5Q9`B#|!l&qq909b7ZL;(NG!d~Io+P4B~t=f zyIZ*#uBSo@0=NMG09xnQ;x?la?KTiQj)bulQs>6rBfnCSwY8eJ8G#Eo=4&NJuE$fx zQSN#Uz2Xa9BG~zpD!JiMbv5PpnuPk5(Uwt&vz1=|09vdqrJ8dk%(717tH^RqPOH}g zCc5cS~U6BRtZy5@U0(6e6)vxA|8^k0rN#L3cIDFw9PUsZ=|I*B!G-qTx23(bDOjFpk_TQ}Oi`)mv+p7h6DWudMq=U z?Lg=VuQ`qeLWQ%CbAeuirz8E5I3Vrg@~xmcH?hX+v5|I0eo@YA6JYIjA=O^UfTXa}xpAk@3a z;+2LwaO6-AT8QLilgXeq2PTeDTyr_=N~3=pGGt?L9WmOO=TlBK5$F1hS(Jde zHIT|kIUpX@(Q2@RA;CF4MP&Yo=t0LF z^H*UCm_123;+vj=Q964|%eM+uusy3{+U?d+=1KzkS2=4WuO1>Beq0>X&u4QeO|C)i z0QRm)JF}rHBeI8Ag$V{#1p4$fI_s9|yL{1}{MQ5hmvqbXJDeQn6n|%2?&{#+V4U+x z!#xf?ZU!I;N7p=5r(L#>?@FNkMS0X#mqhH#01r`9eS+fyG7q!17v_YRU70!QSI}N;n zQpcc1GGENW1CG=PwSD47m=PO(RnOjB&m_)CE$(Zfk4g%pgg*J}O`A$Ge-Cd;0Of>| znFH=SanRJ?Y?3@G9A~|2N#WOTm}dvDqTj;uE2}o(3vf{xAS@$x zK7dfV71?6K83N=MSc8NUkl|;7SLkPAiLtM7{%YNeCV4WYcfUeb)=# zrRWD>*LKkV0Lx6DYON*Ya{br*>k=I<>ySf!RdPK#Kyu32tYtZ0L~979wJfL(!1=3z z+cjhNVR@69qV`UzL|}&MDg?EJqMm;MLZROx|kyfI% zl#W5A%`oMOqy3;U-#+4+Z~N7MB;%1ydvnGEXX#MqB9tOn{?Z+dIdw2Pn$9+)b~LL7 zIKin?koh8OE~un+CZrmiXbVWeN2#ojEmUV|%~rUISr-5iR;M6viK#b{rco+`E-NvgB>n%T$;&O3^y z{ethwjk)z&cl;xY7yUyYu4=7u786yrnTO7Q6IbH9jFka_&%I&)0AR=u2zvTet9>fw zG6)Th*sR?$l-au*f(ANNha;S3t6N%Kt~X;JO4f!PFU&ck*_F;`znIJSPCMXMebuD1 z4ZPyIl|=O7pXH$FqJ>Y)PG_84cz#zT%L$BDL%~)TvSSx z%Z*zckhEd^JkZdvTn@dftTxc|@{hz+X3i7;04#?!9>taIZgF#4%dv=ZA3WpIv!(k? zL!HOzUWfgk0qTOIeJa?3b_&r`?q=qXIekLrGsf?zs1CiTq4^8(-!gA6o;`c}P$xqC2AF@`hAQ;sTQq{5`+06j5QptZIH4hPUt z%#bB>TH5%!jFNt}ei`@Hd=W;8lh9Sfk|B+~JK~o*2NOjYRGb>5v!EY(kF}uwF;&ck zW?b9_BTA#KXT8=-5aXdeYMi%CgM&vh3o~J-MeaX3Z=Rfd!}G3A=JHbi04p%ZTpF+T z+kwv`@u_keM{DOVWBSx>I0N3erqyPN^3ohr*IImX`S+ye(D_cDYt~%g)@9bWEIHaU z_*Es;Or>eyk~b9uRQp%he5FbJQFe;oCvG^X2a7In7^WAd>Xut{X$us(P!l#SHMVpo5--@h@Zy+QfPzeH_wwCNiPIxq)fUIc8;wFFL+Hup? zuP&?z2L$Ju%eS+)gy1M6J?hddYPbLaSjtklqKYr3tQd44`VmsDsTg1xfInKsmv3SL z&p52PmPJ1=T=gc1&EIkIBe4F{LBVQO)gtw-Nkru@pk-Dk zZB(AxL!F|psYm;S5lRpo*3B6wp@h~_V3K*JCZ8xIg-{Q0Yj~hOhL~dnbm>!J+{G4C zbjTl#32!uH>W1gnA=DQJtmEd|- zMb5th9Bt>+_Miqyr_2r%XX{Wdop2<{81^)y#4!$-{AyqLNns2FCVrFwVhA2K!xA%F zFgQd5zpZ0MuS7_~uRRWGbk*T*<2mVy2V-$%QUyQdAXYE-q+ozKsS{I8z-}B;3mYMa zt|;CsB`?vA3w1Rw+Es@VV0~xDWIPjJJZF>&cnOU{`zz|#SL8VV0es4kZo z%}6dd1RRP&CkQEV#YD1$-ku(S8pjm_6WXS6x~r6s9u8?(cN@8bb5o>%^)(TRit|+E zigCiR;+PsnRrRIw69b-W2%CVwFg$muJo|;`%4`|{+1#hznsL&yqn_j_1OZkSX?P9D z^`~GhGILS1W1eXh%MNKt9<-VoWM&n|98_LV&jP2)_cXvmbTylZ?lWM`FPDmT(oYoi zPBKkCP`M5cXlU{(Vxo<-tUHxT;+SgFAgG!ETREnp7b6nmj`b*)Gz($hnsBz;(2^}F`AdlVcMg0$0Sk$GbTRirWx2|b~NIsq~ot@jIMffMaDFqN$pGxgHJKN zAcXUiMa5!Rra1td4%IQbU^uFbr4$-(n~th*J*k0dub6)i>q6gT<8S6_i^?<86%3aJ zN6NYMBAOF5+U;@3#XxSpY=PdhMcE?+REai!hNzQX3+xfQrD#QVjt4c)qcJ~sin6UD z<7no9H;n3fR8Jz4$*j+`$cxHk)KXo@bA=$%0`!uqWag^Lsj3b-)_b&$FiH0`8(qti zbL~#RO8Ubb_WIUlp?+puH#}7GSm&!B!l+)r(2S3mRYyiAv59hUAB<#iSno3^JRD~S z6{~j1C;*Hyo()xNWONG8*RZan&PTaWT&Z7}f(NA}x3YYqGNab44LKVibUmnR0T|Dg zFguR5R{@sp<+orDe_E@n%FS+9s3U_`B$P&k0v8^&n|Y|)lmbQv908uRnz$USfwvV6 zwSSqa?i(kX+`6*+N6!RDZ*h@XGb2PuW#_$1L%9OJ(mCRgkWPD0!*Dq3ij0OF9`z$0 z+YWawNaVpPy667!tiP(u`}4{ zZNLFCPDtk_wXM!m3j0Vr40Wvgc$9!~$GvM>!mWT0IO&?_md7k#yjYAmBjq1KS}?{4 z1cOzgUTXY6V<7YCSe?<>MvOAnZRMHg1B%#OWbv9FB_M)9IOJ8rqlU#COt$4*rUL;` zOK%~_UI(>xH~MDu{ni5!)K@!m4b7{t!Q<3q8ttc9Ov%NfgYJZtcR2Q{hV+>>q<9$W zPc<~|&c`)VVOApw0q>gK8M5qm0oM`%f$LIviU#E-s`+WOlyRS}APj+W!1LO!;vY5c z(Z^F&;=Gs52X+soKWZ`++%r}F&dS3Cdm1hlHPZ4~1_{XY0;}9w%`$m_V~TZ(xN=85 z_^Y?q`z>~Pdrmnfn~l)=oUDpgVx(ZGu9w3SmY5HibIwOv<=vU2CkJsg)cAHX(yttY z&3W~7Ox`T?J7O9YJpMIg3Z-a%P`$g=p(f$&TqTnOkxXJp!8Cz}G7UAFw23T&L6Uf= z)cm>cnvy}4JmAzLD~{k+^mjQi4$(SI1(eRJ%1WN5w>7~Z_G5&=IOE>AtsYPGgu%e? zTe_}(z}V*%-2M}lKXl+^`|Nq^-jFcko@!T9BjY?0Mk_|k!t&qXt3F3SJ!_s)QQXd* z2~FB2VI`vkB&1+s5yV6efxQ;~5Frb1ep;b3xDqxzAF^_;xsH15ID^Bv-H90+LfVZt} zbArLRf=J^u!dP*PobqZ+Gd~06^fh+ZO?%luNckrmQk2wIrj+QpyCXE6%mMYM80F^> z$jUpa6JD33cseMNTHq-CO>`0Hx^!v)whivp%<&zMLO2C&S>k?wmH;ri`jWV*ep7%B zc;^Paj^o36P1Hpm%>eeUH(c-|Tcb~<$W8|^zj5qnRnSiat)a$|gMr_@8vq9^0O^`n zMo03dMvg`Mz>f5WFvqyAn7gZRZg|4oA zh;=wS5msVPS2LKfciQ9W$GlW-2<8yj2Bo{Rb89D2Xrg+sL z<0~*!!?sW1QtWvY?OfxjrVY3Nbq1_iTS;|tv8X(pV0WRr7fKw>L`y9?>rkCxg$ZW< zRo!V{4`D@DzQ8?7=RDU#;mr~qD$Es8=CI2)JJY;D;yWz@$*wM>P(V9ZJxy`Wt=@;Z zLk$=!bsHaq^mx|-1NZ)sdey}p-fvrK{R7-W(< zdsiFajXckKW?(S5ARk)w8KnC)t1})Ib6l0C?_=4*QM7LNE9#ovj*)EB-by2l2l*A| zxBmbgEFijQ?QF!6sljr`{40j|o8nuG-DX=KHN2(!$PWXW^JZh6!zAa5m{YpDJNZ&R zqwwd%%`e0*BVDn`dt{I2U0vO^wxw!S(H&TK74glb+uK|$@jE1-f^d4*(jN^xO#0rC zqE^esHn%yboLm@krnEV~5$Fd-zXm*;X-@?I00H!@X%}i^jMuGrvrkLCE?<);1cP2p zGL=@q$zHjxsuOZnXOE4dqWPCnvH%!>r>`XUH8aM|fI9k9AtCd}HFDMllJX_b4B%GN zc1JB3-c~&e!CErKZkKY#42SOS{u=5vO;#N;&P$2T7BQ3WMwb%9V;U&H3OMwyJovAw zJ+_k~A;BQ+Aos66Qf;3>N(n0*XNx{AYInDjTIo}Lo&_a*z&>JYk+Jdr0ElfaBbl`e zi9(#RJg1*(=ADQGj1$~b6_4Rts&TP=*3kM>!5L2X|QTm3>iZL zE9M^w>JMeF+DRE877A z=DNQbTlpG@bH`jTKc#bawvRO6ASC0Qj+N+`$&QBWqcqK9TcmB@;?On9&uf-isKEYwntH1s_I16ifN<8+hXz8=}iWK z7;Zy!BnYGo^&3db2<)*bXbXY|Cj1e+qGjpFx_S-1dD?|z~HjV{&wuLc|RkmZt z&IjvW(Q5mx_&uwK5dGuXz%Ov~Z;E=%mYQ6mId(A{RO3Bsz~;GZk}%JonEIOauZz&k z(W3&z6_mHPTJibOmC46`d8wq8k5W#^XPQfrN&G9&J{aqA>H6e$Z0^xYa0Yr;0I9jU zb6tOdtt7bdMSw*)Sw?Z`RZ(atT>5E~?KVdvlD$1E#{5%kmfG3c01OXbTK2fdmu5*& zK1`bN&lkuf*4;n^B6L3WIDIB?b6wNrwY`=HLawi$sH||De8A+_R2p$Kn$()y zkXJbwJP}__d^(m(pAOr*^x5fOH`!Y>k|c#Tyy4C5fy)FWuz@iQiy zD(>5#THWxoDAi*GaqCz+bIn@Q?#-R#QVfyOwWzNXiwQLvis!Y5#hYWO72qEguddFk z6h*&uPu&Nm|<7j*1CTbY6)p%W8MQFPg>=cvJ~WxF4YKaPIm{4 z;UB(ah!y0`LVbivB8 z74_RBI)$z{AddCr9xnK4Jk!f{V4Shs%A>7u)0=}ng33to0}~Q4T6$)mE#1^s@kU+b zaH>5?u9N-{ePhq^g^aA-vWC4!;r{@`m(t~3M^lUkQSwH^kZWnxy0Qfo9a-M!HZ5VL zTEiy|9AG!s9M=uwE0ZPJhz#yI$F+9)?y(M+V(iQVWBiKpd)xW1Zrb8g$_>bX9eCEB4Sg0Q` z_pd6F(W7CUliXsyy?bk2PAo_f!5^h^x8DnNYukpHJ3>!TxX0yKQ>x>mJ!i`;&zvB# zl0%hTjMveh3Vb&vi{aBX+(j-fpLtdss`mc?8oi_ZHt_zFaJL>=o<%tux_%fJ&31Z)ggTw8AyCT0k?meP8F*${AZ?C^sPA2VjpKxX?7iFo<2|c}wHJP9pF@Gh zE?!wZPAkNp4Q`>kd95Qa4u0tEST_C&)ZTF#S;+0%01kf|`Wn+-(=O3*a}Ufi12Cyy zUD55bUjD)|I_5|%Z{{V9%`PWC{9cm3e$&|)4o)1H8a3HMR8QaJKiU+hsQ-LOy0ZrO{U$>(j~{0p4&z%W5eGM zG(QhqEy}2#<$5t(0DhItf5OStQ7|;vBt4nVKar{zUOMp|@F$%v{F#|u& zx@l45)$VzCtar3lj>JcdQ%EPhN)edBCR)@1kF_cxLu6sn<_KjqP=KOc0{H@aalqCBE;u$*WOXMIYVo+LUn7Tbj!;ZF{Q4i@V#MO5ogG%3q(Adk?~^ z<|x#$89tRR&zCqj_Nwo0&cg?(#dSh9Jo=R-H+DwSd8Z1b4)mx1>}tujF<@hZN-awb z%BMcKtt?>T$Z!wz6xWU8b$E`}^%Z06(mo2QI5;GBH9A?!bBLLMJh0?cxUoj*g`bGE zYY+lTWKekzTEFnI^>~vBr`yPT7jyk8ifMNYq^-NK_F9l>7m|Rn*vbc~0<&}?^|9Sg z7g{RU8FS-b6JDuNG#1gG(8bT@O=S6V$XZ$Dca_O3&T>t33E|C8Zx&J?eTRyfJS(cp zw5_o}UMa?kj>sz4t5I2;;*GcjeQBFZ6VwCP*IWMp2v)4^pR?e4ZXe@P$KXv*87RL- ztL0}Ls7<|&F-F%h^#-jYY(fVW*TvvXN1T*WduNKUzYp%5g7U?Y>fhm1lM=&B-~>dm z9dk-;Ro4yE>t2YT5126~bpHT=pZ>K-J|9HK_m@CprqNH7xX_wB$@J*Sz>FR`kxd#z zSs%JZVcaOMRQ~{k0@x5uMPgx;~ahhkiX&hQsqPT3%TV9;jKxR3k&3)PTHD3 z3F^bN z08zDn-XPa{+KsGO-E|6s(=IuvCD!!FMrG73*Xt-B)|fgJ`kZ@s4)M><;{&D`3Z6d! z+ywyKMhCxI=%2*eEPsDfwo&flt3Qo27|9=RRwMhWNT3xOMpAeOIS+Fg2iTgLKLJ~y z=Hrv!6*KtzLsS0%9}*Gm6I5^U3r1Yy?F@hGkrZ7NsnSG|_#VbSvavq6sT08(Vzx`U zC)*XC{{Rv6%w=uvNcGw(KloV|XYSd`f8aukpyj97+g}LjYy2&q*uegj@!?%79LC4$ zYny+F>yjg~eEJs^1AIuh&KFG|_wfG!g&fPcHBEFo2>dmq#rJK%=cQVf+6ZC!6aXuS zgW@Fe$g3rgMJE|kT}*eacW$l+%EPTRIJiHA;yh4C+KxXO57>iWp#NBL%1CE&op3z*NS?BpS#rOClt~d+ZZDq2dzPx1JmENG=}O= z&;eFb(o&&{kO!?sN8SWE5>?er;hd1jrdX9nt&-J40Z2KXiF$u<+0R% zDu)}IDNSt6XzqdeiQ_e4XAj6>k4oo6Y^9r$K*l{O@w}=*Cm(4cc+Moa&V0WgSM=P9lsrC%N zuG2P5!)PVB$27w-;2qVB*R6w$5!lssxS7TYIPHqHK+1Ugd??qJ@f2lGO3$A5S384X z4@!+KnX=Mhc<$WNEI22U!1fiiD8(F=E7qx{gvpTZ>zYub)O*xV1nQuipr)~904V(H zPDUtFo81-w9%E!5t|$NkK2eMwNveWZI6VC`L(3*cGmlE814Tw%QFbt9kbnRu(~MP- zWg4md?hZS3&1YMk#FL&6YP!;SBoMgol6W+1apIz)wG^~qlni$%0F&HRTey=h0}^qb zm2DhM<()@7@lf4D%!B}?NIB=V8XjzZG;msw2IYVm=cuZ&LYu*0D_2v6Bbejm9Whzp zdUg6$M#t1)+vG*zDA*MvPyokDg=3I8aEdwWR&0Sxx0YYu6+F)?VEJl`^{o-PUOP6B zi6n4GpdD%Mfn8M)eQCeF>SS-g(s_;MZ~#3zQe#I~plPWxgChcc0It^CN3v7}l%J@s zOT%)o3ObNEuFe~bs0RYDdNXyZ5wxpA{{Sqw^%URit8SZk_Z4krQYqWBQ*qd*{g-S2 z0wp8fp1OUoQapqQ*j1p|=sBQd_3ufHg=}r}{-}NxGaseHJP{IXN{QUOl{ z3Sc0O2o6Z|Wmr72-Z4}9@O!o!8M82h6?N?)@;e}R80K;HD=!`F%e z%xSZ??t+{4TUFpE9+;^M=9AyG7Z~3n0n#z~Q%o`TQBTbqg)5HaYi@_IrTa2>8K>?P zyM-$tyCU)<{@|vYXvxT4YQ}h^#TG$!R~E4zsyfq_(gFVfEX7V1mu(h7%*chcxFCp> zA6!#}G3OyhY1pSOX_6>K$K7AbhDATZDatsf5t?9EF)#NDKO`GGtIAl|CiBB!L3~o-%sW&}#aX!DHnW z9l5TNblXJ7?v&%9BAnKcV~E87VMTp>Ps~Ot*u0%rEOYb~blM>3wDq=7IT@v4+|L?> z*}y_-%HBziRMoE~0nX9+QME^E23PxI6ZZ(Il5*X6rx2&LC@80lW|*u8DE$Ima~)EtH*#DLQ8W=AGxN=YduZmACHITa6O#Qarh~f!j1HY&nKK*5G#39$_4_ zWAUT@5#2z)6DS{Aj%^cBLHD%8RRmIZvMQnLw z`{K1NG-;K8dyl10D-L9Hlg}g|kQkhF6_+-xb+qRSqt?5rw6w-HWS*Q>J29Sjt?TWE&l*`L#f^9DfZqK zh7-NA$2|zGSnYg)wm86A&S+?eMBsDj%|`B2;F{4Jk6*_X47P?|qwy7&BW8)1^4+FR z<~i+wP{S#fLRp9a)$6S)FgIbd^{gx8nipR!u&1c1RBk6b9SkKn!4+%dVh0B`!&_Zy zvCPT{+InOYTlUu)n#LQ*3{QMwk720&s@G3;{guC$Y9y*+XTEFm$Ku;{(dQv}yBHi*a z0Q(9ZfMuVFVVHd3qhrnptw{AaUkV&^-!(=*2*6nGb_W9lcB?UXVIljnIVAPYDj7+Z zW>~IcJNf!n9nXi7W+XQUu{F@cr1@k0VL11xTFtT6kj^c;O*ekf3cT2=QT)IIaa>Cg^Gs^2Wplbe&!4b6!ZAkK>i*_ z=et$hkEpGPZjwx3)>>#Q8RL*D>~_Ko1wWlj8GJDHr6d7V z+CmK>n6Evl47hqzNXV!baBbb46$8V;`+Re%1~nat~aS)|H2Iuv@Hs<^cPeu(y$IA2w@_j$5Z6f94%? z%}SF@rwmCv(P5oiUdFufibcJM=PUvAu6b^89|V`~D!i8t#Ngo4upL>si1cuO8U)e* z0C*gG*B|zhgkWTzbDC`WlZ3z}K8C3wHg;m_HP6f`!sHBdocdRtzO#0Xfcf;urCny} zesXh~e2k8Bzxz^_ARd$k4cun9W!B}$W(Pl7u)5^S^8!wL5mM>0xz5MQ_Mpds(z#Ue zGo}Nhegd!Cc$yb)pKuO zg#~Gd$$L&|%V=@UUSv6^1?)utP-{{88ysY+s_QG6wKwvUBalc`HiuauzKXyiIC!HY8u3ME_|{|)_dGTCS1!KlZZYy_7QnLmOBsQ1Q5ob-)~II-eWt20 z*fxTB6_IynVg!N@wrj7{;bi0~Ae!ZGCRLN>QH)o83hGMC&TzJ<&B0Pi=M;Ie5)gD4 z$E{h35z~W#Op-W3`^2}Ub=?_QYLCp{h@IaNK|~(yPlmU}W*$p&OZjKz|OE4s8uYmfkm!)w=puZQ<)j zi!vSq0iG+L(k$9}Q*TUiF?q;PxH zi2EAkMHYrzy)28g9z`%e6xWkE6?YRF$FCWtC&~tT6G+D-VAG;pw(MJXa$H-5y>(2_+&H8Deuw78%t-;GcSp$Pa=r zPv=uxukV))f!mDNM7BJtYV%0+j|b^u2tLru^B#oyRcwoEew#^{^}q3$jd*J61cF$6lw> zy3ZZQ{+kBH{xe*o9OsTeuBt7#E1m{ADO4e1L$2XncY^JF>+v?wLL7hvas=)jdRKGc zNfs#`4^z+KPOgy*0=+}fCX>m4l5ha8n|>$juc&LEX7gF2UdP(LjMPbMCJX#S74qMX zZKRLHGjCiI%AZkORMK-j`1~g?B!K6pX^9{tW}50kXB?U%jF%beMmQDRlChsNx$oZz zb+d79Z5@dz!1`C9c%Il?X!7Tv86v#1;LVGRyNPj>*^Jk&>#ULKa&I64r=P;Oo|1Mh zrpJwJ%7qM0-kj4@JDG97J$-5Kw`pu-l4>|e&q2Y+uR=Q?IbHk3t2hkzk)}d|dXrwo zr9!aS#sK~h1$ewS1`C+v!OFNG0oJ{bMY zAA0%vS)K404E5=X`a9xgg)XC`O7X7dQMi5_*Ur~aFp%S}af;4^SF!26iZ3DOXy?|n z^hxB0QMZydWp!?==~U9zLU31%*G=H<5^YOcwSoxC68``>$7<-CT%EWcb>l0*+CGsvp{eHD9w3?iZgqvkO3&1))b=Lv@pd@ayHIR zR?FqoscxC?O$tsxXpER_fQ+BDgCiq`Uhc_ZDd6?RbFO*grF!qg zzXx1fUQ4Lk##%B6a0gF%^2V}u+!asOwWTYgs%i8p!lbty>)d_{LhBvb`HEz7j{gAX z73F$XhjDp%6i~!nn;$KGG2mYe{{UcUk;dtXTn23Q%|&S@?1k`0Q%_uAx@-31`d5rj z%6GO2$vF0}O!3C7w$_FvVY&WQ1HE~CgfbnV=jmGE*6i~!ve6=}e=MBm9^SQ~XE&33 z1F_171lD>GuanMtk4mu2Kml=&Q(Y5RN1aMmmCte0CllGB9D={4d7s6dK3TN4kS;=y zax0?nUbwScEwqGrk&Jyut#sPHl@6_B@JOMRmlfv8G|!=>G}X_KuA+5ddT~%h3E=)> zy+g#m4D~Auxf?2ngDx*J@ab5!Wc)A%|>*XJ411O)}KEGP(_5D^oKGBs}83@KJ z8GF(R%_Yi@JMmb1?O?|bI3ynY`qC^AX?Bd;zF;{dbu}jSpAd%45p05cW^k*3(kYQR|v?kl+%-gXv#A>fRc^(=XmD zn|HuJduhdeA*A@G%K9V{NU0+X;F{66(=^RZf6^_YnSE=CHx_%bnrQh}4K`_{^3pbD zZWIBYYuf%8_!?a}E~R{=IR|2qiteEB&WULLWLk7;-ngdgJ|?iyZSyq9t&A*cdHks6 zY$Y{q3AOD`4K~70GC-t`zLnxPmqzyXS=;!}Us}K74-n7d8;*?~xI7^}YaAg_&ra3Z zLY2Mdc$myem$?yNX8;kJVaF6~+~2J`VLbH}(s{ss13i0<@eK3QoKKkCWg4{u84twWpMN2PHh!`wCMmBd*C1plBE9tD${?6ei)4lHmal4 zY;W+cM5i4OT~>=%MYMP`PWs@^Ht{0DLYC=GtIi(gQV<;ZYIv<7N^)iu@lcAr^)~Ny7rwb^Sm6&qYYOIL zER1uJo+=Nu%G?~&3lYxT*J_QGj}E-$QQeZ@b}mls4v2oVzGJW;FFy3_ zV4~5}cyGk-r#f3)H^>hLy*AeB*HVBs=Q#S2L5s%!!0jxf+G|vA3t-{-$ldgD*-$k@1DjyhB2E4NW z09v0@xiZ|zjJFHe3d)!5mlGG7Y36>-BbGm{Gsu@1+H>1A(N2<%tn=|0r#&O0EY9K1 z3CQ-S2GZCZ0Zb6f?~hYMT1wa(h!xPRd2@r1pkhWWz<_wiaZlX244f6@8ey|y2V9C( zvu)m=N;DiG^HjO>u3HERD<4{=CBbGPc&i^_PB8iW zX&T-%Y>;zZF-j`Q9(`#}qq``loO6SoX-J%pzt`HXWanxF_zDDa^O#%mtqyNy%3fW- z7|#_d+em(33CCPj*u=*HAte6*DzLELlf}G&PhXdVMVX`^)}dwMJzGs|EXB}$(EQ+6 zPp5oC1|qkLra(AU#!u&5)Ouai>7OOBo}o=i7K46B5ZXxRxeL;;l?cmpc2mSvj?CHC zJa4Gpp@&Z&V?+0(I4_UsT(dwVoX;!CG|V}99I^dtbN&&HRg@pHxcZD5dU$J6zyiur zew9$5qp~xrh^svrfs7nuG&?a(s-KN?Y2h7N`dc6P7AnGcCsb|>N)P+hr!0;?XC`tY zGro zk}?4;>M#4NlTM4_@}qNk$EgC2R%;3^9&XxkBMqE-W{_#IE(whf)MmX${uS++zT4lN0Jq9?i3BNp(EMwD`_GRrUg=NMpAg5uVtuQIEiyJYzVO{=C%V!P+{I zRwf738fu@Ioi=$XiJiV|h3ri|Vu^Zu&Ffyeo)yv504 z5WSJ&uVQXz%!P;@0@by(WkQj|As+SYD`%uYG2~mQ^*BGyk)+WhBQ0XSnA=ApA1;=; z0# z?4#WC1krB*!`iVvfk~+o!}qVqvzO_#kLO;B{x$I85BUf}-|me607|ak5IjCI7U|pB zVl*fqaEDfKJ#xZON!h6K(O7u$jN!II8F3WZA@e zNaLY1fAy%eLHiZda(q6#D}yv@KD9dhJ(oB)QGxC=R9oU@={Q|7AbsUO;ZRBOA6jGb z*x7;p@g|RSSD=l>_+SC$OfuSSqyE$n|01{TUSICqGuDkHVTNHubdx{sz4FNAU))HT+Oq>Ql@Z z{nl)MD)d&kklB)_ZyiN6bV5;**q{3kNQp@{Pyy=IUFm{;1o$ho9@J!ZV5BA3&tvPj_0yM$CumjM@ zro2=`7$gY5$FEun1#m)ueQ`^i%j-|E?2`De!?yU{s9NK&L7IkN9e8pqf5gF9`XUov zOA@Gkzz@Ju$lHk|4AIU%txK`$hvE)^KjpmS`UqN~KM^!<;9HglrX$69b0|4%b4ozm zp+*}Nxyky}yB?1J024Iza*Jbl*v@`YQ6Gucq#c@N&_0Efe_He4IOD1BNMk)H=NHy$ z9pijUeE#oA03POGYBl(iagxoaMgZ-+lUzEX1Dk>zY z)owHD7>cOc=Ahi2Qtb23?@#oqBtaR&%)ItJX>)AKFxmAqT%Kn7mL%2h+?|(`WDmYv zlUd&U)c-{uMw8WsxF|GV(dXfnBbL;JCsIjZut_f8~;#0rfS@ zQnxO*E`=G@dz|I9#2r48o3o$By#qycYY6esC?BPI)Lqfx$~?6iIo}aPUgTrbrDa<9ds4gF(A&sRpY?@! zu9sMiTTq9wW6o=$vAb9;)kxt-09LJB!O~Nkxxq`}E2sf?je`!{^HD+J>)HNfkEe59 zl+t~rH<8DorXX0yk35sZ_j~q{x&1RzFNH6TSfZ#sgI8z>`$kCSuVer^ zQOb%~c$@^D6uE&GN88BA0MladtnKrb3P&Is^l2ekpbEq3Ri52Z3C9$2qP>DgmEKu3 zw2q~LB>czLs1*aL#c%k8g}ao1IOr>vGnf0ogWMX*QL)J_8DY^jjB?(z-HDDzJ?bTp zzbpjBO%ZMfENeSs=5sO)zZqZ$jw%kV5|sH^`ykoV4ZLcnB)7S$C#1G`nzm&=xdSXnWpW*pa&U`tsuDP29syCA&VqX1j2lGr-_HHRAGu^5-1&wHJBdt zBCt5*R!T}o6(E>_LXes?{!`wUAa|_Ma>AY`&w6~qv7!h+N`6I9j(qp2#G}@o#bRbO z+GhOyX{=iuQ@9Ui#YANt>KP-Ix;0jjBwptxkQeu_b`%Fp^%c(DM{-*tNA?-0Rp*UQ z%_ARrKy@X@pv@-n>N8xhy1e7&Wfc^ftg#Xcu|4Qa4zS7r>M1_Z4*>J^t|nb}T%EhI z>&;S=T)kiKbI|%z26`BoamnVMWKcfx{&nW3#9ERA#`WxaVw%1n)Y$F|$DyECJtxjy zl%ha;ir``K2Byt}0;=P_O<7HAQkiia86C(pwH?mX$h|X0RP;F&&RI))G5ON~_VlgG zXxJ#pqQP>;+=^j`gNl`UQ@G}f4&_fQifKmgnz#ToyFl$y(C$&#!@WE)1NzmXnLQ~A z4@y=UTg@tI>vTcE6!Q>0F`93ani69iE>zUZAa3;lhZ!{WjEZ*?EN4CGLW9m~H3SZ6 z;MJx>AB+k?#U|=a#+Zf2Jp~~i)VaW*wIPs{UUHz*S|o0&F;gAA>A4x}NDAV@-M;id z^O}(?ErG~|e=3)F^`p!kjXQ;g8z?s5#s|`zEnx$N=7y93_t!sKXPgi53Rgj9NMKE- zs>^A=AXMIA&stLW?kQabnFJOhEaj@ffpBq19FtBGQ%wb#M&nPGVT52SBIm<*5|TW` z`uDD!I3k|1DC>%#vpCQAMXwQoS%(9<)Uj#0lw^&Hz;`v+Z&SxgQS((MB8e;MNtN^z zJa{+;nYSH#R&1n50HwgFw+~)v-eBpTX2n#w&X zF_?F^H!*_9xyP+zzOQ>5kKLSm^scU074wW$V__3@QAiAneOls7ZjTx5io7q|ZzBe* z{{UyEatAc?WSGJIDqY59zN+z`xxh53tFvST=B>V#81y)#8e=K#`BA78n^%=TgyYu~ zN3P(V;j!AUe`hc}0BRS~nV6Fh`r?`ZU1~NTbp2_=TDClH!S7X{N+of$im3W2000|3 z%`r1!b$AZ}{{SkQJJ@C58s?_bT}Q|qbJnP}jpR?c8MEt(VmoG$al;C$IVuSTxk&CW z<3BWvPq?cCRGI(}LGZpXH*$T&4P0gSo>hLFXV#v#QZUBTSuL!5*fEk%wF|7FbCAjh zwPfQfl$tkEMZoz;r+L9ndBtYMsK(t|t%4;`P~;x8;+otphsk{yJ9l9ERavh7Q-=Ce z-p~`0DX(H3e(yC`10roqvtTw2RcnGz`p{3Qtw+(-n>#88(MIfqY}FwdjWxm(lls+p zE+^l$UkBTvt!XsEfP{`lHA-zh;d%1U;wg&dF>@(DF~IhzlIB1*@JGEz_GyEB%Yo^N zk!|J2%NZx!P%D;TpArM;D*i($K3_S;YaOAvjdSI&IT*mHqkE)a8a5wMQzDV5(C$D~ z4xI&75SBRaikb$LoM7|oQ+aMWA6+=11D&1Ju($ zu|$NGBpTKY8A&~kUt@L8wMvnKHsh^q$)ynccAWa+rcE~+M$SRx`iiGCM=LSnwOy_G zRk39Wj0cf{9e}M?)A#o6P)VlBVj&I~V;QM)Onj`UmXJ#L65)rfUV}%C<1QHqJ?l1o zHsCSH=h)QNwwDnRhGXs8rO14ypwKPO*(8*b1~9m%{{Uj!2U4Vr9=WC@7b>7Lu|28A zIiqZ4kG?8fWhjyjI7UHNIQBJe0#oHY`mW{{XeGQSj*4?0qWKZVpyEB3rIc=Rw>tT+CYhqvUwVJ&jsA`9!kEvcMA63TRg^G2b4*!*6z$-iCs#7S5@diyV8ni6J!^kQ1zda9Y>M9r(nKA|IL12> z*0pUFuuu0zQHYO}gPtn%3`hf!&Umb>c~`WJG-VN=kYsnMhuz?Gs;GWkbQNg_%sI%c zCbd0WJnoAsx#pkclZ+1h)7Jq&;+_cufl*_mJe-BbI249F1IINY9!^a>;P&Q|11jp! zO1(Mvt{21_VTHWZLQtGHv9C&HQhBPkb}(GTQI8&#F?M$;GsXnZ6BP%KN_$)(Ae861 z&2`$pgB{(awg8?^J!_phCBhG$-H)#s#dpH0XwAgV7b-J>&%H8BhIGL>J*v#wY>Iy4 z0(uNl7Ljox@Qgt`8n;k6N?{2(AYl5{+bb_Ih6h^Ov+(rNB8gC_9nEw$nrt@80A0im zwa-$zTNa{J((Js1S7C?8AP$wXoJWl2lV}4t>rPQza+8y}RuxCgJJpzu&_9(#6b@&!CzCq1-lvJ2_zak!4BLZB-hMZySv>;$Clhf z3i`)c)BfFN@qx<<`LD$q1EcAgjT)Y4A~Xqd6+1$9bsv5Jei>pu_Kj+Rr9Rk`#xlbBgu7 zGWIL$G?5q`!y}sF#6{fpFmp~8K6dz%XvyL&%%^D_99Ii0B*t;tzMAp3fkwY*&u#+D z21gtdUMq9peO}UOBa+Ry=t`V_Dw`4A& z=zCUAhx`G3EyQ7=A&*Abcs1?58}RHp4S-XFDIYPbsUI!dcW6X=m0r;0$`Fu>-xB^L=E{W_{j z==mOf66GZ^%MnIX$Rh++o`vCC%|`7K7@5m<9jodY^eras_s^%o?fv4lBo=yRksCZP zL2DTM&w!)ztv#!;ZO5^b;O`4X;hh~}BpH|nkotQMO2P5ph$2|cj52PLPB{J%-mG|+ z;su4gZ*8Z)+NI@5jQpVeYs}}lY36C=JEd+|)lsF+?#>)mB|VEg7 zWl{=C#`t_gr6b;?iYwc4j53TluPX6J!Uw#$lJ81%4$ZsEZU^$GX&yGe)55LF8KMIj zQ_XgIcaJoS(5hsTDGwW2anI*mZW4<0L zMaN3&rxg|Ec{sZK-s;$;G=p%@1JacaMgbWk6iM?O06!XJU~%Y0Y>~p7BTI=PxD2jT zgT;D(g?w2I@uj`YinC*pp1$?v(l^hA&*Ml53V{OUYL_7itN+Imv*+nuMru? zP@=gdLUBE4V&K+}#`cTg%@09uGS=UGy`E2)iabZ+i%k~WYe)?3!bYc)UURMZ-&ntu zlHTp@ZTfAAMo;66isl;7Eo#aC6q3_WpExF$Z8*r1}Uk1kauHrp%3!6&YI)Y7ona&duCM5lQGbDEao zB2XQ?(;*DAzqqoUC%0m
6;>0Xba{6Ml~Sg&_P{jxGYI`bf{+;dCiZef9*dRA2_ zMrTC~OzG&gN50zYI(_1=lXVmB=r;61Rp5;Ynh%&t_xpZ%)AZTGxtSj zSXsqq0?O;oI2B7#ylKlS94>hky*es7^)Rc6b5>d+9Y<4^;!UwiQa?~RtoGd@-0n}g zrz}LEU^qPuScbvoQSzMUgIgtIf?Uj|3q(#2UW8Q9mXR=b6X{mQoXWvlw`#VYR1xhF zF5ogvFjVBq5XpIAD3;zvjmJ3^(doYt@9hd0Iw{{R$j0sM_~jdEv@qK3df-J)AU z%6K3i_^hW&Gu<6D zO5C8jw;h0~rLtn>QU@e)!V_8jUMSgOsm#<3MZ6fpl8r{Pl znH4R+hxJ(j#gwh-h3i#zB|#MJ?d{nx>PbF_6%?9aP+hnkxvrYa!&-@ueWKChQP|ex zo*skj;35$H^Gu~g^Ms4bBV!SR!5wP+dZwiWWLsa{A@x@O02`yl~B#?4Jr;9_6(!D8s0b~Xq?p7a4ka!1795l0^#*S7$VvjKvSv-+Q zY*W`c^siG-0_fnK-g^&oQV#`aWBypkaon8I$oq$~Jge+0gO)hJ&V6Y`q<&igf}~)R zUa~wRp(h5{IrThLtKp3aN6TXo9-FB4er2ehLM@_h19blFFWCA3t&)3+_BGM;cz^=V z1;=7)RMYg#{I+l(qS5U9$L!NQXY52Dx^wiU7OD<5vl4m%Ueqk?l;B##KMIsb3XCif zkN60tpe02fDm3>zED~qkO-MAGqH--H&#wL_M5N5q=)(B`|IxLQg#^WcYVN*6Y33l$??~Tq`+(V)MuTs z_WVsx2aEOc;a^iYJw8AvvK(r`o{GK%(Yvh8^=f+f8$(hL+2lX)D)V`KUE)?!2CPOp zZHY(ptmpABh-7wG)usezBw&9kYQvRS$D!;C;Vl_PKFUr#O-ug(2=0!G16jv`{q8Hp z4!Nti!|JyzM{VSPDvfnJ*(57H?Zbo9_pOiTPhop#9^d_+q1zw$^|e##aZgpz$;gV& zKS7%D7sSo`$1De8n>~% z`j$~%3?NSXil5;pik3Tg{{V#mHAX()$oCWCe-EhnbqhQX?vQ_#R(~335jg_+f8Ypf z$5&4WoN@fA#@t1cy?dNgxgwQWc0GDe9%wPfU9V2j+#xlYC&e8IF%gTII}hD5=Df%K zYK(wzc%{mqkVxb=tAaYE4bod|MU@Oo5%p*<1f;!~X zY@0^qqnJ*uOCEyX6C?l_^z|VB0De#K6g}{xbi>gp%uaT%)}{Ck5N+$#}RUR zp0sl^Re5(iIsPPS#TB8kwOo#OF(iK~q@NRY)?yY5L(fK1f30!vBgjApHD);0AQ<&M zX>%}Dq~7OKH;?>8%aZm{5B4D>kIkz-Um19oQ}XHxqdlSmv3Z%u7*X$2tKb2So#}J1 zm1%b`f5K7Xg2bIxO!_LX_)}9|@dLJBSi1wb3dANs3o4@@^0=+G5Lv^j(=K(@PM)TN2sV|yF?gW#QIUp#OEeV@u>h7a&z6Y zN|42ne6`5xNUF(uwMZbJttZ;D!wJWFT7}td!YRrs=h#!kgUTSF+_^E>>JFGtDLg54}{(R|?87PDMCFa1J>FfaNZ$;Nh@FI@3!jILWKoj-Iru8bqbH41v!z43hbwMm}7e=e;yljeibI4y=Kc^M%h!^?Nu)&AN!!s_;!~9gdm}+Q*w}gZ(;1$iX@0sF;*8wsJ>8YtZKK6xR~8 zl3hkO9N;P9l|CM?M!P}uT+}$WOQAOQJnzeFl0nS|CSlNu^tJE|0Q}dCN3zt*;5|GH zHN>P*$iwQ=Jj5dg*g9jk}zGsd7f?t>AZfa4bOi9d7pZ0mLUoEA?zcX2= z{{U%}RA*Pwqd)Qg0AdgQbXqx4OAQsfJdLz#qN6Y{K7>=F@b09?KiTcG-@SUfc#}m= zx|OfcI5i^bwzp7jx0pz$p;~GsDll6!#&4sZ*cjR)5ywI?SwR|I!Jif0_|`u@MP*Vm zo=tF~)%SD2CxJ>z$1OzEh=q{P`rLz7MZ771yz$iYQ5Xt?&m+>E6Dp`&bnI#j(y-@^ z0`BAb*Gu6R*?2;Z$2HCX82!!%eAhwYc|5&9?p%)8tBWcR-aB1dL>g znK5-ki>O?2-n{O33Ayr5-X|32v9(q2Bcom+Oh(9V+4%Xqj-kO1%g>6kSS5q9c#}gXxc-!I2GGMe9Fhq<`k4? z%tFU*dVAMJ;W7h~I+iugf(c>9IO$y%g?zC)yRlWlZ5Al)csBr*e*jJMLQP-Qx zTNtGyc3HsgI|}tF3Hu*jFl)oUA;jO>dBMiP`PU63oUDB#+UJ?PnUJd zg70UbA$e?Ta1;E5<$)#(v*9 zh8*lb8JmuCUfXpM7C2+hImLPP5>sbKL(H{2E%b^Q<2Bp(eUbFY{IW;@XNuzWjjO21 z$0YZzzrzeol8&5LsfXC`D(P8~>noec*qi`yT?UyNO%k>{RtB`czl@$MOHY`^7#p}E zx(wj$Hf-InhA)(Msut22GoHDpnT5b)1fQ)|hE#@aj7CZIrf%8^RIR`wmDb`z^0v|5 zv?H>PQXSa-6;}4<2w%$*s6LsXHZR){B2dke2YQm>14Kt`Ry3E1Zw~U~9`yTtQagxo z<^Vm-A@ie(@j|RKF#{xW)yc@qBZg6qIj)z)*9k4z*mvafisj@4GaL{-#b+jPP3pm2 zk&b_rJV*zB|E*E0(b-UuDuRcnmsyDN+JXRQt~SCGTaX8>SI* z>}=$WoadZY3iUZSBep8h@8I9MXu~S1<+;ybGgAw&#~^J{*ox0We;Tn0sEc_en4h`@ zS=vs`xd+plt0Qtp@S2uaB=QbDDhBzRq4pHO)X~rhI+90DYrM38v?>c{j@7|wLQL&N z0FLInTN_P9qC#Z@a2+|UX0GM_LAGIimlS`C2nM7JK zIqgqdVh>V9UJ=v6fk!BF6ve3Tnw@ROVN-x9*u^^vHX5>0lWi6i$O_X+;MIb( zo?d9M$a_;;nz7|jA@54VxlNS%R4k^nyozbJ%?$<2qBhclSERKh3<`)@obpXBQQU(W z0-Odac1^rum{gvEm4I&}y**ul_N5UM+N4`{Jw+A}ETq(nDWzL%)QbiMQV=VWJ*nXp z`haOxI(S@D5YMy6{lI?;LvI)S^IZKZVM~f&Q+p^|AjUCJ9V*n4e3cpNf!4Ij((M!o z%Kpc-$NHuGslV7(ho32bAzJ%IE(HK&jSj?hfluL54I<4mwgukMSie__D6wNe6%|jUxd{O3} z^&yKi(+x{cpvD=(^`;xJIjKw_jz={awkMz!9`Q=UKGZRub5C25`Oqv}@zdU{a#14X4#^#LTj00W3`y#s~uK#JiC1{TH+xo z-LQo|wF}rrbMp16yDQx@lUTVJ0gvEoLf=uid=r!S(>}oh<0GfNSdKJ|3{txbBFf&) zvjsVz-%7uEIrgRr2Wo4|x#W!dR*G)KSrUy+vCxW;YHf)wgmYv=y%(IR^vjP^HApCU=}vPmQ<@`qL6* ziMc${b~_tz%HtU|Xie)_(CRUeIjNsejE|J$(^nOZHke@ZRoZ-i7HbCUSZMfFJn^4O zr~SDg<8Ef_c@q0mUn^*y{z#w@P=K4mqw}bs3Zcvw_zpv|zk4C_8cWG`WM6*%ARx z66Uj(Qp2gIq=Zu>(A*Dd0blNls*;ZRsf3A)^FWy)jx*SPRU6yH-@-HNN*odGOS?40 zReJ~<{#lBvE}d=9?v}Jmkx$B@sRxGdtkUQe6ExuHI-Fi`Q zCQ!Y0)50M<4r(tdRTuB=y8g7A1NQ% zp&*8he=0#~4o(nL%%?aanA4T%`B8CljutUDJ4QV*N7x|loc1`Rj_h(al4@aa548=B z)*>2w8?%9$kXgig3{#A#z>)N)E7XjS>=7J|fcu(Mut@&s=h~)M=BG(IQ$i^l1!o(D z3u6!%+ge+c)P3jzpV=cEfl4hRCy~WkBAJ|fQUWiqKy&hg?nNi|d|iP2s&6wCd4oM@ zxLAN$Mh4nv9m0EBKuBN2kX-SwfoH6g((8Pij>@` z&U(^$pybkS<46^p9!*LlB;&n892%K0a79STH;^fO?rEh<4k{9jlRy`Q%FDHeM|#cG zbS*ztgvT^s6VQR)rBJ~2G^N|67qIMkCy4$Y+}TR<*p-qzXK!=**9mh3*31@2NIB;` zV!n=?2@V)!d)F_m_)gzZ4$Bx0dy3K(dy?RIo0N3}jo9t$R9#qco|V;Wz7@OELrAIn zwQituT(M#ugLMZ7HL{X>7)~}J!O6%Vj?~6n8kL3*9X;u+GEUqYrbtE(dRIfDruhy= zKox-)Y~!_bT0z68Y;E_f6e51W++AGN0c5P5NIIOX_41x0c=B(LWNRAgI zbJnv*j@{&LtXoxi4A|&uWIJ0FTV64QgN~IMZOlleQWsZ8Whrtsa^gu-M<+jxP*ypq zkn}v}xf$sxU0l&ZtUFV?RaIxgg%~;H)WGC*{Hj|i1AY7vkH(lrSbtjZVnAI08)-lGAhy&b{rcAty{H-%D@gzd8i?`EZku8-nu<9$I4SHE(cof!_n&_ zhY?oVA%4VRwhjkTSdz=V$S0ijtsPqR*sO837uvEmfaj7|Jxz2;>Tot+)4}^l$;rsZ zE3CW7uzZd-*Da)&&B*E3jMr%PrsB|{Cnah0HKeYOJc&=*iQUJcuSW2L=G6KIBbwkf z3mc0YhWWWXsUo)gH{v0tTkW}uMp4}cO>)+z+R*F5$wpRZr|?I$Wa|DG()GxUcX4ys zm#t!-hav?j3>6RNK3rYq0T}y9OnXD_XiAh$YddD%;-Oy94)4Wb?-~ z<@vGz`qWN5%EpxH%A2}9Z%XlAnW#oFa~eN&V}n~n+uR@_W0W7EuL<%&U_j@&tJe0h z%a1Z?5qtdX2lK9fVEP@=#zpS6J%W4fKTJZ?OK)z!?JyaxM_BlVu}S4=mM?LTaWuJ9 z&-JWZRPgre`lh>gtAX~QiaP8? zz!i{PmB4SppCZUz*|{X=r6gdg{s-yFf$pOJeFyWTY0Sre-VF3O;-XfPGn0}#ir7yN z>WhMG=5In)tVQ8%Vrb4R*b;p^RoLg`Z&MwdO}CH6qzQqF*^9w?&zX^HCI@U{t+#@8 zxfBnx06YHhQOe2oa_n;?3}e*wrG@To3442qBOvGGI2o>~JO``+gA`fqnFkdA0Qf+4 zhUJNeo z_8j_SikW^KN5`3dPtis{m1?4LIx=Sjh~8NM0zK(t45Y75YV>jN`qg6EZ(s7M;_xn) z65;2NliX3tU$S7FSz;Oz^F^+oVjlmR|v!w+^J;ZhFAECXb8l=h{pJ{>*_P?IyF8djAo+-6p5RkN z4#eaYBh*)~2{cp~Cr?!#rD$2SA@>_j{5I0|XkNuWr;oL(w;>zfiWbH~d5y^R!LMJF zQP5!-X|(0XIm*>G@lS^`NA{JN#Zrxf*+q3cqx&}D*zC5KAMP5KEgJeym24+t?3u4l zlg0WHE>}~vY<5r$F+6vmC?T~NhpWVLR>Q4$iw}JoBSz_@hd=4g}I%Z(O_@zp`=}-+~wQA*Q%LYcW3T!Mn6h{ zybr6A8Er|&;7x04o;{N3g6XR;_1-a>w{PQ!?5&X9$1A=+gCEw71CjTb<3fB*mD_6Q<3IJ*qo3j~qaPzpg#qXbl7FQuA^U^l z_-$|-_qR}E)K$2C9V8z!Uj{kP-2VXU)fjwttInH^rL0TpL1X;uKJVfNxU!Xm+VR`U zKjTk9E<|-l!3ipblJKhf1pff*)2;jirrQ$9GrJz8hHIR)@s7DHLFRj8$jKoqF89Xz z+s?dMR*^@vYyK5> z!&&h)^Wn9Nm0sj3{{V#-LQ{+AcZ=YS6>t=KW%DNr5GR15M z`+V1s!)EWcLo}+Rvq(;VI%J|Zm&#BwPf%%GuWNpXt&LYh^8j0mRX&AhhXKlV$e!g<}0JZoZ`|q`p6k zej&1v&-+Id_0w$7U`L;=IdtnB^K74mW%Z9EUts%*7mscwU)|{wF#iCqfphfhM7}${ ziAxDE|PBZr*qi;E9?m#2^gduO_&gxDBl4C*`U8MsrnDhNhgJ zIq@^(dGIg$v7hm%zu_|RIq80j^n_MR$g$uS`HyOJD$b1IPCdm6ZJA1PweD#j75JV` zx~nMv0Ae*-kNbbbbGaYd)9v*HjG=a+0MNXI*V6TeO5Glg=SE3+PjS}!+JT0I>RK7kG%CVl&_)F z1u2|No+a@wPqxH9w)v<|zppzflTmaZ^v*0-q^E^6?c0ni^dhXCA4`C37O?^8ik@j2 z`zPG;rq%UkEEiL`C)e)OCi_=>AGh8y?g1jbI%Lt%oF%h2w>1QJ8fattxPk5R(sPj2 z7J0E6yrgFC{QViYrwc34K6!7Qk7Dg!uLSnYK1GFB=ql`9K_~rJ;G&Xp?jFSP!K7Zu z0WsXS)!Lz(N|iz11B?zbO?zV)z`~V2y(=SFg&x*Jv~V+;F8hhn(C54??ljP(ZNSDW z3&)5`#Q7r)$*!Y83Kj4%&wA&)exvN@zwL_MY;#mriRY}O5y?39rXJk!-k#@>1t3rb zGlD}%9R_jRns6i#bJCmGeJKK#=uILEkjx0@^Q4~HiQETXm0Jvpj>e~s=3W880B~ww zk+PNaV^$ImLzCBvQ)=JcAoj&6yOTU9{OLZ|H?BV#T+DV%XOS^HD-Xh@7V;k4(>~L5 zdNwiX-ks;nKJ(=LF-6$aQ7_qFIbo6qK}2!7Fv%ZEfJt!8m6n>zFnpKA9LyYh8jSKV z*%`qHo@ug!3TMpT{+_j-1dQbFdK=9nB(eIMNVhj@5wVal+Hl950aC#;E;kY$K*?mARX zOoMJP0KldR40n0hD*fL1H7Ai8Mt7dQ=s+V(5t4bP4b!V+a1Aoho@5;{oOh%$!;Fw| zQh6|-X`%Gnts`BVPXnHY>8QHmDj zmD>>IPod_RhKHDt$9EL6Njl+?&U=C=`%@f{ryYS5-?YfYpD**EE;~08E=kAInq#>q z1hJ(T6A`ska5Gqj2g?d(xkndMFKH%+;*vElBp}`br10;Q!GM3YQIo({OShy zi>%)a_e|g8QJJUCS>$2<(;D@=ogc&2cI_wGqAUkMxi#ndm)UObe7h*NjNlAo znsyx2qtwG2TmD(8ZuuFfv~J6R2qPHA+VuYb5BO@rC>BeY)>g)TZsxWow9{QoQ9%ws z!3v{_IZ9A%UgwG|MOXm}?(K!edLM-^m8>#&BN-l*pW-bPTdb2r0;2MGqr%EvWKqz! zU&@OU7t1RXc+Jd~v552cy4MWrGXb@UBei-5iXsVQGJ18c6p{+y9D7vE&a(T_o%)doD*2&CAdMoArOf5S5F)f93F9qR~4tO4&@ z8VeuoRVZ+JW7euWmkrNQy17W~owJe?(!A2{oQ{oUHlwQ9+C+@cEUEwlwrlGxGR)dqDi8+M!2-BH0em%o z56}Ijsx*IY{{WU~oP-$ub=m70s##kw4gv0KDza0SgARehn!$gbK@QMnLwmVk~<4+5=p=?ZXvoJZz^%dM%Ir0>qm1WX71|4z@ zd5Tt*&!~>a%NnnT=CzfBDGWVED>4gNLt#*sCjfUQzM;MFrj4jJ>EdGEpwiiRLqM>Y zPaT>`DCp8CAXfhXSo7Vs?Fg+>@ zm;KQ^aqC>}S9fKeYpy1B7bM_u#dQ7`V%GS_70v6C$Ni$i0ho3jtD^9$F}6{FIOe@< zKF5V!e)ylnpri>P86fnoUT+d!#JgccRrMn#y5A8;zRZ$wUVV1IFrabI3qmMPCIf%E3#DDWYLKx=2?{&*mF!~LN=B@nH0jr^aqM>-XkL! z^q{#;<4TbxI}S67n{Ug)hQ%yFSzS+1DUTxr+MogJNYW2Mj3kZspxir(h)8qD+E1-3 z%EV))dgHxCj`Yn@>7ELkHgS$~(>2~iax2aJ6*lP9Z~#38dPF0SY7b7I!ixY=igJo} zDV9~Agg;92&l5X5n8!-=TZQ=zdFP4{B)xj{r*S(RqsJ1lGt37Z0otogEPW!$&r)hR z*m;B%&U>0@+kzBx?^&|B;<|)xaz+oQ$3$3_wykWYWiOUBTKwKD9h{s?I?<0QTuj@#O~D$!qenpxA&Ma>BW^Bc7Gl_?OCx zGO3K7qPX-%B=7(ysXc0u?%>mmbu6GHinRnX0t%1@dYXbfgPd+2#;(UY1sO~qt!R$W z^0tG!1br$tP6H3X)ZS^3;TNa9L=sm4bl6sy3dyEZ;i%}GQ{8yNu=X%vx@P@_q^oK(S%IW!D- zY;jLg3Fe~ROSlREpE#ulH4tpmffRt3)`3jjKxzP!tpRgQ4hIzN)C_*gU9{cwZlD8Z zX*|4B!KZOR2#Jc63TAOe`T&zOhMBuG7N7;qE@^_C4FD}6=9e^aKn>fPP$_aLH&6oN zlyOn{fOV#cfjwvfV?`$H(;2{^1!Iv=Nc>VsA;H0@*XBIZ0XDOofl?$bQzioTr|uMh zYR8I@3TEmzoYN5cT+;&%w7b_GX^eJhGfBKsZlDPPr43LPqkR_w#^Fi2t2DS30lLAZ zaIvBfH0sY=pnKGU=OY=TnFlFzB9OIK6AxNXI8){e773%RLL>wZY2mRKKUaYp)S zY6d$vq|G-pW{?sLQsS5?*%Sb6pe_wA>Tomwxj4ljr5L5+m<|-Zc%&3&fD8&vqpx~1 zNty%(no&<-PNXJ)8|A4O+A&9vqnuLiq%M7E7@k`6z!ZWYDZtX^m5>ec*BvRpXF=Me z6tr@nxm?<-cc!(91w2)}QXJCcL*`{6Xh0xS9?nMKRqm9z6uq2B%*>&s$j6qY{>pGh zYgiFZ%^uDn&dg=gWCs)tJ%?20wh7Gu`%&zo9PG(918D^+l-f%>ZU7G4S4q}@qtdD{ zNL=j2c!?&n?kr2OXF07YCELbuYd-4!IET#Qq3&8K8#PnFr8bMkR8(oK+cxi*XFL*d zny@de-Et*grf6s`Fhvx2-5=rwHRpv%#9$H9ru$4RzkN?0wMKM`LP(Hf*wJy2O>q$< zvIFgks?8fe$bfO!bftSG-;pmL%9U)6!m9jLCW#g{P^A309YL!K*6%1_$3B9iOFZ=% zsRf?TyP8dfi(W)*yN2QJY9>)1QZd^GmMG^3)q8_ac#d)u55l0NLVURfHxB-f`sJO}NSnGK>Lxjm4#V_`ZMqt_Jd z0B|cAbqNmzPJXpIUX#}%fiqNN9MgaUpsFb_Y#j4emQY7pVjRnnRPHw@Bz5gq3xYTz zqi`5t^FYjZjLLpt#Sz*C`qlP;1Ci2@t_Mm$R}t*>G`J_Ir;yesXEj~nBkqD~+<@nfl@Xay@ZCM>1mw-XQK_jyk|+V|CPr$^Ob#lUQ|NxRBzXjL#W5HAbrch~2f3(~`0Yr?B7h~{ z4KatMN0J2$%qamJoDQa#Bm;_9IjY3qng&_kzP)HOFG`}|o`m9<6}JP=)_^pGgB2pk zzM`nAw^N)`)kvf=@0>koGlAcVt&GwX-NgbfEz7kgXbgmX>VU>^)|NQ%LB}-0#h8KV+OI^T81Gdg7{yzR z^Fk3}P-2`SQ}v`=;*He6caW{xnD*oFr+K&?X{|T__oM_8T8xUW(XtbYu_e-|>re}r zlK@cM;12cen$cCXlb#uC%WnWT4p=GtIjyMf zV_4xPwGl5~N&Kp~!68Wl+}BfgZEY(C!5reUC)1Hz3&|wsHPFmTaj3~0V?AqYM~#f? zcK638sI18C&Oq#Y5nH-cVmTuupK6J0XH!&dvM~dU5mH1pvZ=sgYR*1U+M4lx^bl93 zNY6Q}QRTSWcQoxmZ0YdF4H7gj>U8L82@`c`U4K_l|3F}UbSA4=qL zX!K(w)`i`}aOd@>f*4@cb&v(cIazq-m5U~9U{rY-=Q#GGaK~CqamlA(BW|QrWcrNM zt$|H-1v5wrU)duWI>-7S;{d=>Pmbvx4vc~Kra zfN6D2K`m6r3uiqrYn+jpn7NRaJ!_^@OGI$FUvXqE9@nliWSU*1a6Hx@(yb4O7UwvMaz28q&*RWRF~cZe ze~1cK6`=Z&$Kahz{La5I@4B3P6L>~GPy6bm9y*YLn28zZnq;0fmDq^whaK64E@T{# z?l^cB?a0fMlW4g?_m-`H>v7&BX9H z#tqT|-z4UzkHK&#=I9ml#d8P7TEG}qfd2rzl@alVw#WT^D1D+7b1uTYGLQO-9~ndqPJifF(b z`OWns`c$xZV?~5yLe2HTuQPpTSCjARcMLrPWBF7EQNIWNKW;toA*Id=q&pt2`W}o( z{{TY+A3;_l)AXo;RJMG{=d)3ar6r$he$U61(HCvf(W z?0ZbM`a~q=-URi_5AmoT<3@>TBheLbw|03QdJ6LGiHwy~pGv7R0)Fm5J!x}?v}>X3U+|Xbi~j&G z*5GHVfN2}X+9>}3m%)!@uOwp}QUEcZTCy1r&Abumj8f+-+CImnx5OP0K3_gl{^UnA zhvFWHpr1D2`*|ld=40kL4S`H%2LmAU+Mhcm)sj2+_@AYDjFG{ADIL6^2lJ}Z{8O`! zJ2cD2J;B;Pt#N4@BX47XI#Aa(fw0&o*EIQq+R2@9_^Pe}O&;S1p=T8$d`x4>(p>uq z1#qu%Xu}H1m0!&Z%ADt+qT=?FJL$eDIAW=!HsSs0c&G=&ok~JkEG*P|Wr?mlD3UTy zQYp6Q%OraDr*d6cC#lv?@h@B$329=#P{;a;t^WWEAH)rut%`drXZ&lKxFGF5{L}}M z2*{%5a;qfwI>Y0S5jvOi;Rmn~ifZ`B#Bz>x5R2%Lu75LFP?O~jez~Z`zz_xi&sto} zeD2q|y51w#ne+XtF!$Q0`c-$<^@(%l>X$A4>uvr*vs&Uc$leM1)I#qI-*{AH2M|bI_ABXZh6zyog}r@@dBQK0wI&(RM}T`j$gD z;iZwst2ri3gvb#YV@}fPjW&bV0vbvxr<^A z{{VRUQs!m2B(5iz&kzJ>Zx|kxQf?nPZ>DPM58dv^6-r=4q+*@*Gnc{wX&3I3pITTW zmg-Cwc5Lu7OB7|!0N@_AxoZp-Fqxkl$m{7w#3tK9#Te6*e4BDdQB+=ewHd;UZBzUv zqn_dK?gAhrb`_-zBTu(1$^&|y^o@z5iW>;GzFJIj1yYPndpk(#HiPo0>?vbOZ>~Ja z5AM^TrN6saGaMWobQBC_=Agj@5g;9?val|9$^q~5RCX3^EBTW2>yuL7Ux>hpJYaPK zff3)|?E)kK0o01k^EVvxx|mqIZavR>vu|$FvZ^5?xfIB|9Rx2su16W`Te4mYD}9In zIP2?CgiSu&vjA8Qm5}W=p*}Ve#Qp-4Hjac7&Gwe_3mo?bpa7$Ln%(;iy{))u$Ia*} zi@mZFxc~>D?kN)_-lZUSlAYA?B6e;s*Q1OFcTREsHYp<SX5A;Z5S0o?s6Ea91m*0xNP0q z6^$e2MxgWzyQXs~&PlA78l%Y*CdSyfsZLvj#l!>(zdQ>&2N-_su!;8NW# z=FL^pTja%CxNHt=NJtxY}?6k{KaXIwY$0UZTySb)~(eMM(5-i0j8~o@+yKRQJ{xB?SWN8% z=B}RR^vZh439Z{ZeZ_IR73!9E7LnSgmftSX$sC&UKN6RU{xj4bNfp20&00&D(H+he zLg3WPbGn3*b~@X;{Zi%GY;D3sI1c9o);-KR%=?kdN~ft(b6q&PM1$rd7_57}R^B!s zx%>r5*kXTSU6IVnr~RDK{{RU6!93gmPhKlQHCUYFImf+A{iheGsjytlO$KPmD{x29 z(n+JtPtAQd;MlDf)Zzf+lkHF&vnlD1#)|vkd+yQes9;nzS zH6M$kYnwo;j@7za95dA(WOKU&QWhZK^zB-|*(|A_IU5~DYMa|_lzVy_OyiUp7=*C{ z9GbMYs)H=R8l7;Kz>+yuiCAO38RH9AWK)~m%b$%G|^m_H|urXWNAuY7$jL~=D-6|Ui40hmONmq7^pL^omI5y*$abGTxm9CKo~*IF&)k!0u`< zD&PCVbuJ!u!E#5SrE4-2ob;p{>^sU;PJqy{r*#y_%K@>M2BajMV~PoGz_CWm$~YpE z%i4G&A6iyW$2~nLRLKLTJJE6*4Wq8nnmT8-DC0RljVN4#+2WZu5FC^G@l9!wG7mn& zqjn=9Pg+>5k^XrY_4UOv;diht%WqM%Z10Y>HuAi!LQzbGV`XAJJ5#b3mo|gATNWkb*_TTNYn2%29oW`U~*KPb6U5)AJQR&l!tS51h#QX%p7GmdycYM zWwIM2AZ_4-QCYmP-bo9{TRx_)=~3>t^3}dk+|{JgpthB+9#OdS^BSX6v^mcdKxEU| zwq&hyJ{{Zrq>Gb+4;l9rv*NvC0*z~JFp+`zwwl1uPBla$t~%57^_9V?R3EhHMlZ3G?PH8INS);djL4ElV5hswj6$ndo3 zvPB33ZY1KjwPo`3$qsv0FX2^FcJ5yT7*U!9Ehdd$6sUbXH=sGMJz~N5;0pAA5h#;S zAoRyI=TfKy>Nia+Wf3#{M+DZ5T^;ox8AdPn~N*RFShjqh{NSh|+8MrHTJM06ueu$_tNHNe^j;nul3 zo9oR^XG<2LywURq@LzOQ;!R1%lE9q5B8e1CXOXz$sOv?W zwWQ*81+muyHS7aI(PA0<3+GE0#8Pk zQlt4(M~(bI;DM)DAoUE-{RMZ8{{RU5ByL+3KILjQ)Odri6Ii+3aW(;HgxZ0+((6kh9WG5Y4amhnf1U>FzHL)kED89Z&_)i_(Y z*#7{t5kJzO)oFGc#8m!ciT=^?YhWAp9==_={{V#}TllK?DJ9kHh>21Q-jT6-{`j*q4Lb4D9On<$)|E>8>7l@RN;@xFlxHPo;-C&6@K?Y5QSlqMqt1K4%1RvLAh{o8c<;+pzxs{@GCA52kW z8DKBe`TqdKHj?dfRhy3etCJDzlPpR0&r0{d6zFjMj%SPoY-guh@m)qC9m@q?l~&N+ zjVDh+80B{PR4zWW;zl!?iWwPleo((oYRO~(7G6(!wXx77YQ-|3{c}K8+%ueJr1O7w z^0C3}I#X4coH6O|ObKjQ$94!j=DjOLm6{dXgZS5%tg5#NS3H{UG;79=1;Op!vYzIV zJ0UMj^{0pLSj(zL7v^!zFZQYoeBJt1Wt&_5DBf{dNvI=ZEC4>WC)-oA3{x4Qx|eb9 zR8sK><-b~SypK382jfT!!H*a;@K3MjS#79WLzZiW9>mpi;tNgN1gc2%G=SdSj;52$ zu6X!{41MmjgI|fdKQs*K17zbg;N11Dcm5I>0%V>?YKBi0+NzVgk?BAkSUq{8aLzMa zQ+VRc01ItCrMRbC_{Pzk0^n!9Xal!XoO4eH-no_WBpX2u*P-oBJ|bRlq~p?nIz9Bb z&o$4*t$C*cG6$_`L3zKSpbOv%LUB-u3Fv5MWA&g3H{zTmUiF^xNEm=Byp!Axnfl_8 z8x10k^%=NOde$pTa7RN>Nj=d156sfJRyWPco-%2saqC!+HNzagAB|aNmv0YCn0%%4 zA#Ri@+s$FTw=Vb+m0v(AWb+VnF>kFL!sRy%-uzT%VV<>%EyRjAZ_cZIs_BmmFgo!= zni_%8ZdUFMJxCo5V#O?*a$i2YQ~uE8b*$Y>73|HSD92h1tDYLM43GWuO!H+20gioY zeX}34H+<#E=OUQ%s*k-`Qb{7ladoAL~?)V^S`q5&ku0nC(m3eq3|fvo1A=;ouH?)Jv=hTMBsk)odeZIU=3Dv0GM+3CnTl4N-p* z#;4`{+lnqL9Y>j(JkUGWGZwKV{Ho*LhSV+_I0K5!)w48I?sVeidSp@OsOLGZGUHm7 z1B`CxuccA{0EEJ2`?lr(0HstX%u9nup?SmBoF>WZn)Ai+jE9%Ekw<)rc=6OqP9c1H zde(%Vhvy1#lvf14JhK_x8;_+w{u8TAe5ocrlnC#HfQ}6#J_o&VcHT3#pEwS@`c{-) zAh(o%tQq&B;B+2mGzZOQ$Ed>U2ylJ#Q?1l&cww3o0_N&BR3cD$rQSVhh>)6YO(#)G zC>WzOxuYKA6xJa}CV(Uq;A)%P#~8S2V!$fo(KscQa?+vuWx{y#B%(&1ZkQ@QGxWy%)&L-bexJ{@=<~>epMmWc72Nj(?_&`ezJ!yW=a%0E` z>6)(AQ!@O>Se~Y>ASynv$sj4$(w`o>9ggM4tujqL!TX*0;;h@)D8VQJ`coCeT~rk$ zMsc1EA=QW@F}5p7ETJRjLDHrE&bM$js1&RhGZ$ZuJPdR1PhS*U@~lYDLZdZyO$rHe z83t;ko)x!0FdvwpR~!ET2{ZwMhROQW$>JXPek7R!+kPvPJx>kjiRQ)i};G^b}Y{pRua; zsa7>pf_OdZ1k^Y3RDthPE!1ZRiU6Hs1Eox$;}poGM^TP5Q?5GF7~Q1s0H*mboRSBy zIjM^%?@Zn^?NlK0$Q0HD1B!T=2UAPETj@X*!xP5pa0K_Mf~h@)J7Q7-6Br}jqBhw% z>sGJ^FZniA($@!9%)D* z=OU1d_Y?r0VaKI4q&~GG##s8)o<~fMDcCMm7YC^4>reAb4o~4zwYUSNK=B^KnoSI2 zHA3#aGg7n?9*2sF?b{f~G=QT!sU)irReseZO~V{}n!MV4gq$8K88oBR{*^!x-=hE@ zjCZR^a~lDSWYq&>uyd1&dP1mprUs(OGsjAuW?XyK7>B<#X#%kTjC;^YA-)O5Gf}pq zk<$XD`#Lz}1L;u9Vmk_8F?AT*KR-`ej!X3&8$U{g?4NrQI42^ITXXYJ0y{L_8-r6p z3omN3Z)gTMtK!{C(gT>*6^*-Y${6WX(pGFlqgBnHNF*igy1gN}REh78by*mVM$6OaJljMix$ zWWFIHwP`s7A8K&Z?=p76eT_*Nc#c;f=e1vlTfTuABMF1tuQj4Ii)g43l>n6+k5NaI zqF<98I@HGXt{-&n#2%p2cg4Hpa7U&n2Oe$4vK{;`eL0{K06qNysgc1v=M?seGB{v8 zDjXupjOPuAl2hM5N_=v&bJ~Qrc}WU7cLJ@)VpT9y)-HqSZwycK5eGT;sWa^RzN21HbF_YS8Iz23rC8;2g!<+mTp$mb@I8 zt!?PoYl&DSr|&na2Lm|9X?&)~Kgx@i zqE^dwB>oi88M1PD=qk#<>@cWsJp~_TY?Fh!i?X>{3~9;B0rjEdRUa?%saD;?9u5Jg z7@d#ZqT+F65wTnW(yb$ThYWH(DW7Ly#wb{dw(Jp_E;y!JYdGRiU%xyal}Xec-C>rF7BwTKWF~<=w#dTCpF5wL>6pvmQEb;+WPN zM=FspY-52+P@V$fyHnvUO@aRaMqHlZhxMq(f;C3T^3Z!16s$k1$mCSwJ*=Ywt4br} z^sdqT6{;$c1=?#~tWRqGv{NS2Dod_}p>yphiK+oIQ*k@)86cj5lYjeYbc6x{Ryg zELAwf9GmRz8u0wV3 z{{T_7DT~WFGuSB@{b{Y?OQ=)LY2nBnhJUSeQ`yBDm-|WG^{mU8t{Nh+zT!B^q^{1d zX9dvZ`AHcWvcrQ*AI`)MaZ5A?IoL|sbIxis`CI@o?kdh2t6c`&0Aaif#xM_R96~ba%jOF( zoXQFBO<1h*4pS9KT8sn91KxpXta|>mS(Sex;f~NT`ILP~q%B|$7%8faVhGN_aqUeu zs0iA={7}%jyp1@otspyNRSoM-n((>;tG$l_NaC|apbQSo6W`XPjqV_DBj5wvbg5-V zTI^mBNK^8h{iM4n1T&H+W>ssPJ5ceySS3+)RBw~Qzu~l)3`Gfh6F*}o=se}w0np1 zCnsS!G->){%)@cQbw2fO{_$;X+Bj4f=m(_%uTm@fnBpE>L3kMAvmr;8Ub)RT=9#x( zlis(iZGOuSohb@&kUc24w;KhVcJcX=s5$4Fp>;UClt&Ii{VHp#=ev-{7f$tR+Q}^! z%#Z-gGn3kjl%kN!Xrr@-dwuTaqT40(qXdY@Q$xr0$$$m6gW9IKm299fq30BbVJ_~Y zwu{S;hV4}>ZT`_KG`qHS$?9n=ty=a^GC&3oQ&w+oR@fMjg5Z3_cBX-bp?w?(BabA3 zj1DUmoRV3&C#j~$URK;rNi}K+ckon`j?~QCZ$vWQGcgE&vGm1mz@K7-xx$b+%}Z-- z9h@RoP_kpcYRsN#FXjLcvFCxFzVw?eF}CAoo_ounqXkbG^sNY@dkBlZ(Aer~YilI4 ziKUPLz+{@CB$Hp=r~sJGM+2oI$bp*vbMpLy@)Vagix33z)u_`$VGop%{PmM7yqWJn zifV^PXzNh+5O3HO=2#&0-6(kiBWG zPfF<t0!}f|u@C<0p@$de!v4bGcFS*Ohpg!s=u)^sHXwS6<$TivcVB*ond*-SSQ+j59iqDsO6oinyK9x?(Qfm{w83Ash zw0u;px;6topjR%c&)4sI(ti=WU8QrVJ~q_~oyijc=m@O&d}S$oy|H8LYcfDYc+L(v ztm$|o1Fw3nRCgzIbR)*tQ~rSD{{YuP&*@SB0K#){bF)let4mz)12{cTdXZ2s7@;H= zH%E-`ZNhnkkA-88N{0Yv6w*F$d8c3=PZZ8}+hZH$IrXJclkGtTp9dKF)wpbAUq8(^Hy}){1RIfA+mbcC2g$Ba;k1!nU7EjHCt2E0>b`CD#D8$s%&nl ze;VDhk`+%%n?}~H?XDTPe1YD$sch~qW->gC0{z}|#W31j+w2gr@aYb=0?gdbgUD+|gvh^Ert6rsK5!RLEvXLlsaM^*HNMDr}EDaZzBg{AnB# zlje3D-et?>k9tr-kOxsuF0m*BmZgdy)n?jNvW_!_U& zj+7HAbVb`#jP*cBt6VWEv68-oR%CAKaEA@ru8WJ&8O&?blj%WFlvd*=fg)ho!6u$v zh*2KV?^PsskPuj$9t}jL(~bQ5QEQ8xC!#c26;!m04;?d1Srj1=fDgS=EbPh$%n0Uy zO0hZV+Ky0lbuJ)gJEVP}4uiR-u>_J29@PwL?zt`Art&0q3ZHk@i&#^s%nS`VF9Y0EnIr;#6G5EycM!2T0A`xohZOburGesuf--*tL6aK1f*9l+V~Q{aKx2bL zbB^Yh0N}43u|SBVTo7~Hr7$+^Z$B+gLb%(`Y7-a@jP<6CBPNRiWQjj_7#SUEv_~?t z5!BOp98{6u5IfLQlVy|B8RDUsDME46y-2*dT1Vi16oiP8fdCHTy)VO(5A2x6c)-nh zn!eIE3iLkJ~(GSIY)IKbd~)^XnFJRiJzG`3U8YQt|VIQFkS)U?aJF7Qh#@J{T5 z+P9CyhY=ADm|2HH@?cjns`!TMRV2=dANw(qMQL-Ytl-w?py?MdUfL*E3_$7+TGE3_ zf*B0s?;ie@ zD3V705PMb!g=HfBm)oUbNtvW)ZN=Y~VtF;U;bR(V!B}z^jM00tZs$9lKDMRw*?7St zjMtmX^0NWK2c>$JwCXg;hB?^8epTfYS~I&l5=ke&y(xuwHuN2zUJW(Mh6R`mbf`YW zz#KOpT2W+60!~k{tjrV}Er*9_{p$13RQA(BZ#;55pD=DKH0j{-&A>e|Q^REplSU*e zK;REbYja4e9p<0o>q~foEu_;nI17POzr-8Y;vEi59-d=jwLCv(rrO%aBzBQ4s zQ|dk|({!>B!pz>0pvUvAj>zAaa}j)B;t7{@dNMDdA&zOM#C|WA{Z^F%9^s>7{(m}} zPl>i_aGG@F_RBB$)Nk=H9wE~lk<>JRQszTX%vIF9Z6M;(08e#*@&5piP)ClYBnfr{ z{n*rhI;#Hw6D~=>)1yQ0AvFVhO1}ZIYi}M0A9&>cbez!Fsek(~$1)yoyaI@k7YmOP@fz4ich&bC=YQKf1OXYiB>ni;T7>L#}n&v zE`PfC{#2vDnv*Z@wV7L?#kfNHXnVXVZ z-0WB3)NVKHaEF#QnPGkNRk6X>OW7n(pC; zqe@Tnq~wvLXBW`*Vc~BL$BfCq=b2X&zu2A?kNDuvbLR}#m|NJ~+^ATRX&m=JPx7r5 z@RqFL7m8$GaahX`lhoccGN#`yW_u?it+YM zgzp=UG0!!*;b5as+acqy&03wz`SsZJEnYiAXwHzNV;q%Q^4qozDeZ$^n|I~CjDWUI z+Vfe_7VYG`a9DP% znV+$CxeENm9%;;ljxyNvrzn3ZSSTRUA2D;+nvxt6L@gLzFmvmiQfxSVI} zNu7r*r27gCIc&to`$GWqr6-DN6=FeOz|)8uKvBTxC^Sn#GINpIkbt@Ck9vO91LnXK zIRJnM2Bnsw#;m;YnvfmpSPTQ}O<0NhgCB)XsCI47dPhtfwT+(*I7^T}h}W!HurMdm zy!*o1AeKQqrw2S&p~8z4VOOB0j_NUKYFICUnvBbyl%Qsp%cgEMPEA>iR7jXLVMYZs z0ZB?}D#;R-l9qrJQPzqm0~23GHZw69!W!^hV%VF9+n%Qw74&7q2{0koa-O2HuC$Fk zAbqxRE0Mzm$^B`f8a{D*Y1EvdPRI zCmxxp0ycZ%u36hg>aQ!P=bV~-=adN%5ZLyh4A2q@12$Q+#%odw>(>Eb1P^MG^n9Mnv>rrn1^H8*B2B!qSzm1S2^INBJV{Pe9zuGNTbs&m-Y)VU#Wst3?l zGpv(36((Y&8i_gFBF)wZz@Pr@2pS2HU%>MxFO-5gph$uZxOr9E_95@8^ENe{M zOc!?I4M8TQcE5Ci_)+Zx*_F?Rqy%o16YESm1epEXsK;~OtsP2MU>WoD6=5EEFmlVs z(xKL9J(-l=9k^kEE(lY0eG1jl!3)z+}yg6?Q;GBWj)xo2}2g`zf zl?pVhc#!@Tb|jc%<~gbM!}eZcMWi5L#lH;Jgf^=f;M7R6_c@|QnHM1OO;otKEL~Lt z_=PT4J!_e|y}k$cK$D(=piAvkoHTq>=NBo~9i8enXvb>77nj%>JbGe~-^dOdlkG>f zL*zF}OlOa!Lh?oiN&{Kxc_R11E9??>OphCq3olK0!C`Is0Myg2W$#gknD%Hry1n+&mx!mP9cmd zeg>$?4j665eZ@3F#F5mF4k*{CSsH)Zv4N0{fl>beZ6R<3XFlEPlSAdkOB{PsWAc-n z^XW?019BV9<95S?*qWK|kq0Y}dckY&EO4fpFD0MlRmk-fq#>yiW&4d{(lA558$AtH zJ|wUVQAuVUa4I--DQ=yan*)48I+ScoRxQGY6Xta#1^N|10pDH`8!z@p+P$uvlDii_U#ZvKsJOx!r)&!wsV3ZQF{KG@F13E;H*%{f8^D zX&inApS~}2s?k{zIRUC8W2d_=MhHDX#%n=z4X1FBmOiyIXi8g?`O~z;p;9{th6H|{ zaZ>$*By`Pb!>6oR!)Bx~VA1T;+Pod33 z-Vm8TgdTd=pe$?;ImI}mbRB8j4>o@fY7u8-L6^P_Ml?-ZfUvhGu6kFan4CAgKW5ze z&=xp|G>uv`0gm6NdeyYFy^V76WcpUr-eQcWTE@6-M3yPHJ+dlWuR{7p+Ao_m^~ zZu=GN(Yw5K-A#}d2L`hj&jXjnD!jLjkGIX{v{Skv#>L4jjE$D*?^fZq2nGdn^WVt` z+|p!w8iGF-2!2;2qW<6-u%+qr3WP)TvL zb4(MA@-s;8j4_I7iK3Sva%p_V0<5$ue~0s?2yyhNdzMG%wJ4pBV^S@?O*q@)fGe4f zGAgu}47oYtubWJcwGpw+A(;)U1^dAM0-U<-u1cKbb*pmeTgk$MS<+}2a=;#YQXYnc zdY!DJDzz&o@2Mw)JQ748A_ z0;`k`xGZn-j2!o*Ye=((QC!4YrQ{^D#l||;lseuJG@$({GzO{DpgF`~Q-8DKQH)@E z3W7aq7yGB5LsR{|U3!X^QX+dO!TJhk*psmWl6#O8VDf7|OX(vd6U8B#Cr`?rK_1l! zup^^ndQ}NEm561f+xXR4JVsZPEJ5#zEC$2a7RMa+G>fK8GE{Os>mhtd<3D>Ig=*!u zh=~{}`qQ%!vu|%Y1>P}N1Z*+ZvtZXz@DE>Vwl#}(87>7Ok}x2g)hX^?A)IkmPN8gb z^8-;yacd|z!9J#yz|MV0WB{xWsWkC?;{{DD)|T>&s|6;hy|%;h%6}Sn14wEl43kg( z)*h9VBl3m|?mo1}Rc`qdfYmy}0DfS8hNJ%5ho_h~dSh)L+r1Aoi}u89hhPV4mrmi&W4e;$Fh4a$*9rO{IMe9?nDO zM{_2&gYPiKMm4*3Y;RGYdf*)0Hg{Y*XY`^l@f_r^^)*VH>L)aMR9CRb2H6+zHDE}s z_j&ildG)3FLORz$Z>%a{7X0cZ8x*B;s6~v9gEXcjK9!SiszV{h^$m>TuPxMMV|X<- z9l~35JvvomXr%P3Eii5~P6bXdXbY9n(H5+wu-n$000*xXDv>}DtUGE!9%UAyvP|re6*@7;97m*@aDu_9*i!S#RSwi{&S;6}4ri zYL|`vxk*3Y$Q9ftha7*)IFx;A%sM5+EtP17KD9_agic8KS6$n>CW!iBi2jwIabv0J zt^WWM3t2WF;{cWX>(fW}f*=84e0q{AGgyaLy0duvxO}oX5wR!rraxg5ow1uiSk%pN z3br%zkPTUvSMc;438QoV#AUyga*ZaP6s(&II`G3CC`U;w&zzhdwG!CKm;yFa=tX-HX&QWga?&CARLf;*pLX6c{{R6LxkK3_#!i=X z=nC7+bJXlO{#7J;E#L(Gj%FQ*UMtxJv;gEo82 z#s{3Ifv?66W60!ZwM;wk?#T+z#0$_Q%Aa}j6uU;#uqK;HMBbiSHY0LMEH{pt$ct=bhz~7y3 z(MKu^BN2QnrVqUlKaEVD9n#|%TUGo`YSB)^C@zbqFH2bJL8e(ROIW|}nzuz30s&=g zy&#YN`4u3BATT3A{{R7}(M$#iqa6`{DsUL-OGO|GDKkmBfE`6Qbs#*@0!+-Xu|fl5 zf@{Y-X9e5pvQI0slk$c>pVGaQfWriEYZF${EpH=lF$b{+nn7!;9s_qX+sH#4fsScy z?v_N!Jx&F5J~7a3G|=pf{{VL-N$FmF70HNg+*oJQsac$LX(g%Cu1NzuO*xmH#DR}` z%eKAYa@l6+4P0phDCVV@rKz>2>b6!xGR(!Xz(LZYyzxPmu?)8+GsYw}hK~r5nDR$Z zM_Nh3mqr0Xp4Fn*?2gA;{xOytM7M@mk;Hh&k9!U}=QyrS=8_U-Sv=P#EKfN#3EIlo z7|(iCP*4xjhH}()Ek3z^%Bd7l#+c-Rnzdzh6brvvrvn>BEF*Jr!{t4x^Xig$Z4ih?r=cBctRU{sO!Gm(QR+>1fN&TeTvc;} z!0l4Z0^oHfp+r7sUJW#kYL8JsVsHSh9XCyqc^AxJu>q2C*V>zBVr7*}5)>Xtt$T~u z?BnvSV6S86yBMB-5Knkzq4jF;aQK?M=41v#^n+h7UBa+$?dCOug2py#O+WOmGDz zLzT*@wh6q%T#?f>`>W|^+Y@7s398$VCY8q2&L{+H>DG|MjXTL1Y;ZG8m7f0K!i4Mx zmKBps1NpEfebu9jr%j>thaEdmd=m&F5xT_0!btUY=IQc?) zX0)uV(#9b)#2F7k=}D*Q>jY~w_y--$Lv<_P$RdUK&rmZ`SWPs#jo66+^3?XLlE?Na zFa|j5PC*uxZ`*!3JM)^-+K`oW!XWhMt8nlhbF}xQxRLIhZ2QOBnPb}Ft_gPp z5!m`uSSdS;9QswLwDS~MmBSP2Y681X2Ts*2#%od%NzOT~&kTH;q6at!xvcwJM3sw3 z!9eJ9Q^_h>%&i20q)v0%q}DHz(mjGUQEnKK`PLq}acw26i0r*MHOIx{Em>mN7671d z#cMwASky1n@7QvGg)vl`M_jQHlF;Y12?}1zwYVhX9+h0M+6$9b?`>yR-oSc*MPktQlf`uC{;;}dzjR=SEo$XId1S*Xe9ep$Ftqb5=}G9kreIPG3vRfX&QTG$YQ&g z^o)H?Uyezb1C<`atHZpXpK1ImWrZ00+zM+!I<1{Ihjkb<`;Ri=#yta9Y@R%`I8FkA zfZ?mj#k5C~D$Gi;gNz04D^F>qjJeu(JyHB&rcWCvxH<2F5B07yTDyYo;a(T>2Sbm} zuw&ZCBLI$gseJXvQCS6Au2Hp#9GqnI?M+S2*ioN)MVc83?vMbyus!PF)NLU_vLJEm z>rBN(a_m=f$}mC5s)pc)11IPz%$F-Fvve$adQ`U3S;7_GJ@RLOLFR(v0Tl^ORQ@#! zzQqHQaf}Z2CC;WMR`TM)lgJfTJEOe*>Dc;hq*8^Q+Ai9|EWC)>N4<4k9&;RS4;ZdU z>XWLn>?pYWX)L@)EsC&6x972JQ;vgiI!_hMHXz{ctSGNkU^rH9RjPOT-NpNU@*t`@ zb5KPwWAhuZNF6ijNtx8x>--;+ zsO=w9?Omq2Q~Nqr&PZR@y!XQw5{*egKosMV^{&fXd0S1B4S|koqwt*4I7#I@$X5Ar zRih=dntO%Zan#c}PSqzRM|N9^0PLW!!Ru2soO!~y+|^@Wz8%(~irz6jz{wpA zcea8FEtUM}%DC)BQi&34q2fB8in>M0+wCe?cc?zk8jK!)3hKTf3wZTwRE5$)0~RXT z$JV)%gY#etPeaeH-N-g5IqjNB5Dc=O+a!vX_ze$Hh71GM%Zyo-;~Mkf4kf z1HA*fE1NfBzb-NP)5U>q4tPC}H51)RSm5pYQRmJ`!;m|gdXspT64j%WFzOF_(JUG^ z4f6&Vz%_(kVo3Acw3Wg(Pn8$28WnR(yG(Nc5`6l1Y{X?FXJ| z%Wlnu%YFusU3M&emK6sR4c$S_G(d+XolZL9nr%A<0MIPJCoi9D(zvd>5~@aU6SYbt z@`gH8ViOU_Jmb=a+QaAm6OeO7$dr;oZfOqVfyX>khXC>peJQQM8+pj-PguwpDnT8o z8Qg)v&O!Ys^EWOrgVLsCLDN5ps2E`GUNPQ+qS_;A0!X6_euAcoOtD-Hj!sQ9NEqOZ zRBXRFWu{X_q0<@bNz{ERG?Snsnv)~agElUE4z!zoTnvv~8bZ5Bz~ijibR0} z9sab|`?<#=oH9-^NZAp#deDnSUPveU)8bs5k~8U=YV@T%I6PvRMTqwe!1Nsr4bbz? zYCzmm!X247&!r(P%ID_o&V4J;JR>KWr-sitJbPCF+#2fqFRs|>P?WrFfRo7_R7(EkA8G4PwNWVjMA^o`H-rnikeBNFZrGh>gI)Up0l z+Dy4ZFI$`dvz)$shdzWaT9q`bse0Q@{{Vc~Zhj*8eLvLNPDgX(?G%skFHA+udVSNb za0pNb>r0gr$xp0~IdmOJk+#lFzwRDtMDXUU0P;jkf2DNq@j}>VW|eT*>{tqn z{7bofd0IMi{ril6B{Z!OdpcdrPxwT2XI0r}CP(*_in5*!)#U&^upZ>qnSLZ{fRMU% zq5yIJwV(P5t0%-wb&ty(k^}z$OxXVbQB7EOqKgaQT~MzH82Z2e09u}&0MxUR@C={g zZl9%RzmN6v(o0q2_+iiUHC%Y>#BNS5V;}a+aYfL%sNCpB!^^g8wbVHD1pfeqOurB1 z#v1Ao^w0QLEdDU@3l4QRT=rPk{3?{bCD(`~>sKe(V1FS>=)P)8q2ELB_8flt@SkN* z>sq>hgtW~y%!&&(Io;B{sWt6xM8vwq*i+eCAFo=Wb$f9me)8(#L*IO?f2}@bTB!xH zJy*pS))sbBM%NLBDnL!#^z^SKmg+`gRmoo5RaT6klbFh&^X_(HVn-k8I z{{RzF=a7E!9^}%6aGVSi?OOgCn$p(#Tbtc9UH|}%S@wlJ&%H&^>BYBW9VC;@;$7M6 zgON{JCK3}EcO#%wCcOty)=i9^Ran$**zJdI5Co+`>F#Eb5E!~Uqy&Z%7&??LVdxrQ zqn^4VICF;X9`p*Y}>?BFWjDf5ki6p zV0OJu^suylTby>9ePnecH>*)Z*ZHPYfTr}@Wp~L3T*u1K`+W?0Jf`y^#==!bZFy;L zi4Q4uO*aQ!Rn4L`L@BL9jU#<%zLJ=Z$jq1tH7pN!0lkCx3YZ*DQyk{T=EX1nMgIqo zy|XKEvq|RQc z^#!5aWWME{AH^c}Llc#*%}inP57DWptDm$EVEF&p|PY-$eduZC;DSa+viSmA{y%to%dklP-#1Ioy4KQQdS5u!Hk&_oi z^w|sum(gvruYTe6n55q_N-jSQw+?j=jUP=J1v7K;bU4sS&44z@i)@kS2pC<@lc9eW zb`NrahwR^tQZNOXTp}uyKYjG-_EB@spEIH3j8ptT{2##4 z^u6?x|7*BdypaWQ2`QRgw(oxc@7E$d>p_ZN$j0wABzt$(@o0*ZGXb9|mK}Y3F3p&R z3ig>YglSl8ov0M9+mNkQZxU5)T*bSQGo{)B`cWcs7rORw95L*LaaQCyiU1z+w6=U~ zRd-24*S+|Y5P`TEj{*JGctHkJ#|*#4uRK|spn>|e@LP(35y__qiX(bKJfgl_!0%(J z#k_S;5~_i`T{ zCMUJqrq00I&F**M^Hr^013(Y8<$hpsd}>h@Ay9)pnc9}n4`FVf$&hZu`C3Xy6GrJ7 zIE$TdAU0;?>Kwx9CYop}p$!pYw@@e;@-6Unfkkpjn%W?zwM&RQM^9UsTjjod2hARd zs;yZC?OaJYYkHD-rAra8f+)hF$!yX|{YEj#yxi;dzLZV^0_VIEj;vQpC&^BuM$!_? zq+@^&C5RH8rv34x^|?D^yc03<8TY<3V){u92D`qIp#D~D=@Ni z1-B+ACz>jhol~y=(a(05q{bNj*6yKtQs<=aN=kVRQS~a02Z)9m&2x61y8pebyap2yUj0?j#LKetp{L5ZyTR%F93+ieI{ne}9n|FKtedPQ-(G}a8>7GV)VGJ% zzgJ$bZ0p%cQ|%4m_1CdQQxrC1E0swn8}Wdp+tcc)5a^_sFx3bu>ZZy^De<%(HfuQH zp#U^$1YG?rX*t+^IUc$4D|-!As7 zm*WcT-w~?DHu)qMa;PzQSS@tI@y5U0lfzR=`>ksqtxi(#JL-rgntH|V36!#BteA^6{sBE6MQgW-^oc;Nl{;ak-?kajo#Myg0=F z=yEWz%o&_&q~CGYtzYl9URdn%DsjFIr|d2n>)tJ#h6zg8LigrQN|L(wf27aFqypIm znCJxth!SXrXEr^Uo3%{Ab>1#^i|Re(o{C0a_@woTXrKD{DXA*QGHKe(rwx{) zn9U*Z^sEZM(C$j9I2w?#=b|j%VpY8cR(fTKQVGPvOKWrNa3ab59Z58u{Id-eY2$;Z z6HDmTnZxS>=Px+KcjLhCDO6oDU&@#nXRF{DM7Gz+M^Pa|-k%d5?7+Q4I|pS8$_f4_61U zqN+rLau|~#phep}ic{_dDzu%>2%6X2_}o z>|sLnSDw|<5?%}fj~L|JfRJQ^4;t;US*H?{7(hj8?9w~Lb$j@M8{3q@e#Z*h*`~;# zTYJp5PUbJpkL|4qKTx~=qw-R&JabsNT<#RCAQj8+&mz}-hCOo>(n^sn&od#bQ05T( z8>9K@thV?t#apMUTrrBF(t37tY0Q=;K@A5;(6lRMxd-Q=<4T00*2K@yQpA{g+l_w> z>0NN;649i3uHM$7O+0&g{mD2jB651|Wo~*6V*$_9_rE;0-Go)f8+{Qt%}*Ppdyqj;0G(nA2-Z zH(^yu_{lV-N9C?e8yJ`E+WjWBhfbm_#&c;67j?Za9I*H;3S!Yc8RkXxDx1$Uxi$){ zmCa(8wAjb?VIQ^@PZifd6E1Z$Pf7MQl691V=9#@Ia#%}=b+qd&5pW`A=ElB;b06? zRxPgf(v9Z$sYtFThR%?F{L8dx@GkPJVDK+#XSDZSsvSev)?{ZQ_w% zxZPn{)Bk&FQz^z@efzdC$v=p?iv|<`F>x=~3temin{DJc;Eb**+i=i+ZR;rh9YFAi z+48;7%Hyd4D%14iAJOIYd)m&Y4ttkHA?#X+PY>==bU6ma4EWWn)R9=>m=L(hq@1ae zBpoR{D)>CqnG$`yba{^OkRr@=LxKtg?mun;JJY#~5w4XzEO3>x?H` zjW>ZEuz(oLFa@?3TL-OoveTw&4sGZ7&Kg^qpWwE($4 zfIu#L|DBmLdDeNzl&+Aque6Wo39T%Zu_uv&tt0M};%HF+C5g3qW8;$^O->5#B*wzm zr#kaubM~#BR3C!a;J`MRh)emo)PjdJ#^y{?^9MGV5@Yg_NdunhsX~TZYk`93ZpS|P zPJZGSrx;pL|J9%XNYyl)45aupAF#lHLd1N={e@SF>oc4LV(L<-D^Bu{_qnZ9n&wtw z{+Y#)r4)Tr_1Z|qB}zQ=P+I>}AYCUbJDLkg+S7vlM_-<%VYYYwD(#~cZEa~usSaG) zsAT5zzCi9PR8!vD=F=S~uCnq54Z3(U&dSWhqpiqYz%)|Uryhs7B5;^WjO%B4%M!{=nfif4@L#jdZi%seD=o_)SaVdSr17*n56uT zJ3ucpHC*wBC}iliLNNcbHNWb`3$=5?fZLMXSK1~~I8E<9jfaAMugD$A8k;%eonzam zUkwYdR<-nA<%J7&rgO5bynj_PSKOWSwO!GKQHts0ZJCWZz&7Fg#q9kw7Rt;w$Rc zeWb#S--^U}ob#h2nfY3OZ6-fIzTNIYmh$3G#B=;jeX|V>w=;8(5C{`@;xHdW*nHJV zbQ+J>l`R&p+d&?SE3IPq)VMAEAgRF%2&{}KuGl-AGE9di1_sjKVe$%P>=br{7+WA| zM<@^TtyQ;AP3O}KqU7U2GV=u3dVONsmZ1f|?Jvw{|II{6`Q=2gsH{I%VGR7B{MOfE zSlNK+ozSAiW{AYD?_0N^y&A2+fq}{TS|~XK{}>F;@@2de?l16|YB6=;W=^zyTQMPi zrk14{{@%uxZNmkYR%1J9x>0wDHNL}rv!P6=oIK7mnE26wX_X*cs8+8f{Pz?~l*{4F zHj@qI?JjnDF;pujB)HN-K@*DhLpt!vpirCK;hLP3lgyOZaT9E{j59Z%V`3L$D?xwf zHVf+PQoMHk=z)6heD^za@yx#0q-3>%sB#+1!ODp2L6NEo&Tfa5{FGG>dElc*%Gia*m^fI_ zsvf@>BuyMwQqraVAK-hF=?C29@}91qd)1(B|N2ChaALU&bqK8mNaPpaR%>bZYrEvB zvzjl)ms#HpZACAo(3AyUnv(h%Jg>_s@pmcDbc`D^F7N^s-6a8zpQhNw^&S`VoygAX z)0=6rb{eCQw38w(vG}>Uw0fZ76GIk@hI$+c5ex@k&2%>M2g+{SXAaS3!LHzAMa*l? zkD()}P_U!wPlXTaSIpF|Vf_mv+?)NL01?ZZfw%tDV4mWhBWh8UU(QxK^s`l8laej1 zodL(vhKRY2z=G+`UxOHfNtOu>pvHn=vOHwj2v$Q1nTvyqd2KUW1nUqyu$OI z-vMMGxz+TkCFaxFDWT|nbKiasYJa4`FP^pZ1%wR(zidWv^yz`swFQmXS&V~Lc zEn1n8IRJvmNKd7IfX?2hezK_u;h>wMD@p~$ybz+lMPo!4-p#;3$o8sSdmw{m;zyQn z_Ad-AQZPsEZu7-BzS`5mw0M3~cHdQK?4dNfDux8HvzISN2pODw+2j&l)~-)zXiyZV zh#R?(s476%G`^|pPvPBXQ(8kdiYaPL%mSsnxR|>=QUnZQ-iQr?=yyuVRx^nhx%&_- zeT_%;`rQ6QJK_G~p1(w1d!F;8Zp3e;V1o_$GI6Bu&|#hlLp#YM>k$q_p)h$gbNX~v z@ij$}y1#+~3)wlo)NSUXYk!^egh(fMbzb1edtAsK$-e2YFh7(irRV|NmT^8@sI_>I z$8mkfdi?IONhC!?Eh==V;x|&FToX{mgcH6JW{Q@J0q2NEEqhNi z?Uy8;u^7FqhyhHc;1{Pjp8xb0c%sfZ`cnjP-zg}G%QTY57@>jA!63BOcjhxOB^W-~ zz#~CO_#zMtyJfWu2~QkMIyXlFwFg7^BnFhZnsI3fbr~Hw&07ML_MVY(-ql2m3>Q4XyxWtf{y?!3E#Z=!A4JPKJv0 zL4)(mhYMLS8#`(*2YjDPFnTy6=4CKPU&LdVfSd=kh4O(Qj9*9{DtPDtzz0VMmBdog z2`KiL3QK|Vmw9*xV0(k2Zyp2Zy%m^44jJPQvP!~3{Kw5qOkPGl3&^In7QMh&k9@zV zyR{uKYlONH4=H~+&1Bt|GomYEmFhjIpUvTec=t@yUa=^A|# z##Jb)jPzTq&-doykE5<1rHx>eBZo3g(~4y;3rl8MRIuf`|16e0^UbjYwuDOD=82y@Sxih!w$?#HT6Ozbh9q4Z)>w5HKE@&`4opYVf8@~a-B=<#UZ`Oc z&Eem;YH8hw;2DoLndKUZQavF>B`mW;hxO9Q=QVc0wkhrsRbojjt>}W|@ZyKcA9l&t zov5L(OX%SC07%luALIH$0IPMF?)Wgq!SC$j$`TEUR*AKr(=!EB)Ou3W+1H>&%n;EC zfpQI1dF$yNUm_%(kYj)5qMV0KLWgZY57q9P5ZGy_TCtWxxoV`0ML(1))zQSx#t6NO zQg|U^f=9rH`&1yWuOyiCa(Aq4`s~oowU)YWJm{~3)5FVZ5A>N1ELq7E=i^$OBi9l~ zQA4QgwY7ox-2lYKxeRHjU*!+lIa^S_RV7N2PkiC@>e?)wtipz0 zR+!CJ@iMEOXqIP5`?SvkAW&0zPbYtlo~*T3!O-nr^ID@lYUAPHZtJkbM`I@t7a@D| zdJH39VjN$#7%HVbdv?A` z^9=+(pE0FOAQ3tOpwpK@HApEPB`5FBSV<+H{{XKxT5Co%t|r2Z-M*d9J+*dK zq|RM&UQN7kd=PB5jq+g%LuVMNG5sxM-i9+Ydkz3@hB!BViiZIkQa=@d?97w9ac;`@ zejo9QDQ_cJj~}@Hk>5({f11ne+rXKx))RYmgb!5{!aqTbH-5DKOqEtre0#7@3k0Vo}naVL)1^C=lBKuXfpnq}8`k>0V|5zVR zt-?US7bulNLRsoV)!4Za8KD<;c}iOl9Ng^&B-sUlFzsGy31U6v{}Tp8dI~%mo`*B4 zyNdVp)cB)P>Pf&VUpZY1KZ~~Eii|$!Vc|*#W%ps3wUIvko#BY=8;vdxBZCI>gWYu8 z!-ZmPPY#UxGc7VSb(|2{G6;y)_e7Hj2G9gAzl&tu0{&06PBt5P=Zt+`GRXHORapp@ zFsT-K2wGYAxL91kE;_1ar%gDmv7gs*c$}U5vM^~7a-RwU7~o6oiZQay%_W5LN16LkgvOweGq4{6G~hPBZw1H zM^D55Wa?M^8lQ-&c*2p=K371aFbUsDbX=NR9vnF`BSacketZU-`iPxV|Al%)yUim# zj>Ab4Pa40CJP?~>2|cZyFMx@FXk;&cN`s$YI*tH;DkR9a^b9-mf>c!iWb|UNtD^Lc z?n@9Yx{zYD2i!<_`xU2bpUm7J?$=z8N+D6z_Ni27>hC!t=u1nfN(Oip1<|8OoMojruhE3LKZUb z6kMgsFQuIxnt&fTTYsk3v6AUtB`;CWoW19vb;D3snY39QL6lEo+74w%60f#A2ro*% z6w}|)2^S!&CwSAx*8Ra2Aq=!pS(6#fz-R-&nQ@M=7C# z&n#y!+ZrdHGHGfX;a74SrMempMBUyKoQiE$9xdeEKPV62lsB;QhI48BG*K|xyR1NM zJGbBEgB~E2!Y$2|fHrCw6YbH3y__XH=1 za-b^|tKU@)^7>2M9>ns7?Y$h3U##E#Nlx7NoW^`^KBwgr&IsUq_0yb8@*Xhf8i16@ z$Lke#V2tx?>$95w*oJcO!)m#1ptq;kb?rLPxeEzOyC%q)XWv5JeT4xY#=)OyYZ~?L zIle(>rYCv#rxsi1ALVzz4krgJim`4fJ+2-DhU3OJI2@>5P1{HD^iXoQ*{q0>^+>G$=C$orRh=n!NHpy?r!qV$`ld4SB@FRjSi0#E zTd}sYJ376!`-ZQU1;V~2s_QW&ecJ&9=%XN*%+nJ?`;-elYX|&4RVTX|>Wo)Cm5O~? z5$hY=9`(R>BZ8XaPwry{F_ynY+&i-cojCV3bU`vxqr_{(c-Y^+rYy7ObnyCj|CxC~ z6M1xEksJrwhq$Km;&S&TG!e2#4&w{t?#@)3=MxO*$2JeA&g4a`io8uWyRh4xo2?@$ z+t!gE83FI+7xo4~N%yY(N;oV1P@vd7G6`u6C0sV>k49YUr!|xW;0_s=b_49;+r+;? z4gWYq`KhVlM_T5zwq-L#dJ_VgZa7_p_BE-3NPhe7KPbr+-&~m`&2PYuGC4I}{H`Wi z?&{ ziEHfVw$~9Y$?3`Le*ggTrsk`{)qQG>0BFIHney=?#vf{KE; z-J|I|EKROx3{o~kYH-Kx$&zB3tcm6ui*Z??T5!3v-w4GM{uSQ?ba!gofGL4JK~G zk~A-7dZ WO`D{k*dy;ieG3u$`UB(S-d_l|eC2EIS;q%63-xFz~33*#RfeT;wS>BtR_2Vn-~hTS$2RHgRoL&je|u3~i)DsN13J8?NmKmM5a5v7!x8l5lSdMB{F^CZ)88(nu(oh}x-T|IYDD=D~ zju{B!bxS$c8lTt=?`Rv~$%}1oH-n&%{~18eo}cd%44A0Oj`(Ocqq5P=Z(v5k@wRNX zg(!rpvwB?<*z}hczd5QJv|)Qj@rKOydM=>JyLr4cCW`5+Z$Lq%hBLL0>@bZjrQSmF zTEzg0U#q8@sF}>1upI8K3yCX7awO|mY6-Wv9;kva>yRTLGjtd*w|h>PkHx zy+YbeMPJ(a=lJFWm2OttnlttxP2g9cu3w!0a-Wpjq$Zc>py!gMc!7Yva>Xy)+0`Ny z&w&86jwTmNv!g0fLW~zEL(_u>n99f&#YO*41a3_#7)zY(&^u66V*Om}?@azg5SrRM zFQt}cc}`2XjdUXsiLB}WJfC8G(^F*%wz^F2S>xC^Fkk{RC^??dER|(a7l!bY+f-Yu z1;eG!*0kh|EotU(mR|ZFqx~_cdg}4GF7GBEXR4=txE_jl*>i?!W^-qTI?Me#({7uX z)#LdJJ&=-^5K@AGv?k^@oMVm@tF-RA9e%1F7uqn=-q)y3*K-~&wEID=pSen76OoqknzA;%e?|E z5$tcn5I4Yx)8c`vb7s)bPy0DxVCNImT87M*F7w)vY`3&D3XY9YLbG-%k21O~(2*g2 zBEQ;4nA;&_5<0M(r8J}v7IV3TE|z|Jtl8S_Up{@(Rc;$y0DTk7!1eILhp|OKd(mpy zpB83fcMpS269+bK+1p7~L&?We=*dLP&ChQLwpE=kiFY+GpN!$B$_sEoA=PpBz>!Y7*>fJ(3nr^kxTMiL zTjBUE+^KK6&JEMIV77>HA(D?2<}nj`ZM~yqNU%R?jMb+j3%a%UM`N1guH!~mb~;NR zOpD(O)sF%KAiCxjRmOtwli8U{&Y?qiSh%VK-+m>? z)(ozw?`G0tO3|RVO-+c#DJ251%dufzmI+IRh!&v-&Sre0;C9HB6y)p&N`08_`L5bhv3eG`|Bcz3=$855-`so3-QX35((Y}{ycej=><4ov9) z@8b7)k+|_<9(N_2fFY`Zw}99+gcMgi;nSWjQx>iXey&xbQ+i(Po1D1lu@yYP;hb)Y z0_kEL));#z1`ZqBOzw3q%3UyQ9kkRZ47w?k^!xkciW|1Ft_D+#RMON4PR! zj8r}_Pia=iv<>ZqsocxVWv}!EKo8RBkdcf5Q!0X{9i?~b-%3QyAmmx%IJEJ%B{#IZ z(@deih?E9e>~f!A_)~gE@U*@~^r#^e(2KkOOsiupRL+n`ObLkX^n+h3z&g9vI#hZl z%s3t&Tii3i!!XT`1Jl4w_Mk+zM|KiD3S-%C)YC)#BMtc<{g6F?zib?#Jg>HyYz_0eY(S{Xln3j^MDMBt6Fkjl(IT7lD&PI^mrcyL>eo8fKIhUs&cKbrjAjWSGw*ROl0%3rU1 z@(Vye%t#1OdVFyZQM^>aUpZD2V!7#VHu6SiS=W zIbSVz`NDV*aOHdX`u(djkY_^x5pAhQ{C(vNPEz_HKkAd!QoCg+m~u;JY~$Gk+R)aty{noh z-|5%Yl70c<2viI!h^YGPh8apZDEVs7NUNA2#+sFxmbkRGxTS$Co8V-?^ed2ZZf1}z zy78!S*-pvb_<^Fn2DE9VtM%FGtgD)T^oNR=j3j~? z->N=u4fKQF9mNb*1~EqHx7`o=d8pq>zA)ew4(7Z}h1jLgN298w@M~!3!&Sa8gdR(ouZCbx@a`# z-gdU=Gu!#z)pA?6=B-@~STxN$%r+CaR|BZla~FY5oB>5MJvPA14j$;N#ie&Mf`79<_oW1Z=P5*7gWfVnIxxciVxQ)82k>K7E&lRiKXeB zX&I3T?{bG_)CQNEQ(e?-7@mGjsyf92ED81U_-Ez8s;%gu49GnU_(R^y_VU^Wt}egD|8B@H>Q4|E~_WPc(gQ#@t2Vqi}<7 z+PuptHo<}chEl~yAJN(e5IJrMl9}3&ZOK1};Zuy=W9OfpJi4W120{Q14xKa2kiF}m zCJ=|RtY2LNzJBBxJ--Ms2dR-^dt!5H%Eyxt8O5Ci)rW@bWowtp4v7$RAEwb-#H=|; zYz5BCN7SEkfm$*_(9XtRtpq(>hk`$PxXT@pkqK#TFc47F zcgfZ?BX{Tq!yU*;!Aai-^W9e=7c)@X0I$2b!`(~!@((zmY^pZSKG;cj53!Y=sAr-YTOn@%&xG_cKki8hiMp zfIlU=ny)a0ZCwM{0?o0RB%qzMr1ONGMpMz80)$nFvT2*LlWPnAuTPtYg&dGL8&@QW z0)hp%8~CGdrGR7M;9V}kx4dH#;`D8`{9Tb`@`6Y=iAmFY2CBv{b{I_VZbG-U^c}-l z;Zty@SdNB0D6XkH=549O1c(yFu6hv~4o4NezejZ7gihHs-kQgvW=ehE^DUCWJXcTG z5?+7GBULpy#H7xw-595!ID$`5#9{z>XlWy@;ZGI;K%%vJUp`eNL*B* z1h5!8Y$I1goZ$EPUIv6TcHjQJf^G$Cyvdd#{ib@Iu^{5QR>64JGa%B0Fms!VFRNcy zCoy??FKhQbaWK?_G9hreOaX<9Wa6Xd%SGe^&YDMUogS_GnF-ID)x(n8)t4xgx#e6fbY=qeQc$FXa-nxAt4W5c@s3FIt_m;{6*Gw z%n|(Z3+3~%LA&0X?Lw=gZEI6BArd&@lzv}UK9CMoXsIum2pxcD@Y*n4B$hgfcE;pl zA9RMP?8&9C2ZL29uaJk3WI`SuMyG`gf=Nx5zaYFZJIaiv2$kz9gd3gBVlPAM+5i;{D%U z>ArfzxfvRyJD^)I75fZYN1d51q~vRAJP3_s-uO3{2j=B)IAr{{Ro`YR+fWB z(+IK4PD|@gJiy--OjGEzm~zk%e3#^mmD`!Ji87fc8x8+A7-QmPHR+MkUPlI{Q!Bcf z5`Sh;eNlcB3*7OdI6?Y2gZI?{`DK~Htbb&ij4aABX$;uqR2bi!3SPgxvZ&f>K!fk? zAlPDV?~lBiqS?ZC6`#t!G-+q{>4k>SKzBmgmIn}~L&VGJ(e+gxo4tFk?vM*h@7K|M zoR~+%(`b2NunHC8*2#J+`;ZzXr53es_6OpH)0f?D? z{~jj`f}jNG?=K<$Xile@cVfaWa#yHH9>#9A zs$nQ9mh50dxG*%F$EhhW`L_5*8!7C zl1N}q`^wUy~Be+wf5M=f;{>v~GZ7BKB6C0)_;o(N=x=B~LYm5&`2M--%_cA7{Gy9VJ9^ zr)W`9k4{@-Zg|wYJbqD)Tgz6Nw5Yp4QuD<7&qW8hubCFb2aK z#qath^#=Ow7_wfPt0O8>Kry@0fO+!`CxI}+PsvNvM#OqQU$O!Ci^k>spQ|Q~bmrD? zn)Q*NolQ6HFU!W?Oty{_J4r=zRNPB_+?Nm4#hsR<=gLU=Rdc^-rX7OH?%4_`f(qLu)2?Wl z%ROHMITdy&6|BS#xZ*^~T5)`~p}d zx-~;JTT_z)fpakE0^&((xUi*Eb}%GF>;)u7(uYt*${-(6J$=JLcR`OZC%MX%s2;}T zxn$!6uyFW3b1*0N3@d;F6aHAKx#NWVKwRL;{>ZF%TcsvxWp&URQ@vv9{naE0i01TP-VB(2jMC|$x)-rD?w-IKP-f!Fdm%CCUpa6MzLuxFfde_QV=C?{^^p_N z;gikmHi)FPz;JZ~HjMld>j?pv1V)~qVi0Ll!-XDqbp+wO7nVPe(^Kq)vbyfR?SW!> zjqw#cU7-DqyR#^8nRy0uUX_|y3O4zw#9HFj%gT6HBX~5r_OauhqN8HO%#HXp9hMd8 z(;)Xx1&cJpXcmX5m@x5&GQzF$E$BgdA|?luOxg^N`augnW1evZ3c0KQ{)-q>swsqM z3)<~KA@?YL1|oR1i^*#w6EfeVm%6$(FJ(K3zW3K@i+ePFcO~SNEZQExk?5K2C*q9` zG|)@9l_m;jR~8RC*G7kiokpy3EHKC^DCrT023?ciR}>Pinyn~VXHX||d@+Njhy0-G zvoGE)fu7fd+ne{()DaC;?h@}+ETER+(eqI3Eh`zcexb zD}G@ked{Yw(3&sHj%n`8-SHS){BrGm)B+FoyQBOHo*>)prz1?Cc0^;1CVwrAR|x## z?Uqkvd+6KsIw^zlJ(Jg-xp7fvR6B2!!2HTN%O8-|wdTPU%^Xay%nysgC#!5NEqNay zJ^F_fp8o;*sM81bQu^=(+m6TMCcoewJF4)@!&^N-O*Rt=)ki+n#V;~( zK8pHRXR8O4)xn%|=7rw^R<1m&%tRq`wiF~$ZwN!~aY}^8HVzsM@6hEjzMKaRz6>x`ssT?#+y+GEl zIr%W~vWqjX_p{_iuZ9I|%?~wD?_Fy_3|?#p512;#4;n$|hM;@8={W9m!JNJPOOoLR zhseuoWfwhLf0gc@4*`nT=1bpyni(%Kn{BpDa3V&{ofho`#hCDmlA6%NNQlCu{>-li zE;iw~VYCGKRH~0>p6&h{ZNN&49u#!q3iKDDf|)Fx;j~q1F}Jj!6{qgWP0hFQ!q`*9 zb1-PPyehk5-3IdHx3wt?tbe&XGX+&~Je7FJu}Obs%~GS?y1lDjbs13)eDT_Y+-(HP zPo&(~3>iiSB%L!6bfYI{6zXDO?vfXkbx|@#O}@<{Uh!yQh~!;^;s{4+MygD9(c20P zO61RozDa{Dmb|SEx~pJ5gvp|Z4q#s?u*e$GDM=d0x4M%XwBgr|!%>)$K3e!-a)IZ@ zGVLoLDkN)+U_&H>Pa3H7x^o->hEhnY=$-_d?9;%hMP zIS84F=W;*62}hKzE4XdAsNT*J@nc2D|CiGAtyjoKu`Io+w16*+f z{Q336B_EN}5Rj}ny+pAO1|@TfQ*1rA@<9(ke|cEMK+xEMrAyJco0h(ba0ROs%?G{N zHu1rUgp#hZCLByOeq22v|JQl;^fr%-%bPc6=zJV>UQ)jwQ0?Dh8zNgHBSdXp*Nr1` zZu;+AVQ`$Gnl}zD?L#d|S1jW^9S%VUW1!B6dG^e&{uc#Wz(_A10*0=4rKU!<-7Jcr&zx>Os;2T#wXS}exb+%CI( zBU7T8^Q}Q23(=H0I#T9|DL;p9zK`?AwvEl9b?5TYkUZ^Ii5yfe(Y;)ZufBCwjPs(& z{2hYmsEz#tdGEekMmazm*&9Ibup^SPBKuuQ|1fX<75x7&c9suKzHb{J-Q6&{Q@Te< zcehAMj2xp&8X04>!W>9oG)L7Bm_z z#WpuakJiA}0&RSbxJ9+;YwjtF_2Xy54=$uWmZj}A>MyyxOzYfwSeo|mD6D9q=qb!W zIX7#z_@QX~e;UY7e^fqwO}OXzzFLsUSd{A7$|u7XM9-<}m#QXMe%f)q%o~Plr@3e1OmOioX z42jE0c;wqZIZb@@ECuqG{{i9-w95;)M~U%xX-xg9QA!+lT_x%(eHR#4=wR&M0?=MT zjBhf{xz*j&$OMyf+ztf{3`)ya3`P{U;d`D3Pt>kSt^jmjQP|8S5if}tVjb+cUU z;IO6Tc(eFaRPc`ZL=+6B7x3kc_kve~Td+7C@Myag2gaR=fh%exl?JIz?aoUwf7P#O zW!Wihw^6a~A5I~ie_%E?Z$FbK5Q1V%#;>up`M8w?wPmbPzYpP}KwaI|nbF$GVk5^d z0zPFW#k>0diaxubKjL@~F9e@#U?5~~tJc|Do3CN^BlcNddEP3Hnd{}AYO?m1nqXN1 zE;upPv{nE?#%DCSZqAtJEOpy!Oign`6*$jk?aYOC2@y`d;>DJ5Uno;|2V_BhY9yXB z&G~m`P$llIQkR6atW2O7A=5V&qsGsP@i(%ip+>#q`s19b z3e8@qcu*OD(dWU$kVdQPF9{-eTrKUe54pVj(ezuxCr8-UJ2J{T zA#Y*MttRA}v@nN;y&y)G7Y@V9P205kty(FTk)`IZ1$K$7!BCE=#EljmrN&8$+6+)- zx#c;0^-%VB3@;lW2O?Tsi9`BNRgwy|#|}|U4Afo0ya2Qh>=pYRI?F2VK|ZI0n-h;9 zjq>b^Fe$|U;Yl2mHXUc6xGCh_R2PwQZ1O2%AHE+%ovA%3@bRQ;SRzy>h$m|^H8@Ls zUBPi#Hl^=`ME+nuhh!S*&4s(a$LyI<@KrE~Mu6fY;;D5oE`SuQy~v!#VM{II`L}By zT^W!0IU35x_(@k;-5bHu1nsMn zjtZj6bIapB?z^-G&3ax0AY%WchivPFH!0Cu$0v;e&*|4NWx33{dZ^D!fzK{PD#Q&G z6z-)2bxY;^!L^#~QFZ;`f8}uKCkh_OLR_)V^w$gxBE4&B1$3X})3!6tufDAfj!!;H z3!4J9&%9Z}mu!b)$-7z-Q)BxaZV-)*MGXkZZV;|s3cx#%#$G&28_1F~Y*WTHVMqTX zv>Xr{gM)|55weyY%&$0532HI97-PUYHl<(We71pxG0PT=y2MfMA-&if#U)^3KcFyw zE@Jds)g`rwESrs0&@tRRg);v76+!_Pyh~P9Ou7p}ksfB&7L4TeW0RuiK%bdtZ`U9i z_CHVN`AkWkRDl8mO%=Fgz2ce-7?UpT0{ZTNLcDNcM}OTki}Q<=;jF9CAm;iPd990l+=bahxgck8DDDSBO@t#)w4KjYeJrcWaITC3+Q> z+kpoU>JGgda>kOKtax1yoge3b7eZH%=YoYgoC_aOF1*2rPv!!H?k;87BTsCcL{Pvz z1sPgId*%Md1`*`hf1_cnoa+L3+Pkdye3e!zq_8Al{+CX6)lPdO-Rg>FKaOkZ*l7#w5n?M`%V85+EV&&rc?5w#CA$Jzy*qWe6H z#YSP==VEn5a1OQyAc>eH6mdf{w4L+ZtQMcxYhAL z0I?40DR7!;a1}X!?V4{AI?hqvHkXS({==DWbJ(hI)08Qed|idLKAb9)^=zKv@FCgH zA{}|XNp@rWH9Af|0kD7+%pC9mumR{B*ri#r*FPCVkaw=VjirrNB z3G{}}>MB5nWwIdYLyH*jvmL}p;!f-=^%ea{h?xpg4EFvUu_;t_?5Is-yR@3+zz^<#}8N+?i^L$i0bOZ#pdo69FZc;19$wv6*=CHxD3vq?N z2m0ZWuOYtZ8B$A^x1%Z6$37PL$l{h|1;g-Iy0TS~=JnW|lXJHw2Fv~lk zF&FE*#_HYjWP{INWZPOjBWST5qj_rR_1eW^tsHyb&M-F_o~X_OSiGc)MZ1Hg>Xlee zuX6-_$Uq&wqpNLRgO}M>Iq{&aX7?%p%98a_=nM762nXz#unGf;`P9i!bN#4yl~7rr z!OmIv&iBh-Y0u3IIHeZE=@Ml#=GL{0S+$>I+uT@wOsBT8g?!ox#LG|?xHj2Mrvf){ zcCGqeh9?r1vc@!g8)(`%K0a(MbZI)sJ4gZPlpL&&hE;AlY^o8z9ml-G`f_Spi-Ov; zTSbS*Rc%B7Enzn`YAk$3Ci-gg8Vp5FFurMqBAk+J$)Y)c7LBR-jD{UZpeIpP&QYm# zXohKomUzXt|5Je1*t0!BId6!=)~;viU+j47EPPhmD<5;w%&vasniO%;vmH_akG>PF z1Cz!X>!eML5r`?tV96E2fDY4fzVUL=h3RmIw3lDU7(>7xN4S_JS~oLWy`8jDr~FvQ zzc`O?uh*+0#XFA+09`X@G~pI4=oNhBk`2g^aEL4yEP%k;%UwUV+ru%AGffnOjdz-` zk9uv8+q;HzY!QTI+bqcajGugXt8MnKYbaA5gdH8WANC!Ya)_N`LmYBm~g%9{E=f6#T?OWZG+uAnHiL9plbXzV?m)cmzC`w);!UnD1q+Z4tPf%Tc=ixrc_9|wT9AwFM~I= zSA4G?G&R5)->W#e&UhDj8hCPGxXXZrTscru1-xqRoD&#sZpKG6x7+chrMH?@cUzt? zS2u(SN*y*kz zv8xLp)3$vbZssDQ89`ykdYNjgE(ZVWT$ZlU@g}Az@TabEipl%uKHp*b%tP>S%T`(w z0O@wr34PsN3=PDxT|2%}il56YC*R3YAEWKHKxiC`cuBKc;l9$GrYEglDJnxLSEtNK zP+HxDG{&v)v+a%3Py4fxpOdm5$Tl!r+zKDv|8Z!J8q?M*WX*4crT#Wcs6G*#_H854 zm0}m+W)>A&uOj;A=0@0}H>-bB87yM9!szkm!q!M!TvqCkNTh{=^-F;Ez6%V=Y&S#^ z-)ja4W>B6;(`Y(Y$Y!pgiv+?Byn}>wol;!9S$+@uZL}t;Izo@1Gw?^cF8PUIa9PB3 zIiMEkuh%OE1?q?D{Ha}z%}R9;mSq%w&0|%l>%_Y$!|OG=5GwE}h?OpuHanK$yrV#p z$LJ<&u2_Seq8j)+9Ao^jR4mRD%t$@G_~F4#L)<`XoPq!M@<>d!@wh9u*&?XwKK?m} zAN43@#{B1~nvO>v^7J0KQc3H36`1CxG1YAqn!rdOk3Ki87Zw-4P&D!V4eiAGM*X0u z;dUZDX4AdnoP4<-3K+uwV-a%M3bylAxf#afefriihSA5{YZGsQF!k@-n_JPoLkd#qqU(1 z(YlNlmj{?*baO4StDd43@=!aCzPThhZ@5G74kUlPf{dT*3YR(SnH-1$T`sE`*uP|m zVm!w(6TW8cWx=br(B|IRG2d3NQy?3tmSdMpO^qN`a!IczsakJP4H~O?R-st>lO;+Z zVVmWxioe#L-Ec=2ydLTSrse%0rgI@Mu=$)v`qPKv29rqTKyDnvIgEYMwoEt<*+S+fa)i3k%2h&;pb12#K`5J-09$u%ySz>n$g&L`?k z*P9B?x99+|$Z}IsWXQBs4~0+bPKH;58O-!6wY?C8xBu;6ci<7M_F3Exj($YWJ;RvP z#)LmX4T(Rs>-@~%+am!*cE+pD%wt&CH$??U|sHj}N^=~KOiJ^Szt1eID8sMZ9rq!w+5dW)&zitxU zZ@8~sG$XF`m$Vns7tSCLz65!W$ZA~@FS~^9ljE`6jEiW!`?;O%(&SOc`v zv+=;DF>?MFKsn9QM|Y=#klMY$lX%s0o?!h;Il*h%=$}$4+*8x>W5XO1Q{r1uo<;7O zBIj#Cth&T27qS9Mxk(AiSI#8`uBsWM8_4h`+mXGz3G|aAdCIWt31Ep)uv*)(C?#&l zl=fTcupsVm7Wp}!I;_SBizeaTfJO5%I;nv9PURu_Xc}FgkwLRzrvh+EUJ3u$anJr~ zCOii^mK6Un_Qc`Y$I@o=YW50Z8n)GKN<{T)$=^WHz8URx3ERG*te@LWg$);n#7|r6 z;dJbaN)^#Q8TZUG%{bghoQ{oUq^>XuM80byr;9Jemn*9iV*R&L4403mS)$wVk`HmiudFxN?SMf%wd0i| zVVe?`OuF6h%QB2pZJ$c}edtY%{##f{pRXc39K%dF!JXbd-q@adJ-dw*aB9J5H?~GD zb}OZByH*D^Z~@H21kPz6c3tKeiy0=Xw6)lFB9>0W zhxRY(>2EsUXDD^jh%W4cM)w8mo?A)a+~J`&{dxhzAxUHP!Heuf*Fk9cjX~w}xSEXs zevb)*QdAcTb)AWvb|?Op=JoAs8Q~zL?}rzCHL)r%SgIF<2;1K4a3sgu)7F$LQ;gz| zs#U`k3m}~xLKd@o$EZ~^Cx?HY9C=-Dl8+J9hf23q(ZkH-+3}B9zPhGDw0)pLRb3d_ z_EIp}fvV^qo#P}%<&<(@Lx?<%!iG^AZB)I_S{SHAg)6DxbXH> zV8rN{wY4bou!7hNYFx3!58*G$st5L$D;IrB7^Ht4wSQkJiLlu->9v8L>-Gn#^~I0% zpCeTyRx6=L|ewbBhGfiH&KF^kNP zgba;*2P#_zI%kz`@Nd6ijdh~kru(ZA4naGazcNqolncVyj*TbKhg<5T|4;ph=0KTF zKU*cTI#f%Ia9obR^hqDy$I624)2+Tu~GxPUS&Ay6>G~rr& z1bbL3&990N5c0@WK)d$%eZy;$tF-cj5uUg(RM4+J)~S_Uj}UW5;UZ?Z7o775Mj%z)8V z#0PS!pC-0%Md8SgGKF;Ym;gUgQF8NG5&VaI&%zg9k7i8HVHsgC|0AAQ(lxbTVRv3T~8NZD7%V%PM+q zXwp=00Rfk4Rh zvut-3y}1w%aoqO-{#nXQ^q2*(f|K?$dG(hrGt6RRVT9eCnW!wW#g&Y9CVFQmf{%d= z1<^rCNBxipr*fxfCNacE=j!d@9k%{lA_|1~*&n<5A3bCRWc#c7g;beA$6v?yo#UA{ zgQ5RCWmq8F8IPS#V|P;Q7VAvd=4pa&iuh*j=K?e#!#GLk192@^J)Fk~#9!R`7Rq=& ziBVX#lpt`R%5Y1AoPR;HwckE#>M6XR2`m&P5lvfsrtPm>&qDM5kOQ2Qq- zi~5&S*pR}9qIv23<^DZ$1h+IZxKN@1O{F&EO5Do+@Fd@ls2cPs#XCiJRBQu=*s_j$rSPE*gnbZQ zmg4qKFqYJ)x@v#%dq;*~16B~5a|4;wN1Cay3%<9L0{ZXZ(?2w@Qk#5wEt5o^;T^<39$y6l%-V;e`;l1Y5cb_epeelBz8 z^ed@@q10dJ_94^WFH{eGSpz$QftG>D7u%%E4^dj-LgRNSEj+t-yArKqqac4U-V(3* zz|_Ni?Jv&`RfLNiZ>;(L!ZRZ28|W<1^g!}1@nzeL_Ei0EWM>Ci3;P)82cz(+ayJ;M zOtzJ!3>Asa)s^O+*(V5*%{9vZw$fd|H1r?9&4}-L=MIY<&6L*n?wPChDE#_bKa!Wy z(i`0}&Ys)q_BRH+!?fZtt2m{Rfml*TL!a8}w`#R8u&I^`b0kij`EC07m;$iayCnLlcUV9 z|J>#%5;Z;~Zhzh2<)S(Kz=e3T1e5ktG;k8Uuo?Mg`zk#xa6?ND)$!5HMtCR6(tqOa zEboVQm0cfWN#a+6vGTM0%8oR|$>L}`U5IE&@o5~9i*k9mx@{p!$l^{Xt&9JlVDOJs z?C=h=%~uKbw45Whot4`!F>UWtEE@a{^CMEYu`TB;E#0WHd=HpuQDw?F}1Hhht0`RHr zeVkpgplo?_X9iq@A2fNGFI@luy5`v!v*;q0H)MvQ*s1X)kDGpQt_u)Ea~v;xx6{v$ zJpo|86N<>m)*|w$oDJjG_Sw4HBwS4%M7~kJI_3D_WOw=dX<&=#OkR4hFa%=g_eMVd z=*++753O9O;U1*xJzlbuYSLe(%u^WhV&oUT#p{+?Lpxssoo7QN=9#Gq-mLb>h~K9s zCNuAS?L)>#uS-=-_^p4xH2(6*Diq0WhRV{S*?7;>-a^rR!LB_G@w+0j+|Y0|`FXT1w#Uw5>XyoN_sZ8chgGP6KhVIgn3ruUFjMJAu3G zd$?&I4kaf@x$~s+1YE)8^tcUvGx39T{MM ze}M;kAUrhBrF6i+VVbuZ_RT0puhw6YHM)COwWr{PVmEj!{4m#6mYliJ#U%rWj!IO44+!O5e-8=1?wBgplqHm< zv9VIzC$oKz9RnyD-yRADP{98#2)dx-Ks!Nb3=%4fPvYY*&e`eiOUX@s|7ujk9IiR( z4gMOyv&0r?g{a6N$JGo7&(^i`d%b`pJ$UrM#X$tn!&D5z_mTLryV*dP8gMW!3QQgo zxLe_!$WgK>A5yf=9i|F8o(+$|HVPk6fz39eO zwOeZEI4UIl4@?x&#ovi1D_dr%fAG<$T;lBa%wh(Ag(7)a$v}%n=e8$e+1&h23OIp# zhT}FPgQah}#|ybTECg^;(?#Krs4`G@KWEhq9tK{2&|h>VHj_n{h2CUJBM6T5->M9G zE0UJfVA_1XI_i{iqMBg%sS&3D+pth_Lb@X3!<=RN?L&%ab019dzRK(Jep)xrG1e=P4PqC zt%K>4G`bNVRa^b}cXHWR)%I`tot?pB#=|ZokJDkjrC*QR`^^m`M;X{0-HJVJcU=S< z@PB{=^|+iYt4prO(Osw=+}u&UnkOMw6nH!g zBquo4Lk0cgV{{2-*QdyeSg6BSVJWEY!_~*?lN&ELw7%W@%qN8?!MTuSi7PJLk56Ez zewB@dMWd4>yAy2{cm77hF?Es3I_+o~{k zCwz`1j8o1pA923*@AT_!ZPus2ZaY@?$J*f_e~0g>O$zBIwi*Qo_!gp=+5KZ<_13N_ z>?Q{d5hzQao;UQE@HNH5`mvC93bn>I<9y&0^P3AJC*xd>!a?jsIxbpJl!QJOXj0xr-TRb$4`#9%QT*4ut0COADcAFCxt?I8hM>#z{HJqBJH_yxg(3`L;~ zF=Lky-0Z+*5jKl~G>g-@smjb%*Tr6>q@V$S)?05HiNWEEIn5?)rZUP*8ZIrmT|_aS zmtbUhnTD_w!!GuIjU!b zlijL5>mV-_7V6!!hH}cI^$GT8w$E7q-Vy!dFYt$W+~G&lc}oAziujs>g#wh)SnmE+ zn}0T3_}=fXdNr=>;;_eI_pfb_V>UQs5tq$bXF3F(AdENS=YO%7xl}NcS<-Y8?)s;E zitxHj`uHm~)b=V4k5?+Ka&yzLl=hdv)wO6}ect#e2%M2GOdYeZNbdZOI>%THqRB6z zhXn9@l*C{y)auc5EhFPBiBNNR&vx~cr6*M3F%k~^wL?u4kPI@kn9E_Waq~Yw@mLM1 zzt&2Ro^9H?8>PSMERDJZ&5JIzuUO@}=vthL8L{?^QLi33FuD~VRpncTiZH7$Gm)jA z);uE02<6Djqhe>)IjoW|Oe;>CPb>Bhhg%tu6bp0#!&e2rPsX@l`O;gxBp!7WMC#c8 zFj9NfW^o~5R)>#gzoZ+WfoA2>-)fu*sKg<~PW6!3AeHhxDf&|*Ty&g`pwin^PKw2V zUlLGk`3?|Vfu(5xP{3MI?&T<_*_zB!U=b!vVo_9%8~g9$UizvF~_oT6aNsMU_2yRZ|HI^gp>hBV#l; zvXR-6HaK4~TJ-lDjOuacq4!{)(G}#&mE4Sru{4zWubxFa!dPyZ9E=hMXs;-;bj(ZnA2e@aZP{IsuWf#LYfEsG;ajJ z&`5Yi5gfXabUO{=Kt=6J+|~<`wyt0;yjQV;%K~pJv$k`e*(wB9eAFR(!v&MZj~0 zKc-<~H|zXE=q32`;F7Trm&i9``(`9{FOmcd8n<)!OUA5RXxGvCT#I&-LVk1LQvR@L z7i$)t?n}^kcw-nIFGg*g#kXk2=P69%-UN z)E?JWUa>!iNnOOPAbH>&T%;cD;He(HEDAZ+>o3BOEW0RLw8eIci>o`QPQX~mqlunm zIAwe?XR=OKe>qXN2dduiXr`D|m%du45KmX?N!q`kM6|ou5bRoeEYvb%8$aUhS(I$JYJs7f( ziZhj;CBCQ%mUcHCp^Yzk*sI^(iItk{?{h7rFn9`)^lh9x1wv|QSh^1NpW}f|!^mQ|e_)6a{ zOyx+f{)!R~St#yIV0~&6#F^p|FD27WxnPxbj?S&WGamBWA%uP%a{1ADE2W*y&G53i zuM*TM{)`xE^)yI<4fs;P-;Nc7XImte_I8y^Ms>tB8z?Nishg@JJ(0sgExW^6^R9mg@SuZKxGfs}n%rgMH&OyG)eLoJ!ksH~bIS7l zxLC*zRNRVQO`m+@Ej;;bLIu)OB}njUq;> z|209ciQ`w19t@vclS~8T|15+_f4LslIYwCqS{cXSz9#G?86xd6i<9jyImgLn@jkc4 zbOJ`02YB8YtdOHG+QXXQ=3XPAuJU>YYaVbZ zC5&PB9r`Du^;gu@agU{SfAKly=;2G~^ozgRSO^cQJ1n@_k<%FbevzC~MF6BBtzc;% zqdf|>MFYp&vi;fo`6Dz5@k=-|NIUT+QOVY}Y{S&Z%FPKZY$60TQ3X7J1j9C~I?H6ib3Z+eLZ=ISBEKN=RTJiR2i-*8}30BXIevk(M z?DvpWwb{a?srvIf8kD*cg#&F|OX#^4BLv1~i2Hq7Nl;Te?t%f`fHoUqVO=Wsxe}ZJ z(IJ~9Pki(mZ8pc62K^CsU;N7HERB1!C%Lqb)~r5^Ge4nDKQTD79p%;z4*hwTc|dDi z=6DcRcE`$}S*1dG{@CW2a5F3=%$*x!&W17C>tijmF4Dq7e=FCpJF&f>5ctfKXfJCj zCR0a461bu``B!Nl>y1q>zL`lF>6b8imdC(G%crG9&UenOYzWaB`Nab?g-POX+bgA| zfa2?x@pfHn0f3HFu}h_WzVZ@Tz3)krt<7dFhh{z}lNVHd$>+f2pvsbEsY~}zvWMAE z2qR0~F;s4p<{Kie>s)FhIz0XbA*!nGpbN5O%U4oX^#AHHyc|}dj|wKq%(cX0%YLCC zUNuRM*K7XXVsQs=y0=3=XeurPNSnEnW;&quDs-dWs!%ZGiK6--@Y)Elzq3*s`a#{n zuo8^dQ}kN?t?+AI)UM!PccoN;?8lP^S|K|-?p7xap(}#YSI5YJnJjqmSoyTdjGpD? zEOMH^li~>FGYt(cWQmv@XWtgBPaCqT94pZnB!(p^D0oP$!mVrxq?`4lafmBaBZTs6J8T=_c!EVX6^w1(f2<=%O>OcoO7Wwo)XutCeGHKa`bzcm28-zp=b(K_|kg=T&OLsScWKG zFV5>Xx8+=MAaGf>cwG6%(t1v=RGd{1AFtQN)@X6f<@8}>b==yX)GHs6`dyN?G0p}7 zJDD_orFiC4{(kI*b^U6d-PpW9vxVx594yoYUbzS_x4wV3>m4&C^FQU9sBob$kRF{Gv|%&} zE_h8f(|%|^ZYRrj?iLx&Hzx7^JrnqCgG1;=;Au86^Oq4`Q!W2c(l)_6dT*B|$tKicl%}SV{)-f5FnS`z%?xec+~UoUb9^K;c!#|`N{n=UpNhfm9LBX0 zXJcRY{9a!bxZBIII;SsD)OB%x^cLv2oa#q(vink8fggm}7OZ%;n^gEAfN2o%9q;#CH1Agck)1;a@UisKW6ojP zeujl?wLxpzJ0>E7f3z>W-{jX&&+WAJYnU`#f;sIgZ}C9-sfo-`J4mvNtXp4sAeEyo zHWH)yHTAsMe}M41;mh5fj0O7<6g1nMb=P(4b&G!lmdNXJ_w7iHrG|`QY68CxyWfzK zB&10%ldqaEZt+`AK(7TNUz25trFZbpx_r27U^QF{lIrwazq&#_PG{OShkmn8rx+Fz zMu=OcVU8V-4*nou`WYTq=?9d~fxR z`J)GR_K$G2-wK0QpXXYRzD&cP+GHL%Y-zVSA-@lMW}Z=Q)zC({IYx=|H|};Pk3G$G zW{`eI*GS{KBGb*{2R~82{51%<@f9#D_25g0dMkz3mGK|I%t2VB4Z<&U{|*B>@=A*6 zTk_v~sB#ljV_>%FoWCqI7^{06o;gQ1Eww+#9#x{CuGF^c6B?_nV@;-ywCIh;3y`2# zgNcY(t=$m>y};!0`?gMdAu7oD*Lo4?L@XAAp2^<-Yu?Ck`b$<9$8&p2|5L2?eD&p? z6?rWmvJQm%N`hI?jt}LbX$LixmNpCK83QfeAs>&*aW634QkHVAzy5xDk7qq6FcJ+B z5E(w}nHhKu^vaHb`o;rys2)$cLt89--z9>A(cvh<^e_UP+4LCKi z+v$*jjwQhH0yH4f=^xYT<6rQ^$~`Tbp6SdO8tK|k4d~^r{cM9!uaHiO_Z#im{|88p zWWsGa)Ls;V2vRg@Np)0Blnfz$SAS;N))c<@9?d#ECRtux4;p@*B=7VxYgfZNoY+!5 z8mGf6`OT&@-6z=1SD=u003OZEh?@Ry#cZ3_z+a_#pDthJqQXp#dS6MWdl$u(byQ2O zg9D{)CA78BFRp`j(K&t?WT4u$Hlp&fZglcc$ys74dDS$3f+LMv)ZuJ zi?vf&y?dEWe=towXLe!Zbf8$Albqy6DAp!16nU!m9Cvw=XJtac>?s+5{W_p$aVUim zTnqFdcSKG8{9=L_GAiex!)yz)#;p=*9LKr)R}l&@>&u0pKtV(6Ju-!SPe_3?E$WAJ`T zl!1Ae;wV!~{M@3N3w2MOlKo!2oh5|`y<jP3N)`cSNF}Y*Yw|t#gNDZh=7pIaaHPm#FLdC8~3JCTmpqD(fadU(bQTk)v zR=*mMak2a9uhnaW`+T2|cL}z+*h5w4powUQ*RDcQZf&dsbe064e+2E|(D2$8izIVK zK$LU*Rj^$!t2VY|{maM(x|?>qCWkiNlej@2>Y=trNv;bPTW(ftd({2&`D#&`rub&D zi}k9+g|2xn@OzM;jQGX6_H1=Ik0pTC7*xH+Owc>MwvBm8pCLiDQ6AL(hnmV(cu>wB z5%*D1`1{HdmrbEjPGH~8Dm191W<$s;goC_u0%hX-mZ|Hgqn=tOKs`Bl`*%&;D+V@7 zueR1po(~WS#Z@bk!Xo16u8NZV3MddsW0Dwa+0#xOgPgXD-^8c7)V+N>>IvPltvgcyS81g#}=oH2TSKEkp z0nNEpB9DSW0-2UV+GvKe*a*M5(BH_>f$CY?L@t~d-s^HCwd*EEwTMs)*T*_nb=7H8 z(j&R5Js#7|6ImmA+;yHMZ8K2LP^4@Wke5n^8A*)m{BdkMBAnRNqx#81XiPM>(% zN^g8J#;6=B*R;560;wLB=7?q=30dERespfvI%(nq;INPhQov}N61PurToX%zxesT| z1c!k3$t28v>?oJFH-;<&l^&j6%=?)iPk5!^W8=0jnQm!8#oGH=EWr#dsF9-BtDpK7 zR{mI2F#7Y1BLyQ970H#on1HT5rJJh6p~}0wXywmVr2VCuRW~7e8}UbvP#dvn56n4%m!!VJtP#>i}M7d=TOqi2LSjJXu6jQ%vRIGGZjGlz{M*q}z{I|`-p)^BeRFZkw|rJk zGPW@sy8Q{${uQJZ6K_@OoNn^d*U?C;wA1-mLDw5+vER#_bD}!|1h+h`duUyc0&*gq z>Cg4Ct;xSBC~}!{tbFDKZoY6|rP@Dhi|yeV?)7c|W_(mBw-Nfis;>AO+T)(Rp8q}H zx?Q0*u;GIh&e?|S9X0-SSTSLrE4;Ae(=?t@8~H`(P#U75D>W}wAM(gs9{9wR33ow= ziXk0khAcBR=*5PpT~JnB`?Sgv-Mx`+n^$YFJ;ye?)FKoj+S?eLVzf7DSh#So{)K_K zr%GT)M(nEKi|xd6RZsfR@5cL4yK?m_aQSnW{`2)1#b`YS7rfB^n_+Qofi;k7qv}fQ zo0&7dy@k&F;!w9&SRWuNDS9IPoi{b6_C--mml4QL{F2q+A;sx1%IBo-3GnN0?I7mBb0+q9rbl!8h$kk1CSsn#dJ}NHq zB=0Y;Yl4W#Yn1CfHX?=Q>6F1s31}fs;D3OWM*dE{YS%5`0v{(_j&-7H+EW^962ggr zU~yBPT9kKk*`n( qh%4P{W`@z{(?Wrpm62p6t|BSF4d<0xFXD_P`f+I#wbLJJwH zCFDh`Q3(dFjk+=<)eoif{RY*2E~RRZkABWwu4X)qa4r$3PmQLldK% zr<&7efEgT2UXjYGKgKc1^vnjLLl&VA>1% zL~Zs5+mr9T{z`Wm0plk@sxO$GXG)8!X^%tE=q1|o@%`KCw_(} zx0{wW%7bt`kj5D}isO%-tL$~f=0qVgpJOcTqCb{Wyip!j$qQd`U|o3^@l3^|v&+Cl z_O|S=+PzeM?=(Accs5clc_Pgu;B)I$AX&Lf&8N&6urWOZWikbC_8~dP=-KNrBEpX^7se;3WR8&aGcNcXG!?lWP?lGk{QItzP9T8;?=KEiWlKjI% z_+c!W(C1txo%HXO7)WU|j5xDJTol)CT8?)$M&!1_{NYg(tF5OoF8VbYLS~C=@HuXo z{5{Z=L9T+sd%?G=VTe7BZiMBY5W!J9!5O?AfE=9_kvu4Viz;~HUJTca87 znr?6YS3P-Rn!{7V{PSjIk!)GkA4&Uc7}zs0Kaerg-;1Pe(%hK{A%AUvzB5l+l%>p& z7$3G63S_cc$w;KhWNGrj;XQS#>v$>Pm}-+}Sh47(0hB zJ=k-?1LJoYr=;6ENqnd0rz+1)eW|yW0PnSrbup-myDBkBL>YC4Wsn)W`90CpqEzMV z{`^F4d7kzJSWB@r6o%-$x!#xUccE2bJcT%PL{zxc-NVo0^*Syq^78i(Z(>cjmSgpsZ_I`}rl5=I;M4*EIb63beulbc} z`J5B^#kT`nnvoxk>Vfw}Ea5`?ZhV~HR7->{r1`;Q<6p3rcDsu`X+z;;MV0sz;iMji z6yp`|BWrrKmgYEm;TPsYuM2{S=wP+1J z)OU009{&NBSqcs^v-NX+uVXT8`oU17(hqMvHpg|wB(P? zKD8iAJ~R&KPf`FH^LX;Ka{cW+3BAR)FZdZJh;dWxVo1{mnpS(8J!BY-GVVJr47Fx% z%wBI189EEdl4Z%?t>$XxjJyy9MVKLq1({)5z@wGewR++0Vj_R*bg--K@b)fiumY7; z!bbmAf01m3m4J{M3KNs<;;_7!<7J&aEa4rr+Eu*oe}{fTs1`+k*Sn zRWER$yCaSP9BfNX>-Owht?6LH!LE8XtP3<#M^SqaBhB(Tq|n%rMHK|@cgNz5*A8YG zfW*n8mFW`A=?*vPVO;8bD*wmWS#`D1hHE%@(c(pd6?b<60g5}pt+*D7yIUc}ofIwZ zUcAMFOK>U09a>!5Z)g93z4pPJ%;BtA@0xj@`?_xbQ>a#JHYLZKO&D|LzWLNFGJ}Di zqmSE1o7wP@SY@JKFWICE=F{}anQb}{d1|`cmt2rj9!Kday6MGE@I5Un{mrB>tHhIT zlL~akpkqM$AuLL>I$fGgFez&pwnk>F;?cjNRfSgOhRZhl2h-U*Qu@@mdEPH`-p#-js7F zb?}YP&+@#79zQTXF79=P{1C_sToQAyxmt|-J@5y~RdalJBaB84q-|}mbtCyrq-VWw zepi10`0FBvZ?PDMbK>z^a|&YwzP%TgyDu)iNdIU5>&vfz-Vx_3XM;(=rrY2Q z!}sgp0dkE9gle_0A35(<()d?&7%RWIHSgPH_e3f?fzOI;kGKv6Onxd^NGfiZP zV<;ctd%wAlH5#>J1toeRS}>VxZLc(ZbPbf4%}4Su(R`HxJ^IUe$Nho2S6E1V*_yyN z;h&GHlPKE4Urt$7uTD+ylwK#zfGZXvf{gTBeAp};i}9eE8{TFT6-FWDCsu^(&wY== z5Q6V$Y%%8QPGd{ITU>kV#{otIHF79#rJ2Q$siZS@w_U!Q8~JLGPpN#`<0+ws8PLbdj{u)&QXtb6~8fUVMx$j>OPYigI83C1DRqNj;wEi zO(BowI)?6_gBokFQaXW5ues;g0naU?6A;316p*-?=~H15lZeFLUmdx~v9&#)hB0Z- z$NkX<*MEX!kGozW`R+q#wEqu{NI*mm*+0ToRM(6%DdB*R^nP}5PdMxd!4wac44`qz z=)LSx>2y6`uV8+lEAz^>pkLro8KlU#gQzrj8ZY@n)tD4z*cl^!!J-CLaSvlCfdsds zRRM+G36m?k9(CtLZau$#iqh_+te!ks^=Z3&)zk~&OrK5Lwa#53S;0Ada{(PUg~?kj z=qRXIDUfQT{NGn>xL9G_THR7%(Kt6yfs>~AG7r!26O)!?R#!)s?nau~p-fEB>tVLh zS!T-stjC?6NFn!d%ReB;xM6bg{_olWzhS@T7+czM-%mQus5h7lU}SzG3+z+Aj#|mX zsfoLwS+C~GzCk5=eKF@@RnLSv{l4t+rCh;zlABEn{Aftf+W@RhAzz} z2dm-*Fm(O{#AJVEM>+qkSFow+$ga@R06H>*?f%-)gpSK81eyXvcba6jnHGFNCZg?r zP-1sR*2?=Lpb3a8Rj0@Dx*)X8WO8)r#JD+Vv12ZPN9Bg}RU!#%dN_y9euJh40qG5C zr0^;D6@0VO%nQ~@k0y4k$0D_p0<3_pCT1iS@Fy%MB9rvW#sn%Lu?DA03Ema^(QSy> zZ3BKst3%Hkz#QKB+&VX-t0_rld|~f1JXAuPh^T$n9Eo0*6PPt+V$SsyIMw}k&0FUK zgBPsat1D^fTMT-4a_B?d8(R*~(t;JSN`^KjJKtn=Sa4Ye;gAP>LiV%mhc}auQPeuF z=jqv@_7AX9Y`eZwojBXg0O>^oe%%&f3*paPSL|>rb>-E6R`)79C9U&&VK9x_-T)A% z=J?2=cBiSD5Z=#~8yz{tY%e<*t_JNe4$pU{GK@A&{Rh30ihsCcN>NR(>~e0YPj%J8 z@QqWLlNOb?u$hsJyuNiNXMyyr02>q0g#zbj+?RH*q@PoPmvgQ7vhoTpZrGIgl>a;9 zlTz76hhk+dXUzbhnoQH_NA7fvTr1*~Rp(qkT6qjMWqJ-Vay%d=$JyzEb~szRNsAQ~ z)^M{{m2l?5e0XG#f$cyxr=bK5UB8G(ZdSk=B;qOofN#E7%l)?Pt&mlL_=lx+I-a@9 zHlzyB?0Z?g(HI4Ufhkbe@s`2G(W?QEAvZWi40KvGTNE{lQ7nI^;Q6}BKI*v%V*;=5IG-}^b!ws<4HyR-JN*&hL!aV-%)}lH|@zhRcYH-OVYKU{$ zoEJtAP^T=s!aV=!3ov|_0u52eC~BJ|eIj=DyR1E4Ru&n@)4%o~MO!Ki5Q13r#OFuf zSKi&OP@l>U>I4l%_$Ii~#hA_8KQr&BN}x^YBxA&V?2)8O{Y?7?Rw`CQn~VkJN}Hv0 zLnY(2-*F;Nnr~ zP%EPRLUiW43}sVIw5Z2Q{Rbd8yEMWr@Z6xisU>g^)Lxv*&|S&LsSni-5v$UD7`(R@ zyRRPq#a@23z*b~8SIH+1--a7_h)`_-9K+V8| zNdFmUIZtGN+rb1%p5^N@R?01(n=(xj7)rlP89jhsIgm(`yI`+S*GVMB5nz=^^nj?O z7#2zcCE^5}!T_mq_pAjErMwiQ1{*<_iXrUSqeocV;8%Q_Diy({9_pi{d0RU<1ixhu zD-aRgAJuiWQLozpJGrC4`78E524I0B;jpgL1`obu0?GnJ`4l|Zi>~Y0QTlTVASsRx z2)HHf4sk*|hpWElYkV7y(&`}o!o~_9dYBIYv11iaE6{T*unb_!sQ&!3Kl*PDy+vrQZLrOnwI|zm_RwvV;*u zAz)#-8C>xpL53>5Bj8 zz`9t6apC)HJ}wUV zkZStGGQ%eb2*GZ^Z(Lx?$$XYSM*=h}D-W@_uTav?n|lEtU}p)sN?Zr)v$sL(H<4JJ zv6d2s$q(gs2M6bb-x*oy0~a5IZ9Z~+@Kb5M{h1VIvj6**?Up*3-?PYjO1+j{WM@Q> zG#P+*U#TVtQ2C9>tVp&r1Mb!dzw!tVjV!(1Fz+LodZjeE+7AqI!nr$D76W=0y%R`f zB(qkMvM&6HjYE;QQ@D?r@(pa}r4Dm#BGZh`$|BQ{W2=P+bfhFj(tdabR|wY z>ePytZkt9FO1xxq$we( zAQQ!s<|+Ug7qw%>5*Iq-Ea=?&J6182g8~LFt4VN$6AL2c!`m9ZVsqAM+GRmhH#8b;b|0BGOeMkgryH;;%~b+IUToSR8v+dr}US`Kf4nM$d*|i z`MXXgItePgJ-75!YJ0~^ma%(V=jti;UMF)rew&h73-UP#&mu6C%)-_O3$0Lf_6oWy!**Bp{w?#z%+Ev{bMAWQB;3H%Pguw5 z-f;F|^-IAPfxjL)!2@#q@H)v~7GPl(}vwRt{8Az+^=j^vzzn{ZztOv>GgUQ`;^sv^sJ!DLlqEG$-Zh$w2b zeKPG)PjvzA|v0)Mx=Oyb+ByBc$5Y7ay2VxB5v(j!%j<<7aW4 z8Nm&!bth~^U3fB5?UU1M%by&FxzTGi$tI3#{K@Jbns$#~FpY2T4%yvC8cYn#*GWZ0 zfh6b39l+FK;avUboJ0BuSQhEN>x}ZBfAQtG?`#0R>uE*~u!>qIgD~fWxXAhd9DXD6 z?*fZlZ;iIv+WIIk)zhE!)e4DE-yq`c{7E@&Yd!viN$l!XUt1h@)XZut-{ecGH<3S> zD)%3EB)|@P)T|s_Nd#gH&t3-}!V`s$idTVmDHVS`H^TC5H#UD-j2&*83DpM@^;O46 zKn<--dRcK9(s+w#f*=%ba6~2(UMVdGn^tx`h_g!YaIf|T*!&1~Ri{13frpvd-j|JF zV@V;&3pR%t5TKmf_DqqYUMVouqaY}WLoB}FeHsgnOnlXuu~8)E_Ie#^22d20B3uBa z>}px+W#u$o`L#O2<_$^{_>&+%2>ES3kfLSc1tbRlRu`Aj<>8sE{SUx?syieL#+Ffs z7zdom-jad3BBsSjb1$}F`yx`j0{y;Yk+`Ce&0e{mgK`z1nh~pxAeU`6po8#nAVFoe zLA4*=6V=v`LY3LA<#c3P3Ll7FrQY5s!CAm*Xi;sVu%*wq(U1SN1^Ozgk5hO zzHmZ@s4DIfPdWImW>ar#&)&U>nhGSP-=$Hn7QhS^yA`&7-GxGzXh<)Vr{5-5nyiE9 zBHFj1EwN|#l9c&ln;p6d=;NJQ2D#uU{9Ofvb7~E0HvRPF(h!7wxlcXu`gesFwbqk8 zOyml)Nz$Lj58Mg9s~M3txt5`LHz5R7Vug8Z+@ub||NX$g#tXv!0I8T;+ z3Wg!t(@^r8fbE_xx<;$|k&!(GrS`=%qG=jhqVff8+TW!uejdlI%~q^>>iZEK3Lm+z zEBQEo8IdJBfJw#hDsJKja=qcjhouPotcs%>Fwq<8i8SAYg8yaOuPe@;+rGIoA| z?FbhVIiGsZac{?C$x=nAe0BC~e}gvNnI>mS=>-G)S}uOi9=9u+|3=_#>J>SsC z3e$7ujhq&=rOr&)v>`12eC9WZwN~Ao>d7E`iKu%JYWT#*=8~v5)UGR9ojmd4GIp3| ztoTb@kDy2&QXx0={f0~FCk{sv%+=^_cv+hAIKIuk*;B$bv6S_SEW0uoJm0`X{twu! zB;IF(4G!azTu!e`T;HcxvN|C_?WV(b%$}`vo1N$pl}tehcOE?nXP&Qd51;Qv7pOaH zVzv3Wk5qP0-W_!QK4|5GCwZ>QWO@@3iVgpck;3}{< zmhw9}v5^AWsKXUhbX1jr+HVujRIO#$#2RQW1MI$k!9m?kFsy$+!!fXKC}o)N(Bx+E zSlZVwg=P@%z;xzU&`Am~O|YcBCHeh2GPI-0+7+t$M@bc+55Pm!1UX9wkJxP3NN4i> z3^(#RS9i?wz6gS%yEr-Zb}+$Cxl5jllBYYSL>ywK5q<%49KN!YdK|zj7PC@ zhVVjt%4j=n2e~<_PKxHn;nSc0>CiaKQqIWhg|&0V{|7LhGWulr%__CKLATd&-}+D? zCO*E5t?#zX^r5gk;J4D6HR$-N@lf8q@1`n)Ly>B9!UNn@8Di!au%ULeqqU)8+#FPJYy4Dx)sy01 z`Ye%@$#bIZi2Aw(8f!|&XL-eO=lBy$QTJ6*g(2A@;|4L{0bSljq`w-z z3vW~Z=J5Y+=+8OfW;&x$xw)~6;S7eXZE|-I0(TdO z^QA)>0hsiv+Y39HGduC>v>L{MH$IXK)8`dTAfq!m*55kWK(?sP%}64_;&(YZvc6#n z&~7~4qP?_`Qw5Wah{&S9&R`pQjQ(;A+tj`b4l7pR!hkTSN~-A?jAw{dCMC>}Ov52c zAb|rY^e+{t=SY8C-O{J7;(f!6bqti0uxEGig%L?j#h~yI!~{KcBVb2Gq?srPW^%tw0hr9jwHRE)=ITI%pCDPW-bD z47MLZO(sjQn7t^T7n?FCUxlPr>x^$0p1S^VrcDqQ<#Sk^f43j1Al%cbsA+}r?#ikB z(2s1i0lIkENg6`njChC?MalJz`Xw|AQi=0i=q#ML$vGe5LZ12V49W>3YwC zPipWr&DEWK5U7=ru+7#<3X?LFvT_$?C{k2{sBAsgIYgyeXv@qq`!o&;?RYHC(N=S1cmKh0EvY zeHcHoRtamofM$94B=mG#yfD!!rEgt@%dH~AUz^QYcIvl^6RA+_)J#-p60#fg9Rcbh zYP^r3slsgUe`i9DG=$!WbJp=V0A8)vYmpfp8v=kIv5w7;I@;0``{s?UKqCM2oqZW< z@}&68!T#u}4@;S?*(kBMOhL=)83HrLou_wLtw--gP%gp_E z0RaAE?N+B0fG~jqlL7z0kSze@G~w!oVx9Z6@Llf7LnD)qkHc-8Q|+Vk#yOdO-PxE_ zQbFsn4O5DybHX>f(hUJV{$bq|7;j%zlP#*s(?WOA&&=Q;gZHbp99Z;8ySbPp zq!&C8OXROi#BW{P%6`hg!&2x`l~u3DEY;WF-u0wa(-Kj7nZr$M!yKdT#>!_(&TVZX ze+Gs7;eLUM&y61c7S(xgtWDR)}rp5?7w})B}T?WWUHG) zdVj>XsI5MJ&Y5>qi)w1rq7?cM(2@y2-5~HX_JCI+iI5i#JE~;5pc4gNhXZNP!_0Ld z;jTuy9!5lU#saQ`O(-hN@;jcg!OVxidF@88uf8qe^#bd?D&;(do&6dW>%!Qdv@_1# zS8h=&BB!7I#uEz-XxJM&YaFbPBKVYK^3BuLVan_GG45h(&UySNjz#3>vx_AxrSaMC zMvz^uc8n}8xN+FbrA)M?3$9!fbQsA?ttLTvF{z$fx&+QP&du~3;)8RM;(1t$UbAW)Mi%h zb`%q=&>L!p_Nz?jJ(APqyoV}&R|4*4{N z=iZOfV7zEc8|hXQ+a|a=Ri~ZcFdJJn7&K$@HPn~UPx$R)Y9=FX2}?9<)rK+d#Ip_c zOq=p9YP0ai*D6H6s9!b@TDWc}y1AkyvuAIFWnP$;y_CNyXFG~B3j4h?&Mcl6#=B6? zjk{55G2lo8+!U=J}dx-IQlx-u%n+@Y9lg$xcwB0{`ACJz7#A!jt`dRd1<_ z^#wTF$ZPrFw>kcBV%bzTSrWY@VK3)6V}UG#r4gO;!sj80$PsG;Y7i3co$?Hzxe=+D zO}NKv%4BUsEu$srT*JkXhC>fEe^deth?~+E;jFi%$;OM21FGo$@112Hm1FrzcR247 z4-~F#V#&h5^9V{YCP2WHd&?51cRy74T0CGAa=o@`3^=D7lVe8zKr-G!ZU zjk7p0icNUGfS@bCzRwA!UbypNxk}E9Vzj?@&k4CRQy|sL`2W~@yrj8jOP6YyA~5|D z40B%tT&kZ#r!ukXgOHJ`58D!Xx|BP}Tyfjs?il#B`>(&w%ZPup&TsXeb)yx;A5H55 zBRVw^uZMPEJUgtk&Ll?^R6OY9SvsrWrm7=J$bRyaT<3_>KkIgRm>Gf+eriFH=0xS4 ztEhxL2BQWC?z~V2x(ZCmPI$;=BRi{W>|9B*mBBU(2zJ3#y4Q4L8^VMYG&o_mr#!BN zj>{fd9mM&AndcVi{j`gkyIPR}DE@=i;Rm*Xw%zCb{d6YZYn>`12stVNfjY5c2azhB zLN=sRaGGO&7(hjWY9@BJ(uZd6C+BDW- zW7E^DjvlM;r8P2IT^?)ZE|vg+k%HPIa$|WUQ_@?905a`t?L&r|TmsvCc1G)2T%e zJ+DWXB2&0a(VzRc_llnA7S6jDhd_H6hk#+zan}Z{b}1o?P#I3K(d!b2j4#L=WNG}e z%pE&1@_IRSmWlT~M-g&Ys+q>R5juQG_bxd=l!zZ0cqQ-aeY72M?81uYVjc33U@iT` zNVaU&@BJ<8nBr$rKt11!>Vlt@(1g#793s7NR^RkL0L3X)v?LX$KjFRH(7%Av6>+Ad zFyn;=?gqQa&HWwlufCPq1`&vNdP{3k5wPh{*jdesvo&3%H)juKlMx|pH1=em#O1c{ z^;HXKZuV|YB&+f@t<86@2Sd6Y%+zTs-X9e7csOnN3rXNL>B!Q~*!>i-h#cC7D$l01 zy!NKSFKV6Uez8~`W5-&i?AE@L0cZT?jPl-B?9U>A6A!h&`Jv~}9hAxCNP?Fm$;oX?S+yxOi4m|<8bl*ECnzNuwuv65+Q5*Rfgv|3$u?z@ZaeX% zxCA5P3z}rYbDJ_=vFh(Wni#8Ui|lQt4Fb6o1!Jh`=$_HO`C#X<>`dJ)Z^>&h^5-GT zDAPbt@sAFpZ_&v$guT@<;a&!j=yItEavD9`r1_c;fci0IoNl~W6i znpEa(af}cJU#iU#FBZrs?MR2(jL>+0EDCZhzyPqUI!M3V(rHJ{E`mGbzeB5|w5*`F zL{#l*_Z9TAp-OKqY^##qOra3$CS?G6d_ZjIwt+g4y^dI^>S#$y!ShZY{~-l`QnL)y z$dp(4g;+%)A|=6QGn`cPJBAoZ5__~O>pCJ2Xj2AY6o>cn5eIpxdcn-R`%b}_(mJQV zH6DA}`|jYRZy@s#U=*=Fio-e{|DAL4|hiq0XYfqPbQJXS4g6e5m~TyCY#w!9!63oe95M zk`^fdSscY)`UHs^EjqMzBAvfs~p3K`^mN!H48}>+!uVS;LEbJqx&Wzi|IdrMC=t}&F3w7x?k0A z^S11W-^Ac-#dUPc{9TzW7n8&7{X7Hv_iY#-yaBLSljz*tnbIa!0`Se00Emh6%Acm@ zTe>{qJ@hf)A}f3)?28yvgk(3Tf0~P86@yMJq8MW5 zY7iQ?_j9ciF5S)97?DxovJLX>t#h@OIzS{HwduTdlbm&?2&V)tdl4JwV4l~8w$^&< zwkTROl&`%<9nh0q1=mX)%%8Q88H}E}G%r#iC{`*_;&w4Rau2WTfl*gc;p{hp4Hzzo zGXUN23hCaek^=UL$d&V?R@xwfY6blq{ievGBu|d~5kCNiu3*6sn6|teEQXvD2mgFk zG2HHMjSVj@x1*V0@GZ!L<=`c8a5MI?3_KS7Xx$x78_%WCNZmQbZ;sP6%qx=h#Ky6D%Eb z0~!=zNeZOBm9k}c{Ny}MERl!ScjT-koS;6rYBP)IqyWVyS|ADAE%f(60tCM5Ii7dgH9qo+7*=C z>hESXMlbT{@Y~%yy0@7RJWR_WgbU5j|?=OR&>gZ`6w3YO^qp!Blfqb#PbQ$u<|Wa= zKN*bJZcEdPp=T^75D25%O@{WoOMUcRjz_(-jS~!QEA;WJ+8q0GdVFEn@S9Kk1%t3e zNA*0ZoaYmB8lxo|afSO4{;M-;hR%D^Vt-bk15}%{9-hdpGKZVySM&r65~$SfH-&w2 zQ!2UxIllLJoVETLziDmiylvP{W_E!k_E>d3N^!NmbFW1Jn--%B~owohk`RFc&-cJ?#*5b>3%qPRLbFCk6&wv0>5 z;?q(~2E@Rj8@s$d=~?~qJa$Me%YXD_QjDylfOnS3{Jhp!5yX_kdo8?IpzSeBbfh3) z>Uf2#_#fCtapEhziX2EFm5*a zVr+vcj-h5ry(hbJL<^d(aa9pxhd`Ji8d^a}6|N1M&`n&+#Z4WtK$VVySup=zBub6O zz#s9l=*)z~o+lWjv)j6kaimUv+K@gJ-X7RnH2T?J#R7|-s%V4c+P?Odo)y6LPFnD{CPdOigbwLbc%x`QWFK#%uae&cG_2pTKMJgH|!$-t>EuNG16>+xdAMk z&JoxVffPMa6>}2tGSV)3O6x@>g`AYu$898h^H_@iV88P4Rf#^2=-9;f+}1WpTq&D& zyQgSu*p5NllLB~G^@WL-Lb@$J-65>v{R8d7Ye9{S(GpB2!hHB~9?op?5FNfN=>!*J zSk1_x45Fu1@m?d^n0ai3&_3npYJ3z zgp3#uYn{hDOQ%|KiEo?t(G}Gb^Wr#Xquoom4$^6VdNP##`oL-4X2p5je2&GCV?#>y zlV;}A&De$9hO?ip3OgDOwIkWO=`c{0oR8luG^c^8VeNMs+TU4GqNim;$3L#9?6CKq z?4<8ep^j3J7CqECCsN3!6AZPB~y=l{gbBXv5@Cs zQRQvR0j8-L?{OhfaaYen4Scq)5}-VM!$mCL`cLi)r8bt-LfW~pnAz6t+Y&S^dP|r! z7u@SDD%qQrRG95mPhz@Uqs~m(JNQ1U_-;iV8rP~sjotLGI@ge|G$mdsfOE6I-;Ebs zDP|bSnlRGGi(b)uvVo4Xp$Ab`b5b}8mr~8tLD9d(H#Wf zNcTV1#9Doyv}ax05P3n9TSyCkTS|+KBgojqbeIILnN54uV>Y>}=9RuIomug5N9mNw zPN|$d^&x=!>DoZ+(^fWf4m(`i*=P(7-PV1B7g9w%+!r!xO50gE5@koUVLNuAVNifC zO(te%bK->J?%xT=cMI*VI^XG(G({#^yyneKl?r*$pKr?HoazFkfFLNQH{G9fb;WmP zA%VI`ZdPs*g(D1SRDq+cv~Nm-@)K6-Z4v&uxuy7+A`*&^g2;)%+dOH5UGCpU{MPxr zD$b#=7v`R<2CU<7pgDIu%y?FyEEHCj;Hv8 zd68!4+`u8fQPS|upd*w6JNQx|*`CID2jjAE=Ev>qhN>{gg zJT%SgvELe|ifELi+xA0;KD_>x%q)3!@W8-zn_l*BWvNWj<`1Iy#JKW~ptc=%ymJJdFuifjdx2JQ*5W`1dn$ayH|J!S`*o zeli21xF04h;FG4i&8sv|gD}WD8 zb6AqJqa00Su0`lX5RBax!j9({n1DdUu!J)N`L91XV>T*IS*&ZYlIB4+c;@7v`9W0# zd4R25;bIsHne;T{fxX(%Y`ae3NUFC#^{x#W-=(>fWHPdIkBOJt0`kgXX z=UNi&G{XE1sU?+j9;BmlU7Td=Mt6#I)#g--mb!EhTLE}&!u3Wh^N-h%;$)~^y1&51wn(my;Yrv?cU=i08;t^K z4nJHtELgbu>0gdiQ~QxTwn=k`7y$uF!9L~DF8yUgh5Tj(s}=bo z43Sv!dh-?uyZd*2QVYkG!@QE;b{FOw3Ds;#^L)sRcjc(}bOn<~YBw~^@`!#3g9Y6| z8mO$X^nt-`PBw6+bnUO-xASyIlLjT@P}8Ys?`e(p{&0}g*19G*oa*mIr{6z5Ex6iy z^^BG&S+jvx%V8(qu)>^MXs)EOWlRqLR4bbSIE*I9(PT2o(Y@8Y=%k=kQtMsP9BIYY zrU5U>AE^>sb1HfAx<&rO_fufGmx7KF3KWookhivC%u2pHYq68r)a*zVgv4i zOA#c}BNn;U2-6W+nr=u>GZsXHFMZ*kee@cx8IiTRgClC)$QRa(TOR{Sn;+32Mdw9WngwAUUguz{|;A*J&!j`HEfOON4VFy+CER9 zcg3q%uO#+szJ0mU(>#hRkh83WL)@iub-0&20E_gCl`W?JsHD=qmP*PEg|Jxym9|$n z7HEpIv6(v_3k!gtd|-4GzpHHIhnn~Jl<3yRl{$_g-zrA>UF24SzG+&l?CRAyII2M& z5>4%YD2x;JcSCRPSr-K<1UljH`IVPC#o>Ke7?`Pg05e1dP0M_uGqE?Ve^rwU7C+Vb zzR7R!^(~&;RuX8KJ{)sfuTYmGREA2UyAq`nU|Gqer>;k{0XSy9 zBU&F-PrlxW*Ki65kNrGOHn9h5hpRPHhCZV)IHRhgsi zf}X5P(gB2$+88X_LsxoF&@{}!7^c6@jQM?0ZM{yHO`AryGlA$9NUaKYdch*gtgN_9 zBDm<=E168KMP(XCl!^o#8%aC>WxUvycSS)EBEd3!xeXv%5RF74w6>uH%IF1bdcy#= zorKK(Qg3(VzV+W4NH$BGe^tt%7o(9)7lrazHf8Gtsx0NuP6~J_RDW%f_BJ}4TD&sz z3vTKd&53^r^>}_!;YA*zW4e8y`~WxR>hUnjV#4wY)J4gk=VhU>t@ZGdsJzRFwb|>t za6q(HmPqpdRo`QFzNS8fI0e2#46GZmk4U7O2Qj6c=-BTm z?>EG)9$7l+$7VB;kx03T9Dk%>;pDQ0H&#YKm5mZn)x*4Y>kmirS5USs8_F6J!_W0T zlv(1tNpJnPZfm(U7kPT#rHBuR1Yja7O16m_)dch=&62v0NqsyddMq#APZz@L0;ZBm zpU5VZ+|ydYm%mWEg5Fac8xk~OWlSDeJAyA3Fsz7A~W>*aO@R5k2zSA8$HGlqIM6Ee>nyPYrH|{p5JJy#dGuQKFJzdoY(8fYD0V71LvE@M19|i zai@qqK`taNN6Ux6!KehzPU-x+3A=6Bxx&R3H2ouM%U~0R?gCC0wqNdW%+^Kbt44}F zg4`PG$fiv8seY`cx?lKCoYfX*spCo;5mVOcwaqr2r{;y>Z@klpF})1YgnDEg?U=Ca@r)>ckD*q%b8Pt~&7j55|zT zRI_txcVLq+S8kn%m|FMBL3fri!#brDkB27Gk=qFswV(;7FAU6i2z}(G70`>3+PYNF z5AFA&o2)(ArKbzcOy`5PfNZo7H>P6R@-~=qd)Z@5|9mVSFWvfyg(;3m^{DJNwA>o- zTTsV-QP!Fp4r#AmBn4Li^~Ob&$~2vh?6d^2bCR1@W3lwPWIHVEOgmZ0};;B(mBdeeBmTig$u8eq=#O~|KSp+2cXtYp! zu?9<(EW4Wp&k=P*B#h=TTu}|$W;e*3Q5xU%va)K73U1eQzH`AvFOp2=jyyG9?F`# zQw;iWvsu*C(GuExr(R4?r&Y17dBWT^MGYQB_ENW*Iu;4qfs`>xh^d#?T7EY)aV4wo z7)D1FjxXLgs+^-xFe$6{QHTFMqLail=HS#<_( zOM!v9B#%0IvuMeh?0}v8WD|TeD#g&>La#Hf#BYRp3B=0!nTQs&(fqOK0gfjMY-Y*w zvOvEgj8O~rB2N!Z&I05ug4h)N4ZZ8l)KXRsNyIIaZ&4+aeGYb^s&Ub3f`vf3b)bZzY+Aa|L>&R>FCC+t5~Gp}JZuB7_)&S@OgokOAbU$l z@w~jB=H)HDi(r7?>KHW6`mB*0T)st3XqzeVG&C!8`@)wARhlkl`PoJBoFO}hxifhU@^@VD!Ng84#$HN}~=-ZTq@qQya zk-xh6e5dK~`~E(6J;5#~Z`sR(LFAo7yXv3OwlAMi>pn_;g!B(hMIBx^rgCC*$v_D`;U zbX?rh`Kit<$`-;YPz2p5}Gx!p9? zV4_JumRRgq%Ozf$=CKqBTV>R@` zNp?y=k*11(pFWA)T1kCj9)88a%H&hQz!69sq&K^+!eUkh@D(!KB(0A%#zZH^qM0J0 z`_;tA_zgpiohSuL0E!W3Bqq>rIfa@HKeIsVcm}#5O!ug@efQjy7+~6iJXfRCeFa96 za}EE)Xu=cOd(y{<@-E6{kuxS=tKWz;F|7;=2KT`>qdaMV1FLi!s7CdY2>rvlzoe2X zkE(i=Yx(FesSbcQ&55sWY2^sV)wmi=cKn+l_FrueHzI0WjE z=(`2nGeDN3Eq!Ie2Tg-ca+`ajBzhZD0>`j(ft?`lg+gTG$44a#axdpSN zB20OleE@B2*w{Aq)pb6?M|x55mB}u(EN(%D24VbNq*hg3vhYzW={37G0R38d67=eY zO`JY(AyqN4kUt4Po*xb>`h2K~@iY4&5U^N4K#a zq4M{aPl!gb!y=(RNC)!#%c5w?B6ZkD%_(ghokFqN%Y99QWrDJzx(o9>N86v-RZ3Ig z(b`p}>ZC|$`ng#c)hO7+*a)gh0H<(#Q#k>A1#hFwQ2v%p==?fCG=dj_@STjJp$KyJ6Aq64Rt zWX6q+Dtetufy7k+<1xgUm4!c=QTpcSZMqeU93~bSwZvnjklYL+N>eF_m~&seA8l4w z)sJO=I)uZh?k6M9Rz0T2v3hDVMd3c!WR0u@gK~^1_7Engxjn+Z-ORt1vMU8csl!ge z|58O6bS0g!;`xJz;I;g*mbKRzJH?nIJyuhx)y5z8Q+XZ_IBKp4p#(fh5JutlVLn_J z$z6%;MheOrkkE8#6Ks|U+4_uxT&rpc#YVZW-Ye}Y>zjK#&Lw5gN_dyLXq*^k@los) zvtm&Qdok7Xv0e28c46sVnF0Mr5Mz-$=^LppNJOmhk7yg8N&2jp@_7<(7iXFzBoHO3 zy#BM9?WNp$46q;sgJFVll`QM$uLCiP8h&=L(;$kL^b4%^UKNXyb*+jqw$4f8#B_on zFc2~nlZ}-eSVA_C=1HA;Y!H0IeveJ2h=%)T=xS)|HN;dx*`Eo|YC}m}x-AoE)tC9^ z&rOZCg_#mZH6hAvwNT83Z`Sggdp1(j@ci%2lgr-6d-2UR-N3x1k2sX8u3j*1R98VV&dZY z2)!Hv+G&naIMW{CXtR1;%0~o_*A(hutcbET6v79?}a|Ad;in3^kv6CEoRVM6r9&zl(27TrxBq~u{dSO2$@V#~gs zYm9=UCTVrpix{EgW3^k^dTX>bck}F+Vo8|$A;ims=tUp#);g>O@7m9Qhi-DGXU_XH zU$)(JMNK;FFwYj+CIT(v{hozvwTu zEr=|21shbqd?Y3p{zMlZtl>pJlF8zc(80m!rTOr22UlxT^IIz0AusY!+i{d2uaMoY zW1Z6RsGPL*J?h*t40BEyim+DDIX45vG|rdc1_hRVa(qI0ST?ROH&r9fK@(AwWfd>7 z?#r zg_Av#RJE($Cb_vg2*sf8Rw+2b>21Ta8uSOv*KIHu0OB`Dn`bic6KX2FdlW^x^X-$) zCH>X*ll-luV!!xU-RN1sG=`~~nU2TGq3VfSA#)dRlQ4;FeG`CUfuIC-ikJ&vx^nst zV3Tkw)JFS>{##e)^r6`k8q8+pWN+U=|E|7oP2uk@_*=MVz!PF25a@TuQ^$_Ji83SX zEJN^KC0XLJ_gnJ6ULPxKGfPN&(bM8vO`l*+I$FDhX{8UBx?uzCwrX~=tes@DoaOBO z3$*;|2IBo&&ls-#rqcgI*jfHH^}m0dkPr!h(aq?RmQex{qjB^IY1jzq20;X*yE{g= zbV+wJI;0zFtbdM;E<61R?t8~1G8b!NS zz<+4eu7N>>>v(Y!!re|1bM3E4aqDA~pIx-7a_{)I6j8jzzDoh+ z1aM$sq0Osjxpb05PIS{IqV({hK=+|c5ivfYyL^S5&E$fL+T0+_Tq!pdzWC2EXhs{V znV~j{M{c*J;n?xR2l3G}xWXr9^4h`<<=!Q4g|SA)Fh2-eln5{Ggnik=rWe;%qaqW7 zdz(pdIp_;0Y~7bplm1;r@^OheTm?gRq%Aqm*J=o`Y0;rJlJ_O)N>pT$MF)bBwA%Q# zx!jg#6|j;8i4P+~C6+!uC!E_Vw`9eR`ko3BXZ--zW&e>$!j)kWW|gu25PkJruvlq8 z+-6F;8}o|}Ga2Tps5#WQ`}77XJ%$5?AEnu7q~&j!9h6Y04r!9ObXTiGh9H>J9e2Qv_Rgz6Ib@;?bQ@fu!+@wxL9XN6z_LRDF)C}c5;O`iuMOZ z8W+t1;Ue^3N-D`+vV(u=C0fT5+Do~+8%+ZM~*ki_5aC=5eR9L8n8B`EV z>G+(Ce_d}Lfajx*57q``dY?hFkIGf zvS2FcvOgMwz+=*{kv@g0OAS9r_7?E)WtjTWxPEB)8{;jGh=GwRI%Is5(p0QwZ)5H4 z=C?pylfjT?gBmFToeW;u_d-=)FMw+zJYG0JmaEZ&_Htg~W4D;1pR~wVg=^-`b&T1I zX^ayTLF@!KSZDB-`vN{Rr<7X0&{qU&J-}$m?4$k+pS5|=l10ksxOb$7AHd9)3qKE=m|}?#!p@d>65A^ zyJ9OI02dyzAqCcaOL<&p~JsDPdBT<_@pjwXl7)V^e4_LqVu|S`43Mj8!b|^B~6}sncA4 zoJxymM3*WD)osP6?ZeR{98+}(WK^LxQ1J#saR}nQt|PGao_D00NoK@5j$2VPB8qq)?YWg7*fsYuN>K#ZY1l;PBVy%Vl!FO z)f>KOVSw(2r8!rIbX=Cj#LOhwP7sv~pM5#>6!}IIwEh>i3;B9UOX6qKiVm1%xC@Uh z65&YP;?sRNk4ytd&aQjT*>R}0)xQpV%e*Py9;9lTa0o32%77)5WZ1Yc8%bH!xYI`gK=q9#11VN6zRf zG;IzJ;Zk;Tn`_5cLf=R~Y?jbwk--^L_086fqdSqz&h^v6Vu#eupr63Ts+_@?QrIxQ zm*&x1vC1WVe+hlHnD-oX>&ip_L-P}{l>7?^FtXv)BGd{3+y=?fU(#sIxZ(gVC~dNV z!z@>N)x3$8H&(=pQRq6HE3JfBXuH|LP(eevypx>eyzL<@h&QV~*N9XZdT@x>L6IvC z+ReF2RO9n_q@5PX3ACHZ!_QJKsV%tU*b%f_B96>T^Av&v@92|v_X#d~EopxoDyc(M)tb!QF58^H>q5Cn=7ta8y4Zo9j4cEv?rw!;6 z(yw}cQ=!VJZOLqP4edJXG%k|AJo4+$~W8*+Xp{iJp%Fx@yM> z_sig}RLnE=vedlWEMLBahxS`8y@Sfwo&*PutP^5+FBVZ5))=7o(=Iifh>^#-AoZh8 z+MWV>9AbUQiaq(u%p}Y2Cj_r?0N2+7pWeiG!P1r#y4-j+VTrlcAPbVtw?33OW`o0G>&EB1}8c zBWk-`uM6285vNah-rhrUuzeyM!p}pUW3PUZPJ8n1A!|}1o(k@RjqpEJy;gRsR2R-k z9-Exrg&I`9Y|0CNq8v9DSo_=O`dP?0S)V#B{0*JOC(eG`L*uZ2x~EX7i56eq#_=$q zbi5)^eB5Grt;~3b8M*!mmr7B&RMqcQ`#p z)O$HPw+%!lWcbUZL*{(YW6m3T1lGL(($%ROH(biMOaL|t6P8+Ts~(!flWiR}-%+zf z_Y5sdw+(_b-^(9PB&XsOu#+A6h6nA>S3ht2Hdy{apS0*NnDiWM9oe#4U>ortRHeZs zC+?QnyOfdQnqINcAYqC_fZbo6+WcLHNWIk&GWyu}Q#c=U1zuy$Y;RD{&((@k+vMfT zW5*l$(EI0j(D`*yiK>tQPPxd+A9Jss!3G*sN;mw4jdulq&}$)MwOxXxVAGJDqa>TN z_<)Y3yy;MOI?g+hFUTlQEa7_KVrpuL`E0As`p8TAu!JlZ-e^2Iq2N=+bxbfeaUKG% z2$c!O!2~R@(9U3dqS3%Xaf8nXICq=4>WkUg($S8UN4D_Pw&r_}d-7lWnqjEMcbl$gBn;G`#l|@I(!MIB?2kG3BKV zr5NC{!)-GNIHiqQR`RwB>`RMpi;!RIxXYI-V+ZW^4*SN5NxGMEO!*uHku}I5@Lbeb zzHkmf#B({&aqw~ALX%?Ae__S6aVlt>L>SqMpp8MHS|9=qvzl*9opQK|aTtLnk?UFW znc8mM_ez6>@kMSI7FyC~5FLea(tJy`p=#1W*~=F8YCU|N!xn@TYeMmdI>OH?_$9tJ z5dzeKKXpfHY)$MkPu;7EmKX2C`9)Q8^IZ(ull9UvJ3knMVwsn1F~thLOHgj}e!Msz zZW2`G=3o0_U2oEq7uLx$f!@)c@F5f$87(JkXs2e^Y z?oTi_7-wo<(>?3JTeB)w#Dt@kIXiP3BkuFV4=tXPRz%^Bd*yrN6ToHodO!nq)xk^# z>3Pzxoh*S}t#J)oV+0?CM2>XKGYTZo72D@}VO1(;Oo>YV{9WY*!jTeEGwW!Ne$*>& zuB5#t$al2tt>`v3wV}iaa8Wye#nkD>ZmGBgd6TWL{`taDKwR;5$EW6_W+YC#f|oA+ z-6|Be>LVk61(HfFS3GDu5zEL-tvrOb3WyrzOH~GSvDQRz=}QT6uLI}YThCj-SDeGm z_G6MptjVhh>XQ2(x-GB>$@S@!+n7V!LrsgYi>(~2HAPGb^GPFHQB-FN%x*41>91zb z`KTjAm}m=#0Y!fG0+zt43R>UgypTw&6b1C5OA#u79g9~@^|Xim^#WNU{weOR7TYGu zyd}+j5XQ)?I{+C+S{OfA9ysWvqbq^R)LRo`HT0XYFq-b!R9n}h1zvcOv27h(|yy#z`WmpqAq-&`w|nKW3#w4^>?Al1$`Q$A*S8sI{1&yV|PQM zC=UCKo)Mfe`X>0)_~GpKItmc`7W?uvBo49*tDtb=Gp`Gubgtc ztH`$))bQtfLAaBI&pQx{fi#RZc;J%VGFTZ9Xq3 zW)qcHtIG|`t*W8#sM+!w{|Y-V%@h&nnY_Sqr!L8HW~R5|5tKlZjnhyH(FyYFQL!d` zA6*IJii#QD-wS|Eb!(GZbBD~t!dhRrWD@rpo?40Wm9inOcX`{Crx8k&T!)+4?-p$` zBA4CdX%2WpjyMq-n??vA!zOxCq#+Ki7CG6FfW}4#)gZsX$_PWu8%BJK;8;obQ`N+t z$`FW0icjU@+h4*ZWkkwA_VXCPHMg^Za-7ZcgKIUp5BLViS)fuTPmw!yxYR z2BAzof=WH(>Zg&B($`lVE#q2Q$+>0+>?4Q!5T#?yg>%ImS4MUcD-4`2cVDlspK5p) zWu5D;dND!I$IJ7};6CvTVzO&1v`btlbN0wuX#H+pW{rB`IAG%YMlB9%oY^zdEBWyGB}%I7CPlr^o592Qb5ds$C(r?;>BD;MF~>M6-HY_a3Y7T zS(l%XFa*2di1buA1NBaeyrwi6M$WvSX=p8_=Mwv8H4TqvmvXtwpNyFbC@*eVOy1Ub znIDG3eLO7uTJajR?LCS>4}SQ8=PLKZSMQ+%f43wcQksgGvIVP7rqWOv5dmtL6r^G1HoBdepJjOV(O)l)v23@-thjdFI$ z>5G@W&(s5Hd$05j;NESh`&Fih5f6^;5@g=5_)8V8t#I`sjH2n^#th$7nJBJuRMRS0 zJ5mBGhOpQYj(Nnv*AaY9U@^NP311y`7ye!$K8c-->H>;H(jiURLEDwO$bDRzwxjhM zb@{;liH)X^5AAXmk+!nPZ&LzlsoY2D7lJNp*1q(yEfnMe&1Y;ll!LbRi?uXD<&?dW z+1h)6{DgjF4=Bg{4sH7@c%%#Q` zAMX~D`71U%KMcohl&>WijbAzWVGWR{Hqh_qaqAJGpA;;7 zR3il|dJe}S7vLtM^KbHEsP|%?D!EyxPSz%MTK`1t@LIelTCFb7qmjGI`@eCA)g zxOZy$vY=FzpEuWd_K!r}j@s~z1)sAjN#Mu1)KZA`C%j_;wO?-Kp!Ve47vTtB-Kqp0 zczt2vZa&!{Z%JOk$f(cf1L7HOGwP$p0FAkWcee&~Ns`j@&y$$qWXBq1Gl}S>3%DMD zMGOm9n~ zED}FE(M|nju9E+bvZ0cbtcY4Rs5`JVDN+w<{cm? z$oJZJP6)%96F;-}yI}o0eyP(rVUW;k%tZT%?FUvp%-Fl1e*z&VpnlJ)6AIG0Z@YEn z$t_KKU(E<6NAD|@4XH^uKbdmrc+%ZyMJM%$mGA1EaiDJ(TP`A2hbt|Q!9l+P*DnF+ zud-b-zm3M;amzvTQx~#PM&toJS4zZC;uAu`R=8&r?Ft8xbs3Z1eY ztd@-QVFmxzU6saGepkB{^q`?D(IXdU&9|a4xQuN?IH*o5C;ZGHITm}nq0bd7bJ|Zm z3~<@v;JNS4<*vy5_w)$Q!#^^2<$4!ecanH5^eI6gXx@{6%+vF{Rv9}7)nowUt_xt+ z=j{ehU{i^3YwJUW!R?d#t%wRKX)->tt##`QTvPh4U5KOd*S#IK5hh(l(uwFwU+eR! zHFqV7kETLSnUk$9*>;oMs}Bz z{wjE?Ru~F7DpB24#;^Bny>@$#`A)sLBSI!VZ>X8rfDkV4F2(r_p`6W*Ov=VXzb}o} z!n7NFN0lGT8T_hM#+94zmo~8#)+B5!E7WG%{6G{u$tJ8t-B0|lYWEaEU=*AX=>}V# zqR5P>l1MO~Pp&Pf*k}8PG!B@9DU8cq~x%<&{-|&e!X43DNc}Gb6S$nSLve zoN*avz~t9HlT-*mXhPJaS+!?e1MD+1=XSK5tCM~L#sm0%1sWuxy@RH)LBBe=f7(&T zDdA$flFSb(qmeH8KCkK)?eyY*9$d@Og;1MAps4}*@HeNdln=K>PoBSE5{d!G7V|6b z%{k*rRe=N*Jpo)krOx|7KQ7}pzPNp-A4bS;vb7tZCB7@tvFvXl97t4>sxaU7GXHHP z-CA9^XUR@;#1hEf7Qgl2Gpz+*Jzc^l;!>7$6j6BQbe{06q4?Qk)O@*D7oGSSQ|IAp zCfmQ&jMr3@n5%`ThIppKE<6A}kjXP0%}!sEFHM{FBJmwxa@UqW;#<@49?&&1`;@PZ z73WarU4uO!EO+ zYbc7LEw~h{*Rt@_CqEpJM~Qn}xe9F!$o!fXag@{~En^mHe7Z6AnX{Er{&2!cK4;}r zg&n{ZP!)bQyI#{pu9F?=gtJ&RSn(d{Uv12{vMVFFavm8s)d^9=WiJ)p)ssCd^yS(d z7&uUvE`jY_lP)SS#5kuG9`^{6LY>2LLP9QJ?dJ~c3Un3|;W_KR^Ur(iUj&TDs`9Pc z=pN^!CK6~lEnq_(O!MM7W4`np>o{|5@(ZO9H0{hLa)b+;pjb5-gqB*IiSe$~>4hHG z&$qvguFLhFlVXbX%GXn4>wp=8H!N#g`QJZ9<4?5ArzNgffzpvO}&9r3P({y z=1t1CESuglO}Xi$d|k86F-G+U46j?jQn<(ep)FQ?v{~4q!cZ_j5*ze25;Th`Ea1s^ z?0Lq5rhMDC&5pRkVgT_h9}4qstj2pevX|8y91OBLp9G0YafR3wT%T3EES(A+o3gT} zfT2XJ{*Ss*0am0<54YG&Kjq{IkC1V`)oc+Y+X;gGNeN2A?^9yK^@46A{+ve6hW!JM zVMg}H_St1zqH^l8yCQJm1Q}Ma*q#oEIq@yYwdm7wx%{QTR%EY47ZKU(Rx1Y#S59M3 zaltX=wHfW?M?E~#`VXVeaDzMEe10kK-eQPIPSBJ%l4NYR>_HtO9>mTP8F2>y!W?dT zCn+!{qUEgIbpPcF5!^n8!FW$^4!xqJ> zI(&h@CQsD$|4kZXF_hJ0Jm?ok>JL*dF*@ja?x=(vwG&z}%5|)+Y2V$uSG2D7_#T2vn!bL0Go~SR z+RQJ%p)?o2IvnJ=;HOAiO5$Lnk1KS2y)0s71P*f019nR+8Qr@yT4QsD&FbeA(SJ!U z+1%&IZs>nw%rD}^$-ZrnZF^OH^NAjtf)>JBNIEhE2hE&~Ijb@~$bjgM|M`_#<{|7@ z8=@VbkI&&mtg^q0_gxcm-=teIS{_6GR?+7N>I$t6p|${8UA1XbV!}0jBMCO&g5x>; zM`#!;;;MCt@h!6-Ez)d=fVI`SE0W*p_o4Nm7&mqCfX?ECAStvm&zmC-{Nu#xKPZ1m z@Za!PNnt&7sKe#(X(lk}NL{5x+mXsV`VpDu=y3sW8`!qYK)M?;t;@W4(&t$R@5akA zhOBmUsa%edpB>iK&>!Knva`6&P#+auxarCpeM2EBVf5Kr>+Uadkz0oP2Q?w+`OdCx zk;ZQ}_v?|6U#7An({f6Hs%?F$f64e$8M2l`(v8a_Ak4OMRxa7~0S1Hu!`K7bKOH8) zzumZ|gm4R-%UHOW&iPXhtraS|bZvFy@{>%CEfQo9x(vQ0DB|uK65eby%XVWw9)4RPQmvcotrwmRk2qCFKhDN&z&P=&XMzA z+Q?PDkWUg7({L4r9gOziZS~hmVNFS1W$}@GPQ15KCMTyo+v;vte@@Jua8DA*W$PynF)KNosd z<4hY6iPB9w)M;73{ojIz7xx$y z5=q=S1pE7I#ym=TNuC1N%1Qb>Jiokf993*?*WHY3(f}`=Ly_0sgTAaWjp|Og<|EZS z-#RYbsaec3rg$-p<$Bs8TeUphIGG8iFAhBmUM4fcjn&}Z8A z?rNUs<0_M~>9K-K0Vq9F%txK535g%x*qV|{*2T+E1t+woZ}A{jY`D6pn1R1itwN|# zqxFTU)KI%R>41$()Y_4k?`!gQ+c5U%@?h}oxiLi)&-po8<|bB52!_f$*}TMnIhT_X zzLWx=)THGRDHYF5NG~Q?y{stupSdLE_8{4O?0QNOja^%(CXXN>!e#@F2K9Xg#`F3k zT0OFba%lM}7KveI-x4hyTiGEt!;XpShGW~yK`7K}5n?wx- zh6aIoQw>=?o9xP0jxNB`-z$%S9tGva-5k`888^D)uVt9L$wt_toXi*Xj&})YNUv)* zF_%y`X5#*l;FA-8PSb$#KQxcPPybL2NZ^dwTumaSmEdbl-pvra>YTrM12Js!3avh5 zSEIP#Nq6YyZ;gLtF!4{^mhWnb!-kx_cnIB)!K%zY4mw|moW+WD;EhdE_ts$tLR2YW z>F~_`yILIR=qH~08|8yL&>j(r7y{0MD9=fWAZ`pUD@SSy&m~lYw*p;N_7j0ch; zA9CKQ^eXC$x9!ZHtnO7T28Hk8?NuKPOoW+J0?Y1d;F`3P9!)CDH&aHy2idr>45M&E&iE(yB%T~9JJ+fx#mL-8-IZ!FhIC9Ry{o~=2!Iv#RL zo6I?}KBLCR7WV$={HtAqpJ3Q4Y2+J1tF2EGq0TQFxKW!N-?LkAk?w@7&#+1(9eyo2 zlR(+9M$_RET$??b)HG$MN8$TcM2O5B;ANBox}N(KK%}0Mg&!)>G+GqPZ247w53%(q#B3dc1b{`@TIkX z#{u>k3B@61M83L|s9`F&VDObKUDt6nvFUBl&0;nTZAJh*;I(BFeGO9{Ii5t5qzCOJ z)VahB#lIC3X6Ovy401w2A$HmG7GuWe--YslSWx~&wA@zVRtFcAcX)y_=YO;?on7X; zg!ht;HAjcpZ%Xp21#k%kAn0m9AZSnuKpgWtgIPZ)5IZ}qlChwJFA9qZ!(_iL#-w-= z8P7>Y-`L;q_Q9tVZ89WD<`pF{k}g8*5HMFIPAz8yK)V>q7~PA7xy|PiFiF^dQP&z0ZF;rYHc`1V)-s z?Jh&Uv=*cM*H2284|C|9#Jxq>c|n||pnU9W-`HGa5lirD@~5Hgo?@2Y!f0FDL_p!Y zE|U`~T&gl9Dmqw2)eR%ij#oBD-piMF@$_TTI~i_v{k-uG?Jtzsw>9Ca-qmN=q%LdO z`k>D&Nt;5-uA?|Tu^w?BZNJVxzREAE$N?o+L z_$*c7j%rZ05H6*uwBVHgR*6vH0&en3D@-B{@=WVys`Kg1O(UDp(_n-M318)bbxny5 zd#MJOW4VUiBbU(#Td?RzFe*nKf>>*6c=-L2et+u%v&maDCqSg(3$>E<-Y191A09O) zUOi#i3iN>|9HYlr(L)cF;x~4DSGdh&Iozs zHu*70IhA9Shk{Jdi@!~SgRiEB*i6xeHxv)VKG$yNPq&lyt-WuSk!sb3@tIqsdp?8NEnY%s zR#sXdruHSdG@-RVaw-E-WKw3H(d@bK3h)V_$f$ukr9l1&OR@~(ja@DrP|>vLP~{!l zUdhhgDaxGsHTIFGTjIIt1S*GGZ7+J6mAYJ@Uq{BLN0PsfyrIbw zCA9Hi?IO@MpzZcAkzVuFFQAd|oZ6cTuy-9-ZM4GLj`?$>7YaG6tz2>P;YpoMLCc?R zE&j47w!aQE-mRCb z{&J}?5B>nwaNY>pWWA~BsOX2M-amf5lItR4psZ4D-P}2x&Q;2kbDcP3L0%Q9?1hTm zl^w8}6tN#b0a@#``y}^yJ1=ir@dZ>YsivVn-bJmRFl-75B}69}s5*R19R%xIN}}Hm z>I=A3auZ~_Nk%_dO!&AQ4vB8K%Yo%ON z8Cafl>QrSrNnTEZdXHDLIA1k-2_O82rjHsAB=E4cW4mwnAG#qv#UDF@!Cx_yPdLcJ z9hg&OM;_<);*~%31B%##dPsZNn=tE5^*FY}wY+QcG_PFOR;pZ!(`DDt@D5X7zkCSE z9V+ts^p+_|?95K2WZh(D!|8-qao>qtK@b1sAzRCNr*E@fA<)4#9)CZNu8W&oLMB8E zJ%E#n8Hgdw;(HV6_11%Bmb{?C_@t%ee5^254t>yJ*?UY~nv4j)A>o;OCa@_nb?kv9 z_*^}app7O7yIe?wE%xg(xZP_23jKQLg%UnqAeM0mc_s4@Kq`G zgcIC5>;g$w2AZ>me}r3|xV}7%g;6z`Yi()wrAiXQBE}A~5oz(xO1}8kt-}^ovc1e- zxo{?PeLqku-AGocCe0wvxz4l_;@o5;3?do^d}qc}b#dOQKx99u*b_&)Dqj#V8;mj> zP?-s==1N=k6pHOAZtA<7CqX29zPdCLrsuafg%~<_-&Jo*e1}zlhn@A%@I53Kwb3>{ z=Lk)vZh9ngQc=26`BB5DXUleOrOItH4X~H3hK*CI)FJ;^!W5F~q=-a%*ZveiZM3CU zT4UbrXAu;1cep5j-jUdK*jaq_%Enpo_Ure!!H8-f3tw&$x7A%$7w=6q{P(mMcrLe9 zmG-Kk9ibT}XwDPhovJK-nB?d|sx646BT?w~SY0%av!DNw7BWN6ct^)QK&{(UW#Kbm z%lKMTZLw>QnrtjJ$?&^>^ts**(H{38c5XR`TdLW+h=}S+DV1y1>(uQ8zZYnMjczPz z73Ji2+?2ddC92v$MT2u&lTrqi>BQG~7g`GNij3rX+xT2%$xMU?egZ1EW&C&c6tXb| zQ|vb*ckcN9zSWkI9zMSz%N$=>=ZiH6iOY`ZJiI9~g%?sDppt1}(!gl-uZCw?cd6Qz(zaGO0g}Y?XLX z$#xO-%6;pCM@$m0uH^PFE74Hu9R z79Ht>OlQ_ddMZM4GtP}TrB)eboq@x0QS&!tvt-KL!*kiBz*_j^Xx)8u%;0!-cd1v> zF%!dBc5_9bAs?ID63@Wi+zSwpYFHCqhmLlLRX@Z@pldZNY$rw=dnW`kk6pmSY$V|i z;F9fl5vzdBXEMtCLv+?hm1itJ5dgxxp0ukSF!`t!Y+1LASBB|tIK7)W^?jaC1e9TM zjYR*QeaT(a_{XnoBmeq>DLwZu+F!1ia^>aWtev!i8mclS@(X~BHTmHPaL^tH~C@%k!y?C<`sRLz439J zbv$)za?&>iF@c34uY>-~+(zCs^ZZV5fDd}0xvh8lfOjlB-VvcKu>9bXx5J31kY%Sh z1G}TfK%0gpk=bD(N_JAyLs4E`bh}Ab06r9|0+jx;vFG`^QyeG`#Ft+vZcFESBh zHSlZ3{cI+KJ523(oKV- zw&ky7JTax*bbqQNNBWH=FsJ9rMO7t~n^X6G0~3*(+s3@k=(k+1!^tK_U*Z5^xIZ9%xy{~^@|v3{dVPk`!e;(FgV zEhw>RT%+ z3t2eFm!&8*sJQB`R8jC4X=eV}e*6viVTx;l;=3rWHk7%KUy<1RNI(vn40OU``ubLo zVSCbmWMTtwkOyD_Nx{d=JOML+oEq@H_oFUMZ!aXs&B)+|D@V_;iiKFz`8%yPkjbA5 zu4rkhP9Eb!(6MPmJxm63{yLvfMDkrA04pB-$WJ><21(~UALrDxdVOhp!_j1N!TWe$t3zo7+8qv z6se2Oes;DgnMS#E&w{?L$ZdR3n$iCJ-7#X+_#YX_*R@{Q5Nm`&?fb_EtJ2Hz?ny#{ z{U9#cY2ii`S({?T{6Dl@)jR}8OZY#Z+I>xSz}Fjvc$4sy*Z;7l=aQKTJtJYlHtB?` z=}(36W}d|xs$i_$83;h{1dFOj7|l_3HOV3u*@gfNFb{^{|z^@Jg1Znu)-}gv53ha1m?}+-||HVJ|ahHFxiFChY^5%C6!PDpu5FYwSS`(oZoT*f`HI z0 z(?q_PwjPOJblgwUGj$uodXXe?l639moqSc0ER}O$O0EcZnJl5n@O4Q`1O%f{c2w#J z`^>?Igz*C2IM*#FE)fwC?c44nQhSMaH{~|b+(*WOgb4pO$ zPn*stSFAcM{0o+zpFinbf};7yv{I;DD3LBh%*SirE3MI&YQ&pmc$4tbXDs!MMvPC8YtHE&m7$z%u?a2 z-zY(Co3cS2>x-*NizCdC?$R%_@zpiVLq<%q)0=7XF zEPN_>z(Z~_@sXA2`3RanaBY%Y7oF{7X9DO=(AGbUB=k7k!vw8PIBm42 zFA;2P-7ny9D6$~4Uo}=5q`)~|BXvAA9E-EBCb@N6lawAGmyB;_QD`20$#L3SFa^jh z2~M%LAfmn6Okw#z?vf@2YoHQ4@@A(jQJfM;)y|XQED(JD=$5pGFlhn>X6tga^++j+ z2#(EW@8Ya2mh($EV(FMQY7C=Z+D5HKO=eYq&@B;XQB&sBNzX5u(oL+Jb)R}j5(B~k zYco-B#vdt8s-M>1T9Fysv>Q3Pt6D!zln>#Mjr7ALQm%iy%mXtwn^d)EZ&u*yYRKjx4!NyxqhLxwEO)A+SlJ1g3-OoELYjiu_w>m5X?PfPX6sq4n)diz zs&fs^sXmXtV{NMXQ@^e^7fY9rwXCR#niNIrqT)M zXFfG|Nm3a*qstRvPyTSZRvFNv-V)SKK?WlTjTRle{#zLL^SF%jyRU&FoQ)WrHZ2Y+l`Tw6x5z6Zat?J1Ysi{gZkLehHt6Gb+7MIDUDl~u z0aMJ+q1a@E`hVhBb_+zrnYOa$KPdU8cuRoUe@g1oLZF%L!l>^-JW;v&UgoY?iPpw7 z%>7cX9~^hJ)bpjWs|O(5cbsS3bGN@JVZ`!SXO2Pd4l^A7=~mGP1E8~#A1dJbzi6Oj zp@eUDYv;c5YJ^Cqo-1!0!hEv+)yO~f1 zJ-LsXN$ircmqtY?{x%l~c(aJ^T?ZVCIJ>mZ+&D65=V|;f1X`Xb_->|Eqkh<++*LyX zGT%)POLd^XHg{H%A;fZk3&9>u!bU7(a4A0|fZ@EramkORJdcT;f?PGu{dARi)Mh76 z6gSlbmgnL*XNijE)R@;_?8T1flbK3rI?QxLEgjuy*pi%jD4YX&E9UGxqop0p;#7`> zKV!q&a~EawHrhL03q369{2)3r3qlO;g%1A~|I8J(vVyBzG@A9kSsNAFC_^F2zgcl$ zcbw)C9AAwF1OH)E!@8;FE}TTwuCazKK!3StV*;Y9e4eSvIvZkxyn2p}ULSids;C4h zQ;w2tz;nsxcy53D>BNg&Oy(UM>re}Bnh4U#?)2_!s6#CF5-3)SFwKp(cD~HMWyLc1 zMBqab$G2TF?so0`j;r3SNEU4%QS{7HtU^yP({A*J*+W9w`0k+n2OiHU)59p5m&k~! zRXpf=4RoRI(M^)6X!i9gvslfv%RCeGmYo0d4C}O| zLUp@@xwc;OZ#FUC?m^7VAc;~(Xq3Z%jopOBTj$Ml}y~hG#cKSzuM2^Jua>?Ni$sn=79EOqwuj(_Q-@MVeRIbT2oTSX4lg4wVo2q z;!Q32HIT7Psgo+=ICyEbW^bf|yf+|Rz*P+ad9G5y@YDFkKc&H zSkC<5pMZ`!@#tJ6C9Y>u*a$rmvv*jGj3Ip>1=uAew0vJIEZnT5Mh!pcS(tKONXHEnR7m$5Bn$Vz1Mo4`@Syct8sT7Yv(g|Dchbr2-QgxlYLxCV!re?FQYku`*%0P#9Dux8nfAy3?uZ=ZR>V=SM7S8{5p8ZKx6+G};w&_A zT6_iA0bYsJIOOO}d;d5jv(1SRLtC8VQ^p36Oe@RE+1-1mkpKyM^!uKoXcJ$MY;?0orMp6zp5Jt3yG!``0Du-2iB1 zt!Pdxx=5-;@eQ&?M%o~yC!mq^dkQ0O6%Lcb7s z0H$ff1OBI`*s&K?mKJ|y1Dia!bo8xD#ow)#M8Yul(Vl;;c9Kl}V!k1st$~Hz|1QJT z;@+dLz8Os-R`%CJJc09GUcVShtcraUHfjE} zh(K7qMsq#B=DBYHgmu)S$<7<1{w?-Sj!64QCifp;@Q(xN4S0kE(TzWMu6*ZXw_rH$ zho^U+P0Z0w!OJEM0~K*=vmhbSXlkYw%7;Cq19Vr-+oCl~Xfy zH)s}v2ce#*s^i#xFZ%~T15%QpYJ?50Q%EO5=HH@uBysbjV{4tISO!wma_EVCblIjQ zzf zIadv*RQ9(?kRUv0h>iz_9jTE98A4zzJ~uX0k zttbCzS7I;HoR1wDSa@^$x9MCFR~YMxJJjlMLk6wQI+T)IGSZ!(MKR5x)2`*|lkFmJ z271FyrosG!YOgCr2YX^5zY212_8(x$>g)TL37^(PbQ}K$bM@~<>lR&clqw|KjZCSs z(z_aD6y@Ybmt=pl3-3EU>6u?q8cWC8m>dNUUns($TAe$}scioNsO~f!MH^ZUNJfXe zya)_0zm@vtyP7FAMiSf5jF`r0S4tJfGCq+wkaNl5K4wGG)1qwaD!=t4s>}hYROM4(F%) z2Q@d*HCCp;6E{9}o~QofMdK1TD!10Xbj?=~VRyTxciiWt?rfU~CV^xZL>4sT_&g#2 z*+dl+$(OLd5p3mh)TmN4q>0#@yJx%i(mL}d&>Us&OF*D6B{J%PYsY3pDr+P>An!N~ zZR&6=f10_ZloCfEjaery5_Po2v935w&XK(M$%DO0SLKkJSI+ioBQA;`HRks3n8A5F z3~}O6gEU#BqfyC~(oHYTc^AvaE@ws$6O;ek$coj`!EikqGDlNZ;UJz3@MTQhP{Fqc zIaHT_pdeUTTsk_>n3&*e07WJT&vEyBBGriC&Cp24*t@MB*v7xDif#~hgy~USjg=&M zG8+#}5B>*T9lFi5e@ z)Yyi3$OSqphDq@)=JM5eW#Yt*SXu>KT=&w<^_0_0*6P!zJ~HxdCx6Ri;2&r`(C13~ z!UP(-uR|TTc;}_8YpI;@>y@QSb>G;zMfv0f zt>!F0KfOWAWIbN_N={7adzPRDNPCMtK_a*5U%etjoW$klC%xaWcWe}cxHd`A*Oj?C z#a$e7F9z<9m1tRHGAN4T5aP%u0~YOI^i1qxi7RERJ6cs3;Lj`?IK|8pgU$?jaPF(* z*E<&|a5WjBM7^sFt?-A7;a~ILRZ#;j%Sm1N1~jPPrkIkhVCYhefCZkMn&llpVB5!l zQFHN4rDJLv8>-Ch_8qos;GV7*tyw`=zNP?F*Nb^mlZ#h3M__ZSr2#Ebe_C2hXIErO ziAHvBo;o4(?xotop9}LKld9$&aTl>3&H}wBW!VvzDHiNqIBu+?+y*WCGoq?8pDg~h zDs+}oTaS&ac#HG`73?2a`9?=X0Fep+$s`7#f;73Xf@iY#XJ3OSI+x%n)XL)_^PYoZ z{PZ-(68ke);JyCZPvaVlxuNYtd{kZh1EsIHGCaGWWYW zvEnHn$fP!jeiSl(b5+bzHajTR??`Y8l-4ykTt1Yvc;86lrl>3M-f?=k0bnhwA&eWI zV2mQv?gPE}Sjtjr>3SvyD3bVX;sFz^<$Op0&SYmSGhv7U)})D_`Pp?A@swJ@Bz!J}7K z^1uZ1Ft_GfrN2~iNmvlbBGD`oH;8PO!4-j{X$llHX>h6MTP%tnkr1+Vm}K}-*D&rx zELs@7MJ9);+V$efcAJD01$G5Ce^h435RJldA$l1a@(*@7e#-f5D9=YfHHP1@p{!SJ zY7TRw*sfQ@s?Jpu0YR<9`LW{OVP%aMOwM~8x=PBfYZ?0S{=%q$BhEL!jUu-+lsk6O zXllhRW_|gZH~=3wM>wt6$r4CVwZvBV|5ny?;*9;)SFZc&FT$9SGy=1S^9<69?4=o2 z%>BxjtmEUPl?>DFs=|~!`EUhHVvJ89GAl9?=1eIVeA}6nEJmyqu3Z8FU_V|GH8a4D0Uc)j1q*8n_UDNuhbkJJQ{be?NIB^Djc~O{03c#V<>#St| z0S%z%xobx0B{5puBXT#aeV=vYy4cnoKQ2{^eA7CllF{Nh;#$<`{2#jzlGo0bawLfgtQ zgODwD?U$lY=4~^v)UGBiAM&q=ko}Wp=*U^H6?m$2XFEDcAJk1f39AIm9>a56nGPceQ01_F~_!iLw$NMTmzq?k`QhPcjAmX_g zZ?8n%=re{|m$-QA=|&v@H}mrNE_C7C;a$KH;4839F~is#wrCLgOJ${lwlcTQJO>Y& zW@zRhsnYjQ_dK@mARZ_g=T_9!)13f4M9nvT+g$6G$yCC$R{E?KYX`DOTzW?q7j}F* zrTX`4pKS!*iOV(kQ0}2Ad88~ox5$JP*u#x3eReBIuROe!9Ff2|<^F;1piv3&r%nTdQUvOdy z9gKpJ0^BKGJwzFiy{px+9P@UvYd5N&w|!hJc5aito~5&(+Ew7jW+Sl5!kt!z*T&POL-a~`L_|T`X!rxtE8}=b6+4Mj^*xBsU^cK6FCm;V^HF#(c z3;4W3Knvr|LG!Mn33Zbr(2QWtXkRWJ7}V=reA2zSvCBXS_N}8kx6=lu1XCMj5)x=L zd_u_fk_FLa@w7NxO=FQo`32#kmN@uL$*t{;2GfSv71Kk{eAP(*uIUmp!F=Ma)4ck% zx7n{A(_JXyl`sa#; znAbumFDEAN>20VbgAN+Fnt0Ida+u@~J2koU;lnxPxWx%GT=a;<>7;SO@hm1$1SC-g=FKl;yNNraT+U$|q~876U)j1x_evAjbCzP*I8et6BACbdT@2_X-b z+P`&uqCn}i~bc~T3lzbt32&yJV?KqB9=BJ914A5At zv$iYf2*?e$D*_T4`3Lqp0bI=@D~^fDnlRJc22}wK@zpmFI>uWvARu5@5^)fH#SFWA=UmO z_3ufuOqU9AsN?sMT$iey5HiC!!KVV!Nv`qW z-EFD#XcF8yZC7vFi6&@H$be+LVDzOKWp{spJldx}h6F6vZW9LSKG{q~yi?9;vP{^d z8}sSGx{!GkVIdJRy;G2Wnz2xtVMFAPha51b<2X)C}VqExX2voMPrET)^x`=xdlT$gy6YG);c-2@Xt z%FML&0vp0d#L&fjqe4uz5GNJJF28SqJ>kXSaNaaUIp*RM zto`~lK-Z&KzkuSX!}>2e?s)ov3r^760G}6)AC;9z2xFB4KC>YZZL8dfu$=5m<75CZ zc_+Us`i+szU~!LZ{bzv%#uVR6fiEe)UvU)fCHbF!#fW1XhzJ^fXJ8@PE>1__dShXZ zpe&Tph`_Qi*7o{U<}SJyAlMfeU^sjGY^Uc{d?^JD8BcWV-88+J& zy%bmnG;?y2(Dq;aZS!wNnhzRG^~=LaN@x=7FE`@eRrb%FlxK7)s=#iNf3EF1;QiPXmH3IlR6Y!ebgxF5D$3$ zZ^=Rh(kez1Sk=0h774y7l=+Z270jCOL#YTsgBkQiup`d_eYbk2>gY3DVL5ZVROZ6y z^CARALJwowC7)0}I=OtS7@^rwwFHKO@zVR6SR!a;ZYx0eH<5v*PSi8D%{eZJC|048IO*KG;u?5R7 z&?Ak(OR*A!L8uw50UEdg6j;EW$Vdy{om8jC6w=*O6?4%NbguH!DF#XYMZFl{Ypu7u zvxlcLaq%<&=>(V^NcO||;{qBOpc^IWBD))@iS7iph&*vdF>!*i@Gd9yodfssE%0Xn zU~$@(Z4|GLnQv?fu{H!&23kb+KS?1cH01H_Ga1Osm=%3%V5ikq%U`O832{Vy&5QTXi0fd|y*-O8$|vf#4$(@rd^&FD6*(^wC;iZO+Sm|l__}}k?(uAA-dqhksOBUWuH6uMT80~1@f*R6}#^z9e!=Gisg!fr)hqkJK#j^M;dD2lso2r;WS zfwg7F@^33sYTr=O$jB7eYKpPFr61cZs<>-ijWaSn8pM!Y;C$zpv3F0}o1LyH)a5>f zBq7S~Xp0K~J)POf?F_-z#=zU_Je}Jy#O`e^1o*jJTvC&|_-rvI#(+K<%sJzi`5!>- zBU`78mQ>ys#m39l;q?xNEG7|FNln=u4;C6c?Pr+ z@>NZuB+qoWOMUH;SVGD*l+! zQ!USdRKVQfH)pm6q2j!RF=R4k9PfiRy3drEVFX3Fc1vy2JWJ-AVQJU-2Ov_(b;BQBnd1StT68!ePE!6oJ2V=@tFaZ(3ekDr_-#Cd7cr`geWkj=|ipDH~`C53-uK z8R@}0c1}qaMn~lOo}{=*!)Ka|AQ<&j_~W##UMLeOjn;GPnDv9AJV^MSyC_^Z{?7ZC z-2!aJX7GjM{CkvN=gx*ZrOAJQPqB3Me&@BWcmtb_4{HSc&&oRCy&>;^4Zm|vS>?xk z4>;vg`VYWOP9vOhRh{$eqD*^Avg@z4^mwb;&aZEGlT&xD2|Y2$?p*lu(cETTzb)HZ zSA_o!j+4ebdhuL(`rYF9ax!YAB_l|WCJ87n^e3vVl#yU4QQ{F~p9p4y5C5_zWZ>o= zUW{L$po3|zrBYe!ngo{W%Urg6`WzDX=e7FZoL`U#-?7|~?(igzbg9g@AnS=RI>l2o+NdnJIRq_>oBj+^@I& zjl*E=kTs>g83x=e=U1)2E~j=^+7Q{P^_&$1O; zI=A*&Q|YLd=r z0?*|Cfh^m4h&aCX$VMyoT-io zJyT^SYl&8s0-RPPIXqU+Wj`}y;(wYar5qdPqVIZRIYd~o(68BFkrIfN%n{Jd$1W48 z19?@BnR-rW8Njd}nXY^&BiXI5nsRjq)8FuBr+iyg@O4-h&%UwxB|dpWYur$EmnF9u zI}x|!_2Rs`*L4IAGm)9HxfkdwV@M)eJYkI(K-uh-l`1ta_9HUg?(W7_Hnu=Onq!0 zT@wU)7aqIkh;<`CA3t#*S#gJ1m^%}`+@oJMSgA@i4IBOU=kR*!L!i9Q-130>`ljRb zhIpew(2@!uZCW$X8BG6^%awl>*QG6{?I2OzpIO(|rHOc1U@!r?ER}Mlp7cP8a5z>F|jJ2=MjQNAYG`0_^b7ScyXN{M3 zg61xldyMfatm!P9h+j_7%1(u9zqwIYMIghzV8xL7Z}9sV{I7eo>$P}8Q=g5;FcL(j z$g$*vBm$Ys^Xx`KaF2bpaW`Ed)ZR+)&aq*KjnVm0831hz?rjQ|(6fOx@>C_6M5NCF z(lW~`e{_Xm6;uIfyY1+9kqUv%g&7jd@vzVBe^xyA5XAPg#=@aHB6fMDNx~u`WA3;G zG-}Wg((+5%7^o_UbGKReKY&%`M^xu&xI;ShYU0YE=p3HIhz#II8*{e?*-(4eVf8wm z2)LZtul6rVpndeL=i<+@zSxC+(}A z*0m@F6kU#*qA)`Y-D-Q)KCD6XX?XVRuj?teCv$j5W?H2a9)|t$o#K0hy(2a@f;6yx z=38GfwkFQt6MXLPe zxAp8|EpO@XLcdS7Mvqg3^}&~|Sv{J-bigE`>IlfH);=s9!=yYdf+lr^Gkj+T)3hXB zHEK=OC-%+p*k1zYW8pu`6-FxV_N@^`U!}rfs!kv9vQM!8EG`*su@fuj_NP>lxsj=$ z<_KiA3?Wn3x-xkA{HjXq5iKp5Er1``s9*gkl{5QLwS$*I!;V`DR6>7rB8%vDg77ri z)~C;WEDBIMn?~F^uR^Pm?-fVT99HmH$Is6VWNs-(@2X9B=}s{vIo?X3sdYE^&onrr zQ1}$xwU>$->yC+@ntbU)qY$0ab_x+JkIMB7q~Z8b^X?s@X0_=$hc$oJ2rYf-@Ks>6 z?kMV8z*1zx$)|0!vw_Ba#~euvCz=##vu0q)4H6)7!_?q z1@Cc(AIx^+&frtZx9^4Oy-GgxFQ=pW23L6L=oNJLC{q^TT?=YdQ=8=dklF(y}9Z1sPu?$sh`*Lxr__Fmna$6gLsIFQ!ZB9W|Pw1D7 zcFd)Eq20;YzpG=pVu2D8%;Wn#RbwRzTr2%pJcJ9NiV?CCa#9Men`#kXD{6J+1HC|J z>=qv$3`bn+aw&%uKAMh@5lRj#e>0Z$waes#TZytDxRy7(jy@4jbE(+w(@4h-|lWAkkrSRe z&UZD&qmj-nacCqh^P?M)7TdKGCJ}MWdI&~NwRbsbO~+<}JyuCNdk?B-CZ)w((n5%z zmV+y?wnX6A&9iBb%UZCu_i5yKRsR_B6Zg^WMXH7fqQ|O=_{uZ%&mE);jI19)qM zP?hhC>~+v3se7~RPW*KfEcxzpeLk!$kUOsk=P!CAi?lCzl)HNd@%=O_rO7UhgnHfs z4Rd`@&z~}1dZW+`GHlLV@XvpxY`d~=`C6yTX}78q6pqma6bBc&J90@`*BclldI0zS zBsYGERpLBdT~sz++8uMw>${!u*FAn5*+YK@H*zgPg4|MI9;AQr+LCGfHdWFJOxqsB zaq2lelrAhhqhycMz$dXax2x<5xI`P)<23`F8LwQFC*!ZG&H9-Eq;y#>9tg$1>>ZzO z%LY2L{(knDevSTcTP@v825NsYO2nEk4?-%LeZX2c7lJHcWlhm@4KYXlbY8uwAV&Pm zx?{hf#Vg|KdtEwlZW=ZogezPq0*?gyp0Z})G3w$SI>B@}ZplCH9wW4~*ya(Gy?F@E@?`mf^)k-{#Shwnxz0XrN8*5a#WBtd4zL7M?qXQ6~g7t55fE=h^ShD%~tgJx0 zI$S%(H+?pX1v1BKLyH=Fv|_Vp1<3@){^#0U+GdG)A&c#{rQe)-l@{!KnIt}KFXGFN zEK~m0^*&Qu;lctgvK&7+A%8`Z$Dfk_vMoWpx--7tR4cCk3FW9xeAZv0340JU`z*Jz z_Cr}xlkw;4l}JOHxHF&pkNUS|XIx1t7b~6B3MWD5rlJ%u{7~luyM3j`LYDytrUp*> z=HR(rM6hUd>gr9#qJGctnHyH3aT31VC7j0bey%!NBeel9PL{xXU zGT9rPwoM4N`!e|JaXm*OfNViP6kr3=c;-Fr2qmDMi|63|{tNi^WTrj2&!FkZ-&u)H z+6;Nqh@2n{t*(WC`oXt*EIi9l_VN?j_Dd1_LuTBF~ZeC zWZ?BmRD~T2#IH?95aLR%Z@$uI`ApJ#OH)C{z((?&fL06daxg&*7r^$>4sMF(55wnk z#>=}o%J#t*>=IsdY(Bi4s;JM3HNI>}75gV}$Dyc`%>6=**2DmgUN!W;1j)CFZrH;G zH-!e*^JD+UQZoR3rD*eiM7o$>Ew}t?alrE0XUV!KgM4(AJj#|*$QK_NPR{wYXre(th&)pOtSGU@HHnhvpI{N(hfKI1r1%5$~R z9-F&*7kWr?M@_mpB!V|ZSH`kga`6^T@KrmZDlcL1mDvOULHY|DJ($WN_fR=mNdiCE zt}L8TZd~a#-0UbD?abBoBSOFjBU%0*aqJieV5dZiHZWm*eRjpuLrKylj<_h(!g-IW zDWBnaa6av2wwSR|TJ6+q&iqk{gZ!&z$GScUs!{7j39TMT_F}&(MX-Ek$Cqi z5fIs8>s~vNSq$BYX1o@mj>EnsGc##>jaUJnena3$ypw9FhYx6dYSbieJOlmH>mtgz zBE!#~7?ZB|PpVWnQ&-{zyUcm~q+@tFu1+k6T+adz(Rxjiw}eK=vuJ8-#mL$SUq!3< zI@?>+>=e#s#|yacZuln`9=&ntz=u54{}6a_LL<{~c?`o5y(=Y1B+Mf{0RTc4zm(Ej z#8cj$ni*xUBilVoaS3VvNESXkEx|UN@l`pAcDQe?IV+Me6 zm3uPXG;ZL4L1^ zF-&L~3VCB3{{Ri+z#9&QCCQb!Osy745l9gHzRbEDLD<#RekK3L!tT=hn;Q?rCxcm8 zyj@ptTQ*LMJq1m*2)&*IujLGrZCA)`J)6g`Jg*ZzMVV#Ie$ovIkB4avDtV2sf5^IR z(+r4Qo$g7h$KQossS~W1VnB(HIA#5uBXEDba8LBV5qKm|I7>2U;s0?j(Gc=iZ;i89(Ig!W3vWk5=D0Y}CXuUiT z9+6{h3f&7Ae(3frfC6)xXc@Zi-ATuOs@l$}r3i@F_~RHMERfh!Jv&qp3E95;;yU}@ z>|l;AEp4kOe(*BBE5Qa};&f~^16N2ytpU_v0SvzGxLhi4l|*2f*^pjx;1VlJ!`_qX zFz~DAv$LVNxL|Pe;IfrP{NJNy#)iV~Tv38i37wx)!MssH8pzF2^YSqT4w~+=oMN_} z(B|9JK{_fmyXcM)BA<0e%|9{;%A3lvkk+It2VbnKH#>5T{*d%?WtnSP5#>n_Nne7C z0^z*B>ZPa^`AYU9$d;osfj6e)v&s%J<|q_2NWhes3$ykXul=cMyZ7AmW4HU~=E!NO z-{0#!0{s=35) zjFsGB6MFy3e1Kg-iDlDJ!Z&aS{HY|F{HkI-Uw)XLN|psGQX)u63RsbJ&72j;ThH%! zM4;BpNX(Y}l*(%@!YZNSd+iyU`>T^vQ?3dOFXD1pjF6OadL4BUrX#YqbUknyfXtADpB*8cqL6Ll-LloZJ_%CaJ zrAzU=n@`<|!6rOb)A+OYH=_Y$EBH@o{kzGAxvkS;Qah6$0z>IeOemXbRZ=}G(2Wz} zuB-+15Ye>NJ#R10;Pt`w_Mh}^wimKhckgj6kJAzz91Qz6#OJEB6j?shg^;36iHr>M zcB9stx;&6W-Ynz1{e!=vh!yEK0i|oAX#Ni%Nkq3?IhApC;lo>n7X7rqs^?|=rQZKP zz-5DAYNst4(3d3qu9j2hvIqtr%(ET;f<>EYlBn-|XkXyw;YqaI>cO=l<$ye3(NM;d zWnU@{)h1Q=jlyAd&X_-vL48v!V%}~_COz5HKgPW405e$iAJqLYMl6|hBo|k-%O1@p zjC{Dy|0tpSGK_O;jvx4gQH8?bl1pfs(Ek^y3mz!QhJ&XY`Jqak7ykBw6p1{%Bq;;E z>IMrfzj%H)N1)B#R@Hgb5e$4;c8Vo z{&c4&QKdH=nhI%{Jn2!SR)uGwJ48Pj7i^5oMbS~mmwwS&QSv>+>NvM@1K|u7?nS7g z%~x%`JDb81MTP}Rwskg9P-7)-E0bcM2TO*jWoVokqW~1c0AVIccC{!ziWC^jq;JI_ zApshyGJw#f6HXM2^pEBPtCZ<312#7~pK^>3s+RYiEVlzN9A!|4g7sQ^}9Y?Q31nMBjk&{u2}(EvJ- zCR&6h+bBA**4nVQm-2EX0TVclT!eI*eXt%NGJ@Stf1_q^)p@SLN+YJ*G0W?Z#2R0? zpd7A6kM1oHN;(sZJa<-zU`1zWD2cqd>_#I%GB^lZRj7U=I{`p2;aJAqhKi_OfXYS{ ziX;c~01pMAhmuolfFc4ke4l>lq<7eRMAL=sG%lSbXkVC#2J*d#)Ib$XtjR8b8gVe8 zk_#3VY0p0az~=|q@^qhkJtCT_(_=8e*TD&98rx489lauGDT|isLb>SVB3d$DiI6QD z{pmJnPqEYDXPrI!O%&aTFvkx_nQj*dw1f99?eq+RFbyO~M$+<)xy&CwS}nFo2?RAogV4lUyny{1U8QZpbKMJ;(1 zcFATB{SQLkh3$Cll9w)xM(O0h&y)bIrBOyf|%P#RxLa-T(HV< z-QvQc(}Pz+cK-@3s4SFpty=VaGr4D`x=DNwv+l}6>wvidTWuFVbuS`!u}GS+*f?2& zb`}t0?AY|&@9o$cctnQ}@WuFYtJdBHCReUWEVS|c;;ZVNs30gqVIJ;}oCjI@kFO4T zfN--VQrIrAPPA_u!VQ-0JT%kpIG;SDfHlG>+Vj0u4<@Rf0rfpnrn>~MrhLK}mbkW9 zl2wvhZ)$<%}`8iNYPH#>?t1_PE*WfJ5fJ{Du)qiW+ui+Q15s zi1?8pqk1CcK?mFSP0R|Ly4=sqXp4*FuaqgqJSC4y=LPYoJ<$!)54Iqg?Vh*MmDm@HdpPH`OIhbNI$?Gf@(=uBRG_kh%*nrRJl;L#r$UDoqaY&nVw{~-9 zYAmf8{vET!ir$+mDh0(MS>J#LS7{_LpkmsrR$nznS$tFWq3TmgfxiLd zDq2&OJMTdaGUPu)W?P}E@2W%`Zl;s?i#Jo^J zmdAa`Jpem=IAkAx372;)Q7|QEA#vEVtFpQ^#6sOwE_L!x_vc z3#qb*K|$Po^EH@mh6>IgDrT^5stRBp9gYG9I1*|v7qP>%1@7qmNc;RnU}#&plUQob zImNCr8lg!FCWn;OXza)o%OrFs;uSGiKUz~lhtLJkLZWSz*|Llg$FC(0HU}QGy^%SQ zp}&+Rn?&#p92p6YH}*Gln>0HreV}ls+S4Ohh_w@u03V%!44T&0dk0OcaZR#nsKR5G zLuDH(dp|Jmm+LNE)rXk+ua=6SzgO$D4Wb&N)Zt{YpK90>0jazyr^>{ z+JGn@_0>_y7Ojp_QGqgv_mhE4`TNqpc(Zk5TG%Ajim%{5T-$@QR?;C@lzn8nFQ*L78x^w%@|peTG!%EXpyE;OrNJ0Oe^=rtA1O)X>ku) zqRJ4V|o5GZ3B2E zhWgvm?l2oPpc6BdUP(sALInqxITC`rBRVnB@jiKY_yPa1pq*)<*dYrM~}ktXyHabweW;}Nix!#9~sxSpVB9SWcFdL zlZE>JiuhT{f#Wd%#9*oB16~+y9Wvw=Yuv*ley2}8%@fDbZdOrjfS^XBbJ!|0*Dl8y z!(6U)KZO8y!y2WsBeDm%qiTGpKSrgNX!*Aq+6GgD&|pUCf~@-%j*+R&-biN0m;_|8 z0NbNOQfzTfiMm~WE%Md7Ad#1<>$eiIFH;u8PoEt0BtDGp3dHF%?GKx@WY!)1K*Itj z8}vP8UY&5f6``c5F`-4)Z@;`gx;$#c{BSeyvZ^OqW48G4jir}(U5&9__PR`ZGIW}A zprW@^J~pc{#Mos!$+qt8M?SsDZEw}SU6`Yu_|PTrH!=SdHo@j+-U@BhbvfB*ql1~t zO01ju4_By~6x5Gst-{a75=s@tW{L#SvgwO<+)4^)jk+2gv$120Zci1gjQ~9FOr^)!fMgncsHP+Gz4?c;>HR$2;FpzO+?;HicI0*`q$B>drZiaBDh<+cd*kge z;ownyZ4_X!cT>5uG&c{qGZ$f2$?Mv!S0sw?V8IjI+|3>d)3>s9YY;!-ZA#s{)^eLW zlaQxux0p1I7~xl(D${-+d%Nz)$eJ~JCrEcMSawH%@EEC`sIw52GDFGOSaR(7mI{!I zT+h$Wc(3;#;NCKCcVhHUKD-KPYobMWm5M4?A6x3n>bS2(DhtLisf6uQE;8i6ESjq~ zQ?e56sY8!@5g-$v9+*l1M)+Do)Zg9o+o#V7rg4FLxND8tSf!W;Yr2sSdzO96X|uaa z6Y|sjY*KesGa!m7=8Q24|8)pI_Y2$wh#*@}Tdm&c_Dy+!w1#K(OV5wth$1Rx&!4HJ4 zK1U%mEk#zv?(2~LzJI{&`h1;hlk z`9g^x>km5`Kut^3(P6&u2_{jian89U+Slh5BknRugD`_67c5__OW63p(e6v4#mn_* zI8_=Kd3Srql%L)7#(x07OO0Y{L^wdeyUAj2ZI0BIGU9g1*v+QAHiEP58kyWKQh(BW z(%pWEzOHGc4dGMii{WdxjTOuiN~uDw&drg7-y6(SG zWY5inwum~D;&w{FxB9QnHF+SjeFq)_s@yBwElt0T%UcVz0GMqOY5BTu*zqTcwKsXf zT7JI+Eu!4kGv<;}VqL;*IBKMQrc9FG*zhR=^|P9W-zkvO+<&r*bg$FeRl|{dgukH& zDKp|F3F(9f|>ZwC*f z_0|-br`~e_fovspPK|W2cD<855!%0W1&8`>x{$$%_gN3Z;Q{CB`y-nMR0HJvpcT}V zcFpd`_~qmes}_*WX9-rr4P(B!Cv8W$R5Mzb*6)uH;j$0X zMl~;A+9N9!J+xT?3LRe`1-3&u;@1%MqMplz!*-9b(Hgrw;$xfXOJrRlemAW=!Z(&p?V|@8DF08I4cSFQaI1gDvUIZx5aG zYT`FpBaSB7J=XmX;NUXZ4r|=^oxYnC~0l{Z$c| zC$vh%5Y&f&G0spTkkyv(0$LFp7sA0MnPcq@K-H(kF^ssdmXES?@rN1;dk}qWeT^-6 zX=OI$sSF{5qS8s7m|bDg=CPc;Kt82my(|_uvgO`}XZ4R!S&C~a5(K;_f52zom@Oro zp_lM>GkUcCwG0zXPZf7xpL5eZXGLxYpgfyh=4>P0&&)IadQ@>ul zt1M8W;Z)#Z%D0?Yy;19*oNRV}xf`bYV4JMz@&uzHR#7A)VUKJTnwqQ~R=|e5*@ix6 ztP8T-?cx*7uHZPYPzR;OOSJ}hzC|uJoPx)?sn`nL)I=rhO5L)6BsjMXX68>T&;J2r z+{7&Xf4%LO14wo)ajUu_+!r{Z?{!xfGK)B)kRlPVe2#c~F!I*ca;5s#Fslu@5}X?y zJy7;4A;IS%3+o_fEzdG*RiP6O*Hh7hW6cFPWk!jOyyF8eLcAs&#` z#S-qevQllvaK6DhyI*2y^}?I8upOezg8m#yqv@hZk0u_6rE3st zucY2vJKqdnlH2pYhlS++P#G1WafN=SCLGdRRNy;RhjO`VS69*Ls`@0X5>JDMCC{M_ zF&h{PscL)!yeV>QsGHwL`Z=16{ zOj*L>aD+J4!>h)A-gM(Umz^QV51xht8Y?inENRc72DN-?r>5$R50b7QY=3;`0L+nN zi(RrO`O!&=)Qts<26`5bRS`4`(>h7DpwxV1kOVy%NP9p!0jNZ-Gtc7H$ka-`DAU>? zG(&}e{^;kRUM>8=O_UC3aQaSszJuJG7oxWh`fX_BsxKY3h~L_&Y~}!g!}LO$p&l=; zJvnSX9p`_*wXvW1x^6P&Ye#CCFljgnHaLaQfK=V?W07%x+03xJs`aXX5PkV7G~j$< z9L@;41(%5X2(KoOf|fs6bNiZIVhO9L#loLr`7&j@^6AZ zQdDKXz1>bZy@IyKfN^9p^f6wt#-7XJ63L46G)(r%|8z~q0n9cFlO;yEa2;4%tA3KH z5k<^rivGK2J9M{5_{P2Sj|0>a8Lv2OV39VFQ5+m3AK6+Ua50!gB=(`{$iTo!DX~k9 zSKH8bDaphF;xk`3_LZ%eXh3x`bMV)wFzQ>@)3Sd`rV(2G#9^{sOj-vtTwIR46*))p(1NlG(zcDZ}I?x5USddA;>_tnv--@pr z9j6@R_7yG)<2~pBOP{Fenm~7a+4jvQ3E=1RrWFg&ezXAa*<-h-ttxHg(?Q^kxc8y5 zBHP>PNC{QPanhPuT%H2rkT@e59{f{*UKoH!aX`h#9Fu|CoD=~~4YdX^Y0AJ5I60&t z!GO=G_NN9OW=N*yjp_&^r7@i@g5&KGmEh;6wR=9A#i0k(3h|8t5>FREbJrE^8d8t4 zpa-=kQZzw0r)9qiZZSncL&4{*J3LfsS3b2MIqYZv8TF;j08-+C258ME0+S+u9hzEb zr)HQ16o!*^04*&yG`XM!q%?&3Q+X$?ARU@%rN_M#0K#cAPBj_p??Az_eJU~-bu|8I zq03)rH(4PYPK!H-at?NbQO!@Z94Ay(c^@k zN8w&+K8|8L>Yq5vS8Ln=cfDn8Ow z`ikQ`PNI95)!RItPg?Aw0i$j!j`1K1eIFmg)A6Q=keWu5Gabk{;|97?uWt|>k_TFk zK#+ZveqK&EtNM~Kgy3T%n!6df9%JG+&D3W-B(Fg5-O8OlEZ_~GV4Cxdeo)gk&UUx! zNe%X(B3NR(l~){v!2Xm+LkYKY)-JqFqS&_EyW2S5(e{&7o8lLS)8rb>ssY(ZuO+y$ znoZ2o4K^#B^Q{EY6;W4H0Pk9i?meL%{4{HL17@h!!*>?R=L znfL@AmBTKJsKBJPtjg*M1OgAx8m(-%7TStQGEUs&`MK%%)hBXXk6ZB7m9~*!ts4N$ zxo16Uj<@5}V>3l)i93P(b+4r)S5~U8wU-?#+xTZgk%PXO1Hbo(=9zlf;9>Zgsu@Df zXAFRz7Bo5jwbt0{5o-2<-W5{Aly0E=)~s4ak#CT?b*h8ca39vDVPOGiI9Z8~d2StbBBF~>n&e~kQ6w#?C31eRcM2T(oDdG*Gl zeR_9XsbV{4{3;qbYDzad4+>e$aHd#E&nonqKXWsuF12)Gty=PRCL`Gf-PxEO!d!g5dH= zuRFgwkYoGl2_3@_Dv_H}F@^JG9P)P>=WE_ORaIl#W!CK0)%RSW0eJz1a5tKg%XnTR zyPSbsQ%7=1Iox}boYUhs;QWuUdiSji+><*gHS37*jS87V^b_-e&&yXAV-%d(+G`e$bjB=Hao08FR}t)*K(1KsJ!{f+%lReK{I!k7?hmDT z+?MykM`lf#P2dhQNt4!r4(Y`&81<$Tz~h{Z(&r+9h<&KYKUzX) z#yZdgvzkIVruAS4$p$iVv2DF7OH+HvVfV_R`Oc*Qwa zV&@?JXgu*qcXsPQ1Dx?m(v74OllW5c-hcs}qyRE|(&VqPr0MjgoEiX-IU|}vezb~4 zdQit5IG_PvEsWy^r7SidloDzcA3l9eO2=;iAIg!PLvKa5ic%t#0nZ~n>h`OqK@>h@ zaD{cO{{RfQ`)=k38RI6pU1j1n&c(6Y6d2s(V!2Ck^URq&^NO(_i=?n8%LS2o5l~2$ zq>bE@-!&rX_VS9|Pj%XKhkfe1WRi>>t9vwNG7&-Rfl^&L#`+yB-ap#me$33E^MX24 z?)*)oUB~lSNh@PHX)*mP&REIj9;ZEPLf8VxN&4og8&yk|=Eb$gOs8&@Kid*9wm3#l zJB>CI2uyb)oKs2(Bn3yxI?_DZN!)^PZeKEheKAs`5J84-%B4O~QU-T=RBZ`3C!nCs z!L3N-kVtTc1KyT6g==T#{*j&y6yxDBj3V-;mJN!V^wk%zTcmrMfm zBD$5&QC*&o;oC;GEi{F}{t!A<@*`(9aQcjwH_+jtW%sT|;?X0WquZ7h>{|SKewk$9 zc7UTKwRnBrsU^+SvPT(FyN<+)i7Ob%x4ExvqM453fG=)&sIM*l$0jg19SNu{^({qW z#BJrKI_H|FF}arDnWc9pzpYJ-qS88#3$k5Ez<@Ataa}dkX%u))waEBozRt37^KY)1 zq>@QSc^;K-;W{Zw?7t9W8suXm)}Ml=mM}yhh36a!jf1ydE0vw-aXXs=n%;nON+MxR zV#~*INMI8unw3V;j8$cjgMu^fQzWB`0G~Wjl1EC6xhH{ADdUbx@wW7U_B(w@H%Tr}zDob#FY$}n>8eX5O zTFJgGF5=~vr|!#FRNoSH2%8_-Hh>Pw-~DQd{v_)%@eQS{e~xN-(A3joBf9a7xkx-d zBONmERm*#SAEC-xTfz^dOP}XaL-7+@j3}1g2PEU~a6chTxcH5)sSL2$s{a6WOJx2g zpR_}@&HXD&@iezv^;vR&a4-PLRR^eu59vthST8fn{E0_CTW9^#PDmUA%M^vXkcU6Yy=n`) zSTW`@XTA`Bg

P83*o|egIHX!KKvkXSAJ=x7pDO0sY`3+NQoLaoHR(Pf zWRls{fqabPHJjlHCAgL0h8|S&j?@z9B`X~2cq?3yGBoxC{{VTFf2}C+7PrZJc#wLu z!y>(eTZrS`BdEaS*B`EUyH2s+ADXf_I3Y4m=|R+}MC2F1nu+_+#dw9fV z_R$Bk8f?BZf!vgiP`!y$Pq*<)NIqE|^VDr46o>4hK|jOmh?S4_mA(gH4RX4!mmQRf zB$P4FAwjP|T~J&g-bg3Z*CFCSlE|!`n;eR0nNv$+k9gHwHYCb6j6MZ(RVmuCV96o4~< zR}j2IbCy3-Qgt+xI+9}KMlQ6aBX4T+ z`TqIb>N0cIy(3tN$rEGKkzQq}TZ1_#xiz&Xq0L$;GD}p&+MVH!dm8jj79{&PAOa6s z^Gidra7R(vy&J>wVhm%B!lJC7LuyJb8{Sf5pv@-1j+E|$j+D9PvF2vBLIhlLp#5pL zcvxH9Q?rVS>~6L>>rO80Qd%4~sHG)*5uUY<_cswQ{CuznumIM^tN#EWMF8X8wKTm# z-qXuJ*|2N_md0HB=Di5&k3LG$IP-9&cFA!w5_!qm59L)}B$gqW^(g#r z;Oj{VxX~I(NaXoDzxvf9d|B|lt`-dnbse@^s6WoBnxt?#1*Fkjhif_9gT`YxKKV84 zI!)E#jU$fOs*dfzu3J#}zXZ9C$4t6b>BvAc_!C!rK0HIOAGBQD3n&TsRD#S$<|<0D z=$5Z3KxNsV_D*W(Ijs9FJ#C{^Gs`n~E^9z8Dv%4BT+(8Sp$nQRDQN&^idrZDqKYYi zj(Dm!6BS1Jc&qF(DzveNQ^251@*f&Z&2ziU$IF6$6JB$0PU1=DHSB&lwO6$JqjH|2 zyoUJ#$iNDr6;qswoA^#@7=a-0d8t?C9CV~1y}H%?AOU!#o3Bcsat;W=t5#A3oetid zW`U#Dv@%2r3vM{-YoLt!*A1iUiyTTB)N#_cqu1?JeDf|nd90bLIuLVGj@8Vc6j>B0o2zA?c z>oVi(SEIj)#zTTVXc>N#8mhM_-5h455)WEHSlviiR7OShq%J*007zsfr7q)9?_XL& zC*@2DcT)AJgVWUJfEP3qL8AtM5aiTnK7;eA!qKvTDKftAY86;@HEoijV4!kn0fqLi zYNWb>h!KqXQ>M9%K?MF)mvMOrVmUOJ6E?c&apnHC1Ne}r7P*1fx z2Qj=>kmq%A^Z5EBk17_Z6UQ$+zFNcsW0G5?77Ly1YEC(;h&bz98u*gw<199TRV3H7 zS0~GmAswg@>41UOk1%5yA4>8`_1$y^A8UMpz*0x`sxo+!Sznl3$fOQ&$*M%N+I++q z$pbWoWF1{c)YpkOiS^gV`do~sgPzp^)^(<1zV=eRu}nv}o2bWEU(TA>Q83A2_!{w; zHCy<8X{DWk=mQ*9l6Z;01T=*GXs{ljWlp<>KD7*tr;y*Rd5y=2@82FsbzfW>jy-cy zV2$TW6|>tMiW(Ycq)G#4o_(sbqis7$KSNw>TGpsZQtZRr^{ps%%ed66?DmDf~t zEpEj}Y}FfI5I*h36wkP=ICXhu{{WU}IQ=PdB*x`(kJ$BpH!{s3IOmV>tFXQ0y7FDI z{p!@VxoI$2diEl;QDbp}gWrm@LpkQwr-Y5ru=gge+Ul~*!zf48R;yUsIQgOn@T6N9 zQ2eoh?@UACkh+8GRut4~fj|IoDNBXyXc;&(rK+L1$8MDq-s7U0E`YpSH4`=}k-Z@B z38>#uBdQu)$ShrHNT^=nx&u_ss~%41&ONFLb!&7ytB;_~Lz*j;lIKu(LC!JQlUVZj zn`4zyMmWeBr`+nclg2|K{6$d^Se#>aPbA`|Qo1c7^m@hQysP!~sg9v|yoMR7X(hBc zRXIJls|h?kPTcyM&z+Bz5{*kxU`Rhq3b2<~pT~^))mGH4U|h2(1KzAhs6{9Gyb&}XJa3##0{4&Z+Z#}}5dmCLId zzi)Pv3?W>5)u%3`J2M39mv8(kLG6l>H3J~a#+7(!Fph`mQvU#D0=NJl!jze;Rg9T0 zpL^O~;r)@_yY zf#;z$FZ?4Hft>jdl6cKR{vEwu3|Q<4=Cz7TV+pp(k|mU_lB*ccYMR?hvXp{mAP$%{ z8+dN$UMF>N1EG4&N`*prJldW22# zvB>Hwc=apD%Xxt3J?o{ov$tF^193dn86mYylGz0GHCGZd(^A&LCWRgk%jiSI;%hN?13!SlZ(z6~|3-^=-qJ7%e+n=V5s zW9&^eVO^R@aB=>yk8IVHxH!OWYb|UUfGVUKlk7J@Wiy`Hq|zxGi!}R(mcaAQO)%cx zu1@|>p{fn`v}2WWd*gvjGu^2F09W}MgswA5wR^$xwm9x7jjY{FZa@g>zm#dS+a@5C>e-{{XkoQ`^&;rxfWfcc}cTLliQBfH6|i9m^l^ zl0}olbIx&6!{Q`!^C`gT+OwM84!cH2py^P#gmBD4(a4ybtaM4Q#Nz>QN3B?0Rx-Ib z`d2IrARI}B>`gsqfB}=AOj6`w&U7uT+m_l#Bc(+8lns-?$EmCd=78XXf;w|lrJV}! zaD8d0HXP?dZ(=e7zy$HlXxrSv2*jgydSbY3&%p(;>MB^w%E7lbd)50Zk?jvd7pd8W zJY1`SK_2zOrR0V(!*+4N0-N^h&Tw3D(9-ruYN6i=GI%5NsN9aEkIuMNzSIVOXZmKG zx`oLE?~@t90OF5igW4UQ_{((}_N5A?fZg=2F>fx59kNNsy&~#2f?vEy9<+NQ`$M(z zz+$|SNFxArBNfM|h%Z&hJbh}y_?mR#vQN6w_CxlEO^$fUr)~AD7<@*oxMlo6t8weL z@-SbUr(Lx^&7rD@*oRT0BN8e06s=+N+_S!yc11*5 zKI{kMN*X@LGzG~wH)<7gkj9l-Kksu>D#e}{dvidpL**`d3XR}V$miCr>{F5rF|eTe zQwx}SngxZ39eP&*s4mHf>}$Q%Bq19d{uRMrlJg!p&jPlixrI`m^S5q(ywQw|V~<)z zh1xbQUF@^yn@aBOO-0f_NYB}A=r%94deQB%9fO!-F zZWcH`l_B2D8=gBCS$lnn~p5oCZ^Z zGwVQy57L~Y<_4HK;+&Zcj2=7CGosMhjlzI>o-tn4q=GGwcExyxk0D8;z(06&uWHhz z{{Tdf1F)%OBVV6GPX`^UC6J!AARyF~NC@<$$fo5-@d`4&v;h3klTFPn0t``#Gl~JA z02*3Mk4iew0^*R0Fy6F>iU26hH#7n*MnvIPhIo}hm`(mMT$EO`DlhZ`ONM<7kp|3-^wT|UV$Z!p3FNZYreaP}Jr~-5#y(3)`3jv(agDL(9`xlagkxa{U@&VY_dthGlsvMK z0ptN%NbMpKpac(5QQuk%sEXhW_2RA46N&)D(=-@tWM&TAnB?}Yu%Hep z22W8&4FE1Fq*K2dF~@2EjAVDJ*HNn>B=c7`f;x(;b+u6AnnNhW;xNj3S0}D0xx568 zxIBF;tBpj2h6mcYKN8{@W807zkZPm3oX&^C@!?k|j>5LDVJ{H?43Swr6StD;E#-mQ zqpff1?LD=LVJvCen%2fGo=L6gaa-Imc?l)5K&@{JY8otHM)vU;2YFNye>&xL_A=c| zDUsOcoYXpgk$#ccyg>yCn@Ze=~sY=-8|)l6~Qk=QD(1znDO0p+SF{{Uq`uQt*A z9ebw8B%XNf*C3Ic*L`am#DEERk5O6_i1j^IYh-3)tb$PmjDFar`U~Kb>?MwyfF}iF1O=IA2Q6@c#gcbsb@|EGV(| zD!Ag9J8XHbvmMThakAnZASd^PaBDp3Pq_TK&umw!_`E`F9i~XmMnG=$=BD6e>`3qr zrDr6LN&Bp(x6`n~hEw#Wo2#%!RmnAVuBFGys=tLd?Q(4))k)4qDjQvfr_h2ZFE0rR zX*7pD0u#+?TX-{Do>y4(`8s57&38Ts@icK+G%`j5?%;$OuFhNcy4XXvAB8OsLX;Gu zcs>6BhIP9ICT%+y?m4Q1O23qVAP6(gMS7o$GGUVkpy%Gwhz_OThx+V%}LQ1(Cu;~1|x@l>r2q6j$WgPybv!84uI zG~1}6-Xr6_Pc>u0w{k~*iy^^oIrOVDg}I0Kl99))L8Du$>LEYYC}GH|j^<5S=yzJ1 zkz(aSpO>81nBHm^PdlqO%DfC$rD|5px_dDv1#@0!eQ_9-&<(^MwWWm{+@+2D=A+tw zygxdS;0))jM01mZLG_^M6dZIs)44oTR02<>1Lf&V1;z)pG@OmN$o^EPlkH1`_)r5* zK&2!uG0i3hea$X86adn9A4*(cQ}7KmfPH8IxEqJ(Mty%eQn_vi(vXa?JZf)KJ)_#_;0iU3T~70Ke1jNp!x-K00A04QE? zO*;S_1DcGm+;VxP=)4dp0p*l+q%F-fZezgBOVM&d{&WDs_~;4E3Ub4YeQ8Un8*#{^ zf<3*dfDzu49+bG^l90i04>_f7aC4eX!1Xxyqwf7E00Sg*-=$7YP>%HwBRR%uQjxDL zPJIESMD{M|hCzA($WvVgrU|ygcNKxA$r+tWmJA5sis)~5HMZlDeJC+2Xxbfx^j>w& zs};6bk0>r%Bk-<@$HQ8AkVhV;EXWUF20u#U?Jm|Vu^~a~4Rsn0qiz^0NWFW~G=eVb z9u?BzQy_WR`>?FYw7UbfS{&r}HPUJ~HtvN{)bX4HT=17{fq_s#>6*@4o5dq~&q31_ z3oIPtuIhAJHKgogF_WJ|Nd~8D6d*LJ4mkwY?}uLA=2wxyDUX*QTDYsDDwanRu6RZp zMKi-2jCJ|ABi^}|wur`CDlzJ7*L-QI*jZ^Vu0(RT3Qw(g>4rJkOw;_M)|*y2Dq7+Q z8Q9^JDd<6~fAEgpTtW;AuaS^Wd8*H-T3L;;L?vPC#dJC+itY?i!yUM7iaHL0iwc|6 z;Vv{yWoKxX$=hkcWgKR%$DwMgwWPKPI^dp_>3?p&ykJT)20b%dwweXy&9c0kaNPXn zpDQ}$QZ6<;mKd59+Uhq0+J-EQPDlp2j}%)&W2rT}d3(SFZ0;+YkyL|@b5ePAC243j zJL^cv8yV#Erx}{;ZUbtL*u^5moE&uPPYZx{(lT`$8zvP>VEfc%xEL52r^~$Ijy{yk zWKap*dhyVGX*10r+yNy16rgTWM_Oed+m;#W?^b?Yxl#$p6<=c?n0@a`NbK+KmjX17wq*zXLsgH!hwv6=w$K6jMn~4w~}sQ$Wg^|^6A=*t1sHL%b;JC z-wCR>I(_-We`j3m$6c5LgxWhJ2}Nvl$5+y1#Gl$SC#T5OdOsT2TOf@tB$yBGsje;? zMqoEW~-8-@<^n&f`X9^=T#IRhOl ztbYjVg|;kkhCPg!{*^-a!g{5QMoGoGpzgA6{(_TtB5BybWOMR@qytH@(2&d&pF>sz z3=o#;4OfygB&=9~p!cHZE4j1b*w#zHirF1WuIcP;EZ#THP7R;D9?< zqS;G5)B&ZBYU4cBUg+qdqaPfsM?4ehQvs2huCapMasjJJjiVg}b2HFGaZHm3JvvjR z&+yb?7z~j}qOn59G^-f|bHz{P=aL8%!`6Tvo4X2r7{Eaqov2%b zDO^n*q^m3BsOyS&_=Tlf#$XX$yC~yiTz+P%>dCzdfHFC*F6fB2obm}6u9&?JDw;D| z^Hx41)MB?7w^lu6JqM|+*nB0TEL*O1ZO)^GjYmI?dBQ&XkV~D!_BgJh#y4mku z08|XpD-*#4^Ia8(hAr+OMr(qlhVPYnS0;!E3=h6*TGzy{r^E-@-b@^Prxekh8AqE_ zsJHN5nA0(q^7X!jRDUXVq2Y}--rEovSd)#?5Kr>1Z2U=(Nwz&J9;M{zRB!xkcYF6D zUO53z0;#PI+ra4UJPQrz-!`Xl86U$8YClp9WNQ8$wbJ&icQ+Gdwv!}s&#p;*q$PSg`>FDQrSHL=Ctf3wzXd|*>`sKtce`2-Oeeix8} zw>H;N6Y6&R2{DHmQO53T+2Ge~*4av{Dk_c%99M-~GF!?dE0Pb&4{F$LYT@Gu1_2z? zI&k$ZCU$zH`mcyDGiwW&RN+%ReN9%MLDy0}vPl$SyDJcDM?&!!w$o#Xv|&K&ik9!ov|#E?l$Wik|H-CDWadjcQoC3Hmds3M<^2|>d01DbW8MR@u zg)B*6f~T_)U>P&hwL)V@>&8F4YF(lw1WFIE6<}XzbonC(E)QZwXHK!Bm5U@FYHyp2 zhRMm!Nu)nH$UA+3ppky)>61(HxdRxci1G$pije|_`7@7SS^#i~GPps-NVcX#B^QM} z(*{A#YeLf){&a>@l52}til!8v;0mF-d7SxynY~SDUopw&80m_kyqxlL-jK?(F4B0$ zdsdEu*tXxV=k~EJ8lI_yDOTUd8#o!TI>99i2 z#}XDl$X1VrW7c(xlX0m`in+*9Qp-xmq*<9fuw@c`FlU_j)vgV(1MahPfnH5} z5%Wv7?Y-;Vd|IrUY^)SuV>us%c*dsqa-0u(q70$}{{XsuY3YH`a68gqdgM{JECxsv z0Xlr=ps7rrP{PNPjHd`GjAkujPp}Rpx&Gq#E005_C?d+&UP+-m1QjBQNpb-JbE1qTi!5@x7eTX zu7gd`^#pY?%;PxXy%<}m2P3T?XN+Uz8K7v#wz70lmL%hoR~9B6>i3qulo-VWC^Rg8 zh|}Y?IONsOEDBIDNDAWI=aW(hJ9VjPX^4-?#W_;~qym=|0Ujwpr&0_G0A49^#V8}v zot4K*0ED466WbRDty##UbpT||r)~!Vv*ppZ=dNp|JkwcI@ua}wZag#?ll;wAkHdmC zEtVMQ0j}uA3B@qmDeXzcF{fjgip0hME1#`D>`d9(r;kBf&1y4BuF7H#wrn4s`fJ$;d6cBhrufLiF>E%5n4+(SuISF&yadR+3IkJo^Dt zf5IW8kOz~1JuzFGsdrEoF%N|F!;jr`r!R$cv{C+!3H7a=)S%M~7^A}aXdm(Jq`W#qh1Nwr~&BQlAQ0Gw$-iK9~Z!F0{N-0|`7eXBp3yrmV-K+aTcp z`c|1Vo2Y0C>1Kd%Dp3k9F;CnnH&6k#lWi{QH&6k#o3v8yrOg0DU{l(Y>}YxKQ;JbV zfU4GtGf_2)vF5MR9Ab`C7c!qtLD2q{Qf)7I7m^7y$@4$4ct@_7v6t^%Y!*o@1J8NAy39P`cBur5RRW2X58b6;s$!Z9&y( zC?WGR&Te##Qd5YcJ5TXs)gj>vwmFrpMMkEKcxhX$(TG$?{RebGmg z7at&|866L(rSpO6D7iKrU&WgG~XEa|EY9A;o9DoU#%hI3t?roQ4OEDx+-AQ9zD%T`hdQqjhGs zioh^T<2;jHiBNOXnvJ7CGQ~jeMx!{1G-pF0a20_m6KPF&}= z6tZcT>_$UV1UrGSw-$_O}^1wA(Z2@H;>iHe(vo_1^N7+Uw1BqV`sQaL(&p9;b z(KZlO@IIB<8(;@G#aEiu2t4AXXA^Oy$f|JJBhXe%nq1CK0V2EkE!QL+zl~Hjs-*4X zC$&F5p*A6kCdlkCo0>;RFuz&(Xb zx?%&9f<1+7HH1aDD^FW(oDPDQwPh-1Qdq*yH#o?_3yQrBwX(S`qaL`c1{Nv`fq_vx z5)?hDdsz?JqD|H@f_5g~Q9-)X0l`!Uwnb;jr*2|S>>k;uf3le5bo9vSRTPKRSJTU7{%vVIx zq@?F8%iEfg7rKaztbUY5cN;R0cs|vo50uJsag&;stW-+ve{iHXmc-y^2AKM_;;H-T zp7`xr!rC_K-=#8bE;$B6WYShB!aBv?K@BH7;8W9Ezd?|v9;K^D=<(&n@pR<#ZO49jrpcwubBNTCKZIhU{?3$t%Mwqu7KbCPJ%j#QK`%?yh8!%LUkXdh=VeSj!$qlF6QePu8~wPgOvk>~Cq9)M02k%Xao(IxM+2IMXDGP?Bv1r00mvjP4_a!N_jNh! zb4Xk_&e85Y@@WtwK6WlW4>SRGJmBu@o+(-Ok;X^Xh55lo zZJ;nfJ*j~F)bpQHjP%U_ARO{@nqJulB7z9|(VQ+R3>k+&2Lui(SxDGb#XqGmWK!~KOCB(4RTT=1 zQ@1xjaY#hm_7rU=y+#TC@cijP{{U+=z<$qP=SDp#GCLYy#()e`5JfvQg~0Tn2ISHb zX?JAMXaTvUq#~4JfE$6$18;oOxTx3+&;z)pnm`xS(Z^~4PLu|~r6!ZFdH_Py$B`6e zk4l#cI-J&ipvWO{o-sffnwN_7tve!VzI@;+F5*wpvK!(SozLzrh#&ONAJ)9f#aA-E zq~OW4=O6~Gk#j3ye8$J7YLFh|rFfppSYjfL(2kqWTHR0zf~#IN;RY?Lpx(m+I0y0m zmF$-CFoAQ|9ceHhgXv8weJW2dnnGy|iw)Qe`_oSD>rW*16o5*{8ylZ$Krl8t8Vizo z8kk2R{szy|gA{}x-L(Kg)|VVp%q}|seb`hIE8`^Odp2kSL62I7VgNZA0+%>MurO#~Mbd2$8=uNA4`pBU+SYy~Ejk(hknDdhWCBduHs zi=e>-7}yB@DE#2*hi8Ec0lt|4MSK}jdY9}e4LN?m>t5&ZF9Vv+(d zdUwTW=$d`Luc)Q5mJ4NZ{neEUM-C|FDpcgkS`Wl8u||+;5itjb zeDFUC>d(Zj0vOMgD@i6Y5fJtI^sgt^G?&t^3=b!o2|HgH$gIQwW3@Eya?YfwyEC@e zyjgjzyAQI6AY;Oo+{AmBJ%$-~6 zbY39w3D+cDfy6_hJ?j%-T9obVGyZ1Dymd*jE zv_eEG22OA)^g4CfL72*e(BhTNDbsJ>W}k&En(pbA8I=l*ux0@MwcOrcNuyeMvr7z^ z>?IqqUQKmuVwYl>3m#6wMn5XEZD(^b?1~2=jtde^Qfk{B^yJbsd_&`#dAFd7OcTy) zlpZgJIg2H`uu;cqwW@e}rX4YIUNOgmGmWVB;eyb*Qm9fv^FYtGhu%^;4kDyxReAL2Nko}mAQyU2^~cz zBARe1fDwa(OY6odxzAtB(&y097-ylQIsX9lQs*O{ed)?N@jwj0^`+VfIqU64 z?@B^{IskTa!Tjj~BRtRtIi~j`@}vZrB;uOKwJLF%LymLan1s*0FHxSsE3dr&c> z?+`^U&@gd8$YN<&lhERT5wZx!-S(snxE=`}w7m20OU?#H0OElOwBsl6rw?jIY%VAa zbIt(zPy@1Y(~3;;ev}qCz!VNfIL!bvCyb2I&q{CuI6P92pm4ySN&rPTr#H+#_6hc; zgM(HQFw6IV9=M=VS3+2Mk=~#uJc{jRB-;GToDWLnEsRmjzr=INHPuUUe#m!y-Mk76 z4oX0L#zPac1K9CVyq9qT@WQ|j#MYEkDc_TZ-P0Xvaq-C zSl8LGD!hN%Y%=UUEUK*rt&Q4Ew#Ssn9elEm0bKtCEVR0yP6U^*N&UB9gp~D_n3he-CM59q~ljBkwfF zihS(sblt9wLOB{~46?g3w^nnSvH;+W5mYZc$Y+%iH=?#OrlJ>9B7n+8N#<74RyBay z0PCKlQwbuf!E?AOx#QNX5(9j#k?%;t;yYw#turKZ+MMSinxiObnm|UAC+0M&NH_wU zwMz}dAXC_91!y#m~qxjuQ22?lE495o*&ewvsaEH z?F%+Z1EHYnqU|HobzAWz#5n=VgMz?un!wj3k*!PTpzJF$=UfRW-f+XNYM!O8eX<6P z9aLkIO+H(lyy(I6*fVl{tF-Xt;+tgLOCHA+!A#IXp`^QwSoIh+V^8rEHbqi9pulti zO$q~))sI$$nXX1UpK48Z%&wDjJcvY5MqRk)0=X?C#}HY}^UpJ>BWV4}ZYmEF_~kXd zIqaZ&riIQV{nwTldS}wC=9I2-4%6N_Fc6WRhrTHu+sllHlXISw)FwCrMsd({=}d9t zfW^UM*wh^Ik)xn6ZB8=rs}2I>cdtmAPxN9G0ramq&@SVTQ$~2V1K0}gWV&fos>W1% z)x~IOPjM54 zAZ*j59Zg0E%>Y%@U=0{-@&`5Nck&UaNsd!ISE6b_vcIuLtRy`kK?t3#UjBN0|8PD{-i>BAO5Q6+5lf5@;X$;#zbE;%ahX>Jk+agD}M&wIR~`{RbtxI zjv0y_rE)6KRF)%w!9A&qYcA5tQ1jf<67UsLRBr4VmCO_yBYQ|X6OXMjJ7`mZpKdB= zW-YZ94ttSOM{6h>q-DVEj8NM&YDru~L{pVt&XkeRiV4~ghW4&UQb)H4s|*O^_{Zf)%EzpXMJY5MnH0UGisVEWVNJ6S=Ufi4DT?LOc6;W# z`;nV=HRk>#0d6wiP-|F8vkH+#TL}wl3x*^UUY(_ZUU45Ukk;9ckc=qvh>d-X^??Yr_<33vT|kl^_WYA=7e_e=M5fZY7ddW|7M~9Gv>n zloB$PQc3RNX4w=cKi(&$b$%ArjjUu~C?~aYG3nP+726pHu1{*wwzIgl$TJoGRVtOs zjL$}!Urm4=&7PPw65nOMSl#>Nn&Y97lzh`EV0)U^x7BaWdUqEY+hP06IK2kZa3f0kCLcneS z0N{xgl;}p7!~DuMoTX~oY!k- z5hyc~Ynr38H-@O{qrZ!*IH^VKS@}+D8XH!8Za5WsJ0K61#l27>s-07zP!xYR8m2dyZPan_54iE~I_6wfeIOODiB2RzI=Ek@F}_f0PG zN)P2o2>jVI!q8@y`?Vo;6<&Lx5|U380WX@}NHm^d^sGCd5F{Ns)gj`N#DN}8dkRgY zQcay=x#FY*o@qZavtDXMO0eS*FS0E2rh6GkEpG9r&j=joX`cJ)bMH`+zNPM zNC)+$6o86%1HAwo(}1S#6uF=U&M6tVq|dmfvw=?FAtcewG|oC=nq~l0xg_vq z-lEvuoc?q=h&frVB~HvKrgY~lD<{fgKKakqfdR&Mus)Rzs~;(>CPUtyubzZgKQhRG z?UA$ftQ-5CKui@Tk#Ww^-l{XWIG%&NFH#5Ao#v(qBmrJcCZ(>Sbn|9h4CjMLy6(B( z%wPs`dRCVu#PzWv_02T6KT7hn@ouh!Ze0EbuUh!KQ+6BRLcX{;{&dN)=)a8^u1*gV z7vYeD=~{N0ymRs!KB9m&z@@73&JQ5*Qu%<6v;gvWq|HWT0MnJjbf9DDI?=k9JawQ1 z#}va-<2@-h13(dhPQ^Q5T3P^ZIQ2AnY<`rqs!y#k7=rKKq+8`3O=X!OZDG%h2{{{TG>DPDOa83dY!DaPz52OjluCP(|o zGfK>NMr7Bsf_NZ%)KT8d56lKVbJDkEia8@7qURlPS@YXQgzR3t(O|k5ZyRCfIjVBa zJcA0r52aW!><0t2F?k>X&#f>i6`1|tGw)G1+CP8{4!NxtUB;p@4Cf?!P$H~yTs}br zd)3I==>Qqv9@Q)|M!C-10nTdVa>jB198vMqwb^fph&yA z40=-oAuMnDnX^;J1F8^{H0n8w2If zy#O~9-ReDaQZ$H9p{BD(?MPz_QWfM;z2&WH}+Rk6Kq5gkJA%7pK;dWV_B9 zw|>Hbcr_csnftuc<{6zCm!TZhgkszggX#rL@F?S)(2#}t(ab9iD!oX^^rrbh^o(cg zR(63>0-%F}O*F*OMWD-l+=@neUaVsr?lbwtCQ@^re zJo$W@x{{3J+NW8Q8OA8*CzQu+CNR5p0DDz;(d^ms(O{n9x67fa$1EHW=VFMmW z$vrBY3luH&X=DTBV13PMLo=`?lLVeAS4)79Re(M7Qwv~&0Q9JAX%sIm8(~wqN3gCd zQDyVXD`%dS-Co;+8xk|caC(vjxFD7p=sOzLlhn$t#WFH?gMfO900NrH{qBR(jll2* zJq2|f;LCzB(9>l3vT!mupq6a&$fn2v2l>zicO39=I^aU>xA%(9m#H07xMI7^aN;zb-N| zX~c|lCV&McyVAA?UX;)Va;vu@qysDS9t8j<{+n_Ky#Rxa+~d^K3uoUwF-QuG9Pyd} zpBX*HFy)RykOv&ogr_V6U<1L$Ihl%b>Q8T40Ep+mS_ADoaz!ziHw2mn6pVfp4A|1! zbn4r9+yNf7?V1F#J)&kDWA(2S(xxdO3)G$tE809gGm99;dsH%!zq!v<#W*%QRAN^= zXNq{ouQer-Zp|3YBCR-55TQqKDR$$fChjSv@M(bhQBm&)v8Mw-4yIsdr7mc}>ybbR zIHmIl>?q=zPG|v3=e0K`iYNgK5IWLikxD`IqzBr70oI*?*S#j@#}v}d>yM=XDWuIb z=hm2cpa-6nO8jQs*VSs)K<`k>qD3kw8Q>lzh0|7NE0x?vaaq1zNGg9G)$6*?fge?v z%M|fMN&YNWY<~-`)9-3F+fQIKPU1PQ3>HmJ4WkTCHSBiJ`;Z9)*FU6qF560!OC+La z1B?y@bR%SH0~5* zNhNa1KI)oFP;SQ6_r%W@Uo#7Pm~7)c0;f2vnY>lvsfW$2+;h~a#b*u%cAxO40iLy| zDW5wm4PRfB9op5|9)+_^HyV=G#nkDpL$&3snMlDiz>j@9Wm5)m6?t}D#ET1gUQ zb~vOdY`$qjBMo3r=T1LRGbsGeC#aXb{ zXRx_4uOrX_OwyIEdmMfjNZ?joPBl2_u@)cFrnb_qc1s*rF+aQIYs>EbCTa-~Na0|? zcpLBsO7Y&f$sl;} zNff96UAz1V2Rf2rK zcu|Zw!RgS_XEJs)ULDwFppBLs3U?%0mAD3F4=C%%C#$tX_tz-q@LCc=?Yz zzMNH`?K}1X8g^AYV4jsy2xiGuU_T7jgnDh%ikY3F(@XSn*DlRh6zHRv+yO=OpnKpBW4;l!McX%6c8p*!0aZ zW;Vc*LB~AT8REHj-Lo?iN#K4p6`zkZsACB8zvWn(uZS%5TY@2w0iGC~RVASk+`P9} zGuxzVAzTi*q_RhX@EIlCOLN6$w2KTlOQkK20Bo9zOlOl)LoB8F;AX1UW)pfInIy3` znonLjit`;tTwcq7K-^DWwd!%(#JWgf&R3pm&2^}iZ=ckh*3vRYJ2vLYq$dW3IDAk5 zC$1_^fu)D7DZycm!kiQeLUMXj0YNI+G`?bzK|z{m1B`X0C!R$h8bAhuMmkUk^yleD z<{bb7+)#!)p46L{1b3v#q$A#d5R!hL^qijby!Ye}dI;y*fE# z5QR%)Cm5guK{=sVj^cn9JX1P0b4MhaHu_Kms>_Z>X|BPK$^ge&0uj_22pt6gG%0h8 z)%$o+*K2hZMMpdyYI|jpRy%St)`3f7M&C=_IDat!&vRWNNX$VPgMrq$xX;;0c_co7 z6I$EeSTYVqDVW@CrM;||C(KgdAK^F^)M;?o39v0=I2{|4T!n)?E^@q9q#DXw-ENes zFG6ZdiaTrn04Z$KWxOeYzz8dsXUvCzl6wlZb>f{aOLbMaMqoQvKQ_Imh9q3Z4teIW znm2+=DQnRnIaL%fOvM>_~g~W zXhlY@XlouD66uq?rwWKz;Cc%3d$SxQ#yKi+z^_p8SBxfyN1hZmO7f{f1fiG$F~_}m zGu^_hWSE9>c@<4qXmQ2^+(xbL)l%bAu(^X4(iuTwI2;P|i;*%u*$xTqinpg;Y7xRBwzx4y zr#~vLe^Ei-FNEHbJ=dFANCao4E2IFh+zIp))s>>yZdsk&edE@j9p;}3Gdg*X>zWP; zDBn_~@p*X2;Pe8lM56=gNi2ftRH6W*rxf_WUV4g5;hJ392>1ZhW1dAw{O1FTjZbCk zKtYR+anglsHYpn_+@5KzBCp;!KJ*$~bC5<4deDPWzK$VpZz@ECzRqz~B1Mo5+zMGP z64-5yES%)AG|_RBPeH|HmS$;XX&9bM8dkPnEVG`SstE6uO-e90Fhs)nbj ztvZ)}@t<>NCDQ={j1HvKYot$Z#fvB&fK{<|3y>`%Kc zWMS!!DJQt{m&%NueX2=JmrtL{)FD6#UV{Ug^te#9zugK#_pdh6p<#anhpz5(Ua0~D zY%n^GwWM}8qV+M*kV!tZqi=A^IK@zuc~0TD=YdT7NKm6ZpK9l8Q`1jE{lu*)`M*l2 zS0|@5ESVTB%{AskKX_-*npO*rG39BdFRea1sEYE-*VdaY%z4VPnmJfpX+n4vD#eA# z!8J|pf^t{^^`?zN9AwG}_B8oeb0b4$Jtio)<5;`4lW&(2jN|4etig4u+%Du0{tJOeu$Vg0EMK8SYkMV$wSCbwwTIb%j*bI?~oG>MQf zHiOU(E6Y6VsDISRP>%GHTUTgh$-w<8@V1E~9%=cB?a8K*oob3}LI@q4{{Rs^2m-Wi^egM)e#vO= z!>JvriVXKX=cZWK^f-&p7!mc&diI2OTdsPM&3ToT zm{|+5f)s!S2Nn_lT zP^dE9L}HJvEU-rLHsu84wQL(pCO<4JquGs9ytIv=b%>NW>r|*P_K5NS02U-rT^V2i zIcyR-;<0y@OgJYV^|#{N2e!RTNxybU$mvYA9BV=}> zYoD}avg18LraGu>2{TRdvWJ`;aave`8QAg%G}T!fqVrQC~>&&d9Hgww*|-}JG)n;>2XCBvf?lpQ;d=@X~@WzL?6I}DC|!(w%R1pN)k93 z*!0>7u8`aa+&EPvcI{SE#PVCN*sS3PJxT3WswSU zwLu;8oK{=-%IFin?C3qY#YWyHwUB=P`7_-?sC6y5e2MH}_`WDmc~Rh=xgD#5Nb_^b zvjBMlyAKd*cGo4mrYsLbT*bOSo+Vh=f_i~jIo!&mZ0vNJS(EI<{gY~*jNMH>?k_pO zR9)D?sMk|~L*?%(;A0h@w+Od?X!}Eq9+hyYwq-W0xzSj7N=tW$XBhXd5JzcD~2*3cG@H5R~grtj+cnid{ zMy5MB3lY#c{dlXe{4eob*e!2o4u8EbPsmf_@wTZ11VeCRAH%hJR&~$BZxk0kPN4CD z#zaf~MN!cUSl_q!L9Y3M=fBg_9N~92^sTFH0_#SbW!|G}v~YF<{cFwN;tz|ZTuH1= zhB)FR2lQIq(5x@@xzbHfP`Hr^$px?tOEpKP*wAaKi-=~&uElciY3 z1--0Fd$ux7Z!XLYpbw=qG1RnD;;2GW=87l)q|F4=PG}hX(VCAYlr;c6^s3UU6UA8^ z)N&9g6FI$h+DYx0DZ%>JkZO>nyUQ6M;PGDHs%-KfaRZK~yi3I5F?lx0K4oqI&Hn%ns*Qs=AmD;4(QH*Vf)tDj^REs=iE>+# zeQVO}zts;+Rx(xG}*3CKT4ifJq8Ps zdeTbXYJf)=sRfwFQ<|A=IHr>g40&|xd5O$wbL&tplN4m^jYdylT@bSzaZeVYcBJCi zl&o{DXy6qJK=lHs&!@{LAsGG@*)6yosp2FYfHOj;s5zc@CXsaHZGpHv3{#=e?^vDj zy5pQ;y%a{hfE0!$?g6a`IA^fCXoPBvr|DH&K)7;A>+CDgyp{gw#V3@b_(cGD@bJX! zz?I|Pt*3^F!1DTcCcAMTH6TUwrOF2p{{RS*N>s|Aka+YI**p^zgqD6i1$PBUr5gn_ ztOo$z0}R0LVz}r!RFM2Xi5M}Nv*3XHM+UxkFlWoR6CTcWj*cYen7vCSDNzp zWQPOrt-rCaUeuz>COoL2CK?>eYPy7DfFB;!ELxrPjJb?}eMd^@TFw9m?$rJj8I2S8 z7e7jD3UJ)YPtJt%*j2~|e1c_LbE z6+g424U><;o%T5tb>gg>v606VhTswJN3)1?GMR{}$tIn<1BIzrgG~WWL8r(UDob*) zj#vtTuTX+kRs3pujV>AakdvQEpxz#bITA4R=8i@tD%_Wo1dMwcw;2)<@)A99PPNi) z;0kw^ZuvcHRydOYU{h4Z%up8KWwtJTaZt|+1v_IOfUV_)O5lM@_BhX=t59f8M+rTI zvXVloujFco(XIyxC;)Uh=N0I(Y00>s93Ob)-#zTsNm$(wD=6McaUV39Q+? z7rlw!*P+EyxSuG+@stWlZQFh7!g$)um0oe4Nam`4!V4P$T(f!(l?m`$BXC=2>zZU8 z6h0)imjzpoQ&*E#w}1I+gYm9PPYccy<-(7qb5tkr<=}0|WCs}ePADCY_-YWa$dD1+ znt8oW2s~E-2A_Kqs<)g^Zb_|(VYo%ZvmA5)R&tv~sHSw^ZBlyE#nPTZ09QL4cQ1^B z2hyJL%(x-geJLuA;Np@wIBo7AI5IIEfojo#rYp;1+#2JW;{G*3hb&0RJt_YHY`=u% znZF9DKx#)xbk|^#j9Z?SLQ9Lp;J!~@J62oY-yATMka-+cd377D{-e3bG}I6|8f~au z`I!c8M@KIX!w-O5Mr0f}rQ2J?I*bRVl#q9Vzl6T$yf5`|?I#A45Xk zUABI93`b*CMxwd@09H8aOJM&ePbxMa zHV%C&HY+HTo^$o9NeNXX9%@{MmC63g1FqBg=BHRAPr5}^RBZ81JD0yTJmcgh^74NF z0Ov}v0CT@Mtjn936Q?zr`jyJ^vA*AWah1Ww$4=x9j4HFU9z$0(Cbe@L97N1O^x~i% zAe=T@FQ_%DS0S@@N5DB^Mtat4^Dao-MN^Z+F*2R;k@PvL@2Of#{>dYyQi!>cWv(NO z7;KZ&W~{@0snF-p)*CcZ6XsdQ(k{l^f$xjfev{_ooZBJ;igOx{yd1 z=AF5)Fy}N}IZlsyagqqA-H-!}RvKK%j!p=vMDE9y;(=Ja(kL{IDv&C$btjWg;{bz6 zp^n@b9E??0Or99$(-kW=0raZUT&!Rc3B??ta#0pB&S~30Jd^oV7S&)-No;#iHLENQ z&w_gze2h7Zq=oOzH_aL5sJ^daI5RI!xv2jDwX6Xn%;(oMC^20cia{cz5r+ILGCfY* z<7<60R?_k_(S|8n!!9f!65h1GB5+1(1-Ti<>TH)Ba6$S|CQf#oZQ!2N-zYXuQae>s zE_e-wt1(K70S7tiY1l+<5$Y2j)GSQgY$C1+R~%xLOUb|$NeIrC&7=hLntT6@pIphz*o+drl^rj|fTUoCgqaTQ^81(3fB&htU=;_#0qCwh$70rY|;~4r=e#WDW zkUeVIlwz9Ff-#B!#ndf`i2VNmjd|9nqwNeCv4iVgnW!;nnMNzkHFKMSezmn9h{~?U zW=_I5IqyQ@oMCZ5Qp!o-ibZg^;E#M)NzOZ-eMzV#&m+A|PI^=`0@=qt^Z``k<@rZm zYIIZp3>~@1#X++j>T7T#Cj`DvKQ?Fr**jd1N_x!deqG9aYBTe@AC*_IJ!ts>>OTrB zA;sC7a~!w57$gDSqsY!P*QGd;qo^m^fsfb%oUq94K{4QAw|b0JX!0Blfclzl- z4%9Fd-~o<brfE=WNPi)ih7!T)6A2#4rkEK~i@&HepjzFMk zT!5_$89DFIO1ic;5)cvz80V-`MQhl2XHvY8e5*+a>5_*Zj})#u5a`y;BdYm$T=nl> z$D+mL+C~bHLXM)b{5|0*tW{;XRRU9iz z8j^+Hag5UMY;b8Aa4DdGMF2<(pW!qVZ%R;B}T*2g5LDq*)#x{9PV8HGz2~WVqF@T_CZ6>o89RacSBzX-EH`pwfOE*tYN)+PnRVkK0aCaJl4`Sz9D~h4_V}4XiBx+QrD>wa z%{*h*=M|;V2{LpAfhQl0PLV3(zrHxE=DfFr3|vNk;8f_Yyv`BYLFl~HxgyjVenO?V z^r(wRgS=*}*y(ze?nE{hQWMi;b!Pj*`t`NAoat8q2QBg(ip|%iotrg{DOi`oGAY$# zDn3KhkzU1S;q8?0KdpFIhXvAW;wy;cgnBr^#d~FlD{K^u`ct}kqFS+L;eU2WBc*xQ zir{jLG2c0_L7O{IVeedyx+DJgT$2j$@ zgaxyaj%l=c)fS}jF;WOPHEJ`?YLWsn2=7*+Ss5}07Lkc!DG3CQ-D!+QHu<6!Md*Dl!eN>C-jPn-+pmG}bJ!Dd+|% zZf}dANUd$+QPr`QG|xV*JG~B7qG7{z6ez*x^{or2*^cpycc^VG{Q1KAp1Gjolp1y` zg(o;8BcQ1xougo-h&}71I!2iUAj@=CLOKDO#ksUab}^~j*pbPpc4aDZM*jeZBDK4_ zL31ZgabCS>V79c|Z_^z`cn!FkCl3=9ZZV4Mpz&U>X9}rUn*)v2J067XlxJCweD~AJzhf2iGpx;Rz>}d%p|Ka0zV2@X09)xfpMh= za!iGfs~VvCX+WSbIP^8JZDo&04KDl)sd z_Q9@((?OQz;3P}tH)RJouFB8BdcTsV`w+0las?~1bel(;+gdC~cGI8fTGl4nE?{k{ zNq!D1uDSSm;tBFbn~eVe(?P{%%kbyL5fISn?pi)n2U?_=oZ!y6XG3BFjjC6SSDI@R zf5gGYbDs4r_M_rWCpNcnNo)zm9eUPpo^G3Tq?h%rFLN8&kjct}#%X{S@6Ad{83b|f zO$2Atp485ju+ojj(n&pyFG4{C8hbj9bI-j-ar`8ob3n$B0T?ITnvfm9kxc9k2fYYg z2Tl(nfUxZPP&Xd^DGLt66r(^wH{C7KmqGUMtP+x z-?{Hfag2M=15X2iNCr(QJo{3T6i@1j~M`~P-IO2c+;GbGhK?aw2$3gX`tEK?K&#eFi1KyiKKiyx(lni}n06D?u z6x;*Fr3 z2_xxI=RJ)mARcHCq+>L5w;81-j5a-}0RZ3}^`%^LPf9_B z>UkZgKTJ>oxCOu*(gwk#$29D5kw6Q);NzN4Op0*EIUkiT1aJ=&0T|C}bKOk}A18yy zIL$dw^&+KM!(;#n?@XC&Q;umSlrym;p7q~btY2mTcV3mjw30<|tG8}@kzK`(UdlE+ zFj@>5n=R3fXH;CUJxQ#)xGwKV!Pr}{scur`uGmGrj(7+%YU~#JtV$&Q&$)0%1VqFi z(xKd_-uf5~qFz9onp1<P>XlI#-A<7kSd|Hg+K}KU%0XJxrW6w6T%Y zFvUZ5F4Hnjlotj!Dtlnnh;+#pC+!jf$C4x?Kdo%q_+M7J{{U4JHCa9o)|BJQQr&@l zw9{sCQ!*D$w~YtRtli1xo-E;GxVrQ2T9SA}TZT7jt)pHukuY!2R#4OB!ShBo`kH&3 z^*NT~w%f$tD}q4nijG}UNE2*86YGv>Hdx~v)!jP77YfXPu6YDgNs$(=b5|2w-dq9Y zNg)IHRMw7_X?Rh;(d15gu*VhY_BXIv!USS)8S2})B-)KNpI#$kP{sDBA@2Gt+}vTrJj9zCOc|{`FI|b1q4x*U%YWm zM=UB%HuW4p!N96c7iLv>$4PZGs(DyzQ0Pf#i$Ia9JsVx9I_Tjty_eGN2H)Re(v5N*$c*pr&3 z$!yQLm=ZhHk!@{^ZyfYAJTL$NbvW-%<1JZDq{OZEsp4Gp3^HojlTOqeMQyVKq=aoB ztz!u7#&a?PDavfu8>CU5`KNSJlIm|yVW(L|x=ZLoB&6?XiIfL^C+K+ zc%^YBIo?k=d1r3ZkZZBf{7E6(ZE#gs-~z|3aqI+3mdHJZDlELO)QoyljI2_dN2uLc z{jm$A-@NX3V>OL7k#gs0yV>qvKi0VrvXBE$F$btFPAR56q@j_B+mKni)vA%~ZmUW4 zI+oDzNPG6&Kk23jq)isxA2Mofx6z)tGZbYBSpzx#9MeQdp;V~ka%uZ$_7tkgZqCYR zEFe?AQGrKdUa_25$sxyx6%#y&r2ha4!I~u*+ZP?`TOB*?a|Osk$MB)nU5bq4&WIfV zCLdI34mre)lTBN%4M&_@Za&emKgzAc;Aoy9B)32izr)UIOCJf?d5j)uah@LAW!6?;BKyT+vg8g62dcJjMY1O*>ie^_7%i?f32jB)exd%H2$(2nZ~v zvCRsjIqF^qNd6?zPx_rUX&c@pAI__v6Y0Q^+Cz{#4WJspfaf_KX|fdEj330+dubUd zT<8;JpIV_RymJ`>p&pAM zsrHg7!Q0&}Y6AXwR#`6#bCm&c`c<2KV_kwRkzRbGu|R5sQW*~7a5KQoURBC)$MC4< zmvc8MY{|d0^;ydOrt!)ipa7%vsIH~7#yrqu`cqjk878TKk01mNw49sVX}b}ud*&l} z0Q%J7qln-}W?(P}7^QncnIV;%uoQ?cV+4q?{_v?KG`B2y(>w$$A|*T=3XklhF7jI* zx#Fv|l9QPU$E8ZMMn3l-dYS~}u1X3BVETl=Bxw(NaHmNWf%d#6s*q8m0FXUa=Rqkm0^>TJJd;PB$wxGARje8IWl&? z=~DSjSRC+uYC*p%`&xYmR5|%^W=fpS4XGn z9v`z+R%^KkAHfg;&WG3wA=~nCtkTQ7o6jW1FPhEHx$(~(p5A%*SaP0qa*$5aFh^8Ju8)6 zVmQanKLB%@nKj#HAPYI%pYFIH&aF}tsLsB{R$|{a4m(#PF}A!Ue(^{ znxr<+q-3*u?XFJCPL_B^*yMBS2Ng3V#iNbU$bfo^h{3(f=SQG6s**7XxgO$yf06P= zSo@0N6Ir~BVmD##6lSJ_T)cJ*=gWiX*YvFwG()J)(XQ?Y0L02E+n?<0(njD9YQ(b_ zR|QnP%WgOWaR#+6{3jfi`>uq9k(0Vy;;-4F9cFo-jdg29y@oVbc@*+gbkA(`r|Etg zxzu7=6hj*0kj``Z3eUV2>8Z$(TbwInfw*veYtTL($>yc(GTJPqNMtS3^6TD(8!>xX zJ&p@h(XMQ6BUp;EJ8cC=Lt0vYh31~zNh1K<;XtnA$FWY@Br^S$ID~Tn!eES!)hEOI z@9fP5qc(x&d70WkKrQ(7;;FPN&8wb!cj2qMd#I9Vw#O*SvoB%RuRnzdhjbO;{P#djPzk1T{RIQGx4O6j$`#Z5MNqqhTiz$+He zPrWW^ha+b@;msFJlSzr04Dy`r%&c&IFe;yjG_z@UZe3mrMi^CGjN|dG?*&~?2Ay#N zT5kR3;=)b5k@Ts2Nhz4yz07cgjGU-qNzFcGVpJW-qVVpPZ6ggB+*D=V$tJw_TC{@4 zRk@7(>;UGUkxLk0gP2@_kQAonkiX2IXwfU}Ro0y~(QaI>=7l=jtgG zr67^nq`_hc5me4us7H6mNjxOtLp9*Szjvj|%uHy=u_FK$%fU{jvvf|ZcxwrL2#KZR*&9v{Bd zE(Nuu1?0!fSl}r2HIy%Ixf>K5@Ib3pT9y5*=3VTg7$I^qPQ}HhcWdy=T{hsY#isuN z?&SXfI%51I)@E$Ye*|HNAOLFtd}XRb7RU^W51}OfwIT67u;@!__tB6!R5%~XhIhd$ z9XwwKr5jpJWMp&1LyEk<5w_5==4-6OxF{F;*O^^-t5^ZH>Q~H+dCY|7v~(>wwTTj4 zPU7N7$3%Gv{3=PlcGCMnd0kPV;;F-{bQ08~=0MNBF=4k?Jl)a;sDcTnAZ zYsP#H2Xd z)q9g(U!j)!P*y4cARJey>DxpJ$2jEXvXXh#+A2NZP$ZxSvVl>RW@NigUg5zV!&}hlY#|T^B1wBf1#r2EKRzMiiF8b^Johe3j;~J-mCe! z8Kmo0yV5;93UTsBH6^hz%%Pl-|tQjMUcjQmOTB@ zO=~#M8%0QDr1N>A$S!inL$o7>P(3QF+6}kxr#`D)0ZuqH!lyXJWZN`b9GtogOwIDP zamT$?6(&l40(cwqv*a!|l?@k^QQ@ahx9+lW^G`mk~Iha`- zdw5L%{v6X2!m+8x3O=>jG;CL%l?0HSW{zeqL~}{uq}&Gck6}^C;fYLTMaJLm;cKPZ zRMmvb4h0;+%5f5SdiFQM%;%0sJ!w-))Zt|+(jIyiHQa5-YH1klM=;Vk*dWvqhYiQS zTGEc*{ z`BSzQJgyB{X&dWN8BPf_2Ba-+91v2XI&^M6?>@C>&J`eVM+T70nRHc<5zjT9H-%OC zW5BMI$_Gxg!!bM>r0gpkl)e@~P96H^+N-~X!0vK?3hT_7%|g+c2`46>GZTr)$Kl3C zz>}KNw$Vx`!B9cu=dEikvDyoD#Y~B`fkTk25ZWRjR_BVcEu%R320oPC>bNxTv;o*- z>r0q+94u|Y;x)ncr5bz#{#ma+)Gf-NYL#bSTCQPoksAwexF|4Ac@)!UZU+hnpaP#I z$mD*tLQAv_gCNh=i;W`B*$^ngjAE1Q@#B;k?NFukK!N51^ff5EiGls#0;C4DqU{F) zoAyOL1wF1~U@+=O)|F;Y@BS35RoM^NKs*kW8`&wwMsZpTI&qc)l1UT-cPSrQ1DTn> zW5(f*wHsS7Jq=&;qdi?mr!?O>EPt$1_|hHB$su(as*+72V+Wz>TM|nH3>Q(Kdaito z=L7Ph!?{u^WO0(X`c;*bsOFv)KjA&;NKTZjFcPZ{L8#=lj%CkJYM3N!IK@fj`3DW@~EZKl&{O5r3&a9IapeCU<iN;vx&{px% zIL2|BL7}+l{{V(6?zMgueX(EsB9>=X}MXK7mWX`$t2E6C{4)P@=!yqH3+F{eK<7{q_5HfwK`#6i4o}9Xc zvkduz>za{nB5{!-pHK+mys)L*YFl)PgTW@3?RtcGV=2#|?^Ep1`Pu0DhSLdTbtmgy zbF0VxmB9pi8f$8IZ}LcF$JVM(A#x6ILFTFuv$->s$g#&b9D35Jzzc-}np_;vPiolA zX7w^Q7v=3xToPN7cno+c8rfJ+`J!v+s;@ImzggD)hItoMl%{jK5@N-DLvN-ghVe*FKIrgL=bs53+ zqkuUdjX3jxp45P7!8y%7C|YS%Kqn`t6&T3Dt!*U>O&?9cxcbr>-06HX;itJGNv&VY z&+#u>^ow0K+Qt<~tYH`(T>;7Us$L$7XsjXyIodx8-caAfDjPIJD)J{pjeR!82lS^K znT|IXyz}Rf)8qqNG7BhpaleqP^q|;3|%qOX*D9<~9pkf{=HxtsFTOab!f$S-z$^QVBjDEBL<;^=L zm@$r~kcKCN`p^QiQU?R6Ka~YY9Fh6bWC7GrA^FJmrW#K)0Bbu@)-1I6T1%ONDDG$j zM6Q2}@}$l?*Ph&bUhvhd#xrtQj=@j$#ZO`JOF`772^GOsJ&F1Gyri>WwX+q=8@Kb7DYMgY7&{q$*By0iiPLEKQ3qk zlJS5EWg$iZfa{w1^H=kxzI?j@pU%De#d5^fk`gf3;{&C6DYergy?HKY+{cg`6%E*> z8?&C%v>W|OMHbfbI6Y5l>umlS+ywJ=304H`y-A?>$4}DKC73cuqoSMvSl8Y**Dsul zcl$b@?u?(-qEeIC(MHF2Z{eQ~X$j_Bk2QenD{TUje;a6;G-f*y5FlU(6fykGd0R<; zcW_#NK6wvQAttAbNYt(!Om=UM#e{9-Jzw38!0k1&QrCBXk9-Ym2+!wQIn$k@oIvv?nKf*mL)U=m>vaVF* z3hTpNQ?ohi{6@9FVH0GJ&bWUOw0Lasf!4a)nMjQ81aa$Lb>fq8D038U-k9dM>SFdd zEBrn5rEtSNMJ2S!03qX3=y95gQzR0yI{e`Lz|?+ecflAQ-K$1<^W3#H+Ddk;Wk;?! zr^PENP!ArMsDQUrIehWfqDd2Q=QyabjH6>|Ze>-%l~eA5q8BrXK?e>_G6hwN>33x0 zuWV8Fle==`IpCUWaw9u4tg~CmA{(yfKBLSyuAfD*v`_Sj?!;sh!(@|QY`WF-JVhv9 zpdZ$i^^ICl{{SC^C;OmQs>bfTZMoTayIz7aE$wc6#Liy|K>ceH+FLo(b;R+ijt(k2i|gx#0^;IEPQV-w#-!>~ zO>B3*1GCd^FC=Y3BPPy^oMcybbbKjjfWDh(+5QsStH``PzH5|1*jC`?y=zF&Y>Z32 zcd_gRV^XIsi*wS$K}r`d*y}zNw~Hz)?Y)&Ue?d{|ej@PH_RSP+46H{Oh@2nFuYbZd zY{Vb3pdar6{Dm>}n=5gH1S22clnRb|osN!39!;)UeZKHZXAlF`6fI}3hwhsP%VK?N z*oxT2!i!J){!jA7ME4qEH_q0IJ=u*80#{$_)9V!-T{)ML8afmEeau}Ux`pT|gue7z%3C$VKv zKb>*9zrmA4OER#2VV;kV-%y6KBR3TIeGvFN$*hdq=I>? z6G)(qr?poA9Fx~P)uUywsv9KdKZOdsoX}ezN?q6##vlPt0MnVd$2}>8oQ?6&--pabOxBRTreGo1FOoQB0Opr8kmGsvcs z&rH%BvEwAtjD;J805!VsF+s^7Q;Py|Nt^@gOc({mGHJvBI)hE<3EW9NXdLwYXb|C? zeQ5~*^U{J&I({_Vp5l;D)SoUoW`T_ycc2~s;6NY0r1qseV*;4?>C%7~c6p@FY*UqZr(greS^z*W zC>&>;nj1YSFvR+M&;s=5y#@Hj2|c)^JPJkWp7aPs`JWXaTdhWR;E*}(Q`?|nyV8M6Vwm$~yg=h5 z{*~9JqibbkzGTBV=qs6M2)joFW4>#nhf1}c0L%%`VNB<2rKjtcHn)cE#&ZicKs!|N zpKxod(|kv&UR^5PU%auNszQ(C1#vRlNVoq0WwwX~-GIz^6~Av1X|ai>o-?O z5X=J+UPa=Ybg|X0VL+|{90N_b_?3Bo3q=b|3ygBba4Vl{yOSx9uJXq`nr_D}U9~RS zyseDGw>)Ik?K1k;?Lb}b@=)QtwaZoo#r6E-U<|nIqN}Z?%AhLlppHm9(4Cpe_t5mG z*7O*mSfNRj6T`{^fm^n^?}w~xNw}WT&N(IV$Kzft_6K~Il15)fIjJDi?WDrV8g=94 z6~DDzN^?maAB#21ZFf|+HWu;21Ob3#Ip3Urg=A!$sB*ma?@EzH4pb;?a4DeS^Uzi@ zmoqskyRz26aEl)HBh=H@(nz8&A`zN`JJyBs9&=AOa!vqwSo-rwPEoaz7lOGRX;pGC z+=>?%Jn$-bQKcX#scyoIT%C~%LAh`RRb+UZ1aV!4pW%D!=){Y*Bs~k9aaOLp4?0Fk zl^@e>V(Y~_GrBk`jyJKwylW@}JoX}(G}7R%_UFE8?y00)*f9*G4@`8dS2sit-!?m7 z*71DX9Mg-Y^)C%8<)b zINcw=G}hDY)Qqx`*b`Yz1N0@a=uHc3alq%?)8&1{>Mq8hwt)^qE`2jkPqPFkdXtWV zvOdZ)f;051R<>wmNPs1r;0#o_wXMeo%_}1F-2C6ULd5mR;+?wvh}#iW_1lqM?}vOZ zXKsru@d;l5;fDgc#DWOM)VGCG(PIPpS0wRCJ0yEFvgat?PREUXnpQcH`SitIwzY|f zQ@3&MO?pnJq*~oTe{zfNsxm9h^@}I7y)Ys(1JSDK*Hh5Sz7f;(C2J^En>P`0+cjEy zWaK1~=hrn+;*tmpJZuO(4MKeBLa>Rs7(Ugh%F|mS<}7W%W;>f4HJSGH<3^Vv90%+tA?l-t!84VRwey~6+xO0XqcHjKb>=-KO>)f8#U?LA5Kr)D&8 zCL}jPJJU8?{Snp=9^2Z(vPfiR#xR35Oa2qE?#%|DG7nh@0b$c#t9~L`R@-}7 z+e8Td1sSY84dqzz5ON6_*a@vIS#Jy{&4OUK;Ih}F3Uv7{C01$KBL~A5Fs`E@y0jN0 zpO7))y*$o>z&tu+5e#q@27fy9uL;@7Hmc`f1QXQay)tN8D*_qe$RBrqHNx$4z8A6N z-X(W!Pb!-U{_5u^=qkpUp!kmN7HG7)poHaKSjusaaZ>AZTv=;&w^4}1kvL_~%rjlJ zzl${+n>7+jc~A%n1xv7$6PBkGbS-v9DlDE>1EBeTon~BU8l9>C07{5P#PltkSE$%r zJe!L*QP9>Gi8xR*z^G-aFga~L(XI3646*1lTQT@+Qq%xwyr|G}JjUx;OD5Sv7Rj#f zN0hz3(KYy0gRFNdLoogjKsD|9R-9*v$Rl8E zXRkGb@pfSlcH`(qb4Y`0& zGlDUih(;Cg4t>Q*!8me*91u@Vq#BV@dDw_k<@EzNsO5~ZfrHN#2bXmS!p|b)^c2X9 zl4X-*P!l_bZot$c2bNUBh~phjDai>cT2r~bSkmm<5{&)P&L}2Rceye{Z3HDymT~P& zC72JJ1L;fvgviM`0~F$=N6f)}s3Pu6Z~=}FPUKTk-T@$I+~Yk56o|$~D;XpXr`Ddp zj1K+j6s0IKYng3igUgD~YYvQBwLB-F4Mo-NC3K0o%8mdB`PMpuD`P}fY(^w>8RRQs ztuwNNa(8E2sd#@yw6rR+u#+4dl1Z*EYe-si5R*LDbN!tQM4|UF#|5OSpV){AWs7mo zV_PXjoozI8OQpgNP!dOTQ^BXB$e?5}JwUCA8cR$s*b5%nYK^a6Kb}>J9CT1>u7uQ? zv2AWF?46K>1asPzm0TgY$Qy}cMcC< zm{h6Ta_p>dYj1HMCNcr7%_b4&shA=T#MSLeeHI1(0FTyUI{-h%x%Sp=oyx)=1G!UF zri9~j(O}f{?K=l_Y;oHetbKRIQ(eI#x+Oz%^G*fqnfOLZYIq>{Nk z6-lXEOxFMg-pWJ=jEM96jVC5bX&v8*;kRubR+jD~Fkr~0UP;ekny2A8Ztmco2%QSW zjO2lg*D-71-x0g-lEUHh{{T$e{15Z1!%Nhy6@<187(aNj(sI{fbK9xX>$c4d5zRD_ zZ{LE8BIN!6)`$Ei7LnQ^@{aJlfO-B^=XWwo$QxAj%Agff?6a^|HxjTNw;WRE1vS*_ zAn^(Q)tY2U^COqqtDI)9Y8u#hu*&K&{AZuaxRf*6K0`3iaB5+BB$6G?och#V2ewu_ zJsVw1OIZh&m~QNGSo-F*9r#p^XqbbR2tmbj*AN*-9A$pBUOPAtZA98VsOGRbsN1x@ zlF~*kFe*>oFOSla^HrANc7$e(e-=2b+gm^`GO8E-rWqBo(h&)b`PfE>Cg=DV2!|SdmgJ84c6{-1nv^!vUT>=nFD6<+t}8>66{O zdD?P%b*nQ!l>y)adR9_G^32_Ko-<5VW!QBGZKKLK9ax%4?o@^Z4tis)LdqcHJbF{3 zjyV;b@^RZV(X4eU;4@%fGa9jx|5ZVu4$3I>@HqA*%60bj7JpE<7CfUwD@Uo6ui2!J7a}N zfFGYVVEjFnL`WvnU>l1_$d>zlAhy1~nsAk@4A_SB|~zuIx+S-7)lQhyMT?+wk>} z)FxlFxdfhhC-pT9)iu!d8y#OmNd$2_PbW+%C;3-fYa+g$U`wMiA6pApT z8;Ag!=&j|BQIv2;v7rv+;L^}2s}NH5qKaT86jIOvVvJEsNMclS42qJG#}o+6ytdyF z^{*lEjfjHf+dMJg5nji0Dk2@-y4RO@(&je0!VKVbBc)O$o@#){FG3ZMaZ^aj4oC+b ziR(qgyUF9J;MIOkdj2%TNMvka90A&+40F1gps~T+0q!bg5UP>3Lc^h;W$hYWmuD^4 zwR(<`Fl%)=@6gwkX|E8Uq1;be^i3+}G=K(dA6m*rk!M!2RI1?CANGVG0p@fZ=A1Qq zRZ>jr$9j^D^^jA~1@h+Z#{{W<~9)_zwi>*)kz0IEB{{Z#r4D3wV98w7nZneap z87hKSB0%*$YNWnCkq66YN2xjHkk3N%NTA8bHRdvS_U>L1B|+|L?XQV$uJAHfj)3NX zO6PoK8RduPN#`&3g>drfccC*AusP+BsB1aLo5!dW!1ZA;J^uh&kz5}2=5Xsej6j(ki5z=Yj9ws}P@gd5 zRNM~u5uUW~m(+fB=TmsL>K4LcMaE8etn=e*<&c3Ak9uUY)%c`f0L^*jr;R0-3dnFe z^IZj|xAuTAhn}R+2IRLX5ay~q{9qGNj7`fD2c`8X5}LJVqbky>~&5(a4HtnZgMe!O%6(i-BGfj8@B*`DjSz_lww;=LgB|=eKSgK z=WaLP)_Ijs4tYH(;^H+Qf3IrKnnhYAvv+X3d4ubUPqf{)-E;U=Cc2LYk@?as!k%{l zigue8g{dyD5M<0xu>!I#we3a+U>xz+Dk|IE!biifAkRYRd0O?3++`IO);|;|s+=e_JDe+lEdI44z z#xODk10fH)y#;git3PH{98_j7r|*6gm=)M<>rpk%!+}%E6nD*MPuzi@rDrK}nnpJ# zI-b*lY00Xg>T42aa4756g^#IHnjQBRI`)hsQCT z2vSBqxHQJ`ozoScH9~I^UEr~ig7>DZ*qdjh28}Va(oK5|E0XKa zy?F)Ci1io1j&=lpbmJze4O3B>2b#|NhE7jP(IOi?a!qa#CervnTAejpPzGjReNA}j zlJqHX?m!vls!Z3V{J|us*zHweT=zxPpgajvBmJRIO-9|01jtW919Yzd`%Uta5^2fq zcaSOZ-0HFrKGiy?>$KxE1<~{e+ab>`xb@8`x`%=s9Q)UVM=qx(HeJjBIX^X7dG&As zH#0cTV~^!S1KYmU5XM3hvU`$oRw3~wswC!CAXB(l^_{_mC*fXw2Z=7qD?4@i z)r9eEsg28%^`*?N7CO^`*NSN(m~wjaO0|<_s8$};5nR;ZgFpb%0s$A+kgn5!GgdYZ zIi{HD0bJ7`-mEfIO$#*xDzRMikEy1Y3(}s}EX3uw^r3X(4-#V@)Bu7~cnW@|qLOl) z)v*h&B!iCB)`xyc1L;5`J?{dKx>%n|i|wtCxWFFurY*gxt!kuUhG`UKe`zp1e+omY z$OqjR_N_0nL^G7dLnWjnV{S)!22%dma1Io7=xR3AoT)6kaqm{z&I6B>h4iZLVFMvv z)B#-TgKkc6dSKL%>dN2%agGjX8f-Wm@+n4^n9B7BGzhSlp}8id6DttgxbIZf-^vGY zs9t1HcJv*n8KvhS&m$h@o|DFT4lACOS(|WX`e%xad5e&&Ks~4fsQXNP*izd~bk~49=N2y#=5?miK+djFZ*d%L9sHXA*jw!3CDJSL_tb+=UOrNh)NG-RMf^&~r z5Y4~0!;J2xzN-vew1g=3tmy1F1;}IXQa*~(V`G7X$fk*8l6ZqLD6b38E>}uE8 z034_vg#dD)?iI2dk9xHf*9ZPu99H4d)sM`1`cO2qPH-q0N*U(B%VdvQmFJYiPw{7^ zP4;cAfTxPF9kF5eX;^nLT+YOn2R*7MNlKgs9@W&Xijm4w8%|E@b47)7mk~?1o_z%Y zE>QO)-nu8UMd%J{7PUDT8KxI91I`zPIiq#Tki-%VZO3X#jHm{rTL9z&ezckzW-2uM zLFaGN6)MjlaB$eI)zg5+c>Fa&vH? z(^}+?)X%dF=Lhho7($MnXb~#h7Qn&HNV7LQ@l?44aB5XKri9DN)GH3AJibhH%FgVHUTn4Xb zu+COD81}D7y|`f$bK8pZyVaxyLd7bo~3$65Rt3 zJ*fbjaz5@T+k?`O2hS`|)YHO~+nPWp0Opj?RF2ewm<`+YrwV$gB9y2dXaSiW&M4fU z^UxFYro6C536b`J+>i(AYck`+njNb!lT@`<9YL8gKUx6Q3@O`z99KF2013~BbAzqg zk6>#;*Th;y=mOhRieh^q=72A;#UOfP$QzK^9<>%Z>%|~01{ldAnp_^@tL;)ba6bxi zgdfMBr2tGE4%w!c%`r6AJK)n5E0$tgs0H>~MzW)Hio*i+^55Uj^OE`5J|S37B&=bKu+Ic@NxKD)Bq+Z#?FE~yYH2#0 zcCx7ug3H|1sC+T1&lo9XJMs6HGC`}b_%l}8q}W_-&p*34sppS#MHY`;@HVh-EF(Bj z3E+X&yP-0J$*vE;`ds!lNV7okZQutL+B0PEr2Q(Eq%y-!4@^{h$9iZP9WnJHhCz-g zfV+u23Px5Vx8f>4n0Fjfi4Jp`0KoALn_Sx!$US+*cz=mBV{drwz><1b(3d1g3b4*= z2T;)Mu6}7P1fU+7#YDV{Tb>7LY~OV(q?w8102=9Z-6K|<53=}lIXyBD{{X7J9knB( zA&%R_>T%G=7V51hj66#+5pSf-hp;J+=xdf<(d`qVa;3SAXW-uy-QfQKW?5SQ0Ke9@ zBKUu(pa%Z{R<*a!@Wi~I&Z~J#zkDe@c}` ztMV(_MICfr7tr+f5?yOIOyiu1HV@@R&avRQ5tZj_rvsllc6|OB=kl&J{5|m@JB6C> z{``-VSFQX3t}`#&X0?Soo$JM1aILR;MEhmfxo@cH+ODLDVQCrx(5yvx{A<0igUh#E z@x@|k8U~-Es4F^6H%zZJyd`x|dJfgmPMU(UFr2xV+skh{JRVvn`gSd)po`;NU4ZBg8lgVSvQ4XrSj!j zYi@_1Q*uU;To8cg)|(oTLC#G%#ySCtlHM@Jiy2E|Xd^PXRROwb^7<=aac~^GA2}>rlF8JIb2|l2sN^rkJ%!` zab$k_A)g*0iSZ)w{yU6CC=Qt)yPY0^!ttHPXWF z%1V!y9eY;=T9Z;e{51-Eh9--l&8Ob3W>yMETJ)F;rXK^sOKV@2RwA8&jD!wq=EIMG!dVtr755Qj1GFz1IHAqPI^#WcyY z)TOqO#~tVaUH5(zfM=~440xx3^6}Py5DHQ$7?ICP0m#h&HAWe!{{X?yIW*IO%_i@Z z`p_YApx_MA?l?5U*fixipkQ0pjtB?6D=$3KfVkp-0NB8%0twDJrZDF?p&J?OXaFS9 zoc(*!?g#6R;*+faC$$@h=qW;$IXwj_00ZklhLfL9!hyjQZ8#+Q&^prsUoVFyfX!@s{a7Q z&Sp62uw(gDn<%z$cGr-_IgG}nkCc)s`%JqspkvasSHspjvF1p``qs^-g0$%nJKV|0 z;3@wA8cJ6tR3vgR-(u_+U8(9S+}flqxgu6(?ZtHI;LRnj6(loA2cuxrdcTLX-73au z>}}a3L7mLxlT3w0uBSa~1=Yyh(CuGVz^Jb*B#)9Y^fl^!8rS?c{f%pjcp{ue1EZXs z-TKvSX{|Lo(I!=41N~a21tGjLXOgY>iHt>~WA4=Uk=ck;KY-15I-Q+|l*?@bgN_(3 zIr`S0gYJfzU@h7xgz9o#&=ZfXG)u!rW6xo*zmY_qPSK3=q*H#&a|@MtWCZh_haa7K zwxO;~J>oQTe5x=&L66W?En5EE*|N(%=3#=nO;QxFu(9V+AD1P#`tx09hP3$Z97y>* zj8`8P4cp-Sq0R@jcis|g#0d5Ls|xPX78a8BsU56QtWm0t!kk-!Ny$M-I`dvzdY<}6 zE#j+Gdsl38jtQ?aXu;qd^IoyyFh0p9dJ$eu>9N~AK|EKXgKeY5%;J+wfS?A0js^ud z^GVp|yU!Jj0}f6rbIBvt3FX=y5rsYDJvt2J^CaatNk{{V@l zyRjTMKx!xOv!@O5qt~neTW}YU0OqY1z^a;P{{Tl&I$%|OXYE1~Efv|1psx;FpIIG^ z2a_m9M4c9)3`>($zO4A(E>*%~NGKnVwt?OWmBzGI308#a6| z;oT2Z&}?t7qBGr37-m;+KtDrPt~3n}*HCniO}7XDJ8{NphlBh}c`l6wq&j%TvMgnu zKn6hVj%xM%vqx}dxp>w|4saU1J2rXnaj~1PSXq6XtX5FQFisJ1TtP^X97McVU#;KA zBws73IOGFdM3*OX0y-WsQq3%m_rq&%*DQns_(bDJGgYNZF&{vY~v=8&hUAlo@tK+{H z!KdiAR&X<|?9uIvsTo}NuNQ*YM-aw&IXOAW^{2{l*Qsrbb4;$>Dy}*K%|&=(S2kDBIIF>)Y!#(Os@-1ms zmzL|cDV8+P=T~(r`^SU_oya59)>BOkPFXh(U@Jz`NY%ASgWK3#OdFv%10Ri7Gdk(s z#zma>iz!&=WXoqGy>#m|(OC~N{r5NCAOJ_{RoB7V>bj5Yxd9zWbwAd$c*yHYx_l8f z(;fcJZocOz#Eog2i;hh)?(TZEP_E&X!|mZY-5hV4ANFY`pW8cv3yUm zg5P9msH+~)Mo<&@wR3uww|}kPt;@XS6|##n79;bhBSnr~&Wu1ETcE4SFm=FH1Jre+ zn3|ROqoGJkdn=PPpD8>l3{|M(+Za7P1xWZ+9D|?IfI{P*NydFD4kp`Ufjc=oRC(-9 zYBKX9kYtR5{3ESP78~y#ooFSy0bG&LP)5<7-NilF-~}1xpk{IoP6wtaC9%r?05;;s zcWN3qiz`T2och&%_{k?dg-U>h=x}?Q2AhK|d9k7tiUm@Ch;^o*%Y4;c30KZ?wP?Bo zEHj*RG!&mcqHbK3QI;KPir3~qU}+;gnH2HwS{g*qM{ysRV`A;fj({o@rm@S~_*srD%mByqS6DFT45Fch>~n$_oVmkTFYT z6tj@9!#u2eMH4sj6pcCN%~>^@(HIg)UA<3Q$i2R}n3j>xK9#t>9@U*goigB$bRwdg zK)sHd@GDjQ%$;}Os?=n~-wG!^Qjo5lA ztw?Sxh%v!t03CAN)i`8^L<*aCp5~wScp+AKE|ecZO6<}xWA0Ma0lv~U$^IuK)!jPd zOMnLc&$HY+I_@<#nc;h_LIHAaE#is(@0i`H(eT~0ZX#Vu+C$u-2l~}1FmRVdTu&PP zmug$-@vs8`0u+BLbiWWa5sxmy70;`aQrmbg+EB0d=Fg}=f2~|T2eefz*Ov@^0;vB0 z8ade2IkJR4HPok*Y>>d9_gv@oHE!~0F6_%W1mm1mE~lr*r(8rMcVJID`u>%mvX8Ui zE0R~J98t{KE-h%z7Wo-2nQ|}>0MqS`W7-8XP|w>PpCE(KdRJlLjTXY{HJ;`Lm5)Ww z6q%Z*d08Bb$GDI|&(f<;W>=IrY;X^H_RDV#=|lj!WxwLNtE=JL2)RpJW%@)aP1Y6n zJPIp|l#CR&SIFadr%8W%vxp+yUgI{2rURF=wPHW%kf;TojT0Q&*)BVnmp{sY`m^qM z!rWaqK2ovAJ%{+xH23nb5k(ii6xX>#wmf+$Z=Ty@U+}9WlYxW-x5_DKHHLl9pV@E0 zF6vMY;1DSDUQhL*PDeafuy}$5ducq+x&h#En(~X7luY0N7d#BmbJnNHpr38K0AlIz zIsw3{j*^08EM1RMPEAi7USTR51HCM>TU*3bzGNpD6z*kh3X6LpwlD}DgPOLNl9d~y zBRvTf3eE}uiam}x*7lpHX}2+{yM|d@j&mtd`ckoUqT4ySZ*EoC7Qj6Kq>AEq8&S6& z{MTbIhcu}OXsqG@9(OT6%+*`#Ya2u>ZDRoJNY5gjjsC83tt5`i=Sr#@?v34RV$#Y} zZcK2>!#T)9kIuVa2-|p9PSc{fp4uO^zbs`S?LX{~O5MEic9MTTZ z6`6_rxS(;OlQ|224{GwpT{QOtug~(6`PB=(BT|5deLhve8=+b4?sFvS*;^-U0B{&;ngrY3Axjnn3)xt!Magp}9HK<3&H+BR`&N$mE{zf)+vs zJx)b2AiA3kG`9qM$it7$nb!)jNcHG`7W9<{S|E2L*`DJ{(}bWCO-^rs0kSyuNB?S?t4+<{gF zuyadQqjv9B0mz_XMrg$tpajhsqLPpf-9s?iX*l(!Om-$ope|IoRWY`GE6Y4<3Z&bR za@|FBek1X{j*JROl02P&92)X1bH);C*94?b9C^phjMX9=xs^MWlZD_OhMB#X@qtLv zmu#N2qn`Qt(?Eq*Zkg%YpNCb*#!qS^AG|D20936cVv+3(zooV5_ z6kV+v{#C6Gg{LS0Tc#@}%`AB0*gV@Z7_$&?xvi@$3hOJj2|D!0^siQnOR|h{665Js zmIzbs#sKydfb;k~Ie998Aq(~ERu6*iq{iYfPfYZ$Kuw?wC<2|Hm=uO^k$gQy0LdUd z$i-`0_&O_b@-SauE2hb%=7E??;dt;%%*WUo4~6Z)$aVwkTeOEXtb*+4U&64l;m_qw z{{Vzo5EL*T_^y+sC^T3ubD!{tsQ?)PA6iE6d>rM@JwdLMe;sKH3M_|nm463Wx8KP) z#zz$x@O_9l+w{*h)!-UwQ9zD$d_Q9l09(ci^dM8^g-`&ID&x|(9xRHB?7^}Kr0z2r zWsq=t3UHXQ% zcgJdcJLHfCRyi3QS9&zdb?AWp6o$gzp^1MguVl&ghbaO^#9>dr6?|BR(2e%d92p2zeepMia2k;F2DSI?EHjXwZZUT?pk@cjW+DvC3 zHaZIIj0k$Dpj*Z|AgOdwYN_XqWpwYjBLj{J6*}oM9wsbLwReAIOynS^eU?5lqK{&S z?M?qmDquCV;>)vCqwlY>kWnc_OyoOo6*|=};XSCOHH3 zsc^YURypbA$lXOPxyBBxOiFIqO?;d_0Kq zj;h112U@Ey!}&qVy8abWq?5TWqd9Ad;CToQ*R@3$xBmcV9m`iz-w$p`B*>?ZIH7`KP&gT>Tfld!-z$)ZsK--Lp99?n zoAO!A}Kqr6=P5%H0CZGs-BI6jrVg)&T4|=2Li#&6T z(&a7Lo@f zENlSvt0L`VzzL8zBOU9tkHEJopa2)ujYz)^-S>Htpxh5mDy}Au5w$$1J208SIO#~Y zZ23M}Aa}0)J{=+{Q8^ylMk>m91yw*Zf(NS8xi&n>Wr{}K<>MZm>U1dQJ6H_y+Px(_ z2@rP6;ZJ;WYIN{5xIZ(4^%OS7l05DkxMJaAY>xP=vFeZ&c#JYwIpntPnvG5hB`>u2EPG17r0oMoAQm_~{ zX2RfhCm0#v*3GwvZ6;9LFi&w>7QPa+wL5|aar{J@)r!=_pksm3m>8e%i`$gICv8OD z5r;Wb&u%NH0E%{bqQG+vuUj18^z{`N_T(=31pPp)b+v{}5Lcgidf3J@`@pO1T=zFo zHjbwd=gc2UmJM3njyK@?Rts98%I;u&eQK*|@*K2NVZ8yTaIxAY)GhpA{VB%gA<>3@ zwdeA!{9tUImpy^OrmVN^_oO7_sWio7(8P+yjpICH@U9LEjYR?d>ye(hJXQE_Z^i-3 zdxJn7aAiGd*k4T7KL(>X0JTE7;i8z3$ZLTC}7P#R&3Re!dq88uREYB-pN&*eZG zB@batG5Xeg8s)U@v0vu;Vzd%fW!<`!hj0-bd(#@Ug1IYmKNV=_? zkV7v%v;l5ZGGLDNT-yd#Qlg$U2tm%_k4i&%3ui7rIzuSUZsg#0_Na}!9^89X^_myP z*8ELK3|-xL>xx4%#5;e0(lx1X;peq&B0%a2ur)8()Qs*Qogv)kO`$9@rvQ3VrK142 z&PVHA2iW?J%4w$5CnOK83gL8R!)8N$V5yUmzglQSD*9jZ--ns^{% z)|4`n!Jq+mDCMXv+cYubsL#DdK_`j;cP&U@40&n-usv#E0P1<53g*|`ntH*G1z6lL zJt+?~0SS+3&sqZa#Vacl=|EBkCXmLJIHodjnwyS!6l~8*b^?(FU=37h9Fvhi3dqFpX@(Z{;+!9@ zX~=gRiU5nqsN{w~zbMUUDB^|~6oBThZLW$Rml>`jS+qj+)IpV0hVTe2*OjXx8 zSI1hjX{Tw|I#l-;7bPweJ4WC!fyW*5S=Fl=QRa~Cb0Hsd1L?(Hjay(mVD#pw!Uq6? z4tV#gXb4~SYf?$GwR#Fnj-X)BaknG2AoV7I6nFW*3J4g@Hvp09Y3x_tkP)^z(y!h3 zq-IgU&pyfAsAIRdm zh)E!DbM&rXL%5K@F)J=H&Uxuw6cSF@%#6q0p_-!RNT&_PqQjoGDn?1hX#p%lJxHla zkMCpYO;o_@Dc^{oLIfo8{Cm=v=?Ui>hv!k5LjM2|KSMwgF$g#rs?$utNdlzv0}6(4 z85m==3}=gcQq}HdwrfB;Z$`TUe0U zW%+^WibE_|*u@$K2%C>_U5|xPBEO8}gPxVm#<8jSRG;_>uAjrUH!|ESDs2Rhn;oi& zJ!aLF;8xs7$9k7?58|pY?v4dr#~7#N^(K(ZhE&IMO%I-c)lW1I^x<%$xXmCgsNj5r z{xpZ$H6M*vOQD~>qt`VdxlDhoQ}h%7_g34SepOq{AmeQ|NsDxL$F)Pbv-cdIVL%c~ zmhD*Do{VqD$l^2VMQF;>s3&VL)~lJh`I?5VG|U9>{<##sUA66=!Tsq#HLGo-YB3Pk zSN3=u;UpxV(xx{Nt7mp;8tO7ILZ5S4`xtgF+DN)3@|S2T-r}TLn>?vL^_TX@SD)op zAh}lghFM3YXqAZE(*(HA+GLx@P-{L-S}5`v_8!?47}hO8!(A>ugwq2=$DVnl`B#m` zsSS5Z#vb_x`~knhp_5zEj!Ing?jtz;X))NjESPRHieSkZ$*fDC5ow9Y)B!yxiSCu7Xafd2rsRHyM8U>~%~PjQ1q zm?U-&b$Buw=0WZo6wkFc8`?<^`%@a?f49l`o!!QG8?jGs6sR~$Hb3ndD6<<#?98S? zg@^GhO*w6q`6URfQ?n820?}6oem%jb z$#onHhIVXwSD1fm>IF~l8=kpiigN1Lyl$0x;}lqWBfFncwJJ~DZ1f{Jrai*VWW`4A zD~>m}7%c3d4@$zl@h#WSZkIBGowsp9joF;!t)QCp)~8XCRwmE!6Vkc405XuCZLT1la>SPT5NGt2!pW0D8_r%#fFzO%b1i9dK}`he8HRsB=^N`>GH6) z+qZ>05PH(Nlh;DS!#$zfC{graYIrVm(ueJDAbjwuI{hlF#$r`WSVBJcrBFY+o8}og zq-Q6{bW>?-cM_PF%7}nQ^Mi`bme0y!0S9T|fmR_6Bw#C&$DqwjZ7#MJE0K=4rV5&p zyE3Idyq`f)0l)*bSTcEXZbB5~^c`yDo{@K`9Kxq(_lW6C$Ct60vA_+E54~B59q_85 zeOZlPy3pjZ`DK{{9)9&wTWqmoIbu6vi;vl~MDfnPzQqqpxo>fG5a!}Rp2dm9QD7o% z&hN?TgNj|w{1Qfe>RL?F6=fHrI-L&T?k`auV#js`dVD|&V56|FDDd-HAoQ*i#LI?tBRS1OS7SWl;Ns^dwzT48Ob|voRY9gT z&BpNRtDg0%M>6&uw81F&p+nN9sh$jaWq>?aA zFd-+~-kiVyJ$niO8M(z9vD-9+<%b8SS~mJn0lS>yn#ZOvJ?TeG9=#|dkEI|1`cj-? zn0r%~2ZPpt515WW8bC=rkIJ3M=}ugCIHm(fT1@2oQ_j*l@+qWJ0001Tb4|`E)Y7E$ zjs*ZGUVC~{s^_g62lq$iM<7!H$~FvjKC}lTp7hf63IH*mrgKWX6VDU@PT&rh{3sB@ z**!Bx87M!=)T+!vulKp6&baP&rJ6T69E#Ymxn@-xxW#!t_U5+vEpw86MLl)Bby#NR zMpN4yR7GlQHhPuDr7e`j)s(P3`K%3V#20rku+CKVRUK;v+g6#Q-EiC6`>j>3ZrWC3 z!ukPJWVL5s;Z0u7*$3O=k2&LbuC{*_=z=m;ESJ+eb6znO;URb zG>2oc@ehr8F=^==AMay|e}lEzB$18O3vgMv-^d?@aFGKvnP%!c@m-ID;0buh2rKPP zA{*58FYQKnLd9VUjCNoCwP5RlNv(^^3aAU#x;Rx<6*w8J-w-HkH|h6tRbYD_R|AK- zeWwHy#dkgueT+tX*B@tY71-`o%brixy8i$Tf#(g8EP^2RsV1rjWXfB%TSus?Csn>U%Sb z$WKhTsg|hTgS64?Iy+|BewD1QRB&r2L>abUrD`6P;m>pG;jtXHhw0w zmV1lqyKs^i%uqy0J@Q)wcdgsMhq^wSBqe0MkT5wDxId;V*64XqgtteJNZRb`t0nY` zndqt)^~Fmah7_4@C3nYC+0A<8*M;;^W1q7E*x=V0b*5TFJI5SQ>Yfv^TWJM`n+ix&?PVP2>T8GlISxd- zl&Qh?HKE5^7I(QUQGw10#aEtuzR{7`R96!hA~+a^AH)w@p57J%bK#q~#%fMyB!z+% z9ao=RRIdxol|?0wU^7-D3gf5*_RUQM^6AovU}a_pp*f^Vk|Tn~YjyJ^v6tl;EW-l3 zy&uGOM%@vo@>xJ#jBpKbx~{9JYEcxDTt?q`0gU@rRC-R8AY*eBk{o}}LsXH~3`A0~ z?2D?}B%Wv6Ai@6trh=$z9wN876kjB;^GE+iZWZNFMZN^NRgdmpr%%^*Y_fa^?kwt_N|63v{Gil}9gow1UA z=tgpOs&4J>DHQ8-X<~eb2LmVhQV^sNNzb)cks1-W&KEtYP_tm~Bx9y3L8(Vpi%~~! z5{>J<&r)fRBD8?21syo=P{|u9B<7Gp&ZO?(QzlcCovcdIj)iG6yPR-6>YK9|VA2Q@I6|8nT>1=V@MZLZDq$aw6Nf|lXdS<Go(qMzIjn8iy&OuGX8nShCKD@V^Q87z6lR&X|C4r?;v^uqgnxvben z7l@g@(1h{MYSp*RW--%lMP_RkMrJNXMn(l%x42;fGhTnKPrB*D5s-Sx%3a-%PZGc~bAyBQp);b4T6aBJ zym{fPWeGi{vaK*Wz_+bPwMeBSnHYdO@m6gvUd6IKcz@&573=di9 zlN0IY8cdmD6i;V9E49z=$#L|mdXJ1FjvtXeW5&{RUT1G{cB`{26nDtxrGGj8XKpe0 z)_l(AJn^q&j87SAZE-N zM&_Osa0YnwH7L)PTXDdsMhG0_`c#UpfsY3us29Oej9CJzqFf}|iP!0=AwwfB3aP^=C+e@~S zc%aBJKnOqsnqd?c29t0UfN2C%2_mH}O*kTx84sAkm&~Dn#%Y8M3{n{X05NI8K~TPVG@|2A6&X0b)v8i_D|U6a|U5VvxRSBH+_^QE(^S zN)1=uJ5VH`3qpc;s^UZIPTfEcCYWgpQyGmQAGiU{H+s}(C#?W+NMq?nN79+iC?$dOJIx#FznMy2s^MZ|C>?30U~$b= zkeqQ<+jynSK2rNmJw-H139QzYm#qe3Jw+VB%5mb#MJfPoxa*2|jnzoQ0q!aG+O*Pr z_(&tLt81w4A$+sR6hR0o0Tm1DkxY4v6WfZ)Z89;37i43or$-g6a(vS(A5dznNq_BegS}#0 znp3UJsj(0MIt)zn z0QTmsLnfgcjJD6 zz7~mx$jqlb&1cWynWG=Ol#)-~BD%OI^CS6~XEiVG&sJRfnnSt4OQc_-xdF-TQGaFX zDTgY@oDwV0e7M=UEBVp|gQiA3b4j75aN90n7$D}UNp*CuxkD~HitpvOwPS))^s18S zHqvwQ{{SkIu5rt#+%5rf3Fji89CH5Faz$PXXSW%nl?v>U?P8q?%~bx%mnUnJ>CIhDChpyEBr*Zm){Iv2 zkOM9~=`=oL3;RA*KQZKbQkb0v2sP5Jo^i%%L#KxrWf=NYS(c=6?rsMtc&c-1HxTY2 ziC{VdU9;&3z#^{Eo=rl0I|Gb3$n>g;u$+;?j}cz-tChj$bvZmieYkGx*a6nNBjJlP zyX3$)Jt`OQ?Yg(hojoegydr$^}!{@ z@(;Z4_03AUjog2D5suiP4*h2s>OTrbxI#MD6CSm35d=nDpI$0Y_(&!rn`R#1&<9v$ zQ=IgsgBx|OPy2p+{{X7O`kInGaz=2ifrG%!0Cj5|U3jN#Uf8TCH89xux$X^HTjyUxEc2RF7%^^9^4?nhBaf zq>jVTRvX64xd_7#TK0J@W0^|2f<5aZ^TN7);Uu6#>N8tLt(K;8f#lAcINS+6s*@`_ zwif^%O?sg41(w{2m5zEaH3{$ym?tcY-yEOPuiBz{4>d#_41??{(tL}w9y8yycDG&& zwTV7fRwIyh;}yed_KRt9JhyBfpqg>0o`gykCMR@YoCA(=Q5gVWxfwmpW+=FG!;+qY zo%U&EI4#rFt3nMUD(3)zMMh@>t0`>ss#02cM+QYdLr~>IU^n6@xEey`HxZtGl-9pR zVaOQk#Vj#K(e6+)j&oEl6?YxLW9eCYLmAd_WuvLZk=%O<(9`eHrck7ep0&)#FsE*D zS2VJTDQA2RxhJJkmCB7vp5@`^-vW%DMRZZK0sjEkt~U@h=I8K4r>Dbd1ubZB_#I|nsyU6W$}ii zhTA+5^O?DSF4cd$(KbIihJ94qxsH2)kI)7< zIrOPnzo*JF65r| zJdAwtJpyf7IL_9R6&?0Oqxw`!s@iTJ=|M+sg1qhZdj$-9(~(fNy=D|JJx&HW%^bE5 zX%p69*DO!~Z_|%fKhRb9_3b&1!+#Ouva$Y^;=^6H0~vlhbpEv>c#$IJH2J%o!k;Ld z(d*ZKBGcgqZPrNiLs_5jm)kMHl1{IUBOvkrB{c7@m_(&TEVyPJGjw=?e5tH{tJ0SL`_1E#w_boP$ za!o=!WaYBZI*!PX$^CSNt$9noPpdLYiRcoE_}k@TCP+c(VMTX85f(!Y;`%!Lb}2^Dw8oIlf`m( zeryDckVRHmWng}0`GyT9h3#3^ORB_9eAD>xRpiv*f0xa51apSPb4EZ23>k-}YU~#q z)GAqHBdZ>0NM6;OD|>7>1YsMT+D$FniT21)1U~N;9;J^4ql+R?qa%*>c|iq9 z=9)2=yvZPGZQ~8Q1a_#U)h^}vT4%w?+tRmeY~a5@9x`*+130C=(Cr{995Q3>^MOpM zDJ5f_w`4|A{HW`i-;YtaiU79n$Dlk^Cfdp*#?^MJ&2(X5<=d{&(uNfDdX@o}XDulG zY2dU=nALOcDbZ?@Tqf1FMfVGumIej>W%+Z-BNZ1ne)h&a#PZ20+% zT9>VCnPY}MxUANeDME!CLFg)zIpr3ar=ncSZq%Nn^z;?$b}nAga({-rqer%s-6kU? zf4%QsuVA>g18y)Yj%j*P89$I6QT(GsKw)#~nLTxQ;T_n{Wj2o+@jG zT;yjWu_wQp2>^@^y-i%Uxp~xihjw|zS<6#$(P!F1oD)sU9Ay4<{@M4WAaTjhsH#QB zVnBCC&u%kOk&cJ+r0La-8-d{UrceRjwJ%Yg-jslFe@akJDS+Jb(-i*SjWFbzO{cM- z3Ax+TifcFB9B^rvd;y$+M>*tB1IxE##UZ8bNrFuv8b%EuY}1G!;L(mapa$oj1w1h$ z81GF0_8F&+C;>Sw)C1{BwfW^SLn#L$noppj;3}!^N8wK6J?VfNckxgIx`R=koOY)i z4l~K^NsJTeKnapZr8yWLqM4jxloOg@D<%g6gVKaK;EqKp+yL|xfMjko0IYHV9AMDQ zTaIx_^q>OWjQ}{DfsTTZj?^AM3IXTdfE$izH1Dk@(~d~|=?G4o(bRUN+rX(U;A!Ou z4+pgXFf$JLr76&poch*;+E&OznGkI}f_bV3t~1hr6l_t_g3F!(r1YdG9dSSo!0HVl z>F-EBZuk^%3CB2~0E{Tf;)MqvN>X!*KuGUQ2OMLXK%+TWF~_xbJ`?i%wp8db-iYpUOLCuyx5Xqx zgMxV?u~y@!&Bb-TDOkLmHrz4e+PL8WC$0yjDXmOofL%;m}Ef(y#DBcYYjJ$`{n0uY{{Y##ha0RVB>w=jUCx)N+t|)SBL(yWn&?M}t?|N6ev4G1N~q5$ zZ7%jO8f!^nOm!lOgl0gR4Wx*KED-2)izDV<6l~WvK8o3k`UE80u ztEz#(=}(eF_K|4fBtvgAp>4z-Yo_q5nVgPtPD!ktTGkk6A7_b&_t}nfS9~)gM|wi8 zdRHxF?y@Mq-lNl_U?UmysR0JD?llIrfHR@#+NRR)-uM%-l}D(rDWlw54c3NjSRYO+ z$!}3o;#_}vy>nJl(H=MzZL2_DFDdk zy#v8xX~U;pw4r-}yV{p)?cCdO*a`zt2`s~oJJhhYE+aYQFvUZkPMPUXk7$-N*f8r# zTN+dNk7Ll7n^?)~v}Uy)O{>YQPY%9qBj+b*tvlGBYjTl&^V6E}rmZG@Wi4WaX;ksJ zXVSTU5&$jVIUVa)PSCGyrD?9Nav0}s?Bb|+kyWkSb_1vS`B)K@I~Ct}6A%iFNz(n=_6|#<68MV0Q!QPEE`Rtccp;G7C4#Jq22hRyfNVEM;=(17Qx_`U)a- zETRiud$}2?JoH2)^`tk9plu|54k?;bsTl5wt|V>vXE_~(HDi)d@(izXYM_v_mLnvb z)q!~`s;V3gn8gKiC#hi}NV#O(O;}V6Kh*3~-JY|a;$&=+7$0tw*1BTc^F_#&Sfy(h zOmO*|cjS8-iDn8&0CIbZtS6R00>{Wanv?}sQpAsL^cd>(MC}vY9jyBh^})p;iU?4E z>|4}|M%yXC=hHP42~?b>F-X!=y0wK3(;eyJLYTm)516UAl>mC0ksa6p{1k{utw~~z z66RS3n6LbtSj`WQkS0!QXByICC&U;jD@qvJ#1L$f8 z5fV0|Gv}ykR*ltgM+Smr8AskGig@8{Byk^7Mol@cT2{{exaomZzRWYj5mJb72`&Kb zlR-T4lhk~(1tTu3dyLbd@@8SZfEnkSgg~-jENsWr4AAg2L=vQX8VwvJ2X<`Dd1G$_ zq&q`njl9-Rp40rtc6*cFqA-rarbHV?Pa}*_Xr$X48Z_5YDuP_F;2zcL7IyM2lx9WR z6#+Hp+AAb_yk(ekjz1djFQ?RHu#!7Jyi?^k&1)Twsz~PHhC7XV;R$WTh8SO^dNz?~ zb7^jcCObgk3F%&Kqd|G6--)i6dBBEk!`{6z$5s+s`I$xIoSKGq(78SB)ZR(o$Q|oC z#m8e%Y8s2mrFRxmdvv11IUbbdgZ)F6lT(PaOdUVFM8@E2aH!eug1m+IqE8+ zCV1@8M(1c#xp?NQn{1Ps)SV9Y1RUp%Di0@~bIogVSxzf(N!|$^fT<=>k$k6->T29} z>iGnYJ!z8Kp=>E!`kDkorR;4&4xpCiy`x6}TZ}($wd3}7ZntsB8E~vKlU}=`j9bRP z?2amAG-$~3Y&dg|rE^zu&F8RY$tTjf!mH)51GRD*z}Yg8*d*3cDH+$|c_SfIVze~) zLtCMI7VXDM&b(%10ZVk}6@N>~v|dg??r5fS)sDA0FAyTfen-}`VU^EEJXV*9RHfEW zTy(5xQ$M z5^eW3I4p20)pYx>3rK^_(yX1&LnD8UT$b;{5JX)xTO?u7h_m|EsU5t^$CN|o-Ka6! z6;Duj%{JoJb%+6OWM(`B8^4uwTF#|qd3Juy2b7uQfse|xG>vA$#Z_5kEI+uJG!qtZ z!%Eeg5B-&Ox1c^*6!f&ZjlX*XMn`5CuTYo95P2nHx4B{d?%L(GElxYhLz{L|J7*-( zVai7|+I{rNh%F?T=b|YztKpv!5Fh(Jk$qdOb{1O6w24pHr)Bj~S}Ed3xFrpfMhA9( z{cCw zg2yd^-!%aiha4#*)KXk4?#|ZF(xOn{oCA+>iisTjvg}%bBgj_(f_TSj&{!2zaB>GG zvn|;9qC%%5jDcEtu1?leSx#4QC$(sgPYBbAtRHa)Xa@(N zr=+D=06LnB&muFnFbB6aG$f7+jQZAy>nG0TCzI@HhE1)tS0|}7@aJ{{{zYd#s*ZZZX0 zS)v_SS2@sHj&^RmW~`wZ89$9@{iYFstUo%DZll2Y#V|D0mmC^+VT#II_`yFg#WnSN zbT}-33U><{`^RcGS3NI??cxXTA9|+#FM&7+$LK0tkaDxEGGdwLd+}Uko-&U-LgVnN z(s<01giEplp`_k9AJ)A1__j$HhF1gJRM6|wToMvj1L;Z3rA@QC5-+Hx z8RO133gp)EW&rt(nsJ(9GF;R;sIO*qMr1t*rj`e#a&2{VgXAtxYH! zxbaJ#C2})$q`;^iY;>&Atid&&nH8M<8Q|A{ct{rjG zmvv{Q#ya$=7U%=Xs!~F6Xtqr-wkk1j4@zDb9%#6RwbCb3Q8uRl;I}mt_J&_tq}oe@ zPb7V6WZKxIk)$;U&)uhs=$=-0o^Cp@r29&arGGl%B)Qa1($cX9 zt|}=W{{S2_I6nBRPU1V`c%Hn|TJ|;S;8&fs#;873cLa6CN95~LsVh5-kEy03(hck@ z)%*f;DOH+(>jl(a8~->u{3JlPSnR~h2LYr6 zgVY77ld*9}MAxGy130LS{yFmas)(<(NmEH6Za@V4VzO=YEhI|Xn9mAH`cuX1q-V-( zRWTHuh7Y|=vQDeCC?NIY6*rLVi5pc|&&;ik=9~SyZ|Z+4sXePo7z2j)tl4z8d;snE z8g~mLd~4R-3H&N}wTL7j0zJ8|LG|iQylGarPc5x|M>< z3$9K%Q^j<4`kKgqu{2mNKl>g9Cv0o=6oX2IPY5>xkJWa^34E6>`&MG_ytRfm5tt z4%FsjiiPGYoGGH#88+1-fdUhgRs8em`Oq$ko|FMQTB#gnsY|E%oOY`}Y}^MJ{AqsB z4InY(@Qt0r?_j&Wl*8bQGIP71YTa2!bBcJE(9y7tar_@13ahp|WYtN04HSnyYpLzD zS7GNLT0-a6oxtM&jrO4uHxy2wn;$2@?VYMS{ z6UJLK!F{V_3^3=Bn)Gk5!U+LC8jbX*OeR+KgC^Q z=@E>B5+8CZ%4v{{W+BH+aZ_That(KIh+8a3tl9OwLLz*nW>en14CyxbAjj9la zKkC==rnCm`dAIx|dXNOL2hah{TD0*UqJ%}65f>po48Fxu-P*O9Y7UbPNuSb_rMsWI~{nHax+dcrVVqjPj!&8 zXC3oXO?qQoFIp}ZHW|U^wL;7@o@<%7)$ZfY)nk*u#%dPU@4BjI9YGx^3mr)$^c0|X zJu8qtCA&}x?b>sbj+BeytFSr*2wAxJ!%K>6lw+|IrpG;E8J=CDZt8%^~Gnlg(2X!eZ^lsAc*I5 zWRQ9aku}S5pt9}A@6R;JW>@wD1Ic1NL8cudMf;iK*0+;Zx6TS>PeVyAv1u6j#s{t` zfzHXN-KzYENcGMt1+}}4fdPs7*7Ta?k-^)?W*k!nwP%cs5%j01u2P6z1?3OZ(zRd` z1bTadNd=@(52sqNn!cUJCLf(GK%6OVPhVPiLP#Y?6x7u$GmkZM?rL?^EL?Lk ztpg+4I+%f{Y*IOeSPsNg%c$56eATCm>nFkUqtDicGM>mwf5)&Ng+j>_1N*FEwU%pU zKP$#hv7w}goRs6%kQg#S0l;|1DkqN475Rw#t8z%7m#I>Hb5$qP?eUgSanm#biud|_ zWZ{lSd{YLgXjg*3_Z2nHk!s9J$H_gbE?o$aU08rU>X9teU0MOOteD4KioBZbx~K*~ zYm;pjQp(>k80py5LqoX?T0|^AgfCoG2=5nKwr0ngznx0Dy}mLfU(c<1+vzf^08&Lc z^`?tvS#g;Q4w)y4Rs+(8riDk$Gu#St-e2(X8-@9xIu60dQBnLtVsHTva)anh0SmU*MSBVpK=0G^dZ>?(ZRkD;yp$IO38d%%_qDdeRfv)q*qR^$OYPP+Y`BflfMSAl8Mf zd()Hi0oJ0LFP)2H+v!-n&KmEbna2Bx9hhc8HbjxDI%zyp89TAB8l_ zrqzo&bfgSI%ffef0m!R&I&_wq5(eb(aZyKX z89`QIo+*tcF{F2HeJP}n2nX`52=v*cIELP7y-F!+eELkbv2VJymLxq(3{haQl#VdU zM+En&grI%loOY{GSj!}UMFW&Q7>+7durY2DM}`zKC83(~0)9Y1_n}G80M>%q#z5V{ z`cod=SMKsCMt3R!gU5QA83O+BFdo$`N%H}myJ z9)^P_B=ssy6p1J-02%LA)<w zWqM)Ma<_EhFadqZ2RKt+NXVP^|;#^$4rW?8mT;#8qT~t{*jt(Eb9Xj^7AzMS=tV_pUT67< zK7iLv;y(`S8caf4tu{#Q+<&Ybh5FQ97x2~gy>Q8A13uB6*ueZvK2~Peyk?aVDazz~ zRaaCXHUI{_8&mKPh%9WL<~tZN-xawzG(xbB*YG`g2cHFJ&Ye zZmaeSV~B}8c<)s;9dd0-R1(G`jCSs8(=@+@GRtO6U*7%R_AeiW?DB?n_F+QLh+KFqAm=(R1~jMfk_o-$j$=Ivc?!_N#wuPw{H*ZyanSO;G)p9)LKmLZqj6<&`?tC;JpsmR zsL?dIEttZwBe*yZj=uG|sd!6ExUy+(B%90wB@uuWii8?GgHaK}Hit)lKyy%9>{Gpw zeYnmlZCb@GbvaTQ3q#R+)M`;9$mi0j9Miusxu@U1+M`w5w@YA78u8a@Jn*JxnyO0$Fel4MX3Gl41)Qh%gzhm9XC9iQ^R0O=qO@ zJ-MbK+k%QiAlufNoy7E}NIfV4vOfo&)yVjOZ%HzHaa~M@Z@qIG;{vR4#w$4#k1fB9 zB*P7npO|~qs}6eb-j!cf=3keCxc)UIg7KbnR+-CNb6aoA)MA;8p8o)y8PC>?5;Ka? z4jTdDn#5;;N;zs$GCq{b5m_3&;xom%rk@3QnPN)6pix= zQaPXl0+&CfCI`JC7^VZk@99WLBvNDfQe&C`aT`xiX}ixLQW5ijX-Wce37|uX01Wj# zX?G?*T8zhzbDBYsNCz`yaMa!S>ItBlY1~f(iUvuZcpOvJjAtN~VbIiLf$vF73B1>k z^Cn00q-GiE+L#YHr(|FNIiNyyrsEx{$0Cp%5t=|I8h0RI99!7AKZp_6{S!}Ucz zbtyj2UH!*|^ovP$#?z3;yASDBH2(kz=@Y(6$&uIQtgfzX)Q)RN)voPYH&G)>JDx}4 z4QyU`$5$xP#}&Gxa7c^_>!I+Tn-YNpU}vdglUC;NO`Mj+l}7AlwoTZ%d@st0KxJ41Y)f|{F0EbB%$ zO&ulY#CzjqCB43x9iuSD^T|k|et_E&!QxgP&q5n&HR~&f`uoBz-_1 zO22B(Z)%>M4#)lzYrRrP66V6%D^+k&_ zT2^oX3_5lqk7~#5(sxK>>X%p2Jkv%a49DfpO>1Zu2_5Qya0waw>m8SkzzwIiDQ#QJ zl$G6(at&iR^D6`@%biH}J812$VN)ziARPg#f4hlx#TugeEpQq?i{iJ$S3sy<;Fh9iR-B9V#VKKp}JJE7Cky z1SxAF5k?L=;@^p!cmPVVqwyh{R?vn&g1C&ZbbaVVB;n zv&Diia(V$!#@2SpkPAq9lTp3Ok;Xab1$LfP`yuyn2x;&C3hZJ^>NkSJm@aa|0W=zDaIMUjgPk?CBt)=F=U z$!Ag@Z~)UgBI(;x(`+<-KkTMJWG+@eQL}aoIx24u`Uk`DYDFF0m#R< zr6ZDjk74X~$FM?Ky{fdaN-$Y=ik)>c9~}>_DUCe0MCZGWN0EVo0jSJNob4H@PDtSMnub9lzBj2SusNh>C^xBQ zJ8v-t*1$XxMLgRqC7GPNFvkL^Eb>MUGDoE~u4IvL!0>p*JB?N4jf*U$4(0o}=h~J# zl*#i60FDS1UkuE-EP#%8cc}OuDx92=iU>+iR9x8;$+_~%dkU1bx}imlfb2_E2384$ zCnwUCBbmG8_RmTRbz9JtopN#bP_iDqKouOD7BET6_Y@>vWJUIzdYVJ_a!TasG;p32 z2Bmw0D}2X3)e9#9h{*zx0Ae#hbGM@romKEp(ve+v5KkE9kfC`B#+#3>Y2wY$Zhn*m zpw^?~z4AavCG|=DWn_U5sumPsTw~lkPhs36poHt3=Hwkva0f&{cF>7x$Y&?;%OuRGIDFpk(YS{ zjlg6I?euXpx^gQyDhC3t4BC@9y>8}2@fs*?%FH(aYtr;MZQ8~%$lHpJ39mKRZNxgv zPM8kN2TrEFmrA#?g3<&t2araf^WPNOx!FQa=5@`YjO>VhHCED0br?0!-5AOrElBhv z*E*~Ot&W+j+B%EO+yhve;4N;%44hW1lc+&~&1LE`hlGRaRS;*DUL!2*HLLc5MOgOX}wGofMfk?mYwzLFb&7bl*z)(eyK zcdmC-l(F5lPd$ZZ(9DUWK2cJ6+r?Van0=3)ql^lxI?C#BJ5{|IF&hFtw4k*ys&hUk zjJ4>H@(Sbp{&mixq6G(_uFJ(yZBjtNu0}ZuaG`Q~mNjhVlvT#WGa+x`?Oh(66ez(t z`d2uUtI3k+KtIB3pwrxAgPP^2dRT3ZqSynqChjshq-F#Ifzp^;6^YtOnoNLdF!`r- zpb2x&6(pJRc&JfubK0y+{-6O(ZcO$$Tj*8p3rGnbl?;AJ`Bpp+t!*xWE~9W*Tr^9L zxXm{A!wq18d3v!>kvH@sV5b{e`YrJz$(j}9+(ur zYr2hACY84K8LQ?<*V-djTZ>GyolUI8&VFTeBBHX??3I9?Yb$g;N$vSnB39%Kj+_!H zk!kTc`M4hRoYN^yooaZ4!xqqOYlXX)(kPsd&lQP%u3BB)ESA;_0w-WOYK0ck2=doM zcc4$}NYmR$;3>!*u}RLul)Dozh*1=yK`|tDTAJI&7VttsXwP!_#%1|MQ&?ee&C{Me zX~iOrG4JhD?NGg|>`!;Dz5djfPPBkyfgF85TC9<)HtYaB0H}QBc`+PEk6crlSqLO9 z)g5{7OPR>ZPUW=<6!XWWCe?&u6 zVw{Y9XpTS*T;o21rf1GFatBQMR!ri>D-X5~iI8!D(v{uHoSK(+?pGKGu0=+81&QQT zo<&=&6FJ>pHZV6C$nGnVf-+=007tcU`or&yxWFLvt{G)Mf67YzJJlo9z&~`r+P?6Oh;*^`boj}fOtHSQ#E*wJDts} zPa+M>*{j0WY7d#c`Kp#TPGTJo;aUkKq?s|ls$PFSC%M=ZM)%#LpA+BlT_s(%W{mi$_=3kh#}?+%X%JmjBRttW?Uq$Qjj z{cA`;^)rxgh=A^IA53A(n0po=H3fQgK~m9v;(TkP!rA`kr%IkyzVD z_aa610<`3hVmX=5+TF__ALy*P^;*$~&X53O3tHA?J{doM8OIjMBnB`4(CPpv?7S;5DaqWu3I%R(Jpx# zILAy1>p-WBam6oWhwT}}pAX#UD!W+v)X-^qluQmr-*H`*M_doekev3bQAk|O!HyZD zKQPbXQ>0{$REpEWgVKs9jV0uxoiqI$xG{h-# zkC@D4W74BkE7Vr8g>k^B+6Ad`A2CBCG;mK9W#Ad8%slbdro*`w+|q=_Od>RFz@ou& zGMrO(kb2bNXemy?av)e7gHy*j%^*q&bfzN8O`4rZHJ^-B@ymlvF*IBegHA98>IFuU z=c%cLpw(zjq-N4TN{Q?uZmJ3Pt6RaNH0*-xpmfNy%JE1vxCd-jj%lRQ{ z;6OQCj@7i*>fJ>~Y}6c7O8o|`W)wm`WdKxrE#x~&DL+cpHfTpQEs`%mQ)v~Ufi|50 z$vqEjRbwT!n|!g3opD`DSjOY#%|hBWteh1b^{Q7EhcGpO56cN)dK22O+UjCJ2uu$3 ztTY=m00bOU*Gacey0{*d5{%hN#T9(EqbtZI(?RuokocXqC{Xm-kS7diK({=~Kfkhu4!%Q16A!-D4J z&^)ZYIsrtwqQUpr4{TQH(W5K0w;t6}e-2y9aKj_lG}I;39Fdl~?YNXF=zEb@;J>t# z$Ba+A7H_t%az@Awkb&r+tFoJVvA3RiJ}36~{^}BAIr_2AUk_nrK!X={B}`HH&7c z6K6EmP-&a7-jSaat~&_v15q1tdK#0=r1M9uE0tmsWbOQTr=_f_aAX*%RzcG=qE2`; z2vG@9$;~dxaDFLwiUdSay3+1!42qj@BAQl!A@iAY^3y#0pSnd@+m526ARg2K3r<0x zT!Ge}$PGqd28)GF{hgf@6NpreDprze@7R8tUx zBdDoEW3?z8awywC0CSvE_a9Cvpi`&;bCFA*T0ubufE;>L4m~I!`qN6__n-ib(+p~U zw7BcdDzAC~j6j{mI7EQ-6(%^QwsAnlGK>`f0D9GFB1Hq9MNZ(6#X@3p)_^EUv^n*v z%+Tj?P-{|4Lfxu_+H*4yy$5Pm3zf%`{A6aN7BIOu9chbWA~^lnKIHVR7-8A~J!l!8 z+AXVtl^oO`*tW{p+nU`m@$XD9lg=m+js1&jo<`qsQznyY1{Jb#SByD4^G;X-;(?Tx zNs9*zc%(WsWwOJMaaySn6(LhVT*ev{9=&}94WL_)Kv9a-C6|CHyU6Q68K2l_1_d?r z6_Ih!gTbwZly@}sxKY9BO;}o-%$^lSI0ck<0-=+^>$l{QfhVSGuonnNY7FuFAI6=@ zvBWonWK*5z6ojz_(9{$lzHYck^$kj^aV(+*d1gX!Lwbi38Y(=ip=fSKvftx6blz@`TVbnCTj zvpz?9Q)zH`d0zvuTJB77x#l%A*0zB4h)^ShneHG=srqD83#wlx2bP}1*L5Y8sTeT| ztlC|ZHd#3Kr*;P#`o;5b_UL`qnf;?AiVND32V>g16Qfy{$W!#Fj)81)KJf3iAQv2;O0^Z%oczdkpG;P?z8Qs%LzF#;6k_N2km)O^B+DgOg4%p*bg-MFBf}zSNkR(OKikK)jEpDk?Zm=A*Vk zAw=vNP=A#*7HLIY9Eh@&iR57W(;H5caWTn}-d5cpUa~0!enr=tI>BEoJ00F&^z+^{M<6Ump$`b z?3T&A?d#orD7l|AGS=P4J5D>*n5^a5yUREyjyl$q7R-oGKaX)!x?SBe#cmEq836J? z4ZrLt8j~?Z3?D2Ch_A!v;TtPV!1RR%pNd3t9QkkmA0uaV3aUiVYAm2%||LkaLxhr6z*txAB9#)eqGF? zrxn*+cxKY|LtK)(yOG!PuQ$+qNoi%1ERF!_wR4)#)I4_!l~}yNlfygU{#9JamYdk@ z?|eI@>DEkRyhJL!qZQ-&ppsoqavYe0VSmQ9Zv06t>IG|!!?(>nN^teIH_h8 zbn0ivZESGY7eyD)4z%+GG7MXzu<6pY&|1j&mJP!-*!X{EmaP;@obmvwjBaNca~w6c zk#Q*=U9^WC4%1iD!+L|aI(5^7-B5vErljK~$Uc=IJ;V0(tK~-O2bxFW{Z25;29qMO z7~H^v`qURT8tt-XMP$dLbgx9bm4Y!1&uYQGGLS>R1ab$`hO9nQh_$-7H*3CE$T%ZE z&brwdp2r=%Ym0(JO;NY*KRM}L>}zh?cqOn%>6()_ba|ejj`wc)IOG5-ymro90&sEC zwr?$?T}n`Zg)Q~PMJ#YdkPM9Mc*Z!O#!Z!lqbSK`G{3#ug^XZ~62pqMZr1A}nU%-~ zpf#~3v8Bfj$TayRe0}0L{&b0pIphL77sfrR%6|DauYXF8<-GX|5ELG8y{ZH=TRv5| z?nNL{vo>us`<;3{V(y2kin;tShw@kFrkkgh-^*EOK)mv;B@Fp<~?A1aP( z+w}cg?bbxkaX3<>Z37w22Te4ldDn*~lfsv6ZFD!tjgOVLC^f&V_}1$3#iEJCVfZ0W zIIPbTrkp1N)pnK6NjWCDpm{m}0QFFAl1jx5V%P2D$k`+e0&A3()Wa()1{mqZcO^y# za4MbloF_(XV74pg;y`5ihJ7(flBChCCF| zX7*}fW1O<>Ao}svu)Gzh>2@SZab&j)c>(zq=y!fDvRh*nwvA|?F9nowPl39_@44ZMEO+tNteORNA~|5U`{`WK}>Hw_Mtla_fvCpX$qNy7jI6IwL z$QeBbF6~;cPs0P5ekPl;u zaMUl{4BbieW;A<9ha);``a+->!y zuO{42T4QJi>QU)Mn zG;PO0OPq{%_M{=e{JklshR6U6bOMe+>qp-D&@l#bDcgu00ne=qjzuF3W|$5qk-!5T zsShN3Q+o+0nrnbD^KX4;+lICX*cU zXdfpdy*HuFF$>??j+|4tJPiG5G6QG}2^)#XA7= zM@~Ix0dh~)fOh`?_35M#aYhe8Ko0~OObi~mqyvlt%`Z8}dITokK9mooD9(8pr6VJX z003XgmpMQ`N@C`n$8&)|!(jENgSMNvbQFN{XcGy6U{4sWzX!Vu@~m*V#bg)Cg(HFO zTRs_Gm!a1f&q_;knp>T2w;t;^>@az*AkL^U<+BRywd<8j1{+U9(zw_)Sl~mObw<2axrQB^E^pM}d9I8ZMjPOlCeSEjPG1{Y`0;tD@kTG50AG@Bl9ITIMu6J5q zs*QCTfww(KuI?#I+L9O^IXSN&U2<4s3vXi#Y&tP)pUSJt;+=H?9(e%z0f9~Ib<>gP zI*Vc_mp zG-)J$YhiQg&2&=g`fa7Le>?7soGpC&rg)1|ia_(q^KrtnbgTM@i8U=k6A?aKNBCF# zYh=}qS-nZM{bmhIS(;mN%A2qO7|8Xi2_rcGgNmY^ef!m@*osG$UHiqNM+4B*k*IYn zNEqu?)v_v8bpz(b2R+H2K&kQ?uJRm!&7X2<%vML>U{q!WApEB}>zZN8=dksZ0fKTW zV|ewmGE72|lE| zh;DKZvEqVqNi>TdL11_tXwNtt(y_E}Mhf5_aB*If;xJ9Kk5FsP5R4Jr z6J7XCQ#@SPOB0?dCT8e^@~M?c6r%tYL&@u1i5?~H%=X-0CBFkrb(42|{cB1n?Bhb$ z3i3&wfv^QfJm~T%iX}t`xy?}OMmEsTTWOsC01@>x{{XVF;oPd@s5N#;&e4V(e|C|K zY@wXteGLRbM*5Yav{Fb?TfXXSuriXp>haW3W7!taJ<_6S5x!?{nEOy^K344#2;(u} z_o)~XI30aWOpz<&VdK`BEMeH7Z~*FRM+Il7LmHE@vG{X}nA$+@LWT?nT-3IaSzDn6 zor&x!wcLu5Ziu$i*!HHIHJp@o9VM`jX*qAkqb4(*pfU8Q*72W$coibZth;uM`qdfp zUD&SMf#xuP_2g1Kn`6Nk$g3?HM!VeZ`cw41GJShfFhHeK_?(UuP-y5T^kz(P8Jm-V zpIW*j7SR>P39nML_*tg#ZdfK$r+Qrn5OGcF=ltq;pFB30p1z&OIsX6}&6TmUGnNtCHJ(l?swv zkj=lY9h+4P6mCcqxXtPZM^bDMK8*BiAxdQf)a01+1oDM=N;-` z_OT(_fH3V@+a_fJTaQw3X{Hkz^4W9H4%El(B$bhKJD9TVQR+`YN0_Qc7!Z9bx0V(# zW@pEsrlJos5UUV~& zy%{Ucs@qO5DS_0IRMXWFoR2KA$3aeeS4c|;%JbfkI7u#IF?djw=N`GI{h(tZv!2A& zQ*K=Io_o}>#Ho$T&N@&i$-TyXuM&O3*Qx1Nqq~tZQBd*J)IVdI=`IzcJ>sJlVm?agVpW<|1w#4Az z4^GwE_*!WG#TX5e1#x~SiDPIPj&gb)D|5qlc?r`P>IG5PMe27~54t>$PL<5uP2|jT zTO#B-5xbLIwzoS(#Hr0E8=V~XExw>O1>IS?mE=BAC6CKo+`7R=CPENqvh@!Y>7GDF zxGv|ag+I=kjfKr}h5hhdOvtf@qLTrIM+U$)+NrTXDsqaC4PDV*i}P$0VRQR z$E8+*&T6&DVUO0LHyIon%xkFj}^NsfaCjm6G-WEX)`b~{xoi-U72sK6P{F;rl_ z)ufF?i4DADX8}8Xb5g~163#sNOP=Ho1x%7iYE80jLuy;G;~-XkiE;sMatY?H>bI66 z)q+Z- z;W->~DF`N{A2JLM0H))dR!5*P15aP4G`Q!Ul)Mk607#i)Gr$#NXn0uX09AB6b*aGJ z8Rmt#GT4_(J8m)0TI&)$IK)2F!^=LEymoolkHa-2-X!p)oLeKl(~5z@$F;wec*og9pM7^Wcn8+C zEj&A^&Q?gQ*^!4IE-JaMayrkkx#ABJY5J6AJ4o=L{H_-ntP2ei{{UCG31@7l9bMZ3 zop+~QSu-q=l`4HYS6kpGjLud5o$$i+A~oirZk@_RrKr@r1omoO zFUcP8{{Z#t)sa;cDvSYC^=E->U(ValKz(RE4`&-5B`1Y$U5NX1Dl^w+PvunQ@YT(x zPufMtek0mz(PD-ZF8ORj~$nvQ4tCtJ=hrr;Frj_)&rXUMzi9V5^ z@UL6jpI^?Nxg9h4)-HArs==OXrg%oeY)Pm!>SXeXmHz>8NE!*Kdo&a1^9Jf1$49r)Vm++TG7G-^a8a~ z*}5amx^_2;I-Xk}xN z;GE#oYRKTOz3mO33Lh@;Jd!Fdc*(C^vbcsw7i`h9W1XhHexAnTEy|J(RE`a9cx%Kj zqR0~Ur7`FD2JHS6leWX7SCdA2kUUcJT#c8+PYp_;B)w>4^p$qj{jR&FUZ`tpsGNH> zYMsv2B+K~7u5-jht+U~XPlIgDpH^)w(| zV~*yv(E^U7(bUp|%>iJeH0+9Lpe!gfy=pQ@=}q3iQUZM9jEb-3K6#)!9-@Jh?@$hD z%IbSnaM`El6bPKipme4ih3uxIpmm@J3A4`AQVBN?xq*{$k&%jPDK#k+1)vCgzH?65 zQjtlF(hHIKed;z!u}DQ03zc>p^raD+v5HVBSa&Ok&!sNPu}OhW!Eyr~AWv$s#T#== zlrBUE6rqUePbo-JfE=!BRceV=o(3wAi3z3?%`GJ{3Jp7TMouWsC<0B?78KBF4nG<| zDJQ6-G?a%l0Q?F{W_hK}10TfzVwsvyXaW3FNfc5JXaNlaIj3M!;7|Z5)PoeXAYqDO zT+{ngaZE#h3Q@%&G?a!+8kcrzAZg(HQxN=$Gfl-V-%12#8B2Gge-%m@oT%IYHDP2^ z*RQ2u+BaJY>_;N2$ulo()chZ%MDeS4seVNwqusVouhO75QfIH^YQ&b=gL-4l4+=cOTV1yb{g=-hp2%Euhi zxQkw9DSYa#8`hDS3Se0Cxuj`(=Bn>(^r4-NFtI3({~J0 z0C{%x6$yR$;-(ZR$7(|=vJ+9XY%+3xI=;YTfl-wPknT`&<2;&#O6oi2udjEZNJNj{XW$7Db4a}&!_i^)bsL?Ujzvq4kRi?P`g zE%c+kJZcVl)iy@XdkSXK2YN0mBS|#_yXF82clMSKDlyv?nxNCV(QvXff3yMT7^f}h zZnc?;LfGj~m|Upcj_DY1YEL|1o!nx%(>o3WU{g%4N8To%Fu4waoDrSFo|McScKquF zWswh4k55XJU6sMzRdI5gfZ%gWy!Nbx)R}sW)QhQ>=lFdoTscip#P#b&+>V*53#cYI z#(ip4ybL%r)3|b$e6gNIBP!#8QHzCP*P4FpjPXFMQN0QwZa%zMmUyN1+IHmUiK%ig4Bj~^DVE9HX+5D@W?s>SMh}+O!HJdX4Na!oq^b5#R(Mt8tO7aa0Le%vO zgjiP$aq|;^1$uU!;SEj*#{2k_-41`HQfFQoH;$(D=ZNC8z$iZxS(A9ssXHNDdel>R zNn8^ysucQ?4RX51kTm8dEkSM<*i%x}>T1VfABn!%2@NQZBeK^4;;YL`d$*PpX=cDX znBzXx3>uqTh6X{LbRCUzI<5BmrDtv2^v^X+!lTfR=U=*&@gzC@#x`yDrbnk*Oi5?jPu8pLWn#>dGLGUigFwE9IY#K4ZaNjk zRBks;Owo@+vfKyTk}!G_Tl!SL*?MefSNlySEy!OcPv&^6=hV@Z0Iay_j8%5kq6>yu zNgX;>>NQG9?mF{Hibo(_CIye`LcS7 z>vRbMK!kK8n&oZbmRANaPvM&Dw7V;ap;neRRqR+|wt=M$?rc5uj7R_CpTSdURsMw=7?8-6CN?I)R82(-)9=wzNDbi`yE)MNVAbotMHHxxM>N2Er_)@r?z$KV~cmkc-gKJ}A9WzMUS+zc% zkdspwbYxC0<(E8UL^%Cx4Q=jU1w;N6CY^R)1}T6&4$>%hAz2#&(@9g7mV9>`0RFWT zrjD$9w76#VC2?8O>6d6u_-4mrjw-9$G-D@rM@pA*=x7LHNlQY;FLHUUNIXR(YLKyvh4ft)`#a6Q-13w6SYraPA@D}8EFwjSs3SRkD+d1nRi8o37iG7v zA1iLfCQ;M)-pj);2HSf`QcQf(bCP{4$L`Y3-sVW+W@KKKHlyM(eQ~%FdE|7bS!u&l zVV423(>SSa!ju$@zmfSsK%@kzAJVVtT3gtX;nc4}1yl$M=XNQknm8v17HDbmNIvQL zM{3-SnZPDP`PL4d883w=>FZq-agh-DaD5FkvXgEggE`&Ok<~yuMh~@27bD)7=u~GE z8l29tm6rz?6@N!__Hck=sp~2k^Nt28_LA9+aD^lgPSrC^q+xj!fT?j8JF$__8ppnbfLnPP^{uIy)brEQvagu9JRUu$6^?L>PDiC{ z+N92-$^qZfvm}i}oM*3EyQf^u1kL4;%$u>YEpEUC!zmrbY1&=g+eAL|`ew1r z*VhcWX&h&u^sQKL4ZK6`5WWEFX<0qT3AD>cTDp+oZ8Cj!{{Z#rW4P31Cu|t@Dl01E zUxqguVUft{L8MO`5lM zma{1Sq#mNL+Ft5VVPbW_=vi}8(oaM*QHssJy}Ob3DBF&lP_AFKi|S@y>5PD=B<8eqTft&*(Q-#QHAKsCBZD-I z%js89V|d2Za7RK-GoEuy(bR6^x{Qx0Q0E|nSpNV~#Y-qS#&PwiM;PZdaoEx?LBJgG zP8@^upfcl=NDAjCBzg*>fGOB12*Bo-cg%JI2W-&9j1njTGIsJgrskcT^rRq;qL>N> zdC%cVgWMVyx2;M?Ly^*f5mDBcy##Q1qyV5Fym%dHz$Wj!arCH%IRKn@qa!%U_B6nG z;QG^#-N6GNN=0Bnr0Q@w&;fut9MUxfvEG5npkbN=W43Ae01i4+4|7NZcR3(Z1}EBq z(t$t@BO|Q}GsY=1o+(@9?q~q%#VW2_turOL%__N5$e;;^#8O!2+K{?17+OYPChLK1V%h;B!V7JPaSLE=NK$KnfX0J?R+t$K^;s zJ+bXdJA2a*fS-THg4v}g3H#rL1whGC4FdtiJ$AYuT8}3j&`IoZKnmCc98w@V!4%WG zBaw=gMjPAGffBl?QcJFWwXxxbR=OZ^M-_!Q486r__*zjN*CPiwqp8g;&c9n<_?Ni~ z3CBV>uQ)9sV!UsC@U7;Fair!SPP{;5el%}vRSPP#vY`jAgH=TfkM;~+a^ALWXp7sI_uV$8QT zimFK5N#uHpT`|>me2UG-AXjH=ItYO*RFRAt8qn^hqhrsmd<`YEgv)yo=lCO}hr&xX zA{QVG`ewR)P4`N}JZ7s~NCcyfJ!_fnbn?Zami_{_iZyq-CytAX)Q`a$e3s;|+8vK^ zAr*cZ(U4@oq=HX1l+LnuUb= zl3UtJB=Y|N)@>sjy5hJ(!HL>Frjya0RwXOkmvX452>cb7;;HD6)1&RU?y6G zawxa3!!E`hG3!=_qZ}#%#;o4rsm%#QIRttGP$;#-Oi(jO z5P`_Y6#QUNPNeEaGm1R*QbS`Mss&xn0rjOZx17j`TOH{a6yC(oa2ySrusse1MkbM0 zJ9$2}C)u4rl0_h6fs6`#5G=r%B@w9YNYXJ*R&K_hhUQUzp^gFQ2Ws^jXAKA-=Dc#^ z7~|XINc)HJDaBNKR>5HMGmhp%T-E4%M|67_Ok`-smFjzz^(276k=r!MCWanonkbjm z+zRpyKT*}vJ+|#Tu5t3N>aVD+%&r>tGD$p%2Q|vDuJ&y7KD{1Wq|W=qn&y_Vykh>| zNio7B?k2qCGj`zSmOEJEP(q^p1q~vp$?IK|sVZlYj>UUxD_9wTIcb}x3OJ`BkRd8^ zDqCr+*DoUPBe693wHPNDjvas;X0|wI$z@`m9Fj@n(vrxm?tr`$^rHo8^J#PneqrEd)Qf>}ci8t5-@ zQiG;gTdTz!{@kCJKG>;+yE2A$XLiVKj&ChUouKBzRuk8UI7{)kI;9{#c!>x4WtJtrwl%MHJ z%-VQn-OXm1yaq9p!ce6YjA`G2XQ{VD{k_}dmD)%o=DZ#`?Q!HNgb`MywM2h`LyJ{-EaMz~$~5=eJDD9bZdE13d=OBTBNvhnZG~J|PUg;Nh2V~F`kc@!CoK{eV2*7Drlk~3V zT=A8y#1b{MX!j1ARod8$ekA_@O7pGz$QdL7#ziKqa@L$J?Of<2_8p?Z14$Q_EW`=bCU{spE^xaux?c>z=e4!ke18 zFPfP`z!e_7Gg3*ZZEPyWqi;~WlUdTP)+>{Y_o5OOP+3)nqY4b&Nn4iXhPzUwoRWQo zGwldE0)48>%o#$*03dbwX^E#?NC}Zbj=1STr?GsuxYWLAm5SsZ_@p;YE;mTWpW-Cc zLO97Ppp_oI>B|;zwBUnC&zf5@c-S!%*`!c@P}_%5NhC9c0u{;6Qffh9(W6OmG<&hY z-OUF6%iXz4?Gkc1#&{GYrFmn?r)(tWwMdAlc>w)rFxKNu%klDXJK~x4h9e@an}4*B zfy7{UJ%udRup|LeK+T?bqQ=sVmD4GGrcwyWKGoj%EraRo%yL5!isAf)VyqbS9eY=C z;Kki+@u|pOezj2@3%Tkqi~P*-n_GG=S>KmH$sr)zL$j(jom~qi$6%uH^7eYMy&n$X0;84|#Inn3eYS)+o z+Qr%J%%>Ewje2LoYBz3wx}@{@SELPct->DEe2QAZl~z!ef@#kP5k zzlL?mV_7cen+Kdcho{oIzYC&RDUFEQKJh&>TC;eAL_>?2W+SE+GDSY$#l9D@$%fM9 zoc9p_0F4nQa#youKNC+J_Bf2?h~omh;!6mFa#SASNv`Kw@infa8H(1@M9J$R!Tl?b zx=qYv$N+VvCUaDlx)DbOq-~!o^sQYzWAn10fJZ}F35=3S=eVtV78`*Xu4;#V7FS0? zTy0b6DFbfik#JCP`O=ES^pnsJN;8hMp?7zs5t6wCecMIp`uzDVqdhbcIwzJGI1p}@HV$Xc`k}H6_Lvl@Z zx;Cw4sUTS-Oyi(x>!)UqBDJp3=aV=|xIm>_BpUC0FR4v&3ZpA+0~sGmwST8*Z8E%; zLPiIvY-Y8sZuI*LF|A1dlIm*$0Xvp=T#?SqW%33LbdUHyFxUjjyjej^r@~jAGLr> zl6z#=ok4OVy$WK+LB=blfuxot@}YKq%A+LLHGF+4OWtQ=t!>TCJ%h~IJm$Ix*W?wC zrRZ9#NFCvdBqOUnPvix5HkLvNlsOFD&MTG`>S7(KtvkJrif!9dH4`I_euAZ2W;h{F zM|(1Pper_}5h(k>^&`o>>g@l2x;u_p8_p zrHC07UidtB?pyJ#Eh^qC=>jn;pHojov4trn-!Y#$FP2|ooDWK6v9fqM&*z>&*xGi5a5x7BO@NQ3Q4t? zzBcEBQhB~%%x#Q%(0CPAqqPLgC3jonWF+@LO2!Bq3P{hhL?EJ#-Ia%Tk&cN27A{t zc4tgg(X6EI2Q@m3fmx|~g>pgq)a!Meb*Z@Q%c4B<#W*Oc;^1em6(F5yfi5_rm?uu= zk3Kx)9w=-H06&EoG{JDaDn)f8trs1J;L?xQoN#&?IvM~<1qbU(k&0xoMI%#5raZec zO&}eS-j{OLZ2Ghi{qiyES+e-5#uI|W*n>dMjFsb7^Q{wTBl8_ynC)%_~&gW)@usNwi9)#B`7mIY~U<{#0x$9am z_=3hjHq5`BRf6W=G`Xz!^%!LPt(vm4t78;^n>2N%j(gN{5;__Hkcw&J=~SeaLBOaU zcK~O1;Yqs`ja}lGdXv_<>24>%+nTCxF0;!K$E{`UOHjGh?^Dpy@J9x@2GnPdyBr>B z88wTQU^2rawI10I*)z5IeMKPyKJ~@_0BqbZEbY>T@dVvV{&ag}9?6}SImIqO?_6j6 zBsTzqyCR?e00|VJWr~lW%~!NcJ)1i18jnH3-jAFdsH6H zoqrwp`qG9K$iAU?hr`#BS^`cw9ai;D$CC-B8g+K#YJ5kVfis)Tl}B98w6oknL*?+W2( z)OC>CKz8HYip_0HT8M^mxc>kV0MofArTKuKqZFlp9YuM}I=-;1qEJfvb*(tHJJ3%J z>Pe+>qqGvQb4p}iTIEwwxnc7jy)oLK_SwsK_n>D{=89dw)(kp>a37PN)ujZ&PWbxL z0_7Beln$bhy#PLx3W!KOzdCoCGfYIdrKm)}oCDI7N(XuXl8jSCi=MRaF?y5D10C3U z(q@h06vD&56bNx(DDw~uD&&g@&E zCydb6qZq|;w%Wz~V+6K3;MTkv{{YB0?&;2ZRC1y7Gh^(h98^XpQa}e40M_Hc=yT~# zO={ix_0Kq|Xm=dQon>oU;|rJkz)|YydOXmjbhe?h2{z-lSXZ zFetdJTr8s;P-I%qd!lpeP)R)CWMBi+6aq%1j5_2~cMKeg!j|%MT#$J5HC6Rnz3Pgc zdFFtz)9(cIz^8^&(z#Qp-wsNU2c2qW0j3xSi#`d6JDLsN|4%-F{qkw`V|Ml6Pziuw~y!aWpR05M1|Mtau+2Z^r; z+F0!e891#Nb&oR}o0^u2M_Klao((uKKgC?^daP&xBXK_UGHXz=&M}HZHdxb0$f^sg zK;xHDQ^$D&0sGOPN-Q#8DD^!lL}1in<{t74pL&o_76IPBolA=sF!hKIql#lF8~`ca zbYvVhN3}%LNB!|dnE8enn3L&A<$8*cTqZh-LntFTADuo?^9=HP;-hHDJu1pMVZ}I% z=8jOgL@R%Gk)v$%KZRWpahg#FzD*{Fb2P?5=}!oKD@a=p{{USE9Ao97CN5(vk5%ba znM;2TIjyIIJ!&_#8Q^A^?u>$`6oi~(rD;8|8L0lwIpd`!JEDgp9GZA`2ZL74zqb^_ zZH)0qG$UEvdy|TkYD_!R1Oy*yf$h#u6z-Rh*qdS@I8^PPI+Np+H=InHxkz03`? zjk|xXa5~cBQ^S36T2uIpYOM@+JI_u%sp%1KZ^n@$V@@bQ=Q#Z|%tAJwzo}|)y0kNjYWVKcbFnSzQ=4MNb4a1z0IL#%C6-UP>x3vY%qlRALJL;DX!!k(6>x!pwdm&GnJP%ydoNYd}R^&I9arshJ8PO=2Qr+9e%+qhl z90A_B`|H?dxCR8;-mGZVRg8|$lh|PJD%QF1uBfk}55pK!> z3_$Bu45I*Kk@-`Rl&)1ug~tl9iG z*9T2GbJ51nDkHUkYRZQn3wU!Bv4S8X2b%p8U%ou{>S&G8@1wh`t=fA3^+ zK9uflL9S8=^eeCJ1+_bOv+WpeI`=izx5I7mZ2;=b;(Rf3{H~O`bNo{HjAbsX+WY-<7 zYBOJSgb~zXxix>o-aem1xBDK~RUHSJ)AFIPJ8f6Nx}KR4nrSWZ*J8=Z{VJZ1p+M8tP0*r7X)$D?Zh01wu}#ie~(+%^sr z=bG`Wi%s=MkjPA9IeW3YZ`nFASH|a86eWNeGKX?igxSofsSok+i z`yT0aGEO;ET#;C}`dn5sfeg&)k%ClY*C(d)q9c-yEn9J z3(IH(l3PeY9N~GzXX|$p%nV7VPMqU$Ltf3G>IE!f1{llZB(jXwCy6x~WS_1v=qN+> zNb(r8o0(Zh*`&$rRMq&rE33#0uAe3cpd&w}ciLs+3)uc+)OW8!Tjpyf+Hf}DQzcPH zglS$JxW2ns0tm{VoXA4s+nVV$9|qfL)(>*maJf}KAUP(l+<P`<{G0@O$$r1}60!@0^7qH-U;Qs)HRo65n@bWL2I!U7E;gt%g;?@WPSoOZDWm4&)`0-xmm@sVF(86Z z9q7m>BauJ{9C1Mcf>`z#rQ;L~T#knnWqmlNKRkm%o`QfJc<1$|{uL`Q!2_SAL>y;< z`cNTpp2t4onhEr$2XmYpXV#6R_Y{UEawyLf;f{Wk-MoD$0LFXKfGIYd)PRBrBPZ5? zBf|dxdj^fzq-6k(lyQz|5Tl=^Eg|47I0nJniU0>RGLSmbbKG-E4@}Sk0h|m{k;y%& zK?GyHGbM64>p%`X4Cm`Yl_Q=_HzfC^A#ga!pkjgx9xy#AN$20vg&k=!3Fd$opyH64 zQU(P#Jdv6Ja1`8R`_tFl(@7mg0012S06H>hLFXK1fIVmdH*re8l{pCqf%;H-iedu1 zQ%I%U2;-4T6c9#maX`e|#xu{-lSXe^FR-0Wl{=($6Qt44MXPYKSTKn zjok!k^5-L(O$J#b)ds*aTc4#ar!==ajb`rJ+f9(j8bTEOp!Kc{%nn(UC~iQ`abAgh zfa%ScVq#Z<%bZu7UU|}8GL#CVph1CEBc7(lm9zrk07(Mz*F7r2+Cv0o=8;&hPn)e^ zFP^L;4#)}YYGABCjho+^n-HoySnKS3S>gR6)-*ailUxjzeZ-9ZHBRf|GkK2o_5l!_ z>^%qTS8RS9-Q8Ox^6Hi`M(P*?A#9JznKyxfV;WyVFz8Eh zTg8~pEuLp7XPbKgyz{`Rb`SvQ53O{5A@Ho4Rl-jZ%w%Bi~HP=PA$=b)tbJo@l$ z*p4Sy$s?Mwx}l5ipvmjSR#;ikzm`!)r9wtu9jH9{IYHR5b8#ihDPnLbh*UTPXC0}# zez+9Uq)WaQ9Ni+Z8#;x-1Hx|EQ<y^q_HzeMU`rHO~(3j?12u(6it-L7H*$?c~ccvHn$gFD+I)yxilW zj+7M$CjH`zJgP@HG_p$|PnhJM^vjJx24S$|XQ>qf+$5Zg%|PZOWff zTKZHzPOSuNi=H?<_pYY%z3Dp(*fX`ZNSaD_u`x>B_FtImVoh}8#K~u z3mjXpQ>f{j))lRsHl=60o;`yHX>XYNis<}zb>wPsssJ($c;>kU-E$^eAa7#*^6nr1R>j}iv?S@J%WR!IE6m>h%Ng<|2A z0QpZ`b4_T0T)Um!xXlJmE_(^)C_5dF)7G@@ZuGlbavlK0^dNIsuNXzi$;qTdUf_N- zB2?uK3wnjrH!|WBWKoW_PXiS8*m1W59+ZJWZ99>T%6n{>>#-<+xQ- z{4|ZBOPV*iMBcUz2M6AoZlslzZrVMm(p!a{(N0%9Fcg9vj0hP3^~EzTX=mNbpIG`-3qd9rY6rdb)n0Lwr$zw?t;BY=F^ zW06is{(ev6K^9~|BtXQ-0Pd%n)zS5vttC~gcCj5df<-|Mv~o(TF6Ir`9<|l!z6{iF zAST}4+7v%^rI(-5sVC6uj1|4z#7`f1i5KO2Fn{ZbKl?RBFT^hswpAvzL+Y^q0Ew&8 z{5{npOugNo9N`Ji@~ofuM()kukX|5jjOY9+z2fguC0TrJ;+AopS%VYNZPWZJLE^s> zx`Q^QD+Aa@i~TEJF9b;nf^VYp4<~eGs>$$#yI0KAP?69q7$44yNY~!n&5y*_r2@-! zak%<6Kb2!&YZ{D_W*tiGVDd}my0hUVV~H=Fy$VN+Rl5%Z>2ekq7dJ8i>4l}sF6Dd7 z^Leke2}u&_7i@9R%xb^dZUEZ1Gw$wu(_XnhfP6jW7ZJ`|9pp8_>z*84K6dh>VIOSv z6g1aTYDRqyX_e#!ifSwo$c`=nPw|q#mr1 zlZsjHrUd<>;%u+*oUSXhu-E0hv@IpML5$!=NA#{=T)FdZjF3mTuT(3+r^;*ZCAps* zzG9t;BYG01n$ogJBM9urvW%Ma4IfCPlwA1HxRA|`_!&g@s{16N)ak7RusIojgKKg z0*J=U;*-17$kO~1tIkK-WLOgeKQ`n1>#4TzPKy!`w27_=>RwZi%C+rpAe#jzSpoj* zW{c}ax`@V)jl+&{Rvf71waXt3>DKS$!4gUb0VFy8b;8SV%7jIi9f4v2{HvzbJQ=9P zBTME+$ay0*&AFBvmQGdIt~wg?aaY{qsXj+`MGgJzQtw+!QsdQF{{UL(^v!Qv9$fxi zoN9W55$XBXU9HE?&PozGErQEmntiX&er>+qX2(O_HxW^DtL7o zv)9b_u-MvFDW>GF)Y%{tnp&f6tJ+;0MCUz#8x+J2j zHT|lb8PFe1!mHeC7O=)xKJQ`Pl}v6Pn!Kij=M}pn*C+C9usX58uOHQ*5=`080=nII z#Fw|ywX9a_7$^5_yc3UFE)1mX2?8Q{7qeoPXYf`rQ zfSB?VzH6&*7FspCMvs{>jkwM$Ea}mv0-yua6pdvN2jvC5YpV~AjWN>puXbTy$}VmU zfOFs8t8UzckaqULt>a}F&O-eNs11@5LZDE4S9CK3*`mWuv!0S8g4vN&@xu|CuA8F- z$Gaf)B$6wkxUt=UGqfDw)k$>b>IN&&r;CeQgP~PBq*YBtqfo6YG3$T@T7rE-?CiD$ zv(7g3suEf3%Mee#DImR`*+`B?TyQ`*u9($NV@TJkotrv1wCnQ_H!l=t(VS=UsHU`u zScbUX*yz1074GM9ujjDe9HEbydTagw;I zHrJaD!-5Y?nzYww;N*;s!kz9*ZbSu!3gaU_wC%zZIMls5TIOm#l*Mn$OImfM27ki`y z&)qy=Qw6!&=}hmpENgWED)0ZBu_{~?7$J*TLe3&7CdV`Zw$s)Ot>WRGZ>FrKZNaL^8 zyk>tA>(^iFZ)8Av1miU(pW=N+8N_o>BlC>2bgTAlD~p;ZvaUvQI??<hGO-m7aB17P6agokLF>glPw!Q;&O6hKi7Fej7ESXNVx z!n2FSpzoCv9<7S0F1e?`*f&bVbqVuTD~X%GFM6$a5Rx*ZzolWnitHo%j?R6BAn|>h z5CS_Nr%HArhzZqy4Twolmlm{h}zz4i^9)%CU6_u2`Qb9le0A zpZkAD3<}&v$JIzVq#XScEF?uf_0Wut20a$`LN>(g*cdxVty?`SQMDnqxH##KE3c2l zT3*m2D(p@MYUDb^GYq6^G1Ov{l3R@#I#jpg0it2gIUTF7v@?_&mlc{X;RhobJ&jJf zylH{XYd&;WD>jpMDf>?#^H~F2K)DH#>S_smQxqfSkDp^rNe3%8JhACWVp4inGbfL9 z*w`eSm(IF_4 z0*+ZOfy_VqIw8nzN2NQ+iauMB=}b$NkYq3(xis_T5to%tJ?dN;N=SbA@y8U$mLwT5 zhNy^(al?Q;%{87O!6CEnOO>sM%!uCU7;=gfds2P1R1K)PJ{mOUl+GLrOhG zut>?{rYakqLSVn@diNuxNF|6wN@E2ux7sb+J89j=Px}8weZxK$yT=o@C=frx9Wry9{)DhmY+r$wZ51)?9-l)r}h7QUJ zB=M7zS;b8fxSwcDLjnSDzlv9E`_oW@}rb4cd~ex?f_1HxT#Nx zjCjPL`d0)*!E#Z(F;YU4;P7$=cKXt=?stpgXM7PZKN@p*q{cvzvMYvou314%*gu9U zyG1bU+3!L@ba&0;ctZd%-$744AhfzrWk8_!HNeAdbB)3yfO^y9YlUE>Cft0-JqrPASpE`+!C*pL%u?+`*>l#Ns7JBa_~* zrGU;t0qzBI7B-hKmY2+I_8aS7E6d1$21C=*vz!!_ij3Mf#j#LuDFkGExHVEOR^X>9 zy*ibvDXT6N7}s$)KGmPGMvkjCmrb`qaD$&}k!@lfs!jQ&EGn4p$leIR7^oT`4;iaj z7^X4LL5c)a@_^6E4MgArouHBJS2(5=2Bo$%icf;1Z5XP~2G5!?gWOh=M6BEnDi^R; zIR&%no+)!kdK~@4@JEo*5=XUBZBopzPa}@JoL5OMlqCQ$#t)@ce-EI1fTS8O!p2wH ztz<$(1br%4O_LqOmE)nS-`FfTOei$bqfH(%Ljmncy$gyJVT6o=aqUjo8NuJ$o-HL9 z0Z$!xrZv2skdx_Ib299RTHRUx`8lYb$P@Ru^{3Abz|Il5>48~O!KjDKdxm=CR*}?F zvJ0&#pCoQRgmB{BG&hnUnP&eD&lG?T!1$HYoYrz z1%W7}j+vx;SRF_1*B+RuX%wW)f3)O%?B~*+vW{@W@in0OU9$`Y#%dqzD7Ss~$EM>` zVy;8Kp{3vIarCQ0O=L_1nuu6QjB~d=#Q;Vm12{SQ(yQR~$v&o^_9NdvK|zaW){wxy zMhYoDrlSOI`-AeQ=i{0Eif2?fx!qX(YzC~jct}rqH?_QTC znFFc)*!tqB&!R;l0p*fMOx39oW6tB&bu|NY&$M?Z2ABJ0`+{YBdm8K~@VrmbB0m#V z&x4VMce0;uY4agjoa{QLpyU$mkU8eIEcF@AH}7J74QWH*#T{j0dseNlharVPEKWUX zHioWNwZD7-V_}ZwwIZL)9Mq|&MuP)69nC-Nfqkk=Ok(<)cwvfPBi58g1xpKw<{Czj zdein`ReOvol1?xv1Ua2HlFkKY-D{Rsxe`s!qVi30o+R-PkQylDbBRVzBCFW35%lJq%${f@^Ndz9N1t8l zZCK7(#~fDaZZEbFD)m9sMWIm{czm;bs+2~=Kpryp9W za&Z|wtDqhq)m}2Gr(7TRkdNjo8&t5nvm0)0q>I^xDtTGEYR3tyF)ZE1V@IDiIqBOq zx2eG-lVL~;Sq*B|@0L90InFD1Ee<-dySZl@h$IS?6^HN=r@kr3U_c8U<~HE zZ8J*o6zGP^)>zo}D-dcqQMEZFv^&jj$J0${$z`RGf4pNAB-;mHmmi=N#ok(7T3pK=$YqqAklyuiNgCZTg-*^QT#>;htGI6X_Qgs# zz$6kW8<2Rb5gN_6_<0p-$6C0yoH9PZ4;#7P0=RQCj)XK2G3EMpZ*|PrvwWIT9pO(BQU!3GP#Ws~ms&>l?_9H{K^q z1HhzJxmllcq9hR(jf*#;jMOmNUB*EWusQCgwP(3f;RCoGuqXj{0<9~0;Ypy;$c{U0 zMnuQhnDf*rAI_Y*Mf*1q2>Ij}0no!trY4BWMBdAdexgr0x*jC%smVZzv3@>*-S#JRv#vrcARc{{XY?+KZELbQ0v_1ostI zNLn0`xO>&OO2m3*h;bWWl0o&UwkbP+0)V-2 zFf;X`p}LY}gd-o2w*!m{WXqHQ5_#%sV7o!}Bhr{+Vw_M*ZKA72O6~yhT3St;-AV*~ zGlNtBBOv~@cTT*P)?iWgp*+(HZqm8ZP2uZgwheJP2h+83X`{y`uF=6EBdH_nTX&kk zo&pd#Be|?NR#v(aL|94>P-)!l=Sb~sd_ASZW4`i7^G|i{TsMf}(^FN9SZ*o@&QC&k zt-0p7OI8jt*yNV}m4UGggt~4$vqi#liq$iq&~$rgRx>foY(8KOU)J=`3tHPc2`(B} z8%D$!2iCAHF3d^ts04e|H*!gE`E~ho)82&aPqa+Cp=mKR5z6x@P(J9b4OMKQw|M-q zAtM{O6_05Yks)*+DLnIvNlA7a!#K}CdQgh?ip6az$~C(E>nU385<3`eSYZxVjIVm; zfRKPK>&Ba|4WE^q@+%rcR_Ic?pG10rai!3_Njxl|XaJ?^I;dJg|2^;Z=&PK$LdR za0#GZ($4JknLJkxoetf^oO8uu+>%XE_E2~$UPgH!to8xn9{P^>Wy_KK4nlqu2L%&OoE_~&aDW7D9OMbu~l=L zRZCWve`R%$C?n8{=+nf;NP*xt=q&_ zPb*^%3aw&~73wqRh{5fJ#afm%l|mUnQT^^sQF|0g!-JJQ4k$ME@2VBNPp!hI$#vVF zKwtj7Q=eJA)C!x1B#-YBYpK!nyIYx6WRGw>5t`rDd@W|So1%qR1F+;(C2^|yo_zpt zG7ko%!NBF1=>2~no&Vz?0-5;iUcVc$)p24cpk=(=dq__jP|54 zF_VE#Ia*^54{xO?90UC50mS^Knn?Ah7Qm#)3y{4i0fYi`(vuwHwLI=`;o_4R?mmg)kh$@b;lV??}VY z{&Z&`3P3J4f=)A@DBZ;&7{@uMY-U1KQ?Oi4ah&v|$p@uR5+DQ2J5PL4%CV{W31CO3 zN(FKSImp{i6pVI`l!2Ik%O?7fK<##o0xo~zolE#8ZYf7QVA>XO)XAI%I`z5o<%l2GxD0^CY~?0 zGKBB*2ICdzGsLFHa*UF^3iAy@Sq`B$INDEYbBWJVrIDg8V96prl^B^GOzi{OvOMWC z_s%K8cLWi)k~uxAK2rr#Q@_)$ZeHD1C|QOvkT|W|UFrdK!R`%ndMA$UG|Lo%;?d=i zd#K>m9aG{Vy16pj*t|=O43SlB4?>+&q}79mC-`e37Y!&K^IXLKGoEwIP6_qtO^;o> zm3~rydk$+EQ2HBDW$&+A;0xUJ||}zm7zW zl0%>3&mV}bcsyfwZx}?=?WT}t=aiB^D%LBbGM!6mdKbhkXG6Hr3R>L6_Z!tgKuE@U zuP%pD*h%uYHh3iBlK%iw)OCp#OQela56K*9wN|Pa*bbb~&o32Gxm_9;8jROTg&+?_ z9V(76!ky+FgXI8$*iv-`x#Fbal$@TU*CbSB&PX)7hB!Rb5q@;M}SCWB~Q411|v_ePxNq*!jQ0pBjg6o%s@h;V+L>BH?$ z!h!+o#RE|Tr@}`vu|4u>%VBB;RoI^3nppJfi3iT*2XjtsGs?m98MEA)2Wt|=9i(6u zO!L>$gEg`<0-=CBP`X4;!CG#6^VXhph!I(d-GS3I8o=p%J072K1K~*>0QIRnOk;-J zGO6oat-8-=yXN(HO}=sAZ|!JQQ`}m zdsH91%aiL|!M41Nf%dmjdf*CuuAJ>Dc?{0OkW6PEoeC|3sFEC-qGUGA`(nL6!CJMn zmP)abxW)&luR3VaV*z3r?lDfcoS+*S<15gq!KZr}CueqhrS-&dSu;w0Mit~5o~;$n zi4DdeGv<08=b=9P6u~Ef$*ULZ zx-v1IDvyWU8yNB3M-{HX9<@he*yG!JO8)@6Kb2Y2b?rv$t&KpDkffaY3Tl|%=ng^-xTvjJWhi7plxhzF)lXfu+#xdAvNeiY?6>-kff7mup^-iD*xNEuKK22EIzrB)YbGlZw*`)vz{Mg`DtTyN(B(6>5L_a7dZo_Xa>rbH#algx|t<)1MZCCq1UAH zZQZ1RGKDAS71SG;p^StGrySr{3F15BJjN+@v{>L$VwT4veQ^Z*mDqF95DLv{$Q(N= zk80YyOF1JO8Z>b0Q`!`Wx>L+ z!0Vp1X2R-AOO=*BNZ{nqwXidBb0-YW`D3rM%szBZ}ERF1fn3 z@}h-LV#B3!cd^YC;kuBhkiO!+m1gxDRhC>yOcVPcPY! z3w)EoD2BS&udXJAS|wqgxg3gTLV6k6DbF41^m?3IxtIZ1x}Aj9Zo`}o-t~m{GsHk; zVVw4-&tsvUg1W7kUEXV8dr)=DG5zEC*Pg|5EUmL~Q=ThQ*4pCcMPIzfrYQEWVkC8~ ztiVPRIT)V7b5PH&&kea{h=u5-ffcRc%`@!iUVH+21KOM7r$eW_Nb!Ps7{y)NM?9)N z$DV4M#MiQwcKLeZvmjO6L5&W3mC2=+=PoxQkOn$Z$8d;p5ElL%j`ft8%{jJgTHIaR zMt;vM=oEhm;0oB&{BNvUFcL_!pd%sj5A(%j+e<5;%P-IENcK+B_A^da zz0RWR$NH7TMkce1W`6K)qPd%k<2=SfFiHEOqw;!jjHEBv> ztnGt^$Fc8It?Z8Qg)bna4&4}b_f`UiO?^fXfBn-Pl z4{X+4GP0tOf~>6jf#(Lixx=BsI#ZL-=%Uu|VFwoqeVISPn);>W-DfNQ=129cNTe-~ zTDuTt#szZ9nu(OLIE1-**>~-iNB&+P@)c&<=Hb&1JHAgw0~q|OpoIBgsRZW)W~_-k zurL9~7zVMGhf1w(Z+c8~#yr5-$sH*&U2;dwo|P{Ajuhng%>)$#J$-9Co`xDPn&_({ zlhhBws=8!x)~~;DRoQtywWMTw)VdU&FHupL!5ulPY!2>wR4%#6uF5laJK~DQK2IGg zH&2rUROIndn)K;QL!lY-TPcjy8FciJo-vMww%IeCk6I5{0SuF7@!w>YX{+#S(a124*@bLwi$Hc_Zo znnGVZjPY6GJ%on&PimD~MnypEGuH;XQzo2=u4F`Dv6eod(;;HO`yLHfa@ZL>jwo3l zfu09yE^*a<`EF_D*g=u8=nZnZyR*uyG4hj~*F_<75n0`ome+{5Zg#W z2d}MOTaBtPMn1KKvXDmBIPX&lRQ2Hfde+GG&5?dXY-S~SJW$$;!(j1ku~q3uWd$NGUu&f?}o zNQPpn%1a)Dtyzyskd5*vQO{18rCZxr&SPVq#G0`b-f7D-?LL)I_n5B5OK8LpUf%SIfm?Xtk9yX_O`8JJKP(n?0DIP5=z$4UC5i4TIbF}olEd_< z%w<=0(d&w1H~cxMi)RZVI2{ja^eZi9+sgT+P;1C-9mJsr1-Vm-?{rTM++W*=YmJ-^ z0Oqiq70n?xvDNr9JG)tKR}q*d>Zwd`wa8mAq3}z!bh%?1S>44>gxdzT3OWV!g3dFDmR?8t=^%d)WTK31~K}8(^rhxKg@IIv@f`MWHVEo54YBCp5Se0p<(v+UOj~a(;`&ID9n@ z!+pc4_ODGNiUk8a{tt&X@gMcBefJvDi^66Iw#M!C#dX-F0;R<)fGk&$x+(}Kb3oS2c;Muf~b?iSHar2U>4In=O-)uD%yBY zRt`MNHqJVLNd8srY%|AiN{`D>Fc*p#9z_p?@4yPtkVj!t9Rl(k1&x>WuU0WB&jOll zqhJ9*X$4rhmdWs1_lem*{KNJdk)a-yuQ!qMs;S^C$4-m1^Y~X|<#9?Q9qEC_H-T-L zND>wI1DdXWA6hZMb{QRa*L$#HlVGL?3m3!7MHy*Wu;_TD9}lf@%*+?Rt#>;`J7Ssw z?BNH)%{XMl?g{I=nsR(Uu?z_gSadtM9`)Raz&$D9MFKdK@CKYZ2@7{Sy3~!}Yhm|U zlzI#g>0Oz}YD`gJIMLwfm2tSY)O4s%gZA?n8Twan7LcVD1B8>p*Gdl5U#Y5%;d|o4 zg#-PX^lg-d2c-i%+J6k)EJPAcPf#l=IaS=2wX7* zBVZ3^HK}jm$G3@hfM32i#d?pFJqP7XHp)TyS074NV0qhFNQ;F=$n_OQ;N4q|+Xx-W z73s}rjr<~^eJw7AOYw|{{RC{TbrlLGazHvHR;Xa>kY-cuu1i$ z8V;UU4FqlYP&?>GN4)^?PU}d++OahgG!u$$an_jUjwuWY&w6g|zefig{3=@DJ9StItePVce8s9EwI*vC0EVGsiT?Cp`70gjSiY z*Q|Lxsv!llo&H#2f4x(<6vliG2NdoWA$uER$c+@9z)>BtMtJ^JAdrvY%^{cO8bm88ik|7{DjetC;xRf+{u*+cd5gE(tTA zmyyz>N64xPDNlSrN|BE0KZPrVo)+nKl^eMlfn8-oHw)2|Z}Q&olv@G?!T$ z7m8qO%>2kJTouLur1^WUXaa;x=Np$5Idk|_(s%t>|`^c6~2y7R?oU0X*CWyIWpn$2Y|^Nrc5U{*10 z<2)X;(3yTo#yi!L81YRg20CJufUd~Hqf~CZaB9&5zo%-9s9 ztFkazL2zrICD$voC?bI!yqPLsp>t(BynYuQC7&B>9DYt!vMAZb?i z=?-n-1aJ_V@c7E8A;}Al-n7e)DdNI|pMJE?oHMjfaJu-Dr>Y+=;eP>KezD^VT}OWT z3o{(^URcmFIm#$pbu}yy`HVJ!??sW)-O;-=;%SQ@+681^#^zz1l|Ac!O^snpvIZxy zto>H^e47MlpdJbBO2$%p8PLL@xW+`p!4 zQR%Oivss6uHV5*q=EvgvmX^yJX;$NC9HxK5xIeII%BRh{F4*J+Jk>d+iWer`Bj=!X z&MBJHt;n@I{Zr!w?c^;Cad}L7o`8Q-UTLf9vfti`rjWdZb*DVWQ-?(7`>F+0p50_z zrgAEgr`8i09mHT{w=|~mKB3tD6v|v04#|g$kI26Cb}Q-@pRzy z^PHdOT*P6Kv4T&vUx0kTfsa}Y9e1)cyvv#7K3NC83e;0ieHKGX*&T-z=%!^;jO2B| zt1t*%{{Vfslg=tRl4fl-jOV_+S1T37ib&_?JX507bp{1Z+|AgHdH$RO}{{RUk>hP?pf80@z(zA+kTb3u%nez?+#(hN& zL_3-*;w?r%!KY)-1XX$UJL!nuaK(FM^r)h=xtdnng1(rm5^3f%4$Lw-hN-!3Eg?}F z;xFDv8mipH*0^Zn0Z#znQpEdTYK(!L)R!R57+e(ty(^U+jK!3*jmPHbPAcuFhyq^V z2JE<~Y^>GhE9MQuu@$Ft;j-4PG=5~b>J@mVYZ$%B5({aV7oHus=yRH@er;FxFp|yu zOgaHt8YhOYH5J4#{E5Nba5MPQ>Yf<6wY`c48(qf%2JGbhX_nz8bDl-NJKcfx#XTYi zAtc;8af$Ox=Yw2`E&E_AD<-FHjUw@zq*pzKi^3Um1aYQKH`HvV9ru#BoD{s znwmQ~q+hsk^sd)e@YI?%$)$!S-M|I&gZNd(&@P(MoJka5u2d@LwE^rI!^5K9GM89} z-nrdX=1ZfPoUkDF^sc+Z8XUTX-0@F!wIgG>y}gI6S@CCw?5q+$F7D(OV80@$82m*E z57=EC6QmZZeASS)IUc5;Zy26IAQk>9kj&_}XnG>B$@#S|gVE zWKeRyon6z@PE9H=^cYSMWU}P+q*|hpk0vt1~LCw2DaM-74A%QudwM86d_MdxcY#FR&2!Dx`)mvW- zYFE&->2D^((1j%amFQkDno0D}B)1#0pTdt1yZ-=WF6M3q0L=q*Q#|G$58i#h?5l4p zN$6C9e+s>+cw<(wwDYF3l_D6+GT;j7po(?zNV-z#w;+u5?OQ%0X(ZC*Mv#>&&w2q+ zM+>KTV^X}g#4$4hG6(}7nX13onv8mpw(`@={_mxFCx;{!`cf!?&vhlSn$9uHFN%bM zG6-(n2NVraMkUsX;u{M+?jedU`Cv^Zo#9*UR@__(V=JDm(z~s8Ao^3UB%FPERbLLW zL#GIw?ZG{0AF@XiABGF-A7PT_81vDII5oGZcs?yZOlhOPiR3|?E?fFk@ z0pOA8T?Vp~K9cDaTiJm5K*^wf%_EJ`{5cM<13b45yG}TdHIw2`4aK8Ok;KmFAmPe@ zGvB$c>%%b3X=Lj(ER0{c#wv%3wEMkIbP&R1jDL5NoOh>kWlZy_ZJ-g7WnKP+RajyJ zq1--|+9!kVr31{11ogon{{Sj<-VeNt9k37x`A*VBOJ*LzPh*<3(vsscJh8^3yPQ;a zc5qweVVFsu?u^$!JT<9?+x9s!JL8IMz8Sv=LAG=!ra7TIgP|q4&%tW$e|FE$YMu1i zp^2VEAP-*kVYKV3G4o2%`e5TVO_E6@X1JP3J(;p8nNBS&ih>5)z^BAQI1j~KGi_c5 z1y?AuAS7Y4`cpZcjJp(ia8EJsBMtq~4r;B;kxMFwa#4B`I@MpZ#=N%U?NTd_-30}E zMsz+H!(ZU@j@8`i=#8ejxE!u|t`oyks^6i;I*ROdiHXvrARK@Q`c=ncSZa?lyig}) z35*kiREfzX^{cls6C?dkN}|Bzo=4V$s+^UD+nNMrc^uM&IP09$s|>i{F#3uSt;hyW zXaJ6;rZ&M7E<7nQvh`=Dur?axip{vN$*p`Zg2}SC_Tv(tsS^K1=L0Rfa5d{ z=&yiIDN6)i4>fQ5Jnh~bY#sAi^IX}+O1;8nkX(N4;|7y%)*0kfKX224$(_OWLyEB- z&4Uo$dlCNaF>?y+cKoO@^`tEI+S1J2}i3WJZvoG%L5i#m1_WI<{%SQ0eRy+C=O#lMI#&l+BSc%&6{m(r~!EqN2@Rt#EBi7 zY^j0YHO)R{ZPGDfdy|@)6eool9+X^aOz0XY1_8TF`U+@USlF}PE?z!q7|(iSbF$#n3E{92v;rkhFoIM4glQ6fUh z2+MB46{eOb=vc%E^v)=-xtUa7$u1T+0m^HRm8T}-)4X^0-EMJAZ;%8PZ- z9Bv1SveFy^%t$pXdIqTS0=80*LJ;D#Bk7NI2 za8FilmDpPNN6mmQ*?=Ri?rNm|0@T_}L2fqsgNki3bveepoq>%Q?aw$hcSl=+e;k35`>~l^`&T&k|dq)G2%`jWJ=)6{w-xfI#G5jcw z?30Fsfu7t}cR9Hcm{6v3k@TpT1D-yWxg<+E?if?(Msh1EXc;6q7{R8QGK+~xqRAvw zkdH4otq3h$&M}aBVx*H!BMsd46lgUmEr=swAQ?S+)s!1~2A~$REPy0zM{`ogxE4Y% zLF7`Bu@0n(jM6aMlZrsjPh5{mZZY(ysKa4KO-Y2L+YpE1m9neO4?QtbIgn#=WhZ5XQ!X_hh;EM}5B zdFLCXJa-wXBDaYfb7yz4sUA|fRm~x`kt*B85Evk1v8g=Z4is@z)w9X#^`{e)flQus zZ)mnFs@*(uPSD1qoD9~UwV_&A>CGjz#E$tGE;1^Qgn?_>7dhiSYo*t1is_Ax2=@9_ zsH+_m?DaXVJ4|c%5=4qj6NANBhd`Q5N9?KyOajIGdskcGyQv>WhvY@V_FQM)sNCGT zc#b{H6du{9%VTa-Zd%8t_pLQ(Q7fp=$_YHy zrIJ|Lgn1REkT!6f3Z{r=J0clA;+3stw)v!WKEj~qg=s+a4KK%9WwL=ZGQ<>Pk}+1M z_^aW#4jJxUy(5oz@~nQbUJ~YA!^0W!udYQofl?eFHaNzk~ z8XR|fqyGTJ*O;qJK45tC#Y~MOF6?pbMaS*g=q>S=Q|E4lZao7|PxPvD{8{k@%w{oX zV{e|MWsmDzFx+O?ptE`bS}mptA`Nje#*8@wA*c^**j{TFx~TTq90{~Uab+u&% zd077dvbCP>mgr%%P0Q+ez@)bd?UxxUeS6Y5D$CxwIy9cjIFFNO&~+{U0M@Lj=2vsI zPCY69WLrRzLb>cIPubEw7q3P=Xfkqg8j+AZzzO!LB5(uNTLGx=3t^qj6^z&_OPHI4xs`kF#;X%@H3 zDIqu>rkLpHxiSLYf~K~0E9Hgmec<uJ1Or@g|oDJ}>1W8$tdH>Xu7od&)0TbK5#+C9rXmI9E&p{{#X@q*mjn35M$ z{o*l^OtJBuwVkdS-r<;a!5IAM^CLwx-Oip1w`tlo``zm&#adHb*))-3%^ZvlYnr(6 zi8r2oq!IN=aBw9L3CCt_`_IgYB9vFQ3V&_!UZwo$}ba7$jt@) zfI!@7POElTYh6g{Is)dZ$vesO5IXwQxm?bp=Q>>i;9DxpWmwpHoL6lAC|IJ~=0HjH zerw4VRTymGj<_`(lLcMIOy{62oKiKXRnv{EcRHS+ms4+Mi#X?NRy2}X9QlMWJ@Z_< zO0qCJj_+EnETl2no!#xfBZ4ZtHKr&^r- zqCf|hPpKlR>`r%9B)ObONn9!GOo5rf0lR04L1S`XB`}Bk)huyI3lPOe7(FU=IpqtZ zPS)teptk^2l3zRV{5_3j3xo@^e0Uu4<23m0gzTvn$qRNy$sd5IvRa(-rzfH`eCZ_4 z0m$wuNba4Ai3l;DsxXdL=olw(8bRnALUuPiMtufi|e4kv9w}O zFkt$OVxqtV_a3y?0hL07w>inABq9Zy+x1l3BP(MnNFFI1Cn}N_(MJ4fD z`dyHJEy>^Xm<0N_9$zkoUu zR-rvX8Lu9tM%bZ**WN-bLu#f;Be@kQi)a9zNU1WpC#5vlFDWOSY z$)|0>``MsiWYnEBsI{RRuj5t9lb+ROiR9E|{G?;?tBXB4Q7THmAjc-6AQjFID#2_M z$4Z5pEC3yAcs7~a0<%S&j(-YgmIg*mSk5}sPl5Ahy-HsV&Ekk05O8yfVaHVmBBXA- zo|M8luDH#YVg^8Ys3eU~L--L^m>#{VHW{v%Xge79c8egzkA$ZM{i6!eJnN z(b~D)Sd5nL2LiWu1xFa_D+f^Z^`dQ%mK zK2<^Vs}Mq`IO+VV;OrL|CHcW)#(Pw+bO^%qs3o^yj@&;yC2^Fq^4N^a6kD}{%Nvri65sDj{9J#h)6L`5>OT-qM7Cl zQM^zDnWmFX-YE;v0L)D$>{4&0yWnP}v6611aH`&6Jvvjj98$RKNLrJ2Y9bG<7&HMX z9Cf8p&stz7)|7hYnqp>Vaf)e^Z+fD23v>SfEovz>7&hQYIOq*v*|J5}oDB0(HO@L3 zpl;)oU@$(kWU$D=6pFEFXFHE02CNUCwPt0va5MC)F-U%t1&fOsu1^^>5Tnwd^H;gY zu4$&?JYbQU7#39Fv;3-1+-9jQz&$DAT>6i~kc%c1Ax9khRcV}^xIEMtke)fF z1;HsinsUeoZfdIenBy59w4-=D&;_v|q$7E%erXvPr=*XOj%Ywx5QfsxjuS!4sA zl+$o|_Ml_kM^5!!;Ut`O^`#d~&w{lloz8G50(JmQeYKe49diZIv%6cumAfCIaBeX3L^9GZk@JerkHxTXZbfE>~mIHvAgaz!sA$TnLAE;5l9A@!yM#{nvO^|_2hP`NjzZDBLg1Z z`5fYyh!HXmYGWr%;CuSi`54FRQDCtE^!415NzY1Sl30^ZjB}p#BRUN!u&O;f*0hhXc!$|H=p=mM^DLCqMqAzB%lHXH@V2OVma%wACP*bUhotG8PnZSDU6(X1w4 zM>hHWaa^{mW2+0oE?}Gy)P*HYG;3Cyv5rPt1GQOI445PFsNsw}rAj&MK3=A}oj<{P z)%;>ebm>`Ga9e>?VG44S(C1-PEwPzY_AF}KSlX3VlJX>O>wP0KEyBCzbB zn#I2G_M>D~rMG2A;1=wE$f@dXqd22JSfSj)CM=-+;xS9)Zj51ht<4L8_ z{{V%zb~a|_Tj&{+=GeFdpG^0vnm2}_xR-U@^MTn=0mr37v7~8FW^(p0U&y3v7{?`! zD7w?7R}9idTe_=f73o)A9@A~C_Q7dz@-X1ZDLE$^do2lANKCX`rSQ-qe z_2_DUE>~s5OSc{C+K+(rGPv?7v3LtaiSy(J9*svU7uAvDA8phv(5!x1r?L$GbxKvc zxh176N$e}$X7EOdDis#Up6W4CL*N}67cI5hJ&EZ@D+hn2f04mNA%EZ3s6vtzVHq6!`Sr`(S&N=B=9v-lg!tzrzZyJ+@ zEIN#z@vlsqSJExAX1=qJAKsNm^{k7p9e7&Q9omc%9^xQh`A|Ma`W%0XP|XZW3bdGP zkOpaAQ?j$6{Xn^lz}Yw9lRENWPVfwM-k!sc}A^u8;+RfpW^FAREUw2+ZDg0Y16K=a~oT_ z+#Gy>eQN%<;cMHXlFp$aQ?!iwnqZMPgLH{*w1@*SSoVyt711w)G{uz48eu6IF0G9I zl|GcvX&O{;3#1uL-JM5BM3Nu3t0K2ZD5^pU)AWG#rN9 zdeyVxyCzVsipo86{x#+ct!seutKDPSu~rvc)v?a0a!fj3&uBknF3`}PZ?e-wTy|N8}ZYc@sA8lVz@;a<*V3i z12wvn&PPgg)}}R*TOM=c*x^|aB63?lTH?*J>>oJEuSM~_uzX;2?_4Ogzy+5$?OMp@ zO6Gg%8l31J-qgB!gVw0Hp3+U1Hu6N@?T!s}@OXp!IP6#04;VD-*;i4vXJkXUc*v=` zGM*hXlxu|}CvGXJBxR1)8T6|*mT}3crLD^tpk~JKpcSu9(tHcyos7PGlgLIxG2{8r zVfAKt)}5+a*h;d@l3;&yX18wqbzyS{l?)TJW2sOxT^70E+bFGr$0}hmHmYs@wZ(s9 z*++0eImceK)U0T*(zb>hU8#3)p?Tm`b77+_@{INs-e~?2vD9+zFah8UkLydV_%_c^ ziA+UU9;#}SxRn;SJiYD;ou#q|p{SO2Sqa?44xHC|bQ?B1=zo-LbcQmyz3+O)8}njMz*R}cQ| zME?LvvmT#&Y{$*9xKKL&?9p)KIghh4zSc$y>P2b6VzMYIpd59nuH4Tdfg@n#{lYO@ z+JA-ho2b+5_5>;FO94g2%5wJ_dBMRX`U;}9t~q2Yj^?|2j|uCRV6^tC6n72{W;LOC z1T3Gt%@-O*9Cofo{{SO)JMQaKE}L;UJ5>SqHQwpp4z-);gt0xmXnJ{%{{YsjS3eCk zTLd#3>q0=~P?CR@JC(|hGMh-cw;6vdk5x5x-$rJObc_kbTb|P7YAb0mD$Lm3itqG~ zhj856ER*VzCV47}nwy6rJi<*k4g&N&=^EI@l>{&Z^cCwD-w(9NE!mRp>O!M{c8}yM zhSW5HYkHRPIo#|NZs|_s@|cUJ$0U2%xjxkBbgOv@R$?>U9&6Gx?}ldX0M}ZyQ50tn95`Ata7BXQf;5C7haV!op^0 z5S|ZA*HPgA01WBZ@FbU!G?_i00+q*Pa_W}KNJ6Zm)|qu3x0R6^?!|jS@SlgGO{=Fu za5}KfdGC#MyGux0?7<>*Ckmqii;YDykFvIbkdYoS*mSExB9elLNyi`z*Ky!>(V?@A zt}Wn}QH|bU&o$mlsc7=Yg|@R%j`4~U29FfFy0#Dqf*siIxXo3wi_FHzozHEkTDnge zTv$l0ccHLR(B~IPxh{@u?zZ(O$YK2}K-ftj+OatY z)oa#d@kNi9&CDYsqc$sv@i&UuBWUbq11B56rkW;kZ=ue?;r$le=TeZXw>vi;pPgH4 z9|@oz>M{P=Y}YL;vtPg3E@m>yaHAu&O1gc)Dnw)<83z>k&UTT~5BNpKRu_YJY%3bG z1bRjbGob_hkMXWORil`x9SvQM8>ZoY=W~vf`Ph<7=%v;CJ!)`ck;v?cnj!IKh_ALg z8?5%kNzeX0T+Gm7L_&8n91tsh$4at}C7eOJPgXrCI;|F|Ut>u;N{@n?WXe5c3O|vn zZQ@^(G21ykz+r*<*B7i@Op+Bw+P>97JKLzh9&2N`=~d3!xecW3c2^!SXbvW|KZDe^ zUMpMQyAVJR@fzdIqIk~n^J9W)#gs9^cPUa2TvAhFZ5>tjiY~1HFhvWD@>@8nuz2fJ za&rVlLC47-ADOI|xJhLRG(<=1j+HsTuzPv^2CI0{l!nlSvn7;DF{{Sjj*uaeO1zyC{Qf$gov$3at;;m)l#l_pS zXRuH|kgT8WS7*syyp!Im&oemNkl8fVh;1di3Pw|#Wx=VCF|>YFJXgYERDtH_f_mUo*r!tE$espW(Gh{h zDpF)BHpj*~%&uWv2@!0%R0vwp}BI8ly(cBYWkXxmgvcc@7OhA=QYjC80XVC1)R z$v(ARR$1gO`6QlATM(>6lh36$vCS!6++L^Jt=p0mu0I;2NzW8{k`6&Ud(tva(z&Ge z;S@ZxDuOZ>sjTKI(~?`|9qO~sB&-#f;Cs`Uf&z{WBYta=Gqk5_oG7ahk0DMET81df z00|h+YI*C{kesZC2E!71A8KH1@kpep;O8E+@^Vi+3T92VH)|FEV;<(EU;qFRPjV@P z2B(fcGv(Z%W2rR8qjOusGYIuC6~{x7_}5>oNjqthDzCXdg1K!3Sy}24ypt<7MnE~w zHR#e<$Ew*hQLsTO@Wc3PNWBi~5qzdsh1kiaF80aV4>gJ7FWpZY#&FxYBd#m5w$g2M zD;5$?6e!7NHRtzt5No>b(KCIRe5!h6(DpT&X%p!lEWWYX8EDL1+44>+x=XlqEj&of zt+{#{#f#zfgx2U%d5dGNbBfuIMNKlmDJ1%_F-XCbN88vrE`9E)r{u1-cAv*>?tF+*)BY$Ja-j$&6@>7 zZ61JBfZPmqZ}y1I0!@$&JI_`!5Rs0c3XbSQ3MyNMG80d@Gn^rnj(PwwQrkpgD(%MJ za%rP=HqjNWmE4N_M~>ZaWHK zuE1!l0rM^uJ*mlI3?Qg*#P=qhHk+tpbF|?5ilFvaC`oBgKbmPVfz?=a7TJ@ZeF zH6-TeC^`d*%-Jv9EZGOvrnl3suVfKGuFiiU?r5(4s>C$PyytZOD>UTXdlw|ZsyQo@N+rZ5XMc53S9M(HsLWgvT zk8D(eX{MBJxL}>aj8mO$qa?_8A6(KRaj{+R;8@PciDT2`>rH)8kl|shzJpBH#=h)mac*u_J(J6|O@ZixK<0{b};eynqiU(vRKC?AYR< z3$T;vRAV?av@JsrU`vzqrp!@(?+4I#r$FNyPjkVm=_QmX!bIID83!~36nTB)Fbp;h zc@*8G9y-;D=Sij95U9rjp;pNSdgg;0UD*#OJap)jYzn!~499WUd8EXI(hL)?_WGO}iW%@x@k~%8ZP{ODMs~uFlFY^j0#3+y@8N zxxG?rdyAnEfyX?`J!&H>yBf-hicNJgjLO{?X!I2zxX20v1MVxb(YzU>UV!%#UcPz4 z%eNnpu8uzf_+~CmrOb!@ySM&^rB;iVDmtT=PEqD;^5mRk14=~dnWS*Z9&dSSBLrMB#79yMP+u*Wc`~j) z+G_PUwM{nV_^^ndSs_}vb7yHZ1%;$4Nd5@Gpub>`Es7Q3%W>17K~uQ5c*fVxdWJP? zTniP^g<=VgrySQ);B6a4)GX3ln{zCo%8>3rKZO=Bl_ce3g=osD zAf9T-Sqx;0l+Aq`r|G&JcIdX&7U6O7krMOo(z(AC>2~JMcM%}kt$+}EQ?aM9jjqod zwZ5D$mZ!`ks0dC!DzQGFd32lF*64%$LI%g@iuCV?cQ!WKXpT!*y!_>+AY}glo|W8Q zO&!bxVKMknI8uvRpD@X1G;;{P&oPmX5q2D(!xgn<;VpLJJ@M!|iy`XfFhBGnE4#b7 zhe`3BmDa>%A{TOx}Q8WFkkebG)B95d#A4>Lb6k9^}7Y_Wk!+-}`#qbWMk=Ywo+!#4I>}go1PA!}({5kOy ze>~c3F${2g@NxX>3im|0)1_$c5mmiMBEFQJmRoF|amY2~em#Lj!mz+C*N%fUnB__- zXmR>xfd%Ve+{qbkyEgIpit4TYAL*?Mw3io-I^f6$@)ecg#Eec@l5^=@CabLdj>w3( zY#e8`KaNh5rC*S3lOYV(^!StrP^&?VX4BquuqAL_JMlr_31Nl@p0Z{D(HnDe^bXfTZK7rY=e2udOfIU(GxLlOG`U?_Eu# zVGt_t53OTq@q`&0c{$>?;%))yUpb4Ll!~Q6TIHzmoO7C)PC9j}=^~8eb5jnybgw>0 z*Vz*Sd(*(rK9vA&NX<#V9qTrS8ePdq3_u5(nPM)Z1EA)hkA?>z)#aK9VQD6nQ9#Ko zaZ=MYj1twAC5vj4?kWdH#{m9R+pS$$h_^uJ^C$49TH0UVDKCEoyl18`-<}AqBL{1} z2>R3%xg)D8N{kLk6;?}_qxqTDN4c#_-6A_XQsYrG$UgDM2kGz9xm|L`RDqp02JQ&! zU3hpY$wuR+jkRB8C1yT-ddea}kg*+rtjnJkL>S^GDm&LNJF>amocq;M?nypgSJyT5 z)N<-dI_i5d*y`8DR!k22TcM7mDE|N&yKS%8+~BEU>AM5^*A5xKiE;SUsuuv{DI9}a zJPkW&QRpdi1gn*8)Z$f!d-~TUV|>dd(s;&mT^+5;OCPwdT9hSCls(Bc6E5TJQ?^Rv zRC)HSlWCJE-5B>!m10)2+Zh?H+m-oGwPVX3#y!EV*h=W}@ie(!g=q%nV83*AHI1nQ zu%4h+*H^(DRz{?t2EjNrv>v44w2{rZVt2{9Pp;y1r@##?9NzVs?Rxyadm~w&>3k(I zP?^RL1bS4|Ug=QW_8U^ZNXB^WnzpUQVp?4wjX_{=1!%`|jn%L#mghx_f?QL?wM@?u zJjf{w@s5%LeT^%Q#qTpT(*E_F*8qcu1M#K_Gn3|z&W6L3(=YEwo9|h|RbEWF{AxtG zi2nc|G$sueiDu~7rWo5ldZHJWfW`Ux69imo%YooXt-F=+$biqjri<1 zrvCtFQOtvs(+&k2>pS~FGtD1vOwr7O%+TFR8ngb~r1AQSc)J~QM=}c+w{cA`RGRq~ zqHRhp**}FG$Slnb^lq%izF$WCsq1z<4IIc;G`D-xOH~7TfzvdC^x)(i(Qq_F(~E#J zo+~Z&6;M7>ew7nyYC7i>xrbw5NHM{nK5HCmAo3BvDv)0j&dw=wAhD^tnhb*&tigMp z#8Q7~ARL-}$b78PE-9X6Xa4|b#zFZ>`cqp`PfSwhL*!o4u&9Vw>po|GzxIa#RE4_axM4y{>!YqvS3kj;;nkw-cXR%?rt0A+l&Me1?&HHHv_jFNq+aDB}#aq=4G@*&A_ z`Or4HiZ^-kP^A*ldr?ZY1 z1anniPMN(|9{8trD;;`X!rdGZQhlZ}cy;{iiCYV}`A2pi?;4&vTjgLrVhHL_N_@hx z*nOcf_s8c)o}G6O#Mdy8-V6f7eJWorU`RXoJ?OYt=zh}~=)?1)&Q{I{#dG9K&edT| zbi3*#W%^RMBy?MV?kT~mlvln+I3RTLY9L@ok6h3@9XK>(Rt#6SgyEt%$E{Af zjEnc9Z|6)#&S?sh(AHw=MZe{gnDxa@mu%m{K=-DE&NRmk-Y(FeW~jt40hXChzZJo| z+&eBLd@m;;iet-i-6SqOjYFm8TAMrY_J{%VkYj_BP(Gn-GmF3oJq2)5Oyr;`BNgp~ z)}@UmcJjr%x%5$!LV^!y&f#?^9d?_np4~+`Zg>FE|l=JF&spUiFY`Y!k z!8`V-?rDFukr0}{BDwGE>*ZYe zQfK|D8plyaBgrgC7{{d+70tt|u{Z<+>rtImz~FLv;<5#W=avCOp5mtRt`~t5XWyDl z6?05#joaluz0F9vgE86|7Wb@wBJ*%z7IW6GK^)4sF_3%YQD!vJVBdyP00q732fmjF z2!|aiLW-jsa8FvTJWYeQKG^R|Qm%;2`8+WS$Ec>ZqUeWc$?id@zQpdqo-z-uN;JMQ zRk8lfI}vgw)h6H-!qSaNh$^ZWpHotQX2!}!B;(emwbCMpmN6F3UB{&XauKLpfE6M9 zb5lpC-D3?4WBb{w!q)@+Ur$O_gerhnfzVI`BEN0}aaM++I2{kILF6tou;bShqBX(& z(fXQJ3zGi;Xak;3ed(WXB>nDcCybtukII-MAe^DW{{Uv4hFcfha^#;%KebAdGsRa` zbzr||EDwBBg`Q4KKzStvBo}N6Md_SD#Is{nQyAlq3z3 zHl{kUs>fOk;c>^UK_;Jhx9)LNWYaDg#y0`ps=~Rtnwt^|lZ^5z%4(yJnQ}Uc!H+?i z*XEJVYIC4WR0WZgihQfMT-zG4BjpOm({&%(vW3Zy@T^F*E0trJTiBYqnloe>CUzs< ziwLy(#QDP8lk_5l)t?_UBp&B9qe}oEoScri=|R(!05|<`Xt2aO!5w37%A5VNMo*U1 zzhPDWBTP2XbTW(%xa~k(b8GJy++t=PfZ~|mD2)bouec|gjqPmTi6`UG8mQ4|(K*2z zhjT!iEw_uH{_=tCQ6CpVa0X3OdyOtIM!>-K098NjT_O|vxK{+8cF|-mV_f*DNdp5v zT0`Q4w}1vm8LWTptue9wi<9U;CZ>;2(wmWL%b)f@q&u?nc$PwNHhvkXPl#v8I8Z&! zFlu%Ql9q%p?s=eVHYg9s6;Dt-Xc;)x?-*qHSUoVbqgc5F1BO3LRVLSMSBTIbeU13|n)JZx2?44~tI%`^TIc{%dz-IuY=K$5XPG%7LN4z;0gaG?Fj(0{rp zx(hO|{3O>02ka98>@!L=`=|c^n0(mv#c8yujE7!(0ae}j>M=^_c4b%BWdH`WVh?gF zD^b@Q48BPmcg<`Wvb{m9`}s+?Wl*4cLr0m^y)(ACa$(TvcU2WL*BE-H(-o=3S^9P$Ruz& zfI8IC;iATJ0H} zi5d@4P2L7qoSJra;|sXcKsh9iah%a{kx0Cp8mT`Z3bP^L;;PAzta{Y3qLhOi;+nsB zdgh$u@<_!BGsQ?7HVhMX^O`tk_A0rn9kWl3!vGi@@PRpe~I^Nvqi(bMjdDKjLyLi1G@ zbFPcj`cbugIK%t0oj3q=t_Q{1j7@ChVB@YAt#NsTQGWA6GGu6gApFcT{VUA;M|-1c8QXYWvyc@?{$janzZ0#* zhB3L691M!cyPwRFT&OGGBC5#U&qJ}$wK(nP0w-b4+~&KdylEi)HvjUi5{flvujbQ9>a64&v?idEP8D<-05=4EMq=n0vFc2 zH$}eGCzV99Z5iM#dtQvpblA&v#YL=Al4cKyd_k((Tokpwl?F0#kISWVPp|lfVV2de z7dTi#67Q{rC|sn7P!$zQEkCj=A52Q5rIiS=Sno2uTw zv6$2li6n2G<&^g_IdA7$vjvp>-^Ql5fe;Urb4Wd-AhxnnrHp78;~5nd>@s!Ra6G-&m_)L)4`H|a12w%E;8szU20cWko&$6%$rUYFxaw#4vtL_izR44?W*9g%$3n(JG6v&Q-Wcz1 zq?STS-N30~NTWH&PJ)rG$>NLvGsmq=8ypU5zna95qw}N;;O2oATjpGY_*7-e{VBVN z1DqNPGbtti04iWby`1n5H6rJsrV$|Eezb*~7;I*mC%rJ=D)aZL4IKf$ zWkSU8D=KYf8D{d{S?LB?y?w27Up zV*qqfRZUruT;{xV%M^Qd1}-~xuRmimKu91TO7DDh#9Iu3*C3wN=kY%DJGefTq?OKe zbGnU`w--uweBWB%(V~_(5hpA_=sl{W`~3C67#`KHVyw{nj+Ke0LC+nP)%;e-0=xXV zKDF6snj`7<+l=$jd8AOvje@b2Vf3sB3(}C5_tK&Y8j+jJ%hs+h)3W2F;@IZaGpw) zA&DFe^P2IiJ!?~lffUT6Jq2pRd9L5eyH;sP?7cDTR}w1fZ%uJHf%bxZNgXQ!!Zf

{v5sgQ7I+_&NoKfi-Z^S8Kv{g$6W9noAlK02AQ^f1`Ab|BgW`Ct~ z7BHvT_hXFWi-^X?#~#MC<|f89-l;v#u^i<9VB9F_UX`TyitTKbL=mtH$t-y_<&wIk z;{2fVUEYxSfN_9Vfl%bpNhWOG>-UWV2;)R!+!J19u4*@9Qb}a_m@s7kcdqv5{Zjxr zt`lBAzEQ%Q{o_eVwl@@!+i4y&ji5!6!cxI`D&Pb9RjK@ByIEt?@JQ5L?lwSf4YSK04nG)Iqi2+pH#SA(IWiZ1+J6Bt#brHQf5G-0|&KX&0%n} zDQF!=e~n7#^RAamwZq~kns#HAS6h~)U#Jxwn;Iv z8C&Rt*EixgrHDIfi z>U$Juq|psXQm9 zT-^ooV+C{FyVB)g+BZC;3~&JBt}6>%wvWkT(kSPF>s{&awfIn4OK>s5@2*S4njOqg zzWHIu>H#L2O%mE@<0CH%Wg8$?tT&G?(9<^DbSAUxB0+koKks4<%BjZTUaz9*UJx)w z$)qbtM z9qYBYx3Lg{Eszp8Jk+?F!Y(=eD#yezH@44}h z%vYq^7{$Iejos^WMbkv#*e3*x^NP|t8On?kJXY&OywRjVbYc0rZ8`iYl0zJXWarww zL*fpR1-6zZlqku<GJ!=(YcwZ-|?^YLCxj}?GN3f?ONKGU<_A;&e z%w*IM$GwK*^7g39%RA;rEXS#zLbCXHDf=^@Go1D@z zl&(7mIn6R+cKo9zosdU01GwHm>6!$G+d%F~#y+(xKoz$Z$u$Xcw;3Zol<2tVay{vr zY>7uF)|?34f-_C+&*w^*89DEYl1UL&aur4oT1HSa$o0l5c+hRmYB?Dl_T&ulnq~4_ zhrTLk?PPYy2M4}zDbS*TafTz(q>_17F@-=nW|L(?mDn^%ZpzI(O2Fpf-!09MVXlRajcoAjr1S3+%WaFKYkUAByfZe~z82Lq*6m&CfZpmB43J1PDW#2?bV zE`JKzUku4*3a6qoFY>C5r|CK%A}cEpM@)k3e=|kIu=DPD(Y$yvb}$*_jGTqm%)`()DyV2}Tv$R@etV_^rhzx#ICSS02-19lFZ|)ls zT+MLA{{S17&+AJao%1noC@PNK>eiudw%V2>!esX1y$9j;jihS2Y}0B%W|d_)Mm@c0 zw{wlsa+fLQX3prY0U7+N6CBXvaNJnnVDzt{u6#S;_~HH5m2Sj$D0uwqgt^nS)$v`0 zz3sFwWh|viG1#EvjN`UwH2SIL?YnMBjc_^33Wx0q7=ZDU?BM?ZD*9$04|sMMRU*=~ z;DmAelsO+@EBQ;wfUu((XP{oI5J#^EJ@v@;`_EB*x+db(+|R1qR{sbyL{?07G7- z7NO_H8DeF~<8h#I!@&8kQPFR-$(Y^Q%?o!Y7_Nsv@E?e^i)6V-WVN?$QRQ&Ehpsx} zyT2T1f_(>3mn4|tX9RkIkypGK;z=&NJ!c%!D@hzmq~o3j2kD9mRA8CFYo8Bw%{ti} zNgTlS3n%!B<0naNXJ{@5l_K>AoLA9WnS0BAHfIC^)#3g#h{56+QbkbAi}y#?iwdk2 ziuz}UB-KtEP-wyA6o?<@YpS;JU)W&@4!?OG;q&cfGAckhtHvzjNgISAfEBwVr1Dw@C`>67 zYlnO&8%MPLomqh1x8g!Y_aFos^Qa(?e$YO)kffbKFo zimNxM`%`_$2iwttL?MjG9*?lyRPO60Da}Fdd5;h)Uv2 zl2{LzRE1fS1yxiYy-h?FjDun8#UohB-5!_WV!vjLx881?*HU?|OT#{Al!cDqF~_}i zB$3*=Bm6_@q5LFD0YFF<7>ZdAca_hz2*u6|W78EViO)yp+}B~wX6kJ4Te7UAvGlJ# zy}Xew8KpS@@N3a;?In1apxnZ^yS+I?j3l#dO{{UwzTr;$Uo!bUSw>9N{9*N7$p_z6_c*kn*tae9dhMlr`AhD&?7RNi| z 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

Txf%oSoe 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

wu(c~hcAt$&!Jg4BpamVXC!Gbt&nl%!s>-Mn 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 Ol&|+__Hhnp-2d4z@{Sh( literal 0 HcmV?d00001 From 7a0af003fb576cea6ac4d14e4a80910b895ee143 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:35:53 -0400 Subject: [PATCH 106/123] Updated README file --- README.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.rst b/README.rst index 60ab7e0..cedd6b9 100644 --- a/README.rst +++ b/README.rst @@ -14,6 +14,14 @@ Usage: This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. It has been tested on Linux OS only, but should be compatible with Windows as well. +.. image:: images/pizero.jpg + :alt: Pi Zere + :align: center + :width: 200px + + The server running on a Pi Zero. + + 1. Go to /src/gshocktimeserver directory. 2. run: From 5d7c8a1a7301fa562f79e0b6b491d43cdf60cdbe Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:37:33 -0400 Subject: [PATCH 107/123] Updated README file --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index cedd6b9..4b3f5ca 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ This app can run on any device with Python and Bluetooth capabilities - from a d It has been tested on Linux OS only, but should be compatible with Windows as well. .. image:: images/pizero.jpg - :alt: Pi Zere + :alt: Pi Zero :align: center :width: 200px From 7700aca4a8c650d5e77d6d32978b00b5fd58b717 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:41:38 -0400 Subject: [PATCH 108/123] Updated README file --- README.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 4b3f5ca..91e690f 100644 --- a/README.rst +++ b/README.rst @@ -14,10 +14,7 @@ Usage: This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. It has been tested on Linux OS only, but should be compatible with Windows as well. -.. image:: images/pizero.jpg - :alt: Pi Zero - :align: center - :width: 200px +![Pi Zero](https://github.com/izivkov/GShockTimeServer/blob/main/images/pizero.jpg?raw=true) The server running on a Pi Zero. From 001ecbed31f120832cbbc2eb1bc177f63b5b0176 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:43:36 -0400 Subject: [PATCH 109/123] Updated README file --- README.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 91e690f..705b37c 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,12 @@ Usage: This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. It has been tested on Linux OS only, but should be compatible with Windows as well. -![Pi Zero](https://github.com/izivkov/GShockTimeServer/blob/main/images/pizero.jpg?raw=true) +![Pi Zero](?raw=true) +Pi Zero The server running on a Pi Zero. From ead0867d95fbca81c3631f07dd8d4e72bca688d8 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:45:11 -0400 Subject: [PATCH 110/123] Updated README file --- README.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/README.rst b/README.rst index 705b37c..ab8dc1d 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,6 @@ Usage: This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. It has been tested on Linux OS only, but should be compatible with Windows as well. -![Pi Zero](?raw=true) Pi Zero Date: Sun, 7 Jul 2024 19:45:56 -0400 Subject: [PATCH 111/123] Updated README file --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ab8dc1d..df85372 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ It has been tested on Linux OS only, but should be compatible with Windows as we width=240 style="margin: 10px;" /> - The server running on a Pi Zero. +The server running on a Pi Zero. 1. Go to /src/gshocktimeserver directory. From 4c1e7c8dbf0562790d40efb4bee71efca4b34197 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:50:10 -0400 Subject: [PATCH 112/123] Updated README file --- README.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index df85372..84fe971 100644 --- a/README.rst +++ b/README.rst @@ -14,13 +14,18 @@ Usage: This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. It has been tested on Linux OS only, but should be compatible with Windows as well. -Pi Zero - -The server running on a Pi Zero. +.. Pi Zero + +..image:: images/pizero.jpg + :alt: Pi Zero + :align: center + :width: 200px + + The server running on a Pi Zero. 1. Go to /src/gshocktimeserver directory. From 44e86ad19a01bb6fd3251b873f4fa5051e00c7fe Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:50:52 -0400 Subject: [PATCH 113/123] Updated README file --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 84fe971..f41e3ce 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ It has been tested on Linux OS only, but should be compatible with Windows as we .. width=240 .. style="margin: 10px;" /> -..image:: images/pizero.jpg +.. image:: images/pizero.jpg :alt: Pi Zero :align: center :width: 200px From ede86c5060f2520bc7a1364641f8795fb45b424b Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 19:53:41 -0400 Subject: [PATCH 114/123] Updated README file --- README.rst | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index f41e3ce..0bf77eb 100644 --- a/README.rst +++ b/README.rst @@ -14,16 +14,10 @@ Usage: This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. It has been tested on Linux OS only, but should be compatible with Windows as well. -.. Pi Zero - .. image:: images/pizero.jpg - :alt: Pi Zero - :align: center - :width: 200px + :alt: Pi Zero + :align: center + :width: 200px The server running on a Pi Zero. From 3ec7147fe296d709191b292a2058a333be485651 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 21:09:20 -0400 Subject: [PATCH 115/123] Updated README file --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 0bf77eb..e7a6571 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ Usage: This app can run on any device with Python and Bluetooth capabilities - from a desktop to a Raspberry Pi Zero. It has been tested on Linux OS only, but should be compatible with Windows as well. -.. image:: images/pizero.jpg +.. figure:: images/pizero.jpg :alt: Pi Zero :align: center :width: 200px From edb04101bfba2a2de2998200936875612c01fdb1 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 21:10:41 -0400 Subject: [PATCH 116/123] Updated README file --- README.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index e7a6571..5fd70d3 100644 --- a/README.rst +++ b/README.rst @@ -9,11 +9,6 @@ This project allows you to set the correct time to your Casio G-Shock `B5600 Date: Sun, 7 Jul 2024 21:11:54 -0400 Subject: [PATCH 117/123] Updated README file --- README.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 5fd70d3..ce5162d 100644 --- a/README.rst +++ b/README.rst @@ -9,6 +9,11 @@ This project allows you to set the correct time to your Casio G-Shock `B5600 Date: Sun, 7 Jul 2024 23:22:27 -0400 Subject: [PATCH 118/123] Removed RxPy dependency --- src/gshocktimeserver/data_watcher.py | 58 ---------------------------- src/gshocktimeserver/gshock_api.py | 8 ++-- 2 files changed, 4 insertions(+), 62 deletions(-) delete mode 100644 src/gshocktimeserver/data_watcher.py diff --git a/src/gshocktimeserver/data_watcher.py b/src/gshocktimeserver/data_watcher.py deleted file mode 100644 index a5a355c..0000000 --- a/src/gshocktimeserver/data_watcher.py +++ /dev/null @@ -1,58 +0,0 @@ -from reactivex.subject import Subject -import logging - - -class DataWatcher: - logger = logging.getLogger("DataWatcher") - - def __init__(self): - self.subjects = {} - self.subscribers = {} - - def add_subject(self, name: str): - if name in self.subjects: - return - subject = Subject() - self.subjects[name] = subject - - def add_subscriber_and_subject(self, subscriber, subject): - if subscriber not in self.subscribers: - subjects_for_this_subscriber = set() - self.subscribers[subscriber] = subjects_for_this_subscriber - subjects_for_this_subscriber = self.subscribers[subscriber] - if subject not in subjects_for_this_subscriber: - subjects_for_this_subscriber.add(subject) - else: - self.logger("Subject {} alreadt added...".format(subject)) - - def subscriber_already_subscribed(self, subscriber, subject): - if subscriber not in self.subscribers: - return False - subjects_for_this_subscriber = self.subscribers[subscriber] - if ( - subjects_for_this_subscriber is None - or subject not in subjects_for_this_subscriber - ): - return False - return True - - def subscribe(self, subscriber_name, subject, on_next): - if not self.subscriber_already_subscribed(subscriber_name, subject): - self.get_processor(subject).subscribe(on_next) - self.add_subscriber_and_subject(subscriber_name, subject) - - def subscribe_with_deferred(self, subscriber_name, subject, on_next): - if not self.subscriber_already_subscribed(subscriber_name, subject): - self.get_processor(subject).subscribe(on_next) - self.add_subscriber_and_subject(subscriber_name, subject) - - def get_processor(self, name): - return self.subjects.get(name) - - def emit_event(self, name, event): - subject = self.subjects[name] - if subject is not None: - subject.on_next(event) - - -data_watcher = DataWatcher() diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 9c57df8..7b2bca0 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -3,7 +3,7 @@ import json import time -from data_watcher import data_watcher +# from data_watcher import data_watcher from iolib.dst_watch_state_io import DtsState from iolib.button_pressed_io import WatchButton import message_dispatcher @@ -451,6 +451,6 @@ async def get_app_info(self): result = await message_dispatcher.AppInfoIO.request(self.connection) return await result - def subscribe(self, subject_name, on_next) -> None: - data_watcher.add_subject(subject_name) - data_watcher.subscribe("GshockAPI", subject_name, on_next) + # def subscribe(self, subject_name, on_next) -> None: + # data_watcher.add_subject(subject_name) + # data_watcher.subscribe("GshockAPI", subject_name, on_next) From a8f20985b3b3d6a382da57c44ecc6f95bb589fe3 Mon Sep 17 00:00:00 2001 From: Ivo Zivkov Date: Sun, 7 Jul 2024 23:29:53 -0400 Subject: [PATCH 119/123] Removed RxPy dependency --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index ce5162d..e2b8d8e 100644 --- a/README.rst +++ b/README.rst @@ -42,8 +42,6 @@ Install the following dependencies: pip3 install bleak - pip3 install reactivex - Troubleshooting: ================ If your watch cannot connect, and the ``--multi-watch`` parameter is not used, remove the "config.ini" file and try again. From 95560c09231fd3eff424c1507693492495fe0fcb Mon Sep 17 00:00:00 2001 From: Florent de Lamotte Date: Wed, 27 Nov 2024 09:54:30 +0100 Subject: [PATCH 120/123] Added GBM-2100 model (which is a GA-2100) --- src/gshocktimeserver/watch_info.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gshocktimeserver/watch_info.py b/src/gshocktimeserver/watch_info.py index f3d68fa..0ee26a9 100644 --- a/src/gshocktimeserver/watch_info.py +++ b/src/gshocktimeserver/watch_info.py @@ -213,6 +213,8 @@ def set_name_and_model(self, name): self.model = WATCH_MODEL.GST elif self.shortName.startswith("GBD"): self.model = WATCH_MODEL.GBD + elif self.shortName.startswith("GBM"): + self.model = WATCH_MODEL.GA elif self.shortName.startswith("GMW"): self.model = WATCH_MODEL.GMW elif self.shortName.startswith("DW"): From f3d9a4b65c482edd951cf87242ad49c5cfabf35d Mon Sep 17 00:00:00 2001 From: Florent de Lamotte Date: Wed, 27 Nov 2024 09:57:00 +0100 Subject: [PATCH 121/123] Added the FIND condition (long press on lower right) --- src/gshocktimeserver/iolib/button_pressed_io.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gshocktimeserver/iolib/button_pressed_io.py b/src/gshocktimeserver/iolib/button_pressed_io.py index 06f1f3d..0c03b04 100644 --- a/src/gshocktimeserver/iolib/button_pressed_io.py +++ b/src/gshocktimeserver/iolib/button_pressed_io.py @@ -16,6 +16,7 @@ class WatchButton(IntEnum): LOWER_RIGHT = 4 NO_BUTTON = 5 INVALID = 6 + FIND = 7 class ButtonPressedIO: result: CancelableResult = None @@ -65,6 +66,8 @@ def button_pressed_callback(data): if button_indicator == 4 else WatchButton.NO_BUTTON if button_indicator == 3 + else WatchButton.FIND + if button_indicator == 2 # assime that all other buttons from watches such as the ECB-30 are for time set else WatchButton.LOWER_RIGHT ) From db92ddf57958a1a76c5b36e23100e76c435d53bd Mon Sep 17 00:00:00 2001 From: Florent Date: Sat, 14 Dec 2024 20:19:50 +0100 Subject: [PATCH 122/123] Send all reminders on set_reminders, even disabled ones set_enabled_reminders implements the old behaviour if needed ... --- src/gshocktimeserver/gshock_api.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index 7b2bca0..e4c0b7b 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -422,17 +422,33 @@ def to_json(events: list): return events_json + await self.connection.sendMessage( + """{{\"action\": \"SET_REMINDERS\", \"value\": {}}}""".format( + json.dumps(events) + ) + ) + + async def set_enabled_reminders(self, events: list): + """Sets events (reminders) to the watch. Up to 5 events are supported. + + Only sends enabled events + + Parameters + ---------- + events: list of `Event` + + Returns + ------- + None + """ def get_enabled_events(events: list): enabled_events = [event for event in events if event["time"]["enabled"]] return enabled_events # to_json(enabled_events) enabled = get_enabled_events(events) - await self.connection.sendMessage( - """{{\"action\": \"SET_REMINDERS\", \"value\": {}}}""".format( - json.dumps(enabled) - ) - ) + await set_reminders(enabled) + async def get_app_info(self): """Gets and internally sets app info to the watch. From f5771ff14788363cc45a54e8bb6df7cfa7cabecd Mon Sep 17 00:00:00 2001 From: Florent de Lamotte Date: Sun, 26 Jan 2025 16:19:06 +0100 Subject: [PATCH 123/123] better way to get tz name --- src/gshocktimeserver/api_tests.py | 2 +- src/gshocktimeserver/gshock_api.py | 44 +++++++++++++++++++++---- src/gshocktimeserver/gshock_server.py | 4 +-- src/gshocktimeserver/iolib/events_io.py | 4 +++ 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/gshocktimeserver/api_tests.py b/src/gshocktimeserver/api_tests.py index bd76681..57c90d6 100644 --- a/src/gshocktimeserver/api_tests.py +++ b/src/gshocktimeserver/api_tests.py @@ -71,7 +71,7 @@ async def run_api_tests(): logger.info("settings: {}".format(settings_local)) settings_local["button_tone"] = True - settings_local["language"] = "Russian" + settings_local["language"] = "French" settings_local["time_format"] = "24h" await api.set_settings(settings_local) diff --git a/src/gshocktimeserver/gshock_api.py b/src/gshocktimeserver/gshock_api.py index e4c0b7b..d7436b2 100644 --- a/src/gshocktimeserver/gshock_api.py +++ b/src/gshocktimeserver/gshock_api.py @@ -17,7 +17,7 @@ from alarms import alarms_inst from event import Event from watch_info import watch_info - +from tz_helper import sys_tz, casio_city_name class GshockAPI: """ @@ -100,6 +100,12 @@ async def get_world_cities(self, cityNumber: int): city = await self._get_world_cities(cityNumber) return city + async def get_world_cities_TZ(self, cityNumber: int): + city = await self.get_world_cities(cityNumber) + city = casio_city_name(city[0:2], sys_tz.get_name()) + self.logger.info(f"Current city name : {city}") + return city + async def _get_world_cities(self, key: str): result = await message_dispatcher.WorldCitiesIO.request(self.connection, key) return await result @@ -118,6 +124,18 @@ async def get_dst_for_world_cities(self, cityNumber: int) -> str: """ return await self._get_dst_for_world_cities(cityNumber) + async def get_dst_for_world_cities_TZ(self, cityNumber: int) -> str: + val = await self._get_dst_for_world_cities(cityNumber) + + tz = sys_tz.casiotz + val[2] = tz["A"] + val[3] = tz["B"] + val[4] = tz["OFF"] + val[5] = tz["DOFF"] + val[6] = tz["DST"] + + return val + async def _get_dst_for_world_cities(self, key: str) -> str: result = await message_dispatcher.DstForWorldCitiesIO.request( self.connection, key @@ -137,6 +155,16 @@ async def get_dst_watch_state(self, state: DtsState) -> str: """ return await self._get_dst_watch_state(state) + async def get_dst_watch_state_TZ(self, state: DtsState) -> str: + val = await self.get_dst_watch_state(state) + + tz = sys_tz.casiotz + val[3] = tz["DST"] + val[5] = tz["A"] + val[6] = tz["B"] + + return val + async def _get_dst_watch_state(self, state: DtsState) -> str: result = await message_dispatcher.DstWatchStateIO.request( self.connection, state @@ -155,7 +183,7 @@ async def read_and_write(self, function, param): async def read_write_dst_watch_states(self): array_of_dst_watch_state = [ - {"function": self.get_dst_watch_state, "state": DtsState.ZERO}, + {"function": self.get_dst_watch_state_TZ, "state": DtsState.ZERO}, {"function": self.get_dst_watch_state, "state": DtsState.TWO}, {"function": self.get_dst_watch_state, "state": DtsState.FOUR}, ] @@ -165,7 +193,7 @@ async def read_write_dst_watch_states(self): async def read_write_dst_for_world_cities(self): array_of_get_dst_for_world_cities = [ - {"function": self.get_dst_for_world_cities, "city_number": 0}, + {"function": self.get_dst_for_world_cities_TZ, "city_number": 0}, {"function": self.get_dst_for_world_cities, "city_number": 1}, {"function": self.get_dst_for_world_cities, "city_number": 2}, {"function": self.get_dst_for_world_cities, "city_number": 3}, @@ -178,7 +206,7 @@ async def read_write_dst_for_world_cities(self): async def read_write_world_cities(self): array_of_world_cities = [ - {"function": self.get_world_cities, "city_number": 0}, + {"function": self.get_world_cities_TZ, "city_number": 0}, {"function": self.get_world_cities, "city_number": 1}, {"function": self.get_world_cities, "city_number": 2}, {"function": self.get_world_cities, "city_number": 3}, @@ -202,14 +230,17 @@ async def set_time(self, current_time=None): ------- None """ - + sys_tz.refresh () if current_time == None: current_time = time.time() + time_diff = current_time - time.time() + self.logger.info(f"=======> passed: ${current_time}, ${time.time()}") await self.initialize_for_setting_time() - await self._set_time(current_time) + self.logger.info(f"Time is now {time.time()}, diff : {time.time()-current_time}") + await self._set_time(time.time() + time_diff + 1) # 1s for xmit current_time = None async def _set_time(self, current_time): @@ -448,7 +479,6 @@ def get_enabled_events(events: list): enabled = get_enabled_events(events) await set_reminders(enabled) - async def get_app_info(self): """Gets and internally sets app info to the watch. diff --git a/src/gshocktimeserver/gshock_server.py b/src/gshocktimeserver/gshock_server.py index c45ead8..c4cb941 100644 --- a/src/gshocktimeserver/gshock_server.py +++ b/src/gshocktimeserver/gshock_server.py @@ -19,8 +19,8 @@ async def main(argv): - await run_time_server() - # await run_api_tests() + #await run_time_server() + await run_api_tests() def prompt(): diff --git a/src/gshocktimeserver/iolib/events_io.py b/src/gshocktimeserver/iolib/events_io.py index 6419c13..0eae232 100644 --- a/src/gshocktimeserver/iolib/events_io.py +++ b/src/gshocktimeserver/iolib/events_io.py @@ -39,6 +39,10 @@ class EventsIO: connection = None title = None + @staticmethod + async def set_connection(connection): + EventsIO.connection = connection + @staticmethod async def request(connection, event_number): logger.info(f"EventsIO request")